From 2ef72a95c5dec907fba4be36437c3e38e076d14e Mon Sep 17 00:00:00 2001 From: Jackson Kearl Date: Fri, 15 Jun 2018 09:51:25 -0700 Subject: [PATCH 0001/1276] Add config option for when autoclosing is enabled. --- .../editor/common/config/commonEditorConfig.ts | 5 +++++ src/vs/editor/common/config/editorOptions.ts | 16 ++++++++++++++++ src/vs/editor/common/controller/cursorCommon.ts | 2 ++ .../common/controller/cursorTypeOperations.ts | 4 ++-- src/vs/monaco.d.ts | 7 +++++++ .../platform/telemetry/common/telemetryUtils.ts | 1 + 6 files changed, 33 insertions(+), 2 deletions(-) diff --git a/src/vs/editor/common/config/commonEditorConfig.ts b/src/vs/editor/common/config/commonEditorConfig.ts index 9077cbe130a..ef250aa222b 100644 --- a/src/vs/editor/common/config/commonEditorConfig.ts +++ b/src/vs/editor/common/config/commonEditorConfig.ts @@ -428,6 +428,11 @@ const editorConfiguration: IConfigurationNode = { 'default': EDITOR_DEFAULTS.autoClosingBrackets, 'description': nls.localize('autoClosingBrackets', "Controls if the editor should automatically close brackets after opening them") }, + 'editor.autoClosingEnabledBefore': { + 'type': 'string', + 'default': EDITOR_DEFAULTS.autoClosingEnabledBefore, + 'description': nls.localize('autoClosingEnabledBefore', "Sets which characters may fall after the cursor in order for auto closing of brackets to occur") + }, 'editor.formatOnType': { 'type': 'boolean', 'default': EDITOR_DEFAULTS.contribInfo.formatOnType, diff --git a/src/vs/editor/common/config/editorOptions.ts b/src/vs/editor/common/config/editorOptions.ts index 8a7b483c0e2..46d16523936 100644 --- a/src/vs/editor/common/config/editorOptions.ts +++ b/src/vs/editor/common/config/editorOptions.ts @@ -429,6 +429,11 @@ export interface IEditorOptions { * Defaults to true. */ autoClosingBrackets?: boolean; + /** + * Which characters may fall after the cursor in order for auto closing of brackets to occur. + * Defaults to " \n\t". + */ + autoClosingEnabledBefore?: string; /** * Enable auto indentation adjustment. * Defaults to false. @@ -906,6 +911,7 @@ export interface IValidatedEditorOptions { readonly wordWrapBreakAfterCharacters: string; readonly wordWrapBreakObtrusiveCharacters: string; readonly autoClosingBrackets: boolean; + readonly autoClosingEnabledBefore: string; readonly autoIndent: boolean; readonly dragAndDrop: boolean; readonly emptySelectionClipboard: boolean; @@ -941,6 +947,7 @@ export class InternalEditorOptions { // ---- cursor options readonly wordSeparators: string; readonly autoClosingBrackets: boolean; + readonly autoClosingEnabledBefore: string; readonly autoIndent: boolean; readonly useTabStops: boolean; readonly tabFocusMode: boolean; @@ -968,6 +975,7 @@ export class InternalEditorOptions { multiCursorMergeOverlapping: boolean; wordSeparators: string; autoClosingBrackets: boolean; + autoClosingEnabledBefore: string; autoIndent: boolean; useTabStops: boolean; tabFocusMode: boolean; @@ -990,6 +998,7 @@ export class InternalEditorOptions { this.multiCursorMergeOverlapping = source.multiCursorMergeOverlapping; this.wordSeparators = source.wordSeparators; this.autoClosingBrackets = source.autoClosingBrackets; + this.autoClosingEnabledBefore = source.autoClosingEnabledBefore; this.autoIndent = source.autoIndent; this.useTabStops = source.useTabStops; this.tabFocusMode = source.tabFocusMode; @@ -1018,6 +1027,7 @@ export class InternalEditorOptions { && this.multiCursorMergeOverlapping === other.multiCursorMergeOverlapping && this.wordSeparators === other.wordSeparators && this.autoClosingBrackets === other.autoClosingBrackets + && this.autoClosingEnabledBefore === other.autoClosingEnabledBefore && this.autoIndent === other.autoIndent && this.useTabStops === other.useTabStops && this.tabFocusMode === other.tabFocusMode @@ -1047,6 +1057,7 @@ export class InternalEditorOptions { multiCursorMergeOverlapping: (this.multiCursorMergeOverlapping !== newOpts.multiCursorMergeOverlapping), wordSeparators: (this.wordSeparators !== newOpts.wordSeparators), autoClosingBrackets: (this.autoClosingBrackets !== newOpts.autoClosingBrackets), + autoClosingEnabledBefore: (this.autoClosingEnabledBefore !== newOpts.autoClosingEnabledBefore), autoIndent: (this.autoIndent !== newOpts.autoIndent), useTabStops: (this.useTabStops !== newOpts.useTabStops), tabFocusMode: (this.tabFocusMode !== newOpts.tabFocusMode), @@ -1392,6 +1403,7 @@ export interface IConfigurationChangedEvent { readonly multiCursorMergeOverlapping: boolean; readonly wordSeparators: boolean; readonly autoClosingBrackets: boolean; + readonly autoClosingEnabledBefore: boolean; readonly autoIndent: boolean; readonly useTabStops: boolean; readonly tabFocusMode: boolean; @@ -1587,6 +1599,7 @@ export class EditorOptionsValidator { wordWrapBreakAfterCharacters: _string(opts.wordWrapBreakAfterCharacters, defaults.wordWrapBreakAfterCharacters), wordWrapBreakObtrusiveCharacters: _string(opts.wordWrapBreakObtrusiveCharacters, defaults.wordWrapBreakObtrusiveCharacters), autoClosingBrackets: _boolean(opts.autoClosingBrackets, defaults.autoClosingBrackets), + autoClosingEnabledBefore: _string(opts.autoClosingEnabledBefore, defaults.autoClosingEnabledBefore), autoIndent: _boolean(opts.autoIndent, defaults.autoIndent), dragAndDrop: _boolean(opts.dragAndDrop, defaults.dragAndDrop), emptySelectionClipboard: _boolean(opts.emptySelectionClipboard, defaults.emptySelectionClipboard), @@ -1827,6 +1840,7 @@ export class InternalEditorOptionsFactory { wordWrapBreakAfterCharacters: opts.wordWrapBreakAfterCharacters, wordWrapBreakObtrusiveCharacters: opts.wordWrapBreakObtrusiveCharacters, autoClosingBrackets: opts.autoClosingBrackets, + autoClosingEnabledBefore: opts.autoClosingEnabledBefore, autoIndent: opts.autoIndent, dragAndDrop: opts.dragAndDrop, emptySelectionClipboard: opts.emptySelectionClipboard, @@ -2047,6 +2061,7 @@ export class InternalEditorOptionsFactory { multiCursorMergeOverlapping: opts.multiCursorMergeOverlapping, wordSeparators: opts.wordSeparators, autoClosingBrackets: opts.autoClosingBrackets, + autoClosingEnabledBefore: opts.autoClosingEnabledBefore, autoIndent: opts.autoIndent, useTabStops: opts.useTabStops, tabFocusMode: opts.readOnly ? true : env.tabFocusMode, @@ -2280,6 +2295,7 @@ export const EDITOR_DEFAULTS: IValidatedEditorOptions = { wordWrapBreakAfterCharacters: ' \t})]?|&,;¢°′″‰℃、。。、¢,.:;?!%・・ゝゞヽヾーァィゥェォッャュョヮヵヶぁぃぅぇぉっゃゅょゎゕゖㇰㇱㇲㇳㇴㇵㇶㇷㇸㇹㇺㇻㇼㇽㇾㇿ々〻ァィゥェォャュョッー”〉》」』】〕)]}」', wordWrapBreakObtrusiveCharacters: '.', autoClosingBrackets: true, + autoClosingEnabledBefore: ' \n\t', autoIndent: true, dragAndDrop: true, emptySelectionClipboard: true, diff --git a/src/vs/editor/common/controller/cursorCommon.ts b/src/vs/editor/common/controller/cursorCommon.ts index 0563b6a0771..7d03e9aa835 100644 --- a/src/vs/editor/common/controller/cursorCommon.ts +++ b/src/vs/editor/common/controller/cursorCommon.ts @@ -80,6 +80,7 @@ export class CursorConfiguration { public readonly emptySelectionClipboard: boolean; public readonly multiCursorMergeOverlapping: boolean; public readonly autoClosingBrackets: boolean; + public readonly autoClosingEnabledBefore: string; public readonly autoIndent: boolean; public readonly autoClosingPairsOpen: CharacterMap; public readonly autoClosingPairsClose: CharacterMap; @@ -122,6 +123,7 @@ export class CursorConfiguration { this.emptySelectionClipboard = c.emptySelectionClipboard; this.multiCursorMergeOverlapping = c.multiCursorMergeOverlapping; this.autoClosingBrackets = c.autoClosingBrackets; + this.autoClosingEnabledBefore = c.autoClosingEnabledBefore; this.autoIndent = c.autoIndent; this.autoClosingPairsOpen = {}; diff --git a/src/vs/editor/common/controller/cursorTypeOperations.ts b/src/vs/editor/common/controller/cursorTypeOperations.ts index 7085aa16c93..e110980d889 100644 --- a/src/vs/editor/common/controller/cursorTypeOperations.ts +++ b/src/vs/editor/common/controller/cursorTypeOperations.ts @@ -538,7 +538,7 @@ export class TypeOperations { const characterAfter = lineText.charAt(position.column - 1); if (characterAfter) { let isBeforeCloseBrace = TypeOperations._isBeforeClosingBrace(config, ch, characterAfter); - if (!isBeforeCloseBrace && !/\s/.test(characterAfter)) { + if (!isBeforeCloseBrace && config.autoClosingEnabledBefore.indexOf(characterAfter) === -1) { return false; } } @@ -749,7 +749,7 @@ export class TypeOperations { if (characterAfter) { let isBeforeCloseBrace = TypeOperations._isBeforeClosingBrace(config, ch, characterAfter); - if (!isBeforeCloseBrace && !/\s/.test(characterAfter)) { + if (!isBeforeCloseBrace && config.autoClosingEnabledBefore.indexOf(characterAfter) === -1) { continue; } } diff --git a/src/vs/monaco.d.ts b/src/vs/monaco.d.ts index 05aad76b9ef..f5196549459 100644 --- a/src/vs/monaco.d.ts +++ b/src/vs/monaco.d.ts @@ -2771,6 +2771,11 @@ declare namespace monaco.editor { * Defaults to true. */ autoClosingBrackets?: boolean; + /** + * Which characters may fall after the cursor in order for auto closing of brackets to occur. + * Defaults to " \n\t". + */ + autoClosingEnabledBefore?: string; /** * Enable auto indentation adjustment. * Defaults to false. @@ -3182,6 +3187,7 @@ declare namespace monaco.editor { readonly showUnused: boolean; readonly wordSeparators: string; readonly autoClosingBrackets: boolean; + readonly autoClosingEnabledBefore: string; readonly autoIndent: boolean; readonly useTabStops: boolean; readonly tabFocusMode: boolean; @@ -3320,6 +3326,7 @@ declare namespace monaco.editor { readonly multiCursorMergeOverlapping: boolean; readonly wordSeparators: boolean; readonly autoClosingBrackets: boolean; + readonly autoClosingEnabledBefore: boolean; readonly autoIndent: boolean; readonly useTabStops: boolean; readonly tabFocusMode: boolean; diff --git a/src/vs/platform/telemetry/common/telemetryUtils.ts b/src/vs/platform/telemetry/common/telemetryUtils.ts index 3d75158aa79..2e1e9b5f710 100644 --- a/src/vs/platform/telemetry/common/telemetryUtils.ts +++ b/src/vs/platform/telemetry/common/telemetryUtils.ts @@ -93,6 +93,7 @@ const configurationValueWhitelist = [ 'editor.quickSuggestionsDelay', 'editor.parameterHints', 'editor.autoClosingBrackets', + 'editor.autoClosingEnabledBefore', 'editor.autoIndent', 'editor.formatOnType', 'editor.formatOnPaste', From 578d3dbc22f5ea154f97b8c522715683ceb310fd Mon Sep 17 00:00:00 2001 From: Jackson Kearl Date: Tue, 19 Jun 2018 15:24:33 -0700 Subject: [PATCH 0002/1276] Extend the default enabled before set --- src/vs/editor/common/config/editorOptions.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vs/editor/common/config/editorOptions.ts b/src/vs/editor/common/config/editorOptions.ts index 46d16523936..e9f9e8a256c 100644 --- a/src/vs/editor/common/config/editorOptions.ts +++ b/src/vs/editor/common/config/editorOptions.ts @@ -2295,7 +2295,7 @@ export const EDITOR_DEFAULTS: IValidatedEditorOptions = { wordWrapBreakAfterCharacters: ' \t})]?|&,;¢°′″‰℃、。。、¢,.:;?!%・・ゝゞヽヾーァィゥェォッャュョヮヵヶぁぃぅぇぉっゃゅょゎゕゖㇰㇱㇲㇳㇴㇵㇶㇷㇸㇹㇺㇻㇼㇽㇾㇿ々〻ァィゥェォャュョッー”〉》」』】〕)]}」', wordWrapBreakObtrusiveCharacters: '.', autoClosingBrackets: true, - autoClosingEnabledBefore: ' \n\t', + autoClosingEnabledBefore: ',.;:<> \n\t', autoIndent: true, dragAndDrop: true, emptySelectionClipboard: true, From 7be7e2f8a2c455dc66ce7144a1d56d6a87d01f7e Mon Sep 17 00:00:00 2001 From: Jackson Kearl Date: Thu, 21 Jun 2018 10:40:38 -0700 Subject: [PATCH 0003/1276] Implementation --- .../common/config/commonEditorConfig.ts | 60 ++++++++++++-- src/vs/editor/common/config/editorOptions.ts | 83 ++++++++++++++----- .../editor/common/controller/cursorCommon.ts | 9 +- .../controller/cursorDeleteOperations.ts | 8 +- .../common/controller/cursorTypeOperations.ts | 29 ++++--- src/vs/monaco.d.ts | 32 +++++-- 6 files changed, 170 insertions(+), 51 deletions(-) diff --git a/src/vs/editor/common/config/commonEditorConfig.ts b/src/vs/editor/common/config/commonEditorConfig.ts index ef250aa222b..949b1aeafd4 100644 --- a/src/vs/editor/common/config/commonEditorConfig.ts +++ b/src/vs/editor/common/config/commonEditorConfig.ts @@ -424,14 +424,62 @@ const editorConfiguration: IConfigurationNode = { 'description': nls.localize('parameterHints', "Enables pop-up that shows parameter documentation and type information as you type") }, 'editor.autoClosingBrackets': { - 'type': 'boolean', + 'anyOf': [ + { + type: 'boolean', + }, + { + type: 'object', + properties: { + autoClose: { + type: 'boolean', + default: EDITOR_DEFAULTS.autoClosingBrackets.autoClose, + description: nls.localize('autoClosingBrackets.autoClose', "Controls if the editor should automatically close brackets after opening them.") + }, + autoWrap: { + type: 'boolean', + default: EDITOR_DEFAULTS.autoClosingBrackets.autoWrap, + description: nls.localize('autoClosingBrackets.autoWrap', "Controls if the editor should automatically wrap selections in brackets.") + }, + enabledBefore: { + type: 'string', + default: EDITOR_DEFAULTS.autoClosingBrackets.enabledBefore, + description: nls.localize('autoClosingBrackets.enabledBefore', "List of all characters which the editor should allow bracket auto-closing before.") + } + } + } + ], 'default': EDITOR_DEFAULTS.autoClosingBrackets, - 'description': nls.localize('autoClosingBrackets', "Controls if the editor should automatically close brackets after opening them") + 'description': nls.localize('autoClosingBrackets', "Controls if and when the editor should automatically close brackets after opening them") }, - 'editor.autoClosingEnabledBefore': { - 'type': 'string', - 'default': EDITOR_DEFAULTS.autoClosingEnabledBefore, - 'description': nls.localize('autoClosingEnabledBefore', "Sets which characters may fall after the cursor in order for auto closing of brackets to occur") + 'editor.autoClosingQuotes': { + 'anyOf': [ + { + type: 'boolean', + }, + { + type: 'object', + properties: { + autoClose: { + type: 'boolean', + default: EDITOR_DEFAULTS.autoClosingQuotes.autoClose, + description: nls.localize('autoClosingQuotes.autoClose', "Controls if the editor should automatically close quotes after opening them.") + }, + autoWrap: { + type: 'boolean', + default: EDITOR_DEFAULTS.autoClosingQuotes.autoWrap, + description: nls.localize('autoClosingQuotes.autoWrap', "Controls if the editor should automatically wrap selections in quotes.") + }, + enabledBefore: { + type: 'string', + default: EDITOR_DEFAULTS.autoClosingQuotes.enabledBefore, + description: nls.localize('autoClosingQuotes.enabledBefore', "List of all characters which the editor should allow quote auto-closing before.") + + } + } + } + ], 'default': EDITOR_DEFAULTS.autoClosingQuotes, + 'description': nls.localize('autoClosingQuotes', "Controls if and when the editor should automatically close quotes after opening them") }, 'editor.formatOnType': { 'type': 'boolean', diff --git a/src/vs/editor/common/config/editorOptions.ts b/src/vs/editor/common/config/editorOptions.ts index e9f9e8a256c..244740739b4 100644 --- a/src/vs/editor/common/config/editorOptions.ts +++ b/src/vs/editor/common/config/editorOptions.ts @@ -95,6 +95,24 @@ export interface IEditorFindOptions { globalFindClipboard: boolean; } +/** + * Configuration options for auto closing both quotes and brackets + */ +export interface EditorAutoClosingOptions { + /** + * Controls if we wrap selections with the auto-pairing character + */ + autoWrap: boolean; + /** + * Controls if we automatically insert a matching close to this pair + */ + autoClose: boolean; + /** + * controls the set of characters that we may insert a matching close before + */ + enabledBefore: string; +} + /** * Configuration options for editor minimap */ @@ -428,12 +446,12 @@ export interface IEditorOptions { * Enable auto closing brackets. * Defaults to true. */ - autoClosingBrackets?: boolean; + autoClosingBrackets?: EditorAutoClosingOptions; /** - * Which characters may fall after the cursor in order for auto closing of brackets to occur. - * Defaults to " \n\t". + * Enable auto closing quotes. + * Defaults to true. */ - autoClosingEnabledBefore?: string; + autoClosingQuotes?: EditorAutoClosingOptions; /** * Enable auto indentation adjustment. * Defaults to false. @@ -910,8 +928,8 @@ export interface IValidatedEditorOptions { readonly wordWrapBreakBeforeCharacters: string; readonly wordWrapBreakAfterCharacters: string; readonly wordWrapBreakObtrusiveCharacters: string; - readonly autoClosingBrackets: boolean; - readonly autoClosingEnabledBefore: string; + readonly autoClosingBrackets: EditorAutoClosingOptions; + readonly autoClosingQuotes: EditorAutoClosingOptions; readonly autoIndent: boolean; readonly dragAndDrop: boolean; readonly emptySelectionClipboard: boolean; @@ -946,8 +964,8 @@ export class InternalEditorOptions { // ---- cursor options readonly wordSeparators: string; - readonly autoClosingBrackets: boolean; - readonly autoClosingEnabledBefore: string; + readonly autoClosingBrackets: EditorAutoClosingOptions; + readonly autoClosingQuotes: EditorAutoClosingOptions; readonly autoIndent: boolean; readonly useTabStops: boolean; readonly tabFocusMode: boolean; @@ -974,8 +992,8 @@ export class InternalEditorOptions { multiCursorModifier: 'altKey' | 'ctrlKey' | 'metaKey'; multiCursorMergeOverlapping: boolean; wordSeparators: string; - autoClosingBrackets: boolean; - autoClosingEnabledBefore: string; + autoClosingBrackets: EditorAutoClosingOptions; + autoClosingQuotes: EditorAutoClosingOptions; autoIndent: boolean; useTabStops: boolean; tabFocusMode: boolean; @@ -998,7 +1016,7 @@ export class InternalEditorOptions { this.multiCursorMergeOverlapping = source.multiCursorMergeOverlapping; this.wordSeparators = source.wordSeparators; this.autoClosingBrackets = source.autoClosingBrackets; - this.autoClosingEnabledBefore = source.autoClosingEnabledBefore; + this.autoClosingQuotes = source.autoClosingQuotes; this.autoIndent = source.autoIndent; this.useTabStops = source.useTabStops; this.tabFocusMode = source.tabFocusMode; @@ -1026,8 +1044,6 @@ export class InternalEditorOptions { && this.multiCursorModifier === other.multiCursorModifier && this.multiCursorMergeOverlapping === other.multiCursorMergeOverlapping && this.wordSeparators === other.wordSeparators - && this.autoClosingBrackets === other.autoClosingBrackets - && this.autoClosingEnabledBefore === other.autoClosingEnabledBefore && this.autoIndent === other.autoIndent && this.useTabStops === other.useTabStops && this.tabFocusMode === other.tabFocusMode @@ -1036,6 +1052,8 @@ export class InternalEditorOptions { && this.emptySelectionClipboard === other.emptySelectionClipboard && InternalEditorOptions._equalsLayoutInfo(this.layoutInfo, other.layoutInfo) && this.fontInfo.equals(other.fontInfo) + && InternalEditorOptions._equalsAutoClosingConfig(this.autoClosingBrackets, other.autoClosingBrackets) + && InternalEditorOptions._equalsAutoClosingConfig(this.autoClosingQuotes, other.autoClosingQuotes) && InternalEditorOptions._equalsViewOptions(this.viewInfo, other.viewInfo) && InternalEditorOptions._equalsWrappingInfo(this.wrappingInfo, other.wrappingInfo) && InternalEditorOptions._equalsContribOptions(this.contribInfo, other.contribInfo) @@ -1056,8 +1074,8 @@ export class InternalEditorOptions { multiCursorModifier: (this.multiCursorModifier !== newOpts.multiCursorModifier), multiCursorMergeOverlapping: (this.multiCursorMergeOverlapping !== newOpts.multiCursorMergeOverlapping), wordSeparators: (this.wordSeparators !== newOpts.wordSeparators), - autoClosingBrackets: (this.autoClosingBrackets !== newOpts.autoClosingBrackets), - autoClosingEnabledBefore: (this.autoClosingEnabledBefore !== newOpts.autoClosingEnabledBefore), + autoClosingBrackets: (!InternalEditorOptions._equalsAutoClosingConfig(this.autoClosingBrackets, newOpts.autoClosingBrackets)), + autoClosingQuotes: (!InternalEditorOptions._equalsAutoClosingConfig(this.autoClosingQuotes, newOpts.autoClosingQuotes)), autoIndent: (this.autoIndent !== newOpts.autoIndent), useTabStops: (this.useTabStops !== newOpts.useTabStops), tabFocusMode: (this.tabFocusMode !== newOpts.tabFocusMode), @@ -1100,6 +1118,17 @@ export class InternalEditorOptions { ); } + /** + * @internal + */ + private static _equalsAutoClosingConfig(a: EditorAutoClosingOptions, b: EditorAutoClosingOptions) { + return ( + a.autoClose === b.autoClose + && a.autoWrap === b.autoWrap + && a.enabledBefore === b.enabledBefore + ); + } + /** * @internal */ @@ -1403,7 +1432,7 @@ export interface IConfigurationChangedEvent { readonly multiCursorMergeOverlapping: boolean; readonly wordSeparators: boolean; readonly autoClosingBrackets: boolean; - readonly autoClosingEnabledBefore: boolean; + readonly autoClosingQuotes: boolean; readonly autoIndent: boolean; readonly useTabStops: boolean; readonly tabFocusMode: boolean; @@ -1569,6 +1598,16 @@ export class EditorOptionsValidator { wordWrap = _stringSet<'off' | 'on' | 'wordWrapColumn' | 'bounded'>(wordWrap, defaults.wordWrap, ['off', 'on', 'wordWrapColumn', 'bounded']); } + const _autoClosingOptions = (config: any, defaultValue: EditorAutoClosingOptions): EditorAutoClosingOptions => { + if (typeof config === 'boolean') { return { autoClose: config, autoWrap: config, enabledBefore: ' \t\n' }; } + + let copy: EditorAutoClosingOptions = { autoClose: defaultValue.autoClose, autoWrap: defaultValue.autoWrap, enabledBefore: defaultValue.enabledBefore }; + if (typeof config.autoClose === 'boolean') { copy.autoClose = config.autoClose; } + if (typeof config.autoWrap === 'boolean') { copy.autoWrap = config.autoWrap; } + if (typeof config.enabledBefore === 'string') { copy.enabledBefore = config.enabledBefore; } + return copy; + }; + const viewInfo = this._sanitizeViewInfo(opts, defaults.viewInfo); const contribInfo = this._sanitizeContribInfo(opts, defaults.contribInfo); @@ -1598,8 +1637,8 @@ export class EditorOptionsValidator { wordWrapBreakBeforeCharacters: _string(opts.wordWrapBreakBeforeCharacters, defaults.wordWrapBreakBeforeCharacters), wordWrapBreakAfterCharacters: _string(opts.wordWrapBreakAfterCharacters, defaults.wordWrapBreakAfterCharacters), wordWrapBreakObtrusiveCharacters: _string(opts.wordWrapBreakObtrusiveCharacters, defaults.wordWrapBreakObtrusiveCharacters), - autoClosingBrackets: _boolean(opts.autoClosingBrackets, defaults.autoClosingBrackets), - autoClosingEnabledBefore: _string(opts.autoClosingEnabledBefore, defaults.autoClosingEnabledBefore), + autoClosingBrackets: _autoClosingOptions(opts.autoClosingBrackets, defaults.autoClosingBrackets), + autoClosingQuotes: _autoClosingOptions(opts.autoClosingQuotes, defaults.autoClosingQuotes), autoIndent: _boolean(opts.autoIndent, defaults.autoIndent), dragAndDrop: _boolean(opts.dragAndDrop, defaults.dragAndDrop), emptySelectionClipboard: _boolean(opts.emptySelectionClipboard, defaults.emptySelectionClipboard), @@ -1840,7 +1879,7 @@ export class InternalEditorOptionsFactory { wordWrapBreakAfterCharacters: opts.wordWrapBreakAfterCharacters, wordWrapBreakObtrusiveCharacters: opts.wordWrapBreakObtrusiveCharacters, autoClosingBrackets: opts.autoClosingBrackets, - autoClosingEnabledBefore: opts.autoClosingEnabledBefore, + autoClosingQuotes: opts.autoClosingQuotes, autoIndent: opts.autoIndent, dragAndDrop: opts.dragAndDrop, emptySelectionClipboard: opts.emptySelectionClipboard, @@ -2061,7 +2100,7 @@ export class InternalEditorOptionsFactory { multiCursorMergeOverlapping: opts.multiCursorMergeOverlapping, wordSeparators: opts.wordSeparators, autoClosingBrackets: opts.autoClosingBrackets, - autoClosingEnabledBefore: opts.autoClosingEnabledBefore, + autoClosingQuotes: opts.autoClosingQuotes, autoIndent: opts.autoIndent, useTabStops: opts.useTabStops, tabFocusMode: opts.readOnly ? true : env.tabFocusMode, @@ -2294,8 +2333,8 @@ export const EDITOR_DEFAULTS: IValidatedEditorOptions = { wordWrapBreakBeforeCharacters: '([{‘“〈《「『【〔([{「£¥$£¥++', wordWrapBreakAfterCharacters: ' \t})]?|&,;¢°′″‰℃、。。、¢,.:;?!%・・ゝゞヽヾーァィゥェォッャュョヮヵヶぁぃぅぇぉっゃゅょゎゕゖㇰㇱㇲㇳㇴㇵㇶㇷㇸㇹㇺㇻㇼㇽㇾㇿ々〻ァィゥェォャュョッー”〉》」』】〕)]}」', wordWrapBreakObtrusiveCharacters: '.', - autoClosingBrackets: true, - autoClosingEnabledBefore: ',.;:<> \n\t', + autoClosingBrackets: { autoClose: true, autoWrap: true, enabledBefore: ',.:; \n\t' }, + autoClosingQuotes: { autoClose: true, autoWrap: true, enabledBefore: ' \n\t' }, autoIndent: true, dragAndDrop: true, emptySelectionClipboard: true, diff --git a/src/vs/editor/common/controller/cursorCommon.ts b/src/vs/editor/common/controller/cursorCommon.ts index 7d03e9aa835..0b570cee02b 100644 --- a/src/vs/editor/common/controller/cursorCommon.ts +++ b/src/vs/editor/common/controller/cursorCommon.ts @@ -15,7 +15,7 @@ import { LanguageConfigurationRegistry } from 'vs/editor/common/modes/languageCo import { onUnexpectedError } from 'vs/base/common/errors'; import { LanguageIdentifier } from 'vs/editor/common/modes'; import { IAutoClosingPair } from 'vs/editor/common/modes/languageConfiguration'; -import { IConfigurationChangedEvent } from 'vs/editor/common/config/editorOptions'; +import { IConfigurationChangedEvent, EditorAutoClosingOptions } from 'vs/editor/common/config/editorOptions'; import { IViewModel } from 'vs/editor/common/viewModel/viewModel'; import { CursorChangeReason } from 'vs/editor/common/controller/cursorEvents'; import { VerticalRevealType } from 'vs/editor/common/view/viewEvents'; @@ -79,8 +79,8 @@ export class CursorConfiguration { public readonly wordSeparators: string; public readonly emptySelectionClipboard: boolean; public readonly multiCursorMergeOverlapping: boolean; - public readonly autoClosingBrackets: boolean; - public readonly autoClosingEnabledBefore: string; + public readonly autoClosingBrackets: EditorAutoClosingOptions; + public readonly autoClosingQuotes: EditorAutoClosingOptions; public readonly autoIndent: boolean; public readonly autoClosingPairsOpen: CharacterMap; public readonly autoClosingPairsClose: CharacterMap; @@ -96,6 +96,7 @@ export class CursorConfiguration { || e.emptySelectionClipboard || e.multiCursorMergeOverlapping || e.autoClosingBrackets + || e.autoClosingQuotes || e.useTabStops || e.lineHeight || e.readOnly @@ -123,7 +124,7 @@ export class CursorConfiguration { this.emptySelectionClipboard = c.emptySelectionClipboard; this.multiCursorMergeOverlapping = c.multiCursorMergeOverlapping; this.autoClosingBrackets = c.autoClosingBrackets; - this.autoClosingEnabledBefore = c.autoClosingEnabledBefore; + this.autoClosingQuotes = c.autoClosingQuotes; this.autoIndent = c.autoIndent; this.autoClosingPairsOpen = {}; diff --git a/src/vs/editor/common/controller/cursorDeleteOperations.ts b/src/vs/editor/common/controller/cursorDeleteOperations.ts index e5b498b40e9..c214269277c 100644 --- a/src/vs/editor/common/controller/cursorDeleteOperations.ts +++ b/src/vs/editor/common/controller/cursorDeleteOperations.ts @@ -49,7 +49,8 @@ export class DeleteOperations { } private static _isAutoClosingPairDelete(config: CursorConfiguration, model: ICursorSimpleModel, selections: Selection[]): boolean { - if (!config.autoClosingBrackets) { + if (!(config.autoClosingBrackets.autoClose || config.autoClosingBrackets.autoWrap + || config.autoClosingQuotes.autoClose || config.autoClosingQuotes.autoWrap)) { return false; } @@ -64,7 +65,10 @@ export class DeleteOperations { const lineText = model.getLineContent(position.lineNumber); const character = lineText[position.column - 2]; - if (!config.autoClosingPairsOpen.hasOwnProperty(character)) { + const characterIsQuote = (character === '\'' || character === '"'); + const autoCloseConfig = characterIsQuote ? config.autoClosingQuotes : config.autoClosingBrackets; + + if (!config.autoClosingPairsOpen.hasOwnProperty(character) || !(autoCloseConfig.autoWrap || autoCloseConfig.autoClose)) { return false; } diff --git a/src/vs/editor/common/controller/cursorTypeOperations.ts b/src/vs/editor/common/controller/cursorTypeOperations.ts index e110980d889..f026298bc31 100644 --- a/src/vs/editor/common/controller/cursorTypeOperations.ts +++ b/src/vs/editor/common/controller/cursorTypeOperations.ts @@ -437,7 +437,10 @@ export class TypeOperations { } private static _isAutoClosingCloseCharType(config: CursorConfiguration, model: ITextModel, selections: Selection[], ch: string): boolean { - if (!config.autoClosingBrackets || !config.autoClosingPairsClose.hasOwnProperty(ch)) { + const chIsQuote = (ch === '\'' || ch === '"'); + const autoCloseConfig = chIsQuote ? config.autoClosingQuotes : config.autoClosingBrackets; + + if (!autoCloseConfig.autoClose || !config.autoClosingPairsClose.hasOwnProperty(ch)) { return false; } @@ -511,7 +514,9 @@ export class TypeOperations { } private static _isAutoClosingOpenCharType(config: CursorConfiguration, model: ITextModel, selections: Selection[], ch: string): boolean { - if (!config.autoClosingBrackets || !config.autoClosingPairsOpen.hasOwnProperty(ch)) { + const chIsQuote = (ch === '\'' || ch === '"'); + const autoCloseConfig = chIsQuote ? config.autoClosingQuotes : config.autoClosingBrackets; + if (!autoCloseConfig.autoClose || !config.autoClosingPairsOpen.hasOwnProperty(ch)) { return false; } @@ -524,8 +529,9 @@ export class TypeOperations { const position = selection.getPosition(); const lineText = model.getLineContent(position.lineNumber); + // Do not auto-close ' or " after a word character - if ((ch === '\'' || ch === '"') && position.column > 1) { + if (chIsQuote && position.column > 1) { const wordSeparators = getMapForWordSeparators(config.wordSeparators); const characterBeforeCode = lineText.charCodeAt(position.column - 2); const characterBeforeType = wordSeparators.get(characterBeforeCode); @@ -538,7 +544,8 @@ export class TypeOperations { const characterAfter = lineText.charAt(position.column - 1); if (characterAfter) { let isBeforeCloseBrace = TypeOperations._isBeforeClosingBrace(config, ch, characterAfter); - if (!isBeforeCloseBrace && config.autoClosingEnabledBefore.indexOf(characterAfter) === -1) { + + if (!isBeforeCloseBrace && autoCloseConfig.enabledBefore.indexOf(characterAfter) === -1) { return false; } } @@ -580,12 +587,12 @@ export class TypeOperations { } private static _isSurroundSelectionType(config: CursorConfiguration, model: ITextModel, selections: Selection[], ch: string): boolean { - if (!config.autoClosingBrackets || !config.surroundingPairs.hasOwnProperty(ch)) { + const chIsQuote = (ch === '\'' || ch === '"'); + const autoCloseConfig = chIsQuote ? config.autoClosingQuotes : config.autoClosingBrackets; + if (!autoCloseConfig.autoWrap || !config.surroundingPairs.hasOwnProperty(ch)) { return false; } - const isTypingAQuoteCharacter = (ch === '\'' || ch === '"'); - for (let i = 0, len = selections.length; i < len; i++) { const selection = selections[i]; @@ -611,7 +618,7 @@ export class TypeOperations { return false; } - if (isTypingAQuoteCharacter && selection.startLineNumber === selection.endLineNumber && selection.startColumn + 1 === selection.endColumn) { + if (chIsQuote && selection.startLineNumber === selection.endLineNumber && selection.startColumn + 1 === selection.endColumn) { const selectionText = model.getValueInRange(selection); if ((selectionText === '\'' || selectionText === '"')) { // Typing a quote character on top of another quote character @@ -708,7 +715,7 @@ export class TypeOperations { } public static compositionEndWithInterceptors(prevEditOperationType: EditOperationType, config: CursorConfiguration, model: ITextModel, selections: Selection[]): EditOperationResult { - if (!config.autoClosingBrackets) { + if (!config.autoClosingQuotes.autoClose) { return null; } @@ -749,7 +756,9 @@ export class TypeOperations { if (characterAfter) { let isBeforeCloseBrace = TypeOperations._isBeforeClosingBrace(config, ch, characterAfter); - if (!isBeforeCloseBrace && config.autoClosingEnabledBefore.indexOf(characterAfter) === -1) { + const chIsQuote = (ch === '\'' || ch === '"'); + const autoCloseConfig = chIsQuote ? config.autoClosingQuotes : config.autoClosingBrackets; + if (!autoCloseConfig.autoClose || (!isBeforeCloseBrace && autoCloseConfig.enabledBefore.indexOf(characterAfter) === -1)) { continue; } } diff --git a/src/vs/monaco.d.ts b/src/vs/monaco.d.ts index f5196549459..435bde313dd 100644 --- a/src/vs/monaco.d.ts +++ b/src/vs/monaco.d.ts @@ -2445,6 +2445,24 @@ declare namespace monaco.editor { autoFindInSelection: boolean; } + /** + * Configuration options for auto closing both quotes and brackets + */ + export interface EditorAutoClosingOptions { + /** + * Controls if we wrap selections with the auto-pairing character + */ + autoWrap: boolean; + /** + * Controls if we automatically insert a matching close to this pair + */ + autoClose: boolean; + /** + * controls the set of characters that we may insert a matching close before + */ + enabledBefore: string; + } + /** * Configuration options for editor minimap */ @@ -2770,12 +2788,12 @@ declare namespace monaco.editor { * Enable auto closing brackets. * Defaults to true. */ - autoClosingBrackets?: boolean; + autoClosingBrackets?: EditorAutoClosingOptions; /** - * Which characters may fall after the cursor in order for auto closing of brackets to occur. - * Defaults to " \n\t". + * Enable auto closing quotes. + * Defaults to true. */ - autoClosingEnabledBefore?: string; + autoClosingQuotes?: EditorAutoClosingOptions; /** * Enable auto indentation adjustment. * Defaults to false. @@ -3186,8 +3204,8 @@ declare namespace monaco.editor { readonly multiCursorMergeOverlapping: boolean; readonly showUnused: boolean; readonly wordSeparators: string; - readonly autoClosingBrackets: boolean; - readonly autoClosingEnabledBefore: string; + readonly autoClosingBrackets: EditorAutoClosingOptions; + readonly autoClosingQuotes: EditorAutoClosingOptions; readonly autoIndent: boolean; readonly useTabStops: boolean; readonly tabFocusMode: boolean; @@ -3326,7 +3344,7 @@ declare namespace monaco.editor { readonly multiCursorMergeOverlapping: boolean; readonly wordSeparators: boolean; readonly autoClosingBrackets: boolean; - readonly autoClosingEnabledBefore: boolean; + readonly autoClosingQuotes: boolean; readonly autoIndent: boolean; readonly useTabStops: boolean; readonly tabFocusMode: boolean; From 8ad23858a8b3bd68e658e105d3018fa54fa728ba Mon Sep 17 00:00:00 2001 From: Jackson Kearl Date: Thu, 21 Jun 2018 11:12:51 -0700 Subject: [PATCH 0004/1276] tests and bug fixes --- src/vs/editor/common/config/editorOptions.ts | 2 +- .../controller/cursorDeleteOperations.ts | 2 +- .../common/controller/cursorTypeOperations.ts | 8 +- .../test/browser/controller/cursor.test.ts | 169 +++++++++++++++++- 4 files changed, 167 insertions(+), 14 deletions(-) diff --git a/src/vs/editor/common/config/editorOptions.ts b/src/vs/editor/common/config/editorOptions.ts index 244740739b4..aadb957cbc4 100644 --- a/src/vs/editor/common/config/editorOptions.ts +++ b/src/vs/editor/common/config/editorOptions.ts @@ -1600,7 +1600,7 @@ export class EditorOptionsValidator { const _autoClosingOptions = (config: any, defaultValue: EditorAutoClosingOptions): EditorAutoClosingOptions => { if (typeof config === 'boolean') { return { autoClose: config, autoWrap: config, enabledBefore: ' \t\n' }; } - + if (!config) { config = {}; } let copy: EditorAutoClosingOptions = { autoClose: defaultValue.autoClose, autoWrap: defaultValue.autoWrap, enabledBefore: defaultValue.enabledBefore }; if (typeof config.autoClose === 'boolean') { copy.autoClose = config.autoClose; } if (typeof config.autoWrap === 'boolean') { copy.autoWrap = config.autoWrap; } diff --git a/src/vs/editor/common/controller/cursorDeleteOperations.ts b/src/vs/editor/common/controller/cursorDeleteOperations.ts index c214269277c..bdbc5db16c2 100644 --- a/src/vs/editor/common/controller/cursorDeleteOperations.ts +++ b/src/vs/editor/common/controller/cursorDeleteOperations.ts @@ -65,7 +65,7 @@ export class DeleteOperations { const lineText = model.getLineContent(position.lineNumber); const character = lineText[position.column - 2]; - const characterIsQuote = (character === '\'' || character === '"'); + const characterIsQuote = (character === '\'' || character === '"' || character === '`'); const autoCloseConfig = characterIsQuote ? config.autoClosingQuotes : config.autoClosingBrackets; if (!config.autoClosingPairsOpen.hasOwnProperty(character) || !(autoCloseConfig.autoWrap || autoCloseConfig.autoClose)) { diff --git a/src/vs/editor/common/controller/cursorTypeOperations.ts b/src/vs/editor/common/controller/cursorTypeOperations.ts index f026298bc31..2316812ca77 100644 --- a/src/vs/editor/common/controller/cursorTypeOperations.ts +++ b/src/vs/editor/common/controller/cursorTypeOperations.ts @@ -437,7 +437,7 @@ export class TypeOperations { } private static _isAutoClosingCloseCharType(config: CursorConfiguration, model: ITextModel, selections: Selection[], ch: string): boolean { - const chIsQuote = (ch === '\'' || ch === '"'); + const chIsQuote = (ch === '\'' || ch === '"' || ch === '`'); const autoCloseConfig = chIsQuote ? config.autoClosingQuotes : config.autoClosingBrackets; if (!autoCloseConfig.autoClose || !config.autoClosingPairsClose.hasOwnProperty(ch)) { @@ -514,7 +514,7 @@ export class TypeOperations { } private static _isAutoClosingOpenCharType(config: CursorConfiguration, model: ITextModel, selections: Selection[], ch: string): boolean { - const chIsQuote = (ch === '\'' || ch === '"'); + const chIsQuote = (ch === '\'' || ch === '"' || ch === '`'); const autoCloseConfig = chIsQuote ? config.autoClosingQuotes : config.autoClosingBrackets; if (!autoCloseConfig.autoClose || !config.autoClosingPairsOpen.hasOwnProperty(ch)) { return false; @@ -587,7 +587,7 @@ export class TypeOperations { } private static _isSurroundSelectionType(config: CursorConfiguration, model: ITextModel, selections: Selection[], ch: string): boolean { - const chIsQuote = (ch === '\'' || ch === '"'); + const chIsQuote = (ch === '\'' || ch === '"' || ch === '`'); const autoCloseConfig = chIsQuote ? config.autoClosingQuotes : config.autoClosingBrackets; if (!autoCloseConfig.autoWrap || !config.surroundingPairs.hasOwnProperty(ch)) { return false; @@ -620,7 +620,7 @@ export class TypeOperations { if (chIsQuote && selection.startLineNumber === selection.endLineNumber && selection.startColumn + 1 === selection.endColumn) { const selectionText = model.getValueInRange(selection); - if ((selectionText === '\'' || selectionText === '"')) { + if ((selectionText === '\'' || selectionText === '"' || selectionText === '`')) { // Typing a quote character on top of another quote character // => disable surround selection type return false; diff --git a/src/vs/editor/test/browser/controller/cursor.test.ts b/src/vs/editor/test/browser/controller/cursor.test.ts index 7c4d3136f27..9888d8afe61 100644 --- a/src/vs/editor/test/browser/controller/cursor.test.ts +++ b/src/vs/editor/test/browser/controller/cursor.test.ts @@ -3999,14 +3999,14 @@ suite('autoClosingPairs', () => { }, (model, cursor) => { let autoClosePositions = [ - 'var| a| =| [|];|', - 'var| b| =| `asd`;|', - 'var| c| =| \'asd\';|', - 'var| d| =| "asd";|', - 'var| e| =| /*3*/| 3;|', - 'var| f| =| /**| 3| */3;|', - 'var| g| =| (3+5|);|', - 'var| h| =| {| a:| \'value\'| |};|', + 'var| a| =| [|]|;|', + 'var| b| =| `asd`|;|', + 'var| c| =| \'asd\'|;|', + 'var| d| =| "asd"|;|', + 'var| e| =| /*3*/| 3|;|', + 'var| f| =| /**| 3| */3|;|', + 'var| g| =| (3+5|)|;|', + 'var| h| =| {| a|:| \'value\'| |}|;|', ]; for (let i = 0, len = autoClosePositions.length; i < len; i++) { const lineNumber = i + 1; @@ -4025,6 +4025,159 @@ suite('autoClosingPairs', () => { mode.dispose(); }); + + test('configurable open parens', () => { + let mode = new AutoClosingMode(); + usingCursor({ + text: [ + 'var a = [];', + 'var b = `asd`;', + 'var c = \'asd\';', + 'var d = "asd";', + 'var e = /*3*/ 3;', + 'var f = /** 3 */3;', + 'var g = (3+5);', + 'var h = { a: \'value\' };', + ], + languageIdentifier: mode.getLanguageIdentifier(), + editorOpts: { + autoClosingBrackets: { + enabledBefore: 'abc', + autoClose: true, + autoWrap: true + } + } + }, (model, cursor) => { + + let autoClosePositions = [ + 'v|ar |a = [|];|', + 'v|ar |b = `|asd`;|', + 'v|ar |c = \'|asd\';|', + 'v|ar d = "|asd";|', + 'v|ar e = /*3*/ 3;|', + 'v|ar f = /** 3 */3;|', + 'v|ar g = (3+5|);|', + 'v|ar h = { |a: \'v|alue\' |};|', + ]; + for (let i = 0, len = autoClosePositions.length; i < len; i++) { + const lineNumber = i + 1; + const autoCloseColumns = extractSpecialColumns(model.getLineMaxColumn(lineNumber), autoClosePositions[i]); + + for (let column = 1; column < autoCloseColumns.length; column++) { + model.forceTokenization(lineNumber); + if (autoCloseColumns[column] === ColumnType.Special1) { + assertType(model, cursor, lineNumber, column, '(', '()', `auto closes @ (${lineNumber}, ${column})`); + } else { + assertType(model, cursor, lineNumber, column, '(', '(', `does not auto close @ (${lineNumber}, ${column})`); + } + } + } + }); + mode.dispose(); + }); + + test('auto-pairing can be disabled', () => { + let mode = new AutoClosingMode(); + usingCursor({ + text: [ + 'var a = [];', + 'var b = `asd`;', + 'var c = \'asd\';', + 'var d = "asd";', + 'var e = /*3*/ 3;', + 'var f = /** 3 */3;', + 'var g = (3+5);', + 'var h = { a: \'value\' };', + ], + languageIdentifier: mode.getLanguageIdentifier(), + editorOpts: { + autoClosingBrackets: { + enabledBefore: 'abc', + autoClose: false, + autoWrap: true + }, + autoClosingQuotes: { + enabledBefore: 'abc', + autoClose: false, + autoWrap: true + } + } + }, (model, cursor) => { + + let autoClosePositions = [ + 'var a = [];', + 'var b = `asd`;', + 'var c = \'asd\';', + 'var d = "asd";', + 'var e = /*3*/ 3;', + 'var f = /** 3 */3;', + 'var g = (3+5);', + 'var h = { a: \'value\' };', + ]; + for (let i = 0, len = autoClosePositions.length; i < len; i++) { + const lineNumber = i + 1; + const autoCloseColumns = extractSpecialColumns(model.getLineMaxColumn(lineNumber), autoClosePositions[i]); + + for (let column = 1; column < autoCloseColumns.length; column++) { + model.forceTokenization(lineNumber); + if (autoCloseColumns[column] === ColumnType.Special1) { + assertType(model, cursor, lineNumber, column, '(', '()', `auto closes @ (${lineNumber}, ${column})`); + assertType(model, cursor, lineNumber, column, '"', '""', `auto closes @ (${lineNumber}, ${column})`); + } else { + assertType(model, cursor, lineNumber, column, '(', '(', `does not auto close @ (${lineNumber}, ${column})`); + assertType(model, cursor, lineNumber, column, '"', '"', `does not auto close @ (${lineNumber}, ${column})`); + } + } + } + }); + mode.dispose(); + }); + + test('auto wrapping is configurable', () => { + let mode = new AutoClosingMode(); + usingCursor({ + text: [ + 'var a = asd' + ], + languageIdentifier: mode.getLanguageIdentifier() + }, (model, cursor) => { + + cursor.setSelections('test', [ + new Selection(1, 1, 1, 4), + new Selection(1, 9, 1, 12), + ]); + + // type a ` + cursorCommand(cursor, H.Type, { text: '`' }, 'keyboard'); + + assert.equal(model.getValue(), '`var` a = `asd`'); + }); + usingCursor({ + text: [ + 'var a = asd' + ], + languageIdentifier: mode.getLanguageIdentifier(), + editorOpts: { + autoClosingBrackets: { + autoWrap: false, + autoClose: true, + enabledBefore: '' + } + } + }, (model, cursor) => { + + cursor.setSelections('test', [ + new Selection(1, 1, 1, 4), + ]); + + // type a ` + cursorCommand(cursor, H.Type, { text: '`' }, 'keyboard'); + + assert.equal(model.getValue(), '` a = asd'); + }); + mode.dispose(); + }); + test('quote', () => { let mode = new AutoClosingMode(); usingCursor({ From d6688b2e9780569458071e5adaa9ac4633e644ee Mon Sep 17 00:00:00 2001 From: Jackson Kearl Date: Thu, 21 Jun 2018 11:20:30 -0700 Subject: [PATCH 0005/1276] Fix bug in tests --- src/vs/editor/test/browser/controller/cursor.test.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vs/editor/test/browser/controller/cursor.test.ts b/src/vs/editor/test/browser/controller/cursor.test.ts index 9888d8afe61..be832003143 100644 --- a/src/vs/editor/test/browser/controller/cursor.test.ts +++ b/src/vs/editor/test/browser/controller/cursor.test.ts @@ -4158,7 +4158,7 @@ suite('autoClosingPairs', () => { ], languageIdentifier: mode.getLanguageIdentifier(), editorOpts: { - autoClosingBrackets: { + autoClosingQuotes: { autoWrap: false, autoClose: true, enabledBefore: '' From 1c3bb74e990d8d1a14c760beba1d10c6fb3b764c Mon Sep 17 00:00:00 2001 From: Jackson Kearl Date: Thu, 21 Jun 2018 11:28:01 -0700 Subject: [PATCH 0006/1276] Add html specific auto close config --- extensions/html-language-features/package.json | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/extensions/html-language-features/package.json b/extensions/html-language-features/package.json index 5781a2d2faa..d9f223623bd 100644 --- a/extensions/html-language-features/package.json +++ b/extensions/html-language-features/package.json @@ -170,6 +170,20 @@ "description": "%html.trace.server.desc%" } } + }, + "configurationDefaults": { + "[html]": { + "editor.autoClosingQuotes": { + "autoClose": true, + "autoWrap": true, + "enabledBefore": "<> \n\t" + }, + "editor.autoClosingBrackets": { + "autoClose": true, + "autoWrap": true, + "enabledBefore": ",.:;<> \n\t" + } + } } }, "dependencies": { @@ -181,4 +195,4 @@ "devDependencies": { "@types/node": "7.0.43" } -} +} \ No newline at end of file From 64f18659a5cd6732989f7915e5115b0682dda42b Mon Sep 17 00:00:00 2001 From: Jackson Kearl Date: Thu, 21 Jun 2018 11:43:00 -0700 Subject: [PATCH 0007/1276] Documentation for autowrapping configs --- src/vs/editor/common/config/editorOptions.ts | 8 ++++---- src/vs/monaco.d.ts | 8 ++++---- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/vs/editor/common/config/editorOptions.ts b/src/vs/editor/common/config/editorOptions.ts index aadb957cbc4..b1f318970ac 100644 --- a/src/vs/editor/common/config/editorOptions.ts +++ b/src/vs/editor/common/config/editorOptions.ts @@ -443,13 +443,13 @@ export interface IEditorOptions { */ iconsInSuggestions?: boolean; /** - * Enable auto closing brackets. - * Defaults to true. + * Options for auto closing brackets. + * Defaults to allowing autoclosing before whitespace and punctuation and allowing autowrapping always. */ autoClosingBrackets?: EditorAutoClosingOptions; /** - * Enable auto closing quotes. - * Defaults to true. + * Options for auto closing quotes. + * Defaults to allowing autoclosing before whitespace and allowing autowrapping always. */ autoClosingQuotes?: EditorAutoClosingOptions; /** diff --git a/src/vs/monaco.d.ts b/src/vs/monaco.d.ts index 435bde313dd..436ce8b8b90 100644 --- a/src/vs/monaco.d.ts +++ b/src/vs/monaco.d.ts @@ -2785,13 +2785,13 @@ declare namespace monaco.editor { */ iconsInSuggestions?: boolean; /** - * Enable auto closing brackets. - * Defaults to true. + * Options for auto closing brackets. + * Defaults to allowing both autowrapping and autoclosing. */ autoClosingBrackets?: EditorAutoClosingOptions; /** - * Enable auto closing quotes. - * Defaults to true. + * Options for auto closing quotes. + * Defaults to allowing autoclosing before whitespace and allwoing autowrapping always. */ autoClosingQuotes?: EditorAutoClosingOptions; /** From da77fb3b2af121140e0c5af92826de55a73b26a0 Mon Sep 17 00:00:00 2001 From: Jackson Kearl Date: Thu, 21 Jun 2018 12:01:35 -0700 Subject: [PATCH 0008/1276] Fix monaco.d.ts not being generated and causing my terrible spelling to be committed --- src/vs/editor/common/config/editorOptions.ts | 4 ++-- src/vs/monaco.d.ts | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/vs/editor/common/config/editorOptions.ts b/src/vs/editor/common/config/editorOptions.ts index b1f318970ac..a9b6a08ab17 100644 --- a/src/vs/editor/common/config/editorOptions.ts +++ b/src/vs/editor/common/config/editorOptions.ts @@ -444,12 +444,12 @@ export interface IEditorOptions { iconsInSuggestions?: boolean; /** * Options for auto closing brackets. - * Defaults to allowing autoclosing before whitespace and punctuation and allowing autowrapping always. + * Defaults to allowing auto-closing before whitespace and punctuation and allowing auto-wrapping always. */ autoClosingBrackets?: EditorAutoClosingOptions; /** * Options for auto closing quotes. - * Defaults to allowing autoclosing before whitespace and allowing autowrapping always. + * Defaults to allowing auto-closing before whitespace and allowing auto-wrapping always. */ autoClosingQuotes?: EditorAutoClosingOptions; /** diff --git a/src/vs/monaco.d.ts b/src/vs/monaco.d.ts index 436ce8b8b90..fefe1b10614 100644 --- a/src/vs/monaco.d.ts +++ b/src/vs/monaco.d.ts @@ -2786,12 +2786,12 @@ declare namespace monaco.editor { iconsInSuggestions?: boolean; /** * Options for auto closing brackets. - * Defaults to allowing both autowrapping and autoclosing. + * Defaults to allowing auto-closing before whitespace and punctuation and allowing auto-wrapping always. */ autoClosingBrackets?: EditorAutoClosingOptions; /** * Options for auto closing quotes. - * Defaults to allowing autoclosing before whitespace and allwoing autowrapping always. + * Defaults to allowing auto-closing before whitespace and allowing auto-wrapping always. */ autoClosingQuotes?: EditorAutoClosingOptions; /** From 8ed3b20539fcb05b639cf2efb2dc5c57897a003f Mon Sep 17 00:00:00 2001 From: Joao Moreno Date: Tue, 3 Jul 2018 14:53:32 +0200 Subject: [PATCH 0009/1276] remove progress from winjs promises --- src/vs/base/common/winjs.base.d.ts | 15 +++++---------- 1 file changed, 5 insertions(+), 10 deletions(-) diff --git a/src/vs/base/common/winjs.base.d.ts b/src/vs/base/common/winjs.base.d.ts index b176120a06b..49d6008b68c 100644 --- a/src/vs/base/common/winjs.base.d.ts +++ b/src/vs/base/common/winjs.base.d.ts @@ -5,25 +5,21 @@ /// Interfaces for WinJS export type ErrorCallback = (error: any) => void; -export type ProgressCallback = (progress: TProgress) => void; -export declare class Promise { +export declare class Promise { constructor( executor: ( resolve: (value: T | PromiseLike) => void, - reject: (reason: any) => void, - progress: (progress: TProgress) => void) => void, + reject: (reason: any) => void) => void, oncancel?: () => void); public then( onfulfilled?: ((value: T) => TResult1 | PromiseLike) | null, - onrejected?: ((reason: any) => TResult2 | PromiseLike) | null, - onprogress?: (progress: TProgress) => void): Promise; + onrejected?: ((reason: any) => TResult2 | PromiseLike) | null): Promise; public done( onfulfilled?: (value: T) => void, - onrejected?: (reason: any) => void, - onprogress?: (progress: TProgress) => void): void; + onrejected?: (reason: any) => void): void; public cancel(): void; @@ -58,8 +54,7 @@ export type TValueCallback = (value: T | PromiseLike) => void; export { Promise as TPromise, Promise as PPromise, - TValueCallback as ValueCallback, - ProgressCallback as TProgressCallback + TValueCallback as ValueCallback }; export interface IPromiseErrorDetail { From 8f521a10d2b90884598f70d5932d8ec7750c07ce Mon Sep 17 00:00:00 2001 From: Joao Moreno Date: Tue, 3 Jul 2018 14:56:16 +0200 Subject: [PATCH 0010/1276] remove progress from async --- src/vs/base/common/async.ts | 44 +++++++--------- src/vs/base/test/common/async.test.ts | 72 --------------------------- 2 files changed, 17 insertions(+), 99 deletions(-) diff --git a/src/vs/base/common/async.ts b/src/vs/base/common/async.ts index 985c5185c3a..8d20e594590 100644 --- a/src/vs/base/common/async.ts +++ b/src/vs/base/common/async.ts @@ -6,7 +6,7 @@ 'use strict'; import * as errors from 'vs/base/common/errors'; -import { TPromise, ValueCallback, ErrorCallback, ProgressCallback } from 'vs/base/common/winjs.base'; +import { TPromise, ValueCallback, ErrorCallback } from 'vs/base/common/winjs.base'; import { CancellationToken, CancellationTokenSource } from 'vs/base/common/cancellation'; import { Disposable, IDisposable } from 'vs/base/common/lifecycle'; import { Event, Emitter } from 'vs/base/common/event'; @@ -68,7 +68,7 @@ export function createCancelablePromise(callback: (token: CancellationToken) export function asWinJsPromise(callback: (token: CancellationToken) => T | TPromise | Thenable): TPromise { let source = new CancellationTokenSource(); - return new TPromise((resolve, reject, progress) => { + return new TPromise((resolve, reject) => { let item = callback(source.token); if (item instanceof TPromise) { item.then(result => { @@ -77,7 +77,7 @@ export function asWinJsPromise(callback: (token: CancellationToken) => T | TP }, err => { source.dispose(); reject(err); - }, progress); + }); } else if (isThenable(item)) { item.then(result => { source.dispose(); @@ -194,15 +194,15 @@ export class Throttler { return result; }; - this.queuedPromise = new TPromise((c, e, p) => { - this.activePromise.then(onComplete, onComplete, p).done(c); + this.queuedPromise = new TPromise(c => { + this.activePromise.then(onComplete, onComplete).done(c); }, () => { this.activePromise.cancel(); }); } - return new TPromise((c, e, p) => { - this.queuedPromise.then(c, e, p); + return new TPromise((c, e) => { + this.queuedPromise.then(c, e); }, () => { // no-op }); @@ -210,14 +210,14 @@ export class Throttler { this.activePromise = promiseFactory(); - return new TPromise((c, e, p) => { + return new TPromise((c, e) => { this.activePromise.done((result: any) => { this.activePromise = null; c(result); }, (err: any) => { this.activePromise = null; e(err); - }, p); + }); }, () => { this.activePromise.cancel(); }); @@ -378,20 +378,18 @@ export class ShallowCancelThenPromise extends TPromise { constructor(outer: TPromise) { let completeCallback: ValueCallback, - errorCallback: ErrorCallback, - progressCallback: ProgressCallback; + errorCallback: ErrorCallback; - super((c, e, p) => { + super((c, e) => { completeCallback = c; errorCallback = e; - progressCallback = p; }, () => { // cancel this promise but not the // outer promise errorCallback(errors.canceled()); }); - outer.then(completeCallback, errorCallback, progressCallback); + outer.then(completeCallback, errorCallback); } } @@ -425,7 +423,7 @@ export function always(thenable: TPromise, f: Function): TPromise; export function always(promise: Thenable, f: Function): Thenable; export function always(winjsPromiseOrThenable: Thenable | TPromise, f: Function): TPromise | Thenable { if (isWinJSPromise(winjsPromiseOrThenable)) { - return new TPromise((c, e, p) => { + return new TPromise((c, e) => { winjsPromiseOrThenable.done((result) => { try { f(result); @@ -440,8 +438,6 @@ export function always(winjsPromiseOrThenable: Thenable | TPromise, f: errors.onUnexpectedError(e1); } e(err); - }, (progress) => { - p(progress); }); }, () => { winjsPromiseOrThenable.cancel(); @@ -512,7 +508,6 @@ interface ILimitedTaskFactory { factory: ITask; c: ValueCallback; e: ErrorCallback; - p: ProgressCallback; } /** @@ -541,14 +536,9 @@ export class Limiter { } queue(promiseFactory: ITask): TPromise; - queue(promiseFactory: ITask>): TPromise { - return new TPromise((c, e, p) => { - this.outstandingPromises.push({ - factory: promiseFactory, - c: c, - e: e, - p: p - }); + queue(factory: ITask>): TPromise { + return new TPromise((c, e) => { + this.outstandingPromises.push({ factory, c, e }); this.consume(); }); @@ -560,7 +550,7 @@ export class Limiter { this.runningPromises++; const promise = iLimitedTask.factory(); - promise.done(iLimitedTask.c, iLimitedTask.e, iLimitedTask.p); + promise.done(iLimitedTask.c, iLimitedTask.e); promise.done(() => this.consumed(), () => this.consumed()); } } diff --git a/src/vs/base/test/common/async.test.ts b/src/vs/base/test/common/async.test.ts index 9cab77a9881..e4d0f16503d 100644 --- a/src/vs/base/test/common/async.test.ts +++ b/src/vs/base/test/common/async.test.ts @@ -189,30 +189,6 @@ suite('Async', () => { return TPromise.join(promises); }); - test('Throttler - progress should work', function () { - let order = 0; - let factory = () => new TPromise((c, e, p) => { - TPromise.timeout(0).done(() => { - p(order++); - c(true); - }); - }); - - let throttler = new async.Throttler(); - let promises: TPromise[] = []; - let progresses: any[][] = [[], [], []]; - - promises.push(throttler.queue(factory).then(null, null, (p) => progresses[0].push(p))); - promises.push(throttler.queue(factory).then(null, null, (p) => progresses[1].push(p))); - promises.push(throttler.queue(factory).then(null, null, (p) => progresses[2].push(p))); - - return TPromise.join(promises).then(() => { - assert.deepEqual(progresses[0], [0]); - assert.deepEqual(progresses[1], [0]); - assert.deepEqual(progresses[2], [0]); - }); - }); - test('Delayer', function () { let count = 0; let factory = () => { @@ -364,54 +340,6 @@ suite('Async', () => { return p; }); - test('Delayer - progress should work', function () { - let order = 0; - let factory = () => new TPromise((c, e, p) => { - TPromise.timeout(0).done(() => { - p(order++); - c(true); - }); - }); - - let delayer = new async.Delayer(0); - let promises: TPromise[] = []; - let progresses: any[][] = [[], [], []]; - - promises.push(delayer.trigger(factory).then(null, null, (p) => progresses[0].push(p))); - promises.push(delayer.trigger(factory).then(null, null, (p) => progresses[1].push(p))); - promises.push(delayer.trigger(factory).then(null, null, (p) => progresses[2].push(p))); - - return TPromise.join(promises).then(() => { - assert.deepEqual(progresses[0], [0]); - assert.deepEqual(progresses[1], [0]); - assert.deepEqual(progresses[2], [0]); - }); - }); - - test('ThrottledDelayer - progress should work', function () { - let order = 0; - let factory = () => new TPromise((c, e, p) => { - TPromise.timeout(0).done(() => { - p(order++); - c(true); - }); - }); - - let delayer = new async.ThrottledDelayer(0); - let promises: TPromise[] = []; - let progresses: any[][] = [[], [], []]; - - promises.push(delayer.trigger(factory).then(null, null, (p) => progresses[0].push(p))); - promises.push(delayer.trigger(factory).then(null, null, (p) => progresses[1].push(p))); - promises.push(delayer.trigger(factory).then(null, null, (p) => progresses[2].push(p))); - - return TPromise.join(promises).then(() => { - assert.deepEqual(progresses[0], [0]); - assert.deepEqual(progresses[1], [0]); - assert.deepEqual(progresses[2], [0]); - }); - }); - test('Sequence', function () { let factoryFactory = (n: number) => () => { return TPromise.as(n); From d2397aa52803c68e9fbb5aa2d47ac8293c3d3229 Mon Sep 17 00:00:00 2001 From: HookyQR Date: Wed, 4 Jul 2018 14:06:40 +1200 Subject: [PATCH 0011/1276] Improve word part move and delete for capitalized snake case In ruby (and perhaps other languages) the convention for constants is ALL_CAPS_SNAKE_CASE. This change allows stepping through word parts for this case. It also handles mixed case where an all caps part is likely an acronym with a capitalized word following. eg: `DSLModel`. --- .../common/controller/cursorWordOperations.ts | 25 ++- .../test/wordPartOperations.test.ts | 181 +++++++++++------- 2 files changed, 130 insertions(+), 76 deletions(-) diff --git a/src/vs/editor/common/controller/cursorWordOperations.ts b/src/vs/editor/common/controller/cursorWordOperations.ts index b69d9799b53..da290068cf9 100644 --- a/src/vs/editor/common/controller/cursorWordOperations.ts +++ b/src/vs/editor/common/controller/cursorWordOperations.ts @@ -466,22 +466,37 @@ export class WordOperations { } export function _lastWordPartEnd(str: string, startIndex: number = str.length - 1): number { + let ignoreUpperCase = !strings.isLowerAsciiLetter(str.charCodeAt(startIndex + 1)); for (let i = startIndex; i >= 0; i--) { let chCode = str.charCodeAt(i); - if (chCode === CharCode.Space || chCode === CharCode.Tab || strings.isUpperAsciiLetter(chCode) || chCode === CharCode.Underline) { + if (chCode === CharCode.Space || chCode === CharCode.Tab || (!ignoreUpperCase && strings.isUpperAsciiLetter(chCode)) || chCode === CharCode.Underline) { return i - 1; } + if (ignoreUpperCase && i < startIndex && strings.isLowerAsciiLetter(chCode)) { + return i; + } + ignoreUpperCase = ignoreUpperCase && strings.isUpperAsciiLetter(chCode); } return -1; } -export function _nextWordPartBegin(str: string, startIndex: number = str.length - 1): number { - const checkLowerCase = str.charCodeAt(startIndex - 1) === CharCode.Space; // does a lc char count as a part start? +export function _nextWordPartBegin(str: string, startIndex: number = 0): number { + let prevChCode = str.charCodeAt(startIndex - 1); + let chCode = str.charCodeAt(startIndex); + // handle the special case ' X' and ' x' which is different from the standard methods + if ((prevChCode === CharCode.Space || prevChCode === CharCode.Tab) && (strings.isLowerAsciiLetter(chCode) || strings.isUpperAsciiLetter(chCode))) { + return startIndex + 1; + } + let ignoreUpperCase = strings.isUpperAsciiLetter(chCode); for (let i = startIndex; i < str.length; ++i) { - let chCode = str.charCodeAt(i); - if (chCode === CharCode.Space || chCode === CharCode.Tab || strings.isUpperAsciiLetter(chCode) || (checkLowerCase && strings.isLowerAsciiLetter(chCode))) { + chCode = str.charCodeAt(i); + if (chCode === CharCode.Space || chCode === CharCode.Tab || (!ignoreUpperCase && strings.isUpperAsciiLetter(chCode))) { return i + 1; } + if (ignoreUpperCase && strings.isLowerAsciiLetter(chCode)) { + return i; // multiple UPPERCase : assume an upper case word and a CamelCase word - like DSLModel + } + ignoreUpperCase = ignoreUpperCase && strings.isUpperAsciiLetter(chCode); if (chCode === CharCode.Underline) { return i + 2; } diff --git a/src/vs/editor/contrib/wordPartOperations/test/wordPartOperations.test.ts b/src/vs/editor/contrib/wordPartOperations/test/wordPartOperations.test.ts index 2074dd9cfc6..ee993f138a0 100644 --- a/src/vs/editor/contrib/wordPartOperations/test/wordPartOperations.test.ts +++ b/src/vs/editor/contrib/wordPartOperations/test/wordPartOperations.test.ts @@ -39,7 +39,7 @@ suite('WordPartOperations', () => { test('move word part left basic', () => { withTestCodeEditor([ 'start line', - 'thisIsACamelCaseVar this_is_a_snake_case_var', + 'thisIsACamelCaseVar this_is_a_snake_case_var THIS_IS_CAPS_SNAKE this_ISMixedUse', 'end line' ], {}, (editor, _) => { editor.setPosition(new Position(3, 8)); @@ -47,6 +47,16 @@ suite('WordPartOperations', () => { [3, 5], [3, 4], [3, 1], + [2, 81], + [2, 78], + [2, 73], + [2, 70], + [2, 66], + [2, 65], + [2, 59], + [2, 54], + [2, 51], + [2, 47], [2, 46], [2, 42], [2, 37], @@ -82,7 +92,7 @@ suite('WordPartOperations', () => { test('move word part right basic', () => { withTestCodeEditor([ 'start line', - 'thisIsACamelCaseVar this_is_a_snake_case_var', + 'thisIsACamelCaseVar this_is_a_snake_case_var THIS_IS_CAPS_SNAKE this_ISMixedUse', 'end line' ], {}, (editor, _) => { editor.setPosition(new Position(1, 1)); @@ -105,6 +115,16 @@ suite('WordPartOperations', () => { [2, 38], [2, 43], [2, 46], + [2, 47], + [2, 52], + [2, 55], + [2, 60], + [2, 65], + [2, 66], + [2, 71], + [2, 73], + [2, 78], + [2, 81], [3, 1], [3, 4], [3, 5], @@ -117,93 +137,112 @@ suite('WordPartOperations', () => { const pos = editor.getPosition(); actualStops.push([pos.lineNumber, pos.column]); } - assert.deepEqual(actualStops, expectedStops); }); }); test('delete word part left basic', () => { withTestCodeEditor([ - ' /* Just some text a+= 3 +5-3 */ thisIsACamelCaseVar this_is_a_snake_case_var' + ' /* Just some text a+= 3 +5-3 */ thisIsACamelCaseVar this_is_a_snake_case_var THIS_IS_CAPS_SNAKE this_ISMixedUse' ], {}, (editor, _) => { const model = editor.getModel(); - editor.setPosition(new Position(1, 84)); + editor.setPosition(new Position(1, 1000)); - deleteWordPartLeft(editor); assert.equal(model.getLineContent(1), ' /* Just some text a+= 3 +5-3 */ thisIsACamelCaseVar this_is_a_snake_case', '001'); - deleteWordPartLeft(editor); assert.equal(model.getLineContent(1), ' /* Just some text a+= 3 +5-3 */ thisIsACamelCaseVar this_is_a_snake', '002'); - deleteWordPartLeft(editor); assert.equal(model.getLineContent(1), ' /* Just some text a+= 3 +5-3 */ thisIsACamelCaseVar this_is_a', '003'); - deleteWordPartLeft(editor); assert.equal(model.getLineContent(1), ' /* Just some text a+= 3 +5-3 */ thisIsACamelCaseVar this_is', '004'); - deleteWordPartLeft(editor); assert.equal(model.getLineContent(1), ' /* Just some text a+= 3 +5-3 */ thisIsACamelCaseVar this', '005'); - deleteWordPartLeft(editor); assert.equal(model.getLineContent(1), ' /* Just some text a+= 3 +5-3 */ thisIsACamelCaseVar ', '006'); - deleteWordPartLeft(editor); assert.equal(model.getLineContent(1), ' /* Just some text a+= 3 +5-3 */ thisIsACamelCaseVar', '007'); - deleteWordPartLeft(editor); assert.equal(model.getLineContent(1), ' /* Just some text a+= 3 +5-3 */ thisIsACamelCase', '008'); - deleteWordPartLeft(editor); assert.equal(model.getLineContent(1), ' /* Just some text a+= 3 +5-3 */ thisIsACamel', '009'); - deleteWordPartLeft(editor); assert.equal(model.getLineContent(1), ' /* Just some text a+= 3 +5-3 */ thisIsA', '010'); - deleteWordPartLeft(editor); assert.equal(model.getLineContent(1), ' /* Just some text a+= 3 +5-3 */ thisIs', '011'); - deleteWordPartLeft(editor); assert.equal(model.getLineContent(1), ' /* Just some text a+= 3 +5-3 */ this', '012'); - deleteWordPartLeft(editor); assert.equal(model.getLineContent(1), ' /* Just some text a+= 3 +5-3 */ ', '013'); - deleteWordPartLeft(editor); assert.equal(model.getLineContent(1), ' /* Just some text a+= 3 +5-3 */', '014'); - deleteWordPartLeft(editor); assert.equal(model.getLineContent(1), ' /* Just some text a+= 3 +5-3 ', '015'); - deleteWordPartLeft(editor); assert.equal(model.getLineContent(1), ' /* Just some text a+= 3 +5-3', '015bis'); - deleteWordPartLeft(editor); assert.equal(model.getLineContent(1), ' /* Just some text a+= 3 +5-', '016'); - deleteWordPartLeft(editor); assert.equal(model.getLineContent(1), ' /* Just some text a+= 3 +5', '017'); - deleteWordPartLeft(editor); assert.equal(model.getLineContent(1), ' /* Just some text a+= 3 +', '018'); - deleteWordPartLeft(editor); assert.equal(model.getLineContent(1), ' /* Just some text a+= 3 ', '019'); - deleteWordPartLeft(editor); assert.equal(model.getLineContent(1), ' /* Just some text a+= 3', '019bis'); - deleteWordPartLeft(editor); assert.equal(model.getLineContent(1), ' /* Just some text a+= ', '020'); - deleteWordPartLeft(editor); assert.equal(model.getLineContent(1), ' /* Just some text a+=', '021'); - deleteWordPartLeft(editor); assert.equal(model.getLineContent(1), ' /* Just some text a', '022'); - deleteWordPartLeft(editor); assert.equal(model.getLineContent(1), ' /* Just some text ', '023'); - deleteWordPartLeft(editor); assert.equal(model.getLineContent(1), ' /* Just some text', '024'); - deleteWordPartLeft(editor); assert.equal(model.getLineContent(1), ' /* Just some ', '025'); - deleteWordPartLeft(editor); assert.equal(model.getLineContent(1), ' /* Just some', '026'); - deleteWordPartLeft(editor); assert.equal(model.getLineContent(1), ' /* Just ', '027'); - deleteWordPartLeft(editor); assert.equal(model.getLineContent(1), ' /* Just', '028'); - deleteWordPartLeft(editor); assert.equal(model.getLineContent(1), ' /* ', '029'); - deleteWordPartLeft(editor); assert.equal(model.getLineContent(1), ' /*', '030'); - deleteWordPartLeft(editor); assert.equal(model.getLineContent(1), ' ', '031'); - deleteWordPartLeft(editor); assert.equal(model.getLineContent(1), '', '032'); + deleteWordPartLeft(editor); assert.equal(model.getLineContent(1), ' /* Just some text a+= 3 +5-3 */ thisIsACamelCaseVar this_is_a_snake_case_var THIS_IS_CAPS_SNAKE this_ISMixed', '001'); + deleteWordPartLeft(editor); assert.equal(model.getLineContent(1), ' /* Just some text a+= 3 +5-3 */ thisIsACamelCaseVar this_is_a_snake_case_var THIS_IS_CAPS_SNAKE this_IS', '002'); + deleteWordPartLeft(editor); assert.equal(model.getLineContent(1), ' /* Just some text a+= 3 +5-3 */ thisIsACamelCaseVar this_is_a_snake_case_var THIS_IS_CAPS_SNAKE this', '003'); + deleteWordPartLeft(editor); assert.equal(model.getLineContent(1), ' /* Just some text a+= 3 +5-3 */ thisIsACamelCaseVar this_is_a_snake_case_var THIS_IS_CAPS_SNAKE ', '004'); + deleteWordPartLeft(editor); assert.equal(model.getLineContent(1), ' /* Just some text a+= 3 +5-3 */ thisIsACamelCaseVar this_is_a_snake_case_var THIS_IS_CAPS_SNAKE', '005'); + deleteWordPartLeft(editor); assert.equal(model.getLineContent(1), ' /* Just some text a+= 3 +5-3 */ thisIsACamelCaseVar this_is_a_snake_case_var THIS_IS_CAPS', '006'); + deleteWordPartLeft(editor); assert.equal(model.getLineContent(1), ' /* Just some text a+= 3 +5-3 */ thisIsACamelCaseVar this_is_a_snake_case_var THIS_IS', '007'); + deleteWordPartLeft(editor); assert.equal(model.getLineContent(1), ' /* Just some text a+= 3 +5-3 */ thisIsACamelCaseVar this_is_a_snake_case_var THIS', '008'); + deleteWordPartLeft(editor); assert.equal(model.getLineContent(1), ' /* Just some text a+= 3 +5-3 */ thisIsACamelCaseVar this_is_a_snake_case_var ', '009'); + deleteWordPartLeft(editor); assert.equal(model.getLineContent(1), ' /* Just some text a+= 3 +5-3 */ thisIsACamelCaseVar this_is_a_snake_case_var', '010'); + deleteWordPartLeft(editor); assert.equal(model.getLineContent(1), ' /* Just some text a+= 3 +5-3 */ thisIsACamelCaseVar this_is_a_snake_case', '011'); + deleteWordPartLeft(editor); assert.equal(model.getLineContent(1), ' /* Just some text a+= 3 +5-3 */ thisIsACamelCaseVar this_is_a_snake', '012'); + deleteWordPartLeft(editor); assert.equal(model.getLineContent(1), ' /* Just some text a+= 3 +5-3 */ thisIsACamelCaseVar this_is_a', '013'); + deleteWordPartLeft(editor); assert.equal(model.getLineContent(1), ' /* Just some text a+= 3 +5-3 */ thisIsACamelCaseVar this_is', '014'); + deleteWordPartLeft(editor); assert.equal(model.getLineContent(1), ' /* Just some text a+= 3 +5-3 */ thisIsACamelCaseVar this', '015'); + deleteWordPartLeft(editor); assert.equal(model.getLineContent(1), ' /* Just some text a+= 3 +5-3 */ thisIsACamelCaseVar ', '016'); + deleteWordPartLeft(editor); assert.equal(model.getLineContent(1), ' /* Just some text a+= 3 +5-3 */ thisIsACamelCaseVar', '017'); + deleteWordPartLeft(editor); assert.equal(model.getLineContent(1), ' /* Just some text a+= 3 +5-3 */ thisIsACamelCase', '018'); + deleteWordPartLeft(editor); assert.equal(model.getLineContent(1), ' /* Just some text a+= 3 +5-3 */ thisIsACamel', '019'); + deleteWordPartLeft(editor); assert.equal(model.getLineContent(1), ' /* Just some text a+= 3 +5-3 */ thisIsA', '020'); + deleteWordPartLeft(editor); assert.equal(model.getLineContent(1), ' /* Just some text a+= 3 +5-3 */ thisIs', '021'); + deleteWordPartLeft(editor); assert.equal(model.getLineContent(1), ' /* Just some text a+= 3 +5-3 */ this', '022'); + deleteWordPartLeft(editor); assert.equal(model.getLineContent(1), ' /* Just some text a+= 3 +5-3 */ ', '023'); + deleteWordPartLeft(editor); assert.equal(model.getLineContent(1), ' /* Just some text a+= 3 +5-3 */', '024'); + deleteWordPartLeft(editor); assert.equal(model.getLineContent(1), ' /* Just some text a+= 3 +5-3 ', '025'); + deleteWordPartLeft(editor); assert.equal(model.getLineContent(1), ' /* Just some text a+= 3 +5-3', '025bis'); + deleteWordPartLeft(editor); assert.equal(model.getLineContent(1), ' /* Just some text a+= 3 +5-', '026'); + deleteWordPartLeft(editor); assert.equal(model.getLineContent(1), ' /* Just some text a+= 3 +5', '027'); + deleteWordPartLeft(editor); assert.equal(model.getLineContent(1), ' /* Just some text a+= 3 +', '028'); + deleteWordPartLeft(editor); assert.equal(model.getLineContent(1), ' /* Just some text a+= 3 ', '029'); + deleteWordPartLeft(editor); assert.equal(model.getLineContent(1), ' /* Just some text a+= 3', '029bis'); + deleteWordPartLeft(editor); assert.equal(model.getLineContent(1), ' /* Just some text a+= ', '030'); + deleteWordPartLeft(editor); assert.equal(model.getLineContent(1), ' /* Just some text a+=', '031'); + deleteWordPartLeft(editor); assert.equal(model.getLineContent(1), ' /* Just some text a', '032'); + deleteWordPartLeft(editor); assert.equal(model.getLineContent(1), ' /* Just some text ', '033'); + deleteWordPartLeft(editor); assert.equal(model.getLineContent(1), ' /* Just some text', '034'); + deleteWordPartLeft(editor); assert.equal(model.getLineContent(1), ' /* Just some ', '035'); + deleteWordPartLeft(editor); assert.equal(model.getLineContent(1), ' /* Just some', '036'); + deleteWordPartLeft(editor); assert.equal(model.getLineContent(1), ' /* Just ', '037'); + deleteWordPartLeft(editor); assert.equal(model.getLineContent(1), ' /* Just', '038'); + deleteWordPartLeft(editor); assert.equal(model.getLineContent(1), ' /* ', '039'); + deleteWordPartLeft(editor); assert.equal(model.getLineContent(1), ' /*', '040'); + deleteWordPartLeft(editor); assert.equal(model.getLineContent(1), ' ', '041'); + deleteWordPartLeft(editor); assert.equal(model.getLineContent(1), '', '042'); }); }); test('delete word part right basic', () => { withTestCodeEditor([ - ' /* Just some text a+= 3 +5-3 */ thisIsACamelCaseVar this_is_a_snake_case_var' + ' /* Just some text a+= 3 +5-3 */ thisIsACamelCaseVar this_is_a_snake_case_var THIS_IS_CAPS_SNAKE this_ISMixedUse' ], {}, (editor, _) => { const model = editor.getModel(); editor.setPosition(new Position(1, 1)); - deleteWordPartRight(editor); assert.equal(model.getLineContent(1), '/* Just some text a+= 3 +5-3 */ thisIsACamelCaseVar this_is_a_snake_case_var', '001'); - deleteWordPartRight(editor); assert.equal(model.getLineContent(1), ' Just some text a+= 3 +5-3 */ thisIsACamelCaseVar this_is_a_snake_case_var', '002'); - deleteWordPartRight(editor); assert.equal(model.getLineContent(1), 'Just some text a+= 3 +5-3 */ thisIsACamelCaseVar this_is_a_snake_case_var', '003'); - deleteWordPartRight(editor); assert.equal(model.getLineContent(1), ' some text a+= 3 +5-3 */ thisIsACamelCaseVar this_is_a_snake_case_var', '004'); - deleteWordPartRight(editor); assert.equal(model.getLineContent(1), 'some text a+= 3 +5-3 */ thisIsACamelCaseVar this_is_a_snake_case_var', '005'); - deleteWordPartRight(editor); assert.equal(model.getLineContent(1), ' text a+= 3 +5-3 */ thisIsACamelCaseVar this_is_a_snake_case_var', '006'); - deleteWordPartRight(editor); assert.equal(model.getLineContent(1), 'text a+= 3 +5-3 */ thisIsACamelCaseVar this_is_a_snake_case_var', '007'); - deleteWordPartRight(editor); assert.equal(model.getLineContent(1), ' a+= 3 +5-3 */ thisIsACamelCaseVar this_is_a_snake_case_var', '008'); - deleteWordPartRight(editor); assert.equal(model.getLineContent(1), 'a+= 3 +5-3 */ thisIsACamelCaseVar this_is_a_snake_case_var', '009'); - deleteWordPartRight(editor); assert.equal(model.getLineContent(1), '+= 3 +5-3 */ thisIsACamelCaseVar this_is_a_snake_case_var', '010'); - deleteWordPartRight(editor); assert.equal(model.getLineContent(1), ' 3 +5-3 */ thisIsACamelCaseVar this_is_a_snake_case_var', '011'); - deleteWordPartRight(editor); assert.equal(model.getLineContent(1), ' +5-3 */ thisIsACamelCaseVar this_is_a_snake_case_var', '012'); - deleteWordPartRight(editor); assert.equal(model.getLineContent(1), '5-3 */ thisIsACamelCaseVar this_is_a_snake_case_var', '013'); - deleteWordPartRight(editor); assert.equal(model.getLineContent(1), '-3 */ thisIsACamelCaseVar this_is_a_snake_case_var', '014'); - deleteWordPartRight(editor); assert.equal(model.getLineContent(1), '3 */ thisIsACamelCaseVar this_is_a_snake_case_var', '015'); - deleteWordPartRight(editor); assert.equal(model.getLineContent(1), ' */ thisIsACamelCaseVar this_is_a_snake_case_var', '016'); - deleteWordPartRight(editor); assert.equal(model.getLineContent(1), ' thisIsACamelCaseVar this_is_a_snake_case_var', '017'); - deleteWordPartRight(editor); assert.equal(model.getLineContent(1), 'thisIsACamelCaseVar this_is_a_snake_case_var', '018'); - deleteWordPartRight(editor); assert.equal(model.getLineContent(1), 'IsACamelCaseVar this_is_a_snake_case_var', '019'); - deleteWordPartRight(editor); assert.equal(model.getLineContent(1), 'ACamelCaseVar this_is_a_snake_case_var', '020'); - deleteWordPartRight(editor); assert.equal(model.getLineContent(1), 'CamelCaseVar this_is_a_snake_case_var', '021'); - deleteWordPartRight(editor); assert.equal(model.getLineContent(1), 'CaseVar this_is_a_snake_case_var', '022'); - deleteWordPartRight(editor); assert.equal(model.getLineContent(1), 'Var this_is_a_snake_case_var', '023'); - deleteWordPartRight(editor); assert.equal(model.getLineContent(1), ' this_is_a_snake_case_var', '024'); - deleteWordPartRight(editor); assert.equal(model.getLineContent(1), 'this_is_a_snake_case_var', '025'); - deleteWordPartRight(editor); assert.equal(model.getLineContent(1), 'is_a_snake_case_var', '026'); - deleteWordPartRight(editor); assert.equal(model.getLineContent(1), 'a_snake_case_var', '027'); - deleteWordPartRight(editor); assert.equal(model.getLineContent(1), 'snake_case_var', '028'); - deleteWordPartRight(editor); assert.equal(model.getLineContent(1), 'case_var', '029'); - deleteWordPartRight(editor); assert.equal(model.getLineContent(1), 'var', '030'); - deleteWordPartRight(editor); assert.equal(model.getLineContent(1), '', '031'); + deleteWordPartRight(editor); assert.equal(model.getLineContent(1), '/* Just some text a+= 3 +5-3 */ thisIsACamelCaseVar this_is_a_snake_case_var THIS_IS_CAPS_SNAKE this_ISMixedUse', '001'); + deleteWordPartRight(editor); assert.equal(model.getLineContent(1), ' Just some text a+= 3 +5-3 */ thisIsACamelCaseVar this_is_a_snake_case_var THIS_IS_CAPS_SNAKE this_ISMixedUse', '002'); + deleteWordPartRight(editor); assert.equal(model.getLineContent(1), 'Just some text a+= 3 +5-3 */ thisIsACamelCaseVar this_is_a_snake_case_var THIS_IS_CAPS_SNAKE this_ISMixedUse', '003'); + deleteWordPartRight(editor); assert.equal(model.getLineContent(1), ' some text a+= 3 +5-3 */ thisIsACamelCaseVar this_is_a_snake_case_var THIS_IS_CAPS_SNAKE this_ISMixedUse', '004'); + deleteWordPartRight(editor); assert.equal(model.getLineContent(1), 'some text a+= 3 +5-3 */ thisIsACamelCaseVar this_is_a_snake_case_var THIS_IS_CAPS_SNAKE this_ISMixedUse', '005'); + deleteWordPartRight(editor); assert.equal(model.getLineContent(1), ' text a+= 3 +5-3 */ thisIsACamelCaseVar this_is_a_snake_case_var THIS_IS_CAPS_SNAKE this_ISMixedUse', '006'); + deleteWordPartRight(editor); assert.equal(model.getLineContent(1), 'text a+= 3 +5-3 */ thisIsACamelCaseVar this_is_a_snake_case_var THIS_IS_CAPS_SNAKE this_ISMixedUse', '007'); + deleteWordPartRight(editor); assert.equal(model.getLineContent(1), ' a+= 3 +5-3 */ thisIsACamelCaseVar this_is_a_snake_case_var THIS_IS_CAPS_SNAKE this_ISMixedUse', '008'); + deleteWordPartRight(editor); assert.equal(model.getLineContent(1), 'a+= 3 +5-3 */ thisIsACamelCaseVar this_is_a_snake_case_var THIS_IS_CAPS_SNAKE this_ISMixedUse', '009'); + deleteWordPartRight(editor); assert.equal(model.getLineContent(1), '+= 3 +5-3 */ thisIsACamelCaseVar this_is_a_snake_case_var THIS_IS_CAPS_SNAKE this_ISMixedUse', '010'); + deleteWordPartRight(editor); assert.equal(model.getLineContent(1), ' 3 +5-3 */ thisIsACamelCaseVar this_is_a_snake_case_var THIS_IS_CAPS_SNAKE this_ISMixedUse', '011'); + deleteWordPartRight(editor); assert.equal(model.getLineContent(1), ' +5-3 */ thisIsACamelCaseVar this_is_a_snake_case_var THIS_IS_CAPS_SNAKE this_ISMixedUse', '012'); + deleteWordPartRight(editor); assert.equal(model.getLineContent(1), '5-3 */ thisIsACamelCaseVar this_is_a_snake_case_var THIS_IS_CAPS_SNAKE this_ISMixedUse', '013'); + deleteWordPartRight(editor); assert.equal(model.getLineContent(1), '-3 */ thisIsACamelCaseVar this_is_a_snake_case_var THIS_IS_CAPS_SNAKE this_ISMixedUse', '014'); + deleteWordPartRight(editor); assert.equal(model.getLineContent(1), '3 */ thisIsACamelCaseVar this_is_a_snake_case_var THIS_IS_CAPS_SNAKE this_ISMixedUse', '015'); + deleteWordPartRight(editor); assert.equal(model.getLineContent(1), ' */ thisIsACamelCaseVar this_is_a_snake_case_var THIS_IS_CAPS_SNAKE this_ISMixedUse', '016'); + deleteWordPartRight(editor); assert.equal(model.getLineContent(1), ' thisIsACamelCaseVar this_is_a_snake_case_var THIS_IS_CAPS_SNAKE this_ISMixedUse', '017'); + deleteWordPartRight(editor); assert.equal(model.getLineContent(1), 'thisIsACamelCaseVar this_is_a_snake_case_var THIS_IS_CAPS_SNAKE this_ISMixedUse', '018'); + deleteWordPartRight(editor); assert.equal(model.getLineContent(1), 'IsACamelCaseVar this_is_a_snake_case_var THIS_IS_CAPS_SNAKE this_ISMixedUse', '019'); + deleteWordPartRight(editor); assert.equal(model.getLineContent(1), 'ACamelCaseVar this_is_a_snake_case_var THIS_IS_CAPS_SNAKE this_ISMixedUse', '020'); + deleteWordPartRight(editor); assert.equal(model.getLineContent(1), 'CamelCaseVar this_is_a_snake_case_var THIS_IS_CAPS_SNAKE this_ISMixedUse', '021'); + deleteWordPartRight(editor); assert.equal(model.getLineContent(1), 'CaseVar this_is_a_snake_case_var THIS_IS_CAPS_SNAKE this_ISMixedUse', '022'); + deleteWordPartRight(editor); assert.equal(model.getLineContent(1), 'Var this_is_a_snake_case_var THIS_IS_CAPS_SNAKE this_ISMixedUse', '023'); + deleteWordPartRight(editor); assert.equal(model.getLineContent(1), ' this_is_a_snake_case_var THIS_IS_CAPS_SNAKE this_ISMixedUse', '024'); + deleteWordPartRight(editor); assert.equal(model.getLineContent(1), 'this_is_a_snake_case_var THIS_IS_CAPS_SNAKE this_ISMixedUse', '025'); + deleteWordPartRight(editor); assert.equal(model.getLineContent(1), 'is_a_snake_case_var THIS_IS_CAPS_SNAKE this_ISMixedUse', '026'); + deleteWordPartRight(editor); assert.equal(model.getLineContent(1), 'a_snake_case_var THIS_IS_CAPS_SNAKE this_ISMixedUse', '027'); + deleteWordPartRight(editor); assert.equal(model.getLineContent(1), 'snake_case_var THIS_IS_CAPS_SNAKE this_ISMixedUse', '028'); + deleteWordPartRight(editor); assert.equal(model.getLineContent(1), 'case_var THIS_IS_CAPS_SNAKE this_ISMixedUse', '029'); + deleteWordPartRight(editor); assert.equal(model.getLineContent(1), 'var THIS_IS_CAPS_SNAKE this_ISMixedUse', '030'); + deleteWordPartRight(editor); assert.equal(model.getLineContent(1), ' THIS_IS_CAPS_SNAKE this_ISMixedUse', '031'); + deleteWordPartRight(editor); assert.equal(model.getLineContent(1), 'THIS_IS_CAPS_SNAKE this_ISMixedUse', '032'); + deleteWordPartRight(editor); assert.equal(model.getLineContent(1), 'IS_CAPS_SNAKE this_ISMixedUse', '033'); + deleteWordPartRight(editor); assert.equal(model.getLineContent(1), 'CAPS_SNAKE this_ISMixedUse', '034'); + deleteWordPartRight(editor); assert.equal(model.getLineContent(1), 'SNAKE this_ISMixedUse', '035'); + deleteWordPartRight(editor); assert.equal(model.getLineContent(1), ' this_ISMixedUse', '036'); + deleteWordPartRight(editor); assert.equal(model.getLineContent(1), 'this_ISMixedUse', '037'); + deleteWordPartRight(editor); assert.equal(model.getLineContent(1), 'ISMixedUse', '038'); + deleteWordPartRight(editor); assert.equal(model.getLineContent(1), 'MixedUse', '039'); + deleteWordPartRight(editor); assert.equal(model.getLineContent(1), 'Use', '040'); + deleteWordPartRight(editor); assert.equal(model.getLineContent(1), '', '041'); }); }); }); From cb1432f79a6b792d90afaa6a2b79a04fd4702903 Mon Sep 17 00:00:00 2001 From: Joao Moreno Date: Wed, 4 Jul 2018 08:52:58 +0200 Subject: [PATCH 0012/1276] monaco.d.ts --- src/vs/monaco.d.ts | 13 ++++--------- 1 file changed, 4 insertions(+), 9 deletions(-) diff --git a/src/vs/monaco.d.ts b/src/vs/monaco.d.ts index f46a6a4bbd2..15eac9554ab 100644 --- a/src/vs/monaco.d.ts +++ b/src/vs/monaco.d.ts @@ -48,26 +48,21 @@ declare namespace monaco { export type TValueCallback = (value: T | PromiseLike) => void; - export type ProgressCallback = (progress: TProgress) => void; - - export class Promise { + export class Promise { constructor( executor: ( resolve: (value: T | PromiseLike) => void, - reject: (reason: any) => void, - progress: (progress: TProgress) => void) => void, + reject: (reason: any) => void) => void, oncancel?: () => void); public then( onfulfilled?: ((value: T) => TResult1 | PromiseLike) | null, - onrejected?: ((reason: any) => TResult2 | PromiseLike) | null, - onprogress?: (progress: TProgress) => void): Promise; + onrejected?: ((reason: any) => TResult2 | PromiseLike) | null): Promise; public done( onfulfilled?: (value: T) => void, - onrejected?: (reason: any) => void, - onprogress?: (progress: TProgress) => void): void; + onrejected?: (reason: any) => void): void; public cancel(): void; From 5800ea2ef77958eaf6ee1cbd17ead0f0954f73ac Mon Sep 17 00:00:00 2001 From: Joao Moreno Date: Wed, 4 Jul 2018 08:57:24 +0200 Subject: [PATCH 0013/1276] cleanup types --- .../workbench/test/workbenchTestServices.ts | 32 +++++++++---------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/src/vs/workbench/test/workbenchTestServices.ts b/src/vs/workbench/test/workbenchTestServices.ts index 9c15b408467..5ea115ee115 100644 --- a/src/vs/workbench/test/workbenchTestServices.ts +++ b/src/vs/workbench/test/workbenchTestServices.ts @@ -7,7 +7,7 @@ import 'vs/workbench/parts/files/electron-browser/files.contribution'; // load our contribution into the test import { FileEditorInput } from 'vs/workbench/parts/files/common/editors/fileEditorInput'; -import { Promise, TPromise } from 'vs/base/common/winjs.base'; +import { TPromise } from 'vs/base/common/winjs.base'; import { TestInstantiationService } from 'vs/platform/instantiation/test/common/instantiationServiceMock'; import * as paths from 'vs/base/common/paths'; import URI from 'vs/base/common/uri'; @@ -294,13 +294,13 @@ export class TestExtensionService implements IExtensionService { _serviceBrand: any; onDidRegisterExtensions: Event = Event.None; onDidChangeExtensionsStatus: Event = Event.None; - activateByEvent(activationEvent: string): Promise { return TPromise.as(void 0); } - whenInstalledExtensionsRegistered(): Promise { return TPromise.as(true); } - getExtensions(): Promise { return TPromise.as([]); } - readExtensionPointContributions(extPoint: IExtensionPoint): Promise[]> { return TPromise.as(Object.create(null)); } + activateByEvent(activationEvent: string): TPromise { return TPromise.as(void 0); } + whenInstalledExtensionsRegistered(): TPromise { return TPromise.as(true); } + getExtensions(): TPromise { return TPromise.as([]); } + readExtensionPointContributions(extPoint: IExtensionPoint): TPromise[]> { return TPromise.as(Object.create(null)); } getExtensionsStatus(): { [id: string]: IExtensionsStatus; } { return Object.create(null); } canProfileExtensionHost(): boolean { return false; } - startExtensionHostProfile(): Promise { return TPromise.as(Object.create(null)); } + startExtensionHostProfile(): TPromise { return TPromise.as(Object.create(null)); } restartExtensionHost(): void { } startExtensionHost(): void { } stopExtensionHost(): void { } @@ -361,11 +361,11 @@ export class TestDialogService implements IDialogService { public _serviceBrand: any; - public confirm(confirmation: IConfirmation): Promise { + public confirm(confirmation: IConfirmation): TPromise { return TPromise.as({ confirmed: false }); } - public show(severity: Severity, message: string, buttons: string[], options?: IDialogOptions): Promise { + public show(severity: Severity, message: string, buttons: string[], options?: IDialogOptions): TPromise { return TPromise.as(0); } } @@ -590,7 +590,7 @@ export class TestEditorGroup implements IEditorGroupView { disposed: boolean; editors: ReadonlyArray = []; label: string; - whenRestored: Promise = TPromise.as(void 0); + whenRestored: TPromise = TPromise.as(void 0); element: HTMLElement; minimumWidth: number; maximumWidth: number; @@ -1076,7 +1076,7 @@ export class TestWindowService implements IWindowService { return TPromise.wrap(void 0); } - updateTouchBar(items: ISerializableCommandAction[][]): Promise { + updateTouchBar(items: ISerializableCommandAction[][]): TPromise { return TPromise.as(void 0); } } @@ -1270,27 +1270,27 @@ export class TestWindowsService implements IWindowsService { return TPromise.as(void 0); } - showPreviousWindowTab(): Promise { + showPreviousWindowTab(): TPromise { return TPromise.as(void 0); } - showNextWindowTab(): Promise { + showNextWindowTab(): TPromise { return TPromise.as(void 0); } - moveWindowTabToNewWindow(): Promise { + moveWindowTabToNewWindow(): TPromise { return TPromise.as(void 0); } - mergeAllWindowTabs(): Promise { + mergeAllWindowTabs(): TPromise { return TPromise.as(void 0); } - toggleWindowTabsBar(): Promise { + toggleWindowTabsBar(): TPromise { return TPromise.as(void 0); } - updateTouchBar(windowId: number, items: ISerializableCommandAction[][]): Promise { + updateTouchBar(windowId: number, items: ISerializableCommandAction[][]): TPromise { return TPromise.as(void 0); } From 88b22b0928780e734801d4fdfa7554c65af6b634 Mon Sep 17 00:00:00 2001 From: Joao Moreno Date: Wed, 4 Jul 2018 08:58:06 +0200 Subject: [PATCH 0014/1276] cleanup types --- .../api/electron-browser/mainThreadFileSystem.ts | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/vs/workbench/api/electron-browser/mainThreadFileSystem.ts b/src/vs/workbench/api/electron-browser/mainThreadFileSystem.ts index 29bf1a401c4..0cb44cf4f64 100644 --- a/src/vs/workbench/api/electron-browser/mainThreadFileSystem.ts +++ b/src/vs/workbench/api/electron-browser/mainThreadFileSystem.ts @@ -94,36 +94,36 @@ class RemoteFileSystemProvider implements IFileSystemProvider { }); } - readFile(resource: URI): TPromise { + readFile(resource: URI): TPromise { return this._proxy.$readFile(this._handle, resource).then(encoded => { return Buffer.from(encoded, 'base64'); }); } - writeFile(resource: URI, content: Uint8Array, opts: FileWriteOptions): TPromise { + writeFile(resource: URI, content: Uint8Array, opts: FileWriteOptions): TPromise { let encoded = Buffer.isBuffer(content) ? content.toString('base64') : Buffer.from(content.buffer, content.byteOffset, content.byteLength).toString('base64'); return this._proxy.$writeFile(this._handle, resource, encoded, opts); } - delete(resource: URI, opts: FileDeleteOptions): TPromise { + delete(resource: URI, opts: FileDeleteOptions): TPromise { return this._proxy.$delete(this._handle, resource, opts); } - mkdir(resource: URI): TPromise { + mkdir(resource: URI): TPromise { return this._proxy.$mkdir(this._handle, resource); } - readdir(resource: URI): TPromise<[string, FileType][], any> { + readdir(resource: URI): TPromise<[string, FileType][]> { return this._proxy.$readdir(this._handle, resource); } - rename(resource: URI, target: URI, opts: FileOverwriteOptions): TPromise { + rename(resource: URI, target: URI, opts: FileOverwriteOptions): TPromise { return this._proxy.$rename(this._handle, resource, target, opts); } - copy(resource: URI, target: URI, opts: FileOverwriteOptions): TPromise { + copy(resource: URI, target: URI, opts: FileOverwriteOptions): TPromise { return this._proxy.$copy(this._handle, resource, target, opts); } } From 5277fef2eedfe8260c904c35b16786d884f26b33 Mon Sep 17 00:00:00 2001 From: Joao Moreno Date: Wed, 4 Jul 2018 09:03:16 +0200 Subject: [PATCH 0015/1276] cleanup types --- src/vs/editor/contrib/format/format.ts | 2 +- .../contrib/parameterHints/parameterHintsWidget.ts | 2 +- src/vs/workbench/api/node/extHostFileSystem.ts | 14 +++++++------- .../parts/preferences/browser/settingsTree.ts | 4 ++-- 4 files changed, 11 insertions(+), 11 deletions(-) diff --git a/src/vs/editor/contrib/format/format.ts b/src/vs/editor/contrib/format/format.ts index 60b2b6e72c5..93d850116fa 100644 --- a/src/vs/editor/contrib/format/format.ts +++ b/src/vs/editor/contrib/format/format.ts @@ -26,7 +26,7 @@ export class NoProviderError extends Error { } } -export function getDocumentRangeFormattingEdits(model: ITextModel, range: Range, options: FormattingOptions): TPromise { +export function getDocumentRangeFormattingEdits(model: ITextModel, range: Range, options: FormattingOptions): TPromise { const providers = DocumentRangeFormattingEditProviderRegistry.ordered(model); diff --git a/src/vs/editor/contrib/parameterHints/parameterHintsWidget.ts b/src/vs/editor/contrib/parameterHints/parameterHintsWidget.ts index c0390869a9f..925efbc547e 100644 --- a/src/vs/editor/contrib/parameterHints/parameterHintsWidget.ts +++ b/src/vs/editor/contrib/parameterHints/parameterHintsWidget.ts @@ -50,7 +50,7 @@ export class ParameterHintsModel extends Disposable { private triggerCharactersListeners: IDisposable[]; private active: boolean; private throttledDelayer: RunOnceScheduler; - private provideSignatureHelpRequest?: TPromise; + private provideSignatureHelpRequest?: TPromise; constructor(editor: ICodeEditor) { super(); diff --git a/src/vs/workbench/api/node/extHostFileSystem.ts b/src/vs/workbench/api/node/extHostFileSystem.ts index 1b1d65efcea..7a07b0069e2 100644 --- a/src/vs/workbench/api/node/extHostFileSystem.ts +++ b/src/vs/workbench/api/node/extHostFileSystem.ts @@ -148,11 +148,11 @@ export class ExtHostFileSystem implements ExtHostFileSystemShape { return { type, ctime, mtime, size }; } - $stat(handle: number, resource: UriComponents): TPromise { + $stat(handle: number, resource: UriComponents): TPromise { return asWinJsPromise(() => this._fsProvider.get(handle).stat(URI.revive(resource))).then(ExtHostFileSystem._asIStat); } - $readdir(handle: number, resource: UriComponents): TPromise<[string, files.FileType][], any> { + $readdir(handle: number, resource: UriComponents): TPromise<[string, files.FileType][]> { return asWinJsPromise(() => this._fsProvider.get(handle).readDirectory(URI.revive(resource))); } @@ -164,23 +164,23 @@ export class ExtHostFileSystem implements ExtHostFileSystemShape { }); } - $writeFile(handle: number, resource: UriComponents, base64Content: string, opts: files.FileWriteOptions): TPromise { + $writeFile(handle: number, resource: UriComponents, base64Content: string, opts: files.FileWriteOptions): TPromise { return asWinJsPromise(() => this._fsProvider.get(handle).writeFile(URI.revive(resource), Buffer.from(base64Content, 'base64'), opts)); } - $delete(handle: number, resource: UriComponents, opts: files.FileDeleteOptions): TPromise { + $delete(handle: number, resource: UriComponents, opts: files.FileDeleteOptions): TPromise { return asWinJsPromise(() => this._fsProvider.get(handle).delete(URI.revive(resource), opts)); } - $rename(handle: number, oldUri: UriComponents, newUri: UriComponents, opts: files.FileOverwriteOptions): TPromise { + $rename(handle: number, oldUri: UriComponents, newUri: UriComponents, opts: files.FileOverwriteOptions): TPromise { return asWinJsPromise(() => this._fsProvider.get(handle).rename(URI.revive(oldUri), URI.revive(newUri), opts)); } - $copy(handle: number, oldUri: UriComponents, newUri: UriComponents, opts: files.FileOverwriteOptions): TPromise { + $copy(handle: number, oldUri: UriComponents, newUri: UriComponents, opts: files.FileOverwriteOptions): TPromise { return asWinJsPromise(() => this._fsProvider.get(handle).copy(URI.revive(oldUri), URI.revive(newUri), opts)); } - $mkdir(handle: number, resource: UriComponents): TPromise { + $mkdir(handle: number, resource: UriComponents): TPromise { return asWinJsPromise(() => this._fsProvider.get(handle).createDirectory(URI.revive(resource))); } diff --git a/src/vs/workbench/parts/preferences/browser/settingsTree.ts b/src/vs/workbench/parts/preferences/browser/settingsTree.ts index ac53257f46e..870882c7dfe 100644 --- a/src/vs/workbench/parts/preferences/browser/settingsTree.ts +++ b/src/vs/workbench/parts/preferences/browser/settingsTree.ts @@ -307,7 +307,7 @@ export class SettingsDataSource implements IDataSource { return false; } - getChildren(tree: ITree, element: SettingsTreeElement): TPromise { + getChildren(tree: ITree, element: SettingsTreeElement): TPromise { return TPromise.as(this._getChildren(element)); } @@ -322,7 +322,7 @@ export class SettingsDataSource implements IDataSource { } } - getParent(tree: ITree, element: SettingsTreeElement): TPromise { + getParent(tree: ITree, element: SettingsTreeElement): TPromise { return TPromise.wrap(element.parent); } From da9fea226822619e80c7e3692d03f70ae0904091 Mon Sep 17 00:00:00 2001 From: Joao Moreno Date: Wed, 4 Jul 2018 10:51:35 +0200 Subject: [PATCH 0016/1276] more PPRomise cleanup --- src/vs/base/common/winjs.base.d.ts | 1 - src/vs/base/parts/ipc/test/node/ipc.perf.ts | 114 ------------------ .../base/parts/ipc/test/node/testService.ts | 37 +----- src/vs/platform/url/common/urlIpc.ts | 2 +- .../parts/debug/test/common/mockDebug.ts | 2 +- .../parts/preferences/browser/tocTree.ts | 4 +- .../electron-browser/webviewEditorInput.ts | 2 +- .../electron-browser/remoteFileService.ts | 12 +- 8 files changed, 12 insertions(+), 162 deletions(-) delete mode 100644 src/vs/base/parts/ipc/test/node/ipc.perf.ts diff --git a/src/vs/base/common/winjs.base.d.ts b/src/vs/base/common/winjs.base.d.ts index 49d6008b68c..ddf943a6212 100644 --- a/src/vs/base/common/winjs.base.d.ts +++ b/src/vs/base/common/winjs.base.d.ts @@ -53,7 +53,6 @@ export type TValueCallback = (value: T | PromiseLike) => void; export { Promise as TPromise, - Promise as PPromise, TValueCallback as ValueCallback }; diff --git a/src/vs/base/parts/ipc/test/node/ipc.perf.ts b/src/vs/base/parts/ipc/test/node/ipc.perf.ts deleted file mode 100644 index 2e1fcbcbd83..00000000000 --- a/src/vs/base/parts/ipc/test/node/ipc.perf.ts +++ /dev/null @@ -1,114 +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'; - -import * as assert from 'assert'; -import { Client } from 'vs/base/parts/ipc/node/ipc.cp'; -import uri from 'vs/base/common/uri'; -import { always } from 'vs/base/common/async'; -import { ITestChannel, TestServiceClient, ITestService } from './testService'; - -function createClient(): Client { - return new Client(uri.parse(require.toUrl('bootstrap')).fsPath, { - serverName: 'TestServer', - env: { AMD_ENTRYPOINT: 'vs/base/parts/ipc/test/node/testApp', verbose: true } - }); -} - -// Rename to ipc.perf.test.ts and run with ./scripts/test.sh --grep IPC.performance --timeout 60000 -suite('IPC performance', () => { - - test('increasing batch size', () => { - const client = createClient(); - const channel = client.getChannel('test'); - const service = new TestServiceClient(channel); - - const runs = [ - { batches: 250000, size: 1 }, - { batches: 2500, size: 100 }, - { batches: 500, size: 500 }, - { batches: 250, size: 1000 }, - { batches: 50, size: 5000 }, - { batches: 25, size: 10000 }, - // { batches: 10, size: 25000 }, - // { batches: 5, size: 50000 }, - // { batches: 1, size: 250000 }, - ]; - const dataSizes = [ - 100, - 250, - ]; - let i = 0, j = 0; - const result = measure(service, 10, 10, 250) // warm-up - .then(() => { - return (function nextRun() { - if (i >= runs.length) { - if (++j >= dataSizes.length) { - return; - } - i = 0; - } - const run = runs[i++]; - return measure(service, run.batches, run.size, dataSizes[j]) - .then(() => { - return nextRun(); - }); - })(); - }); - - return always(result, () => client.dispose()); - }); - - test('increasing raw data size', () => { - const client = createClient(); - const channel = client.getChannel('test'); - const service = new TestServiceClient(channel); - - const runs = [ - { batches: 250000, dataSize: 100 }, - { batches: 25000, dataSize: 1000 }, - { batches: 2500, dataSize: 10000 }, - { batches: 1250, dataSize: 20000 }, - { batches: 500, dataSize: 50000 }, - { batches: 250, dataSize: 100000 }, - { batches: 125, dataSize: 200000 }, - { batches: 50, dataSize: 500000 }, - { batches: 25, dataSize: 1000000 }, - ]; - let i = 0; - const result = measure(service, 10, 10, 250) // warm-up - .then(() => { - return (function nextRun() { - if (i >= runs.length) { - return; - } - const run = runs[i++]; - return measure(service, run.batches, 1, run.dataSize) - .then(() => { - return nextRun(); - }); - })(); - }); - - return always(result, () => client.dispose()); - }); - - function measure(service: ITestService, batches: number, size: number, dataSize: number) { - const start = Date.now(); - let hits = 0; - let count = 0; - return service.batchPerf(batches, size, dataSize) - .then(() => { - console.log(`Batches: ${batches}, size: ${size}, dataSize: ${dataSize}, n: ${batches * size * dataSize}, duration: ${Date.now() - start}`); - assert.strictEqual(hits, batches); - assert.strictEqual(count, batches * size); - }, err => assert.fail(err), - batch => { - hits++; - count += batch.length; - }); - } -}); \ No newline at end of file diff --git a/src/vs/base/parts/ipc/test/node/testService.ts b/src/vs/base/parts/ipc/test/node/testService.ts index a53ff5ed37b..f90d54708f6 100644 --- a/src/vs/base/parts/ipc/test/node/testService.ts +++ b/src/vs/base/parts/ipc/test/node/testService.ts @@ -4,7 +4,7 @@ *--------------------------------------------------------------------------------------------*/ 'use strict'; -import { TPromise, PPromise } from 'vs/base/common/winjs.base'; +import { TPromise } from 'vs/base/common/winjs.base'; import { IChannel } from 'vs/base/parts/ipc/common/ipc'; import { Event, Emitter } from 'vs/base/common/event'; @@ -17,7 +17,6 @@ export interface ITestService { marco(): TPromise; pong(ping: string): TPromise<{ incoming: string, outgoing: string }>; cancelMe(): TPromise; - batchPerf(batches: number, size: number, dataSize: number): PPromise; } export class TestService implements ITestService { @@ -25,8 +24,6 @@ export class TestService implements ITestService { private _onMarco = new Emitter(); onMarco: Event = this._onMarco.event; - private _data = 'abcdefghijklmnopqrstuvwxyz'; - marco(): TPromise { this._onMarco.fire({ answer: 'polo' }); return TPromise.as('polo'); @@ -39,32 +36,6 @@ export class TestService implements ITestService { cancelMe(): TPromise { return TPromise.timeout(100).then(() => true); } - - batchPerf(batches: number, size: number, dataSize: number): PPromise { - while (this._data.length < dataSize) { - this._data += this._data; - } - const self = this; - return new PPromise((complete, error, progress) => { - let j = 0; - function send() { - if (j >= batches) { - complete(null); - return; - } - j++; - const batch = []; - for (let i = 0; i < size; i++) { - batch.push({ - prop: `${i}${self._data}`.substr(0, dataSize) - }); - } - progress(batch); - process.nextTick(send); - } - process.nextTick(send); - }); - } } export interface ITestChannel extends IChannel { @@ -74,7 +45,6 @@ export interface ITestChannel extends IChannel { call(command: 'marco'): TPromise; call(command: 'pong', ping: string): TPromise; call(command: 'cancelMe'): TPromise; - call(command: 'batchPerf', args: { batches: number; size: number; dataSize: number; }): PPromise; call(command: string, ...args: any[]): TPromise; } @@ -95,7 +65,6 @@ export class TestChannel implements ITestChannel { case 'pong': return this.testService.pong(args[0]); case 'cancelMe': return this.testService.cancelMe(); case 'marco': return this.testService.marco(); - case 'batchPerf': return this.testService.batchPerf(args[0].batches, args[0].size, args[0].dataSize); default: return TPromise.wrapError(new Error('command not found')); } } @@ -118,8 +87,4 @@ export class TestServiceClient implements ITestService { cancelMe(): TPromise { return this.channel.call('cancelMe'); } - - batchPerf(batches: number, size: number, dataSize: number): PPromise { - return this.channel.call('batchPerf', { batches, size, dataSize }); - } } \ No newline at end of file diff --git a/src/vs/platform/url/common/urlIpc.ts b/src/vs/platform/url/common/urlIpc.ts index 84fdc5c2e65..5cc4e919f95 100644 --- a/src/vs/platform/url/common/urlIpc.ts +++ b/src/vs/platform/url/common/urlIpc.ts @@ -39,7 +39,7 @@ export class URLServiceChannelClient implements IURLService { constructor(private channel: IChannel) { } - open(url: URI): TPromise { + open(url: URI): TPromise { return this.channel.call('open', url.toJSON()); } diff --git a/src/vs/workbench/parts/debug/test/common/mockDebug.ts b/src/vs/workbench/parts/debug/test/common/mockDebug.ts index aaa7993b320..6f953f1327c 100644 --- a/src/vs/workbench/parts/debug/test/common/mockDebug.ts +++ b/src/vs/workbench/parts/debug/test/common/mockDebug.ts @@ -218,7 +218,7 @@ export class MockSession implements IRawSession { return TPromise.as(null); } - public terminateThreads(args: DebugProtocol.TerminateThreadsArguments): TPromise { + public terminateThreads(args: DebugProtocol.TerminateThreadsArguments): TPromise { return TPromise.as(null); } diff --git a/src/vs/workbench/parts/preferences/browser/tocTree.ts b/src/vs/workbench/parts/preferences/browser/tocTree.ts index 54c4d4297e8..66298737e34 100644 --- a/src/vs/workbench/parts/preferences/browser/tocTree.ts +++ b/src/vs/workbench/parts/preferences/browser/tocTree.ts @@ -83,7 +83,7 @@ export class TOCDataSource implements IDataSource { (element instanceof SettingsTreeGroupElement && element.children && element.children.every(child => child instanceof SettingsTreeGroupElement)); } - getChildren(tree: ITree, element: TOCTreeElement): TPromise { + getChildren(tree: ITree, element: TOCTreeElement): TPromise { return TPromise.as(this._getChildren(element)); } @@ -99,7 +99,7 @@ export class TOCDataSource implements IDataSource { return element.children; } - getParent(tree: ITree, element: TOCTreeElement): TPromise { + getParent(tree: ITree, element: TOCTreeElement): TPromise { return TPromise.wrap(element instanceof SettingsTreeGroupElement && element.parent); } diff --git a/src/vs/workbench/parts/webview/electron-browser/webviewEditorInput.ts b/src/vs/workbench/parts/webview/electron-browser/webviewEditorInput.ts index 8a2a3f989bc..e9ba743cdc3 100644 --- a/src/vs/workbench/parts/webview/electron-browser/webviewEditorInput.ts +++ b/src/vs/workbench/parts/webview/electron-browser/webviewEditorInput.ts @@ -154,7 +154,7 @@ export class WebviewEditorInput extends EditorInput { } } - public resolve(refresh?: boolean): TPromise { + public resolve(refresh?: boolean): TPromise { if (this.reviver && !this._revived) { this._revived = true; return this.reviver.reviveWebview(this).then(() => new EditorModel()); diff --git a/src/vs/workbench/services/files/electron-browser/remoteFileService.ts b/src/vs/workbench/services/files/electron-browser/remoteFileService.ts index 3f2e2a1806f..295a9182a39 100644 --- a/src/vs/workbench/services/files/electron-browser/remoteFileService.ts +++ b/src/vs/workbench/services/files/electron-browser/remoteFileService.ts @@ -282,7 +282,7 @@ export class RemoteFileService extends FileService { }); } - existsFile(resource: URI): TPromise { + existsFile(resource: URI): TPromise { if (resource.scheme === Schemas.file) { return super.existsFile(resource); } else { @@ -290,7 +290,7 @@ export class RemoteFileService extends FileService { } } - resolveFile(resource: URI, options?: IResolveFileOptions): TPromise { + resolveFile(resource: URI, options?: IResolveFileOptions): TPromise { if (resource.scheme === Schemas.file) { return super.resolveFile(resource, options); } else { @@ -307,7 +307,7 @@ export class RemoteFileService extends FileService { } } - resolveFiles(toResolve: { resource: URI; options?: IResolveFileOptions; }[]): TPromise { + resolveFiles(toResolve: { resource: URI; options?: IResolveFileOptions; }[]): TPromise { // soft-groupBy, keep order, don't rearrange/merge groups let groups: (typeof toResolve)[] = []; @@ -320,7 +320,7 @@ export class RemoteFileService extends FileService { group.push(request); } - const promises: TPromise[] = []; + const promises: TPromise[] = []; for (const group of groups) { if (group[0].resource.scheme === Schemas.file) { promises.push(super.resolveFiles(group)); @@ -331,7 +331,7 @@ export class RemoteFileService extends FileService { return TPromise.join(promises).then(data => flatten(data)); } - private _doResolveFiles(toResolve: { resource: URI; options?: IResolveFileOptions; }[]): TPromise { + private _doResolveFiles(toResolve: { resource: URI; options?: IResolveFileOptions; }[]): TPromise { return this._withProvider(toResolve[0].resource).then(provider => { let result: IResolveFileResult[] = []; let promises = toResolve.map((item, idx) => { @@ -532,7 +532,7 @@ export class RemoteFileService extends FileService { } } - createFolder(resource: URI): TPromise { + createFolder(resource: URI): TPromise { if (resource.scheme === Schemas.file) { return super.createFolder(resource); } else { From a25aaa711f2dc32d0b372b61456ea1de329d01c9 Mon Sep 17 00:00:00 2001 From: Joao Moreno Date: Wed, 4 Jul 2018 11:53:04 +0200 Subject: [PATCH 0017/1276] remove ProgressCallback from monaco d ts recipe --- build/monaco/monaco.d.ts.recipe | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build/monaco/monaco.d.ts.recipe b/build/monaco/monaco.d.ts.recipe index 218d4cdf8f5..e39100bc3bc 100644 --- a/build/monaco/monaco.d.ts.recipe +++ b/build/monaco/monaco.d.ts.recipe @@ -44,7 +44,7 @@ declare namespace monaco { } -#include(vs/base/common/winjs.base.d.ts): TValueCallback, ProgressCallback, Promise +#include(vs/base/common/winjs.base.d.ts): TValueCallback, Promise #include(vs/base/common/cancellation): CancellationTokenSource, CancellationToken #include(vs/base/common/uri): URI, UriComponents #include(vs/editor/common/standalone/standaloneBase): KeyCode, KeyMod From 72f36d7f8fd84cb186f44114bb30561b2d42060e Mon Sep 17 00:00:00 2001 From: Joao Moreno Date: Wed, 4 Jul 2018 16:02:25 +0200 Subject: [PATCH 0018/1276] missing monaco.d.ts --- src/vs/monaco.d.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/src/vs/monaco.d.ts b/src/vs/monaco.d.ts index 15eac9554ab..7b8f3defa43 100644 --- a/src/vs/monaco.d.ts +++ b/src/vs/monaco.d.ts @@ -78,7 +78,6 @@ declare namespace monaco { public static join(promises: [T1 | PromiseLike, T2 | PromiseLike]): Promise<[T1, T2]>; public static join(promises: (T | PromiseLike)[]): Promise; - public static join(promises: { [n: string]: T | PromiseLike }): Promise<{ [n: string]: T }>; public static any(promises: (T | PromiseLike)[]): Promise<{ key: string; value: Promise; }>; From 8771ff770401cf3cfcc1a6e5a224fd982db92d5f Mon Sep 17 00:00:00 2001 From: Joao Moreno Date: Thu, 5 Jul 2018 10:28:18 +0200 Subject: [PATCH 0019/1276] remove extra types --- src/vs/workbench/parts/preferences/browser/settingsTree.ts | 4 ++-- .../parts/tasks/electron-browser/task.contribution.ts | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/vs/workbench/parts/preferences/browser/settingsTree.ts b/src/vs/workbench/parts/preferences/browser/settingsTree.ts index 870882c7dfe..35c087a34b6 100644 --- a/src/vs/workbench/parts/preferences/browser/settingsTree.ts +++ b/src/vs/workbench/parts/preferences/browser/settingsTree.ts @@ -942,11 +942,11 @@ export class SearchResultModel { } export class NonExpandableTree extends WorkbenchTree { - expand(): TPromise { + expand(): TPromise { return TPromise.wrap(null); } - collapse(): TPromise { + collapse(): TPromise { return TPromise.wrap(null); } } diff --git a/src/vs/workbench/parts/tasks/electron-browser/task.contribution.ts b/src/vs/workbench/parts/tasks/electron-browser/task.contribution.ts index 70ebf3100a0..0d3dc726688 100644 --- a/src/vs/workbench/parts/tasks/electron-browser/task.contribution.ts +++ b/src/vs/workbench/parts/tasks/electron-browser/task.contribution.ts @@ -1070,7 +1070,7 @@ class TaskService implements ITaskService { }); } - private writeConfiguration(workspaceFolder: IWorkspaceFolder, key: string, value: any): TPromise { + private writeConfiguration(workspaceFolder: IWorkspaceFolder, key: string, value: any): TPromise { if (this.contextService.getWorkbenchState() === WorkbenchState.FOLDER) { return this.configurationService.updateValue(key, value, { resource: workspaceFolder.uri }, ConfigurationTarget.WORKSPACE); } else if (this.contextService.getWorkbenchState() === WorkbenchState.WORKSPACE) { From f450e0b1fe3ac26ce6bf8367ff1bd60fb1387a7d Mon Sep 17 00:00:00 2001 From: misolori Date: Thu, 5 Jul 2018 10:37:58 -0700 Subject: [PATCH 0020/1276] Increase opacity to meet color contrast ratio, fixes #52023 --- src/vs/workbench/common/theme.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vs/workbench/common/theme.ts b/src/vs/workbench/common/theme.ts index cb1b5e23623..e7ebc3a7067 100644 --- a/src/vs/workbench/common/theme.ts +++ b/src/vs/workbench/common/theme.ts @@ -188,7 +188,7 @@ export const PANEL_ACTIVE_TITLE_FOREGROUND = registerColor('panelTitle.activeFor }, nls.localize('panelActiveTitleForeground', "Title color for the active panel. Panels are shown below the editor area and contain views like output and integrated terminal.")); export const PANEL_INACTIVE_TITLE_FOREGROUND = registerColor('panelTitle.inactiveForeground', { - dark: transparent(PANEL_ACTIVE_TITLE_FOREGROUND, 0.5), + dark: transparent(PANEL_ACTIVE_TITLE_FOREGROUND, 0.6), light: transparent(PANEL_ACTIVE_TITLE_FOREGROUND, 0.75), hc: Color.white }, nls.localize('panelInactiveTitleForeground', "Title color for the inactive panel. Panels are shown below the editor area and contain views like output and integrated terminal.")); From 467836e19f3dc05b12814ee26e26cd2ff743324a Mon Sep 17 00:00:00 2001 From: misolori Date: Thu, 5 Jul 2018 11:25:36 -0700 Subject: [PATCH 0021/1276] Update colors to meet color contrast ratio, fixes #51974 --- src/vs/platform/theme/common/colorRegistry.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/vs/platform/theme/common/colorRegistry.ts b/src/vs/platform/theme/common/colorRegistry.ts index 241993fb8f8..5787ed067a1 100644 --- a/src/vs/platform/theme/common/colorRegistry.ts +++ b/src/vs/platform/theme/common/colorRegistry.ts @@ -151,7 +151,7 @@ export function getColorRegistry(): IColorRegistry { export const foreground = registerColor('foreground', { dark: '#CCCCCC', light: '#6C6C6C', hc: '#FFFFFF' }, nls.localize('foreground', "Overall foreground color. This color is only used if not overridden by a component.")); export const errorForeground = registerColor('errorForeground', { dark: '#F48771', light: '#A1260D', hc: '#F48771' }, nls.localize('errorForeground', "Overall foreground color for error messages. This color is only used if not overridden by a component.")); -export const descriptionForeground = registerColor('descriptionForeground', { light: transparent(foreground, 0.7), dark: transparent(foreground, 0.7), hc: transparent(foreground, 0.7) }, nls.localize('descriptionForeground', "Foreground color for description text providing additional information, for example for a label.")); +export const descriptionForeground = registerColor('descriptionForeground', { light: '#717171', dark: transparent(foreground, 0.7), hc: transparent(foreground, 0.7) }, nls.localize('descriptionForeground', "Foreground color for description text providing additional information, for example for a label.")); export const focusBorder = registerColor('focusBorder', { dark: Color.fromHex('#0E639C').transparent(0.6), light: Color.fromHex('#007ACC').transparent(0.4), hc: '#F38518' }, nls.localize('focusBorder', "Overall border color for focused elements. This color is only used if not overridden by a component.")); @@ -163,8 +163,8 @@ export const selectionBackground = registerColor('selection.background', { light // ------ text colors export const textSeparatorForeground = registerColor('textSeparator.foreground', { light: '#0000002e', dark: '#ffffff2e', hc: Color.black }, nls.localize('textSeparatorForeground', "Color for text separators.")); -export const textLinkForeground = registerColor('textLink.foreground', { light: '#4080D0', dark: '#4080D0', hc: '#4080D0' }, nls.localize('textLinkForeground', "Foreground color for links in text.")); -export const textLinkActiveForeground = registerColor('textLink.activeForeground', { light: '#4080D0', dark: '#4080D0', hc: '#4080D0' }, nls.localize('textLinkActiveForeground', "Foreground color for links in text when clicked on and on mouse hover.")); +export const textLinkForeground = registerColor('textLink.foreground', { light: '#007acc', dark: '#0089E4', hc: '#007acc' }, nls.localize('textLinkForeground', "Foreground color for links in text.")); +export const textLinkActiveForeground = registerColor('textLink.activeForeground', { light: '#007acc', dark: '#0089E4', hc: '#007acc' }, nls.localize('textLinkActiveForeground', "Foreground color for links in text when clicked on and on mouse hover.")); export const textPreformatForeground = registerColor('textPreformat.foreground', { light: '#A31515', dark: '#D7BA7D', hc: '#D7BA7D' }, nls.localize('textPreformatForeground', "Foreground color for preformatted text segments.")); export const textBlockQuoteBackground = registerColor('textBlockQuote.background', { light: '#7f7f7f1a', dark: '#7f7f7f1a', hc: null }, nls.localize('textBlockQuoteBackground', "Background color for block quotes in text.")); export const textBlockQuoteBorder = registerColor('textBlockQuote.border', { light: '#007acc80', dark: '#007acc80', hc: Color.white }, nls.localize('textBlockQuoteBorder', "Border color for block quotes in text.")); From 479855f9cd756a2b16fcf42177cf54f86c2a0dfb Mon Sep 17 00:00:00 2001 From: misolori Date: Thu, 5 Jul 2018 16:52:53 -0700 Subject: [PATCH 0022/1276] Update colors to meet color contrast ratio, fixes #51831 --- extensions/theme-defaults/themes/dark_defaults.json | 3 ++- extensions/theme-defaults/themes/light_defaults.json | 2 +- src/vs/platform/theme/common/colorRegistry.ts | 8 ++++---- .../welcome/overlay/browser/media/commandpalette.svg | 2 +- 4 files changed, 8 insertions(+), 7 deletions(-) diff --git a/extensions/theme-defaults/themes/dark_defaults.json b/extensions/theme-defaults/themes/dark_defaults.json index cb9e20066b5..0feebc56060 100644 --- a/extensions/theme-defaults/themes/dark_defaults.json +++ b/extensions/theme-defaults/themes/dark_defaults.json @@ -10,6 +10,7 @@ "editor.selectionHighlightBackground": "#ADD6FF26", "list.dropBackground": "#383B3D", "activityBarBadge.background": "#007ACC", - "sideBarTitle.foreground": "#BBBBBB" + "sideBarTitle.foreground": "#BBBBBB", + "input.placeholderForeground": "#A6A6A6" } } \ No newline at end of file diff --git a/extensions/theme-defaults/themes/light_defaults.json b/extensions/theme-defaults/themes/light_defaults.json index 2ee46debb3a..17f154862a1 100644 --- a/extensions/theme-defaults/themes/light_defaults.json +++ b/extensions/theme-defaults/themes/light_defaults.json @@ -12,6 +12,6 @@ "activityBarBadge.background": "#007ACC", "sideBarTitle.foreground": "#6F6F6F", "list.hoverBackground": "#E8E8E8", - "input.placeholderForeground": "#ADADAD" + "input.placeholderForeground": "#767676" } } \ No newline at end of file diff --git a/src/vs/platform/theme/common/colorRegistry.ts b/src/vs/platform/theme/common/colorRegistry.ts index 5787ed067a1..bd263a6fcb9 100644 --- a/src/vs/platform/theme/common/colorRegistry.ts +++ b/src/vs/platform/theme/common/colorRegistry.ts @@ -163,8 +163,8 @@ export const selectionBackground = registerColor('selection.background', { light // ------ text colors export const textSeparatorForeground = registerColor('textSeparator.foreground', { light: '#0000002e', dark: '#ffffff2e', hc: Color.black }, nls.localize('textSeparatorForeground', "Color for text separators.")); -export const textLinkForeground = registerColor('textLink.foreground', { light: '#007acc', dark: '#0089E4', hc: '#007acc' }, nls.localize('textLinkForeground', "Foreground color for links in text.")); -export const textLinkActiveForeground = registerColor('textLink.activeForeground', { light: '#007acc', dark: '#0089E4', hc: '#007acc' }, nls.localize('textLinkActiveForeground', "Foreground color for links in text when clicked on and on mouse hover.")); +export const textLinkForeground = registerColor('textLink.foreground', { light: '#006AB1', dark: '#3794FF', hc: '#006AB1' }, nls.localize('textLinkForeground', "Foreground color for links in text.")); +export const textLinkActiveForeground = registerColor('textLink.activeForeground', { light: '#007acc', dark: '#3794FF', hc: '#007acc' }, nls.localize('textLinkActiveForeground', "Foreground color for links in text when clicked on and on mouse hover.")); export const textPreformatForeground = registerColor('textPreformat.foreground', { light: '#A31515', dark: '#D7BA7D', hc: '#D7BA7D' }, nls.localize('textPreformatForeground', "Foreground color for preformatted text segments.")); export const textBlockQuoteBackground = registerColor('textBlockQuote.background', { light: '#7f7f7f1a', dark: '#7f7f7f1a', hc: null }, nls.localize('textBlockQuoteBackground', "Background color for block quotes in text.")); export const textBlockQuoteBorder = registerColor('textBlockQuote.border', { light: '#007acc80', dark: '#007acc80', hc: Color.white }, nls.localize('textBlockQuoteBorder', "Border color for block quotes in text.")); @@ -191,7 +191,7 @@ export const selectListBackground = registerColor('dropdown.listBackground', { d export const selectForeground = registerColor('dropdown.foreground', { dark: '#F0F0F0', light: null, hc: Color.white }, nls.localize('dropdownForeground', "Dropdown foreground.")); export const selectBorder = registerColor('dropdown.border', { dark: selectBackground, light: '#CECECE', hc: contrastBorder }, nls.localize('dropdownBorder', "Dropdown border.")); -export const listFocusBackground = registerColor('list.focusBackground', { dark: '#073655', light: '#DCEBFC', hc: null }, nls.localize('listFocusBackground', "List/Tree background color for the focused item when the list/tree is active. An active list/tree has keyboard focus, an inactive does not.")); +export const listFocusBackground = registerColor('list.focusBackground', { dark: '#062F4A', light: '#DFF0FF', hc: null }, nls.localize('listFocusBackground', "List/Tree background color for the focused item when the list/tree is active. An active list/tree has keyboard focus, an inactive does not.")); export const listFocusForeground = registerColor('list.focusForeground', { dark: null, light: null, hc: null }, nls.localize('listFocusForeground', "List/Tree foreground color for the focused item when the list/tree is active. An active list/tree has keyboard focus, an inactive does not.")); export const listActiveSelectionBackground = registerColor('list.activeSelectionBackground', { dark: '#094771', light: '#3399FF', hc: null }, nls.localize('listActiveSelectionBackground', "List/Tree background color for the selected item when the list/tree is active. An active list/tree has keyboard focus, an inactive does not.")); export const listActiveSelectionForeground = registerColor('list.activeSelectionForeground', { dark: Color.white, light: Color.white, hc: null }, nls.localize('listActiveSelectionForeground', "List/Tree foreground color for the selected item when the list/tree is active. An active list/tree has keyboard focus, an inactive does not.")); @@ -206,7 +206,7 @@ export const listInvalidItemForeground = registerColor('list.invalidItemForegrou export const listErrorForeground = registerColor('list.errorForeground', { dark: '#ea4646', light: '#d60a0a', hc: null }, nls.localize('listErrorForeground', 'Foreground color of list items containing errors.')); export const listWarningForeground = registerColor('list.warningForeground', { dark: '#4d9e4d', light: '#117711', hc: null }, nls.localize('listWarningForeground', 'Foreground color of list items containing warnings.')); -export const pickerGroupForeground = registerColor('pickerGroup.foreground', { dark: Color.fromHex('#0097FB').transparent(0.6), light: Color.fromHex('#007ACC').transparent(0.6), hc: Color.white }, nls.localize('pickerGroupForeground', "Quick picker color for grouping labels.")); +export const pickerGroupForeground = registerColor('pickerGroup.foreground', { dark: '#3794FF', light: '#006AB1', 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.")); export const buttonForeground = registerColor('button.foreground', { dark: Color.white, light: Color.white, hc: Color.white }, nls.localize('buttonForeground', "Button foreground color.")); diff --git a/src/vs/workbench/parts/welcome/overlay/browser/media/commandpalette.svg b/src/vs/workbench/parts/welcome/overlay/browser/media/commandpalette.svg index 56e91eb8410..5d4d668d107 100644 --- a/src/vs/workbench/parts/welcome/overlay/browser/media/commandpalette.svg +++ b/src/vs/workbench/parts/welcome/overlay/browser/media/commandpalette.svg @@ -1 +1 @@ -Asset 9 \ No newline at end of file +Asset 9 \ No newline at end of file From a31f93b53009aaa57397a3cba5f08be1639f9d0e Mon Sep 17 00:00:00 2001 From: misolori Date: Fri, 6 Jul 2018 12:51:00 -0700 Subject: [PATCH 0023/1276] Update color to meet color contrast ratio, fixes #52570 --- extensions/theme-defaults/themes/dark_vs.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/extensions/theme-defaults/themes/dark_vs.json b/extensions/theme-defaults/themes/dark_vs.json index c2a15addb8d..2cbdca4a8f1 100644 --- a/extensions/theme-defaults/themes/dark_vs.json +++ b/extensions/theme-defaults/themes/dark_vs.json @@ -33,7 +33,7 @@ { "scope": "comment", "settings": { - "foreground": "#608b4e" + "foreground": "#6A9955" } }, { @@ -143,7 +143,7 @@ { "scope": "beginning.punctuation.definition.quote.markdown", "settings": { - "foreground": "#608b4e" + "foreground": "#6A9955" } }, { From eb05098ab814c9f6d4af62ce3ab5bf00149515b5 Mon Sep 17 00:00:00 2001 From: misolori Date: Fri, 6 Jul 2018 12:59:53 -0700 Subject: [PATCH 0024/1276] Incrase opacity to meet color contrast ratio, fixes #52026 --- src/vs/base/browser/ui/iconLabel/iconlabel.css | 1 - 1 file changed, 1 deletion(-) diff --git a/src/vs/base/browser/ui/iconLabel/iconlabel.css b/src/vs/base/browser/ui/iconLabel/iconlabel.css index 66125a6d41a..3516227e43d 100644 --- a/src/vs/base/browser/ui/iconLabel/iconlabel.css +++ b/src/vs/base/browser/ui/iconLabel/iconlabel.css @@ -40,7 +40,6 @@ } .monaco-icon-label > .monaco-icon-label-description-container > .label-description { - opacity: 0.7; margin-left: 0.5em; font-size: 0.9em; white-space: pre; /* enable to show labels that include multiple whitespaces */ From ff780b4c4be0b3c6752e4e841cfb7bcf7e624ba9 Mon Sep 17 00:00:00 2001 From: misolori Date: Fri, 6 Jul 2018 13:03:33 -0700 Subject: [PATCH 0025/1276] Increase opacity to meet color contrast ratio, fixes #52587 --- src/vs/workbench/parts/scm/electron-browser/media/scmViewlet.css | 1 - 1 file changed, 1 deletion(-) diff --git a/src/vs/workbench/parts/scm/electron-browser/media/scmViewlet.css b/src/vs/workbench/parts/scm/electron-browser/media/scmViewlet.css index f6e3ec0c18a..e48bf8a0838 100644 --- a/src/vs/workbench/parts/scm/electron-browser/media/scmViewlet.css +++ b/src/vs/workbench/parts/scm/electron-browser/media/scmViewlet.css @@ -15,7 +15,6 @@ .scm-viewlet .empty-message { padding: 10px 22px 0 22px; - opacity: 0.5; } .scm-viewlet:not(.empty) .empty-message, From f253e66e84073189652fd9a105db77368daea8a7 Mon Sep 17 00:00:00 2001 From: misolori Date: Fri, 6 Jul 2018 13:18:31 -0700 Subject: [PATCH 0026/1276] Update colors to meet color contrast ratio, fixes #52586 --- src/vs/platform/theme/common/colorRegistry.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/vs/platform/theme/common/colorRegistry.ts b/src/vs/platform/theme/common/colorRegistry.ts index bd263a6fcb9..786cd99218c 100644 --- a/src/vs/platform/theme/common/colorRegistry.ts +++ b/src/vs/platform/theme/common/colorRegistry.ts @@ -149,7 +149,7 @@ export function getColorRegistry(): IColorRegistry { // ----- base colors -export const foreground = registerColor('foreground', { dark: '#CCCCCC', light: '#6C6C6C', hc: '#FFFFFF' }, nls.localize('foreground', "Overall foreground color. This color is only used if not overridden by a component.")); +export const foreground = registerColor('foreground', { dark: '#CCCCCC', light: '#616161', hc: '#FFFFFF' }, nls.localize('foreground', "Overall foreground color. This color is only used if not overridden by a component.")); export const errorForeground = registerColor('errorForeground', { dark: '#F48771', light: '#A1260D', hc: '#F48771' }, nls.localize('errorForeground', "Overall foreground color for error messages. This color is only used if not overridden by a component.")); export const descriptionForeground = registerColor('descriptionForeground', { light: '#717171', dark: transparent(foreground, 0.7), hc: transparent(foreground, 0.7) }, nls.localize('descriptionForeground', "Foreground color for description text providing additional information, for example for a label.")); @@ -214,7 +214,7 @@ export const buttonBackground = registerColor('button.background', { dark: '#0E6 export const buttonHoverBackground = registerColor('button.hoverBackground', { dark: lighten(buttonBackground, 0.2), light: darken(buttonBackground, 0.2), hc: null }, nls.localize('buttonHoverBackground', "Button background color when hovering.")); export const badgeBackground = registerColor('badge.background', { dark: '#4D4D4D', light: '#BEBEBE', hc: Color.black }, nls.localize('badgeBackground', "Badge background color. Badges are small information labels, e.g. for search results count.")); -export const badgeForeground = registerColor('badge.foreground', { dark: Color.white, light: Color.white, hc: Color.white }, nls.localize('badgeForeground', "Badge foreground color. Badges are small information labels, e.g. for search results count.")); +export const badgeForeground = registerColor('badge.foreground', { dark: Color.white, light: '#4E4E4E', hc: Color.white }, nls.localize('badgeForeground', "Badge foreground color. Badges are small information labels, e.g. for search results count.")); export const scrollbarShadow = registerColor('scrollbar.shadow', { dark: '#000000', light: '#DDDDDD', hc: null }, nls.localize('scrollbarShadow', "Scrollbar shadow to indicate that the view is scrolled.")); export const scrollbarSliderBackground = registerColor('scrollbarSlider.background', { dark: Color.fromHex('#797979').transparent(0.4), light: Color.fromHex('#646464').transparent(0.4), hc: transparent(contrastBorder, 0.6) }, nls.localize('scrollbarSliderBackground', "Scrollbar slider background color.")); From 29aa40aa2a5e2c2c0a276be43ca495f65a8014aa Mon Sep 17 00:00:00 2001 From: misolori Date: Fri, 6 Jul 2018 13:29:51 -0700 Subject: [PATCH 0027/1276] Increase opacity to meet color contrast ratio, fixes #52684 --- .../browser/parts/notifications/media/notificationsList.css | 1 - 1 file changed, 1 deletion(-) diff --git a/src/vs/workbench/browser/parts/notifications/media/notificationsList.css b/src/vs/workbench/browser/parts/notifications/media/notificationsList.css index 73fad28fcc0..24552a04bd6 100644 --- a/src/vs/workbench/browser/parts/notifications/media/notificationsList.css +++ b/src/vs/workbench/browser/parts/notifications/media/notificationsList.css @@ -115,7 +115,6 @@ /** Notification: Source */ .monaco-workbench .notifications-list-container .notification-list-item .notification-list-item-source { - opacity: 0.7; flex: 1; font-size: 12px; overflow: hidden; /* always give away space to buttons container */ From f02240f4f9d805cb36e4ddaed6ad73241fbc42fd Mon Sep 17 00:00:00 2001 From: Joao Moreno Date: Mon, 9 Jul 2018 16:12:16 +0200 Subject: [PATCH 0028/1276] remove PPromise from IPC related to #53487 --- src/vs/base/parts/ipc/common/ipc.ts | 13 +++---------- src/vs/base/parts/ipc/node/ipc.cp.ts | 5 ++--- 2 files changed, 5 insertions(+), 13 deletions(-) diff --git a/src/vs/base/parts/ipc/common/ipc.ts b/src/vs/base/parts/ipc/common/ipc.ts index ed35efadee0..3dd6964eec9 100644 --- a/src/vs/base/parts/ipc/common/ipc.ts +++ b/src/vs/base/parts/ipc/common/ipc.ts @@ -14,7 +14,6 @@ enum MessageType { RequestPromiseCancel, ResponseInitialize, ResponsePromiseSuccess, - ResponsePromiseProgress, ResponsePromiseError, ResponsePromiseErrorObj, @@ -172,8 +171,6 @@ export class ChannelServer implements IChannelServer, IDisposable { } delete this.activeRequests[request.id]; - }, data => { - this.protocol.send({ id, data, type: MessageType.ResponsePromiseProgress }); }); this.activeRequests[request.id] = toDisposable(() => requestPromise.cancel()); @@ -282,7 +279,7 @@ export class ChannelClient implements IChannelClient, IDisposable { private doRequest(request: IRequest): Promise { const id = request.raw.id; - return new TPromise((c, e, p) => { + return new TPromise((c, e) => { this.handlers[id] = response => { switch (response.type) { case MessageType.ResponsePromiseSuccess: @@ -302,10 +299,6 @@ export class ChannelClient implements IChannelClient, IDisposable { delete this.handlers[id]; e(response.data); break; - - case MessageType.ResponsePromiseProgress: - p(response.data); - break; } }; @@ -317,12 +310,12 @@ export class ChannelClient implements IChannelClient, IDisposable { private bufferRequest(request: IRequest): Promise { let flushedRequest: Promise = null; - return new TPromise((c, e, p) => { + return new TPromise((c, e) => { this.bufferedRequests.push(request); request.flush = () => { request.flush = null; - flushedRequest = this.doRequest(request).then(c, e, p); + flushedRequest = this.doRequest(request).then(c, e); }; }, () => { request.flush = null; diff --git a/src/vs/base/parts/ipc/node/ipc.cp.ts b/src/vs/base/parts/ipc/node/ipc.cp.ts index 38a8a96f813..154fdd5ea68 100644 --- a/src/vs/base/parts/ipc/node/ipc.cp.ts +++ b/src/vs/base/parts/ipc/node/ipc.cp.ts @@ -107,9 +107,8 @@ export class Client implements IChannelClient, IDisposable { const channel = this.channels[channelName] || (this.channels[channelName] = this.client.getChannel(channelName)); const request: TPromise = channel.call(name, arg); - // Progress doesn't propagate across 'then', we need to create a promise wrapper - const result = new TPromise((c, e, p) => { - request.then(c, e, p).done(() => { + const result = new TPromise((c, e) => { + request.then(c, e).done(() => { if (!this.activeRequests) { return; } From f71de35ae265426faceb77a0eafd65627c45e7fa Mon Sep 17 00:00:00 2001 From: Miguel Solorio Date: Mon, 9 Jul 2018 11:30:05 -0700 Subject: [PATCH 0029/1276] Increase opactiy to meet color contrast ratio, fixes #51984 --- .../electron-browser/media/extensionsViewlet.css | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/vs/workbench/parts/extensions/electron-browser/media/extensionsViewlet.css b/src/vs/workbench/parts/extensions/electron-browser/media/extensionsViewlet.css index a83f6a0c066..138ba991e38 100644 --- a/src/vs/workbench/parts/extensions/electron-browser/media/extensionsViewlet.css +++ b/src/vs/workbench/parts/extensions/electron-browser/media/extensionsViewlet.css @@ -179,10 +179,15 @@ flex: 1; font-size: 90%; padding-right: 6px; - opacity: 0.6; + opacity: 0.8; font-weight: 600; } +.extensions-viewlet > .extensions .selected .extension > .details > .footer > .author, +.extensions-viewlet > .extensions .selected.focused .extension > .details > .footer > .author { + opacity: 1; +} + .extensions-viewlet > .extensions .extension > .details > .footer > .monaco-action-bar > .actions-container { flex-wrap: wrap-reverse; } @@ -220,4 +225,4 @@ background-image: url("data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNCIgaGVpZ2h0PSIxNCIgdmlld0JveD0iMiAyIDE0IDE0IiBlbmFibGUtYmFja2dyb3VuZD0ibmV3IDIgMiAxNCAxNCI+PHBhdGggZmlsbD0iI2ZmZiIgZD0iTTkgMTZjLTMuODYgMC03LTMuMTQtNy03czMuMTQtNyA3LTdjMy44NTkgMCA3IDMuMTQxIDcgN3MtMy4xNDEgNy03IDd6bTAtMTIuNmMtMy4wODggMC01LjYgMi41MTMtNS42IDUuNnMyLjUxMiA1LjYgNS42IDUuNiA1LjYtMi41MTIgNS42LTUuNi0yLjUxMi01LjYtNS42LTUuNnptMy44NiA3LjFsLTMuMTYtMS44OTZ2LTMuODA0aC0xLjR2NC41OTZsMy44NCAyLjMwNS43Mi0xLjIwMXoiLz48L3N2Zz4="); background-position: center center; background-repeat: no-repeat; -} \ No newline at end of file +} From 5b57b2dee0bfca46df8dc59cba261d1305e23f92 Mon Sep 17 00:00:00 2001 From: Miguel Solorio Date: Mon, 9 Jul 2018 14:01:21 -0700 Subject: [PATCH 0030/1276] Update colors to meet color contrast ratio, also fixes #51984 --- src/vs/platform/theme/common/colorRegistry.ts | 2 +- src/vs/platform/theme/common/styler.ts | 6 +++--- src/vs/workbench/common/theme.ts | 4 ++-- .../extensions/electron-browser/media/extensionsViewlet.css | 2 +- 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/vs/platform/theme/common/colorRegistry.ts b/src/vs/platform/theme/common/colorRegistry.ts index 786cd99218c..459fd927dab 100644 --- a/src/vs/platform/theme/common/colorRegistry.ts +++ b/src/vs/platform/theme/common/colorRegistry.ts @@ -193,7 +193,7 @@ export const selectBorder = registerColor('dropdown.border', { dark: selectBackg export const listFocusBackground = registerColor('list.focusBackground', { dark: '#062F4A', light: '#DFF0FF', hc: null }, nls.localize('listFocusBackground', "List/Tree background color for the focused item when the list/tree is active. An active list/tree has keyboard focus, an inactive does not.")); export const listFocusForeground = registerColor('list.focusForeground', { dark: null, light: null, hc: null }, nls.localize('listFocusForeground', "List/Tree foreground color for the focused item when the list/tree is active. An active list/tree has keyboard focus, an inactive does not.")); -export const listActiveSelectionBackground = registerColor('list.activeSelectionBackground', { dark: '#094771', light: '#3399FF', hc: null }, nls.localize('listActiveSelectionBackground', "List/Tree background color for the selected item when the list/tree is active. An active list/tree has keyboard focus, an inactive does not.")); +export const listActiveSelectionBackground = registerColor('list.activeSelectionBackground', { dark: '#094771', light: '#2477CE', hc: null }, nls.localize('listActiveSelectionBackground', "List/Tree background color for the selected item when the list/tree is active. An active list/tree has keyboard focus, an inactive does not.")); export const listActiveSelectionForeground = registerColor('list.activeSelectionForeground', { dark: Color.white, light: Color.white, hc: null }, nls.localize('listActiveSelectionForeground', "List/Tree foreground color for the selected item when the list/tree is active. An active list/tree has keyboard focus, an inactive does not.")); export const listInactiveSelectionBackground = registerColor('list.inactiveSelectionBackground', { dark: '#3F3F46', light: '#CCCEDB', hc: null }, nls.localize('listInactiveSelectionBackground', "List/Tree background color for the selected item when the list/tree is inactive. An active list/tree has keyboard focus, an inactive does not.")); export const listInactiveSelectionForeground = registerColor('list.inactiveSelectionForeground', { dark: null, light: null, hc: null }, nls.localize('listInactiveSelectionForeground', "List/Tree foreground color for the selected item when the list/tree is inactive. An active list/tree has keyboard focus, an inactive does not.")); diff --git a/src/vs/platform/theme/common/styler.ts b/src/vs/platform/theme/common/styler.ts index 07dfd1d9551..d5627901f0f 100644 --- a/src/vs/platform/theme/common/styler.ts +++ b/src/vs/platform/theme/common/styler.ts @@ -6,7 +6,7 @@ 'use strict'; 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, lighten, badgeBackground, badgeForeground, progressBarBackground } 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 } 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'; @@ -177,7 +177,7 @@ export function attachQuickOpenStyler(widget: IThemable, themeService: IThemeSer inputValidationErrorBackground: (style && style.inputValidationErrorBackground) || inputValidationErrorBackground, listFocusBackground: (style && style.listFocusBackground) || listFocusBackground, listFocusForeground: (style && style.listFocusForeground) || listFocusForeground, - listActiveSelectionBackground: (style && style.listActiveSelectionBackground) || lighten(listActiveSelectionBackground, 0.1), + listActiveSelectionBackground: (style && style.listActiveSelectionBackground) || listActiveSelectionBackground, listActiveSelectionForeground: (style && style.listActiveSelectionForeground) || listActiveSelectionForeground, listFocusAndSelectionBackground: style && style.listFocusAndSelectionBackground || listActiveSelectionBackground, listFocusAndSelectionForeground: (style && style.listFocusAndSelectionForeground) || listActiveSelectionForeground, @@ -219,7 +219,7 @@ export function attachListStyler(widget: IThemable, themeService: IThemeService, export const defaultListStyles: IColorMapping = { listFocusBackground: listFocusBackground, listFocusForeground: listFocusForeground, - listActiveSelectionBackground: lighten(listActiveSelectionBackground, 0.1), + listActiveSelectionBackground: listActiveSelectionBackground, listActiveSelectionForeground: listActiveSelectionForeground, listFocusAndSelectionBackground: listActiveSelectionBackground, listFocusAndSelectionForeground: listActiveSelectionForeground, diff --git a/src/vs/workbench/common/theme.ts b/src/vs/workbench/common/theme.ts index e7ebc3a7067..94120adb639 100644 --- a/src/vs/workbench/common/theme.ts +++ b/src/vs/workbench/common/theme.ts @@ -161,7 +161,7 @@ export const EDITOR_GROUP_BORDER = registerColor('editorGroup.border', { export const EDITOR_DRAG_AND_DROP_BACKGROUND = registerColor('editorGroup.dropBackground', { dark: Color.fromHex('#53595D').transparent(0.5), - light: Color.fromHex('#3399FF').transparent(0.18), + light: Color.fromHex('#2677CB').transparent(0.18), hc: null }, nls.localize('editorDragAndDropBackground', "Background color when dragging editors around. The color should have transparency so that the editor contents can still shine through.")); @@ -201,7 +201,7 @@ export const PANEL_ACTIVE_TITLE_BORDER = registerColor('panelTitle.activeBorder' export const PANEL_DRAG_AND_DROP_BACKGROUND = registerColor('panel.dropBackground', { dark: Color.white.transparent(0.12), - light: Color.fromHex('#3399FF').transparent(0.18), + light: Color.fromHex('#2677CB').transparent(0.18), hc: Color.white.transparent(0.12) }, nls.localize('panelDragAndDropBackground', "Drag and drop feedback color for the panel title items. The color should have transparency so that the panel entries can still shine through. Panels are shown below the editor area and contain views like output and integrated terminal.")); diff --git a/src/vs/workbench/parts/extensions/electron-browser/media/extensionsViewlet.css b/src/vs/workbench/parts/extensions/electron-browser/media/extensionsViewlet.css index 138ba991e38..3d7ffd21842 100644 --- a/src/vs/workbench/parts/extensions/electron-browser/media/extensionsViewlet.css +++ b/src/vs/workbench/parts/extensions/electron-browser/media/extensionsViewlet.css @@ -179,7 +179,7 @@ flex: 1; font-size: 90%; padding-right: 6px; - opacity: 0.8; + opacity: 0.9; font-weight: 600; } From 72699f4529b79a74dd58b9059359ea5063a78f00 Mon Sep 17 00:00:00 2001 From: Miguel Solorio Date: Mon, 9 Jul 2018 14:19:54 -0700 Subject: [PATCH 0031/1276] Update colors to meet color contrast ratio, fixes #53140 --- src/vs/platform/theme/common/colorRegistry.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/vs/platform/theme/common/colorRegistry.ts b/src/vs/platform/theme/common/colorRegistry.ts index 459fd927dab..09c79f74f7c 100644 --- a/src/vs/platform/theme/common/colorRegistry.ts +++ b/src/vs/platform/theme/common/colorRegistry.ts @@ -195,7 +195,7 @@ export const listFocusBackground = registerColor('list.focusBackground', { dark: export const listFocusForeground = registerColor('list.focusForeground', { dark: null, light: null, hc: null }, nls.localize('listFocusForeground', "List/Tree foreground color for the focused item when the list/tree is active. An active list/tree has keyboard focus, an inactive does not.")); export const listActiveSelectionBackground = registerColor('list.activeSelectionBackground', { dark: '#094771', light: '#2477CE', hc: null }, nls.localize('listActiveSelectionBackground', "List/Tree background color for the selected item when the list/tree is active. An active list/tree has keyboard focus, an inactive does not.")); export const listActiveSelectionForeground = registerColor('list.activeSelectionForeground', { dark: Color.white, light: Color.white, hc: null }, nls.localize('listActiveSelectionForeground', "List/Tree foreground color for the selected item when the list/tree is active. An active list/tree has keyboard focus, an inactive does not.")); -export const listInactiveSelectionBackground = registerColor('list.inactiveSelectionBackground', { dark: '#3F3F46', light: '#CCCEDB', hc: null }, nls.localize('listInactiveSelectionBackground', "List/Tree background color for the selected item when the list/tree is inactive. An active list/tree has keyboard focus, an inactive does not.")); +export const listInactiveSelectionBackground = registerColor('list.inactiveSelectionBackground', { dark: '#37373D', light: '#CCCEDB', hc: null }, nls.localize('listInactiveSelectionBackground', "List/Tree background color for the selected item when the list/tree is inactive. An active list/tree has keyboard focus, an inactive does not.")); export const listInactiveSelectionForeground = registerColor('list.inactiveSelectionForeground', { dark: null, light: null, hc: null }, nls.localize('listInactiveSelectionForeground', "List/Tree foreground color for the selected item when the list/tree is inactive. An active list/tree has keyboard focus, an inactive does not.")); export const listInactiveFocusBackground = registerColor('list.inactiveFocusBackground', { dark: '#313135', light: '#d8dae6', hc: null }, nls.localize('listInactiveSelectionBackground', "List/Tree background color for the selected item when the list/tree is inactive. An active list/tree has keyboard focus, an inactive does not.")); export const listHoverBackground = registerColor('list.hoverBackground', { dark: '#2A2D2E', light: '#F0F0F0', hc: null }, nls.localize('listHoverBackground', "List/Tree background when hovering over items using the mouse.")); @@ -203,7 +203,7 @@ export const listHoverForeground = registerColor('list.hoverForeground', { dark: export const listDropBackground = registerColor('list.dropBackground', { dark: listFocusBackground, light: listFocusBackground, hc: null }, nls.localize('listDropBackground', "List/Tree drag and drop background when moving items around using the mouse.")); export const listHighlightForeground = registerColor('list.highlightForeground', { dark: '#0097fb', light: '#007acc', hc: focusBorder }, nls.localize('highlight', 'List/Tree foreground color of the match highlights when searching inside the list/tree.')); export const listInvalidItemForeground = registerColor('list.invalidItemForeground', { dark: '#B89500', light: '#B89500', hc: '#B89500' }, nls.localize('invalidItemForeground', 'List/Tree foreground color for invalid items, for example an unresolved root in explorer.')); -export const listErrorForeground = registerColor('list.errorForeground', { dark: '#ea4646', light: '#d60a0a', hc: null }, nls.localize('listErrorForeground', 'Foreground color of list items containing errors.')); +export const listErrorForeground = registerColor('list.errorForeground', { dark: '#F88070', light: '#B01011', hc: null }, nls.localize('listErrorForeground', 'Foreground color of list items containing errors.')); export const listWarningForeground = registerColor('list.warningForeground', { dark: '#4d9e4d', light: '#117711', hc: null }, nls.localize('listWarningForeground', 'Foreground color of list items containing warnings.')); export const pickerGroupForeground = registerColor('pickerGroup.foreground', { dark: '#3794FF', light: '#006AB1', hc: Color.white }, nls.localize('pickerGroupForeground', "Quick picker color for grouping labels.")); From cb6a0326f2436ee01757b6d76947542b407d70b4 Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Wed, 18 Jul 2018 10:38:53 -0700 Subject: [PATCH 0032/1276] Prefer const enum over const object --- src/vs/editor/common/model/intervalTree.ts | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/vs/editor/common/model/intervalTree.ts b/src/vs/editor/common/model/intervalTree.ts index 8f8c9de9ba5..28839e413af 100644 --- a/src/vs/editor/common/model/intervalTree.ts +++ b/src/vs/editor/common/model/intervalTree.ts @@ -12,14 +12,14 @@ import { IModelDecoration, TrackedRangeStickiness as ActualTrackedRangeStickines // The red-black tree is based on the "Introduction to Algorithms" by Cormen, Leiserson and Rivest. // -export const ClassName = { - EditorHintDecoration: 'squiggly-hint', - EditorInfoDecoration: 'squiggly-info', - EditorWarningDecoration: 'squiggly-warning', - EditorErrorDecoration: 'squiggly-error', - EditorUnnecessaryDecoration: 'squiggly-unnecessary', - EditorUnnecessaryInlineDecoration: 'squiggly-inline-unnecessary' -}; +export const enum ClassName { + EditorHintDecoration = 'squiggly-hint', + EditorInfoDecoration = 'squiggly-info', + EditorWarningDecoration = 'squiggly-warning', + EditorErrorDecoration = 'squiggly-error', + EditorUnnecessaryDecoration = 'squiggly-unnecessary', + EditorUnnecessaryInlineDecoration = 'squiggly-inline-unnecessary' +} /** * Describes the behavior of decorations when typing/editing near their edges. From c060253db41822e401ea6eafad9dff5e664648da Mon Sep 17 00:00:00 2001 From: Miguel Solorio Date: Thu, 19 Jul 2018 11:53:03 -0700 Subject: [PATCH 0033/1276] Update line number colors to meet color contrast ratio, fixes #52420 and #52432 --- src/vs/editor/common/view/editorColorRegistry.ts | 4 ++-- .../welcome/walkThrough/electron-browser/walkThroughPart.ts | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/vs/editor/common/view/editorColorRegistry.ts b/src/vs/editor/common/view/editorColorRegistry.ts index 74dfb7da133..c4c369cb0d2 100644 --- a/src/vs/editor/common/view/editorColorRegistry.ts +++ b/src/vs/editor/common/view/editorColorRegistry.ts @@ -21,9 +21,9 @@ export const editorCursorBackground = registerColor('editorCursor.background', n export const editorWhitespaces = registerColor('editorWhitespace.foreground', { dark: '#e3e4e229', light: '#33333333', hc: '#e3e4e229' }, nls.localize('editorWhitespaces', 'Color of whitespace characters in the editor.')); export const editorIndentGuides = registerColor('editorIndentGuide.background', { dark: editorWhitespaces, light: editorWhitespaces, hc: editorWhitespaces }, nls.localize('editorIndentGuides', 'Color of the editor indentation guides.')); export const editorActiveIndentGuides = registerColor('editorIndentGuide.activeBackground', { dark: editorWhitespaces, light: editorWhitespaces, hc: editorWhitespaces }, nls.localize('editorActiveIndentGuide', 'Color of the active editor indentation guides.')); -export const editorLineNumbers = registerColor('editorLineNumber.foreground', { dark: '#5A5A5A', light: '#2B91AF', hc: Color.white }, nls.localize('editorLineNumbers', 'Color of editor line numbers.')); +export const editorLineNumbers = registerColor('editorLineNumber.foreground', { dark: '#858585', light: '#237893', hc: Color.white }, nls.localize('editorLineNumbers', 'Color of editor line numbers.')); -const deprecatedEditorActiveLineNumber = registerColor('editorActiveLineNumber.foreground', { dark: '#AAAAAA', light: '#0B216F', hc: activeContrastBorder }, nls.localize('editorActiveLineNumber', 'Color of editor active line number'), false, nls.localize('deprecatedEditorActiveLineNumber', 'Id is deprecated. Use \'editorLineNumber.activeForeground\' instead.')); +const deprecatedEditorActiveLineNumber = registerColor('editorActiveLineNumber.foreground', { dark: '#c6c6c6', light: '#0B216F', hc: activeContrastBorder }, nls.localize('editorActiveLineNumber', 'Color of editor active line number'), false, nls.localize('deprecatedEditorActiveLineNumber', 'Id is deprecated. Use \'editorLineNumber.activeForeground\' instead.')); export const editorActiveLineNumber = registerColor('editorLineNumber.activeForeground', { dark: deprecatedEditorActiveLineNumber, light: deprecatedEditorActiveLineNumber, hc: deprecatedEditorActiveLineNumber }, nls.localize('editorActiveLineNumber', 'Color of editor active line number')); export const editorRuler = registerColor('editorRuler.foreground', { dark: '#5A5A5A', light: Color.lightgrey, hc: Color.white }, nls.localize('editorRuler', 'Color of the editor rulers.')); diff --git a/src/vs/workbench/parts/welcome/walkThrough/electron-browser/walkThroughPart.ts b/src/vs/workbench/parts/welcome/walkThrough/electron-browser/walkThroughPart.ts index 0c8665ff148..19924b0b073 100644 --- a/src/vs/workbench/parts/welcome/walkThrough/electron-browser/walkThroughPart.ts +++ b/src/vs/workbench/parts/welcome/walkThrough/electron-browser/walkThroughPart.ts @@ -517,7 +517,7 @@ export class WalkThroughPart extends BaseEditor { export const embeddedEditorBackground = registerColor('walkThrough.embeddedEditorBackground', { dark: null, light: null, hc: null }, localize('walkThrough.embeddedEditorBackground', 'Background color for the embedded editors on the Interactive Playground.')); registerThemingParticipant((theme, collector) => { - const color = getExtraColor(theme, embeddedEditorBackground, { dark: 'rgba(0, 0, 0, .4)', extra_dark: 'rgba(200, 235, 255, .064)', light: 'rgba(0,0,0,.08)', hc: null }); + const color = getExtraColor(theme, embeddedEditorBackground, { dark: 'rgba(0, 0, 0, .4)', extra_dark: 'rgba(200, 235, 255, .064)', light: '#f4f4f4', hc: null }); if (color) { collector.addRule(`.monaco-workbench > .part.editor > .content .walkThroughContent .monaco-editor-background, .monaco-workbench > .part.editor > .content .walkThroughContent .margin-view-overlays { background: ${color}; }`); From 851092b3cdf2fdcc12ed4eb2bd6f90bce638f550 Mon Sep 17 00:00:00 2001 From: Miguel Solorio Date: Thu, 19 Jul 2018 12:49:04 -0700 Subject: [PATCH 0034/1276] Update opacity to meet color contrast ratio, fixes #52479 --- .../parts/preferences/browser/media/settingsEditor2.css | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/vs/workbench/parts/preferences/browser/media/settingsEditor2.css b/src/vs/workbench/parts/preferences/browser/media/settingsEditor2.css index b3b54ddc0cc..674cd5786ed 100644 --- a/src/vs/workbench/parts/preferences/browser/media/settingsEditor2.css +++ b/src/vs/workbench/parts/preferences/browser/media/settingsEditor2.css @@ -45,7 +45,7 @@ .settings-editor > .settings-header > .settings-preview-header > .settings-preview-warning { text-align: right; text-transform: uppercase; - background: rgba(136, 136, 136, 0.3); + background: rgba(136, 136, 136, 0.2); border-radius: 2px; font-size: 0.8em; padding: 0 3px; @@ -190,11 +190,11 @@ } .settings-editor > .settings-body > .settings-tree-container .setting-item .setting-item-category { - opacity: 0.7; + opacity: 0.9; } .settings-editor > .settings-body > .settings-tree-container .setting-item .setting-item-description { - opacity: 0.7; + opacity: 0.9; margin-top: 3px; overflow: hidden; white-space: pre; From 3c37960bd808c43e17d4d0fe6ce2f16ab6acfdbc Mon Sep 17 00:00:00 2001 From: Miguel Solorio Date: Thu, 19 Jul 2018 12:58:45 -0700 Subject: [PATCH 0035/1276] Update color to meet color contrast ratiom, fixes #52580 --- extensions/git/package.json | 2 +- src/vs/workbench/parts/preferences/browser/settingsTree.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/extensions/git/package.json b/extensions/git/package.json index 9a723045468..82c3988c713 100644 --- a/extensions/git/package.json +++ b/extensions/git/package.json @@ -1022,7 +1022,7 @@ "id": "gitDecoration.untrackedResourceForeground", "description": "%colors.untracked%", "defaults": { - "light": "#019001", + "light": "#018101", "dark": "#73C991", "highContrast": "#73C991" } diff --git a/src/vs/workbench/parts/preferences/browser/settingsTree.ts b/src/vs/workbench/parts/preferences/browser/settingsTree.ts index ac53257f46e..a30f9616f35 100644 --- a/src/vs/workbench/parts/preferences/browser/settingsTree.ts +++ b/src/vs/workbench/parts/preferences/browser/settingsTree.ts @@ -34,7 +34,7 @@ import { ISearchResult, ISetting, ISettingsGroup } from 'vs/workbench/services/p const $ = DOM.$; export const modifiedItemForeground = registerColor('settings.modifiedItemForeground', { - light: '#019001', + light: '#018101', dark: '#73C991', hc: '#73C991' }, localize('modifiedItemForeground', "(For settings editor preview) The foreground color for a modified setting.")); From 28699de351534ac33f821aa00411ec7138fdfa14 Mon Sep 17 00:00:00 2001 From: Jackson Kearl Date: Thu, 19 Jul 2018 15:09:58 -0700 Subject: [PATCH 0036/1276] Begin move to if/when style --- src/vs/editor/common/modes/languageConfiguration.ts | 7 +++++++ src/vs/monaco.d.ts | 6 ++++++ .../languageConfigurationExtensionPoint.ts | 5 +++++ 3 files changed, 18 insertions(+) diff --git a/src/vs/editor/common/modes/languageConfiguration.ts b/src/vs/editor/common/modes/languageConfiguration.ts index aaf139ee7ba..1b5a057a8f6 100644 --- a/src/vs/editor/common/modes/languageConfiguration.ts +++ b/src/vs/editor/common/modes/languageConfiguration.ts @@ -62,6 +62,13 @@ export interface LanguageConfiguration { */ surroundingPairs?: IAutoClosingPair[]; + /** + * Defines what characters must be after the cursor for bracket or quote autoclosing to occur when using the \'languageDefined\' autoclosing setting. + * + * This is typically the set of characters which can not start an expression, such as whitespace, closing brackets, non-unary operators, etc. + */ + autoCloseBefore?: string; + /** * The language's folding rules. */ diff --git a/src/vs/monaco.d.ts b/src/vs/monaco.d.ts index fefe1b10614..2c98169d0a3 100644 --- a/src/vs/monaco.d.ts +++ b/src/vs/monaco.d.ts @@ -4453,6 +4453,12 @@ declare namespace monaco.languages { * settings will be used. */ surroundingPairs?: IAutoClosingPair[]; + /** + * Defines what characters must be after the cursor for bracket or quote autoclosing to occur when using the \'languageDefined\' autoclosing setting. + * + * This is typically the set of characters which can not start an expression, such as whitespace, closing brackets, non-unary operators, etc. + */ + autoCloseBefore?: string; /** * The language's folding rules. */ diff --git a/src/vs/workbench/parts/codeEditor/electron-browser/languageConfiguration/languageConfigurationExtensionPoint.ts b/src/vs/workbench/parts/codeEditor/electron-browser/languageConfiguration/languageConfigurationExtensionPoint.ts index 15a56872cdc..6cf9ddb02c0 100644 --- a/src/vs/workbench/parts/codeEditor/electron-browser/languageConfiguration/languageConfigurationExtensionPoint.ts +++ b/src/vs/workbench/parts/codeEditor/electron-browser/languageConfiguration/languageConfigurationExtensionPoint.ts @@ -433,6 +433,11 @@ const schema: IJSONSchema = { }] } }, + autoCloseBefore: { + default: ';:.,=}])> \n\t', + description: nls.localize('schema.autoCloseBefore', 'Defines what characters must be after the cursor in order for bracket or quote autoclosing to occur when using the \'languageDefined\' autoclosing setting. This is typically the set of characters which can not start an expression.'), + type: 'string', + }, surroundingPairs: { default: [['(', ')'], ['[', ']'], ['{', '}']], description: nls.localize('schema.surroundingPairs', 'Defines the bracket pairs that can be used to surround a selected string.'), From dbc8505cd795faf2c76ab1b2dc3c9bbc15e12434 Mon Sep 17 00:00:00 2001 From: SteVen Batten <6561887+sbatten@users.noreply.github.com> Date: Thu, 19 Jul 2018 16:24:56 -0700 Subject: [PATCH 0037/1276] removing the old menubar implementation --- src/vs/code/electron-main/app.ts | 10 -- src/vs/code/electron-main/menubar.ts | 121 +++++++++--------- src/vs/platform/menubar/common/menubar.ts | 22 +++- .../menubar/electron-main/menubarService.ts | 6 +- .../browser/parts/menubar/menubarPart.ts | 74 ++++++----- 5 files changed, 124 insertions(+), 109 deletions(-) diff --git a/src/vs/code/electron-main/app.ts b/src/vs/code/electron-main/app.ts index 0abf0261e30..7df7b4e057d 100644 --- a/src/vs/code/electron-main/app.ts +++ b/src/vs/code/electron-main/app.ts @@ -63,8 +63,6 @@ import { serve as serveDriver } from 'vs/platform/driver/electron-main/driver'; import { IMenubarService } from 'vs/platform/menubar/common/menubar'; import { MenubarService } from 'vs/platform/menubar/electron-main/menubarService'; import { MenubarChannel } from 'vs/platform/menubar/common/menubarIpc'; -// TODO@sbatten: Remove after conversion to new dynamic menubar -import { CodeMenu } from 'vs/code/electron-main/menus'; export class CodeApplication { @@ -511,14 +509,6 @@ export class CodeApplication { } } - // TODO@sbatten: Remove when menu is converted - // Install Menu - const instantiationService = accessor.get(IInstantiationService); - const configurationService = accessor.get(IConfigurationService); - if (platform.isMacintosh || configurationService.getValue('window.titleBarStyle') !== 'custom') { - instantiationService.createInstance(CodeMenu); - } - // Jump List this.historyMainService.updateWindowsJumpList(); this.historyMainService.onRecentlyOpenedChange(() => this.historyMainService.updateWindowsJumpList()); diff --git a/src/vs/code/electron-main/menubar.ts b/src/vs/code/electron-main/menubar.ts index 5870ea0ad31..4bc7076d0a2 100644 --- a/src/vs/code/electron-main/menubar.ts +++ b/src/vs/code/electron-main/menubar.ts @@ -21,7 +21,7 @@ import { KeybindingsResolver } from 'vs/code/electron-main/keyboard'; import { IWindowsMainService, IWindowsCountChangedEvent } from 'vs/platform/windows/electron-main/windows'; import { IHistoryMainService } from 'vs/platform/history/common/history'; import { IWorkspaceIdentifier, getWorkspaceLabel, ISingleFolderWorkspaceIdentifier, isSingleFolderWorkspaceIdentifier } from 'vs/platform/workspaces/common/workspaces'; -import { IMenubarData, IMenubarMenuItemAction, IMenubarMenuItemSeparator } from 'vs/platform/menubar/common/menubar'; +import { IMenubarData, isMenubarMenuItemSeparator, isMenubarMenuItemSubmenu, isMenubarMenuItemAction, MenubarMenuItem } from 'vs/platform/menubar/common/menubar'; // interface IExtensionViewlet { // id: string; @@ -33,17 +33,6 @@ const telemetryFrom = 'menu'; export class Menubar { private static readonly MAX_MENU_RECENT_ENTRIES = 10; - - // private keys = [ - // 'files.autoSave', - // 'editor.multiCursorModifier', - // 'workbench.sideBar.location', - // 'workbench.statusBar.visible', - // 'workbench.activityBar.visible', - // 'window.enableMenuBarMnemonics', - // 'window.nativeTabs' - // ]; - private isQuitting: boolean; private appMenuInstalled: boolean; @@ -113,7 +102,7 @@ export class Menubar { // this.updateService.onStateChange(() => this.updateMenu()); // Listen to keybindings change - this.keybindingsResolver.onKeybindingsChanged(() => this.scheduleUpdateMenu()); + // this.keybindingsResolver.onKeybindingsChanged(() => this.scheduleUpdateMenu()); } private get currentEnableMenuBarMnemonics(): boolean { @@ -228,19 +217,6 @@ export class Menubar { menubar.append(editMenuItem); } - // Recent - const recentMenu = new Menu(); - const recentMenuItem = new MenuItem({ label: this.mnemonicLabel(nls.localize({ key: 'miRecent', comment: ['&& denotes a mnemonic'] }, "&&Recent")), submenu: recentMenu, enabled: recentMenu.items.length > 0 }); - if (this.shouldDrawMenu('Recent')) { - if (this.shouldFallback('Recent')) { - this.setFallbackMenuById(recentMenu, 'Recent'); - } else { - this.setMenuById(recentMenu, 'Recent'); - } - - menubar.append(recentMenuItem); - } - // Selection const selectionMenu = new Menu(); const selectionMenuItem = new MenuItem({ label: this.mnemonicLabel(nls.localize({ key: 'mSelection', comment: ['&& denotes a mnemonic'] }, "&&Selection")), submenu: selectionMenu }); @@ -277,6 +253,15 @@ export class Menubar { menubar.append(gotoMenuItem); } + // Terminal + const terminalMenu = new Menu(); + const terminalMenuItem = new MenuItem({ label: this.mnemonicLabel(nls.localize({ key: 'mTerminal', comment: ['&& denotes a mnemonic'] }, "Ter&&minal")), submenu: terminalMenu }); + + if (this.shouldDrawMenu('Terminal')) { + this.setMenuById(terminalMenu, 'Terminal'); + menubar.append(terminalMenuItem); + } + // Debug const debugMenu = new Menu(); const debugMenuItem = new MenuItem({ label: this.mnemonicLabel(nls.localize({ key: 'mDebug', comment: ['&& denotes a mnemonic'] }, "&&Debug")), submenu: debugMenu }); @@ -290,8 +275,8 @@ export class Menubar { const taskMenu = new Menu(); const taskMenuItem = new MenuItem({ label: this.mnemonicLabel(nls.localize({ key: 'mTask', comment: ['&& denotes a mnemonic'] }, "&&Tasks")), submenu: taskMenu }); - if (this.shouldDrawMenu('Task')) { - this.setMenuById(taskMenu, 'Task'); + if (this.shouldDrawMenu('Tasks')) { + this.setMenuById(taskMenu, 'Tasks'); menubar.append(taskMenuItem); } @@ -405,32 +390,12 @@ export class Menubar { case 'Recent': menu.append(this.createMenuItem(nls.localize({ key: 'miReopenClosedEditor', comment: ['&& denotes a mnemonic'] }, "&&Reopen Closed Editor"), 'workbench.action.reopenClosedEditor')); - const { workspaces, files } = this.historyMainService.getRecentlyOpened(); + this.insertRecentMenuItems(menu); - // Workspaces - if (workspaces.length > 0) { - menu.append(__separator__()); - - for (let i = 0; i < Menubar.MAX_MENU_RECENT_ENTRIES && i < workspaces.length; i++) { - menu.append(this.createOpenRecentMenuItem(workspaces[i], 'openRecentWorkspace', false)); - } - } - - // Files - if (files.length > 0) { - menu.append(__separator__()); - - for (let i = 0; i < Menubar.MAX_MENU_RECENT_ENTRIES && i < files.length; i++) { - menu.append(this.createOpenRecentMenuItem(files[i], 'openRecentFile', true)); - } - } - - if (workspaces.length || files.length) { - menu.append(__separator__()); - menu.append(this.createMenuItem(nls.localize({ key: 'miMore', comment: ['&& denotes a mnemonic'] }, "&&More..."), 'workbench.action.openRecent')); - menu.append(__separator__()); - menu.append(new MenuItem(this.likeAction('workbench.action.clearRecentFiles', { label: this.mnemonicLabel(nls.localize({ key: 'miClearRecentOpen', comment: ['&& denotes a mnemonic'] }, "&&Clear Recently Opened")), click: () => this.historyMainService.clearRecentlyOpened() }))); - } + menu.append(__separator__()); + menu.append(this.createMenuItem(nls.localize({ key: 'miMore', comment: ['&& denotes a mnemonic'] }, "&&More..."), 'workbench.action.openRecent')); + menu.append(__separator__()); + menu.append(new MenuItem(this.likeAction('workbench.action.clearRecentFiles', { label: this.mnemonicLabel(nls.localize({ key: 'miClearRecentOpen', comment: ['&& denotes a mnemonic'] }, "&&Clear Recently Opened")), click: () => this.historyMainService.clearRecentlyOpened() }))); break; @@ -495,22 +460,52 @@ export class Menubar { } } - private setMenuById(menu: Electron.Menu, menuId: string): void { - console.log(`Attempting to set menu for ${menuId}`); - - // Build dynamic menu - this.menubarMenus[menuId].items.forEach((item: IMenubarMenuItemAction | IMenubarMenuItemSeparator) => { - if (item.id === 'vscode.menubar.separator') { + private setMenu(menu: Electron.Menu, items: Array) { + items.forEach((item: MenubarMenuItem) => { + if (isMenubarMenuItemSeparator(item)) { menu.append(__separator__()); - } else { - let menuItem: Electron.MenuItem; - let action: IMenubarMenuItemAction = item; - menuItem = this.createMenuItem(action.label, action.id, action.enabled, action.checked); + } else if (isMenubarMenuItemSubmenu(item)) { + const submenu = new Menu(); + const submenuItem = new MenuItem({ label: this.mnemonicLabel(item.label), submenu: submenu }); + this.setMenu(submenu, item.submenu.items); + menu.append(submenuItem); + } else if (isMenubarMenuItemAction(item)) { + if (item.id === 'workbench.action.openRecent') { + this.insertRecentMenuItems(menu); + } + + const menuItem = this.createMenuItem(item.label, item.id, item.enabled, item.checked); menu.append(menuItem); } }); } + private setMenuById(menu: Electron.Menu, menuId: string): void { + this.setMenu(menu, this.menubarMenus[menuId].items); + } + + private insertRecentMenuItems(menu: Electron.Menu) { + const { workspaces, files } = this.historyMainService.getRecentlyOpened(); + + // Workspaces + if (workspaces.length > 0) { + for (let i = 0; i < Menubar.MAX_MENU_RECENT_ENTRIES && i < workspaces.length; i++) { + menu.append(this.createOpenRecentMenuItem(workspaces[i], 'openRecentWorkspace', false)); + } + + menu.append(__separator__()); + } + + // Files + if (files.length > 0) { + for (let i = 0; i < Menubar.MAX_MENU_RECENT_ENTRIES && i < files.length; i++) { + menu.append(this.createOpenRecentMenuItem(files[i], 'openRecentFile', true)); + } + + menu.append(__separator__()); + } + } + private createOpenRecentMenuItem(workspace: IWorkspaceIdentifier | ISingleFolderWorkspaceIdentifier | string, commandId: string, isFile: boolean): Electron.MenuItem { let label: string; let path: string; diff --git a/src/vs/platform/menubar/common/menubar.ts b/src/vs/platform/menubar/common/menubar.ts index 5fcc3ecec23..735e234ac93 100644 --- a/src/vs/platform/menubar/common/menubar.ts +++ b/src/vs/platform/menubar/common/menubar.ts @@ -23,7 +23,7 @@ export interface IMenubarData { } export interface IMenubarMenu { - items: Array; + items: Array; } export interface IMenubarMenuItemAction { @@ -33,6 +33,26 @@ export interface IMenubarMenuItemAction { enabled: boolean; } +export interface IMenubarMenuItemSubmenu { + id: string; + label: string; + submenu: IMenubarMenu; +} + export interface IMenubarMenuItemSeparator { id: 'vscode.menubar.separator'; +} + +export type MenubarMenuItem = IMenubarMenuItemAction | IMenubarMenuItemSubmenu | IMenubarMenuItemSeparator; + +export function isMenubarMenuItemSubmenu(menuItem: MenubarMenuItem): menuItem is IMenubarMenuItemSubmenu { + return (menuItem).submenu !== undefined; +} + +export function isMenubarMenuItemAction(menuItem: MenubarMenuItem): menuItem is IMenubarMenuItemAction { + return (menuItem).checked !== undefined || (menuItem).enabled !== undefined; +} + +export function isMenubarMenuItemSeparator(menuItem: MenubarMenuItem): menuItem is IMenubarMenuItemSeparator { + return (menuItem).id === 'vscode.menubar.separator'; } \ No newline at end of file diff --git a/src/vs/platform/menubar/electron-main/menubarService.ts b/src/vs/platform/menubar/electron-main/menubarService.ts index d4a846baf26..a24dd49126b 100644 --- a/src/vs/platform/menubar/electron-main/menubarService.ts +++ b/src/vs/platform/menubar/electron-main/menubarService.ts @@ -10,7 +10,6 @@ import { Menubar } from 'vs/code/electron-main/menubar'; import { ILogService } from 'vs/platform/log/common/log'; import { TPromise } from 'vs/base/common/winjs.base'; import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; -import { isMacintosh, isWindows } from 'vs/base/common/platform'; export class MenubarService implements IMenubarService { _serviceBrand: any; @@ -22,10 +21,7 @@ export class MenubarService implements IMenubarService { @ILogService private logService: ILogService ) { // Install Menu - // TODO@sbatten: Remove if block - if (isMacintosh && isWindows) { - this._menubar = this.instantiationService.createInstance(Menubar); - } + this._menubar = this.instantiationService.createInstance(Menubar); } updateMenubar(windowId: number, menus: IMenubarData): TPromise { diff --git a/src/vs/workbench/browser/parts/menubar/menubarPart.ts b/src/vs/workbench/browser/parts/menubar/menubarPart.ts index f1c8b0bba50..1dda968530d 100644 --- a/src/vs/workbench/browser/parts/menubar/menubarPart.ts +++ b/src/vs/workbench/browser/parts/menubar/menubarPart.ts @@ -10,7 +10,7 @@ import 'vs/css!./media/menubarpart'; import * as nls from 'vs/nls'; import * as browser from 'vs/base/browser/browser'; import { Part } from 'vs/workbench/browser/part'; -import { IMenubarService, IMenubarMenu, IMenubarMenuItemAction, IMenubarData } from 'vs/platform/menubar/common/menubar'; +import { IMenubarService, IMenubarMenu, IMenubarMenuItemAction, IMenubarData, IMenubarMenuItemSubmenu } from 'vs/platform/menubar/common/menubar'; import { IMenuService, MenuId, IMenu, SubmenuItemAction } from 'vs/platform/actions/common/actions'; import { IThemeService, registerThemingParticipant, ITheme, ICssStyleCollector } from 'vs/platform/theme/common/themeService'; import { IWindowService, MenuBarVisibility, IWindowsService } from 'vs/platform/windows/common/windows'; @@ -438,10 +438,7 @@ export class MenubarPart extends Part { } private setupNativeMenubar(): void { - // TODO@sbatten: Remove once native menubar is ready - if (isMacintosh && isWindows) { - this.menubarService.updateMenubar(this.windowService.getCurrentWindowId(), this.getMenubarMenus()); - } + this.menubarService.updateMenubar(this.windowService.getCurrentWindowId(), this.getMenubarMenus()); } @@ -796,37 +793,54 @@ export class MenubarPart extends Part { } } + private populateMenuItems(menu: IMenu, menuToPopulate: IMenubarMenu) { + let groups = menu.getActions(); + for (let group of groups) { + const [, actions] = group; + + actions.forEach(menuItem => { + + if (menuItem instanceof SubmenuItemAction) { + const submenu = { items: [] }; + this.populateMenuItems(this.menuService.createMenu(menuItem.item.submenu, this.contextKeyService), submenu); + + let menubarSubmenuItem: IMenubarMenuItemSubmenu = { + id: menuItem.id, + label: menuItem.label, + submenu: submenu + }; + + menuToPopulate.items.push(menubarSubmenuItem); + } else { + let menubarMenuItem: IMenubarMenuItemAction = { + id: menuItem.id, + label: menuItem.label, + checked: menuItem.checked, + enabled: menuItem.enabled + }; + + this.setCheckedStatus(menubarMenuItem); + menubarMenuItem.label = this.calculateActionLabel(menubarMenuItem); + + menuToPopulate.items.push(menubarMenuItem); + } + }); + + menuToPopulate.items.push({ id: 'vscode.menubar.separator' }); + } + + if (menuToPopulate.items.length > 0) { + menuToPopulate.items.pop(); + } + } + private getMenubarMenus(): IMenubarData { let ret: IMenubarData = {}; for (let topLevelMenuName of Object.keys(this.topLevelMenus)) { const menu = this.topLevelMenus[topLevelMenuName]; let menubarMenu: IMenubarMenu = { items: [] }; - let groups = menu.getActions(); - for (let group of groups) { - const [, actions] = group; - - actions.forEach(menuItemAction => { - let menubarMenuItem: IMenubarMenuItemAction = { - id: menuItemAction.id, - label: menuItemAction.label, - checked: menuItemAction.checked, - enabled: menuItemAction.enabled - }; - - this.setCheckedStatus(menubarMenuItem); - menubarMenuItem.label = this.calculateActionLabel(menubarMenuItem); - - menubarMenu.items.push(menubarMenuItem); - }); - - menubarMenu.items.push({ id: 'vscode.menubar.separator' }); - } - - if (menubarMenu.items.length > 0) { - menubarMenu.items.pop(); - } - + this.populateMenuItems(menu, menubarMenu); ret[topLevelMenuName] = menubarMenu; } From 3ce86b446b0d245bf9d173827acb04a2a1439c74 Mon Sep 17 00:00:00 2001 From: SteVen Batten Date: Fri, 20 Jul 2018 14:42:47 -0700 Subject: [PATCH 0038/1276] some fixes for mac menus --- src/vs/code/electron-main/menubar.ts | 16 ++++++ .../parts/menubar/menubar.contribution.ts | 36 ++++++------ .../browser/parts/menubar/menubarPart.ts | 1 + .../electron-browser/main.contribution.ts | 57 ++++++++++++------- 4 files changed, 71 insertions(+), 39 deletions(-) diff --git a/src/vs/code/electron-main/menubar.ts b/src/vs/code/electron-main/menubar.ts index 4bc7076d0a2..f577118d5c0 100644 --- a/src/vs/code/electron-main/menubar.ts +++ b/src/vs/code/electron-main/menubar.ts @@ -324,6 +324,14 @@ export class Menubar { private setMacApplicationMenu(macApplicationMenu: Electron.Menu): void { const about = new MenuItem({ label: nls.localize('mAbout', "About {0}", product.nameLong), role: 'about' }); const checkForUpdates = this.getUpdateMenuItems(); + + let preferences; + if (this.shouldDrawMenu('Preferences')) { + const preferencesMenu = new Menu(); + this.setMenuById(preferencesMenu, 'Preferences'); + preferences = new MenuItem({ label: this.mnemonicLabel(nls.localize({ key: 'miPreferences', comment: ['&& denotes a mnemonic'] }, "&&Preferences")), submenu: preferencesMenu }); + } + const servicesMenu = new Menu(); const services = new MenuItem({ label: nls.localize('mServices', "Services"), role: 'services', submenu: servicesMenu }); const hide = new MenuItem({ label: nls.localize('mHide', "Hide {0}", product.nameLong), role: 'hide', accelerator: 'Command+H' }); @@ -339,6 +347,14 @@ export class Menubar { const actions = [about]; actions.push(...checkForUpdates); + + if (preferences) { + actions.push(...[ + __separator__(), + preferences + ]); + } + actions.push(...[ __separator__(), services, diff --git a/src/vs/workbench/browser/parts/menubar/menubar.contribution.ts b/src/vs/workbench/browser/parts/menubar/menubar.contribution.ts index 3dbe2a29b12..7ea43eabbe4 100644 --- a/src/vs/workbench/browser/parts/menubar/menubar.contribution.ts +++ b/src/vs/workbench/browser/parts/menubar/menubar.contribution.ts @@ -652,22 +652,24 @@ function helpMenuRegistration() { order: 2 }); - MenuRegistry.appendMenuItem(MenuId.MenubarHelpMenu, { - group: '5_tools', - command: { - id: 'workbench.action.showAccessibilityOptions', - title: nls.localize({ key: 'miAccessibilityOptions', comment: ['&& denotes a mnemonic'] }, "Accessibility &&Options") - }, - order: 3 - }); + if (!isMacintosh) { + MenuRegistry.appendMenuItem(MenuId.MenubarHelpMenu, { + group: '5_tools', + command: { + id: 'workbench.action.showAccessibilityOptions', + title: nls.localize({ key: 'miAccessibilityOptions', comment: ['&& denotes a mnemonic'] }, "Accessibility &&Options") + }, + order: 3 + }); - // About - MenuRegistry.appendMenuItem(MenuId.MenubarHelpMenu, { - group: 'z_about', - command: { - id: 'workbench.action.showAboutDialog', - title: nls.localize({ key: 'miAbout', comment: ['&& denotes a mnemonic'] }, "&&About") - }, - order: 1 - }); + // About + MenuRegistry.appendMenuItem(MenuId.MenubarHelpMenu, { + group: 'z_about', + command: { + id: 'workbench.action.showAboutDialog', + title: nls.localize({ key: 'miAbout', comment: ['&& denotes a mnemonic'] }, "&&About") + }, + order: 1 + }); + } } diff --git a/src/vs/workbench/browser/parts/menubar/menubarPart.ts b/src/vs/workbench/browser/parts/menubar/menubarPart.ts index 1dda968530d..1ff50ca0311 100644 --- a/src/vs/workbench/browser/parts/menubar/menubarPart.ts +++ b/src/vs/workbench/browser/parts/menubar/menubarPart.ts @@ -144,6 +144,7 @@ export class MenubarPart extends Part { }; if (isMacintosh) { + this.topLevelMenus['Preferences'] = this._register(this.menuService.createMenu(MenuId.MenubarPreferencesMenu, this.contextKeyService)); this.topLevelMenus['Window'] = this._register(this.menuService.createMenu(MenuId.MenubarWindowMenu, this.contextKeyService)); } diff --git a/src/vs/workbench/electron-browser/main.contribution.ts b/src/vs/workbench/electron-browser/main.contribution.ts index 847b5e6972f..52e7a997679 100644 --- a/src/vs/workbench/electron-browser/main.contribution.ts +++ b/src/vs/workbench/electron-browser/main.contribution.ts @@ -163,23 +163,34 @@ MenuRegistry.appendMenuItem(MenuId.MenubarFileMenu, { order: 2 }); -MenuRegistry.appendMenuItem(MenuId.MenubarFileMenu, { - group: '2_open', - command: { - id: OpenFileAction.ID, - title: nls.localize({ key: 'miOpenFile', comment: ['&& denotes a mnemonic'] }, "&&Open File...") - }, - order: 1 -}); +if (!isMacintosh) { + 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: { + id: OpenFolderAction.ID, + title: nls.localize({ key: 'miOpenFolder', comment: ['&& denotes a mnemonic'] }, "Open &&Folder...") + }, + order: 2 + }); +} else { + MenuRegistry.appendMenuItem(MenuId.MenubarFileMenu, { + group: '2_open', + command: { + id: OpenFileFolderAction.ID, + title: nls.localize({ key: 'miOpen', comment: ['&& denotes a mnemonic'] }, "&&Open...") + }, + order: 1 + }); +} MenuRegistry.appendMenuItem(MenuId.MenubarFileMenu, { group: '2_open', @@ -226,12 +237,14 @@ MenuRegistry.appendMenuItem(MenuId.MenubarFileMenu, { order: 2 }); -MenuRegistry.appendMenuItem(MenuId.MenubarFileMenu, { - title: nls.localize({ key: 'miPreferences', comment: ['&& denotes a mnemonic'] }, "&&Preferences"), - submenu: MenuId.MenubarPreferencesMenu, - group: '5_autosave', - order: 2 -}); +if (!isMacintosh) { + MenuRegistry.appendMenuItem(MenuId.MenubarFileMenu, { + title: nls.localize({ key: 'miPreferences', comment: ['&& denotes a mnemonic'] }, "&&Preferences"), + submenu: MenuId.MenubarPreferencesMenu, + group: '5_autosave', + order: 2 + }); +} MenuRegistry.appendMenuItem(MenuId.MenubarFileMenu, { group: '6_close', From d332988da180871b6d08836c8b1223998203a53f Mon Sep 17 00:00:00 2001 From: SteVen Batten <6561887+sbatten@users.noreply.github.com> Date: Sun, 22 Jul 2018 11:11:01 -0700 Subject: [PATCH 0039/1276] fix keybinding resolution --- src/vs/code/electron-main/menubar.ts | 21 ++++++++------- src/vs/platform/menubar/common/menubar.ts | 7 +++++ .../browser/parts/menubar/menubarPart.ts | 26 +++++++++++++++++-- 3 files changed, 43 insertions(+), 11 deletions(-) diff --git a/src/vs/code/electron-main/menubar.ts b/src/vs/code/electron-main/menubar.ts index f577118d5c0..d9479c68031 100644 --- a/src/vs/code/electron-main/menubar.ts +++ b/src/vs/code/electron-main/menubar.ts @@ -17,7 +17,7 @@ import product from 'vs/platform/node/product'; import { RunOnceScheduler } from 'vs/base/common/async'; import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; import { mnemonicMenuLabel as baseMnemonicLabel, unmnemonicLabel, getPathLabel } from 'vs/base/common/labels'; -import { KeybindingsResolver } from 'vs/code/electron-main/keyboard'; +import { IKeybinding } from 'vs/code/electron-main/keyboard'; import { IWindowsMainService, IWindowsCountChangedEvent } from 'vs/platform/windows/electron-main/windows'; import { IHistoryMainService } from 'vs/platform/history/common/history'; import { IWorkspaceIdentifier, getWorkspaceLabel, ISingleFolderWorkspaceIdentifier, isSingleFolderWorkspaceIdentifier } from 'vs/platform/workspaces/common/workspaces'; @@ -38,14 +38,12 @@ export class Menubar { private menuUpdater: RunOnceScheduler; - private keybindingsResolver: KeybindingsResolver; - - // private extensionViewlets: IExtensionViewlet[]; - private nativeTabMenuItems: Electron.MenuItem[]; private menubarMenus: IMenubarData = {}; + private keybindings: { [commandId: string]: IKeybinding }; + constructor( @IUpdateService private updateService: IUpdateService, @IInstantiationService instantiationService: IInstantiationService, @@ -59,7 +57,8 @@ export class Menubar { // this.nativeTabMenuItems = []; this.menuUpdater = new RunOnceScheduler(() => this.doUpdateMenu(), 0); - this.keybindingsResolver = instantiationService.createInstance(KeybindingsResolver); + // this.keybindingsResolver = instantiationService.createInstance(KeybindingsResolver); + this.keybindings = Object.create(null); this.install(); @@ -372,7 +371,6 @@ export class Menubar { private shouldDrawMenu(menuId: string): boolean { switch (menuId) { case 'File': - case 'Recent': case 'Help': return true; default: @@ -381,7 +379,7 @@ export class Menubar { } private shouldFallback(menuId: string): boolean { - return this.shouldDrawMenu(menuId) && (this.windowsMainService.getWindowCount() === 0 || !this.menubarMenus[menuId]); + return this.shouldDrawMenu(menuId) && (this.windowsMainService.getWindowCount() === 0); } private setFallbackMenuById(menu: Electron.Menu, menuId: string): void { @@ -490,6 +488,11 @@ export class Menubar { this.insertRecentMenuItems(menu); } + // Store the keybinding + if (item.keybinding) { + this.keybindings[item.id] = item.keybinding; + } + const menuItem = this.createMenuItem(item.label, item.id, item.enabled, item.checked); menu.append(menuItem); } @@ -685,7 +688,7 @@ export class Menubar { } private withKeybinding(commandId: string, options: Electron.MenuItemConstructorOptions): Electron.MenuItemConstructorOptions { - const binding = this.keybindingsResolver.getKeybinding(commandId); + const binding = this.keybindings[commandId]; // Apply binding if there is one if (binding && binding.label) { diff --git a/src/vs/platform/menubar/common/menubar.ts b/src/vs/platform/menubar/common/menubar.ts index 735e234ac93..817b099cc32 100644 --- a/src/vs/platform/menubar/common/menubar.ts +++ b/src/vs/platform/menubar/common/menubar.ts @@ -26,11 +26,18 @@ export interface IMenubarMenu { items: Array; } +export interface IMenubarKeybinding { + id: string; + label: string; + isNative: boolean; +} + export interface IMenubarMenuItemAction { id: string; label: string; checked: boolean; enabled: boolean; + keybinding?: IMenubarKeybinding; } export interface IMenubarMenuItemSubmenu { diff --git a/src/vs/workbench/browser/parts/menubar/menubarPart.ts b/src/vs/workbench/browser/parts/menubar/menubarPart.ts index 1ff50ca0311..6ec3ff3a9b0 100644 --- a/src/vs/workbench/browser/parts/menubar/menubarPart.ts +++ b/src/vs/workbench/browser/parts/menubar/menubarPart.ts @@ -10,7 +10,7 @@ import 'vs/css!./media/menubarpart'; import * as nls from 'vs/nls'; import * as browser from 'vs/base/browser/browser'; import { Part } from 'vs/workbench/browser/part'; -import { IMenubarService, IMenubarMenu, IMenubarMenuItemAction, IMenubarData, IMenubarMenuItemSubmenu } from 'vs/platform/menubar/common/menubar'; +import { IMenubarService, IMenubarMenu, IMenubarMenuItemAction, IMenubarData, IMenubarMenuItemSubmenu, IMenubarKeybinding } from 'vs/platform/menubar/common/menubar'; import { IMenuService, MenuId, IMenu, SubmenuItemAction } from 'vs/platform/actions/common/actions'; import { IThemeService, registerThemingParticipant, ITheme, ICssStyleCollector } from 'vs/platform/theme/common/themeService'; import { IWindowService, MenuBarVisibility, IWindowsService } from 'vs/platform/windows/common/windows'; @@ -794,6 +794,27 @@ export class MenubarPart extends Part { } } + private getMenubarKeybinding(id: string): IMenubarKeybinding { + const binding = this.keybindingService.lookupKeybinding(id); + if (!binding) { + return null; + } + + // first try to resolve a native accelerator + const electronAccelerator = binding.getElectronAccelerator(); + if (electronAccelerator) { + return { id, label: electronAccelerator, isNative: true }; + } + + // we need this fallback to support keybindings that cannot show in electron menus (e.g. chords) + const acceleratorLabel = binding.getLabel(); + if (acceleratorLabel) { + return { id, label: acceleratorLabel, isNative: false }; + } + + return null; + } + private populateMenuItems(menu: IMenu, menuToPopulate: IMenubarMenu) { let groups = menu.getActions(); for (let group of groups) { @@ -817,7 +838,8 @@ export class MenubarPart extends Part { id: menuItem.id, label: menuItem.label, checked: menuItem.checked, - enabled: menuItem.enabled + enabled: menuItem.enabled, + keybinding: this.getMenubarKeybinding(menuItem.id) }; this.setCheckedStatus(menubarMenuItem); From 5dc414cbc9393aafc3eafe43d752d39e9446dcf1 Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Mon, 23 Jul 2018 07:34:16 -0700 Subject: [PATCH 0040/1276] Revert "Merge pull request #54854 from Microsoft/revert-52782-electron-2.0.x" This reverts commit 90fc7e66e2e10f643871b42f9c0f1f989d0ed221, reversing changes made to 3b25417fa204cef38019cd6335807bc073079c96. --- .yarnrc | 2 +- resources/linux/debian/control.template | 3 +- resources/linux/rpm/dependencies.json | 4 +- scripts/code-cli.bat | 2 +- scripts/code-cli.sh | 2 +- scripts/code.sh | 5 +- scripts/test.sh | 5 +- src/main.js | 7 + src/typings/electron.d.ts | 1264 ++- src/typings/node.d.ts | 9582 +++++++++++------ .../processExplorer/processExplorerMain.ts | 2 +- src/vs/code/electron-main/app.ts | 2 +- src/vs/code/electron-main/window.ts | 22 - .../browser/services/codeEditorServiceImpl.ts | 2 +- .../editor/browser/widget/codeEditorWidget.ts | 2 +- .../electron-main/updateService.darwin.ts | 2 +- .../parts/activitybar/activitybarPart.ts | 33 +- .../node/configurationService.ts | 16 +- .../electron-browser/contextmenuService.ts | 34 +- .../electron-browser/extensionHost.ts | 10 +- 20 files changed, 7314 insertions(+), 3687 deletions(-) diff --git a/.yarnrc b/.yarnrc index 42f08fa0c02..f1749b387ef 100644 --- a/.yarnrc +++ b/.yarnrc @@ -1,3 +1,3 @@ disturl "https://atom.io/download/electron" -target "1.7.12" +target "2.0.5" runtime "electron" diff --git a/resources/linux/debian/control.template b/resources/linux/debian/control.template index 57f7c2075ff..eeaf96e0751 100644 --- a/resources/linux/debian/control.template +++ b/resources/linux/debian/control.template @@ -1,7 +1,7 @@ Package: @@NAME@@ Version: @@VERSION@@ Section: devel -Depends: libnotify4, libnss3, gnupg, apt, libxkbfile1, libgconf-2-4, libsecret-1-0 +Depends: libnotify4, libnss3, gnupg, apt, libxkbfile1, libgconf-2-4, libsecret-1-0, libgtk-3-0 (>= 3.10.0) Priority: optional Architecture: @@ARCHITECTURE@@ Maintainer: Microsoft Corporation @@ -12,3 +12,4 @@ Conflicts: visual-studio-@@NAME@@ Replaces: visual-studio-@@NAME@@ Description: Code editing. Redefined. Visual Studio Code is a new choice of tool that combines the simplicity of a code editor with what developers need for the core edit-build-debug cycle. See https://code.visualstudio.com/docs/setup/linux for installation instructions and FAQ. + \ No newline at end of file diff --git a/resources/linux/rpm/dependencies.json b/resources/linux/rpm/dependencies.json index e78bf4f85ca..c2ae8b8fe31 100644 --- a/resources/linux/rpm/dependencies.json +++ b/resources/linux/rpm/dependencies.json @@ -4,7 +4,7 @@ "libpthread.so.0(GLIBC_2.2.5)(64bit)", "libpthread.so.0(GLIBC_2.3.2)(64bit)", "libpthread.so.0(GLIBC_2.3.3)(64bit)", - "libgtk-x11-2.0.so.0()(64bit)", + "libgtk-3.so.0()(64bit)", "libgdk-x11-2.0.so.0()(64bit)", "libatk-1.0.so.0()(64bit)", "libgio-2.0.so.0()(64bit)", @@ -114,7 +114,7 @@ "libglib-2.0.so.0", "libgmodule-2.0.so.0", "libgobject-2.0.so.0", - "libgtk-x11-2.0.so.0", + "libgtk-3.so.0", "libm.so.6", "libm.so.6(GLIBC_2.0)", "libm.so.6(GLIBC_2.1)", diff --git a/scripts/code-cli.bat b/scripts/code-cli.bat index f08ddb744e0..7bca260314d 100644 --- a/scripts/code-cli.bat +++ b/scripts/code-cli.bat @@ -29,7 +29,7 @@ set ELECTRON_ENABLE_LOGGING=1 set ELECTRON_ENABLE_STACK_DUMPING=1 :: Launch Code -%CODE% --debug=5874 out\cli.js . %* +%CODE% --inspect=5874 out\cli.js . %* popd endlocal diff --git a/scripts/code-cli.sh b/scripts/code-cli.sh index 89e518322fc..ba2121d9bb9 100755 --- a/scripts/code-cli.sh +++ b/scripts/code-cli.sh @@ -32,7 +32,7 @@ function code() { VSCODE_DEV=1 \ ELECTRON_ENABLE_LOGGING=1 \ ELECTRON_ENABLE_STACK_DUMPING=1 \ - "$CODE" --debug=5874 "$ROOT/out/cli.js" . "$@" + "$CODE" --inspect=5874 "$ROOT/out/cli.js" . "$@" } code "$@" diff --git a/scripts/code.sh b/scripts/code.sh index f6d103ceda5..26332faea6c 100755 --- a/scripts/code.sh +++ b/scripts/code.sh @@ -3,6 +3,10 @@ if [[ "$OSTYPE" == "darwin"* ]]; then realpath() { [[ $1 = /* ]] && echo "$1" || echo "$PWD/${1#./}"; } ROOT=$(dirname "$(dirname "$(realpath "$0")")") + + # On Linux with Electron 2.0.x running out of a VM causes + # a freeze so we only enable this flag on macOS + export ELECTRON_ENABLE_LOGGING=1 else ROOT=$(dirname "$(dirname "$(readlink -f $0)")") fi @@ -40,7 +44,6 @@ function code() { export NODE_ENV=development export VSCODE_DEV=1 export VSCODE_CLI=1 - export ELECTRON_ENABLE_LOGGING=1 export ELECTRON_ENABLE_STACK_DUMPING=1 # Launch Code diff --git a/scripts/test.sh b/scripts/test.sh index d88a28c5e2d..ac96627846f 100755 --- a/scripts/test.sh +++ b/scripts/test.sh @@ -4,6 +4,10 @@ if [[ "$OSTYPE" == "darwin"* ]]; then realpath() { [[ $1 = /* ]] && echo "$1" || echo "$PWD/${1#./}"; } ROOT=$(dirname $(dirname $(realpath "$0"))) + + # On Linux with Electron 2.0.x running out of a VM causes + # a freeze so we only enable this flag on macOS + export ELECTRON_ENABLE_LOGGING=1 else ROOT=$(dirname $(dirname $(readlink -f $0))) fi @@ -25,7 +29,6 @@ test -d node_modules || yarn node build/lib/electron.js || ./node_modules/.bin/gulp electron # Unit Tests -export ELECTRON_ENABLE_LOGGING=1 if [[ "$OSTYPE" == "darwin"* ]]; then cd $ROOT ; ulimit -n 4096 ; \ "$CODE" \ diff --git a/src/main.js b/src/main.js index 850cda67f2d..ca00474ba1e 100644 --- a/src/main.js +++ b/src/main.js @@ -81,6 +81,13 @@ if (isTempPortable) { const app = require('electron').app; +// TODO@Ben Electron 2.0.x: prevent localStorage migration from SQLite to LevelDB due to issues +app.commandLine.appendSwitch('disable-mojo-local-storage'); + +// TODO@Ben Electron 2.0.x: force srgb color profile (for https://github.com/Microsoft/vscode/issues/51791) +// This also seems to fix: https://github.com/Microsoft/vscode/issues/48043 +app.commandLine.appendSwitch('force-color-profile', 'srgb'); + const minimist = require('minimist'); const paths = require('./paths'); diff --git a/src/typings/electron.d.ts b/src/typings/electron.d.ts index daf41dbc736..445234b2076 100644 --- a/src/typings/electron.d.ts +++ b/src/typings/electron.d.ts @@ -1,4 +1,4 @@ -// Type definitions for Electron 1.7.9 +// Type definitions for Electron 2.0.5 // Project: http://electron.atom.io/ // Definitions by: The Electron Team // Definitions: https://github.com/electron/electron-typescript-definitions @@ -58,6 +58,7 @@ declare namespace Electron { dialog: Dialog; DownloadItem: typeof DownloadItem; globalShortcut: GlobalShortcut; + inAppPurchase: InAppPurchase; IncomingMessage: typeof IncomingMessage; ipcMain: IpcMain; Menu: typeof Menu; @@ -94,6 +95,7 @@ declare namespace Electron { const desktopCapturer: DesktopCapturer; const dialog: Dialog; const globalShortcut: GlobalShortcut; + const inAppPurchase: InAppPurchase; const ipcMain: IpcMain; const ipcRenderer: IpcRenderer; type nativeImage = NativeImage; @@ -157,12 +159,54 @@ declare namespace Electron { hasVisibleWindows: boolean) => void): this; removeListener(event: 'activate', listener: (event: Event, hasVisibleWindows: boolean) => void): this; + /** + * Emitted during Handoff after an activity from this device was successfully + * resumed on another one. + */ + on(event: 'activity-was-continued', listener: (event: Event, + /** + * A string identifying the activity. Maps to . + */ + type: string, + /** + * Contains app-specific state stored by the activity. + */ + userInfo: any) => void): this; + once(event: 'activity-was-continued', listener: (event: Event, + /** + * A string identifying the activity. Maps to . + */ + type: string, + /** + * Contains app-specific state stored by the activity. + */ + userInfo: any) => void): this; + addListener(event: 'activity-was-continued', listener: (event: Event, + /** + * A string identifying the activity. Maps to . + */ + type: string, + /** + * Contains app-specific state stored by the activity. + */ + userInfo: any) => void): this; + removeListener(event: 'activity-was-continued', listener: (event: Event, + /** + * A string identifying the activity. Maps to . + */ + type: string, + /** + * Contains app-specific state stored by the activity. + */ + userInfo: any) => void): this; /** * Emitted before the application starts closing its windows. Calling * event.preventDefault() will prevent the default behaviour, which is terminating * the application. Note: If application quit was initiated by * autoUpdater.quitAndInstall() then before-quit is emitted after emitting close - * event on all windows and closing them. + * event on all windows and closing them. Note: On Windows, this event will not be + * emitted if the app is closed due to a shutdown/restart of the system or a user + * logout. */ on(event: 'before-quit', listener: (event: Event) => void): this; once(event: 'before-quit', listener: (event: Event) => void): this; @@ -286,6 +330,46 @@ declare namespace Electron { * Contains app-specific state stored by the activity on another device. */ userInfo: any) => void): this; + /** + * Emitted during Handoff when an activity from a different device fails to be + * resumed. + */ + on(event: 'continue-activity-error', listener: (event: Event, + /** + * A string identifying the activity. Maps to . + */ + type: string, + /** + * A string with the error's localized description. + */ + error: string) => void): this; + once(event: 'continue-activity-error', listener: (event: Event, + /** + * A string identifying the activity. Maps to . + */ + type: string, + /** + * A string with the error's localized description. + */ + error: string) => void): this; + addListener(event: 'continue-activity-error', listener: (event: Event, + /** + * A string identifying the activity. Maps to . + */ + type: string, + /** + * A string with the error's localized description. + */ + error: string) => void): this; + removeListener(event: 'continue-activity-error', listener: (event: Event, + /** + * A string identifying the activity. Maps to . + */ + type: string, + /** + * A string with the error's localized description. + */ + error: string) => void): this; /** * Emitted when the gpu process crashes or is killed. */ @@ -364,7 +448,9 @@ declare namespace Electron { removeListener(event: 'open-url', listener: (event: Event, url: string) => void): this; /** - * Emitted when the application is quitting. + * Emitted when the application is quitting. Note: On Windows, this event will not + * be emitted if the app is closed due to a shutdown/restart of the system or a + * user logout. */ on(event: 'quit', listener: (event: Event, exitCode: number) => void): this; @@ -410,6 +496,49 @@ declare namespace Electron { url: string, certificateList: Certificate[], callback: (certificate?: Certificate) => void) => void): this; + /** + * Emitted when Handoff is about to be resumed on another device. If you need to + * update the state to be transferred, you should call event.preventDefault() + * immediately, construct a new userInfo dictionary and call + * app.updateCurrentActiviy() in a timely manner. Otherwise the operation will fail + * and continue-activity-error will be called. + */ + on(event: 'update-activity-state', listener: (event: Event, + /** + * A string identifying the activity. Maps to . + */ + type: string, + /** + * Contains app-specific state stored by the activity. + */ + userInfo: any) => void): this; + once(event: 'update-activity-state', listener: (event: Event, + /** + * A string identifying the activity. Maps to . + */ + type: string, + /** + * Contains app-specific state stored by the activity. + */ + userInfo: any) => void): this; + addListener(event: 'update-activity-state', listener: (event: Event, + /** + * A string identifying the activity. Maps to . + */ + type: string, + /** + * Contains app-specific state stored by the activity. + */ + userInfo: any) => void): this; + removeListener(event: 'update-activity-state', listener: (event: Event, + /** + * A string identifying the activity. Maps to . + */ + type: string, + /** + * Contains app-specific state stored by the activity. + */ + userInfo: any) => void): this; /** * Emitted when a new webContents is created. */ @@ -421,6 +550,31 @@ declare namespace Electron { webContents: WebContents) => void): this; removeListener(event: 'web-contents-created', listener: (event: Event, webContents: WebContents) => void): this; + /** + * Emitted during Handoff before an activity from a different device wants to be + * resumed. You should call event.preventDefault() if you want to handle this + * event. + */ + on(event: 'will-continue-activity', listener: (event: Event, + /** + * A string identifying the activity. Maps to . + */ + type: string) => void): this; + once(event: 'will-continue-activity', listener: (event: Event, + /** + * A string identifying the activity. Maps to . + */ + type: string) => void): this; + addListener(event: 'will-continue-activity', listener: (event: Event, + /** + * A string identifying the activity. Maps to . + */ + type: string) => void): this; + removeListener(event: 'will-continue-activity', listener: (event: Event, + /** + * A string identifying the activity. Maps to . + */ + type: string) => void): this; /** * Emitted when the application has finished basic startup. On Windows and Linux, * the will-finish-launching event is the same as the ready event; on macOS, this @@ -437,7 +591,9 @@ declare namespace Electron { * Emitted when all windows have been closed and the application will quit. Calling * event.preventDefault() will prevent the default behaviour, which is terminating * the application. See the description of the window-all-closed event for the - * differences between the will-quit and window-all-closed events. + * differences between the will-quit and window-all-closed events. Note: On + * Windows, this event will not be emitted if the app is closed due to a + * shutdown/restart of the system or a user logout. */ on(event: 'will-quit', listener: (event: Event) => void): this; once(event: 'will-quit', listener: (event: Event) => void): this; @@ -482,7 +638,7 @@ declare namespace Electron { */ enableMixedSandbox(): void; /** - * Exits immediately with exitCode. exitCode defaults to 0. All windows will be + * Exits immediately with exitCode. exitCode defaults to 0. All windows will be * closed immediately without asking user and the before-quit and will-quit events * will not be emitted. */ @@ -492,7 +648,6 @@ declare namespace Electron { * the active app. On Windows, focuses on the application's first window. */ focus(): void; - getAppMemoryInfo(): ProcessMetric[]; getAppMetrics(): ProcessMetric[]; getAppPath(): string; getBadgeCount(): number; @@ -501,24 +656,24 @@ declare namespace Electron { * Fetches a path's associated icon. On Windows, there a 2 kinds of icons: On Linux * and macOS, icons depend on the application associated with file mime type. */ - getFileIcon(path: string, options: FileIconOptions, callback: (error: Error, icon: NativeImage) => void): void; + getFileIcon(path: string, callback: (error: Error, icon: NativeImage) => void): void; /** * Fetches a path's associated icon. On Windows, there a 2 kinds of icons: On Linux * and macOS, icons depend on the application associated with file mime type. */ - getFileIcon(path: string, callback: (error: Error, icon: NativeImage) => void): void; + getFileIcon(path: string, options: FileIconOptions, callback: (error: Error, icon: NativeImage) => void): void; getGPUFeatureStatus(): GPUFeatureStatus; getJumpListSettings(): JumpListSettings; /** - * Note: When distributing your packaged app, you have to also ship the locales - * folder. Note: On Windows you have to call it after the ready events gets - * emitted. + * To set the locale, you'll want to use a command line switch at app startup, + * which may be found here. Note: When distributing your packaged app, you have to + * also ship the locales folder. Note: On Windows you have to call it after the + * ready events gets emitted. */ getLocale(): string; /** * If you provided path and args options to app.setLoginItemSettings then you need - * to pass the same arguments here for openAtLogin to be set correctly. Note: This - * API has no effect on MAS builds. + * to pass the same arguments here for openAtLogin to be set correctly. */ getLoginItemSettings(options?: LoginItemSettingsOptions): LoginItemSettings; /** @@ -544,6 +699,10 @@ declare namespace Electron { * net_error_list. */ importCertificate(options: ImportCertificateOptions, callback: (result: number) => void): void; + /** + * Invalidates the current Handoff user activity. + */ + invalidateCurrentActivity(type: string): void; isAccessibilitySupportEnabled(): boolean; /** * This method checks if the current executable is the default handler for a @@ -555,6 +714,7 @@ declare namespace Electron { * the Windows Registry and LSCopyDefaultHandlerForURLScheme internally. */ isDefaultProtocolClient(protocol: string, path?: string, args?: string[]): boolean; + isInApplicationsFolder(): boolean; isReady(): boolean; isUnityRunning(): boolean; /** @@ -578,6 +738,15 @@ declare namespace Electron { * instance starts: */ makeSingleInstance(callback: (argv: string[], workingDirectory: string) => void): boolean; + /** + * No confirmation dialog will be presented by default, if you wish to allow the + * user to confirm the operation you may do so using the dialog API. NOTE: This + * method throws errors if anything other than the user causes the move to fail. + * For instance if the user cancels the authorization dialog this method returns + * false. If we fail to perform the copy then this method will throw an error. The + * message in the error should be informative and tell you exactly what went wrong + */ + moveToApplicationsFolder(): boolean; /** * Try to close all windows. The before-quit event will be emitted first. If all * windows are successfully closed, the will-quit event will be emitted and by @@ -615,6 +784,15 @@ declare namespace Electron { * .plist file. See the Apple docs for more details. */ setAboutPanelOptions(options: AboutPanelOptionsOptions): void; + /** + * Manually enables Chrome's accessibility support, allowing to expose + * accessibility switch to users in application settings. + * https://www.chromium.org/developers/design-documents/accessibility for more + * details. Disabled by default. Note: Rendering accessibility tree can + * significantly affect the performance of your app. It should not be enabled by + * default. + */ + setAccessibilitySupportEnabled(enabled: boolean): void; /** * Changes the Application User Model ID to id. */ @@ -660,8 +838,7 @@ declare namespace Electron { /** * Set the app's login item settings. To work with Electron's autoUpdater on * Windows, which uses Squirrel, you'll want to set the launch path to Update.exe, - * and pass arguments that specify your application name. For example: Note: This - * API has no effect on MAS builds. + * and pass arguments that specify your application name. For example: */ setLoginItemSettings(settings: Settings): void; /** @@ -694,6 +871,18 @@ declare namespace Electron { * them. */ show(): void; + /** + * Start accessing a security scoped resource. With this method electron + * applications that are packaged for the Mac App Store may reach outside their + * sandbox to access files chosen by the user. See Apple's documentation for a + * description of how this system works. + */ + startAccessingSecurityScopedResource(bookmarkData: string): Function; + /** + * Updates the current activity if its type matches type, merging the entries from + * userInfo into its current userInfo dictionary. + */ + updateCurrentActivity(type: string, userInfo: any): void; commandLine: CommandLine; dock: Dock; } @@ -763,16 +952,18 @@ declare namespace Electron { getFeedURL(): string; /** * Restarts the app and installs the update after it has been downloaded. It should - * only be called after update-downloaded has been emitted. Note: - * autoUpdater.quitAndInstall() will close all application windows first and only - * emit before-quit event on app after that. This is different from the normal quit - * event sequence. + * only be called after update-downloaded has been emitted. Under the hood calling + * autoUpdater.quitAndInstall() will close all application windows first, and + * automatically call app.quit() after all windows have been closed. Note: If the + * application is quit without calling this API after the update-downloaded event + * has been emitted, the application will still be replaced by the updated one on + * the next run. */ quitAndInstall(): void; /** * Sets the url and initialize the auto updater. */ - setFeedURL(url: string, requestHeaders?: any): void; + setFeedURL(options: FeedURLOptions): void; } interface BluetoothDevice { @@ -789,6 +980,15 @@ declare namespace Electron { constructor(options?: BrowserViewConstructorOptions); static fromId(id: number): BrowserView; + static fromWebContents(webContents: WebContents): BrowserView | null; + static getAllViews(): BrowserView[]; + /** + * Force closing the view, the unload and beforeunload events won't be emitted for + * the web page. After you're done with a view, call this function in order to free + * memory and other resources as soon as possible. + */ + destroy(): void; + isDestroyed(): boolean; setAutoResize(options: AutoResizeOptions): void; setBackgroundColor(color: string): void; /** @@ -831,7 +1031,11 @@ declare namespace Electron { * cancel the close. Usually you would want to use the beforeunload handler to * decide whether the window should be closed, which will also be called when the * window is reloaded. In Electron, returning any value other than undefined would - * cancel the close. For example: + * cancel the close. For example: Note: There is a subtle difference between the + * behaviors of window.onbeforeunload = handler and + * window.addEventListener('beforeunload', handler). It is recommended to always + * set the event.returnValue explicitly, instead of just returning a value, as the + * former works more consistently within Electron. */ on(event: 'close', listener: (event: Event) => void): this; once(event: 'close', listener: (event: Event) => void): this; @@ -1056,6 +1260,7 @@ declare namespace Electron { * This API cannot be called before the ready event of the app module is emitted. */ static addExtension(path: string): void; + static fromBrowserView(browserView: BrowserView): BrowserWindow | null; static fromId(id: number): BrowserWindow; static fromWebContents(webContents: WebContents): BrowserWindow; static getAllWindows(): BrowserWindow[]; @@ -1080,6 +1285,10 @@ declare namespace Electron { * ready event of the app module is emitted. */ static removeExtension(name: string): void; + /** + * Adds a window as a tab on this window, after the tab for the window instance. + */ + addTabbedWindow(browserWindow: BrowserWindow): void; /** * Removes focus from the window. */ @@ -1123,6 +1332,11 @@ declare namespace Electron { focus(): void; focusOnWebView(): void; getBounds(): Rectangle; + /** + * Note: The BrowserView API is currently experimental and may change or be removed + * in future Electron releases. + */ + getBrowserView(): BrowserView | null; getChildWindows(): BrowserWindow[]; getContentBounds(): Rectangle; getContentSize(): number[]; @@ -1133,6 +1347,7 @@ declare namespace Electron { * (unsigned long) on Linux. */ getNativeWindowHandle(): Buffer; + getOpacity(): number; getParentWindow(): BrowserWindow; getPosition(): number[]; getRepresentedFilename(): string; @@ -1184,12 +1399,18 @@ declare namespace Electron { */ isMovable(): boolean; isResizable(): boolean; + isSimpleFullScreen(): boolean; isVisible(): boolean; /** * Note: This API always returns false on Windows. */ isVisibleOnAllWorkspaces(): boolean; isWindowMessageHooked(message: number): boolean; + /** + * Same as webContents.loadFile, filePath should be a path to an HTML file relative + * to the root of your application. See the webContents docs for more information. + */ + loadFile(filePath: string): void; /** * Same as webContents.loadURL(url[, options]). The url can be a remote address * (e.g. http://) or a path to a local HTML file using the file:// protocol. To @@ -1203,11 +1424,21 @@ declare namespace Electron { * being displayed already. */ maximize(): void; + /** + * Merges all windows into one window with multiple tabs when native tabs are + * enabled and there is more than one open window. + */ + mergeAllWindows(): void; /** * Minimizes the window. On some platforms the minimized window will be shown in * the Dock. */ minimize(): void; + /** + * Moves the current tab into a new window if native tabs are enabled and there is + * more than one tab in the current window. + */ + moveTabToNewWindow(): void; /** * Uses Quick Look to preview a file at a given path. */ @@ -1220,6 +1451,16 @@ declare namespace Electron { * Restores the window from minimized state to its previous state. */ restore(): void; + /** + * Selects the next tab when native tabs are enabled and there are other tabs in + * the window. + */ + selectNextTab(): void; + /** + * Selects the previous tab when native tabs are enabled and there are other tabs + * in the window. + */ + selectPreviousTab(): void; /** * Sets whether the window should show always on top of other windows. After * setting this, the window is still a normal window, not a toolbox window which @@ -1261,10 +1502,6 @@ declare namespace Electron { * Resizes and moves the window to the supplied bounds */ setBounds(bounds: Rectangle, animate?: boolean): void; - /** - * Note: The BrowserView API is currently experimental and may change or be removed - * in future Electron releases. - */ setBrowserView(browserView: BrowserView): void; /** * Sets whether the window can be manually closed by user. On Linux does nothing. @@ -1290,6 +1527,10 @@ declare namespace Electron { * bar will become gray when set to true. */ setDocumentEdited(edited: boolean): void; + /** + * Disable or enable the window. + */ + setEnabled(enable: boolean): void; /** * Changes whether the window can be focused. */ @@ -1316,7 +1557,7 @@ declare namespace Electron { * window will be passed to the window below this window, but if this window has * focus, it will still receive keyboard events. */ - setIgnoreMouseEvents(ignore: boolean): void; + setIgnoreMouseEvents(ignore: boolean, options?: IgnoreMouseEventsOptions): void; /** * Enters or leaves the kiosk mode. */ @@ -1353,6 +1594,10 @@ declare namespace Electron { * Sets whether the window can be moved by user. On Linux does nothing. */ setMovable(movable: boolean): void; + /** + * Sets the opacity of the window. On Linux does nothing. + */ + setOpacity(opacity: number): void; /** * Sets a 16 x 16 pixel overlay onto the current taskbar icon, usually used to * convey some sort of application status or to passively notify the user. @@ -1393,6 +1638,11 @@ declare namespace Electron { * HTML-rendered toolbar. For example: */ setSheetOffset(offsetY: number, offsetX?: number): void; + /** + * Enters or leaves simple fullscreen mode. Simple fullscreen mode emulates the + * native fullscreen behavior found in versions of Mac OS X prior to Lion (10.7). + */ + setSimpleFullScreen(flag: boolean): void; /** * Resizes the window to width and height. */ @@ -1456,6 +1706,11 @@ declare namespace Electron { * Shows the window but doesn't focus on it. */ showInactive(): void; + /** + * Toggles the visibility of the tab bar if native tabs are enabled and there is + * only one tab in the current window. + */ + toggleTabBar(): void; /** * Unhooks all of the window messages. */ @@ -1689,7 +1944,7 @@ declare namespace Electron { * An object representing the HTTP response message. */ response: IncomingMessage) => void): this; - constructor(options: any | string); + constructor(options: 'method' | 'url' | 'session' | 'partition' | 'protocol' | 'host' | 'hostname' | 'port' | 'path' | 'redirect'); /** * Cancels an ongoing HTTP transaction. If the request has already emitted the * close event, the abort operation will have no effect. Otherwise an ongoing event @@ -1917,7 +2172,7 @@ declare namespace Electron { */ on(event: 'changed', listener: (event: Event, /** - * The cookie that was changed + * The cookie that was changed. */ cookie: Cookie, /** @@ -1930,7 +2185,7 @@ declare namespace Electron { removed: boolean) => void): this; once(event: 'changed', listener: (event: Event, /** - * The cookie that was changed + * The cookie that was changed. */ cookie: Cookie, /** @@ -1943,7 +2198,7 @@ declare namespace Electron { removed: boolean) => void): this; addListener(event: 'changed', listener: (event: Event, /** - * The cookie that was changed + * The cookie that was changed. */ cookie: Cookie, /** @@ -1956,7 +2211,7 @@ declare namespace Electron { removed: boolean) => void): this; removeListener(event: 'changed', listener: (event: Event, /** - * The cookie that was changed + * The cookie that was changed. */ cookie: Cookie, /** @@ -1972,8 +2227,8 @@ declare namespace Electron { */ flushStore(callback: Function): void; /** - * Sends a request to get all cookies matching details, callback will be called - * with callback(error, cookies) on complete. + * Sends a request to get all cookies matching filter, callback will be called with + * callback(error, cookies) on complete. */ get(filter: Filter, callback: (error: Error, cookies: Cookie[]) => void): void; /** @@ -1994,7 +2249,7 @@ declare namespace Electron { /** * The number of average idle cpu wakeups per second since the last call to - * getCPUUsage. First call returns 0. + * getCPUUsage. First call returns 0. Will always return 0 on Windows. */ idleWakeupsPerSecond: number; /** @@ -2007,19 +2262,31 @@ declare namespace Electron { // Docs: http://electron.atom.io/docs/api/structures/crash-report - date: string; - ID: number; + date: Date; + id: string; } interface CrashReporter extends EventEmitter { // Docs: http://electron.atom.io/docs/api/crash-reporter + /** + * Set an extra parameter to be sent with the crash report. The values specified + * here will be sent in addition to any values set via the extra option when start + * was called. This API is only available on macOS, if you need to add/update extra + * parameters on Linux and Windows after your first call to start you can call + * start again with the updated extra options. + */ + addExtraParameter(key: string, value: string): void; /** * Returns the date and ID of the last crash report. If no crash reports have been * sent or the crash reporter has not been started, null is returned. */ getLastCrashReport(): CrashReport; + /** + * See all of the current parameters being passed to the crash reporter. + */ + getParameters(): void; /** * Returns all uploaded crash reports. Each report contains the date and uploaded * ID. @@ -2030,13 +2297,10 @@ declare namespace Electron { */ getUploadToServer(): boolean; /** - * Set an extra parameter to be sent with the crash report. The values specified - * here will be sent in addition to any values set via the extra option when start - * was called. This API is only available on macOS, if you need to add/update extra - * parameters on Linux and Windows after your first call to start you can call - * start again with the updated extra options. + * Remove a extra parameter from the current set of parameters so that it will not + * be sent with the crash report. */ - setExtraParameter(key: string, value: string): void; + removeExtraParameter(key: string): void; /** * This would normally be controlled by user preferences. This has no effect if * called before start is called. Note: This API can only be called from the main @@ -2057,7 +2321,7 @@ declare namespace Electron { * well. This will start the process that will monitor and send the crash reports. * Replace submitURL, productName and crashesDirectory with appropriate values. * Note: If you need send additional/updated extra parameters after your first call - * start you can call setExtraParameter on macOS or call start again with the + * start you can call addExtraParameter on macOS or call start again with the * new/updated extra parameters on Linux and Windows. Note: On macOS, Electron uses * a new crashpad client for crash collection and reporting. If you want to enable * crash reporting, initializing crashpad from the main process using @@ -2225,7 +2489,7 @@ declare namespace Electron { /** * Displays a modal dialog that shows an error message. This API can be called * safely before the ready event the app module emits, it is usually used to report - * errors in early stage of startup. If called before the app readyevent on Linux, + * errors in early stage of startup. If called before the app readyevent on Linux, * the message will be emitted to stderr, and no GUI dialog will appear. */ showErrorBox(title: string, content: string): void; @@ -2253,11 +2517,11 @@ declare namespace Electron { * dots (e.g. 'png' is good but '.png' and '*.png' are bad). To show all files, use * the '*' wildcard (no other wildcard is supported). If a callback is passed, the * API call will be asynchronous and the result will be passed via - * callback(filenames) Note: On Windows and Linux an open dialog can not be both a + * callback(filenames). Note: On Windows and Linux an open dialog can not be both a * file selector and a directory selector, so if you set properties to ['openFile', * 'openDirectory'] on these platforms, a directory selector will be shown. */ - showOpenDialog(browserWindow: BrowserWindow, options: OpenDialogOptions, callback?: (filePaths: string[]) => void): string[]; + showOpenDialog(browserWindow: BrowserWindow, options: OpenDialogOptions, callback?: (filePaths: string[], bookmarks: string[]) => void): string[]; /** * The browserWindow argument allows the dialog to attach itself to a parent * window, making it modal. The filters specifies an array of file types that can @@ -2266,27 +2530,27 @@ declare namespace Electron { * dots (e.g. 'png' is good but '.png' and '*.png' are bad). To show all files, use * the '*' wildcard (no other wildcard is supported). If a callback is passed, the * API call will be asynchronous and the result will be passed via - * callback(filenames) Note: On Windows and Linux an open dialog can not be both a + * callback(filenames). Note: On Windows and Linux an open dialog can not be both a * file selector and a directory selector, so if you set properties to ['openFile', * 'openDirectory'] on these platforms, a directory selector will be shown. */ - showOpenDialog(options: OpenDialogOptions, callback?: (filePaths: string[]) => void): string[]; + showOpenDialog(options: OpenDialogOptions, callback?: (filePaths: string[], bookmarks: string[]) => void): string[]; /** * The browserWindow argument allows the dialog to attach itself to a parent * window, making it modal. The filters specifies an array of file types that can * be displayed, see dialog.showOpenDialog for an example. If a callback is passed, * the API call will be asynchronous and the result will be passed via - * callback(filename) + * callback(filename). */ - showSaveDialog(browserWindow: BrowserWindow, options: SaveDialogOptions, callback?: (filename: string) => void): string; + showSaveDialog(browserWindow: BrowserWindow, options: SaveDialogOptions, callback?: (filename: string, bookmark: string) => void): string; /** * The browserWindow argument allows the dialog to attach itself to a parent * window, making it modal. The filters specifies an array of file types that can * be displayed, see dialog.showOpenDialog for an example. If a callback is passed, * the API call will be asynchronous and the result will be passed via - * callback(filename) + * callback(filename). */ - showSaveDialog(options: SaveDialogOptions, callback?: (filename: string) => void): string; + showSaveDialog(options: SaveDialogOptions, callback?: (filename: string, bookmark: string) => void): string; } interface Display { @@ -2325,33 +2589,54 @@ declare namespace Electron { * download that can't be resumed. The state can be one of following: */ on(event: 'done', listener: (event: Event, - state: string) => void): this; + /** + * Can be `completed`, `cancelled` or `interrupted`. + */ + state: ('completed' | 'cancelled' | 'interrupted')) => void): this; once(event: 'done', listener: (event: Event, - state: string) => void): this; + /** + * Can be `completed`, `cancelled` or `interrupted`. + */ + state: ('completed' | 'cancelled' | 'interrupted')) => void): this; addListener(event: 'done', listener: (event: Event, - state: string) => void): this; + /** + * Can be `completed`, `cancelled` or `interrupted`. + */ + state: ('completed' | 'cancelled' | 'interrupted')) => void): this; removeListener(event: 'done', listener: (event: Event, - state: string) => void): this; + /** + * Can be `completed`, `cancelled` or `interrupted`. + */ + state: ('completed' | 'cancelled' | 'interrupted')) => void): this; /** * Emitted when the download has been updated and is not done. The state can be one * of following: */ on(event: 'updated', listener: (event: Event, - state: string) => void): this; + /** + * Can be `progressing` or `interrupted`. + */ + state: ('progressing' | 'interrupted')) => void): this; once(event: 'updated', listener: (event: Event, - state: string) => void): this; + /** + * Can be `progressing` or `interrupted`. + */ + state: ('progressing' | 'interrupted')) => void): this; addListener(event: 'updated', listener: (event: Event, - state: string) => void): this; + /** + * Can be `progressing` or `interrupted`. + */ + state: ('progressing' | 'interrupted')) => void): this; removeListener(event: 'updated', listener: (event: Event, - state: string) => void): this; + /** + * Can be `progressing` or `interrupted`. + */ + state: ('progressing' | 'interrupted')) => void): this; /** * Cancels the download operation. */ cancel(): void; - /** - * Resumes Boolean - Whether the download can resume. - */ - canResume(): void; + canResume(): boolean; getContentDisposition(): string; getETag(): string; /** @@ -2491,6 +2776,38 @@ declare namespace Electron { webgl2: string; } + interface InAppPurchase extends EventEmitter { + + // Docs: http://electron.atom.io/docs/api/in-app-purchase + + /** + * Emitted when one or more transactions have been updated. + */ + on(event: 'transactions-updated', listener: (event: Event, + /** + * Array of transactions. + */ + transactions: Transaction[]) => void): this; + once(event: 'transactions-updated', listener: (event: Event, + /** + * Array of transactions. + */ + transactions: Transaction[]) => void): this; + addListener(event: 'transactions-updated', listener: (event: Event, + /** + * Array of transactions. + */ + transactions: Transaction[]) => void): this; + removeListener(event: 'transactions-updated', listener: (event: Event, + /** + * Array of transactions. + */ + transactions: Transaction[]) => void): this; + canMakePayments(): boolean; + getReceiptURL(): string; + purchaseProduct(productID: string, quantity?: number, callback?: (isProductValid: boolean) => void): void; + } + class IncomingMessage extends EventEmitter { // Docs: http://electron.atom.io/docs/api/incoming-message @@ -2624,7 +2941,7 @@ declare namespace Electron { /** * Removes all listeners, or those of the specified channel. */ - removeAllListeners(channel?: string): this; + removeAllListeners(channel: string): this; /** * Removes the specified listener from the listener array for the specified * channel. @@ -2646,6 +2963,10 @@ declare namespace Electron { * renderer process, unless you know what you are doing you should never use it. */ sendSync(channel: string, ...args: any[]): any; + /** + * Sends a message to a window with windowid via channel. + */ + sendTo(windowId: number, channel: string, ...args: any[]): void; /** * Like ipcRenderer.send but the event will be sent to the element in the * host page instead of the main process. @@ -2760,6 +3081,20 @@ declare namespace Electron { // Docs: http://electron.atom.io/docs/api/menu + /** + * Emitted when a popup is closed either manually or with menu.closePopup(). + */ + on(event: 'menu-will-close', listener: (event: Event) => void): this; + once(event: 'menu-will-close', listener: (event: Event) => void): this; + addListener(event: 'menu-will-close', listener: (event: Event) => void): this; + removeListener(event: 'menu-will-close', listener: (event: Event) => void): this; + /** + * Emitted when menu.popup() is called. + */ + on(event: 'menu-will-show', listener: (event: Event) => void): this; + once(event: 'menu-will-show', listener: (event: Event) => void): this; + addListener(event: 'menu-will-show', listener: (event: Event) => void): this; + removeListener(event: 'menu-will-show', listener: (event: Event) => void): this; constructor(); /** * Generally, the template is just an array of options for constructing a MenuItem. @@ -2772,7 +3107,7 @@ declare namespace Electron { * Note: The returned Menu instance doesn't support dynamic addition or removal of * menu items. Instance properties can still be dynamically modified. */ - static getApplicationMenu(): Menu; + static getApplicationMenu(): Menu | null; /** * Sends the action to the first responder of application. This is used for * emulating default macOS menu behaviors. Usually you would just use the role @@ -2786,7 +3121,7 @@ declare namespace Electron { * Windows and Linux but has no effect on macOS. Note: This API has to be called * after the ready event of app module. */ - static setApplicationMenu(menu: Menu): void; + static setApplicationMenu(menu: Menu | null): void; /** * Appends the menuItem to the menu. */ @@ -2795,14 +3130,15 @@ declare namespace Electron { * Closes the context menu in the browserWindow. */ closePopup(browserWindow?: BrowserWindow): void; + getMenuItemById(id: string): MenuItem; /** * Inserts the menuItem to the pos position of the menu. */ insert(pos: number, menuItem: MenuItem): void; /** - * Pops up this menu as a context menu in the browserWindow. + * Pops up this menu as a context menu in the BrowserWindow. */ - popup(browserWindow?: BrowserWindow, options?: PopupOptions): void; + popup(options: PopupOptions): void; items: MenuItem[]; } @@ -2848,6 +3184,13 @@ declare namespace Electron { * Creates a new NativeImage instance from dataURL. */ static createFromDataURL(dataURL: string): NativeImage; + /** + * Creates a new NativeImage instance from the NSImage that maps to the given image + * name. See NSImageName for a list of possible values. The hslShift is applied to + * the image with the following rules This means that [-1, 0, 1] will make the + * image completely white and [-1, 1, 0] will make the image completely black. + */ + static createFromNamedImage(imageName: string, hslShift: number[]): NativeImage; /** * Creates a new NativeImage instance from a file located at path. This method * returns an empty image if the path does not exist, cannot be read, or is not a @@ -2911,22 +3254,22 @@ declare namespace Electron { on(event: 'action', listener: (event: Event, /** - * The index of the action that was activated + * The index of the action that was activated. */ index: number) => void): this; once(event: 'action', listener: (event: Event, /** - * The index of the action that was activated + * The index of the action that was activated. */ index: number) => void): this; addListener(event: 'action', listener: (event: Event, /** - * The index of the action that was activated + * The index of the action that was activated. */ index: number) => void): this; removeListener(event: 'action', listener: (event: Event, /** - * The index of the action that was activated + * The index of the action that was activated. */ index: number) => void): this; /** @@ -2938,7 +3281,7 @@ declare namespace Electron { removeListener(event: 'click', listener: (event: Event) => void): this; /** * Emitted when the notification is closed by manual intervention from the user. - * This event is not guarunteed to be emitted in all cases where the notification + * This event is not guaranteed to be emitted in all cases where the notification * is closed. */ on(event: 'close', listener: (event: Event) => void): this; @@ -2951,22 +3294,22 @@ declare namespace Electron { */ on(event: 'reply', listener: (event: Event, /** - * The string the user entered into the inline reply field + * The string the user entered into the inline reply field. */ reply: string) => void): this; once(event: 'reply', listener: (event: Event, /** - * The string the user entered into the inline reply field + * The string the user entered into the inline reply field. */ reply: string) => void): this; addListener(event: 'reply', listener: (event: Event, /** - * The string the user entered into the inline reply field + * The string the user entered into the inline reply field. */ reply: string) => void): this; removeListener(event: 'reply', listener: (event: Event, /** - * The string the user entered into the inline reply field + * The string the user entered into the inline reply field. */ reply: string) => void): this; /** @@ -2980,11 +3323,17 @@ declare namespace Electron { removeListener(event: 'show', listener: (event: Event) => void): this; constructor(options: NotificationConstructorOptions); static isSupported(): boolean; + /** + * Dismisses the notification. + */ + close(): void; /** * Immediately shows the notification to the user, please note this means unlike * the HTML5 Notification implementation, simply instantiating a new Notification * does not immediately show it to the user, you need to call this method before - * the OS will display it. + * the OS will display it. If the notification has been shown before, this method + * will dismiss the previously shown notification and create a new one with + * identical properties. */ show(): void; } @@ -3036,6 +3385,16 @@ declare namespace Electron { once(event: 'resume', listener: Function): this; addListener(event: 'resume', listener: Function): this; removeListener(event: 'resume', listener: Function): this; + /** + * Emitted when the system is about to reboot or shut down. If the event handler + * invokes e.preventDefault(), Electron will attempt to delay system shutdown in + * order for the app to exit cleanly. If e.preventDefault() is called, the app + * should exit as soon as possible by calling something like app.quit(). + */ + on(event: 'shutdown', listener: Function): this; + once(event: 'shutdown', listener: Function): this; + addListener(event: 'shutdown', listener: Function): this; + removeListener(event: 'shutdown', listener: Function): this; /** * Emitted when the system is suspending. */ @@ -3118,6 +3477,11 @@ declare namespace Electron { * sends a new HTTP request as a response. */ interceptHttpProtocol(scheme: string, handler: (request: InterceptHttpProtocolRequest, callback: (redirectRequest: RedirectRequest) => void) => void, completion?: (error: Error) => void): void; + /** + * Same as protocol.registerStreamProtocol, except that it replaces an existing + * protocol handler. + */ + interceptStreamProtocol(scheme: string, handler: (request: InterceptStreamProtocolRequest, callback: (stream?: ReadableStream | StreamProtocolResponse) => void) => void, completion?: (error: Error) => void): void; /** * Intercepts scheme protocol and uses handler as the protocol's new handler which * sends a String as a response. @@ -3178,6 +3542,15 @@ declare namespace Electron { * the ready event of the app module gets emitted. */ registerStandardSchemes(schemes: string[], options?: RegisterStandardSchemesOptions): void; + /** + * Registers a protocol of scheme that will send a Readable as a response. The + * usage is similar to the other register{Any}Protocol, except that the callback + * should be called with either a Readable object or an object that has the data, + * statusCode, and headers properties. Example: It is possible to pass any object + * that implements the readable stream API (emits data/end/error events). For + * example, here's how a file could be returned: + */ + registerStreamProtocol(scheme: string, handler: (request: RegisterStreamProtocolRequest, callback: (stream?: ReadableStream | StreamProtocolResponse) => void) => void, completion?: (error: Error) => void): void; /** * Registers a protocol of scheme that will send a String as a response. The usage * is the same with registerFileProtocol, except that the callback should be called @@ -3380,7 +3753,7 @@ declare namespace Electron { * options, you have to ensure the Session with the partition has never been used * before. There is no way to change the options of an existing Session object. */ - static fromPartition(partition: string, options: FromPartitionOptions): Session; + static fromPartition(partition: string, options?: FromPartitionOptions): Session; /** * A Session object, the default session object of the app. */ @@ -3444,11 +3817,12 @@ declare namespace Electron { * Writes any unwritten DOMStorage data to disk. */ flushStorageData(): void; - getBlobData(identifier: string, callback: (result: Buffer) => void): Blob; + getBlobData(identifier: string, callback: (result: Buffer) => void): void; /** * Callback is invoked with the session's current cache size. */ getCacheSize(callback: (size: number) => void): void; + getPreloads(): string[]; getUserAgent(): string; /** * Resolves the proxy information for url. The callback will be called with @@ -3471,9 +3845,14 @@ declare namespace Electron { /** * Sets the handler which can be used to respond to permission requests for the * session. Calling callback(true) will allow the permission and callback(false) - * will reject it. + * will reject it. To clear the handler, call setPermissionRequestHandler(null). */ - setPermissionRequestHandler(handler: (webContents: WebContents, permission: string, callback: (permissionGranted: boolean) => void) => void): void; + setPermissionRequestHandler(handler: (webContents: WebContents, permission: string, callback: (permissionGranted: boolean) => void, details: PermissionRequestHandlerDetails) => void | null): void; + /** + * Adds scripts that will be executed on ALL web contents that are associated with + * this session just before normal preload scripts run. + */ + setPreloads(preloads: string[]): void; /** * Sets the proxy settings. When pacScript and proxyRules are provided together, * the proxyRules option is ignored and pacScript configuration is applied. The @@ -3578,6 +3957,24 @@ declare namespace Electron { width: number; } + interface StreamProtocolResponse { + + // Docs: http://electron.atom.io/docs/api/structures/stream-protocol-response + + /** + * A Node.js readable stream representing the response body + */ + data: ReadableStream; + /** + * An object containing the response headers + */ + headers: Headers; + /** + * The HTTP response code + */ + statusCode: number; + } + interface SystemPreferences extends EventEmitter { // Docs: http://electron.atom.io/docs/api/system-preferences @@ -3633,7 +4030,7 @@ declare namespace Electron { getAccentColor(): string; getColor(color: '3d-dark-shadow' | '3d-face' | '3d-highlight' | '3d-light' | '3d-shadow' | 'active-border' | 'active-caption' | 'active-caption-gradient' | 'app-workspace' | 'button-text' | 'caption-text' | 'desktop' | 'disabled-text' | 'highlight' | 'highlight-text' | 'hotlight' | 'inactive-border' | 'inactive-caption' | 'inactive-caption-gradient' | 'inactive-caption-text' | 'info-background' | 'info-text' | 'menu' | 'menu-highlight' | 'menubar' | 'menu-text' | 'scrollbar' | 'window' | 'window-frame' | 'window-text'): string; /** - * This API uses NSUserDefaults on macOS. Some popular key and types are: + * Some popular key and types are: */ getUserDefault(key: string, type: 'string' | 'boolean' | 'integer' | 'float' | 'double' | 'url' | 'array' | 'dictionary'): any; /** @@ -3655,14 +4052,22 @@ declare namespace Electron { */ postNotification(event: string, userInfo: any): void; /** - * Set the value of key in system preferences. Note that type should match actual - * type of value. An exception is thrown if they don't. This API uses - * NSUserDefaults on macOS. Some popular key and types are: + * Add the specified defaults to your application's NSUserDefaults. + */ + registerDefaults(defaults: any): void; + /** + * Removes the key in NSUserDefaults. This can be used to restore the default or + * global value of a key previously set with setUserDefault. + */ + removeUserDefault(key: string): void; + /** + * Set the value of key in NSUserDefaults. Note that type should match actual type + * of value. An exception is thrown if they don't. Some popular key and types are: */ setUserDefault(key: string, type: string, value: string): void; /** * Same as subscribeNotification, but uses NSNotificationCenter for local defaults. - * This is necessary for events such as NSUserDefaultsDidChangeNotification + * This is necessary for events such as NSUserDefaultsDidChangeNotification. */ subscribeLocalNotification(event: string, callback: (event: string, userInfo: any) => void): void; /** @@ -3830,7 +4235,7 @@ declare namespace Electron { // Docs: http://electron.atom.io/docs/api/touch-bar constructor(options: TouchBarConstructorOptions); - escapeItem: any; + escapeItem: (TouchBarButton | TouchBarColorPicker | TouchBarGroup | TouchBarLabel | TouchBarPopover | TouchBarScrubber | TouchBarSegmentedControl | TouchBarSlider | TouchBarSpacer | null); static TouchBarButton: typeof TouchBarButton; static TouchBarColorPicker: typeof TouchBarColorPicker; static TouchBarGroup: typeof TouchBarGroup; @@ -3842,6 +4247,23 @@ declare namespace Electron { static TouchBarSpacer: typeof TouchBarSpacer; } + interface Transaction { + + // Docs: http://electron.atom.io/docs/api/structures/transaction + + errorCode: number; + errorMessage: string; + originalTransactionIdentifier: string; + payment: Payment; + transactionDate: string; + transactionIdentifier: string; + /** + * The transaction sate ("purchasing", "purchased", "failed", "restored", or + * "deferred") + */ + transactionState: string; + } + class Tray extends EventEmitter { // Docs: http://electron.atom.io/docs/api/tray @@ -3873,45 +4295,61 @@ declare namespace Electron { */ on(event: 'click', listener: (event: Event, /** - * The bounds of tray icon + * The bounds of tray icon. */ - bounds: Rectangle) => void): this; + bounds: Rectangle, + /** + * The position of the event. + */ + position: Point) => void): this; once(event: 'click', listener: (event: Event, /** - * The bounds of tray icon + * The bounds of tray icon. */ - bounds: Rectangle) => void): this; + bounds: Rectangle, + /** + * The position of the event. + */ + position: Point) => void): this; addListener(event: 'click', listener: (event: Event, /** - * The bounds of tray icon + * The bounds of tray icon. */ - bounds: Rectangle) => void): this; + bounds: Rectangle, + /** + * The position of the event. + */ + position: Point) => void): this; removeListener(event: 'click', listener: (event: Event, /** - * The bounds of tray icon + * The bounds of tray icon. */ - bounds: Rectangle) => void): this; + bounds: Rectangle, + /** + * The position of the event. + */ + position: Point) => void): this; /** * Emitted when the tray icon is double clicked. */ on(event: 'double-click', listener: (event: Event, /** - * The bounds of tray icon + * The bounds of tray icon. */ bounds: Rectangle) => void): this; once(event: 'double-click', listener: (event: Event, /** - * The bounds of tray icon + * The bounds of tray icon. */ bounds: Rectangle) => void): this; addListener(event: 'double-click', listener: (event: Event, /** - * The bounds of tray icon + * The bounds of tray icon. */ bounds: Rectangle) => void): this; removeListener(event: 'double-click', listener: (event: Event, /** - * The bounds of tray icon + * The bounds of tray icon. */ bounds: Rectangle) => void): this; /** @@ -3970,22 +4408,22 @@ declare namespace Electron { */ on(event: 'drop-text', listener: (event: Event, /** - * the dropped text string + * the dropped text string. */ text: string) => void): this; once(event: 'drop-text', listener: (event: Event, /** - * the dropped text string + * the dropped text string. */ text: string) => void): this; addListener(event: 'drop-text', listener: (event: Event, /** - * the dropped text string + * the dropped text string. */ text: string) => void): this; removeListener(event: 'drop-text', listener: (event: Event, /** - * the dropped text string + * the dropped text string. */ text: string) => void): this; /** @@ -3993,22 +4431,22 @@ declare namespace Electron { */ on(event: 'mouse-enter', listener: (event: Event, /** - * The position of the event + * The position of the event. */ position: Point) => void): this; once(event: 'mouse-enter', listener: (event: Event, /** - * The position of the event + * The position of the event. */ position: Point) => void): this; addListener(event: 'mouse-enter', listener: (event: Event, /** - * The position of the event + * The position of the event. */ position: Point) => void): this; removeListener(event: 'mouse-enter', listener: (event: Event, /** - * The position of the event + * The position of the event. */ position: Point) => void): this; /** @@ -4016,22 +4454,45 @@ declare namespace Electron { */ on(event: 'mouse-leave', listener: (event: Event, /** - * The position of the event + * The position of the event. */ position: Point) => void): this; once(event: 'mouse-leave', listener: (event: Event, /** - * The position of the event + * The position of the event. */ position: Point) => void): this; addListener(event: 'mouse-leave', listener: (event: Event, /** - * The position of the event + * The position of the event. */ position: Point) => void): this; removeListener(event: 'mouse-leave', listener: (event: Event, /** - * The position of the event + * The position of the event. + */ + position: Point) => void): this; + /** + * Emitted when the mouse moves in the tray icon. + */ + on(event: 'mouse-move', listener: (event: Event, + /** + * The position of the event. + */ + position: Point) => void): this; + once(event: 'mouse-move', listener: (event: Event, + /** + * The position of the event. + */ + position: Point) => void): this; + addListener(event: 'mouse-move', listener: (event: Event, + /** + * The position of the event. + */ + position: Point) => void): this; + removeListener(event: 'mouse-move', listener: (event: Event, + /** + * The position of the event. */ position: Point) => void): this; /** @@ -4039,22 +4500,22 @@ declare namespace Electron { */ on(event: 'right-click', listener: (event: Event, /** - * The bounds of tray icon + * The bounds of tray icon. */ bounds: Rectangle) => void): this; once(event: 'right-click', listener: (event: Event, /** - * The bounds of tray icon + * The bounds of tray icon. */ bounds: Rectangle) => void): this; addListener(event: 'right-click', listener: (event: Event, /** - * The bounds of tray icon + * The bounds of tray icon. */ bounds: Rectangle) => void): this; removeListener(event: 'right-click', listener: (event: Event, /** - * The bounds of tray icon + * The bounds of tray icon. */ bounds: Rectangle) => void): this; constructor(image: NativeImage | string); @@ -4096,7 +4557,8 @@ declare namespace Electron { */ setPressedImage(image: NativeImage): void; /** - * Sets the title displayed aside of the tray icon in the status bar. + * Sets the title displayed aside of the tray icon in the status bar (Support ANSI + * colors). */ setTitle(title: string): void; /** @@ -4150,7 +4612,7 @@ declare namespace Electron { */ length: number; /** - * Last Modification time in number of seconds sine the UNIX epoch. + * Last Modification time in number of seconds since the UNIX epoch. */ modificationTime: number; /** @@ -4176,7 +4638,7 @@ declare namespace Electron { */ length: number; /** - * Last Modification time in number of seconds sine the UNIX epoch. + * Last Modification time in number of seconds since the UNIX epoch. */ modificationTime: number; /** @@ -4217,22 +4679,22 @@ declare namespace Electron { */ on(event: 'before-input-event', listener: (event: Event, /** - * Input properties + * Input properties. */ input: Input) => void): this; once(event: 'before-input-event', listener: (event: Event, /** - * Input properties + * Input properties. */ input: Input) => void): this; addListener(event: 'before-input-event', listener: (event: Event, /** - * Input properties + * Input properties. */ input: Input) => void): this; removeListener(event: 'before-input-event', listener: (event: Event, /** - * Input properties + * Input properties. */ input: Input) => void): this; /** @@ -4242,7 +4704,7 @@ declare namespace Electron { on(event: 'certificate-error', listener: (event: Event, url: string, /** - * The error code + * The error code. */ error: string, certificate: Certificate, @@ -4250,7 +4712,7 @@ declare namespace Electron { once(event: 'certificate-error', listener: (event: Event, url: string, /** - * The error code + * The error code. */ error: string, certificate: Certificate, @@ -4258,7 +4720,7 @@ declare namespace Electron { addListener(event: 'certificate-error', listener: (event: Event, url: string, /** - * The error code + * The error code. */ error: string, certificate: Certificate, @@ -4266,11 +4728,31 @@ declare namespace Electron { removeListener(event: 'certificate-error', listener: (event: Event, url: string, /** - * The error code + * The error code. */ error: string, certificate: Certificate, callback: (isTrusted: boolean) => void) => void): this; + /** + * Emitted when the associated window logs a console message. Will not be emitted + * for windows with offscreen rendering enabled. + */ + on(event: 'console-message', listener: (level: number, + message: string, + line: number, + sourceId: string) => void): this; + once(event: 'console-message', listener: (level: number, + message: string, + line: number, + sourceId: string) => void): this; + addListener(event: 'console-message', listener: (level: number, + message: string, + line: number, + sourceId: string) => void): this; + removeListener(event: 'console-message', listener: (level: number, + message: string, + line: number, + sourceId: string) => void): this; /** * Emitted when there is a new context menu that needs to be handled. */ @@ -4300,69 +4782,69 @@ declare namespace Electron { * nwse-resize, col-resize, row-resize, m-panning, e-panning, n-panning, * ne-panning, nw-panning, s-panning, se-panning, sw-panning, w-panning, move, * vertical-text, cell, context-menu, alias, progress, nodrop, copy, none, - * not-allowed, zoom-in, zoom-out, grab, grabbing, custom. If the type parameter is - * custom, the image parameter will hold the custom cursor image in a NativeImage, - * and scale, size and hotspot will hold additional information about the custom - * cursor. + * not-allowed, zoom-in, zoom-out, grab, grabbing or custom. If the type parameter + * is custom, the image parameter will hold the custom cursor image in a + * NativeImage, and scale, size and hotspot will hold additional information about + * the custom cursor. */ on(event: 'cursor-changed', listener: (event: Event, type: string, image?: NativeImage, /** - * scaling factor for the custom cursor + * scaling factor for the custom cursor. */ scale?: number, /** - * the size of the `image` + * the size of the `image`. */ size?: Size, /** - * coordinates of the custom cursor's hotspot + * coordinates of the custom cursor's hotspot. */ hotspot?: Point) => void): this; once(event: 'cursor-changed', listener: (event: Event, type: string, image?: NativeImage, /** - * scaling factor for the custom cursor + * scaling factor for the custom cursor. */ scale?: number, /** - * the size of the `image` + * the size of the `image`. */ size?: Size, /** - * coordinates of the custom cursor's hotspot + * coordinates of the custom cursor's hotspot. */ hotspot?: Point) => void): this; addListener(event: 'cursor-changed', listener: (event: Event, type: string, image?: NativeImage, /** - * scaling factor for the custom cursor + * scaling factor for the custom cursor. */ scale?: number, /** - * the size of the `image` + * the size of the `image`. */ size?: Size, /** - * coordinates of the custom cursor's hotspot + * coordinates of the custom cursor's hotspot. */ hotspot?: Point) => void): this; removeListener(event: 'cursor-changed', listener: (event: Event, type: string, image?: NativeImage, /** - * scaling factor for the custom cursor + * scaling factor for the custom cursor. */ scale?: number, /** - * the size of the `image` + * the size of the `image`. */ size?: Size, /** - * coordinates of the custom cursor's hotspot + * coordinates of the custom cursor's hotspot. */ hotspot?: Point) => void): this; /** @@ -4400,14 +4882,53 @@ declare namespace Electron { once(event: 'devtools-reload-page', listener: Function): this; addListener(event: 'devtools-reload-page', listener: Function): this; removeListener(event: 'devtools-reload-page', listener: Function): this; + /** + * Emitted when a has been attached to this web contents. + */ + on(event: 'did-attach-webview', listener: (event: Event, + /** + * The guest web contents that is used by the ``. + */ + webContents: WebContents) => void): this; + once(event: 'did-attach-webview', listener: (event: Event, + /** + * The guest web contents that is used by the ``. + */ + webContents: WebContents) => void): this; + addListener(event: 'did-attach-webview', listener: (event: Event, + /** + * The guest web contents that is used by the ``. + */ + webContents: WebContents) => void): this; + removeListener(event: 'did-attach-webview', listener: (event: Event, + /** + * The guest web contents that is used by the ``. + */ + webContents: WebContents) => void): this; /** * Emitted when a page's theme color changes. This is usually due to encountering a * meta tag: */ - on(event: 'did-change-theme-color', listener: Function): this; - once(event: 'did-change-theme-color', listener: Function): this; - addListener(event: 'did-change-theme-color', listener: Function): this; - removeListener(event: 'did-change-theme-color', listener: Function): this; + on(event: 'did-change-theme-color', listener: (event: Event, + /** + * Theme color is in format of '#rrggbb'. It is `null` when no theme color is set. + */ + color: string | null) => void): this; + once(event: 'did-change-theme-color', listener: (event: Event, + /** + * Theme color is in format of '#rrggbb'. It is `null` when no theme color is set. + */ + color: string | null) => void): this; + addListener(event: 'did-change-theme-color', listener: (event: Event, + /** + * Theme color is in format of '#rrggbb'. It is `null` when no theme color is set. + */ + color: string | null) => void): this; + removeListener(event: 'did-change-theme-color', listener: (event: Event, + /** + * Theme color is in format of '#rrggbb'. It is `null` when no theme color is set. + */ + color: string | null) => void): this; /** * This event is like did-finish-load but emitted when the load failed or was * cancelled, e.g. window.stop() is invoked. The full list of error codes and their @@ -4643,7 +5164,7 @@ declare namespace Electron { */ disposition: ('default' | 'foreground-tab' | 'background-tab' | 'new-window' | 'save-to-disk' | 'other'), /** - * The options which will be used for creating the new `BrowserWindow`. + * The options which will be used for creating the new . */ options: any, /** @@ -4660,7 +5181,7 @@ declare namespace Electron { */ disposition: ('default' | 'foreground-tab' | 'background-tab' | 'new-window' | 'save-to-disk' | 'other'), /** - * The options which will be used for creating the new `BrowserWindow`. + * The options which will be used for creating the new . */ options: any, /** @@ -4677,7 +5198,7 @@ declare namespace Electron { */ disposition: ('default' | 'foreground-tab' | 'background-tab' | 'new-window' | 'save-to-disk' | 'other'), /** - * The options which will be used for creating the new `BrowserWindow`. + * The options which will be used for creating the new . */ options: any, /** @@ -4694,7 +5215,7 @@ declare namespace Electron { */ disposition: ('default' | 'foreground-tab' | 'background-tab' | 'new-window' | 'save-to-disk' | 'other'), /** - * The options which will be used for creating the new `BrowserWindow`. + * The options which will be used for creating the new . */ options: any, /** @@ -4707,22 +5228,22 @@ declare namespace Electron { */ on(event: 'page-favicon-updated', listener: (event: Event, /** - * Array of URLs + * Array of URLs. */ favicons: string[]) => void): this; once(event: 'page-favicon-updated', listener: (event: Event, /** - * Array of URLs + * Array of URLs. */ favicons: string[]) => void): this; addListener(event: 'page-favicon-updated', listener: (event: Event, /** - * Array of URLs + * Array of URLs. */ favicons: string[]) => void): this; removeListener(event: 'page-favicon-updated', listener: (event: Event, /** - * Array of URLs + * Array of URLs. */ favicons: string[]) => void): this; /** @@ -4771,8 +5292,8 @@ declare namespace Electron { /** * Emitted when bluetooth device needs to be selected on call to * navigator.bluetooth.requestDevice. To use navigator.bluetooth api webBluetooth - * should be enabled. If event.preventDefault is not called, first available - * device will be selected. callback should be called with deviceId to be selected, + * should be enabled. If event.preventDefault is not called, first available device + * will be selected. callback should be called with deviceId to be selected, * passing empty string to callback will cancel the request. */ on(event: 'select-bluetooth-device', listener: (event: Event, @@ -4935,13 +5456,13 @@ declare namespace Electron { * called with callback(image). The image is an instance of NativeImage that stores * data of the snapshot. Omitting rect will capture the whole visible page. */ - capturePage(rect: Rectangle, callback: (image: NativeImage) => void): void; + capturePage(callback: (image: NativeImage) => void): void; /** * Captures a snapshot of the page within rect. Upon completion callback will be * called with callback(image). The image is an instance of NativeImage that stores * data of the snapshot. Omitting rect will capture the whole visible page. */ - capturePage(callback: (image: NativeImage) => void): void; + capturePage(rect: Rectangle, callback: (image: NativeImage) => void): void; /** * Clears the navigation history. */ @@ -4988,16 +5509,15 @@ declare namespace Electron { * requestFullScreen can only be invoked by a gesture from the user. Setting * userGesture to true will remove this limitation. If the result of the executed * code is a promise the callback result will be the resolved value of the promise. - * We recommend that you use the returned Promise to handle code that results in a + * We recommend that you use the returned Promise to handle code that results in a * Promise. */ executeJavaScript(code: string, userGesture?: boolean, callback?: (result: any) => void): Promise; /** - * Starts a request to find all matches for the text in the web page and returns an - * Integer representing the request id used for the request. The result of the - * request can be obtained by subscribing to found-in-page event. + * Starts a request to find all matches for the text in the web page. The result of + * the request can be obtained by subscribing to found-in-page event. */ - findInPage(text: string, options?: FindInPageOptions): void; + findInPage(text: string, options?: FindInPageOptions): number; /** * Focuses the web page. */ @@ -5076,6 +5596,12 @@ declare namespace Electron { isOffscreen(): boolean; isPainting(): boolean; isWaitingForResponse(): boolean; + /** + * Loads the given file in the window, filePath should be a path to an HTML file + * relative to the root of your application. For instance an app structure like + * this: Would require code like this + */ + loadFile(filePath: string): void; /** * Loads the url in the window. The url must contain the protocol prefix, e.g. the * http:// or file://. If the load should bypass http cache then use the pragma @@ -5083,7 +5609,9 @@ declare namespace Electron { */ loadURL(url: string, options?: LoadURLOptions): void; /** - * Opens the devtools. + * Opens the devtools. When contents is a tag, the mode would be detach + * by default, explicitly passing an empty mode can force using last used dock + * state. */ openDevTools(options?: OpenDevToolsOptions): void; /** @@ -5101,7 +5629,7 @@ declare namespace Electron { * webContents.print({silent: false, printBackground: false, deviceName: ''}). Use * page-break-before: always; CSS style to force to print to a new page. */ - print(options?: PrintOptions): void; + print(options?: PrintOptions, callback?: (success: boolean) => void): void; /** * Prints window's web page as PDF with Chromium's preview printing custom * settings. The callback will be called with callback(error, data) on completion. @@ -5160,6 +5688,19 @@ declare namespace Electron { * Mute the audio on the current web page. */ setAudioMuted(muted: boolean): void; + /** + * Uses the devToolsWebContents as the target WebContents to show devtools. The + * devToolsWebContents must not have done any navigation, and it should not be used + * for other purposes after the call. By default Electron manages the devtools by + * creating an internal WebContents with native view, which developers have very + * limited control of. With the setDevToolsWebContents method, developers can use + * any WebContents to show the devtools in it, including BrowserWindow, BrowserView + * and tag. Note that closing the devtools does not destroy the + * devToolsWebContents, it is caller's responsibility to destroy + * devToolsWebContents. An example of showing devtools in a tag: An + * example of showing devtools in a BrowserWindow: + */ + setDevToolsWebContents(devToolsWebContents: WebContents): void; /** * If offscreen rendering is enabled sets the frame rate to the specified number. * Only values between 1 and 60 are accepted. @@ -5187,7 +5728,7 @@ declare namespace Electron { setVisualZoomLevelLimits(minimumLevel: number, maximumLevel: number): void; /** * Setting the WebRTC IP handling policy allows you to control which IPs are - * exposed via WebRTC. See BrowserLeaks for more details. + * exposed via WebRTC. See BrowserLeaks for more details. */ setWebRTCIPHandlingPolicy(policy: 'default' | 'default_public_interface_only' | 'default_public_and_private_interfaces' | 'disable_non_proxied_udp'): void; /** @@ -5198,14 +5739,10 @@ declare namespace Electron { /** * Changes the zoom level to the specified level. The original size is 0 and each * increment above or below represents zooming 20% larger or smaller to default - * limits of 300% and 50% of original size, respectively. + * limits of 300% and 50% of original size, respectively. The formula for this is + * scale := 1.2 ^ level. */ setZoomLevel(level: number): void; - /** - * Deprecated: Call setVisualZoomLevelLimits instead to set the visual zoom level - * limits. This method will be removed in Electron 2.0. - */ - setZoomLevelLimits(minimumLevel: number, maximumLevel: number): void; /** * Shows pop-up dictionary that searches the selected word on the page. */ @@ -5276,6 +5813,10 @@ declare namespace Electron { * userGesture to true will remove this limitation. */ executeJavaScript(code: string, userGesture?: boolean, callback?: (result: any) => void): Promise; + /** + * Work like executeJavaScript but evaluates scripts in isolated context. + */ + executeJavaScriptInIsolatedWorld(worldId: number, scripts: WebSource[], userGesture?: boolean, callback?: (result: any) => void): void; /** * Returns an object describing usage information of Blink's internal memory * caches. This will generate: @@ -5305,6 +5846,18 @@ declare namespace Electron { * cannot be corrupted by active network attackers. */ registerURLSchemeAsSecure(scheme: string): void; + /** + * Set the content security policy of the isolated world. + */ + setIsolatedWorldContentSecurityPolicy(worldId: number, csp: string): void; + /** + * Set the name of the isolated world. Useful in devtools. + */ + setIsolatedWorldHumanReadableName(worldId: number, name: string): void; + /** + * Set the security origin of the isolated world. + */ + setIsolatedWorldSecurityOrigin(worldId: number, securityOrigin: string): void; /** * Sets the maximum and minimum layout-based (i.e. non-visual) zoom level. */ @@ -5330,22 +5883,28 @@ declare namespace Electron { * limits of 300% and 50% of original size, respectively. */ setZoomLevel(level: number): void; - /** - * Deprecated: Call setVisualZoomLevelLimits instead to set the visual zoom level - * limits. This method will be removed in Electron 2.0. - */ - setZoomLevelLimits(minimumLevel: number, maximumLevel: number): void; } class WebRequest extends EventEmitter { // Docs: http://electron.atom.io/docs/api/web-request + /** + * The listener will be called with listener(details) when a server initiated + * redirect is about to occur. + */ + onBeforeRedirect(listener: (details: OnBeforeRedirectDetails) => void): void; /** * The listener will be called with listener(details) when a server initiated * redirect is about to occur. */ onBeforeRedirect(filter: OnBeforeRedirectFilter, listener: (details: OnBeforeRedirectDetails) => void): void; + /** + * The listener will be called with listener(details, callback) when a request is + * about to occur. The uploadData is an array of UploadData objects. The callback + * has to be called with an response object. + */ + onBeforeRequest(listener: (details: OnBeforeRequestDetails, callback: (response: Response) => void) => void): void; /** * The listener will be called with listener(details, callback) when a request is * about to occur. The uploadData is an array of UploadData objects. The callback @@ -5359,10 +5918,25 @@ declare namespace Electron { * has to be called with an response object. */ onBeforeSendHeaders(filter: OnBeforeSendHeadersFilter, listener: Function): void; + /** + * The listener will be called with listener(details, callback) before sending an + * HTTP request, once the request headers are available. This may occur after a TCP + * connection is made to the server, but before any http data is sent. The callback + * has to be called with an response object. + */ + onBeforeSendHeaders(listener: Function): void; /** * The listener will be called with listener(details) when a request is completed. */ onCompleted(filter: OnCompletedFilter, listener: (details: OnCompletedDetails) => void): void; + /** + * The listener will be called with listener(details) when a request is completed. + */ + onCompleted(listener: (details: OnCompletedDetails) => void): void; + /** + * The listener will be called with listener(details) when an error occurs. + */ + onErrorOccurred(listener: (details: OnErrorOccurredDetails) => void): void; /** * The listener will be called with listener(details) when an error occurs. */ @@ -5373,6 +5947,18 @@ declare namespace Electron { * response object. */ onHeadersReceived(filter: OnHeadersReceivedFilter, listener: Function): void; + /** + * The listener will be called with listener(details, callback) when HTTP response + * headers of a request have been received. The callback has to be called with an + * response object. + */ + onHeadersReceived(listener: Function): void; + /** + * The listener will be called with listener(details) when first byte of the + * response body is received. For HTTP requests, this means that the status line + * and response headers are available. + */ + onResponseStarted(listener: (details: OnResponseStartedDetails) => void): void; /** * The listener will be called with listener(details) when first byte of the * response body is received. For HTTP requests, this means that the status line @@ -5385,6 +5971,24 @@ declare namespace Electron { * response are visible by the time this listener is fired. */ onSendHeaders(filter: OnSendHeadersFilter, listener: (details: OnSendHeadersDetails) => void): void; + /** + * The listener will be called with listener(details) just before a request is + * going to be sent to the server, modifications of previous onBeforeSendHeaders + * response are visible by the time this listener is fired. + */ + onSendHeaders(listener: (details: OnSendHeadersDetails) => void): void; + } + + interface WebSource { + + // Docs: http://electron.atom.io/docs/api/structures/web-source + + code: string; + /** + * Default is 1. + */ + startLine?: number; + url?: string; } interface WebviewTag extends HTMLElement { @@ -5575,6 +6179,10 @@ declare namespace Electron { */ addEventListener(event: 'devtools-focused', listener: (event: Event) => void, useCapture?: boolean): this; removeEventListener(event: 'devtools-focused', listener: (event: Event) => void): this; + addEventListener(type: K, listener: (this: HTMLElement, ev: HTMLElementEventMap[K]) => any, useCapture?: boolean): void; + addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; + removeEventListener(type: K, listener: (this: HTMLElement, ev: HTMLElementEventMap[K]) => any, useCapture?: boolean): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; canGoBack(): boolean; canGoForward(): boolean; canGoToOffset(offset: number): boolean; @@ -5613,13 +6221,12 @@ declare namespace Electron { * context in the page. HTML APIs like requestFullScreen, which require user * action, can take advantage of this option for automation. */ - executeJavaScript(code: string, userGesture: boolean, callback?: (result: any) => void): void; + executeJavaScript(code: string, userGesture?: boolean, callback?: (result: any) => void): void; /** - * Starts a request to find all matches for the text in the web page and returns an - * Integer representing the request id used for the request. The result of the - * request can be obtained by subscribing to found-in-page event. + * Starts a request to find all matches for the text in the web page. The result of + * the request can be obtained by subscribing to found-in-page event. */ - findInPage(text: string, options?: FindInPageOptions): void; + findInPage(text: string, options?: FindInPageOptions): number; getTitle(): string; getURL(): string; getUserAgent(): string; @@ -6062,6 +6669,10 @@ declare namespace Electron { * is true. */ fullscreenable?: boolean; + /** + * Use pre-Lion fullscreen on macOS. Default is false. + */ + simpleFullscreen?: boolean; /** * Whether to show the window in taskbar. Default is false. */ @@ -6115,7 +6726,7 @@ declare namespace Electron { */ enableLargerThanScreen?: boolean; /** - * Window's background color as Hexadecimal value, like #66CD00 or #FFF or + * Window's background color as a hexadecimal value, like #66CD00 or #FFF or * #80FFFFFF (alpha is supported). Default is #FFF (white). */ backgroundColor?: string; @@ -6124,6 +6735,11 @@ declare namespace Electron { * is true. */ hasShadow?: boolean; + /** + * Set the initial opacity of the window, between 0.0 (fully transparent) and 1.0 + * (fully opaque). This is only implemented on Windows and macOS. + */ + opacity?: number; /** * Forces using dark theme for the window, only works on some GTK+3 desktop * environments. Default is false. @@ -6140,9 +6756,9 @@ declare namespace Electron { /** * The style of window title bar. Default is default. Possible values are: */ - titleBarStyle?: ('default' | 'hidden' | 'hidden-inset' | 'hiddenInset' | 'customButtonsOnHover'); + titleBarStyle?: ('default' | 'hidden' | 'hiddenInset' | 'customButtonsOnHover'); /** - * Shows the title in the tile bar in full screen mode on macOS for all + * Shows the title in the title bar in full screen mode on macOS for all * titleBarStyle options. Default is false. */ fullscreenWindowTitle?: boolean; @@ -6155,7 +6771,8 @@ declare namespace Electron { /** * Add a type of vibrancy effect to the window, only on macOS. Can be * appearance-based, light, dark, titlebar, selection, menu, popover, sidebar, - * medium-light or ultra-dark. + * medium-light or ultra-dark. Please note that using frame: false in combination + * with a vibrancy value requires that you use a non-default titleBarStyle as well. */ vibrancy?: ('appearance-based' | 'light' | 'dark' | 'titlebar' | 'selection' | 'menu' | 'popover' | 'sidebar' | 'medium-light' | 'ultra-dark'); /** @@ -6196,7 +6813,11 @@ declare namespace Electron { /** * Verification result from chromium. */ - error: string; + verificationResult: string; + /** + * Error code. + */ + errorCode: number; } interface ClearStorageDataOptions { @@ -6206,7 +6827,7 @@ declare namespace Electron { origin?: string; /** * The types of storages to clear, can contain: appcache, cookies, filesystem, - * indexdb, localstorage, shadercache, websql, serviceworkers + * indexdb, localstorage, shadercache, websql, serviceworkers. */ storages?: string[]; /** @@ -6253,11 +6874,11 @@ declare namespace Electron { interface ContextMenuParams { /** - * x coordinate + * x coordinate. */ x: number; /** - * y coordinate + * y coordinate. */ y: number; /** @@ -6317,8 +6938,8 @@ declare namespace Electron { */ inputFieldType: string; /** - * Input source that invoked the context menu. Can be none, mouse, keyboard, touch, - * touchMenu. + * Input source that invoked the context menu. Can be none, mouse, keyboard, touch + * or touchMenu. */ menuSourceType: ('none' | 'mouse' | 'keyboard' | 'touch' | 'touchMenu'); /** @@ -6355,9 +6976,10 @@ declare namespace Electron { * properties are sent correctly. Nested objects are not supported and the property * names and values must be less than 64 characters long. */ - extra?: any; + extra?: Extra; /** - * Only used when the crash reporter is used in a forked process (macOS only). + * Directory to store the crashreports temporarily (only used when the crash + * reporter is started via process.crashReporter.start). */ crashesDirectory?: string; } @@ -6502,9 +7124,12 @@ declare namespace Electron { } interface DisplayBalloonOptions { + /** + * - + */ icon?: NativeImage | string; - title?: string; - content?: string; + title: string; + content: string; } interface Dock { @@ -6569,6 +7194,18 @@ declare namespace Electron { interface Extensions { } + interface FeedURLOptions { + url: string; + /** + * HTTP request headers. + */ + headers?: Headers; + /** + * Either json or default, see the README for more information. + */ + serverType?: string; + } + interface FileIconOptions { size: ('small' | 'normal' | 'large'); } @@ -6584,7 +7221,7 @@ declare namespace Electron { */ name?: string; /** - * Retrieves cookies whose domains match or are subdomains of domains + * Retrieves cookies whose domains match or are subdomains of domains. */ domain?: string; /** @@ -6644,6 +7281,18 @@ declare namespace Electron { name: string; } + interface Headers { + } + + interface IgnoreMouseEventsOptions { + /** + * If true, forwards mouse move messages to Chromium, enabling mouse related events + * such as mouseleave. Only used when ignore is true. If ignore is false, + * forwarding is always disabled regardless of this value. + */ + forward?: boolean; + } + interface ImportCertificateOptions { /** * Path for the pkcs12 file. @@ -6657,35 +7306,35 @@ declare namespace Electron { interface Input { /** - * Either keyUp or keyDown + * Either keyUp or keyDown. */ type: string; /** - * Equivalent to + * Equivalent to . */ key: string; /** - * Equivalent to + * Equivalent to . */ code: string; /** - * Equivalent to + * Equivalent to . */ isAutoRepeat: boolean; /** - * Equivalent to + * Equivalent to . */ shift: boolean; /** - * Equivalent to + * Equivalent to . */ control: boolean; /** - * Equivalent to + * Equivalent to . */ alt: boolean; /** - * Equivalent to + * Equivalent to . */ meta: boolean; } @@ -6711,6 +7360,14 @@ declare namespace Electron { uploadData: UploadData[]; } + interface InterceptStreamProtocolRequest { + url: string; + headers: Headers; + referrer: string; + method: string; + uploadData: UploadData[]; + } + interface InterceptStringProtocolRequest { url: string; referrer: string; @@ -6767,6 +7424,9 @@ declare namespace Electron { * Extra headers separated by "\n" */ extraHeaders?: string; + /** + * - + */ postData?: UploadRawData[] | UploadFile[] | UploadFileSystem[] | UploadBlob[]; /** * Base url (with trailing path separator) for files to be loaded by the data url. @@ -6783,25 +7443,25 @@ declare namespace Electron { */ openAtLogin: boolean; /** - * true if the app is set to open as hidden at login. This setting is only - * supported on macOS. + * true if the app is set to open as hidden at login. This setting is not available + * on . */ openAsHidden: boolean; /** - * true if the app was opened at login automatically. This setting is only - * supported on macOS. + * true if the app was opened at login automatically. This setting is not available + * on . */ wasOpenedAtLogin: boolean; /** * true if the app was opened as a hidden login item. This indicates that the app - * should not open any windows at startup. This setting is only supported on macOS. + * should not open any windows at startup. This setting is not available on . */ wasOpenedAsHidden: boolean; /** * true if the app was opened as a login item that should restore the state from * the previous session. This indicates that the app should restore the windows - * that were open the last time the app was closed. This setting is only supported - * on macOS. + * that were open the last time the app was closed. This setting is not available + * on . */ restoreState: boolean; } @@ -6827,7 +7487,7 @@ declare namespace Electron { * Define the action of the menu item, when specified the click property will be * ignored. See . */ - role?: MenuItemRole; + role?: string; /** * Can be normal, separator, submenu, checkbox or radio. */ @@ -6850,7 +7510,7 @@ declare namespace Electron { checked?: boolean; /** * Should be specified for submenu type menu items. If submenu is specified, the - * type: 'submenu' can be omitted. If the value is not a Menu then it will be + * type: 'submenu' can be omitted. If the value is not a then it will be * automatically converted to one using Menu.buildFromTemplate. */ submenu?: MenuItemConstructorOptions[] | Menu; @@ -6940,7 +7600,7 @@ declare namespace Electron { */ disposition: ('default' | 'foreground-tab' | 'background-tab' | 'new-window' | 'save-to-disk' | 'other'); /** - * The options which should be used for creating the new `BrowserWindow`. + * The options which should be used for creating the new . */ options: Options; } @@ -6948,7 +7608,7 @@ declare namespace Electron { interface NotificationConstructorOptions { /** * A title for the notification, which will be shown at the top of the notification - * window when it is shown + * window when it is shown. */ title: string; /** @@ -6957,17 +7617,17 @@ declare namespace Electron { subtitle?: string; /** * The body text of the notification, which will be displayed below the title or - * subtitle + * subtitle. */ body: string; /** - * Whether or not to emit an OS notification noise when showing the notification + * Whether or not to emit an OS notification noise when showing the notification. */ silent?: boolean; /** - * An icon to use in the notification + * An icon to use in the notification. */ - icon?: NativeImage; + icon?: string | NativeImage; /** * Whether or not to add an inline reply option to the notification. */ @@ -6982,15 +7642,21 @@ declare namespace Electron { sound?: string; /** * Actions to add to the notification. Please read the available actions and - * limitations in the NotificationAction documentation + * limitations in the NotificationAction documentation. */ actions?: NotificationAction[]; + /** + * A custom title for the close button of an alert. An empty string will cause the + * default localized text to be used. + */ + closeButtonText?: string; } interface OnBeforeRedirectDetails { - id: string; + id: number; url: string; method: string; + webContentsId?: number; resourceType: string; timestamp: number; redirectURL: string; @@ -7015,6 +7681,7 @@ declare namespace Electron { id: number; url: string; method: string; + webContentsId?: number; resourceType: string; timestamp: number; uploadData: UploadData[]; @@ -7040,6 +7707,7 @@ declare namespace Electron { id: number; url: string; method: string; + webContentsId?: number; resourceType: string; timestamp: number; responseHeaders: ResponseHeaders; @@ -7060,6 +7728,7 @@ declare namespace Electron { id: number; url: string; method: string; + webContentsId?: number; resourceType: string; timestamp: number; fromCache: boolean; @@ -7089,6 +7758,7 @@ declare namespace Electron { id: number; url: string; method: string; + webContentsId?: number; resourceType: string; timestamp: number; responseHeaders: ResponseHeaders; @@ -7112,6 +7782,7 @@ declare namespace Electron { id: number; url: string; method: string; + webContentsId?: number; resourceType: string; timestamp: number; requestHeaders: RequestHeaders; @@ -7152,6 +7823,10 @@ declare namespace Electron { * Message to display above input boxes. */ message?: string; + /** + * Create when packaged for the Mac App Store. + */ + securityScopedBookmarks?: boolean; } interface OpenExternalOptions { @@ -7175,50 +7850,56 @@ declare namespace Electron { interface Parameters { /** - * Specify the screen type to emulate (default: desktop) + * Specify the screen type to emulate (default: desktop): */ screenPosition: ('desktop' | 'mobile'); /** - * Set the emulated screen size (screenPosition == mobile) + * Set the emulated screen size (screenPosition == mobile). */ screenSize: Size; /** * Position the view on the screen (screenPosition == mobile) (default: {x: 0, y: - * 0}) + * 0}). */ viewPosition: Point; /** * Set the device scale factor (if zero defaults to original device scale factor) - * (default: 0) + * (default: 0). */ deviceScaleFactor: number; /** * Set the emulated view size (empty means no override) */ viewSize: Size; - /** - * Whether emulated view should be scaled down if necessary to fit into available - * space (default: false) - */ - fitToView: boolean; - /** - * Offset of the emulated view inside available space (not in fit to view mode) - * (default: {x: 0, y: 0}) - */ - offset: Point; /** * Scale of emulated view inside available space (not in fit to view mode) - * (default: 1) + * (default: 1). */ scale: number; } + interface Payment { + productIdentifier: string; + quantity: number; + } + + interface PermissionRequestHandlerDetails { + /** + * The url of the openExternal request. + */ + externalURL: string; + } + interface PluginCrashedEvent extends Event { name: string; version: string; } interface PopupOptions { + /** + * Default is the focused window. + */ + window?: BrowserWindow; /** * Default is the current mouse cursor position. Must be declared if y is declared. */ @@ -7227,16 +7908,15 @@ declare namespace Electron { * Default is the current mouse cursor position. Must be declared if x is declared. */ y?: number; - /** - * Set to true to have this method return immediately called, false to return after - * the menu has been selected or closed. Defaults to false. - */ - async?: boolean; /** * The index of the menu item to be positioned under the mouse cursor at the * specified coordinates. Default is -1. */ positioningItem?: number; + /** + * Called when menu is closed. + */ + callback?: () => void; } interface PrintOptions { @@ -7295,21 +7975,21 @@ declare namespace Electron { privateBytes: number; /** * The amount of memory shared between processes, typically memory consumed by the - * Electron code itself + * Electron code itself. */ sharedBytes: number; } interface ProgressBarOptions { /** - * Mode for the progress bar. Can be none, normal, indeterminate, error, or paused. + * Mode for the progress bar. Can be none, normal, indeterminate, error or paused. */ - mode: ('none' | 'normal' | 'indeterminate' | 'error'); + mode: ('none' | 'normal' | 'indeterminate' | 'error' | 'paused'); } interface Provider { /** - * Returns Boolean + * Returns Boolean. */ spellCheck: (text: string) => void; } @@ -7354,6 +8034,14 @@ declare namespace Electron { secure?: boolean; } + interface RegisterStreamProtocolRequest { + url: string; + headers: Headers; + referrer: string; + method: string; + uploadData: UploadData[]; + } + interface RegisterStringProtocolRequest { url: string; referrer: string; @@ -7401,7 +8089,7 @@ declare namespace Electron { */ width?: number; /** - * Defaults to the image's height + * Defaults to the image's height. */ height?: number; /** @@ -7472,6 +8160,11 @@ declare namespace Electron { * Show the tags input box, defaults to true. */ showsTagField?: boolean; + /** + * Create a when packaged for the Mac App Store. If this option is enabled and the + * file doesn't already exist a blank file will be created at the chosen path. + */ + securityScopedBookmarks?: boolean; } interface Settings { @@ -7484,7 +8177,7 @@ declare namespace Electron { * true to open the app as hidden. Defaults to false. The user can edit this * setting from the System Preferences so * app.getLoginItemStatus().wasOpenedAsHidden should be checked when the app is - * opened to know the current value. This setting is only supported on macOS. + * opened to know the current value. This setting is not available on . */ openAsHidden?: boolean; /** @@ -7499,11 +8192,26 @@ declare namespace Electron { } interface SizeOptions { + /** + * true to make the webview container automatically resize within the bounds + * specified by the attributes normal, min and max. + */ + enableAutoSize?: boolean; /** * Normal size of the page. This can be used in combination with the attribute to * manually resize the webview guest contents. */ - normal?: Normal; + normal?: Size; + /** + * Minimum size of the page. This can be used in combination with the attribute to + * manually resize the webview guest contents. + */ + min?: Size; + /** + * Maximium size of the page. This can be used in combination with the attribute to + * manually resize the webview guest contents. + */ + max?: Size; } interface SourcesOptions { @@ -7585,7 +8293,7 @@ declare namespace Electron { /** * Can be left, right or overlay. */ - iconPosition: ('left' | 'right' | 'overlay'); + iconPosition?: ('left' | 'right' | 'overlay'); /** * Function to call when the button is clicked. */ @@ -7608,8 +8316,8 @@ declare namespace Electron { } interface TouchBarConstructorOptions { - items: (TouchBarButton | TouchBarColorPicker | TouchBarGroup | TouchBarLabel | TouchBarPopover | TouchBarScrubber | TouchBarSegmentedControl | TouchBarSlider | TouchBarSpacer)[]; - escapeItem?: TouchBarButton | TouchBarColorPicker | TouchBarGroup | TouchBarLabel | TouchBarPopover | TouchBarScrubber | TouchBarSegmentedControl | TouchBarSlider | TouchBarSpacer; + items: Array; + escapeItem?: TouchBarButton | TouchBarColorPicker | TouchBarGroup | TouchBarLabel | TouchBarPopover | TouchBarScrubber | TouchBarSegmentedControl | TouchBarSlider | TouchBarSpacer | null; } interface TouchBarGroupConstructorOptions { @@ -7652,15 +8360,15 @@ declare namespace Electron { interface TouchBarScrubberConstructorOptions { /** - * An array of items to place in this scrubber + * An array of items to place in this scrubber. */ items: ScrubberItem[]; /** - * Called when the user taps an item that was not the last tapped item + * Called when the user taps an item that was not the last tapped item. */ select: (selectedIndex: number) => void; /** - * Called when the user taps any item + * Called when the user taps any item. */ highlight: (highlightedIndex: number) => void; /** @@ -7704,7 +8412,7 @@ declare namespace Electron { */ selectedIndex?: number; /** - * Called when the user selects a new segment + * Called when the user selects a new segment. */ change: (selectedIndex: number, isSelected: boolean) => void; } @@ -7809,9 +8517,6 @@ declare namespace Electron { finalUpdate: boolean; } - interface Headers { - } - interface MediaFlags { /** * Whether the media element has crashed. @@ -7847,11 +8552,6 @@ declare namespace Electron { canRotate: boolean; } - interface Normal { - width: number; - height: number; - } - interface Options { } @@ -7911,6 +8611,15 @@ declare namespace Electron { * session. */ partition?: string; + /** + * When specified, web pages with the same affinity will run in the same renderer + * process. Note that due to reusing the renderer process, certain webPreferences + * options will also be shared between the web pages even when you specified + * different values for them, including but not limited to preload, sandbox and + * nodeIntegration. So it is suggested to use exact same webPreferences for web + * pages with the same affinity. + */ + affinity?: string; /** * The default zoom factor of the page, 3.0 represents 300%. Default is 1.0. */ @@ -7994,7 +8703,7 @@ declare namespace Electron { defaultEncoding?: string; /** * Whether to throttle animations and timers when the page becomes background. This - * also affects the [Page Visibility API][#page-visibility]. Defaults to true. + * also affects the . Defaults to true. */ backgroundThrottling?: boolean; /** @@ -8031,6 +8740,12 @@ declare namespace Electron { * alter the 's initial settings. */ webviewTag?: boolean; + /** + * A list of strings that will be appended to process.argv in the renderer process + * of this app. Useful for passing small bits of data down to renderer process + * preload scripts. + */ + additionArguments?: string[]; } interface DefaultFontFamily { @@ -8108,6 +8823,7 @@ declare namespace NodeJS { // Docs: http://electron.atom.io/docs/api/process + // ### BEGIN VSCODE MODIFICATION ### // /** // * Emitted when Electron has loaded its internal initialization script and is // * beginning to load the web page or the main script. It can be used by the preload @@ -8118,6 +8834,8 @@ declare namespace NodeJS { // once(event: 'loaded', listener: Function): this; // addListener(event: 'loaded', listener: Function): this; // removeListener(event: 'loaded', listener: Function): this; + // ### END VSCODE MODIFICATION ### + /** * Causes the main thread of the current process crash. */ @@ -8160,8 +8878,8 @@ declare namespace NodeJS { noAsar?: boolean; /** * A Boolean that controls whether or not deprecation warnings are printed to - * stderr. Setting this to true will silence deprecation warnings. This property - * is used instead of the --no-deprecation command line flag. + * stderr. Setting this to true will silence deprecation warnings. This property is + * used instead of the --no-deprecation command line flag. */ noDeprecation?: boolean; /** @@ -8170,21 +8888,21 @@ declare namespace NodeJS { resourcesPath?: string; /** * A Boolean that controls whether or not deprecation warnings will be thrown as - * exceptions. Setting this to true will throw errors for deprecations. This + * exceptions. Setting this to true will throw errors for deprecations. This * property is used instead of the --throw-deprecation command line flag. */ throwDeprecation?: boolean; /** * A Boolean that controls whether or not deprecations printed to stderr include - * their stack trace. Setting this to true will print stack traces for + * their stack trace. Setting this to true will print stack traces for * deprecations. This property is instead of the --trace-deprecation command line * flag. */ traceDeprecation?: boolean; /** * A Boolean that controls whether or not process warnings printed to stderr - * include their stack trace. Setting this to true will print stack traces for - * process warnings (including deprecations). This property is instead of the + * include their stack trace. Setting this to true will print stack traces for + * process warnings (including deprecations). This property is instead of the * --trace-warnings command line flag. */ traceProcessWarnings?: boolean; diff --git a/src/typings/node.d.ts b/src/typings/node.d.ts index 1b6661edd71..b8e246d1ecf 100644 --- a/src/typings/node.d.ts +++ b/src/typings/node.d.ts @@ -1,41 +1,67 @@ -// Type definitions for Node.js v7.x +// Type definitions for Node.js 8.9.x // Project: http://nodejs.org/ // Definitions by: Microsoft TypeScript // DefinitelyTyped // Parambir Singh -// Roberto Desideri // Christian Vaagland Tellnes // Wilco Bakker -// Daniel Imms +// Nicolas Voigt +// Chigozirim C. +// Flarna +// Mariusz Wiktorczyk +// wwwy3y3 +// Deividas Bakanas +// Kelvin Jin +// Alvis HT Tang +// Sebastian Silbermann +// Hannes Magnusson +// Alberto Schiabel +// Huw +// Nicolas Even +// Bruno Scheufler +// Hoàng Văn Khải +// Lishude +// Andrew Makarov // Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped +// TypeScript Version: 2.1 -/************************************************ -* * -* Node.js v7.x API * -* * -************************************************/ +// ### BEGIN VSCODE MODIFICATION ### +// /** inspector module types */ +// /// +// ### BEGIN VSCODE MODIFICATION ### // This needs to be global to avoid TS2403 in case lib.dom.d.ts is present in the same build interface Console { - Console: NodeJS.ConsoleConstructor; - assert(value: any, message?: string, ...optionalParams: any[]): void; - dir(obj: any, options?: NodeJS.InspectOptions): void; - error(message?: any, ...optionalParams: any[]): void; - info(message?: any, ...optionalParams: any[]): void; - log(message?: any, ...optionalParams: any[]): void; - time(label: string): void; - timeEnd(label: string): void; - trace(message?: any, ...optionalParams: any[]): void; - warn(message?: any, ...optionalParams: any[]): void; + Console: NodeJS.ConsoleConstructor; + assert(value: any, message?: string, ...optionalParams: any[]): void; + dir(obj: any, options?: NodeJS.InspectOptions): void; + debug(message?: any, ...optionalParams: any[]): void; + error(message?: any, ...optionalParams: any[]): void; + info(message?: any, ...optionalParams: any[]): void; + log(message?: any, ...optionalParams: any[]): void; + time(label: string): void; + timeEnd(label: string): void; + trace(message?: any, ...optionalParams: any[]): void; + warn(message?: any, ...optionalParams: any[]): void; } interface Error { - stack?: string; + stack?: string; } +// Declare "static" methods in Error interface ErrorConstructor { - captureStackTrace(targetObject: Object, constructorOpt?: Function): void; - stackTraceLimit: number; + /** Create .stack property on a target object */ + captureStackTrace(targetObject: Object, constructorOpt?: Function): void; + + /** + * Optional override for formatting stack traces + * + * @see https://github.com/v8/v8/wiki/Stack%20Trace%20API#customizing-stack-traces + */ + prepareStackTrace?: (err: Error, stackTraces: NodeJS.CallSite[]) => any; + + stackTraceLimit: number; } // compat for TypeScript 1.8 @@ -49,55 +75,90 @@ interface WeakSetConstructor { } // Forward-declare needed types from lib.es2015.d.ts (in case users are using `--lib es5`) interface Iterable { } interface Iterator { - next(value?: any): IteratorResult; + next(value?: any): IteratorResult; } interface IteratorResult { } interface SymbolConstructor { - readonly iterator: symbol; + readonly iterator: symbol; } declare var Symbol: SymbolConstructor; +// Node.js ESNEXT support +interface String { + /** Removes whitespace from the left end of a string. */ + trimLeft(): string; + /** Removes whitespace from the right end of a string. */ + trimRight(): string; +} + /************************************************ * * * GLOBAL * * * ************************************************/ declare var process: NodeJS.Process; -declare var global: any; +declare var global: NodeJS.Global; declare var console: Console; -// Don't use these!! :) +// ### BEGIN VSCODE MODIFICATION ### // declare var __filename: string; // declare var __dirname: string; // declare function setTimeout(callback: (...args: any[]) => void, ms: number, ...args: any[]): NodeJS.Timer; +// declare namespace setTimeout { +// export function __promisify__(ms: number): Promise; +// export function __promisify__(ms: number, value: T): Promise; +// } // declare function clearTimeout(timeoutId: NodeJS.Timer): void; // declare function setInterval(callback: (...args: any[]) => void, ms: number, ...args: any[]): NodeJS.Timer; // declare function clearInterval(intervalId: NodeJS.Timer): void; +// ### END VSCODE MODIFICATION ### + declare function setImmediate(callback: (...args: any[]) => void, ...args: any[]): any; +declare namespace setImmediate { + export function __promisify__(): Promise; + export function __promisify__(value: T): Promise; +} declare function clearImmediate(immediateId: any): void; +// TODO: change to `type NodeRequireFunction = (id: string) => any;` in next mayor version. interface NodeRequireFunction { - (id: string): any; + /* tslint:disable-next-line:callable-types */ + (id: string): any; } +// ### BEGIN VSCODE MODIFICATION ### // interface NodeRequire extends NodeRequireFunction { -// resolve(id: string): string; +// resolve: RequireResolve; // cache: any; -// extensions: any; +// extensions: NodeExtensions; // main: NodeModule | undefined; // } +// interface RequireResolve { +// (id: string, options?: { paths?: string[]; }): string; +// paths(request: string): string[] | null; +// } + +// interface NodeExtensions { +// '.js': (m: NodeModule, filename: string) => any; +// '.json': (m: NodeModule, filename: string) => any; +// '.node': (m: NodeModule, filename: string) => any; +// [ext: string]: (m: NodeModule, filename: string) => any; +// } + // declare var require: NodeRequire; +// ### END VSCODE MODIFICATION ### interface NodeModule { - exports: any; - require: NodeRequireFunction; - id: string; - filename: string; - loaded: boolean; - parent: NodeModule | null; - children: NodeModule[]; + exports: any; + require: NodeRequireFunction; + id: string; + filename: string; + loaded: boolean; + parent: NodeModule | null; + children: NodeModule[]; + paths: string[]; } declare var module: NodeModule; @@ -105,17 +166,16 @@ declare var module: NodeModule; // Same as module.exports declare var exports: any; declare var SlowBuffer: { - new(str: string, encoding?: string): Buffer; - new(size: number): Buffer; - new(size: Uint8Array): Buffer; - new(array: any[]): Buffer; - prototype: Buffer; - isBuffer(obj: any): boolean; - byteLength(string: string, encoding?: string): number; - concat(list: Buffer[], totalLength?: number): Buffer; + new(str: string, encoding?: string): Buffer; + new(size: number): Buffer; + new(size: Uint8Array): Buffer; + new(array: any[]): Buffer; + prototype: Buffer; + isBuffer(obj: any): boolean; + byteLength(string: string, encoding?: string): number; + concat(list: Buffer[], totalLength?: number): Buffer; }; - // Buffer class type BufferEncoding = "ascii" | "utf8" | "utf16le" | "ucs2" | "base64" | "latin1" | "binary" | "hex"; interface Buffer extends NodeBuffer { } @@ -132,19 +192,19 @@ declare var Buffer: { * @param str String to store in buffer. * @param encoding encoding to use, optional. Default is 'utf8' */ - new(str: string, encoding?: string): Buffer; + new(str: string, encoding?: string): Buffer; /** * Allocates a new buffer of {size} octets. * * @param size count of octets to allocate. */ - new(size: number): Buffer; + new(size: number): Buffer; /** * Allocates a new buffer containing the given {array} of octets. * * @param array The octets to store. */ - new(array: Uint8Array): Buffer; + new(array: Uint8Array): Buffer; /** * Produces a Buffer backed by the same allocated memory as * the given {ArrayBuffer}. @@ -152,26 +212,20 @@ declare var Buffer: { * * @param arrayBuffer The ArrayBuffer with which to share memory. */ - new(arrayBuffer: ArrayBuffer): Buffer; + new(arrayBuffer: ArrayBuffer): Buffer; /** * Allocates a new buffer containing the given {array} of octets. * * @param array The octets to store. */ - new(array: any[]): Buffer; + new(array: any[]): Buffer; /** * Copies the passed {buffer} data onto a new {Buffer} instance. * * @param buffer The buffer to copy. */ - new(buffer: Buffer): Buffer; - prototype: Buffer; - /** - * Allocates a new Buffer using an {array} of octets. - * - * @param array - */ - from(array: any[]): Buffer; + new(buffer: Buffer): Buffer; + prototype: Buffer; /** * When passed a reference to the .buffer property of a TypedArray instance, * the newly created Buffer will share the same allocated memory as the TypedArray. @@ -179,45 +233,40 @@ declare var Buffer: { * within the {arrayBuffer} that will be shared by the Buffer. * * @param arrayBuffer The .buffer property of a TypedArray or a new ArrayBuffer() - * @param byteOffset - * @param length */ - from(arrayBuffer: ArrayBuffer, byteOffset?: number, length?: number): Buffer; + from(arrayBuffer: ArrayBuffer, byteOffset?: number, length?: number): Buffer; /** - * Copies the passed {buffer} data onto a new Buffer instance. - * - * @param buffer + * Creates a new Buffer using the passed {data} + * @param data data to create a new Buffer */ - from(buffer: Buffer): Buffer; + from(data: any[] | string | Buffer | ArrayBuffer /*| TypedArray*/): Buffer; /** * Creates a new Buffer containing the given JavaScript string {str}. * If provided, the {encoding} parameter identifies the character encoding. * If not provided, {encoding} defaults to 'utf8'. - * - * @param str */ - from(str: string, encoding?: string): Buffer; + from(str: string, encoding?: string): Buffer; /** * Returns true if {obj} is a Buffer * * @param obj object to test. */ - isBuffer(obj: any): obj is Buffer; + isBuffer(obj: any): obj is Buffer; /** * Returns true if {encoding} is a valid encoding argument. * Valid string encodings in Node 0.12: 'ascii'|'utf8'|'utf16le'|'ucs2'(alias of 'utf16le')|'base64'|'binary'(deprecated)|'hex' * * @param encoding string to test. */ - isEncoding(encoding: string): boolean; + isEncoding(encoding: string): boolean; /** * Gives the actual byte length of a string. encoding defaults to 'utf8'. * This is not the same as String.prototype.length since that returns the number of characters in a string. * - * @param string string to test. + * @param string string to test. (TypedArray is also allowed, but it is only available starting ES2017) * @param encoding encoding used to evaluate (defaults to 'utf8') */ - byteLength(string: string, encoding?: string): number; + byteLength(string: string | Buffer | DataView | ArrayBuffer, encoding?: string): number; /** * Returns a buffer which is the result of concatenating all the buffers in the list together. * @@ -229,11 +278,11 @@ declare var Buffer: { * @param totalLength Total length of the buffers when concatenated. * If totalLength is not provided, it is read from the buffers in the list. However, this adds an additional loop to the function, so it is faster to provide the length explicitly. */ - concat(list: Buffer[], totalLength?: number): Buffer; + concat(list: Buffer[], totalLength?: number): Buffer; /** * The same as buf1.compare(buf2). */ - compare(buf1: Buffer, buf2: Buffer): number; + compare(buf1: Buffer, buf2: Buffer): number; /** * Allocates a new buffer of {size} octets. * @@ -242,21 +291,25 @@ declare var Buffer: { * If parameter is omitted, buffer will be filled with zeros. * @param encoding encoding used for call to buf.fill while initalizing */ - alloc(size: number, fill?: string | Buffer | number, encoding?: string): Buffer; + alloc(size: number, fill?: string | Buffer | number, encoding?: string): Buffer; /** * Allocates a new buffer of {size} octets, leaving memory not initialized, so the contents * of the newly created Buffer are unknown and may contain sensitive data. * * @param size count of octets to allocate */ - allocUnsafe(size: number): Buffer; + allocUnsafe(size: number): Buffer; /** * Allocates a new non-pooled buffer of {size} octets, leaving memory not initialized, so the contents * of the newly created Buffer are unknown and may contain sensitive data. * * @param size count of octets to allocate */ - allocUnsafeSlow(size: number): Buffer; + allocUnsafeSlow(size: number): Buffer; + /** + * This is the number of bytes used to determine the size of pre-allocated, internal Buffer instances used for pooling. This value may be modified. + */ + poolSize: number; }; /************************************************ @@ -265,273 +318,506 @@ declare var Buffer: { * * ************************************************/ declare namespace NodeJS { - export interface InspectOptions { - showHidden?: boolean; - depth?: number | null; - colors?: boolean; - customInspect?: boolean; - showProxy?: boolean; - maxArrayLength?: number | null; - breakLength?: number; - } + export interface InspectOptions { + showHidden?: boolean; + depth?: number | null; + colors?: boolean; + customInspect?: boolean; + showProxy?: boolean; + maxArrayLength?: number | null; + breakLength?: number; + } - export interface ConsoleConstructor { - prototype: Console; - new(stdout: WritableStream, stderr?: WritableStream): Console; - } + export interface ConsoleConstructor { + prototype: Console; + new(stdout: WritableStream, stderr?: WritableStream): Console; + } - export interface ErrnoException extends Error { - errno?: number; - code?: string; - path?: string; - syscall?: string; - stack?: string; - } + export interface CallSite { + /** + * Value of "this" + */ + getThis(): any; - export class EventEmitter { - addListener(event: string | symbol, listener: Function): this; - on(event: string | symbol, listener: Function): this; - once(event: string | symbol, listener: Function): this; - removeListener(event: string | symbol, listener: Function): this; - removeAllListeners(event?: string | symbol): this; - setMaxListeners(n: number): this; - getMaxListeners(): number; - listeners(event: string | symbol): Function[]; - emit(event: string | symbol, ...args: any[]): boolean; - listenerCount(type: string | symbol): number; - // Added in Node 6... - prependListener(event: string | symbol, listener: Function): this; - prependOnceListener(event: string | symbol, listener: Function): this; - eventNames(): (string | symbol)[]; - } + /** + * Type of "this" as a string. + * This is the name of the function stored in the constructor field of + * "this", if available. Otherwise the object's [[Class]] internal + * property. + */ + getTypeName(): string | null; - export interface ReadableStream extends EventEmitter { - readable: boolean; - read(size?: number): string | Buffer; - setEncoding(encoding: string | null): this; - pause(): this; - resume(): this; - isPaused(): boolean; - pipe(destination: T, options?: { end?: boolean; }): T; - unpipe(destination?: T): this; - unshift(chunk: string): void; - unshift(chunk: Buffer): void; - wrap(oldStream: ReadableStream): ReadableStream; - } + /** + * Current function + */ + getFunction(): Function | undefined; - export interface WritableStream extends EventEmitter { - writable: boolean; - write(buffer: Buffer | string, cb?: Function): boolean; - write(str: string, encoding?: string, cb?: Function): boolean; - end(): void; - end(buffer: Buffer, cb?: Function): void; - end(str: string, cb?: Function): void; - end(str: string, encoding?: string, cb?: Function): void; - } + /** + * Name of the current function, typically its name property. + * If a name property is not available an attempt will be made to try + * to infer a name from the function's context. + */ + getFunctionName(): string | null; - export interface ReadWriteStream extends ReadableStream, WritableStream { } + /** + * Name of the property [of "this" or one of its prototypes] that holds + * the current function + */ + getMethodName(): string | null; - export interface Events extends EventEmitter { } + /** + * Name of the script [if this function was defined in a script] + */ + getFileName(): string | null; - export interface Domain extends Events { - run(fn: Function): void; - add(emitter: Events): void; - remove(emitter: Events): void; - bind(cb: (err: Error, data: any) => any): any; - intercept(cb: (data: any) => any): any; - dispose(): void; + /** + * Current line number [if this function was defined in a script] + */ + getLineNumber(): number | null; - addListener(event: string, listener: Function): this; - on(event: string, listener: Function): this; - once(event: string, listener: Function): this; - removeListener(event: string, listener: Function): this; - removeAllListeners(event?: string): this; - } + /** + * Current column number [if this function was defined in a script] + */ + getColumnNumber(): number | null; - export interface MemoryUsage { - rss: number; - heapTotal: number; - heapUsed: number; - } + /** + * A call site object representing the location where eval was called + * [if this function was created using a call to eval] + */ + getEvalOrigin(): string | undefined; - export interface CpuUsage { - user: number; - system: number; - } + /** + * Is this a toplevel invocation, that is, is "this" the global object? + */ + isToplevel(): boolean; - export interface ProcessVersions { - http_parser: string; - node: string; - v8: string; - ares: string; - uv: string; - zlib: string; - modules: string; - openssl: string; - } + /** + * Does this call take place in code defined by a call to eval? + */ + isEval(): boolean; - type Platform = 'aix' - | 'android' - | 'darwin' - | 'freebsd' - | 'linux' - | 'openbsd' - | 'sunos' - | 'win32'; + /** + * Is this call in native V8 code? + */ + isNative(): boolean; - export interface Socket extends ReadWriteStream { - isTTY?: true; - } + /** + * Is this a constructor call? + */ + isConstructor(): boolean; + } - export interface WriteStream extends Socket { - columns?: number; - rows?: number; - } - export interface ReadStream extends Socket { - isRaw?: boolean; - setRawMode?(mode: boolean): void; - } + export interface ErrnoException extends Error { + errno?: number; + code?: string; + path?: string; + syscall?: string; + stack?: string; + } - export interface Process extends EventEmitter { - stdout: WriteStream; - stderr: WriteStream; - stdin: ReadStream; - openStdin(): Socket; - argv: string[]; - argv0: string; - execArgv: string[]; - execPath: string; - abort(): void; - chdir(directory: string): void; - cwd(): string; - emitWarning(warning: string | Error, name?: string, ctor?: Function): void; - env: any; - exit(code?: number): void; - exitCode: number; - getgid(): number; - setgid(id: number): void; - setgid(id: string): void; - getuid(): number; - setuid(id: number): void; - setuid(id: string): void; - version: string; - versions: ProcessVersions; - config: { - target_defaults: { - cflags: any[]; - default_configuration: string; - defines: string[]; - include_dirs: string[]; - libraries: string[]; - }; - variables: { - clang: number; - host_arch: string; - node_install_npm: boolean; - node_install_waf: boolean; - node_prefix: string; - node_shared_openssl: boolean; - node_shared_v8: boolean; - node_shared_zlib: boolean; - node_use_dtrace: boolean; - node_use_etw: boolean; - node_use_openssl: boolean; - target_arch: string; - v8_no_strict_aliasing: number; - v8_use_snapshot: boolean; - visibility: string; - }; - }; - kill(pid: number, signal?: string | number): void; - pid: number; - title: string; - arch: string; - platform: Platform; - mainModule?: NodeModule; - memoryUsage(): MemoryUsage; - cpuUsage(previousValue?: CpuUsage): CpuUsage; - nextTick(callback: Function, ...args: any[]): void; - umask(mask?: number): number; - uptime(): number; - hrtime(time?: [number, number]): [number, number]; - domain: Domain; + export class EventEmitter { + addListener(event: string | symbol, listener: (...args: any[]) => void): this; + on(event: string | symbol, listener: (...args: any[]) => void): this; + once(event: string | symbol, listener: (...args: any[]) => void): this; + removeListener(event: string | symbol, listener: (...args: any[]) => void): this; + removeAllListeners(event?: string | symbol): this; + setMaxListeners(n: number): this; + getMaxListeners(): number; + listeners(event: string | symbol): Function[]; + emit(event: string | symbol, ...args: any[]): boolean; + listenerCount(type: string | symbol): number; + // Added in Node 6... + prependListener(event: string | symbol, listener: (...args: any[]) => void): this; + prependOnceListener(event: string | symbol, listener: (...args: any[]) => void): this; + eventNames(): Array; + } - // Worker - send?(message: any, sendHandle?: any): void; - disconnect(): void; - connected: boolean; - } + export interface ReadableStream extends EventEmitter { + readable: boolean; + read(size?: number): string | Buffer; + setEncoding(encoding: string): this; + pause(): this; + resume(): this; + isPaused(): boolean; + pipe(destination: T, options?: { end?: boolean; }): T; + unpipe(destination?: T): this; + unshift(chunk: string): void; + unshift(chunk: Buffer): void; + wrap(oldStream: ReadableStream): this; + } - export interface Global { - Array: typeof Array; - ArrayBuffer: typeof ArrayBuffer; - Boolean: typeof Boolean; - Buffer: typeof Buffer; - DataView: typeof DataView; - Date: typeof Date; - Error: typeof Error; - EvalError: typeof EvalError; - Float32Array: typeof Float32Array; - Float64Array: typeof Float64Array; - Function: typeof Function; - GLOBAL: Global; - Infinity: typeof Infinity; - Int16Array: typeof Int16Array; - Int32Array: typeof Int32Array; - Int8Array: typeof Int8Array; - Intl: typeof Intl; - JSON: typeof JSON; - Map: MapConstructor; - Math: typeof Math; - NaN: typeof NaN; - Number: typeof Number; - Object: typeof Object; - Promise: Function; - RangeError: typeof RangeError; - ReferenceError: typeof ReferenceError; - RegExp: typeof RegExp; - Set: SetConstructor; - String: typeof String; - Symbol: Function; - SyntaxError: typeof SyntaxError; - TypeError: typeof TypeError; - URIError: typeof URIError; - Uint16Array: typeof Uint16Array; - Uint32Array: typeof Uint32Array; - Uint8Array: typeof Uint8Array; - Uint8ClampedArray: Function; - WeakMap: WeakMapConstructor; - WeakSet: WeakSetConstructor; - clearImmediate: (immediateId: any) => void; - clearInterval: (intervalId: NodeJS.Timer) => void; - clearTimeout: (timeoutId: NodeJS.Timer) => void; - console: typeof console; - decodeURI: typeof decodeURI; - decodeURIComponent: typeof decodeURIComponent; - encodeURI: typeof encodeURI; - encodeURIComponent: typeof encodeURIComponent; - escape: (str: string) => string; - eval: typeof eval; - global: Global; - isFinite: typeof isFinite; - isNaN: typeof isNaN; - parseFloat: typeof parseFloat; - parseInt: typeof parseInt; - process: Process; - root: Global; - setImmediate: (callback: (...args: any[]) => void, ...args: any[]) => any; - setInterval: (callback: (...args: any[]) => void, ms: number, ...args: any[]) => NodeJS.Timer; - setTimeout: (callback: (...args: any[]) => void, ms: number, ...args: any[]) => NodeJS.Timer; - undefined: typeof undefined; - unescape: (str: string) => string; - gc: () => void; - v8debug?: any; - } + export interface WritableStream extends EventEmitter { + writable: boolean; + write(buffer: Buffer | string, cb?: Function): boolean; + write(str: string, encoding?: string, cb?: Function): boolean; + end(cb?: Function): void; + end(buffer: Buffer, cb?: Function): void; + end(str: string, cb?: Function): void; + end(str: string, encoding?: string, cb?: Function): void; + } - export interface Timer { - ref(): void; - unref(): void; - } + export interface ReadWriteStream extends ReadableStream, WritableStream { } + + export interface Events extends EventEmitter { } + + export interface Domain extends Events { + run(fn: Function): void; + add(emitter: Events): void; + remove(emitter: Events): void; + bind(cb: (err: Error, data: any) => any): any; + intercept(cb: (data: any) => any): any; + dispose(): void; + + addListener(event: string, listener: (...args: any[]) => void): this; + on(event: string, listener: (...args: any[]) => void): this; + once(event: string, listener: (...args: any[]) => void): this; + removeListener(event: string, listener: (...args: any[]) => void): this; + removeAllListeners(event?: string): this; + } + + export interface MemoryUsage { + rss: number; + heapTotal: number; + heapUsed: number; + external: number; + } + + export interface CpuUsage { + user: number; + system: number; + } + + export interface ProcessVersions { + http_parser: string; + node: string; + v8: string; + ares: string; + uv: string; + zlib: string; + modules: string; + openssl: string; + } + + type Platform = 'aix' + | 'android' + | 'darwin' + | 'freebsd' + | 'linux' + | 'openbsd' + | 'sunos' + | 'win32' + | 'cygwin'; + + type Signals = + "SIGABRT" | "SIGALRM" | "SIGBUS" | "SIGCHLD" | "SIGCONT" | "SIGFPE" | "SIGHUP" | "SIGILL" | "SIGINT" | "SIGIO" | + "SIGIOT" | "SIGKILL" | "SIGPIPE" | "SIGPOLL" | "SIGPROF" | "SIGPWR" | "SIGQUIT" | "SIGSEGV" | "SIGSTKFLT" | + "SIGSTOP" | "SIGSYS" | "SIGTERM" | "SIGTRAP" | "SIGTSTP" | "SIGTTIN" | "SIGTTOU" | "SIGUNUSED" | "SIGURG" | + "SIGUSR1" | "SIGUSR2" | "SIGVTALRM" | "SIGWINCH" | "SIGXCPU" | "SIGXFSZ" | "SIGBREAK" | "SIGLOST" | "SIGINFO"; + + type BeforeExitListener = (code: number) => void; + type DisconnectListener = () => void; + type ExitListener = (code: number) => void; + type RejectionHandledListener = (promise: Promise) => void; + type UncaughtExceptionListener = (error: Error) => void; + type UnhandledRejectionListener = (reason: any, promise: Promise) => void; + type WarningListener = (warning: Error) => void; + type MessageListener = (message: any, sendHandle: any) => void; + type SignalsListener = () => void; + type NewListenerListener = (type: string | symbol, listener: (...args: any[]) => void) => void; + type RemoveListenerListener = (type: string | symbol, listener: (...args: any[]) => void) => void; + + export interface Socket extends ReadWriteStream { + isTTY?: true; + } + + export interface ProcessEnv { + [key: string]: string | undefined; + } + + export interface WriteStream extends Socket { + readonly writableHighWaterMark: number; + columns?: number; + rows?: number; + _write(chunk: any, encoding: string, callback: Function): void; + _destroy(err: Error, callback: Function): void; + _final(callback: Function): void; + setDefaultEncoding(encoding: string): this; + cork(): void; + uncork(): void; + destroy(error?: Error): void; + } + export interface ReadStream extends Socket { + readonly readableHighWaterMark: number; + isRaw?: boolean; + setRawMode?(mode: boolean): void; + _read(size: number): void; + _destroy(err: Error, callback: Function): void; + push(chunk: any, encoding?: string): boolean; + destroy(error?: Error): void; + } + + export interface Process extends EventEmitter { + stdout: WriteStream; + stderr: WriteStream; + stdin: ReadStream; + openStdin(): Socket; + argv: string[]; + argv0: string; + execArgv: string[]; + execPath: string; + abort(): void; + chdir(directory: string): void; + cwd(): string; + debugPort: number; + emitWarning(warning: string | Error, name?: string, ctor?: Function): void; + env: ProcessEnv; + exit(code?: number): never; + exitCode: number; + getgid(): number; + setgid(id: number | string): void; + getuid(): number; + setuid(id: number | string): void; + geteuid(): number; + seteuid(id: number | string): void; + getegid(): number; + setegid(id: number | string): void; + getgroups(): number[]; + setgroups(groups: Array): void; + version: string; + versions: ProcessVersions; + config: { + target_defaults: { + cflags: any[]; + default_configuration: string; + defines: string[]; + include_dirs: string[]; + libraries: string[]; + }; + variables: { + clang: number; + host_arch: string; + node_install_npm: boolean; + node_install_waf: boolean; + node_prefix: string; + node_shared_openssl: boolean; + node_shared_v8: boolean; + node_shared_zlib: boolean; + node_use_dtrace: boolean; + node_use_etw: boolean; + node_use_openssl: boolean; + target_arch: string; + v8_no_strict_aliasing: number; + v8_use_snapshot: boolean; + visibility: string; + }; + }; + kill(pid: number, signal?: string | number): void; + pid: number; + title: string; + arch: string; + platform: Platform; + mainModule?: NodeModule; + memoryUsage(): MemoryUsage; + cpuUsage(previousValue?: CpuUsage): CpuUsage; + nextTick(callback: Function, ...args: any[]): void; + umask(mask?: number): number; + uptime(): number; + hrtime(time?: [number, number]): [number, number]; + domain: Domain; + + // Worker + send?(message: any, sendHandle?: any): void; + disconnect(): void; + connected: boolean; + + /** + * EventEmitter + * 1. beforeExit + * 2. disconnect + * 3. exit + * 4. message + * 5. rejectionHandled + * 6. uncaughtException + * 7. unhandledRejection + * 8. warning + * 9. message + * 10. + * 11. newListener/removeListener inherited from EventEmitter + */ + addListener(event: "beforeExit", listener: BeforeExitListener): this; + addListener(event: "disconnect", listener: DisconnectListener): this; + addListener(event: "exit", listener: ExitListener): this; + addListener(event: "rejectionHandled", listener: RejectionHandledListener): this; + addListener(event: "uncaughtException", listener: UncaughtExceptionListener): this; + addListener(event: "unhandledRejection", listener: UnhandledRejectionListener): this; + addListener(event: "warning", listener: WarningListener): this; + addListener(event: "message", listener: MessageListener): this; + addListener(event: Signals, listener: SignalsListener): this; + addListener(event: "newListener", listener: NewListenerListener): this; + addListener(event: "removeListener", listener: RemoveListenerListener): this; + + emit(event: "beforeExit", code: number): boolean; + emit(event: "disconnect"): boolean; + emit(event: "exit", code: number): boolean; + emit(event: "rejectionHandled", promise: Promise): boolean; + emit(event: "uncaughtException", error: Error): boolean; + emit(event: "unhandledRejection", reason: any, promise: Promise): boolean; + emit(event: "warning", warning: Error): boolean; + emit(event: "message", message: any, sendHandle: any): this; + emit(event: Signals): boolean; + emit(event: "newListener", eventName: string | symbol, listener: (...args: any[]) => void): this; + emit(event: "removeListener", eventName: string, listener: (...args: any[]) => void): this; + + on(event: "beforeExit", listener: BeforeExitListener): this; + on(event: "disconnect", listener: DisconnectListener): this; + on(event: "exit", listener: ExitListener): this; + on(event: "rejectionHandled", listener: RejectionHandledListener): this; + on(event: "uncaughtException", listener: UncaughtExceptionListener): this; + on(event: "unhandledRejection", listener: UnhandledRejectionListener): this; + on(event: "warning", listener: WarningListener): this; + on(event: "message", listener: MessageListener): this; + on(event: Signals, listener: SignalsListener): this; + on(event: "newListener", listener: NewListenerListener): this; + on(event: "removeListener", listener: RemoveListenerListener): this; + + once(event: "beforeExit", listener: BeforeExitListener): this; + once(event: "disconnect", listener: DisconnectListener): this; + once(event: "exit", listener: ExitListener): this; + once(event: "rejectionHandled", listener: RejectionHandledListener): this; + once(event: "uncaughtException", listener: UncaughtExceptionListener): this; + once(event: "unhandledRejection", listener: UnhandledRejectionListener): this; + once(event: "warning", listener: WarningListener): this; + once(event: "message", listener: MessageListener): this; + once(event: Signals, listener: SignalsListener): this; + once(event: "newListener", listener: NewListenerListener): this; + once(event: "removeListener", listener: RemoveListenerListener): this; + + prependListener(event: "beforeExit", listener: BeforeExitListener): this; + prependListener(event: "disconnect", listener: DisconnectListener): this; + prependListener(event: "exit", listener: ExitListener): this; + prependListener(event: "rejectionHandled", listener: RejectionHandledListener): this; + prependListener(event: "uncaughtException", listener: UncaughtExceptionListener): this; + prependListener(event: "unhandledRejection", listener: UnhandledRejectionListener): this; + prependListener(event: "warning", listener: WarningListener): this; + prependListener(event: "message", listener: MessageListener): this; + prependListener(event: Signals, listener: SignalsListener): this; + prependListener(event: "newListener", listener: NewListenerListener): this; + prependListener(event: "removeListener", listener: RemoveListenerListener): this; + + prependOnceListener(event: "beforeExit", listener: BeforeExitListener): this; + prependOnceListener(event: "disconnect", listener: DisconnectListener): this; + prependOnceListener(event: "exit", listener: ExitListener): this; + prependOnceListener(event: "rejectionHandled", listener: RejectionHandledListener): this; + prependOnceListener(event: "uncaughtException", listener: UncaughtExceptionListener): this; + prependOnceListener(event: "unhandledRejection", listener: UnhandledRejectionListener): this; + prependOnceListener(event: "warning", listener: WarningListener): this; + prependOnceListener(event: "message", listener: MessageListener): this; + prependOnceListener(event: Signals, listener: SignalsListener): this; + prependOnceListener(event: "newListener", listener: NewListenerListener): this; + prependOnceListener(event: "removeListener", listener: RemoveListenerListener): this; + + listeners(event: "beforeExit"): BeforeExitListener[]; + listeners(event: "disconnect"): DisconnectListener[]; + listeners(event: "exit"): ExitListener[]; + listeners(event: "rejectionHandled"): RejectionHandledListener[]; + listeners(event: "uncaughtException"): UncaughtExceptionListener[]; + listeners(event: "unhandledRejection"): UnhandledRejectionListener[]; + listeners(event: "warning"): WarningListener[]; + listeners(event: "message"): MessageListener[]; + listeners(event: Signals): SignalsListener[]; + listeners(event: "newListener"): NewListenerListener[]; + listeners(event: "removeListener"): RemoveListenerListener[]; + } + + export interface Global { + Array: typeof Array; + ArrayBuffer: typeof ArrayBuffer; + Boolean: typeof Boolean; + Buffer: typeof Buffer; + DataView: typeof DataView; + Date: typeof Date; + Error: typeof Error; + EvalError: typeof EvalError; + Float32Array: typeof Float32Array; + Float64Array: typeof Float64Array; + Function: typeof Function; + GLOBAL: Global; + Infinity: typeof Infinity; + Int16Array: typeof Int16Array; + Int32Array: typeof Int32Array; + Int8Array: typeof Int8Array; + Intl: typeof Intl; + JSON: typeof JSON; + Map: MapConstructor; + Math: typeof Math; + NaN: typeof NaN; + Number: typeof Number; + Object: typeof Object; + Promise: Function; + RangeError: typeof RangeError; + ReferenceError: typeof ReferenceError; + RegExp: typeof RegExp; + Set: SetConstructor; + String: typeof String; + Symbol: Function; + SyntaxError: typeof SyntaxError; + TypeError: typeof TypeError; + URIError: typeof URIError; + Uint16Array: typeof Uint16Array; + Uint32Array: typeof Uint32Array; + Uint8Array: typeof Uint8Array; + Uint8ClampedArray: Function; + WeakMap: WeakMapConstructor; + WeakSet: WeakSetConstructor; + clearImmediate: (immediateId: any) => void; + clearInterval: (intervalId: NodeJS.Timer) => void; + clearTimeout: (timeoutId: NodeJS.Timer) => void; + console: typeof console; + decodeURI: typeof decodeURI; + decodeURIComponent: typeof decodeURIComponent; + encodeURI: typeof encodeURI; + encodeURIComponent: typeof encodeURIComponent; + escape: (str: string) => string; + eval: typeof eval; + global: Global; + isFinite: typeof isFinite; + isNaN: typeof isNaN; + parseFloat: typeof parseFloat; + parseInt: typeof parseInt; + process: Process; + root: Global; + setImmediate: (callback: (...args: any[]) => void, ...args: any[]) => any; + setInterval: (callback: (...args: any[]) => void, ms: number, ...args: any[]) => NodeJS.Timer; + setTimeout: (callback: (...args: any[]) => void, ms: number, ...args: any[]) => NodeJS.Timer; + undefined: typeof undefined; + unescape: (str: string) => string; + gc: () => void; + v8debug?: any; + } + + export interface Timer { + ref(): void; + unref(): void; + } + + class Module { + static runMain(): void; + static wrap(code: string): string; + static builtinModules: string[]; + + static Module: typeof Module; + + exports: any; + require: NodeRequireFunction; + id: string; + filename: string; + loaded: boolean; + parent: Module | null; + children: Module[]; + paths: string[]; + + constructor(id: string, parent?: Module); + } } interface IterableIterator { } @@ -540,59 +826,59 @@ interface IterableIterator { } * @deprecated */ interface NodeBuffer extends Uint8Array { - write(string: string, offset?: number, length?: number, encoding?: string): number; - toString(encoding?: string, start?: number, end?: number): string; - toJSON(): { type: 'Buffer', data: any[] }; - equals(otherBuffer: Buffer): boolean; - compare(otherBuffer: Buffer, targetStart?: number, targetEnd?: number, sourceStart?: number, sourceEnd?: number): number; - copy(targetBuffer: Buffer, targetStart?: number, sourceStart?: number, sourceEnd?: number): number; - slice(start?: number, end?: number): Buffer; - writeUIntLE(value: number, offset: number, byteLength: number, noAssert?: boolean): number; - writeUIntBE(value: number, offset: number, byteLength: number, noAssert?: boolean): number; - writeIntLE(value: number, offset: number, byteLength: number, noAssert?: boolean): number; - writeIntBE(value: number, offset: number, byteLength: number, noAssert?: boolean): number; - readUIntLE(offset: number, byteLength: number, noAssert?: boolean): number; - readUIntBE(offset: number, byteLength: number, noAssert?: boolean): number; - readIntLE(offset: number, byteLength: number, noAssert?: boolean): number; - readIntBE(offset: number, byteLength: number, noAssert?: boolean): number; - readUInt8(offset: number, noAssert?: boolean): number; - readUInt16LE(offset: number, noAssert?: boolean): number; - readUInt16BE(offset: number, noAssert?: boolean): number; - readUInt32LE(offset: number, noAssert?: boolean): number; - readUInt32BE(offset: number, noAssert?: boolean): number; - readInt8(offset: number, noAssert?: boolean): number; - readInt16LE(offset: number, noAssert?: boolean): number; - readInt16BE(offset: number, noAssert?: boolean): number; - readInt32LE(offset: number, noAssert?: boolean): number; - readInt32BE(offset: number, noAssert?: boolean): number; - readFloatLE(offset: number, noAssert?: boolean): number; - readFloatBE(offset: number, noAssert?: boolean): number; - readDoubleLE(offset: number, noAssert?: boolean): number; - readDoubleBE(offset: number, noAssert?: boolean): number; - swap16(): Buffer; - swap32(): Buffer; - swap64(): Buffer; - writeUInt8(value: number, offset: number, noAssert?: boolean): number; - writeUInt16LE(value: number, offset: number, noAssert?: boolean): number; - writeUInt16BE(value: number, offset: number, noAssert?: boolean): number; - writeUInt32LE(value: number, offset: number, noAssert?: boolean): number; - writeUInt32BE(value: number, offset: number, noAssert?: boolean): number; - writeInt8(value: number, offset: number, noAssert?: boolean): number; - writeInt16LE(value: number, offset: number, noAssert?: boolean): number; - writeInt16BE(value: number, offset: number, noAssert?: boolean): number; - writeInt32LE(value: number, offset: number, noAssert?: boolean): number; - writeInt32BE(value: number, offset: number, noAssert?: boolean): number; - writeFloatLE(value: number, offset: number, noAssert?: boolean): number; - writeFloatBE(value: number, offset: number, noAssert?: boolean): number; - writeDoubleLE(value: number, offset: number, noAssert?: boolean): number; - writeDoubleBE(value: number, offset: number, noAssert?: boolean): number; - fill(value: any, offset?: number, end?: number): this; - indexOf(value: string | number | Buffer, byteOffset?: number, encoding?: string): number; - lastIndexOf(value: string | number | Buffer, byteOffset?: number, encoding?: string): number; - entries(): IterableIterator<[number, number]>; - includes(value: string | number | Buffer, byteOffset?: number, encoding?: string): boolean; - keys(): IterableIterator; - values(): IterableIterator; + write(string: string, offset?: number, length?: number, encoding?: string): number; + toString(encoding?: string, start?: number, end?: number): string; + toJSON(): { type: 'Buffer', data: any[] }; + equals(otherBuffer: Buffer): boolean; + compare(otherBuffer: Buffer, targetStart?: number, targetEnd?: number, sourceStart?: number, sourceEnd?: number): number; + copy(targetBuffer: Buffer, targetStart?: number, sourceStart?: number, sourceEnd?: number): number; + slice(start?: number, end?: number): Buffer; + writeUIntLE(value: number, offset: number, byteLength: number, noAssert?: boolean): number; + writeUIntBE(value: number, offset: number, byteLength: number, noAssert?: boolean): number; + writeIntLE(value: number, offset: number, byteLength: number, noAssert?: boolean): number; + writeIntBE(value: number, offset: number, byteLength: number, noAssert?: boolean): number; + readUIntLE(offset: number, byteLength: number, noAssert?: boolean): number; + readUIntBE(offset: number, byteLength: number, noAssert?: boolean): number; + readIntLE(offset: number, byteLength: number, noAssert?: boolean): number; + readIntBE(offset: number, byteLength: number, noAssert?: boolean): number; + readUInt8(offset: number, noAssert?: boolean): number; + readUInt16LE(offset: number, noAssert?: boolean): number; + readUInt16BE(offset: number, noAssert?: boolean): number; + readUInt32LE(offset: number, noAssert?: boolean): number; + readUInt32BE(offset: number, noAssert?: boolean): number; + readInt8(offset: number, noAssert?: boolean): number; + readInt16LE(offset: number, noAssert?: boolean): number; + readInt16BE(offset: number, noAssert?: boolean): number; + readInt32LE(offset: number, noAssert?: boolean): number; + readInt32BE(offset: number, noAssert?: boolean): number; + readFloatLE(offset: number, noAssert?: boolean): number; + readFloatBE(offset: number, noAssert?: boolean): number; + readDoubleLE(offset: number, noAssert?: boolean): number; + readDoubleBE(offset: number, noAssert?: boolean): number; + swap16(): Buffer; + swap32(): Buffer; + swap64(): Buffer; + writeUInt8(value: number, offset: number, noAssert?: boolean): number; + writeUInt16LE(value: number, offset: number, noAssert?: boolean): number; + writeUInt16BE(value: number, offset: number, noAssert?: boolean): number; + writeUInt32LE(value: number, offset: number, noAssert?: boolean): number; + writeUInt32BE(value: number, offset: number, noAssert?: boolean): number; + writeInt8(value: number, offset: number, noAssert?: boolean): number; + writeInt16LE(value: number, offset: number, noAssert?: boolean): number; + writeInt16BE(value: number, offset: number, noAssert?: boolean): number; + writeInt32LE(value: number, offset: number, noAssert?: boolean): number; + writeInt32BE(value: number, offset: number, noAssert?: boolean): number; + writeFloatLE(value: number, offset: number, noAssert?: boolean): number; + writeFloatBE(value: number, offset: number, noAssert?: boolean): number; + writeDoubleLE(value: number, offset: number, noAssert?: boolean): number; + writeDoubleBE(value: number, offset: number, noAssert?: boolean): number; + fill(value: any, offset?: number, end?: number): this; + indexOf(value: string | number | Buffer, byteOffset?: number, encoding?: string): number; + lastIndexOf(value: string | number | Buffer, byteOffset?: number, encoding?: string): number; + entries(): IterableIterator<[number, number]>; + includes(value: string | number | Buffer, byteOffset?: number, encoding?: string): boolean; + keys(): IterableIterator; + values(): IterableIterator; } /************************************************ @@ -601,205 +887,271 @@ interface NodeBuffer extends Uint8Array { * * ************************************************/ declare module "buffer" { - export var INSPECT_MAX_BYTES: number; - var BuffType: typeof Buffer; - var SlowBuffType: typeof SlowBuffer; - export { BuffType as Buffer, SlowBuffType as SlowBuffer }; + export var INSPECT_MAX_BYTES: number; + var BuffType: typeof Buffer; + var SlowBuffType: typeof SlowBuffer; + export { BuffType as Buffer, SlowBuffType as SlowBuffer }; } declare module "querystring" { - export interface StringifyOptions { - encodeURIComponent?: Function; - } + export interface StringifyOptions { + encodeURIComponent?: Function; + } - export interface ParseOptions { - maxKeys?: number; - decodeURIComponent?: Function; - } + export interface ParseOptions { + maxKeys?: number; + decodeURIComponent?: Function; + } - export function stringify(obj: T, sep?: string, eq?: string, options?: StringifyOptions): string; - export function parse(str: string, sep?: string, eq?: string, options?: ParseOptions): any; - export function parse(str: string, sep?: string, eq?: string, options?: ParseOptions): T; - export function escape(str: string): string; - export function unescape(str: string): string; + interface ParsedUrlQuery { [key: string]: string | string[] | undefined; } + + export function stringify(obj: T, sep?: string, eq?: string, options?: StringifyOptions): string; + export function parse(str: string, sep?: string, eq?: string, options?: ParseOptions): ParsedUrlQuery; + export function parse(str: string, sep?: string, eq?: string, options?: ParseOptions): T; + export function escape(str: string): string; + export function unescape(str: string): string; } declare module "events" { - class internal extends NodeJS.EventEmitter { } + class internal extends NodeJS.EventEmitter { } - namespace internal { - export class EventEmitter extends internal { - static listenerCount(emitter: EventEmitter, event: string | symbol): number; // deprecated - static defaultMaxListeners: number; + namespace internal { + export class EventEmitter extends internal { + static listenerCount(emitter: EventEmitter, event: string | symbol): number; // deprecated + static defaultMaxListeners: number; - addListener(event: string | symbol, listener: Function): this; - on(event: string | symbol, listener: Function): this; - once(event: string | symbol, listener: Function): this; - prependListener(event: string | symbol, listener: Function): this; - prependOnceListener(event: string | symbol, listener: Function): this; - removeListener(event: string | symbol, listener: Function): this; - removeAllListeners(event?: string | symbol): this; - setMaxListeners(n: number): this; - getMaxListeners(): number; - listeners(event: string | symbol): Function[]; - emit(event: string | symbol, ...args: any[]): boolean; - eventNames(): (string | symbol)[]; - listenerCount(type: string | symbol): number; - } - } + addListener(event: string | symbol, listener: (...args: any[]) => void): this; + on(event: string | symbol, listener: (...args: any[]) => void): this; + once(event: string | symbol, listener: (...args: any[]) => void): this; + prependListener(event: string | symbol, listener: (...args: any[]) => void): this; + prependOnceListener(event: string | symbol, listener: (...args: any[]) => void): this; + removeListener(event: string | symbol, listener: (...args: any[]) => void): this; + removeAllListeners(event?: string | symbol): this; + setMaxListeners(n: number): this; + getMaxListeners(): number; + listeners(event: string | symbol): Function[]; + emit(event: string | symbol, ...args: any[]): boolean; + eventNames(): Array; + listenerCount(type: string | symbol): number; + } + } - export = internal; + export = internal; } declare module "http" { - import * as events from "events"; - import * as net from "net"; - import * as stream from "stream"; + import * as events from "events"; + import * as net from "net"; + import * as stream from "stream"; + import { URL } from "url"; - export interface RequestOptions { - protocol?: string; - host?: string; - hostname?: string; - family?: number; - port?: number; - localAddress?: string; - socketPath?: string; - method?: string; - path?: string; - headers?: { [key: string]: any }; - auth?: string; - agent?: Agent | boolean; - timeout?: number; - } + // incoming headers will never contain number + export interface IncomingHttpHeaders { + 'accept'?: string; + 'access-control-allow-origin'?: string; + 'access-control-allow-credentials'?: string; + 'access-control-expose-headers'?: string; + 'access-control-max-age'?: string; + 'access-control-allow-methods'?: string; + 'access-control-allow-headers'?: string; + 'accept-patch'?: string; + 'accept-ranges'?: string; + 'authorization'?: string; + 'age'?: string; + 'allow'?: string; + 'alt-svc'?: string; + 'cache-control'?: string; + 'connection'?: string; + 'content-disposition'?: string; + 'content-encoding'?: string; + 'content-language'?: string; + 'content-length'?: string; + 'content-location'?: string; + 'content-range'?: string; + 'content-type'?: string; + 'date'?: string; + 'expires'?: string; + 'host'?: string; + 'last-modified'?: string; + 'location'?: string; + 'pragma'?: string; + 'proxy-authenticate'?: string; + 'public-key-pins'?: string; + 'retry-after'?: string; + 'set-cookie'?: string[]; + 'strict-transport-security'?: string; + 'trailer'?: string; + 'transfer-encoding'?: string; + 'tk'?: string; + 'upgrade'?: string; + 'vary'?: string; + 'via'?: string; + 'warning'?: string; + 'www-authenticate'?: string; + [header: string]: string | string[] | undefined; + } - export interface Server extends net.Server { - setTimeout(msecs: number, callback: Function): void; - maxHeadersCount: number; - timeout: number; - listening: boolean; - } + // outgoing headers allows numbers (as they are converted internally to strings) + export interface OutgoingHttpHeaders { + [header: string]: number | string | string[] | undefined; + } + + export interface ClientRequestArgs { + protocol?: string; + host?: string; + hostname?: string; + family?: number; + port?: number | string; + defaultPort?: number | string; + localAddress?: string; + socketPath?: string; + method?: string; + path?: string; + headers?: OutgoingHttpHeaders; + auth?: string; + agent?: Agent | boolean; + _defaultAgent?: Agent; + timeout?: number; + // https://github.com/nodejs/node/blob/master/lib/_http_client.js#L278 + createConnection?: (options: ClientRequestArgs, oncreate: (err: Error, socket: net.Socket) => void) => net.Socket; + } + + export class Server extends net.Server { + constructor(requestListener?: (req: IncomingMessage, res: ServerResponse) => void); + + setTimeout(msecs?: number, callback?: () => void): this; + setTimeout(callback: () => void): this; + maxHeadersCount: number; + timeout: number; + keepAliveTimeout: number; + } /** * @deprecated Use IncomingMessage */ - export interface ServerRequest extends IncomingMessage { - connection: net.Socket; - } - export interface ServerResponse extends stream.Writable { - // Extended base methods - write(buffer: Buffer): boolean; - write(buffer: Buffer, cb?: Function): boolean; - write(str: string, cb?: Function): boolean; - write(str: string, encoding?: string, cb?: Function): boolean; - write(str: string, encoding?: string, fd?: string): boolean; + export class ServerRequest extends IncomingMessage { + connection: net.Socket; + } - writeContinue(): void; - writeHead(statusCode: number, reasonPhrase?: string, headers?: any): void; - writeHead(statusCode: number, headers?: any): void; - statusCode: number; - statusMessage: string; - headersSent: boolean; - setHeader(name: string, value: string | string[]): void; - setTimeout(msecs: number, callback: Function): ServerResponse; - sendDate: boolean; - getHeader(name: string): string; - removeHeader(name: string): void; - write(chunk: any, encoding?: string): any; - addTrailers(headers: any): void; - finished: boolean; + // https://github.com/nodejs/node/blob/master/lib/_http_outgoing.js + export class OutgoingMessage extends stream.Writable { + upgrading: boolean; + chunkedEncoding: boolean; + shouldKeepAlive: boolean; + useChunkedEncodingByDefault: boolean; + sendDate: boolean; + finished: boolean; + headersSent: boolean; + connection: net.Socket; - // Extended base methods - end(): void; - end(buffer: Buffer, cb?: Function): void; - end(str: string, cb?: Function): void; - end(str: string, encoding?: string, cb?: Function): void; - end(data?: any, encoding?: string): void; - } - export interface ClientRequest extends stream.Writable { - // Extended base methods - write(buffer: Buffer): boolean; - write(buffer: Buffer, cb?: Function): boolean; - write(str: string, cb?: Function): boolean; - write(str: string, encoding?: string, cb?: Function): boolean; - write(str: string, encoding?: string, fd?: string): boolean; + constructor(); - write(chunk: any, encoding?: string): void; - abort(): void; - setTimeout(timeout: number, callback?: Function): void; - setNoDelay(noDelay?: boolean): void; - setSocketKeepAlive(enable?: boolean, initialDelay?: number): void; + setTimeout(msecs: number, callback?: () => void): this; + destroy(error: Error): void; + setHeader(name: string, value: number | string | string[]): void; + getHeader(name: string): number | string | string[] | undefined; + getHeaders(): OutgoingHttpHeaders; + getHeaderNames(): string[]; + hasHeader(name: string): boolean; + removeHeader(name: string): void; + addTrailers(headers: OutgoingHttpHeaders | Array<[string, string]>): void; + flushHeaders(): void; + } - setHeader(name: string, value: string | string[]): void; - getHeader(name: string): string; - removeHeader(name: string): void; - addTrailers(headers: any): void; + // https://github.com/nodejs/node/blob/master/lib/_http_server.js#L108-L256 + export class ServerResponse extends OutgoingMessage { + statusCode: number; + statusMessage: string; - // Extended base methods - end(): void; - end(buffer: Buffer, cb?: Function): void; - end(str: string, cb?: Function): void; - end(str: string, encoding?: string, cb?: Function): void; - end(data?: any, encoding?: string): void; - } - export interface IncomingMessage extends stream.Readable { - httpVersion: string; - httpVersionMajor: number; - httpVersionMinor: number; - connection: net.Socket; - headers: any; - rawHeaders: string[]; - trailers: any; - rawTrailers: any; - setTimeout(msecs: number, callback: Function): NodeJS.Timer; + constructor(req: IncomingMessage); + + assignSocket(socket: net.Socket): void; + detachSocket(socket: net.Socket): void; + // https://github.com/nodejs/node/blob/master/test/parallel/test-http-write-callbacks.js#L53 + // no args in writeContinue callback + writeContinue(callback?: () => void): void; + writeHead(statusCode: number, reasonPhrase?: string, headers?: OutgoingHttpHeaders): void; + writeHead(statusCode: number, headers?: OutgoingHttpHeaders): void; + } + + // https://github.com/nodejs/node/blob/master/lib/_http_client.js#L77 + export class ClientRequest extends OutgoingMessage { + connection: net.Socket; + socket: net.Socket; + aborted: number; + + constructor(url: string | URL | ClientRequestArgs, cb?: (res: IncomingMessage) => void); + + abort(): void; + onSocket(socket: net.Socket): void; + setTimeout(timeout: number, callback?: () => void): this; + setNoDelay(noDelay?: boolean): void; + setSocketKeepAlive(enable?: boolean, initialDelay?: number): void; + } + + export class IncomingMessage extends stream.Readable { + constructor(socket: net.Socket); + + httpVersion: string; + httpVersionMajor: number; + httpVersionMinor: number; + connection: net.Socket; + headers: IncomingHttpHeaders; + rawHeaders: string[]; + trailers: { [key: string]: string | undefined }; + rawTrailers: string[]; + setTimeout(msecs: number, callback: () => void): this; /** * Only valid for request obtained from http.Server. */ - method?: string; + method?: string; /** * Only valid for request obtained from http.Server. */ - url?: string; + url?: string; /** * Only valid for response obtained from http.ClientRequest. */ - statusCode?: number; + statusCode?: number; /** * Only valid for response obtained from http.ClientRequest. */ - statusMessage?: string; - socket: net.Socket; - destroy(error?: Error): void; - } + statusMessage?: string; + socket: net.Socket; + destroy(error?: Error): void; + } + /** * @deprecated Use IncomingMessage */ - export interface ClientResponse extends IncomingMessage { } + export class ClientResponse extends IncomingMessage { } - export interface AgentOptions { + export interface AgentOptions { /** * Keep sockets around in a pool to be used by other requests in the future. Default = false */ - keepAlive?: boolean; + keepAlive?: boolean; /** * When using HTTP KeepAlive, how often to send TCP KeepAlive packets over sockets being kept alive. Default = 1000. * Only relevant if keepAlive is set to true. */ - keepAliveMsecs?: number; + keepAliveMsecs?: number; /** * Maximum number of sockets to allow per host. Default for Node 0.10 is 5, default for Node 0.12 is Infinity */ - maxSockets?: number; + maxSockets?: number; /** * Maximum number of sockets to leave open in a free state. Only relevant if keepAlive is set to true. Default = 256. */ - maxFreeSockets?: number; - } + maxFreeSockets?: number; + } - export class Agent { - maxSockets: number; - sockets: any; - requests: any; + export class Agent { + maxFreeSockets: number; + maxSockets: number; + sockets: any; + requests: any; - constructor(opts?: AgentOptions); + constructor(opts?: AgentOptions); /** * Destroy any sockets that are currently in use by the agent. @@ -807,62 +1159,61 @@ declare module "http" { * then it is best to explicitly shut down the agent when you know that it will no longer be used. Otherwise, * sockets may hang open for quite a long time before the server terminates them. */ - destroy(): void; - } + destroy(): void; + } - export var METHODS: string[]; + export var METHODS: string[]; - export var STATUS_CODES: { - [errorCode: number]: string; - [errorCode: string]: string; - }; - export function createServer(requestListener?: (request: IncomingMessage, response: ServerResponse) => void): Server; - export function createClient(port?: number, host?: string): any; - export function request(options: RequestOptions, callback?: (res: IncomingMessage) => void): ClientRequest; - export function get(options: any, callback?: (res: IncomingMessage) => void): ClientRequest; - export var globalAgent: Agent; + export var STATUS_CODES: { + [errorCode: number]: string | undefined; + [errorCode: string]: string | undefined; + }; + + export function createServer(requestListener?: (request: IncomingMessage, response: ServerResponse) => void): Server; + export function createClient(port?: number, host?: string): any; + + // although RequestOptions are passed as ClientRequestArgs to ClientRequest directly, + // create interface RequestOptions would make the naming more clear to developers + export interface RequestOptions extends ClientRequestArgs { } + export function request(options: RequestOptions | string | URL, callback?: (res: IncomingMessage) => void): ClientRequest; + export function get(options: RequestOptions | string | URL, callback?: (res: IncomingMessage) => void): ClientRequest; + export var globalAgent: Agent; } declare module "cluster" { - import * as child from "child_process"; - import * as events from "events"; - import * as net from "net"; + import * as child from "child_process"; + import * as events from "events"; + import * as net from "net"; - // interfaces - export interface ClusterSettings { - execArgv?: string[]; // default: process.execArgv - exec?: string; - args?: string[]; - silent?: boolean; - stdio?: any[]; - uid?: number; - gid?: number; - } + // interfaces + export interface ClusterSettings { + execArgv?: string[]; // default: process.execArgv + exec?: string; + args?: string[]; + silent?: boolean; + stdio?: any[]; + uid?: number; + gid?: number; + inspectPort?: number | (() => number); + } - export interface ClusterSetupMasterSettings { - exec?: string; // default: process.argv[1] - args?: string[]; // default: process.argv.slice(2) - silent?: boolean; // default: false - stdio?: any[]; - } + export interface Address { + address: string; + port: number; + addressType: number | "udp4" | "udp6"; // 4, 6, -1, "udp4", "udp6" + } - export interface Address { - address: string; - port: number; - addressType: number | "udp4" | "udp6"; // 4, 6, -1, "udp4", "udp6" - } - - export class Worker extends events.EventEmitter { - id: string; - process: child.ChildProcess; - suicide: boolean; - send(message: any, sendHandle?: any, callback?: (error: Error) => void): boolean; - kill(signal?: string): void; - destroy(signal?: string): void; - disconnect(): void; - isConnected(): boolean; - isDead(): boolean; - exitedAfterDisconnect: boolean; + export class Worker extends events.EventEmitter { + id: number; + process: child.ChildProcess; + suicide: boolean; + send(message: any, sendHandle?: any, callback?: (error: Error) => void): boolean; + kill(signal?: string): void; + destroy(signal?: string): void; + disconnect(): void; + isConnected(): boolean; + isDead(): boolean; + exitedAfterDisconnect: boolean; /** * events.EventEmitter @@ -873,68 +1224,68 @@ declare module "cluster" { * 5. message * 6. online */ - addListener(event: string, listener: Function): this; - addListener(event: "disconnect", listener: () => void): this; - addListener(event: "error", listener: (error: Error) => void): this; - addListener(event: "exit", listener: (code: number, signal: string) => void): this; - addListener(event: "listening", listener: (address: Address) => void): this; - addListener(event: "message", listener: (message: any, handle: net.Socket | net.Server) => void): this; // the handle is a net.Socket or net.Server object, or undefined. - addListener(event: "online", listener: () => void): this; + addListener(event: string, listener: (...args: any[]) => void): this; + addListener(event: "disconnect", listener: () => void): this; + addListener(event: "error", listener: (error: Error) => void): this; + addListener(event: "exit", listener: (code: number, signal: string) => void): this; + addListener(event: "listening", listener: (address: Address) => void): this; + addListener(event: "message", listener: (message: any, handle: net.Socket | net.Server) => void): this; // the handle is a net.Socket or net.Server object, or undefined. + addListener(event: "online", listener: () => void): this; - emit(event: string | symbol, ...args: any[]): boolean; - emit(event: "disconnect", listener: () => void): boolean - emit(event: "error", listener: (error: Error) => void): boolean - emit(event: "exit", listener: (code: number, signal: string) => void): boolean - emit(event: "listening", listener: (address: Address) => void): boolean - emit(event: "message", listener: (message: any, handle: net.Socket | net.Server) => void): boolean - emit(event: "online", listener: () => void): boolean + emit(event: string | symbol, ...args: any[]): boolean; + emit(event: "disconnect"): boolean; + emit(event: "error", error: Error): boolean; + emit(event: "exit", code: number, signal: string): boolean; + emit(event: "listening", address: Address): boolean; + emit(event: "message", message: any, handle: net.Socket | net.Server): boolean; + emit(event: "online"): boolean; - on(event: string, listener: Function): this; - on(event: "disconnect", listener: () => void): this; - on(event: "error", listener: (error: Error) => void): this; - on(event: "exit", listener: (code: number, signal: string) => void): this; - on(event: "listening", listener: (address: Address) => void): this; - on(event: "message", listener: (message: any, handle: net.Socket | net.Server) => void): this; // the handle is a net.Socket or net.Server object, or undefined. - on(event: "online", listener: () => void): this; + on(event: string, listener: (...args: any[]) => void): this; + on(event: "disconnect", listener: () => void): this; + on(event: "error", listener: (error: Error) => void): this; + on(event: "exit", listener: (code: number, signal: string) => void): this; + on(event: "listening", listener: (address: Address) => void): this; + on(event: "message", listener: (message: any, handle: net.Socket | net.Server) => void): this; // the handle is a net.Socket or net.Server object, or undefined. + on(event: "online", listener: () => void): this; - once(event: string, listener: Function): this; - once(event: "disconnect", listener: () => void): this; - once(event: "error", listener: (error: Error) => void): this; - once(event: "exit", listener: (code: number, signal: string) => void): this; - once(event: "listening", listener: (address: Address) => void): this; - once(event: "message", listener: (message: any, handle: net.Socket | net.Server) => void): this; // the handle is a net.Socket or net.Server object, or undefined. - once(event: "online", listener: () => void): this; + once(event: string, listener: (...args: any[]) => void): this; + once(event: "disconnect", listener: () => void): this; + once(event: "error", listener: (error: Error) => void): this; + once(event: "exit", listener: (code: number, signal: string) => void): this; + once(event: "listening", listener: (address: Address) => void): this; + once(event: "message", listener: (message: any, handle: net.Socket | net.Server) => void): this; // the handle is a net.Socket or net.Server object, or undefined. + once(event: "online", listener: () => void): this; - prependListener(event: string, listener: Function): this; - prependListener(event: "disconnect", listener: () => void): this; - prependListener(event: "error", listener: (error: Error) => void): this; - prependListener(event: "exit", listener: (code: number, signal: string) => void): this; - prependListener(event: "listening", listener: (address: Address) => void): this; - prependListener(event: "message", listener: (message: any, handle: net.Socket | net.Server) => void): this; // the handle is a net.Socket or net.Server object, or undefined. - prependListener(event: "online", listener: () => void): this; + prependListener(event: string, listener: (...args: any[]) => void): this; + prependListener(event: "disconnect", listener: () => void): this; + prependListener(event: "error", listener: (error: Error) => void): this; + prependListener(event: "exit", listener: (code: number, signal: string) => void): this; + prependListener(event: "listening", listener: (address: Address) => void): this; + prependListener(event: "message", listener: (message: any, handle: net.Socket | net.Server) => void): this; // the handle is a net.Socket or net.Server object, or undefined. + prependListener(event: "online", listener: () => void): this; - prependOnceListener(event: string, listener: Function): this; - prependOnceListener(event: "disconnect", listener: () => void): this; - prependOnceListener(event: "error", listener: (error: Error) => void): this; - prependOnceListener(event: "exit", listener: (code: number, signal: string) => void): this; - prependOnceListener(event: "listening", listener: (address: Address) => void): this; - prependOnceListener(event: "message", listener: (message: any, handle: net.Socket | net.Server) => void): this; // the handle is a net.Socket or net.Server object, or undefined. - prependOnceListener(event: "online", listener: () => void): this; - } + prependOnceListener(event: string, listener: (...args: any[]) => void): this; + prependOnceListener(event: "disconnect", listener: () => void): this; + prependOnceListener(event: "error", listener: (error: Error) => void): this; + prependOnceListener(event: "exit", listener: (code: number, signal: string) => void): this; + prependOnceListener(event: "listening", listener: (address: Address) => void): this; + prependOnceListener(event: "message", listener: (message: any, handle: net.Socket | net.Server) => void): this; // the handle is a net.Socket or net.Server object, or undefined. + prependOnceListener(event: "online", listener: () => void): this; + } - export interface Cluster extends events.EventEmitter { - Worker: Worker; - disconnect(callback?: Function): void; - fork(env?: any): Worker; - isMaster: boolean; - isWorker: boolean; - // TODO: cluster.schedulingPolicy - settings: ClusterSettings; - setupMaster(settings?: ClusterSetupMasterSettings): void; - worker: Worker; - workers: { - [index: string]: Worker - }; + export interface Cluster extends events.EventEmitter { + Worker: Worker; + disconnect(callback?: Function): void; + fork(env?: any): Worker; + isMaster: boolean; + isWorker: boolean; + // TODO: cluster.schedulingPolicy + settings: ClusterSettings; + setupMaster(settings?: ClusterSettings): void; + worker?: Worker; + workers?: { + [index: string]: Worker | undefined + }; /** * events.EventEmitter @@ -946,73 +1297,72 @@ declare module "cluster" { * 6. online * 7. setup */ - addListener(event: string, listener: Function): this; - addListener(event: "disconnect", listener: (worker: Worker) => void): this; - addListener(event: "exit", listener: (worker: Worker, code: number, signal: string) => void): this; - addListener(event: "fork", listener: (worker: Worker) => void): this; - addListener(event: "listening", listener: (worker: Worker, address: Address) => void): this; - addListener(event: "message", listener: (worker: Worker, message: any, handle: net.Socket | net.Server) => void): this; // the handle is a net.Socket or net.Server object, or undefined. - addListener(event: "online", listener: (worker: Worker) => void): this; - addListener(event: "setup", listener: (settings: any) => void): this; + addListener(event: string, listener: (...args: any[]) => void): this; + addListener(event: "disconnect", listener: (worker: Worker) => void): this; + addListener(event: "exit", listener: (worker: Worker, code: number, signal: string) => void): this; + addListener(event: "fork", listener: (worker: Worker) => void): this; + addListener(event: "listening", listener: (worker: Worker, address: Address) => void): this; + addListener(event: "message", listener: (worker: Worker, message: any, handle: net.Socket | net.Server) => void): this; // the handle is a net.Socket or net.Server object, or undefined. + addListener(event: "online", listener: (worker: Worker) => void): this; + addListener(event: "setup", listener: (settings: any) => void): this; - emit(event: string | symbol, ...args: any[]): boolean; - emit(event: "disconnect", listener: (worker: Worker) => void): boolean; - emit(event: "exit", listener: (worker: Worker, code: number, signal: string) => void): boolean; - emit(event: "fork", listener: (worker: Worker) => void): boolean; - emit(event: "listening", listener: (worker: Worker, address: Address) => void): boolean; - emit(event: "message", listener: (worker: Worker, message: any, handle: net.Socket | net.Server) => void): boolean; - emit(event: "online", listener: (worker: Worker) => void): boolean; - emit(event: "setup", listener: (settings: any) => void): boolean; + emit(event: string | symbol, ...args: any[]): boolean; + emit(event: "disconnect", worker: Worker): boolean; + emit(event: "exit", worker: Worker, code: number, signal: string): boolean; + emit(event: "fork", worker: Worker): boolean; + emit(event: "listening", worker: Worker, address: Address): boolean; + emit(event: "message", worker: Worker, message: any, handle: net.Socket | net.Server): boolean; + emit(event: "online", worker: Worker): boolean; + emit(event: "setup", settings: any): boolean; - on(event: string, listener: Function): this; - on(event: "disconnect", listener: (worker: Worker) => void): this; - on(event: "exit", listener: (worker: Worker, code: number, signal: string) => void): this; - on(event: "fork", listener: (worker: Worker) => void): this; - on(event: "listening", listener: (worker: Worker, address: Address) => void): this; - on(event: "message", listener: (worker: Worker, message: any, handle: net.Socket | net.Server) => void): this; // the handle is a net.Socket or net.Server object, or undefined. - on(event: "online", listener: (worker: Worker) => void): this; - on(event: "setup", listener: (settings: any) => void): this; + on(event: string, listener: (...args: any[]) => void): this; + on(event: "disconnect", listener: (worker: Worker) => void): this; + on(event: "exit", listener: (worker: Worker, code: number, signal: string) => void): this; + on(event: "fork", listener: (worker: Worker) => void): this; + on(event: "listening", listener: (worker: Worker, address: Address) => void): this; + on(event: "message", listener: (worker: Worker, message: any, handle: net.Socket | net.Server) => void): this; // the handle is a net.Socket or net.Server object, or undefined. + on(event: "online", listener: (worker: Worker) => void): this; + on(event: "setup", listener: (settings: any) => void): this; - once(event: string, listener: Function): this; - once(event: "disconnect", listener: (worker: Worker) => void): this; - once(event: "exit", listener: (worker: Worker, code: number, signal: string) => void): this; - once(event: "fork", listener: (worker: Worker) => void): this; - once(event: "listening", listener: (worker: Worker, address: Address) => void): this; - once(event: "message", listener: (worker: Worker, message: any, handle: net.Socket | net.Server) => void): this; // the handle is a net.Socket or net.Server object, or undefined. - once(event: "online", listener: (worker: Worker) => void): this; - once(event: "setup", listener: (settings: any) => void): this; + once(event: string, listener: (...args: any[]) => void): this; + once(event: "disconnect", listener: (worker: Worker) => void): this; + once(event: "exit", listener: (worker: Worker, code: number, signal: string) => void): this; + once(event: "fork", listener: (worker: Worker) => void): this; + once(event: "listening", listener: (worker: Worker, address: Address) => void): this; + once(event: "message", listener: (worker: Worker, message: any, handle: net.Socket | net.Server) => void): this; // the handle is a net.Socket or net.Server object, or undefined. + once(event: "online", listener: (worker: Worker) => void): this; + once(event: "setup", listener: (settings: any) => void): this; - prependListener(event: string, listener: Function): this; - prependListener(event: "disconnect", listener: (worker: Worker) => void): this; - prependListener(event: "exit", listener: (worker: Worker, code: number, signal: string) => void): this; - prependListener(event: "fork", listener: (worker: Worker) => void): this; - prependListener(event: "listening", listener: (worker: Worker, address: Address) => void): this; - prependListener(event: "message", listener: (worker: Worker, message: any, handle: net.Socket | net.Server) => void): this; // the handle is a net.Socket or net.Server object, or undefined. - prependListener(event: "online", listener: (worker: Worker) => void): this; - prependListener(event: "setup", listener: (settings: any) => void): this; + prependListener(event: string, listener: (...args: any[]) => void): this; + prependListener(event: "disconnect", listener: (worker: Worker) => void): this; + prependListener(event: "exit", listener: (worker: Worker, code: number, signal: string) => void): this; + prependListener(event: "fork", listener: (worker: Worker) => void): this; + prependListener(event: "listening", listener: (worker: Worker, address: Address) => void): this; + prependListener(event: "message", listener: (worker: Worker, message: any, handle: net.Socket | net.Server) => void): this; // the handle is a net.Socket or net.Server object, or undefined. + prependListener(event: "online", listener: (worker: Worker) => void): this; + prependListener(event: "setup", listener: (settings: any) => void): this; - prependOnceListener(event: string, listener: Function): this; - prependOnceListener(event: "disconnect", listener: (worker: Worker) => void): this; - prependOnceListener(event: "exit", listener: (worker: Worker, code: number, signal: string) => void): this; - prependOnceListener(event: "fork", listener: (worker: Worker) => void): this; - prependOnceListener(event: "listening", listener: (worker: Worker, address: Address) => void): this; - prependOnceListener(event: "message", listener: (worker: Worker, message: any, handle: net.Socket | net.Server) => void): this; // the handle is a net.Socket or net.Server object, or undefined. - prependOnceListener(event: "online", listener: (worker: Worker) => void): this; - prependOnceListener(event: "setup", listener: (settings: any) => void): this; + prependOnceListener(event: string, listener: (...args: any[]) => void): this; + prependOnceListener(event: "disconnect", listener: (worker: Worker) => void): this; + prependOnceListener(event: "exit", listener: (worker: Worker, code: number, signal: string) => void): this; + prependOnceListener(event: "fork", listener: (worker: Worker) => void): this; + prependOnceListener(event: "listening", listener: (worker: Worker, address: Address) => void): this; + prependOnceListener(event: "message", listener: (worker: Worker, message: any, handle: net.Socket | net.Server) => void): this; // the handle is a net.Socket or net.Server object, or undefined. + prependOnceListener(event: "online", listener: (worker: Worker) => void): this; + prependOnceListener(event: "setup", listener: (settings: any) => void): this; + } - } - - export function disconnect(callback?: Function): void; - export function fork(env?: any): Worker; - export var isMaster: boolean; - export var isWorker: boolean; - // TODO: cluster.schedulingPolicy - export var settings: ClusterSettings; - export function setupMaster(settings?: ClusterSetupMasterSettings): void; - export var worker: Worker; - export var workers: { - [index: string]: Worker - }; + export function disconnect(callback?: Function): void; + export function fork(env?: any): Worker; + export var isMaster: boolean; + export var isWorker: boolean; + // TODO: cluster.schedulingPolicy + export var settings: ClusterSettings; + export function setupMaster(settings?: ClusterSettings): void; + export var worker: Worker; + export var workers: { + [index: string]: Worker | undefined + }; /** * events.EventEmitter @@ -1024,499 +1374,522 @@ declare module "cluster" { * 6. online * 7. setup */ - export function addListener(event: string, listener: Function): Cluster; - export function addListener(event: "disconnect", listener: (worker: Worker) => void): Cluster; - export function addListener(event: "exit", listener: (worker: Worker, code: number, signal: string) => void): Cluster; - export function addListener(event: "fork", listener: (worker: Worker) => void): Cluster; - export function addListener(event: "listening", listener: (worker: Worker, address: Address) => void): Cluster; - export function addListener(event: "message", listener: (worker: Worker, message: any, handle: net.Socket | net.Server) => void): Cluster; // the handle is a net.Socket or net.Server object, or undefined. - export function addListener(event: "online", listener: (worker: Worker) => void): Cluster; - export function addListener(event: "setup", listener: (settings: any) => void): Cluster; + export function addListener(event: string, listener: (...args: any[]) => void): Cluster; + export function addListener(event: "disconnect", listener: (worker: Worker) => void): Cluster; + export function addListener(event: "exit", listener: (worker: Worker, code: number, signal: string) => void): Cluster; + export function addListener(event: "fork", listener: (worker: Worker) => void): Cluster; + export function addListener(event: "listening", listener: (worker: Worker, address: Address) => void): Cluster; + export function addListener(event: "message", listener: (worker: Worker, message: any, handle: net.Socket | net.Server) => void): Cluster; // the handle is a net.Socket or net.Server object, or undefined. + export function addListener(event: "online", listener: (worker: Worker) => void): Cluster; + export function addListener(event: "setup", listener: (settings: any) => void): Cluster; - export function emit(event: string | symbol, ...args: any[]): boolean; - export function emit(event: "disconnect", listener: (worker: Worker) => void): boolean; - export function emit(event: "exit", listener: (worker: Worker, code: number, signal: string) => void): boolean; - export function emit(event: "fork", listener: (worker: Worker) => void): boolean; - export function emit(event: "listening", listener: (worker: Worker, address: Address) => void): boolean; - export function emit(event: "message", listener: (worker: Worker, message: any, handle: net.Socket | net.Server) => void): boolean; - export function emit(event: "online", listener: (worker: Worker) => void): boolean; - export function emit(event: "setup", listener: (settings: any) => void): boolean; + export function emit(event: string | symbol, ...args: any[]): boolean; + export function emit(event: "disconnect", worker: Worker): boolean; + export function emit(event: "exit", worker: Worker, code: number, signal: string): boolean; + export function emit(event: "fork", worker: Worker): boolean; + export function emit(event: "listening", worker: Worker, address: Address): boolean; + export function emit(event: "message", worker: Worker, message: any, handle: net.Socket | net.Server): boolean; + export function emit(event: "online", worker: Worker): boolean; + export function emit(event: "setup", settings: any): boolean; - export function on(event: string, listener: Function): Cluster; - export function on(event: "disconnect", listener: (worker: Worker) => void): Cluster; - export function on(event: "exit", listener: (worker: Worker, code: number, signal: string) => void): Cluster; - export function on(event: "fork", listener: (worker: Worker) => void): Cluster; - export function on(event: "listening", listener: (worker: Worker, address: Address) => void): Cluster; - export function on(event: "message", listener: (worker: Worker, message: any, handle: net.Socket | net.Server) => void): Cluster; // the handle is a net.Socket or net.Server object, or undefined. - export function on(event: "online", listener: (worker: Worker) => void): Cluster; - export function on(event: "setup", listener: (settings: any) => void): Cluster; + export function on(event: string, listener: (...args: any[]) => void): Cluster; + export function on(event: "disconnect", listener: (worker: Worker) => void): Cluster; + export function on(event: "exit", listener: (worker: Worker, code: number, signal: string) => void): Cluster; + export function on(event: "fork", listener: (worker: Worker) => void): Cluster; + export function on(event: "listening", listener: (worker: Worker, address: Address) => void): Cluster; + export function on(event: "message", listener: (worker: Worker, message: any, handle: net.Socket | net.Server) => void): Cluster; // the handle is a net.Socket or net.Server object, or undefined. + export function on(event: "online", listener: (worker: Worker) => void): Cluster; + export function on(event: "setup", listener: (settings: any) => void): Cluster; - export function once(event: string, listener: Function): Cluster; - export function once(event: "disconnect", listener: (worker: Worker) => void): Cluster; - export function once(event: "exit", listener: (worker: Worker, code: number, signal: string) => void): Cluster; - export function once(event: "fork", listener: (worker: Worker) => void): Cluster; - export function once(event: "listening", listener: (worker: Worker, address: Address) => void): Cluster; - export function once(event: "message", listener: (worker: Worker, message: any, handle: net.Socket | net.Server) => void): Cluster; // the handle is a net.Socket or net.Server object, or undefined. - export function once(event: "online", listener: (worker: Worker) => void): Cluster; - export function once(event: "setup", listener: (settings: any) => void): Cluster; + export function once(event: string, listener: (...args: any[]) => void): Cluster; + export function once(event: "disconnect", listener: (worker: Worker) => void): Cluster; + export function once(event: "exit", listener: (worker: Worker, code: number, signal: string) => void): Cluster; + export function once(event: "fork", listener: (worker: Worker) => void): Cluster; + export function once(event: "listening", listener: (worker: Worker, address: Address) => void): Cluster; + export function once(event: "message", listener: (worker: Worker, message: any, handle: net.Socket | net.Server) => void): Cluster; // the handle is a net.Socket or net.Server object, or undefined. + export function once(event: "online", listener: (worker: Worker) => void): Cluster; + export function once(event: "setup", listener: (settings: any) => void): Cluster; - export function removeListener(event: string, listener: Function): Cluster; - export function removeAllListeners(event?: string): Cluster; - export function setMaxListeners(n: number): Cluster; - export function getMaxListeners(): number; - export function listeners(event: string): Function[]; - export function listenerCount(type: string): number; + export function removeListener(event: string, listener: (...args: any[]) => void): Cluster; + export function removeAllListeners(event?: string): Cluster; + export function setMaxListeners(n: number): Cluster; + export function getMaxListeners(): number; + export function listeners(event: string): Function[]; + export function listenerCount(type: string): number; - export function prependListener(event: string, listener: Function): Cluster; - export function prependListener(event: "disconnect", listener: (worker: Worker) => void): Cluster; - export function prependListener(event: "exit", listener: (worker: Worker, code: number, signal: string) => void): Cluster; - export function prependListener(event: "fork", listener: (worker: Worker) => void): Cluster; - export function prependListener(event: "listening", listener: (worker: Worker, address: Address) => void): Cluster; - export function prependListener(event: "message", listener: (worker: Worker, message: any, handle: net.Socket | net.Server) => void): Cluster; // the handle is a net.Socket or net.Server object, or undefined. - export function prependListener(event: "online", listener: (worker: Worker) => void): Cluster; - export function prependListener(event: "setup", listener: (settings: any) => void): Cluster; + export function prependListener(event: string, listener: (...args: any[]) => void): Cluster; + export function prependListener(event: "disconnect", listener: (worker: Worker) => void): Cluster; + export function prependListener(event: "exit", listener: (worker: Worker, code: number, signal: string) => void): Cluster; + export function prependListener(event: "fork", listener: (worker: Worker) => void): Cluster; + export function prependListener(event: "listening", listener: (worker: Worker, address: Address) => void): Cluster; + export function prependListener(event: "message", listener: (worker: Worker, message: any, handle: net.Socket | net.Server) => void): Cluster; // the handle is a net.Socket or net.Server object, or undefined. + export function prependListener(event: "online", listener: (worker: Worker) => void): Cluster; + export function prependListener(event: "setup", listener: (settings: any) => void): Cluster; - export function prependOnceListener(event: string, listener: Function): Cluster; - export function prependOnceListener(event: "disconnect", listener: (worker: Worker) => void): Cluster; - export function prependOnceListener(event: "exit", listener: (worker: Worker, code: number, signal: string) => void): Cluster; - export function prependOnceListener(event: "fork", listener: (worker: Worker) => void): Cluster; - export function prependOnceListener(event: "listening", listener: (worker: Worker, address: Address) => void): Cluster; - export function prependOnceListener(event: "message", listener: (worker: Worker, message: any, handle: net.Socket | net.Server) => void): Cluster; // the handle is a net.Socket or net.Server object, or undefined. - export function prependOnceListener(event: "online", listener: (worker: Worker) => void): Cluster; - export function prependOnceListener(event: "setup", listener: (settings: any) => void): Cluster; + export function prependOnceListener(event: string, listener: (...args: any[]) => void): Cluster; + export function prependOnceListener(event: "disconnect", listener: (worker: Worker) => void): Cluster; + export function prependOnceListener(event: "exit", listener: (worker: Worker, code: number, signal: string) => void): Cluster; + export function prependOnceListener(event: "fork", listener: (worker: Worker) => void): Cluster; + export function prependOnceListener(event: "listening", listener: (worker: Worker, address: Address) => void): Cluster; + export function prependOnceListener(event: "message", listener: (worker: Worker, message: any, handle: net.Socket | net.Server) => void): Cluster; // the handle is a net.Socket or net.Server object, or undefined. + export function prependOnceListener(event: "online", listener: (worker: Worker) => void): Cluster; + export function prependOnceListener(event: "setup", listener: (settings: any) => void): Cluster; - export function eventNames(): string[]; + export function eventNames(): string[]; } declare module "zlib" { - import * as stream from "stream"; + import * as stream from "stream"; - export interface ZlibOptions { - flush?: number; // default: zlib.constants.Z_NO_FLUSH - finishFlush?: number; // default: zlib.constants.Z_FINISH - chunkSize?: number; // default: 16*1024 - windowBits?: number; - level?: number; // compression only - memLevel?: number; // compression only - strategy?: number; // compression only - dictionary?: any; // deflate/inflate only, empty dictionary by default - } + export interface ZlibOptions { + flush?: number; // default: zlib.constants.Z_NO_FLUSH + finishFlush?: number; // default: zlib.constants.Z_FINISH + chunkSize?: number; // default: 16*1024 + windowBits?: number; + level?: number; // compression only + memLevel?: number; // compression only + strategy?: number; // compression only + dictionary?: any; // deflate/inflate only, empty dictionary by default + } - export interface Gzip extends stream.Transform { } - export interface Gunzip extends stream.Transform { } - export interface Deflate extends stream.Transform { } - export interface Inflate extends stream.Transform { } - export interface DeflateRaw extends stream.Transform { } - export interface InflateRaw extends stream.Transform { } - export interface Unzip extends stream.Transform { } + export interface Zlib { + readonly bytesRead: number; + close(callback?: () => void): void; + flush(kind?: number | (() => void), callback?: () => void): void; + } - export function createGzip(options?: ZlibOptions): Gzip; - export function createGunzip(options?: ZlibOptions): Gunzip; - export function createDeflate(options?: ZlibOptions): Deflate; - export function createInflate(options?: ZlibOptions): Inflate; - export function createDeflateRaw(options?: ZlibOptions): DeflateRaw; - export function createInflateRaw(options?: ZlibOptions): InflateRaw; - export function createUnzip(options?: ZlibOptions): Unzip; + export interface ZlibParams { + params(level: number, strategy: number, callback: () => void): void; + } - export function deflate(buf: Buffer | string, callback: (error: Error, result: Buffer) => void): void; - export function deflate(buf: Buffer | string, options: ZlibOptions, callback: (error: Error, result: Buffer) => void): void; - export function deflateSync(buf: Buffer | string, options?: ZlibOptions): Buffer; - export function deflateRaw(buf: Buffer | string, callback: (error: Error, result: Buffer) => void): void; - export function deflateRaw(buf: Buffer | string, options: ZlibOptions, callback: (error: Error, result: Buffer) => void): void; - export function deflateRawSync(buf: Buffer | string, options?: ZlibOptions): Buffer; - export function gzip(buf: Buffer | string, callback: (error: Error, result: Buffer) => void): void; - export function gzip(buf: Buffer | string, options: ZlibOptions, callback: (error: Error, result: Buffer) => void): void; - export function gzipSync(buf: Buffer | string, options?: ZlibOptions): Buffer; - export function gunzip(buf: Buffer | string, callback: (error: Error, result: Buffer) => void): void; - export function gunzip(buf: Buffer | string, options: ZlibOptions, callback: (error: Error, result: Buffer) => void): void; - export function gunzipSync(buf: Buffer | string, options?: ZlibOptions): Buffer; - export function inflate(buf: Buffer | string, callback: (error: Error, result: Buffer) => void): void; - export function inflate(buf: Buffer | string, options: ZlibOptions, callback: (error: Error, result: Buffer) => void): void; - export function inflateSync(buf: Buffer | string, options?: ZlibOptions): Buffer; - export function inflateRaw(buf: Buffer | string, callback: (error: Error, result: Buffer) => void): void; - export function inflateRaw(buf: Buffer | string, options: ZlibOptions, callback: (error: Error, result: Buffer) => void): void; - export function inflateRawSync(buf: Buffer | string, options?: ZlibOptions): Buffer; - export function unzip(buf: Buffer | string, callback: (error: Error, result: Buffer) => void): void; - export function unzip(buf: Buffer | string, options: ZlibOptions, callback: (error: Error, result: Buffer) => void): void; - export function unzipSync(buf: Buffer | string, options?: ZlibOptions): Buffer; + export interface ZlibReset { + reset(): void; + } - export namespace constants { - // Allowed flush values. + export interface Gzip extends stream.Transform, Zlib { } + export interface Gunzip extends stream.Transform, Zlib { } + export interface Deflate extends stream.Transform, Zlib, ZlibReset, ZlibParams { } + export interface Inflate extends stream.Transform, Zlib, ZlibReset { } + export interface DeflateRaw extends stream.Transform, Zlib, ZlibReset, ZlibParams { } + export interface InflateRaw extends stream.Transform, Zlib, ZlibReset { } + export interface Unzip extends stream.Transform, Zlib { } - export const Z_NO_FLUSH: number; - export const Z_PARTIAL_FLUSH: number; - export const Z_SYNC_FLUSH: number; - export const Z_FULL_FLUSH: number; - export const Z_FINISH: number; - export const Z_BLOCK: number; - export const Z_TREES: number; + export function createGzip(options?: ZlibOptions): Gzip; + export function createGunzip(options?: ZlibOptions): Gunzip; + export function createDeflate(options?: ZlibOptions): Deflate; + export function createInflate(options?: ZlibOptions): Inflate; + export function createDeflateRaw(options?: ZlibOptions): DeflateRaw; + export function createInflateRaw(options?: ZlibOptions): InflateRaw; + export function createUnzip(options?: ZlibOptions): Unzip; - // Return codes for the compression/decompression functions. Negative values are errors, positive values are used for special but normal events. + type InputType = string | Buffer | DataView /* | TypedArray */; + export function deflate(buf: InputType, callback: (error: Error | null, result: Buffer) => void): void; + export function deflate(buf: InputType, options: ZlibOptions, callback: (error: Error | null, result: Buffer) => void): void; + export function deflateSync(buf: InputType, options?: ZlibOptions): Buffer; + export function deflateRaw(buf: InputType, callback: (error: Error | null, result: Buffer) => void): void; + export function deflateRaw(buf: InputType, options: ZlibOptions, callback: (error: Error | null, result: Buffer) => void): void; + export function deflateRawSync(buf: InputType, options?: ZlibOptions): Buffer; + export function gzip(buf: InputType, callback: (error: Error | null, result: Buffer) => void): void; + export function gzip(buf: InputType, options: ZlibOptions, callback: (error: Error | null, result: Buffer) => void): void; + export function gzipSync(buf: InputType, options?: ZlibOptions): Buffer; + export function gunzip(buf: InputType, callback: (error: Error | null, result: Buffer) => void): void; + export function gunzip(buf: InputType, options: ZlibOptions, callback: (error: Error | null, result: Buffer) => void): void; + export function gunzipSync(buf: InputType, options?: ZlibOptions): Buffer; + export function inflate(buf: InputType, callback: (error: Error | null, result: Buffer) => void): void; + export function inflate(buf: InputType, options: ZlibOptions, callback: (error: Error | null, result: Buffer) => void): void; + export function inflateSync(buf: InputType, options?: ZlibOptions): Buffer; + export function inflateRaw(buf: InputType, callback: (error: Error | null, result: Buffer) => void): void; + export function inflateRaw(buf: InputType, options: ZlibOptions, callback: (error: Error | null, result: Buffer) => void): void; + export function inflateRawSync(buf: InputType, options?: ZlibOptions): Buffer; + export function unzip(buf: InputType, callback: (error: Error | null, result: Buffer) => void): void; + export function unzip(buf: InputType, options: ZlibOptions, callback: (error: Error | null, result: Buffer) => void): void; + export function unzipSync(buf: InputType, options?: ZlibOptions): Buffer; - export const Z_OK: number; - export const Z_STREAM_END: number; - export const Z_NEED_DICT: number; - export const Z_ERRNO: number; - export const Z_STREAM_ERROR: number; - export const Z_DATA_ERROR: number; - export const Z_MEM_ERROR: number; - export const Z_BUF_ERROR: number; - export const Z_VERSION_ERROR: number; + export namespace constants { + // Allowed flush values. - // Compression levels. + export const Z_NO_FLUSH: number; + export const Z_PARTIAL_FLUSH: number; + export const Z_SYNC_FLUSH: number; + export const Z_FULL_FLUSH: number; + export const Z_FINISH: number; + export const Z_BLOCK: number; + export const Z_TREES: number; - export const Z_NO_COMPRESSION: number; - export const Z_BEST_SPEED: number; - export const Z_BEST_COMPRESSION: number; - export const Z_DEFAULT_COMPRESSION: number; + // Return codes for the compression/decompression functions. Negative values are errors, positive values are used for special but normal events. - // Compression strategy. + export const Z_OK: number; + export const Z_STREAM_END: number; + export const Z_NEED_DICT: number; + export const Z_ERRNO: number; + export const Z_STREAM_ERROR: number; + export const Z_DATA_ERROR: number; + export const Z_MEM_ERROR: number; + export const Z_BUF_ERROR: number; + export const Z_VERSION_ERROR: number; - export const Z_FILTERED: number; - export const Z_HUFFMAN_ONLY: number; - export const Z_RLE: number; - export const Z_FIXED: number; - export const Z_DEFAULT_STRATEGY: number; - } + // Compression levels. - // Constants - export var Z_NO_FLUSH: number; - export var Z_PARTIAL_FLUSH: number; - export var Z_SYNC_FLUSH: number; - export var Z_FULL_FLUSH: number; - export var Z_FINISH: number; - export var Z_BLOCK: number; - export var Z_TREES: number; - export var Z_OK: number; - export var Z_STREAM_END: number; - export var Z_NEED_DICT: number; - export var Z_ERRNO: number; - export var Z_STREAM_ERROR: number; - export var Z_DATA_ERROR: number; - export var Z_MEM_ERROR: number; - export var Z_BUF_ERROR: number; - export var Z_VERSION_ERROR: number; - export var Z_NO_COMPRESSION: number; - export var Z_BEST_SPEED: number; - export var Z_BEST_COMPRESSION: number; - export var Z_DEFAULT_COMPRESSION: number; - export var Z_FILTERED: number; - export var Z_HUFFMAN_ONLY: number; - export var Z_RLE: number; - export var Z_FIXED: number; - export var Z_DEFAULT_STRATEGY: number; - export var Z_BINARY: number; - export var Z_TEXT: number; - export var Z_ASCII: number; - export var Z_UNKNOWN: number; - export var Z_DEFLATED: number; + export const Z_NO_COMPRESSION: number; + export const Z_BEST_SPEED: number; + export const Z_BEST_COMPRESSION: number; + export const Z_DEFAULT_COMPRESSION: number; + + // Compression strategy. + + export const Z_FILTERED: number; + export const Z_HUFFMAN_ONLY: number; + export const Z_RLE: number; + export const Z_FIXED: number; + export const Z_DEFAULT_STRATEGY: number; + } + + // Constants + export var Z_NO_FLUSH: number; + export var Z_PARTIAL_FLUSH: number; + export var Z_SYNC_FLUSH: number; + export var Z_FULL_FLUSH: number; + export var Z_FINISH: number; + export var Z_BLOCK: number; + export var Z_TREES: number; + export var Z_OK: number; + export var Z_STREAM_END: number; + export var Z_NEED_DICT: number; + export var Z_ERRNO: number; + export var Z_STREAM_ERROR: number; + export var Z_DATA_ERROR: number; + export var Z_MEM_ERROR: number; + export var Z_BUF_ERROR: number; + export var Z_VERSION_ERROR: number; + export var Z_NO_COMPRESSION: number; + export var Z_BEST_SPEED: number; + export var Z_BEST_COMPRESSION: number; + export var Z_DEFAULT_COMPRESSION: number; + export var Z_FILTERED: number; + export var Z_HUFFMAN_ONLY: number; + export var Z_RLE: number; + export var Z_FIXED: number; + export var Z_DEFAULT_STRATEGY: number; + export var Z_BINARY: number; + export var Z_TEXT: number; + export var Z_ASCII: number; + export var Z_UNKNOWN: number; + export var Z_DEFLATED: number; } declare module "os" { - export interface CpuInfo { - model: string; - speed: number; - times: { - user: number; - nice: number; - sys: number; - idle: number; - irq: number; - }; - } + export interface CpuInfo { + model: string; + speed: number; + times: { + user: number; + nice: number; + sys: number; + idle: number; + irq: number; + }; + } - export interface NetworkInterfaceInfo { - address: string; - netmask: string; - family: string; - mac: string; - internal: boolean; - } + export interface NetworkInterfaceBase { + address: string; + netmask: string; + mac: string; + internal: boolean; + } - export function hostname(): string; - export function loadavg(): number[]; - export function uptime(): number; - export function freemem(): number; - export function totalmem(): number; - export function cpus(): CpuInfo[]; - export function type(): string; - export function release(): string; - export function networkInterfaces(): { [index: string]: NetworkInterfaceInfo[] }; - export function homedir(): string; - export function userInfo(options?: { encoding: string }): { username: string, uid: number, gid: number, shell: any, homedir: string } - export var constants: { - UV_UDP_REUSEADDR: number, - signals: { - SIGHUP: number; - SIGINT: number; - SIGQUIT: number; - SIGILL: number; - SIGTRAP: number; - SIGABRT: number; - SIGIOT: number; - SIGBUS: number; - SIGFPE: number; - SIGKILL: number; - SIGUSR1: number; - SIGSEGV: number; - SIGUSR2: number; - SIGPIPE: number; - SIGALRM: number; - SIGTERM: number; - SIGCHLD: number; - SIGSTKFLT: number; - SIGCONT: number; - SIGSTOP: number; - SIGTSTP: number; - SIGTTIN: number; - SIGTTOU: number; - SIGURG: number; - SIGXCPU: number; - SIGXFSZ: number; - SIGVTALRM: number; - SIGPROF: number; - SIGWINCH: number; - SIGIO: number; - SIGPOLL: number; - SIGPWR: number; - SIGSYS: number; - SIGUNUSED: number; - }, - errno: { - E2BIG: number; - EACCES: number; - EADDRINUSE: number; - EADDRNOTAVAIL: number; - EAFNOSUPPORT: number; - EAGAIN: number; - EALREADY: number; - EBADF: number; - EBADMSG: number; - EBUSY: number; - ECANCELED: number; - ECHILD: number; - ECONNABORTED: number; - ECONNREFUSED: number; - ECONNRESET: number; - EDEADLK: number; - EDESTADDRREQ: number; - EDOM: number; - EDQUOT: number; - EEXIST: number; - EFAULT: number; - EFBIG: number; - EHOSTUNREACH: number; - EIDRM: number; - EILSEQ: number; - EINPROGRESS: number; - EINTR: number; - EINVAL: number; - EIO: number; - EISCONN: number; - EISDIR: number; - ELOOP: number; - EMFILE: number; - EMLINK: number; - EMSGSIZE: number; - EMULTIHOP: number; - ENAMETOOLONG: number; - ENETDOWN: number; - ENETRESET: number; - ENETUNREACH: number; - ENFILE: number; - ENOBUFS: number; - ENODATA: number; - ENODEV: number; - ENOENT: number; - ENOEXEC: number; - ENOLCK: number; - ENOLINK: number; - ENOMEM: number; - ENOMSG: number; - ENOPROTOOPT: number; - ENOSPC: number; - ENOSR: number; - ENOSTR: number; - ENOSYS: number; - ENOTCONN: number; - ENOTDIR: number; - ENOTEMPTY: number; - ENOTSOCK: number; - ENOTSUP: number; - ENOTTY: number; - ENXIO: number; - EOPNOTSUPP: number; - EOVERFLOW: number; - EPERM: number; - EPIPE: number; - EPROTO: number; - EPROTONOSUPPORT: number; - EPROTOTYPE: number; - ERANGE: number; - EROFS: number; - ESPIPE: number; - ESRCH: number; - ESTALE: number; - ETIME: number; - ETIMEDOUT: number; - ETXTBSY: number; - EWOULDBLOCK: number; - EXDEV: number; - }, - }; - export function arch(): string; - export function platform(): NodeJS.Platform; - export function tmpdir(): string; - export var EOL: string; - export function endianness(): "BE" | "LE"; + export interface NetworkInterfaceInfoIPv4 extends NetworkInterfaceBase { + family: "IPv4"; + } + + export interface NetworkInterfaceInfoIPv6 extends NetworkInterfaceBase { + family: "IPv6"; + scopeid: number; + } + + export type NetworkInterfaceInfo = NetworkInterfaceInfoIPv4 | NetworkInterfaceInfoIPv6; + + export function hostname(): string; + export function loadavg(): number[]; + export function uptime(): number; + export function freemem(): number; + export function totalmem(): number; + export function cpus(): CpuInfo[]; + export function type(): string; + export function release(): string; + export function networkInterfaces(): { [index: string]: NetworkInterfaceInfo[] }; + export function homedir(): string; + export function userInfo(options?: { encoding: string }): { username: string, uid: number, gid: number, shell: any, homedir: string }; + export var constants: { + UV_UDP_REUSEADDR: number, + signals: { + SIGHUP: number; + SIGINT: number; + SIGQUIT: number; + SIGILL: number; + SIGTRAP: number; + SIGABRT: number; + SIGIOT: number; + SIGBUS: number; + SIGFPE: number; + SIGKILL: number; + SIGUSR1: number; + SIGSEGV: number; + SIGUSR2: number; + SIGPIPE: number; + SIGALRM: number; + SIGTERM: number; + SIGCHLD: number; + SIGSTKFLT: number; + SIGCONT: number; + SIGSTOP: number; + SIGTSTP: number; + SIGTTIN: number; + SIGTTOU: number; + SIGURG: number; + SIGXCPU: number; + SIGXFSZ: number; + SIGVTALRM: number; + SIGPROF: number; + SIGWINCH: number; + SIGIO: number; + SIGPOLL: number; + SIGPWR: number; + SIGSYS: number; + SIGUNUSED: number; + }, + errno: { + E2BIG: number; + EACCES: number; + EADDRINUSE: number; + EADDRNOTAVAIL: number; + EAFNOSUPPORT: number; + EAGAIN: number; + EALREADY: number; + EBADF: number; + EBADMSG: number; + EBUSY: number; + ECANCELED: number; + ECHILD: number; + ECONNABORTED: number; + ECONNREFUSED: number; + ECONNRESET: number; + EDEADLK: number; + EDESTADDRREQ: number; + EDOM: number; + EDQUOT: number; + EEXIST: number; + EFAULT: number; + EFBIG: number; + EHOSTUNREACH: number; + EIDRM: number; + EILSEQ: number; + EINPROGRESS: number; + EINTR: number; + EINVAL: number; + EIO: number; + EISCONN: number; + EISDIR: number; + ELOOP: number; + EMFILE: number; + EMLINK: number; + EMSGSIZE: number; + EMULTIHOP: number; + ENAMETOOLONG: number; + ENETDOWN: number; + ENETRESET: number; + ENETUNREACH: number; + ENFILE: number; + ENOBUFS: number; + ENODATA: number; + ENODEV: number; + ENOENT: number; + ENOEXEC: number; + ENOLCK: number; + ENOLINK: number; + ENOMEM: number; + ENOMSG: number; + ENOPROTOOPT: number; + ENOSPC: number; + ENOSR: number; + ENOSTR: number; + ENOSYS: number; + ENOTCONN: number; + ENOTDIR: number; + ENOTEMPTY: number; + ENOTSOCK: number; + ENOTSUP: number; + ENOTTY: number; + ENXIO: number; + EOPNOTSUPP: number; + EOVERFLOW: number; + EPERM: number; + EPIPE: number; + EPROTO: number; + EPROTONOSUPPORT: number; + EPROTOTYPE: number; + ERANGE: number; + EROFS: number; + ESPIPE: number; + ESRCH: number; + ESTALE: number; + ETIME: number; + ETIMEDOUT: number; + ETXTBSY: number; + EWOULDBLOCK: number; + EXDEV: number; + }, + }; + export function arch(): string; + export function platform(): NodeJS.Platform; + export function tmpdir(): string; + export const EOL: string; + export function endianness(): "BE" | "LE"; } declare module "https" { - import * as tls from "tls"; - import * as events from "events"; - import * as http from "http"; + import * as tls from "tls"; + import * as events from "events"; + import * as http from "http"; + import { URL } from "url"; - export interface ServerOptions { - pfx?: any; - key?: any; - passphrase?: string; - cert?: any; - ca?: any; - crl?: any; - ciphers?: string; - honorCipherOrder?: boolean; - requestCert?: boolean; - rejectUnauthorized?: boolean; - NPNProtocols?: any; - SNICallback?: (servername: string, cb: (err: Error, ctx: tls.SecureContext) => any) => any; - } + export type ServerOptions = tls.SecureContextOptions & tls.TlsOptions; - export interface RequestOptions extends http.RequestOptions { - pfx?: any; - key?: any; - passphrase?: string; - cert?: any; - ca?: any; - ciphers?: string; - rejectUnauthorized?: boolean; - secureProtocol?: string; - } + // see https://nodejs.org/docs/latest-v8.x/api/https.html#https_https_request_options_callback + type extendedRequestKeys = "pfx" | + "key" | + "passphrase" | + "cert" | + "ca" | + "ciphers" | + "rejectUnauthorized" | + "secureProtocol" | + "servername"; - export interface Agent extends http.Agent { } + export type RequestOptions = http.RequestOptions & Pick; - export interface AgentOptions extends http.AgentOptions { - pfx?: any; - key?: any; - passphrase?: string; - cert?: any; - ca?: any; - ciphers?: string; - rejectUnauthorized?: boolean; - secureProtocol?: string; - maxCachedSessions?: number; - } + export interface AgentOptions extends http.AgentOptions, tls.ConnectionOptions { + rejectUnauthorized?: boolean; + maxCachedSessions?: number; + } - export var Agent: { - new(options?: AgentOptions): Agent; - }; - export interface Server extends tls.Server { } - export function createServer(options: ServerOptions, requestListener?: Function): Server; - export function request(options: RequestOptions, callback?: (res: http.IncomingMessage) => void): http.ClientRequest; - export function get(options: RequestOptions, callback?: (res: http.IncomingMessage) => void): http.ClientRequest; - export var globalAgent: Agent; + export class Agent extends http.Agent { + constructor(options?: AgentOptions); + options: AgentOptions; + } + + export class Server extends tls.Server { + setTimeout(callback: () => void): this; + setTimeout(msecs?: number, callback?: () => void): this; + timeout: number; + keepAliveTimeout: number; + } + + export function createServer(options: ServerOptions, requestListener?: (req: http.IncomingMessage, res: http.ServerResponse) => void): Server; + export function request(options: RequestOptions | string | URL, callback?: (res: http.IncomingMessage) => void): http.ClientRequest; + export function get(options: RequestOptions | string | URL, callback?: (res: http.IncomingMessage) => void): http.ClientRequest; + export var globalAgent: Agent; } declare module "punycode" { - export function decode(string: string): string; - export function encode(string: string): string; - export function toUnicode(domain: string): string; - export function toASCII(domain: string): string; - export var ucs2: ucs2; - interface ucs2 { - decode(string: string): number[]; - encode(codePoints: number[]): string; - } - export var version: any; + export function decode(string: string): string; + export function encode(string: string): string; + export function toUnicode(domain: string): string; + export function toASCII(domain: string): string; + export var ucs2: ucs2; + interface ucs2 { + decode(string: string): number[]; + encode(codePoints: number[]): string; + } + export var version: any; } declare module "repl" { - import * as stream from "stream"; - import * as readline from "readline"; + import * as stream from "stream"; + import * as readline from "readline"; - export interface ReplOptions { - prompt?: string; - input?: NodeJS.ReadableStream; - output?: NodeJS.WritableStream; - terminal?: boolean; - eval?: Function; - useColors?: boolean; - useGlobal?: boolean; - ignoreUndefined?: boolean; - writer?: Function; - completer?: Function; - replMode?: any; - breakEvalOnSigint?: any; - } + export interface ReplOptions { + prompt?: string; + input?: NodeJS.ReadableStream; + output?: NodeJS.WritableStream; + terminal?: boolean; + eval?: Function; + useColors?: boolean; + useGlobal?: boolean; + ignoreUndefined?: boolean; + writer?: Function; + completer?: Function; + replMode?: any; + breakEvalOnSigint?: any; + } - export interface REPLServer extends readline.ReadLine { - context: any; - defineCommand(keyword: string, cmd: Function | { help: string, action: Function }): void; - displayPrompt(preserveCursor?: boolean): void; + export interface REPLServer extends readline.ReadLine { + context: any; + inputStream: NodeJS.ReadableStream; + outputStream: NodeJS.WritableStream; + + defineCommand(keyword: string, cmd: Function | { help: string, action: Function }): void; + displayPrompt(preserveCursor?: boolean): void; /** * events.EventEmitter * 1. exit * 2. reset - **/ + */ - addListener(event: string, listener: Function): this; - addListener(event: "exit", listener: () => void): this; - addListener(event: "reset", listener: Function): this; + addListener(event: string, listener: (...args: any[]) => void): this; + addListener(event: "exit", listener: () => void): this; + addListener(event: "reset", listener: (...args: any[]) => void): this; - emit(event: string | symbol, ...args: any[]): boolean; - emit(event: "exit"): boolean; - emit(event: "reset", context: any): boolean; + emit(event: string | symbol, ...args: any[]): boolean; + emit(event: "exit"): boolean; + emit(event: "reset", context: any): boolean; - on(event: string, listener: Function): this; - on(event: "exit", listener: () => void): this; - on(event: "reset", listener: Function): this; + on(event: string, listener: (...args: any[]) => void): this; + on(event: "exit", listener: () => void): this; + on(event: "reset", listener: (...args: any[]) => void): this; - once(event: string, listener: Function): this; - once(event: "exit", listener: () => void): this; - once(event: "reset", listener: Function): this; + once(event: string, listener: (...args: any[]) => void): this; + once(event: "exit", listener: () => void): this; + once(event: "reset", listener: (...args: any[]) => void): this; - prependListener(event: string, listener: Function): this; - prependListener(event: "exit", listener: () => void): this; - prependListener(event: "reset", listener: Function): this; + prependListener(event: string, listener: (...args: any[]) => void): this; + prependListener(event: "exit", listener: () => void): this; + prependListener(event: "reset", listener: (...args: any[]) => void): this; - prependOnceListener(event: string, listener: Function): this; - prependOnceListener(event: "exit", listener: () => void): this; - prependOnceListener(event: "reset", listener: Function): this; - } + prependOnceListener(event: string, listener: (...args: any[]) => void): this; + prependOnceListener(event: "exit", listener: () => void): this; + prependOnceListener(event: "reset", listener: (...args: any[]) => void): this; + } - export function start(options?: string | ReplOptions): REPLServer; + export function start(options?: string | ReplOptions): REPLServer; + + export class Recoverable extends SyntaxError { + err: Error; + + constructor(err: Error); + } } declare module "readline" { - import * as events from "events"; - import * as stream from "stream"; + import * as events from "events"; + import * as stream from "stream"; - export interface Key { - sequence?: string; - name?: string; - ctrl?: boolean; - meta?: boolean; - shift?: boolean; - } + export interface Key { + sequence?: string; + name?: string; + ctrl?: boolean; + meta?: boolean; + shift?: boolean; + } - export interface ReadLine extends events.EventEmitter { - setPrompt(prompt: string): void; - prompt(preserveCursor?: boolean): void; - question(query: string, callback: (answer: string) => void): void; - pause(): ReadLine; - resume(): ReadLine; - close(): void; - write(data: string | Buffer, key?: Key): void; + export interface ReadLine extends events.EventEmitter { + setPrompt(prompt: string): void; + prompt(preserveCursor?: boolean): void; + question(query: string, callback: (answer: string) => void): void; + pause(): ReadLine; + resume(): ReadLine; + close(): void; + write(data: string | Buffer, key?: Key): void; /** * events.EventEmitter @@ -1527,138 +1900,141 @@ declare module "readline" { * 5. SIGCONT * 6. SIGINT * 7. SIGTSTP - **/ + */ - addListener(event: string, listener: Function): this; - addListener(event: "close", listener: () => void): this; - addListener(event: "line", listener: (input: any) => void): this; - addListener(event: "pause", listener: () => void): this; - addListener(event: "resume", listener: () => void): this; - addListener(event: "SIGCONT", listener: () => void): this; - addListener(event: "SIGINT", listener: () => void): this; - addListener(event: "SIGTSTP", listener: () => void): this; + addListener(event: string, listener: (...args: any[]) => void): this; + addListener(event: "close", listener: () => void): this; + addListener(event: "line", listener: (input: any) => void): this; + addListener(event: "pause", listener: () => void): this; + addListener(event: "resume", listener: () => void): this; + addListener(event: "SIGCONT", listener: () => void): this; + addListener(event: "SIGINT", listener: () => void): this; + addListener(event: "SIGTSTP", listener: () => void): this; - emit(event: string | symbol, ...args: any[]): boolean; - emit(event: "close"): boolean; - emit(event: "line", input: any): boolean; - emit(event: "pause"): boolean; - emit(event: "resume"): boolean; - emit(event: "SIGCONT"): boolean; - emit(event: "SIGINT"): boolean; - emit(event: "SIGTSTP"): boolean; + emit(event: string | symbol, ...args: any[]): boolean; + emit(event: "close"): boolean; + emit(event: "line", input: any): boolean; + emit(event: "pause"): boolean; + emit(event: "resume"): boolean; + emit(event: "SIGCONT"): boolean; + emit(event: "SIGINT"): boolean; + emit(event: "SIGTSTP"): boolean; - on(event: string, listener: Function): this; - on(event: "close", listener: () => void): this; - on(event: "line", listener: (input: any) => void): this; - on(event: "pause", listener: () => void): this; - on(event: "resume", listener: () => void): this; - on(event: "SIGCONT", listener: () => void): this; - on(event: "SIGINT", listener: () => void): this; - on(event: "SIGTSTP", listener: () => void): this; + on(event: string, listener: (...args: any[]) => void): this; + on(event: "close", listener: () => void): this; + on(event: "line", listener: (input: any) => void): this; + on(event: "pause", listener: () => void): this; + on(event: "resume", listener: () => void): this; + on(event: "SIGCONT", listener: () => void): this; + on(event: "SIGINT", listener: () => void): this; + on(event: "SIGTSTP", listener: () => void): this; - once(event: string, listener: Function): this; - once(event: "close", listener: () => void): this; - once(event: "line", listener: (input: any) => void): this; - once(event: "pause", listener: () => void): this; - once(event: "resume", listener: () => void): this; - once(event: "SIGCONT", listener: () => void): this; - once(event: "SIGINT", listener: () => void): this; - once(event: "SIGTSTP", listener: () => void): this; + once(event: string, listener: (...args: any[]) => void): this; + once(event: "close", listener: () => void): this; + once(event: "line", listener: (input: any) => void): this; + once(event: "pause", listener: () => void): this; + once(event: "resume", listener: () => void): this; + once(event: "SIGCONT", listener: () => void): this; + once(event: "SIGINT", listener: () => void): this; + once(event: "SIGTSTP", listener: () => void): this; - prependListener(event: string, listener: Function): this; - prependListener(event: "close", listener: () => void): this; - prependListener(event: "line", listener: (input: any) => void): this; - prependListener(event: "pause", listener: () => void): this; - prependListener(event: "resume", listener: () => void): this; - prependListener(event: "SIGCONT", listener: () => void): this; - prependListener(event: "SIGINT", listener: () => void): this; - prependListener(event: "SIGTSTP", listener: () => void): this; + prependListener(event: string, listener: (...args: any[]) => void): this; + prependListener(event: "close", listener: () => void): this; + prependListener(event: "line", listener: (input: any) => void): this; + prependListener(event: "pause", listener: () => void): this; + prependListener(event: "resume", listener: () => void): this; + prependListener(event: "SIGCONT", listener: () => void): this; + prependListener(event: "SIGINT", listener: () => void): this; + prependListener(event: "SIGTSTP", listener: () => void): this; - prependOnceListener(event: string, listener: Function): this; - prependOnceListener(event: "close", listener: () => void): this; - prependOnceListener(event: "line", listener: (input: any) => void): this; - prependOnceListener(event: "pause", listener: () => void): this; - prependOnceListener(event: "resume", listener: () => void): this; - prependOnceListener(event: "SIGCONT", listener: () => void): this; - prependOnceListener(event: "SIGINT", listener: () => void): this; - prependOnceListener(event: "SIGTSTP", listener: () => void): this; - } + prependOnceListener(event: string, listener: (...args: any[]) => void): this; + prependOnceListener(event: "close", listener: () => void): this; + prependOnceListener(event: "line", listener: (input: any) => void): this; + prependOnceListener(event: "pause", listener: () => void): this; + prependOnceListener(event: "resume", listener: () => void): this; + prependOnceListener(event: "SIGCONT", listener: () => void): this; + prependOnceListener(event: "SIGINT", listener: () => void): this; + prependOnceListener(event: "SIGTSTP", listener: () => void): this; + } - type Completer = (line: string) => CompleterResult; - type AsyncCompleter = (line: string, callback: (err: any, result: CompleterResult) => void) => any; + type Completer = (line: string) => CompleterResult; + type AsyncCompleter = (line: string, callback: (err: any, result: CompleterResult) => void) => any; - export type CompleterResult = [string[], string]; + export type CompleterResult = [string[], string]; - export interface ReadLineOptions { - input: NodeJS.ReadableStream; - output?: NodeJS.WritableStream; - completer?: Completer | AsyncCompleter; - terminal?: boolean; - historySize?: number; - prompt?: string; - crlfDelay?: number; - removeHistoryDuplicates?: boolean; - } + export interface ReadLineOptions { + input: NodeJS.ReadableStream; + output?: NodeJS.WritableStream; + completer?: Completer | AsyncCompleter; + terminal?: boolean; + historySize?: number; + prompt?: string; + crlfDelay?: number; + removeHistoryDuplicates?: boolean; + } - export function createInterface(input: NodeJS.ReadableStream, output?: NodeJS.WritableStream, completer?: Completer | AsyncCompleter, terminal?: boolean): ReadLine; - export function createInterface(options: ReadLineOptions): ReadLine; + export function createInterface(input: NodeJS.ReadableStream, output?: NodeJS.WritableStream, completer?: Completer | AsyncCompleter, terminal?: boolean): ReadLine; + export function createInterface(options: ReadLineOptions): ReadLine; - export function cursorTo(stream: NodeJS.WritableStream, x: number, y: number): void; - export function moveCursor(stream: NodeJS.WritableStream, dx: number | string, dy: number | string): void; - export function clearLine(stream: NodeJS.WritableStream, dir: number): void; - export function clearScreenDown(stream: NodeJS.WritableStream): void; + export function cursorTo(stream: NodeJS.WritableStream, x: number, y?: number): void; + export function emitKeypressEvents(stream: NodeJS.ReadableStream, interface?: ReadLine): void; + export function moveCursor(stream: NodeJS.WritableStream, dx: number | string, dy: number | string): void; + export function clearLine(stream: NodeJS.WritableStream, dir: number): void; + export function clearScreenDown(stream: NodeJS.WritableStream): void; } declare module "vm" { - export interface Context { } - export interface ScriptOptions { - filename?: string; - lineOffset?: number; - columnOffset?: number; - displayErrors?: boolean; - timeout?: number; - cachedData?: Buffer; - produceCachedData?: boolean; - } - export interface RunningScriptOptions { - filename?: string; - lineOffset?: number; - columnOffset?: number; - displayErrors?: boolean; - timeout?: number; - } - export class Script { - constructor(code: string, options?: ScriptOptions); - runInContext(contextifiedSandbox: Context, options?: RunningScriptOptions): any; - runInNewContext(sandbox?: Context, options?: RunningScriptOptions): any; - runInThisContext(options?: RunningScriptOptions): any; - } - export function createContext(sandbox?: Context): Context; - export function isContext(sandbox: Context): boolean; - export function runInContext(code: string, contextifiedSandbox: Context, options?: RunningScriptOptions): any; - export function runInDebugContext(code: string): any; - export function runInNewContext(code: string, sandbox?: Context, options?: RunningScriptOptions): any; - export function runInThisContext(code: string, options?: RunningScriptOptions): any; + export interface Context { } + export interface ScriptOptions { + filename?: string; + lineOffset?: number; + columnOffset?: number; + displayErrors?: boolean; + timeout?: number; + cachedData?: Buffer; + produceCachedData?: boolean; + } + export interface RunningScriptOptions { + filename?: string; + lineOffset?: number; + columnOffset?: number; + displayErrors?: boolean; + timeout?: number; + } + export class Script { + constructor(code: string, options?: ScriptOptions); + runInContext(contextifiedSandbox: Context, options?: RunningScriptOptions): any; + runInNewContext(sandbox?: Context, options?: RunningScriptOptions): any; + runInThisContext(options?: RunningScriptOptions): any; + } + export function createContext(sandbox?: Context): Context; + export function isContext(sandbox: Context): boolean; + export function runInContext(code: string, contextifiedSandbox: Context, options?: RunningScriptOptions | string): any; + export function runInDebugContext(code: string): any; + export function runInNewContext(code: string, sandbox?: Context, options?: RunningScriptOptions | string): any; + export function runInThisContext(code: string, options?: RunningScriptOptions | string): any; } declare module "child_process" { - import * as events from "events"; - import * as stream from "stream"; - import * as net from "net"; + import * as events from "events"; + import * as stream from "stream"; + import * as net from "net"; - export interface ChildProcess extends events.EventEmitter { - stdin: stream.Writable; - stdout: stream.Readable; - stderr: stream.Readable; - stdio: [stream.Writable, stream.Readable, stream.Readable]; - killed: boolean; - pid: number; - kill(signal?: string): void; - send(message: any, sendHandle?: any): boolean; - connected: boolean; - disconnect(): void; - unref(): void; - ref(): void; + export interface ChildProcess extends events.EventEmitter { + stdin: stream.Writable; + stdout: stream.Readable; + stderr: stream.Readable; + stdio: [stream.Writable, stream.Readable, stream.Readable]; + killed: boolean; + pid: number; + kill(signal?: string): void; + send(message: any, callback?: (error: Error) => void): boolean; + send(message: any, sendHandle?: net.Socket | net.Server, callback?: (error: Error) => void): boolean; + send(message: any, sendHandle?: net.Socket | net.Server, options?: MessageOptions, callback?: (error: Error) => void): boolean; + connected: boolean; + disconnect(): void; + unref(): void; + ref(): void; /** * events.EventEmitter @@ -1667,464 +2043,625 @@ declare module "child_process" { * 3. error * 4. exit * 5. message - **/ + */ - addListener(event: string, listener: Function): this; - addListener(event: "close", listener: (code: number, signal: string) => void): this; - addListener(event: "disconnect", listener: () => void): this; - addListener(event: "error", listener: (err: Error) => void): this; - addListener(event: "exit", listener: (code: number, signal: string) => void): this; - addListener(event: "message", listener: (message: any, sendHandle: net.Socket | net.Server) => void): this; + addListener(event: string, listener: (...args: any[]) => void): this; + addListener(event: "close", listener: (code: number, signal: string) => void): this; + addListener(event: "disconnect", listener: () => void): this; + addListener(event: "error", listener: (err: Error) => void): this; + addListener(event: "exit", listener: (code: number, signal: string) => void): this; + addListener(event: "message", listener: (message: any, sendHandle: net.Socket | net.Server) => void): this; - emit(event: string | symbol, ...args: any[]): boolean; - emit(event: "close", code: number, signal: string): boolean; - emit(event: "disconnect"): boolean; - emit(event: "error", err: Error): boolean; - emit(event: "exit", code: number, signal: string): boolean; - emit(event: "message", message: any, sendHandle: net.Socket | net.Server): boolean; + emit(event: string | symbol, ...args: any[]): boolean; + emit(event: "close", code: number, signal: string): boolean; + emit(event: "disconnect"): boolean; + emit(event: "error", err: Error): boolean; + emit(event: "exit", code: number, signal: string): boolean; + emit(event: "message", message: any, sendHandle: net.Socket | net.Server): boolean; - on(event: string, listener: Function): this; - on(event: "close", listener: (code: number, signal: string) => void): this; - on(event: "disconnect", listener: () => void): this; - on(event: "error", listener: (err: Error) => void): this; - on(event: "exit", listener: (code: number, signal: string) => void): this; - on(event: "message", listener: (message: any, sendHandle: net.Socket | net.Server) => void): this; + on(event: string, listener: (...args: any[]) => void): this; + on(event: "close", listener: (code: number, signal: string) => void): this; + on(event: "disconnect", listener: () => void): this; + on(event: "error", listener: (err: Error) => void): this; + on(event: "exit", listener: (code: number, signal: string) => void): this; + on(event: "message", listener: (message: any, sendHandle: net.Socket | net.Server) => void): this; - once(event: string, listener: Function): this; - once(event: "close", listener: (code: number, signal: string) => void): this; - once(event: "disconnect", listener: () => void): this; - once(event: "error", listener: (err: Error) => void): this; - once(event: "exit", listener: (code: number, signal: string) => void): this; - once(event: "message", listener: (message: any, sendHandle: net.Socket | net.Server) => void): this; + once(event: string, listener: (...args: any[]) => void): this; + once(event: "close", listener: (code: number, signal: string) => void): this; + once(event: "disconnect", listener: () => void): this; + once(event: "error", listener: (err: Error) => void): this; + once(event: "exit", listener: (code: number, signal: string) => void): this; + once(event: "message", listener: (message: any, sendHandle: net.Socket | net.Server) => void): this; - prependListener(event: string, listener: Function): this; - prependListener(event: "close", listener: (code: number, signal: string) => void): this; - prependListener(event: "disconnect", listener: () => void): this; - prependListener(event: "error", listener: (err: Error) => void): this; - prependListener(event: "exit", listener: (code: number, signal: string) => void): this; - prependListener(event: "message", listener: (message: any, sendHandle: net.Socket | net.Server) => void): this; + prependListener(event: string, listener: (...args: any[]) => void): this; + prependListener(event: "close", listener: (code: number, signal: string) => void): this; + prependListener(event: "disconnect", listener: () => void): this; + prependListener(event: "error", listener: (err: Error) => void): this; + prependListener(event: "exit", listener: (code: number, signal: string) => void): this; + prependListener(event: "message", listener: (message: any, sendHandle: net.Socket | net.Server) => void): this; - prependOnceListener(event: string, listener: Function): this; - prependOnceListener(event: "close", listener: (code: number, signal: string) => void): this; - prependOnceListener(event: "disconnect", listener: () => void): this; - prependOnceListener(event: "error", listener: (err: Error) => void): this; - prependOnceListener(event: "exit", listener: (code: number, signal: string) => void): this; - prependOnceListener(event: "message", listener: (message: any, sendHandle: net.Socket | net.Server) => void): this; - } + prependOnceListener(event: string, listener: (...args: any[]) => void): this; + prependOnceListener(event: "close", listener: (code: number, signal: string) => void): this; + prependOnceListener(event: "disconnect", listener: () => void): this; + prependOnceListener(event: "error", listener: (err: Error) => void): this; + prependOnceListener(event: "exit", listener: (code: number, signal: string) => void): this; + prependOnceListener(event: "message", listener: (message: any, sendHandle: net.Socket | net.Server) => void): this; + } - export interface SpawnOptions { - cwd?: string; - env?: any; - stdio?: any; - detached?: boolean; - uid?: number; - gid?: number; - shell?: boolean | string; - windowsVerbatimArguments?: boolean; - } - export function spawn(command: string, args?: string[], options?: SpawnOptions): ChildProcess; + export interface MessageOptions { + keepOpen?: boolean; + } - export interface ExecOptions { - cwd?: string; - env?: any; - shell?: string; - timeout?: number; - maxBuffer?: number; - killSignal?: string; - uid?: number; - gid?: number; - } - export interface ExecOptionsWithStringEncoding extends ExecOptions { - encoding: BufferEncoding; - } - export interface ExecOptionsWithBufferEncoding extends ExecOptions { - encoding: string; // specify `null`. - } - export function exec(command: string, callback?: (error: Error, stdout: string, stderr: string) => void): ChildProcess; - export function exec(command: string, options: ExecOptionsWithStringEncoding, callback?: (error: Error, stdout: string, stderr: string) => void): ChildProcess; - // usage. child_process.exec("tsc", {encoding: null as string}, (err, stdout, stderr) => {}); - export function exec(command: string, options: ExecOptionsWithBufferEncoding, callback?: (error: Error, stdout: Buffer, stderr: Buffer) => void): ChildProcess; - export function exec(command: string, options: ExecOptions, callback?: (error: Error, stdout: string, stderr: string) => void): ChildProcess; + export interface SpawnOptions { + cwd?: string; + env?: any; + stdio?: any; + detached?: boolean; + uid?: number; + gid?: number; + shell?: boolean | string; + windowsVerbatimArguments?: boolean; + windowsHide?: boolean; + } - export interface ExecFileOptions { - cwd?: string; - env?: any; - timeout?: number; - maxBuffer?: number; - killSignal?: string; - uid?: number; - gid?: number; - } - export interface ExecFileOptionsWithStringEncoding extends ExecFileOptions { - encoding: BufferEncoding; - } - export interface ExecFileOptionsWithBufferEncoding extends ExecFileOptions { - encoding: string; // specify `null`. - } - export function execFile(file: string, callback?: (error: Error, stdout: string, stderr: string) => void): ChildProcess; - export function execFile(file: string, options?: ExecFileOptionsWithStringEncoding, callback?: (error: Error, stdout: string, stderr: string) => void): ChildProcess; - // usage. child_process.execFile("file.sh", {encoding: null as string}, (err, stdout, stderr) => {}); - export function execFile(file: string, options?: ExecFileOptionsWithBufferEncoding, callback?: (error: Error, stdout: Buffer, stderr: Buffer) => void): ChildProcess; - export function execFile(file: string, options?: ExecFileOptions, callback?: (error: Error, stdout: string, stderr: string) => void): ChildProcess; - export function execFile(file: string, args?: string[], callback?: (error: Error, stdout: string, stderr: string) => void): ChildProcess; - export function execFile(file: string, args?: string[], options?: ExecFileOptionsWithStringEncoding, callback?: (error: Error, stdout: string, stderr: string) => void): ChildProcess; - // usage. child_process.execFile("file.sh", ["foo"], {encoding: null as string}, (err, stdout, stderr) => {}); - export function execFile(file: string, args?: string[], options?: ExecFileOptionsWithBufferEncoding, callback?: (error: Error, stdout: Buffer, stderr: Buffer) => void): ChildProcess; - export function execFile(file: string, args?: string[], options?: ExecFileOptions, callback?: (error: Error, stdout: string, stderr: string) => void): ChildProcess; + export function spawn(command: string, args?: ReadonlyArray, options?: SpawnOptions): ChildProcess; - export interface ForkOptions { - cwd?: string; - env?: any; - execPath?: string; - execArgv?: string[]; - silent?: boolean; - stdio?: any[]; - uid?: number; - gid?: number; - } - export function fork(modulePath: string, args?: string[], options?: ForkOptions): ChildProcess; + export interface ExecOptions { + cwd?: string; + env?: any; + shell?: string; + timeout?: number; + maxBuffer?: number; + killSignal?: string; + uid?: number; + gid?: number; + windowsHide?: boolean; + } - export interface SpawnSyncOptions { - cwd?: string; - input?: string | Buffer; - stdio?: any; - env?: any; - uid?: number; - gid?: number; - timeout?: number; - killSignal?: string; - maxBuffer?: number; - encoding?: string; - shell?: boolean | string; - } - export interface SpawnSyncOptionsWithStringEncoding extends SpawnSyncOptions { - encoding: BufferEncoding; - } - export interface SpawnSyncOptionsWithBufferEncoding extends SpawnSyncOptions { - encoding: string; // specify `null`. - } - export interface SpawnSyncReturns { - pid: number; - output: string[]; - stdout: T; - stderr: T; - status: number; - signal: string; - error: Error; - } - export function spawnSync(command: string): SpawnSyncReturns; - export function spawnSync(command: string, options?: SpawnSyncOptionsWithStringEncoding): SpawnSyncReturns; - export function spawnSync(command: string, options?: SpawnSyncOptionsWithBufferEncoding): SpawnSyncReturns; - export function spawnSync(command: string, options?: SpawnSyncOptions): SpawnSyncReturns; - export function spawnSync(command: string, args?: string[], options?: SpawnSyncOptionsWithStringEncoding): SpawnSyncReturns; - export function spawnSync(command: string, args?: string[], options?: SpawnSyncOptionsWithBufferEncoding): SpawnSyncReturns; - export function spawnSync(command: string, args?: string[], options?: SpawnSyncOptions): SpawnSyncReturns; + export interface ExecOptionsWithStringEncoding extends ExecOptions { + encoding: BufferEncoding; + } - export interface ExecSyncOptions { - cwd?: string; - input?: string | Buffer; - stdio?: any; - env?: any; - shell?: string; - uid?: number; - gid?: number; - timeout?: number; - killSignal?: string; - maxBuffer?: number; - encoding?: string; - } - export interface ExecSyncOptionsWithStringEncoding extends ExecSyncOptions { - encoding: BufferEncoding; - } - export interface ExecSyncOptionsWithBufferEncoding extends ExecSyncOptions { - encoding: string; // specify `null`. - } - export function execSync(command: string): Buffer; - export function execSync(command: string, options?: ExecSyncOptionsWithStringEncoding): string; - export function execSync(command: string, options?: ExecSyncOptionsWithBufferEncoding): Buffer; - export function execSync(command: string, options?: ExecSyncOptions): Buffer; + export interface ExecOptionsWithBufferEncoding extends ExecOptions { + encoding: string | null; // specify `null`. + } - export interface ExecFileSyncOptions { - cwd?: string; - input?: string | Buffer; - stdio?: any; - env?: any; - uid?: number; - gid?: number; - timeout?: number; - killSignal?: string; - maxBuffer?: number; - encoding?: string; - } - export interface ExecFileSyncOptionsWithStringEncoding extends ExecFileSyncOptions { - encoding: BufferEncoding; - } - export interface ExecFileSyncOptionsWithBufferEncoding extends ExecFileSyncOptions { - encoding: string; // specify `null`. - } - export function execFileSync(command: string): Buffer; - export function execFileSync(command: string, options?: ExecFileSyncOptionsWithStringEncoding): string; - export function execFileSync(command: string, options?: ExecFileSyncOptionsWithBufferEncoding): Buffer; - export function execFileSync(command: string, options?: ExecFileSyncOptions): Buffer; - export function execFileSync(command: string, args?: string[], options?: ExecFileSyncOptionsWithStringEncoding): string; - export function execFileSync(command: string, args?: string[], options?: ExecFileSyncOptionsWithBufferEncoding): Buffer; - export function execFileSync(command: string, args?: string[], options?: ExecFileSyncOptions): Buffer; + // no `options` definitely means stdout/stderr are `string`. + export function exec(command: string, callback?: (error: Error | null, stdout: string, stderr: string) => void): ChildProcess; + + // `options` with `"buffer"` or `null` for `encoding` means stdout/stderr are definitely `Buffer`. + export function exec(command: string, options: { encoding: "buffer" | null } & ExecOptions, callback?: (error: Error | null, stdout: Buffer, stderr: Buffer) => void): ChildProcess; + + // `options` with well known `encoding` means stdout/stderr are definitely `string`. + export function exec(command: string, options: { encoding: BufferEncoding } & ExecOptions, callback?: (error: Error | null, stdout: string, stderr: string) => void): ChildProcess; + + // `options` with an `encoding` whose type is `string` means stdout/stderr could either be `Buffer` or `string`. + // There is no guarantee the `encoding` is unknown as `string` is a superset of `BufferEncoding`. + export function exec(command: string, options: { encoding: string } & ExecOptions, callback?: (error: Error | null, stdout: string | Buffer, stderr: string | Buffer) => void): ChildProcess; + + // `options` without an `encoding` means stdout/stderr are definitely `string`. + export function exec(command: string, options: ExecOptions, callback?: (error: Error | null, stdout: string, stderr: string) => void): ChildProcess; + + // fallback if nothing else matches. Worst case is always `string | Buffer`. + export function exec(command: string, options: ({ encoding?: string | null } & ExecOptions) | undefined | null, callback?: (error: Error | null, stdout: string | Buffer, stderr: string | Buffer) => void): ChildProcess; + + // NOTE: This namespace provides design-time support for util.promisify. Exported members do not exist at runtime. + export namespace exec { + export function __promisify__(command: string): Promise<{ stdout: string, stderr: string }>; + export function __promisify__(command: string, options: { encoding: "buffer" | null } & ExecOptions): Promise<{ stdout: Buffer, stderr: Buffer }>; + export function __promisify__(command: string, options: { encoding: BufferEncoding } & ExecOptions): Promise<{ stdout: string, stderr: string }>; + export function __promisify__(command: string, options: ExecOptions): Promise<{ stdout: string, stderr: string }>; + export function __promisify__(command: string, options?: ({ encoding?: string | null } & ExecOptions) | null): Promise<{ stdout: string | Buffer, stderr: string | Buffer }>; + } + + export interface ExecFileOptions { + cwd?: string; + env?: any; + timeout?: number; + maxBuffer?: number; + killSignal?: string; + uid?: number; + gid?: number; + windowsHide?: boolean; + windowsVerbatimArguments?: boolean; + } + export interface ExecFileOptionsWithStringEncoding extends ExecFileOptions { + encoding: BufferEncoding; + } + export interface ExecFileOptionsWithBufferEncoding extends ExecFileOptions { + encoding: 'buffer' | null; + } + export interface ExecFileOptionsWithOtherEncoding extends ExecFileOptions { + encoding: string; + } + + export function execFile(file: string): ChildProcess; + export function execFile(file: string, options: ({ encoding?: string | null } & ExecFileOptions) | undefined | null): ChildProcess; + export function execFile(file: string, args: string[] | undefined | null): ChildProcess; + export function execFile(file: string, args: string[] | undefined | null, options: ({ encoding?: string | null } & ExecFileOptions) | undefined | null): ChildProcess; + + // no `options` definitely means stdout/stderr are `string`. + export function execFile(file: string, callback: (error: Error | null, stdout: string, stderr: string) => void): ChildProcess; + export function execFile(file: string, args: string[] | undefined | null, callback: (error: Error | null, stdout: string, stderr: string) => void): ChildProcess; + + // `options` with `"buffer"` or `null` for `encoding` means stdout/stderr are definitely `Buffer`. + export function execFile(file: string, options: ExecFileOptionsWithBufferEncoding, callback: (error: Error | null, stdout: Buffer, stderr: Buffer) => void): ChildProcess; + export function execFile(file: string, args: string[] | undefined | null, options: ExecFileOptionsWithBufferEncoding, callback: (error: Error | null, stdout: Buffer, stderr: Buffer) => void): ChildProcess; + + // `options` with well known `encoding` means stdout/stderr are definitely `string`. + export function execFile(file: string, options: ExecFileOptionsWithStringEncoding, callback: (error: Error | null, stdout: string, stderr: string) => void): ChildProcess; + export function execFile(file: string, args: string[] | undefined | null, options: ExecFileOptionsWithStringEncoding, callback: (error: Error | null, stdout: string, stderr: string) => void): ChildProcess; + + // `options` with an `encoding` whose type is `string` means stdout/stderr could either be `Buffer` or `string`. + // There is no guarantee the `encoding` is unknown as `string` is a superset of `BufferEncoding`. + export function execFile(file: string, options: ExecFileOptionsWithOtherEncoding, callback: (error: Error | null, stdout: string | Buffer, stderr: string | Buffer) => void): ChildProcess; + export function execFile(file: string, args: string[] | undefined | null, options: ExecFileOptionsWithOtherEncoding, callback: (error: Error | null, stdout: string | Buffer, stderr: string | Buffer) => void): ChildProcess; + + // `options` without an `encoding` means stdout/stderr are definitely `string`. + export function execFile(file: string, options: ExecFileOptions, callback: (error: Error | null, stdout: string, stderr: string) => void): ChildProcess; + export function execFile(file: string, args: string[] | undefined | null, options: ExecFileOptions, callback: (error: Error | null, stdout: string, stderr: string) => void): ChildProcess; + + // fallback if nothing else matches. Worst case is always `string | Buffer`. + export function execFile(file: string, options: ({ encoding?: string | null } & ExecFileOptions) | undefined | null, callback: ((error: Error | null, stdout: string | Buffer, stderr: string | Buffer) => void) | undefined | null): ChildProcess; + export function execFile(file: string, args: string[] | undefined | null, options: ({ encoding?: string | null } & ExecFileOptions) | undefined | null, callback: ((error: Error | null, stdout: string | Buffer, stderr: string | Buffer) => void) | undefined | null): ChildProcess; + + // NOTE: This namespace provides design-time support for util.promisify. Exported members do not exist at runtime. + export namespace execFile { + export function __promisify__(file: string): Promise<{ stdout: string, stderr: string }>; + export function __promisify__(file: string, args: string[] | undefined | null): Promise<{ stdout: string, stderr: string }>; + export function __promisify__(file: string, options: ExecFileOptionsWithBufferEncoding): Promise<{ stdout: Buffer, stderr: Buffer }>; + export function __promisify__(file: string, args: string[] | undefined | null, options: ExecFileOptionsWithBufferEncoding): Promise<{ stdout: Buffer, stderr: Buffer }>; + export function __promisify__(file: string, options: ExecFileOptionsWithStringEncoding): Promise<{ stdout: string, stderr: string }>; + export function __promisify__(file: string, args: string[] | undefined | null, options: ExecFileOptionsWithStringEncoding): Promise<{ stdout: string, stderr: string }>; + export function __promisify__(file: string, options: ExecFileOptionsWithOtherEncoding): Promise<{ stdout: string | Buffer, stderr: string | Buffer }>; + export function __promisify__(file: string, args: string[] | undefined | null, options: ExecFileOptionsWithOtherEncoding): Promise<{ stdout: string | Buffer, stderr: string | Buffer }>; + export function __promisify__(file: string, options: ExecFileOptions): Promise<{ stdout: string, stderr: string }>; + export function __promisify__(file: string, args: string[] | undefined | null, options: ExecFileOptions): Promise<{ stdout: string, stderr: string }>; + export function __promisify__(file: string, options: ({ encoding?: string | null } & ExecFileOptions) | undefined | null): Promise<{ stdout: string | Buffer, stderr: string | Buffer }>; + export function __promisify__(file: string, args: string[] | undefined | null, options: ({ encoding?: string | null } & ExecFileOptions) | undefined | null): Promise<{ stdout: string | Buffer, stderr: string | Buffer }>; + } + + export interface ForkOptions { + cwd?: string; + env?: any; + execPath?: string; + execArgv?: string[]; + silent?: boolean; + stdio?: any[]; + uid?: number; + gid?: number; + windowsVerbatimArguments?: boolean; + } + export function fork(modulePath: string, args?: string[], options?: ForkOptions): ChildProcess; + + export interface SpawnSyncOptions { + cwd?: string; + input?: string | Buffer; + stdio?: any; + env?: any; + uid?: number; + gid?: number; + timeout?: number; + killSignal?: string; + maxBuffer?: number; + encoding?: string; + shell?: boolean | string; + windowsHide?: boolean; + windowsVerbatimArguments?: boolean; + } + export interface SpawnSyncOptionsWithStringEncoding extends SpawnSyncOptions { + encoding: BufferEncoding; + } + export interface SpawnSyncOptionsWithBufferEncoding extends SpawnSyncOptions { + encoding: string; // specify `null`. + } + export interface SpawnSyncReturns { + pid: number; + output: string[]; + stdout: T; + stderr: T; + status: number; + signal: string; + error: Error; + } + export function spawnSync(command: string): SpawnSyncReturns; + export function spawnSync(command: string, options?: SpawnSyncOptionsWithStringEncoding): SpawnSyncReturns; + export function spawnSync(command: string, options?: SpawnSyncOptionsWithBufferEncoding): SpawnSyncReturns; + export function spawnSync(command: string, options?: SpawnSyncOptions): SpawnSyncReturns; + export function spawnSync(command: string, args?: string[], options?: SpawnSyncOptionsWithStringEncoding): SpawnSyncReturns; + export function spawnSync(command: string, args?: string[], options?: SpawnSyncOptionsWithBufferEncoding): SpawnSyncReturns; + export function spawnSync(command: string, args?: string[], options?: SpawnSyncOptions): SpawnSyncReturns; + + export interface ExecSyncOptions { + cwd?: string; + input?: string | Buffer; + stdio?: any; + env?: any; + shell?: string; + uid?: number; + gid?: number; + timeout?: number; + killSignal?: string; + maxBuffer?: number; + encoding?: string; + windowsHide?: boolean; + } + export interface ExecSyncOptionsWithStringEncoding extends ExecSyncOptions { + encoding: BufferEncoding; + } + export interface ExecSyncOptionsWithBufferEncoding extends ExecSyncOptions { + encoding: string; // specify `null`. + } + export function execSync(command: string): Buffer; + export function execSync(command: string, options?: ExecSyncOptionsWithStringEncoding): string; + export function execSync(command: string, options?: ExecSyncOptionsWithBufferEncoding): Buffer; + export function execSync(command: string, options?: ExecSyncOptions): Buffer; + + export interface ExecFileSyncOptions { + cwd?: string; + input?: string | Buffer; + stdio?: any; + env?: any; + uid?: number; + gid?: number; + timeout?: number; + killSignal?: string; + maxBuffer?: number; + encoding?: string; + windowsHide?: boolean; + } + export interface ExecFileSyncOptionsWithStringEncoding extends ExecFileSyncOptions { + encoding: BufferEncoding; + } + export interface ExecFileSyncOptionsWithBufferEncoding extends ExecFileSyncOptions { + encoding: string; // specify `null`. + } + export function execFileSync(command: string): Buffer; + export function execFileSync(command: string, options?: ExecFileSyncOptionsWithStringEncoding): string; + export function execFileSync(command: string, options?: ExecFileSyncOptionsWithBufferEncoding): Buffer; + export function execFileSync(command: string, options?: ExecFileSyncOptions): Buffer; + export function execFileSync(command: string, args?: string[], options?: ExecFileSyncOptionsWithStringEncoding): string; + export function execFileSync(command: string, args?: string[], options?: ExecFileSyncOptionsWithBufferEncoding): Buffer; + export function execFileSync(command: string, args?: string[], options?: ExecFileSyncOptions): Buffer; } declare module "url" { - export interface Url { - href?: string; - protocol?: string; - auth?: string; - hostname?: string; - port?: string; - host?: string; - pathname?: string; - search?: string; - query?: string | any; - slashes?: boolean; - hash?: string; - path?: string; - } + import { ParsedUrlQuery } from 'querystring'; - export interface UrlObject { - protocol?: string; - slashes?: boolean; - auth?: string; - host?: string; - hostname?: string; - port?: string | number; - pathname?: string; - search?: string; - query?: { [key: string]: any; }; - hash?: string; - } + export interface UrlObjectCommon { + auth?: string; + hash?: string; + host?: string; + hostname?: string; + href?: string; + path?: string; + pathname?: string; + protocol?: string; + search?: string; + slashes?: boolean; + } - export function parse(urlStr: string, parseQueryString?: boolean, slashesDenoteHost?: boolean): Url; - export function format(URL: URL, options?: URLFormatOptions): string; - export function format(urlObject: UrlObject): string; - export function resolve(from: string, to: string): string; + // Input to `url.format` + export interface UrlObject extends UrlObjectCommon { + port?: string | number; + query?: string | null | { [key: string]: any }; + } - export interface URLFormatOptions { - auth?: boolean; - fragment?: boolean; - search?: boolean; - unicode?: boolean; - } + // Output of `url.parse` + export interface Url extends UrlObjectCommon { + port?: string; + query?: string | null | ParsedUrlQuery; + } - export class URLSearchParams implements Iterable { - constructor(init?: URLSearchParams | string | { [key: string]: string | string[] } | Iterable); - append(name: string, value: string): void; - delete(name: string): void; - entries(): Iterator; - forEach(callback: (value: string, name: string) => void): void; - get(name: string): string | null; - getAll(name: string): string[]; - has(name: string): boolean; - keys(): Iterator; - set(name: string, value: string): void; - sort(): void; - toString(): string; - values(): Iterator; - [Symbol.iterator](): Iterator; - } + export interface UrlWithParsedQuery extends Url { + query: ParsedUrlQuery; + } - export class URL { - constructor(input: string, base?: string | URL); - hash: string; - host: string; - hostname: string; - href: string; - readonly origin: string; - password: string; - pathname: string; - port: string; - protocol: string; - search: string; - readonly searchParams: URLSearchParams; - username: string; - toString(): string; - toJSON(): string; - } + export interface UrlWithStringQuery extends Url { + query: string | null; + } + + export function parse(urlStr: string): UrlWithStringQuery; + export function parse(urlStr: string, parseQueryString: false | undefined, slashesDenoteHost?: boolean): UrlWithStringQuery; + export function parse(urlStr: string, parseQueryString: true, slashesDenoteHost?: boolean): UrlWithParsedQuery; + export function parse(urlStr: string, parseQueryString: boolean, slashesDenoteHost?: boolean): Url; + + export function format(URL: URL, options?: URLFormatOptions): string; + export function format(urlObject: UrlObject | string): string; + export function resolve(from: string, to: string): string; + + export function domainToASCII(domain: string): string; + export function domainToUnicode(domain: string): string; + + export interface URLFormatOptions { + auth?: boolean; + fragment?: boolean; + search?: boolean; + unicode?: boolean; + } + + export class URLSearchParams implements Iterable<[string, string]> { + constructor(init?: URLSearchParams | string | { [key: string]: string | string[] | undefined } | Iterable<[string, string]> | Array<[string, string]>); + append(name: string, value: string): void; + delete(name: string): void; + entries(): IterableIterator<[string, string]>; + forEach(callback: (value: string, name: string) => void): void; + get(name: string): string | null; + getAll(name: string): string[]; + has(name: string): boolean; + keys(): IterableIterator; + set(name: string, value: string): void; + sort(): void; + toString(): string; + values(): IterableIterator; + [Symbol.iterator](): IterableIterator<[string, string]>; + } + + export class URL { + constructor(input: string, base?: string | URL); + hash: string; + host: string; + hostname: string; + href: string; + readonly origin: string; + password: string; + pathname: string; + port: string; + protocol: string; + search: string; + readonly searchParams: URLSearchParams; + username: string; + toString(): string; + toJSON(): string; + } } declare module "dns" { - // Supported getaddrinfo flags. - export const ADDRCONFIG: number; - export const V4MAPPED: number; + // Supported getaddrinfo flags. + export const ADDRCONFIG: number; + export const V4MAPPED: number; - export interface LookupOptions { - family?: number; - hints?: number; - all?: boolean; - } + export interface LookupOptions { + family?: number; + hints?: number; + all?: boolean; + } - export interface LookupOneOptions extends LookupOptions { - all?: false; - } + export interface LookupOneOptions extends LookupOptions { + all?: false; + } - export interface LookupAllOptions extends LookupOptions { - all: true; - } + export interface LookupAllOptions extends LookupOptions { + all: true; + } - export interface LookupAddress { - address: string; - family: number; - } + export interface LookupAddress { + address: string; + family: number; + } - export function lookup(hostname: string, family: number, callback: (err: NodeJS.ErrnoException, address: string, family: number) => void): void; - export function lookup(hostname: string, options: LookupOneOptions, callback: (err: NodeJS.ErrnoException, address: string, family: number) => void): void; - export function lookup(hostname: string, options: LookupAllOptions, callback: (err: NodeJS.ErrnoException, addresses: LookupAddress[]) => void): void; - export function lookup(hostname: string, options: LookupOptions, callback: (err: NodeJS.ErrnoException, address: string | LookupAddress[], family: number) => void): void; - export function lookup(hostname: string, callback: (err: NodeJS.ErrnoException, address: string, family: number) => void): void; + export function lookup(hostname: string, family: number, callback: (err: NodeJS.ErrnoException, address: string, family: number) => void): void; + export function lookup(hostname: string, options: LookupOneOptions, callback: (err: NodeJS.ErrnoException, address: string, family: number) => void): void; + export function lookup(hostname: string, options: LookupAllOptions, callback: (err: NodeJS.ErrnoException, addresses: LookupAddress[]) => void): void; + export function lookup(hostname: string, options: LookupOptions, callback: (err: NodeJS.ErrnoException, address: string | LookupAddress[], family: number) => void): void; + export function lookup(hostname: string, callback: (err: NodeJS.ErrnoException, address: string, family: number) => void): void; - export interface ResolveOptions { - ttl: boolean; - } + // NOTE: This namespace provides design-time support for util.promisify. Exported members do not exist at runtime. + export namespace lookup { + export function __promisify__(hostname: string, options: LookupAllOptions): Promise<{ address: LookupAddress[] }>; + export function __promisify__(hostname: string, options?: LookupOneOptions | number): Promise<{ address: string, family: number }>; + export function __promisify__(hostname: string, options?: LookupOptions | number): Promise<{ address: string | LookupAddress[], family?: number }>; + } - export interface ResolveWithTtlOptions extends ResolveOptions { - ttl: true; - } + export function lookupService(address: string, port: number, callback: (err: NodeJS.ErrnoException, hostname: string, service: string) => void): void; - export interface RecordWithTtl { - address: string; - ttl: number; - } + export namespace lookupService { + export function __promisify__(address: string, port: number): Promise<{ hostname: string, service: string }>; + } - export interface MxRecord { - priority: number; - exchange: string; - } + export interface ResolveOptions { + ttl: boolean; + } - export interface NaptrRecord { - flags: string; - service: string; - regexp: string; - replacement: string; - order: number; - preference: number; - } + export interface ResolveWithTtlOptions extends ResolveOptions { + ttl: true; + } - export interface SoaRecord { - nsname: string; - hostmaster: string; - serial: number; - refresh: number; - retry: number; - expire: number; - minttl: number; - } + export interface RecordWithTtl { + address: string; + ttl: number; + } - export interface SrvRecord { - priority: number; - weight: number; - port: number; - name: string; - } + export interface MxRecord { + priority: number; + exchange: string; + } - export function resolve(hostname: string, callback: (err: NodeJS.ErrnoException, addresses: string[]) => void): void; - export function resolve(hostname: string, rrtype: "A", callback: (err: NodeJS.ErrnoException, addresses: string[]) => void): void; - export function resolve(hostname: string, rrtype: "AAAA", callback: (err: NodeJS.ErrnoException, addresses: string[]) => void): void; - export function resolve(hostname: string, rrtype: "CNAME", callback: (err: NodeJS.ErrnoException, addresses: string[]) => void): void; - export function resolve(hostname: string, rrtype: "MX", callback: (err: NodeJS.ErrnoException, addresses: MxRecord[]) => void): void; - export function resolve(hostname: string, rrtype: "NAPTR", callback: (err: NodeJS.ErrnoException, addresses: NaptrRecord[]) => void): void; - export function resolve(hostname: string, rrtype: "NS", callback: (err: NodeJS.ErrnoException, addresses: string[]) => void): void; - export function resolve(hostname: string, rrtype: "PTR", callback: (err: NodeJS.ErrnoException, addresses: string[]) => void): void; - export function resolve(hostname: string, rrtype: "SOA", callback: (err: NodeJS.ErrnoException, addresses: SoaRecord) => void): void; - export function resolve(hostname: string, rrtype: "SRV", callback: (err: NodeJS.ErrnoException, addresses: SrvRecord[]) => void): void; - export function resolve(hostname: string, rrtype: "TXT", callback: (err: NodeJS.ErrnoException, addresses: string[][]) => void): void; - export function resolve(hostname: string, rrtype: string, callback: (err: NodeJS.ErrnoException, addresses: string[] | MxRecord[] | NaptrRecord[] | SoaRecord | SrvRecord[] | string[][]) => void): void; + export interface NaptrRecord { + flags: string; + service: string; + regexp: string; + replacement: string; + order: number; + preference: number; + } - export function resolve4(hostname: string, callback: (err: NodeJS.ErrnoException, addresses: string[]) => void): void; - export function resolve4(hostname: string, options: ResolveWithTtlOptions, callback: (err: NodeJS.ErrnoException, addresses: RecordWithTtl[]) => void): void; - export function resolve4(hostname: string, options: ResolveOptions, callback: (err: NodeJS.ErrnoException, addresses: string[] | RecordWithTtl[]) => void): void; + export interface SoaRecord { + nsname: string; + hostmaster: string; + serial: number; + refresh: number; + retry: number; + expire: number; + minttl: number; + } - export function resolve6(hostname: string, callback: (err: NodeJS.ErrnoException, addresses: string[]) => void): void; - export function resolve6(hostname: string, options: ResolveWithTtlOptions, callback: (err: NodeJS.ErrnoException, addresses: RecordWithTtl[]) => void): void; - export function resolve6(hostname: string, options: ResolveOptions, callback: (err: NodeJS.ErrnoException, addresses: string[] | RecordWithTtl[]) => void): void; + export interface SrvRecord { + priority: number; + weight: number; + port: number; + name: string; + } - export function resolveCname(hostname: string, callback: (err: NodeJS.ErrnoException, addresses: string[]) => void): void; - export function resolveMx(hostname: string, callback: (err: NodeJS.ErrnoException, addresses: MxRecord[]) => void): void; - export function resolveNaptr(hostname: string, callback: (err: NodeJS.ErrnoException, addresses: NaptrRecord[]) => void): void; - export function resolveNs(hostname: string, callback: (err: NodeJS.ErrnoException, addresses: string[]) => void): void; - export function resolvePtr(hostname: string, callback: (err: NodeJS.ErrnoException, addresses: string[]) => void): void; - export function resolveSoa(hostname: string, callback: (err: NodeJS.ErrnoException, address: SoaRecord) => void): void; - export function resolveSrv(hostname: string, callback: (err: NodeJS.ErrnoException, addresses: SrvRecord[]) => void): void; - export function resolveTxt(hostname: string, callback: (err: NodeJS.ErrnoException, addresses: string[][]) => void): void; + export function resolve(hostname: string, callback: (err: NodeJS.ErrnoException, addresses: string[]) => void): void; + export function resolve(hostname: string, rrtype: "A", callback: (err: NodeJS.ErrnoException, addresses: string[]) => void): void; + export function resolve(hostname: string, rrtype: "AAAA", callback: (err: NodeJS.ErrnoException, addresses: string[]) => void): void; + export function resolve(hostname: string, rrtype: "CNAME", callback: (err: NodeJS.ErrnoException, addresses: string[]) => void): void; + export function resolve(hostname: string, rrtype: "MX", callback: (err: NodeJS.ErrnoException, addresses: MxRecord[]) => void): void; + export function resolve(hostname: string, rrtype: "NAPTR", callback: (err: NodeJS.ErrnoException, addresses: NaptrRecord[]) => void): void; + export function resolve(hostname: string, rrtype: "NS", callback: (err: NodeJS.ErrnoException, addresses: string[]) => void): void; + export function resolve(hostname: string, rrtype: "PTR", callback: (err: NodeJS.ErrnoException, addresses: string[]) => void): void; + export function resolve(hostname: string, rrtype: "SOA", callback: (err: NodeJS.ErrnoException, addresses: SoaRecord) => void): void; + export function resolve(hostname: string, rrtype: "SRV", callback: (err: NodeJS.ErrnoException, addresses: SrvRecord[]) => void): void; + export function resolve(hostname: string, rrtype: "TXT", callback: (err: NodeJS.ErrnoException, addresses: string[][]) => void): void; + export function resolve(hostname: string, rrtype: string, callback: (err: NodeJS.ErrnoException, addresses: string[] | MxRecord[] | NaptrRecord[] | SoaRecord | SrvRecord[] | string[][]) => void): void; - export function reverse(ip: string, callback: (err: NodeJS.ErrnoException, hostnames: string[]) => void): void; - export function setServers(servers: string[]): void; + // NOTE: This namespace provides design-time support for util.promisify. Exported members do not exist at runtime. + export namespace resolve { + export function __promisify__(hostname: string, rrtype?: "A" | "AAAA" | "CNAME" | "NS" | "PTR"): Promise; + export function __promisify__(hostname: string, rrtype: "MX"): Promise; + export function __promisify__(hostname: string, rrtype: "NAPTR"): Promise; + export function __promisify__(hostname: string, rrtype: "SOA"): Promise; + export function __promisify__(hostname: string, rrtype: "SRV"): Promise; + export function __promisify__(hostname: string, rrtype: "TXT"): Promise; + export function __promisify__(hostname: string, rrtype?: string): Promise; + } - //Error codes - export var NODATA: string; - export var FORMERR: string; - export var SERVFAIL: string; - export var NOTFOUND: string; - export var NOTIMP: string; - export var REFUSED: string; - export var BADQUERY: string; - export var BADNAME: string; - export var BADFAMILY: string; - export var BADRESP: string; - export var CONNREFUSED: string; - export var TIMEOUT: string; - export var EOF: string; - export var FILE: string; - export var NOMEM: string; - export var DESTRUCTION: string; - export var BADSTR: string; - export var BADFLAGS: string; - export var NONAME: string; - export var BADHINTS: string; - export var NOTINITIALIZED: string; - export var LOADIPHLPAPI: string; - export var ADDRGETNETWORKPARAMS: string; - export var CANCELLED: string; + export function resolve4(hostname: string, callback: (err: NodeJS.ErrnoException, addresses: string[]) => void): void; + export function resolve4(hostname: string, options: ResolveWithTtlOptions, callback: (err: NodeJS.ErrnoException, addresses: RecordWithTtl[]) => void): void; + export function resolve4(hostname: string, options: ResolveOptions, callback: (err: NodeJS.ErrnoException, addresses: string[] | RecordWithTtl[]) => void): void; + + // NOTE: This namespace provides design-time support for util.promisify. Exported members do not exist at runtime. + export namespace resolve4 { + export function __promisify__(hostname: string): Promise; + export function __promisify__(hostname: string, options: ResolveWithTtlOptions): Promise; + export function __promisify__(hostname: string, options?: ResolveOptions): Promise; + } + + export function resolve6(hostname: string, callback: (err: NodeJS.ErrnoException, addresses: string[]) => void): void; + export function resolve6(hostname: string, options: ResolveWithTtlOptions, callback: (err: NodeJS.ErrnoException, addresses: RecordWithTtl[]) => void): void; + export function resolve6(hostname: string, options: ResolveOptions, callback: (err: NodeJS.ErrnoException, addresses: string[] | RecordWithTtl[]) => void): void; + + // NOTE: This namespace provides design-time support for util.promisify. Exported members do not exist at runtime. + export namespace resolve6 { + export function __promisify__(hostname: string): Promise; + export function __promisify__(hostname: string, options: ResolveWithTtlOptions): Promise; + export function __promisify__(hostname: string, options?: ResolveOptions): Promise; + } + + export function resolveCname(hostname: string, callback: (err: NodeJS.ErrnoException, addresses: string[]) => void): void; + export function resolveMx(hostname: string, callback: (err: NodeJS.ErrnoException, addresses: MxRecord[]) => void): void; + export function resolveNaptr(hostname: string, callback: (err: NodeJS.ErrnoException, addresses: NaptrRecord[]) => void): void; + export function resolveNs(hostname: string, callback: (err: NodeJS.ErrnoException, addresses: string[]) => void): void; + export function resolvePtr(hostname: string, callback: (err: NodeJS.ErrnoException, addresses: string[]) => void): void; + export function resolveSoa(hostname: string, callback: (err: NodeJS.ErrnoException, address: SoaRecord) => void): void; + export function resolveSrv(hostname: string, callback: (err: NodeJS.ErrnoException, addresses: SrvRecord[]) => void): void; + export function resolveTxt(hostname: string, callback: (err: NodeJS.ErrnoException, addresses: string[][]) => void): void; + + export function reverse(ip: string, callback: (err: NodeJS.ErrnoException, hostnames: string[]) => void): void; + export function setServers(servers: string[]): void; + + // Error codes + export var NODATA: string; + export var FORMERR: string; + export var SERVFAIL: string; + export var NOTFOUND: string; + export var NOTIMP: string; + export var REFUSED: string; + export var BADQUERY: string; + export var BADNAME: string; + export var BADFAMILY: string; + export var BADRESP: string; + export var CONNREFUSED: string; + export var TIMEOUT: string; + export var EOF: string; + export var FILE: string; + export var NOMEM: string; + export var DESTRUCTION: string; + export var BADSTR: string; + export var BADFLAGS: string; + export var NONAME: string; + export var BADHINTS: string; + export var NOTINITIALIZED: string; + export var LOADIPHLPAPI: string; + export var ADDRGETNETWORKPARAMS: string; + export var CANCELLED: string; } declare module "net" { - import * as stream from "stream"; - import * as events from "events"; + import * as stream from "stream"; + import * as events from "events"; + import * as dns from "dns"; - export interface Socket extends stream.Duplex { - // Extended base methods - write(buffer: Buffer): boolean; - write(buffer: Buffer, cb?: Function): boolean; - write(str: string, cb?: Function): boolean; - write(str: string, encoding?: string, cb?: Function): boolean; - write(str: string, encoding?: string, fd?: string): boolean; + type LookupFunction = (hostname: string, options: dns.LookupOneOptions, callback: (err: NodeJS.ErrnoException | null, address: string, family: number) => void) => void; - connect(port: number, host?: string, connectionListener?: Function): void; - connect(path: string, connectionListener?: Function): void; - bufferSize: number; - setEncoding(encoding?: string): this; - write(data: any, encoding?: string, callback?: Function): void; - destroy(err?: any): void; - pause(): this; - resume(): this; - setTimeout(timeout: number, callback?: Function): void; - setNoDelay(noDelay?: boolean): void; - setKeepAlive(enable?: boolean, initialDelay?: number): void; - address(): { port: number; family: string; address: string; }; - unref(): void; - ref(): void; + export interface SocketConstructorOpts { + fd?: number; + allowHalfOpen?: boolean; + readable?: boolean; + writable?: boolean; + } - remoteAddress: string; - remoteFamily: string; - remotePort: number; - localAddress: string; - localPort: number; - bytesRead: number; - bytesWritten: number; - connecting: boolean; - destroyed: boolean; + export interface TcpSocketConnectOpts { + port: number; + host?: string; + localAddress?: string; + localPort?: number; + hints?: number; + family?: number; + lookup?: LookupFunction; + } - // Extended base methods - end(): void; - end(buffer: Buffer, cb?: Function): void; - end(str: string, cb?: Function): void; - end(str: string, encoding?: string, cb?: Function): void; - end(data?: any, encoding?: string): void; + export interface IpcSocketConnectOpts { + path: string; + } + + export type SocketConnectOpts = TcpSocketConnectOpts | IpcSocketConnectOpts; + + export class Socket extends stream.Duplex { + constructor(options?: SocketConstructorOpts); + + // Extended base methods + write(buffer: Buffer): boolean; + write(buffer: Buffer, cb?: Function): boolean; + write(str: string, cb?: Function): boolean; + write(str: string, encoding?: string, cb?: Function): boolean; + write(str: string, encoding?: string, fd?: string): boolean; + write(data: any, encoding?: string, callback?: Function): void; + + connect(options: SocketConnectOpts, connectionListener?: Function): this; + connect(port: number, host: string, connectionListener?: Function): this; + connect(port: number, connectionListener?: Function): this; + connect(path: string, connectionListener?: Function): this; + + bufferSize: number; + setEncoding(encoding?: string): this; + destroy(err?: any): void; + pause(): this; + resume(): this; + setTimeout(timeout: number, callback?: Function): this; + setNoDelay(noDelay?: boolean): this; + setKeepAlive(enable?: boolean, initialDelay?: number): this; + address(): { port: number; family: string; address: string; }; + unref(): void; + ref(): void; + + remoteAddress?: string; + remoteFamily?: string; + remotePort?: number; + localAddress: string; + localPort: number; + bytesRead: number; + bytesWritten: number; + connecting: boolean; + destroyed: boolean; + + // Extended base methods + end(): void; + end(buffer: Buffer, cb?: Function): void; + end(str: string, cb?: Function): void; + end(str: string, encoding?: string, cb?: Function): void; + end(data?: any, encoding?: string): void; /** * events.EventEmitter @@ -2137,97 +2674,97 @@ declare module "net" { * 7. lookup * 8. timeout */ - addListener(event: string, listener: Function): this; - addListener(event: "close", listener: (had_error: boolean) => void): this; - addListener(event: "connect", listener: () => void): this; - addListener(event: "data", listener: (data: Buffer) => void): this; - addListener(event: "drain", listener: () => void): this; - addListener(event: "end", listener: () => void): this; - addListener(event: "error", listener: (err: Error) => void): this; - addListener(event: "lookup", listener: (err: Error, address: string, family: string | number, host: string) => void): this; - addListener(event: "timeout", listener: () => void): this; + addListener(event: string, listener: (...args: any[]) => void): this; + addListener(event: "close", listener: (had_error: boolean) => void): this; + addListener(event: "connect", listener: () => void): this; + addListener(event: "data", listener: (data: Buffer) => void): this; + addListener(event: "drain", listener: () => void): this; + addListener(event: "end", listener: () => void): this; + addListener(event: "error", listener: (err: Error) => void): this; + addListener(event: "lookup", listener: (err: Error, address: string, family: string | number, host: string) => void): this; + addListener(event: "timeout", listener: () => void): this; - emit(event: string | symbol, ...args: any[]): boolean; - emit(event: "close", had_error: boolean): boolean; - emit(event: "connect"): boolean; - emit(event: "data", data: Buffer): boolean; - emit(event: "drain"): boolean; - emit(event: "end"): boolean; - emit(event: "error", err: Error): boolean; - emit(event: "lookup", err: Error, address: string, family: string | number, host: string): boolean; - emit(event: "timeout"): boolean; + emit(event: string | symbol, ...args: any[]): boolean; + emit(event: "close", had_error: boolean): boolean; + emit(event: "connect"): boolean; + emit(event: "data", data: Buffer): boolean; + emit(event: "drain"): boolean; + emit(event: "end"): boolean; + emit(event: "error", err: Error): boolean; + emit(event: "lookup", err: Error, address: string, family: string | number, host: string): boolean; + emit(event: "timeout"): boolean; - on(event: string, listener: Function): this; - on(event: "close", listener: (had_error: boolean) => void): this; - on(event: "connect", listener: () => void): this; - on(event: "data", listener: (data: Buffer) => void): this; - on(event: "drain", listener: () => void): this; - on(event: "end", listener: () => void): this; - on(event: "error", listener: (err: Error) => void): this; - on(event: "lookup", listener: (err: Error, address: string, family: string | number, host: string) => void): this; - on(event: "timeout", listener: () => void): this; + on(event: string, listener: (...args: any[]) => void): this; + on(event: "close", listener: (had_error: boolean) => void): this; + on(event: "connect", listener: () => void): this; + on(event: "data", listener: (data: Buffer) => void): this; + on(event: "drain", listener: () => void): this; + on(event: "end", listener: () => void): this; + on(event: "error", listener: (err: Error) => void): this; + on(event: "lookup", listener: (err: Error, address: string, family: string | number, host: string) => void): this; + on(event: "timeout", listener: () => void): this; - once(event: string, listener: Function): this; - once(event: "close", listener: (had_error: boolean) => void): this; - once(event: "connect", listener: () => void): this; - once(event: "data", listener: (data: Buffer) => void): this; - once(event: "drain", listener: () => void): this; - once(event: "end", listener: () => void): this; - once(event: "error", listener: (err: Error) => void): this; - once(event: "lookup", listener: (err: Error, address: string, family: string | number, host: string) => void): this; - once(event: "timeout", listener: () => void): this; + once(event: string, listener: (...args: any[]) => void): this; + once(event: "close", listener: (had_error: boolean) => void): this; + once(event: "connect", listener: () => void): this; + once(event: "data", listener: (data: Buffer) => void): this; + once(event: "drain", listener: () => void): this; + once(event: "end", listener: () => void): this; + once(event: "error", listener: (err: Error) => void): this; + once(event: "lookup", listener: (err: Error, address: string, family: string | number, host: string) => void): this; + once(event: "timeout", listener: () => void): this; - prependListener(event: string, listener: Function): this; - prependListener(event: "close", listener: (had_error: boolean) => void): this; - prependListener(event: "connect", listener: () => void): this; - prependListener(event: "data", listener: (data: Buffer) => void): this; - prependListener(event: "drain", listener: () => void): this; - prependListener(event: "end", listener: () => void): this; - prependListener(event: "error", listener: (err: Error) => void): this; - prependListener(event: "lookup", listener: (err: Error, address: string, family: string | number, host: string) => void): this; - prependListener(event: "timeout", listener: () => void): this; + prependListener(event: string, listener: (...args: any[]) => void): this; + prependListener(event: "close", listener: (had_error: boolean) => void): this; + prependListener(event: "connect", listener: () => void): this; + prependListener(event: "data", listener: (data: Buffer) => void): this; + prependListener(event: "drain", listener: () => void): this; + prependListener(event: "end", listener: () => void): this; + prependListener(event: "error", listener: (err: Error) => void): this; + prependListener(event: "lookup", listener: (err: Error, address: string, family: string | number, host: string) => void): this; + prependListener(event: "timeout", listener: () => void): this; - prependOnceListener(event: string, listener: Function): this; - prependOnceListener(event: "close", listener: (had_error: boolean) => void): this; - prependOnceListener(event: "connect", listener: () => void): this; - prependOnceListener(event: "data", listener: (data: Buffer) => void): this; - prependOnceListener(event: "drain", listener: () => void): this; - prependOnceListener(event: "end", listener: () => void): this; - prependOnceListener(event: "error", listener: (err: Error) => void): this; - prependOnceListener(event: "lookup", listener: (err: Error, address: string, family: string | number, host: string) => void): this; - prependOnceListener(event: "timeout", listener: () => void): this; - } + prependOnceListener(event: string, listener: (...args: any[]) => void): this; + prependOnceListener(event: "close", listener: (had_error: boolean) => void): this; + prependOnceListener(event: "connect", listener: () => void): this; + prependOnceListener(event: "data", listener: (data: Buffer) => void): this; + prependOnceListener(event: "drain", listener: () => void): this; + prependOnceListener(event: "end", listener: () => void): this; + prependOnceListener(event: "error", listener: (err: Error) => void): this; + prependOnceListener(event: "lookup", listener: (err: Error, address: string, family: string | number, host: string) => void): this; + prependOnceListener(event: "timeout", listener: () => void): this; + } - export var Socket: { - new(options?: { fd?: number; allowHalfOpen?: boolean; readable?: boolean; writable?: boolean; }): Socket; - }; + export interface ListenOptions { + port?: number; + host?: string; + backlog?: number; + path?: string; + exclusive?: boolean; + } - export interface ListenOptions { - port?: number; - host?: string; - backlog?: number; - path?: string; - exclusive?: boolean; - } + // https://github.com/nodejs/node/blob/master/lib/net.js + export class Server extends events.EventEmitter { + constructor(connectionListener?: (socket: Socket) => void); + constructor(options?: { allowHalfOpen?: boolean, pauseOnConnect?: boolean }, connectionListener?: (socket: Socket) => void); - export interface Server extends events.EventEmitter { - listen(port: number, hostname?: string, backlog?: number, listeningListener?: Function): Server; - listen(port: number, hostname?: string, listeningListener?: Function): Server; - listen(port: number, backlog?: number, listeningListener?: Function): Server; - listen(port: number, listeningListener?: Function): Server; - listen(path: string, backlog?: number, listeningListener?: Function): Server; - listen(path: string, listeningListener?: Function): Server; - listen(options: ListenOptions, listeningListener?: Function): Server; - listen(handle: any, backlog?: number, listeningListener?: Function): Server; - listen(handle: any, listeningListener?: Function): Server; - close(callback?: Function): Server; - address(): { port: number; family: string; address: string; }; - getConnections(cb: (error: Error, count: number) => void): void; - ref(): Server; - unref(): Server; - maxConnections: number; - connections: number; - listening: boolean; + listen(port?: number, hostname?: string, backlog?: number, listeningListener?: Function): this; + listen(port?: number, hostname?: string, listeningListener?: Function): this; + listen(port?: number, backlog?: number, listeningListener?: Function): this; + listen(port?: number, listeningListener?: Function): this; + listen(path: string, backlog?: number, listeningListener?: Function): this; + listen(path: string, listeningListener?: Function): this; + listen(options: ListenOptions, listeningListener?: Function): this; + listen(handle: any, backlog?: number, listeningListener?: Function): this; + listen(handle: any, listeningListener?: Function): this; + close(callback?: Function): this; + address(): { port: number; family: string; address: string; }; + getConnections(cb: (error: Error | null, count: number) => void): void; + ref(): this; + unref(): this; + maxConnections: number; + connections: number; + listening: boolean; /** * events.EventEmitter @@ -2236,101 +2773,123 @@ declare module "net" { * 3. error * 4. listening */ - addListener(event: string, listener: Function): this; - addListener(event: "close", listener: () => void): this; - addListener(event: "connection", listener: (socket: Socket) => void): this; - addListener(event: "error", listener: (err: Error) => void): this; - addListener(event: "listening", listener: () => void): this; + addListener(event: string, listener: (...args: any[]) => void): this; + addListener(event: "close", listener: () => void): this; + addListener(event: "connection", listener: (socket: Socket) => void): this; + addListener(event: "error", listener: (err: Error) => void): this; + addListener(event: "listening", listener: () => void): this; - emit(event: string | symbol, ...args: any[]): boolean; - emit(event: "close"): boolean; - emit(event: "connection", socket: Socket): boolean; - emit(event: "error", err: Error): boolean; - emit(event: "listening"): boolean; + emit(event: string | symbol, ...args: any[]): boolean; + emit(event: "close"): boolean; + emit(event: "connection", socket: Socket): boolean; + emit(event: "error", err: Error): boolean; + emit(event: "listening"): boolean; - on(event: string, listener: Function): this; - on(event: "close", listener: () => void): this; - on(event: "connection", listener: (socket: Socket) => void): this; - on(event: "error", listener: (err: Error) => void): this; - on(event: "listening", listener: () => void): this; + on(event: string, listener: (...args: any[]) => void): this; + on(event: "close", listener: () => void): this; + on(event: "connection", listener: (socket: Socket) => void): this; + on(event: "error", listener: (err: Error) => void): this; + on(event: "listening", listener: () => void): this; - once(event: string, listener: Function): this; - once(event: "close", listener: () => void): this; - once(event: "connection", listener: (socket: Socket) => void): this; - once(event: "error", listener: (err: Error) => void): this; - once(event: "listening", listener: () => void): this; + once(event: string, listener: (...args: any[]) => void): this; + once(event: "close", listener: () => void): this; + once(event: "connection", listener: (socket: Socket) => void): this; + once(event: "error", listener: (err: Error) => void): this; + once(event: "listening", listener: () => void): this; - prependListener(event: string, listener: Function): this; - prependListener(event: "close", listener: () => void): this; - prependListener(event: "connection", listener: (socket: Socket) => void): this; - prependListener(event: "error", listener: (err: Error) => void): this; - prependListener(event: "listening", listener: () => void): this; + prependListener(event: string, listener: (...args: any[]) => void): this; + prependListener(event: "close", listener: () => void): this; + prependListener(event: "connection", listener: (socket: Socket) => void): this; + prependListener(event: "error", listener: (err: Error) => void): this; + prependListener(event: "listening", listener: () => void): this; - prependOnceListener(event: string, listener: Function): this; - prependOnceListener(event: "close", listener: () => void): this; - prependOnceListener(event: "connection", listener: (socket: Socket) => void): this; - prependOnceListener(event: "error", listener: (err: Error) => void): this; - prependOnceListener(event: "listening", listener: () => void): this; - } - export function createServer(connectionListener?: (socket: Socket) => void): Server; - export function createServer(options?: { allowHalfOpen?: boolean, pauseOnConnect?: boolean }, connectionListener?: (socket: Socket) => void): Server; - export function connect(options: { port: number, host?: string, localAddress?: string, localPort?: string, family?: number, allowHalfOpen?: boolean; }, connectionListener?: Function): Socket; - export function connect(port: number, host?: string, connectionListener?: Function): Socket; - export function connect(path: string, connectionListener?: Function): Socket; - export function createConnection(options: { port: number, host?: string, localAddress?: string, localPort?: string, family?: number, allowHalfOpen?: boolean; }, connectionListener?: Function): Socket; - export function createConnection(port: number, host?: string, connectionListener?: Function): Socket; - export function createConnection(path: string, connectionListener?: Function): Socket; - export function isIP(input: string): number; - export function isIPv4(input: string): boolean; - export function isIPv6(input: string): boolean; + prependOnceListener(event: string, listener: (...args: any[]) => void): this; + prependOnceListener(event: "close", listener: () => void): this; + prependOnceListener(event: "connection", listener: (socket: Socket) => void): this; + prependOnceListener(event: "error", listener: (err: Error) => void): this; + prependOnceListener(event: "listening", listener: () => void): this; + } + + export interface TcpNetConnectOpts extends TcpSocketConnectOpts, SocketConstructorOpts { + timeout?: number; + } + + export interface IpcNetConnectOpts extends IpcSocketConnectOpts, SocketConstructorOpts { + timeout?: number; + } + + export type NetConnectOpts = TcpNetConnectOpts | IpcNetConnectOpts; + + export function createServer(connectionListener?: (socket: Socket) => void): Server; + export function createServer(options?: { allowHalfOpen?: boolean, pauseOnConnect?: boolean }, connectionListener?: (socket: Socket) => void): Server; + export function connect(options: NetConnectOpts, connectionListener?: Function): Socket; + export function connect(port: number, host?: string, connectionListener?: Function): Socket; + export function connect(path: string, connectionListener?: Function): Socket; + export function createConnection(options: NetConnectOpts, connectionListener?: Function): Socket; + export function createConnection(port: number, host?: string, connectionListener?: Function): Socket; + export function createConnection(path: string, connectionListener?: Function): Socket; + export function isIP(input: string): number; + export function isIPv4(input: string): boolean; + export function isIPv6(input: string): boolean; } declare module "dgram" { - import * as events from "events"; + import * as events from "events"; + import * as dns from "dns"; - interface RemoteInfo { - address: string; - family: string; - port: number; - } + interface RemoteInfo { + address: string; + family: string; + port: number; + } - interface AddressInfo { - address: string; - family: string; - port: number; - } + interface AddressInfo { + address: string; + family: string; + port: number; + } - interface BindOptions { - port: number; - address?: string; - exclusive?: boolean; - } + interface BindOptions { + port: number; + address?: string; + exclusive?: boolean; + } - type SocketType = "udp4" | "udp6"; + type SocketType = "udp4" | "udp6"; - interface SocketOptions { - type: SocketType; - reuseAddr?: boolean; - } + interface SocketOptions { + type: SocketType; + reuseAddr?: boolean; + recvBufferSize?: number; + sendBufferSize?: number; + lookup?: (hostname: string, options: dns.LookupOneOptions, callback: (err: NodeJS.ErrnoException, address: string, family: number) => void) => void; + } - export function createSocket(type: SocketType, callback?: (msg: Buffer, rinfo: RemoteInfo) => void): Socket; - export function createSocket(options: SocketOptions, callback?: (msg: Buffer, rinfo: RemoteInfo) => void): Socket; + export function createSocket(type: SocketType, callback?: (msg: Buffer, rinfo: RemoteInfo) => void): Socket; + export function createSocket(options: SocketOptions, callback?: (msg: Buffer, rinfo: RemoteInfo) => void): Socket; - export interface Socket extends events.EventEmitter { - send(msg: Buffer | String | any[], port: number, address: string, callback?: (error: Error, bytes: number) => void): void; - send(msg: Buffer | String | any[], offset: number, length: number, port: number, address: string, callback?: (error: Error, bytes: number) => void): void; - bind(port?: number, address?: string, callback?: () => void): void; - bind(options: BindOptions, callback?: Function): void; - close(callback?: () => void): void; - address(): AddressInfo; - setBroadcast(flag: boolean): void; - setTTL(ttl: number): void; - setMulticastTTL(ttl: number): void; - setMulticastLoopback(flag: boolean): void; - addMembership(multicastAddress: string, multicastInterface?: string): void; - dropMembership(multicastAddress: string, multicastInterface?: string): void; - ref(): this; - unref(): this; + export class Socket extends events.EventEmitter { + send(msg: Buffer | string | Uint8Array | any[], port: number, address?: string, callback?: (error: Error | null, bytes: number) => void): void; + send(msg: Buffer | string | Uint8Array, offset: number, length: number, port: number, address?: string, callback?: (error: Error | null, bytes: number) => void): void; + bind(port?: number, address?: string, callback?: () => void): void; + bind(port?: number, callback?: () => void): void; + bind(callback?: () => void): void; + bind(options: BindOptions, callback?: Function): void; + close(callback?: () => void): void; + address(): AddressInfo; + setBroadcast(flag: boolean): void; + setTTL(ttl: number): void; + setMulticastTTL(ttl: number): void; + setMulticastInterface(multicastInterface: string): void; + setMulticastLoopback(flag: boolean): void; + addMembership(multicastAddress: string, multicastInterface?: string): void; + dropMembership(multicastAddress: string, multicastInterface?: string): void; + ref(): this; + unref(): this; + setRecvBufferSize(size: number): void; + setSendBufferSize(size: number): void; + getRecvBufferSize(): number; + getSendBufferSize(): number; /** * events.EventEmitter @@ -2338,586 +2897,1738 @@ declare module "dgram" { * 2. error * 3. listening * 4. message - **/ - addListener(event: string, listener: Function): this; - addListener(event: "close", listener: () => void): this; - addListener(event: "error", listener: (err: Error) => void): this; - addListener(event: "listening", listener: () => void): this; - addListener(event: "message", listener: (msg: Buffer, rinfo: AddressInfo) => void): this; + */ + addListener(event: string, listener: (...args: any[]) => void): this; + addListener(event: "close", listener: () => void): this; + addListener(event: "error", listener: (err: Error) => void): this; + addListener(event: "listening", listener: () => void): this; + addListener(event: "message", listener: (msg: Buffer, rinfo: AddressInfo) => void): this; - emit(event: string | symbol, ...args: any[]): boolean; - emit(event: "close"): boolean; - emit(event: "error", err: Error): boolean; - emit(event: "listening"): boolean; - emit(event: "message", msg: Buffer, rinfo: AddressInfo): boolean; + emit(event: string | symbol, ...args: any[]): boolean; + emit(event: "close"): boolean; + emit(event: "error", err: Error): boolean; + emit(event: "listening"): boolean; + emit(event: "message", msg: Buffer, rinfo: AddressInfo): boolean; - on(event: string, listener: Function): this; - on(event: "close", listener: () => void): this; - on(event: "error", listener: (err: Error) => void): this; - on(event: "listening", listener: () => void): this; - on(event: "message", listener: (msg: Buffer, rinfo: AddressInfo) => void): this; + on(event: string, listener: (...args: any[]) => void): this; + on(event: "close", listener: () => void): this; + on(event: "error", listener: (err: Error) => void): this; + on(event: "listening", listener: () => void): this; + on(event: "message", listener: (msg: Buffer, rinfo: AddressInfo) => void): this; - once(event: string, listener: Function): this; - once(event: "close", listener: () => void): this; - once(event: "error", listener: (err: Error) => void): this; - once(event: "listening", listener: () => void): this; - once(event: "message", listener: (msg: Buffer, rinfo: AddressInfo) => void): this; + once(event: string, listener: (...args: any[]) => void): this; + once(event: "close", listener: () => void): this; + once(event: "error", listener: (err: Error) => void): this; + once(event: "listening", listener: () => void): this; + once(event: "message", listener: (msg: Buffer, rinfo: AddressInfo) => void): this; - prependListener(event: string, listener: Function): this; - prependListener(event: "close", listener: () => void): this; - prependListener(event: "error", listener: (err: Error) => void): this; - prependListener(event: "listening", listener: () => void): this; - prependListener(event: "message", listener: (msg: Buffer, rinfo: AddressInfo) => void): this; + prependListener(event: string, listener: (...args: any[]) => void): this; + prependListener(event: "close", listener: () => void): this; + prependListener(event: "error", listener: (err: Error) => void): this; + prependListener(event: "listening", listener: () => void): this; + prependListener(event: "message", listener: (msg: Buffer, rinfo: AddressInfo) => void): this; - prependOnceListener(event: string, listener: Function): this; - prependOnceListener(event: "close", listener: () => void): this; - prependOnceListener(event: "error", listener: (err: Error) => void): this; - prependOnceListener(event: "listening", listener: () => void): this; - prependOnceListener(event: "message", listener: (msg: Buffer, rinfo: AddressInfo) => void): this; - } + prependOnceListener(event: string, listener: (...args: any[]) => void): this; + prependOnceListener(event: "close", listener: () => void): this; + prependOnceListener(event: "error", listener: (err: Error) => void): this; + prependOnceListener(event: "listening", listener: () => void): this; + prependOnceListener(event: "message", listener: (msg: Buffer, rinfo: AddressInfo) => void): this; + } } declare module "fs" { - import * as stream from "stream"; - import * as events from "events"; + import * as stream from "stream"; + import * as events from "events"; + import { URL } from "url"; - interface Stats { - isFile(): boolean; - isDirectory(): boolean; - isBlockDevice(): boolean; - isCharacterDevice(): boolean; - isSymbolicLink(): boolean; - isFIFO(): boolean; - isSocket(): boolean; - dev: number; - ino: number; - mode: number; - nlink: number; - uid: number; - gid: number; - rdev: number; - size: number; - blksize: number; - blocks: number; - atime: Date; - mtime: Date; - ctime: Date; - birthtime: Date; - } + /** + * Valid types for path values in "fs". + */ + export type PathLike = string | Buffer | URL; - interface FSWatcher extends events.EventEmitter { - close(): void; + export class Stats { + isFile(): boolean; + isDirectory(): boolean; + isBlockDevice(): boolean; + isCharacterDevice(): boolean; + isSymbolicLink(): boolean; + isFIFO(): boolean; + isSocket(): boolean; + dev: number; + ino: number; + mode: number; + nlink: number; + uid: number; + gid: number; + rdev: number; + size: number; + blksize: number; + blocks: number; + atimeMs: number; + mtimeMs: number; + ctimeMs: number; + birthtimeMs: number; + atime: Date; + mtime: Date; + ctime: Date; + birthtime: Date; + } + + export interface FSWatcher extends events.EventEmitter { + close(): void; /** * events.EventEmitter * 1. change * 2. error */ - addListener(event: string, listener: Function): this; - addListener(event: "change", listener: (eventType: string, filename: string | Buffer) => void): this; - addListener(event: "error", listener: (error: Error) => void): this; + addListener(event: string, listener: (...args: any[]) => void): this; + addListener(event: "change", listener: (eventType: string, filename: string | Buffer) => void): this; + addListener(event: "error", listener: (error: Error) => void): this; - on(event: string, listener: Function): this; - on(event: "change", listener: (eventType: string, filename: string | Buffer) => void): this; - on(event: "error", listener: (error: Error) => void): this; + on(event: string, listener: (...args: any[]) => void): this; + on(event: "change", listener: (eventType: string, filename: string | Buffer) => void): this; + on(event: "error", listener: (error: Error) => void): this; - once(event: string, listener: Function): this; - once(event: "change", listener: (eventType: string, filename: string | Buffer) => void): this; - once(event: "error", listener: (error: Error) => void): this; + once(event: string, listener: (...args: any[]) => void): this; + once(event: "change", listener: (eventType: string, filename: string | Buffer) => void): this; + once(event: "error", listener: (error: Error) => void): this; - prependListener(event: string, listener: Function): this; - prependListener(event: "change", listener: (eventType: string, filename: string | Buffer) => void): this; - prependListener(event: "error", listener: (error: Error) => void): this; + prependListener(event: string, listener: (...args: any[]) => void): this; + prependListener(event: "change", listener: (eventType: string, filename: string | Buffer) => void): this; + prependListener(event: "error", listener: (error: Error) => void): this; - prependOnceListener(event: string, listener: Function): this; - prependOnceListener(event: "change", listener: (eventType: string, filename: string | Buffer) => void): this; - prependOnceListener(event: "error", listener: (error: Error) => void): this; - } + prependOnceListener(event: string, listener: (...args: any[]) => void): this; + prependOnceListener(event: "change", listener: (eventType: string, filename: string | Buffer) => void): this; + prependOnceListener(event: "error", listener: (error: Error) => void): this; + } - export interface ReadStream extends stream.Readable { - close(): void; - destroy(): void; - bytesRead: number; - path: string | Buffer; + export class ReadStream extends stream.Readable { + close(): void; + destroy(): void; + bytesRead: number; + path: string | Buffer; /** * events.EventEmitter * 1. open * 2. close */ - addListener(event: string, listener: Function): this; - addListener(event: "open", listener: (fd: number) => void): this; - addListener(event: "close", listener: () => void): this; + addListener(event: string, listener: (...args: any[]) => void): this; + addListener(event: "open", listener: (fd: number) => void): this; + addListener(event: "close", listener: () => void): this; - on(event: string, listener: Function): this; - on(event: "open", listener: (fd: number) => void): this; - on(event: "close", listener: () => void): this; + on(event: string, listener: (...args: any[]) => void): this; + on(event: "open", listener: (fd: number) => void): this; + on(event: "close", listener: () => void): this; - once(event: string, listener: Function): this; - once(event: "open", listener: (fd: number) => void): this; - once(event: "close", listener: () => void): this; + once(event: string, listener: (...args: any[]) => void): this; + once(event: "open", listener: (fd: number) => void): this; + once(event: "close", listener: () => void): this; - prependListener(event: string, listener: Function): this; - prependListener(event: "open", listener: (fd: number) => void): this; - prependListener(event: "close", listener: () => void): this; + prependListener(event: string, listener: (...args: any[]) => void): this; + prependListener(event: "open", listener: (fd: number) => void): this; + prependListener(event: "close", listener: () => void): this; - prependOnceListener(event: string, listener: Function): this; - prependOnceListener(event: "open", listener: (fd: number) => void): this; - prependOnceListener(event: "close", listener: () => void): this; - } + prependOnceListener(event: string, listener: (...args: any[]) => void): this; + prependOnceListener(event: "open", listener: (fd: number) => void): this; + prependOnceListener(event: "close", listener: () => void): this; + } - export interface WriteStream extends stream.Writable { - close(): void; - bytesWritten: number; - path: string | Buffer; + export class WriteStream extends stream.Writable { + close(): void; + bytesWritten: number; + path: string | Buffer; /** * events.EventEmitter * 1. open * 2. close */ - addListener(event: string, listener: Function): this; - addListener(event: "open", listener: (fd: number) => void): this; - addListener(event: "close", listener: () => void): this; + addListener(event: string, listener: (...args: any[]) => void): this; + addListener(event: "open", listener: (fd: number) => void): this; + addListener(event: "close", listener: () => void): this; - on(event: string, listener: Function): this; - on(event: "open", listener: (fd: number) => void): this; - on(event: "close", listener: () => void): this; + on(event: string, listener: (...args: any[]) => void): this; + on(event: "open", listener: (fd: number) => void): this; + on(event: "close", listener: () => void): this; - once(event: string, listener: Function): this; - once(event: "open", listener: (fd: number) => void): this; - once(event: "close", listener: () => void): this; + once(event: string, listener: (...args: any[]) => void): this; + once(event: "open", listener: (fd: number) => void): this; + once(event: "close", listener: () => void): this; - prependListener(event: string, listener: Function): this; - prependListener(event: "open", listener: (fd: number) => void): this; - prependListener(event: "close", listener: () => void): this; + prependListener(event: string, listener: (...args: any[]) => void): this; + prependListener(event: "open", listener: (fd: number) => void): this; + prependListener(event: "close", listener: () => void): this; - prependOnceListener(event: string, listener: Function): this; - prependOnceListener(event: "open", listener: (fd: number) => void): this; - prependOnceListener(event: "close", listener: () => void): this; - } + prependOnceListener(event: string, listener: (...args: any[]) => void): this; + prependOnceListener(event: "open", listener: (fd: number) => void): this; + prependOnceListener(event: "close", listener: () => void): this; + } /** - * Asynchronous rename. - * @param oldPath - * @param newPath - * @param callback No arguments other than a possible exception are given to the completion callback. + * Asynchronous rename(2) - Change the name or location of a file or directory. + * @param oldPath A path to a file. If a URL is provided, it must use the `file:` protocol. + * URL support is _experimental_. + * @param newPath A path to a file. If a URL is provided, it must use the `file:` protocol. + * URL support is _experimental_. */ - export function rename(oldPath: string, newPath: string, callback?: (err?: NodeJS.ErrnoException) => void): void; + export function rename(oldPath: PathLike, newPath: PathLike, callback: (err: NodeJS.ErrnoException) => void): void; + + // NOTE: This namespace provides design-time support for util.promisify. Exported members do not exist at runtime. + export namespace rename { + /** + * Asynchronous rename(2) - Change the name or location of a file or directory. + * @param oldPath A path to a file. If a URL is provided, it must use the `file:` protocol. + * URL support is _experimental_. + * @param newPath A path to a file. If a URL is provided, it must use the `file:` protocol. + * URL support is _experimental_. + */ + export function __promisify__(oldPath: PathLike, newPath: PathLike): Promise; + } + /** - * Synchronous rename - * @param oldPath - * @param newPath + * Synchronous rename(2) - Change the name or location of a file or directory. + * @param oldPath A path to a file. If a URL is provided, it must use the `file:` protocol. + * URL support is _experimental_. + * @param newPath A path to a file. If a URL is provided, it must use the `file:` protocol. + * URL support is _experimental_. */ - export function renameSync(oldPath: string, newPath: string): void; - export function truncate(path: string | Buffer, callback?: (err?: NodeJS.ErrnoException) => void): void; - export function truncate(path: string | Buffer, len: number, callback?: (err?: NodeJS.ErrnoException) => void): void; - export function truncateSync(path: string | Buffer, len?: number): void; - export function ftruncate(fd: number, callback?: (err?: NodeJS.ErrnoException) => void): void; - export function ftruncate(fd: number, len: number, callback?: (err?: NodeJS.ErrnoException) => void): void; - export function ftruncateSync(fd: number, len?: number): void; - export function chown(path: string | Buffer, uid: number, gid: number, callback?: (err?: NodeJS.ErrnoException) => void): void; - export function chownSync(path: string | Buffer, uid: number, gid: number): void; - export function fchown(fd: number, uid: number, gid: number, callback?: (err?: NodeJS.ErrnoException) => void): void; - export function fchownSync(fd: number, uid: number, gid: number): void; - export function lchown(path: string | Buffer, uid: number, gid: number, callback?: (err?: NodeJS.ErrnoException) => void): void; - export function lchownSync(path: string | Buffer, uid: number, gid: number): void; - export function chmod(path: string | Buffer, mode: number, callback?: (err?: NodeJS.ErrnoException) => void): void; - export function chmod(path: string | Buffer, mode: string, callback?: (err?: NodeJS.ErrnoException) => void): void; - export function chmodSync(path: string | Buffer, mode: number): void; - export function chmodSync(path: string | Buffer, mode: string): void; - export function fchmod(fd: number, mode: number, callback?: (err?: NodeJS.ErrnoException) => void): void; - export function fchmod(fd: number, mode: string, callback?: (err?: NodeJS.ErrnoException) => void): void; - export function fchmodSync(fd: number, mode: number): void; - export function fchmodSync(fd: number, mode: string): void; - export function lchmod(path: string | Buffer, mode: number, callback?: (err?: NodeJS.ErrnoException) => void): void; - export function lchmod(path: string | Buffer, mode: string, callback?: (err?: NodeJS.ErrnoException) => void): void; - export function lchmodSync(path: string | Buffer, mode: number): void; - export function lchmodSync(path: string | Buffer, mode: string): void; - export function stat(path: string | Buffer, callback?: (err: NodeJS.ErrnoException, stats: Stats) => any): void; - export function lstat(path: string | Buffer, callback?: (err: NodeJS.ErrnoException, stats: Stats) => any): void; - export function fstat(fd: number, callback?: (err: NodeJS.ErrnoException, stats: Stats) => any): void; - export function statSync(path: string | Buffer): Stats; - export function lstatSync(path: string | Buffer): Stats; - export function fstatSync(fd: number): Stats; - export function link(srcpath: string | Buffer, dstpath: string | Buffer, callback?: (err?: NodeJS.ErrnoException) => void): void; - export function linkSync(srcpath: string | Buffer, dstpath: string | Buffer): void; - export function symlink(srcpath: string | Buffer, dstpath: string | Buffer, type?: string, callback?: (err?: NodeJS.ErrnoException) => void): void; - export function symlinkSync(srcpath: string | Buffer, dstpath: string | Buffer, type?: string): void; - export function readlink(path: string | Buffer, callback?: (err: NodeJS.ErrnoException, linkString: string) => any): void; - export function readlinkSync(path: string | Buffer): string; - export function realpath(path: string | Buffer, callback?: (err: NodeJS.ErrnoException, resolvedPath: string) => any): void; - export function realpath(path: string | Buffer, cache: { [path: string]: string }, callback: (err: NodeJS.ErrnoException, resolvedPath: string) => any): void; - export function realpathSync(path: string | Buffer, cache?: { [path: string]: string }): string; + export function renameSync(oldPath: PathLike, newPath: PathLike): void; + /** - * Asynchronous unlink - deletes the file specified in {path} - * - * @param path - * @param callback No arguments other than a possible exception are given to the completion callback. + * Asynchronous truncate(2) - Truncate a file to a specified length. + * @param path A path to a file. If a URL is provided, it must use the `file:` protocol. + * @param len If not specified, defaults to `0`. */ - export function unlink(path: string | Buffer, callback?: (err?: NodeJS.ErrnoException) => void): void; + export function truncate(path: PathLike, len: number | undefined | null, callback: (err: NodeJS.ErrnoException) => void): void; + /** - * Synchronous unlink - deletes the file specified in {path} - * - * @param path + * Asynchronous truncate(2) - Truncate a file to a specified length. + * @param path A path to a file. If a URL is provided, it must use the `file:` protocol. + * URL support is _experimental_. */ - export function unlinkSync(path: string | Buffer): void; + export function truncate(path: PathLike, callback: (err: NodeJS.ErrnoException) => void): void; + + // NOTE: This namespace provides design-time support for util.promisify. Exported members do not exist at runtime. + export namespace truncate { + /** + * Asynchronous truncate(2) - Truncate a file to a specified length. + * @param path A path to a file. If a URL is provided, it must use the `file:` protocol. + * @param len If not specified, defaults to `0`. + */ + export function __promisify__(path: PathLike, len?: number | null): Promise; + } + /** - * Asynchronous rmdir - removes the directory specified in {path} - * - * @param path - * @param callback No arguments other than a possible exception are given to the completion callback. + * Synchronous truncate(2) - Truncate a file to a specified length. + * @param path A path to a file. If a URL is provided, it must use the `file:` protocol. + * @param len If not specified, defaults to `0`. */ - export function rmdir(path: string | Buffer, callback?: (err?: NodeJS.ErrnoException) => void): void; + export function truncateSync(path: PathLike, len?: number | null): void; + /** - * Synchronous rmdir - removes the directory specified in {path} - * - * @param path + * Asynchronous ftruncate(2) - Truncate a file to a specified length. + * @param fd A file descriptor. + * @param len If not specified, defaults to `0`. */ - export function rmdirSync(path: string | Buffer): void; + export function ftruncate(fd: number, len: number | undefined | null, callback: (err: NodeJS.ErrnoException) => void): void; + /** - * Asynchronous mkdir - creates the directory specified in {path}. Parameter {mode} defaults to 0777. - * - * @param path - * @param callback No arguments other than a possible exception are given to the completion callback. + * Asynchronous ftruncate(2) - Truncate a file to a specified length. + * @param fd A file descriptor. */ - export function mkdir(path: string | Buffer, callback?: (err?: NodeJS.ErrnoException) => void): void; + export function ftruncate(fd: number, callback: (err: NodeJS.ErrnoException) => void): void; + + // NOTE: This namespace provides design-time support for util.promisify. Exported members do not exist at runtime. + export namespace ftruncate { + /** + * Asynchronous ftruncate(2) - Truncate a file to a specified length. + * @param fd A file descriptor. + * @param len If not specified, defaults to `0`. + */ + export function __promisify__(fd: number, len?: number | null): Promise; + } + /** - * Asynchronous mkdir - creates the directory specified in {path}. Parameter {mode} defaults to 0777. - * - * @param path - * @param mode - * @param callback No arguments other than a possible exception are given to the completion callback. + * Synchronous ftruncate(2) - Truncate a file to a specified length. + * @param fd A file descriptor. + * @param len If not specified, defaults to `0`. */ - export function mkdir(path: string | Buffer, mode: number, callback?: (err?: NodeJS.ErrnoException) => void): void; + export function ftruncateSync(fd: number, len?: number | null): void; + /** - * Asynchronous mkdir - creates the directory specified in {path}. Parameter {mode} defaults to 0777. - * - * @param path - * @param mode - * @param callback No arguments other than a possible exception are given to the completion callback. + * Asynchronous chown(2) - Change ownership of a file. + * @param path A path to a file. If a URL is provided, it must use the `file:` protocol. */ - export function mkdir(path: string | Buffer, mode: string, callback?: (err?: NodeJS.ErrnoException) => void): void; + export function chown(path: PathLike, uid: number, gid: number, callback: (err: NodeJS.ErrnoException) => void): void; + + // NOTE: This namespace provides design-time support for util.promisify. Exported members do not exist at runtime. + export namespace chown { + /** + * Asynchronous chown(2) - Change ownership of a file. + * @param path A path to a file. If a URL is provided, it must use the `file:` protocol. + */ + export function __promisify__(path: PathLike, uid: number, gid: number): Promise; + } + /** - * Synchronous mkdir - creates the directory specified in {path}. Parameter {mode} defaults to 0777. - * - * @param path - * @param mode - * @param callback No arguments other than a possible exception are given to the completion callback. + * Synchronous chown(2) - Change ownership of a file. + * @param path A path to a file. If a URL is provided, it must use the `file:` protocol. */ - export function mkdirSync(path: string | Buffer, mode?: number): void; + export function chownSync(path: PathLike, uid: number, gid: number): void; + /** - * Synchronous mkdir - creates the directory specified in {path}. Parameter {mode} defaults to 0777. - * - * @param path - * @param mode - * @param callback No arguments other than a possible exception are given to the completion callback. + * Asynchronous fchown(2) - Change ownership of a file. + * @param fd A file descriptor. */ - export function mkdirSync(path: string | Buffer, mode?: string): void; + export function fchown(fd: number, uid: number, gid: number, callback: (err: NodeJS.ErrnoException) => void): void; + + // NOTE: This namespace provides design-time support for util.promisify. Exported members do not exist at runtime. + export namespace fchown { + /** + * Asynchronous fchown(2) - Change ownership of a file. + * @param fd A file descriptor. + */ + export function __promisify__(fd: number, uid: number, gid: number): Promise; + } + /** - * Asynchronous mkdtemp - Creates a unique temporary directory. Generates six random characters to be appended behind a required prefix to create a unique temporary directory. - * - * @param prefix - * @param callback The created folder path is passed as a string to the callback's second parameter. + * Synchronous fchown(2) - Change ownership of a file. + * @param fd A file descriptor. */ - export function mkdtemp(prefix: string, callback?: (err: NodeJS.ErrnoException, folder: string) => void): void; + export function fchownSync(fd: number, uid: number, gid: number): void; + /** - * Synchronous mkdtemp - Creates a unique temporary directory. Generates six random characters to be appended behind a required prefix to create a unique temporary directory. - * - * @param prefix - * @returns Returns the created folder path. + * Asynchronous lchown(2) - Change ownership of a file. Does not dereference symbolic links. + * @param path A path to a file. If a URL is provided, it must use the `file:` protocol. */ - export function mkdtempSync(prefix: string): string; - export function readdir(path: string | Buffer, callback: (err: NodeJS.ErrnoException, files: string[]) => void): void; - export function readdir(path: string | Buffer, options: string | {}, callback: (err: NodeJS.ErrnoException, files: string[]) => void): void; - export function readdirSync(path: string | Buffer, options?: string | {}): string[]; - export function close(fd: number, callback?: (err?: NodeJS.ErrnoException) => void): void; - export function closeSync(fd: number): void; - export function open(path: string | Buffer, flags: string | number, callback: (err: NodeJS.ErrnoException, fd: number) => void): void; - export function open(path: string | Buffer, flags: string | number, mode: number, callback: (err: NodeJS.ErrnoException, fd: number) => void): void; - export function openSync(path: string | Buffer, flags: string | number, mode?: number): number; - export function utimes(path: string | Buffer, atime: number, mtime: number, callback?: (err?: NodeJS.ErrnoException) => void): void; - export function utimes(path: string | Buffer, atime: Date, mtime: Date, callback?: (err?: NodeJS.ErrnoException) => void): void; - export function utimesSync(path: string | Buffer, atime: number, mtime: number): void; - export function utimesSync(path: string | Buffer, atime: Date, mtime: Date): void; - export function futimes(fd: number, atime: number, mtime: number, callback?: (err?: NodeJS.ErrnoException) => void): void; - export function futimes(fd: number, atime: Date, mtime: Date, callback?: (err?: NodeJS.ErrnoException) => void): void; - export function futimesSync(fd: number, atime: number, mtime: number): void; - export function futimesSync(fd: number, atime: Date, mtime: Date): void; - export function fsync(fd: number, callback?: (err?: NodeJS.ErrnoException) => void): void; - export function fsyncSync(fd: number): void; - export function write(fd: number, buffer: Buffer, offset: number, length: number, position: number | null, callback?: (err: NodeJS.ErrnoException, written: number, buffer: Buffer) => void): void; - export function write(fd: number, buffer: Buffer, offset: number, length: number, callback?: (err: NodeJS.ErrnoException, written: number, buffer: Buffer) => void): void; - export function write(fd: number, data: any, callback?: (err: NodeJS.ErrnoException, written: number, str: string) => void): void; - export function write(fd: number, data: any, offset: number, callback?: (err: NodeJS.ErrnoException, written: number, str: string) => void): void; - export function write(fd: number, data: any, offset: number, encoding: string, callback?: (err: NodeJS.ErrnoException, written: number, str: string) => void): void; - export function writeSync(fd: number, buffer: Buffer, offset: number, length: number, position?: number | null): number; - export function writeSync(fd: number, data: any, position?: number | null, enconding?: string): number; - export function read(fd: number, buffer: Buffer, offset: number, length: number, position: number | null, callback?: (err: NodeJS.ErrnoException, bytesRead: number, buffer: Buffer) => void): void; - export function readSync(fd: number, buffer: Buffer, offset: number, length: number, position: number | null): number; + export function lchown(path: PathLike, uid: number, gid: number, callback: (err: NodeJS.ErrnoException) => void): void; + + // NOTE: This namespace provides design-time support for util.promisify. Exported members do not exist at runtime. + export namespace lchown { + /** + * Asynchronous lchown(2) - Change ownership of a file. Does not dereference symbolic links. + * @param path A path to a file. If a URL is provided, it must use the `file:` protocol. + */ + export function __promisify__(path: PathLike, uid: number, gid: number): Promise; + } + /** - * Asynchronous readFile - Asynchronously reads the entire contents of a file. - * - * @param fileName - * @param encoding - * @param callback - The callback is passed two arguments (err, data), where data is the contents of the file. + * Synchronous lchown(2) - Change ownership of a file. Does not dereference symbolic links. + * @param path A path to a file. If a URL is provided, it must use the `file:` protocol. */ - export function readFile(filename: string, encoding: null, callback: (err: NodeJS.ErrnoException, data: Buffer) => void): void; - export function readFile(filename: string, encoding: string, callback: (err: NodeJS.ErrnoException, data: string) => void): void; - export function readFile(filename: string, encoding: string | null, callback: (err: NodeJS.ErrnoException, data: string | Buffer) => void): void; + export function lchownSync(path: PathLike, uid: number, gid: number): void; + /** - * Asynchronous readFile - Asynchronously reads the entire contents of a file. - * - * @param fileName - * @param options An object with optional {encoding} and {flag} properties. If {encoding} is specified, readFile returns a string; otherwise it returns a Buffer. - * @param callback - The callback is passed two arguments (err, data), where data is the contents of the file. + * Asynchronous chmod(2) - Change permissions of a file. + * @param path A path to a file. If a URL is provided, it must use the `file:` protocol. + * @param mode A file mode. If a string is passed, it is parsed as an octal integer. */ - export function readFile(filename: string, options: { encoding: null; flag?: string; }, callback: (err: NodeJS.ErrnoException, data: Buffer) => void): void; - export function readFile(filename: string, options: { encoding: string; flag?: string; }, callback: (err: NodeJS.ErrnoException, data: string) => void): void; - export function readFile(filename: string, options: { encoding: string | null; flag?: string; }, callback: (err: NodeJS.ErrnoException, data: string | Buffer) => void): void; + export function chmod(path: PathLike, mode: string | number, callback: (err: NodeJS.ErrnoException) => void): void; + + // NOTE: This namespace provides design-time support for util.promisify. Exported members do not exist at runtime. + export namespace chmod { + /** + * Asynchronous chmod(2) - Change permissions of a file. + * @param path A path to a file. If a URL is provided, it must use the `file:` protocol. + * @param mode A file mode. If a string is passed, it is parsed as an octal integer. + */ + export function __promisify__(path: PathLike, mode: string | number): Promise; + } + /** - * Asynchronous readFile - Asynchronously reads the entire contents of a file. - * - * @param fileName - * @param options An object with optional {encoding} and {flag} properties. If {encoding} is specified, readFile returns a string; otherwise it returns a Buffer. - * @param callback - The callback is passed two arguments (err, data), where data is the contents of the file. + * Synchronous chmod(2) - Change permissions of a file. + * @param path A path to a file. If a URL is provided, it must use the `file:` protocol. + * @param mode A file mode. If a string is passed, it is parsed as an octal integer. */ - export function readFile(filename: string, options: { flag?: string; }, callback: (err: NodeJS.ErrnoException, data: Buffer) => void): void; + export function chmodSync(path: PathLike, mode: string | number): void; + /** - * Asynchronous readFile - Asynchronously reads the entire contents of a file. - * - * @param fileName - * @param callback - The callback is passed two arguments (err, data), where data is the contents of the file. + * Asynchronous fchmod(2) - Change permissions of a file. + * @param fd A file descriptor. + * @param mode A file mode. If a string is passed, it is parsed as an octal integer. */ - export function readFile(filename: string, callback: (err: NodeJS.ErrnoException, data: Buffer) => void): void; + export function fchmod(fd: number, mode: string | number, callback: (err: NodeJS.ErrnoException) => void): void; + + // NOTE: This namespace provides design-time support for util.promisify. Exported members do not exist at runtime. + export namespace fchmod { + /** + * Asynchronous fchmod(2) - Change permissions of a file. + * @param fd A file descriptor. + * @param mode A file mode. If a string is passed, it is parsed as an octal integer. + */ + export function __promisify__(fd: number, mode: string | number): Promise; + } + /** - * Synchronous readFile - Synchronously reads the entire contents of a file. - * - * @param fileName - * @param encoding + * Synchronous fchmod(2) - Change permissions of a file. + * @param fd A file descriptor. + * @param mode A file mode. If a string is passed, it is parsed as an octal integer. */ - export function readFileSync(filename: string, encoding: null): Buffer; - export function readFileSync(filename: string, encoding: string): string; - export function readFileSync(filename: string, encoding: string | null): string | Buffer; + export function fchmodSync(fd: number, mode: string | number): void; + /** - * Synchronous readFile - Synchronously reads the entire contents of a file. - * - * @param fileName - * @param options An object with optional {encoding} and {flag} properties. If {encoding} is specified, readFileSync returns a string; otherwise it returns a Buffer. + * Asynchronous lchmod(2) - Change permissions of a file. Does not dereference symbolic links. + * @param path A path to a file. If a URL is provided, it must use the `file:` protocol. + * @param mode A file mode. If a string is passed, it is parsed as an octal integer. */ - export function readFileSync(filename: string, options: { encoding: null; flag?: string; }): Buffer; - export function readFileSync(filename: string, options: { encoding: string; flag?: string; }): string; - export function readFileSync(filename: string, options: { encoding: string | null; flag?: string; }): string | Buffer; + export function lchmod(path: PathLike, mode: string | number, callback: (err: NodeJS.ErrnoException) => void): void; + + // NOTE: This namespace provides design-time support for util.promisify. Exported members do not exist at runtime. + export namespace lchmod { + /** + * Asynchronous lchmod(2) - Change permissions of a file. Does not dereference symbolic links. + * @param path A path to a file. If a URL is provided, it must use the `file:` protocol. + * @param mode A file mode. If a string is passed, it is parsed as an octal integer. + */ + export function __promisify__(path: PathLike, mode: string | number): Promise; + } + /** - * Synchronous readFile - Synchronously reads the entire contents of a file. - * - * @param fileName - * @param options An object with optional {encoding} and {flag} properties. If {encoding} is specified, readFileSync returns a string; otherwise it returns a Buffer. + * Synchronous lchmod(2) - Change permissions of a file. Does not dereference symbolic links. + * @param path A path to a file. If a URL is provided, it must use the `file:` protocol. + * @param mode A file mode. If a string is passed, it is parsed as an octal integer. */ - export function readFileSync(filename: string, options?: { flag?: string; }): Buffer; - export function writeFile(filename: string | number, data: any, callback?: (err: NodeJS.ErrnoException) => void): void; - export function writeFile(filename: string | number, data: any, encoding: string, callback: (err: NodeJS.ErrnoException) => void): void; - export function writeFile(filename: string | number, data: any, options: { encoding?: string; mode?: number; flag?: string; }, callback?: (err: NodeJS.ErrnoException) => void): void; - export function writeFile(filename: string | number, data: any, options: { encoding?: string; mode?: string; flag?: string; }, callback?: (err: NodeJS.ErrnoException) => void): void; - export function writeFileSync(filename: string | number, data: any, encoding: string): void; - export function writeFileSync(filename: string | number, data: any, options?: { encoding?: string; mode?: number; flag?: string; }): void; - export function writeFileSync(filename: string | number, data: any, options?: { encoding?: string; mode?: string; flag?: string; }): void; - export function appendFile(filename: string, data: any, encoding: string, callback: (err: NodeJS.ErrnoException) => void): void; - export function appendFile(filename: string, data: any, options: { encoding?: string; mode?: number; flag?: string; }, callback?: (err: NodeJS.ErrnoException) => void): void; - export function appendFile(filename: string, data: any, options: { encoding?: string; mode?: string; flag?: string; }, callback?: (err: NodeJS.ErrnoException) => void): void; - export function appendFile(filename: string, data: any, callback?: (err: NodeJS.ErrnoException) => void): void; - export function appendFileSync(filename: string, data: any, encoding: string): void; - export function appendFileSync(filename: string, data: any, options?: { encoding?: string; mode?: number; flag?: string; }): void; - export function appendFileSync(filename: string, data: any, options?: { encoding?: string; mode?: string; flag?: string; }): void; - export function watchFile(filename: string, listener: (curr: Stats, prev: Stats) => void): void; - export function watchFile(filename: string, options: { persistent?: boolean; interval?: number; }, listener: (curr: Stats, prev: Stats) => void): void; - export function unwatchFile(filename: string, listener?: (curr: Stats, prev: Stats) => void): void; - export function watch(filename: string, listener?: (event: string, filename: string) => any): FSWatcher; - export function watch(filename: string, encoding: string, listener?: (event: string, filename: string | Buffer) => any): FSWatcher; - export function watch(filename: string, options: { persistent?: boolean; recursive?: boolean; encoding?: string }, listener?: (event: string, filename: string | Buffer) => any): FSWatcher; - export function exists(path: string | Buffer, callback?: (exists: boolean) => void): void; - export function existsSync(path: string | Buffer): boolean; + export function lchmodSync(path: PathLike, mode: string | number): void; - export namespace constants { - // File Access Constants + /** + * Asynchronous stat(2) - Get file status. + * @param path A path to a file. If a URL is provided, it must use the `file:` protocol. + */ + export function stat(path: PathLike, callback: (err: NodeJS.ErrnoException, stats: Stats) => void): void; - /** Constant for fs.access(). File is visible to the calling process. */ - export const F_OK: number; + // NOTE: This namespace provides design-time support for util.promisify. Exported members do not exist at runtime. + export namespace stat { + /** + * Asynchronous stat(2) - Get file status. + * @param path A path to a file. If a URL is provided, it must use the `file:` protocol. + */ + export function __promisify__(path: PathLike): Promise; + } - /** Constant for fs.access(). File can be read by the calling process. */ - export const R_OK: number; + /** + * Synchronous stat(2) - Get file status. + * @param path A path to a file. If a URL is provided, it must use the `file:` protocol. + */ + export function statSync(path: PathLike): Stats; - /** Constant for fs.access(). File can be written by the calling process. */ - export const W_OK: number; + /** + * Asynchronous fstat(2) - Get file status. + * @param fd A file descriptor. + */ + export function fstat(fd: number, callback: (err: NodeJS.ErrnoException, stats: Stats) => void): void; - /** Constant for fs.access(). File can be executed by the calling process. */ - export const X_OK: number; + // NOTE: This namespace provides design-time support for util.promisify. Exported members do not exist at runtime. + export namespace fstat { + /** + * Asynchronous fstat(2) - Get file status. + * @param fd A file descriptor. + */ + export function __promisify__(fd: number): Promise; + } - // File Open Constants + /** + * Synchronous fstat(2) - Get file status. + * @param fd A file descriptor. + */ + export function fstatSync(fd: number): Stats; - /** Constant for fs.open(). Flag indicating to open a file for read-only access. */ - export const O_RDONLY: number; + /** + * Asynchronous lstat(2) - Get file status. Does not dereference symbolic links. + * @param path A path to a file. If a URL is provided, it must use the `file:` protocol. + */ + export function lstat(path: PathLike, callback: (err: NodeJS.ErrnoException, stats: Stats) => void): void; - /** Constant for fs.open(). Flag indicating to open a file for write-only access. */ - export const O_WRONLY: number; + // NOTE: This namespace provides design-time support for util.promisify. Exported members do not exist at runtime. + export namespace lstat { + /** + * Asynchronous lstat(2) - Get file status. Does not dereference symbolic links. + * @param path A path to a file. If a URL is provided, it must use the `file:` protocol. + */ + export function __promisify__(path: PathLike): Promise; + } - /** Constant for fs.open(). Flag indicating to open a file for read-write access. */ - export const O_RDWR: number; + /** + * Synchronous lstat(2) - Get file status. Does not dereference symbolic links. + * @param path A path to a file. If a URL is provided, it must use the `file:` protocol. + */ + export function lstatSync(path: PathLike): Stats; - /** Constant for fs.open(). Flag indicating to create the file if it does not already exist. */ - export const O_CREAT: number; + /** + * Asynchronous link(2) - Create a new link (also known as a hard link) to an existing file. + * @param existingPath A path to a file. If a URL is provided, it must use the `file:` protocol. + * @param newPath A path to a file. If a URL is provided, it must use the `file:` protocol. + */ + export function link(existingPath: PathLike, newPath: PathLike, callback: (err: NodeJS.ErrnoException) => void): void; - /** Constant for fs.open(). Flag indicating that opening a file should fail if the O_CREAT flag is set and the file already exists. */ - export const O_EXCL: number; + // NOTE: This namespace provides design-time support for util.promisify. Exported members do not exist at runtime. + export namespace link { + /** + * Asynchronous link(2) - Create a new link (also known as a hard link) to an existing file. + * @param existingPath A path to a file. If a URL is provided, it must use the `file:` protocol. + * @param newPath A path to a file. If a URL is provided, it must use the `file:` protocol. + */ + export function link(existingPath: PathLike, newPath: PathLike): Promise; + } - /** Constant for fs.open(). Flag indicating that if path identifies a terminal device, opening the path shall not cause that terminal to become the controlling terminal for the process (if the process does not already have one). */ - export const O_NOCTTY: number; + /** + * Synchronous link(2) - Create a new link (also known as a hard link) to an existing file. + * @param existingPath A path to a file. If a URL is provided, it must use the `file:` protocol. + * @param newPath A path to a file. If a URL is provided, it must use the `file:` protocol. + */ + export function linkSync(existingPath: PathLike, newPath: PathLike): void; - /** Constant for fs.open(). Flag indicating that if the file exists and is a regular file, and the file is opened successfully for write access, its length shall be truncated to zero. */ - export const O_TRUNC: number; + /** + * Asynchronous symlink(2) - Create a new symbolic link to an existing file. + * @param target A path to an existing file. If a URL is provided, it must use the `file:` protocol. + * @param path A path to the new symlink. If a URL is provided, it must use the `file:` protocol. + * @param type May be set to `'dir'`, `'file'`, or `'junction'` (default is `'file'`) and is only available on Windows (ignored on other platforms). + * When using `'junction'`, the `target` argument will automatically be normalized to an absolute path. + */ + export function symlink(target: PathLike, path: PathLike, type: symlink.Type | undefined | null, callback: (err: NodeJS.ErrnoException) => void): void; - /** Constant for fs.open(). Flag indicating that data will be appended to the end of the file. */ - export const O_APPEND: number; + /** + * Asynchronous symlink(2) - Create a new symbolic link to an existing file. + * @param target A path to an existing file. If a URL is provided, it must use the `file:` protocol. + * @param path A path to the new symlink. If a URL is provided, it must use the `file:` protocol. + */ + export function symlink(target: PathLike, path: PathLike, callback: (err: NodeJS.ErrnoException) => void): void; - /** Constant for fs.open(). Flag indicating that the open should fail if the path is not a directory. */ - export const O_DIRECTORY: number; + // NOTE: This namespace provides design-time support for util.promisify. Exported members do not exist at runtime. + export namespace symlink { + /** + * Asynchronous symlink(2) - Create a new symbolic link to an existing file. + * @param target A path to an existing file. If a URL is provided, it must use the `file:` protocol. + * @param path A path to the new symlink. If a URL is provided, it must use the `file:` protocol. + * @param type May be set to `'dir'`, `'file'`, or `'junction'` (default is `'file'`) and is only available on Windows (ignored on other platforms). + * When using `'junction'`, the `target` argument will automatically be normalized to an absolute path. + */ + export function __promisify__(target: PathLike, path: PathLike, type?: string | null): Promise; - /** Constant for fs.open(). Flag indicating reading accesses to the file system will no longer result in an update to the atime information associated with the file. This flag is available on Linux operating systems only. */ - export const O_NOATIME: number; + export type Type = "dir" | "file" | "junction"; + } - /** Constant for fs.open(). Flag indicating that the open should fail if the path is a symbolic link. */ - export const O_NOFOLLOW: number; + /** + * Synchronous symlink(2) - Create a new symbolic link to an existing file. + * @param target A path to an existing file. If a URL is provided, it must use the `file:` protocol. + * @param path A path to the new symlink. If a URL is provided, it must use the `file:` protocol. + * @param type May be set to `'dir'`, `'file'`, or `'junction'` (default is `'file'`) and is only available on Windows (ignored on other platforms). + * When using `'junction'`, the `target` argument will automatically be normalized to an absolute path. + */ + export function symlinkSync(target: PathLike, path: PathLike, type?: symlink.Type | null): void; - /** Constant for fs.open(). Flag indicating that the file is opened for synchronous I/O. */ - export const O_SYNC: number; + /** + * Asynchronous readlink(2) - read value of a symbolic link. + * @param path A path to a file. If a URL is provided, it must use the `file:` protocol. + * @param options The encoding (or an object specifying the encoding), used as the encoding of the result. If not provided, `'utf8'` is used. + */ + export function readlink(path: PathLike, options: { encoding?: BufferEncoding | null } | BufferEncoding | undefined | null, callback: (err: NodeJS.ErrnoException, linkString: string) => void): void; - /** Constant for fs.open(). Flag indicating to open the symbolic link itself rather than the resource it is pointing to. */ - export const O_SYMLINK: number; + /** + * Asynchronous readlink(2) - read value of a symbolic link. + * @param path A path to a file. If a URL is provided, it must use the `file:` protocol. + * @param options The encoding (or an object specifying the encoding), used as the encoding of the result. If not provided, `'utf8'` is used. + */ + export function readlink(path: PathLike, options: { encoding: "buffer" } | "buffer", callback: (err: NodeJS.ErrnoException, linkString: Buffer) => void): void; - /** Constant for fs.open(). When set, an attempt will be made to minimize caching effects of file I/O. */ - export const O_DIRECT: number; + /** + * Asynchronous readlink(2) - read value of a symbolic link. + * @param path A path to a file. If a URL is provided, it must use the `file:` protocol. + * @param options The encoding (or an object specifying the encoding), used as the encoding of the result. If not provided, `'utf8'` is used. + */ + export function readlink(path: PathLike, options: { encoding?: string | null } | string | undefined | null, callback: (err: NodeJS.ErrnoException, linkString: string | Buffer) => void): void; - /** Constant for fs.open(). Flag indicating to open the file in nonblocking mode when possible. */ - export const O_NONBLOCK: number; + /** + * Asynchronous readlink(2) - read value of a symbolic link. + * @param path A path to a file. If a URL is provided, it must use the `file:` protocol. + */ + export function readlink(path: PathLike, callback: (err: NodeJS.ErrnoException, linkString: string) => void): void; - // File Type Constants + // NOTE: This namespace provides design-time support for util.promisify. Exported members do not exist at runtime. + export namespace readlink { + /** + * Asynchronous readlink(2) - read value of a symbolic link. + * @param path A path to a file. If a URL is provided, it must use the `file:` protocol. + * @param options The encoding (or an object specifying the encoding), used as the encoding of the result. If not provided, `'utf8'` is used. + */ + export function __promisify__(path: PathLike, options?: { encoding?: BufferEncoding | null } | BufferEncoding | null): Promise; - /** Constant for fs.Stats mode property for determining a file's type. Bit mask used to extract the file type code. */ - export const S_IFMT: number; + /** + * Asynchronous readlink(2) - read value of a symbolic link. + * @param path A path to a file. If a URL is provided, it must use the `file:` protocol. + * @param options The encoding (or an object specifying the encoding), used as the encoding of the result. If not provided, `'utf8'` is used. + */ + export function __promisify__(path: PathLike, options: { encoding: "buffer" } | "buffer"): Promise; - /** Constant for fs.Stats mode property for determining a file's type. File type constant for a regular file. */ - export const S_IFREG: number; + /** + * Asynchronous readlink(2) - read value of a symbolic link. + * @param path A path to a file. If a URL is provided, it must use the `file:` protocol. + * @param options The encoding (or an object specifying the encoding), used as the encoding of the result. If not provided, `'utf8'` is used. + */ + export function __promisify__(path: PathLike, options?: { encoding?: string | null } | string | null): Promise; + } - /** Constant for fs.Stats mode property for determining a file's type. File type constant for a directory. */ - export const S_IFDIR: number; + /** + * Synchronous readlink(2) - read value of a symbolic link. + * @param path A path to a file. If a URL is provided, it must use the `file:` protocol. + * @param options The encoding (or an object specifying the encoding), used as the encoding of the result. If not provided, `'utf8'` is used. + */ + export function readlinkSync(path: PathLike, options?: { encoding?: BufferEncoding | null } | BufferEncoding | null): string; - /** Constant for fs.Stats mode property for determining a file's type. File type constant for a character-oriented device file. */ - export const S_IFCHR: number; + /** + * Synchronous readlink(2) - read value of a symbolic link. + * @param path A path to a file. If a URL is provided, it must use the `file:` protocol. + * @param options The encoding (or an object specifying the encoding), used as the encoding of the result. If not provided, `'utf8'` is used. + */ + export function readlinkSync(path: PathLike, options: { encoding: "buffer" } | "buffer"): Buffer; - /** Constant for fs.Stats mode property for determining a file's type. File type constant for a block-oriented device file. */ - export const S_IFBLK: number; + /** + * Synchronous readlink(2) - read value of a symbolic link. + * @param path A path to a file. If a URL is provided, it must use the `file:` protocol. + * @param options The encoding (or an object specifying the encoding), used as the encoding of the result. If not provided, `'utf8'` is used. + */ + export function readlinkSync(path: PathLike, options?: { encoding?: string | null } | string | null): string | Buffer; - /** Constant for fs.Stats mode property for determining a file's type. File type constant for a FIFO/pipe. */ - export const S_IFIFO: number; + /** + * Asynchronous realpath(3) - return the canonicalized absolute pathname. + * @param path A path to a file. If a URL is provided, it must use the `file:` protocol. + * @param options The encoding (or an object specifying the encoding), used as the encoding of the result. If not provided, `'utf8'` is used. + */ + export function realpath(path: PathLike, options: { encoding?: BufferEncoding | null } | BufferEncoding | undefined | null, callback: (err: NodeJS.ErrnoException, resolvedPath: string) => void): void; - /** Constant for fs.Stats mode property for determining a file's type. File type constant for a symbolic link. */ - export const S_IFLNK: number; + /** + * Asynchronous realpath(3) - return the canonicalized absolute pathname. + * @param path A path to a file. If a URL is provided, it must use the `file:` protocol. + * @param options The encoding (or an object specifying the encoding), used as the encoding of the result. If not provided, `'utf8'` is used. + */ + export function realpath(path: PathLike, options: { encoding: "buffer" } | "buffer", callback: (err: NodeJS.ErrnoException, resolvedPath: Buffer) => void): void; - /** Constant for fs.Stats mode property for determining a file's type. File type constant for a socket. */ - export const S_IFSOCK: number; + /** + * Asynchronous realpath(3) - return the canonicalized absolute pathname. + * @param path A path to a file. If a URL is provided, it must use the `file:` protocol. + * @param options The encoding (or an object specifying the encoding), used as the encoding of the result. If not provided, `'utf8'` is used. + */ + export function realpath(path: PathLike, options: { encoding?: string | null } | string | undefined | null, callback: (err: NodeJS.ErrnoException, resolvedPath: string | Buffer) => void): void; - // File Mode Constants + /** + * Asynchronous realpath(3) - return the canonicalized absolute pathname. + * @param path A path to a file. If a URL is provided, it must use the `file:` protocol. + */ + export function realpath(path: PathLike, callback: (err: NodeJS.ErrnoException, resolvedPath: string) => void): void; - /** Constant for fs.Stats mode property for determining access permissions for a file. File mode indicating readable, writable and executable by owner. */ - export const S_IRWXU: number; + // NOTE: This namespace provides design-time support for util.promisify. Exported members do not exist at runtime. + export namespace realpath { + /** + * Asynchronous realpath(3) - return the canonicalized absolute pathname. + * @param path A path to a file. If a URL is provided, it must use the `file:` protocol. + * @param options The encoding (or an object specifying the encoding), used as the encoding of the result. If not provided, `'utf8'` is used. + */ + export function __promisify__(path: PathLike, options?: { encoding?: BufferEncoding | null } | BufferEncoding | null): Promise; - /** Constant for fs.Stats mode property for determining access permissions for a file. File mode indicating readable by owner. */ - export const S_IRUSR: number; + /** + * Asynchronous realpath(3) - return the canonicalized absolute pathname. + * @param path A path to a file. If a URL is provided, it must use the `file:` protocol. + * @param options The encoding (or an object specifying the encoding), used as the encoding of the result. If not provided, `'utf8'` is used. + */ + export function __promisify__(path: PathLike, options: { encoding: "buffer" } | "buffer"): Promise; - /** Constant for fs.Stats mode property for determining access permissions for a file. File mode indicating writable by owner. */ - export const S_IWUSR: number; + /** + * Asynchronous realpath(3) - return the canonicalized absolute pathname. + * @param path A path to a file. If a URL is provided, it must use the `file:` protocol. + * @param options The encoding (or an object specifying the encoding), used as the encoding of the result. If not provided, `'utf8'` is used. + */ + export function __promisify__(path: PathLike, options?: { encoding?: string | null } | string | null): Promise; + } - /** Constant for fs.Stats mode property for determining access permissions for a file. File mode indicating executable by owner. */ - export const S_IXUSR: number; + /** + * Synchronous realpath(3) - return the canonicalized absolute pathname. + * @param path A path to a file. If a URL is provided, it must use the `file:` protocol. + * @param options The encoding (or an object specifying the encoding), used as the encoding of the result. If not provided, `'utf8'` is used. + */ + export function realpathSync(path: PathLike, options?: { encoding?: BufferEncoding | null } | BufferEncoding | null): string; - /** Constant for fs.Stats mode property for determining access permissions for a file. File mode indicating readable, writable and executable by group. */ - export const S_IRWXG: number; + /** + * Synchronous realpath(3) - return the canonicalized absolute pathname. + * @param path A path to a file. If a URL is provided, it must use the `file:` protocol. + * @param options The encoding (or an object specifying the encoding), used as the encoding of the result. If not provided, `'utf8'` is used. + */ + export function realpathSync(path: PathLike, options: { encoding: "buffer" } | "buffer"): Buffer; - /** Constant for fs.Stats mode property for determining access permissions for a file. File mode indicating readable by group. */ - export const S_IRGRP: number; + /** + * Synchronous realpath(3) - return the canonicalized absolute pathname. + * @param path A path to a file. If a URL is provided, it must use the `file:` protocol. + * @param options The encoding (or an object specifying the encoding), used as the encoding of the result. If not provided, `'utf8'` is used. + */ + export function realpathSync(path: PathLike, options?: { encoding?: string | null } | string | null): string | Buffer; - /** Constant for fs.Stats mode property for determining access permissions for a file. File mode indicating writable by group. */ - export const S_IWGRP: number; + /** + * Asynchronous unlink(2) - delete a name and possibly the file it refers to. + * @param path A path to a file. If a URL is provided, it must use the `file:` protocol. + */ + export function unlink(path: PathLike, callback: (err: NodeJS.ErrnoException) => void): void; - /** Constant for fs.Stats mode property for determining access permissions for a file. File mode indicating executable by group. */ - export const S_IXGRP: number; + // NOTE: This namespace provides design-time support for util.promisify. Exported members do not exist at runtime. + export namespace unlink { + /** + * Asynchronous unlink(2) - delete a name and possibly the file it refers to. + * @param path A path to a file. If a URL is provided, it must use the `file:` protocol. + */ + export function __promisify__(path: PathLike): Promise; + } - /** Constant for fs.Stats mode property for determining access permissions for a file. File mode indicating readable, writable and executable by others. */ - export const S_IRWXO: number; + /** + * Synchronous unlink(2) - delete a name and possibly the file it refers to. + * @param path A path to a file. If a URL is provided, it must use the `file:` protocol. + */ + export function unlinkSync(path: PathLike): void; - /** Constant for fs.Stats mode property for determining access permissions for a file. File mode indicating readable by others. */ - export const S_IROTH: number; + /** + * Asynchronous rmdir(2) - delete a directory. + * @param path A path to a file. If a URL is provided, it must use the `file:` protocol. + */ + export function rmdir(path: PathLike, callback: (err: NodeJS.ErrnoException) => void): void; - /** Constant for fs.Stats mode property for determining access permissions for a file. File mode indicating writable by others. */ - export const S_IWOTH: number; + // NOTE: This namespace provides design-time support for util.promisify. Exported members do not exist at runtime. + export namespace rmdir { + /** + * Asynchronous rmdir(2) - delete a directory. + * @param path A path to a file. If a URL is provided, it must use the `file:` protocol. + */ + export function __promisify__(path: PathLike): Promise; + } - /** Constant for fs.Stats mode property for determining access permissions for a file. File mode indicating executable by others. */ - export const S_IXOTH: number; - } + /** + * Synchronous rmdir(2) - delete a directory. + * @param path A path to a file. If a URL is provided, it must use the `file:` protocol. + */ + export function rmdirSync(path: PathLike): void; - /** Tests a user's permissions for the file specified by path. */ - export function access(path: string | Buffer, callback: (err: NodeJS.ErrnoException) => void): void; - export function access(path: string | Buffer, mode: number, callback: (err: NodeJS.ErrnoException) => void): void; - /** Synchronous version of fs.access. This throws if any accessibility checks fail, and does nothing otherwise. */ - export function accessSync(path: string | Buffer, mode?: number): void; - export function createReadStream(path: string | Buffer, options?: { - flags?: string; - encoding?: string; - fd?: number; - mode?: number; - autoClose?: boolean; - start?: number; - end?: number; - }): ReadStream; - export function createWriteStream(path: string | Buffer, options?: { - flags?: string; - encoding?: string; - fd?: number; - mode?: number; - autoClose?: boolean; - start?: number; - }): WriteStream; - export function fdatasync(fd: number, callback: Function): void; - export function fdatasyncSync(fd: number): void; + /** + * Asynchronous mkdir(2) - create a directory. + * @param path A path to a file. If a URL is provided, it must use the `file:` protocol. + * @param mode A file mode. If a string is passed, it is parsed as an octal integer. If not specified, defaults to `0o777`. + */ + export function mkdir(path: PathLike, mode: number | string | undefined | null, callback: (err: NodeJS.ErrnoException) => void): void; + + /** + * Asynchronous mkdir(2) - create a directory with a mode of `0o777`. + * @param path A path to a file. If a URL is provided, it must use the `file:` protocol. + */ + export function mkdir(path: PathLike, callback: (err: NodeJS.ErrnoException) => void): void; + + // NOTE: This namespace provides design-time support for util.promisify. Exported members do not exist at runtime. + export namespace mkdir { + /** + * Asynchronous mkdir(2) - create a directory. + * @param path A path to a file. If a URL is provided, it must use the `file:` protocol. + * @param mode A file mode. If a string is passed, it is parsed as an octal integer. If not specified, defaults to `0o777`. + */ + export function __promisify__(path: PathLike, mode?: number | string | null): Promise; + } + + /** + * Synchronous mkdir(2) - create a directory. + * @param path A path to a file. If a URL is provided, it must use the `file:` protocol. + * @param mode A file mode. If a string is passed, it is parsed as an octal integer. If not specified, defaults to `0o777`. + */ + export function mkdirSync(path: PathLike, mode?: number | string | null): void; + + /** + * Asynchronously creates a unique temporary directory. + * Generates six random characters to be appended behind a required prefix to create a unique temporary directory. + * @param options The encoding (or an object specifying the encoding), used as the encoding of the result. If not provided, `'utf8'` is used. + */ + export function mkdtemp(prefix: string, options: { encoding?: BufferEncoding | null } | BufferEncoding | undefined | null, callback: (err: NodeJS.ErrnoException, folder: string) => void): void; + + /** + * Asynchronously creates a unique temporary directory. + * Generates six random characters to be appended behind a required prefix to create a unique temporary directory. + * @param options The encoding (or an object specifying the encoding), used as the encoding of the result. If not provided, `'utf8'` is used. + */ + export function mkdtemp(prefix: string, options: "buffer" | { encoding: "buffer" }, callback: (err: NodeJS.ErrnoException, folder: Buffer) => void): void; + + /** + * Asynchronously creates a unique temporary directory. + * Generates six random characters to be appended behind a required prefix to create a unique temporary directory. + * @param options The encoding (or an object specifying the encoding), used as the encoding of the result. If not provided, `'utf8'` is used. + */ + export function mkdtemp(prefix: string, options: { encoding?: string | null } | string | undefined | null, callback: (err: NodeJS.ErrnoException, folder: string | Buffer) => void): void; + + /** + * Asynchronously creates a unique temporary directory. + * Generates six random characters to be appended behind a required prefix to create a unique temporary directory. + */ + export function mkdtemp(prefix: string, callback: (err: NodeJS.ErrnoException, folder: string) => void): void; + + // NOTE: This namespace provides design-time support for util.promisify. Exported members do not exist at runtime. + export namespace mkdtemp { + /** + * Asynchronously creates a unique temporary directory. + * Generates six random characters to be appended behind a required prefix to create a unique temporary directory. + * @param options The encoding (or an object specifying the encoding), used as the encoding of the result. If not provided, `'utf8'` is used. + */ + export function __promisify__(prefix: string, options?: { encoding?: BufferEncoding | null } | BufferEncoding | null): Promise; + + /** + * Asynchronously creates a unique temporary directory. + * Generates six random characters to be appended behind a required prefix to create a unique temporary directory. + * @param options The encoding (or an object specifying the encoding), used as the encoding of the result. If not provided, `'utf8'` is used. + */ + export function __promisify__(prefix: string, options: { encoding: "buffer" } | "buffer"): Promise; + + /** + * Asynchronously creates a unique temporary directory. + * Generates six random characters to be appended behind a required prefix to create a unique temporary directory. + * @param options The encoding (or an object specifying the encoding), used as the encoding of the result. If not provided, `'utf8'` is used. + */ + export function __promisify__(prefix: string, options?: { encoding?: string | null } | string | null): Promise; + } + + /** + * Synchronously creates a unique temporary directory. + * Generates six random characters to be appended behind a required prefix to create a unique temporary directory. + * @param options The encoding (or an object specifying the encoding), used as the encoding of the result. If not provided, `'utf8'` is used. + */ + export function mkdtempSync(prefix: string, options?: { encoding?: BufferEncoding | null } | BufferEncoding | null): string; + + /** + * Synchronously creates a unique temporary directory. + * Generates six random characters to be appended behind a required prefix to create a unique temporary directory. + * @param options The encoding (or an object specifying the encoding), used as the encoding of the result. If not provided, `'utf8'` is used. + */ + export function mkdtempSync(prefix: string, options: { encoding: "buffer" } | "buffer"): Buffer; + + /** + * Synchronously creates a unique temporary directory. + * Generates six random characters to be appended behind a required prefix to create a unique temporary directory. + * @param options The encoding (or an object specifying the encoding), used as the encoding of the result. If not provided, `'utf8'` is used. + */ + export function mkdtempSync(prefix: string, options?: { encoding?: string | null } | string | null): string | Buffer; + + /** + * Asynchronous readdir(3) - read a directory. + * @param path A path to a file. If a URL is provided, it must use the `file:` protocol. + * @param options The encoding (or an object specifying the encoding), used as the encoding of the result. If not provided, `'utf8'` is used. + */ + export function readdir(path: PathLike, options: { encoding: BufferEncoding | null } | BufferEncoding | undefined | null, callback: (err: NodeJS.ErrnoException, files: string[]) => void): void; + + /** + * Asynchronous readdir(3) - read a directory. + * @param path A path to a file. If a URL is provided, it must use the `file:` protocol. + * @param options The encoding (or an object specifying the encoding), used as the encoding of the result. If not provided, `'utf8'` is used. + */ + export function readdir(path: PathLike, options: { encoding: "buffer" } | "buffer", callback: (err: NodeJS.ErrnoException, files: Buffer[]) => void): void; + + /** + * Asynchronous readdir(3) - read a directory. + * @param path A path to a file. If a URL is provided, it must use the `file:` protocol. + * @param options The encoding (or an object specifying the encoding), used as the encoding of the result. If not provided, `'utf8'` is used. + */ + export function readdir(path: PathLike, options: { encoding?: string | null } | string | undefined | null, callback: (err: NodeJS.ErrnoException, files: string[] | Buffer[]) => void): void; + + /** + * Asynchronous readdir(3) - read a directory. + * @param path A path to a file. If a URL is provided, it must use the `file:` protocol. + */ + export function readdir(path: PathLike, callback: (err: NodeJS.ErrnoException, files: string[]) => void): void; + + // NOTE: This namespace provides design-time support for util.promisify. Exported members do not exist at runtime. + export namespace readdir { + /** + * Asynchronous readdir(3) - read a directory. + * @param path A path to a file. If a URL is provided, it must use the `file:` protocol. + * @param options The encoding (or an object specifying the encoding), used as the encoding of the result. If not provided, `'utf8'` is used. + */ + export function __promisify__(path: PathLike, options?: { encoding: BufferEncoding | null } | BufferEncoding | null): Promise; + + /** + * Asynchronous readdir(3) - read a directory. + * @param path A path to a file. If a URL is provided, it must use the `file:` protocol. + * @param options The encoding (or an object specifying the encoding), used as the encoding of the result. If not provided, `'utf8'` is used. + */ + export function __promisify__(path: PathLike, options: "buffer" | { encoding: "buffer" }): Promise; + + /** + * Asynchronous readdir(3) - read a directory. + * @param path A path to a file. If a URL is provided, it must use the `file:` protocol. + * @param options The encoding (or an object specifying the encoding), used as the encoding of the result. If not provided, `'utf8'` is used. + */ + export function __promisify__(path: PathLike, options?: { encoding?: string | null } | string | null): Promise; + } + + /** + * Synchronous readdir(3) - read a directory. + * @param path A path to a file. If a URL is provided, it must use the `file:` protocol. + * @param options The encoding (or an object specifying the encoding), used as the encoding of the result. If not provided, `'utf8'` is used. + */ + export function readdirSync(path: PathLike, options?: { encoding: BufferEncoding | null } | BufferEncoding | null): string[]; + + /** + * Synchronous readdir(3) - read a directory. + * @param path A path to a file. If a URL is provided, it must use the `file:` protocol. + * @param options The encoding (or an object specifying the encoding), used as the encoding of the result. If not provided, `'utf8'` is used. + */ + export function readdirSync(path: PathLike, options: { encoding: "buffer" } | "buffer"): Buffer[]; + + /** + * Synchronous readdir(3) - read a directory. + * @param path A path to a file. If a URL is provided, it must use the `file:` protocol. + * @param options The encoding (or an object specifying the encoding), used as the encoding of the result. If not provided, `'utf8'` is used. + */ + export function readdirSync(path: PathLike, options?: { encoding?: string | null } | string | null): string[] | Buffer[]; + + /** + * Asynchronous close(2) - close a file descriptor. + * @param fd A file descriptor. + */ + export function close(fd: number, callback: (err: NodeJS.ErrnoException) => void): void; + + // NOTE: This namespace provides design-time support for util.promisify. Exported members do not exist at runtime. + export namespace close { + /** + * Asynchronous close(2) - close a file descriptor. + * @param fd A file descriptor. + */ + export function __promisify__(fd: number): Promise; + } + + /** + * Synchronous close(2) - close a file descriptor. + * @param fd A file descriptor. + */ + export function closeSync(fd: number): void; + + /** + * Asynchronous open(2) - open and possibly create a file. + * @param path A path to a file. If a URL is provided, it must use the `file:` protocol. + * @param mode A file mode. If a string is passed, it is parsed as an octal integer. If not supplied, defaults to `0o666`. + */ + export function open(path: PathLike, flags: string | number, mode: string | number | undefined | null, callback: (err: NodeJS.ErrnoException, fd: number) => void): void; + + /** + * Asynchronous open(2) - open and possibly create a file. If the file is created, its mode will be `0o666`. + * @param path A path to a file. If a URL is provided, it must use the `file:` protocol. + */ + export function open(path: PathLike, flags: string | number, callback: (err: NodeJS.ErrnoException, fd: number) => void): void; + + // NOTE: This namespace provides design-time support for util.promisify. Exported members do not exist at runtime. + export namespace open { + /** + * Asynchronous open(2) - open and possibly create a file. + * @param path A path to a file. If a URL is provided, it must use the `file:` protocol. + * @param mode A file mode. If a string is passed, it is parsed as an octal integer. If not supplied, defaults to `0o666`. + */ + export function __promisify__(path: PathLike, flags: string | number, mode?: string | number | null): Promise; + } + + /** + * Synchronous open(2) - open and possibly create a file, returning a file descriptor.. + * @param path A path to a file. If a URL is provided, it must use the `file:` protocol. + * @param mode A file mode. If a string is passed, it is parsed as an octal integer. If not supplied, defaults to `0o666`. + */ + export function openSync(path: PathLike, flags: string | number, mode?: string | number | null): number; + + /** + * Asynchronously change file timestamps of the file referenced by the supplied path. + * @param path A path to a file. If a URL is provided, it must use the `file:` protocol. + * @param atime The last access time. If a string is provided, it will be coerced to number. + * @param mtime The last modified time. If a string is provided, it will be coerced to number. + */ + export function utimes(path: PathLike, atime: string | number | Date, mtime: string | number | Date, callback: (err: NodeJS.ErrnoException) => void): void; + + // NOTE: This namespace provides design-time support for util.promisify. Exported members do not exist at runtime. + export namespace utimes { + /** + * Asynchronously change file timestamps of the file referenced by the supplied path. + * @param path A path to a file. If a URL is provided, it must use the `file:` protocol. + * @param atime The last access time. If a string is provided, it will be coerced to number. + * @param mtime The last modified time. If a string is provided, it will be coerced to number. + */ + export function __promisify__(path: PathLike, atime: string | number | Date, mtime: string | number | Date): Promise; + } + + /** + * Synchronously change file timestamps of the file referenced by the supplied path. + * @param path A path to a file. If a URL is provided, it must use the `file:` protocol. + * @param atime The last access time. If a string is provided, it will be coerced to number. + * @param mtime The last modified time. If a string is provided, it will be coerced to number. + */ + export function utimesSync(path: PathLike, atime: string | number | Date, mtime: string | number | Date): void; + + /** + * Asynchronously change file timestamps of the file referenced by the supplied file descriptor. + * @param fd A file descriptor. + * @param atime The last access time. If a string is provided, it will be coerced to number. + * @param mtime The last modified time. If a string is provided, it will be coerced to number. + */ + export function futimes(fd: number, atime: string | number | Date, mtime: string | number | Date, callback: (err: NodeJS.ErrnoException) => void): void; + + // NOTE: This namespace provides design-time support for util.promisify. Exported members do not exist at runtime. + export namespace futimes { + /** + * Asynchronously change file timestamps of the file referenced by the supplied file descriptor. + * @param fd A file descriptor. + * @param atime The last access time. If a string is provided, it will be coerced to number. + * @param mtime The last modified time. If a string is provided, it will be coerced to number. + */ + export function __promisify__(fd: number, atime: string | number | Date, mtime: string | number | Date): Promise; + } + + /** + * Synchronously change file timestamps of the file referenced by the supplied file descriptor. + * @param fd A file descriptor. + * @param atime The last access time. If a string is provided, it will be coerced to number. + * @param mtime The last modified time. If a string is provided, it will be coerced to number. + */ + export function futimesSync(fd: number, atime: string | number | Date, mtime: string | number | Date): void; + + /** + * Asynchronous fsync(2) - synchronize a file's in-core state with the underlying storage device. + * @param fd A file descriptor. + */ + export function fsync(fd: number, callback: (err: NodeJS.ErrnoException) => void): void; + + // NOTE: This namespace provides design-time support for util.promisify. Exported members do not exist at runtime. + export namespace fsync { + /** + * Asynchronous fsync(2) - synchronize a file's in-core state with the underlying storage device. + * @param fd A file descriptor. + */ + export function __promisify__(fd: number): Promise; + } + + /** + * Synchronous fsync(2) - synchronize a file's in-core state with the underlying storage device. + * @param fd A file descriptor. + */ + export function fsyncSync(fd: number): void; + + /** + * Asynchronously writes `buffer` to the file referenced by the supplied file descriptor. + * @param fd A file descriptor. + * @param offset The part of the buffer to be written. If not supplied, defaults to `0`. + * @param length The number of bytes to write. If not supplied, defaults to `buffer.length - offset`. + * @param position The offset from the beginning of the file where this data should be written. If not supplied, defaults to the current position. + */ + export function write(fd: number, buffer: TBuffer, offset: number | undefined | null, length: number | undefined | null, position: number | undefined | null, callback: (err: NodeJS.ErrnoException, written: number, buffer: TBuffer) => void): void; + + /** + * Asynchronously writes `buffer` to the file referenced by the supplied file descriptor. + * @param fd A file descriptor. + * @param offset The part of the buffer to be written. If not supplied, defaults to `0`. + * @param length The number of bytes to write. If not supplied, defaults to `buffer.length - offset`. + */ + export function write(fd: number, buffer: TBuffer, offset: number | undefined | null, length: number | undefined | null, callback: (err: NodeJS.ErrnoException, written: number, buffer: TBuffer) => void): void; + + /** + * Asynchronously writes `buffer` to the file referenced by the supplied file descriptor. + * @param fd A file descriptor. + * @param offset The part of the buffer to be written. If not supplied, defaults to `0`. + */ + export function write(fd: number, buffer: TBuffer, offset: number | undefined | null, callback: (err: NodeJS.ErrnoException, written: number, buffer: TBuffer) => void): void; + + /** + * Asynchronously writes `buffer` to the file referenced by the supplied file descriptor. + * @param fd A file descriptor. + */ + export function write(fd: number, buffer: TBuffer, callback: (err: NodeJS.ErrnoException, written: number, buffer: TBuffer) => void): void; + + /** + * Asynchronously writes `string` to the file referenced by the supplied file descriptor. + * @param fd A file descriptor. + * @param string A string to write. If something other than a string is supplied it will be coerced to a string. + * @param position The offset from the beginning of the file where this data should be written. If not supplied, defaults to the current position. + * @param encoding The expected string encoding. + */ + export function write(fd: number, string: any, position: number | undefined | null, encoding: string | undefined | null, callback: (err: NodeJS.ErrnoException, written: number, str: string) => void): void; + + /** + * Asynchronously writes `string` to the file referenced by the supplied file descriptor. + * @param fd A file descriptor. + * @param string A string to write. If something other than a string is supplied it will be coerced to a string. + * @param position The offset from the beginning of the file where this data should be written. If not supplied, defaults to the current position. + */ + export function write(fd: number, string: any, position: number | undefined | null, callback: (err: NodeJS.ErrnoException, written: number, str: string) => void): void; + + /** + * Asynchronously writes `string` to the file referenced by the supplied file descriptor. + * @param fd A file descriptor. + * @param string A string to write. If something other than a string is supplied it will be coerced to a string. + */ + export function write(fd: number, string: any, callback: (err: NodeJS.ErrnoException, written: number, str: string) => void): void; + + // NOTE: This namespace provides design-time support for util.promisify. Exported members do not exist at runtime. + export namespace write { + /** + * Asynchronously writes `buffer` to the file referenced by the supplied file descriptor. + * @param fd A file descriptor. + * @param offset The part of the buffer to be written. If not supplied, defaults to `0`. + * @param length The number of bytes to write. If not supplied, defaults to `buffer.length - offset`. + * @param position The offset from the beginning of the file where this data should be written. If not supplied, defaults to the current position. + */ + export function __promisify__(fd: number, buffer?: TBuffer, offset?: number, length?: number, position?: number | null): Promise<{ bytesWritten: number, buffer: TBuffer }>; + + /** + * Asynchronously writes `string` to the file referenced by the supplied file descriptor. + * @param fd A file descriptor. + * @param string A string to write. If something other than a string is supplied it will be coerced to a string. + * @param position The offset from the beginning of the file where this data should be written. If not supplied, defaults to the current position. + * @param encoding The expected string encoding. + */ + export function __promisify__(fd: number, string: any, position?: number | null, encoding?: string | null): Promise<{ bytesWritten: number, buffer: string }>; + } + + /** + * Synchronously writes `buffer` to the file referenced by the supplied file descriptor, returning the number of bytes written. + * @param fd A file descriptor. + * @param offset The part of the buffer to be written. If not supplied, defaults to `0`. + * @param length The number of bytes to write. If not supplied, defaults to `buffer.length - offset`. + * @param position The offset from the beginning of the file where this data should be written. If not supplied, defaults to the current position. + */ + export function writeSync(fd: number, buffer: Buffer | Uint8Array, offset?: number | null, length?: number | null, position?: number | null): number; + + /** + * Synchronously writes `string` to the file referenced by the supplied file descriptor, returning the number of bytes written. + * @param fd A file descriptor. + * @param string A string to write. If something other than a string is supplied it will be coerced to a string. + * @param position The offset from the beginning of the file where this data should be written. If not supplied, defaults to the current position. + * @param encoding The expected string encoding. + */ + export function writeSync(fd: number, string: any, position?: number | null, encoding?: string | null): number; + + /** + * Asynchronously reads data from the file referenced by the supplied file descriptor. + * @param fd A file descriptor. + * @param buffer The buffer that the data will be written to. + * @param offset The offset in the buffer at which to start writing. + * @param length The number of bytes to read. + * @param position The offset from the beginning of the file from which data should be read. If `null`, data will be read from the current position. + */ + export function read(fd: number, buffer: TBuffer, offset: number, length: number, position: number | null, callback?: (err: NodeJS.ErrnoException, bytesRead: number, buffer: TBuffer) => void): void; + + // NOTE: This namespace provides design-time support for util.promisify. Exported members do not exist at runtime. + export namespace read { + /** + * @param fd A file descriptor. + * @param buffer The buffer that the data will be written to. + * @param offset The offset in the buffer at which to start writing. + * @param length The number of bytes to read. + * @param position The offset from the beginning of the file from which data should be read. If `null`, data will be read from the current position. + */ + export function __promisify__(fd: number, buffer: TBuffer, offset: number, length: number, position: number | null): Promise<{ bytesRead: number, buffer: TBuffer }>; + } + + /** + * Synchronously reads data from the file referenced by the supplied file descriptor, returning the number of bytes read. + * @param fd A file descriptor. + * @param buffer The buffer that the data will be written to. + * @param offset The offset in the buffer at which to start writing. + * @param length The number of bytes to read. + * @param position The offset from the beginning of the file from which data should be read. If `null`, data will be read from the current position. + */ + export function readSync(fd: number, buffer: Buffer | Uint8Array, offset: number, length: number, position: number | null): number; + + /** + * Asynchronously reads the entire contents of a file. + * @param path A path to a file. If a URL is provided, it must use the `file:` protocol. + * If a file descriptor is provided, the underlying file will _not_ be closed automatically. + * @param options An object that may contain an optional flag. + * If a flag is not provided, it defaults to `'r'`. + */ + export function readFile(path: PathLike | number, options: { encoding?: null; flag?: string; } | undefined | null, callback: (err: NodeJS.ErrnoException, data: Buffer) => void): void; + + /** + * Asynchronously reads the entire contents of a file. + * @param path A path to a file. If a URL is provided, it must use the `file:` protocol. + * URL support is _experimental_. + * If a file descriptor is provided, the underlying file will _not_ be closed automatically. + * @param options Either the encoding for the result, or an object that contains the encoding and an optional flag. + * If a flag is not provided, it defaults to `'r'`. + */ + export function readFile(path: PathLike | number, options: { encoding: string; flag?: string; } | string, callback: (err: NodeJS.ErrnoException, data: string) => void): void; + + /** + * Asynchronously reads the entire contents of a file. + * @param path A path to a file. If a URL is provided, it must use the `file:` protocol. + * URL support is _experimental_. + * If a file descriptor is provided, the underlying file will _not_ be closed automatically. + * @param options Either the encoding for the result, or an object that contains the encoding and an optional flag. + * If a flag is not provided, it defaults to `'r'`. + */ + export function readFile(path: PathLike | number, options: { encoding?: string | null; flag?: string; } | string | undefined | null, callback: (err: NodeJS.ErrnoException, data: string | Buffer) => void): void; + + /** + * Asynchronously reads the entire contents of a file. + * @param path A path to a file. If a URL is provided, it must use the `file:` protocol. + * If a file descriptor is provided, the underlying file will _not_ be closed automatically. + */ + export function readFile(path: PathLike | number, callback: (err: NodeJS.ErrnoException, data: Buffer) => void): void; + + // NOTE: This namespace provides design-time support for util.promisify. Exported members do not exist at runtime. + export namespace readFile { + /** + * Asynchronously reads the entire contents of a file. + * @param path A path to a file. If a URL is provided, it must use the `file:` protocol. + * If a file descriptor is provided, the underlying file will _not_ be closed automatically. + * @param options An object that may contain an optional flag. + * If a flag is not provided, it defaults to `'r'`. + */ + export function __promisify__(path: PathLike | number, options?: { encoding?: null; flag?: string; } | null): Promise; + + /** + * Asynchronously reads the entire contents of a file. + * @param path A path to a file. If a URL is provided, it must use the `file:` protocol. + * URL support is _experimental_. + * If a file descriptor is provided, the underlying file will _not_ be closed automatically. + * @param options Either the encoding for the result, or an object that contains the encoding and an optional flag. + * If a flag is not provided, it defaults to `'r'`. + */ + export function __promisify__(path: PathLike | number, options: { encoding: string; flag?: string; } | string): Promise; + + /** + * Asynchronously reads the entire contents of a file. + * @param path A path to a file. If a URL is provided, it must use the `file:` protocol. + * URL support is _experimental_. + * If a file descriptor is provided, the underlying file will _not_ be closed automatically. + * @param options Either the encoding for the result, or an object that contains the encoding and an optional flag. + * If a flag is not provided, it defaults to `'r'`. + */ + export function __promisify__(path: PathLike | number, options?: { encoding?: string | null; flag?: string; } | string | null): Promise; + } + + /** + * Synchronously reads the entire contents of a file. + * @param path A path to a file. If a URL is provided, it must use the `file:` protocol. + * URL support is _experimental_. + * If a file descriptor is provided, the underlying file will _not_ be closed automatically. + * @param options An object that may contain an optional flag. If a flag is not provided, it defaults to `'r'`. + */ + export function readFileSync(path: PathLike | number, options?: { encoding?: null; flag?: string; } | null): Buffer; + + /** + * Synchronously reads the entire contents of a file. + * @param path A path to a file. If a URL is provided, it must use the `file:` protocol. + * URL support is _experimental_. + * If a file descriptor is provided, the underlying file will _not_ be closed automatically. + * @param options Either the encoding for the result, or an object that contains the encoding and an optional flag. + * If a flag is not provided, it defaults to `'r'`. + */ + export function readFileSync(path: PathLike | number, options: { encoding: string; flag?: string; } | string): string; + + /** + * Synchronously reads the entire contents of a file. + * @param path A path to a file. If a URL is provided, it must use the `file:` protocol. + * URL support is _experimental_. + * If a file descriptor is provided, the underlying file will _not_ be closed automatically. + * @param options Either the encoding for the result, or an object that contains the encoding and an optional flag. + * If a flag is not provided, it defaults to `'r'`. + */ + export function readFileSync(path: PathLike | number, options?: { encoding?: string | null; flag?: string; } | string | null): string | Buffer; + + /** + * Asynchronously writes data to a file, replacing the file if it already exists. + * @param path A path to a file. If a URL is provided, it must use the `file:` protocol. + * URL support is _experimental_. + * If a file descriptor is provided, the underlying file will _not_ be closed automatically. + * @param data The data to write. If something other than a Buffer or Uint8Array is provided, the value is coerced to a string. + * @param options Either the encoding for the file, or an object optionally specifying the encoding, file mode, and flag. + * If `encoding` is not supplied, the default of `'utf8'` is used. + * If `mode` is not supplied, the default of `0o666` is used. + * If `mode` is a string, it is parsed as an octal integer. + * If `flag` is not supplied, the default of `'w'` is used. + */ + export function writeFile(path: PathLike | number, data: any, options: { encoding?: string | null; mode?: number | string; flag?: string; } | string | undefined | null, callback: (err: NodeJS.ErrnoException) => void): void; + + /** + * Asynchronously writes data to a file, replacing the file if it already exists. + * @param path A path to a file. If a URL is provided, it must use the `file:` protocol. + * URL support is _experimental_. + * If a file descriptor is provided, the underlying file will _not_ be closed automatically. + * @param data The data to write. If something other than a Buffer or Uint8Array is provided, the value is coerced to a string. + */ + export function writeFile(path: PathLike | number, data: any, callback: (err: NodeJS.ErrnoException) => void): void; + + // NOTE: This namespace provides design-time support for util.promisify. Exported members do not exist at runtime. + export namespace writeFile { + /** + * Asynchronously writes data to a file, replacing the file if it already exists. + * @param path A path to a file. If a URL is provided, it must use the `file:` protocol. + * URL support is _experimental_. + * If a file descriptor is provided, the underlying file will _not_ be closed automatically. + * @param data The data to write. If something other than a Buffer or Uint8Array is provided, the value is coerced to a string. + * @param options Either the encoding for the file, or an object optionally specifying the encoding, file mode, and flag. + * If `encoding` is not supplied, the default of `'utf8'` is used. + * If `mode` is not supplied, the default of `0o666` is used. + * If `mode` is a string, it is parsed as an octal integer. + * If `flag` is not supplied, the default of `'w'` is used. + */ + export function __promisify__(path: PathLike | number, data: any, options?: { encoding?: string | null; mode?: number | string; flag?: string; } | string | null): Promise; + } + + /** + * Synchronously writes data to a file, replacing the file if it already exists. + * @param path A path to a file. If a URL is provided, it must use the `file:` protocol. + * URL support is _experimental_. + * If a file descriptor is provided, the underlying file will _not_ be closed automatically. + * @param data The data to write. If something other than a Buffer or Uint8Array is provided, the value is coerced to a string. + * @param options Either the encoding for the file, or an object optionally specifying the encoding, file mode, and flag. + * If `encoding` is not supplied, the default of `'utf8'` is used. + * If `mode` is not supplied, the default of `0o666` is used. + * If `mode` is a string, it is parsed as an octal integer. + * If `flag` is not supplied, the default of `'w'` is used. + */ + export function writeFileSync(path: PathLike | number, data: any, options?: { encoding?: string | null; mode?: number | string; flag?: string; } | string | null): void; + + /** + * Asynchronously append data to a file, creating the file if it does not exist. + * @param file A path to a file. If a URL is provided, it must use the `file:` protocol. + * URL support is _experimental_. + * If a file descriptor is provided, the underlying file will _not_ be closed automatically. + * @param data The data to write. If something other than a Buffer or Uint8Array is provided, the value is coerced to a string. + * @param options Either the encoding for the file, or an object optionally specifying the encoding, file mode, and flag. + * If `encoding` is not supplied, the default of `'utf8'` is used. + * If `mode` is not supplied, the default of `0o666` is used. + * If `mode` is a string, it is parsed as an octal integer. + * If `flag` is not supplied, the default of `'a'` is used. + */ + export function appendFile(file: PathLike | number, data: any, options: { encoding?: string | null, mode?: string | number, flag?: string } | string | undefined | null, callback: (err: NodeJS.ErrnoException) => void): void; + + /** + * Asynchronously append data to a file, creating the file if it does not exist. + * @param file A path to a file. If a URL is provided, it must use the `file:` protocol. + * URL support is _experimental_. + * If a file descriptor is provided, the underlying file will _not_ be closed automatically. + * @param data The data to write. If something other than a Buffer or Uint8Array is provided, the value is coerced to a string. + */ + export function appendFile(file: PathLike | number, data: any, callback: (err: NodeJS.ErrnoException) => void): void; + + // NOTE: This namespace provides design-time support for util.promisify. Exported members do not exist at runtime. + export namespace appendFile { + /** + * Asynchronously append data to a file, creating the file if it does not exist. + * @param file A path to a file. If a URL is provided, it must use the `file:` protocol. + * URL support is _experimental_. + * If a file descriptor is provided, the underlying file will _not_ be closed automatically. + * @param data The data to write. If something other than a Buffer or Uint8Array is provided, the value is coerced to a string. + * @param options Either the encoding for the file, or an object optionally specifying the encoding, file mode, and flag. + * If `encoding` is not supplied, the default of `'utf8'` is used. + * If `mode` is not supplied, the default of `0o666` is used. + * If `mode` is a string, it is parsed as an octal integer. + * If `flag` is not supplied, the default of `'a'` is used. + */ + export function __promisify__(file: PathLike | number, data: any, options?: { encoding?: string | null, mode?: string | number, flag?: string } | string | null): Promise; + } + + /** + * Synchronously append data to a file, creating the file if it does not exist. + * @param file A path to a file. If a URL is provided, it must use the `file:` protocol. + * URL support is _experimental_. + * If a file descriptor is provided, the underlying file will _not_ be closed automatically. + * @param data The data to write. If something other than a Buffer or Uint8Array is provided, the value is coerced to a string. + * @param options Either the encoding for the file, or an object optionally specifying the encoding, file mode, and flag. + * If `encoding` is not supplied, the default of `'utf8'` is used. + * If `mode` is not supplied, the default of `0o666` is used. + * If `mode` is a string, it is parsed as an octal integer. + * If `flag` is not supplied, the default of `'a'` is used. + */ + export function appendFileSync(file: PathLike | number, data: any, options?: { encoding?: string | null; mode?: number | string; flag?: string; } | string | null): void; + + /** + * Watch for changes on `filename`. The callback `listener` will be called each time the file is accessed. + */ + export function watchFile(filename: PathLike, options: { persistent?: boolean; interval?: number; } | undefined, listener: (curr: Stats, prev: Stats) => void): void; + + /** + * Watch for changes on `filename`. The callback `listener` will be called each time the file is accessed. + * @param filename A path to a file or directory. If a URL is provided, it must use the `file:` protocol. + * URL support is _experimental_. + */ + export function watchFile(filename: PathLike, listener: (curr: Stats, prev: Stats) => void): void; + + /** + * Stop watching for changes on `filename`. + * @param filename A path to a file or directory. If a URL is provided, it must use the `file:` protocol. + * URL support is _experimental_. + */ + export function unwatchFile(filename: PathLike, listener?: (curr: Stats, prev: Stats) => void): void; + + /** + * Watch for changes on `filename`, where `filename` is either a file or a directory, returning an `FSWatcher`. + * @param filename A path to a file or directory. If a URL is provided, it must use the `file:` protocol. + * URL support is _experimental_. + * @param options Either the encoding for the filename provided to the listener, or an object optionally specifying encoding, persistent, and recursive options. + * If `encoding` is not supplied, the default of `'utf8'` is used. + * If `persistent` is not supplied, the default of `true` is used. + * If `recursive` is not supplied, the default of `false` is used. + */ + export function watch(filename: PathLike, options: { encoding?: BufferEncoding | null, persistent?: boolean, recursive?: boolean } | BufferEncoding | undefined | null, listener?: (event: string, filename: string) => void): FSWatcher; + + /** + * Watch for changes on `filename`, where `filename` is either a file or a directory, returning an `FSWatcher`. + * @param filename A path to a file or directory. If a URL is provided, it must use the `file:` protocol. + * URL support is _experimental_. + * @param options Either the encoding for the filename provided to the listener, or an object optionally specifying encoding, persistent, and recursive options. + * If `encoding` is not supplied, the default of `'utf8'` is used. + * If `persistent` is not supplied, the default of `true` is used. + * If `recursive` is not supplied, the default of `false` is used. + */ + export function watch(filename: PathLike, options: { encoding: "buffer", persistent?: boolean, recursive?: boolean } | "buffer", listener?: (event: string, filename: Buffer) => void): FSWatcher; + + /** + * Watch for changes on `filename`, where `filename` is either a file or a directory, returning an `FSWatcher`. + * @param filename A path to a file or directory. If a URL is provided, it must use the `file:` protocol. + * URL support is _experimental_. + * @param options Either the encoding for the filename provided to the listener, or an object optionally specifying encoding, persistent, and recursive options. + * If `encoding` is not supplied, the default of `'utf8'` is used. + * If `persistent` is not supplied, the default of `true` is used. + * If `recursive` is not supplied, the default of `false` is used. + */ + export function watch(filename: PathLike, options: { encoding?: string | null, persistent?: boolean, recursive?: boolean } | string | null, listener?: (event: string, filename: string | Buffer) => void): FSWatcher; + + /** + * Watch for changes on `filename`, where `filename` is either a file or a directory, returning an `FSWatcher`. + * @param filename A path to a file or directory. If a URL is provided, it must use the `file:` protocol. + * URL support is _experimental_. + */ + export function watch(filename: PathLike, listener?: (event: string, filename: string) => any): FSWatcher; + + /** + * Asynchronously tests whether or not the given path exists by checking with the file system. + * @deprecated + * @param path A path to a file or directory. If a URL is provided, it must use the `file:` protocol. + * URL support is _experimental_. + */ + export function exists(path: PathLike, callback: (exists: boolean) => void): void; + + // NOTE: This namespace provides design-time support for util.promisify. Exported members do not exist at runtime. + export namespace exists { + /** + * @param path A path to a file or directory. If a URL is provided, it must use the `file:` protocol. + * URL support is _experimental_. + */ + function __promisify__(path: PathLike): Promise; + } + + /** + * Synchronously tests whether or not the given path exists by checking with the file system. + * @param path A path to a file or directory. If a URL is provided, it must use the `file:` protocol. + * URL support is _experimental_. + */ + export function existsSync(path: PathLike): boolean; + + export namespace constants { + // File Access Constants + + /** Constant for fs.access(). File is visible to the calling process. */ + export const F_OK: number; + + /** Constant for fs.access(). File can be read by the calling process. */ + export const R_OK: number; + + /** Constant for fs.access(). File can be written by the calling process. */ + export const W_OK: number; + + /** Constant for fs.access(). File can be executed by the calling process. */ + export const X_OK: number; + + // File Open Constants + + /** Constant for fs.open(). Flag indicating to open a file for read-only access. */ + export const O_RDONLY: number; + + /** Constant for fs.open(). Flag indicating to open a file for write-only access. */ + export const O_WRONLY: number; + + /** Constant for fs.open(). Flag indicating to open a file for read-write access. */ + export const O_RDWR: number; + + /** Constant for fs.open(). Flag indicating to create the file if it does not already exist. */ + export const O_CREAT: number; + + /** Constant for fs.open(). Flag indicating that opening a file should fail if the O_CREAT flag is set and the file already exists. */ + export const O_EXCL: number; + + /** Constant for fs.open(). Flag indicating that if path identifies a terminal device, opening the path shall not cause that terminal to become the controlling terminal for the process (if the process does not already have one). */ + export const O_NOCTTY: number; + + /** Constant for fs.open(). Flag indicating that if the file exists and is a regular file, and the file is opened successfully for write access, its length shall be truncated to zero. */ + export const O_TRUNC: number; + + /** Constant for fs.open(). Flag indicating that data will be appended to the end of the file. */ + export const O_APPEND: number; + + /** Constant for fs.open(). Flag indicating that the open should fail if the path is not a directory. */ + export const O_DIRECTORY: number; + + /** Constant for fs.open(). Flag indicating reading accesses to the file system will no longer result in an update to the atime information associated with the file. This flag is available on Linux operating systems only. */ + export const O_NOATIME: number; + + /** Constant for fs.open(). Flag indicating that the open should fail if the path is a symbolic link. */ + export const O_NOFOLLOW: number; + + /** Constant for fs.open(). Flag indicating that the file is opened for synchronous I/O. */ + export const O_SYNC: number; + + /** Constant for fs.open(). Flag indicating that the file is opened for synchronous I/O with write operations waiting for data integrity. */ + export const O_DSYNC: number; + + /** Constant for fs.open(). Flag indicating to open the symbolic link itself rather than the resource it is pointing to. */ + export const O_SYMLINK: number; + + /** Constant for fs.open(). When set, an attempt will be made to minimize caching effects of file I/O. */ + export const O_DIRECT: number; + + /** Constant for fs.open(). Flag indicating to open the file in nonblocking mode when possible. */ + export const O_NONBLOCK: number; + + // File Type Constants + + /** Constant for fs.Stats mode property for determining a file's type. Bit mask used to extract the file type code. */ + export const S_IFMT: number; + + /** Constant for fs.Stats mode property for determining a file's type. File type constant for a regular file. */ + export const S_IFREG: number; + + /** Constant for fs.Stats mode property for determining a file's type. File type constant for a directory. */ + export const S_IFDIR: number; + + /** Constant for fs.Stats mode property for determining a file's type. File type constant for a character-oriented device file. */ + export const S_IFCHR: number; + + /** Constant for fs.Stats mode property for determining a file's type. File type constant for a block-oriented device file. */ + export const S_IFBLK: number; + + /** Constant for fs.Stats mode property for determining a file's type. File type constant for a FIFO/pipe. */ + export const S_IFIFO: number; + + /** Constant for fs.Stats mode property for determining a file's type. File type constant for a symbolic link. */ + export const S_IFLNK: number; + + /** Constant for fs.Stats mode property for determining a file's type. File type constant for a socket. */ + export const S_IFSOCK: number; + + // File Mode Constants + + /** Constant for fs.Stats mode property for determining access permissions for a file. File mode indicating readable, writable and executable by owner. */ + export const S_IRWXU: number; + + /** Constant for fs.Stats mode property for determining access permissions for a file. File mode indicating readable by owner. */ + export const S_IRUSR: number; + + /** Constant for fs.Stats mode property for determining access permissions for a file. File mode indicating writable by owner. */ + export const S_IWUSR: number; + + /** Constant for fs.Stats mode property for determining access permissions for a file. File mode indicating executable by owner. */ + export const S_IXUSR: number; + + /** Constant for fs.Stats mode property for determining access permissions for a file. File mode indicating readable, writable and executable by group. */ + export const S_IRWXG: number; + + /** Constant for fs.Stats mode property for determining access permissions for a file. File mode indicating readable by group. */ + export const S_IRGRP: number; + + /** Constant for fs.Stats mode property for determining access permissions for a file. File mode indicating writable by group. */ + export const S_IWGRP: number; + + /** Constant for fs.Stats mode property for determining access permissions for a file. File mode indicating executable by group. */ + export const S_IXGRP: number; + + /** Constant for fs.Stats mode property for determining access permissions for a file. File mode indicating readable, writable and executable by others. */ + export const S_IRWXO: number; + + /** Constant for fs.Stats mode property for determining access permissions for a file. File mode indicating readable by others. */ + export const S_IROTH: number; + + /** Constant for fs.Stats mode property for determining access permissions for a file. File mode indicating writable by others. */ + export const S_IWOTH: number; + + /** Constant for fs.Stats mode property for determining access permissions for a file. File mode indicating executable by others. */ + export const S_IXOTH: number; + + /** Constant for fs.copyFile. Flag indicating the destination file should not be overwritten if it already exists. */ + export const COPYFILE_EXCL: number; + } + + /** + * Asynchronously tests a user's permissions for the file specified by path. + * @param path A path to a file or directory. If a URL is provided, it must use the `file:` protocol. + * URL support is _experimental_. + */ + export function access(path: PathLike, mode: number | undefined, callback: (err: NodeJS.ErrnoException) => void): void; + + /** + * Asynchronously tests a user's permissions for the file specified by path. + * @param path A path to a file or directory. If a URL is provided, it must use the `file:` protocol. + * URL support is _experimental_. + */ + export function access(path: PathLike, callback: (err: NodeJS.ErrnoException) => void): void; + + // NOTE: This namespace provides design-time support for util.promisify. Exported members do not exist at runtime. + export namespace access { + /** + * Asynchronously tests a user's permissions for the file specified by path. + * @param path A path to a file or directory. If a URL is provided, it must use the `file:` protocol. + * URL support is _experimental_. + */ + export function __promisify__(path: PathLike, mode?: number): Promise; + } + + /** + * Synchronously tests a user's permissions for the file specified by path. + * @param path A path to a file or directory. If a URL is provided, it must use the `file:` protocol. + * URL support is _experimental_. + */ + export function accessSync(path: PathLike, mode?: number): void; + + /** + * Returns a new `ReadStream` object. + * @param path A path to a file. If a URL is provided, it must use the `file:` protocol. + * URL support is _experimental_. + */ + export function createReadStream(path: PathLike, options?: string | { + flags?: string; + encoding?: string; + fd?: number; + mode?: number; + autoClose?: boolean; + start?: number; + end?: number; + highWaterMark?: number; + }): ReadStream; + + /** + * Returns a new `WriteStream` object. + * @param path A path to a file. If a URL is provided, it must use the `file:` protocol. + * URL support is _experimental_. + */ + export function createWriteStream(path: PathLike, options?: string | { + flags?: string; + encoding?: string; + fd?: number; + mode?: number; + autoClose?: boolean; + start?: number; + }): WriteStream; + + /** + * Asynchronous fdatasync(2) - synchronize a file's in-core state with storage device. + * @param fd A file descriptor. + */ + export function fdatasync(fd: number, callback: (err: NodeJS.ErrnoException) => void): void; + + // NOTE: This namespace provides design-time support for util.promisify. Exported members do not exist at runtime. + export namespace fdatasync { + /** + * Asynchronous fdatasync(2) - synchronize a file's in-core state with storage device. + * @param fd A file descriptor. + */ + export function __promisify__(fd: number): Promise; + } + + /** + * Synchronous fdatasync(2) - synchronize a file's in-core state with storage device. + * @param fd A file descriptor. + */ + export function fdatasyncSync(fd: number): void; + + /** + * Asynchronously copies src to dest. By default, dest is overwritten if it already exists. + * No arguments other than a possible exception are given to the callback function. + * Node.js makes no guarantees about the atomicity of the copy operation. + * If an error occurs after the destination file has been opened for writing, Node.js will attempt + * to remove the destination. + * @param src A path to the source file. + * @param dest A path to the destination file. + */ + export function copyFile(src: PathLike, dest: PathLike, callback: (err: NodeJS.ErrnoException) => void): void; + /** + * Asynchronously copies src to dest. By default, dest is overwritten if it already exists. + * No arguments other than a possible exception are given to the callback function. + * Node.js makes no guarantees about the atomicity of the copy operation. + * If an error occurs after the destination file has been opened for writing, Node.js will attempt + * to remove the destination. + * @param src A path to the source file. + * @param dest A path to the destination file. + * @param flags An integer that specifies the behavior of the copy operation. The only supported flag is fs.constants.COPYFILE_EXCL, which causes the copy operation to fail if dest already exists. + */ + export function copyFile(src: PathLike, dest: PathLike, flags: number, callback: (err: NodeJS.ErrnoException) => void): void; + + // NOTE: This namespace provides design-time support for util.promisify. Exported members do not exist at runtime. + export namespace copyFile { + /** + * Asynchronously copies src to dest. By default, dest is overwritten if it already exists. + * No arguments other than a possible exception are given to the callback function. + * Node.js makes no guarantees about the atomicity of the copy operation. + * If an error occurs after the destination file has been opened for writing, Node.js will attempt + * to remove the destination. + * @param src A path to the source file. + * @param dest A path to the destination file. + * @param flags An optional integer that specifies the behavior of the copy operation. The only supported flag is fs.constants.COPYFILE_EXCL, which causes the copy operation to fail if dest already exists. + */ + export function __promisify__(src: PathLike, dst: PathLike, flags?: number): Promise; + } + + /** + * Synchronously copies src to dest. By default, dest is overwritten if it already exists. + * Node.js makes no guarantees about the atomicity of the copy operation. + * If an error occurs after the destination file has been opened for writing, Node.js will attempt + * to remove the destination. + * @param src A path to the source file. + * @param dest A path to the destination file. + * @param flags An optional integer that specifies the behavior of the copy operation. The only supported flag is fs.constants.COPYFILE_EXCL, which causes the copy operation to fail if dest already exists. + */ + export function copyFileSync(src: PathLike, dest: PathLike, flags?: number): void; } declare module "path" { - /** * A parsed path object generated by path.parse() or consumed by path.format(). */ - export interface ParsedPath { + export interface ParsedPath { /** * The root of the path such as '/' or 'c:\' */ - root: string; + root: string; /** * The full directory path such as '/home/user/dir' or 'c:\path\dir' */ - dir: string; + dir: string; /** * The file name including extension (if any) such as 'index.html' */ - base: string; + base: string; /** * The file extension (if any) such as '.html' */ - ext: string; + ext: string; /** * The file name without extension (if any) such as 'index' */ - name: string; - } + name: string; + } + export interface FormatInputPathObject { + /** + * The root of the path such as '/' or 'c:\' + */ + root?: string; + /** + * The full directory path such as '/home/user/dir' or 'c:\path\dir' + */ + dir?: string; + /** + * The file name including extension (if any) such as 'index.html' + */ + base?: string; + /** + * The file extension (if any) such as '.html' + */ + ext?: string; + /** + * The file name without extension (if any) such as 'index' + */ + name?: string; + } /** * Normalize a string path, reducing '..' and '.' parts. @@ -2925,14 +4636,14 @@ declare module "path" { * * @param p string path to normalize. */ - export function normalize(p: string): string; + export function normalize(p: string): string; /** * Join all arguments together and normalize the resulting path. * Arguments must be strings. In v0.8, non-string arguments were silently ignored. In v0.10 and up, an exception is thrown. * * @param paths paths to join. */ - export function join(...paths: string[]): string; + export function join(...paths: string[]): string; /** * The right-most parameter is considered {to}. Other parameters are considered an array of {from}. * @@ -2942,27 +4653,24 @@ declare module "path" { * * @param pathSegments string paths to join. Non-string arguments are ignored. */ - export function resolve(...pathSegments: any[]): string; + export function resolve(...pathSegments: string[]): string; /** * Determines whether {path} is an absolute path. An absolute path will always resolve to the same location, regardless of the working directory. * * @param path path to test. */ - export function isAbsolute(path: string): boolean; + export function isAbsolute(path: string): boolean; /** * Solve the relative path from {from} to {to}. * At times we have two absolute paths, and we need to derive the relative path from one to the other. This is actually the reverse transform of path.resolve. - * - * @param from - * @param to */ - export function relative(from: string, to: string): string; + export function relative(from: string, to: string): string; /** * Return the directory name of a path. Similar to the Unix dirname command. * * @param p the path to evaluate. */ - export function dirname(p: string): string; + export function dirname(p: string): string; /** * Return the last portion of a path. Similar to the Unix basename command. * Often used to extract the file name from a fully qualified path. @@ -2970,176 +4678,177 @@ declare module "path" { * @param p the path to evaluate. * @param ext optionally, an extension to remove from the result. */ - export function basename(p: string, ext?: string): string; + export function basename(p: string, ext?: string): string; /** * Return the extension of the path, from the last '.' to end of string in the last portion of the path. * If there is no '.' in the last portion of the path or the first character of it is '.', then it returns an empty string * * @param p the path to evaluate. */ - export function extname(p: string): string; + export function extname(p: string): string; /** * The platform-specific file separator. '\\' or '/'. */ - export var sep: string; + export var sep: '\\' | '/'; /** * The platform-specific file delimiter. ';' or ':'. */ - export var delimiter: string; + export var delimiter: ';' | ':'; /** * Returns an object from a path string - the opposite of format(). * * @param pathString path to evaluate. */ - export function parse(pathString: string): ParsedPath; + export function parse(pathString: string): ParsedPath; /** * Returns a path string from an object - the opposite of parse(). * * @param pathString path to evaluate. */ - export function format(pathObject: ParsedPath): string; + export function format(pathObject: FormatInputPathObject): string; - export module posix { - export function normalize(p: string): string; - export function join(...paths: any[]): string; - export function resolve(...pathSegments: any[]): string; - export function isAbsolute(p: string): boolean; - export function relative(from: string, to: string): string; - export function dirname(p: string): string; - export function basename(p: string, ext?: string): string; - export function extname(p: string): string; - export var sep: string; - export var delimiter: string; - export function parse(p: string): ParsedPath; - export function format(pP: ParsedPath): string; - } + export module posix { + export function normalize(p: string): string; + export function join(...paths: any[]): string; + export function resolve(...pathSegments: any[]): string; + export function isAbsolute(p: string): boolean; + export function relative(from: string, to: string): string; + export function dirname(p: string): string; + export function basename(p: string, ext?: string): string; + export function extname(p: string): string; + export var sep: string; + export var delimiter: string; + export function parse(p: string): ParsedPath; + export function format(pP: FormatInputPathObject): string; + } - export module win32 { - export function normalize(p: string): string; - export function join(...paths: any[]): string; - export function resolve(...pathSegments: any[]): string; - export function isAbsolute(p: string): boolean; - export function relative(from: string, to: string): string; - export function dirname(p: string): string; - export function basename(p: string, ext?: string): string; - export function extname(p: string): string; - export var sep: string; - export var delimiter: string; - export function parse(p: string): ParsedPath; - export function format(pP: ParsedPath): string; - } + export module win32 { + export function normalize(p: string): string; + export function join(...paths: any[]): string; + export function resolve(...pathSegments: any[]): string; + export function isAbsolute(p: string): boolean; + export function relative(from: string, to: string): string; + export function dirname(p: string): string; + export function basename(p: string, ext?: string): string; + export function extname(p: string): string; + export var sep: string; + export var delimiter: string; + export function parse(p: string): ParsedPath; + export function format(pP: FormatInputPathObject): string; + } } declare module "string_decoder" { - export interface NodeStringDecoder { - write(buffer: Buffer): string; - end(buffer?: Buffer): string; - } - export var StringDecoder: { - new(encoding?: string): NodeStringDecoder; - }; + export interface NodeStringDecoder { + write(buffer: Buffer): string; + end(buffer?: Buffer): string; + } + export var StringDecoder: { + new(encoding?: string): NodeStringDecoder; + }; } declare module "tls" { - import * as crypto from "crypto"; - import * as net from "net"; - import * as stream from "stream"; + import * as crypto from "crypto"; + import * as dns from "dns"; + import * as net from "net"; + import * as stream from "stream"; - var CLIENT_RENEG_LIMIT: number; - var CLIENT_RENEG_WINDOW: number; + var CLIENT_RENEG_LIMIT: number; + var CLIENT_RENEG_WINDOW: number; - export interface Certificate { + export interface Certificate { /** * Country code. */ - C: string; + C: string; /** * Street. */ - ST: string; + ST: string; /** * Locality. */ - L: string; + L: string; /** * Organization. */ - O: string; + O: string; /** * Organizational unit. */ - OU: string; + OU: string; /** * Common name. */ - CN: string; - } + CN: string; + } - export interface PeerCertificate { - subject: Certificate; - issuer: Certificate; - subjectaltname: string; - infoAccess: { [index: string]: string[] }; - modulus: string; - exponent: string; - valid_from: string; - valid_to: string; - fingerprint: string; - ext_key_usage: string[]; - serialNumber: string; - raw: Buffer; - } + export interface PeerCertificate { + subject: Certificate; + issuer: Certificate; + subjectaltname: string; + infoAccess: { [index: string]: string[] | undefined }; + modulus: string; + exponent: string; + valid_from: string; + valid_to: string; + fingerprint: string; + ext_key_usage: string[]; + serialNumber: string; + raw: Buffer; + } - export interface DetailedPeerCertificate extends PeerCertificate { - issuerCertificate: DetailedPeerCertificate; - } + export interface DetailedPeerCertificate extends PeerCertificate { + issuerCertificate: DetailedPeerCertificate; + } - export interface CipherNameAndProtocol { + export interface CipherNameAndProtocol { /** * The cipher name. */ - name: string; + name: string; /** * SSL/TLS protocol version. */ - version: string; - } + version: string; + } - export class TLSSocket extends net.Socket { + export class TLSSocket extends net.Socket { /** * Construct a new tls.TLSSocket object from an existing TCP socket. */ - constructor(socket: net.Socket, options?: { + constructor(socket: net.Socket, options?: { /** * An optional TLS context object from tls.createSecureContext() */ - secureContext?: SecureContext, + secureContext?: SecureContext, /** * If true the TLS socket will be instantiated in server-mode. * Defaults to false. */ - isServer?: boolean, + isServer?: boolean, /** * An optional net.Server instance. */ - server?: net.Server, + server?: net.Server, /** * If true the server will request a certificate from clients that * connect and attempt to verify that certificate. Defaults to * false. */ - requestCert?: boolean, + requestCert?: boolean, /** * If true the server will reject any connection which is not * authorized with the list of supplied CAs. This option only has an * effect if requestCert is true. Defaults to false. */ - rejectUnauthorized?: boolean, + rejectUnauthorized?: boolean, /** * An array of strings or a Buffer naming possible NPN protocols. * (Protocols should be ordered by their priority.) */ - NPNProtocols?: string[] | Buffer, + NPNProtocols?: string[] | Buffer[] | Uint8Array[] | Buffer | Uint8Array, /** * An array of strings or a Buffer naming possible ALPN protocols. * (Protocols should be ordered by their priority.) When the server @@ -3147,7 +4856,7 @@ declare module "tls" { * precedence over NPN and the server does not send an NPN extension * to the client. */ - ALPNProtocols?: string[] | Buffer, + ALPNProtocols?: string[] | Buffer[] | Uint8Array[] | Buffer | Uint8Array, /** * SNICallback(servername, cb) A function that will be * called if the client supports SNI TLS extension. Two arguments @@ -3157,99 +4866,81 @@ declare module "tls" { * SecureContext.) If SNICallback wasn't provided the default callback * with high-level API will be used (see below). */ - SNICallback?: Function, + SNICallback?: (servername: string, cb: (err: Error | null, ctx: SecureContext) => void) => void, /** * An optional Buffer instance containing a TLS session. */ - session?: Buffer, + session?: Buffer, /** * If true, specifies that the OCSP status request extension will be * added to the client hello and an 'OCSPResponse' event will be * emitted on the socket before establishing a secure communication */ - requestOCSP?: boolean - }); - /** - * Returns the bound address, the address family name and port of the underlying socket as reported by - * the operating system. - * @returns {any} - An object with three properties, e.g. { port: 12346, family: 'IPv4', address: '127.0.0.1' }. - */ - address(): { port: number; family: string; address: string }; + requestOCSP?: boolean + }); + /** * A boolean that is true if the peer certificate was signed by one of the specified CAs, otherwise false. */ - authorized: boolean; + authorized: boolean; /** * The reason why the peer's certificate has not been verified. * This property becomes available only when tlsSocket.authorized === false. */ - authorizationError: Error; + authorizationError: Error; /** * Static boolean value, always true. * May be used to distinguish TLS sockets from regular ones. */ - encrypted: boolean; + encrypted: boolean; /** * Returns an object representing the cipher name and the SSL/TLS protocol version of the current connection. - * @returns {CipherNameAndProtocol} - Returns an object representing the cipher name + * @returns Returns an object representing the cipher name * and the SSL/TLS protocol version of the current connection. */ - getCipher(): CipherNameAndProtocol; + getCipher(): CipherNameAndProtocol; /** * Returns an object representing the peer's certificate. * The returned object has some properties corresponding to the field of the certificate. * If detailed argument is true the full chain with issuer property will be returned, * if false only the top certificate without issuer property. * If the peer does not provide a certificate, it returns null or an empty object. - * @param {boolean} detailed - If true; the full chain with issuer property will be returned. - * @returns {PeerCertificate | DetailedPeerCertificate} - An object representing the peer's certificate. + * @param detailed - If true; the full chain with issuer property will be returned. + * @returns An object representing the peer's certificate. */ - getPeerCertificate(detailed: true): DetailedPeerCertificate; - getPeerCertificate(detailed?: false): PeerCertificate; - getPeerCertificate(detailed?: boolean): PeerCertificate | DetailedPeerCertificate; + getPeerCertificate(detailed: true): DetailedPeerCertificate; + getPeerCertificate(detailed?: false): PeerCertificate; + getPeerCertificate(detailed?: boolean): PeerCertificate | DetailedPeerCertificate; + /** + * Returns a string containing the negotiated SSL/TLS protocol version of the current connection. + * The value `'unknown'` will be returned for connected sockets that have not completed the handshaking process. + * The value `null` will be returned for server sockets or disconnected client sockets. + * See https://www.openssl.org/docs/man1.0.2/ssl/SSL_get_version.html for more information. + * @returns negotiated SSL/TLS protocol version of the current connection + */ + getProtocol(): string | null; /** * Could be used to speed up handshake establishment when reconnecting to the server. - * @returns {any} - ASN.1 encoded TLS session or undefined if none was negotiated. + * @returns ASN.1 encoded TLS session or undefined if none was negotiated. */ - getSession(): any; + getSession(): any; /** * NOTE: Works only with client TLS sockets. * Useful only for debugging, for session reuse provide session option to tls.connect(). - * @returns {any} - TLS session ticket or undefined if none was negotiated. + * @returns TLS session ticket or undefined if none was negotiated. */ - getTLSTicket(): any; - /** - * The string representation of the local IP address. - */ - localAddress: string; - /** - * The numeric representation of the local port. - */ - localPort: number; - /** - * The string representation of the remote IP address. - * For example, '74.125.127.100' or '2001:4860:a005::68'. - */ - remoteAddress: string; - /** - * The string representation of the remote IP family. 'IPv4' or 'IPv6'. - */ - remoteFamily: string; - /** - * The numeric representation of the remote port. For example, 443. - */ - remotePort: number; + getTLSTicket(): any; /** * Initiate TLS renegotiation process. * * NOTE: Can be used to request peer's certificate after the secure connection has been established. * ANOTHER NOTE: When running as the server, socket will be destroyed with an error after handshakeTimeout timeout. - * @param {TlsOptions} options - The options may contain the following fields: rejectUnauthorized, + * @param options - The options may contain the following fields: rejectUnauthorized, * requestCert (See tls.createServer() for details). - * @param {Function} callback - callback(err) will be executed with null as err, once the renegotiation + * @param callback - callback(err) will be executed with null as err, once the renegotiation * is successfully completed. */ - renegotiate(options: TlsOptions, callback: (err: Error) => any): any; + renegotiate(options: { rejectUnauthorized?: boolean, requestCert?: boolean }, callback: (err: Error | null) => void): any; /** * Set maximum TLS fragment size (default and maximum value is: 16384, minimum is: 512). * Smaller fragment size decreases buffering latency on the client: large fragments are buffered by @@ -3257,97 +4948,74 @@ declare module "tls" { * large fragments can span multiple roundtrips, and their processing can be delayed due to packet * loss or reordering. However, smaller fragments add extra TLS framing bytes and CPU overhead, * which may decrease overall server throughput. - * @param {number} size - TLS fragment size (default and maximum value is: 16384, minimum is: 512). - * @returns {boolean} - Returns true on success, false otherwise. + * @param size - TLS fragment size (default and maximum value is: 16384, minimum is: 512). + * @returns Returns true on success, false otherwise. */ - setMaxSendFragment(size: number): boolean; + setMaxSendFragment(size: number): boolean; /** * events.EventEmitter * 1. OCSPResponse * 2. secureConnect - **/ - addListener(event: string, listener: Function): this; - addListener(event: "OCSPResponse", listener: (response: Buffer) => void): this; - addListener(event: "secureConnect", listener: () => void): this; + */ + addListener(event: string, listener: (...args: any[]) => void): this; + addListener(event: "OCSPResponse", listener: (response: Buffer) => void): this; + addListener(event: "secureConnect", listener: () => void): this; - emit(event: string | symbol, ...args: any[]): boolean; - emit(event: "OCSPResponse", response: Buffer): boolean; - emit(event: "secureConnect"): boolean; + emit(event: string | symbol, ...args: any[]): boolean; + emit(event: "OCSPResponse", response: Buffer): boolean; + emit(event: "secureConnect"): boolean; - on(event: string, listener: Function): this; - on(event: "OCSPResponse", listener: (response: Buffer) => void): this; - on(event: "secureConnect", listener: () => void): this; + on(event: string, listener: (...args: any[]) => void): this; + on(event: "OCSPResponse", listener: (response: Buffer) => void): this; + on(event: "secureConnect", listener: () => void): this; - once(event: string, listener: Function): this; - once(event: "OCSPResponse", listener: (response: Buffer) => void): this; - once(event: "secureConnect", listener: () => void): this; + once(event: string, listener: (...args: any[]) => void): this; + once(event: "OCSPResponse", listener: (response: Buffer) => void): this; + once(event: "secureConnect", listener: () => void): this; - prependListener(event: string, listener: Function): this; - prependListener(event: "OCSPResponse", listener: (response: Buffer) => void): this; - prependListener(event: "secureConnect", listener: () => void): this; + prependListener(event: string, listener: (...args: any[]) => void): this; + prependListener(event: "OCSPResponse", listener: (response: Buffer) => void): this; + prependListener(event: "secureConnect", listener: () => void): this; - prependOnceListener(event: string, listener: Function): this; - prependOnceListener(event: "OCSPResponse", listener: (response: Buffer) => void): this; - prependOnceListener(event: "secureConnect", listener: () => void): this; - } + prependOnceListener(event: string, listener: (...args: any[]) => void): this; + prependOnceListener(event: "OCSPResponse", listener: (response: Buffer) => void): this; + prependOnceListener(event: "secureConnect", listener: () => void): this; + } - export interface TlsOptions { - host?: string; - port?: number; - pfx?: string | Buffer[]; - key?: string | string[] | Buffer | any[]; - passphrase?: string; - cert?: string | string[] | Buffer | Buffer[]; - ca?: string | string[] | Buffer | Buffer[]; - crl?: string | string[]; - ciphers?: string; - honorCipherOrder?: boolean; - requestCert?: boolean; - rejectUnauthorized?: boolean; - NPNProtocols?: string[] | Buffer; - SNICallback?: (servername: string, cb: (err: Error, ctx: SecureContext) => any) => any; - ecdhCurve?: string; - dhparam?: string | Buffer; - handshakeTimeout?: number; - ALPNProtocols?: string[] | Buffer; - sessionTimeout?: number; - ticketKeys?: any; - sessionIdContext?: string; - secureProtocol?: string; - } + export interface TlsOptions extends SecureContextOptions { + handshakeTimeout?: number; + requestCert?: boolean; + rejectUnauthorized?: boolean; + NPNProtocols?: string[] | Buffer[] | Uint8Array[] | Buffer | Uint8Array; + ALPNProtocols?: string[] | Buffer[] | Uint8Array[] | Buffer | Uint8Array; + SNICallback?: (servername: string, cb: (err: Error | null, ctx: SecureContext) => void) => void; + sessionTimeout?: number; + ticketKeys?: Buffer; + } - export interface ConnectionOptions { - host?: string; - port?: number; - socket?: net.Socket; - pfx?: string | Buffer - key?: string | string[] | Buffer | Buffer[]; - passphrase?: string; - cert?: string | string[] | Buffer | Buffer[]; - ca?: string | Buffer | (string | Buffer)[]; - rejectUnauthorized?: boolean; - NPNProtocols?: (string | Buffer)[]; - servername?: string; - path?: string; - ALPNProtocols?: (string | Buffer)[]; - checkServerIdentity?: (servername: string, cert: string | Buffer | (string | Buffer)[]) => any; - secureProtocol?: string; - secureContext?: Object; - session?: Buffer; - minDHSize?: number; - } + export interface ConnectionOptions extends SecureContextOptions { + host?: string; + port?: number; + path?: string; // Creates unix socket connection to path. If this option is specified, `host` and `port` are ignored. + socket?: net.Socket; // Establish secure connection on a given socket rather than creating a new socket + rejectUnauthorized?: boolean; // Defaults to true + NPNProtocols?: string[] | Buffer[] | Uint8Array[] | Buffer | Uint8Array; + ALPNProtocols?: string[] | Buffer[] | Uint8Array[] | Buffer | Uint8Array; + checkServerIdentity?: typeof checkServerIdentity; + servername?: string; // SNI TLS Extension + session?: Buffer; + minDHSize?: number; + secureContext?: SecureContext; // If not provided, the entire ConnectionOptions object will be passed to tls.createSecureContext() + lookup?: net.LookupFunction; + } - export interface Server extends net.Server { - close(callback?: Function): Server; - address(): { port: number; family: string; address: string; }; - addContext(hostName: string, credentials: { - key: string; - cert: string; - ca: string; - }): void; - maxConnections: number; - connections: number; + export class Server extends net.Server { + addContext(hostName: string, credentials: { + key: string; + cert: string; + ca: string; + }): void; /** * events.EventEmitter @@ -3356,1022 +5024,2216 @@ declare module "tls" { * 3. OCSPRequest * 4. resumeSession * 5. secureConnection - **/ - addListener(event: string, listener: Function): this; - addListener(event: "tlsClientError", listener: (err: Error, tlsSocket: TLSSocket) => void): this; - addListener(event: "newSession", listener: (sessionId: any, sessionData: any, callback: (err: Error, resp: Buffer) => void) => void): this; - addListener(event: "OCSPRequest", listener: (certificate: Buffer, issuer: Buffer, callback: Function) => void): this; - addListener(event: "resumeSession", listener: (sessionId: any, callback: (err: Error, sessionData: any) => void) => void): this; - addListener(event: "secureConnection", listener: (tlsSocket: TLSSocket) => void): this; + */ + addListener(event: string, listener: (...args: any[]) => void): this; + addListener(event: "tlsClientError", listener: (err: Error, tlsSocket: TLSSocket) => void): this; + addListener(event: "newSession", listener: (sessionId: any, sessionData: any, callback: (err: Error, resp: Buffer) => void) => void): this; + addListener(event: "OCSPRequest", listener: (certificate: Buffer, issuer: Buffer, callback: Function) => void): this; + addListener(event: "resumeSession", listener: (sessionId: any, callback: (err: Error, sessionData: any) => void) => void): this; + addListener(event: "secureConnection", listener: (tlsSocket: TLSSocket) => void): this; - emit(event: string | symbol, ...args: any[]): boolean; - emit(event: "tlsClientError", err: Error, tlsSocket: TLSSocket): boolean; - emit(event: "newSession", sessionId: any, sessionData: any, callback: (err: Error, resp: Buffer) => void): boolean; - emit(event: "OCSPRequest", certificate: Buffer, issuer: Buffer, callback: Function): boolean; - emit(event: "resumeSession", sessionId: any, callback: (err: Error, sessionData: any) => void): boolean; - emit(event: "secureConnection", tlsSocket: TLSSocket): boolean; + emit(event: string | symbol, ...args: any[]): boolean; + emit(event: "tlsClientError", err: Error, tlsSocket: TLSSocket): boolean; + emit(event: "newSession", sessionId: any, sessionData: any, callback: (err: Error, resp: Buffer) => void): boolean; + emit(event: "OCSPRequest", certificate: Buffer, issuer: Buffer, callback: Function): boolean; + emit(event: "resumeSession", sessionId: any, callback: (err: Error, sessionData: any) => void): boolean; + emit(event: "secureConnection", tlsSocket: TLSSocket): boolean; - on(event: string, listener: Function): this; - on(event: "tlsClientError", listener: (err: Error, tlsSocket: TLSSocket) => void): this; - on(event: "newSession", listener: (sessionId: any, sessionData: any, callback: (err: Error, resp: Buffer) => void) => void): this; - on(event: "OCSPRequest", listener: (certificate: Buffer, issuer: Buffer, callback: Function) => void): this; - on(event: "resumeSession", listener: (sessionId: any, callback: (err: Error, sessionData: any) => void) => void): this; - on(event: "secureConnection", listener: (tlsSocket: TLSSocket) => void): this; + on(event: string, listener: (...args: any[]) => void): this; + on(event: "tlsClientError", listener: (err: Error, tlsSocket: TLSSocket) => void): this; + on(event: "newSession", listener: (sessionId: any, sessionData: any, callback: (err: Error, resp: Buffer) => void) => void): this; + on(event: "OCSPRequest", listener: (certificate: Buffer, issuer: Buffer, callback: Function) => void): this; + on(event: "resumeSession", listener: (sessionId: any, callback: (err: Error, sessionData: any) => void) => void): this; + on(event: "secureConnection", listener: (tlsSocket: TLSSocket) => void): this; - once(event: string, listener: Function): this; - once(event: "tlsClientError", listener: (err: Error, tlsSocket: TLSSocket) => void): this; - once(event: "newSession", listener: (sessionId: any, sessionData: any, callback: (err: Error, resp: Buffer) => void) => void): this; - once(event: "OCSPRequest", listener: (certificate: Buffer, issuer: Buffer, callback: Function) => void): this; - once(event: "resumeSession", listener: (sessionId: any, callback: (err: Error, sessionData: any) => void) => void): this; - once(event: "secureConnection", listener: (tlsSocket: TLSSocket) => void): this; + once(event: string, listener: (...args: any[]) => void): this; + once(event: "tlsClientError", listener: (err: Error, tlsSocket: TLSSocket) => void): this; + once(event: "newSession", listener: (sessionId: any, sessionData: any, callback: (err: Error, resp: Buffer) => void) => void): this; + once(event: "OCSPRequest", listener: (certificate: Buffer, issuer: Buffer, callback: Function) => void): this; + once(event: "resumeSession", listener: (sessionId: any, callback: (err: Error, sessionData: any) => void) => void): this; + once(event: "secureConnection", listener: (tlsSocket: TLSSocket) => void): this; - prependListener(event: string, listener: Function): this; - prependListener(event: "tlsClientError", listener: (err: Error, tlsSocket: TLSSocket) => void): this; - prependListener(event: "newSession", listener: (sessionId: any, sessionData: any, callback: (err: Error, resp: Buffer) => void) => void): this; - prependListener(event: "OCSPRequest", listener: (certificate: Buffer, issuer: Buffer, callback: Function) => void): this; - prependListener(event: "resumeSession", listener: (sessionId: any, callback: (err: Error, sessionData: any) => void) => void): this; - prependListener(event: "secureConnection", listener: (tlsSocket: TLSSocket) => void): this; + prependListener(event: string, listener: (...args: any[]) => void): this; + prependListener(event: "tlsClientError", listener: (err: Error, tlsSocket: TLSSocket) => void): this; + prependListener(event: "newSession", listener: (sessionId: any, sessionData: any, callback: (err: Error, resp: Buffer) => void) => void): this; + prependListener(event: "OCSPRequest", listener: (certificate: Buffer, issuer: Buffer, callback: Function) => void): this; + prependListener(event: "resumeSession", listener: (sessionId: any, callback: (err: Error, sessionData: any) => void) => void): this; + prependListener(event: "secureConnection", listener: (tlsSocket: TLSSocket) => void): this; - prependOnceListener(event: string, listener: Function): this; - prependOnceListener(event: "tlsClientError", listener: (err: Error, tlsSocket: TLSSocket) => void): this; - prependOnceListener(event: "newSession", listener: (sessionId: any, sessionData: any, callback: (err: Error, resp: Buffer) => void) => void): this; - prependOnceListener(event: "OCSPRequest", listener: (certificate: Buffer, issuer: Buffer, callback: Function) => void): this; - prependOnceListener(event: "resumeSession", listener: (sessionId: any, callback: (err: Error, sessionData: any) => void) => void): this; - prependOnceListener(event: "secureConnection", listener: (tlsSocket: TLSSocket) => void): this; - } + prependOnceListener(event: string, listener: (...args: any[]) => void): this; + prependOnceListener(event: "tlsClientError", listener: (err: Error, tlsSocket: TLSSocket) => void): this; + prependOnceListener(event: "newSession", listener: (sessionId: any, sessionData: any, callback: (err: Error, resp: Buffer) => void) => void): this; + prependOnceListener(event: "OCSPRequest", listener: (certificate: Buffer, issuer: Buffer, callback: Function) => void): this; + prependOnceListener(event: "resumeSession", listener: (sessionId: any, callback: (err: Error, sessionData: any) => void) => void): this; + prependOnceListener(event: "secureConnection", listener: (tlsSocket: TLSSocket) => void): this; + } - export interface ClearTextStream extends stream.Duplex { - authorized: boolean; - authorizationError: Error; - getPeerCertificate(): any; - getCipher: { - name: string; - version: string; - }; - address: { - port: number; - family: string; - address: string; - }; - remoteAddress: string; - remotePort: number; - } + export interface ClearTextStream extends stream.Duplex { + authorized: boolean; + authorizationError: Error; + getPeerCertificate(): any; + getCipher: { + name: string; + version: string; + }; + address: { + port: number; + family: string; + address: string; + }; + remoteAddress: string; + remotePort: number; + } - export interface SecurePair { - encrypted: any; - cleartext: any; - } + export interface SecurePair { + encrypted: any; + cleartext: any; + } - export interface SecureContextOptions { - pfx?: string | Buffer; - key?: string | Buffer; - passphrase?: string; - cert?: string | Buffer; - ca?: string | Buffer; - crl?: string | string[] - ciphers?: string; - honorCipherOrder?: boolean; - } + export interface SecureContextOptions { + pfx?: string | Buffer | Array; + key?: string | Buffer | Array; + passphrase?: string; + cert?: string | Buffer | Array; + ca?: string | Buffer | Array; + ciphers?: string; + honorCipherOrder?: boolean; + ecdhCurve?: string; + crl?: string | Buffer | Array; + dhparam?: string | Buffer; + secureOptions?: number; // Value is a numeric bitmask of the `SSL_OP_*` options + secureProtocol?: string; // SSL Method, e.g. SSLv23_method + sessionIdContext?: string; + } - export interface SecureContext { - context: any; - } + export interface SecureContext { + context: any; + } - export function createServer(options: TlsOptions, secureConnectionListener?: (socket: TLSSocket) => void): Server; - export function connect(options: ConnectionOptions, secureConnectionListener?: () => void): TLSSocket; - export function connect(port: number, host?: string, options?: ConnectionOptions, secureConnectListener?: () => void): TLSSocket; - export function connect(port: number, options?: ConnectionOptions, secureConnectListener?: () => void): TLSSocket; - export function createSecurePair(credentials?: crypto.Credentials, isServer?: boolean, requestCert?: boolean, rejectUnauthorized?: boolean): SecurePair; - export function createSecureContext(details: SecureContextOptions): SecureContext; + /* + * Verifies the certificate `cert` is issued to host `host`. + * @host The hostname to verify the certificate against + * @cert PeerCertificate representing the peer's certificate + * + * Returns Error object, populating it with the reason, host and cert on failure. On success, returns undefined. + */ + export function checkServerIdentity(host: string, cert: PeerCertificate): Error | undefined; + export function createServer(options: TlsOptions, secureConnectionListener?: (socket: TLSSocket) => void): Server; + export function connect(options: ConnectionOptions, secureConnectionListener?: () => void): TLSSocket; + export function connect(port: number, host?: string, options?: ConnectionOptions, secureConnectListener?: () => void): TLSSocket; + export function connect(port: number, options?: ConnectionOptions, secureConnectListener?: () => void): TLSSocket; + export function createSecurePair(credentials?: crypto.Credentials, isServer?: boolean, requestCert?: boolean, rejectUnauthorized?: boolean): SecurePair; + export function createSecureContext(details: SecureContextOptions): SecureContext; + export function getCiphers(): string[]; + + export var DEFAULT_ECDH_CURVE: string; } declare module "crypto" { - export interface Certificate { - exportChallenge(spkac: string | Buffer): Buffer; - exportPublicKey(spkac: string | Buffer): Buffer; - verifySpkac(spkac: Buffer): boolean; - } - export var Certificate: { - new(): Certificate; - (): Certificate; - } + export interface Certificate { + exportChallenge(spkac: string | Buffer): Buffer; + exportPublicKey(spkac: string | Buffer): Buffer; + verifySpkac(spkac: Buffer): boolean; + } + export var Certificate: { + new(): Certificate; + (): Certificate; + }; - export var fips: boolean; + export var fips: boolean; - export interface CredentialDetails { - pfx: string; - key: string; - passphrase: string; - cert: string; - ca: string | string[]; - crl: string | string[]; - ciphers: string; - } - export interface Credentials { context?: any; } - export function createCredentials(details: CredentialDetails): Credentials; - export function createHash(algorithm: string): Hash; - export function createHmac(algorithm: string, key: string | Buffer): Hmac; + export interface CredentialDetails { + pfx: string; + key: string; + passphrase: string; + cert: string; + ca: string | string[]; + crl: string | string[]; + ciphers: string; + } + export interface Credentials { context?: any; } + export function createCredentials(details: CredentialDetails): Credentials; + export function createHash(algorithm: string): Hash; + export function createHmac(algorithm: string, key: string | Buffer): Hmac; - type Utf8AsciiLatin1Encoding = "utf8" | "ascii" | "latin1"; - type HexBase64Latin1Encoding = "latin1" | "hex" | "base64"; - type Utf8AsciiBinaryEncoding = "utf8" | "ascii" | "binary"; - type HexBase64BinaryEncoding = "binary" | "base64" | "hex"; - type ECDHKeyFormat = "compressed" | "uncompressed" | "hybrid"; + type Utf8AsciiLatin1Encoding = "utf8" | "ascii" | "latin1"; + type HexBase64Latin1Encoding = "latin1" | "hex" | "base64"; + type Utf8AsciiBinaryEncoding = "utf8" | "ascii" | "binary"; + type HexBase64BinaryEncoding = "binary" | "base64" | "hex"; + type ECDHKeyFormat = "compressed" | "uncompressed" | "hybrid"; - export interface Hash extends NodeJS.ReadWriteStream { - update(data: string | Buffer): Hash; - update(data: string | Buffer, input_encoding: Utf8AsciiLatin1Encoding): Hash; - digest(): Buffer; - digest(encoding: HexBase64Latin1Encoding): string; - } - export interface Hmac extends NodeJS.ReadWriteStream { - update(data: string | Buffer): Hmac; - update(data: string | Buffer, input_encoding: Utf8AsciiLatin1Encoding): Hmac; - digest(): Buffer; - digest(encoding: HexBase64Latin1Encoding): string; - } - export function createCipher(algorithm: string, password: any): Cipher; - export function createCipheriv(algorithm: string, key: any, iv: any): Cipher; - export interface Cipher extends NodeJS.ReadWriteStream { - update(data: Buffer): Buffer; - update(data: string, input_encoding: Utf8AsciiBinaryEncoding): Buffer; - update(data: Buffer, input_encoding: any, output_encoding: HexBase64BinaryEncoding): string; - update(data: string, input_encoding: Utf8AsciiBinaryEncoding, output_encoding: HexBase64BinaryEncoding): string; - final(): Buffer; - final(output_encoding: string): string; - setAutoPadding(auto_padding?: boolean): void; - getAuthTag(): Buffer; - setAAD(buffer: Buffer): void; - } - export function createDecipher(algorithm: string, password: any): Decipher; - export function createDecipheriv(algorithm: string, key: any, iv: any): Decipher; - export interface Decipher extends NodeJS.ReadWriteStream { - update(data: Buffer): Buffer; - update(data: string, input_encoding: HexBase64BinaryEncoding): Buffer; - update(data: Buffer, input_encoding: any, output_encoding: Utf8AsciiBinaryEncoding): string; - update(data: string, input_encoding: HexBase64BinaryEncoding, output_encoding: Utf8AsciiBinaryEncoding): string; - final(): Buffer; - final(output_encoding: string): string; - setAutoPadding(auto_padding?: boolean): void; - setAuthTag(tag: Buffer): void; - setAAD(buffer: Buffer): void; - } - export function createSign(algorithm: string): Signer; - export interface Signer extends NodeJS.WritableStream { - update(data: string | Buffer): Signer; - update(data: string | Buffer, input_encoding: Utf8AsciiLatin1Encoding): Signer; - sign(private_key: string | { key: string; passphrase: string }): Buffer; - sign(private_key: string | { key: string; passphrase: string }, output_format: HexBase64Latin1Encoding): string; - } - export function createVerify(algorith: string): Verify; - export interface Verify extends NodeJS.WritableStream { - update(data: string | Buffer): Verify; - update(data: string | Buffer, input_encoding: Utf8AsciiLatin1Encoding): Verify; - verify(object: string, signature: Buffer): boolean; - verify(object: string, signature: string, signature_format: HexBase64Latin1Encoding): boolean; - } - export function createDiffieHellman(prime_length: number, generator?: number): DiffieHellman; - export function createDiffieHellman(prime: Buffer): DiffieHellman; - export function createDiffieHellman(prime: string, prime_encoding: HexBase64Latin1Encoding): DiffieHellman; - export function createDiffieHellman(prime: string, prime_encoding: HexBase64Latin1Encoding, generator: number | Buffer): DiffieHellman; - export function createDiffieHellman(prime: string, prime_encoding: HexBase64Latin1Encoding, generator: string, generator_encoding: HexBase64Latin1Encoding): DiffieHellman; - export interface DiffieHellman { - generateKeys(): Buffer; - generateKeys(encoding: HexBase64Latin1Encoding): string; - computeSecret(other_public_key: Buffer): Buffer; - computeSecret(other_public_key: string, input_encoding: HexBase64Latin1Encoding): Buffer; - computeSecret(other_public_key: string, input_encoding: HexBase64Latin1Encoding, output_encoding: HexBase64Latin1Encoding): string; - getPrime(): Buffer; - getPrime(encoding: HexBase64Latin1Encoding): string; - getGenerator(): Buffer; - getGenerator(encoding: HexBase64Latin1Encoding): string; - getPublicKey(): Buffer; - getPublicKey(encoding: HexBase64Latin1Encoding): string; - getPrivateKey(): Buffer; - getPrivateKey(encoding: HexBase64Latin1Encoding): string; - setPublicKey(public_key: Buffer): void; - setPublicKey(public_key: string, encoding: string): void; - setPrivateKey(private_key: Buffer): void; - setPrivateKey(private_key: string, encoding: string): void; - verifyError: number; - } - export function getDiffieHellman(group_name: string): DiffieHellman; - export function pbkdf2(password: string | Buffer, salt: string | Buffer, iterations: number, keylen: number, digest: string, callback: (err: Error, derivedKey: Buffer) => any): void; - export function pbkdf2Sync(password: string | Buffer, salt: string | Buffer, iterations: number, keylen: number, digest: string): Buffer; - export function randomBytes(size: number): Buffer; - export function randomBytes(size: number, callback: (err: Error, buf: Buffer) => void): void; - export function pseudoRandomBytes(size: number): Buffer; - export function pseudoRandomBytes(size: number, callback: (err: Error, buf: Buffer) => void): void; - export function randomFillSync(buffer: Buffer | Uint8Array, offset?: number, size?: number): Buffer; - export function randomFill(buffer: Buffer, callback: (err: Error, buf: Buffer) => void): void; - export function randomFill(buffer: Uint8Array, callback: (err: Error, buf: Uint8Array) => void): void; - export function randomFill(buffer: Buffer, offset: number, callback: (err: Error, buf: Buffer) => void): void; - export function randomFill(buffer: Uint8Array, offset: number, callback: (err: Error, buf: Uint8Array) => void): void; - export function randomFill(buffer: Buffer, offset: number, size: number, callback: (err: Error, buf: Buffer) => void): void; - export function randomFill(buffer: Uint8Array, offset: number, size: number, callback: (err: Error, buf: Uint8Array) => void): void; - export interface RsaPublicKey { - key: string; - padding?: number; - } - export interface RsaPrivateKey { - key: string; - passphrase?: string, - padding?: number; - } - export function publicEncrypt(public_key: string | RsaPublicKey, buffer: Buffer): Buffer - export function privateDecrypt(private_key: string | RsaPrivateKey, buffer: Buffer): Buffer - export function privateEncrypt(private_key: string | RsaPrivateKey, buffer: Buffer): Buffer - export function publicDecrypt(public_key: string | RsaPublicKey, buffer: Buffer): Buffer - export function getCiphers(): string[]; - export function getCurves(): string[]; - export function getHashes(): string[]; - export interface ECDH { - generateKeys(): Buffer; - generateKeys(encoding: HexBase64Latin1Encoding): string; - generateKeys(encoding: HexBase64Latin1Encoding, format: ECDHKeyFormat): string; - computeSecret(other_public_key: Buffer): Buffer; - computeSecret(other_public_key: string, input_encoding: HexBase64Latin1Encoding): Buffer; - computeSecret(other_public_key: string, input_encoding: HexBase64Latin1Encoding, output_encoding: HexBase64Latin1Encoding): string; - getPrivateKey(): Buffer; - getPrivateKey(encoding: HexBase64Latin1Encoding): string; - getPublicKey(): Buffer; - getPublicKey(encoding: HexBase64Latin1Encoding): string; - getPublicKey(encoding: HexBase64Latin1Encoding, format: ECDHKeyFormat): string; - setPrivateKey(private_key: Buffer): void; - setPrivateKey(private_key: string, encoding: HexBase64Latin1Encoding): void; - } - export function createECDH(curve_name: string): ECDH; - export function timingSafeEqual(a: Buffer, b: Buffer): boolean; - export var DEFAULT_ENCODING: string; + export interface Hash extends NodeJS.ReadWriteStream { + update(data: string | Buffer | DataView): Hash; + update(data: string | Buffer | DataView, input_encoding: Utf8AsciiLatin1Encoding): Hash; + digest(): Buffer; + digest(encoding: HexBase64Latin1Encoding): string; + } + export interface Hmac extends NodeJS.ReadWriteStream { + update(data: string | Buffer | DataView): Hmac; + update(data: string | Buffer | DataView, input_encoding: Utf8AsciiLatin1Encoding): Hmac; + digest(): Buffer; + digest(encoding: HexBase64Latin1Encoding): string; + } + export function createCipher(algorithm: string, password: any): Cipher; + export function createCipheriv(algorithm: string, key: any, iv: any): Cipher; + export interface Cipher extends NodeJS.ReadWriteStream { + update(data: Buffer | DataView): Buffer; + update(data: string, input_encoding: Utf8AsciiBinaryEncoding): Buffer; + update(data: Buffer | DataView, input_encoding: any, output_encoding: HexBase64BinaryEncoding): string; + update(data: string, input_encoding: Utf8AsciiBinaryEncoding, output_encoding: HexBase64BinaryEncoding): string; + final(): Buffer; + final(output_encoding: string): string; + setAutoPadding(auto_padding?: boolean): this; + getAuthTag(): Buffer; + setAAD(buffer: Buffer): this; + } + export function createDecipher(algorithm: string, password: any): Decipher; + export function createDecipheriv(algorithm: string, key: any, iv: any): Decipher; + export interface Decipher extends NodeJS.ReadWriteStream { + update(data: Buffer | DataView): Buffer; + update(data: string, input_encoding: HexBase64BinaryEncoding): Buffer; + update(data: Buffer | DataView, input_encoding: any, output_encoding: Utf8AsciiBinaryEncoding): string; + update(data: string, input_encoding: HexBase64BinaryEncoding, output_encoding: Utf8AsciiBinaryEncoding): string; + final(): Buffer; + final(output_encoding: string): string; + setAutoPadding(auto_padding?: boolean): this; + setAuthTag(tag: Buffer): this; + setAAD(buffer: Buffer): this; + } + export function createSign(algorithm: string): Signer; + export interface Signer extends NodeJS.WritableStream { + update(data: string | Buffer | DataView): Signer; + update(data: string | Buffer | DataView, input_encoding: Utf8AsciiLatin1Encoding): Signer; + sign(private_key: string | { key: string; passphrase: string }): Buffer; + sign(private_key: string | { key: string; passphrase: string }, output_format: HexBase64Latin1Encoding): string; + } + export function createVerify(algorith: string): Verify; + export interface Verify extends NodeJS.WritableStream { + update(data: string | Buffer | DataView): Verify; + update(data: string | Buffer | DataView, input_encoding: Utf8AsciiLatin1Encoding): Verify; + verify(object: string | Object, signature: Buffer | DataView): boolean; + verify(object: string | Object, signature: string, signature_format: HexBase64Latin1Encoding): boolean; + // https://nodejs.org/api/crypto.html#crypto_verifier_verify_object_signature_signature_format + // The signature field accepts a TypedArray type, but it is only available starting ES2017 + } + export function createDiffieHellman(prime_length: number, generator?: number): DiffieHellman; + export function createDiffieHellman(prime: Buffer): DiffieHellman; + export function createDiffieHellman(prime: string, prime_encoding: HexBase64Latin1Encoding): DiffieHellman; + export function createDiffieHellman(prime: string, prime_encoding: HexBase64Latin1Encoding, generator: number | Buffer): DiffieHellman; + export function createDiffieHellman(prime: string, prime_encoding: HexBase64Latin1Encoding, generator: string, generator_encoding: HexBase64Latin1Encoding): DiffieHellman; + export interface DiffieHellman { + generateKeys(): Buffer; + generateKeys(encoding: HexBase64Latin1Encoding): string; + computeSecret(other_public_key: Buffer): Buffer; + computeSecret(other_public_key: string, input_encoding: HexBase64Latin1Encoding): Buffer; + computeSecret(other_public_key: string, input_encoding: HexBase64Latin1Encoding, output_encoding: HexBase64Latin1Encoding): string; + getPrime(): Buffer; + getPrime(encoding: HexBase64Latin1Encoding): string; + getGenerator(): Buffer; + getGenerator(encoding: HexBase64Latin1Encoding): string; + getPublicKey(): Buffer; + getPublicKey(encoding: HexBase64Latin1Encoding): string; + getPrivateKey(): Buffer; + getPrivateKey(encoding: HexBase64Latin1Encoding): string; + setPublicKey(public_key: Buffer): void; + setPublicKey(public_key: string, encoding: string): void; + setPrivateKey(private_key: Buffer): void; + setPrivateKey(private_key: string, encoding: string): void; + verifyError: number; + } + export function getDiffieHellman(group_name: string): DiffieHellman; + export function pbkdf2(password: string | Buffer, salt: string | Buffer, iterations: number, keylen: number, digest: string, callback: (err: Error, derivedKey: Buffer) => any): void; + export function pbkdf2Sync(password: string | Buffer, salt: string | Buffer, iterations: number, keylen: number, digest: string): Buffer; + export function randomBytes(size: number): Buffer; + export function randomBytes(size: number, callback: (err: Error, buf: Buffer) => void): void; + export function pseudoRandomBytes(size: number): Buffer; + export function pseudoRandomBytes(size: number, callback: (err: Error, buf: Buffer) => void): void; + export function randomFillSync(buffer: Buffer | Uint8Array, offset?: number, size?: number): Buffer; + export function randomFill(buffer: Buffer, callback: (err: Error, buf: Buffer) => void): void; + export function randomFill(buffer: Uint8Array, callback: (err: Error, buf: Uint8Array) => void): void; + export function randomFill(buffer: Buffer, offset: number, callback: (err: Error, buf: Buffer) => void): void; + export function randomFill(buffer: Uint8Array, offset: number, callback: (err: Error, buf: Uint8Array) => void): void; + export function randomFill(buffer: Buffer, offset: number, size: number, callback: (err: Error, buf: Buffer) => void): void; + export function randomFill(buffer: Uint8Array, offset: number, size: number, callback: (err: Error, buf: Uint8Array) => void): void; + export interface RsaPublicKey { + key: string; + padding?: number; + } + export interface RsaPrivateKey { + key: string; + passphrase?: string; + padding?: number; + } + export function publicEncrypt(public_key: string | RsaPublicKey, buffer: Buffer): Buffer; + export function privateDecrypt(private_key: string | RsaPrivateKey, buffer: Buffer): Buffer; + export function privateEncrypt(private_key: string | RsaPrivateKey, buffer: Buffer): Buffer; + export function publicDecrypt(public_key: string | RsaPublicKey, buffer: Buffer): Buffer; + export function getCiphers(): string[]; + export function getCurves(): string[]; + export function getHashes(): string[]; + export interface ECDH { + generateKeys(): Buffer; + generateKeys(encoding: HexBase64Latin1Encoding): string; + generateKeys(encoding: HexBase64Latin1Encoding, format: ECDHKeyFormat): string; + computeSecret(other_public_key: Buffer): Buffer; + computeSecret(other_public_key: string, input_encoding: HexBase64Latin1Encoding): Buffer; + computeSecret(other_public_key: string, input_encoding: HexBase64Latin1Encoding, output_encoding: HexBase64Latin1Encoding): string; + getPrivateKey(): Buffer; + getPrivateKey(encoding: HexBase64Latin1Encoding): string; + getPublicKey(): Buffer; + getPublicKey(encoding: HexBase64Latin1Encoding): string; + getPublicKey(encoding: HexBase64Latin1Encoding, format: ECDHKeyFormat): string; + setPrivateKey(private_key: Buffer): void; + setPrivateKey(private_key: string, encoding: HexBase64Latin1Encoding): void; + } + export function createECDH(curve_name: string): ECDH; + export function timingSafeEqual(a: Buffer, b: Buffer): boolean; + export var DEFAULT_ENCODING: string; } declare module "stream" { - import * as events from "events"; + import * as events from "events"; - class internal extends events.EventEmitter { - pipe(destination: T, options?: { end?: boolean; }): T; - } + class internal extends events.EventEmitter { + pipe(destination: T, options?: { end?: boolean; }): T; + } - namespace internal { + namespace internal { + export class Stream extends internal { } - export class Stream extends internal { } + export interface ReadableOptions { + highWaterMark?: number; + encoding?: string; + objectMode?: boolean; + read?: (this: Readable, size?: number) => any; + destroy?: (error?: Error) => any; + } - export interface ReadableOptions { - highWaterMark?: number; - encoding?: string; - objectMode?: boolean; - read?: (this: Readable, size?: number) => any; - } - - export class Readable extends Stream implements NodeJS.ReadableStream { - readable: boolean; - constructor(opts?: ReadableOptions); - _read(size: number): void; - read(size?: number): any; - setEncoding(encoding: string): this; - pause(): this; - resume(): this; - isPaused(): boolean; - pipe(destination: T, options?: { end?: boolean; }): T; - unpipe(destination?: T): this; - unshift(chunk: any): void; - wrap(oldStream: NodeJS.ReadableStream): Readable; - push(chunk: any, encoding?: string): boolean; + export class Readable extends Stream implements NodeJS.ReadableStream { + readable: boolean; + readonly readableHighWaterMark: number; + constructor(opts?: ReadableOptions); + _read(size: number): void; + read(size?: number): any; + setEncoding(encoding: string): this; + pause(): this; + resume(): this; + isPaused(): boolean; + unpipe(destination?: T): this; + unshift(chunk: any): void; + wrap(oldStream: NodeJS.ReadableStream): this; + push(chunk: any, encoding?: string): boolean; + _destroy(err: Error, callback: Function): void; + destroy(error?: Error): void; /** * Event emitter * The defined events on documents including: - * 1. close - * 2. data - * 3. end - * 4. readable - * 5. error - **/ - addListener(event: string, listener: Function): this; - addListener(event: string, listener: Function): this; - addListener(event: "close", listener: () => void): this; - addListener(event: "data", listener: (chunk: Buffer | string) => void): this; - addListener(event: "end", listener: () => void): this; - addListener(event: "readable", listener: () => void): this; - addListener(event: "error", listener: (err: Error) => void): this; + * 1. close + * 2. data + * 3. end + * 4. readable + * 5. error + */ + addListener(event: string, listener: (...args: any[]) => void): this; + addListener(event: "close", listener: () => void): this; + addListener(event: "data", listener: (chunk: Buffer | string) => void): this; + addListener(event: "end", listener: () => void): this; + addListener(event: "readable", listener: () => void): this; + addListener(event: "error", listener: (err: Error) => void): this; - emit(event: string | symbol, ...args: any[]): boolean; - emit(event: "close"): boolean; - emit(event: "data", chunk: Buffer | string): boolean; - emit(event: "end"): boolean; - emit(event: "readable"): boolean; - emit(event: "error", err: Error): boolean; + emit(event: string | symbol, ...args: any[]): boolean; + emit(event: "close"): boolean; + emit(event: "data", chunk: Buffer | string): boolean; + emit(event: "end"): boolean; + emit(event: "readable"): boolean; + emit(event: "error", err: Error): boolean; - on(event: string, listener: Function): this; - on(event: "close", listener: () => void): this; - on(event: "data", listener: (chunk: Buffer | string) => void): this; - on(event: "end", listener: () => void): this; - on(event: "readable", listener: () => void): this; - on(event: "error", listener: (err: Error) => void): this; + on(event: string, listener: (...args: any[]) => void): this; + on(event: "close", listener: () => void): this; + on(event: "data", listener: (chunk: Buffer | string) => void): this; + on(event: "end", listener: () => void): this; + on(event: "readable", listener: () => void): this; + on(event: "error", listener: (err: Error) => void): this; - once(event: string, listener: Function): this; - once(event: "close", listener: () => void): this; - once(event: "data", listener: (chunk: Buffer | string) => void): this; - once(event: "end", listener: () => void): this; - once(event: "readable", listener: () => void): this; - once(event: "error", listener: (err: Error) => void): this; + once(event: string, listener: (...args: any[]) => void): this; + once(event: "close", listener: () => void): this; + once(event: "data", listener: (chunk: Buffer | string) => void): this; + once(event: "end", listener: () => void): this; + once(event: "readable", listener: () => void): this; + once(event: "error", listener: (err: Error) => void): this; - prependListener(event: string, listener: Function): this; - prependListener(event: "close", listener: () => void): this; - prependListener(event: "data", listener: (chunk: Buffer | string) => void): this; - prependListener(event: "end", listener: () => void): this; - prependListener(event: "readable", listener: () => void): this; - prependListener(event: "error", listener: (err: Error) => void): this; + prependListener(event: string, listener: (...args: any[]) => void): this; + prependListener(event: "close", listener: () => void): this; + prependListener(event: "data", listener: (chunk: Buffer | string) => void): this; + prependListener(event: "end", listener: () => void): this; + prependListener(event: "readable", listener: () => void): this; + prependListener(event: "error", listener: (err: Error) => void): this; - prependOnceListener(event: string, listener: Function): this; - prependOnceListener(event: "close", listener: () => void): this; - prependOnceListener(event: "data", listener: (chunk: Buffer | string) => void): this; - prependOnceListener(event: "end", listener: () => void): this; - prependOnceListener(event: "readable", listener: () => void): this; - prependOnceListener(event: "error", listener: (err: Error) => void): this; + prependOnceListener(event: string, listener: (...args: any[]) => void): this; + prependOnceListener(event: "close", listener: () => void): this; + prependOnceListener(event: "data", listener: (chunk: Buffer | string) => void): this; + prependOnceListener(event: "end", listener: () => void): this; + prependOnceListener(event: "readable", listener: () => void): this; + prependOnceListener(event: "error", listener: (err: Error) => void): this; - removeListener(event: string, listener: Function): this; - removeListener(event: "close", listener: () => void): this; - removeListener(event: "data", listener: (chunk: Buffer | string) => void): this; - removeListener(event: "end", listener: () => void): this; - removeListener(event: "readable", listener: () => void): this; - removeListener(event: "error", listener: (err: Error) => void): this; - } + removeListener(event: string, listener: (...args: any[]) => void): this; + removeListener(event: "close", listener: () => void): this; + removeListener(event: "data", listener: (chunk: Buffer | string) => void): this; + removeListener(event: "end", listener: () => void): this; + removeListener(event: "readable", listener: () => void): this; + removeListener(event: "error", listener: (err: Error) => void): this; + } - export interface WritableOptions { - highWaterMark?: number; - decodeStrings?: boolean; - objectMode?: boolean; - write?: (chunk: string | Buffer, encoding: string, callback: Function) => any; - writev?: (chunks: { chunk: string | Buffer, encoding: string }[], callback: Function) => any; - } + export interface WritableOptions { + highWaterMark?: number; + decodeStrings?: boolean; + objectMode?: boolean; + write?: (chunk: any, encoding: string, callback: Function) => any; + writev?: (chunks: Array<{ chunk: any, encoding: string }>, callback: Function) => any; + destroy?: (error?: Error) => any; + final?: (callback: (error?: Error) => void) => void; + } - export class Writable extends Stream implements NodeJS.WritableStream { - writable: boolean; - constructor(opts?: WritableOptions); - _write(chunk: any, encoding: string, callback: Function): void; - write(chunk: any, cb?: Function): boolean; - write(chunk: any, encoding?: string, cb?: Function): boolean; - setDefaultEncoding(encoding: string): this; - end(): void; - end(chunk: any, cb?: Function): void; - end(chunk: any, encoding?: string, cb?: Function): void; + export class Writable extends Stream implements NodeJS.WritableStream { + writable: boolean; + readonly writableHighWaterMark: number; + constructor(opts?: WritableOptions); + _write(chunk: any, encoding: string, callback: (err?: Error) => void): void; + _writev?(chunks: Array<{ chunk: any, encoding: string }>, callback: (err?: Error) => void): void; + _destroy(err: Error, callback: Function): void; + _final(callback: Function): void; + write(chunk: any, cb?: Function): boolean; + write(chunk: any, encoding?: string, cb?: Function): boolean; + setDefaultEncoding(encoding: string): this; + end(cb?: Function): void; + end(chunk: any, cb?: Function): void; + end(chunk: any, encoding?: string, cb?: Function): void; + cork(): void; + uncork(): void; + destroy(error?: Error): void; /** * Event emitter * The defined events on documents including: - * 1. close - * 2. drain - * 3. error - * 4. finish - * 5. pipe - * 6. unpipe - **/ - addListener(event: string, listener: Function): this; - addListener(event: "close", listener: () => void): this; - addListener(event: "drain", listener: () => void): this; - addListener(event: "error", listener: (err: Error) => void): this; - addListener(event: "finish", listener: () => void): this; - addListener(event: "pipe", listener: (src: Readable) => void): this; - addListener(event: "unpipe", listener: (src: Readable) => void): this; + * 1. close + * 2. drain + * 3. error + * 4. finish + * 5. pipe + * 6. unpipe + */ + addListener(event: string, listener: (...args: any[]) => void): this; + addListener(event: "close", listener: () => void): this; + addListener(event: "drain", listener: () => void): this; + addListener(event: "error", listener: (err: Error) => void): this; + addListener(event: "finish", listener: () => void): this; + addListener(event: "pipe", listener: (src: Readable) => void): this; + addListener(event: "unpipe", listener: (src: Readable) => void): this; - emit(event: string | symbol, ...args: any[]): boolean; - emit(event: "close"): boolean; - emit(event: "drain", chunk: Buffer | string): boolean; - emit(event: "error", err: Error): boolean; - emit(event: "finish"): boolean; - emit(event: "pipe", src: Readable): boolean; - emit(event: "unpipe", src: Readable): boolean; + emit(event: string | symbol, ...args: any[]): boolean; + emit(event: "close"): boolean; + emit(event: "drain", chunk: Buffer | string): boolean; + emit(event: "error", err: Error): boolean; + emit(event: "finish"): boolean; + emit(event: "pipe", src: Readable): boolean; + emit(event: "unpipe", src: Readable): boolean; - on(event: string, listener: Function): this; - on(event: "close", listener: () => void): this; - on(event: "drain", listener: () => void): this; - on(event: "error", listener: (err: Error) => void): this; - on(event: "finish", listener: () => void): this; - on(event: "pipe", listener: (src: Readable) => void): this; - on(event: "unpipe", listener: (src: Readable) => void): this; + on(event: string, listener: (...args: any[]) => void): this; + on(event: "close", listener: () => void): this; + on(event: "drain", listener: () => void): this; + on(event: "error", listener: (err: Error) => void): this; + on(event: "finish", listener: () => void): this; + on(event: "pipe", listener: (src: Readable) => void): this; + on(event: "unpipe", listener: (src: Readable) => void): this; - once(event: string, listener: Function): this; - once(event: "close", listener: () => void): this; - once(event: "drain", listener: () => void): this; - once(event: "error", listener: (err: Error) => void): this; - once(event: "finish", listener: () => void): this; - once(event: "pipe", listener: (src: Readable) => void): this; - once(event: "unpipe", listener: (src: Readable) => void): this; + once(event: string, listener: (...args: any[]) => void): this; + once(event: "close", listener: () => void): this; + once(event: "drain", listener: () => void): this; + once(event: "error", listener: (err: Error) => void): this; + once(event: "finish", listener: () => void): this; + once(event: "pipe", listener: (src: Readable) => void): this; + once(event: "unpipe", listener: (src: Readable) => void): this; - prependListener(event: string, listener: Function): this; - prependListener(event: "close", listener: () => void): this; - prependListener(event: "drain", listener: () => void): this; - prependListener(event: "error", listener: (err: Error) => void): this; - prependListener(event: "finish", listener: () => void): this; - prependListener(event: "pipe", listener: (src: Readable) => void): this; - prependListener(event: "unpipe", listener: (src: Readable) => void): this; + prependListener(event: string, listener: (...args: any[]) => void): this; + prependListener(event: "close", listener: () => void): this; + prependListener(event: "drain", listener: () => void): this; + prependListener(event: "error", listener: (err: Error) => void): this; + prependListener(event: "finish", listener: () => void): this; + prependListener(event: "pipe", listener: (src: Readable) => void): this; + prependListener(event: "unpipe", listener: (src: Readable) => void): this; - prependOnceListener(event: string, listener: Function): this; - prependOnceListener(event: "close", listener: () => void): this; - prependOnceListener(event: "drain", listener: () => void): this; - prependOnceListener(event: "error", listener: (err: Error) => void): this; - prependOnceListener(event: "finish", listener: () => void): this; - prependOnceListener(event: "pipe", listener: (src: Readable) => void): this; - prependOnceListener(event: "unpipe", listener: (src: Readable) => void): this; + prependOnceListener(event: string, listener: (...args: any[]) => void): this; + prependOnceListener(event: "close", listener: () => void): this; + prependOnceListener(event: "drain", listener: () => void): this; + prependOnceListener(event: "error", listener: (err: Error) => void): this; + prependOnceListener(event: "finish", listener: () => void): this; + prependOnceListener(event: "pipe", listener: (src: Readable) => void): this; + prependOnceListener(event: "unpipe", listener: (src: Readable) => void): this; - removeListener(event: string, listener: Function): this; - removeListener(event: "close", listener: () => void): this; - removeListener(event: "drain", listener: () => void): this; - removeListener(event: "error", listener: (err: Error) => void): this; - removeListener(event: "finish", listener: () => void): this; - removeListener(event: "pipe", listener: (src: Readable) => void): this; - removeListener(event: "unpipe", listener: (src: Readable) => void): this; - } + removeListener(event: string, listener: (...args: any[]) => void): this; + removeListener(event: "close", listener: () => void): this; + removeListener(event: "drain", listener: () => void): this; + removeListener(event: "error", listener: (err: Error) => void): this; + removeListener(event: "finish", listener: () => void): this; + removeListener(event: "pipe", listener: (src: Readable) => void): this; + removeListener(event: "unpipe", listener: (src: Readable) => void): this; + } - export interface DuplexOptions extends ReadableOptions, WritableOptions { - allowHalfOpen?: boolean; - readableObjectMode?: boolean; - writableObjectMode?: boolean; - } + export interface DuplexOptions extends ReadableOptions, WritableOptions { + allowHalfOpen?: boolean; + readableObjectMode?: boolean; + writableObjectMode?: boolean; + } - // Note: Duplex extends both Readable and Writable. - export class Duplex extends Readable implements Writable { - writable: boolean; - constructor(opts?: DuplexOptions); - _write(chunk: any, encoding: string, callback: Function): void; - write(chunk: any, cb?: Function): boolean; - write(chunk: any, encoding?: string, cb?: Function): boolean; - setDefaultEncoding(encoding: string): this; - end(): void; - end(chunk: any, cb?: Function): void; - end(chunk: any, encoding?: string, cb?: Function): void; - } + // Note: Duplex extends both Readable and Writable. + export class Duplex extends Readable implements Writable { + writable: boolean; + readonly writableHighWaterMark: number; + constructor(opts?: DuplexOptions); + _write(chunk: any, encoding: string, callback: (err?: Error) => void): void; + _writev?(chunks: Array<{ chunk: any, encoding: string }>, callback: (err?: Error) => void): void; + _destroy(err: Error, callback: Function): void; + _final(callback: Function): void; + write(chunk: any, cb?: Function): boolean; + write(chunk: any, encoding?: string, cb?: Function): boolean; + setDefaultEncoding(encoding: string): this; + end(cb?: Function): void; + end(chunk: any, cb?: Function): void; + end(chunk: any, encoding?: string, cb?: Function): void; + cork(): void; + uncork(): void; + } - export interface TransformOptions extends DuplexOptions { - transform?: (chunk: string | Buffer, encoding: string, callback: Function) => any; - flush?: (callback: Function) => any; - } + export interface TransformOptions extends DuplexOptions { + transform?: (chunk: string | Buffer, encoding: string, callback: Function) => any; + flush?: (callback: Function) => any; + } - export class Transform extends Duplex { - constructor(opts?: TransformOptions); - _transform(chunk: any, encoding: string, callback: Function): void; - } + export class Transform extends Duplex { + constructor(opts?: TransformOptions); + _transform(chunk: any, encoding: string, callback: Function): void; + destroy(error?: Error): void; + } - export class PassThrough extends Transform { } - } + export class PassThrough extends Transform { } + } - export = internal; + export = internal; } declare module "util" { - export interface InspectOptions extends NodeJS.InspectOptions { } - export function format(format: any, ...param: any[]): string; - export function debug(string: string): void; - export function error(...param: any[]): void; - export function puts(...param: any[]): void; - export function print(...param: any[]): void; - export function log(string: string): void; - export function inspect(object: any, showHidden?: boolean, depth?: number | null, color?: boolean): string; - export function inspect(object: any, options: InspectOptions): string; - export function isArray(object: any): object is any[]; - export function isRegExp(object: any): object is RegExp; - export function isDate(object: any): object is Date; - export function isError(object: any): object is Error; - export function inherits(constructor: any, superConstructor: any): void; - export function debuglog(key: string): (msg: string, ...param: any[]) => void; - export function isBoolean(object: any): object is boolean; - export function isBuffer(object: any): object is Buffer; - export function isFunction(object: any): boolean; - export function isNull(object: any): object is null; - export function isNullOrUndefined(object: any): object is null | undefined; - export function isNumber(object: any): object is number; - export function isObject(object: any): boolean; - export function isPrimitive(object: any): boolean; - export function isString(object: any): object is string; - export function isSymbol(object: any): object is symbol; - export function isUndefined(object: any): object is undefined; - export function deprecate(fn: T, message: string): T; + export interface InspectOptions extends NodeJS.InspectOptions { } + export function format(format: any, ...param: any[]): string; + export function debug(string: string): void; + export function error(...param: any[]): void; + export function puts(...param: any[]): void; + export function print(...param: any[]): void; + export function log(string: string): void; + export var inspect: { + (object: any, showHidden?: boolean, depth?: number | null, color?: boolean): string; + (object: any, options: InspectOptions): string; + colors: { + [color: string]: [number, number] | undefined + } + styles: { + [style: string]: string | undefined + } + defaultOptions: InspectOptions; + custom: symbol; + }; + export function isArray(object: any): object is any[]; + export function isRegExp(object: any): object is RegExp; + export function isDate(object: any): object is Date; + export function isError(object: any): object is Error; + export function inherits(constructor: any, superConstructor: any): void; + export function debuglog(key: string): (msg: string, ...param: any[]) => void; + export function isBoolean(object: any): object is boolean; + export function isBuffer(object: any): object is Buffer; + export function isFunction(object: any): boolean; + export function isNull(object: any): object is null; + export function isNullOrUndefined(object: any): object is null | undefined; + export function isNumber(object: any): object is number; + export function isObject(object: any): boolean; + export function isPrimitive(object: any): boolean; + export function isString(object: any): object is string; + export function isSymbol(object: any): object is symbol; + export function isUndefined(object: any): object is undefined; + export function deprecate(fn: T, message: string): T; + + export interface CustomPromisify extends Function { + __promisify__: TCustom; + } + + export function callbackify(fn: () => Promise): (callback: (err: NodeJS.ErrnoException) => void) => void; + export function callbackify(fn: () => Promise): (callback: (err: NodeJS.ErrnoException, result: TResult) => void) => void; + export function callbackify(fn: (arg1: T1) => Promise): (arg1: T1, callback: (err: NodeJS.ErrnoException) => void) => void; + export function callbackify(fn: (arg1: T1) => Promise): (arg1: T1, callback: (err: NodeJS.ErrnoException, result: TResult) => void) => void; + export function callbackify(fn: (arg1: T1, arg2: T2) => Promise): (arg1: T1, arg2: T2, callback: (err: NodeJS.ErrnoException) => void) => void; + export function callbackify(fn: (arg1: T1, arg2: T2) => Promise): (arg1: T1, arg2: T2, callback: (err: NodeJS.ErrnoException, result: TResult) => void) => void; + export function callbackify(fn: (arg1: T1, arg2: T2, arg3: T3) => Promise): (arg1: T1, arg2: T2, arg3: T3, callback: (err: NodeJS.ErrnoException) => void) => void; + export function callbackify(fn: (arg1: T1, arg2: T2, arg3: T3) => Promise): (arg1: T1, arg2: T2, arg3: T3, callback: (err: NodeJS.ErrnoException, result: TResult) => void) => void; + export function callbackify(fn: (arg1: T1, arg2: T2, arg3: T3, arg4: T4) => Promise): (arg1: T1, arg2: T2, arg3: T3, arg4: T4, callback: (err: NodeJS.ErrnoException) => void) => void; + export function callbackify(fn: (arg1: T1, arg2: T2, arg3: T3, arg4: T4) => Promise): (arg1: T1, arg2: T2, arg3: T3, arg4: T4, callback: (err: NodeJS.ErrnoException, result: TResult) => void) => void; + export function callbackify(fn: (arg1: T1, arg2: T2, arg3: T3, arg4: T4, arg5: T5) => Promise): (arg1: T1, arg2: T2, arg3: T3, arg4: T4, arg5: T5, callback: (err: NodeJS.ErrnoException) => void) => void; + export function callbackify(fn: (arg1: T1, arg2: T2, arg3: T3, arg4: T4, arg5: T5) => Promise): (arg1: T1, arg2: T2, arg3: T3, arg4: T4, arg5: T5, callback: (err: NodeJS.ErrnoException, result: TResult) => void) => void; + export function callbackify(fn: (arg1: T1, arg2: T2, arg3: T3, arg4: T4, arg5: T5, arg6: T6) => Promise): (arg1: T1, arg2: T2, arg3: T3, arg4: T4, arg5: T5, arg6: T6, callback: (err: NodeJS.ErrnoException) => void) => void; + export function callbackify(fn: (arg1: T1, arg2: T2, arg3: T3, arg4: T4, arg5: T5, arg6: T6) => Promise): (arg1: T1, arg2: T2, arg3: T3, arg4: T4, arg5: T5, arg6: T6, callback: (err: NodeJS.ErrnoException, result: TResult) => void) => void; + + export function promisify(fn: CustomPromisify): TCustom; + export function promisify(fn: (callback: (err: Error | null, result: TResult) => void) => void): () => Promise; + export function promisify(fn: (callback: (err: Error | null) => void) => void): () => Promise; + export function promisify(fn: (arg1: T1, callback: (err: Error | null, result: TResult) => void) => void): (arg1: T1) => Promise; + export function promisify(fn: (arg1: T1, callback: (err: Error | null) => void) => void): (arg1: T1) => Promise; + export function promisify(fn: (arg1: T1, arg2: T2, callback: (err: Error | null, result: TResult) => void) => void): (arg1: T1, arg2: T2) => Promise; + export function promisify(fn: (arg1: T1, arg2: T2, callback: (err: Error | null) => void) => void): (arg1: T1, arg2: T2) => Promise; + export function promisify(fn: (arg1: T1, arg2: T2, arg3: T3, callback: (err: Error | null, result: TResult) => void) => void): (arg1: T1, arg2: T2, arg3: T3) => Promise; + export function promisify(fn: (arg1: T1, arg2: T2, arg3: T3, callback: (err: Error | null) => void) => void): (arg1: T1, arg2: T2, arg3: T3) => Promise; + export function promisify(fn: (arg1: T1, arg2: T2, arg3: T3, arg4: T4, callback: (err: Error | null, result: TResult) => void) => void): (arg1: T1, arg2: T2, arg3: T3, arg4: T4) => Promise; + export function promisify(fn: (arg1: T1, arg2: T2, arg3: T3, arg4: T4, callback: (err: Error | null) => void) => void): (arg1: T1, arg2: T2, arg3: T3, arg4: T4) => Promise; + export function promisify(fn: (arg1: T1, arg2: T2, arg3: T3, arg4: T4, arg5: T5, callback: (err: Error | null, result: TResult) => void) => void): (arg1: T1, arg2: T2, arg3: T3, arg4: T4, arg5: T5) => Promise; + export function promisify(fn: (arg1: T1, arg2: T2, arg3: T3, arg4: T4, arg5: T5, callback: (err: Error | null) => void) => void): (arg1: T1, arg2: T2, arg3: T3, arg4: T4, arg5: T5) => Promise; + export function promisify(fn: Function): Function; + export namespace promisify { + const custom: symbol; + } + + export class TextDecoder { + readonly encoding: string; + readonly fatal: boolean; + readonly ignoreBOM: boolean; + constructor( + encoding?: string, + options?: { fatal?: boolean; ignoreBOM?: boolean } + ); + decode( + input?: + Int8Array + | Int16Array + | Int32Array + | Uint8Array + | Uint16Array + | Uint32Array + | Uint8ClampedArray + | Float32Array + | Float64Array + | DataView + | ArrayBuffer + | null, + options?: { stream?: boolean } + ): string; + } + + export class TextEncoder { + readonly encoding: string; + constructor(); + encode(input?: string): Uint8Array; + } } declare module "assert" { - function internal(value: any, message?: string): void; - namespace internal { - export class AssertionError implements Error { - name: string; - message: string; - actual: any; - expected: any; - operator: string; - generatedMessage: boolean; + function internal(value: any, message?: string): void; + namespace internal { + export class AssertionError implements Error { + name: string; + message: string; + actual: any; + expected: any; + operator: string; + generatedMessage: boolean; - constructor(options?: { - message?: string; actual?: any; expected?: any; - operator?: string; stackStartFunction?: Function - }); - } + constructor(options?: { + message?: string; actual?: any; expected?: any; + operator?: string; stackStartFunction?: Function + }); + } - export function fail(actual?: any, expected?: any, message?: string, operator?: string): void; - export function ok(value: any, message?: string): void; - export function equal(actual: any, expected: any, message?: string): void; - export function notEqual(actual: any, expected: any, message?: string): void; - export function deepEqual(actual: any, expected: any, message?: string): void; - export function notDeepEqual(acutal: any, expected: any, message?: string): void; - export function strictEqual(actual: any, expected: any, message?: string): void; - export function notStrictEqual(actual: any, expected: any, message?: string): void; - export function deepStrictEqual(actual: any, expected: any, message?: string): void; - export function notDeepStrictEqual(actual: any, expected: any, message?: string): void; + export function fail(message: string): never; + export function fail(actual: any, expected: any, message?: string, operator?: string): never; + export function ok(value: any, message?: string): void; + export function equal(actual: any, expected: any, message?: string): void; + export function notEqual(actual: any, expected: any, message?: string): void; + export function deepEqual(actual: any, expected: any, message?: string): void; + export function notDeepEqual(acutal: any, expected: any, message?: string): void; + export function strictEqual(actual: any, expected: any, message?: string): void; + export function notStrictEqual(actual: any, expected: any, message?: string): void; + export function deepStrictEqual(actual: any, expected: any, message?: string): void; + export function notDeepStrictEqual(actual: any, expected: any, message?: string): void; - export function throws(block: Function, message?: string): void; - export function throws(block: Function, error: Function, message?: string): void; - export function throws(block: Function, error: RegExp, message?: string): void; - export function throws(block: Function, error: (err: any) => boolean, message?: string): void; + export function throws(block: Function, message?: string): void; + export function throws(block: Function, error: Function, message?: string): void; + export function throws(block: Function, error: RegExp, message?: string): void; + export function throws(block: Function, error: (err: any) => boolean, message?: string): void; - export function doesNotThrow(block: Function, message?: string): void; - export function doesNotThrow(block: Function, error: Function, message?: string): void; - export function doesNotThrow(block: Function, error: RegExp, message?: string): void; - export function doesNotThrow(block: Function, error: (err: any) => boolean, message?: string): void; + export function doesNotThrow(block: Function, message?: string): void; + export function doesNotThrow(block: Function, error: Function, message?: string): void; + export function doesNotThrow(block: Function, error: RegExp, message?: string): void; + export function doesNotThrow(block: Function, error: (err: any) => boolean, message?: string): void; - export function ifError(value: any): void; - } + export function ifError(value: any): void; + } - export = internal; + export = internal; } declare module "tty" { - import * as net from "net"; + import * as net from "net"; - export function isatty(fd: number): boolean; - export interface ReadStream extends net.Socket { - isRaw: boolean; - setRawMode(mode: boolean): void; - isTTY: boolean; - } - export interface WriteStream extends net.Socket { - columns: number; - rows: number; - isTTY: boolean; - } + export function isatty(fd: number): boolean; + export class ReadStream extends net.Socket { + isRaw: boolean; + setRawMode(mode: boolean): void; + isTTY: boolean; + } + export class WriteStream extends net.Socket { + columns: number; + rows: number; + isTTY: boolean; + } } declare module "domain" { - import * as events from "events"; + import * as events from "events"; - export class Domain extends events.EventEmitter implements NodeJS.Domain { - run(fn: Function): void; - add(emitter: events.EventEmitter): void; - remove(emitter: events.EventEmitter): void; - bind(cb: (err: Error, data: any) => any): any; - intercept(cb: (data: any) => any): any; - dispose(): void; - members: any[]; - enter(): void; - exit(): void; - } + export class Domain extends events.EventEmitter implements NodeJS.Domain { + run(fn: Function): void; + add(emitter: events.EventEmitter): void; + remove(emitter: events.EventEmitter): void; + bind(cb: (err: Error, data: any) => any): any; + intercept(cb: (data: any) => any): any; + dispose(): void; + members: any[]; + enter(): void; + exit(): void; + } - export function create(): Domain; + export function create(): Domain; } declare module "constants" { - export var E2BIG: number; - export var EACCES: number; - export var EADDRINUSE: number; - export var EADDRNOTAVAIL: number; - export var EAFNOSUPPORT: number; - export var EAGAIN: number; - export var EALREADY: number; - export var EBADF: number; - export var EBADMSG: number; - export var EBUSY: number; - export var ECANCELED: number; - export var ECHILD: number; - export var ECONNABORTED: number; - export var ECONNREFUSED: number; - export var ECONNRESET: number; - export var EDEADLK: number; - export var EDESTADDRREQ: number; - export var EDOM: number; - export var EEXIST: number; - export var EFAULT: number; - export var EFBIG: number; - export var EHOSTUNREACH: number; - export var EIDRM: number; - export var EILSEQ: number; - export var EINPROGRESS: number; - export var EINTR: number; - export var EINVAL: number; - export var EIO: number; - export var EISCONN: number; - export var EISDIR: number; - export var ELOOP: number; - export var EMFILE: number; - export var EMLINK: number; - export var EMSGSIZE: number; - export var ENAMETOOLONG: number; - export var ENETDOWN: number; - export var ENETRESET: number; - export var ENETUNREACH: number; - export var ENFILE: number; - export var ENOBUFS: number; - export var ENODATA: number; - export var ENODEV: number; - export var ENOENT: number; - export var ENOEXEC: number; - export var ENOLCK: number; - export var ENOLINK: number; - export var ENOMEM: number; - export var ENOMSG: number; - export var ENOPROTOOPT: number; - export var ENOSPC: number; - export var ENOSR: number; - export var ENOSTR: number; - export var ENOSYS: number; - export var ENOTCONN: number; - export var ENOTDIR: number; - export var ENOTEMPTY: number; - export var ENOTSOCK: number; - export var ENOTSUP: number; - export var ENOTTY: number; - export var ENXIO: number; - export var EOPNOTSUPP: number; - export var EOVERFLOW: number; - export var EPERM: number; - export var EPIPE: number; - export var EPROTO: number; - export var EPROTONOSUPPORT: number; - export var EPROTOTYPE: number; - export var ERANGE: number; - export var EROFS: number; - export var ESPIPE: number; - export var ESRCH: number; - export var ETIME: number; - export var ETIMEDOUT: number; - export var ETXTBSY: number; - export var EWOULDBLOCK: number; - export var EXDEV: number; - export var WSAEINTR: number; - export var WSAEBADF: number; - export var WSAEACCES: number; - export var WSAEFAULT: number; - export var WSAEINVAL: number; - export var WSAEMFILE: number; - export var WSAEWOULDBLOCK: number; - export var WSAEINPROGRESS: number; - export var WSAEALREADY: number; - export var WSAENOTSOCK: number; - export var WSAEDESTADDRREQ: number; - export var WSAEMSGSIZE: number; - export var WSAEPROTOTYPE: number; - export var WSAENOPROTOOPT: number; - export var WSAEPROTONOSUPPORT: number; - export var WSAESOCKTNOSUPPORT: number; - export var WSAEOPNOTSUPP: number; - export var WSAEPFNOSUPPORT: number; - export var WSAEAFNOSUPPORT: number; - export var WSAEADDRINUSE: number; - export var WSAEADDRNOTAVAIL: number; - export var WSAENETDOWN: number; - export var WSAENETUNREACH: number; - export var WSAENETRESET: number; - export var WSAECONNABORTED: number; - export var WSAECONNRESET: number; - export var WSAENOBUFS: number; - export var WSAEISCONN: number; - export var WSAENOTCONN: number; - export var WSAESHUTDOWN: number; - export var WSAETOOMANYREFS: number; - export var WSAETIMEDOUT: number; - export var WSAECONNREFUSED: number; - export var WSAELOOP: number; - export var WSAENAMETOOLONG: number; - export var WSAEHOSTDOWN: number; - export var WSAEHOSTUNREACH: number; - export var WSAENOTEMPTY: number; - export var WSAEPROCLIM: number; - export var WSAEUSERS: number; - export var WSAEDQUOT: number; - export var WSAESTALE: number; - export var WSAEREMOTE: number; - export var WSASYSNOTREADY: number; - export var WSAVERNOTSUPPORTED: number; - export var WSANOTINITIALISED: number; - export var WSAEDISCON: number; - export var WSAENOMORE: number; - export var WSAECANCELLED: number; - export var WSAEINVALIDPROCTABLE: number; - export var WSAEINVALIDPROVIDER: number; - export var WSAEPROVIDERFAILEDINIT: number; - export var WSASYSCALLFAILURE: number; - export var WSASERVICE_NOT_FOUND: number; - export var WSATYPE_NOT_FOUND: number; - export var WSA_E_NO_MORE: number; - export var WSA_E_CANCELLED: number; - export var WSAEREFUSED: number; - export var SIGHUP: number; - export var SIGINT: number; - export var SIGILL: number; - export var SIGABRT: number; - export var SIGFPE: number; - export var SIGKILL: number; - export var SIGSEGV: number; - export var SIGTERM: number; - export var SIGBREAK: number; - export var SIGWINCH: number; - export var SSL_OP_ALL: number; - export var SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION: number; - export var SSL_OP_CIPHER_SERVER_PREFERENCE: number; - export var SSL_OP_CISCO_ANYCONNECT: number; - export var SSL_OP_COOKIE_EXCHANGE: number; - export var SSL_OP_CRYPTOPRO_TLSEXT_BUG: number; - export var SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS: number; - export var SSL_OP_EPHEMERAL_RSA: number; - export var SSL_OP_LEGACY_SERVER_CONNECT: number; - export var SSL_OP_MICROSOFT_BIG_SSLV3_BUFFER: number; - export var SSL_OP_MICROSOFT_SESS_ID_BUG: number; - export var SSL_OP_MSIE_SSLV2_RSA_PADDING: number; - export var SSL_OP_NETSCAPE_CA_DN_BUG: number; - export var SSL_OP_NETSCAPE_CHALLENGE_BUG: number; - export var SSL_OP_NETSCAPE_DEMO_CIPHER_CHANGE_BUG: number; - export var SSL_OP_NETSCAPE_REUSE_CIPHER_CHANGE_BUG: number; - export var SSL_OP_NO_COMPRESSION: number; - export var SSL_OP_NO_QUERY_MTU: number; - export var SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION: number; - export var SSL_OP_NO_SSLv2: number; - export var SSL_OP_NO_SSLv3: number; - export var SSL_OP_NO_TICKET: number; - export var SSL_OP_NO_TLSv1: number; - export var SSL_OP_NO_TLSv1_1: number; - export var SSL_OP_NO_TLSv1_2: number; - export var SSL_OP_PKCS1_CHECK_1: number; - export var SSL_OP_PKCS1_CHECK_2: number; - export var SSL_OP_SINGLE_DH_USE: number; - export var SSL_OP_SINGLE_ECDH_USE: number; - export var SSL_OP_SSLEAY_080_CLIENT_DH_BUG: number; - export var SSL_OP_SSLREF2_REUSE_CERT_TYPE_BUG: number; - export var SSL_OP_TLS_BLOCK_PADDING_BUG: number; - export var SSL_OP_TLS_D5_BUG: number; - export var SSL_OP_TLS_ROLLBACK_BUG: number; - export var ENGINE_METHOD_DSA: number; - export var ENGINE_METHOD_DH: number; - export var ENGINE_METHOD_RAND: number; - export var ENGINE_METHOD_ECDH: number; - export var ENGINE_METHOD_ECDSA: number; - export var ENGINE_METHOD_CIPHERS: number; - export var ENGINE_METHOD_DIGESTS: number; - export var ENGINE_METHOD_STORE: number; - export var ENGINE_METHOD_PKEY_METHS: number; - export var ENGINE_METHOD_PKEY_ASN1_METHS: number; - export var ENGINE_METHOD_ALL: number; - export var ENGINE_METHOD_NONE: number; - export var DH_CHECK_P_NOT_SAFE_PRIME: number; - export var DH_CHECK_P_NOT_PRIME: number; - export var DH_UNABLE_TO_CHECK_GENERATOR: number; - export var DH_NOT_SUITABLE_GENERATOR: number; - export var NPN_ENABLED: number; - export var RSA_PKCS1_PADDING: number; - export var RSA_SSLV23_PADDING: number; - export var RSA_NO_PADDING: number; - export var RSA_PKCS1_OAEP_PADDING: number; - export var RSA_X931_PADDING: number; - export var RSA_PKCS1_PSS_PADDING: number; - export var POINT_CONVERSION_COMPRESSED: number; - export var POINT_CONVERSION_UNCOMPRESSED: number; - export var POINT_CONVERSION_HYBRID: number; - export var O_RDONLY: number; - export var O_WRONLY: number; - export var O_RDWR: number; - export var S_IFMT: number; - export var S_IFREG: number; - export var S_IFDIR: number; - export var S_IFCHR: number; - export var S_IFBLK: number; - export var S_IFIFO: number; - export var S_IFSOCK: number; - export var S_IRWXU: number; - export var S_IRUSR: number; - export var S_IWUSR: number; - export var S_IXUSR: number; - export var S_IRWXG: number; - export var S_IRGRP: number; - export var S_IWGRP: number; - export var S_IXGRP: number; - export var S_IRWXO: number; - export var S_IROTH: number; - export var S_IWOTH: number; - export var S_IXOTH: number; - export var S_IFLNK: number; - export var O_CREAT: number; - export var O_EXCL: number; - export var O_NOCTTY: number; - export var O_DIRECTORY: number; - export var O_NOATIME: number; - export var O_NOFOLLOW: number; - export var O_SYNC: number; - export var O_SYMLINK: number; - export var O_DIRECT: number; - export var O_NONBLOCK: number; - export var O_TRUNC: number; - export var O_APPEND: number; - export var F_OK: number; - export var R_OK: number; - export var W_OK: number; - export var X_OK: number; - export var UV_UDP_REUSEADDR: number; - export var SIGQUIT: number; - export var SIGTRAP: number; - export var SIGIOT: number; - export var SIGBUS: number; - export var SIGUSR1: number; - export var SIGUSR2: number; - export var SIGPIPE: number; - export var SIGALRM: number; - export var SIGCHLD: number; - export var SIGSTKFLT: number; - export var SIGCONT: number; - export var SIGSTOP: number; - export var SIGTSTP: number; - export var SIGTTIN: number; - export var SIGTTOU: number; - export var SIGURG: number; - export var SIGXCPU: number; - export var SIGXFSZ: number; - export var SIGVTALRM: number; - export var SIGPROF: number; - export var SIGIO: number; - export var SIGPOLL: number; - export var SIGPWR: number; - export var SIGSYS: number; - export var SIGUNUSED: number; - export var defaultCoreCipherList: string; - export var defaultCipherList: string; - export var ENGINE_METHOD_RSA: number; - export var ALPN_ENABLED: number; + export var E2BIG: number; + export var EACCES: number; + export var EADDRINUSE: number; + export var EADDRNOTAVAIL: number; + export var EAFNOSUPPORT: number; + export var EAGAIN: number; + export var EALREADY: number; + export var EBADF: number; + export var EBADMSG: number; + export var EBUSY: number; + export var ECANCELED: number; + export var ECHILD: number; + export var ECONNABORTED: number; + export var ECONNREFUSED: number; + export var ECONNRESET: number; + export var EDEADLK: number; + export var EDESTADDRREQ: number; + export var EDOM: number; + export var EEXIST: number; + export var EFAULT: number; + export var EFBIG: number; + export var EHOSTUNREACH: number; + export var EIDRM: number; + export var EILSEQ: number; + export var EINPROGRESS: number; + export var EINTR: number; + export var EINVAL: number; + export var EIO: number; + export var EISCONN: number; + export var EISDIR: number; + export var ELOOP: number; + export var EMFILE: number; + export var EMLINK: number; + export var EMSGSIZE: number; + export var ENAMETOOLONG: number; + export var ENETDOWN: number; + export var ENETRESET: number; + export var ENETUNREACH: number; + export var ENFILE: number; + export var ENOBUFS: number; + export var ENODATA: number; + export var ENODEV: number; + export var ENOENT: number; + export var ENOEXEC: number; + export var ENOLCK: number; + export var ENOLINK: number; + export var ENOMEM: number; + export var ENOMSG: number; + export var ENOPROTOOPT: number; + export var ENOSPC: number; + export var ENOSR: number; + export var ENOSTR: number; + export var ENOSYS: number; + export var ENOTCONN: number; + export var ENOTDIR: number; + export var ENOTEMPTY: number; + export var ENOTSOCK: number; + export var ENOTSUP: number; + export var ENOTTY: number; + export var ENXIO: number; + export var EOPNOTSUPP: number; + export var EOVERFLOW: number; + export var EPERM: number; + export var EPIPE: number; + export var EPROTO: number; + export var EPROTONOSUPPORT: number; + export var EPROTOTYPE: number; + export var ERANGE: number; + export var EROFS: number; + export var ESPIPE: number; + export var ESRCH: number; + export var ETIME: number; + export var ETIMEDOUT: number; + export var ETXTBSY: number; + export var EWOULDBLOCK: number; + export var EXDEV: number; + export var WSAEINTR: number; + export var WSAEBADF: number; + export var WSAEACCES: number; + export var WSAEFAULT: number; + export var WSAEINVAL: number; + export var WSAEMFILE: number; + export var WSAEWOULDBLOCK: number; + export var WSAEINPROGRESS: number; + export var WSAEALREADY: number; + export var WSAENOTSOCK: number; + export var WSAEDESTADDRREQ: number; + export var WSAEMSGSIZE: number; + export var WSAEPROTOTYPE: number; + export var WSAENOPROTOOPT: number; + export var WSAEPROTONOSUPPORT: number; + export var WSAESOCKTNOSUPPORT: number; + export var WSAEOPNOTSUPP: number; + export var WSAEPFNOSUPPORT: number; + export var WSAEAFNOSUPPORT: number; + export var WSAEADDRINUSE: number; + export var WSAEADDRNOTAVAIL: number; + export var WSAENETDOWN: number; + export var WSAENETUNREACH: number; + export var WSAENETRESET: number; + export var WSAECONNABORTED: number; + export var WSAECONNRESET: number; + export var WSAENOBUFS: number; + export var WSAEISCONN: number; + export var WSAENOTCONN: number; + export var WSAESHUTDOWN: number; + export var WSAETOOMANYREFS: number; + export var WSAETIMEDOUT: number; + export var WSAECONNREFUSED: number; + export var WSAELOOP: number; + export var WSAENAMETOOLONG: number; + export var WSAEHOSTDOWN: number; + export var WSAEHOSTUNREACH: number; + export var WSAENOTEMPTY: number; + export var WSAEPROCLIM: number; + export var WSAEUSERS: number; + export var WSAEDQUOT: number; + export var WSAESTALE: number; + export var WSAEREMOTE: number; + export var WSASYSNOTREADY: number; + export var WSAVERNOTSUPPORTED: number; + export var WSANOTINITIALISED: number; + export var WSAEDISCON: number; + export var WSAENOMORE: number; + export var WSAECANCELLED: number; + export var WSAEINVALIDPROCTABLE: number; + export var WSAEINVALIDPROVIDER: number; + export var WSAEPROVIDERFAILEDINIT: number; + export var WSASYSCALLFAILURE: number; + export var WSASERVICE_NOT_FOUND: number; + export var WSATYPE_NOT_FOUND: number; + export var WSA_E_NO_MORE: number; + export var WSA_E_CANCELLED: number; + export var WSAEREFUSED: number; + export var SIGHUP: number; + export var SIGINT: number; + export var SIGILL: number; + export var SIGABRT: number; + export var SIGFPE: number; + export var SIGKILL: number; + export var SIGSEGV: number; + export var SIGTERM: number; + export var SIGBREAK: number; + export var SIGWINCH: number; + export var SSL_OP_ALL: number; + export var SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION: number; + export var SSL_OP_CIPHER_SERVER_PREFERENCE: number; + export var SSL_OP_CISCO_ANYCONNECT: number; + export var SSL_OP_COOKIE_EXCHANGE: number; + export var SSL_OP_CRYPTOPRO_TLSEXT_BUG: number; + export var SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS: number; + export var SSL_OP_EPHEMERAL_RSA: number; + export var SSL_OP_LEGACY_SERVER_CONNECT: number; + export var SSL_OP_MICROSOFT_BIG_SSLV3_BUFFER: number; + export var SSL_OP_MICROSOFT_SESS_ID_BUG: number; + export var SSL_OP_MSIE_SSLV2_RSA_PADDING: number; + export var SSL_OP_NETSCAPE_CA_DN_BUG: number; + export var SSL_OP_NETSCAPE_CHALLENGE_BUG: number; + export var SSL_OP_NETSCAPE_DEMO_CIPHER_CHANGE_BUG: number; + export var SSL_OP_NETSCAPE_REUSE_CIPHER_CHANGE_BUG: number; + export var SSL_OP_NO_COMPRESSION: number; + export var SSL_OP_NO_QUERY_MTU: number; + export var SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION: number; + export var SSL_OP_NO_SSLv2: number; + export var SSL_OP_NO_SSLv3: number; + export var SSL_OP_NO_TICKET: number; + export var SSL_OP_NO_TLSv1: number; + export var SSL_OP_NO_TLSv1_1: number; + export var SSL_OP_NO_TLSv1_2: number; + export var SSL_OP_PKCS1_CHECK_1: number; + export var SSL_OP_PKCS1_CHECK_2: number; + export var SSL_OP_SINGLE_DH_USE: number; + export var SSL_OP_SINGLE_ECDH_USE: number; + export var SSL_OP_SSLEAY_080_CLIENT_DH_BUG: number; + export var SSL_OP_SSLREF2_REUSE_CERT_TYPE_BUG: number; + export var SSL_OP_TLS_BLOCK_PADDING_BUG: number; + export var SSL_OP_TLS_D5_BUG: number; + export var SSL_OP_TLS_ROLLBACK_BUG: number; + export var ENGINE_METHOD_DSA: number; + export var ENGINE_METHOD_DH: number; + export var ENGINE_METHOD_RAND: number; + export var ENGINE_METHOD_ECDH: number; + export var ENGINE_METHOD_ECDSA: number; + export var ENGINE_METHOD_CIPHERS: number; + export var ENGINE_METHOD_DIGESTS: number; + export var ENGINE_METHOD_STORE: number; + export var ENGINE_METHOD_PKEY_METHS: number; + export var ENGINE_METHOD_PKEY_ASN1_METHS: number; + export var ENGINE_METHOD_ALL: number; + export var ENGINE_METHOD_NONE: number; + export var DH_CHECK_P_NOT_SAFE_PRIME: number; + export var DH_CHECK_P_NOT_PRIME: number; + export var DH_UNABLE_TO_CHECK_GENERATOR: number; + export var DH_NOT_SUITABLE_GENERATOR: number; + export var NPN_ENABLED: number; + export var RSA_PKCS1_PADDING: number; + export var RSA_SSLV23_PADDING: number; + export var RSA_NO_PADDING: number; + export var RSA_PKCS1_OAEP_PADDING: number; + export var RSA_X931_PADDING: number; + export var RSA_PKCS1_PSS_PADDING: number; + export var POINT_CONVERSION_COMPRESSED: number; + export var POINT_CONVERSION_UNCOMPRESSED: number; + export var POINT_CONVERSION_HYBRID: number; + export var O_RDONLY: number; + export var O_WRONLY: number; + export var O_RDWR: number; + export var S_IFMT: number; + export var S_IFREG: number; + export var S_IFDIR: number; + export var S_IFCHR: number; + export var S_IFBLK: number; + export var S_IFIFO: number; + export var S_IFSOCK: number; + export var S_IRWXU: number; + export var S_IRUSR: number; + export var S_IWUSR: number; + export var S_IXUSR: number; + export var S_IRWXG: number; + export var S_IRGRP: number; + export var S_IWGRP: number; + export var S_IXGRP: number; + export var S_IRWXO: number; + export var S_IROTH: number; + export var S_IWOTH: number; + export var S_IXOTH: number; + export var S_IFLNK: number; + export var O_CREAT: number; + export var O_EXCL: number; + export var O_NOCTTY: number; + export var O_DIRECTORY: number; + export var O_NOATIME: number; + export var O_NOFOLLOW: number; + export var O_SYNC: number; + export var O_DSYNC: number; + export var O_SYMLINK: number; + export var O_DIRECT: number; + export var O_NONBLOCK: number; + export var O_TRUNC: number; + export var O_APPEND: number; + export var F_OK: number; + export var R_OK: number; + export var W_OK: number; + export var X_OK: number; + export var UV_UDP_REUSEADDR: number; + export var SIGQUIT: number; + export var SIGTRAP: number; + export var SIGIOT: number; + export var SIGBUS: number; + export var SIGUSR1: number; + export var SIGUSR2: number; + export var SIGPIPE: number; + export var SIGALRM: number; + export var SIGCHLD: number; + export var SIGSTKFLT: number; + export var SIGCONT: number; + export var SIGSTOP: number; + export var SIGTSTP: number; + export var SIGTTIN: number; + export var SIGTTOU: number; + export var SIGURG: number; + export var SIGXCPU: number; + export var SIGXFSZ: number; + export var SIGVTALRM: number; + export var SIGPROF: number; + export var SIGIO: number; + export var SIGPOLL: number; + export var SIGPWR: number; + export var SIGSYS: number; + export var SIGUNUSED: number; + export var defaultCoreCipherList: string; + export var defaultCipherList: string; + export var ENGINE_METHOD_RSA: number; + export var ALPN_ENABLED: number; +} + +declare module "module" { + export = NodeJS.Module; } declare module "process" { - export = process; + export = process; } +// tslint:disable-next-line:no-declare-current-package declare module "v8" { - interface HeapSpaceInfo { - space_name: string; - space_size: number; - space_used_size: number; - space_available_size: number; - physical_space_size: number; - } + interface HeapSpaceInfo { + space_name: string; + space_size: number; + space_used_size: number; + space_available_size: number; + physical_space_size: number; + } - //** Signifies if the --zap_code_space option is enabled or not. 1 == enabled, 0 == disabled. */ - type DoesZapCodeSpaceFlag = 0 | 1; + // ** Signifies if the --zap_code_space option is enabled or not. 1 == enabled, 0 == disabled. */ + type DoesZapCodeSpaceFlag = 0 | 1; - interface HeapInfo { - total_heap_size: number; - total_heap_size_executable: number; - total_physical_size: number; - total_available_size: number; - used_heap_size: number; - heap_size_limit: number; - malloced_memory: number; - peak_malloced_memory: number; - does_zap_garbage: DoesZapCodeSpaceFlag; - } + interface HeapInfo { + total_heap_size: number; + total_heap_size_executable: number; + total_physical_size: number; + total_available_size: number; + used_heap_size: number; + heap_size_limit: number; + malloced_memory: number; + peak_malloced_memory: number; + does_zap_garbage: DoesZapCodeSpaceFlag; + } - export function getHeapStatistics(): HeapInfo; - export function getHeapSpaceStatistics(): HeapSpaceInfo[]; - export function setFlagsFromString(flags: string): void; + export function getHeapStatistics(): HeapInfo; + export function getHeapSpaceStatistics(): HeapSpaceInfo[]; + export function setFlagsFromString(flags: string): void; } declare module "timers" { - export function setTimeout(callback: (...args: any[]) => void, ms: number, ...args: any[]): NodeJS.Timer; - export function clearTimeout(timeoutId: NodeJS.Timer): void; - export function setInterval(callback: (...args: any[]) => void, ms: number, ...args: any[]): NodeJS.Timer; - export function clearInterval(intervalId: NodeJS.Timer): void; - export function setImmediate(callback: (...args: any[]) => void, ...args: any[]): any; - export function clearImmediate(immediateId: any): void; + export function setTimeout(callback: (...args: any[]) => void, ms: number, ...args: any[]): NodeJS.Timer; + export namespace setTimeout { + export function __promisify__(ms: number): Promise; + export function __promisify__(ms: number, value: T): Promise; + } + export function clearTimeout(timeoutId: NodeJS.Timer): void; + export function setInterval(callback: (...args: any[]) => void, ms: number, ...args: any[]): NodeJS.Timer; + export function clearInterval(intervalId: NodeJS.Timer): void; + export function setImmediate(callback: (...args: any[]) => void, ...args: any[]): any; + export namespace setImmediate { + export function __promisify__(): Promise; + export function __promisify__(value: T): Promise; + } + export function clearImmediate(immediateId: any): void; } declare module "console" { - export = console; + export = console; } /** - * _debugger module is not documented. - * Source code is at https://github.com/nodejs/node/blob/master/lib/_debugger.js + * Async Hooks module: https://nodejs.org/api/async_hooks.html */ -declare module "_debugger" { - export interface Packet { - raw: string; - headers: string[]; - body: Message; - } +declare module "async_hooks" { + /** + * Returns the asyncId of the current execution context. + */ + export function executionAsyncId(): number; + /// @deprecated - replaced by executionAsyncId() + export function currentId(): number; - export interface Message { - seq: number; - type: string; - } + /** + * Returns the ID of the resource responsible for calling the callback that is currently being executed. + */ + export function triggerAsyncId(): number; + /// @deprecated - replaced by triggerAsyncId() + export function triggerId(): number; - export interface RequestInfo { - command: string; - arguments: any; - } + export interface HookCallbacks { + /** + * Called when a class is constructed that has the possibility to emit an asynchronous event. + * @param asyncId a unique ID for the async resource + * @param type the type of the async resource + * @param triggerAsyncId the unique ID of the async resource in whose execution context this async resource was created + * @param resource reference to the resource representing the async operation, needs to be released during destroy + */ + init?(asyncId: number, type: string, triggerAsyncId: number, resource: Object): void; - export interface Request extends Message, RequestInfo { - } + /** + * When an asynchronous operation is initiated or completes a callback is called to notify the user. + * The before callback is called just before said callback is executed. + * @param asyncId the unique identifier assigned to the resource about to execute the callback. + */ + before?(asyncId: number): void; - export interface Event extends Message { - event: string; - body?: any; - } + /** + * Called immediately after the callback specified in before is completed. + * @param asyncId the unique identifier assigned to the resource which has executed the callback. + */ + after?(asyncId: number): void; - export interface Response extends Message { - request_seq: number; - success: boolean; - /** Contains error message if success === false. */ - message?: string; - /** Contains message body if success === true. */ - body?: any; - } + /** + * Called when a promise has resolve() called. This may not be in the same execution id + * as the promise itself. + * @param asyncId the unique id for the promise that was resolve()d. + */ + promiseResolve?(asyncId: number): void; - export interface BreakpointMessageBody { - type: string; - target: number; - line: number; - } + /** + * Called after the resource corresponding to asyncId is destroyed + * @param asyncId a unique ID for the async resource + */ + destroy?(asyncId: number): void; + } - export class Protocol { - res: Packet; - state: string; - execute(data: string): void; - serialize(rq: Request): string; - onResponse: (pkt: Packet) => void; - } + export interface AsyncHook { + /** + * Enable the callbacks for a given AsyncHook instance. If no callbacks are provided enabling is a noop. + */ + enable(): this; - export var NO_FRAME: number; - export var port: number; + /** + * Disable the callbacks for a given AsyncHook instance from the global pool of AsyncHook callbacks to be executed. Once a hook has been disabled it will not be called again until enabled. + */ + disable(): this; + } - export interface ScriptDesc { - name: string; - id: number; - isNative?: boolean; - handle?: number; - type: string; - lineOffset?: number; - columnOffset?: number; - lineCount?: number; - } + /** + * Registers functions to be called for different lifetime events of each async operation. + * @param options the callbacks to register + * @return an AsyncHooks instance used for disabling and enabling hooks + */ + export function createHook(options: HookCallbacks): AsyncHook; - export interface Breakpoint { - id: number; - scriptId: number; - script: ScriptDesc; - line: number; - condition?: string; - scriptReq?: string; - } + export interface AsyncResourceOptions { + /** + * The ID of the execution context that created this async event. + * Default: `executionAsyncId()` + */ + triggerAsyncId?: number; - export interface RequestHandler { - (err: boolean, body: Message, res: Packet): void; - request_seq?: number; - } + /** + * Disables automatic `emitDestroy` when the object is garbage collected. + * This usually does not need to be set (even if `emitDestroy` is called + * manually), unless the resource's `asyncId` is retrieved and the + * sensitive API's `emitDestroy` is called with it. + * Default: `false` + */ + requireManualDestroy?: boolean; + } - export interface ResponseBodyHandler { - (err: boolean, body?: any): void; - request_seq?: number; - } + /** + * The class AsyncResource was designed to be extended by the embedder's async resources. + * Using this users can easily trigger the lifetime events of their own resources. + */ + export class AsyncResource { + /** + * AsyncResource() is meant to be extended. Instantiating a + * new AsyncResource() also triggers init. If triggerAsyncId is omitted then + * async_hook.executionAsyncId() is used. + * @param type The type of async event. + * @param triggerAsyncId The ID of the execution context that created + * this async event (default: `executionAsyncId()`), or an + * AsyncResourceOptions object (since 8.10) + */ + constructor(type: string, triggerAsyncId?: number | AsyncResourceOptions); - export interface ExceptionInfo { - text: string; - } + /** + * Call AsyncHooks before callbacks. + */ + emitBefore(): void; - export interface BreakResponse { - script?: ScriptDesc; - exception?: ExceptionInfo; - sourceLine: number; - sourceLineText: string; - sourceColumn: number; - } + /** + * Call AsyncHooks after callbacks + */ + emitAfter(): void; - export function SourceInfo(body: BreakResponse): string; + /** + * Call AsyncHooks destroy callbacks. + */ + emitDestroy(): void; - export interface ClientInstance extends NodeJS.EventEmitter { - protocol: Protocol; - scripts: ScriptDesc[]; - handles: ScriptDesc[]; - breakpoints: Breakpoint[]; - currentSourceLine: number; - currentSourceColumn: number; - currentSourceLineText: string; - currentFrame: number; - currentScript: string; + /** + * @return the unique ID assigned to this AsyncResource instance. + */ + asyncId(): number; - connect(port: number, host: string): void; - req(req: any, cb: RequestHandler): void; - reqFrameEval(code: string, frame: number, cb: RequestHandler): void; - mirrorObject(obj: any, depth: number, cb: ResponseBodyHandler): void; - setBreakpoint(rq: BreakpointMessageBody, cb: RequestHandler): void; - clearBreakpoint(rq: Request, cb: RequestHandler): void; - listbreakpoints(cb: RequestHandler): void; - reqSource(from: number, to: number, cb: RequestHandler): void; - reqScripts(cb: any): void; - reqContinue(cb: RequestHandler): void; - } - - export var Client: { - new(): ClientInstance - } + /** + * @return the trigger ID for this AsyncResource instance. + */ + triggerAsyncId(): number; + } } + +declare module "http2" { + import * as events from "events"; + import * as fs from "fs"; + import * as net from "net"; + import * as stream from "stream"; + import * as tls from "tls"; + import * as url from "url"; + + import { IncomingHttpHeaders, OutgoingHttpHeaders } from "http"; + export { IncomingHttpHeaders, OutgoingHttpHeaders } from "http"; + + // Http2Stream + + export interface StreamPriorityOptions { + exclusive?: boolean; + parent?: number; + weight?: number; + silent?: boolean; + } + + export interface StreamState { + localWindowSize?: number; + state?: number; + streamLocalClose?: number; + streamRemoteClose?: number; + sumDependencyWeight?: number; + weight?: number; + } + + export interface ServerStreamResponseOptions { + endStream?: boolean; + getTrailers?: (trailers: OutgoingHttpHeaders) => void; + } + + export interface StatOptions { + offset: number; + length: number; + } + + export interface ServerStreamFileResponseOptions { + statCheck?: (stats: fs.Stats, headers: OutgoingHttpHeaders, statOptions: StatOptions) => void | boolean; + getTrailers?: (trailers: OutgoingHttpHeaders) => void; + offset?: number; + length?: number; + } + + export interface ServerStreamFileResponseOptionsWithError extends ServerStreamFileResponseOptions { + onError?: (err: NodeJS.ErrnoException) => void; + } + + export interface Http2Stream extends stream.Duplex { + readonly aborted: boolean; + readonly destroyed: boolean; + priority(options: StreamPriorityOptions): void; + readonly rstCode: number; + rstStream(code: number): void; + rstWithNoError(): void; + rstWithProtocolError(): void; + rstWithCancel(): void; + rstWithRefuse(): void; + rstWithInternalError(): void; + readonly session: Http2Session; + setTimeout(msecs: number, callback?: () => void): void; + readonly state: StreamState; + + addListener(event: string, listener: (...args: any[]) => void): this; + addListener(event: "aborted", listener: () => void): this; + addListener(event: "close", listener: () => void): this; + addListener(event: "data", listener: (chunk: Buffer | string) => void): this; + addListener(event: "drain", listener: () => void): this; + addListener(event: "end", listener: () => void): this; + addListener(event: "error", listener: (err: Error) => void): this; + addListener(event: "finish", listener: () => void): this; + addListener(event: "frameError", listener: (frameType: number, errorCode: number) => void): this; + addListener(event: "pipe", listener: (src: stream.Readable) => void): this; + addListener(event: "unpipe", listener: (src: stream.Readable) => void): this; + addListener(event: "streamClosed", listener: (code: number) => void): this; + addListener(event: "timeout", listener: () => void): this; + addListener(event: "trailers", listener: (trailers: IncomingHttpHeaders, flags: number) => void): this; + + emit(event: string | symbol, ...args: any[]): boolean; + emit(event: "aborted"): boolean; + emit(event: "close"): boolean; + emit(event: "data", chunk: Buffer | string): boolean; + emit(event: "drain"): boolean; + emit(event: "end"): boolean; + emit(event: "error", err: Error): boolean; + emit(event: "finish"): boolean; + emit(event: "frameError", frameType: number, errorCode: number): boolean; + emit(event: "pipe", src: stream.Readable): boolean; + emit(event: "unpipe", src: stream.Readable): boolean; + emit(event: "streamClosed", code: number): boolean; + emit(event: "timeout"): boolean; + emit(event: "trailers", trailers: IncomingHttpHeaders, flags: number): boolean; + + on(event: string, listener: (...args: any[]) => void): this; + on(event: "aborted", listener: () => void): this; + on(event: "close", listener: () => void): this; + on(event: "data", listener: (chunk: Buffer | string) => void): this; + on(event: "drain", listener: () => void): this; + on(event: "end", listener: () => void): this; + on(event: "error", listener: (err: Error) => void): this; + on(event: "finish", listener: () => void): this; + on(event: "frameError", listener: (frameType: number, errorCode: number) => void): this; + on(event: "pipe", listener: (src: stream.Readable) => void): this; + on(event: "unpipe", listener: (src: stream.Readable) => void): this; + on(event: "streamClosed", listener: (code: number) => void): this; + on(event: "timeout", listener: () => void): this; + on(event: "trailers", listener: (trailers: IncomingHttpHeaders, flags: number) => void): this; + + once(event: string, listener: (...args: any[]) => void): this; + once(event: "aborted", listener: () => void): this; + once(event: "close", listener: () => void): this; + once(event: "data", listener: (chunk: Buffer | string) => void): this; + once(event: "drain", listener: () => void): this; + once(event: "end", listener: () => void): this; + once(event: "error", listener: (err: Error) => void): this; + once(event: "finish", listener: () => void): this; + once(event: "frameError", listener: (frameType: number, errorCode: number) => void): this; + once(event: "pipe", listener: (src: stream.Readable) => void): this; + once(event: "unpipe", listener: (src: stream.Readable) => void): this; + once(event: "streamClosed", listener: (code: number) => void): this; + once(event: "timeout", listener: () => void): this; + once(event: "trailers", listener: (trailers: IncomingHttpHeaders, flags: number) => void): this; + + prependListener(event: string, listener: (...args: any[]) => void): this; + prependListener(event: "aborted", listener: () => void): this; + prependListener(event: "close", listener: () => void): this; + prependListener(event: "data", listener: (chunk: Buffer | string) => void): this; + prependListener(event: "drain", listener: () => void): this; + prependListener(event: "end", listener: () => void): this; + prependListener(event: "error", listener: (err: Error) => void): this; + prependListener(event: "finish", listener: () => void): this; + prependListener(event: "frameError", listener: (frameType: number, errorCode: number) => void): this; + prependListener(event: "pipe", listener: (src: stream.Readable) => void): this; + prependListener(event: "unpipe", listener: (src: stream.Readable) => void): this; + prependListener(event: "streamClosed", listener: (code: number) => void): this; + prependListener(event: "timeout", listener: () => void): this; + prependListener(event: "trailers", listener: (trailers: IncomingHttpHeaders, flags: number) => void): this; + + prependOnceListener(event: string, listener: (...args: any[]) => void): this; + prependOnceListener(event: "aborted", listener: () => void): this; + prependOnceListener(event: "close", listener: () => void): this; + prependOnceListener(event: "data", listener: (chunk: Buffer | string) => void): this; + prependOnceListener(event: "drain", listener: () => void): this; + prependOnceListener(event: "end", listener: () => void): this; + prependOnceListener(event: "error", listener: (err: Error) => void): this; + prependOnceListener(event: "finish", listener: () => void): this; + prependOnceListener(event: "frameError", listener: (frameType: number, errorCode: number) => void): this; + prependOnceListener(event: "pipe", listener: (src: stream.Readable) => void): this; + prependOnceListener(event: "unpipe", listener: (src: stream.Readable) => void): this; + prependOnceListener(event: "streamClosed", listener: (code: number) => void): this; + prependOnceListener(event: "timeout", listener: () => void): this; + prependOnceListener(event: "trailers", listener: (trailers: IncomingHttpHeaders, flags: number) => void): this; + } + + export interface ClientHttp2Stream extends Http2Stream { + addListener(event: string, listener: (...args: any[]) => void): this; + addListener(event: "headers", listener: (headers: IncomingHttpHeaders, flags: number) => void): this; + addListener(event: "push", listener: (headers: IncomingHttpHeaders, flags: number) => void): this; + addListener(event: "response", listener: (headers: IncomingHttpHeaders, flags: number) => void): this; + + emit(event: string | symbol, ...args: any[]): boolean; + emit(event: "headers", headers: IncomingHttpHeaders, flags: number): boolean; + emit(event: "push", headers: IncomingHttpHeaders, flags: number): boolean; + emit(event: "response", headers: IncomingHttpHeaders, flags: number): boolean; + + on(event: string, listener: (...args: any[]) => void): this; + on(event: "headers", listener: (headers: IncomingHttpHeaders, flags: number) => void): this; + on(event: "push", listener: (headers: IncomingHttpHeaders, flags: number) => void): this; + on(event: "response", listener: (headers: IncomingHttpHeaders, flags: number) => void): this; + + once(event: string, listener: (...args: any[]) => void): this; + once(event: "headers", listener: (headers: IncomingHttpHeaders, flags: number) => void): this; + once(event: "push", listener: (headers: IncomingHttpHeaders, flags: number) => void): this; + once(event: "response", listener: (headers: IncomingHttpHeaders, flags: number) => void): this; + + prependListener(event: string, listener: (...args: any[]) => void): this; + prependListener(event: "headers", listener: (headers: IncomingHttpHeaders, flags: number) => void): this; + prependListener(event: "push", listener: (headers: IncomingHttpHeaders, flags: number) => void): this; + prependListener(event: "response", listener: (headers: IncomingHttpHeaders, flags: number) => void): this; + + prependOnceListener(event: string, listener: (...args: any[]) => void): this; + prependOnceListener(event: "headers", listener: (headers: IncomingHttpHeaders, flags: number) => void): this; + prependOnceListener(event: "push", listener: (headers: IncomingHttpHeaders, flags: number) => void): this; + prependOnceListener(event: "response", listener: (headers: IncomingHttpHeaders, flags: number) => void): this; + } + + export interface ServerHttp2Stream extends Http2Stream { + additionalHeaders(headers: OutgoingHttpHeaders): void; + readonly headersSent: boolean; + readonly pushAllowed: boolean; + pushStream(headers: OutgoingHttpHeaders, callback?: (pushStream: ServerHttp2Stream) => void): void; + pushStream(headers: OutgoingHttpHeaders, options?: StreamPriorityOptions, callback?: (pushStream: ServerHttp2Stream) => void): void; + respond(headers?: OutgoingHttpHeaders, options?: ServerStreamResponseOptions): void; + respondWithFD(fd: number, headers?: OutgoingHttpHeaders, options?: ServerStreamFileResponseOptions): void; + respondWithFile(path: string, headers?: OutgoingHttpHeaders, options?: ServerStreamFileResponseOptionsWithError): void; + } + + // Http2Session + + export interface Settings { + headerTableSize?: number; + enablePush?: boolean; + initialWindowSize?: number; + maxFrameSize?: number; + maxConcurrentStreams?: number; + maxHeaderListSize?: number; + } + + export interface ClientSessionRequestOptions { + endStream?: boolean; + exclusive?: boolean; + parent?: number; + weight?: number; + getTrailers?: (trailers: OutgoingHttpHeaders, flags: number) => void; + } + + export interface SessionShutdownOptions { + graceful?: boolean; + errorCode?: number; + lastStreamID?: number; + opaqueData?: Buffer | Uint8Array; + } + + export interface SessionState { + effectiveLocalWindowSize?: number; + effectiveRecvDataLength?: number; + nextStreamID?: number; + localWindowSize?: number; + lastProcStreamID?: number; + remoteWindowSize?: number; + outboundQueueSize?: number; + deflateDynamicTableSize?: number; + inflateDynamicTableSize?: number; + } + + export interface Http2Session extends events.EventEmitter { + destroy(): void; + readonly destroyed: boolean; + readonly localSettings: Settings; + readonly pendingSettingsAck: boolean; + readonly remoteSettings: Settings; + rstStream(stream: Http2Stream, code?: number): void; + setTimeout(msecs: number, callback?: () => void): void; + shutdown(callback?: () => void): void; + shutdown(options: SessionShutdownOptions, callback?: () => void): void; + readonly socket: net.Socket | tls.TLSSocket; + readonly state: SessionState; + priority(stream: Http2Stream, options: StreamPriorityOptions): void; + settings(settings: Settings): void; + readonly type: number; + + addListener(event: string, listener: (...args: any[]) => void): this; + addListener(event: "close", listener: () => void): this; + addListener(event: "error", listener: (err: Error) => void): this; + addListener(event: "frameError", listener: (frameType: number, errorCode: number, streamID: number) => void): this; + addListener(event: "goaway", listener: (errorCode: number, lastStreamID: number, opaqueData: Buffer) => void): this; + addListener(event: "localSettings", listener: (settings: Settings) => void): this; + addListener(event: "remoteSettings", listener: (settings: Settings) => void): this; + addListener(event: "socketError", listener: (err: Error) => void): this; + addListener(event: "timeout", listener: () => void): this; + + emit(event: string | symbol, ...args: any[]): boolean; + emit(event: "close"): boolean; + emit(event: "error", err: Error): boolean; + emit(event: "frameError", frameType: number, errorCode: number, streamID: number): boolean; + emit(event: "goaway", errorCode: number, lastStreamID: number, opaqueData: Buffer): boolean; + emit(event: "localSettings", settings: Settings): boolean; + emit(event: "remoteSettings", settings: Settings): boolean; + emit(event: "socketError", err: Error): boolean; + emit(event: "timeout"): boolean; + + on(event: string, listener: (...args: any[]) => void): this; + on(event: "close", listener: () => void): this; + on(event: "error", listener: (err: Error) => void): this; + on(event: "frameError", listener: (frameType: number, errorCode: number, streamID: number) => void): this; + on(event: "goaway", listener: (errorCode: number, lastStreamID: number, opaqueData: Buffer) => void): this; + on(event: "localSettings", listener: (settings: Settings) => void): this; + on(event: "remoteSettings", listener: (settings: Settings) => void): this; + on(event: "socketError", listener: (err: Error) => void): this; + on(event: "timeout", listener: () => void): this; + + once(event: string, listener: (...args: any[]) => void): this; + once(event: "close", listener: () => void): this; + once(event: "error", listener: (err: Error) => void): this; + once(event: "frameError", listener: (frameType: number, errorCode: number, streamID: number) => void): this; + once(event: "goaway", listener: (errorCode: number, lastStreamID: number, opaqueData: Buffer) => void): this; + once(event: "localSettings", listener: (settings: Settings) => void): this; + once(event: "remoteSettings", listener: (settings: Settings) => void): this; + once(event: "socketError", listener: (err: Error) => void): this; + once(event: "timeout", listener: () => void): this; + + prependListener(event: string, listener: (...args: any[]) => void): this; + prependListener(event: "close", listener: () => void): this; + prependListener(event: "error", listener: (err: Error) => void): this; + prependListener(event: "frameError", listener: (frameType: number, errorCode: number, streamID: number) => void): this; + prependListener(event: "goaway", listener: (errorCode: number, lastStreamID: number, opaqueData: Buffer) => void): this; + prependListener(event: "localSettings", listener: (settings: Settings) => void): this; + prependListener(event: "remoteSettings", listener: (settings: Settings) => void): this; + prependListener(event: "socketError", listener: (err: Error) => void): this; + prependListener(event: "timeout", listener: () => void): this; + + prependOnceListener(event: string, listener: (...args: any[]) => void): this; + prependOnceListener(event: "close", listener: () => void): this; + prependOnceListener(event: "error", listener: (err: Error) => void): this; + prependOnceListener(event: "frameError", listener: (frameType: number, errorCode: number, streamID: number) => void): this; + prependOnceListener(event: "goaway", listener: (errorCode: number, lastStreamID: number, opaqueData: Buffer) => void): this; + prependOnceListener(event: "localSettings", listener: (settings: Settings) => void): this; + prependOnceListener(event: "remoteSettings", listener: (settings: Settings) => void): this; + prependOnceListener(event: "socketError", listener: (err: Error) => void): this; + prependOnceListener(event: "timeout", listener: () => void): this; + } + + export interface ClientHttp2Session extends Http2Session { + request(headers?: OutgoingHttpHeaders, options?: ClientSessionRequestOptions): ClientHttp2Stream; + + addListener(event: string, listener: (...args: any[]) => void): this; + addListener(event: "connect", listener: (session: ClientHttp2Session, socket: net.Socket | tls.TLSSocket) => void): this; + addListener(event: "stream", listener: (stream: ClientHttp2Stream, headers: IncomingHttpHeaders, flags: number) => void): this; + + emit(event: string | symbol, ...args: any[]): boolean; + emit(event: "connect", session: ClientHttp2Session, socket: net.Socket | tls.TLSSocket): boolean; + emit(event: "stream", stream: ClientHttp2Stream, headers: IncomingHttpHeaders, flags: number): boolean; + + on(event: string, listener: (...args: any[]) => void): this; + on(event: "connect", listener: (session: ClientHttp2Session, socket: net.Socket | tls.TLSSocket) => void): this; + on(event: "stream", listener: (stream: ClientHttp2Stream, headers: IncomingHttpHeaders, flags: number) => void): this; + + once(event: string, listener: (...args: any[]) => void): this; + once(event: "connect", listener: (session: ClientHttp2Session, socket: net.Socket | tls.TLSSocket) => void): this; + once(event: "stream", listener: (stream: ClientHttp2Stream, headers: IncomingHttpHeaders, flags: number) => void): this; + + prependListener(event: string, listener: (...args: any[]) => void): this; + prependListener(event: "connect", listener: (session: ClientHttp2Session, socket: net.Socket | tls.TLSSocket) => void): this; + prependListener(event: "stream", listener: (stream: ClientHttp2Stream, headers: IncomingHttpHeaders, flags: number) => void): this; + + prependOnceListener(event: string, listener: (...args: any[]) => void): this; + prependOnceListener(event: "connect", listener: (session: ClientHttp2Session, socket: net.Socket | tls.TLSSocket) => void): this; + prependOnceListener(event: "stream", listener: (stream: ClientHttp2Stream, headers: IncomingHttpHeaders, flags: number) => void): this; + } + + export interface ServerHttp2Session extends Http2Session { + readonly server: Http2Server | Http2SecureServer; + + addListener(event: string, listener: (...args: any[]) => void): this; + addListener(event: "connect", listener: (session: ServerHttp2Session, socket: net.Socket | tls.TLSSocket) => void): this; + addListener(event: "stream", listener: (stream: ServerHttp2Stream, headers: IncomingHttpHeaders, flags: number) => void): this; + + emit(event: string | symbol, ...args: any[]): boolean; + emit(event: "connect", session: ServerHttp2Session, socket: net.Socket | tls.TLSSocket): boolean; + emit(event: "stream", stream: ServerHttp2Stream, headers: IncomingHttpHeaders, flags: number): boolean; + + on(event: string, listener: (...args: any[]) => void): this; + on(event: "connect", listener: (session: ServerHttp2Session, socket: net.Socket | tls.TLSSocket) => void): this; + on(event: "stream", listener: (stream: ServerHttp2Stream, headers: IncomingHttpHeaders, flags: number) => void): this; + + once(event: string, listener: (...args: any[]) => void): this; + once(event: "connect", listener: (session: ServerHttp2Session, socket: net.Socket | tls.TLSSocket) => void): this; + once(event: "stream", listener: (stream: ServerHttp2Stream, headers: IncomingHttpHeaders, flags: number) => void): this; + + prependListener(event: string, listener: (...args: any[]) => void): this; + prependListener(event: "connect", listener: (session: ServerHttp2Session, socket: net.Socket | tls.TLSSocket) => void): this; + prependListener(event: "stream", listener: (stream: ServerHttp2Stream, headers: IncomingHttpHeaders, flags: number) => void): this; + + prependOnceListener(event: string, listener: (...args: any[]) => void): this; + prependOnceListener(event: "connect", listener: (session: ServerHttp2Session, socket: net.Socket | tls.TLSSocket) => void): this; + prependOnceListener(event: "stream", listener: (stream: ServerHttp2Stream, headers: IncomingHttpHeaders, flags: number) => void): this; + } + + // Http2Server + + export interface SessionOptions { + maxDeflateDynamicTableSize?: number; + maxReservedRemoteStreams?: number; + maxSendHeaderBlockLength?: number; + paddingStrategy?: number; + peerMaxConcurrentStreams?: number; + selectPadding?: (frameLen: number, maxFrameLen: number) => number; + settings?: Settings; + } + + export type ClientSessionOptions = SessionOptions; + export type ServerSessionOptions = SessionOptions; + + export interface SecureClientSessionOptions extends ClientSessionOptions, tls.ConnectionOptions { } + export interface SecureServerSessionOptions extends ServerSessionOptions, tls.TlsOptions { } + + export interface ServerOptions extends ServerSessionOptions { + allowHTTP1?: boolean; + } + + export interface SecureServerOptions extends SecureServerSessionOptions { + allowHTTP1?: boolean; + } + + export interface Http2Server extends net.Server { + addListener(event: string, listener: (...args: any[]) => void): this; + addListener(event: "request", listener: (request: Http2ServerRequest, response: Http2ServerResponse) => void): this; + addListener(event: "sessionError", listener: (err: Error) => void): this; + addListener(event: "socketError", listener: (err: Error) => void): this; + addListener(event: "stream", listener: (stream: ServerHttp2Stream, headers: IncomingHttpHeaders, flags: number) => void): this; + addListener(event: "timeout", listener: () => void): this; + + emit(event: string | symbol, ...args: any[]): boolean; + emit(event: "request", request: Http2ServerRequest, response: Http2ServerResponse): boolean; + emit(event: "sessionError", err: Error): boolean; + emit(event: "socketError", err: Error): boolean; + emit(event: "stream", stream: ServerHttp2Stream, headers: IncomingHttpHeaders, flags: number): boolean; + emit(event: "timeout"): boolean; + + on(event: string, listener: (...args: any[]) => void): this; + on(event: "request", listener: (request: Http2ServerRequest, response: Http2ServerResponse) => void): this; + on(event: "sessionError", listener: (err: Error) => void): this; + on(event: "socketError", listener: (err: Error) => void): this; + on(event: "stream", listener: (stream: ServerHttp2Stream, headers: IncomingHttpHeaders, flags: number) => void): this; + on(event: "timeout", listener: () => void): this; + + once(event: string, listener: (...args: any[]) => void): this; + once(event: "request", listener: (request: Http2ServerRequest, response: Http2ServerResponse) => void): this; + once(event: "sessionError", listener: (err: Error) => void): this; + once(event: "socketError", listener: (err: Error) => void): this; + once(event: "stream", listener: (stream: ServerHttp2Stream, headers: IncomingHttpHeaders, flags: number) => void): this; + once(event: "timeout", listener: () => void): this; + + prependListener(event: string, listener: (...args: any[]) => void): this; + prependListener(event: "request", listener: (request: Http2ServerRequest, response: Http2ServerResponse) => void): this; + prependListener(event: "sessionError", listener: (err: Error) => void): this; + prependListener(event: "socketError", listener: (err: Error) => void): this; + prependListener(event: "stream", listener: (stream: ServerHttp2Stream, headers: IncomingHttpHeaders, flags: number) => void): this; + prependListener(event: "timeout", listener: () => void): this; + + prependOnceListener(event: string, listener: (...args: any[]) => void): this; + prependOnceListener(event: "request", listener: (request: Http2ServerRequest, response: Http2ServerResponse) => void): this; + prependOnceListener(event: "sessionError", listener: (err: Error) => void): this; + prependOnceListener(event: "socketError", listener: (err: Error) => void): this; + prependOnceListener(event: "stream", listener: (stream: ServerHttp2Stream, headers: IncomingHttpHeaders, flags: number) => void): this; + prependOnceListener(event: "timeout", listener: () => void): this; + } + + export interface Http2SecureServer extends tls.Server { + addListener(event: string, listener: (...args: any[]) => void): this; + addListener(event: "request", listener: (request: Http2ServerRequest, response: Http2ServerResponse) => void): this; + addListener(event: "sessionError", listener: (err: Error) => void): this; + addListener(event: "socketError", listener: (err: Error) => void): this; + addListener(event: "stream", listener: (stream: ServerHttp2Stream, headers: IncomingHttpHeaders, flags: number) => void): this; + addListener(event: "timeout", listener: () => void): this; + addListener(event: "unknownProtocol", listener: (socket: tls.TLSSocket) => void): this; + + emit(event: string | symbol, ...args: any[]): boolean; + emit(event: "request", request: Http2ServerRequest, response: Http2ServerResponse): boolean; + emit(event: "sessionError", err: Error): boolean; + emit(event: "socketError", err: Error): boolean; + emit(event: "stream", stream: ServerHttp2Stream, headers: IncomingHttpHeaders, flags: number): boolean; + emit(event: "timeout"): boolean; + emit(event: "unknownProtocol", socket: tls.TLSSocket): boolean; + + on(event: string, listener: (...args: any[]) => void): this; + on(event: "request", listener: (request: Http2ServerRequest, response: Http2ServerResponse) => void): this; + on(event: "sessionError", listener: (err: Error) => void): this; + on(event: "socketError", listener: (err: Error) => void): this; + on(event: "stream", listener: (stream: ServerHttp2Stream, headers: IncomingHttpHeaders, flags: number) => void): this; + on(event: "timeout", listener: () => void): this; + on(event: "unknownProtocol", listener: (socket: tls.TLSSocket) => void): this; + + once(event: string, listener: (...args: any[]) => void): this; + once(event: "request", listener: (request: Http2ServerRequest, response: Http2ServerResponse) => void): this; + once(event: "sessionError", listener: (err: Error) => void): this; + once(event: "socketError", listener: (err: Error) => void): this; + once(event: "stream", listener: (stream: ServerHttp2Stream, headers: IncomingHttpHeaders, flags: number) => void): this; + once(event: "timeout", listener: () => void): this; + once(event: "unknownProtocol", listener: (socket: tls.TLSSocket) => void): this; + + prependListener(event: string, listener: (...args: any[]) => void): this; + prependListener(event: "request", listener: (request: Http2ServerRequest, response: Http2ServerResponse) => void): this; + prependListener(event: "sessionError", listener: (err: Error) => void): this; + prependListener(event: "socketError", listener: (err: Error) => void): this; + prependListener(event: "stream", listener: (stream: ServerHttp2Stream, headers: IncomingHttpHeaders, flags: number) => void): this; + prependListener(event: "timeout", listener: () => void): this; + prependListener(event: "unknownProtocol", listener: (socket: tls.TLSSocket) => void): this; + + prependOnceListener(event: string, listener: (...args: any[]) => void): this; + prependOnceListener(event: "request", listener: (request: Http2ServerRequest, response: Http2ServerResponse) => void): this; + prependOnceListener(event: "sessionError", listener: (err: Error) => void): this; + prependOnceListener(event: "socketError", listener: (err: Error) => void): this; + prependOnceListener(event: "stream", listener: (stream: ServerHttp2Stream, headers: IncomingHttpHeaders, flags: number) => void): this; + prependOnceListener(event: "timeout", listener: () => void): this; + prependOnceListener(event: "unknownProtocol", listener: (socket: tls.TLSSocket) => void): this; + } + + export interface Http2ServerRequest extends stream.Readable { + headers: IncomingHttpHeaders; + httpVersion: string; + method: string; + rawHeaders: string[]; + rawTrailers: string[]; + setTimeout(msecs: number, callback?: () => void): void; + socket: net.Socket | tls.TLSSocket; + stream: ServerHttp2Stream; + trailers: IncomingHttpHeaders; + url: string; + + addListener(event: string, listener: (...args: any[]) => void): this; + addListener(event: "aborted", listener: (hadError: boolean, code: number) => void): this; + + emit(event: string | symbol, ...args: any[]): boolean; + emit(event: "aborted", hadError: boolean, code: number): boolean; + + on(event: string, listener: (...args: any[]) => void): this; + on(event: "aborted", listener: (hadError: boolean, code: number) => void): this; + + once(event: string, listener: (...args: any[]) => void): this; + once(event: "aborted", listener: (hadError: boolean, code: number) => void): this; + + prependListener(event: string, listener: (...args: any[]) => void): this; + prependListener(event: "aborted", listener: (hadError: boolean, code: number) => void): this; + + prependOnceListener(event: string, listener: (...args: any[]) => void): this; + prependOnceListener(event: "aborted", listener: (hadError: boolean, code: number) => void): this; + } + + export interface Http2ServerResponse extends events.EventEmitter { + addTrailers(trailers: OutgoingHttpHeaders): void; + connection: net.Socket | tls.TLSSocket; + end(callback?: () => void): void; + end(data?: string | Buffer, callback?: () => void): void; + end(data?: string | Buffer, encoding?: string, callback?: () => void): void; + readonly finished: boolean; + getHeader(name: string): string; + getHeaderNames(): string[]; + getHeaders(): OutgoingHttpHeaders; + hasHeader(name: string): boolean; + readonly headersSent: boolean; + removeHeader(name: string): void; + sendDate: boolean; + setHeader(name: string, value: number | string | string[]): void; + setTimeout(msecs: number, callback?: () => void): void; + socket: net.Socket | tls.TLSSocket; + statusCode: number; + statusMessage: ''; + stream: ServerHttp2Stream; + write(chunk: string | Buffer, callback?: (err: Error) => void): boolean; + write(chunk: string | Buffer, encoding?: string, callback?: (err: Error) => void): boolean; + writeContinue(): void; + writeHead(statusCode: number, headers?: OutgoingHttpHeaders): void; + writeHead(statusCode: number, statusMessage?: string, headers?: OutgoingHttpHeaders): void; + createPushResponse(headers: OutgoingHttpHeaders, callback: (err: Error | null, res: Http2ServerResponse) => void): void; + + addListener(event: string, listener: (...args: any[]) => void): this; + addListener(event: "aborted", listener: (hadError: boolean, code: number) => void): this; + addListener(event: "close", listener: () => void): this; + addListener(event: "drain", listener: () => void): this; + addListener(event: "error", listener: (error: Error) => void): this; + addListener(event: "finish", listener: () => void): this; + + emit(event: string | symbol, ...args: any[]): boolean; + emit(event: "aborted", hadError: boolean, code: number): boolean; + emit(event: "close"): boolean; + emit(event: "drain"): boolean; + emit(event: "error", error: Error): boolean; + emit(event: "finish"): boolean; + + on(event: string, listener: (...args: any[]) => void): this; + on(event: "aborted", listener: (hadError: boolean, code: number) => void): this; + on(event: "close", listener: () => void): this; + on(event: "drain", listener: () => void): this; + on(event: "error", listener: (error: Error) => void): this; + on(event: "finish", listener: () => void): this; + + once(event: string, listener: (...args: any[]) => void): this; + once(event: "aborted", listener: (hadError: boolean, code: number) => void): this; + once(event: "close", listener: () => void): this; + once(event: "drain", listener: () => void): this; + once(event: "error", listener: (error: Error) => void): this; + once(event: "finish", listener: () => void): this; + + prependListener(event: string, listener: (...args: any[]) => void): this; + prependListener(event: "aborted", listener: (hadError: boolean, code: number) => void): this; + prependListener(event: "close", listener: () => void): this; + prependListener(event: "drain", listener: () => void): this; + prependListener(event: "error", listener: (error: Error) => void): this; + prependListener(event: "finish", listener: () => void): this; + + prependOnceListener(event: string, listener: (...args: any[]) => void): this; + prependOnceListener(event: "aborted", listener: (hadError: boolean, code: number) => void): this; + prependOnceListener(event: "close", listener: () => void): this; + prependOnceListener(event: "drain", listener: () => void): this; + prependOnceListener(event: "error", listener: (error: Error) => void): this; + prependOnceListener(event: "finish", listener: () => void): this; + } + + // Public API + + export namespace constants { + export const NGHTTP2_SESSION_SERVER: number; + export const NGHTTP2_SESSION_CLIENT: number; + export const NGHTTP2_STREAM_STATE_IDLE: number; + export const NGHTTP2_STREAM_STATE_OPEN: number; + export const NGHTTP2_STREAM_STATE_RESERVED_LOCAL: number; + export const NGHTTP2_STREAM_STATE_RESERVED_REMOTE: number; + export const NGHTTP2_STREAM_STATE_HALF_CLOSED_LOCAL: number; + export const NGHTTP2_STREAM_STATE_HALF_CLOSED_REMOTE: number; + export const NGHTTP2_STREAM_STATE_CLOSED: number; + export const NGHTTP2_NO_ERROR: number; + export const NGHTTP2_PROTOCOL_ERROR: number; + export const NGHTTP2_INTERNAL_ERROR: number; + export const NGHTTP2_FLOW_CONTROL_ERROR: number; + export const NGHTTP2_SETTINGS_TIMEOUT: number; + export const NGHTTP2_STREAM_CLOSED: number; + export const NGHTTP2_FRAME_SIZE_ERROR: number; + export const NGHTTP2_REFUSED_STREAM: number; + export const NGHTTP2_CANCEL: number; + export const NGHTTP2_COMPRESSION_ERROR: number; + export const NGHTTP2_CONNECT_ERROR: number; + export const NGHTTP2_ENHANCE_YOUR_CALM: number; + export const NGHTTP2_INADEQUATE_SECURITY: number; + export const NGHTTP2_HTTP_1_1_REQUIRED: number; + export const NGHTTP2_ERR_FRAME_SIZE_ERROR: number; + export const NGHTTP2_FLAG_NONE: number; + export const NGHTTP2_FLAG_END_STREAM: number; + export const NGHTTP2_FLAG_END_HEADERS: number; + export const NGHTTP2_FLAG_ACK: number; + export const NGHTTP2_FLAG_PADDED: number; + export const NGHTTP2_FLAG_PRIORITY: number; + export const DEFAULT_SETTINGS_HEADER_TABLE_SIZE: number; + export const DEFAULT_SETTINGS_ENABLE_PUSH: number; + export const DEFAULT_SETTINGS_INITIAL_WINDOW_SIZE: number; + export const DEFAULT_SETTINGS_MAX_FRAME_SIZE: number; + export const MAX_MAX_FRAME_SIZE: number; + export const MIN_MAX_FRAME_SIZE: number; + export const MAX_INITIAL_WINDOW_SIZE: number; + export const NGHTTP2_DEFAULT_WEIGHT: number; + export const NGHTTP2_SETTINGS_HEADER_TABLE_SIZE: number; + export const NGHTTP2_SETTINGS_ENABLE_PUSH: number; + export const NGHTTP2_SETTINGS_MAX_CONCURRENT_STREAMS: number; + export const NGHTTP2_SETTINGS_INITIAL_WINDOW_SIZE: number; + export const NGHTTP2_SETTINGS_MAX_FRAME_SIZE: number; + export const NGHTTP2_SETTINGS_MAX_HEADER_LIST_SIZE: number; + export const PADDING_STRATEGY_NONE: number; + export const PADDING_STRATEGY_MAX: number; + export const PADDING_STRATEGY_CALLBACK: number; + export const HTTP2_HEADER_STATUS: string; + export const HTTP2_HEADER_METHOD: string; + export const HTTP2_HEADER_AUTHORITY: string; + export const HTTP2_HEADER_SCHEME: string; + export const HTTP2_HEADER_PATH: string; + export const HTTP2_HEADER_ACCEPT_CHARSET: string; + export const HTTP2_HEADER_ACCEPT_ENCODING: string; + export const HTTP2_HEADER_ACCEPT_LANGUAGE: string; + export const HTTP2_HEADER_ACCEPT_RANGES: string; + export const HTTP2_HEADER_ACCEPT: string; + export const HTTP2_HEADER_ACCESS_CONTROL_ALLOW_ORIGIN: string; + export const HTTP2_HEADER_AGE: string; + export const HTTP2_HEADER_ALLOW: string; + export const HTTP2_HEADER_AUTHORIZATION: string; + export const HTTP2_HEADER_CACHE_CONTROL: string; + export const HTTP2_HEADER_CONNECTION: string; + export const HTTP2_HEADER_CONTENT_DISPOSITION: string; + export const HTTP2_HEADER_CONTENT_ENCODING: string; + export const HTTP2_HEADER_CONTENT_LANGUAGE: string; + export const HTTP2_HEADER_CONTENT_LENGTH: string; + export const HTTP2_HEADER_CONTENT_LOCATION: string; + export const HTTP2_HEADER_CONTENT_MD5: string; + export const HTTP2_HEADER_CONTENT_RANGE: string; + export const HTTP2_HEADER_CONTENT_TYPE: string; + export const HTTP2_HEADER_COOKIE: string; + export const HTTP2_HEADER_DATE: string; + export const HTTP2_HEADER_ETAG: string; + export const HTTP2_HEADER_EXPECT: string; + export const HTTP2_HEADER_EXPIRES: string; + export const HTTP2_HEADER_FROM: string; + export const HTTP2_HEADER_HOST: string; + export const HTTP2_HEADER_IF_MATCH: string; + export const HTTP2_HEADER_IF_MODIFIED_SINCE: string; + export const HTTP2_HEADER_IF_NONE_MATCH: string; + export const HTTP2_HEADER_IF_RANGE: string; + export const HTTP2_HEADER_IF_UNMODIFIED_SINCE: string; + export const HTTP2_HEADER_LAST_MODIFIED: string; + export const HTTP2_HEADER_LINK: string; + export const HTTP2_HEADER_LOCATION: string; + export const HTTP2_HEADER_MAX_FORWARDS: string; + export const HTTP2_HEADER_PREFER: string; + export const HTTP2_HEADER_PROXY_AUTHENTICATE: string; + export const HTTP2_HEADER_PROXY_AUTHORIZATION: string; + export const HTTP2_HEADER_RANGE: string; + export const HTTP2_HEADER_REFERER: string; + export const HTTP2_HEADER_REFRESH: string; + export const HTTP2_HEADER_RETRY_AFTER: string; + export const HTTP2_HEADER_SERVER: string; + export const HTTP2_HEADER_SET_COOKIE: string; + export const HTTP2_HEADER_STRICT_TRANSPORT_SECURITY: string; + export const HTTP2_HEADER_TRANSFER_ENCODING: string; + export const HTTP2_HEADER_TE: string; + export const HTTP2_HEADER_UPGRADE: string; + export const HTTP2_HEADER_USER_AGENT: string; + export const HTTP2_HEADER_VARY: string; + export const HTTP2_HEADER_VIA: string; + export const HTTP2_HEADER_WWW_AUTHENTICATE: string; + export const HTTP2_HEADER_HTTP2_SETTINGS: string; + export const HTTP2_HEADER_KEEP_ALIVE: string; + export const HTTP2_HEADER_PROXY_CONNECTION: string; + export const HTTP2_METHOD_ACL: string; + export const HTTP2_METHOD_BASELINE_CONTROL: string; + export const HTTP2_METHOD_BIND: string; + export const HTTP2_METHOD_CHECKIN: string; + export const HTTP2_METHOD_CHECKOUT: string; + export const HTTP2_METHOD_CONNECT: string; + export const HTTP2_METHOD_COPY: string; + export const HTTP2_METHOD_DELETE: string; + export const HTTP2_METHOD_GET: string; + export const HTTP2_METHOD_HEAD: string; + export const HTTP2_METHOD_LABEL: string; + export const HTTP2_METHOD_LINK: string; + export const HTTP2_METHOD_LOCK: string; + export const HTTP2_METHOD_MERGE: string; + export const HTTP2_METHOD_MKACTIVITY: string; + export const HTTP2_METHOD_MKCALENDAR: string; + export const HTTP2_METHOD_MKCOL: string; + export const HTTP2_METHOD_MKREDIRECTREF: string; + export const HTTP2_METHOD_MKWORKSPACE: string; + export const HTTP2_METHOD_MOVE: string; + export const HTTP2_METHOD_OPTIONS: string; + export const HTTP2_METHOD_ORDERPATCH: string; + export const HTTP2_METHOD_PATCH: string; + export const HTTP2_METHOD_POST: string; + export const HTTP2_METHOD_PRI: string; + export const HTTP2_METHOD_PROPFIND: string; + export const HTTP2_METHOD_PROPPATCH: string; + export const HTTP2_METHOD_PUT: string; + export const HTTP2_METHOD_REBIND: string; + export const HTTP2_METHOD_REPORT: string; + export const HTTP2_METHOD_SEARCH: string; + export const HTTP2_METHOD_TRACE: string; + export const HTTP2_METHOD_UNBIND: string; + export const HTTP2_METHOD_UNCHECKOUT: string; + export const HTTP2_METHOD_UNLINK: string; + export const HTTP2_METHOD_UNLOCK: string; + export const HTTP2_METHOD_UPDATE: string; + export const HTTP2_METHOD_UPDATEREDIRECTREF: string; + export const HTTP2_METHOD_VERSION_CONTROL: string; + export const HTTP_STATUS_CONTINUE: number; + export const HTTP_STATUS_SWITCHING_PROTOCOLS: number; + export const HTTP_STATUS_PROCESSING: number; + export const HTTP_STATUS_OK: number; + export const HTTP_STATUS_CREATED: number; + export const HTTP_STATUS_ACCEPTED: number; + export const HTTP_STATUS_NON_AUTHORITATIVE_INFORMATION: number; + export const HTTP_STATUS_NO_CONTENT: number; + export const HTTP_STATUS_RESET_CONTENT: number; + export const HTTP_STATUS_PARTIAL_CONTENT: number; + export const HTTP_STATUS_MULTI_STATUS: number; + export const HTTP_STATUS_ALREADY_REPORTED: number; + export const HTTP_STATUS_IM_USED: number; + export const HTTP_STATUS_MULTIPLE_CHOICES: number; + export const HTTP_STATUS_MOVED_PERMANENTLY: number; + export const HTTP_STATUS_FOUND: number; + export const HTTP_STATUS_SEE_OTHER: number; + export const HTTP_STATUS_NOT_MODIFIED: number; + export const HTTP_STATUS_USE_PROXY: number; + export const HTTP_STATUS_TEMPORARY_REDIRECT: number; + export const HTTP_STATUS_PERMANENT_REDIRECT: number; + export const HTTP_STATUS_BAD_REQUEST: number; + export const HTTP_STATUS_UNAUTHORIZED: number; + export const HTTP_STATUS_PAYMENT_REQUIRED: number; + export const HTTP_STATUS_FORBIDDEN: number; + export const HTTP_STATUS_NOT_FOUND: number; + export const HTTP_STATUS_METHOD_NOT_ALLOWED: number; + export const HTTP_STATUS_NOT_ACCEPTABLE: number; + export const HTTP_STATUS_PROXY_AUTHENTICATION_REQUIRED: number; + export const HTTP_STATUS_REQUEST_TIMEOUT: number; + export const HTTP_STATUS_CONFLICT: number; + export const HTTP_STATUS_GONE: number; + export const HTTP_STATUS_LENGTH_REQUIRED: number; + export const HTTP_STATUS_PRECONDITION_FAILED: number; + export const HTTP_STATUS_PAYLOAD_TOO_LARGE: number; + export const HTTP_STATUS_URI_TOO_LONG: number; + export const HTTP_STATUS_UNSUPPORTED_MEDIA_TYPE: number; + export const HTTP_STATUS_RANGE_NOT_SATISFIABLE: number; + export const HTTP_STATUS_EXPECTATION_FAILED: number; + export const HTTP_STATUS_TEAPOT: number; + export const HTTP_STATUS_MISDIRECTED_REQUEST: number; + export const HTTP_STATUS_UNPROCESSABLE_ENTITY: number; + export const HTTP_STATUS_LOCKED: number; + export const HTTP_STATUS_FAILED_DEPENDENCY: number; + export const HTTP_STATUS_UNORDERED_COLLECTION: number; + export const HTTP_STATUS_UPGRADE_REQUIRED: number; + export const HTTP_STATUS_PRECONDITION_REQUIRED: number; + export const HTTP_STATUS_TOO_MANY_REQUESTS: number; + export const HTTP_STATUS_REQUEST_HEADER_FIELDS_TOO_LARGE: number; + export const HTTP_STATUS_UNAVAILABLE_FOR_LEGAL_REASONS: number; + export const HTTP_STATUS_INTERNAL_SERVER_ERROR: number; + export const HTTP_STATUS_NOT_IMPLEMENTED: number; + export const HTTP_STATUS_BAD_GATEWAY: number; + export const HTTP_STATUS_SERVICE_UNAVAILABLE: number; + export const HTTP_STATUS_GATEWAY_TIMEOUT: number; + export const HTTP_STATUS_HTTP_VERSION_NOT_SUPPORTED: number; + export const HTTP_STATUS_VARIANT_ALSO_NEGOTIATES: number; + export const HTTP_STATUS_INSUFFICIENT_STORAGE: number; + export const HTTP_STATUS_LOOP_DETECTED: number; + export const HTTP_STATUS_BANDWIDTH_LIMIT_EXCEEDED: number; + export const HTTP_STATUS_NOT_EXTENDED: number; + export const HTTP_STATUS_NETWORK_AUTHENTICATION_REQUIRED: number; + } + + export function getDefaultSettings(): Settings; + export function getPackedSettings(settings: Settings): Settings; + export function getUnpackedSettings(buf: Buffer | Uint8Array): Settings; + + export function createServer(onRequestHandler?: (request: Http2ServerRequest, response: Http2ServerResponse) => void): Http2Server; + export function createServer(options: ServerOptions, onRequestHandler?: (request: Http2ServerRequest, response: Http2ServerResponse) => void): Http2Server; + + export function createSecureServer(onRequestHandler?: (request: Http2ServerRequest, response: Http2ServerResponse) => void): Http2SecureServer; + export function createSecureServer(options: SecureServerOptions, onRequestHandler?: (request: Http2ServerRequest, response: Http2ServerResponse) => void): Http2SecureServer; + + export function connect(authority: string | url.URL, listener?: (session: ClientHttp2Session, socket: net.Socket | tls.TLSSocket) => void): ClientHttp2Session; + export function connect(authority: string | url.URL, options?: ClientSessionOptions | SecureClientSessionOptions, listener?: (session: ClientHttp2Session, socket: net.Socket | tls.TLSSocket) => void): ClientHttp2Session; +} + +declare module "perf_hooks" { + export interface PerformanceEntry { + /** + * The total number of milliseconds elapsed for this entry. + * This value will not be meaningful for all Performance Entry types. + */ + readonly duration: number; + + /** + * The name of the performance entry. + */ + readonly name: string; + + /** + * The high resolution millisecond timestamp marking the starting time of the Performance Entry. + */ + readonly startTime: number; + + /** + * The type of the performance entry. + * Currently it may be one of: 'node', 'mark', 'measure', 'gc', or 'function'. + */ + readonly entryType: string; + + /** + * When performanceEntry.entryType is equal to 'gc', the performance.kind property identifies + * the type of garbage collection operation that occurred. + * The value may be one of perf_hooks.constants. + */ + readonly kind?: number; + } + + export interface PerformanceNodeTiming extends PerformanceEntry { + /** + * The high resolution millisecond timestamp at which the Node.js process completed bootstrap. + */ + readonly bootstrapComplete: number; + + /** + * The high resolution millisecond timestamp at which cluster processing ended. + */ + readonly clusterSetupEnd: number; + + /** + * The high resolution millisecond timestamp at which cluster processing started. + */ + readonly clusterSetupStart: number; + + /** + * The high resolution millisecond timestamp at which the Node.js event loop exited. + */ + readonly loopExit: number; + + /** + * The high resolution millisecond timestamp at which the Node.js event loop started. + */ + readonly loopStart: number; + + /** + * The high resolution millisecond timestamp at which main module load ended. + */ + readonly moduleLoadEnd: number; + + /** + * The high resolution millisecond timestamp at which main module load started. + */ + readonly moduleLoadStart: number; + + /** + * The high resolution millisecond timestamp at which the Node.js process was initialized. + */ + readonly nodeStart: number; + + /** + * The high resolution millisecond timestamp at which preload module load ended. + */ + readonly preloadModuleLoadEnd: number; + + /** + * The high resolution millisecond timestamp at which preload module load started. + */ + readonly preloadModuleLoadStart: number; + + /** + * The high resolution millisecond timestamp at which third_party_main processing ended. + */ + readonly thirdPartyMainEnd: number; + + /** + * The high resolution millisecond timestamp at which third_party_main processing started. + */ + readonly thirdPartyMainStart: number; + + /** + * The high resolution millisecond timestamp at which the V8 platform was initialized. + */ + readonly v8Start: number; + } + + export interface Performance { + /** + * If name is not provided, removes all PerformanceFunction objects from the Performance Timeline. + * If name is provided, removes entries with name. + * @param name + */ + clearFunctions(name?: string): void; + + /** + * If name is not provided, removes all PerformanceMark objects from the Performance Timeline. + * If name is provided, removes only the named mark. + * @param name + */ + clearMarks(name?: string): void; + + /** + * If name is not provided, removes all PerformanceMeasure objects from the Performance Timeline. + * If name is provided, removes only objects whose performanceEntry.name matches name. + */ + clearMeasures(name?: string): void; + + /** + * Returns a list of all PerformanceEntry objects in chronological order with respect to performanceEntry.startTime. + * @return list of all PerformanceEntry objects + */ + getEntries(): PerformanceEntry[]; + + /** + * Returns a list of all PerformanceEntry objects in chronological order with respect to performanceEntry.startTime + * whose performanceEntry.name is equal to name, and optionally, whose performanceEntry.entryType is equal to type. + * @param name + * @param type + * @return list of all PerformanceEntry objects + */ + getEntriesByName(name: string, type?: string): PerformanceEntry[]; + + /** + * Returns a list of all PerformanceEntry objects in chronological order with respect to performanceEntry.startTime + * whose performanceEntry.entryType is equal to type. + * @param type + * @return list of all PerformanceEntry objects + */ + getEntriesByType(type: string): PerformanceEntry[]; + + /** + * Creates a new PerformanceMark entry in the Performance Timeline. + * A PerformanceMark is a subclass of PerformanceEntry whose performanceEntry.entryType is always 'mark', + * and whose performanceEntry.duration is always 0. + * Performance marks are used to mark specific significant moments in the Performance Timeline. + * @param name + */ + mark(name?: string): void; + + /** + * Creates a new PerformanceMeasure entry in the Performance Timeline. + * A PerformanceMeasure is a subclass of PerformanceEntry whose performanceEntry.entryType is always 'measure', + * and whose performanceEntry.duration measures the number of milliseconds elapsed since startMark and endMark. + * + * The startMark argument may identify any existing PerformanceMark in the the Performance Timeline, or may identify + * any of the timestamp properties provided by the PerformanceNodeTiming class. If the named startMark does not exist, + * then startMark is set to timeOrigin by default. + * + * The endMark argument must identify any existing PerformanceMark in the the Performance Timeline or any of the timestamp + * properties provided by the PerformanceNodeTiming class. If the named endMark does not exist, an error will be thrown. + * @param name + * @param startMark + * @param endMark + */ + measure(name: string, startMark: string, endMark: string): void; + + /** + * An instance of the PerformanceNodeTiming class that provides performance metrics for specific Node.js operational milestones. + */ + readonly nodeTiming: PerformanceNodeTiming; + + /** + * @return the current high resolution millisecond timestamp + */ + now(): number; + + /** + * The timeOrigin specifies the high resolution millisecond timestamp from which all performance metric durations are measured. + */ + readonly timeOrigin: number; + + /** + * Wraps a function within a new function that measures the running time of the wrapped function. + * A PerformanceObserver must be subscribed to the 'function' event type in order for the timing details to be accessed. + * @param fn + */ + timerify any>(fn: T): T; + } + + export interface PerformanceObserverEntryList { + /** + * @return a list of PerformanceEntry objects in chronological order with respect to performanceEntry.startTime. + */ + getEntries(): PerformanceEntry[]; + + /** + * @return a list of PerformanceEntry objects in chronological order with respect to performanceEntry.startTime + * whose performanceEntry.name is equal to name, and optionally, whose performanceEntry.entryType is equal to type. + */ + getEntriesByName(name: string, type?: string): PerformanceEntry[]; + + /** + * @return Returns a list of PerformanceEntry objects in chronological order with respect to performanceEntry.startTime + * whose performanceEntry.entryType is equal to type. + */ + getEntriesByType(type: string): PerformanceEntry[]; + } + + export type PerformanceObserverCallback = (list: PerformanceObserverEntryList, observer: PerformanceObserver) => void; + + export class PerformanceObserver { + constructor(callback: PerformanceObserverCallback); + + /** + * Disconnects the PerformanceObserver instance from all notifications. + */ + disconnect(): void; + + /** + * Subscribes the PerformanceObserver instance to notifications of new PerformanceEntry instances identified by options.entryTypes. + * When options.buffered is false, the callback will be invoked once for every PerformanceEntry instance. + * Property buffered defaults to false. + * @param options + */ + observe(options: { entryTypes: string[], buffered?: boolean }): void; + } + + export namespace constants { + export const NODE_PERFORMANCE_GC_MAJOR: number; + export const NODE_PERFORMANCE_GC_MINOR: number; + export const NODE_PERFORMANCE_GC_INCREMENTAL: number; + export const NODE_PERFORMANCE_GC_WEAKCB: number; + } + + const performance: Performance; +} \ No newline at end of file diff --git a/src/vs/code/electron-browser/processExplorer/processExplorerMain.ts b/src/vs/code/electron-browser/processExplorer/processExplorerMain.ts index 9c491c0dd95..fe402f18792 100644 --- a/src/vs/code/electron-browser/processExplorer/processExplorerMain.ts +++ b/src/vs/code/electron-browser/processExplorer/processExplorerMain.ts @@ -190,7 +190,7 @@ function showContextMenu(e) { })); } - menu.popup(remote.getCurrentWindow()); + menu.popup({ window: remote.getCurrentWindow() }); } export function startup(data: ProcessExplorerData): void { diff --git a/src/vs/code/electron-main/app.ts b/src/vs/code/electron-main/app.ts index a16543734c3..c9543426700 100644 --- a/src/vs/code/electron-main/app.ts +++ b/src/vs/code/electron-main/app.ts @@ -283,7 +283,7 @@ export class CodeApplication { // See: https://github.com/Microsoft/vscode/issues/35361#issuecomment-399794085 try { if (platform.isMacintosh && this.configurationService.getValue('window.nativeTabs') === true && !systemPreferences.getUserDefault('NSUseImprovedLayoutPass', 'boolean')) { - systemPreferences.setUserDefault('NSUseImprovedLayoutPass', 'boolean', true as any); + systemPreferences.registerDefaults({ NSUseImprovedLayoutPass: true }); } } catch (error) { this.logService.error(error); diff --git a/src/vs/code/electron-main/window.ts b/src/vs/code/electron-main/window.ts index 11099c63863..a3cd3bc01d4 100644 --- a/src/vs/code/electron-main/window.ts +++ b/src/vs/code/electron-main/window.ts @@ -193,23 +193,6 @@ export class CodeWindow implements ICodeWindow { this._win = new BrowserWindow(options); this._id = this._win.id; - // Bug in Electron (https://github.com/electron/electron/issues/10862). On multi-monitor setups, - // it can happen that the position we set to the window is not the correct one on the display. - // To workaround, we ask the window for its position and set it again if not matching. - // This only applies if the window is not fullscreen or maximized and multiple monitors are used. - if (isWindows && !isFullscreenOrMaximized) { - try { - if (screen.getAllDisplays().length > 1) { - const [x, y] = this._win.getPosition(); - if (x !== this.windowState.x || y !== this.windowState.y) { - this._win.setPosition(this.windowState.x, this.windowState.y, false); - } - } - } catch (err) { - this.logService.warn(`Unexpected error fixing window position on windows with multiple windows: ${err}\n${err.stack}`); - } - } - if (useCustomTitleStyle) { this._win.setSheetOffset(22); // offset dialogs by the height of the custom title bar if we have any } @@ -987,11 +970,6 @@ export class CodeWindow implements ICodeWindow { this.touchBarGroups.push(groupTouchBar); } - // Ugly workaround for native crash on macOS 10.12.1. We are not - // leveraging the API for changing the ESC touch bar item. - // See https://github.com/electron/electron/issues/10442 - (this._win)._setEscapeTouchBarItem = () => { }; - this._win.setTouchBar(new TouchBar({ items: this.touchBarGroups })); } diff --git a/src/vs/editor/browser/services/codeEditorServiceImpl.ts b/src/vs/editor/browser/services/codeEditorServiceImpl.ts index 9fad9a52fe4..aec6b1e4030 100644 --- a/src/vs/editor/browser/services/codeEditorServiceImpl.ts +++ b/src/vs/editor/browser/services/codeEditorServiceImpl.ts @@ -212,7 +212,7 @@ class DecorationTypeOptionsProvider implements IModelDecorationOptionsProvider { const _CSS_MAP: { [prop: string]: string; } = { color: 'color:{0} !important;', - opacity: 'opacity:{0};', + opacity: 'opacity:{0}; will-change: opacity;', // TODO@Ben: 'will-change: opacity' is a workaround for https://github.com/Microsoft/vscode/issues/52196 backgroundColor: 'background-color:{0};', outline: 'outline:{0};', diff --git a/src/vs/editor/browser/widget/codeEditorWidget.ts b/src/vs/editor/browser/widget/codeEditorWidget.ts index 387e34f62d1..fee65bb4dc3 100644 --- a/src/vs/editor/browser/widget/codeEditorWidget.ts +++ b/src/vs/editor/browser/widget/codeEditorWidget.ts @@ -1805,7 +1805,7 @@ registerThemingParticipant((theme, collector) => { const unnecessaryForeground = theme.getColor(editorUnnecessaryCodeOpacity); if (unnecessaryForeground) { - collector.addRule(`.${SHOW_UNUSED_ENABLED_CLASS} .monaco-editor .${ClassName.EditorUnnecessaryInlineDecoration} { opacity: ${unnecessaryForeground.rgba.a}; }`); + collector.addRule(`.${SHOW_UNUSED_ENABLED_CLASS} .monaco-editor .${ClassName.EditorUnnecessaryInlineDecoration} { opacity: ${unnecessaryForeground.rgba.a}; will-change: opacity; }`); // TODO@Ben: 'will-change: opacity' is a workaround for https://github.com/Microsoft/vscode/issues/52196 } const unnecessaryBorder = theme.getColor(editorUnnecessaryCodeBorder); diff --git a/src/vs/platform/update/electron-main/updateService.darwin.ts b/src/vs/platform/update/electron-main/updateService.darwin.ts index 01d80b45ea1..8ac8357ef63 100644 --- a/src/vs/platform/update/electron-main/updateService.darwin.ts +++ b/src/vs/platform/update/electron-main/updateService.darwin.ts @@ -52,7 +52,7 @@ export class DarwinUpdateService extends AbstractUpdateService { protected buildUpdateFeedUrl(quality: string): string | undefined { const url = createUpdateURL('darwin', quality); try { - electron.autoUpdater.setFeedURL(url); + electron.autoUpdater.setFeedURL({ url }); } catch (e) { // application is very likely not signed this.logService.error('Failed to set update feed URL', e); diff --git a/src/vs/workbench/browser/parts/activitybar/activitybarPart.ts b/src/vs/workbench/browser/parts/activitybar/activitybarPart.ts index 13f5812793c..298c940d475 100644 --- a/src/vs/workbench/browser/parts/activitybar/activitybarPart.ts +++ b/src/vs/workbench/browser/parts/activitybar/activitybarPart.ts @@ -20,16 +20,19 @@ import { IPartService, Parts, Position as SideBarPosition } from 'vs/workbench/s import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; import { IDisposable, toDisposable } from 'vs/base/common/lifecycle'; import { ToggleActivityBarVisibilityAction } from 'vs/workbench/browser/actions/toggleActivityBarVisibility'; -import { IThemeService } from 'vs/platform/theme/common/themeService'; +import { IThemeService, registerThemingParticipant } from 'vs/platform/theme/common/themeService'; import { ACTIVITY_BAR_BACKGROUND, ACTIVITY_BAR_BORDER, ACTIVITY_BAR_FOREGROUND, ACTIVITY_BAR_BADGE_BACKGROUND, ACTIVITY_BAR_BADGE_FOREGROUND, ACTIVITY_BAR_DRAG_AND_DROP_BACKGROUND } from 'vs/workbench/common/theme'; import { contrastBorder } from 'vs/platform/theme/common/colorRegistry'; import { CompositeBar } from 'vs/workbench/browser/parts/compositebar/compositeBar'; -import { ToggleCompositePinnedAction } from 'vs/workbench/browser/parts/compositebar/compositeBarActions'; -import { ViewletDescriptor } from 'vs/workbench/browser/viewlet'; -import { Dimension } from 'vs/base/browser/dom'; +import { isMacintosh } from 'vs/base/common/platform'; +import { ILifecycleService, LifecyclePhase } from 'vs/platform/lifecycle/common/lifecycle'; +import { scheduleAtNextAnimationFrame, Dimension } from 'vs/base/browser/dom'; +import { Color } from 'vs/base/common/color'; import { IStorageService, StorageScope } from 'vs/platform/storage/common/storage'; import { IExtensionService } from 'vs/workbench/services/extensions/common/extensions'; import URI from 'vs/base/common/uri'; +import { ToggleCompositePinnedAction } from 'vs/workbench/browser/parts/compositebar/compositeBarActions'; +import { ViewletDescriptor } from 'vs/workbench/browser/viewlet'; interface IPlaceholderComposite { id: string; @@ -63,6 +66,7 @@ export class ActivitybarPart extends Part { @IInstantiationService private instantiationService: IInstantiationService, @IPartService private partService: IPartService, @IThemeService themeService: IThemeService, + @ILifecycleService private lifecycleService: ILifecycleService, @IStorageService private storageService: IStorageService, @IExtensionService private extensionService: IExtensionService ) { @@ -161,6 +165,27 @@ export class ActivitybarPart extends Part { // Top Actionbar with action items for each viewlet action this.createGlobalActivityActionBar($('.global-activity').appendTo($result).getHTMLElement()); + // TODO@Ben: workaround for https://github.com/Microsoft/vscode/issues/45700 + // It looks like there are rendering glitches on macOS with Chrome 61 when + // using --webkit-mask with a background color that is different from the image + // The workaround is to promote the element onto its own drawing layer. We do + // this only after the workbench has loaded because otherwise there is ugly flicker. + if (isMacintosh) { + this.lifecycleService.when(LifecyclePhase.Running).then(() => { + scheduleAtNextAnimationFrame(() => { // another delay... + scheduleAtNextAnimationFrame(() => { // ...to prevent more flickering on startup + registerThemingParticipant((theme, collector) => { + const activityBarForeground = theme.getColor(ACTIVITY_BAR_FOREGROUND); + if (activityBarForeground && !activityBarForeground.equals(Color.white)) { + // only apply this workaround if the color is different from the image one (white) + collector.addRule('.monaco-workbench .activitybar > .content .monaco-action-bar .action-label { will-change: transform; }'); + } + }); + }); + }); + }); + } + return $result.getHTMLElement(); } diff --git a/src/vs/workbench/services/configuration/node/configurationService.ts b/src/vs/workbench/services/configuration/node/configurationService.ts index 0ba296dc6db..b21ed903322 100644 --- a/src/vs/workbench/services/configuration/node/configurationService.ts +++ b/src/vs/workbench/services/configuration/node/configurationService.ts @@ -16,8 +16,8 @@ import { Queue } from 'vs/base/common/async'; import { stat, writeFile } from 'vs/base/node/pfs'; import { IJSONContributionRegistry, Extensions as JSONExtensions } from 'vs/platform/jsonschemas/common/jsonContributionRegistry'; import { IWorkspaceContextService, Workspace, WorkbenchState, IWorkspaceFolder, toWorkspaceFolders, IWorkspaceFoldersChangeEvent, WorkspaceFolder } from 'vs/platform/workspace/common/workspace'; +import { isLinux, isWindows, isMacintosh } from 'vs/base/common/platform'; import { IFileService } from 'vs/platform/files/common/files'; -import { isLinux } from 'vs/base/common/platform'; import { IEnvironmentService } from 'vs/platform/environment/common/environment'; import { ConfigurationChangeEvent, ConfigurationModel, DefaultConfigurationModel } from 'vs/platform/configuration/common/configurationModels'; import { IConfigurationChangeEvent, ConfigurationTarget, IConfigurationOverrides, keyFromOverrideIdentifier, isConfigurationOverrides, IConfigurationData } from 'vs/platform/configuration/common/configuration'; @@ -349,7 +349,19 @@ export class WorkspaceService extends Disposable implements IWorkspaceConfigurat if (folder.scheme === Schemas.file) { return stat(folder.fsPath) .then(workspaceStat => { - const ctime = isLinux ? workspaceStat.ino : workspaceStat.birthtime.getTime(); // On Linux, birthtime is ctime, so we cannot use it! We use the ino instead! + let ctime: number; + if (isLinux) { + ctime = workspaceStat.ino; // Linux: birthtime is ctime, so we cannot use it! We use the ino instead! + } else if (isMacintosh) { + ctime = workspaceStat.birthtime.getTime(); // macOS: birthtime is fine to use as is + } else if (isWindows) { + if (typeof workspaceStat.birthtimeMs === 'number') { + ctime = Math.floor(workspaceStat.birthtimeMs); // Windows: fix precision issue in node.js 8.x to get 7.x results (see https://github.com/nodejs/node/issues/19897) + } else { + ctime = workspaceStat.birthtime.getTime(); + } + } + const id = createHash('md5').update(folder.fsPath).update(ctime ? String(ctime) : '').digest('hex'); return new Workspace(id, getWorkspaceLabel(folder, this.environmentService), toWorkspaceFolders([{ path: folder.fsPath }]), null, ctime); }); diff --git a/src/vs/workbench/services/contextview/electron-browser/contextmenuService.ts b/src/vs/workbench/services/contextview/electron-browser/contextmenuService.ts index 8832ac16a31..c4fdf722b72 100644 --- a/src/vs/workbench/services/contextview/electron-browser/contextmenuService.ts +++ b/src/vs/workbench/services/contextview/electron-browser/contextmenuService.ts @@ -17,6 +17,7 @@ import { unmnemonicLabel } from 'vs/base/common/labels'; import { Event, Emitter } from 'vs/base/common/event'; import { INotificationService } from 'vs/platform/notification/common/notification'; import { IContextMenuDelegate, ContextSubMenu, IEvent } from 'vs/base/browser/contextmenu'; +import { once } from 'vs/base/common/functional'; import { Disposable } from 'vs/base/common/lifecycle'; export class ContextMenuService extends Disposable implements IContextMenuService { @@ -41,7 +42,15 @@ export class ContextMenuService extends Disposable implements IContextMenuServic } return TPromise.timeout(0).then(() => { // https://github.com/Microsoft/vscode/issues/3638 - const menu = this.createMenu(delegate, actions); + const onHide = once(() => { + if (delegate.onHide) { + delegate.onHide(undefined); + } + + this._onDidContextMenu.fire(); + }); + + const menu = this.createMenu(delegate, actions, onHide); const anchor = delegate.getAnchor(); let x: number, y: number; @@ -60,16 +69,18 @@ export class ContextMenuService extends Disposable implements IContextMenuServic x *= zoom; y *= zoom; - menu.popup(remote.getCurrentWindow(), { x: Math.floor(x), y: Math.floor(y), positioningItem: delegate.autoSelectFirstItem ? 0 : void 0 }); - this._onDidContextMenu.fire(); - if (delegate.onHide) { - delegate.onHide(undefined); - } + menu.popup({ + window: remote.getCurrentWindow(), + x: Math.floor(x), + y: Math.floor(y), + positioningItem: delegate.autoSelectFirstItem ? 0 : void 0, + callback: () => onHide() + }); }); }); } - private createMenu(delegate: IContextMenuDelegate, entries: (IAction | ContextSubMenu)[]): Electron.Menu { + private createMenu(delegate: IContextMenuDelegate, entries: (IAction | ContextSubMenu)[], onHide: () => void): Electron.Menu { const menu = new remote.Menu(); const actionRunner = delegate.actionRunner || new ActionRunner(); @@ -78,7 +89,7 @@ export class ContextMenuService extends Disposable implements IContextMenuServic menu.append(new remote.MenuItem({ type: 'separator' })); } else if (e instanceof ContextSubMenu) { const submenu = new remote.MenuItem({ - submenu: this.createMenu(delegate, e.entries), + submenu: this.createMenu(delegate, e.entries, onHide), label: unmnemonicLabel(e.label) }); @@ -90,6 +101,13 @@ export class ContextMenuService extends Disposable implements IContextMenuServic type: !!e.checked ? 'checkbox' : !!e.radio ? 'radio' : void 0, enabled: !!e.enabled, click: (menuItem, win, event) => { + + // To preserve pre-electron-2.x behaviour, we first trigger + // the onHide callback and then the action. + // Fixes https://github.com/Microsoft/vscode/issues/45601 + onHide(); + + // Run action which will close the menu this.runAction(actionRunner, e, delegate, event); } }; diff --git a/src/vs/workbench/services/extensions/electron-browser/extensionHost.ts b/src/vs/workbench/services/extensions/electron-browser/extensionHost.ts index 0b6dd68de6e..ab3dda8c90e 100644 --- a/src/vs/workbench/services/extensions/electron-browser/extensionHost.ts +++ b/src/vs/workbench/services/extensions/electron-browser/extensionHost.ts @@ -191,13 +191,13 @@ export class ExtensionHostProcessWorker { }, 100); // Print out extension host output - onDebouncedOutput(data => { - const inspectorUrlIndex = !this._environmentService.isBuilt && data.data && data.data.indexOf('chrome-devtools://'); - if (inspectorUrlIndex >= 0) { - console.log(`%c[Extension Host] %cdebugger inspector at ${data.data.substr(inspectorUrlIndex)}`, 'color: blue', 'color: black'); + onDebouncedOutput(output => { + const inspectorUrlMatch = !this._environmentService.isBuilt && output.data && output.data.match(/ws:\/\/([^\s]+)/); + if (inspectorUrlMatch) { + console.log(`%c[Extension Host] %cdebugger inspector at chrome-devtools://devtools/bundled/inspector.html?experiments=true&v8only=true&ws=${inspectorUrlMatch[1]}`, 'color: blue', 'color: black'); } else { console.group('Extension Host'); - console.log(data.data, ...data.format); + console.log(output.data, ...output.format); console.groupEnd(); } }); From 6d09e4ee0ff004ff237c332713be99f5c5fc7b00 Mon Sep 17 00:00:00 2001 From: Jackson Kearl Date: Mon, 23 Jul 2018 09:40:10 -0700 Subject: [PATCH 0041/1276] Ongoing migration to if/when --- .../html-language-features/package.json | 15 --- .../common/config/commonEditorConfig.ts | 66 +++-------- src/vs/editor/common/config/editorOptions.ts | 104 +++++++++--------- .../editor/common/controller/cursorCommon.ts | 9 +- .../controller/cursorDeleteOperations.ts | 18 ++- .../common/controller/cursorTypeOperations.ts | 5 +- .../telemetry/common/telemetryUtils.ts | 3 +- 7 files changed, 86 insertions(+), 134 deletions(-) diff --git a/extensions/html-language-features/package.json b/extensions/html-language-features/package.json index fbb31ac1ada..68a8807a3ff 100644 --- a/extensions/html-language-features/package.json +++ b/extensions/html-language-features/package.json @@ -171,21 +171,6 @@ } } }, - "configurationDefaults": { - "[html]": { - "editor.autoClosingQuotes": { - "autoClose": true, - "autoWrap": true, - "enabledBefore": "<> \n\t" - }, - "editor.autoClosingBrackets": { - "autoClose": true, - "autoWrap": true, - "enabledBefore": ",.:;<> \n\t" - } - } - } - }, "dependencies": { "vscode-extension-telemetry": "0.0.17", "vscode-languageclient": "^4.1.4", diff --git a/src/vs/editor/common/config/commonEditorConfig.ts b/src/vs/editor/common/config/commonEditorConfig.ts index 0b4c132c6cb..745de474cfc 100644 --- a/src/vs/editor/common/config/commonEditorConfig.ts +++ b/src/vs/editor/common/config/commonEditorConfig.ts @@ -488,62 +488,22 @@ const editorConfiguration: IConfigurationNode = { 'description': nls.localize('parameterHints', "Enables pop-up that shows parameter documentation and type information as you type") }, 'editor.autoClosingBrackets': { - 'anyOf': [ - { - type: 'boolean', - }, - { - type: 'object', - properties: { - autoClose: { - type: 'boolean', - default: EDITOR_DEFAULTS.autoClosingBrackets.autoClose, - description: nls.localize('autoClosingBrackets.autoClose', "Controls if the editor should automatically close brackets after opening them.") - }, - autoWrap: { - type: 'boolean', - default: EDITOR_DEFAULTS.autoClosingBrackets.autoWrap, - description: nls.localize('autoClosingBrackets.autoWrap', "Controls if the editor should automatically wrap selections in brackets.") - }, - enabledBefore: { - type: 'string', - default: EDITOR_DEFAULTS.autoClosingBrackets.enabledBefore, - description: nls.localize('autoClosingBrackets.enabledBefore', "List of all characters which the editor should allow bracket auto-closing before.") - } - } - } - ], + type: 'string', + enum: ['always', 'languageDefined', 'beforeWhitespace', 'never'], 'default': EDITOR_DEFAULTS.autoClosingBrackets, - 'description': nls.localize('autoClosingBrackets', "Controls if and when the editor should automatically close brackets after opening them") + 'description': nls.localize('autoClosingBrackets', "Controls if the editor should automatically close brackets after opening them. Can be:\n 'always' - always autoclose brackets\n 'languageDefined' - use installed extensions to determine when to autoclose brackets\n 'beforeWhitespace' - autoclose brackets only when the cursor is to the left of whitespace\n 'never' - never perform autoclosing on brackets") }, 'editor.autoClosingQuotes': { - 'anyOf': [ - { - type: 'boolean', - }, - { - type: 'object', - properties: { - autoClose: { - type: 'boolean', - default: EDITOR_DEFAULTS.autoClosingQuotes.autoClose, - description: nls.localize('autoClosingQuotes.autoClose', "Controls if the editor should automatically close quotes after opening them.") - }, - autoWrap: { - type: 'boolean', - default: EDITOR_DEFAULTS.autoClosingQuotes.autoWrap, - description: nls.localize('autoClosingQuotes.autoWrap', "Controls if the editor should automatically wrap selections in quotes.") - }, - enabledBefore: { - type: 'string', - default: EDITOR_DEFAULTS.autoClosingQuotes.enabledBefore, - description: nls.localize('autoClosingQuotes.enabledBefore', "List of all characters which the editor should allow quote auto-closing before.") - - } - } - } - ], 'default': EDITOR_DEFAULTS.autoClosingQuotes, - 'description': nls.localize('autoClosingQuotes', "Controls if and when the editor should automatically close quotes after opening them") + type: 'string', + enum: ['always', 'languageDefined', 'beforeWhitespace', 'never'], + 'default': EDITOR_DEFAULTS.autoClosingQuotes, + 'description': nls.localize('autoClosingQuotes', "Controls if the editor should automatically close quotes after opening them. Can be:\n 'always' - always autoclose quotes\n 'languageDefined' - use installed extensions to determine when to autoclose quotes\n 'beforeWhitespace' - autoclose quotes only when the cursor is to the left of whitespace\n 'never' - never perform autoclosing on quotes") + }, + 'editor.autoWrapping': { + type: 'string', + enum: ['always', 'brackets', 'quotes', 'never'], + 'default': EDITOR_DEFAULTS.autoWrapping, + 'description': nls.localize('autoWrapping', "Controls if the editor should automatically wrap selections. Can be:\n 'always' - wrap with both quotes and brackets,\n 'brackets' - wrap with brackets but not quotes,\n 'quotes' - wrap with quotes but not brackets,\n 'never' - do not autowrap selections") }, 'editor.formatOnType': { 'type': 'boolean', diff --git a/src/vs/editor/common/config/editorOptions.ts b/src/vs/editor/common/config/editorOptions.ts index 0a4bc02ff84..af1589bae6b 100644 --- a/src/vs/editor/common/config/editorOptions.ts +++ b/src/vs/editor/common/config/editorOptions.ts @@ -96,22 +96,14 @@ export interface IEditorFindOptions { } /** - * Configuration options for auto closing both quotes and brackets + * Configuration options for auto closing quotes and brackets */ -export interface EditorAutoClosingOptions { - /** - * Controls if we wrap selections with the auto-pairing character - */ - autoWrap: boolean; - /** - * Controls if we automatically insert a matching close to this pair - */ - autoClose: boolean; - /** - * controls the set of characters that we may insert a matching close before - */ - enabledBefore: string; -} +export type EditorAutoClosingStrategy = 'always' | 'languageDefined' | 'beforeWhitespace' | 'never'; + +/** + * Configuration options for auto wrapping quotes and brackets + */ +export type EditorAutoWrappingStrategy = 'always' | 'quotes' | 'brackets' | 'never'; /** * Configuration options for editor minimap @@ -479,14 +471,19 @@ export interface IEditorOptions { iconsInSuggestions?: boolean; /** * Options for auto closing brackets. - * Defaults to allowing auto-closing before whitespace and punctuation and allowing auto-wrapping always. + * Defaults to language defined behavior */ - autoClosingBrackets?: EditorAutoClosingOptions; + autoClosingBrackets?: EditorAutoClosingStrategy; /** * Options for auto closing quotes. - * Defaults to allowing auto-closing before whitespace and allowing auto-wrapping always. + * Defaults to language defined behavior */ - autoClosingQuotes?: EditorAutoClosingOptions; + autoClosingQuotes?: EditorAutoClosingStrategy; + /** + * Options for autowrapping + * Defaults to always allowing autowrapping + */ + autoWrapping?: EditorAutoWrappingStrategy; /** * Enable auto indentation adjustment. * Defaults to false. @@ -982,8 +979,9 @@ export interface IValidatedEditorOptions { readonly wordWrapBreakBeforeCharacters: string; readonly wordWrapBreakAfterCharacters: string; readonly wordWrapBreakObtrusiveCharacters: string; - readonly autoClosingBrackets: EditorAutoClosingOptions; - readonly autoClosingQuotes: EditorAutoClosingOptions; + readonly autoClosingBrackets: EditorAutoClosingStrategy; + readonly autoClosingQuotes: EditorAutoClosingStrategy; + readonly autoWrapping: EditorAutoWrappingStrategy; readonly autoIndent: boolean; readonly dragAndDrop: boolean; readonly emptySelectionClipboard: boolean; @@ -1018,8 +1016,9 @@ export class InternalEditorOptions { // ---- cursor options readonly wordSeparators: string; - readonly autoClosingBrackets: EditorAutoClosingOptions; - readonly autoClosingQuotes: EditorAutoClosingOptions; + readonly autoClosingBrackets: EditorAutoClosingStrategy; + readonly autoClosingQuotes: EditorAutoClosingStrategy; + readonly autoWrapping: EditorAutoWrappingStrategy; readonly autoIndent: boolean; readonly useTabStops: boolean; readonly tabFocusMode: boolean; @@ -1046,8 +1045,9 @@ export class InternalEditorOptions { multiCursorModifier: 'altKey' | 'ctrlKey' | 'metaKey'; multiCursorMergeOverlapping: boolean; wordSeparators: string; - autoClosingBrackets: EditorAutoClosingOptions; - autoClosingQuotes: EditorAutoClosingOptions; + autoClosingBrackets: EditorAutoClosingStrategy; + autoClosingQuotes: EditorAutoClosingStrategy; + autoWrapping: EditorAutoWrappingStrategy; autoIndent: boolean; useTabStops: boolean; tabFocusMode: boolean; @@ -1071,6 +1071,7 @@ export class InternalEditorOptions { this.wordSeparators = source.wordSeparators; this.autoClosingBrackets = source.autoClosingBrackets; this.autoClosingQuotes = source.autoClosingQuotes; + this.autoWrapping = source.autoWrapping; this.autoIndent = source.autoIndent; this.useTabStops = source.useTabStops; this.tabFocusMode = source.tabFocusMode; @@ -1098,6 +1099,9 @@ export class InternalEditorOptions { && this.multiCursorModifier === other.multiCursorModifier && this.multiCursorMergeOverlapping === other.multiCursorMergeOverlapping && this.wordSeparators === other.wordSeparators + && this.autoClosingBrackets === other.autoClosingBrackets + && this.autoClosingQuotes === other.autoClosingQuotes + && this.autoWrapping === other.autoWrapping && this.autoIndent === other.autoIndent && this.useTabStops === other.useTabStops && this.tabFocusMode === other.tabFocusMode @@ -1106,8 +1110,6 @@ export class InternalEditorOptions { && this.emptySelectionClipboard === other.emptySelectionClipboard && InternalEditorOptions._equalsLayoutInfo(this.layoutInfo, other.layoutInfo) && this.fontInfo.equals(other.fontInfo) - && InternalEditorOptions._equalsAutoClosingConfig(this.autoClosingBrackets, other.autoClosingBrackets) - && InternalEditorOptions._equalsAutoClosingConfig(this.autoClosingQuotes, other.autoClosingQuotes) && InternalEditorOptions._equalsViewOptions(this.viewInfo, other.viewInfo) && InternalEditorOptions._equalsWrappingInfo(this.wrappingInfo, other.wrappingInfo) && InternalEditorOptions._equalsContribOptions(this.contribInfo, other.contribInfo) @@ -1128,8 +1130,9 @@ export class InternalEditorOptions { multiCursorModifier: (this.multiCursorModifier !== newOpts.multiCursorModifier), multiCursorMergeOverlapping: (this.multiCursorMergeOverlapping !== newOpts.multiCursorMergeOverlapping), wordSeparators: (this.wordSeparators !== newOpts.wordSeparators), - autoClosingBrackets: (!InternalEditorOptions._equalsAutoClosingConfig(this.autoClosingBrackets, newOpts.autoClosingBrackets)), - autoClosingQuotes: (!InternalEditorOptions._equalsAutoClosingConfig(this.autoClosingQuotes, newOpts.autoClosingQuotes)), + autoClosingBrackets: (this.autoClosingBrackets !== newOpts.autoClosingBrackets), + autoClosingQuotes: (this.autoClosingQuotes !== newOpts.autoClosingQuotes), + autoWrapping: (this.autoWrapping !== newOpts.autoWrapping), autoIndent: (this.autoIndent !== newOpts.autoIndent), useTabStops: (this.useTabStops !== newOpts.useTabStops), tabFocusMode: (this.tabFocusMode !== newOpts.tabFocusMode), @@ -1172,17 +1175,6 @@ export class InternalEditorOptions { ); } - /** - * @internal - */ - private static _equalsAutoClosingConfig(a: EditorAutoClosingOptions, b: EditorAutoClosingOptions) { - return ( - a.autoClose === b.autoClose - && a.autoWrap === b.autoWrap - && a.enabledBefore === b.enabledBefore - ); - } - /** * @internal */ @@ -1513,6 +1505,7 @@ export interface IConfigurationChangedEvent { readonly wordSeparators: boolean; readonly autoClosingBrackets: boolean; readonly autoClosingQuotes: boolean; + readonly autoWrapping: boolean; readonly autoIndent: boolean; readonly useTabStops: boolean; readonly tabFocusMode: boolean; @@ -1678,16 +1671,6 @@ export class EditorOptionsValidator { wordWrap = _stringSet<'off' | 'on' | 'wordWrapColumn' | 'bounded'>(wordWrap, defaults.wordWrap, ['off', 'on', 'wordWrapColumn', 'bounded']); } - const _autoClosingOptions = (config: any, defaultValue: EditorAutoClosingOptions): EditorAutoClosingOptions => { - if (typeof config === 'boolean') { return { autoClose: config, autoWrap: config, enabledBefore: ' \t\n' }; } - if (!config) { config = {}; } - let copy: EditorAutoClosingOptions = { autoClose: defaultValue.autoClose, autoWrap: defaultValue.autoWrap, enabledBefore: defaultValue.enabledBefore }; - if (typeof config.autoClose === 'boolean') { copy.autoClose = config.autoClose; } - if (typeof config.autoWrap === 'boolean') { copy.autoWrap = config.autoWrap; } - if (typeof config.enabledBefore === 'string') { copy.enabledBefore = config.enabledBefore; } - return copy; - }; - const viewInfo = this._sanitizeViewInfo(opts, defaults.viewInfo); const contribInfo = this._sanitizeContribInfo(opts, defaults.contribInfo); @@ -1701,6 +1684,15 @@ export class EditorOptionsValidator { } const multiCursorModifier = _stringSet<'altKey' | 'metaKey' | 'ctrlKey'>(configuredMulticursorModifier, defaults.multiCursorModifier, ['altKey', 'metaKey', 'ctrlKey']); + let autoClosingBracketsDefault = defaults.autoClosingBrackets; + let autoClosingQuotesDefault = defaults.autoClosingQuotes; + let autoWrappingDefault = defaults.autoWrapping; + if (typeof (opts.autoClosingBrackets) === 'boolean' && opts.autoClosingBrackets === false) { + autoClosingBracketsDefault = 'never'; + autoClosingQuotesDefault = 'never'; + autoWrappingDefault = 'never'; + } + return { inDiffEditor: _boolean(opts.inDiffEditor, defaults.inDiffEditor), wordSeparators: _string(opts.wordSeparators, defaults.wordSeparators), @@ -1717,8 +1709,9 @@ export class EditorOptionsValidator { wordWrapBreakBeforeCharacters: _string(opts.wordWrapBreakBeforeCharacters, defaults.wordWrapBreakBeforeCharacters), wordWrapBreakAfterCharacters: _string(opts.wordWrapBreakAfterCharacters, defaults.wordWrapBreakAfterCharacters), wordWrapBreakObtrusiveCharacters: _string(opts.wordWrapBreakObtrusiveCharacters, defaults.wordWrapBreakObtrusiveCharacters), - autoClosingBrackets: _autoClosingOptions(opts.autoClosingBrackets, defaults.autoClosingBrackets), - autoClosingQuotes: _autoClosingOptions(opts.autoClosingQuotes, defaults.autoClosingQuotes), + autoClosingBrackets: _stringSet(opts.autoClosingBrackets, autoClosingBracketsDefault, ['always', 'languageDefined', 'beforeWhitespace', 'never']), + autoClosingQuotes: _stringSet(opts.autoClosingQuotes, autoClosingQuotesDefault, ['always', 'languageDefined', 'beforeWhitespace', 'never']), + autoWrapping: _stringSet(opts.autoWrapping, autoWrappingDefault, ['always', 'brackets', 'quotes', 'never'], ), autoIndent: _boolean(opts.autoIndent, defaults.autoIndent), dragAndDrop: _boolean(opts.dragAndDrop, defaults.dragAndDrop), emptySelectionClipboard: _boolean(opts.emptySelectionClipboard, defaults.emptySelectionClipboard), @@ -1992,6 +1985,7 @@ export class InternalEditorOptionsFactory { wordWrapBreakObtrusiveCharacters: opts.wordWrapBreakObtrusiveCharacters, autoClosingBrackets: opts.autoClosingBrackets, autoClosingQuotes: opts.autoClosingQuotes, + autoWrapping: opts.autoWrapping, autoIndent: opts.autoIndent, dragAndDrop: opts.dragAndDrop, emptySelectionClipboard: opts.emptySelectionClipboard, @@ -2214,6 +2208,7 @@ export class InternalEditorOptionsFactory { wordSeparators: opts.wordSeparators, autoClosingBrackets: opts.autoClosingBrackets, autoClosingQuotes: opts.autoClosingQuotes, + autoWrapping: opts.autoWrapping, autoIndent: opts.autoIndent, useTabStops: opts.useTabStops, tabFocusMode: opts.readOnly ? true : env.tabFocusMode, @@ -2446,8 +2441,9 @@ export const EDITOR_DEFAULTS: IValidatedEditorOptions = { wordWrapBreakBeforeCharacters: '([{‘“〈《「『【〔([{「£¥$£¥++', wordWrapBreakAfterCharacters: ' \t})]?|&,;¢°′″‰℃、。。、¢,.:;?!%・・ゝゞヽヾーァィゥェォッャュョヮヵヶぁぃぅぇぉっゃゅょゎゕゖㇰㇱㇲㇳㇴㇵㇶㇷㇸㇹㇺㇻㇼㇽㇾㇿ々〻ァィゥェォャュョッー”〉》」』】〕)]}」', wordWrapBreakObtrusiveCharacters: '.', - autoClosingBrackets: { autoClose: true, autoWrap: true, enabledBefore: ',.:; \n\t' }, - autoClosingQuotes: { autoClose: true, autoWrap: true, enabledBefore: ' \n\t' }, + autoClosingBrackets: 'languageDefined', + autoClosingQuotes: 'languageDefined', + autoWrapping: 'always', autoIndent: true, dragAndDrop: true, emptySelectionClipboard: true, diff --git a/src/vs/editor/common/controller/cursorCommon.ts b/src/vs/editor/common/controller/cursorCommon.ts index 0b570cee02b..7bb75ff5ef4 100644 --- a/src/vs/editor/common/controller/cursorCommon.ts +++ b/src/vs/editor/common/controller/cursorCommon.ts @@ -15,7 +15,7 @@ import { LanguageConfigurationRegistry } from 'vs/editor/common/modes/languageCo import { onUnexpectedError } from 'vs/base/common/errors'; import { LanguageIdentifier } from 'vs/editor/common/modes'; import { IAutoClosingPair } from 'vs/editor/common/modes/languageConfiguration'; -import { IConfigurationChangedEvent, EditorAutoClosingOptions } from 'vs/editor/common/config/editorOptions'; +import { IConfigurationChangedEvent, EditorAutoClosingStrategy, EditorAutoWrappingStrategy } from 'vs/editor/common/config/editorOptions'; import { IViewModel } from 'vs/editor/common/viewModel/viewModel'; import { CursorChangeReason } from 'vs/editor/common/controller/cursorEvents'; import { VerticalRevealType } from 'vs/editor/common/view/viewEvents'; @@ -79,8 +79,9 @@ export class CursorConfiguration { public readonly wordSeparators: string; public readonly emptySelectionClipboard: boolean; public readonly multiCursorMergeOverlapping: boolean; - public readonly autoClosingBrackets: EditorAutoClosingOptions; - public readonly autoClosingQuotes: EditorAutoClosingOptions; + public readonly autoClosingBrackets: EditorAutoClosingStrategy; + public readonly autoClosingQuotes: EditorAutoClosingStrategy; + public readonly autoWrapping: EditorAutoWrappingStrategy; public readonly autoIndent: boolean; public readonly autoClosingPairsOpen: CharacterMap; public readonly autoClosingPairsClose: CharacterMap; @@ -97,6 +98,7 @@ export class CursorConfiguration { || e.multiCursorMergeOverlapping || e.autoClosingBrackets || e.autoClosingQuotes + || e.autoWrapping || e.useTabStops || e.lineHeight || e.readOnly @@ -125,6 +127,7 @@ export class CursorConfiguration { this.multiCursorMergeOverlapping = c.multiCursorMergeOverlapping; this.autoClosingBrackets = c.autoClosingBrackets; this.autoClosingQuotes = c.autoClosingQuotes; + this.autoWrapping = c.autoWrapping; this.autoIndent = c.autoIndent; this.autoClosingPairsOpen = {}; diff --git a/src/vs/editor/common/controller/cursorDeleteOperations.ts b/src/vs/editor/common/controller/cursorDeleteOperations.ts index bdbc5db16c2..db03dfd11bd 100644 --- a/src/vs/editor/common/controller/cursorDeleteOperations.ts +++ b/src/vs/editor/common/controller/cursorDeleteOperations.ts @@ -49,8 +49,7 @@ export class DeleteOperations { } private static _isAutoClosingPairDelete(config: CursorConfiguration, model: ICursorSimpleModel, selections: Selection[]): boolean { - if (!(config.autoClosingBrackets.autoClose || config.autoClosingBrackets.autoWrap - || config.autoClosingQuotes.autoClose || config.autoClosingQuotes.autoWrap)) { + if (config.autoClosingBrackets === 'never' && config.autoClosingQuotes === 'never') { return false; } @@ -65,13 +64,20 @@ export class DeleteOperations { const lineText = model.getLineContent(position.lineNumber); const character = lineText[position.column - 2]; - const characterIsQuote = (character === '\'' || character === '"' || character === '`'); - const autoCloseConfig = characterIsQuote ? config.autoClosingQuotes : config.autoClosingBrackets; - - if (!config.autoClosingPairsOpen.hasOwnProperty(character) || !(autoCloseConfig.autoWrap || autoCloseConfig.autoClose)) { + if (!config.autoClosingPairsOpen.hasOwnProperty(character)) { return false; } + if (character === '\'' || character === '"' || character === '`') { + if (config.autoClosingQuotes === 'never') { + return false; + } + } else { + if (config.autoClosingBrackets === 'never') { + return false; + } + } + const afterCharacter = lineText[position.column - 1]; const closeCharacter = config.autoClosingPairsOpen[character]; diff --git a/src/vs/editor/common/controller/cursorTypeOperations.ts b/src/vs/editor/common/controller/cursorTypeOperations.ts index 2316812ca77..c31a7560305 100644 --- a/src/vs/editor/common/controller/cursorTypeOperations.ts +++ b/src/vs/editor/common/controller/cursorTypeOperations.ts @@ -440,7 +440,7 @@ export class TypeOperations { const chIsQuote = (ch === '\'' || ch === '"' || ch === '`'); const autoCloseConfig = chIsQuote ? config.autoClosingQuotes : config.autoClosingBrackets; - if (!autoCloseConfig.autoClose || !config.autoClosingPairsClose.hasOwnProperty(ch)) { + if (autoCloseConfig === 'never' || !config.autoClosingPairsClose.hasOwnProperty(ch)) { return false; } @@ -516,7 +516,8 @@ export class TypeOperations { private static _isAutoClosingOpenCharType(config: CursorConfiguration, model: ITextModel, selections: Selection[], ch: string): boolean { const chIsQuote = (ch === '\'' || ch === '"' || ch === '`'); const autoCloseConfig = chIsQuote ? config.autoClosingQuotes : config.autoClosingBrackets; - if (!autoCloseConfig.autoClose || !config.autoClosingPairsOpen.hasOwnProperty(ch)) { + + if (autoCloseConfig === 'never' || !config.autoClosingPairsOpen.hasOwnProperty(ch)) { return false; } diff --git a/src/vs/platform/telemetry/common/telemetryUtils.ts b/src/vs/platform/telemetry/common/telemetryUtils.ts index a17c613f296..2689bd9c503 100644 --- a/src/vs/platform/telemetry/common/telemetryUtils.ts +++ b/src/vs/platform/telemetry/common/telemetryUtils.ts @@ -115,7 +115,8 @@ const configurationValueWhitelist = [ 'editor.quickSuggestionsDelay', 'editor.parameterHints', 'editor.autoClosingBrackets', - 'editor.autoClosingEnabledBefore', + 'editor.autoClosingQuotes', + 'editor.autoWrapping', 'editor.autoIndent', 'editor.formatOnType', 'editor.formatOnPaste', From e6f82004c8723a380d5bc79a41e35ffeb4f9b924 Mon Sep 17 00:00:00 2001 From: Jackson Kearl Date: Mon, 23 Jul 2018 09:43:30 -0700 Subject: [PATCH 0042/1276] Fix html language json --- extensions/html-language-features/package.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/extensions/html-language-features/package.json b/extensions/html-language-features/package.json index 68a8807a3ff..c580436394f 100644 --- a/extensions/html-language-features/package.json +++ b/extensions/html-language-features/package.json @@ -170,7 +170,8 @@ "description": "%html.trace.server.desc%" } } - }, + } + }, "dependencies": { "vscode-extension-telemetry": "0.0.17", "vscode-languageclient": "^4.1.4", From bcf4c3185bebd4637e06d5b80bbbff5f2327ec66 Mon Sep 17 00:00:00 2001 From: Miguel Solorio Date: Mon, 23 Jul 2018 10:01:04 -0700 Subject: [PATCH 0043/1276] Add missing comma --- extensions/theme-defaults/themes/dark_defaults.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/extensions/theme-defaults/themes/dark_defaults.json b/extensions/theme-defaults/themes/dark_defaults.json index c2128772b36..87b37508468 100644 --- a/extensions/theme-defaults/themes/dark_defaults.json +++ b/extensions/theme-defaults/themes/dark_defaults.json @@ -11,7 +11,7 @@ "list.dropBackground": "#383B3D", "activityBarBadge.background": "#007ACC", "sideBarTitle.foreground": "#BBBBBB", - "input.placeholderForeground": "#A6A6A6" + "input.placeholderForeground": "#A6A6A6", "settings.textInputBackground": "#292929", "settings.numberInputBackground": "#292929" } From 2ae3deb731d691f9d004cd16699e6f719b7e043c Mon Sep 17 00:00:00 2001 From: Jackson Kearl Date: Mon, 23 Jul 2018 10:37:22 -0700 Subject: [PATCH 0044/1276] Second round implementation of autoclose config --- .../editor/common/controller/cursorCommon.ts | 24 +++++++++++++++++++ .../common/controller/cursorTypeOperations.ts | 21 ++++++++++------ .../modes/languageConfigurationRegistry.ts | 8 +++++++ .../common/modes/supports/characterPair.ts | 12 +++++++++- 4 files changed, 57 insertions(+), 8 deletions(-) diff --git a/src/vs/editor/common/controller/cursorCommon.ts b/src/vs/editor/common/controller/cursorCommon.ts index 7bb75ff5ef4..3eb11919f8d 100644 --- a/src/vs/editor/common/controller/cursorCommon.ts +++ b/src/vs/editor/common/controller/cursorCommon.ts @@ -20,6 +20,7 @@ import { IViewModel } from 'vs/editor/common/viewModel/viewModel'; import { CursorChangeReason } from 'vs/editor/common/controller/cursorEvents'; import { VerticalRevealType } from 'vs/editor/common/view/viewEvents'; import { TextModelResolvedOptions, ITextModel } from 'vs/editor/common/model'; +import { CharacterPairSupport } from 'vs/editor/common/modes/supports/characterPair'; export interface IColumnSelectData { toViewLineNumber: number; @@ -86,6 +87,7 @@ export class CursorConfiguration { public readonly autoClosingPairsOpen: CharacterMap; public readonly autoClosingPairsClose: CharacterMap; public readonly surroundingPairs: CharacterMap; + public readonly shouldAutoCloseBefore: { quote: (ch: string) => boolean, bracket: (ch: string) => boolean }; private readonly _languageIdentifier: LanguageIdentifier; private _electricChars: { [key: string]: boolean; }; @@ -135,6 +137,11 @@ export class CursorConfiguration { this.surroundingPairs = {}; this._electricChars = null; + this.shouldAutoCloseBefore = { + quote: CursorConfiguration._getShouldAutoclose(languageIdentifier, this.autoClosingQuotes), + bracket: CursorConfiguration._getShouldAutoclose(languageIdentifier, this.autoClosingBrackets) + }; + let autoClosingPairs = CursorConfiguration._getAutoClosingPairs(languageIdentifier); if (autoClosingPairs) { for (let i = 0; i < autoClosingPairs.length; i++) { @@ -186,6 +193,23 @@ export class CursorConfiguration { } } + private static _getShouldAutoclose(languageIdentifier: LanguageIdentifier, autoCloseConfig: EditorAutoClosingStrategy): (ch: string) => boolean { + let autoCloseBeforeSet = CursorConfiguration._getAutoCloseBeforeSet(languageIdentifier); + if (autoCloseConfig === 'beforeWhitespace') { return c => CharacterPairSupport.DEFAULT_AUTOCLOSE_BEFORE_WHITESPACE.indexOf(c) !== -1; } + if (autoCloseConfig === 'languageDefined') { return c => autoCloseBeforeSet.indexOf(c) !== -1; } + if (autoCloseConfig === 'always') { return c => true; } + return c => false; + } + + private static _getAutoCloseBeforeSet(languageIdentifier: LanguageIdentifier): string { + try { + return LanguageConfigurationRegistry.getAutoCloseBeforeSet(languageIdentifier.id); + } catch (e) { + onUnexpectedError(e); + return null; + } + } + private static _getSurroundingPairs(languageIdentifier: LanguageIdentifier): IAutoClosingPair[] { try { return LanguageConfigurationRegistry.getSurroundingPairs(languageIdentifier.id); diff --git a/src/vs/editor/common/controller/cursorTypeOperations.ts b/src/vs/editor/common/controller/cursorTypeOperations.ts index c31a7560305..1cab5adaa4f 100644 --- a/src/vs/editor/common/controller/cursorTypeOperations.ts +++ b/src/vs/editor/common/controller/cursorTypeOperations.ts @@ -19,6 +19,7 @@ import { SurroundSelectionCommand } from 'vs/editor/common/commands/surroundSele import { IElectricAction } from 'vs/editor/common/modes/supports/electricCharacter'; import { getMapForWordSeparators, WordCharacterClass } from 'vs/editor/common/controller/wordCharacterClassifier'; import { CharCode } from 'vs/base/common/charCode'; +import { CharacterPairSupport } from 'vs/editor/common/modes/supports/characterPair'; export class TypeOperations { @@ -521,6 +522,8 @@ export class TypeOperations { return false; } + let shouldAutoCloseBefore = chIsQuote ? config.shouldAutoCloseBefore.quote : config.shouldAutoCloseBefore.bracket; + for (let i = 0, len = selections.length; i < len; i++) { const selection = selections[i]; if (!selection.isEmpty()) { @@ -546,7 +549,7 @@ export class TypeOperations { if (characterAfter) { let isBeforeCloseBrace = TypeOperations._isBeforeClosingBrace(config, ch, characterAfter); - if (!isBeforeCloseBrace && autoCloseConfig.enabledBefore.indexOf(characterAfter) === -1) { + if (!(isBeforeCloseBrace || shouldAutoCloseBefore(characterAfter))) { return false; } } @@ -589,8 +592,12 @@ export class TypeOperations { private static _isSurroundSelectionType(config: CursorConfiguration, model: ITextModel, selections: Selection[], ch: string): boolean { const chIsQuote = (ch === '\'' || ch === '"' || ch === '`'); - const autoCloseConfig = chIsQuote ? config.autoClosingQuotes : config.autoClosingBrackets; - if (!autoCloseConfig.autoWrap || !config.surroundingPairs.hasOwnProperty(ch)) { + let autoWrapping = false; + if (chIsQuote && config.autoWrapping === 'quotes' || !chIsQuote && config.autoWrapping === 'brackets' || config.autoWrapping === 'always') { + autoWrapping = true; + } + + if (!autoWrapping || !config.surroundingPairs.hasOwnProperty(ch)) { return false; } @@ -716,7 +723,7 @@ export class TypeOperations { } public static compositionEndWithInterceptors(prevEditOperationType: EditOperationType, config: CursorConfiguration, model: ITextModel, selections: Selection[]): EditOperationResult { - if (!config.autoClosingQuotes.autoClose) { + if (config.autoClosingQuotes === 'never') { return null; } @@ -757,9 +764,9 @@ export class TypeOperations { if (characterAfter) { let isBeforeCloseBrace = TypeOperations._isBeforeClosingBrace(config, ch, characterAfter); - const chIsQuote = (ch === '\'' || ch === '"'); - const autoCloseConfig = chIsQuote ? config.autoClosingQuotes : config.autoClosingBrackets; - if (!autoCloseConfig.autoClose || (!isBeforeCloseBrace && autoCloseConfig.enabledBefore.indexOf(characterAfter) === -1)) { + const chIsQuote = (ch === '\'' || ch === '"' || ch === '`'); + let shouldAutoCloseBefore = chIsQuote ? config.shouldAutoCloseBefore.quote : config.shouldAutoCloseBefore.bracket; + if (!(isBeforeCloseBrace || shouldAutoCloseBefore(characterAfter))) { continue; } } diff --git a/src/vs/editor/common/modes/languageConfigurationRegistry.ts b/src/vs/editor/common/modes/languageConfigurationRegistry.ts index a184362fd69..65ab6f817c6 100644 --- a/src/vs/editor/common/modes/languageConfigurationRegistry.ts +++ b/src/vs/editor/common/modes/languageConfigurationRegistry.ts @@ -271,6 +271,14 @@ export class LanguageConfigurationRegistryImpl { return characterPairSupport.getAutoClosingPairs(); } + public getAutoCloseBeforeSet(languageId: LanguageId): string { + let characterPairSupport = this._getCharacterPairSupport(languageId); + if (!characterPairSupport) { + return CharacterPairSupport.DEFAULT_AUTOCLOSE_BEFORE_LANGAGE_DEFINED; + } + return characterPairSupport.getAutoCloseBeforeSet(); + } + public getSurroundingPairs(languageId: LanguageId): IAutoClosingPair[] { let characterPairSupport = this._getCharacterPairSupport(languageId); if (!characterPairSupport) { diff --git a/src/vs/editor/common/modes/supports/characterPair.ts b/src/vs/editor/common/modes/supports/characterPair.ts index b6ce3dc3f35..f437f6b139e 100644 --- a/src/vs/editor/common/modes/supports/characterPair.ts +++ b/src/vs/editor/common/modes/supports/characterPair.ts @@ -9,10 +9,14 @@ import { CharacterPair, IAutoClosingPair, IAutoClosingPairConditional, StandardA export class CharacterPairSupport { + static readonly DEFAULT_AUTOCLOSE_BEFORE_LANGAGE_DEFINED = ';:.,=}])> \n\t'; + static readonly DEFAULT_AUTOCLOSE_BEFORE_WHITESPACE = ' \n\t'; + private readonly _autoClosingPairs: StandardAutoClosingPairConditional[]; private readonly _surroundingPairs: IAutoClosingPair[]; + private readonly _autoCloseBefore: string; - constructor(config: { brackets?: CharacterPair[]; autoClosingPairs?: IAutoClosingPairConditional[], surroundingPairs?: IAutoClosingPair[] }) { + constructor(config: { brackets?: CharacterPair[]; autoClosingPairs?: IAutoClosingPairConditional[], surroundingPairs?: IAutoClosingPair[], autoCloseBefore?: string }) { if (config.autoClosingPairs) { this._autoClosingPairs = config.autoClosingPairs.map(el => new StandardAutoClosingPairConditional(el)); } else if (config.brackets) { @@ -21,6 +25,8 @@ export class CharacterPairSupport { this._autoClosingPairs = []; } + this._autoCloseBefore = typeof config.autoCloseBefore === 'string' ? config.autoCloseBefore : CharacterPairSupport.DEFAULT_AUTOCLOSE_BEFORE_LANGAGE_DEFINED; + this._surroundingPairs = config.surroundingPairs || this._autoClosingPairs; } @@ -28,6 +34,10 @@ export class CharacterPairSupport { return this._autoClosingPairs; } + public getAutoCloseBeforeSet(): string { + return this._autoCloseBefore; + } + public shouldAutoClosePair(character: string, context: ScopedLineTokens, column: number): boolean { // Always complete on empty line if (context.getTokenCount() === 0) { From 048e5be700902162f533d4715f9d66cd9510ea01 Mon Sep 17 00:00:00 2001 From: Jackson Kearl Date: Mon, 23 Jul 2018 10:44:11 -0700 Subject: [PATCH 0045/1276] Recreate monaco.d.ts --- src/vs/monaco.d.ts | 41 ++++++++++++++++++++--------------------- 1 file changed, 20 insertions(+), 21 deletions(-) diff --git a/src/vs/monaco.d.ts b/src/vs/monaco.d.ts index c0c0e121e8d..34cb166d5ff 100644 --- a/src/vs/monaco.d.ts +++ b/src/vs/monaco.d.ts @@ -2446,22 +2446,14 @@ declare namespace monaco.editor { } /** - * Configuration options for auto closing both quotes and brackets + * Configuration options for auto closing quotes and brackets */ - export interface EditorAutoClosingOptions { - /** - * Controls if we wrap selections with the auto-pairing character - */ - autoWrap: boolean; - /** - * Controls if we automatically insert a matching close to this pair - */ - autoClose: boolean; - /** - * controls the set of characters that we may insert a matching close before - */ - enabledBefore: string; - } + export type EditorAutoClosingStrategy = 'always' | 'languageDefined' | 'beforeWhitespace' | 'never'; + + /** + * Configuration options for auto wrapping quotes and brackets + */ + export type EditorAutoWrappingStrategy = 'always' | 'quotes' | 'brackets' | 'never'; /** * Configuration options for editor minimap @@ -2821,14 +2813,19 @@ declare namespace monaco.editor { iconsInSuggestions?: boolean; /** * Options for auto closing brackets. - * Defaults to allowing auto-closing before whitespace and punctuation and allowing auto-wrapping always. + * Defaults to language defined behavior */ - autoClosingBrackets?: EditorAutoClosingOptions; + autoClosingBrackets?: EditorAutoClosingStrategy; /** * Options for auto closing quotes. - * Defaults to allowing auto-closing before whitespace and allowing auto-wrapping always. + * Defaults to language defined behavior */ - autoClosingQuotes?: EditorAutoClosingOptions; + autoClosingQuotes?: EditorAutoClosingStrategy; + /** + * Options for autowrapping + * Defaults to always allowing autowrapping + */ + autoWrapping?: EditorAutoWrappingStrategy; /** * Enable auto indentation adjustment. * Defaults to false. @@ -3257,8 +3254,9 @@ declare namespace monaco.editor { readonly multiCursorMergeOverlapping: boolean; readonly showUnused: boolean; readonly wordSeparators: string; - readonly autoClosingBrackets: EditorAutoClosingOptions; - readonly autoClosingQuotes: EditorAutoClosingOptions; + readonly autoClosingBrackets: EditorAutoClosingStrategy; + readonly autoClosingQuotes: EditorAutoClosingStrategy; + readonly autoWrapping: EditorAutoWrappingStrategy; readonly autoIndent: boolean; readonly useTabStops: boolean; readonly tabFocusMode: boolean; @@ -3398,6 +3396,7 @@ declare namespace monaco.editor { readonly wordSeparators: boolean; readonly autoClosingBrackets: boolean; readonly autoClosingQuotes: boolean; + readonly autoWrapping: boolean; readonly autoIndent: boolean; readonly useTabStops: boolean; readonly tabFocusMode: boolean; From db87479e9204f976731442bf77f350bd8239876c Mon Sep 17 00:00:00 2001 From: Jackson Kearl Date: Mon, 23 Jul 2018 10:54:54 -0700 Subject: [PATCH 0046/1276] Update tests --- .../common/controller/cursorTypeOperations.ts | 1 - .../test/browser/controller/cursor.test.ts | 81 ++++++++++++++----- 2 files changed, 61 insertions(+), 21 deletions(-) diff --git a/src/vs/editor/common/controller/cursorTypeOperations.ts b/src/vs/editor/common/controller/cursorTypeOperations.ts index 1cab5adaa4f..72546cb0c00 100644 --- a/src/vs/editor/common/controller/cursorTypeOperations.ts +++ b/src/vs/editor/common/controller/cursorTypeOperations.ts @@ -19,7 +19,6 @@ import { SurroundSelectionCommand } from 'vs/editor/common/commands/surroundSele import { IElectricAction } from 'vs/editor/common/modes/supports/electricCharacter'; import { getMapForWordSeparators, WordCharacterClass } from 'vs/editor/common/controller/wordCharacterClassifier'; import { CharCode } from 'vs/base/common/charCode'; -import { CharacterPairSupport } from 'vs/editor/common/modes/supports/characterPair'; export class TypeOperations { diff --git a/src/vs/editor/test/browser/controller/cursor.test.ts b/src/vs/editor/test/browser/controller/cursor.test.ts index be832003143..ead2a6e5b21 100644 --- a/src/vs/editor/test/browser/controller/cursor.test.ts +++ b/src/vs/editor/test/browser/controller/cursor.test.ts @@ -3947,6 +3947,21 @@ suite('autoClosingPairs', () => { ], })); } + + public setAutocloseEnabledSet(chars: string) { + this._register(LanguageConfigurationRegistry.register(this.getLanguageIdentifier(), { + autoCloseBefore: chars, + autoClosingPairs: [ + { open: '{', close: '}' }, + { open: '[', close: ']' }, + { open: '(', close: ')' }, + { open: '\'', close: '\'', notIn: ['string', 'comment'] }, + { open: '\"', close: '\"', notIn: ['string'] }, + { open: '`', close: '`', notIn: ['string', 'comment'] }, + { open: '/**', close: ' */', notIn: ['string'] } + ], + })); + } } const enum ColumnType { @@ -4028,6 +4043,7 @@ suite('autoClosingPairs', () => { test('configurable open parens', () => { let mode = new AutoClosingMode(); + mode.setAutocloseEnabledSet('abc'); usingCursor({ text: [ 'var a = [];', @@ -4041,11 +4057,7 @@ suite('autoClosingPairs', () => { ], languageIdentifier: mode.getLanguageIdentifier(), editorOpts: { - autoClosingBrackets: { - enabledBefore: 'abc', - autoClose: true, - autoWrap: true - } + autoClosingBrackets: 'languageDefined' } }, (model, cursor) => { @@ -4091,16 +4103,8 @@ suite('autoClosingPairs', () => { ], languageIdentifier: mode.getLanguageIdentifier(), editorOpts: { - autoClosingBrackets: { - enabledBefore: 'abc', - autoClose: false, - autoWrap: true - }, - autoClosingQuotes: { - enabledBefore: 'abc', - autoClose: false, - autoWrap: true - } + autoClosingBrackets: 'never', + autoClosingQuotes: 'never' } }, (model, cursor) => { @@ -4152,17 +4156,14 @@ suite('autoClosingPairs', () => { assert.equal(model.getValue(), '`var` a = `asd`'); }); + usingCursor({ text: [ 'var a = asd' ], languageIdentifier: mode.getLanguageIdentifier(), editorOpts: { - autoClosingQuotes: { - autoWrap: false, - autoClose: true, - enabledBefore: '' - } + autoWrapping: 'never' } }, (model, cursor) => { @@ -4175,6 +4176,46 @@ suite('autoClosingPairs', () => { assert.equal(model.getValue(), '` a = asd'); }); + + usingCursor({ + text: [ + 'var a = asd' + ], + languageIdentifier: mode.getLanguageIdentifier(), + editorOpts: { + autoWrapping: 'quotes' + } + }, (model, cursor) => { + + cursor.setSelections('test', [ + new Selection(1, 1, 1, 4), + ]); + + // type a ` + cursorCommand(cursor, H.Type, { text: '`' }, 'keyboard'); + + assert.equal(model.getValue(), '`var` a = asd'); + }); + + usingCursor({ + text: [ + 'var a = asd' + ], + languageIdentifier: mode.getLanguageIdentifier(), + editorOpts: { + autoWrapping: 'brackets' + } + }, (model, cursor) => { + + cursor.setSelections('test', [ + new Selection(1, 1, 1, 4), + ]); + + // type a ` + cursorCommand(cursor, H.Type, { text: '(' }, 'keyboard'); + + assert.equal(model.getValue(), '(var) a = asd'); + }); mode.dispose(); }); From 108190fa1ade0f27a54834f8b3f0fcf27f40e3a7 Mon Sep 17 00:00:00 2001 From: SteVen Batten <6561887+sbatten@users.noreply.github.com> Date: Mon, 23 Jul 2018 10:55:48 -0700 Subject: [PATCH 0047/1276] remove unused code --- src/vs/code/electron-main/keyboard.ts | 114 +- src/vs/code/electron-main/menubar.ts | 18 +- src/vs/code/electron-main/menus.ts | 1312 ------------------- src/vs/workbench/electron-browser/window.ts | 47 - 4 files changed, 4 insertions(+), 1487 deletions(-) delete mode 100644 src/vs/code/electron-main/menus.ts diff --git a/src/vs/code/electron-main/keyboard.ts b/src/vs/code/electron-main/keyboard.ts index ecd7e284db6..9400d80b5a1 100644 --- a/src/vs/code/electron-main/keyboard.ts +++ b/src/vs/code/electron-main/keyboard.ts @@ -7,14 +7,7 @@ import * as nativeKeymap from 'native-keymap'; import { IDisposable } from 'vs/base/common/lifecycle'; -import { IStateService } from 'vs/platform/state/common/state'; -import { Event, Emitter, once } from 'vs/base/common/event'; -import { ConfigWatcher } from 'vs/base/node/config'; -import { IUserFriendlyKeybinding } from 'vs/platform/keybinding/common/keybinding'; -import { IEnvironmentService } from 'vs/platform/environment/common/environment'; -import { ipcMain as ipc } from 'electron'; -import { IWindowsMainService } from 'vs/platform/windows/electron-main/windows'; -import { ILogService } from 'vs/platform/log/common/log'; +import { Emitter } from 'vs/base/common/event'; export class KeyboardLayoutMonitor { @@ -38,109 +31,4 @@ export class KeyboardLayoutMonitor { } return this._emitter.event(callback); } -} - -export interface IKeybinding { - id: string; - label: string; - isNative: boolean; -} - -export class KeybindingsResolver { - - private static readonly lastKnownKeybindingsMapStorageKey = 'lastKnownKeybindings'; - - private commandIds: Set; - private keybindings: { [commandId: string]: IKeybinding }; - private keybindingsWatcher: ConfigWatcher; - - private _onKeybindingsChanged = new Emitter(); - onKeybindingsChanged: Event = this._onKeybindingsChanged.event; - - constructor( - @IStateService private stateService: IStateService, - @IEnvironmentService environmentService: IEnvironmentService, - @IWindowsMainService private windowsMainService: IWindowsMainService, - @ILogService private logService: ILogService - ) { - this.commandIds = new Set(); - this.keybindings = this.stateService.getItem<{ [id: string]: string; }>(KeybindingsResolver.lastKnownKeybindingsMapStorageKey) || Object.create(null); - this.keybindingsWatcher = new ConfigWatcher(environmentService.appKeybindingsPath, { changeBufferDelay: 100, onError: error => this.logService.error(error) }); - - this.registerListeners(); - } - - private registerListeners(): void { - - // Listen to resolved keybindings from window - ipc.on('vscode:keybindingsResolved', (event, rawKeybindings: string) => { - let keybindings: IKeybinding[] = []; - try { - keybindings = JSON.parse(rawKeybindings); - } catch (error) { - // Should not happen - } - - // Fill hash map of resolved keybindings and check for changes - let keybindingsChanged = false; - let keybindingsCount = 0; - const resolvedKeybindings: { [commandId: string]: IKeybinding } = Object.create(null); - keybindings.forEach(keybinding => { - keybindingsCount++; - - resolvedKeybindings[keybinding.id] = keybinding; - - if (!this.keybindings[keybinding.id] || keybinding.label !== this.keybindings[keybinding.id].label) { - keybindingsChanged = true; - } - }); - - // A keybinding might have been unassigned, so we have to account for that too - if (Object.keys(this.keybindings).length !== keybindingsCount) { - keybindingsChanged = true; - } - - if (keybindingsChanged) { - this.keybindings = resolvedKeybindings; - this.stateService.setItem(KeybindingsResolver.lastKnownKeybindingsMapStorageKey, this.keybindings); // keep to restore instantly after restart - - this._onKeybindingsChanged.fire(); - } - }); - - // Resolve keybindings when any first window is loaded - const onceOnWindowReady = once(this.windowsMainService.onWindowReady); - onceOnWindowReady(win => this.resolveKeybindings(win)); - - // Resolve keybindings again when keybindings.json changes - this.keybindingsWatcher.onDidUpdateConfiguration(() => this.resolveKeybindings()); - - // Resolve keybindings when window reloads because an installed extension could have an impact - this.windowsMainService.onWindowReload(() => this.resolveKeybindings()); - } - - private resolveKeybindings(win = this.windowsMainService.getLastActiveWindow()): void { - if (this.commandIds.size && win) { - const commandIds: string[] = []; - this.commandIds.forEach(id => commandIds.push(id)); - win.sendWhenReady('vscode:resolveKeybindings', JSON.stringify(commandIds)); - } - } - - public getKeybinding(commandId: string): IKeybinding { - if (!commandId) { - return void 0; - } - - if (!this.commandIds.has(commandId)) { - this.commandIds.add(commandId); - } - - return this.keybindings[commandId]; - } - - public dispose(): void { - this._onKeybindingsChanged.dispose(); - this.keybindingsWatcher.dispose(); - } } \ No newline at end of file diff --git a/src/vs/code/electron-main/menubar.ts b/src/vs/code/electron-main/menubar.ts index d9479c68031..69850febf6b 100644 --- a/src/vs/code/electron-main/menubar.ts +++ b/src/vs/code/electron-main/menubar.ts @@ -17,16 +17,10 @@ import product from 'vs/platform/node/product'; import { RunOnceScheduler } from 'vs/base/common/async'; import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; import { mnemonicMenuLabel as baseMnemonicLabel, unmnemonicLabel, getPathLabel } from 'vs/base/common/labels'; -import { IKeybinding } from 'vs/code/electron-main/keyboard'; import { IWindowsMainService, IWindowsCountChangedEvent } from 'vs/platform/windows/electron-main/windows'; import { IHistoryMainService } from 'vs/platform/history/common/history'; import { IWorkspaceIdentifier, getWorkspaceLabel, ISingleFolderWorkspaceIdentifier, isSingleFolderWorkspaceIdentifier } from 'vs/platform/workspaces/common/workspaces'; -import { IMenubarData, isMenubarMenuItemSeparator, isMenubarMenuItemSubmenu, isMenubarMenuItemAction, MenubarMenuItem } from 'vs/platform/menubar/common/menubar'; - -// interface IExtensionViewlet { -// id: string; -// label: string; -// } +import { IMenubarData, isMenubarMenuItemSeparator, isMenubarMenuItemSubmenu, isMenubarMenuItemAction, MenubarMenuItem, IMenubarKeybinding } from 'vs/platform/menubar/common/menubar'; const telemetryFrom = 'menu'; @@ -42,7 +36,7 @@ export class Menubar { private menubarMenus: IMenubarData = {}; - private keybindings: { [commandId: string]: IKeybinding }; + private keybindings: { [commandId: string]: IMenubarKeybinding }; constructor( @IUpdateService private updateService: IUpdateService, @@ -53,11 +47,8 @@ export class Menubar { @ITelemetryService private telemetryService: ITelemetryService, @IHistoryMainService private historyMainService: IHistoryMainService ) { - // this.extensionViewlets = []; - // this.nativeTabMenuItems = []; - this.menuUpdater = new RunOnceScheduler(() => this.doUpdateMenu(), 0); - // this.keybindingsResolver = instantiationService.createInstance(KeybindingsResolver); + this.keybindings = Object.create(null); this.install(); @@ -99,9 +90,6 @@ export class Menubar { // Listen to update service // this.updateService.onStateChange(() => this.updateMenu()); - - // Listen to keybindings change - // this.keybindingsResolver.onKeybindingsChanged(() => this.scheduleUpdateMenu()); } private get currentEnableMenuBarMnemonics(): boolean { diff --git a/src/vs/code/electron-main/menus.ts b/src/vs/code/electron-main/menus.ts deleted file mode 100644 index 4c5a22871d8..00000000000 --- a/src/vs/code/electron-main/menus.ts +++ /dev/null @@ -1,1312 +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'; - -import * as nls from 'vs/nls'; -import { isMacintosh, isLinux, isWindows, language } from 'vs/base/common/platform'; -import * as arrays from 'vs/base/common/arrays'; -import { IEnvironmentService } from 'vs/platform/environment/common/environment'; -import { app, shell, Menu, MenuItem, BrowserWindow } from 'electron'; -import { OpenContext, IRunActionInWindowRequest, IWindowsService } from 'vs/platform/windows/common/windows'; -import { IConfigurationService, IConfigurationChangeEvent } from 'vs/platform/configuration/common/configuration'; -import { AutoSaveConfiguration } from 'vs/platform/files/common/files'; -import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry'; -import { IUpdateService, StateType } from 'vs/platform/update/common/update'; -import product from 'vs/platform/node/product'; -import { RunOnceScheduler } from 'vs/base/common/async'; -import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; -import { mnemonicMenuLabel as baseMnemonicLabel, unmnemonicLabel, getPathLabel } from 'vs/base/common/labels'; -import { KeybindingsResolver } from 'vs/code/electron-main/keyboard'; -import { IWindowsMainService, IWindowsCountChangedEvent } from 'vs/platform/windows/electron-main/windows'; -import { IHistoryMainService } from 'vs/platform/history/common/history'; -import { IWorkspaceIdentifier, getWorkspaceLabel, ISingleFolderWorkspaceIdentifier, isSingleFolderWorkspaceIdentifier } from 'vs/platform/workspaces/common/workspaces'; - -interface IMenuItemClickHandler { - inDevTools: (contents: Electron.WebContents) => void; - inNoWindow: () => void; -} - -const telemetryFrom = 'menu'; - -export class CodeMenu { - - private static readonly MAX_MENU_RECENT_ENTRIES = 10; - - private keys = [ - 'files.autoSave', - 'editor.multiCursorModifier', - 'workbench.sideBar.location', - 'workbench.statusBar.visible', - 'workbench.activityBar.visible', - 'window.enableMenuBarMnemonics', - 'window.nativeTabs' - ]; - - private isQuitting: boolean; - private appMenuInstalled: boolean; - - private menuUpdater: RunOnceScheduler; - - private keybindingsResolver: KeybindingsResolver; - - private closeFolder: Electron.MenuItem; - private closeWorkspace: Electron.MenuItem; - - private nativeTabMenuItems: Electron.MenuItem[]; - - constructor( - @IUpdateService private updateService: IUpdateService, - @IInstantiationService instantiationService: IInstantiationService, - @IConfigurationService private configurationService: IConfigurationService, - @IWindowsMainService private windowsMainService: IWindowsMainService, - @IWindowsService private windowsService: IWindowsService, - @IEnvironmentService private environmentService: IEnvironmentService, - @ITelemetryService private telemetryService: ITelemetryService, - @IHistoryMainService private historyMainService: IHistoryMainService - ) { - this.nativeTabMenuItems = []; - - this.menuUpdater = new RunOnceScheduler(() => this.doUpdateMenu(), 0); - this.keybindingsResolver = instantiationService.createInstance(KeybindingsResolver); - - this.install(); - - this.registerListeners(); - } - - private registerListeners(): void { - - // Keep flag when app quits - app.on('will-quit', () => { - this.isQuitting = true; - }); - - // Listen to some events from window service to update menu - this.historyMainService.onRecentlyOpenedChange(() => this.updateMenu()); - this.windowsMainService.onWindowsCountChanged(e => this.onWindowsCountChanged(e)); - this.windowsMainService.onActiveWindowChanged(() => this.updateWorkspaceMenuItems()); - this.windowsMainService.onWindowReady(() => this.updateWorkspaceMenuItems()); - this.windowsMainService.onWindowClose(() => this.updateWorkspaceMenuItems()); - - // Update when auto save config changes - this.configurationService.onDidChangeConfiguration(e => this.onConfigurationUpdated(e)); - - // Listen to update service - this.updateService.onStateChange(() => this.updateMenu()); - - // Listen to keybindings change - this.keybindingsResolver.onKeybindingsChanged(() => this.updateMenu()); - } - - private onConfigurationUpdated(event: IConfigurationChangeEvent): void { - if (this.keys.some(key => event.affectsConfiguration(key))) { - this.updateMenu(); - } - } - - private get currentAutoSaveSetting(): string { - return this.configurationService.getValue('files.autoSave'); - } - - private get currentMultiCursorModifierSetting(): string { - return this.configurationService.getValue('editor.multiCursorModifier'); - } - - private get currentSidebarLocation(): string { - return this.configurationService.getValue('workbench.sideBar.location') || 'left'; - } - - private get currentStatusbarVisible(): boolean { - let statusbarVisible = this.configurationService.getValue('workbench.statusBar.visible'); - if (typeof statusbarVisible !== 'boolean') { - statusbarVisible = true; - } - return statusbarVisible; - } - - private get currentActivityBarVisible(): boolean { - let activityBarVisible = this.configurationService.getValue('workbench.activityBar.visible'); - if (typeof activityBarVisible !== 'boolean') { - activityBarVisible = true; - } - return activityBarVisible; - } - - private get currentEnableMenuBarMnemonics(): boolean { - let enableMenuBarMnemonics = this.configurationService.getValue('window.enableMenuBarMnemonics'); - if (typeof enableMenuBarMnemonics !== 'boolean') { - enableMenuBarMnemonics = true; - } - return enableMenuBarMnemonics; - } - - private get currentEnableNativeTabs(): boolean { - let enableNativeTabs = this.configurationService.getValue('window.nativeTabs'); - if (typeof enableNativeTabs !== 'boolean') { - enableNativeTabs = false; - } - return enableNativeTabs; - } - - private updateMenu(): void { - this.menuUpdater.schedule(); // buffer multiple attempts to update the menu - } - - private doUpdateMenu(): void { - - // Due to limitations in Electron, it is not possible to update menu items dynamically. The suggested - // workaround from Electron is to set the application menu again. - // See also https://github.com/electron/electron/issues/846 - // - // Run delayed to prevent updating menu while it is open - if (!this.isQuitting) { - setTimeout(() => { - if (!this.isQuitting) { - this.install(); - } - }, 10 /* delay this because there is an issue with updating a menu when it is open */); - } - } - - private onWindowsCountChanged(e: IWindowsCountChangedEvent): void { - if (!isMacintosh) { - return; - } - - // Update menu if window count goes from N > 0 or 0 > N to update menu item enablement - if ((e.oldCount === 0 && e.newCount > 0) || (e.oldCount > 0 && e.newCount === 0)) { - this.updateMenu(); - } - - // Update specific items that are dependent on window count - else if (this.currentEnableNativeTabs) { - this.nativeTabMenuItems.forEach(item => { - if (item) { - item.enabled = e.newCount > 1; - } - }); - } - } - - private updateWorkspaceMenuItems(): void { - const window = this.windowsMainService.getLastActiveWindow(); - const isInWorkspaceContext = window && !!window.openedWorkspace; - const isInFolderContext = window && !!window.openedFolderPath; - - this.closeWorkspace.visible = isInWorkspaceContext; - this.closeFolder.visible = !isInWorkspaceContext; - this.closeFolder.enabled = isInFolderContext || isLinux /* https://github.com/Microsoft/vscode/issues/36431 */; - } - - private install(): void { - - // Menus - const menubar = new Menu(); - - // Mac: Application - let macApplicationMenuItem: Electron.MenuItem; - if (isMacintosh) { - const applicationMenu = new Menu(); - macApplicationMenuItem = new MenuItem({ label: product.nameShort, submenu: applicationMenu }); - this.setMacApplicationMenu(applicationMenu); - } - - // File - const fileMenu = new Menu(); - const fileMenuItem = new MenuItem({ label: this.mnemonicLabel(nls.localize({ key: 'mFile', comment: ['&& denotes a mnemonic'] }, "&&File")), submenu: fileMenu }); - this.setFileMenu(fileMenu); - - // Edit - const editMenu = new Menu(); - const editMenuItem = new MenuItem({ label: this.mnemonicLabel(nls.localize({ key: 'mEdit', comment: ['&& denotes a mnemonic'] }, "&&Edit")), submenu: editMenu }); - this.setEditMenu(editMenu); - - // Selection - const selectionMenu = new Menu(); - const selectionMenuItem = new MenuItem({ label: this.mnemonicLabel(nls.localize({ key: 'mSelection', comment: ['&& denotes a mnemonic'] }, "&&Selection")), submenu: selectionMenu }); - this.setSelectionMenu(selectionMenu); - - // View - const viewMenu = new Menu(); - const viewMenuItem = new MenuItem({ label: this.mnemonicLabel(nls.localize({ key: 'mView', comment: ['&& denotes a mnemonic'] }, "&&View")), submenu: viewMenu }); - this.setViewMenu(viewMenu); - - // Goto - const gotoMenu = new Menu(); - const gotoMenuItem = new MenuItem({ label: this.mnemonicLabel(nls.localize({ key: 'mGoto', comment: ['&& denotes a mnemonic'] }, "&&Go")), submenu: gotoMenu }); - this.setGotoMenu(gotoMenu); - - // Terminal - const terminalMenu = new Menu(); - const terminalMenuItem = new MenuItem({ label: this.mnemonicLabel(nls.localize({ key: 'mTerminal', comment: ['&& denotes a mnemonic'] }, "Ter&&minal")), submenu: terminalMenu }); - this.setTerminalMenu(terminalMenu); - - // Debug - const debugMenu = new Menu(); - const debugMenuItem = new MenuItem({ label: this.mnemonicLabel(nls.localize({ key: 'mDebug', comment: ['&& denotes a mnemonic'] }, "&&Debug")), submenu: debugMenu }); - this.setDebugMenu(debugMenu); - - // Mac: Window - let macWindowMenuItem: Electron.MenuItem; - if (isMacintosh) { - const windowMenu = new Menu(); - macWindowMenuItem = new MenuItem({ label: this.mnemonicLabel(nls.localize('mWindow', "Window")), submenu: windowMenu, role: 'window' }); - this.setMacWindowMenu(windowMenu); - } - - // Help - const helpMenu = new Menu(); - const helpMenuItem = new MenuItem({ label: this.mnemonicLabel(nls.localize({ key: 'mHelp', comment: ['&& denotes a mnemonic'] }, "&&Help")), submenu: helpMenu, role: 'help' }); - this.setHelpMenu(helpMenu); - - // Tasks - const taskMenu = new Menu(); - const taskMenuItem = new MenuItem({ label: this.mnemonicLabel(nls.localize({ key: 'mTask', comment: ['&& denotes a mnemonic'] }, "&&Tasks")), submenu: taskMenu }); - this.setTaskMenu(taskMenu); - - // Menu Structure - if (macApplicationMenuItem) { - menubar.append(macApplicationMenuItem); - } - - menubar.append(fileMenuItem); - menubar.append(editMenuItem); - menubar.append(selectionMenuItem); - menubar.append(viewMenuItem); - menubar.append(gotoMenuItem); - menubar.append(terminalMenuItem); - menubar.append(debugMenuItem); - menubar.append(taskMenuItem); - - if (macWindowMenuItem) { - menubar.append(macWindowMenuItem); - } - - menubar.append(helpMenuItem); - - Menu.setApplicationMenu(menubar); - - // Dock Menu - if (isMacintosh && !this.appMenuInstalled) { - this.appMenuInstalled = true; - - const dockMenu = new Menu(); - dockMenu.append(new MenuItem({ label: this.mnemonicLabel(nls.localize({ key: 'miNewWindow', comment: ['&& denotes a mnemonic'] }, "New &&Window")), click: () => this.windowsMainService.openNewWindow(OpenContext.DOCK) })); - - app.dock.setMenu(dockMenu); - } - } - - private setMacApplicationMenu(macApplicationMenu: Electron.Menu): void { - const about = new MenuItem({ label: nls.localize('mAbout', "About {0}", product.nameLong), role: 'about' }); - const checkForUpdates = this.getUpdateMenuItems(); - const preferences = this.getPreferencesMenu(); - const servicesMenu = new Menu(); - const services = new MenuItem({ label: nls.localize('mServices', "Services"), role: 'services', submenu: servicesMenu }); - const hide = new MenuItem({ label: nls.localize('mHide', "Hide {0}", product.nameLong), role: 'hide', accelerator: 'Command+H' }); - const hideOthers = new MenuItem({ label: nls.localize('mHideOthers', "Hide Others"), role: 'hideothers', accelerator: 'Command+Alt+H' }); - const showAll = new MenuItem({ label: nls.localize('mShowAll', "Show All"), role: 'unhide' }); - const quit = new MenuItem(this.likeAction('workbench.action.quit', { - label: nls.localize('miQuit', "Quit {0}", product.nameLong), click: () => { - if (this.windowsMainService.getWindowCount() === 0 || !!BrowserWindow.getFocusedWindow()) { - this.windowsMainService.quit(); // fix for https://github.com/Microsoft/vscode/issues/39191 - } - } - })); - - const actions = [about]; - actions.push(...checkForUpdates); - actions.push(...[ - __separator__(), - preferences, - __separator__(), - services, - __separator__(), - hide, - hideOthers, - showAll, - __separator__(), - quit - ]); - - actions.forEach(i => macApplicationMenu.append(i)); - } - - private setFileMenu(fileMenu: Electron.Menu): void { - const hasNoWindows = (this.windowsMainService.getWindowCount() === 0); - - let newFile: Electron.MenuItem; - if (hasNoWindows) { - newFile = new MenuItem(this.likeAction('workbench.action.files.newUntitledFile', { label: this.mnemonicLabel(nls.localize({ key: 'miNewFile', comment: ['&& denotes a mnemonic'] }, "&&New File")), click: () => this.windowsMainService.openNewWindow(OpenContext.MENU) })); - } else { - newFile = this.createMenuItem(nls.localize({ key: 'miNewFile', comment: ['&& denotes a mnemonic'] }, "&&New File"), 'workbench.action.files.newUntitledFile'); - } - - let open: Electron.MenuItem; - if (hasNoWindows) { - open = new MenuItem(this.likeAction('workbench.action.files.openFileFolder', { label: this.mnemonicLabel(nls.localize({ key: 'miOpen', comment: ['&& denotes a mnemonic'] }, "&&Open...")), click: (menuItem, win, event) => this.windowsMainService.pickFileFolderAndOpen({ forceNewWindow: this.isOptionClick(event), telemetryExtraData: { from: telemetryFrom } }) })); - } else { - open = this.createMenuItem(nls.localize({ key: 'miOpen', comment: ['&& denotes a mnemonic'] }, "&&Open..."), ['workbench.action.files.openFileFolder', 'workbench.action.files.openFileFolderInNewWindow']); - } - - let openWorkspace: Electron.MenuItem; - if (hasNoWindows) { - openWorkspace = new MenuItem(this.likeAction('workbench.action.openWorkspace', { label: this.mnemonicLabel(nls.localize({ key: 'miOpenWorkspace', comment: ['&& denotes a mnemonic'] }, "Open Wor&&kspace...")), click: (menuItem, win, event) => this.windowsMainService.pickWorkspaceAndOpen({ forceNewWindow: this.isOptionClick(event), telemetryExtraData: { from: telemetryFrom } }) })); - } else { - openWorkspace = this.createMenuItem(nls.localize({ key: 'miOpenWorkspace', comment: ['&& denotes a mnemonic'] }, "Open Wor&&kspace..."), ['workbench.action.openWorkspace', 'workbench.action.openWorkspaceInNewWindow']); - } - - let openFolder: Electron.MenuItem; - if (hasNoWindows) { - openFolder = new MenuItem(this.likeAction('workbench.action.files.openFolder', { label: this.mnemonicLabel(nls.localize({ key: 'miOpenFolder', comment: ['&& denotes a mnemonic'] }, "Open &&Folder...")), click: (menuItem, win, event) => this.windowsMainService.pickFolderAndOpen({ forceNewWindow: this.isOptionClick(event), telemetryExtraData: { from: telemetryFrom } }) })); - } else { - openFolder = this.createMenuItem(nls.localize({ key: 'miOpenFolder', comment: ['&& denotes a mnemonic'] }, "Open &&Folder..."), ['workbench.action.files.openFolder', 'workbench.action.files.openFolderInNewWindow']); - } - - let openFile: Electron.MenuItem; - if (hasNoWindows) { - openFile = new MenuItem(this.likeAction('workbench.action.files.openFile', { label: this.mnemonicLabel(nls.localize({ key: 'miOpenFile', comment: ['&& denotes a mnemonic'] }, "&&Open File...")), click: (menuItem, win, event) => this.windowsMainService.pickFileAndOpen({ forceNewWindow: this.isOptionClick(event), telemetryExtraData: { from: telemetryFrom } }) })); - } else { - openFile = this.createMenuItem(nls.localize({ key: 'miOpenFile', comment: ['&& denotes a mnemonic'] }, "&&Open File..."), ['workbench.action.files.openFile', 'workbench.action.files.openFileInNewWindow']); - } - - const openRecentMenu = new Menu(); - this.setOpenRecentMenu(openRecentMenu); - const openRecent = new MenuItem({ label: this.mnemonicLabel(nls.localize({ key: 'miOpenRecent', comment: ['&& denotes a mnemonic'] }, "Open &&Recent")), submenu: openRecentMenu, enabled: openRecentMenu.items.length > 0 }); - - const saveWorkspaceAs = this.createMenuItem(nls.localize('miSaveWorkspaceAs', "Save Workspace As..."), 'workbench.action.saveWorkspaceAs'); - const addFolder = this.createMenuItem(nls.localize({ key: 'miAddFolderToWorkspace', comment: ['&& denotes a mnemonic'] }, "A&&dd Folder to Workspace..."), 'workbench.action.addRootFolder'); - - const saveFile = this.createMenuItem(nls.localize({ key: 'miSave', comment: ['&& denotes a mnemonic'] }, "&&Save"), 'workbench.action.files.save'); - const saveFileAs = this.createMenuItem(nls.localize({ key: 'miSaveAs', comment: ['&& denotes a mnemonic'] }, "Save &&As..."), 'workbench.action.files.saveAs'); - const saveAllFiles = this.createMenuItem(nls.localize({ key: 'miSaveAll', comment: ['&& denotes a mnemonic'] }, "Save A&&ll"), 'workbench.action.files.saveAll'); - - const autoSaveEnabled = [AutoSaveConfiguration.AFTER_DELAY, AutoSaveConfiguration.ON_FOCUS_CHANGE, AutoSaveConfiguration.ON_WINDOW_CHANGE].some(s => this.currentAutoSaveSetting === s); - - const autoSave = this.createMenuItem(this.mnemonicLabel(nls.localize('miAutoSave', "Auto Save")), 'workbench.action.toggleAutoSave', this.windowsMainService.getWindowCount() > 0, autoSaveEnabled); - - const preferences = this.getPreferencesMenu(); - - const newWindow = new MenuItem(this.likeAction('workbench.action.newWindow', { label: this.mnemonicLabel(nls.localize({ key: 'miNewWindow', comment: ['&& denotes a mnemonic'] }, "New &&Window")), click: () => this.windowsMainService.openNewWindow(OpenContext.MENU) })); - const revertFile = this.createMenuItem(nls.localize({ key: 'miRevert', comment: ['&& denotes a mnemonic'] }, "Re&&vert File"), 'workbench.action.files.revert'); - const closeWindow = new MenuItem(this.likeAction('workbench.action.closeWindow', { label: this.mnemonicLabel(nls.localize({ key: 'miCloseWindow', comment: ['&& denotes a mnemonic'] }, "Clos&&e Window")), click: () => this.windowsMainService.getLastActiveWindow().win.close(), enabled: this.windowsMainService.getWindowCount() > 0 })); - - this.closeWorkspace = this.createMenuItem(nls.localize({ key: 'miCloseWorkspace', comment: ['&& denotes a mnemonic'] }, "Close &&Workspace"), 'workbench.action.closeFolder'); - this.closeFolder = this.createMenuItem(nls.localize({ key: 'miCloseFolder', comment: ['&& denotes a mnemonic'] }, "Close &&Folder"), 'workbench.action.closeFolder'); - - const closeEditor = this.createMenuItem(nls.localize({ key: 'miCloseEditor', comment: ['&& denotes a mnemonic'] }, "&&Close Editor"), 'workbench.action.closeActiveEditor'); - - const exit = new MenuItem(this.likeAction('workbench.action.quit', { label: this.mnemonicLabel(nls.localize({ key: 'miExit', comment: ['&& denotes a mnemonic'] }, "E&&xit")), click: () => this.windowsMainService.quit() })); - - this.updateWorkspaceMenuItems(); - - arrays.coalesce([ - newFile, - newWindow, - __separator__(), - isMacintosh ? open : null, - !isMacintosh ? openFile : null, - !isMacintosh ? openFolder : null, - openWorkspace, - openRecent, - __separator__(), - addFolder, - saveWorkspaceAs, - __separator__(), - saveFile, - saveFileAs, - saveAllFiles, - __separator__(), - autoSave, - __separator__(), - !isMacintosh ? preferences : null, - !isMacintosh ? __separator__() : null, - revertFile, - closeEditor, - this.closeWorkspace, - this.closeFolder, - closeWindow, - !isMacintosh ? __separator__() : null, - !isMacintosh ? exit : null - ]).forEach(item => fileMenu.append(item)); - } - - private getPreferencesMenu(): Electron.MenuItem { - const settings = this.createMenuItem(nls.localize({ key: 'miOpenSettings', comment: ['&& denotes a mnemonic'] }, "&&Settings"), 'workbench.action.openSettings2'); - const kebindingSettings = this.createMenuItem(nls.localize({ key: 'miOpenKeymap', comment: ['&& denotes a mnemonic'] }, "&&Keyboard Shortcuts"), 'workbench.action.openGlobalKeybindings'); - const keymapExtensions = this.createMenuItem(nls.localize({ key: 'miOpenKeymapExtensions', comment: ['&& denotes a mnemonic'] }, "&&Keymap Extensions"), 'workbench.extensions.action.showRecommendedKeymapExtensions'); - const snippetsSettings = this.createMenuItem(nls.localize({ key: 'miOpenSnippets', comment: ['&& denotes a mnemonic'] }, "User &&Snippets"), 'workbench.action.openSnippets'); - const colorThemeSelection = this.createMenuItem(nls.localize({ key: 'miSelectColorTheme', comment: ['&& denotes a mnemonic'] }, "&&Color Theme"), 'workbench.action.selectTheme'); - const iconThemeSelection = this.createMenuItem(nls.localize({ key: 'miSelectIconTheme', comment: ['&& denotes a mnemonic'] }, "File &&Icon Theme"), 'workbench.action.selectIconTheme'); - - const preferencesMenu = new Menu(); - preferencesMenu.append(settings); - preferencesMenu.append(__separator__()); - preferencesMenu.append(kebindingSettings); - preferencesMenu.append(keymapExtensions); - preferencesMenu.append(__separator__()); - preferencesMenu.append(snippetsSettings); - preferencesMenu.append(__separator__()); - preferencesMenu.append(colorThemeSelection); - preferencesMenu.append(iconThemeSelection); - - return new MenuItem({ label: this.mnemonicLabel(nls.localize({ key: 'miPreferences', comment: ['&& denotes a mnemonic'] }, "&&Preferences")), submenu: preferencesMenu }); - } - - private setOpenRecentMenu(openRecentMenu: Electron.Menu): void { - openRecentMenu.append(this.createMenuItem(nls.localize({ key: 'miReopenClosedEditor', comment: ['&& denotes a mnemonic'] }, "&&Reopen Closed Editor"), 'workbench.action.reopenClosedEditor')); - - const { workspaces, files } = this.historyMainService.getRecentlyOpened(); - - // Workspaces - if (workspaces.length > 0) { - openRecentMenu.append(__separator__()); - - for (let i = 0; i < CodeMenu.MAX_MENU_RECENT_ENTRIES && i < workspaces.length; i++) { - openRecentMenu.append(this.createOpenRecentMenuItem(workspaces[i], 'openRecentWorkspace', false)); - } - } - - // Files - if (files.length > 0) { - openRecentMenu.append(__separator__()); - - for (let i = 0; i < CodeMenu.MAX_MENU_RECENT_ENTRIES && i < files.length; i++) { - openRecentMenu.append(this.createOpenRecentMenuItem(files[i], 'openRecentFile', true)); - } - } - - if (workspaces.length || files.length) { - openRecentMenu.append(__separator__()); - openRecentMenu.append(this.createMenuItem(nls.localize({ key: 'miMore', comment: ['&& denotes a mnemonic'] }, "&&More..."), 'workbench.action.openRecent')); - openRecentMenu.append(__separator__()); - openRecentMenu.append(new MenuItem(this.likeAction('workbench.action.clearRecentFiles', { label: this.mnemonicLabel(nls.localize({ key: 'miClearRecentOpen', comment: ['&& denotes a mnemonic'] }, "&&Clear Recently Opened")), click: () => this.historyMainService.clearRecentlyOpened() }))); - } - } - - private createOpenRecentMenuItem(workspace: IWorkspaceIdentifier | ISingleFolderWorkspaceIdentifier | string, commandId: string, isFile: boolean): Electron.MenuItem { - let label: string; - let path: string; - if (isSingleFolderWorkspaceIdentifier(workspace) || typeof workspace === 'string') { - label = unmnemonicLabel(getPathLabel(workspace, this.environmentService)); - path = workspace; - } else { - label = getWorkspaceLabel(workspace, this.environmentService, { verbose: true }); - path = workspace.configPath; - } - - return new MenuItem(this.likeAction(commandId, { - label, - click: (menuItem, win, event) => { - const openInNewWindow = this.isOptionClick(event); - const success = this.windowsMainService.open({ - context: OpenContext.MENU, - cli: this.environmentService.args, - pathsToOpen: [path], forceNewWindow: openInNewWindow, - forceOpenWorkspaceAsFile: isFile - }).length > 0; - - if (!success) { - this.historyMainService.removeFromRecentlyOpened([isSingleFolderWorkspaceIdentifier(workspace) ? workspace : workspace.configPath]); - } - } - }, false)); - } - - private isOptionClick(event: Electron.Event): boolean { - return event && ((!isMacintosh && (event.ctrlKey || event.shiftKey)) || (isMacintosh && (event.metaKey || event.altKey))); - } - - private createRoleMenuItem(label: string, commandId: string, role: Electron.MenuItemRole): Electron.MenuItem { - const options: Electron.MenuItemConstructorOptions = { - label: this.mnemonicLabel(label), - role, - enabled: true - }; - - return new MenuItem(this.withKeybinding(commandId, options)); - } - - private setEditMenu(winLinuxEditMenu: Electron.Menu): void { - let undo: Electron.MenuItem; - let redo: Electron.MenuItem; - let cut: Electron.MenuItem; - let copy: Electron.MenuItem; - let paste: Electron.MenuItem; - - if (isMacintosh) { - undo = this.createContextAwareMenuItem(nls.localize({ key: 'miUndo', comment: ['&& denotes a mnemonic'] }, "&&Undo"), 'undo', { - inDevTools: devTools => devTools.undo(), - inNoWindow: () => Menu.sendActionToFirstResponder('undo:') - }); - redo = this.createContextAwareMenuItem(nls.localize({ key: 'miRedo', comment: ['&& denotes a mnemonic'] }, "&&Redo"), 'redo', { - inDevTools: devTools => devTools.redo(), - inNoWindow: () => Menu.sendActionToFirstResponder('redo:') - }); - cut = this.createRoleMenuItem(nls.localize({ key: 'miCut', comment: ['&& denotes a mnemonic'] }, "Cu&&t"), 'editor.action.clipboardCutAction', 'cut'); - copy = this.createRoleMenuItem(nls.localize({ key: 'miCopy', comment: ['&& denotes a mnemonic'] }, "&&Copy"), 'editor.action.clipboardCopyAction', 'copy'); - paste = this.createRoleMenuItem(nls.localize({ key: 'miPaste', comment: ['&& denotes a mnemonic'] }, "&&Paste"), 'editor.action.clipboardPasteAction', 'paste'); - } else { - undo = this.createMenuItem(nls.localize({ key: 'miUndo', comment: ['&& denotes a mnemonic'] }, "&&Undo"), 'undo'); - redo = this.createMenuItem(nls.localize({ key: 'miRedo', comment: ['&& denotes a mnemonic'] }, "&&Redo"), 'redo'); - cut = this.createMenuItem(nls.localize({ key: 'miCut', comment: ['&& denotes a mnemonic'] }, "Cu&&t"), 'editor.action.clipboardCutAction'); - copy = this.createMenuItem(nls.localize({ key: 'miCopy', comment: ['&& denotes a mnemonic'] }, "&&Copy"), 'editor.action.clipboardCopyAction'); - paste = this.createMenuItem(nls.localize({ key: 'miPaste', comment: ['&& denotes a mnemonic'] }, "&&Paste"), 'editor.action.clipboardPasteAction'); - } - - const find = this.createMenuItem(nls.localize({ key: 'miFind', comment: ['&& denotes a mnemonic'] }, "&&Find"), 'actions.find'); - const replace = this.createMenuItem(nls.localize({ key: 'miReplace', comment: ['&& denotes a mnemonic'] }, "&&Replace"), 'editor.action.startFindReplaceAction'); - const findInFiles = this.createMenuItem(nls.localize({ key: 'miFindInFiles', comment: ['&& denotes a mnemonic'] }, "Find &&in Files"), 'workbench.action.findInFiles'); - const replaceInFiles = this.createMenuItem(nls.localize({ key: 'miReplaceInFiles', comment: ['&& denotes a mnemonic'] }, "Replace &&in Files"), 'workbench.action.replaceInFiles'); - - const emmetExpandAbbreviation = this.createMenuItem(nls.localize({ key: 'miEmmetExpandAbbreviation', comment: ['&& denotes a mnemonic'] }, "Emmet: E&&xpand Abbreviation"), 'editor.emmet.action.expandAbbreviation'); - const showEmmetCommands = this.createMenuItem(nls.localize({ key: 'miShowEmmetCommands', comment: ['&& denotes a mnemonic'] }, "E&&mmet..."), 'workbench.action.showEmmetCommands'); - const toggleLineComment = this.createMenuItem(nls.localize({ key: 'miToggleLineComment', comment: ['&& denotes a mnemonic'] }, "&&Toggle Line Comment"), 'editor.action.commentLine'); - const toggleBlockComment = this.createMenuItem(nls.localize({ key: 'miToggleBlockComment', comment: ['&& denotes a mnemonic'] }, "Toggle &&Block Comment"), 'editor.action.blockComment'); - - [ - undo, - redo, - __separator__(), - cut, - copy, - paste, - __separator__(), - find, - replace, - __separator__(), - findInFiles, - replaceInFiles, - __separator__(), - toggleLineComment, - toggleBlockComment, - emmetExpandAbbreviation, - showEmmetCommands - ].forEach(item => winLinuxEditMenu.append(item)); - } - - private setSelectionMenu(winLinuxEditMenu: Electron.Menu): void { - let multiCursorModifierLabel: string; - if (this.currentMultiCursorModifierSetting === 'ctrlCmd') { - multiCursorModifierLabel = nls.localize('miMultiCursorAlt', "Switch to Alt+Click for Multi-Cursor"); // The default has been overwritten - } else { - multiCursorModifierLabel = ( - isMacintosh - ? nls.localize('miMultiCursorCmd', "Switch to Cmd+Click for Multi-Cursor") - : nls.localize('miMultiCursorCtrl', "Switch to Ctrl+Click for Multi-Cursor") - ); - } - - const multicursorModifier = this.createMenuItem(multiCursorModifierLabel, 'workbench.action.toggleMultiCursorModifier'); - const insertCursorAbove = this.createMenuItem(nls.localize({ key: 'miInsertCursorAbove', comment: ['&& denotes a mnemonic'] }, "&&Add Cursor Above"), 'editor.action.insertCursorAbove'); - const insertCursorBelow = this.createMenuItem(nls.localize({ key: 'miInsertCursorBelow', comment: ['&& denotes a mnemonic'] }, "A&&dd Cursor Below"), 'editor.action.insertCursorBelow'); - const insertCursorAtEndOfEachLineSelected = this.createMenuItem(nls.localize({ key: 'miInsertCursorAtEndOfEachLineSelected', comment: ['&& denotes a mnemonic'] }, "Add C&&ursors to Line Ends"), 'editor.action.insertCursorAtEndOfEachLineSelected'); - const addSelectionToNextFindMatch = this.createMenuItem(nls.localize({ key: 'miAddSelectionToNextFindMatch', comment: ['&& denotes a mnemonic'] }, "Add &&Next Occurrence"), 'editor.action.addSelectionToNextFindMatch'); - const addSelectionToPreviousFindMatch = this.createMenuItem(nls.localize({ key: 'miAddSelectionToPreviousFindMatch', comment: ['&& denotes a mnemonic'] }, "Add P&&revious Occurrence"), 'editor.action.addSelectionToPreviousFindMatch'); - const selectHighlights = this.createMenuItem(nls.localize({ key: 'miSelectHighlights', comment: ['&& denotes a mnemonic'] }, "Select All &&Occurrences"), 'editor.action.selectHighlights'); - - const copyLinesUp = this.createMenuItem(nls.localize({ key: 'miCopyLinesUp', comment: ['&& denotes a mnemonic'] }, "&&Copy Line Up"), 'editor.action.copyLinesUpAction'); - const copyLinesDown = this.createMenuItem(nls.localize({ key: 'miCopyLinesDown', comment: ['&& denotes a mnemonic'] }, "Co&&py Line Down"), 'editor.action.copyLinesDownAction'); - const moveLinesUp = this.createMenuItem(nls.localize({ key: 'miMoveLinesUp', comment: ['&& denotes a mnemonic'] }, "Mo&&ve Line Up"), 'editor.action.moveLinesUpAction'); - const moveLinesDown = this.createMenuItem(nls.localize({ key: 'miMoveLinesDown', comment: ['&& denotes a mnemonic'] }, "Move &&Line Down"), 'editor.action.moveLinesDownAction'); - - let selectAll: Electron.MenuItem; - if (isMacintosh) { - selectAll = this.createContextAwareMenuItem(nls.localize({ key: 'miSelectAll', comment: ['&& denotes a mnemonic'] }, "&&Select All"), 'editor.action.selectAll', { - inDevTools: devTools => devTools.selectAll(), - inNoWindow: () => Menu.sendActionToFirstResponder('selectAll:') - }); - } else { - selectAll = this.createMenuItem(nls.localize({ key: 'miSelectAll', comment: ['&& denotes a mnemonic'] }, "&&Select All"), 'editor.action.selectAll'); - } - const smartSelectGrow = this.createMenuItem(nls.localize({ key: 'miSmartSelectGrow', comment: ['&& denotes a mnemonic'] }, "&&Expand Selection"), 'editor.action.smartSelect.grow'); - const smartSelectshrink = this.createMenuItem(nls.localize({ key: 'miSmartSelectShrink', comment: ['&& denotes a mnemonic'] }, "&&Shrink Selection"), 'editor.action.smartSelect.shrink'); - - [ - selectAll, - smartSelectGrow, - smartSelectshrink, - __separator__(), - copyLinesUp, - copyLinesDown, - moveLinesUp, - moveLinesDown, - __separator__(), - multicursorModifier, - insertCursorAbove, - insertCursorBelow, - insertCursorAtEndOfEachLineSelected, - addSelectionToNextFindMatch, - addSelectionToPreviousFindMatch, - selectHighlights, - ].forEach(item => winLinuxEditMenu.append(item)); - } - - private setViewMenu(viewMenu: Electron.Menu): void { - const commands = this.createMenuItem(nls.localize({ key: 'miCommandPalette', comment: ['&& denotes a mnemonic'] }, "&&Command Palette..."), 'workbench.action.showCommands'); - const openView = this.createMenuItem(nls.localize({ key: 'miOpenView', comment: ['&& denotes a mnemonic'] }, "&&Open View..."), 'workbench.action.openView'); - - // Views - const explorer = this.createMenuItem(nls.localize({ key: 'miViewExplorer', comment: ['&& denotes a mnemonic'] }, "&&Explorer"), 'workbench.view.explorer'); - const search = this.createMenuItem(nls.localize({ key: 'miViewSearch', comment: ['&& denotes a mnemonic'] }, "&&Search"), 'workbench.view.search'); - const scm = this.createMenuItem(nls.localize({ key: 'miViewSCM', comment: ['&& denotes a mnemonic'] }, "S&&CM"), 'workbench.view.scm'); - const debug = this.createMenuItem(nls.localize({ key: 'miViewDebug', comment: ['&& denotes a mnemonic'] }, "&&Debug"), 'workbench.view.debug'); - const extensions = this.createMenuItem(nls.localize({ key: 'miViewExtensions', comment: ['&& denotes a mnemonic'] }, "E&&xtensions"), 'workbench.view.extensions'); - - // Panels - const output = this.createMenuItem(nls.localize({ key: 'miToggleOutput', comment: ['&& denotes a mnemonic'] }, "&&Output"), 'workbench.action.output.toggleOutput'); - const debugConsole = this.createMenuItem(nls.localize({ key: 'miToggleDebugConsole', comment: ['&& denotes a mnemonic'] }, "De&&bug Console"), 'workbench.debug.action.toggleRepl'); - const terminal = this.createMenuItem(nls.localize({ key: 'miToggleTerminal', comment: ['&& denotes a mnemonic'] }, "&&Terminal"), 'workbench.action.terminal.toggleTerminal'); - const problems = this.createMenuItem(nls.localize({ key: 'miMarker', comment: ['&& denotes a mnemonic'] }, "&&Problems"), 'workbench.actions.view.problems'); - - // Appearance - - const appearanceMenu = new Menu(); - - const fullscreen = new MenuItem(this.withKeybinding('workbench.action.toggleFullScreen', { label: this.mnemonicLabel(nls.localize({ key: 'miToggleFullScreen', comment: ['&& denotes a mnemonic'] }, "Toggle &&Full Screen")), click: () => this.windowsMainService.getLastActiveWindow().toggleFullScreen(), enabled: this.windowsMainService.getWindowCount() > 0 })); - const toggleZenMode = this.createMenuItem(nls.localize('miToggleZenMode', "Toggle Zen Mode"), 'workbench.action.toggleZenMode'); - const toggleCenteredLayout = this.createMenuItem(nls.localize('miToggleCenteredLayout', "Toggle Centered Layout"), 'workbench.action.toggleCenteredLayout'); - const toggleMenuBar = this.createMenuItem(nls.localize({ key: 'miToggleMenuBar', comment: ['&& denotes a mnemonic'] }, "Toggle Menu &&Bar"), 'workbench.action.toggleMenuBar'); - - const toggleSidebar = this.createMenuItem(nls.localize({ key: 'miToggleSidebar', comment: ['&& denotes a mnemonic'] }, "&&Toggle Side Bar"), 'workbench.action.toggleSidebarVisibility'); - - let moveSideBarLabel: string; - if (this.currentSidebarLocation !== 'right') { - moveSideBarLabel = nls.localize({ key: 'miMoveSidebarRight', comment: ['&& denotes a mnemonic'] }, "&&Move Side Bar Right"); - } else { - moveSideBarLabel = nls.localize({ key: 'miMoveSidebarLeft', comment: ['&& denotes a mnemonic'] }, "&&Move Side Bar Left"); - } - - const moveSidebar = this.createMenuItem(moveSideBarLabel, 'workbench.action.toggleSidebarPosition'); - const togglePanel = this.createMenuItem(nls.localize({ key: 'miTogglePanel', comment: ['&& denotes a mnemonic'] }, "Toggle &&Panel"), 'workbench.action.togglePanel'); - - let statusBarLabel: string; - if (this.currentStatusbarVisible) { - statusBarLabel = nls.localize({ key: 'miHideStatusbar', comment: ['&& denotes a mnemonic'] }, "&&Hide Status Bar"); - } else { - statusBarLabel = nls.localize({ key: 'miShowStatusbar', comment: ['&& denotes a mnemonic'] }, "&&Show Status Bar"); - } - const toggleStatusbar = this.createMenuItem(statusBarLabel, 'workbench.action.toggleStatusbarVisibility'); - - let activityBarLabel: string; - if (this.currentActivityBarVisible) { - activityBarLabel = nls.localize({ key: 'miHideActivityBar', comment: ['&& denotes a mnemonic'] }, "Hide &&Activity Bar"); - } else { - activityBarLabel = nls.localize({ key: 'miShowActivityBar', comment: ['&& denotes a mnemonic'] }, "Show &&Activity Bar"); - } - const toggleActivtyBar = this.createMenuItem(activityBarLabel, 'workbench.action.toggleActivityBarVisibility'); - - const zoomIn = this.createMenuItem(nls.localize({ key: 'miZoomIn', comment: ['&& denotes a mnemonic'] }, "&&Zoom In"), 'workbench.action.zoomIn'); - const zoomOut = this.createMenuItem(nls.localize({ key: 'miZoomOut', comment: ['&& denotes a mnemonic'] }, "Zoom O&&ut"), 'workbench.action.zoomOut'); - const resetZoom = this.createMenuItem(nls.localize({ key: 'miZoomReset', comment: ['&& denotes a mnemonic'] }, "&&Reset Zoom"), 'workbench.action.zoomReset'); - - arrays.coalesce([ - fullscreen, - toggleZenMode, - toggleCenteredLayout, - isWindows || isLinux ? toggleMenuBar : void 0, - __separator__(), - moveSidebar, - toggleSidebar, - togglePanel, - toggleStatusbar, - toggleActivtyBar, - __separator__(), - zoomIn, - zoomOut, - resetZoom - ]).forEach(item => appearanceMenu.append(item)); - - const appearance = new MenuItem({ label: this.mnemonicLabel(nls.localize({ key: 'miAppearance', comment: ['&& denotes a mnemonic'] }, "&&Appearance")), submenu: appearanceMenu }); - - // Editor Layout - - const editorLayoutMenu = new Menu(); - - const splitEditorUp = this.createMenuItem(nls.localize({ key: 'miSplitEditorUp', comment: ['&& denotes a mnemonic'] }, "Split &&Up"), 'workbench.action.splitEditorUp'); - const splitEditorDown = this.createMenuItem(nls.localize({ key: 'miSplitEditorDown', comment: ['&& denotes a mnemonic'] }, "Split &&Down"), 'workbench.action.splitEditorDown'); - const splitEditorLeft = this.createMenuItem(nls.localize({ key: 'miSplitEditorLeft', comment: ['&& denotes a mnemonic'] }, "Split &&Left"), 'workbench.action.splitEditorLeft'); - const splitEditorRight = this.createMenuItem(nls.localize({ key: 'miSplitEditorRight', comment: ['&& denotes a mnemonic'] }, "Split &&Right"), 'workbench.action.splitEditorRight'); - - const singleColumnEditorLayout = this.createMenuItem(nls.localize({ key: 'miSingleColumnEditorLayout', comment: ['&& denotes a mnemonic'] }, "&&Single"), 'workbench.action.editorLayoutSingle'); - const twoColumnsEditorLayout = this.createMenuItem(nls.localize({ key: 'miTwoColumnsEditorLayout', comment: ['&& denotes a mnemonic'] }, "&&Two Columns"), 'workbench.action.editorLayoutTwoColumns'); - const threeColumnsEditorLayout = this.createMenuItem(nls.localize({ key: 'miThreeColumnsEditorLayout', comment: ['&& denotes a mnemonic'] }, "T&&hree Columns"), 'workbench.action.editorLayoutThreeColumns'); - const twoRowsEditorLayout = this.createMenuItem(nls.localize({ key: 'miTwoRowsEditorLayout', comment: ['&& denotes a mnemonic'] }, "T&&wo Rows"), 'workbench.action.editorLayoutTwoRows'); - const threeRowsEditorLayout = this.createMenuItem(nls.localize({ key: 'miThreeRowsEditorLayout', comment: ['&& denotes a mnemonic'] }, "Three &&Rows"), 'workbench.action.editorLayoutThreeRows'); - const twoByTwoGridEditorLayout = this.createMenuItem(nls.localize({ key: 'miTwoByTwoGridEditorLayout', comment: ['&& denotes a mnemonic'] }, "&&Grid (2x2)"), 'workbench.action.editorLayoutTwoByTwoGrid'); - const twoRowsRightEditorLayout = this.createMenuItem(nls.localize({ key: 'miTwoRowsRightEditorLayout', comment: ['&& denotes a mnemonic'] }, "Two R&&ows Right"), 'workbench.action.editorLayoutTwoRowsRight'); - const twoColumnsBottomEditorLayout = this.createMenuItem(nls.localize({ key: 'miTwoColumnsBottomEditorLayout', comment: ['&& denotes a mnemonic'] }, "Two &&Columns Bottom"), 'workbench.action.editorLayoutTwoColumnsBottom'); - - const toggleEditorLayout = this.createMenuItem(nls.localize({ key: 'miToggleEditorLayout', comment: ['&& denotes a mnemonic'] }, "Toggle Vertical/Horizontal &&Layout"), 'workbench.action.toggleEditorGroupLayout'); - - [ - splitEditorUp, - splitEditorDown, - splitEditorLeft, - splitEditorRight, - __separator__(), - singleColumnEditorLayout, - twoColumnsEditorLayout, - threeColumnsEditorLayout, - twoRowsEditorLayout, - threeRowsEditorLayout, - twoByTwoGridEditorLayout, - twoRowsRightEditorLayout, - twoColumnsBottomEditorLayout, - __separator__(), - toggleEditorLayout - ].forEach(item => editorLayoutMenu.append(item)); - - const editorLayout = new MenuItem({ label: this.mnemonicLabel(nls.localize({ key: 'miEditorLayout', comment: ['&& denotes a mnemonic'] }, "Editor &&Layout")), submenu: editorLayoutMenu }); - - const toggleWordWrap = this.createMenuItem(nls.localize({ key: 'miToggleWordWrap', comment: ['&& denotes a mnemonic'] }, "Toggle &&Word Wrap"), 'editor.action.toggleWordWrap'); - const toggleMinimap = this.createMenuItem(nls.localize({ key: 'miToggleMinimap', comment: ['&& denotes a mnemonic'] }, "Toggle &&Minimap"), 'editor.action.toggleMinimap'); - const toggleRenderWhitespace = this.createMenuItem(nls.localize({ key: 'miToggleRenderWhitespace', comment: ['&& denotes a mnemonic'] }, "Toggle &&Render Whitespace"), 'editor.action.toggleRenderWhitespace'); - const toggleRenderControlCharacters = this.createMenuItem(nls.localize({ key: 'miToggleRenderControlCharacters', comment: ['&& denotes a mnemonic'] }, "Toggle &&Control Characters"), 'editor.action.toggleRenderControlCharacter'); - const toggleBreadcrumbs = this.createMenuItem(nls.localize({ key: 'miToggleBreadcrumbs', comment: ['&& denotes a mnemonic'] }, "Toggle &&Breadcrumbs"), 'breadcrumbs.toggle'); - - arrays.coalesce([ - commands, - openView, - __separator__(), - appearance, - editorLayout, - __separator__(), - explorer, - search, - scm, - debug, - extensions, - __separator__(), - output, - problems, - debugConsole, - terminal, - __separator__(), - toggleWordWrap, - toggleMinimap, - toggleRenderWhitespace, - toggleRenderControlCharacters, - toggleBreadcrumbs - ]).forEach(item => viewMenu.append(item)); - } - - private setGotoMenu(gotoMenu: Electron.Menu): void { - const back = this.createMenuItem(nls.localize({ key: 'miBack', comment: ['&& denotes a mnemonic'] }, "&&Back"), 'workbench.action.navigateBack'); - const forward = this.createMenuItem(nls.localize({ key: 'miForward', comment: ['&& denotes a mnemonic'] }, "&&Forward"), 'workbench.action.navigateForward'); - - const switchEditorMenu = new Menu(); - - const nextEditor = this.createMenuItem(nls.localize({ key: 'miNextEditor', comment: ['&& denotes a mnemonic'] }, "&&Next Editor"), 'workbench.action.nextEditor'); - const previousEditor = this.createMenuItem(nls.localize({ key: 'miPreviousEditor', comment: ['&& denotes a mnemonic'] }, "&&Previous Editor"), 'workbench.action.previousEditor'); - const nextEditorInGroup = this.createMenuItem(nls.localize({ key: 'miNextEditorInGroup', comment: ['&& denotes a mnemonic'] }, "&&Next Used Editor in Group"), 'workbench.action.openNextRecentlyUsedEditorInGroup'); - const previousEditorInGroup = this.createMenuItem(nls.localize({ key: 'miPreviousEditorInGroup', comment: ['&& denotes a mnemonic'] }, "&&Previous Used Editor in Group"), 'workbench.action.openPreviousRecentlyUsedEditorInGroup'); - - [ - nextEditor, - previousEditor, - __separator__(), - nextEditorInGroup, - previousEditorInGroup - ].forEach(item => switchEditorMenu.append(item)); - - const switchEditor = new MenuItem({ label: this.mnemonicLabel(nls.localize({ key: 'miSwitchEditor', comment: ['&& denotes a mnemonic'] }, "Switch &&Editor")), submenu: switchEditorMenu, enabled: true }); - - const switchGroupMenu = new Menu(); - - const focusFirstGroup = this.createMenuItem(nls.localize({ key: 'miFocusFirstGroup', comment: ['&& denotes a mnemonic'] }, "Group &&1"), 'workbench.action.focusFirstEditorGroup'); - const focusSecondGroup = this.createMenuItem(nls.localize({ key: 'miFocusSecondGroup', comment: ['&& denotes a mnemonic'] }, "Group &&2"), 'workbench.action.focusSecondEditorGroup'); - const focusThirdGroup = this.createMenuItem(nls.localize({ key: 'miFocusThirdGroup', comment: ['&& denotes a mnemonic'] }, "Group &&3"), 'workbench.action.focusThirdEditorGroup'); - const focusFourthGroup = this.createMenuItem(nls.localize({ key: 'miFocusFourthGroup', comment: ['&& denotes a mnemonic'] }, "Group &&4"), 'workbench.action.focusFourthEditorGroup'); - const focusFifthGroup = this.createMenuItem(nls.localize({ key: 'miFocusFifthGroup', comment: ['&& denotes a mnemonic'] }, "Group &&5"), 'workbench.action.focusFifthEditorGroup'); - const nextGroup = this.createMenuItem(nls.localize({ key: 'miNextGroup', comment: ['&& denotes a mnemonic'] }, "&&Next Group"), 'workbench.action.focusNextGroup'); - const previousGroup = this.createMenuItem(nls.localize({ key: 'miPreviousGroup', comment: ['&& denotes a mnemonic'] }, "&&Previous Group"), 'workbench.action.focusPreviousGroup'); - - const focusLeftGroup = this.createMenuItem(nls.localize({ key: 'miFocusLeftGroup', comment: ['&& denotes a mnemonic'] }, "Group &&Left"), 'workbench.action.focusLeftGroup'); - const focusRightGroup = this.createMenuItem(nls.localize({ key: 'miFocusRightGroup', comment: ['&& denotes a mnemonic'] }, "Group &&Right"), 'workbench.action.focusRightGroup'); - const focusAboveGroup = this.createMenuItem(nls.localize({ key: 'miFocusAboveGroup', comment: ['&& denotes a mnemonic'] }, "Group &&Above"), 'workbench.action.focusAboveGroup'); - const focusBelowGroup = this.createMenuItem(nls.localize({ key: 'miFocusBelowGroup', comment: ['&& denotes a mnemonic'] }, "Group &&Below"), 'workbench.action.focusBelowGroup'); - - [ - focusFirstGroup, - focusSecondGroup, - focusThirdGroup, - focusFourthGroup, - focusFifthGroup, - __separator__(), - nextGroup, - previousGroup, - __separator__(), - focusAboveGroup, - focusBelowGroup, - focusLeftGroup, - focusRightGroup - ].forEach(item => switchGroupMenu.append(item)); - - const switchGroup = new MenuItem({ label: this.mnemonicLabel(nls.localize({ key: 'miSwitchGroup', comment: ['&& denotes a mnemonic'] }, "Switch &&Group")), submenu: switchGroupMenu, enabled: true }); - - const gotoFile = this.createMenuItem(nls.localize({ key: 'miGotoFile', comment: ['&& denotes a mnemonic'] }, "Go to &&File..."), 'workbench.action.quickOpen'); - const gotoSymbolInFile = this.createMenuItem(nls.localize({ key: 'miGotoSymbolInFile', comment: ['&& denotes a mnemonic'] }, "Go to &&Symbol in File..."), 'workbench.action.gotoSymbol'); - const gotoSymbolInWorkspace = this.createMenuItem(nls.localize({ key: 'miGotoSymbolInWorkspace', comment: ['&& denotes a mnemonic'] }, "Go to Symbol in &&Workspace..."), 'workbench.action.showAllSymbols'); - const gotoDefinition = this.createMenuItem(nls.localize({ key: 'miGotoDefinition', comment: ['&& denotes a mnemonic'] }, "Go to &&Definition"), 'editor.action.goToDeclaration'); - const gotoTypeDefinition = this.createMenuItem(nls.localize({ key: 'miGotoTypeDefinition', comment: ['&& denotes a mnemonic'] }, "Go to &&Type Definition"), 'editor.action.goToTypeDefinition'); - const goToImplementation = this.createMenuItem(nls.localize({ key: 'miGotoImplementation', comment: ['&& denotes a mnemonic'] }, "Go to &&Implementation"), 'editor.action.goToImplementation'); - const gotoLine = this.createMenuItem(nls.localize({ key: 'miGotoLine', comment: ['&& denotes a mnemonic'] }, "Go to &&Line..."), 'workbench.action.gotoLine'); - - [ - back, - forward, - __separator__(), - switchEditor, - switchGroup, - __separator__(), - gotoFile, - gotoSymbolInFile, - gotoSymbolInWorkspace, - gotoDefinition, - gotoTypeDefinition, - goToImplementation, - gotoLine - ].forEach(item => gotoMenu.append(item)); - } - - private setTerminalMenu(terminalMenu: Electron.Menu): void { - const newTerminal = this.createMenuItem(nls.localize({ key: 'miNewTerminal', comment: ['&& denotes a mnemonic'] }, "&&New Terminal"), 'workbench.action.terminal.new'); - const splitTerminal = this.createMenuItem(nls.localize({ key: 'miSplitTerminal', comment: ['&& denotes a mnemonic'] }, "&&Split Terminal"), 'workbench.action.terminal.split'); - const killTerminal = this.createMenuItem(nls.localize({ key: 'miKillTerminal', comment: ['&& denotes a mnemonic'] }, "&&Kill Terminal"), 'workbench.action.terminal.kill'); - const clear = this.createMenuItem(nls.localize({ key: 'miClear', comment: ['&& denotes a mnemonic'] }, "&&Clear"), 'workbench.action.terminal.clear'); - const runActiveFile = this.createMenuItem(nls.localize({ key: 'miRunActiveFile', comment: ['&& denotes a mnemonic'] }, "Run &&Active File"), 'workbench.action.terminal.runActiveFile'); - const runSelectedText = this.createMenuItem(nls.localize({ key: 'miRunSelectedText', comment: ['&& denotes a mnemonic'] }, "Run &&Selected Text"), 'workbench.action.terminal.runSelectedText'); - const scrollToPreviousCommand = this.createMenuItem(nls.localize({ key: 'miScrollToPreviousCommand', comment: ['&& denotes a mnemonic'] }, "Scroll To Previous Command"), 'workbench.action.terminal.scrollToPreviousCommand'); - const scrollToNextCommand = this.createMenuItem(nls.localize({ key: 'miScrollToNextCommand', comment: ['&& denotes a mnemonic'] }, "Scroll To Next Command"), 'workbench.action.terminal.scrollToNextCommand'); - const selectToPreviousCommand = this.createMenuItem(nls.localize({ key: 'miSelectToPreviousCommand', comment: ['&& denotes a mnemonic'] }, "Select To Previous Command"), 'workbench.action.terminal.selectToPreviousCommand'); - const selectToNextCommand = this.createMenuItem(nls.localize({ key: 'miSelectToNextCommand', comment: ['&& denotes a mnemonic'] }, "Select To Next Command"), 'workbench.action.terminal.selectToNextCommand'); - - const menuItems: MenuItem[] = [ - newTerminal, - splitTerminal, - killTerminal, - __separator__(), - clear, - runActiveFile, - runSelectedText, - __separator__(), - scrollToPreviousCommand, - scrollToNextCommand, - selectToPreviousCommand, - selectToNextCommand - ]; - - menuItems.forEach(item => terminalMenu.append(item)); - } - - private setDebugMenu(debugMenu: Electron.Menu): void { - const start = this.createMenuItem(nls.localize({ key: 'miStartDebugging', comment: ['&& denotes a mnemonic'] }, "&&Start Debugging"), 'workbench.action.debug.start'); - const startWithoutDebugging = this.createMenuItem(nls.localize({ key: 'miStartWithoutDebugging', comment: ['&& denotes a mnemonic'] }, "Start &&Without Debugging"), 'workbench.action.debug.run'); - const stop = this.createMenuItem(nls.localize({ key: 'miStopDebugging', comment: ['&& denotes a mnemonic'] }, "&&Stop Debugging"), 'workbench.action.debug.stop'); - const restart = this.createMenuItem(nls.localize({ key: 'miRestart Debugging', comment: ['&& denotes a mnemonic'] }, "&&Restart Debugging"), 'workbench.action.debug.restart'); - - const openConfigurations = this.createMenuItem(nls.localize({ key: 'miOpenConfigurations', comment: ['&& denotes a mnemonic'] }, "Open &&Configurations"), 'workbench.action.debug.configure'); - const addConfiguration = this.createMenuItem(nls.localize({ key: 'miAddConfiguration', comment: ['&& denotes a mnemonic'] }, "Add Configuration..."), 'debug.addConfiguration'); - - const stepOver = this.createMenuItem(nls.localize({ key: 'miStepOver', comment: ['&& denotes a mnemonic'] }, "Step &&Over"), 'workbench.action.debug.stepOver'); - const stepInto = this.createMenuItem(nls.localize({ key: 'miStepInto', comment: ['&& denotes a mnemonic'] }, "Step &&Into"), 'workbench.action.debug.stepInto'); - const stepOut = this.createMenuItem(nls.localize({ key: 'miStepOut', comment: ['&& denotes a mnemonic'] }, "Step O&&ut"), 'workbench.action.debug.stepOut'); - const continueAction = this.createMenuItem(nls.localize({ key: 'miContinue', comment: ['&& denotes a mnemonic'] }, "&&Continue"), 'workbench.action.debug.continue'); - - const toggleBreakpoint = this.createMenuItem(nls.localize({ key: 'miToggleBreakpoint', comment: ['&& denotes a mnemonic'] }, "Toggle &&Breakpoint"), 'editor.debug.action.toggleBreakpoint'); - const breakpointsMenu = new Menu(); - breakpointsMenu.append(this.createMenuItem(nls.localize({ key: 'miConditionalBreakpoint', comment: ['&& denotes a mnemonic'] }, "&&Conditional Breakpoint..."), 'editor.debug.action.conditionalBreakpoint')); - breakpointsMenu.append(this.createMenuItem(nls.localize({ key: 'miInlineBreakpoint', comment: ['&& denotes a mnemonic'] }, "Inline Breakp&&oint"), 'editor.debug.action.toggleInlineBreakpoint')); - breakpointsMenu.append(this.createMenuItem(nls.localize({ key: 'miFunctionBreakpoint', comment: ['&& denotes a mnemonic'] }, "&&Function Breakpoint..."), 'workbench.debug.viewlet.action.addFunctionBreakpointAction')); - breakpointsMenu.append(this.createMenuItem(nls.localize({ key: 'miLogPoint', comment: ['&& denotes a mnemonic'] }, "&&Logpoint..."), 'editor.debug.action.toggleLogPoint')); - const newBreakpoints = new MenuItem({ label: this.mnemonicLabel(nls.localize({ key: 'miNewBreakpoint', comment: ['&& denotes a mnemonic'] }, "&&New Breakpoint")), submenu: breakpointsMenu }); - const enableAllBreakpoints = this.createMenuItem(nls.localize({ key: 'miEnableAllBreakpoints', comment: ['&& denotes a mnemonic'] }, "Enable All Breakpoints"), 'workbench.debug.viewlet.action.enableAllBreakpoints'); - const disableAllBreakpoints = this.createMenuItem(nls.localize({ key: 'miDisableAllBreakpoints', comment: ['&& denotes a mnemonic'] }, "Disable A&&ll Breakpoints"), 'workbench.debug.viewlet.action.disableAllBreakpoints'); - const removeAllBreakpoints = this.createMenuItem(nls.localize({ key: 'miRemoveAllBreakpoints', comment: ['&& denotes a mnemonic'] }, "Remove &&All Breakpoints"), 'workbench.debug.viewlet.action.removeAllBreakpoints'); - - const installAdditionalDebuggers = this.createMenuItem(nls.localize({ key: 'miInstallAdditionalDebuggers', comment: ['&& denotes a mnemonic'] }, "&&Install Additional Debuggers..."), 'debug.installAdditionalDebuggers'); - [ - start, - startWithoutDebugging, - stop, - restart, - __separator__(), - openConfigurations, - addConfiguration, - __separator__(), - stepOver, - stepInto, - stepOut, - continueAction, - __separator__(), - toggleBreakpoint, - newBreakpoints, - enableAllBreakpoints, - disableAllBreakpoints, - removeAllBreakpoints, - __separator__(), - installAdditionalDebuggers - ].forEach(item => debugMenu.append(item)); - } - - private setMacWindowMenu(macWindowMenu: Electron.Menu): void { - const minimize = new MenuItem({ label: nls.localize('mMinimize', "Minimize"), role: 'minimize', accelerator: 'Command+M', enabled: this.windowsMainService.getWindowCount() > 0 }); - const zoom = new MenuItem({ label: nls.localize('mZoom', "Zoom"), role: 'zoom', enabled: this.windowsMainService.getWindowCount() > 0 }); - const bringAllToFront = new MenuItem({ label: nls.localize('mBringToFront', "Bring All to Front"), role: 'front', enabled: this.windowsMainService.getWindowCount() > 0 }); - const switchWindow = this.createMenuItem(nls.localize({ key: 'miSwitchWindow', comment: ['&& denotes a mnemonic'] }, "Switch &&Window..."), 'workbench.action.switchWindow'); - - this.nativeTabMenuItems = []; - const nativeTabMenuItems: Electron.MenuItem[] = []; - if (this.currentEnableNativeTabs) { - const hasMultipleWindows = this.windowsMainService.getWindowCount() > 1; - - this.nativeTabMenuItems.push(this.createMenuItem(nls.localize('mShowPreviousTab', "Show Previous Tab"), 'workbench.action.showPreviousWindowTab', hasMultipleWindows)); - this.nativeTabMenuItems.push(this.createMenuItem(nls.localize('mShowNextTab', "Show Next Tab"), 'workbench.action.showNextWindowTab', hasMultipleWindows)); - this.nativeTabMenuItems.push(this.createMenuItem(nls.localize('mMoveTabToNewWindow', "Move Tab to New Window"), 'workbench.action.moveWindowTabToNewWindow', hasMultipleWindows)); - this.nativeTabMenuItems.push(this.createMenuItem(nls.localize('mMergeAllWindows', "Merge All Windows"), 'workbench.action.mergeAllWindowTabs', hasMultipleWindows)); - - nativeTabMenuItems.push(__separator__(), ...this.nativeTabMenuItems); - } else { - this.nativeTabMenuItems = []; - } - - [ - minimize, - zoom, - switchWindow, - ...nativeTabMenuItems, - __separator__(), - bringAllToFront - ].forEach(item => macWindowMenu.append(item)); - } - - private toggleDevTools(): void { - const w = this.windowsMainService.getFocusedWindow(); - if (w && w.win) { - const contents = w.win.webContents; - if (isMacintosh && w.hasHiddenTitleBarStyle() && !w.win.isFullScreen() && !contents.isDevToolsOpened()) { - contents.openDevTools({ mode: 'undocked' }); // due to https://github.com/electron/electron/issues/3647 - } else { - contents.toggleDevTools(); - } - } - } - - private setHelpMenu(helpMenu: Electron.Menu): void { - const toggleDevToolsItem = new MenuItem(this.likeAction('workbench.action.toggleDevTools', { - label: this.mnemonicLabel(nls.localize({ key: 'miToggleDevTools', comment: ['&& denotes a mnemonic'] }, "&&Toggle Developer Tools")), - click: () => this.toggleDevTools(), - enabled: (this.windowsMainService.getWindowCount() > 0) - })); - - const showAccessibilityOptions = new MenuItem(this.likeAction('accessibilityOptions', { - label: this.mnemonicLabel(nls.localize({ key: 'miAccessibilityOptions', comment: ['&& denotes a mnemonic'] }, "Accessibility &&Options")), - accelerator: null, - click: () => { - this.openAccessibilityOptions(); - } - }, false)); - - const openProcessExplorer = new MenuItem({ label: this.mnemonicLabel(nls.localize({ key: 'miOpenProcessExplorerer', comment: ['&& denotes a mnemonic'] }, "Open &&Process Explorer")), click: () => this.runActionInRenderer('workbench.action.openProcessExplorer') }); - - let reportIssuesItem: Electron.MenuItem = null; - if (product.reportIssueUrl) { - const label = nls.localize({ key: 'miReportIssue', comment: ['&& denotes a mnemonic', 'Translate this to "Report Issue in English" in all languages please!'] }, "Report &&Issue"); - - if (this.windowsMainService.getWindowCount() > 0) { - reportIssuesItem = this.createMenuItem(label, 'workbench.action.openIssueReporter'); - } else { - reportIssuesItem = new MenuItem({ label: this.mnemonicLabel(label), click: () => this.openUrl(product.reportIssueUrl, 'openReportIssues') }); - } - } - - const keyboardShortcutsUrl = isLinux ? product.keyboardShortcutsUrlLinux : isMacintosh ? product.keyboardShortcutsUrlMac : product.keyboardShortcutsUrlWin; - arrays.coalesce([ - new MenuItem({ label: this.mnemonicLabel(nls.localize({ key: 'miWelcome', comment: ['&& denotes a mnemonic'] }, "&&Welcome")), click: () => this.runActionInRenderer('workbench.action.showWelcomePage'), enabled: (this.windowsMainService.getWindowCount() > 0) }), - new MenuItem({ label: this.mnemonicLabel(nls.localize({ key: 'miInteractivePlayground', comment: ['&& denotes a mnemonic'] }, "&&Interactive Playground")), click: () => this.runActionInRenderer('workbench.action.showInteractivePlayground'), enabled: (this.windowsMainService.getWindowCount() > 0) }), - product.documentationUrl ? new MenuItem({ label: this.mnemonicLabel(nls.localize({ key: 'miDocumentation', comment: ['&& denotes a mnemonic'] }, "&&Documentation")), click: () => this.runActionInRenderer('workbench.action.openDocumentationUrl'), enabled: (this.windowsMainService.getWindowCount() > 0) }) : null, - product.releaseNotesUrl ? new MenuItem({ label: this.mnemonicLabel(nls.localize({ key: 'miReleaseNotes', comment: ['&& denotes a mnemonic'] }, "&&Release Notes")), click: () => this.runActionInRenderer('update.showCurrentReleaseNotes'), enabled: (this.windowsMainService.getWindowCount() > 0) }) : null, - __separator__(), - keyboardShortcutsUrl ? new MenuItem({ label: this.mnemonicLabel(nls.localize({ key: 'miKeyboardShortcuts', comment: ['&& denotes a mnemonic'] }, "&&Keyboard Shortcuts Reference")), click: () => this.runActionInRenderer('workbench.action.keybindingsReference'), enabled: (this.windowsMainService.getWindowCount() > 0) }) : null, - product.introductoryVideosUrl ? new MenuItem({ label: this.mnemonicLabel(nls.localize({ key: 'miIntroductoryVideos', comment: ['&& denotes a mnemonic'] }, "Introductory &&Videos")), click: () => this.runActionInRenderer('workbench.action.openIntroductoryVideosUrl'), enabled: (this.windowsMainService.getWindowCount() > 0) }) : null, - product.tipsAndTricksUrl ? new MenuItem({ label: this.mnemonicLabel(nls.localize({ key: 'miTipsAndTricks', comment: ['&& denotes a mnemonic'] }, "&&Tips and Tricks")), click: () => this.runActionInRenderer('workbench.action.openTipsAndTricksUrl'), enabled: (this.windowsMainService.getWindowCount() > 0) }) : null, - (product.introductoryVideosUrl || keyboardShortcutsUrl) ? __separator__() : null, - product.twitterUrl ? new MenuItem({ label: this.mnemonicLabel(nls.localize({ key: 'miTwitter', comment: ['&& denotes a mnemonic'] }, "&&Join us on Twitter")), click: () => this.openUrl(product.twitterUrl, 'openTwitterUrl') }) : null, - product.requestFeatureUrl ? new MenuItem({ label: this.mnemonicLabel(nls.localize({ key: 'miUserVoice', comment: ['&& denotes a mnemonic'] }, "&&Search Feature Requests")), click: () => this.openUrl(product.requestFeatureUrl, 'openUserVoiceUrl') }) : null, - reportIssuesItem, - (product.twitterUrl || product.requestFeatureUrl || product.reportIssueUrl) ? __separator__() : null, - product.licenseUrl ? new MenuItem({ - label: this.mnemonicLabel(nls.localize({ key: 'miLicense', comment: ['&& denotes a mnemonic'] }, "View &&License")), click: () => { - if (language) { - const queryArgChar = product.licenseUrl.indexOf('?') > 0 ? '&' : '?'; - this.openUrl(`${product.licenseUrl}${queryArgChar}lang=${language}`, 'openLicenseUrl'); - } else { - this.openUrl(product.licenseUrl, 'openLicenseUrl'); - } - } - }) : null, - product.privacyStatementUrl ? new MenuItem({ - label: this.mnemonicLabel(nls.localize({ key: 'miPrivacyStatement', comment: ['&& denotes a mnemonic'] }, "&&Privacy Statement")), click: () => { - if (language) { - const queryArgChar = product.licenseUrl.indexOf('?') > 0 ? '&' : '?'; - this.openUrl(`${product.privacyStatementUrl}${queryArgChar}lang=${language}`, 'openPrivacyStatement'); - } else { - this.openUrl(product.privacyStatementUrl, 'openPrivacyStatement'); - } - } - }) : null, - (product.licenseUrl || product.privacyStatementUrl) ? __separator__() : null, - toggleDevToolsItem, - openProcessExplorer, - isWindows && product.quality !== 'stable' ? showAccessibilityOptions : null, - ]).forEach(item => helpMenu.append(item)); - - if (!isMacintosh) { - const updateMenuItems = this.getUpdateMenuItems(); - if (updateMenuItems.length) { - helpMenu.append(__separator__()); - updateMenuItems.forEach(i => helpMenu.append(i)); - } - - helpMenu.append(__separator__()); - helpMenu.append(new MenuItem({ label: this.mnemonicLabel(nls.localize({ key: 'miAbout', comment: ['&& denotes a mnemonic'] }, "&&About")), click: () => this.windowsService.openAboutDialog() })); - } - } - - private setTaskMenu(taskMenu: Electron.Menu): void { - const runTask = this.createMenuItem(nls.localize({ key: 'miRunTask', comment: ['&& denotes a mnemonic'] }, "&&Run Task..."), 'workbench.action.tasks.runTask'); - const buildTask = this.createMenuItem(nls.localize({ key: 'miBuildTask', comment: ['&& denotes a mnemonic'] }, "Run &&Build Task..."), 'workbench.action.tasks.build'); - const showTasks = this.createMenuItem(nls.localize({ key: 'miRunningTask', comment: ['&& denotes a mnemonic'] }, "Show Runnin&&g Tasks..."), 'workbench.action.tasks.showTasks'); - const restartTask = this.createMenuItem(nls.localize({ key: 'miRestartTask', comment: ['&& denotes a mnemonic'] }, "R&&estart Running Task..."), 'workbench.action.tasks.restartTask'); - const terminateTask = this.createMenuItem(nls.localize({ key: 'miTerminateTask', comment: ['&& denotes a mnemonic'] }, "&&Terminate Task..."), 'workbench.action.tasks.terminate'); - const configureTask = this.createMenuItem(nls.localize({ key: 'miConfigureTask', comment: ['&& denotes a mnemonic'] }, "&&Configure Tasks..."), 'workbench.action.tasks.configureTaskRunner'); - const configureBuildTask = this.createMenuItem(nls.localize({ key: 'miConfigureBuildTask', comment: ['&& denotes a mnemonic'] }, "Configure De&&fault Build Task..."), 'workbench.action.tasks.configureDefaultBuildTask'); - - [ - //__separator__(), - runTask, - buildTask, - __separator__(), - terminateTask, - restartTask, - showTasks, - __separator__(), - configureTask, - configureBuildTask - ].forEach(item => taskMenu.append(item)); - } - - private openAccessibilityOptions(): void { - const win = new BrowserWindow({ - alwaysOnTop: true, - skipTaskbar: true, - resizable: false, - width: 450, - height: 300, - show: true, - title: nls.localize('accessibilityOptionsWindowTitle', "Accessibility Options"), - webPreferences: { - disableBlinkFeatures: 'Auxclick' - } - }); - - win.setMenuBarVisibility(false); - - win.loadURL('chrome://accessibility'); - } - - private getUpdateMenuItems(): Electron.MenuItem[] { - const state = this.updateService.state; - - switch (state.type) { - case StateType.Uninitialized: - return []; - - case StateType.Idle: - return [new MenuItem({ - label: nls.localize('miCheckForUpdates', "Check for Updates..."), click: () => setTimeout(() => { - this.reportMenuActionTelemetry('CheckForUpdate'); - - const focusedWindow = this.windowsMainService.getFocusedWindow(); - const context = focusedWindow ? { windowId: focusedWindow.id } : null; - this.updateService.checkForUpdates(context); - }, 0) - })]; - - case StateType.CheckingForUpdates: - return [new MenuItem({ label: nls.localize('miCheckingForUpdates', "Checking For Updates..."), enabled: false })]; - - case StateType.AvailableForDownload: - return [new MenuItem({ - label: nls.localize('miDownloadUpdate', "Download Available Update"), click: () => { - this.updateService.downloadUpdate(); - } - })]; - - case StateType.Downloading: - return [new MenuItem({ label: nls.localize('miDownloadingUpdate', "Downloading Update..."), enabled: false })]; - - case StateType.Downloaded: - return [new MenuItem({ - label: nls.localize('miInstallUpdate', "Install Update..."), click: () => { - this.reportMenuActionTelemetry('InstallUpdate'); - this.updateService.applyUpdate(); - } - })]; - - case StateType.Updating: - return [new MenuItem({ label: nls.localize('miInstallingUpdate', "Installing Update..."), enabled: false })]; - - case StateType.Ready: - return [new MenuItem({ - label: nls.localize('miRestartToUpdate', "Restart to Update..."), click: () => { - this.reportMenuActionTelemetry('RestartToUpdate'); - this.updateService.quitAndInstall(); - } - })]; - } - } - - private createMenuItem(label: string, commandId: string | string[], enabled?: boolean, checked?: boolean): Electron.MenuItem; - private createMenuItem(label: string, click: () => void, enabled?: boolean, checked?: boolean): Electron.MenuItem; - private createMenuItem(arg1: string, arg2: any, arg3?: boolean, arg4?: boolean): Electron.MenuItem { - const label = this.mnemonicLabel(arg1); - const click: () => void = (typeof arg2 === 'function') ? arg2 : (menuItem: Electron.MenuItem, win: Electron.BrowserWindow, event: Electron.Event) => { - let commandId = arg2; - if (Array.isArray(arg2)) { - commandId = this.isOptionClick(event) ? arg2[1] : arg2[0]; // support alternative action if we got multiple action Ids and the option key was pressed while invoking - } - - this.runActionInRenderer(commandId); - }; - const enabled = typeof arg3 === 'boolean' ? arg3 : this.windowsMainService.getWindowCount() > 0; - const checked = typeof arg4 === 'boolean' ? arg4 : false; - - const options: Electron.MenuItemConstructorOptions = { - label, - click, - enabled - }; - - if (checked) { - options['type'] = 'checkbox'; - options['checked'] = checked; - } - - let commandId: string; - if (typeof arg2 === 'string') { - commandId = arg2; - } else if (Array.isArray(arg2)) { - commandId = arg2[0]; - } - - return new MenuItem(this.withKeybinding(commandId, options)); - } - - private createContextAwareMenuItem(label: string, commandId: string, clickHandler: IMenuItemClickHandler): Electron.MenuItem { - return new MenuItem(this.withKeybinding(commandId, { - label: this.mnemonicLabel(label), - enabled: this.windowsMainService.getWindowCount() > 0, - click: () => { - - // No Active Window - const activeWindow = this.windowsMainService.getFocusedWindow(); - if (!activeWindow) { - return clickHandler.inNoWindow(); - } - - // DevTools focused - if (activeWindow.win.webContents.isDevToolsFocused()) { - return clickHandler.inDevTools(activeWindow.win.webContents.devToolsWebContents); - } - - // Finally execute command in Window - this.runActionInRenderer(commandId); - } - })); - } - - private runActionInRenderer(id: string): void { - // We make sure to not run actions when the window has no focus, this helps - // for https://github.com/Microsoft/vscode/issues/25907 and specifically for - // https://github.com/Microsoft/vscode/issues/11928 - const activeWindow = this.windowsMainService.getFocusedWindow(); - if (activeWindow) { - this.windowsMainService.sendToFocused('vscode:runAction', { id, from: 'menu' } as IRunActionInWindowRequest); - } - } - - private withKeybinding(commandId: string, options: Electron.MenuItemConstructorOptions): Electron.MenuItemConstructorOptions { - const binding = this.keybindingsResolver.getKeybinding(commandId); - - // Apply binding if there is one - if (binding && binding.label) { - - // if the binding is native, we can just apply it - if (binding.isNative) { - options.accelerator = binding.label; - } - - // the keybinding is not native so we cannot show it as part of the accelerator of - // the menu item. we fallback to a different strategy so that we always display it - else { - const bindingIndex = options.label.indexOf('['); - if (bindingIndex >= 0) { - options.label = `${options.label.substr(0, bindingIndex)} [${binding.label}]`; - } else { - options.label = `${options.label} [${binding.label}]`; - } - } - } - - // Unset bindings if there is none - else { - options.accelerator = void 0; - } - - return options; - } - - private likeAction(commandId: string, options: Electron.MenuItemConstructorOptions, setAccelerator = !options.accelerator): Electron.MenuItemConstructorOptions { - if (setAccelerator) { - options = this.withKeybinding(commandId, options); - } - - const originalClick = options.click; - options.click = (item, window, event) => { - this.reportMenuActionTelemetry(commandId); - if (originalClick) { - originalClick(item, window, event); - } - }; - - return options; - } - - private openUrl(url: string, id: string): void { - shell.openExternal(url); - this.reportMenuActionTelemetry(id); - } - - private reportMenuActionTelemetry(id: string): void { - /* __GDPR__ - "workbenchActionExecuted" : { - "id" : { "classification": "SystemMetaData", "purpose": "FeatureInsight" }, - "from": { "classification": "SystemMetaData", "purpose": "FeatureInsight" } - } - */ - this.telemetryService.publicLog('workbenchActionExecuted', { id, from: telemetryFrom }); - } - - private mnemonicLabel(label: string): string { - return baseMnemonicLabel(label, !this.currentEnableMenuBarMnemonics); - } -} - -function __separator__(): Electron.MenuItem { - return new MenuItem({ type: 'separator' }); -} diff --git a/src/vs/workbench/electron-browser/window.ts b/src/vs/workbench/electron-browser/window.ts index a87a8f73f31..2a48cb30130 100644 --- a/src/vs/workbench/electron-browser/window.ts +++ b/src/vs/workbench/electron-browser/window.ts @@ -9,7 +9,6 @@ import * as nls from 'vs/nls'; import URI from 'vs/base/common/uri'; import * as errors from 'vs/base/common/errors'; import { TPromise } from 'vs/base/common/winjs.base'; -import * as arrays from 'vs/base/common/arrays'; import * as objects from 'vs/base/common/objects'; import * as DOM from 'vs/base/browser/dom'; import { Separator } from 'vs/base/browser/ui/actionbar/actionbar'; @@ -21,13 +20,11 @@ import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry'; import { IWorkspaceConfigurationService } from 'vs/workbench/services/configuration/common/configuration'; import { IWindowsService, IWindowService, IWindowSettings, IPath, IOpenFileRequest, IWindowsConfiguration, IAddFoldersRequest, IRunActionInWindowRequest } from 'vs/platform/windows/common/windows'; import { IContextMenuService } from 'vs/platform/contextview/browser/contextView'; -import { IKeybindingService } from 'vs/platform/keybinding/common/keybinding'; import { ITitleService } from 'vs/workbench/services/title/common/titleService'; import { IWorkbenchThemeService, VS_HC_THEME, VS_DARK_THEME } from 'vs/workbench/services/themes/common/workbenchThemeService'; import * as browser from 'vs/base/browser/browser'; import { ICommandService } from 'vs/platform/commands/common/commands'; import { IResourceInput } from 'vs/platform/editor/common/editor'; -import { IExtensionService } from 'vs/workbench/services/extensions/common/extensions'; import { KeyboardMapperFactory } from 'vs/workbench/services/keybinding/electron-browser/keybindingService'; import { Themable } from 'vs/workbench/common/theme'; import { ipcRenderer as ipc, webFrame } from 'electron'; @@ -77,9 +74,7 @@ export class ElectronWindow extends Themable { @IWorkbenchThemeService protected themeService: IWorkbenchThemeService, @INotificationService private notificationService: INotificationService, @ICommandService private commandService: ICommandService, - @IExtensionService private extensionService: IExtensionService, @IContextMenuService private contextMenuService: IContextMenuService, - @IKeybindingService private keybindingService: IKeybindingService, @ITelemetryService private telemetryService: ITelemetryService, @IWorkspaceEditingService private workspaceEditingService: IWorkspaceEditingService, @IFileService private fileService: IFileService, @@ -141,23 +136,6 @@ export class ElectronWindow extends Themable { }); }); - // Support resolve keybindings event - ipc.on('vscode:resolveKeybindings', (event: any, rawActionIds: string) => { - let actionIds: string[] = []; - try { - actionIds = JSON.parse(rawActionIds); - } catch (error) { - // should not happen - } - - // Resolve keys using the keybinding service and send back to browser process - this.resolveKeybindings(actionIds).done(keybindings => { - if (keybindings.length) { - ipc.send('vscode:keybindingsResolved', JSON.stringify(keybindings)); - } - }, () => errors.onUnexpectedError); - }); - ipc.on('vscode:reportError', (event: any, error: string) => { if (error) { const errorParsed = JSON.parse(error); @@ -376,31 +354,6 @@ export class ElectronWindow extends Themable { } } - private resolveKeybindings(actionIds: string[]): TPromise<{ id: string; label: string, isNative: boolean; }[]> { - return TPromise.join([this.lifecycleService.when(LifecyclePhase.Running), this.extensionService.whenInstalledExtensionsRegistered()]).then(() => { - return arrays.coalesce(actionIds.map(id => { - const binding = this.keybindingService.lookupKeybinding(id); - if (!binding) { - return null; - } - - // first try to resolve a native accelerator - const electronAccelerator = binding.getElectronAccelerator(); - if (electronAccelerator) { - return { id, label: electronAccelerator, isNative: true }; - } - - // we need this fallback to support keybindings that cannot show in electron menus (e.g. chords) - const acceleratorLabel = binding.getLabel(); - if (acceleratorLabel) { - return { id, label: acceleratorLabel, isNative: false }; - } - - return null; - })); - }); - } - private onAddFoldersRequest(request: IAddFoldersRequest): void { // Buffer all pending requests From efbb2fbc1ccb30ea0f4ea2f48baafd9d4811e286 Mon Sep 17 00:00:00 2001 From: Jackson Kearl Date: Mon, 23 Jul 2018 11:33:08 -0700 Subject: [PATCH 0048/1276] Improve backwards compatibility case handling --- src/vs/editor/common/config/editorOptions.ts | 31 ++++++++++++-------- src/vs/monaco.d.ts | 8 ++--- 2 files changed, 22 insertions(+), 17 deletions(-) diff --git a/src/vs/editor/common/config/editorOptions.ts b/src/vs/editor/common/config/editorOptions.ts index af1589bae6b..d218da5193b 100644 --- a/src/vs/editor/common/config/editorOptions.ts +++ b/src/vs/editor/common/config/editorOptions.ts @@ -471,17 +471,17 @@ export interface IEditorOptions { iconsInSuggestions?: boolean; /** * Options for auto closing brackets. - * Defaults to language defined behavior + * Defaults to language defined behavior. */ autoClosingBrackets?: EditorAutoClosingStrategy; /** * Options for auto closing quotes. - * Defaults to language defined behavior + * Defaults to language defined behavior. */ autoClosingQuotes?: EditorAutoClosingStrategy; /** - * Options for autowrapping - * Defaults to always allowing autowrapping + * Options for autowrapping. + * Defaults to always allowing autowrapping. */ autoWrapping?: EditorAutoWrappingStrategy; /** @@ -1684,13 +1684,18 @@ export class EditorOptionsValidator { } const multiCursorModifier = _stringSet<'altKey' | 'metaKey' | 'ctrlKey'>(configuredMulticursorModifier, defaults.multiCursorModifier, ['altKey', 'metaKey', 'ctrlKey']); - let autoClosingBracketsDefault = defaults.autoClosingBrackets; - let autoClosingQuotesDefault = defaults.autoClosingQuotes; - let autoWrappingDefault = defaults.autoWrapping; + let autoClosingBrackets: EditorAutoClosingStrategy; + let autoClosingQuotes: EditorAutoClosingStrategy; + let autoWrapping: EditorAutoWrappingStrategy; if (typeof (opts.autoClosingBrackets) === 'boolean' && opts.autoClosingBrackets === false) { - autoClosingBracketsDefault = 'never'; - autoClosingQuotesDefault = 'never'; - autoWrappingDefault = 'never'; + // backwards compatibility: disable all on boolean false + autoClosingBrackets = 'never'; + autoClosingQuotes = 'never'; + autoWrapping = 'never'; + } else { + autoClosingBrackets = _stringSet(opts.autoClosingBrackets, defaults.autoClosingBrackets, ['always', 'languageDefined', 'beforeWhitespace', 'never']); + autoClosingQuotes = _stringSet(opts.autoClosingQuotes, defaults.autoClosingQuotes, ['always', 'languageDefined', 'beforeWhitespace', 'never']); + autoWrapping = _stringSet(opts.autoWrapping, defaults.autoWrapping, ['always', 'brackets', 'quotes', 'never'], ); } return { @@ -1709,9 +1714,9 @@ export class EditorOptionsValidator { wordWrapBreakBeforeCharacters: _string(opts.wordWrapBreakBeforeCharacters, defaults.wordWrapBreakBeforeCharacters), wordWrapBreakAfterCharacters: _string(opts.wordWrapBreakAfterCharacters, defaults.wordWrapBreakAfterCharacters), wordWrapBreakObtrusiveCharacters: _string(opts.wordWrapBreakObtrusiveCharacters, defaults.wordWrapBreakObtrusiveCharacters), - autoClosingBrackets: _stringSet(opts.autoClosingBrackets, autoClosingBracketsDefault, ['always', 'languageDefined', 'beforeWhitespace', 'never']), - autoClosingQuotes: _stringSet(opts.autoClosingQuotes, autoClosingQuotesDefault, ['always', 'languageDefined', 'beforeWhitespace', 'never']), - autoWrapping: _stringSet(opts.autoWrapping, autoWrappingDefault, ['always', 'brackets', 'quotes', 'never'], ), + autoClosingBrackets, + autoClosingQuotes, + autoWrapping, autoIndent: _boolean(opts.autoIndent, defaults.autoIndent), dragAndDrop: _boolean(opts.dragAndDrop, defaults.dragAndDrop), emptySelectionClipboard: _boolean(opts.emptySelectionClipboard, defaults.emptySelectionClipboard), diff --git a/src/vs/monaco.d.ts b/src/vs/monaco.d.ts index 34cb166d5ff..53431389492 100644 --- a/src/vs/monaco.d.ts +++ b/src/vs/monaco.d.ts @@ -2813,17 +2813,17 @@ declare namespace monaco.editor { iconsInSuggestions?: boolean; /** * Options for auto closing brackets. - * Defaults to language defined behavior + * Defaults to language defined behavior. */ autoClosingBrackets?: EditorAutoClosingStrategy; /** * Options for auto closing quotes. - * Defaults to language defined behavior + * Defaults to language defined behavior. */ autoClosingQuotes?: EditorAutoClosingStrategy; /** - * Options for autowrapping - * Defaults to always allowing autowrapping + * Options for autowrapping. + * Defaults to always allowing autowrapping. */ autoWrapping?: EditorAutoWrappingStrategy; /** From 70875e2eef75cba226aa45bf72d74e2da29d3d1b Mon Sep 17 00:00:00 2001 From: Jackson Kearl Date: Mon, 23 Jul 2018 11:55:28 -0700 Subject: [PATCH 0049/1276] Fix language defined config --- .../editor/common/modes/languageConfigurationRegistry.ts | 3 ++- src/vs/editor/common/modes/supports/characterPair.ts | 4 ++-- .../languageConfigurationExtensionPoint.ts | 7 +++++++ 3 files changed, 11 insertions(+), 3 deletions(-) diff --git a/src/vs/editor/common/modes/languageConfigurationRegistry.ts b/src/vs/editor/common/modes/languageConfigurationRegistry.ts index 65ab6f817c6..c543dfc5698 100644 --- a/src/vs/editor/common/modes/languageConfigurationRegistry.ts +++ b/src/vs/editor/common/modes/languageConfigurationRegistry.ts @@ -119,6 +119,7 @@ export class RichEditSupport { onEnterRules: (prev ? current.onEnterRules || prev.onEnterRules : current.onEnterRules), autoClosingPairs: (prev ? current.autoClosingPairs || prev.autoClosingPairs : current.autoClosingPairs), surroundingPairs: (prev ? current.surroundingPairs || prev.surroundingPairs : current.surroundingPairs), + autoCloseBefore: (prev ? current.autoCloseBefore || prev.autoCloseBefore : current.autoCloseBefore), folding: (prev ? current.folding || prev.folding : current.folding), __electricCharacterSupport: (prev ? current.__electricCharacterSupport || prev.__electricCharacterSupport : current.__electricCharacterSupport), }; @@ -274,7 +275,7 @@ export class LanguageConfigurationRegistryImpl { public getAutoCloseBeforeSet(languageId: LanguageId): string { let characterPairSupport = this._getCharacterPairSupport(languageId); if (!characterPairSupport) { - return CharacterPairSupport.DEFAULT_AUTOCLOSE_BEFORE_LANGAGE_DEFINED; + return CharacterPairSupport.DEFAULT_AUTOCLOSE_BEFORE_LANGUAGE_DEFINED; } return characterPairSupport.getAutoCloseBeforeSet(); } diff --git a/src/vs/editor/common/modes/supports/characterPair.ts b/src/vs/editor/common/modes/supports/characterPair.ts index f437f6b139e..70eb9ed7b65 100644 --- a/src/vs/editor/common/modes/supports/characterPair.ts +++ b/src/vs/editor/common/modes/supports/characterPair.ts @@ -9,7 +9,7 @@ import { CharacterPair, IAutoClosingPair, IAutoClosingPairConditional, StandardA export class CharacterPairSupport { - static readonly DEFAULT_AUTOCLOSE_BEFORE_LANGAGE_DEFINED = ';:.,=}])> \n\t'; + static readonly DEFAULT_AUTOCLOSE_BEFORE_LANGUAGE_DEFINED = ';:.,=}])> \n\t'; static readonly DEFAULT_AUTOCLOSE_BEFORE_WHITESPACE = ' \n\t'; private readonly _autoClosingPairs: StandardAutoClosingPairConditional[]; @@ -25,7 +25,7 @@ export class CharacterPairSupport { this._autoClosingPairs = []; } - this._autoCloseBefore = typeof config.autoCloseBefore === 'string' ? config.autoCloseBefore : CharacterPairSupport.DEFAULT_AUTOCLOSE_BEFORE_LANGAGE_DEFINED; + this._autoCloseBefore = typeof config.autoCloseBefore === 'string' ? config.autoCloseBefore : CharacterPairSupport.DEFAULT_AUTOCLOSE_BEFORE_LANGUAGE_DEFINED; this._surroundingPairs = config.surroundingPairs || this._autoClosingPairs; } diff --git a/src/vs/workbench/parts/codeEditor/electron-browser/languageConfiguration/languageConfigurationExtensionPoint.ts b/src/vs/workbench/parts/codeEditor/electron-browser/languageConfiguration/languageConfigurationExtensionPoint.ts index 6cf9ddb02c0..6dff0d734b0 100644 --- a/src/vs/workbench/parts/codeEditor/electron-browser/languageConfiguration/languageConfigurationExtensionPoint.ts +++ b/src/vs/workbench/parts/codeEditor/electron-browser/languageConfiguration/languageConfigurationExtensionPoint.ts @@ -38,6 +38,7 @@ interface ILanguageConfiguration { wordPattern?: string | IRegExp; indentationRules?: IIndentationRules; folding?: FoldingRules; + autoCloseBefore?: string; } function isStringArr(something: string[]): boolean { @@ -274,6 +275,12 @@ export class LanguageConfigurationFileHandler { richEditConfig.surroundingPairs = surroundingPairs; } + const autoCloseBefore = configuration.autoCloseBefore; + if (typeof autoCloseBefore === 'string') { + richEditConfig.autoCloseBefore = autoCloseBefore; + } + + if (configuration.wordPattern) { try { let wordPattern = this._parseRegex(configuration.wordPattern); From 183818a1b07400eed2d9b391ac024ff0ceff1224 Mon Sep 17 00:00:00 2001 From: Jackson Kearl Date: Mon, 23 Jul 2018 13:13:06 -0700 Subject: [PATCH 0050/1276] Adopt 'enumDescription' in settings contribution --- .../common/config/commonEditorConfig.ts | 25 ++++++++++++++++--- 1 file changed, 22 insertions(+), 3 deletions(-) diff --git a/src/vs/editor/common/config/commonEditorConfig.ts b/src/vs/editor/common/config/commonEditorConfig.ts index 745de474cfc..5bd74304326 100644 --- a/src/vs/editor/common/config/commonEditorConfig.ts +++ b/src/vs/editor/common/config/commonEditorConfig.ts @@ -490,20 +490,39 @@ const editorConfiguration: IConfigurationNode = { 'editor.autoClosingBrackets': { type: 'string', enum: ['always', 'languageDefined', 'beforeWhitespace', 'never'], + enumDescriptions: [ + nls.localize('editor.autoClosingBrackets.always', "always autoclose brackets"), + nls.localize('editor.autoClosingBrackets.languageDefined', "use language configurations to determine when to autoclose brackets"), + nls.localize('editor.autoClosingBrackets.beforeWhitespace', "autoclose brackets only when the cursor is to the left of whitespace"), + nls.localize('editor.autoClosingBrackets.never', "never perform autoclosing on brackets"), + + ], 'default': EDITOR_DEFAULTS.autoClosingBrackets, - 'description': nls.localize('autoClosingBrackets', "Controls if the editor should automatically close brackets after opening them. Can be:\n 'always' - always autoclose brackets\n 'languageDefined' - use installed extensions to determine when to autoclose brackets\n 'beforeWhitespace' - autoclose brackets only when the cursor is to the left of whitespace\n 'never' - never perform autoclosing on brackets") + 'description': nls.localize('autoClosingBrackets', "Controls if the editor should automatically close brackets after opening them.") }, 'editor.autoClosingQuotes': { type: 'string', enum: ['always', 'languageDefined', 'beforeWhitespace', 'never'], + enumDescriptions: [ + nls.localize('editor.autoClosingQuotes.always', "always autoclose quotes"), + nls.localize('editor.autoClosingQuotes.languageDefined', "use language configurations to determine when to autoclose quotes"), + nls.localize('editor.autoClosingQuotes.beforeWhitespace', "autoclose quotes only when the cursor is to the left of whitespace"), + nls.localize('editor.autoClosingQuotes.never', "never perform autoclosing on quotes"), + ], 'default': EDITOR_DEFAULTS.autoClosingQuotes, - 'description': nls.localize('autoClosingQuotes', "Controls if the editor should automatically close quotes after opening them. Can be:\n 'always' - always autoclose quotes\n 'languageDefined' - use installed extensions to determine when to autoclose quotes\n 'beforeWhitespace' - autoclose quotes only when the cursor is to the left of whitespace\n 'never' - never perform autoclosing on quotes") + 'description': nls.localize('autoClosingQuotes', "Controls if the editor should automatically close quotes after opening them.") }, 'editor.autoWrapping': { type: 'string', enum: ['always', 'brackets', 'quotes', 'never'], + enumDescriptions: [ + nls.localize('editor.autoWrapping.always', "wrap with both quotes and brackets"), + nls.localize('editor.autoWrapping.brackets', " wrap with brackets but not quotes"), + nls.localize('editor.autoWrapping.quotes', "wrap with quotes but not brackets"), + nls.localize('editor.autoWrapping.never', "do not autowrap selections") + ], 'default': EDITOR_DEFAULTS.autoWrapping, - 'description': nls.localize('autoWrapping', "Controls if the editor should automatically wrap selections. Can be:\n 'always' - wrap with both quotes and brackets,\n 'brackets' - wrap with brackets but not quotes,\n 'quotes' - wrap with quotes but not brackets,\n 'never' - do not autowrap selections") + 'description': nls.localize('autoWrapping', "Controls if the editor should automatically wrap selections.") }, 'editor.formatOnType': { 'type': 'boolean', From 4109e4e0939b352ce02896a00551a1378fa1b290 Mon Sep 17 00:00:00 2001 From: Jackson Kearl Date: Mon, 23 Jul 2018 13:16:50 -0700 Subject: [PATCH 0051/1276] Restore trailing newline --- extensions/html-language-features/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/extensions/html-language-features/package.json b/extensions/html-language-features/package.json index c580436394f..9ac18e38fbb 100644 --- a/extensions/html-language-features/package.json +++ b/extensions/html-language-features/package.json @@ -181,4 +181,4 @@ "devDependencies": { "@types/node": "7.0.43" } -} \ No newline at end of file +} From 5f87eae791903272fe5f3b9ab8c58103fba7f472 Mon Sep 17 00:00:00 2001 From: SteVen Batten <6561887+sbatten@users.noreply.github.com> Date: Mon, 23 Jul 2018 13:21:42 -0700 Subject: [PATCH 0052/1276] add go submenus --- src/vs/code/electron-main/menus.ts | 1316 ----------------- src/vs/platform/actions/common/actions.ts | 2 + .../parts/menubar/menubar.contribution.ts | 128 +- 3 files changed, 95 insertions(+), 1351 deletions(-) delete mode 100644 src/vs/code/electron-main/menus.ts diff --git a/src/vs/code/electron-main/menus.ts b/src/vs/code/electron-main/menus.ts deleted file mode 100644 index 54cf3480930..00000000000 --- a/src/vs/code/electron-main/menus.ts +++ /dev/null @@ -1,1316 +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'; - -import * as nls from 'vs/nls'; -import { isMacintosh, isLinux, isWindows, language } from 'vs/base/common/platform'; -import * as arrays from 'vs/base/common/arrays'; -import { IEnvironmentService } from 'vs/platform/environment/common/environment'; -import { app, shell, Menu, MenuItem, BrowserWindow } from 'electron'; -import { OpenContext, IRunActionInWindowRequest, IWindowsService } from 'vs/platform/windows/common/windows'; -import { IConfigurationService, IConfigurationChangeEvent } from 'vs/platform/configuration/common/configuration'; -import { AutoSaveConfiguration } from 'vs/platform/files/common/files'; -import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry'; -import { IUpdateService, StateType } from 'vs/platform/update/common/update'; -import product from 'vs/platform/node/product'; -import { RunOnceScheduler } from 'vs/base/common/async'; -import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; -import { mnemonicMenuLabel as baseMnemonicLabel, unmnemonicLabel, getPathLabel } from 'vs/base/common/labels'; -import { KeybindingsResolver } from 'vs/code/electron-main/keyboard'; -import { IWindowsMainService, IWindowsCountChangedEvent } from 'vs/platform/windows/electron-main/windows'; -import { IHistoryMainService } from 'vs/platform/history/common/history'; -import { IWorkspaceIdentifier, getWorkspaceLabel, ISingleFolderWorkspaceIdentifier, isSingleFolderWorkspaceIdentifier, isWorkspaceIdentifier } from 'vs/platform/workspaces/common/workspaces'; -import URI from 'vs/base/common/uri'; - -interface IMenuItemClickHandler { - inDevTools: (contents: Electron.WebContents) => void; - inNoWindow: () => void; -} - -const telemetryFrom = 'menu'; - -export class CodeMenu { - - private static readonly MAX_MENU_RECENT_ENTRIES = 10; - - private keys = [ - 'files.autoSave', - 'editor.multiCursorModifier', - 'workbench.sideBar.location', - 'workbench.statusBar.visible', - 'workbench.activityBar.visible', - 'window.enableMenuBarMnemonics', - 'window.nativeTabs' - ]; - - private isQuitting: boolean; - private appMenuInstalled: boolean; - - private menuUpdater: RunOnceScheduler; - - private keybindingsResolver: KeybindingsResolver; - - private closeFolder: Electron.MenuItem; - private closeWorkspace: Electron.MenuItem; - - private nativeTabMenuItems: Electron.MenuItem[]; - - constructor( - @IUpdateService private updateService: IUpdateService, - @IInstantiationService instantiationService: IInstantiationService, - @IConfigurationService private configurationService: IConfigurationService, - @IWindowsMainService private windowsMainService: IWindowsMainService, - @IWindowsService private windowsService: IWindowsService, - @IEnvironmentService private environmentService: IEnvironmentService, - @ITelemetryService private telemetryService: ITelemetryService, - @IHistoryMainService private historyMainService: IHistoryMainService - ) { - this.nativeTabMenuItems = []; - - this.menuUpdater = new RunOnceScheduler(() => this.doUpdateMenu(), 0); - this.keybindingsResolver = instantiationService.createInstance(KeybindingsResolver); - - this.install(); - - this.registerListeners(); - } - - private registerListeners(): void { - - // Keep flag when app quits - app.on('will-quit', () => { - this.isQuitting = true; - }); - - // Listen to some events from window service to update menu - this.historyMainService.onRecentlyOpenedChange(() => this.updateMenu()); - this.windowsMainService.onWindowsCountChanged(e => this.onWindowsCountChanged(e)); - this.windowsMainService.onActiveWindowChanged(() => this.updateWorkspaceMenuItems()); - this.windowsMainService.onWindowReady(() => this.updateWorkspaceMenuItems()); - this.windowsMainService.onWindowClose(() => this.updateWorkspaceMenuItems()); - - // Update when auto save config changes - this.configurationService.onDidChangeConfiguration(e => this.onConfigurationUpdated(e)); - - // Listen to update service - this.updateService.onStateChange(() => this.updateMenu()); - - // Listen to keybindings change - this.keybindingsResolver.onKeybindingsChanged(() => this.updateMenu()); - } - - private onConfigurationUpdated(event: IConfigurationChangeEvent): void { - if (this.keys.some(key => event.affectsConfiguration(key))) { - this.updateMenu(); - } - } - - private get currentAutoSaveSetting(): string { - return this.configurationService.getValue('files.autoSave'); - } - - private get currentMultiCursorModifierSetting(): string { - return this.configurationService.getValue('editor.multiCursorModifier'); - } - - private get currentSidebarLocation(): string { - return this.configurationService.getValue('workbench.sideBar.location') || 'left'; - } - - private get currentStatusbarVisible(): boolean { - let statusbarVisible = this.configurationService.getValue('workbench.statusBar.visible'); - if (typeof statusbarVisible !== 'boolean') { - statusbarVisible = true; - } - return statusbarVisible; - } - - private get currentActivityBarVisible(): boolean { - let activityBarVisible = this.configurationService.getValue('workbench.activityBar.visible'); - if (typeof activityBarVisible !== 'boolean') { - activityBarVisible = true; - } - return activityBarVisible; - } - - private get currentEnableMenuBarMnemonics(): boolean { - let enableMenuBarMnemonics = this.configurationService.getValue('window.enableMenuBarMnemonics'); - if (typeof enableMenuBarMnemonics !== 'boolean') { - enableMenuBarMnemonics = true; - } - return enableMenuBarMnemonics; - } - - private get currentEnableNativeTabs(): boolean { - let enableNativeTabs = this.configurationService.getValue('window.nativeTabs'); - if (typeof enableNativeTabs !== 'boolean') { - enableNativeTabs = false; - } - return enableNativeTabs; - } - - private updateMenu(): void { - this.menuUpdater.schedule(); // buffer multiple attempts to update the menu - } - - private doUpdateMenu(): void { - - // Due to limitations in Electron, it is not possible to update menu items dynamically. The suggested - // workaround from Electron is to set the application menu again. - // See also https://github.com/electron/electron/issues/846 - // - // Run delayed to prevent updating menu while it is open - if (!this.isQuitting) { - setTimeout(() => { - if (!this.isQuitting) { - this.install(); - } - }, 10 /* delay this because there is an issue with updating a menu when it is open */); - } - } - - private onWindowsCountChanged(e: IWindowsCountChangedEvent): void { - if (!isMacintosh) { - return; - } - - // Update menu if window count goes from N > 0 or 0 > N to update menu item enablement - if ((e.oldCount === 0 && e.newCount > 0) || (e.oldCount > 0 && e.newCount === 0)) { - this.updateMenu(); - } - - // Update specific items that are dependent on window count - else if (this.currentEnableNativeTabs) { - this.nativeTabMenuItems.forEach(item => { - if (item) { - item.enabled = e.newCount > 1; - } - }); - } - } - - private updateWorkspaceMenuItems(): void { - const window = this.windowsMainService.getLastActiveWindow(); - const isInWorkspaceContext = window && !!window.openedWorkspace; - const isInFolderContext = window && !!window.openedFolderUri; - - this.closeWorkspace.visible = isInWorkspaceContext; - this.closeFolder.visible = !isInWorkspaceContext; - this.closeFolder.enabled = isInFolderContext || isLinux /* https://github.com/Microsoft/vscode/issues/36431 */; - } - - private install(): void { - - // Menus - const menubar = new Menu(); - - // Mac: Application - let macApplicationMenuItem: Electron.MenuItem; - if (isMacintosh) { - const applicationMenu = new Menu(); - macApplicationMenuItem = new MenuItem({ label: product.nameShort, submenu: applicationMenu }); - this.setMacApplicationMenu(applicationMenu); - } - - // File - const fileMenu = new Menu(); - const fileMenuItem = new MenuItem({ label: this.mnemonicLabel(nls.localize({ key: 'mFile', comment: ['&& denotes a mnemonic'] }, "&&File")), submenu: fileMenu }); - this.setFileMenu(fileMenu); - - // Edit - const editMenu = new Menu(); - const editMenuItem = new MenuItem({ label: this.mnemonicLabel(nls.localize({ key: 'mEdit', comment: ['&& denotes a mnemonic'] }, "&&Edit")), submenu: editMenu }); - this.setEditMenu(editMenu); - - // Selection - const selectionMenu = new Menu(); - const selectionMenuItem = new MenuItem({ label: this.mnemonicLabel(nls.localize({ key: 'mSelection', comment: ['&& denotes a mnemonic'] }, "&&Selection")), submenu: selectionMenu }); - this.setSelectionMenu(selectionMenu); - - // View - const viewMenu = new Menu(); - const viewMenuItem = new MenuItem({ label: this.mnemonicLabel(nls.localize({ key: 'mView', comment: ['&& denotes a mnemonic'] }, "&&View")), submenu: viewMenu }); - this.setViewMenu(viewMenu); - - // Goto - const gotoMenu = new Menu(); - const gotoMenuItem = new MenuItem({ label: this.mnemonicLabel(nls.localize({ key: 'mGoto', comment: ['&& denotes a mnemonic'] }, "&&Go")), submenu: gotoMenu }); - this.setGotoMenu(gotoMenu); - - // Terminal - const terminalMenu = new Menu(); - const terminalMenuItem = new MenuItem({ label: this.mnemonicLabel(nls.localize({ key: 'mTerminal', comment: ['&& denotes a mnemonic'] }, "Ter&&minal")), submenu: terminalMenu }); - this.setTerminalMenu(terminalMenu); - - // Debug - const debugMenu = new Menu(); - const debugMenuItem = new MenuItem({ label: this.mnemonicLabel(nls.localize({ key: 'mDebug', comment: ['&& denotes a mnemonic'] }, "&&Debug")), submenu: debugMenu }); - this.setDebugMenu(debugMenu); - - // Mac: Window - let macWindowMenuItem: Electron.MenuItem; - if (isMacintosh) { - const windowMenu = new Menu(); - macWindowMenuItem = new MenuItem({ label: this.mnemonicLabel(nls.localize('mWindow', "Window")), submenu: windowMenu, role: 'window' }); - this.setMacWindowMenu(windowMenu); - } - - // Help - const helpMenu = new Menu(); - const helpMenuItem = new MenuItem({ label: this.mnemonicLabel(nls.localize({ key: 'mHelp', comment: ['&& denotes a mnemonic'] }, "&&Help")), submenu: helpMenu, role: 'help' }); - this.setHelpMenu(helpMenu); - - // Tasks - const taskMenu = new Menu(); - const taskMenuItem = new MenuItem({ label: this.mnemonicLabel(nls.localize({ key: 'mTask', comment: ['&& denotes a mnemonic'] }, "&&Tasks")), submenu: taskMenu }); - this.setTaskMenu(taskMenu); - - // Menu Structure - if (macApplicationMenuItem) { - menubar.append(macApplicationMenuItem); - } - - menubar.append(fileMenuItem); - menubar.append(editMenuItem); - menubar.append(selectionMenuItem); - menubar.append(viewMenuItem); - menubar.append(gotoMenuItem); - menubar.append(terminalMenuItem); - menubar.append(debugMenuItem); - menubar.append(taskMenuItem); - - if (macWindowMenuItem) { - menubar.append(macWindowMenuItem); - } - - menubar.append(helpMenuItem); - - Menu.setApplicationMenu(menubar); - - // Dock Menu - if (isMacintosh && !this.appMenuInstalled) { - this.appMenuInstalled = true; - - const dockMenu = new Menu(); - dockMenu.append(new MenuItem({ label: this.mnemonicLabel(nls.localize({ key: 'miNewWindow', comment: ['&& denotes a mnemonic'] }, "New &&Window")), click: () => this.windowsMainService.openNewWindow(OpenContext.DOCK) })); - - app.dock.setMenu(dockMenu); - } - } - - private setMacApplicationMenu(macApplicationMenu: Electron.Menu): void { - const about = new MenuItem({ label: nls.localize('mAbout', "About {0}", product.nameLong), role: 'about' }); - const checkForUpdates = this.getUpdateMenuItems(); - const preferences = this.getPreferencesMenu(); - const servicesMenu = new Menu(); - const services = new MenuItem({ label: nls.localize('mServices', "Services"), role: 'services', submenu: servicesMenu }); - const hide = new MenuItem({ label: nls.localize('mHide', "Hide {0}", product.nameLong), role: 'hide', accelerator: 'Command+H' }); - const hideOthers = new MenuItem({ label: nls.localize('mHideOthers', "Hide Others"), role: 'hideothers', accelerator: 'Command+Alt+H' }); - const showAll = new MenuItem({ label: nls.localize('mShowAll', "Show All"), role: 'unhide' }); - const quit = new MenuItem(this.likeAction('workbench.action.quit', { - label: nls.localize('miQuit', "Quit {0}", product.nameLong), click: () => { - if (this.windowsMainService.getWindowCount() === 0 || !!BrowserWindow.getFocusedWindow()) { - this.windowsMainService.quit(); // fix for https://github.com/Microsoft/vscode/issues/39191 - } - } - })); - - const actions = [about]; - actions.push(...checkForUpdates); - actions.push(...[ - __separator__(), - preferences, - __separator__(), - services, - __separator__(), - hide, - hideOthers, - showAll, - __separator__(), - quit - ]); - - actions.forEach(i => macApplicationMenu.append(i)); - } - - private setFileMenu(fileMenu: Electron.Menu): void { - const hasNoWindows = (this.windowsMainService.getWindowCount() === 0); - - let newFile: Electron.MenuItem; - if (hasNoWindows) { - newFile = new MenuItem(this.likeAction('workbench.action.files.newUntitledFile', { label: this.mnemonicLabel(nls.localize({ key: 'miNewFile', comment: ['&& denotes a mnemonic'] }, "&&New File")), click: () => this.windowsMainService.openNewWindow(OpenContext.MENU) })); - } else { - newFile = this.createMenuItem(nls.localize({ key: 'miNewFile', comment: ['&& denotes a mnemonic'] }, "&&New File"), 'workbench.action.files.newUntitledFile'); - } - - let open: Electron.MenuItem; - if (hasNoWindows) { - open = new MenuItem(this.likeAction('workbench.action.files.openFileFolder', { label: this.mnemonicLabel(nls.localize({ key: 'miOpen', comment: ['&& denotes a mnemonic'] }, "&&Open...")), click: (menuItem, win, event) => this.windowsMainService.pickFileFolderAndOpen({ forceNewWindow: this.isOptionClick(event), telemetryExtraData: { from: telemetryFrom } }) })); - } else { - open = this.createMenuItem(nls.localize({ key: 'miOpen', comment: ['&& denotes a mnemonic'] }, "&&Open..."), ['workbench.action.files.openFileFolder', 'workbench.action.files.openFileFolderInNewWindow']); - } - - let openWorkspace: Electron.MenuItem; - if (hasNoWindows) { - openWorkspace = new MenuItem(this.likeAction('workbench.action.openWorkspace', { label: this.mnemonicLabel(nls.localize({ key: 'miOpenWorkspace', comment: ['&& denotes a mnemonic'] }, "Open Wor&&kspace...")), click: (menuItem, win, event) => this.windowsMainService.pickWorkspaceAndOpen({ forceNewWindow: this.isOptionClick(event), telemetryExtraData: { from: telemetryFrom } }) })); - } else { - openWorkspace = this.createMenuItem(nls.localize({ key: 'miOpenWorkspace', comment: ['&& denotes a mnemonic'] }, "Open Wor&&kspace..."), ['workbench.action.openWorkspace', 'workbench.action.openWorkspaceInNewWindow']); - } - - let openFolder: Electron.MenuItem; - if (hasNoWindows) { - openFolder = new MenuItem(this.likeAction('workbench.action.files.openFolder', { label: this.mnemonicLabel(nls.localize({ key: 'miOpenFolder', comment: ['&& denotes a mnemonic'] }, "Open &&Folder...")), click: (menuItem, win, event) => this.windowsMainService.pickFolderAndOpen({ forceNewWindow: this.isOptionClick(event), telemetryExtraData: { from: telemetryFrom } }) })); - } else { - openFolder = this.createMenuItem(nls.localize({ key: 'miOpenFolder', comment: ['&& denotes a mnemonic'] }, "Open &&Folder..."), ['workbench.action.files.openFolder', 'workbench.action.files.openFolderInNewWindow']); - } - - let openFile: Electron.MenuItem; - if (hasNoWindows) { - openFile = new MenuItem(this.likeAction('workbench.action.files.openFile', { label: this.mnemonicLabel(nls.localize({ key: 'miOpenFile', comment: ['&& denotes a mnemonic'] }, "&&Open File...")), click: (menuItem, win, event) => this.windowsMainService.pickFileAndOpen({ forceNewWindow: this.isOptionClick(event), telemetryExtraData: { from: telemetryFrom } }) })); - } else { - openFile = this.createMenuItem(nls.localize({ key: 'miOpenFile', comment: ['&& denotes a mnemonic'] }, "&&Open File..."), ['workbench.action.files.openFile', 'workbench.action.files.openFileInNewWindow']); - } - - const openRecentMenu = new Menu(); - this.setOpenRecentMenu(openRecentMenu); - const openRecent = new MenuItem({ label: this.mnemonicLabel(nls.localize({ key: 'miOpenRecent', comment: ['&& denotes a mnemonic'] }, "Open &&Recent")), submenu: openRecentMenu, enabled: openRecentMenu.items.length > 0 }); - - const saveWorkspaceAs = this.createMenuItem(nls.localize('miSaveWorkspaceAs', "Save Workspace As..."), 'workbench.action.saveWorkspaceAs'); - const addFolder = this.createMenuItem(nls.localize({ key: 'miAddFolderToWorkspace', comment: ['&& denotes a mnemonic'] }, "A&&dd Folder to Workspace..."), 'workbench.action.addRootFolder'); - - const saveFile = this.createMenuItem(nls.localize({ key: 'miSave', comment: ['&& denotes a mnemonic'] }, "&&Save"), 'workbench.action.files.save'); - const saveFileAs = this.createMenuItem(nls.localize({ key: 'miSaveAs', comment: ['&& denotes a mnemonic'] }, "Save &&As..."), 'workbench.action.files.saveAs'); - const saveAllFiles = this.createMenuItem(nls.localize({ key: 'miSaveAll', comment: ['&& denotes a mnemonic'] }, "Save A&&ll"), 'workbench.action.files.saveAll'); - - const autoSaveEnabled = [AutoSaveConfiguration.AFTER_DELAY, AutoSaveConfiguration.ON_FOCUS_CHANGE, AutoSaveConfiguration.ON_WINDOW_CHANGE].some(s => this.currentAutoSaveSetting === s); - - const autoSave = this.createMenuItem(this.mnemonicLabel(nls.localize('miAutoSave', "Auto Save")), 'workbench.action.toggleAutoSave', this.windowsMainService.getWindowCount() > 0, autoSaveEnabled); - - const preferences = this.getPreferencesMenu(); - - const newWindow = new MenuItem(this.likeAction('workbench.action.newWindow', { label: this.mnemonicLabel(nls.localize({ key: 'miNewWindow', comment: ['&& denotes a mnemonic'] }, "New &&Window")), click: () => this.windowsMainService.openNewWindow(OpenContext.MENU) })); - const revertFile = this.createMenuItem(nls.localize({ key: 'miRevert', comment: ['&& denotes a mnemonic'] }, "Re&&vert File"), 'workbench.action.files.revert'); - const closeWindow = new MenuItem(this.likeAction('workbench.action.closeWindow', { label: this.mnemonicLabel(nls.localize({ key: 'miCloseWindow', comment: ['&& denotes a mnemonic'] }, "Clos&&e Window")), click: () => this.windowsMainService.getLastActiveWindow().win.close(), enabled: this.windowsMainService.getWindowCount() > 0 })); - - this.closeWorkspace = this.createMenuItem(nls.localize({ key: 'miCloseWorkspace', comment: ['&& denotes a mnemonic'] }, "Close &&Workspace"), 'workbench.action.closeFolder'); - this.closeFolder = this.createMenuItem(nls.localize({ key: 'miCloseFolder', comment: ['&& denotes a mnemonic'] }, "Close &&Folder"), 'workbench.action.closeFolder'); - - const closeEditor = this.createMenuItem(nls.localize({ key: 'miCloseEditor', comment: ['&& denotes a mnemonic'] }, "&&Close Editor"), 'workbench.action.closeActiveEditor'); - - const exit = new MenuItem(this.likeAction('workbench.action.quit', { label: this.mnemonicLabel(nls.localize({ key: 'miExit', comment: ['&& denotes a mnemonic'] }, "E&&xit")), click: () => this.windowsMainService.quit() })); - - this.updateWorkspaceMenuItems(); - - arrays.coalesce([ - newFile, - newWindow, - __separator__(), - isMacintosh ? open : null, - !isMacintosh ? openFile : null, - !isMacintosh ? openFolder : null, - openWorkspace, - openRecent, - __separator__(), - addFolder, - saveWorkspaceAs, - __separator__(), - saveFile, - saveFileAs, - saveAllFiles, - __separator__(), - autoSave, - __separator__(), - !isMacintosh ? preferences : null, - !isMacintosh ? __separator__() : null, - revertFile, - closeEditor, - this.closeWorkspace, - this.closeFolder, - closeWindow, - !isMacintosh ? __separator__() : null, - !isMacintosh ? exit : null - ]).forEach(item => fileMenu.append(item)); - } - - private getPreferencesMenu(): Electron.MenuItem { - const settings = this.createMenuItem(nls.localize({ key: 'miOpenSettings', comment: ['&& denotes a mnemonic'] }, "&&Settings"), 'workbench.action.openSettings2'); - const kebindingSettings = this.createMenuItem(nls.localize({ key: 'miOpenKeymap', comment: ['&& denotes a mnemonic'] }, "&&Keyboard Shortcuts"), 'workbench.action.openGlobalKeybindings'); - const keymapExtensions = this.createMenuItem(nls.localize({ key: 'miOpenKeymapExtensions', comment: ['&& denotes a mnemonic'] }, "&&Keymap Extensions"), 'workbench.extensions.action.showRecommendedKeymapExtensions'); - const snippetsSettings = this.createMenuItem(nls.localize({ key: 'miOpenSnippets', comment: ['&& denotes a mnemonic'] }, "User &&Snippets"), 'workbench.action.openSnippets'); - const colorThemeSelection = this.createMenuItem(nls.localize({ key: 'miSelectColorTheme', comment: ['&& denotes a mnemonic'] }, "&&Color Theme"), 'workbench.action.selectTheme'); - const iconThemeSelection = this.createMenuItem(nls.localize({ key: 'miSelectIconTheme', comment: ['&& denotes a mnemonic'] }, "File &&Icon Theme"), 'workbench.action.selectIconTheme'); - - const preferencesMenu = new Menu(); - preferencesMenu.append(settings); - preferencesMenu.append(__separator__()); - preferencesMenu.append(kebindingSettings); - preferencesMenu.append(keymapExtensions); - preferencesMenu.append(__separator__()); - preferencesMenu.append(snippetsSettings); - preferencesMenu.append(__separator__()); - preferencesMenu.append(colorThemeSelection); - preferencesMenu.append(iconThemeSelection); - - return new MenuItem({ label: this.mnemonicLabel(nls.localize({ key: 'miPreferences', comment: ['&& denotes a mnemonic'] }, "&&Preferences")), submenu: preferencesMenu }); - } - - private setOpenRecentMenu(openRecentMenu: Electron.Menu): void { - openRecentMenu.append(this.createMenuItem(nls.localize({ key: 'miReopenClosedEditor', comment: ['&& denotes a mnemonic'] }, "&&Reopen Closed Editor"), 'workbench.action.reopenClosedEditor')); - - const { workspaces, files } = this.historyMainService.getRecentlyOpened(); - - // Workspaces - if (workspaces.length > 0) { - openRecentMenu.append(__separator__()); - - for (let i = 0; i < CodeMenu.MAX_MENU_RECENT_ENTRIES && i < workspaces.length; i++) { - openRecentMenu.append(this.createOpenRecentMenuItem(workspaces[i], 'openRecentWorkspace', false)); - } - } - - // Files - if (files.length > 0) { - openRecentMenu.append(__separator__()); - - for (let i = 0; i < CodeMenu.MAX_MENU_RECENT_ENTRIES && i < files.length; i++) { - openRecentMenu.append(this.createOpenRecentMenuItem(files[i], 'openRecentFile', true)); - } - } - - if (workspaces.length || files.length) { - openRecentMenu.append(__separator__()); - openRecentMenu.append(this.createMenuItem(nls.localize({ key: 'miMore', comment: ['&& denotes a mnemonic'] }, "&&More..."), 'workbench.action.openRecent')); - openRecentMenu.append(__separator__()); - openRecentMenu.append(new MenuItem(this.likeAction('workbench.action.clearRecentFiles', { label: this.mnemonicLabel(nls.localize({ key: 'miClearRecentOpen', comment: ['&& denotes a mnemonic'] }, "&&Clear Recently Opened")), click: () => this.historyMainService.clearRecentlyOpened() }))); - } - } - - private createOpenRecentMenuItem(workspace: IWorkspaceIdentifier | ISingleFolderWorkspaceIdentifier | string, commandId: string, isFile: boolean): Electron.MenuItem { - let label: string; - let uri: URI; - if (isSingleFolderWorkspaceIdentifier(workspace)) { - label = unmnemonicLabel(getWorkspaceLabel(workspace, this.environmentService, { verbose: true })); - uri = workspace; - } else if (isWorkspaceIdentifier(workspace)) { - label = getWorkspaceLabel(workspace, this.environmentService, { verbose: true }); - uri = URI.file(workspace.configPath); - } else { - label = unmnemonicLabel(getPathLabel(workspace, this.environmentService, null)); - uri = URI.file(workspace); - } - - return new MenuItem(this.likeAction(commandId, { - label, - click: (menuItem, win, event) => { - const openInNewWindow = this.isOptionClick(event); - const success = this.windowsMainService.open({ - context: OpenContext.MENU, - cli: this.environmentService.args, - urisToOpen: [uri], forceNewWindow: openInNewWindow, - forceOpenWorkspaceAsFile: isFile - }).length > 0; - - if (!success) { - this.historyMainService.removeFromRecentlyOpened([workspace]); - } - } - }, false)); - } - - private isOptionClick(event: Electron.Event): boolean { - return event && ((!isMacintosh && (event.ctrlKey || event.shiftKey)) || (isMacintosh && (event.metaKey || event.altKey))); - } - - private createRoleMenuItem(label: string, commandId: string, role: Electron.MenuItemRole): Electron.MenuItem { - const options: Electron.MenuItemConstructorOptions = { - label: this.mnemonicLabel(label), - role, - enabled: true - }; - - return new MenuItem(this.withKeybinding(commandId, options)); - } - - private setEditMenu(winLinuxEditMenu: Electron.Menu): void { - let undo: Electron.MenuItem; - let redo: Electron.MenuItem; - let cut: Electron.MenuItem; - let copy: Electron.MenuItem; - let paste: Electron.MenuItem; - - if (isMacintosh) { - undo = this.createContextAwareMenuItem(nls.localize({ key: 'miUndo', comment: ['&& denotes a mnemonic'] }, "&&Undo"), 'undo', { - inDevTools: devTools => devTools.undo(), - inNoWindow: () => Menu.sendActionToFirstResponder('undo:') - }); - redo = this.createContextAwareMenuItem(nls.localize({ key: 'miRedo', comment: ['&& denotes a mnemonic'] }, "&&Redo"), 'redo', { - inDevTools: devTools => devTools.redo(), - inNoWindow: () => Menu.sendActionToFirstResponder('redo:') - }); - cut = this.createRoleMenuItem(nls.localize({ key: 'miCut', comment: ['&& denotes a mnemonic'] }, "Cu&&t"), 'editor.action.clipboardCutAction', 'cut'); - copy = this.createRoleMenuItem(nls.localize({ key: 'miCopy', comment: ['&& denotes a mnemonic'] }, "&&Copy"), 'editor.action.clipboardCopyAction', 'copy'); - paste = this.createRoleMenuItem(nls.localize({ key: 'miPaste', comment: ['&& denotes a mnemonic'] }, "&&Paste"), 'editor.action.clipboardPasteAction', 'paste'); - } else { - undo = this.createMenuItem(nls.localize({ key: 'miUndo', comment: ['&& denotes a mnemonic'] }, "&&Undo"), 'undo'); - redo = this.createMenuItem(nls.localize({ key: 'miRedo', comment: ['&& denotes a mnemonic'] }, "&&Redo"), 'redo'); - cut = this.createMenuItem(nls.localize({ key: 'miCut', comment: ['&& denotes a mnemonic'] }, "Cu&&t"), 'editor.action.clipboardCutAction'); - copy = this.createMenuItem(nls.localize({ key: 'miCopy', comment: ['&& denotes a mnemonic'] }, "&&Copy"), 'editor.action.clipboardCopyAction'); - paste = this.createMenuItem(nls.localize({ key: 'miPaste', comment: ['&& denotes a mnemonic'] }, "&&Paste"), 'editor.action.clipboardPasteAction'); - } - - const find = this.createMenuItem(nls.localize({ key: 'miFind', comment: ['&& denotes a mnemonic'] }, "&&Find"), 'actions.find'); - const replace = this.createMenuItem(nls.localize({ key: 'miReplace', comment: ['&& denotes a mnemonic'] }, "&&Replace"), 'editor.action.startFindReplaceAction'); - const findInFiles = this.createMenuItem(nls.localize({ key: 'miFindInFiles', comment: ['&& denotes a mnemonic'] }, "Find &&in Files"), 'workbench.action.findInFiles'); - const replaceInFiles = this.createMenuItem(nls.localize({ key: 'miReplaceInFiles', comment: ['&& denotes a mnemonic'] }, "Replace &&in Files"), 'workbench.action.replaceInFiles'); - - const emmetExpandAbbreviation = this.createMenuItem(nls.localize({ key: 'miEmmetExpandAbbreviation', comment: ['&& denotes a mnemonic'] }, "Emmet: E&&xpand Abbreviation"), 'editor.emmet.action.expandAbbreviation'); - const showEmmetCommands = this.createMenuItem(nls.localize({ key: 'miShowEmmetCommands', comment: ['&& denotes a mnemonic'] }, "E&&mmet..."), 'workbench.action.showEmmetCommands'); - const toggleLineComment = this.createMenuItem(nls.localize({ key: 'miToggleLineComment', comment: ['&& denotes a mnemonic'] }, "&&Toggle Line Comment"), 'editor.action.commentLine'); - const toggleBlockComment = this.createMenuItem(nls.localize({ key: 'miToggleBlockComment', comment: ['&& denotes a mnemonic'] }, "Toggle &&Block Comment"), 'editor.action.blockComment'); - - [ - undo, - redo, - __separator__(), - cut, - copy, - paste, - __separator__(), - find, - replace, - __separator__(), - findInFiles, - replaceInFiles, - __separator__(), - toggleLineComment, - toggleBlockComment, - emmetExpandAbbreviation, - showEmmetCommands - ].forEach(item => winLinuxEditMenu.append(item)); - } - - private setSelectionMenu(winLinuxEditMenu: Electron.Menu): void { - let multiCursorModifierLabel: string; - if (this.currentMultiCursorModifierSetting === 'ctrlCmd') { - multiCursorModifierLabel = nls.localize('miMultiCursorAlt', "Switch to Alt+Click for Multi-Cursor"); // The default has been overwritten - } else { - multiCursorModifierLabel = ( - isMacintosh - ? nls.localize('miMultiCursorCmd', "Switch to Cmd+Click for Multi-Cursor") - : nls.localize('miMultiCursorCtrl', "Switch to Ctrl+Click for Multi-Cursor") - ); - } - - const multicursorModifier = this.createMenuItem(multiCursorModifierLabel, 'workbench.action.toggleMultiCursorModifier'); - const insertCursorAbove = this.createMenuItem(nls.localize({ key: 'miInsertCursorAbove', comment: ['&& denotes a mnemonic'] }, "&&Add Cursor Above"), 'editor.action.insertCursorAbove'); - const insertCursorBelow = this.createMenuItem(nls.localize({ key: 'miInsertCursorBelow', comment: ['&& denotes a mnemonic'] }, "A&&dd Cursor Below"), 'editor.action.insertCursorBelow'); - const insertCursorAtEndOfEachLineSelected = this.createMenuItem(nls.localize({ key: 'miInsertCursorAtEndOfEachLineSelected', comment: ['&& denotes a mnemonic'] }, "Add C&&ursors to Line Ends"), 'editor.action.insertCursorAtEndOfEachLineSelected'); - const addSelectionToNextFindMatch = this.createMenuItem(nls.localize({ key: 'miAddSelectionToNextFindMatch', comment: ['&& denotes a mnemonic'] }, "Add &&Next Occurrence"), 'editor.action.addSelectionToNextFindMatch'); - const addSelectionToPreviousFindMatch = this.createMenuItem(nls.localize({ key: 'miAddSelectionToPreviousFindMatch', comment: ['&& denotes a mnemonic'] }, "Add P&&revious Occurrence"), 'editor.action.addSelectionToPreviousFindMatch'); - const selectHighlights = this.createMenuItem(nls.localize({ key: 'miSelectHighlights', comment: ['&& denotes a mnemonic'] }, "Select All &&Occurrences"), 'editor.action.selectHighlights'); - - const copyLinesUp = this.createMenuItem(nls.localize({ key: 'miCopyLinesUp', comment: ['&& denotes a mnemonic'] }, "&&Copy Line Up"), 'editor.action.copyLinesUpAction'); - const copyLinesDown = this.createMenuItem(nls.localize({ key: 'miCopyLinesDown', comment: ['&& denotes a mnemonic'] }, "Co&&py Line Down"), 'editor.action.copyLinesDownAction'); - const moveLinesUp = this.createMenuItem(nls.localize({ key: 'miMoveLinesUp', comment: ['&& denotes a mnemonic'] }, "Mo&&ve Line Up"), 'editor.action.moveLinesUpAction'); - const moveLinesDown = this.createMenuItem(nls.localize({ key: 'miMoveLinesDown', comment: ['&& denotes a mnemonic'] }, "Move &&Line Down"), 'editor.action.moveLinesDownAction'); - - let selectAll: Electron.MenuItem; - if (isMacintosh) { - selectAll = this.createContextAwareMenuItem(nls.localize({ key: 'miSelectAll', comment: ['&& denotes a mnemonic'] }, "&&Select All"), 'editor.action.selectAll', { - inDevTools: devTools => devTools.selectAll(), - inNoWindow: () => Menu.sendActionToFirstResponder('selectAll:') - }); - } else { - selectAll = this.createMenuItem(nls.localize({ key: 'miSelectAll', comment: ['&& denotes a mnemonic'] }, "&&Select All"), 'editor.action.selectAll'); - } - const smartSelectGrow = this.createMenuItem(nls.localize({ key: 'miSmartSelectGrow', comment: ['&& denotes a mnemonic'] }, "&&Expand Selection"), 'editor.action.smartSelect.grow'); - const smartSelectshrink = this.createMenuItem(nls.localize({ key: 'miSmartSelectShrink', comment: ['&& denotes a mnemonic'] }, "&&Shrink Selection"), 'editor.action.smartSelect.shrink'); - - [ - selectAll, - smartSelectGrow, - smartSelectshrink, - __separator__(), - copyLinesUp, - copyLinesDown, - moveLinesUp, - moveLinesDown, - __separator__(), - multicursorModifier, - insertCursorAbove, - insertCursorBelow, - insertCursorAtEndOfEachLineSelected, - addSelectionToNextFindMatch, - addSelectionToPreviousFindMatch, - selectHighlights, - ].forEach(item => winLinuxEditMenu.append(item)); - } - - private setViewMenu(viewMenu: Electron.Menu): void { - const commands = this.createMenuItem(nls.localize({ key: 'miCommandPalette', comment: ['&& denotes a mnemonic'] }, "&&Command Palette..."), 'workbench.action.showCommands'); - const openView = this.createMenuItem(nls.localize({ key: 'miOpenView', comment: ['&& denotes a mnemonic'] }, "&&Open View..."), 'workbench.action.openView'); - - // Views - const explorer = this.createMenuItem(nls.localize({ key: 'miViewExplorer', comment: ['&& denotes a mnemonic'] }, "&&Explorer"), 'workbench.view.explorer'); - const search = this.createMenuItem(nls.localize({ key: 'miViewSearch', comment: ['&& denotes a mnemonic'] }, "&&Search"), 'workbench.view.search'); - const scm = this.createMenuItem(nls.localize({ key: 'miViewSCM', comment: ['&& denotes a mnemonic'] }, "S&&CM"), 'workbench.view.scm'); - const debug = this.createMenuItem(nls.localize({ key: 'miViewDebug', comment: ['&& denotes a mnemonic'] }, "&&Debug"), 'workbench.view.debug'); - const extensions = this.createMenuItem(nls.localize({ key: 'miViewExtensions', comment: ['&& denotes a mnemonic'] }, "E&&xtensions"), 'workbench.view.extensions'); - - // Panels - const output = this.createMenuItem(nls.localize({ key: 'miToggleOutput', comment: ['&& denotes a mnemonic'] }, "&&Output"), 'workbench.action.output.toggleOutput'); - const debugConsole = this.createMenuItem(nls.localize({ key: 'miToggleDebugConsole', comment: ['&& denotes a mnemonic'] }, "De&&bug Console"), 'workbench.debug.action.toggleRepl'); - const terminal = this.createMenuItem(nls.localize({ key: 'miToggleTerminal', comment: ['&& denotes a mnemonic'] }, "&&Terminal"), 'workbench.action.terminal.toggleTerminal'); - const problems = this.createMenuItem(nls.localize({ key: 'miMarker', comment: ['&& denotes a mnemonic'] }, "&&Problems"), 'workbench.actions.view.problems'); - - // Appearance - - const appearanceMenu = new Menu(); - - const fullscreen = new MenuItem(this.withKeybinding('workbench.action.toggleFullScreen', { label: this.mnemonicLabel(nls.localize({ key: 'miToggleFullScreen', comment: ['&& denotes a mnemonic'] }, "Toggle &&Full Screen")), click: () => this.windowsMainService.getLastActiveWindow().toggleFullScreen(), enabled: this.windowsMainService.getWindowCount() > 0 })); - const toggleZenMode = this.createMenuItem(nls.localize('miToggleZenMode', "Toggle Zen Mode"), 'workbench.action.toggleZenMode'); - const toggleCenteredLayout = this.createMenuItem(nls.localize('miToggleCenteredLayout', "Toggle Centered Layout"), 'workbench.action.toggleCenteredLayout'); - const toggleMenuBar = this.createMenuItem(nls.localize({ key: 'miToggleMenuBar', comment: ['&& denotes a mnemonic'] }, "Toggle Menu &&Bar"), 'workbench.action.toggleMenuBar'); - - const toggleSidebar = this.createMenuItem(nls.localize({ key: 'miToggleSidebar', comment: ['&& denotes a mnemonic'] }, "&&Toggle Side Bar"), 'workbench.action.toggleSidebarVisibility'); - - let moveSideBarLabel: string; - if (this.currentSidebarLocation !== 'right') { - moveSideBarLabel = nls.localize({ key: 'miMoveSidebarRight', comment: ['&& denotes a mnemonic'] }, "&&Move Side Bar Right"); - } else { - moveSideBarLabel = nls.localize({ key: 'miMoveSidebarLeft', comment: ['&& denotes a mnemonic'] }, "&&Move Side Bar Left"); - } - - const moveSidebar = this.createMenuItem(moveSideBarLabel, 'workbench.action.toggleSidebarPosition'); - const togglePanel = this.createMenuItem(nls.localize({ key: 'miTogglePanel', comment: ['&& denotes a mnemonic'] }, "Toggle &&Panel"), 'workbench.action.togglePanel'); - - let statusBarLabel: string; - if (this.currentStatusbarVisible) { - statusBarLabel = nls.localize({ key: 'miHideStatusbar', comment: ['&& denotes a mnemonic'] }, "&&Hide Status Bar"); - } else { - statusBarLabel = nls.localize({ key: 'miShowStatusbar', comment: ['&& denotes a mnemonic'] }, "&&Show Status Bar"); - } - const toggleStatusbar = this.createMenuItem(statusBarLabel, 'workbench.action.toggleStatusbarVisibility'); - - let activityBarLabel: string; - if (this.currentActivityBarVisible) { - activityBarLabel = nls.localize({ key: 'miHideActivityBar', comment: ['&& denotes a mnemonic'] }, "Hide &&Activity Bar"); - } else { - activityBarLabel = nls.localize({ key: 'miShowActivityBar', comment: ['&& denotes a mnemonic'] }, "Show &&Activity Bar"); - } - const toggleActivtyBar = this.createMenuItem(activityBarLabel, 'workbench.action.toggleActivityBarVisibility'); - - const zoomIn = this.createMenuItem(nls.localize({ key: 'miZoomIn', comment: ['&& denotes a mnemonic'] }, "&&Zoom In"), 'workbench.action.zoomIn'); - const zoomOut = this.createMenuItem(nls.localize({ key: 'miZoomOut', comment: ['&& denotes a mnemonic'] }, "Zoom O&&ut"), 'workbench.action.zoomOut'); - const resetZoom = this.createMenuItem(nls.localize({ key: 'miZoomReset', comment: ['&& denotes a mnemonic'] }, "&&Reset Zoom"), 'workbench.action.zoomReset'); - - arrays.coalesce([ - fullscreen, - toggleZenMode, - toggleCenteredLayout, - isWindows || isLinux ? toggleMenuBar : void 0, - __separator__(), - moveSidebar, - toggleSidebar, - togglePanel, - toggleStatusbar, - toggleActivtyBar, - __separator__(), - zoomIn, - zoomOut, - resetZoom - ]).forEach(item => appearanceMenu.append(item)); - - const appearance = new MenuItem({ label: this.mnemonicLabel(nls.localize({ key: 'miAppearance', comment: ['&& denotes a mnemonic'] }, "&&Appearance")), submenu: appearanceMenu }); - - // Editor Layout - - const editorLayoutMenu = new Menu(); - - const splitEditorUp = this.createMenuItem(nls.localize({ key: 'miSplitEditorUp', comment: ['&& denotes a mnemonic'] }, "Split &&Up"), 'workbench.action.splitEditorUp'); - const splitEditorDown = this.createMenuItem(nls.localize({ key: 'miSplitEditorDown', comment: ['&& denotes a mnemonic'] }, "Split &&Down"), 'workbench.action.splitEditorDown'); - const splitEditorLeft = this.createMenuItem(nls.localize({ key: 'miSplitEditorLeft', comment: ['&& denotes a mnemonic'] }, "Split &&Left"), 'workbench.action.splitEditorLeft'); - const splitEditorRight = this.createMenuItem(nls.localize({ key: 'miSplitEditorRight', comment: ['&& denotes a mnemonic'] }, "Split &&Right"), 'workbench.action.splitEditorRight'); - - const singleColumnEditorLayout = this.createMenuItem(nls.localize({ key: 'miSingleColumnEditorLayout', comment: ['&& denotes a mnemonic'] }, "&&Single"), 'workbench.action.editorLayoutSingle'); - const twoColumnsEditorLayout = this.createMenuItem(nls.localize({ key: 'miTwoColumnsEditorLayout', comment: ['&& denotes a mnemonic'] }, "&&Two Columns"), 'workbench.action.editorLayoutTwoColumns'); - const threeColumnsEditorLayout = this.createMenuItem(nls.localize({ key: 'miThreeColumnsEditorLayout', comment: ['&& denotes a mnemonic'] }, "T&&hree Columns"), 'workbench.action.editorLayoutThreeColumns'); - const twoRowsEditorLayout = this.createMenuItem(nls.localize({ key: 'miTwoRowsEditorLayout', comment: ['&& denotes a mnemonic'] }, "T&&wo Rows"), 'workbench.action.editorLayoutTwoRows'); - const threeRowsEditorLayout = this.createMenuItem(nls.localize({ key: 'miThreeRowsEditorLayout', comment: ['&& denotes a mnemonic'] }, "Three &&Rows"), 'workbench.action.editorLayoutThreeRows'); - const twoByTwoGridEditorLayout = this.createMenuItem(nls.localize({ key: 'miTwoByTwoGridEditorLayout', comment: ['&& denotes a mnemonic'] }, "&&Grid (2x2)"), 'workbench.action.editorLayoutTwoByTwoGrid'); - const twoRowsRightEditorLayout = this.createMenuItem(nls.localize({ key: 'miTwoRowsRightEditorLayout', comment: ['&& denotes a mnemonic'] }, "Two R&&ows Right"), 'workbench.action.editorLayoutTwoRowsRight'); - const twoColumnsBottomEditorLayout = this.createMenuItem(nls.localize({ key: 'miTwoColumnsBottomEditorLayout', comment: ['&& denotes a mnemonic'] }, "Two &&Columns Bottom"), 'workbench.action.editorLayoutTwoColumnsBottom'); - - const toggleEditorLayout = this.createMenuItem(nls.localize({ key: 'miToggleEditorLayout', comment: ['&& denotes a mnemonic'] }, "Toggle Vertical/Horizontal &&Layout"), 'workbench.action.toggleEditorGroupLayout'); - - [ - splitEditorUp, - splitEditorDown, - splitEditorLeft, - splitEditorRight, - __separator__(), - singleColumnEditorLayout, - twoColumnsEditorLayout, - threeColumnsEditorLayout, - twoRowsEditorLayout, - threeRowsEditorLayout, - twoByTwoGridEditorLayout, - twoRowsRightEditorLayout, - twoColumnsBottomEditorLayout, - __separator__(), - toggleEditorLayout - ].forEach(item => editorLayoutMenu.append(item)); - - const editorLayout = new MenuItem({ label: this.mnemonicLabel(nls.localize({ key: 'miEditorLayout', comment: ['&& denotes a mnemonic'] }, "Editor &&Layout")), submenu: editorLayoutMenu }); - - const toggleWordWrap = this.createMenuItem(nls.localize({ key: 'miToggleWordWrap', comment: ['&& denotes a mnemonic'] }, "Toggle &&Word Wrap"), 'editor.action.toggleWordWrap'); - const toggleMinimap = this.createMenuItem(nls.localize({ key: 'miToggleMinimap', comment: ['&& denotes a mnemonic'] }, "Toggle &&Minimap"), 'editor.action.toggleMinimap'); - const toggleRenderWhitespace = this.createMenuItem(nls.localize({ key: 'miToggleRenderWhitespace', comment: ['&& denotes a mnemonic'] }, "Toggle &&Render Whitespace"), 'editor.action.toggleRenderWhitespace'); - const toggleRenderControlCharacters = this.createMenuItem(nls.localize({ key: 'miToggleRenderControlCharacters', comment: ['&& denotes a mnemonic'] }, "Toggle &&Control Characters"), 'editor.action.toggleRenderControlCharacter'); - const toggleBreadcrumbs = this.createMenuItem(nls.localize({ key: 'miToggleBreadcrumbs', comment: ['&& denotes a mnemonic'] }, "Toggle &&Breadcrumbs"), 'breadcrumbs.toggle'); - - arrays.coalesce([ - commands, - openView, - __separator__(), - appearance, - editorLayout, - __separator__(), - explorer, - search, - scm, - debug, - extensions, - __separator__(), - output, - problems, - debugConsole, - terminal, - __separator__(), - toggleWordWrap, - toggleMinimap, - toggleRenderWhitespace, - toggleRenderControlCharacters, - toggleBreadcrumbs - ]).forEach(item => viewMenu.append(item)); - } - - private setGotoMenu(gotoMenu: Electron.Menu): void { - const back = this.createMenuItem(nls.localize({ key: 'miBack', comment: ['&& denotes a mnemonic'] }, "&&Back"), 'workbench.action.navigateBack'); - const forward = this.createMenuItem(nls.localize({ key: 'miForward', comment: ['&& denotes a mnemonic'] }, "&&Forward"), 'workbench.action.navigateForward'); - - const switchEditorMenu = new Menu(); - - const nextEditor = this.createMenuItem(nls.localize({ key: 'miNextEditor', comment: ['&& denotes a mnemonic'] }, "&&Next Editor"), 'workbench.action.nextEditor'); - const previousEditor = this.createMenuItem(nls.localize({ key: 'miPreviousEditor', comment: ['&& denotes a mnemonic'] }, "&&Previous Editor"), 'workbench.action.previousEditor'); - const nextEditorInGroup = this.createMenuItem(nls.localize({ key: 'miNextEditorInGroup', comment: ['&& denotes a mnemonic'] }, "&&Next Used Editor in Group"), 'workbench.action.openNextRecentlyUsedEditorInGroup'); - const previousEditorInGroup = this.createMenuItem(nls.localize({ key: 'miPreviousEditorInGroup', comment: ['&& denotes a mnemonic'] }, "&&Previous Used Editor in Group"), 'workbench.action.openPreviousRecentlyUsedEditorInGroup'); - - [ - nextEditor, - previousEditor, - __separator__(), - nextEditorInGroup, - previousEditorInGroup - ].forEach(item => switchEditorMenu.append(item)); - - const switchEditor = new MenuItem({ label: this.mnemonicLabel(nls.localize({ key: 'miSwitchEditor', comment: ['&& denotes a mnemonic'] }, "Switch &&Editor")), submenu: switchEditorMenu, enabled: true }); - - const switchGroupMenu = new Menu(); - - const focusFirstGroup = this.createMenuItem(nls.localize({ key: 'miFocusFirstGroup', comment: ['&& denotes a mnemonic'] }, "Group &&1"), 'workbench.action.focusFirstEditorGroup'); - const focusSecondGroup = this.createMenuItem(nls.localize({ key: 'miFocusSecondGroup', comment: ['&& denotes a mnemonic'] }, "Group &&2"), 'workbench.action.focusSecondEditorGroup'); - const focusThirdGroup = this.createMenuItem(nls.localize({ key: 'miFocusThirdGroup', comment: ['&& denotes a mnemonic'] }, "Group &&3"), 'workbench.action.focusThirdEditorGroup'); - const focusFourthGroup = this.createMenuItem(nls.localize({ key: 'miFocusFourthGroup', comment: ['&& denotes a mnemonic'] }, "Group &&4"), 'workbench.action.focusFourthEditorGroup'); - const focusFifthGroup = this.createMenuItem(nls.localize({ key: 'miFocusFifthGroup', comment: ['&& denotes a mnemonic'] }, "Group &&5"), 'workbench.action.focusFifthEditorGroup'); - const nextGroup = this.createMenuItem(nls.localize({ key: 'miNextGroup', comment: ['&& denotes a mnemonic'] }, "&&Next Group"), 'workbench.action.focusNextGroup'); - const previousGroup = this.createMenuItem(nls.localize({ key: 'miPreviousGroup', comment: ['&& denotes a mnemonic'] }, "&&Previous Group"), 'workbench.action.focusPreviousGroup'); - - const focusLeftGroup = this.createMenuItem(nls.localize({ key: 'miFocusLeftGroup', comment: ['&& denotes a mnemonic'] }, "Group &&Left"), 'workbench.action.focusLeftGroup'); - const focusRightGroup = this.createMenuItem(nls.localize({ key: 'miFocusRightGroup', comment: ['&& denotes a mnemonic'] }, "Group &&Right"), 'workbench.action.focusRightGroup'); - const focusAboveGroup = this.createMenuItem(nls.localize({ key: 'miFocusAboveGroup', comment: ['&& denotes a mnemonic'] }, "Group &&Above"), 'workbench.action.focusAboveGroup'); - const focusBelowGroup = this.createMenuItem(nls.localize({ key: 'miFocusBelowGroup', comment: ['&& denotes a mnemonic'] }, "Group &&Below"), 'workbench.action.focusBelowGroup'); - - [ - focusFirstGroup, - focusSecondGroup, - focusThirdGroup, - focusFourthGroup, - focusFifthGroup, - __separator__(), - nextGroup, - previousGroup, - __separator__(), - focusAboveGroup, - focusBelowGroup, - focusLeftGroup, - focusRightGroup - ].forEach(item => switchGroupMenu.append(item)); - - const switchGroup = new MenuItem({ label: this.mnemonicLabel(nls.localize({ key: 'miSwitchGroup', comment: ['&& denotes a mnemonic'] }, "Switch &&Group")), submenu: switchGroupMenu, enabled: true }); - - const gotoFile = this.createMenuItem(nls.localize({ key: 'miGotoFile', comment: ['&& denotes a mnemonic'] }, "Go to &&File..."), 'workbench.action.quickOpen'); - const gotoSymbolInFile = this.createMenuItem(nls.localize({ key: 'miGotoSymbolInFile', comment: ['&& denotes a mnemonic'] }, "Go to &&Symbol in File..."), 'workbench.action.gotoSymbol'); - const gotoSymbolInWorkspace = this.createMenuItem(nls.localize({ key: 'miGotoSymbolInWorkspace', comment: ['&& denotes a mnemonic'] }, "Go to Symbol in &&Workspace..."), 'workbench.action.showAllSymbols'); - const gotoDefinition = this.createMenuItem(nls.localize({ key: 'miGotoDefinition', comment: ['&& denotes a mnemonic'] }, "Go to &&Definition"), 'editor.action.goToDeclaration'); - const gotoTypeDefinition = this.createMenuItem(nls.localize({ key: 'miGotoTypeDefinition', comment: ['&& denotes a mnemonic'] }, "Go to &&Type Definition"), 'editor.action.goToTypeDefinition'); - const goToImplementation = this.createMenuItem(nls.localize({ key: 'miGotoImplementation', comment: ['&& denotes a mnemonic'] }, "Go to &&Implementation"), 'editor.action.goToImplementation'); - const gotoLine = this.createMenuItem(nls.localize({ key: 'miGotoLine', comment: ['&& denotes a mnemonic'] }, "Go to &&Line..."), 'workbench.action.gotoLine'); - - [ - back, - forward, - __separator__(), - switchEditor, - switchGroup, - __separator__(), - gotoFile, - gotoSymbolInFile, - gotoSymbolInWorkspace, - gotoDefinition, - gotoTypeDefinition, - goToImplementation, - gotoLine - ].forEach(item => gotoMenu.append(item)); - } - - private setTerminalMenu(terminalMenu: Electron.Menu): void { - const newTerminal = this.createMenuItem(nls.localize({ key: 'miNewTerminal', comment: ['&& denotes a mnemonic'] }, "&&New Terminal"), 'workbench.action.terminal.new'); - const splitTerminal = this.createMenuItem(nls.localize({ key: 'miSplitTerminal', comment: ['&& denotes a mnemonic'] }, "&&Split Terminal"), 'workbench.action.terminal.split'); - const killTerminal = this.createMenuItem(nls.localize({ key: 'miKillTerminal', comment: ['&& denotes a mnemonic'] }, "&&Kill Terminal"), 'workbench.action.terminal.kill'); - const clear = this.createMenuItem(nls.localize({ key: 'miClear', comment: ['&& denotes a mnemonic'] }, "&&Clear"), 'workbench.action.terminal.clear'); - const runActiveFile = this.createMenuItem(nls.localize({ key: 'miRunActiveFile', comment: ['&& denotes a mnemonic'] }, "Run &&Active File"), 'workbench.action.terminal.runActiveFile'); - const runSelectedText = this.createMenuItem(nls.localize({ key: 'miRunSelectedText', comment: ['&& denotes a mnemonic'] }, "Run &&Selected Text"), 'workbench.action.terminal.runSelectedText'); - const scrollToPreviousCommand = this.createMenuItem(nls.localize({ key: 'miScrollToPreviousCommand', comment: ['&& denotes a mnemonic'] }, "Scroll To Previous Command"), 'workbench.action.terminal.scrollToPreviousCommand'); - const scrollToNextCommand = this.createMenuItem(nls.localize({ key: 'miScrollToNextCommand', comment: ['&& denotes a mnemonic'] }, "Scroll To Next Command"), 'workbench.action.terminal.scrollToNextCommand'); - const selectToPreviousCommand = this.createMenuItem(nls.localize({ key: 'miSelectToPreviousCommand', comment: ['&& denotes a mnemonic'] }, "Select To Previous Command"), 'workbench.action.terminal.selectToPreviousCommand'); - const selectToNextCommand = this.createMenuItem(nls.localize({ key: 'miSelectToNextCommand', comment: ['&& denotes a mnemonic'] }, "Select To Next Command"), 'workbench.action.terminal.selectToNextCommand'); - - const menuItems: MenuItem[] = [ - newTerminal, - splitTerminal, - killTerminal, - __separator__(), - clear, - runActiveFile, - runSelectedText, - __separator__(), - scrollToPreviousCommand, - scrollToNextCommand, - selectToPreviousCommand, - selectToNextCommand - ]; - - menuItems.forEach(item => terminalMenu.append(item)); - } - - private setDebugMenu(debugMenu: Electron.Menu): void { - const start = this.createMenuItem(nls.localize({ key: 'miStartDebugging', comment: ['&& denotes a mnemonic'] }, "&&Start Debugging"), 'workbench.action.debug.start'); - const startWithoutDebugging = this.createMenuItem(nls.localize({ key: 'miStartWithoutDebugging', comment: ['&& denotes a mnemonic'] }, "Start &&Without Debugging"), 'workbench.action.debug.run'); - const stop = this.createMenuItem(nls.localize({ key: 'miStopDebugging', comment: ['&& denotes a mnemonic'] }, "&&Stop Debugging"), 'workbench.action.debug.stop'); - const restart = this.createMenuItem(nls.localize({ key: 'miRestart Debugging', comment: ['&& denotes a mnemonic'] }, "&&Restart Debugging"), 'workbench.action.debug.restart'); - - const openConfigurations = this.createMenuItem(nls.localize({ key: 'miOpenConfigurations', comment: ['&& denotes a mnemonic'] }, "Open &&Configurations"), 'workbench.action.debug.configure'); - const addConfiguration = this.createMenuItem(nls.localize({ key: 'miAddConfiguration', comment: ['&& denotes a mnemonic'] }, "Add Configuration..."), 'debug.addConfiguration'); - - const stepOver = this.createMenuItem(nls.localize({ key: 'miStepOver', comment: ['&& denotes a mnemonic'] }, "Step &&Over"), 'workbench.action.debug.stepOver'); - const stepInto = this.createMenuItem(nls.localize({ key: 'miStepInto', comment: ['&& denotes a mnemonic'] }, "Step &&Into"), 'workbench.action.debug.stepInto'); - const stepOut = this.createMenuItem(nls.localize({ key: 'miStepOut', comment: ['&& denotes a mnemonic'] }, "Step O&&ut"), 'workbench.action.debug.stepOut'); - const continueAction = this.createMenuItem(nls.localize({ key: 'miContinue', comment: ['&& denotes a mnemonic'] }, "&&Continue"), 'workbench.action.debug.continue'); - - const toggleBreakpoint = this.createMenuItem(nls.localize({ key: 'miToggleBreakpoint', comment: ['&& denotes a mnemonic'] }, "Toggle &&Breakpoint"), 'editor.debug.action.toggleBreakpoint'); - const breakpointsMenu = new Menu(); - breakpointsMenu.append(this.createMenuItem(nls.localize({ key: 'miConditionalBreakpoint', comment: ['&& denotes a mnemonic'] }, "&&Conditional Breakpoint..."), 'editor.debug.action.conditionalBreakpoint')); - breakpointsMenu.append(this.createMenuItem(nls.localize({ key: 'miInlineBreakpoint', comment: ['&& denotes a mnemonic'] }, "Inline Breakp&&oint"), 'editor.debug.action.toggleInlineBreakpoint')); - breakpointsMenu.append(this.createMenuItem(nls.localize({ key: 'miFunctionBreakpoint', comment: ['&& denotes a mnemonic'] }, "&&Function Breakpoint..."), 'workbench.debug.viewlet.action.addFunctionBreakpointAction')); - breakpointsMenu.append(this.createMenuItem(nls.localize({ key: 'miLogPoint', comment: ['&& denotes a mnemonic'] }, "&&Logpoint..."), 'editor.debug.action.toggleLogPoint')); - const newBreakpoints = new MenuItem({ label: this.mnemonicLabel(nls.localize({ key: 'miNewBreakpoint', comment: ['&& denotes a mnemonic'] }, "&&New Breakpoint")), submenu: breakpointsMenu }); - const enableAllBreakpoints = this.createMenuItem(nls.localize({ key: 'miEnableAllBreakpoints', comment: ['&& denotes a mnemonic'] }, "Enable All Breakpoints"), 'workbench.debug.viewlet.action.enableAllBreakpoints'); - const disableAllBreakpoints = this.createMenuItem(nls.localize({ key: 'miDisableAllBreakpoints', comment: ['&& denotes a mnemonic'] }, "Disable A&&ll Breakpoints"), 'workbench.debug.viewlet.action.disableAllBreakpoints'); - const removeAllBreakpoints = this.createMenuItem(nls.localize({ key: 'miRemoveAllBreakpoints', comment: ['&& denotes a mnemonic'] }, "Remove &&All Breakpoints"), 'workbench.debug.viewlet.action.removeAllBreakpoints'); - - const installAdditionalDebuggers = this.createMenuItem(nls.localize({ key: 'miInstallAdditionalDebuggers', comment: ['&& denotes a mnemonic'] }, "&&Install Additional Debuggers..."), 'debug.installAdditionalDebuggers'); - [ - start, - startWithoutDebugging, - stop, - restart, - __separator__(), - openConfigurations, - addConfiguration, - __separator__(), - stepOver, - stepInto, - stepOut, - continueAction, - __separator__(), - toggleBreakpoint, - newBreakpoints, - enableAllBreakpoints, - disableAllBreakpoints, - removeAllBreakpoints, - __separator__(), - installAdditionalDebuggers - ].forEach(item => debugMenu.append(item)); - } - - private setMacWindowMenu(macWindowMenu: Electron.Menu): void { - const minimize = new MenuItem({ label: nls.localize('mMinimize', "Minimize"), role: 'minimize', accelerator: 'Command+M', enabled: this.windowsMainService.getWindowCount() > 0 }); - const zoom = new MenuItem({ label: nls.localize('mZoom', "Zoom"), role: 'zoom', enabled: this.windowsMainService.getWindowCount() > 0 }); - const bringAllToFront = new MenuItem({ label: nls.localize('mBringToFront', "Bring All to Front"), role: 'front', enabled: this.windowsMainService.getWindowCount() > 0 }); - const switchWindow = this.createMenuItem(nls.localize({ key: 'miSwitchWindow', comment: ['&& denotes a mnemonic'] }, "Switch &&Window..."), 'workbench.action.switchWindow'); - - this.nativeTabMenuItems = []; - const nativeTabMenuItems: Electron.MenuItem[] = []; - if (this.currentEnableNativeTabs) { - const hasMultipleWindows = this.windowsMainService.getWindowCount() > 1; - - this.nativeTabMenuItems.push(this.createMenuItem(nls.localize('mShowPreviousTab', "Show Previous Tab"), 'workbench.action.showPreviousWindowTab', hasMultipleWindows)); - this.nativeTabMenuItems.push(this.createMenuItem(nls.localize('mShowNextTab', "Show Next Tab"), 'workbench.action.showNextWindowTab', hasMultipleWindows)); - this.nativeTabMenuItems.push(this.createMenuItem(nls.localize('mMoveTabToNewWindow', "Move Tab to New Window"), 'workbench.action.moveWindowTabToNewWindow', hasMultipleWindows)); - this.nativeTabMenuItems.push(this.createMenuItem(nls.localize('mMergeAllWindows', "Merge All Windows"), 'workbench.action.mergeAllWindowTabs', hasMultipleWindows)); - - nativeTabMenuItems.push(__separator__(), ...this.nativeTabMenuItems); - } else { - this.nativeTabMenuItems = []; - } - - [ - minimize, - zoom, - switchWindow, - ...nativeTabMenuItems, - __separator__(), - bringAllToFront - ].forEach(item => macWindowMenu.append(item)); - } - - private toggleDevTools(): void { - const w = this.windowsMainService.getFocusedWindow(); - if (w && w.win) { - const contents = w.win.webContents; - if (isMacintosh && w.hasHiddenTitleBarStyle() && !w.win.isFullScreen() && !contents.isDevToolsOpened()) { - contents.openDevTools({ mode: 'undocked' }); // due to https://github.com/electron/electron/issues/3647 - } else { - contents.toggleDevTools(); - } - } - } - - private setHelpMenu(helpMenu: Electron.Menu): void { - const toggleDevToolsItem = new MenuItem(this.likeAction('workbench.action.toggleDevTools', { - label: this.mnemonicLabel(nls.localize({ key: 'miToggleDevTools', comment: ['&& denotes a mnemonic'] }, "&&Toggle Developer Tools")), - click: () => this.toggleDevTools(), - enabled: (this.windowsMainService.getWindowCount() > 0) - })); - - const showAccessibilityOptions = new MenuItem(this.likeAction('accessibilityOptions', { - label: this.mnemonicLabel(nls.localize({ key: 'miAccessibilityOptions', comment: ['&& denotes a mnemonic'] }, "Accessibility &&Options")), - accelerator: null, - click: () => { - this.openAccessibilityOptions(); - } - }, false)); - - const openProcessExplorer = new MenuItem({ label: this.mnemonicLabel(nls.localize({ key: 'miOpenProcessExplorerer', comment: ['&& denotes a mnemonic'] }, "Open &&Process Explorer")), click: () => this.runActionInRenderer('workbench.action.openProcessExplorer') }); - - let reportIssuesItem: Electron.MenuItem = null; - if (product.reportIssueUrl) { - const label = nls.localize({ key: 'miReportIssue', comment: ['&& denotes a mnemonic', 'Translate this to "Report Issue in English" in all languages please!'] }, "Report &&Issue"); - - if (this.windowsMainService.getWindowCount() > 0) { - reportIssuesItem = this.createMenuItem(label, 'workbench.action.openIssueReporter'); - } else { - reportIssuesItem = new MenuItem({ label: this.mnemonicLabel(label), click: () => this.openUrl(product.reportIssueUrl, 'openReportIssues') }); - } - } - - const keyboardShortcutsUrl = isLinux ? product.keyboardShortcutsUrlLinux : isMacintosh ? product.keyboardShortcutsUrlMac : product.keyboardShortcutsUrlWin; - arrays.coalesce([ - new MenuItem({ label: this.mnemonicLabel(nls.localize({ key: 'miWelcome', comment: ['&& denotes a mnemonic'] }, "&&Welcome")), click: () => this.runActionInRenderer('workbench.action.showWelcomePage'), enabled: (this.windowsMainService.getWindowCount() > 0) }), - new MenuItem({ label: this.mnemonicLabel(nls.localize({ key: 'miInteractivePlayground', comment: ['&& denotes a mnemonic'] }, "&&Interactive Playground")), click: () => this.runActionInRenderer('workbench.action.showInteractivePlayground'), enabled: (this.windowsMainService.getWindowCount() > 0) }), - product.documentationUrl ? new MenuItem({ label: this.mnemonicLabel(nls.localize({ key: 'miDocumentation', comment: ['&& denotes a mnemonic'] }, "&&Documentation")), click: () => this.runActionInRenderer('workbench.action.openDocumentationUrl'), enabled: (this.windowsMainService.getWindowCount() > 0) }) : null, - product.releaseNotesUrl ? new MenuItem({ label: this.mnemonicLabel(nls.localize({ key: 'miReleaseNotes', comment: ['&& denotes a mnemonic'] }, "&&Release Notes")), click: () => this.runActionInRenderer('update.showCurrentReleaseNotes'), enabled: (this.windowsMainService.getWindowCount() > 0) }) : null, - __separator__(), - keyboardShortcutsUrl ? new MenuItem({ label: this.mnemonicLabel(nls.localize({ key: 'miKeyboardShortcuts', comment: ['&& denotes a mnemonic'] }, "&&Keyboard Shortcuts Reference")), click: () => this.runActionInRenderer('workbench.action.keybindingsReference'), enabled: (this.windowsMainService.getWindowCount() > 0) }) : null, - product.introductoryVideosUrl ? new MenuItem({ label: this.mnemonicLabel(nls.localize({ key: 'miIntroductoryVideos', comment: ['&& denotes a mnemonic'] }, "Introductory &&Videos")), click: () => this.runActionInRenderer('workbench.action.openIntroductoryVideosUrl'), enabled: (this.windowsMainService.getWindowCount() > 0) }) : null, - product.tipsAndTricksUrl ? new MenuItem({ label: this.mnemonicLabel(nls.localize({ key: 'miTipsAndTricks', comment: ['&& denotes a mnemonic'] }, "&&Tips and Tricks")), click: () => this.runActionInRenderer('workbench.action.openTipsAndTricksUrl'), enabled: (this.windowsMainService.getWindowCount() > 0) }) : null, - (product.introductoryVideosUrl || keyboardShortcutsUrl) ? __separator__() : null, - product.twitterUrl ? new MenuItem({ label: this.mnemonicLabel(nls.localize({ key: 'miTwitter', comment: ['&& denotes a mnemonic'] }, "&&Join us on Twitter")), click: () => this.openUrl(product.twitterUrl, 'openTwitterUrl') }) : null, - product.requestFeatureUrl ? new MenuItem({ label: this.mnemonicLabel(nls.localize({ key: 'miUserVoice', comment: ['&& denotes a mnemonic'] }, "&&Search Feature Requests")), click: () => this.openUrl(product.requestFeatureUrl, 'openUserVoiceUrl') }) : null, - reportIssuesItem, - (product.twitterUrl || product.requestFeatureUrl || product.reportIssueUrl) ? __separator__() : null, - product.licenseUrl ? new MenuItem({ - label: this.mnemonicLabel(nls.localize({ key: 'miLicense', comment: ['&& denotes a mnemonic'] }, "View &&License")), click: () => { - if (language) { - const queryArgChar = product.licenseUrl.indexOf('?') > 0 ? '&' : '?'; - this.openUrl(`${product.licenseUrl}${queryArgChar}lang=${language}`, 'openLicenseUrl'); - } else { - this.openUrl(product.licenseUrl, 'openLicenseUrl'); - } - } - }) : null, - product.privacyStatementUrl ? new MenuItem({ - label: this.mnemonicLabel(nls.localize({ key: 'miPrivacyStatement', comment: ['&& denotes a mnemonic'] }, "&&Privacy Statement")), click: () => { - if (language) { - const queryArgChar = product.licenseUrl.indexOf('?') > 0 ? '&' : '?'; - this.openUrl(`${product.privacyStatementUrl}${queryArgChar}lang=${language}`, 'openPrivacyStatement'); - } else { - this.openUrl(product.privacyStatementUrl, 'openPrivacyStatement'); - } - } - }) : null, - (product.licenseUrl || product.privacyStatementUrl) ? __separator__() : null, - toggleDevToolsItem, - openProcessExplorer, - isWindows && product.quality !== 'stable' ? showAccessibilityOptions : null, - ]).forEach(item => helpMenu.append(item)); - - if (!isMacintosh) { - const updateMenuItems = this.getUpdateMenuItems(); - if (updateMenuItems.length) { - helpMenu.append(__separator__()); - updateMenuItems.forEach(i => helpMenu.append(i)); - } - - helpMenu.append(__separator__()); - helpMenu.append(new MenuItem({ label: this.mnemonicLabel(nls.localize({ key: 'miAbout', comment: ['&& denotes a mnemonic'] }, "&&About")), click: () => this.windowsService.openAboutDialog() })); - } - } - - private setTaskMenu(taskMenu: Electron.Menu): void { - const runTask = this.createMenuItem(nls.localize({ key: 'miRunTask', comment: ['&& denotes a mnemonic'] }, "&&Run Task..."), 'workbench.action.tasks.runTask'); - const buildTask = this.createMenuItem(nls.localize({ key: 'miBuildTask', comment: ['&& denotes a mnemonic'] }, "Run &&Build Task..."), 'workbench.action.tasks.build'); - const showTasks = this.createMenuItem(nls.localize({ key: 'miRunningTask', comment: ['&& denotes a mnemonic'] }, "Show Runnin&&g Tasks..."), 'workbench.action.tasks.showTasks'); - const restartTask = this.createMenuItem(nls.localize({ key: 'miRestartTask', comment: ['&& denotes a mnemonic'] }, "R&&estart Running Task..."), 'workbench.action.tasks.restartTask'); - const terminateTask = this.createMenuItem(nls.localize({ key: 'miTerminateTask', comment: ['&& denotes a mnemonic'] }, "&&Terminate Task..."), 'workbench.action.tasks.terminate'); - const configureTask = this.createMenuItem(nls.localize({ key: 'miConfigureTask', comment: ['&& denotes a mnemonic'] }, "&&Configure Tasks..."), 'workbench.action.tasks.configureTaskRunner'); - const configureBuildTask = this.createMenuItem(nls.localize({ key: 'miConfigureBuildTask', comment: ['&& denotes a mnemonic'] }, "Configure De&&fault Build Task..."), 'workbench.action.tasks.configureDefaultBuildTask'); - - [ - //__separator__(), - runTask, - buildTask, - __separator__(), - terminateTask, - restartTask, - showTasks, - __separator__(), - configureTask, - configureBuildTask - ].forEach(item => taskMenu.append(item)); - } - - private openAccessibilityOptions(): void { - const win = new BrowserWindow({ - alwaysOnTop: true, - skipTaskbar: true, - resizable: false, - width: 450, - height: 300, - show: true, - title: nls.localize('accessibilityOptionsWindowTitle', "Accessibility Options"), - webPreferences: { - disableBlinkFeatures: 'Auxclick' - } - }); - - win.setMenuBarVisibility(false); - - win.loadURL('chrome://accessibility'); - } - - private getUpdateMenuItems(): Electron.MenuItem[] { - const state = this.updateService.state; - - switch (state.type) { - case StateType.Uninitialized: - return []; - - case StateType.Idle: - return [new MenuItem({ - label: nls.localize('miCheckForUpdates', "Check for Updates..."), click: () => setTimeout(() => { - this.reportMenuActionTelemetry('CheckForUpdate'); - - const focusedWindow = this.windowsMainService.getFocusedWindow(); - const context = focusedWindow ? { windowId: focusedWindow.id } : null; - this.updateService.checkForUpdates(context); - }, 0) - })]; - - case StateType.CheckingForUpdates: - return [new MenuItem({ label: nls.localize('miCheckingForUpdates', "Checking For Updates..."), enabled: false })]; - - case StateType.AvailableForDownload: - return [new MenuItem({ - label: nls.localize('miDownloadUpdate', "Download Available Update"), click: () => { - this.updateService.downloadUpdate(); - } - })]; - - case StateType.Downloading: - return [new MenuItem({ label: nls.localize('miDownloadingUpdate', "Downloading Update..."), enabled: false })]; - - case StateType.Downloaded: - return [new MenuItem({ - label: nls.localize('miInstallUpdate', "Install Update..."), click: () => { - this.reportMenuActionTelemetry('InstallUpdate'); - this.updateService.applyUpdate(); - } - })]; - - case StateType.Updating: - return [new MenuItem({ label: nls.localize('miInstallingUpdate', "Installing Update..."), enabled: false })]; - - case StateType.Ready: - return [new MenuItem({ - label: nls.localize('miRestartToUpdate', "Restart to Update..."), click: () => { - this.reportMenuActionTelemetry('RestartToUpdate'); - this.updateService.quitAndInstall(); - } - })]; - } - } - - private createMenuItem(label: string, commandId: string | string[], enabled?: boolean, checked?: boolean): Electron.MenuItem; - private createMenuItem(label: string, click: () => void, enabled?: boolean, checked?: boolean): Electron.MenuItem; - private createMenuItem(arg1: string, arg2: any, arg3?: boolean, arg4?: boolean): Electron.MenuItem { - const label = this.mnemonicLabel(arg1); - const click: () => void = (typeof arg2 === 'function') ? arg2 : (menuItem: Electron.MenuItem, win: Electron.BrowserWindow, event: Electron.Event) => { - let commandId = arg2; - if (Array.isArray(arg2)) { - commandId = this.isOptionClick(event) ? arg2[1] : arg2[0]; // support alternative action if we got multiple action Ids and the option key was pressed while invoking - } - - this.runActionInRenderer(commandId); - }; - const enabled = typeof arg3 === 'boolean' ? arg3 : this.windowsMainService.getWindowCount() > 0; - const checked = typeof arg4 === 'boolean' ? arg4 : false; - - const options: Electron.MenuItemConstructorOptions = { - label, - click, - enabled - }; - - if (checked) { - options['type'] = 'checkbox'; - options['checked'] = checked; - } - - let commandId: string; - if (typeof arg2 === 'string') { - commandId = arg2; - } else if (Array.isArray(arg2)) { - commandId = arg2[0]; - } - - return new MenuItem(this.withKeybinding(commandId, options)); - } - - private createContextAwareMenuItem(label: string, commandId: string, clickHandler: IMenuItemClickHandler): Electron.MenuItem { - return new MenuItem(this.withKeybinding(commandId, { - label: this.mnemonicLabel(label), - enabled: this.windowsMainService.getWindowCount() > 0, - click: () => { - - // No Active Window - const activeWindow = this.windowsMainService.getFocusedWindow(); - if (!activeWindow) { - return clickHandler.inNoWindow(); - } - - // DevTools focused - if (activeWindow.win.webContents.isDevToolsFocused()) { - return clickHandler.inDevTools(activeWindow.win.webContents.devToolsWebContents); - } - - // Finally execute command in Window - this.runActionInRenderer(commandId); - } - })); - } - - private runActionInRenderer(id: string): void { - // We make sure to not run actions when the window has no focus, this helps - // for https://github.com/Microsoft/vscode/issues/25907 and specifically for - // https://github.com/Microsoft/vscode/issues/11928 - const activeWindow = this.windowsMainService.getFocusedWindow(); - if (activeWindow) { - this.windowsMainService.sendToFocused('vscode:runAction', { id, from: 'menu' } as IRunActionInWindowRequest); - } - } - - private withKeybinding(commandId: string, options: Electron.MenuItemConstructorOptions): Electron.MenuItemConstructorOptions { - const binding = this.keybindingsResolver.getKeybinding(commandId); - - // Apply binding if there is one - if (binding && binding.label) { - - // if the binding is native, we can just apply it - if (binding.isNative) { - options.accelerator = binding.label; - } - - // the keybinding is not native so we cannot show it as part of the accelerator of - // the menu item. we fallback to a different strategy so that we always display it - else { - const bindingIndex = options.label.indexOf('['); - if (bindingIndex >= 0) { - options.label = `${options.label.substr(0, bindingIndex)} [${binding.label}]`; - } else { - options.label = `${options.label} [${binding.label}]`; - } - } - } - - // Unset bindings if there is none - else { - options.accelerator = void 0; - } - - return options; - } - - private likeAction(commandId: string, options: Electron.MenuItemConstructorOptions, setAccelerator = !options.accelerator): Electron.MenuItemConstructorOptions { - if (setAccelerator) { - options = this.withKeybinding(commandId, options); - } - - const originalClick = options.click; - options.click = (item, window, event) => { - this.reportMenuActionTelemetry(commandId); - if (originalClick) { - originalClick(item, window, event); - } - }; - - return options; - } - - private openUrl(url: string, id: string): void { - shell.openExternal(url); - this.reportMenuActionTelemetry(id); - } - - private reportMenuActionTelemetry(id: string): void { - /* __GDPR__ - "workbenchActionExecuted" : { - "id" : { "classification": "SystemMetaData", "purpose": "FeatureInsight" }, - "from": { "classification": "SystemMetaData", "purpose": "FeatureInsight" } - } - */ - this.telemetryService.publicLog('workbenchActionExecuted', { id, from: telemetryFrom }); - } - - private mnemonicLabel(label: string): string { - return baseMnemonicLabel(label, !this.currentEnableMenuBarMnemonics); - } -} - -function __separator__(): Electron.MenuItem { - return new MenuItem({ type: 'separator' }); -} diff --git a/src/vs/platform/actions/common/actions.ts b/src/vs/platform/actions/common/actions.ts index e919252f47a..8ce41cfe124 100644 --- a/src/vs/platform/actions/common/actions.ts +++ b/src/vs/platform/actions/common/actions.ts @@ -93,6 +93,8 @@ export class MenuId { static readonly MenubarAppearanceMenu = new MenuId(); static readonly MenubarLayoutMenu = new MenuId(); static readonly MenubarGoMenu = new MenuId(); + static readonly MenubarSwitchEditorMenu = new MenuId(); + static readonly MenubarSwitchGroupMenu = new MenuId(); static readonly MenubarDebugMenu = new MenuId(); static readonly MenubarTasksMenu = new MenuId(); static readonly MenubarWindowMenu = new MenuId(); diff --git a/src/vs/workbench/browser/parts/menubar/menubar.contribution.ts b/src/vs/workbench/browser/parts/menubar/menubar.contribution.ts index 7e6a2e32e54..46c49d333fd 100644 --- a/src/vs/workbench/browser/parts/menubar/menubar.contribution.ts +++ b/src/vs/workbench/browser/parts/menubar/menubar.contribution.ts @@ -268,7 +268,6 @@ function selectionMenuRegistration() { }); } - function goMenuRegistration() { // Forward/Back MenuRegistry.appendMenuItem(MenuId.MenubarGoMenu, { @@ -290,8 +289,8 @@ function goMenuRegistration() { }); // Switch Editor - MenuRegistry.appendMenuItem(MenuId.MenubarGoMenu, { - group: '2_switch_editor', + MenuRegistry.appendMenuItem(MenuId.MenubarSwitchEditorMenu, { + group: '1_any', command: { id: 'workbench.action.nextEditor', title: nls.localize({ key: 'miNextEditor', comment: ['&& denotes a mnemonic'] }, "&&Next Editor") @@ -299,8 +298,8 @@ function goMenuRegistration() { order: 1 }); - MenuRegistry.appendMenuItem(MenuId.MenubarGoMenu, { - group: '2_switch_editor', + MenuRegistry.appendMenuItem(MenuId.MenubarSwitchEditorMenu, { + group: '1_any', command: { id: 'workbench.action.previousEditor', title: nls.localize({ key: 'miPreviousEditor', comment: ['&& denotes a mnemonic'] }, "&&Previous Editor") @@ -308,27 +307,79 @@ function goMenuRegistration() { order: 2 }); - MenuRegistry.appendMenuItem(MenuId.MenubarGoMenu, { - group: '2_switch_editor', + MenuRegistry.appendMenuItem(MenuId.MenubarSwitchEditorMenu, { + group: '2_used', command: { id: 'workbench.action.openNextRecentlyUsedEditorInGroup', title: nls.localize({ key: 'miNextEditorInGroup', comment: ['&& denotes a mnemonic'] }, "&&Next Used Editor in Group") }, - order: 3 + order: 1 }); - MenuRegistry.appendMenuItem(MenuId.MenubarGoMenu, { - group: '2_switch_editor', + MenuRegistry.appendMenuItem(MenuId.MenubarSwitchEditorMenu, { + group: '2_used', command: { id: 'workbench.action.openPreviousRecentlyUsedEditorInGroup', title: nls.localize({ key: 'miPreviousEditorInGroup', comment: ['&& denotes a mnemonic'] }, "&&Previous Used Editor in Group") }, - order: 4 + order: 2 + }); + + MenuRegistry.appendMenuItem(MenuId.MenubarGoMenu, { + group: '2_switch', + title: nls.localize({ key: 'miSwitchEditor', comment: ['&& denotes a mnemonic'] }, "Switch &&Editor"), + submenu: MenuId.MenubarSwitchEditorMenu, + order: 1 }); // Switch Group - MenuRegistry.appendMenuItem(MenuId.MenubarGoMenu, { - group: '3_switch_group', + MenuRegistry.appendMenuItem(MenuId.MenubarSwitchGroupMenu, { + group: '1_focus_index', + command: { + id: 'workbench.action.focusFirstEditorGroup', + title: nls.localize({ key: 'miFocusFirstGroup', comment: ['&& denotes a mnemonic'] }, "Group &&1") + }, + order: 1 + }); + + MenuRegistry.appendMenuItem(MenuId.MenubarSwitchGroupMenu, { + group: '1_focus_index', + command: { + id: 'workbench.action.focusSecondEditorGroup', + title: nls.localize({ key: 'miFocusSecondGroup', comment: ['&& denotes a mnemonic'] }, "Group &&2") + }, + order: 2 + }); + + MenuRegistry.appendMenuItem(MenuId.MenubarSwitchGroupMenu, { + group: '1_focus_index', + command: { + id: 'workbench.action.focusThirdEditorGroup', + title: nls.localize({ key: 'miFocusThirdGroup', comment: ['&& denotes a mnemonic'] }, "Group &&3") + }, + order: 3 + }); + + MenuRegistry.appendMenuItem(MenuId.MenubarSwitchGroupMenu, { + group: '1_focus_index', + command: { + id: 'workbench.action.focusFourthEditorGroup', + title: nls.localize({ key: 'miFocusFourthGroup', comment: ['&& denotes a mnemonic'] }, "Group &&4") + }, + order: 4 + }); + + MenuRegistry.appendMenuItem(MenuId.MenubarSwitchGroupMenu, { + group: '1_focus_index', + command: { + id: 'workbench.action.focusFifthEditorGroup', + title: nls.localize({ key: 'miFocusFifthGroup', comment: ['&& denotes a mnemonic'] }, "Group &&5") + }, + order: 5 + }); + + MenuRegistry.appendMenuItem(MenuId.MenubarSwitchGroupMenu, { + group: '2_next_prev', command: { id: 'workbench.action.focusNextGroup', title: nls.localize({ key: 'miNextGroup', comment: ['&& denotes a mnemonic'] }, "&&Next Group") @@ -336,8 +387,8 @@ function goMenuRegistration() { order: 1 }); - MenuRegistry.appendMenuItem(MenuId.MenubarGoMenu, { - group: '3_switch_group', + MenuRegistry.appendMenuItem(MenuId.MenubarSwitchGroupMenu, { + group: '2_next_prev', command: { id: 'workbench.action.focusPreviousGroup', title: nls.localize({ key: 'miPreviousGroup', comment: ['&& denotes a mnemonic'] }, "&&Previous Group") @@ -345,40 +396,47 @@ function goMenuRegistration() { order: 2 }); - MenuRegistry.appendMenuItem(MenuId.MenubarGoMenu, { - group: '3_switch_group', + MenuRegistry.appendMenuItem(MenuId.MenubarSwitchGroupMenu, { + group: '3_directional', command: { id: 'workbench.action.focusLeftGroup', title: nls.localize({ key: 'miFocusLeftGroup', comment: ['&& denotes a mnemonic'] }, "Group &&Left") }, + order: 1 + }); + + MenuRegistry.appendMenuItem(MenuId.MenubarSwitchGroupMenu, { + group: '3_directional', + command: { + id: 'workbench.action.focusRightGroup', + title: nls.localize({ key: 'miFocusRightGroup', comment: ['&& denotes a mnemonic'] }, "Group &&Right") + }, + order: 2 + }); + + MenuRegistry.appendMenuItem(MenuId.MenubarSwitchGroupMenu, { + group: '3_directional', + command: { + id: 'workbench.action.focusAboveGroup', + title: nls.localize({ key: 'miFocusAboveGroup', comment: ['&& denotes a mnemonic'] }, "Group &&Above") + }, order: 3 }); MenuRegistry.appendMenuItem(MenuId.MenubarGoMenu, { - group: '3_switch_group', + group: '3_directional', command: { - id: 'workbench.action.focusRightGroup', - title: nls.localize({ key: 'miFocusRightGroup', comment: ['&& denotes a mnemonic'] }, "Group &&Right") + id: 'workbench.action.focusBelowGroup', + title: nls.localize({ key: 'miFocusBelowGroup', comment: ['&& denotes a mnemonic'] }, "Group &&Below") }, order: 4 }); MenuRegistry.appendMenuItem(MenuId.MenubarGoMenu, { - group: '3_switch_group', - command: { - id: 'workbench.action.focusAboveGroup', - title: nls.localize({ key: 'miFocusAboveGroup', comment: ['&& denotes a mnemonic'] }, "Group &&Above") - }, - order: 5 - }); - - MenuRegistry.appendMenuItem(MenuId.MenubarGoMenu, { - group: '3_switch_group', - command: { - id: 'workbench.action.focusBelowGroup', - title: nls.localize({ key: 'miFocusBelowGroup', comment: ['&& denotes a mnemonic'] }, "Group &&Below") - }, - order: 6 + group: '2_switch', + title: nls.localize({ key: 'miSwitchGroup', comment: ['&& denotes a mnemonic'] }, "Switch &&Group"), + submenu: MenuId.MenubarSwitchGroupMenu, + order: 2 }); // Go to From c94682df34eeb8ce5e75a2d9d130dc850c08822b Mon Sep 17 00:00:00 2001 From: SteVen Batten <6561887+sbatten@users.noreply.github.com> Date: Mon, 23 Jul 2018 13:32:34 -0700 Subject: [PATCH 0053/1276] debug submenu --- src/vs/platform/actions/common/actions.ts | 1 + .../electron-browser/debug.contribution.ts | 49 +++++++++++++------ 2 files changed, 34 insertions(+), 16 deletions(-) diff --git a/src/vs/platform/actions/common/actions.ts b/src/vs/platform/actions/common/actions.ts index 8ce41cfe124..21c79a07b8c 100644 --- a/src/vs/platform/actions/common/actions.ts +++ b/src/vs/platform/actions/common/actions.ts @@ -96,6 +96,7 @@ export class MenuId { static readonly MenubarSwitchEditorMenu = new MenuId(); static readonly MenubarSwitchGroupMenu = new MenuId(); static readonly MenubarDebugMenu = new MenuId(); + static readonly MenubarNewBreakpointMenu = new MenuId(); static readonly MenubarTasksMenu = new MenuId(); static readonly MenubarWindowMenu = new MenuId(); static readonly MenubarPreferencesMenu = new MenuId(); diff --git a/src/vs/workbench/parts/debug/electron-browser/debug.contribution.ts b/src/vs/workbench/parts/debug/electron-browser/debug.contribution.ts index a9b45955e1f..91f5ac01c2a 100644 --- a/src/vs/workbench/parts/debug/electron-browser/debug.contribution.ts +++ b/src/vs/workbench/parts/debug/electron-browser/debug.contribution.ts @@ -358,40 +358,47 @@ MenuRegistry.appendMenuItem(MenuId.MenubarDebugMenu, { order: 1 }); -MenuRegistry.appendMenuItem(MenuId.MenubarDebugMenu, { - group: '4_new_breakpoint', +MenuRegistry.appendMenuItem(MenuId.MenubarNewBreakpointMenu, { + group: '1_breakpoints', command: { id: TOGGLE_CONDITIONAL_BREAKPOINT_ID, - title: nls.localize({ key: 'miConditionalBreakpoint', comment: ['&& denotes a mnemonic'] }, "Toggle &&Conditional Breakpoint...") + title: nls.localize({ key: 'miConditionalBreakpoint', comment: ['&& denotes a mnemonic'] }, "&&Conditional Breakpoint...") + }, + order: 1 +}); + +MenuRegistry.appendMenuItem(MenuId.MenubarNewBreakpointMenu, { + group: '1_breakpoints', + command: { + id: TOGGLE_INLINE_BREAKPOINT_ID, + title: nls.localize({ key: 'miInlineBreakpoint', comment: ['&& denotes a mnemonic'] }, "Inline Breakp&&oint") }, order: 2 }); -MenuRegistry.appendMenuItem(MenuId.MenubarDebugMenu, { - group: '4_new_breakpoint', +MenuRegistry.appendMenuItem(MenuId.MenubarNewBreakpointMenu, { + group: '1_breakpoints', command: { - id: TOGGLE_INLINE_BREAKPOINT_ID, - title: nls.localize({ key: 'miInlineBreakpoint', comment: ['&& denotes a mnemonic'] }, "Toggle Inline Breakp&&oint") + id: AddFunctionBreakpointAction.ID, + title: nls.localize({ key: 'miFunctionBreakpoint', comment: ['&& denotes a mnemonic'] }, "&&Function Breakpoint...") }, order: 3 }); -MenuRegistry.appendMenuItem(MenuId.MenubarDebugMenu, { - group: '4_new_breakpoint', +MenuRegistry.appendMenuItem(MenuId.MenubarNewBreakpointMenu, { + group: '1_breakpoints', command: { - id: AddFunctionBreakpointAction.ID, - title: nls.localize({ key: 'miFunctionBreakpoint', comment: ['&& denotes a mnemonic'] }, "Toggle &&Function Breakpoint...") + id: TOGGLE_LOG_POINT_ID, + title: nls.localize({ key: 'miLogPoint', comment: ['&& denotes a mnemonic'] }, "&&Logpoint...") }, order: 4 }); MenuRegistry.appendMenuItem(MenuId.MenubarDebugMenu, { group: '4_new_breakpoint', - command: { - id: TOGGLE_LOG_POINT_ID, - title: nls.localize({ key: 'miLogPoint', comment: ['&& denotes a mnemonic'] }, "Toggle &&Logpoint...") - }, - order: 5 + title: nls.localize({ key: 'miNewBreakpoint', comment: ['&& denotes a mnemonic'] }, "&&New Breakpoint"), + submenu: MenuId.MenubarNewBreakpointMenu, + order: 2 }); // Modify Breakpoints @@ -422,6 +429,16 @@ MenuRegistry.appendMenuItem(MenuId.MenubarDebugMenu, { order: 3 }); +// Install Debuggers +MenuRegistry.appendMenuItem(MenuId.MenubarDebugMenu, { + group: 'z_install', + command: { + id: 'debug.installAdditionalDebuggers', + title: nls.localize({ key: 'miInstallAdditionalDebuggers', comment: ['&& denotes a mnemonic'] }, "&&Install Additional Debuggers...") + }, + order: 1 +}); + // Touch Bar if (isMacintosh) { From 05a9494ae44c8335dc574ccd8844ba963f845a57 Mon Sep 17 00:00:00 2001 From: Jackson Kearl Date: Mon, 23 Jul 2018 13:36:09 -0700 Subject: [PATCH 0054/1276] Add final tests --- .../test/browser/controller/cursor.test.ts | 128 +++++++++++++++++- 1 file changed, 124 insertions(+), 4 deletions(-) diff --git a/src/vs/editor/test/browser/controller/cursor.test.ts b/src/vs/editor/test/browser/controller/cursor.test.ts index ead2a6e5b21..1c131493fa6 100644 --- a/src/vs/editor/test/browser/controller/cursor.test.ts +++ b/src/vs/editor/test/browser/controller/cursor.test.ts @@ -3997,7 +3997,7 @@ suite('autoClosingPairs', () => { cursorCommand(cursor, H.Undo); } - test('open parens', () => { + test('open parens: default', () => { let mode = new AutoClosingMode(); usingCursor({ text: [ @@ -4040,6 +4040,115 @@ suite('autoClosingPairs', () => { mode.dispose(); }); + test('open parens: whitespace', () => { + let mode = new AutoClosingMode(); + usingCursor({ + text: [ + 'var a = [];', + 'var b = `asd`;', + 'var c = \'asd\';', + 'var d = "asd";', + 'var e = /*3*/ 3;', + 'var f = /** 3 */3;', + 'var g = (3+5);', + 'var h = { a: \'value\' };', + ], + languageIdentifier: mode.getLanguageIdentifier(), + editorOpts: { + autoClosingBrackets: 'beforeWhitespace' + } + }, (model, cursor) => { + + let autoClosePositions = [ + 'var| a| =| [|];|', + 'var| b| =| `asd`;|', + 'var| c| =| \'asd\';|', + 'var| d| =| "asd";|', + 'var| e| =| /*3*/| 3;|', + 'var| f| =| /**| 3| */3;|', + 'var| g| =| (3+5|);|', + 'var| h| =| {| a:| \'value\'| |};|', + ]; + for (let i = 0, len = autoClosePositions.length; i < len; i++) { + const lineNumber = i + 1; + const autoCloseColumns = extractSpecialColumns(model.getLineMaxColumn(lineNumber), autoClosePositions[i]); + + for (let column = 1; column < autoCloseColumns.length; column++) { + model.forceTokenization(lineNumber); + if (autoCloseColumns[column] === ColumnType.Special1) { + assertType(model, cursor, lineNumber, column, '(', '()', `auto closes @ (${lineNumber}, ${column})`); + } else { + assertType(model, cursor, lineNumber, column, '(', '(', `does not auto close @ (${lineNumber}, ${column})`); + } + } + } + }); + mode.dispose(); + }); + + test('open parens disabled/enabled open quotes enabled/disabled', () => { + let mode = new AutoClosingMode(); + usingCursor({ + text: [ + 'var a = [];', + ], + languageIdentifier: mode.getLanguageIdentifier(), + editorOpts: { + autoClosingBrackets: 'beforeWhitespace', + autoClosingQuotes: 'never' + } + }, (model, cursor) => { + + let autoClosePositions = [ + 'var| a| =| [|];|', + ]; + for (let i = 0, len = autoClosePositions.length; i < len; i++) { + const lineNumber = i + 1; + const autoCloseColumns = extractSpecialColumns(model.getLineMaxColumn(lineNumber), autoClosePositions[i]); + + for (let column = 1; column < autoCloseColumns.length; column++) { + model.forceTokenization(lineNumber); + if (autoCloseColumns[column] === ColumnType.Special1) { + assertType(model, cursor, lineNumber, column, '(', '()', `auto closes @ (${lineNumber}, ${column})`); + } else { + assertType(model, cursor, lineNumber, column, '(', '(', `does not auto close @ (${lineNumber}, ${column})`); + } + assertType(model, cursor, lineNumber, column, '\'', '\'', `does not auto close @ (${lineNumber}, ${column})`); + } + } + }); + + usingCursor({ + text: [ + 'var a = [];', + ], + languageIdentifier: mode.getLanguageIdentifier(), + editorOpts: { + autoClosingBrackets: 'never', + autoClosingQuotes: 'beforeWhitespace' + } + }, (model, cursor) => { + + let autoClosePositions = [ + 'var| a| =| [|];|', + ]; + for (let i = 0, len = autoClosePositions.length; i < len; i++) { + const lineNumber = i + 1; + const autoCloseColumns = extractSpecialColumns(model.getLineMaxColumn(lineNumber), autoClosePositions[i]); + + for (let column = 1; column < autoCloseColumns.length; column++) { + model.forceTokenization(lineNumber); + if (autoCloseColumns[column] === ColumnType.Special1) { + assertType(model, cursor, lineNumber, column, '\'', '\'\'', `auto closes @ (${lineNumber}, ${column})`); + } else { + assertType(model, cursor, lineNumber, column, '\'', '\'', `does not auto close @ (${lineNumber}, ${column})`); + } + assertType(model, cursor, lineNumber, column, '(', '(', `does not auto close @ (${lineNumber}, ${column})`); + } + } + }); + mode.dispose(); + }); test('configurable open parens', () => { let mode = new AutoClosingMode(); @@ -4155,6 +4264,11 @@ suite('autoClosingPairs', () => { cursorCommand(cursor, H.Type, { text: '`' }, 'keyboard'); assert.equal(model.getValue(), '`var` a = `asd`'); + + // type a ( + cursorCommand(cursor, H.Type, { text: '(' }, 'keyboard'); + + assert.equal(model.getValue(), '`(var)` a = `(asd)`'); }); usingCursor({ @@ -4193,8 +4307,11 @@ suite('autoClosingPairs', () => { // type a ` cursorCommand(cursor, H.Type, { text: '`' }, 'keyboard'); - assert.equal(model.getValue(), '`var` a = asd'); + + // type a ( + cursorCommand(cursor, H.Type, { text: '`' }, 'keyboard'); + assert.equal(model.getValue(), '`(` a = asd'); }); usingCursor({ @@ -4211,10 +4328,13 @@ suite('autoClosingPairs', () => { new Selection(1, 1, 1, 4), ]); - // type a ` + // type a ( cursorCommand(cursor, H.Type, { text: '(' }, 'keyboard'); - assert.equal(model.getValue(), '(var) a = asd'); + + // type a ` + cursorCommand(cursor, H.Type, { text: '`' }, 'keyboard'); + assert.equal(model.getValue(), '(`) a = asd'); }); mode.dispose(); }); From a1601e420684610a404682454cf573b5a3ffbd8b Mon Sep 17 00:00:00 2001 From: Jackson Kearl Date: Mon, 23 Jul 2018 13:55:58 -0700 Subject: [PATCH 0055/1276] Fix tests --- .../test/browser/controller/cursor.test.ts | 38 +++++++++---------- 1 file changed, 19 insertions(+), 19 deletions(-) diff --git a/src/vs/editor/test/browser/controller/cursor.test.ts b/src/vs/editor/test/browser/controller/cursor.test.ts index 1c131493fa6..85f20c7dd29 100644 --- a/src/vs/editor/test/browser/controller/cursor.test.ts +++ b/src/vs/editor/test/browser/controller/cursor.test.ts @@ -4014,14 +4014,14 @@ suite('autoClosingPairs', () => { }, (model, cursor) => { let autoClosePositions = [ - 'var| a| =| [|]|;|', - 'var| b| =| `asd`|;|', - 'var| c| =| \'asd\'|;|', - 'var| d| =| "asd"|;|', - 'var| e| =| /*3*/| 3|;|', - 'var| f| =| /**| 3| */3|;|', - 'var| g| =| (3+5|)|;|', - 'var| h| =| {| a|:| \'value\'| |}|;|', + 'var| a| |=| [|]|;|', + 'var| b| |=| `asd`|;|', + 'var| c| |=| \'asd\'|;|', + 'var| d| |=| "asd"|;|', + 'var| e| |=| /*3*/| 3|;|', + 'var| f| |=| /**| 3| */3|;|', + 'var| g| |=| (3+5|)|;|', + 'var| h| |=| {| a|:| \'value\'| |}|;|', ]; for (let i = 0, len = autoClosePositions.length; i < len; i++) { const lineNumber = i + 1; @@ -4120,7 +4120,7 @@ suite('autoClosingPairs', () => { usingCursor({ text: [ - 'var a = [];', + 'var b = [];', ], languageIdentifier: mode.getLanguageIdentifier(), editorOpts: { @@ -4130,7 +4130,7 @@ suite('autoClosingPairs', () => { }, (model, cursor) => { let autoClosePositions = [ - 'var| a| =| [|];|', + 'var b =| [|];|', ]; for (let i = 0, len = autoClosePositions.length; i < len; i++) { const lineNumber = i + 1; @@ -4310,7 +4310,7 @@ suite('autoClosingPairs', () => { assert.equal(model.getValue(), '`var` a = asd'); // type a ( - cursorCommand(cursor, H.Type, { text: '`' }, 'keyboard'); + cursorCommand(cursor, H.Type, { text: '(' }, 'keyboard'); assert.equal(model.getValue(), '`(` a = asd'); }); @@ -4356,14 +4356,14 @@ suite('autoClosingPairs', () => { }, (model, cursor) => { let autoClosePositions = [ - 'var a =| [|];|', - 'var b =| |`asd`;|', - 'var c =| |\'asd!\';|', - 'var d =| |"asd";|', - 'var e =| /*3*/| 3;|', - 'var f =| /**| 3 */3;|', - 'var g =| (3+5);|', - 'var h =| {| a:| |\'value!\'| |};|', + 'var a |=| [|]|;|', + 'var b |=| |`asd`|;|', + 'var c |=| |\'asd!\'|;|', + 'var d |=| |"asd"|;|', + 'var e |=| /*3*/| 3;|', + 'var f |=| /**| 3 */3;|', + 'var g |=| (3+5)|;|', + 'var h |=| {| a:| |\'value!\'| |}|;|', ]; for (let i = 0, len = autoClosePositions.length; i < len; i++) { const lineNumber = i + 1; From 0e0fc93f16ef60d9200c1b0d6b6a14d309184848 Mon Sep 17 00:00:00 2001 From: Jackson Kearl Date: Mon, 23 Jul 2018 15:27:10 -0700 Subject: [PATCH 0056/1276] Update settings text to match new style suggestions --- .../common/config/commonEditorConfig.ts | 30 +++++++++---------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/src/vs/editor/common/config/commonEditorConfig.ts b/src/vs/editor/common/config/commonEditorConfig.ts index 5bd74304326..886f328a739 100644 --- a/src/vs/editor/common/config/commonEditorConfig.ts +++ b/src/vs/editor/common/config/commonEditorConfig.ts @@ -491,38 +491,38 @@ const editorConfiguration: IConfigurationNode = { type: 'string', enum: ['always', 'languageDefined', 'beforeWhitespace', 'never'], enumDescriptions: [ - nls.localize('editor.autoClosingBrackets.always', "always autoclose brackets"), - nls.localize('editor.autoClosingBrackets.languageDefined', "use language configurations to determine when to autoclose brackets"), - nls.localize('editor.autoClosingBrackets.beforeWhitespace', "autoclose brackets only when the cursor is to the left of whitespace"), - nls.localize('editor.autoClosingBrackets.never', "never perform autoclosing on brackets"), + '', + nls.localize('editor.autoClosingBrackets.languageDefined', "Use language configurations to determine when to autoclose brackets."), + nls.localize('editor.autoClosingBrackets.beforeWhitespace', "Autoclose brackets only when the cursor is to the left of whitespace."), + '', ], 'default': EDITOR_DEFAULTS.autoClosingBrackets, - 'description': nls.localize('autoClosingBrackets', "Controls if the editor should automatically close brackets after opening them.") + 'description': nls.localize('autoClosingBrackets', "Controls whether the editor should automatically close brackets after opening them.") }, 'editor.autoClosingQuotes': { type: 'string', enum: ['always', 'languageDefined', 'beforeWhitespace', 'never'], enumDescriptions: [ - nls.localize('editor.autoClosingQuotes.always', "always autoclose quotes"), - nls.localize('editor.autoClosingQuotes.languageDefined', "use language configurations to determine when to autoclose quotes"), - nls.localize('editor.autoClosingQuotes.beforeWhitespace', "autoclose quotes only when the cursor is to the left of whitespace"), - nls.localize('editor.autoClosingQuotes.never', "never perform autoclosing on quotes"), + '', + nls.localize('editor.autoClosingQuotes.languageDefined', "Use language configurations to determine when to autoclose quotes."), + nls.localize('editor.autoClosingQuotes.beforeWhitespace', "Autoclose quotes only when the cursor is to the left of whitespace."), + '', ], 'default': EDITOR_DEFAULTS.autoClosingQuotes, - 'description': nls.localize('autoClosingQuotes', "Controls if the editor should automatically close quotes after opening them.") + 'description': nls.localize('autoClosingQuotes', "Controls whether the editor should automatically close quotes after opening them.") }, 'editor.autoWrapping': { type: 'string', enum: ['always', 'brackets', 'quotes', 'never'], enumDescriptions: [ - nls.localize('editor.autoWrapping.always', "wrap with both quotes and brackets"), - nls.localize('editor.autoWrapping.brackets', " wrap with brackets but not quotes"), - nls.localize('editor.autoWrapping.quotes', "wrap with quotes but not brackets"), - nls.localize('editor.autoWrapping.never', "do not autowrap selections") + '', + nls.localize('editor.autoWrapping.brackets', "Wrap with brackets but not quotes."), + nls.localize('editor.autoWrapping.quotes', "Wrap with quotes but not brackets."), + '' ], 'default': EDITOR_DEFAULTS.autoWrapping, - 'description': nls.localize('autoWrapping', "Controls if the editor should automatically wrap selections.") + 'description': nls.localize('autoWrapping', "Controls whether the editor should automatically wrap selections.") }, 'editor.formatOnType': { 'type': 'boolean', From ba0933e189f676a858b18ed069075b0b305fdc41 Mon Sep 17 00:00:00 2001 From: Miguel Solorio Date: Mon, 23 Jul 2018 16:06:18 -0700 Subject: [PATCH 0057/1276] Update settings description opacity to reflect themable setting for #52479 --- src/vs/workbench/parts/preferences/browser/settingsEditor2.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vs/workbench/parts/preferences/browser/settingsEditor2.ts b/src/vs/workbench/parts/preferences/browser/settingsEditor2.ts index 8b6d31130d0..815f76e7689 100644 --- a/src/vs/workbench/parts/preferences/browser/settingsEditor2.ts +++ b/src/vs/workbench/parts/preferences/browser/settingsEditor2.ts @@ -367,7 +367,7 @@ export class SettingsEditor2 extends BaseEditor { if (foregroundColor) { // Links appear inside other elements in markdown. CSS opacity acts like a mask. So we have to dynamically compute the description color to avoid // applying an opacity to the link color. - const fgWithOpacity = new Color(new RGBA(foregroundColor.rgba.r, foregroundColor.rgba.g, foregroundColor.rgba.b, .7)); + const fgWithOpacity = new Color(new RGBA(foregroundColor.rgba.r, foregroundColor.rgba.g, foregroundColor.rgba.b, .9)); collector.addRule(`.settings-editor > .settings-body > .settings-tree-container .setting-item .setting-item-description { color: ${fgWithOpacity}; }`); } })); From 629c05f1f814a5f42eb0dd48cad43682cff43057 Mon Sep 17 00:00:00 2001 From: Jackson Kearl Date: Tue, 24 Jul 2018 00:07:42 -0700 Subject: [PATCH 0058/1276] Add special case for js(x) template strings --- extensions/javascript/javascript-language-configuration.json | 1 + 1 file changed, 1 insertion(+) diff --git a/extensions/javascript/javascript-language-configuration.json b/extensions/javascript/javascript-language-configuration.json index 1e8f440a420..b41053843cf 100644 --- a/extensions/javascript/javascript-language-configuration.json +++ b/extensions/javascript/javascript-language-configuration.json @@ -25,6 +25,7 @@ ["\"", "\""], ["`", "`"] ], + "autoCloseBefore": ";:.,=}])>` \n\t", "folding": { "markers": { "start": "^\\s*//\\s*#?region\\b", From 763e939bdd261614de04001fb385151f9d8d1159 Mon Sep 17 00:00:00 2001 From: Jackson Kearl Date: Tue, 24 Jul 2018 00:38:38 -0700 Subject: [PATCH 0059/1276] Document jsx specialization --- extensions/javascript/javascript-language-configuration.json | 1 + 1 file changed, 1 insertion(+) diff --git a/extensions/javascript/javascript-language-configuration.json b/extensions/javascript/javascript-language-configuration.json index b41053843cf..72fa7c6cc81 100644 --- a/extensions/javascript/javascript-language-configuration.json +++ b/extensions/javascript/javascript-language-configuration.json @@ -25,6 +25,7 @@ ["\"", "\""], ["`", "`"] ], + // add ` as an autocloseBefore because templated backtick strings are common "autoCloseBefore": ";:.,=}])>` \n\t", "folding": { "markers": { From 1655e6eb230c4418c24db524c4e4d255d9cd01cf Mon Sep 17 00:00:00 2001 From: Jackson Kearl Date: Tue, 24 Jul 2018 00:42:18 -0700 Subject: [PATCH 0060/1276] Same specialization for ts --- extensions/typescript-basics/language-configuration.json | 2 ++ 1 file changed, 2 insertions(+) diff --git a/extensions/typescript-basics/language-configuration.json b/extensions/typescript-basics/language-configuration.json index 1e8f440a420..72fa7c6cc81 100644 --- a/extensions/typescript-basics/language-configuration.json +++ b/extensions/typescript-basics/language-configuration.json @@ -25,6 +25,8 @@ ["\"", "\""], ["`", "`"] ], + // add ` as an autocloseBefore because templated backtick strings are common + "autoCloseBefore": ";:.,=}])>` \n\t", "folding": { "markers": { "start": "^\\s*//\\s*#?region\\b", From a446812f303795c16457d2c7989ee8226841d6e2 Mon Sep 17 00:00:00 2001 From: SteVen Batten <6561887+sbatten@users.noreply.github.com> Date: Tue, 24 Jul 2018 08:05:22 -0700 Subject: [PATCH 0061/1276] fixing bugs --- src/vs/code/electron-main/menubar.ts | 22 +++++++++++-------- .../browser/parts/menubar/menubarPart.ts | 9 +++----- 2 files changed, 16 insertions(+), 15 deletions(-) diff --git a/src/vs/code/electron-main/menubar.ts b/src/vs/code/electron-main/menubar.ts index eec9bc45066..1cbe2539b44 100644 --- a/src/vs/code/electron-main/menubar.ts +++ b/src/vs/code/electron-main/menubar.ts @@ -281,16 +281,18 @@ export class Menubar { } // Preferences - const preferencesMenu = new Menu(); - const preferencesMenuItem = new MenuItem({ label: this.mnemonicLabel(nls.localize({ key: 'mPreferences', comment: ['&& denotes a mnemonic'] }, "&&Preferences")), submenu: preferencesMenu }); + if (!isMacintosh) { + const preferencesMenu = new Menu(); + const preferencesMenuItem = new MenuItem({ label: this.mnemonicLabel(nls.localize({ key: 'mPreferences', comment: ['&& denotes a mnemonic'] }, "&&Preferences")), submenu: preferencesMenu }); - if (this.shouldDrawMenu('Preferences')) { - if (this.shouldFallback('Preferences')) { - this.setFallbackMenuById(preferencesMenu, 'Preferences'); - } else { - this.setMenuById(preferencesMenu, 'Preferences'); + if (this.shouldDrawMenu('Preferences')) { + if (this.shouldFallback('Preferences')) { + this.setFallbackMenuById(preferencesMenu, 'Preferences'); + } else { + this.setMenuById(preferencesMenu, 'Preferences'); + } + menubar.append(preferencesMenuItem); } - menubar.append(preferencesMenuItem); } // Help @@ -489,7 +491,9 @@ export class Menubar { } private setMenuById(menu: Electron.Menu, menuId: string): void { - this.setMenu(menu, this.menubarMenus[menuId].items); + if (this.menubarMenus[menuId]) { + this.setMenu(menu, this.menubarMenus[menuId].items); + } } private insertRecentMenuItems(menu: Electron.Menu) { diff --git a/src/vs/workbench/browser/parts/menubar/menubarPart.ts b/src/vs/workbench/browser/parts/menubar/menubarPart.ts index 2bfa53a9183..e282e9b3f34 100644 --- a/src/vs/workbench/browser/parts/menubar/menubarPart.ts +++ b/src/vs/workbench/browser/parts/menubar/menubarPart.ts @@ -431,7 +431,9 @@ export class MenubarPart extends Part { if (!isMacintosh && this.currentTitlebarStyleSetting === 'custom') { this.setupCustomMenubar(); } else { - this.setupNativeMenubar(); + // Send menus to main process to be rendered by Electron + this.menubarService.updateMenubar(this.windowService.getCurrentWindowId(), this.getMenubarMenus()); + } } @@ -439,11 +441,6 @@ export class MenubarPart extends Part { this.menuUpdater.schedule(); } - private setupNativeMenubar(): void { - this.menubarService.updateMenubar(this.windowService.getCurrentWindowId(), this.getMenubarMenus()); - } - - private clearMnemonic(topLevelElement: HTMLElement): void { topLevelElement.accessKey = null; } From 9a12f5939d3de47ad31ca00d5cdb98f1a3c4b7ce Mon Sep 17 00:00:00 2001 From: isidor Date: Tue, 24 Jul 2018 18:07:42 +0200 Subject: [PATCH 0062/1276] introduce uriLabelProvider --- src/vs/base/common/labels.ts | 64 +++++++++++++++---- .../electron-browser/files.contribution.ts | 11 ++++ 2 files changed, 61 insertions(+), 14 deletions(-) diff --git a/src/vs/base/common/labels.ts b/src/vs/base/common/labels.ts index 15d9a56d269..e88d8ea6ad7 100644 --- a/src/vs/base/common/labels.ts +++ b/src/vs/base/common/labels.ts @@ -5,8 +5,8 @@ 'use strict'; import URI from 'vs/base/common/uri'; -import { nativeSep, normalize, basename as pathsBasename, sep } from 'vs/base/common/paths'; -import { endsWith, ltrim, startsWithIgnoreCase, rtrim, startsWith } from 'vs/base/common/strings'; +import { nativeSep, basename as pathsBasename, sep } from 'vs/base/common/paths'; +import { endsWith, startsWithIgnoreCase, rtrim, startsWith } from 'vs/base/common/strings'; import { Schemas } from 'vs/base/common/network'; import { isLinux, isWindows, isMacintosh } from 'vs/base/common/platform'; import { isEqual } from 'vs/base/common/resources'; @@ -22,6 +22,11 @@ export interface IUserHomeProvider { userHome: string; } +function resourceToLabel(resource: URI, labelProvider: UriLabelProvider, ): string { + // TODO@Isidor take into account labelProvider.uriDisplay.label and convert the resource into string representation + return ''; +} + /** * @param resource for which to compute the path label * @param userHomeProvider if a resource has a file schema userHomeProvider is used for tildifiying the label @@ -36,6 +41,11 @@ export function getPathLabel(resource: URI | string, userHomeProvider: IUserHome resource = URI.file(resource); } + const labelProvider = UriLabelProviderRegistry.getUriLabelProvider(resource.scheme); + if (!labelProvider) { + return resource.with({ query: null, fragment: null }).toString(true); + } + // return early if we can resolve a relative path label from the root const baseResource = rootProvider ? rootProvider.getWorkspaceFolder(resource) : null; if (baseResource) { @@ -45,34 +55,32 @@ export function getPathLabel(resource: URI | string, userHomeProvider: IUserHome if (isEqual(baseResource.uri, resource, !isLinux)) { pathLabel = ''; // no label if paths are identical } else { - pathLabel = normalize(ltrim(resource.path.substr(baseResource.uri.path.length), sep), true); + const baseResourceLabel = resourceToLabel(baseResource.uri, labelProvider); + pathLabel = resourceToLabel(resource, labelProvider).substr(baseResourceLabel.length); } if (hasMultipleRoots) { - const rootName = (baseResource && baseResource.name) ? baseResource.name : pathsBasename(baseResource.uri.fsPath); + const rootName = (baseResource && baseResource.name) ? baseResource.name : pathsBasename(baseResource.uri.path); pathLabel = pathLabel ? (rootName + ' • ' + pathLabel) : rootName; // always show root basename if there are multiple } return pathLabel; } - // return if the resource is neither file:// nor untitled:// and no baseResource was provided - if (resource.scheme !== Schemas.file && resource.scheme !== Schemas.untitled) { - return resource.with({ query: null, fragment: null }).toString(true); - } + + let label = resourceToLabel(resource, labelProvider); // convert c:\something => C:\something - if (hasDriveLetter(resource.fsPath)) { - return normalize(normalizeDriveLetter(resource.fsPath), true); + if (labelProvider.uriDisplay.normalizeDriveLetter && hasDriveLetter(label)) { + label = normalizeDriveLetter(label); } // normalize and tildify (macOS, Linux only) - let res = normalize(resource.fsPath, true); - if (!isWindows && userHomeProvider) { - res = tildify(res, userHomeProvider.userHome); + if (labelProvider.uriDisplay.tildify && userHomeProvider) { + label = tildify(label, userHomeProvider.userHome); } - return res; + return label; } export function getBaseLabel(resource: URI | string): string { @@ -384,3 +392,31 @@ export function mnemonicButtonLabel(label: string): string { export function unmnemonicLabel(label: string): string { return label.replace(/&/g, '&&'); } + +export interface UriLabelProvider { + schema: string; + label?: string; + uriDisplay: { + label: string; + forwardSlash?: boolean; + tildify?: boolean; + normalizeDriveLetter?: boolean; + }; +} + +export interface IUriLabelProviderRegistry { + registerUriLabelProvider(descriptor: UriLabelProvider): void; + getUriLabelProvider(scheme: string): UriLabelProvider; +} + +export const UriLabelProviderRegistry: IUriLabelProviderRegistry = new class UriLabelProviderRegistry implements IUriLabelProviderRegistry { + private uriLabelProviders = new Map(); + + registerUriLabelProvider(descriptor: UriLabelProvider): void { + this.uriLabelProviders.set(descriptor.schema, descriptor); + } + + getUriLabelProvider(scheme: string): UriLabelProvider { + return this.uriLabelProviders.get(scheme); + } +}; diff --git a/src/vs/workbench/parts/files/electron-browser/files.contribution.ts b/src/vs/workbench/parts/files/electron-browser/files.contribution.ts index c684a9a1e73..24a23202664 100644 --- a/src/vs/workbench/parts/files/electron-browser/files.contribution.ts +++ b/src/vs/workbench/parts/files/electron-browser/files.contribution.ts @@ -34,6 +34,7 @@ import { DataUriEditorInput } from 'vs/workbench/common/editor/dataUriEditorInpu import { LifecyclePhase } from 'vs/platform/lifecycle/common/lifecycle'; import { IEditorService } from 'vs/workbench/services/editor/common/editorService'; import { IEditorGroupsService } from 'vs/workbench/services/group/common/editorGroupsService'; +import { UriLabelProviderRegistry } from 'vs/base/common/labels'; // Viewlet Action export class OpenExplorerViewletAction extends ToggleViewletAction { @@ -381,3 +382,13 @@ MenuRegistry.appendMenuItem(MenuId.MenubarViewMenu, { }, order: 1 }); + +UriLabelProviderRegistry.registerUriLabelProvider({ + schema: 'file', + uriDisplay: { + label: '${path}', + forwardSlash: !platform.isWindows, + tildify: !platform.isWindows, + normalizeDriveLetter: platform.isWindows + } +}); From 9360e06e92877956b544454c674a7ab76a3d46fa Mon Sep 17 00:00:00 2001 From: Miguel Solorio Date: Tue, 24 Jul 2018 09:09:34 -0700 Subject: [PATCH 0063/1276] Update colors for unsaved/badges so that it's easier to read --- src/vs/platform/theme/common/colorRegistry.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/vs/platform/theme/common/colorRegistry.ts b/src/vs/platform/theme/common/colorRegistry.ts index 20da2b69538..0daa9ba3f68 100644 --- a/src/vs/platform/theme/common/colorRegistry.ts +++ b/src/vs/platform/theme/common/colorRegistry.ts @@ -213,8 +213,8 @@ export const buttonForeground = registerColor('button.foreground', { dark: Color export const buttonBackground = registerColor('button.background', { dark: '#0E639C', light: '#007ACC', hc: null }, nls.localize('buttonBackground', "Button background color.")); export const buttonHoverBackground = registerColor('button.hoverBackground', { dark: lighten(buttonBackground, 0.2), light: darken(buttonBackground, 0.2), hc: null }, nls.localize('buttonHoverBackground', "Button background color when hovering.")); -export const badgeBackground = registerColor('badge.background', { dark: '#4D4D4D', light: '#BEBEBE', hc: Color.black }, nls.localize('badgeBackground', "Badge background color. Badges are small information labels, e.g. for search results count.")); -export const badgeForeground = registerColor('badge.foreground', { dark: Color.white, light: '#4E4E4E', hc: Color.white }, nls.localize('badgeForeground', "Badge foreground color. Badges are small information labels, e.g. for search results count.")); +export const badgeBackground = registerColor('badge.background', { dark: '#4D4D4D', light: '#717171', hc: Color.black }, nls.localize('badgeBackground', "Badge background color. Badges are small information labels, e.g. for search results count.")); +export const badgeForeground = registerColor('badge.foreground', { dark: Color.white, light: Color.white, hc: Color.white }, nls.localize('badgeForeground', "Badge foreground color. Badges are small information labels, e.g. for search results count.")); export const scrollbarShadow = registerColor('scrollbar.shadow', { dark: '#000000', light: '#DDDDDD', hc: null }, nls.localize('scrollbarShadow', "Scrollbar shadow to indicate that the view is scrolled.")); export const scrollbarSliderBackground = registerColor('scrollbarSlider.background', { dark: Color.fromHex('#797979').transparent(0.4), light: Color.fromHex('#646464').transparent(0.4), hc: transparent(contrastBorder, 0.6) }, nls.localize('scrollbarSliderBackground', "Scrollbar slider background color.")); From 21e980c81fc95532db01ad7076545f18b114a97f Mon Sep 17 00:00:00 2001 From: Miguel Solorio Date: Tue, 24 Jul 2018 09:42:55 -0700 Subject: [PATCH 0064/1276] Update badge colors to be softer --- src/vs/platform/theme/common/colorRegistry.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/vs/platform/theme/common/colorRegistry.ts b/src/vs/platform/theme/common/colorRegistry.ts index 0daa9ba3f68..d2f8fd97639 100644 --- a/src/vs/platform/theme/common/colorRegistry.ts +++ b/src/vs/platform/theme/common/colorRegistry.ts @@ -213,8 +213,8 @@ export const buttonForeground = registerColor('button.foreground', { dark: Color export const buttonBackground = registerColor('button.background', { dark: '#0E639C', light: '#007ACC', hc: null }, nls.localize('buttonBackground', "Button background color.")); export const buttonHoverBackground = registerColor('button.hoverBackground', { dark: lighten(buttonBackground, 0.2), light: darken(buttonBackground, 0.2), hc: null }, nls.localize('buttonHoverBackground', "Button background color when hovering.")); -export const badgeBackground = registerColor('badge.background', { dark: '#4D4D4D', light: '#717171', hc: Color.black }, nls.localize('badgeBackground', "Badge background color. Badges are small information labels, e.g. for search results count.")); -export const badgeForeground = registerColor('badge.foreground', { dark: Color.white, light: Color.white, hc: Color.white }, nls.localize('badgeForeground', "Badge foreground color. Badges are small information labels, e.g. for search results count.")); +export const badgeBackground = registerColor('badge.background', { dark: '#4D4D4D', light: '#C4C4C4', hc: Color.black }, nls.localize('badgeBackground', "Badge background color. Badges are small information labels, e.g. for search results count.")); +export const badgeForeground = registerColor('badge.foreground', { dark: Color.white, light: '#333', hc: Color.white }, nls.localize('badgeForeground', "Badge foreground color. Badges are small information labels, e.g. for search results count.")); export const scrollbarShadow = registerColor('scrollbar.shadow', { dark: '#000000', light: '#DDDDDD', hc: null }, nls.localize('scrollbarShadow', "Scrollbar shadow to indicate that the view is scrolled.")); export const scrollbarSliderBackground = registerColor('scrollbarSlider.background', { dark: Color.fromHex('#797979').transparent(0.4), light: Color.fromHex('#646464').transparent(0.4), hc: transparent(contrastBorder, 0.6) }, nls.localize('scrollbarSliderBackground', "Scrollbar slider background color.")); From 1d9f32744113bedb4c0834e443cbeec1d90b87e6 Mon Sep 17 00:00:00 2001 From: Miguel Solorio Date: Tue, 24 Jul 2018 10:46:55 -0700 Subject: [PATCH 0065/1276] Update icons for dark theme, fixes #54712 --- src/vs/editor/contrib/documentSymbols/media/Class_16x_darkp.svg | 2 +- src/vs/editor/contrib/documentSymbols/media/Field_16x_darkp.svg | 2 +- .../contrib/documentSymbols/media/Interface_16x_darkp.svg | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/vs/editor/contrib/documentSymbols/media/Class_16x_darkp.svg b/src/vs/editor/contrib/documentSymbols/media/Class_16x_darkp.svg index 746e7dfc6d8..c43aad29efd 100644 --- a/src/vs/editor/contrib/documentSymbols/media/Class_16x_darkp.svg +++ b/src/vs/editor/contrib/documentSymbols/media/Class_16x_darkp.svg @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/src/vs/editor/contrib/documentSymbols/media/Field_16x_darkp.svg b/src/vs/editor/contrib/documentSymbols/media/Field_16x_darkp.svg index e1b5aa5e31d..5fc48ceff0f 100644 --- a/src/vs/editor/contrib/documentSymbols/media/Field_16x_darkp.svg +++ b/src/vs/editor/contrib/documentSymbols/media/Field_16x_darkp.svg @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/src/vs/editor/contrib/documentSymbols/media/Interface_16x_darkp.svg b/src/vs/editor/contrib/documentSymbols/media/Interface_16x_darkp.svg index 0c08c8d50af..f7c2934a55c 100644 --- a/src/vs/editor/contrib/documentSymbols/media/Interface_16x_darkp.svg +++ b/src/vs/editor/contrib/documentSymbols/media/Interface_16x_darkp.svg @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file From b94c44e719c309b6871264936da582a1ad03dace Mon Sep 17 00:00:00 2001 From: Ramya Rao Date: Tue, 24 Jul 2018 12:17:49 -0700 Subject: [PATCH 0066/1276] zh-hans and zh-hant are invalid locales (#54696) * zh-hans and zh-hant are invalid locales * Allow more than 1 result in the gallery query --- .../localizations.contribution.ts | 19 +++++-------------- 1 file changed, 5 insertions(+), 14 deletions(-) diff --git a/src/vs/workbench/parts/localizations/electron-browser/localizations.contribution.ts b/src/vs/workbench/parts/localizations/electron-browser/localizations.contribution.ts index 340f821e0f4..ef0e09b3c44 100644 --- a/src/vs/workbench/parts/localizations/electron-browser/localizations.contribution.ts +++ b/src/vs/workbench/parts/localizations/electron-browser/localizations.contribution.ts @@ -141,19 +141,15 @@ export class LocalizationWorkbenchContribution extends Disposable implements IWo return; } - const extensionIdPostfix = this.getPossibleChineseMapping(locale); - const ceintlExtensionSearch = this.galleryService.query({ names: [`MS-CEINTL.vscode-language-pack-${extensionIdPostfix}`], pageSize: 1 }); - const tagSearch = this.galleryService.query({ text: `tag:lp-${locale}`, pageSize: 1 }); - - TPromise.join([ceintlExtensionSearch, tagSearch]).then(([ceintlResult, tagResult]) => { - if (ceintlResult.total === 0 && tagResult.total === 0) { + this.galleryService.query({ text: `tag:lp-${locale}` }).then(tagResult => { + if (tagResult.total === 0) { return; } - const extensionToInstall = ceintlResult.total === 1 ? ceintlResult.firstPage[0] : tagResult.total === 1 ? tagResult.firstPage[0] : null; - const extensionToFetchTranslationsFrom = extensionToInstall || (tagResult.total > 0 ? tagResult.firstPage[0] : null); + const extensionToInstall = tagResult.total === 1 ? tagResult.firstPage[0] : tagResult.firstPage.filter(e => e.publisher === 'MS-CEINTL' && e.name.indexOf('vscode-language-pack') === 0)[0]; + const extensionToFetchTranslationsFrom = extensionToInstall || tagResult.firstPage[0]; - if (!extensionToFetchTranslationsFrom || !extensionToFetchTranslationsFrom.assets.manifest) { + if (!extensionToFetchTranslationsFrom.assets.manifest) { return; } @@ -236,11 +232,6 @@ export class LocalizationWorkbenchContribution extends Disposable implements IWo } - private getPossibleChineseMapping(locale: string): string { - locale = locale.toLowerCase(); - return locale === 'zh-cn' ? 'zh-hans' : locale === 'zh-tw' ? 'zh-hant' : locale; - } - private getLanguagePackExtension(language: string): TPromise { return this.localizationService.getLanguageIds(LanguageType.Core) .then(coreLanguages => { From 4be0f0723091ae10b14ba20b334847d607bb7d55 Mon Sep 17 00:00:00 2001 From: Matt Bierner Date: Tue, 24 Jul 2018 15:08:46 -0700 Subject: [PATCH 0067/1276] Add WebviewPanel.iconPath (#54912) * Add WebviewPanel.iconPath Allows webviews to provide icons used in UI. Adds a new `WebviewPanel.iconPath` property for this. Replaces the static contribution approach from #49657 Fixes #48864 * Fix doc * Move icon into mainthreadwebview * Cleaning up implementation * Cleaning up implementation --- .../src/extension.ts | 2 +- .../src/features/preview.ts | 9 +++ .../src/markdownExtensions.ts | 9 ++- .../src/test/engine.ts | 1 + src/vs/vscode.d.ts | 5 ++ .../api/electron-browser/mainThreadWebview.ts | 71 +++++++++++++++++-- src/vs/workbench/api/node/extHost.protocol.ts | 1 + src/vs/workbench/api/node/extHostWebview.ts | 28 ++++++-- .../webview/electron-browser/webviewEditor.ts | 4 +- .../electron-browser/webviewEditorInput.ts | 24 +++++-- 10 files changed, 132 insertions(+), 22 deletions(-) diff --git a/extensions/markdown-language-features/src/extension.ts b/extensions/markdown-language-features/src/extension.ts index a9d95e36ce8..7786db20216 100644 --- a/extensions/markdown-language-features/src/extension.ts +++ b/extensions/markdown-language-features/src/extension.ts @@ -24,7 +24,7 @@ export function activate(context: vscode.ExtensionContext) { const telemetryReporter = loadDefaultTelemetryReporter(); context.subscriptions.push(telemetryReporter); - const contributions = getMarkdownExtensionContributions(); + const contributions = getMarkdownExtensionContributions(context); const cspArbiter = new ExtensionContentSecurityPolicyArbiter(context.globalState, context.workspaceState); const engine = new MarkdownEngine(contributions, githubSlugifier); diff --git a/extensions/markdown-language-features/src/features/preview.ts b/extensions/markdown-language-features/src/features/preview.ts index 2f4993fa13a..f15efe24098 100644 --- a/extensions/markdown-language-features/src/features/preview.ts +++ b/extensions/markdown-language-features/src/features/preview.ts @@ -271,6 +271,14 @@ export class MarkdownPreview { this.editor.title = MarkdownPreview.getPreviewTitle(this._resource, this._locked); } + private get iconPath() { + const root = path.join(this._contributions.extensionPath, 'media'); + return { + light: vscode.Uri.file(path.join(root, 'Preview.svg')), + dark: vscode.Uri.file(path.join(root, 'Preview_inverse.svg')) + }; + } + private isPreviewOf(resource: vscode.Uri): boolean { return this._resource.fsPath === resource.fsPath; } @@ -327,6 +335,7 @@ export class MarkdownPreview { const content = await this._contentProvider.provideTextDocumentContent(document, this._previewConfigurations, this.line, this.state); if (this._resource === resource) { this.editor.title = MarkdownPreview.getPreviewTitle(this._resource, this._locked); + this.editor.iconPath = this.iconPath; this.editor.webview.options = MarkdownPreview.getWebviewOptions(resource, this._contributions); this.editor.webview.html = content; } diff --git a/extensions/markdown-language-features/src/markdownExtensions.ts b/extensions/markdown-language-features/src/markdownExtensions.ts index a9ef207cf38..55c8d76e7a4 100644 --- a/extensions/markdown-language-features/src/markdownExtensions.ts +++ b/extensions/markdown-language-features/src/markdownExtensions.ts @@ -26,6 +26,7 @@ const resolveExtensionResources = (extension: vscode.Extension, resourcePat }; export interface MarkdownContributions { + readonly extensionPath: string; readonly previewScripts: vscode.Uri[]; readonly previewStyles: vscode.Uri[]; readonly markdownItPlugins: Thenable<(md: any) => any>[]; @@ -40,6 +41,10 @@ class MarkdownExtensionContributions implements MarkdownContributions { private _loaded = false; + public constructor( + public readonly extensionPath: string, + ) { } + public get previewScripts(): vscode.Uri[] { this.ensureLoaded(); return this._scripts; @@ -111,6 +116,6 @@ class MarkdownExtensionContributions implements MarkdownContributions { } } -export function getMarkdownExtensionContributions(): MarkdownContributions { - return new MarkdownExtensionContributions(); +export function getMarkdownExtensionContributions(context: vscode.ExtensionContext): MarkdownContributions { + return new MarkdownExtensionContributions(context.extensionPath); } \ No newline at end of file diff --git a/extensions/markdown-language-features/src/test/engine.ts b/extensions/markdown-language-features/src/test/engine.ts index 860bafad7cc..a1834e057a2 100644 --- a/extensions/markdown-language-features/src/test/engine.ts +++ b/extensions/markdown-language-features/src/test/engine.ts @@ -9,6 +9,7 @@ import { MarkdownContributions } from '../markdownExtensions'; import { githubSlugifier } from '../slugify'; const emptyContributions = new class implements MarkdownContributions { + readonly extensionPath = ''; readonly previewScripts: vscode.Uri[] = []; readonly previewStyles: vscode.Uri[] = []; readonly previewResourceRoots: vscode.Uri[] = []; diff --git a/src/vs/vscode.d.ts b/src/vs/vscode.d.ts index 607f418e181..ac726df3447 100644 --- a/src/vs/vscode.d.ts +++ b/src/vs/vscode.d.ts @@ -5500,6 +5500,11 @@ declare module 'vscode' { */ title: string; + /** + * Icon for the panel shown in UI. + */ + iconPath?: Uri | { light: Uri; dark: Uri }; + /** * Webview belonging to the panel. */ diff --git a/src/vs/workbench/api/electron-browser/mainThreadWebview.ts b/src/vs/workbench/api/electron-browser/mainThreadWebview.ts index 8def9ec323a..9e36bedbf59 100644 --- a/src/vs/workbench/api/electron-browser/mainThreadWebview.ts +++ b/src/vs/workbench/api/electron-browser/mainThreadWebview.ts @@ -2,23 +2,24 @@ * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -import { IDisposable, dispose } from 'vs/base/common/lifecycle'; +import * as dom from 'vs/base/browser/dom'; +import { dispose, IDisposable } from 'vs/base/common/lifecycle'; import * as map from 'vs/base/common/map'; import URI, { UriComponents } from 'vs/base/common/uri'; import { TPromise } from 'vs/base/common/winjs.base'; import { localize } from 'vs/nls'; -import { EditorViewColumn, viewColumnToEditorGroup, editorGroupToViewColumn } from 'vs/workbench/api/shared/editor'; import { ILifecycleService } from 'vs/platform/lifecycle/common/lifecycle'; import { IOpenerService } from 'vs/platform/opener/common/opener'; import { ExtHostContext, ExtHostWebviewsShape, IExtHostContext, MainContext, MainThreadWebviewsShape, WebviewPanelHandle } from 'vs/workbench/api/node/extHost.protocol'; +import { editorGroupToViewColumn, EditorViewColumn, viewColumnToEditorGroup } from 'vs/workbench/api/shared/editor'; import { WebviewEditor } from 'vs/workbench/parts/webview/electron-browser/webviewEditor'; import { WebviewEditorInput } from 'vs/workbench/parts/webview/electron-browser/webviewEditorInput'; -import { IWebviewEditorService, WebviewInputOptions, WebviewReviver, ICreateWebViewShowOptions } from 'vs/workbench/parts/webview/electron-browser/webviewEditorService'; +import { ICreateWebViewShowOptions, IWebviewEditorService, WebviewInputOptions, WebviewReviver } from 'vs/workbench/parts/webview/electron-browser/webviewEditorService'; import { IEditorService } from 'vs/workbench/services/editor/common/editorService'; import { IExtensionService } from 'vs/workbench/services/extensions/common/extensions'; import { IEditorGroupsService } from 'vs/workbench/services/group/common/editorGroupsService'; -import { extHostNamedCustomer } from './extHostCustomers'; import * as vscode from 'vscode'; +import { extHostNamedCustomer } from './extHostCustomers'; @extHostNamedCustomer(MainContext.MainThreadWebviews) export class MainThreadWebviews implements MainThreadWebviewsShape, WebviewReviver { @@ -29,6 +30,39 @@ export class MainThreadWebviews implements MainThreadWebviewsShape, WebviewReviv private static revivalPool = 0; + private static _styleElement?: HTMLStyleElement; + + private static _icons = new Map(); + + private static updateStyleElement( + webview: WebviewEditorInput, + iconPath: { light: URI, dark: URI } | undefined + ) { + const id = webview.getId(); + if (!this._styleElement) { + this._styleElement = dom.createStyleSheet(); + this._styleElement.className = 'webview-icons'; + } + + if (!iconPath) { + this._icons.delete(id); + } else { + this._icons.set(id, iconPath); + } + + const cssRules: string[] = []; + this._icons.forEach((value, key) => { + const webviewSelector = `.show-file-icons .webview-${key}-name-file-icon::before`; + if (URI.isUri(value)) { + cssRules.push(`${webviewSelector} { content: ""; background-image: url(${value.toString()}); }`); + } else { + cssRules.push(`${webviewSelector} { content: ""; background-image: url(${value.light.toString()}); }`); + cssRules.push(`.vs-dark ${webviewSelector} { content: ""; background-image: url(${value.dark.toString()}); }`); + } + }); + this._styleElement.innerHTML = cssRules.join('\n'); + } + private _toDispose: IDisposable[] = []; private readonly _proxy: ExtHostWebviewsShape; @@ -96,6 +130,11 @@ export class MainThreadWebviews implements MainThreadWebviewsShape, WebviewReviv webview.setName(value); } + public $setIconPath(handle: WebviewPanelHandle, value: { light: UriComponents, dark: UriComponents } | undefined): void { + const webview = this.getWebview(handle); + MainThreadWebviews.updateStyleElement(webview, reviveWebviewIcon(value)); + } + public $setHtml(handle: WebviewPanelHandle, value: string): void { const webview = this.getWebview(handle); webview.html = value; @@ -185,9 +224,16 @@ export class MainThreadWebviews implements MainThreadWebviewsShape, WebviewReviv onDidClickLink: uri => this.onDidClickLink(handle, uri), onMessage: message => this._proxy.$onMessage(handle, message), onDispose: () => { + const cleanUp = () => { + const webview = this._webviews.get(handle); + if (webview) { + MainThreadWebviews.updateStyleElement(webview, undefined); + } + this._webviews.delete(handle); + }; this._proxy.$onDidDisposeWebviewPanel(handle).then( - () => this._webviews.delete(handle), - () => this._webviews.delete(handle)); + cleanUp, + cleanUp); } }; } @@ -297,3 +343,16 @@ function reviveWebviewOptions(options: WebviewInputOptions): WebviewInputOptions localResourceRoots: Array.isArray(options.localResourceRoots) ? options.localResourceRoots.map(URI.revive) : undefined }; } + +function reviveWebviewIcon( + value: { light: UriComponents, dark: UriComponents } | undefined +): { light: URI, dark: URI } | undefined { + if (!value) { + return undefined; + } + + return { + light: URI.revive(value.light), + dark: URI.revive(value.dark) + }; +} \ No newline at end of file diff --git a/src/vs/workbench/api/node/extHost.protocol.ts b/src/vs/workbench/api/node/extHost.protocol.ts index 44947586fd5..dcccdfd0bf9 100644 --- a/src/vs/workbench/api/node/extHost.protocol.ts +++ b/src/vs/workbench/api/node/extHost.protocol.ts @@ -430,6 +430,7 @@ export interface MainThreadWebviewsShape extends IDisposable { $disposeWebview(handle: WebviewPanelHandle): void; $reveal(handle: WebviewPanelHandle, viewColumn: EditorViewColumn | null, preserveFocus: boolean): void; $setTitle(handle: WebviewPanelHandle, value: string): void; + $setIconPath(handle: WebviewPanelHandle, value: { light: UriComponents, dark: UriComponents } | undefined): void; $setHtml(handle: WebviewPanelHandle, value: string): void; $setOptions(handle: WebviewPanelHandle, options: vscode.WebviewOptions): void; $postMessage(handle: WebviewPanelHandle, value: any): Thenable; diff --git a/src/vs/workbench/api/node/extHostWebview.ts b/src/vs/workbench/api/node/extHostWebview.ts index 0ad6b97fa30..78fb98240ea 100644 --- a/src/vs/workbench/api/node/extHostWebview.ts +++ b/src/vs/workbench/api/node/extHostWebview.ts @@ -3,14 +3,17 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -import { MainContext, MainThreadWebviewsShape, IMainContext, ExtHostWebviewsShape, WebviewPanelHandle, WebviewPanelViewState } from './extHost.protocol'; -import * as vscode from 'vscode'; -import { Event, Emitter } from 'vs/base/common/event'; +import { Emitter, Event } from 'vs/base/common/event'; +import URI from 'vs/base/common/uri'; +import { TPromise } from 'vs/base/common/winjs.base'; import * as typeConverters from 'vs/workbench/api/node/extHostTypeConverters'; import { EditorViewColumn } from 'vs/workbench/api/shared/editor'; -import { TPromise } from 'vs/base/common/winjs.base'; +import * as vscode from 'vscode'; +import { ExtHostWebviewsShape, IMainContext, MainContext, MainThreadWebviewsShape, WebviewPanelHandle, WebviewPanelViewState } from './extHost.protocol'; import { Disposable } from './extHostTypes'; -import URI from 'vs/base/common/uri'; + + +type IconPath = URI | { light: URI, dark: URI }; export class ExtHostWebview implements vscode.Webview { private readonly _handle: WebviewPanelHandle; @@ -78,6 +81,7 @@ export class ExtHostWebviewPanel implements vscode.WebviewPanel { private readonly _proxy: MainThreadWebviewsShape; private readonly _viewType: string; private _title: string; + private _iconPath: IconPath; private readonly _options: vscode.WebviewPanelOptions; private readonly _webview: ExtHostWebview; @@ -150,6 +154,20 @@ export class ExtHostWebviewPanel implements vscode.WebviewPanel { } } + get iconPath(): IconPath | undefined { + this.assertNotDisposed(); + return this._iconPath; + } + + set iconPath(value: IconPath | undefined) { + this.assertNotDisposed(); + if (this._iconPath !== value) { + this._iconPath = value; + + this._proxy.$setIconPath(this._handle, URI.isUri(value) ? { light: value, dark: value } : value); + } + } + get options() { return this._options; } diff --git a/src/vs/workbench/parts/webview/electron-browser/webviewEditor.ts b/src/vs/workbench/parts/webview/electron-browser/webviewEditor.ts index 82252859c77..8eb67ef6b68 100644 --- a/src/vs/workbench/parts/webview/electron-browser/webviewEditor.ts +++ b/src/vs/workbench/parts/webview/electron-browser/webviewEditor.ts @@ -5,6 +5,7 @@ import * as DOM from 'vs/base/browser/dom'; import { domEvent } from 'vs/base/browser/event'; +import { CancellationToken } from 'vs/base/common/cancellation'; import { Emitter, Event } from 'vs/base/common/event'; import { IDisposable } from 'vs/base/common/lifecycle'; import URI from 'vs/base/common/uri'; @@ -14,13 +15,12 @@ import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry'; import { IThemeService } from 'vs/platform/theme/common/themeService'; import { IWorkspaceContextService } from 'vs/platform/workspace/common/workspace'; import { EditorOptions } from 'vs/workbench/common/editor'; -import { IEditorGroup } from 'vs/workbench/services/group/common/editorGroupsService'; import { WebviewEditorInput } from 'vs/workbench/parts/webview/electron-browser/webviewEditorInput'; import { IEditorService } from 'vs/workbench/services/editor/common/editorService'; +import { IEditorGroup } from 'vs/workbench/services/group/common/editorGroupsService'; import { IPartService, Parts } from 'vs/workbench/services/part/common/partService'; import { BaseWebviewEditor, KEYBINDING_CONTEXT_WEBVIEWEDITOR_FIND_WIDGET_INPUT_FOCUSED, KEYBINDING_CONTEXT_WEBVIEWEDITOR_FOCUS, KEYBINDING_CONTEXT_WEBVIEW_FIND_WIDGET_VISIBLE } from './baseWebviewEditor'; import { WebviewElement } from './webviewElement'; -import { CancellationToken } from 'vs/base/common/cancellation'; export class WebviewEditor extends BaseWebviewEditor { diff --git a/src/vs/workbench/parts/webview/electron-browser/webviewEditorInput.ts b/src/vs/workbench/parts/webview/electron-browser/webviewEditorInput.ts index 6d48bf36101..07f44326ef7 100644 --- a/src/vs/workbench/parts/webview/electron-browser/webviewEditorInput.ts +++ b/src/vs/workbench/parts/webview/electron-browser/webviewEditorInput.ts @@ -3,15 +3,16 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -import { IDisposable, dispose } from 'vs/base/common/lifecycle'; +import { Emitter } from 'vs/base/common/event'; +import { dispose, IDisposable } from 'vs/base/common/lifecycle'; import URI from 'vs/base/common/uri'; import { TPromise } from 'vs/base/common/winjs.base'; import { IEditorModel } from 'vs/platform/editor/common/editor'; -import { EditorInput, EditorModel, IEditorInput, GroupIdentifier } from 'vs/workbench/common/editor'; +import { EditorInput, EditorModel, GroupIdentifier, IEditorInput } from 'vs/workbench/common/editor'; import { IPartService, Parts } from 'vs/workbench/services/part/common/partService'; +import * as vscode from 'vscode'; import { WebviewEvents, WebviewInputOptions, WebviewReviver } from './webviewEditorService'; import { WebviewElement } from './webviewElement'; -import * as vscode from 'vscode'; export class WebviewEditorInput extends EditorInput { private static handlePool = 0; @@ -35,6 +36,7 @@ export class WebviewEditorInput extends EditorInput { private _revived: boolean = false; public readonly extensionLocation: URI | undefined; + private readonly _id: number; constructor( public readonly viewType: string, @@ -47,6 +49,7 @@ export class WebviewEditorInput extends EditorInput { @IPartService private readonly _partService: IPartService, ) { super(); + this._id = WebviewEditorInput.handlePool++; this._name = name; this._options = options; this._events = events; @@ -58,6 +61,13 @@ export class WebviewEditorInput extends EditorInput { return WebviewEditorInput.typeId; } + public getId(): number { + return this._id; + } + + private readonly _onDidChangeIcon = this._register(new Emitter()); + public readonly onDidChangeIcon = this._onDidChangeIcon.event; + public dispose() { this.disposeWebview(); @@ -76,7 +86,10 @@ export class WebviewEditorInput extends EditorInput { } public getResource(): URI { - return null; + return URI.from({ + scheme: 'webview-panel', + path: `webview-panel/webview-${this._id}` + }); } public getName(): string { @@ -169,9 +182,8 @@ export class WebviewEditorInput extends EditorInput { public get container(): HTMLElement { if (!this._container) { - const id = WebviewEditorInput.handlePool++; this._container = document.createElement('div'); - this._container.id = `webview-${id}`; + this._container.id = `webview-${this._id}`; this._partService.getContainer(Parts.EDITOR_PART).appendChild(this._container); } return this._container; From 8e92f803c8ad9302f4aa3da26490cf6b856af9ea Mon Sep 17 00:00:00 2001 From: Ramya Achutha Rao Date: Tue, 24 Jul 2018 15:20:22 -0700 Subject: [PATCH 0068/1276] Remove unused variable --- .../telemetry/common/telemetryService.ts | 3 +-- .../electron-browser/telemetryService.test.ts | 26 ++----------------- 2 files changed, 3 insertions(+), 26 deletions(-) diff --git a/src/vs/platform/telemetry/common/telemetryService.ts b/src/vs/platform/telemetry/common/telemetryService.ts index dba27cde4b1..0b8470198a3 100644 --- a/src/vs/platform/telemetry/common/telemetryService.ts +++ b/src/vs/platform/telemetry/common/telemetryService.ts @@ -21,7 +21,6 @@ export interface ITelemetryServiceConfig { appender: ITelemetryAppender; commonProperties?: TPromise<{ [name: string]: any }>; piiPaths?: string[]; - userOptIn?: boolean; } export class TelemetryService implements ITelemetryService { @@ -46,7 +45,7 @@ export class TelemetryService implements ITelemetryService { this._appender = config.appender; this._commonProperties = config.commonProperties || TPromise.as({}); this._piiPaths = config.piiPaths || []; - this._userOptIn = typeof config.userOptIn === 'undefined' ? true : config.userOptIn; + this._userOptIn = true; // static cleanup pattern for: `file:///DANGEROUS/PATH/resources/app/Useful/Information` this._cleanupPatterns = [/file:\/\/\/.*?\/resources\/app\//gi]; diff --git a/src/vs/platform/telemetry/test/electron-browser/telemetryService.test.ts b/src/vs/platform/telemetry/test/electron-browser/telemetryService.test.ts index 83ff1f5b7a8..8cd91f0803b 100644 --- a/src/vs/platform/telemetry/test/electron-browser/telemetryService.test.ts +++ b/src/vs/platform/telemetry/test/electron-browser/telemetryService.test.ts @@ -14,8 +14,6 @@ import * as Errors from 'vs/base/common/errors'; import * as sinon from 'sinon'; import { getConfigurationValue } from 'vs/platform/configuration/common/configuration'; -const optInStatusEventName: string = 'optInStatus'; - class TestTelemetryAppender implements ITelemetryAppender { public events: any[]; @@ -719,29 +717,9 @@ suite('TelemetryService', () => { } })); - test('Telemetry Service respects user opt-in settings', sinon.test(function () { + test('Telemetry Service sends events when enableTelemetry is on', sinon.test(function () { let testAppender = new TestTelemetryAppender(); - let service = new TelemetryService({ userOptIn: false, appender: testAppender }, undefined); - - return service.publicLog('testEvent').then(() => { - assert.equal(testAppender.getEventsCount(), 0); - service.dispose(); - }); - })); - - test('Telemetry Service does not sent optInStatus when user opted out', sinon.test(function () { - let testAppender = new TestTelemetryAppender(); - let service = new TelemetryService({ userOptIn: false, appender: testAppender }, undefined); - - return service.publicLog(optInStatusEventName, { optIn: false }).then(() => { - assert.equal(testAppender.getEventsCount(), 0); - service.dispose(); - }); - })); - - test('Telemetry Service sends events when enableTelemetry is on even user optin is on', sinon.test(function () { - let testAppender = new TestTelemetryAppender(); - let service = new TelemetryService({ userOptIn: true, appender: testAppender }, undefined); + let service = new TelemetryService({ appender: testAppender }, undefined); return service.publicLog('testEvent').then(() => { assert.equal(testAppender.getEventsCount(), 1); From 0d2ac78d26e864c22a9e7ea2d9099c6725a48e4d Mon Sep 17 00:00:00 2001 From: Rob Lourens Date: Tue, 24 Jul 2018 15:49:34 -0700 Subject: [PATCH 0069/1276] Settings editor - use lighter color for headings and active TOC item --- .../browser/media/settingsEditor2.css | 61 +++++--- .../preferences/browser/settingsEditor2.ts | 92 ++++-------- .../parts/preferences/browser/settingsTree.ts | 135 +++++++++++++++--- 3 files changed, 178 insertions(+), 110 deletions(-) diff --git a/src/vs/workbench/parts/preferences/browser/media/settingsEditor2.css b/src/vs/workbench/parts/preferences/browser/media/settingsEditor2.css index bdffa1c3f9e..4301d35c32f 100644 --- a/src/vs/workbench/parts/preferences/browser/media/settingsEditor2.css +++ b/src/vs/workbench/parts/preferences/browser/media/settingsEditor2.css @@ -8,16 +8,14 @@ } .settings-editor { - padding-top: 11px; - padding-left: 5px; - max-width: 1100px; + padding: 11px 0px 24px 0px; + max-width: 1000px; margin: auto; } /* header styling */ .settings-editor > .settings-header { - padding-left: 17px; - padding-right: 11px; + padding-right: 24px; box-sizing: border-box; margin: auto; } @@ -55,17 +53,25 @@ .settings-editor > .settings-header .search-container > .settings-search-input > .monaco-inputbox .input { font-size: 14px; - padding-left: 10px; + padding-left: 9px; } .settings-editor > .settings-header > .settings-header-controls { - height: 27px; + height: 29px; display: flex; - border-bottom: solid #3c3c3c 1px; + border-bottom: solid 1px; } -.settings-editor > .settings-header .settings-tabs-widget > .monaco-action-bar .action-item:not(:first-child) .action-label { - margin-left: 14px; +.vs .settings-editor > .settings-header > .settings-header-controls { + color: #6c6c6c; +} + +.vs-dark .settings-editor > .settings-header > .settings-header-controls { + color: #3c3c3c; +} + +.settings-editor > .settings-header .settings-tabs-widget > .monaco-action-bar .action-item .action-label { + margin-right: 0px; } .settings-editor > .settings-header .settings-tabs-widget .monaco-action-bar .action-item .dropdown-icon { @@ -75,7 +81,7 @@ .settings-editor > .settings-header > .settings-header-controls .settings-header-controls-right { margin-left: auto; - padding-top: 3px; + padding-top: 4px; display: flex; } @@ -122,16 +128,16 @@ text-transform: none; font-size: 13px; - padding-bottom: 3px; - padding-top: 6px; - padding-left: 8px; - padding-right: 8px; + padding-bottom: 4px; + padding-top: 7px; + padding-left: 9px; + padding-right: 9px; } .settings-editor > .settings-body { display: flex; margin: auto; - max-width: 1100px; + max-width: 1000px; justify-content: space-between; } @@ -141,14 +147,13 @@ .settings-editor > .settings-body .settings-tree-container .monaco-tree-wrapper, .settings-editor > .settings-body > .settings-tree-container .setting-measure-container { - /** Allocate space for the scrollbar */ - width: calc(100% - 11px) + /** Match header padding, leave room for scrollbar on the outside */ + width: calc(100% - 24px) } .settings-editor > .settings-body .settings-toc-container { - width: 175px; - margin-right: 5px; + width: 160px; padding-top: 8px; box-sizing: border-box; } @@ -177,15 +182,29 @@ overflow: hidden; text-overflow: ellipsis; line-height: 22px; + opacity: 0.7; +} + +.settings-editor > .settings-body .settings-toc-container .monaco-tree-row.has-children > .content:before { + opacity: 0.7; +} + +.settings-editor > .settings-body .settings-toc-container .monaco-tree-row.has-children.selected > .content:before { + opacity: 1; } .settings-editor > .settings-body .settings-toc-container .monaco-tree-row .settings-toc-entry.no-results { opacity: 0.5; } +.settings-editor > .settings-body .settings-toc-container .monaco-tree-row.selected .settings-toc-entry { + font-weight: bold; + opacity: 1; +} + .settings-editor > .settings-body .settings-tree-container { flex: 1; - max-width: 875px; + max-width: 792px; margin-right: 1px; /* So the item doesn't blend into the edge of the view container */ padding-top: 8px; box-sizing: border-box; diff --git a/src/vs/workbench/parts/preferences/browser/settingsEditor2.ts b/src/vs/workbench/parts/preferences/browser/settingsEditor2.ts index 7fe7a471b59..161504cd879 100644 --- a/src/vs/workbench/parts/preferences/browser/settingsEditor2.ts +++ b/src/vs/workbench/parts/preferences/browser/settingsEditor2.ts @@ -11,12 +11,11 @@ import * as arrays from 'vs/base/common/arrays'; import { Delayer, ThrottledDelayer } from 'vs/base/common/async'; import { CancellationToken } from 'vs/base/common/cancellation'; import * as collections from 'vs/base/common/collections'; -import { Color, RGBA } from 'vs/base/common/color'; import { getErrorMessage, isPromiseCanceledError } from 'vs/base/common/errors'; import URI from 'vs/base/common/uri'; import { TPromise } from 'vs/base/common/winjs.base'; import { ITree, ITreeConfiguration } from 'vs/base/parts/tree/browser/tree'; -import { DefaultTreestyler, OpenMode } from 'vs/base/parts/tree/browser/treeDefaults'; +import { OpenMode, DefaultTreestyler } from 'vs/base/parts/tree/browser/treeDefaults'; import 'vs/css!./media/settingsEditor2'; import { localize } from 'vs/nls'; import { ConfigurationTarget, IConfigurationOverrides, IConfigurationService } from 'vs/platform/configuration/common/configuration'; @@ -27,28 +26,22 @@ import { IInstantiationService } from 'vs/platform/instantiation/common/instanti import { WorkbenchTree, WorkbenchTreeController } from 'vs/platform/list/browser/listService'; import { ILogService } from 'vs/platform/log/common/log'; import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry'; -import { editorBackground, focusBorder, foreground, registerColor } from 'vs/platform/theme/common/colorRegistry'; import { attachButtonStyler, attachStyler } from 'vs/platform/theme/common/styler'; -import { ICssStyleCollector, ITheme, IThemeService, registerThemingParticipant } from 'vs/platform/theme/common/themeService'; +import { IThemeService } from 'vs/platform/theme/common/themeService'; import { BaseEditor } from 'vs/workbench/browser/parts/editor/baseEditor'; import { EditorOptions, IEditor } from 'vs/workbench/common/editor'; import { SearchWidget, SettingsTarget, SettingsTargetsWidget } from 'vs/workbench/parts/preferences/browser/preferencesWidgets'; import { commonlyUsedData, tocData } from 'vs/workbench/parts/preferences/browser/settingsLayout'; -import { ISettingsEditorViewState, NonExpandableTree, resolveExtensionsSettings, resolveSettingsTree, SearchResultIdx, SearchResultModel, SettingsAccessibilityProvider, SettingsDataSource, SettingsRenderer, SettingsTreeController, SettingsTreeElement, SettingsTreeFilter, SettingsTreeGroupElement, SettingsTreeModel, SettingsTreeSettingElement } from 'vs/workbench/parts/preferences/browser/settingsTree'; +import { ISettingsEditorViewState, resolveExtensionsSettings, resolveSettingsTree, SearchResultIdx, SearchResultModel, SettingsRenderer, SettingsTree, SettingsTreeElement, SettingsTreeFilter, SettingsTreeGroupElement, SettingsTreeModel, SettingsTreeSettingElement, settingsHeaderForeground } from 'vs/workbench/parts/preferences/browser/settingsTree'; import { TOCDataSource, TOCRenderer, TOCTreeModel } from 'vs/workbench/parts/preferences/browser/tocTree'; import { CONTEXT_SETTINGS_EDITOR, CONTEXT_SETTINGS_FIRST_ROW_FOCUS, CONTEXT_SETTINGS_ROW_FOCUS, CONTEXT_SETTINGS_SEARCH_FOCUS, CONTEXT_TOC_ROW_FOCUS, IPreferencesSearchService, ISearchProvider } from 'vs/workbench/parts/preferences/common/preferences'; import { IPreferencesService, ISearchResult, ISettingsEditorModel } from 'vs/workbench/services/preferences/common/preferences'; import { SettingsEditor2Input } from 'vs/workbench/services/preferences/common/preferencesEditorInput'; import { DefaultSettingsEditorModel } from 'vs/workbench/services/preferences/common/preferencesModels'; +import { editorBackground, foreground } from 'vs/platform/theme/common/colorRegistry'; const $ = DOM.$; -export const settingItemInactiveSelectionBorder = registerColor('settings.inactiveSelectedItemBorder', { - dark: '#3F3F46', - light: '#CCCEDB', - hc: null -}, localize('settingItemInactiveSelectionBorder', "The color of the selected setting row border, when the settings list does not have focus.")); - export class SettingsEditor2 extends BaseEditor { public static readonly ID: string = 'workbench.editor.settings2'; @@ -63,7 +56,6 @@ export class SettingsEditor2 extends BaseEditor { private settingsTreeContainer: HTMLElement; private settingsTree: WorkbenchTree; - private treeDataSource: SettingsDataSource; private tocTreeModel: TOCTreeModel; private settingsTreeModel: SettingsTreeModel; @@ -282,12 +274,29 @@ export class SettingsEditor2 extends BaseEditor { dataSource: tocDataSource, renderer: tocRenderer, controller: this.instantiationService.createInstance(WorkbenchTreeController, { openMode: OpenMode.DOUBLE_CLICK }), - filter: this.instantiationService.createInstance(SettingsTreeFilter, this.viewState) + filter: this.instantiationService.createInstance(SettingsTreeFilter, this.viewState), + styler: new DefaultTreestyler(DOM.createStyleSheet(), 'settings-toc-tree'), }, { showLoading: false, twistiePixels: 15 }); + this.tocTree.getHTMLElement().classList.add('settings-toc-tree'); + + this._register(attachStyler(this.themeService, { + listActiveSelectionBackground: editorBackground, + listActiveSelectionForeground: settingsHeaderForeground, + listFocusAndSelectionBackground: editorBackground, + listFocusAndSelectionForeground: settingsHeaderForeground, + listFocusBackground: editorBackground, + listFocusForeground: settingsHeaderForeground, + listHoverForeground: foreground, + listHoverBackground: editorBackground, + listInactiveSelectionBackground: editorBackground, + listInactiveSelectionForeground: settingsHeaderForeground, + }, colors => { + this.tocTree.style(colors); + })); this._register(this.tocTree.onDidChangeFocus(e => { const element = e.focus; @@ -301,7 +310,6 @@ export class SettingsEditor2 extends BaseEditor { this.settingsTree.setFocus(element); } } - })); this._register(this.tocTree.onDidFocus(() => { @@ -323,66 +331,18 @@ export class SettingsEditor2 extends BaseEditor { private createSettingsTree(parent: HTMLElement): void { this.settingsTreeContainer = DOM.append(parent, $('.settings-tree-container')); - this.treeDataSource = this.instantiationService.createInstance(SettingsDataSource, this.viewState); const renderer = this.instantiationService.createInstance(SettingsRenderer, this.settingsTreeContainer); this._register(renderer.onDidChangeSetting(e => this.onDidChangeSetting(e.key, e.value))); this._register(renderer.onDidOpenSettings(() => this.openSettingsFile())); this._register(renderer.onDidClickSettingLink(settingName => this.revealSetting(settingName))); - const treeClass = 'settings-editor-tree'; - this.settingsTree = this.instantiationService.createInstance(NonExpandableTree, this.settingsTreeContainer, - { - dataSource: this.treeDataSource, - renderer, - controller: this.instantiationService.createInstance(SettingsTreeController), - accessibilityProvider: this.instantiationService.createInstance(SettingsAccessibilityProvider), - filter: this.instantiationService.createInstance(SettingsTreeFilter, this.viewState), - styler: new DefaultTreestyler(DOM.createStyleSheet(), treeClass) - }, + this.settingsTree = this.instantiationService.createInstance(SettingsTree, + this.settingsTreeContainer, + this.viewState, { - ariaLabel: localize('treeAriaLabel', "Settings"), - showLoading: false, - indentPixels: 0, - twistiePixels: 0, + renderer }); - this._register(registerThemingParticipant((theme: ITheme, collector: ICssStyleCollector) => { - const activeBorderColor = theme.getColor(focusBorder); - if (activeBorderColor) { - collector.addRule(`.settings-editor > .settings-body > .settings-tree-container .monaco-tree:focus .monaco-tree-row.focused {outline: solid 1px ${activeBorderColor}; outline-offset: -1px; }`); - } - - const inactiveBorderColor = theme.getColor(settingItemInactiveSelectionBorder); - if (inactiveBorderColor) { - collector.addRule(`.settings-editor > .settings-body > .settings-tree-container .monaco-tree .monaco-tree-row.focused {outline: solid 1px ${inactiveBorderColor}; outline-offset: -1px; }`); - } - - const foregroundColor = theme.getColor(foreground); - if (foregroundColor) { - // Links appear inside other elements in markdown. CSS opacity acts like a mask. So we have to dynamically compute the description color to avoid - // applying an opacity to the link color. - const fgWithOpacity = new Color(new RGBA(foregroundColor.rgba.r, foregroundColor.rgba.g, foregroundColor.rgba.b, .7)); - collector.addRule(`.settings-editor > .settings-body > .settings-tree-container .setting-item .setting-item-description { color: ${fgWithOpacity}; }`); - } - })); - - this.settingsTree.getHTMLElement().classList.add(treeClass); - - this._register(attachStyler(this.themeService, { - listActiveSelectionBackground: editorBackground, - listActiveSelectionForeground: foreground, - listFocusAndSelectionBackground: editorBackground, - listFocusAndSelectionForeground: foreground, - listFocusBackground: editorBackground, - listFocusForeground: foreground, - listHoverForeground: foreground, - listHoverBackground: editorBackground, - listInactiveSelectionBackground: editorBackground, - listInactiveSelectionForeground: foreground - }, colors => { - this.settingsTree.style(colors); - })); - this._register(this.settingsTree.onDidChangeFocus(e => { this.settingsTree.setSelection([e.focus]); if (this.selectedElement) { diff --git a/src/vs/workbench/parts/preferences/browser/settingsTree.ts b/src/vs/workbench/parts/preferences/browser/settingsTree.ts index a43b504ff51..195b722de7d 100644 --- a/src/vs/workbench/parts/preferences/browser/settingsTree.ts +++ b/src/vs/workbench/parts/preferences/browser/settingsTree.ts @@ -12,6 +12,7 @@ import { Checkbox } from 'vs/base/browser/ui/checkbox/checkbox'; import { InputBox } from 'vs/base/browser/ui/inputbox/inputBox'; import { SelectBox } from 'vs/base/browser/ui/selectBox/selectBox'; import * as arrays from 'vs/base/common/arrays'; +import { Color, RGBA } from 'vs/base/common/color'; import { onUnexpectedError } from 'vs/base/common/errors'; import { Emitter, Event } from 'vs/base/common/event'; import { KeyCode } from 'vs/base/common/keyCodes'; @@ -20,47 +21,47 @@ import * as objects from 'vs/base/common/objects'; import { escapeRegExpCharacters, startsWith } from 'vs/base/common/strings'; import URI from 'vs/base/common/uri'; import { TPromise } from 'vs/base/common/winjs.base'; -import { IAccessibilityProvider, IDataSource, IFilter, ITree, IRenderer } from 'vs/base/parts/tree/browser/tree'; +import { IAccessibilityProvider, IDataSource, IFilter, IRenderer, ITree, ITreeConfiguration } from 'vs/base/parts/tree/browser/tree'; +import { DefaultTreestyler } from 'vs/base/parts/tree/browser/treeDefaults'; import { localize } from 'vs/nls'; import { ConfigurationTarget, IConfigurationService } from 'vs/platform/configuration/common/configuration'; +import { IContextKeyService } from 'vs/platform/contextkey/common/contextkey'; import { IContextViewService } from 'vs/platform/contextview/browser/contextView'; -import { WorkbenchTree, WorkbenchTreeController } from 'vs/platform/list/browser/listService'; +import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; +import { IListService, WorkbenchTree, WorkbenchTreeController } from 'vs/platform/list/browser/listService'; import { IOpenerService } from 'vs/platform/opener/common/opener'; -import { inputBackground, inputBorder, inputForeground, registerColor, selectBackground, selectBorder, selectForeground, textLinkForeground } from 'vs/platform/theme/common/colorRegistry'; -import { attachInputBoxStyler, attachSelectBoxStyler, attachButtonStyler } from 'vs/platform/theme/common/styler'; +import { editorBackground, focusBorder, foreground, inputBackground, inputBorder, inputForeground, registerColor, selectBackground, selectBorder, selectForeground, textLinkForeground } from 'vs/platform/theme/common/colorRegistry'; +import { attachButtonStyler, attachInputBoxStyler, attachSelectBoxStyler, attachStyler } from 'vs/platform/theme/common/styler'; import { ICssStyleCollector, ITheme, IThemeService, registerThemingParticipant } from 'vs/platform/theme/common/themeService'; import { SettingsTarget } from 'vs/workbench/parts/preferences/browser/preferencesWidgets'; import { ITOCEntry } from 'vs/workbench/parts/preferences/browser/settingsLayout'; import { ISearchResult, ISetting, ISettingsGroup } from 'vs/workbench/services/preferences/common/preferences'; -import { Color } from 'vs/base/common/color'; const $ = DOM.$; -export const modifiedItemForeground = registerColor('settings.modifiedItemForeground', { - light: '#019001', - dark: '#73C991', - hc: '#73C991' -}, localize('modifiedItemForeground', "(For settings editor preview) The foreground color for a modified setting.")); +export const settingsHeaderForeground = registerColor('settings.headerForeground', { light: '#444444', dark: '#e7e7e7', hc: '#ffffff' }, localize('headerForeground', "(For settings editor preview) The foreground color for a section header/title.")); +export const modifiedItemForeground = registerColor('settings.modifiedItemForeground', { light: '#019001', dark: '#73C991', hc: '#73C991' }, localize('modifiedItemForeground', "(For settings editor preview) The foreground color for a modified setting.")); +export const settingItemInactiveSelectionBorder = registerColor('settings.inactiveSelectedItemBorder', { dark: '#3F3F46', light: '#CCCEDB', hc: null }, localize('settingItemInactiveSelectionBorder', "(For settings editor preview) The color of the selected setting row border, when the settings list does not have focus.")); // Enum control colors -export const settingsSelectBackground = registerColor('settings.dropdownBackground', { dark: selectBackground, light: selectBackground, hc: selectBackground }, localize('settingsDropdownBackground', "Settings editor dropdown background.")); -export const settingsSelectForeground = registerColor('settings.dropdownForeground', { dark: selectForeground, light: selectForeground, hc: selectForeground }, localize('settingsDropdownForeground', "Settings editor dropdown foreground.")); -export const settingsSelectBorder = registerColor('settings.dropdownBorder', { dark: selectBorder, light: selectBorder, hc: selectBorder }, localize('settingsDropdownBorder', "Settings editor dropdown border.")); +export const settingsSelectBackground = registerColor('settings.dropdownBackground', { dark: selectBackground, light: selectBackground, hc: selectBackground }, localize('settingsDropdownBackground', "(For settings editor preview) Settings editor dropdown background.")); +export const settingsSelectForeground = registerColor('settings.dropdownForeground', { dark: selectForeground, light: selectForeground, hc: selectForeground }, localize('settingsDropdownForeground', "(For settings editor preview) Settings editor dropdown foreground.")); +export const settingsSelectBorder = registerColor('settings.dropdownBorder', { dark: selectBorder, light: selectBorder, hc: selectBorder }, localize('settingsDropdownBorder', "(For settings editor preview) Settings editor dropdown border.")); // Bool control colors -export const settingsCheckboxBackground = registerColor('settings.checkboxBackground', { dark: selectBackground, light: selectBackground, hc: selectBackground }, localize('settingsCheckboxBackground', "Settings editor checkbox background.")); -export const settingsCheckboxForeground = registerColor('settings.checkboxForeground', { dark: selectForeground, light: selectForeground, hc: selectForeground }, localize('settingsCheckboxForeground', "Settings editor checkbox foreground.")); -export const settingsCheckboxBorder = registerColor('settings.checkboxBorder', { dark: selectBorder, light: selectBorder, hc: selectBorder }, localize('settingsCheckboxBorder', "Settings editor checkbox border.")); +export const settingsCheckboxBackground = registerColor('settings.checkboxBackground', { dark: selectBackground, light: selectBackground, hc: selectBackground }, localize('settingsCheckboxBackground', "(For settings editor preview) Settings editor checkbox background.")); +export const settingsCheckboxForeground = registerColor('settings.checkboxForeground', { dark: selectForeground, light: selectForeground, hc: selectForeground }, localize('settingsCheckboxForeground', "(For settings editor preview) Settings editor checkbox foreground.")); +export const settingsCheckboxBorder = registerColor('settings.checkboxBorder', { dark: selectBorder, light: selectBorder, hc: selectBorder }, localize('settingsCheckboxBorder', "(For settings editor preview) Settings editor checkbox border.")); // Text control colors -export const settingsTextInputBackground = registerColor('settings.textInputBackground', { dark: inputBackground, light: inputBackground, hc: inputBackground }, localize('textInputBoxBackground', "Settings editor text input box background.")); -export const settingsTextInputForeground = registerColor('settings.textInputForeground', { dark: inputForeground, light: inputForeground, hc: inputForeground }, localize('textInputBoxForeground', "Settings editor text input box foreground.")); -export const settingsTextInputBorder = registerColor('settings.textInputBorder', { dark: inputBorder, light: inputBorder, hc: inputBorder }, localize('textInputBoxBorder', "Settings editor text input box border.")); +export const settingsTextInputBackground = registerColor('settings.textInputBackground', { dark: inputBackground, light: inputBackground, hc: inputBackground }, localize('textInputBoxBackground', "(For settings editor preview) Settings editor text input box background.")); +export const settingsTextInputForeground = registerColor('settings.textInputForeground', { dark: inputForeground, light: inputForeground, hc: inputForeground }, localize('textInputBoxForeground', "(For settings editor preview) Settings editor text input box foreground.")); +export const settingsTextInputBorder = registerColor('settings.textInputBorder', { dark: inputBorder, light: inputBorder, hc: inputBorder }, localize('textInputBoxBorder', "(For settings editor preview) Settings editor text input box border.")); // Number control colors -export const settingsNumberInputBackground = registerColor('settings.numberInputBackground', { dark: inputBackground, light: inputBackground, hc: inputBackground }, localize('numberInputBoxBackground', "Settings editor number input box background.")); -export const settingsNumberInputForeground = registerColor('settings.numberInputForeground', { dark: inputForeground, light: inputForeground, hc: inputForeground }, localize('numberInputBoxForeground', "Settings editor number input box foreground.")); -export const settingsNumberInputBorder = registerColor('settings.numberInputBorder', { dark: inputBorder, light: inputBorder, hc: inputBorder }, localize('numberInputBoxBorder', "Settings editor number input box border.")); +export const settingsNumberInputBackground = registerColor('settings.numberInputBackground', { dark: inputBackground, light: inputBackground, hc: inputBackground }, localize('numberInputBoxBackground', "(For settings editor preview) Settings editor number input box background.")); +export const settingsNumberInputForeground = registerColor('settings.numberInputForeground', { dark: inputForeground, light: inputForeground, hc: inputForeground }, localize('numberInputBoxForeground', "(For settings editor preview) Settings editor number input box foreground.")); +export const settingsNumberInputBorder = registerColor('settings.numberInputBorder', { dark: inputBorder, light: inputBorder, hc: inputBorder }, localize('numberInputBoxBorder', "(For settings editor preview) Settings editor number input box border.")); registerThemingParticipant((theme: ITheme, collector: ICssStyleCollector) => { const modifiedItemForegroundColor = theme.getColor(modifiedItemForeground); @@ -84,6 +85,11 @@ registerThemingParticipant((theme: ITheme, collector: ICssStyleCollector) => { collector.addRule(`.settings-editor > .settings-body > .settings-tree-container .setting-item .setting-item-description a { color: ${link}; }`); collector.addRule(`.settings-editor > .settings-body > .settings-tree-container .setting-item .setting-item-description a > code { color: ${link}; }`); } + + const headerForegroundColor = theme.getColor(settingsHeaderForeground); + if (headerForegroundColor) { + collector.addRule(`.settings-editor > .settings-header > .settings-header-controls .settings-tabs-widget .action-label.checked { color: ${headerForegroundColor}; border-bottom-color: ${headerForegroundColor} };`); + } }); export abstract class SettingsTreeElement { @@ -1157,7 +1163,7 @@ export class SearchResultModel { } } -export class NonExpandableTree extends WorkbenchTree { +class NonExpandableTree extends WorkbenchTree { expand(): TPromise { return TPromise.wrap(null); } @@ -1166,3 +1172,86 @@ export class NonExpandableTree extends WorkbenchTree { return TPromise.wrap(null); } } + +export class SettingsTree extends NonExpandableTree { + constructor( + container: HTMLElement, + viewState: ISettingsEditorViewState, + configuration: Partial, + @IContextKeyService contextKeyService: IContextKeyService, + @IListService listService: IListService, + @IThemeService themeService: IThemeService, + @IInstantiationService instantiationService: IInstantiationService, + @IConfigurationService configurationService: IConfigurationService + ) { + const treeClass = 'settings-editor-tree'; + + const fullConfiguration = { + dataSource: instantiationService.createInstance(SettingsDataSource, viewState), + controller: instantiationService.createInstance(SettingsTreeController), + accessibilityProvider: instantiationService.createInstance(SettingsAccessibilityProvider), + filter: instantiationService.createInstance(SettingsTreeFilter, viewState), + styler: new DefaultTreestyler(DOM.createStyleSheet(), treeClass), + + ...configuration + }; + + const options = { + ariaLabel: localize('treeAriaLabel', "Settings"), + showLoading: false, + indentPixels: 0, + twistiePixels: 0, + }; + + super(container, + fullConfiguration, + options, + contextKeyService, + listService, + themeService, + instantiationService, + configurationService); + + this.disposables.push(registerThemingParticipant((theme: ITheme, collector: ICssStyleCollector) => { + const activeBorderColor = theme.getColor(focusBorder); + if (activeBorderColor) { + collector.addRule(`.settings-editor > .settings-body > .settings-tree-container .monaco-tree:focus .monaco-tree-row.focused {outline: solid 1px ${activeBorderColor}; outline-offset: -1px; }`); + } + + const inactiveBorderColor = theme.getColor(settingItemInactiveSelectionBorder); + if (inactiveBorderColor) { + collector.addRule(`.settings-editor > .settings-body > .settings-tree-container .monaco-tree .monaco-tree-row.focused {outline: solid 1px ${inactiveBorderColor}; outline-offset: -1px; }`); + } + + const foregroundColor = theme.getColor(foreground); + if (foregroundColor) { + // Links appear inside other elements in markdown. CSS opacity acts like a mask. So we have to dynamically compute the description color to avoid + // applying an opacity to the link color. + const fgWithOpacity = new Color(new RGBA(foregroundColor.rgba.r, foregroundColor.rgba.g, foregroundColor.rgba.b, .7)); + collector.addRule(`.settings-editor > .settings-body > .settings-tree-container .setting-item .setting-item-description { color: ${fgWithOpacity}; }`); + } + + const headerForegroundColor = theme.getColor(settingsHeaderForeground); + if (headerForegroundColor) { + collector.addRule(`.settings-editor > .settings-body > .settings-tree-container .settings-group-title-label { color: ${headerForegroundColor} };`); + } + })); + + this.getHTMLElement().classList.add(treeClass); + + this.disposables.push(attachStyler(themeService, { + listActiveSelectionBackground: editorBackground, + listActiveSelectionForeground: foreground, + listFocusAndSelectionBackground: editorBackground, + listFocusAndSelectionForeground: foreground, + listFocusBackground: editorBackground, + listFocusForeground: foreground, + listHoverForeground: foreground, + listHoverBackground: editorBackground, + listInactiveSelectionBackground: editorBackground, + listInactiveSelectionForeground: foreground + }, colors => { + this.style(colors); + })); + } +} From 36dc70b0a666582dc87c158f328dad3fdfe44e34 Mon Sep 17 00:00:00 2001 From: Jackson Kearl Date: Tue, 24 Jul 2018 16:30:07 -0700 Subject: [PATCH 0070/1276] Fix bug causing find widget to appear in extensions search box --- .../parts/extensions/electron-browser/extensionsViewlet.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/vs/workbench/parts/extensions/electron-browser/extensionsViewlet.ts b/src/vs/workbench/parts/extensions/electron-browser/extensionsViewlet.ts index 0c222ed08c5..bc834b46f36 100644 --- a/src/vs/workbench/parts/extensions/electron-browser/extensionsViewlet.ts +++ b/src/vs/workbench/parts/extensions/electron-browser/extensionsViewlet.ts @@ -65,6 +65,7 @@ import { IEditorOptions } from 'vs/editor/common/config/editorOptions'; import { Range } from 'vs/editor/common/core/range'; import { Position } from 'vs/editor/common/core/position'; import { ITextModel } from 'vs/editor/common/model'; +import { SimpleDebugEditor } from 'vs/workbench/parts/debug/electron-browser/simpleDebugEditor'; interface SearchInputEvent extends Event { target: HTMLInputElement; @@ -339,7 +340,7 @@ export class ExtensionsViewlet extends ViewContainerViewlet implements IExtensio const header = append(this.root, $('.header')); this.monacoStyleContainer = append(header, $('.monaco-container')); - this.searchBox = this.instantiationService.createInstance(CodeEditorWidget, this.monacoStyleContainer, SEARCH_INPUT_OPTIONS, { isSimpleWidget: true }); + this.searchBox = this.instantiationService.createInstance(CodeEditorWidget, this.monacoStyleContainer, SEARCH_INPUT_OPTIONS, SimpleDebugEditor.getCodeEditorWidgetOptions()); this.placeholderText = append(this.monacoStyleContainer, $('.search-placeholder', null, localize('searchExtensions', "Search Extensions in Marketplace"))); this.extensionsBox = append(this.root, $('.extensions')); From d196f242643b8dfd0f2eccdce39b96f32ad3400b Mon Sep 17 00:00:00 2001 From: Rob Lourens Date: Tue, 24 Jul 2018 16:56:52 -0700 Subject: [PATCH 0071/1276] Settings editor - fix scope tabs colors, other fixes --- .../browser/media/settingsEditor2.css | 37 +++++++++++++------ .../parts/preferences/browser/settingsTree.ts | 9 ++++- 2 files changed, 32 insertions(+), 14 deletions(-) diff --git a/src/vs/workbench/parts/preferences/browser/media/settingsEditor2.css b/src/vs/workbench/parts/preferences/browser/media/settingsEditor2.css index 4301d35c32f..a9cefe54072 100644 --- a/src/vs/workbench/parts/preferences/browser/media/settingsEditor2.css +++ b/src/vs/workbench/parts/preferences/browser/media/settingsEditor2.css @@ -8,14 +8,13 @@ } .settings-editor { - padding: 11px 0px 24px 0px; + padding: 11px 24px 0px; max-width: 1000px; margin: auto; } /* header styling */ .settings-editor > .settings-header { - padding-right: 24px; box-sizing: border-box; margin: auto; } @@ -51,9 +50,9 @@ width: 100%; } -.settings-editor > .settings-header .search-container > .settings-search-input > .monaco-inputbox .input { +.settings-editor > .settings-header .search-container .settings-search-input > .monaco-inputbox .input { font-size: 14px; - padding-left: 9px; + padding-left: 7px; } .settings-editor > .settings-header > .settings-header-controls { @@ -62,12 +61,25 @@ border-bottom: solid 1px; } +.settings-editor > .settings-header > .settings-header-controls .settings-tabs-widget .action-label { + opacity: 0.7; +} + +.settings-editor > .settings-header > .settings-header-controls .settings-tabs-widget .action-label:hover { + opacity: 1; +} + +.settings-editor > .settings-header > .settings-header-controls .settings-tabs-widget .action-label.checked { + font-weight: 500; + opacity: 1; +} + .vs .settings-editor > .settings-header > .settings-header-controls { - color: #6c6c6c; + border-color: #cccccc; } .vs-dark .settings-editor > .settings-header > .settings-header-controls { - color: #3c3c3c; + border-color: #3c3c3c; } .settings-editor > .settings-header .settings-tabs-widget > .monaco-action-bar .action-item .action-label { @@ -130,8 +142,8 @@ padding-bottom: 4px; padding-top: 7px; - padding-left: 9px; - padding-right: 9px; + padding-left: 8px; + padding-right: 8px; } .settings-editor > .settings-body { @@ -148,13 +160,14 @@ .settings-editor > .settings-body .settings-tree-container .monaco-tree-wrapper, .settings-editor > .settings-body > .settings-tree-container .setting-measure-container { /** Match header padding, leave room for scrollbar on the outside */ - width: calc(100% - 24px) + width: calc(100% - 11px); } .settings-editor > .settings-body .settings-toc-container { width: 160px; - padding-top: 8px; + padding-top: 5px; + padding-left: 5px; box-sizing: border-box; } @@ -337,8 +350,8 @@ .settings-editor > .settings-body > .settings-tree-container .group-title, .settings-editor > .settings-body > .settings-tree-container .setting-item { - padding-left: 10px; - padding-right: 10px; + padding-left: 9px; + padding-right: 9px; } .settings-editor > .settings-body > .settings-tree-container .group-title { diff --git a/src/vs/workbench/parts/preferences/browser/settingsTree.ts b/src/vs/workbench/parts/preferences/browser/settingsTree.ts index 195b722de7d..cf4195241ab 100644 --- a/src/vs/workbench/parts/preferences/browser/settingsTree.ts +++ b/src/vs/workbench/parts/preferences/browser/settingsTree.ts @@ -39,7 +39,7 @@ import { ISearchResult, ISetting, ISettingsGroup } from 'vs/workbench/services/p const $ = DOM.$; -export const settingsHeaderForeground = registerColor('settings.headerForeground', { light: '#444444', dark: '#e7e7e7', hc: '#ffffff' }, localize('headerForeground', "(For settings editor preview) The foreground color for a section header/title.")); +export const settingsHeaderForeground = registerColor('settings.headerForeground', { light: '#444444', dark: '#e7e7e7', hc: '#ffffff' }, localize('headerForeground', "(For settings editor preview) The foreground color for a section header or active title in the editor.")); export const modifiedItemForeground = registerColor('settings.modifiedItemForeground', { light: '#019001', dark: '#73C991', hc: '#73C991' }, localize('modifiedItemForeground', "(For settings editor preview) The foreground color for a modified setting.")); export const settingItemInactiveSelectionBorder = registerColor('settings.inactiveSelectedItemBorder', { dark: '#3F3F46', light: '#CCCEDB', hc: null }, localize('settingItemInactiveSelectionBorder', "(For settings editor preview) The color of the selected setting row border, when the settings list does not have focus.")); @@ -88,7 +88,12 @@ registerThemingParticipant((theme: ITheme, collector: ICssStyleCollector) => { const headerForegroundColor = theme.getColor(settingsHeaderForeground); if (headerForegroundColor) { - collector.addRule(`.settings-editor > .settings-header > .settings-header-controls .settings-tabs-widget .action-label.checked { color: ${headerForegroundColor}; border-bottom-color: ${headerForegroundColor} };`); + collector.addRule(`.settings-editor > .settings-header > .settings-header-controls .settings-tabs-widget .action-label.checked { color: ${headerForegroundColor}; border-bottom-color: ${headerForegroundColor}; }`); + } + + const foregroundColor = theme.getColor(foreground); + if (foregroundColor) { + collector.addRule(`.settings-editor > .settings-header > .settings-header-controls .settings-tabs-widget .action-label { color: ${foregroundColor}; };`); } }); From 90367c26cbd9917bc303e96158352e47f7694200 Mon Sep 17 00:00:00 2001 From: Rob Lourens Date: Tue, 24 Jul 2018 17:23:41 -0700 Subject: [PATCH 0072/1276] Settings editor - fix enumDescriptions --- src/vs/workbench/parts/preferences/browser/settingsTree.ts | 6 +++--- .../services/preferences/common/preferencesModels.ts | 3 +++ 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/src/vs/workbench/parts/preferences/browser/settingsTree.ts b/src/vs/workbench/parts/preferences/browser/settingsTree.ts index cf4195241ab..d9b878efa05 100644 --- a/src/vs/workbench/parts/preferences/browser/settingsTree.ts +++ b/src/vs/workbench/parts/preferences/browser/settingsTree.ts @@ -860,11 +860,11 @@ export class SettingsRenderer implements IRenderer { template.labelElement.title = titleTooltip; let enumDescriptionText = ''; - if (element.valueType === 'string' && element.setting.enumDescriptions && element.setting.enum && element.setting.enum.length < SettingsRenderer.MAX_ENUM_DESCRIPTIONS) { + if (element.valueType === 'enum' && element.setting.enumDescriptions && element.setting.enum && element.setting.enum.length < SettingsRenderer.MAX_ENUM_DESCRIPTIONS) { enumDescriptionText = '\n' + element.setting.enumDescriptions .map((desc, i) => desc ? - ` - \`${element.setting.enum[i]}\` : - ${desc}` : ` - \`${element.setting.enum[i]}\``) + ` - \`${element.setting.enum[i]}\`: ${desc}` : + ` - \`${element.setting.enum[i]}\``) .filter(desc => !!desc) .join('\n'); } diff --git a/src/vs/workbench/services/preferences/common/preferencesModels.ts b/src/vs/workbench/services/preferences/common/preferencesModels.ts index 62a5d8c1997..bf319ad0d53 100644 --- a/src/vs/workbench/services/preferences/common/preferencesModels.ts +++ b/src/vs/workbench/services/preferences/common/preferencesModels.ts @@ -741,6 +741,9 @@ export class DefaultSettingsEditorModel extends AbstractSettingsModel implements private copySetting(setting: ISetting): ISetting { return { description: setting.description, + type: setting.type, + enum: setting.enum, + enumDescriptions: setting.enumDescriptions, key: setting.key, value: setting.value, range: setting.range, From c3118850366fd8fee831128a5413f1e82c45be13 Mon Sep 17 00:00:00 2001 From: Jackson Kearl Date: Tue, 24 Jul 2018 18:09:46 -0700 Subject: [PATCH 0073/1276] Fix title rendering issues (ellipsis, clipping) --- src/vs/workbench/browser/parts/views/media/panelviewlet.css | 1 - .../parts/extensions/electron-browser/extensionsViews.ts | 4 ++++ .../extensions/electron-browser/media/extensionsViewlet.css | 4 ++++ 3 files changed, 8 insertions(+), 1 deletion(-) diff --git a/src/vs/workbench/browser/parts/views/media/panelviewlet.css b/src/vs/workbench/browser/parts/views/media/panelviewlet.css index 7d6c4e36d60..9691ecbdeb7 100644 --- a/src/vs/workbench/browser/parts/views/media/panelviewlet.css +++ b/src/vs/workbench/browser/parts/views/media/panelviewlet.css @@ -10,5 +10,4 @@ font-size: 11px; -webkit-margin-before: 0; -webkit-margin-after: 0; - display: flex; } diff --git a/src/vs/workbench/parts/extensions/electron-browser/extensionsViews.ts b/src/vs/workbench/parts/extensions/electron-browser/extensionsViews.ts index 02cd5b25c9f..02ba5fd8a6d 100644 --- a/src/vs/workbench/parts/extensions/electron-browser/extensionsViews.ts +++ b/src/vs/workbench/parts/extensions/electron-browser/extensionsViews.ts @@ -71,6 +71,10 @@ export class ExtensionsListView extends ViewletPanel { super({ ...(options as IViewletPanelOptions), ariaHeaderLabel: options.title }, keybindingService, contextMenuService, configurationService); } + protected renderHeader(container: HTMLElement): void { + this.renderHeaderTitle(container); + } + renderHeaderTitle(container: HTMLElement): void { super.renderHeaderTitle(container, this.options.title); diff --git a/src/vs/workbench/parts/extensions/electron-browser/media/extensionsViewlet.css b/src/vs/workbench/parts/extensions/electron-browser/media/extensionsViewlet.css index 98391d7599e..e40eed915d3 100644 --- a/src/vs/workbench/parts/extensions/electron-browser/media/extensionsViewlet.css +++ b/src/vs/workbench/parts/extensions/electron-browser/media/extensionsViewlet.css @@ -27,6 +27,10 @@ height: calc(100% - 38px); } +.extensions-viewlet > .extensions .list-actionbar-container { + margin-right: 10px; +} + .extensions-viewlet > .extensions .list-actionbar-container .monaco-action-bar .action-item > .octicon { font-size: 12px; line-height: 1; From 56a962fdf585753cd38788054988078662e7e40a Mon Sep 17 00:00:00 2001 From: Alex Dima Date: Wed, 25 Jul 2018 09:47:31 +0200 Subject: [PATCH 0074/1276] Move more menu bar registrations close to the actions --- .../editor/browser/controller/coreCommands.ts | 6 + .../linesOperations/linesOperations.ts | 25 ++++ .../editor/contrib/multicursor/multicursor.ts | 39 +++++- .../editor/contrib/smartSelect/smartSelect.ts | 13 ++ .../electron-browser/menubarRegistrations.ts | 115 ------------------ 5 files changed, 82 insertions(+), 116 deletions(-) diff --git a/src/vs/editor/browser/controller/coreCommands.ts b/src/vs/editor/browser/controller/coreCommands.ts index 083e0fd94a6..414cf185fe1 100644 --- a/src/vs/editor/browser/controller/coreCommands.ts +++ b/src/vs/editor/browser/controller/coreCommands.ts @@ -1711,6 +1711,12 @@ registerCommand(new EditorOrNativeTextInputCommand({ weight: CORE_WEIGHT, kbExpr: null, primary: KeyMod.CtrlCmd | KeyCode.KEY_A + }, + menubarOpts: { + menuId: MenuId.MenubarSelectionMenu, + group: '1_basic', + title: nls.localize({ key: 'miSelectAll', comment: ['&& denotes a mnemonic'] }, "&&Select All"), + order: 1 } })); diff --git a/src/vs/editor/contrib/linesOperations/linesOperations.ts b/src/vs/editor/contrib/linesOperations/linesOperations.ts index 4171729014e..6ec061f49ac 100644 --- a/src/vs/editor/contrib/linesOperations/linesOperations.ts +++ b/src/vs/editor/contrib/linesOperations/linesOperations.ts @@ -24,6 +24,7 @@ import { TypeOperations } from 'vs/editor/common/controller/cursorTypeOperations import { CoreEditingCommands } from 'vs/editor/browser/controller/coreCommands'; import { ICodeEditor } from 'vs/editor/browser/editorBrowser'; import { KeybindingWeight } from 'vs/platform/keybinding/common/keybindingsRegistry'; +import { MenuId } from 'vs/platform/actions/common/actions'; // copy lines @@ -63,6 +64,12 @@ class CopyLinesUpAction extends AbstractCopyLinesAction { primary: KeyMod.Alt | KeyMod.Shift | KeyCode.UpArrow, linux: { primary: KeyMod.CtrlCmd | KeyMod.Alt | KeyMod.Shift | KeyCode.UpArrow }, weight: KeybindingWeight.EditorContrib + }, + menubarOpts: { + menuId: MenuId.MenubarSelectionMenu, + group: '2_line', + title: nls.localize({ key: 'miCopyLinesUp', comment: ['&& denotes a mnemonic'] }, "&&Copy Line Up"), + order: 1 } }); } @@ -80,6 +87,12 @@ class CopyLinesDownAction extends AbstractCopyLinesAction { primary: KeyMod.Alt | KeyMod.Shift | KeyCode.DownArrow, linux: { primary: KeyMod.CtrlCmd | KeyMod.Alt | KeyMod.Shift | KeyCode.DownArrow }, weight: KeybindingWeight.EditorContrib + }, + menubarOpts: { + menuId: MenuId.MenubarSelectionMenu, + group: '2_line', + title: nls.localize({ key: 'miCopyLinesDown', comment: ['&& denotes a mnemonic'] }, "Co&&py Line Down"), + order: 2 } }); } @@ -124,6 +137,12 @@ class MoveLinesUpAction extends AbstractMoveLinesAction { primary: KeyMod.Alt | KeyCode.UpArrow, linux: { primary: KeyMod.Alt | KeyCode.UpArrow }, weight: KeybindingWeight.EditorContrib + }, + menubarOpts: { + menuId: MenuId.MenubarSelectionMenu, + group: '2_line', + title: nls.localize({ key: 'miMoveLinesUp', comment: ['&& denotes a mnemonic'] }, "Mo&&ve Line Up"), + order: 3 } }); } @@ -141,6 +160,12 @@ class MoveLinesDownAction extends AbstractMoveLinesAction { primary: KeyMod.Alt | KeyCode.DownArrow, linux: { primary: KeyMod.Alt | KeyCode.DownArrow }, weight: KeybindingWeight.EditorContrib + }, + menubarOpts: { + menuId: MenuId.MenubarSelectionMenu, + group: '2_line', + title: nls.localize({ key: 'miMoveLinesDown', comment: ['&& denotes a mnemonic'] }, "Move &&Line Down"), + order: 4 } }); } diff --git a/src/vs/editor/contrib/multicursor/multicursor.ts b/src/vs/editor/contrib/multicursor/multicursor.ts index ed677d9b80f..c93314e994a 100644 --- a/src/vs/editor/contrib/multicursor/multicursor.ts +++ b/src/vs/editor/contrib/multicursor/multicursor.ts @@ -26,6 +26,7 @@ import { themeColorFromId } from 'vs/platform/theme/common/themeService'; import { INewFindReplaceState, FindOptionOverride } from 'vs/editor/contrib/find/findState'; import { ICodeEditor } from 'vs/editor/browser/editorBrowser'; import { KeybindingWeight } from 'vs/platform/keybinding/common/keybindingsRegistry'; +import { MenuId } from 'vs/platform/actions/common/actions'; export class InsertCursorAbove extends EditorAction { @@ -43,6 +44,12 @@ export class InsertCursorAbove extends EditorAction { secondary: [KeyMod.CtrlCmd | KeyMod.Shift | KeyCode.UpArrow] }, weight: KeybindingWeight.EditorContrib + }, + menubarOpts: { + menuId: MenuId.MenubarSelectionMenu, + group: '3_multi', + title: nls.localize({ key: 'miInsertCursorAbove', comment: ['&& denotes a mnemonic'] }, "&&Add Cursor Above"), + order: 2 } }); } @@ -82,6 +89,12 @@ export class InsertCursorBelow extends EditorAction { secondary: [KeyMod.CtrlCmd | KeyMod.Shift | KeyCode.DownArrow] }, weight: KeybindingWeight.EditorContrib + }, + menubarOpts: { + menuId: MenuId.MenubarSelectionMenu, + group: '3_multi', + title: nls.localize({ key: 'miInsertCursorBelow', comment: ['&& denotes a mnemonic'] }, "A&&dd Cursor Below"), + order: 3 } }); } @@ -117,6 +130,12 @@ class InsertCursorAtEndOfEachLineSelected extends EditorAction { kbExpr: EditorContextKeys.editorTextFocus, primary: KeyMod.Shift | KeyMod.Alt | KeyCode.KEY_I, weight: KeybindingWeight.EditorContrib + }, + menubarOpts: { + menuId: MenuId.MenubarSelectionMenu, + group: '3_multi', + title: nls.localize({ key: 'miInsertCursorAtEndOfEachLineSelected', comment: ['&& denotes a mnemonic'] }, "Add C&&ursors to Line Ends"), + order: 4 } }); } @@ -528,6 +547,12 @@ export class AddSelectionToNextFindMatchAction extends MultiCursorSelectionContr kbExpr: EditorContextKeys.focus, primary: KeyMod.CtrlCmd | KeyCode.KEY_D, weight: KeybindingWeight.EditorContrib + }, + menubarOpts: { + menuId: MenuId.MenubarSelectionMenu, + group: '3_multi', + title: nls.localize({ key: 'miAddSelectionToNextFindMatch', comment: ['&& denotes a mnemonic'] }, "Add &&Next Occurrence"), + order: 5 } }); } @@ -542,7 +567,13 @@ export class AddSelectionToPreviousFindMatchAction extends MultiCursorSelectionC id: 'editor.action.addSelectionToPreviousFindMatch', label: nls.localize('addSelectionToPreviousFindMatch', "Add Selection To Previous Find Match"), alias: 'Add Selection To Previous Find Match', - precondition: null + precondition: null, + menubarOpts: { + menuId: MenuId.MenubarSelectionMenu, + group: '3_multi', + title: nls.localize({ key: 'miAddSelectionToPreviousFindMatch', comment: ['&& denotes a mnemonic'] }, "Add P&&revious Occurrence"), + order: 6 + } }); } protected _run(multiCursorController: MultiCursorSelectionController, findController: CommonFindController): void { @@ -594,6 +625,12 @@ export class SelectHighlightsAction extends MultiCursorSelectionControllerAction kbExpr: EditorContextKeys.focus, primary: KeyMod.CtrlCmd | KeyMod.Shift | KeyCode.KEY_L, weight: KeybindingWeight.EditorContrib + }, + menubarOpts: { + menuId: MenuId.MenubarSelectionMenu, + group: '3_multi', + title: nls.localize({ key: 'miSelectHighlights', comment: ['&& denotes a mnemonic'] }, "Select All &&Occurrences"), + order: 7 } }); } diff --git a/src/vs/editor/contrib/smartSelect/smartSelect.ts b/src/vs/editor/contrib/smartSelect/smartSelect.ts index 76b6057a039..cfe14c52788 100644 --- a/src/vs/editor/contrib/smartSelect/smartSelect.ts +++ b/src/vs/editor/contrib/smartSelect/smartSelect.ts @@ -17,6 +17,7 @@ import { TokenSelectionSupport, ILogicalSelectionEntry } from './tokenSelectionS import { ICursorPositionChangedEvent } from 'vs/editor/common/controller/cursorEvents'; import { ICodeEditor } from 'vs/editor/browser/editorBrowser'; import { KeybindingWeight } from 'vs/platform/keybinding/common/keybindingsRegistry'; +import { MenuId } from 'vs/platform/actions/common/actions'; // --- selection state machine @@ -176,6 +177,12 @@ class GrowSelectionAction extends AbstractSmartSelect { primary: KeyMod.Shift | KeyMod.Alt | KeyCode.RightArrow, mac: { primary: KeyMod.CtrlCmd | KeyMod.WinCtrl | KeyMod.Shift | KeyCode.RightArrow }, weight: KeybindingWeight.EditorContrib + }, + menubarOpts: { + menuId: MenuId.MenubarSelectionMenu, + group: '1_basic', + title: nls.localize({ key: 'miSmartSelectGrow', comment: ['&& denotes a mnemonic'] }, "&&Expand Selection"), + order: 2 } }); } @@ -193,6 +200,12 @@ class ShrinkSelectionAction extends AbstractSmartSelect { primary: KeyMod.Shift | KeyMod.Alt | KeyCode.LeftArrow, mac: { primary: KeyMod.CtrlCmd | KeyMod.WinCtrl | KeyMod.Shift | KeyCode.LeftArrow }, weight: KeybindingWeight.EditorContrib + }, + menubarOpts: { + menuId: MenuId.MenubarSelectionMenu, + group: '1_basic', + title: nls.localize({ key: 'miSmartSelectShrink', comment: ['&& denotes a mnemonic'] }, "&&Shrink Selection"), + order: 3 } }); } diff --git a/src/vs/workbench/parts/codeEditor/electron-browser/menubarRegistrations.ts b/src/vs/workbench/parts/codeEditor/electron-browser/menubarRegistrations.ts index 02d2ee2f366..4a47f3ee656 100644 --- a/src/vs/workbench/parts/codeEditor/electron-browser/menubarRegistrations.ts +++ b/src/vs/workbench/parts/codeEditor/electron-browser/menubarRegistrations.ts @@ -10,68 +10,6 @@ import { MenuRegistry, MenuId } from 'vs/platform/actions/common/actions'; selectionMenuRegistration(); function selectionMenuRegistration() { - MenuRegistry.appendMenuItem(MenuId.MenubarSelectionMenu, { - group: '1_basic', - command: { - id: 'editor.action.selectAll', - title: nls.localize({ key: 'miSelectAll', comment: ['&& denotes a mnemonic'] }, "&&Select All") - }, - order: 1 - }); - - MenuRegistry.appendMenuItem(MenuId.MenubarSelectionMenu, { - group: '1_basic', - command: { - id: 'editor.action.smartSelect.grow', - title: nls.localize({ key: 'miSmartSelectGrow', comment: ['&& denotes a mnemonic'] }, "&&Expand Selection") - }, - order: 2 - }); - - MenuRegistry.appendMenuItem(MenuId.MenubarSelectionMenu, { - group: '1_basic', - command: { - id: 'editor.action.smartSelect.shrink', - title: nls.localize({ key: 'miSmartSelectShrink', comment: ['&& denotes a mnemonic'] }, "&&Shrink Selection") - }, - order: 3 - }); - - MenuRegistry.appendMenuItem(MenuId.MenubarSelectionMenu, { - group: '2_line', - command: { - id: 'editor.action.copyLinesUpAction', - title: nls.localize({ key: 'miCopyLinesUp', comment: ['&& denotes a mnemonic'] }, "&&Copy Line Up") - }, - order: 1 - }); - - MenuRegistry.appendMenuItem(MenuId.MenubarSelectionMenu, { - group: '2_line', - command: { - id: 'editor.action.copyLinesDownAction', - title: nls.localize({ key: 'miCopyLinesDown', comment: ['&& denotes a mnemonic'] }, "Co&&py Line Down") - }, - order: 2 - }); - - MenuRegistry.appendMenuItem(MenuId.MenubarSelectionMenu, { - group: '2_line', - command: { - id: 'editor.action.moveLinesUpAction', - title: nls.localize({ key: 'miMoveLinesUp', comment: ['&& denotes a mnemonic'] }, "Mo&&ve Line Up") - }, - order: 3 - }); - - MenuRegistry.appendMenuItem(MenuId.MenubarSelectionMenu, { - group: '2_line', - command: { - id: 'editor.action.moveLinesDownAction', - title: nls.localize({ key: 'miMoveLinesDown', comment: ['&& denotes a mnemonic'] }, "Move &&Line Down") - }, - order: 4 - }); MenuRegistry.appendMenuItem(MenuId.MenubarSelectionMenu, { group: '3_multi', @@ -82,57 +20,4 @@ function selectionMenuRegistration() { order: 1 }); - MenuRegistry.appendMenuItem(MenuId.MenubarSelectionMenu, { - group: '3_multi', - command: { - id: 'editor.action.insertCursorAbove', - title: nls.localize({ key: 'miInsertCursorAbove', comment: ['&& denotes a mnemonic'] }, "&&Add Cursor Above") - }, - order: 2 - }); - - MenuRegistry.appendMenuItem(MenuId.MenubarSelectionMenu, { - group: '3_multi', - command: { - id: 'editor.action.insertCursorBelow', - title: nls.localize({ key: 'miInsertCursorBelow', comment: ['&& denotes a mnemonic'] }, "A&&dd Cursor Below") - }, - order: 3 - }); - - MenuRegistry.appendMenuItem(MenuId.MenubarSelectionMenu, { - group: '3_multi', - command: { - id: 'editor.action.insertCursorAtEndOfEachLineSelected', - title: nls.localize({ key: 'miInsertCursorAtEndOfEachLineSelected', comment: ['&& denotes a mnemonic'] }, "Add C&&ursors to Line Ends") - }, - order: 4 - }); - - MenuRegistry.appendMenuItem(MenuId.MenubarSelectionMenu, { - group: '3_multi', - command: { - id: 'editor.action.addSelectionToNextFindMatch', - title: nls.localize({ key: 'miAddSelectionToNextFindMatch', comment: ['&& denotes a mnemonic'] }, "Add &&Next Occurrence") - }, - order: 5 - }); - - MenuRegistry.appendMenuItem(MenuId.MenubarSelectionMenu, { - group: '3_multi', - command: { - id: 'editor.action.addSelectionToPreviousFindMatch', - title: nls.localize({ key: 'miAddSelectionToPreviousFindMatch', comment: ['&& denotes a mnemonic'] }, "Add P&&revious Occurrence") - }, - order: 6 - }); - - MenuRegistry.appendMenuItem(MenuId.MenubarSelectionMenu, { - group: '3_multi', - command: { - id: 'editor.action.selectHighlights', - title: nls.localize({ key: 'miSelectHighlights', comment: ['&& denotes a mnemonic'] }, "Select All &&Occurrences") - }, - order: 7 - }); } From 4f0c90fa36c2b5b22c337887bcc0a21b7d449a85 Mon Sep 17 00:00:00 2001 From: Martin Aeschlimann Date: Wed, 25 Jul 2018 09:55:57 +0200 Subject: [PATCH 0075/1276] [json] update to latest lsp (folding range support) --- .../client/src/jsonMain.ts | 55 +---------- .../json-language-features/package.json | 3 +- .../server/package.json | 11 +-- .../server/src/jsonServerMain.ts | 2 +- .../json-language-features/server/yarn.lock | 99 +++++++------------ extensions/json-language-features/yarn.lock | 29 +++--- 6 files changed, 57 insertions(+), 142 deletions(-) diff --git a/extensions/json-language-features/client/src/jsonMain.ts b/extensions/json-language-features/client/src/jsonMain.ts index b2fc5658eb5..9040304a4f8 100644 --- a/extensions/json-language-features/client/src/jsonMain.ts +++ b/extensions/json-language-features/client/src/jsonMain.ts @@ -8,12 +8,10 @@ import * as path from 'path'; import * as nls from 'vscode-nls'; const localize = nls.loadMessageBundle(); -import { workspace, languages, ExtensionContext, extensions, Uri, LanguageConfiguration, TextDocument, FoldingRangeKind, FoldingRange, Disposable, FoldingContext } from 'vscode'; -import { LanguageClient, LanguageClientOptions, RequestType, ServerOptions, TransportKind, NotificationType, DidChangeConfigurationNotification, CancellationToken } from 'vscode-languageclient'; +import { workspace, languages, ExtensionContext, extensions, Uri, LanguageConfiguration } from 'vscode'; +import { LanguageClient, LanguageClientOptions, RequestType, ServerOptions, TransportKind, NotificationType, DidChangeConfigurationNotification } from 'vscode-languageclient'; import TelemetryReporter from 'vscode-extension-telemetry'; -import { FoldingRangeRequest, FoldingRangeRequestParam, FoldingRangeClientCapabilities, FoldingRangeKind as LSFoldingRangeKind } from 'vscode-languageserver-protocol-foldingprovider'; - import { hash } from './utils/hash'; namespace VSCodeContentRequest { @@ -97,21 +95,6 @@ export function activate(context: ExtensionContext) { // Create the language client and start the client. let client = new LanguageClient('json', localize('jsonserver.name', 'JSON Language Server'), serverOptions, clientOptions); client.registerProposedFeatures(); - client.registerFeature({ - fillClientCapabilities(capabilities: FoldingRangeClientCapabilities): void { - let textDocumentCap = capabilities.textDocument; - if (!textDocumentCap) { - textDocumentCap = capabilities.textDocument = {}; - } - textDocumentCap.foldingRange = { - dynamicRegistration: false, - rangeLimit: 5000, - lineFoldingOnly: true - }; - }, - initialize(capabilities, documentSelector): void { - } - }); let disposable = client.start(); toDispose.push(disposable); @@ -141,8 +124,6 @@ export function activate(context: ExtensionContext) { toDispose.push(workspace.onDidCloseTextDocument(d => handleContentChange(d.uri))); client.sendNotification(SchemaAssociationNotification.type, getSchemaAssociation(context)); - - toDispose.push(initFoldingProvider()); }); let languageConfiguration: LanguageConfiguration = { @@ -154,38 +135,6 @@ export function activate(context: ExtensionContext) { }; languages.setLanguageConfiguration('json', languageConfiguration); languages.setLanguageConfiguration('jsonc', languageConfiguration); - - function initFoldingProvider(): Disposable { - function getKind(kind: string | undefined): FoldingRangeKind | undefined { - if (kind) { - switch (kind) { - case LSFoldingRangeKind.Comment: - return FoldingRangeKind.Comment; - case LSFoldingRangeKind.Imports: - return FoldingRangeKind.Imports; - case LSFoldingRangeKind.Region: - return FoldingRangeKind.Region; - } - } - return void 0; - } - return languages.registerFoldingRangeProvider(documentSelector, { - provideFoldingRanges(document: TextDocument, context: FoldingContext, token: CancellationToken) { - const param: FoldingRangeRequestParam = { - textDocument: client.code2ProtocolConverter.asTextDocumentIdentifier(document) - }; - return client.sendRequest(FoldingRangeRequest.type, param, token).then(ranges => { - if (Array.isArray(ranges)) { - return ranges.map(r => new FoldingRange(r.startLine, r.endLine, getKind(r.kind))); - } - return null; - }, error => { - client.logFailedRequest(FoldingRangeRequest.type, error); - return null; - }); - } - }); - } } export function deactivate(): Promise { diff --git a/extensions/json-language-features/package.json b/extensions/json-language-features/package.json index 8ea4b2f3d21..610fa55776c 100644 --- a/extensions/json-language-features/package.json +++ b/extensions/json-language-features/package.json @@ -101,8 +101,7 @@ }, "dependencies": { "vscode-extension-telemetry": "0.0.17", - "vscode-languageclient": "^4.1.4", - "vscode-languageserver-protocol-foldingprovider": "^2.0.1", + "vscode-languageclient": "^4.4.0", "vscode-nls": "^3.2.4" }, "devDependencies": { diff --git a/extensions/json-language-features/server/package.json b/extensions/json-language-features/server/package.json index 2f67cd91401..e894d848722 100644 --- a/extensions/json-language-features/server/package.json +++ b/extensions/json-language-features/server/package.json @@ -11,13 +11,12 @@ "vscode-json-languageserver": "./bin/vscode-json-languageserver" }, "dependencies": { - "jsonc-parser": "^2.0.0-next.1", - "request-light": "^0.2.2", - "vscode-json-languageservice": "^3.1.2", - "vscode-languageserver": "^4.1.3", - "vscode-languageserver-protocol-foldingprovider": "^2.0.1", + "jsonc-parser": "^2.0.1", + "request-light": "^0.2.3", + "vscode-json-languageservice": "^3.1.4", + "vscode-languageserver": "^4.4.0", "vscode-nls": "^3.2.4", - "vscode-uri": "^1.0.3" + "vscode-uri": "^1.0.5" }, "devDependencies": { "@types/mocha": "2.2.33", diff --git a/extensions/json-language-features/server/src/jsonServerMain.ts b/extensions/json-language-features/server/src/jsonServerMain.ts index 2fa7619d1ff..b2be7c62132 100644 --- a/extensions/json-language-features/server/src/jsonServerMain.ts +++ b/extensions/json-language-features/server/src/jsonServerMain.ts @@ -19,7 +19,7 @@ import { formatError, runSafe, runSafeAsync } from './utils/runner'; import { JSONDocument, JSONSchema, getLanguageService, DocumentLanguageSettings, SchemaConfiguration } from 'vscode-json-languageservice'; import { getLanguageModelCache } from './languageModelCache'; -import { FoldingRangeRequest, FoldingRangeServerCapabilities } from 'vscode-languageserver-protocol-foldingprovider'; +import { FoldingRangeRequest, FoldingRangeServerCapabilities } from 'vscode-languageserver-protocol'; interface ISchemaAssociations { [pattern: string]: string[]; diff --git a/extensions/json-language-features/server/yarn.lock b/extensions/json-language-features/server/yarn.lock index d9b5875b9bc..8948926b0bd 100644 --- a/extensions/json-language-features/server/yarn.lock +++ b/extensions/json-language-features/server/yarn.lock @@ -16,13 +16,7 @@ agent-base@4, agent-base@^4.1.0: dependencies: es6-promisify "^5.0.0" -debug@2: - version "2.6.9" - resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f" - dependencies: - ms "2.0.0" - -debug@^3.1.0: +debug@3.1.0, debug@^3.1.0: version "3.1.0" resolved "https://registry.yarnpkg.com/debug/-/debug-3.1.0.tgz#5bb5a0672628b64149566ba16819e61518c67261" dependencies: @@ -38,24 +32,20 @@ es6-promisify@^5.0.0: dependencies: es6-promise "^4.0.3" -http-proxy-agent@2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/http-proxy-agent/-/http-proxy-agent-2.0.0.tgz#46482a2f0523a4d6082551709f469cb3e4a85ff4" +http-proxy-agent@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/http-proxy-agent/-/http-proxy-agent-2.1.0.tgz#e4821beef5b2142a2026bd73926fe537631c5405" dependencies: agent-base "4" - debug "2" + debug "3.1.0" -https-proxy-agent@2.1.1: - version "2.1.1" - resolved "https://registry.yarnpkg.com/https-proxy-agent/-/https-proxy-agent-2.1.1.tgz#a7ce4382a1ba8266ee848578778122d491260fd9" +https-proxy-agent@^2.2.1: + version "2.2.1" + resolved "https://registry.yarnpkg.com/https-proxy-agent/-/https-proxy-agent-2.2.1.tgz#51552970fa04d723e04c56d04178c3f92592bbc0" dependencies: agent-base "^4.1.0" debug "^3.1.0" -jsonc-parser@^2.0.0-next.1: - version "2.0.0-next.1" - resolved "https://registry.yarnpkg.com/jsonc-parser/-/jsonc-parser-2.0.0-next.1.tgz#445a824f765a96abfbb286d759a9b1d226b18088" - jsonc-parser@^2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/jsonc-parser/-/jsonc-parser-2.0.1.tgz#9d23cd2709714fff508a1a6679d82135bee1ae60" @@ -64,68 +54,53 @@ ms@2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8" -request-light@^0.2.2: - version "0.2.2" - resolved "https://registry.yarnpkg.com/request-light/-/request-light-0.2.2.tgz#53e48af32ad1514e45221ea5ece5ce782720f712" +request-light@^0.2.3: + version "0.2.3" + resolved "https://registry.yarnpkg.com/request-light/-/request-light-0.2.3.tgz#a18635ec6dd92f8705c019c42ef645f684d94f7e" dependencies: - http-proxy-agent "2.0.0" - https-proxy-agent "2.1.1" - vscode-nls "^2.0.2" + http-proxy-agent "^2.1.0" + https-proxy-agent "^2.2.1" + vscode-nls "^3.2.2" -vscode-json-languageservice@^3.1.2: - version "3.1.2" - resolved "https://registry.yarnpkg.com/vscode-json-languageservice/-/vscode-json-languageservice-3.1.2.tgz#5c70fc32ad389e6da48452e7b0187ea5e70f68bf" +vscode-json-languageservice@^3.1.4: + version "3.1.4" + resolved "https://registry.yarnpkg.com/vscode-json-languageservice/-/vscode-json-languageservice-3.1.4.tgz#72e84e2754ad117f9e8d36876c1a66fe16234235" dependencies: jsonc-parser "^2.0.1" - vscode-languageserver-types "^3.7.2" - vscode-nls "^3.2.2" - vscode-uri "^1.0.3" + vscode-languageserver-types "^3.10.0" + vscode-nls "^3.2.4" + vscode-uri "^1.0.5" vscode-jsonrpc@^3.6.2: version "3.6.2" resolved "https://registry.yarnpkg.com/vscode-jsonrpc/-/vscode-jsonrpc-3.6.2.tgz#3b5eef691159a15556ecc500e9a8a0dd143470c8" -vscode-languageserver-protocol-foldingprovider@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/vscode-languageserver-protocol-foldingprovider/-/vscode-languageserver-protocol-foldingprovider-2.0.1.tgz#051d0d9e58d1b79dc4681acd48f21797f5515bfd" - dependencies: - vscode-languageserver-protocol "^3.7.2" - vscode-languageserver-types "^3.7.2" - -vscode-languageserver-protocol@^3.7.2: - version "3.7.2" - resolved "https://registry.yarnpkg.com/vscode-languageserver-protocol/-/vscode-languageserver-protocol-3.7.2.tgz#df58621c032139010888b6a9ddc969423f9ba9d6" +vscode-languageserver-protocol@^3.10.0: + version "3.10.0" + resolved "https://registry.yarnpkg.com/vscode-languageserver-protocol/-/vscode-languageserver-protocol-3.10.0.tgz#f8dcdf987687f64a26e7c32d498fc781a0e886dc" dependencies: vscode-jsonrpc "^3.6.2" - vscode-languageserver-types "^3.7.2" + vscode-languageserver-types "^3.10.0" -vscode-languageserver-types@^3.7.2: - version "3.7.2" - resolved "https://registry.yarnpkg.com/vscode-languageserver-types/-/vscode-languageserver-types-3.7.2.tgz#aad8846f8e3e27962648554de5a8417e358f34eb" +vscode-languageserver-types@^3.10.0: + version "3.10.0" + resolved "https://registry.yarnpkg.com/vscode-languageserver-types/-/vscode-languageserver-types-3.10.0.tgz#944e5308f3b36a3f372c766f1a344e903ec9c389" -vscode-languageserver@^4.1.3: - version "4.1.3" - resolved "https://registry.yarnpkg.com/vscode-languageserver/-/vscode-languageserver-4.1.3.tgz#937d37c955b6b9c2409388413cd6f54d1eb9fe7d" +vscode-languageserver@^4.4.0: + version "4.4.0" + resolved "https://registry.yarnpkg.com/vscode-languageserver/-/vscode-languageserver-4.4.0.tgz#b6e8b37a739ccb629d92f3635f0099d191c856fa" dependencies: - vscode-languageserver-protocol "^3.7.2" - vscode-uri "^1.0.1" + vscode-languageserver-protocol "^3.10.0" + vscode-uri "^1.0.3" -vscode-nls@^2.0.2: - version "2.0.2" - resolved "https://registry.yarnpkg.com/vscode-nls/-/vscode-nls-2.0.2.tgz#808522380844b8ad153499af5c3b03921aea02da" - -vscode-nls@^3.2.2: - version "3.2.2" - resolved "https://registry.yarnpkg.com/vscode-nls/-/vscode-nls-3.2.2.tgz#3817eca5b985c2393de325197cf4e15eb2aa5350" - -vscode-nls@^3.2.4: +vscode-nls@^3.2.2, vscode-nls@^3.2.4: version "3.2.4" resolved "https://registry.yarnpkg.com/vscode-nls/-/vscode-nls-3.2.4.tgz#2166b4183c8aea884d20727f5449e62be69fd398" -vscode-uri@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/vscode-uri/-/vscode-uri-1.0.1.tgz#11a86befeac3c4aa3ec08623651a3c81a6d0bbc8" - vscode-uri@^1.0.3: version "1.0.3" resolved "https://registry.yarnpkg.com/vscode-uri/-/vscode-uri-1.0.3.tgz#631bdbf716dccab0e65291a8dc25c23232085a52" + +vscode-uri@^1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/vscode-uri/-/vscode-uri-1.0.5.tgz#3b899a8ef71c37f3054d79bdbdda31c7bf36f20d" diff --git a/extensions/json-language-features/yarn.lock b/extensions/json-language-features/yarn.lock index 1e7214749f2..2ff934b3440 100644 --- a/extensions/json-language-features/yarn.lock +++ b/extensions/json-language-features/yarn.lock @@ -38,29 +38,22 @@ vscode-jsonrpc@^3.6.2: version "3.6.2" resolved "https://registry.yarnpkg.com/vscode-jsonrpc/-/vscode-jsonrpc-3.6.2.tgz#3b5eef691159a15556ecc500e9a8a0dd143470c8" -vscode-languageclient@^4.1.4: - version "4.1.4" - resolved "https://registry.yarnpkg.com/vscode-languageclient/-/vscode-languageclient-4.1.4.tgz#fff1a6bca4714835dca7fce35bc4ce81442fdf2c" +vscode-languageclient@^4.4.0: + version "4.4.0" + resolved "https://registry.yarnpkg.com/vscode-languageclient/-/vscode-languageclient-4.4.0.tgz#b05868f6477b6f0c9910b24daae4f3e8c4b65902" dependencies: - vscode-languageserver-protocol "^3.7.2" + vscode-languageserver-protocol "^3.10.0" -vscode-languageserver-protocol-foldingprovider@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/vscode-languageserver-protocol-foldingprovider/-/vscode-languageserver-protocol-foldingprovider-2.0.1.tgz#051d0d9e58d1b79dc4681acd48f21797f5515bfd" - dependencies: - vscode-languageserver-protocol "^3.7.2" - vscode-languageserver-types "^3.7.2" - -vscode-languageserver-protocol@^3.7.2: - version "3.7.2" - resolved "https://registry.yarnpkg.com/vscode-languageserver-protocol/-/vscode-languageserver-protocol-3.7.2.tgz#df58621c032139010888b6a9ddc969423f9ba9d6" +vscode-languageserver-protocol@^3.10.0: + version "3.10.0" + resolved "https://registry.yarnpkg.com/vscode-languageserver-protocol/-/vscode-languageserver-protocol-3.10.0.tgz#f8dcdf987687f64a26e7c32d498fc781a0e886dc" dependencies: vscode-jsonrpc "^3.6.2" - vscode-languageserver-types "^3.7.2" + vscode-languageserver-types "^3.10.0" -vscode-languageserver-types@^3.7.2: - version "3.7.2" - resolved "https://registry.yarnpkg.com/vscode-languageserver-types/-/vscode-languageserver-types-3.7.2.tgz#aad8846f8e3e27962648554de5a8417e358f34eb" +vscode-languageserver-types@^3.10.0: + version "3.10.0" + resolved "https://registry.yarnpkg.com/vscode-languageserver-types/-/vscode-languageserver-types-3.10.0.tgz#944e5308f3b36a3f372c766f1a344e903ec9c389" vscode-nls@^3.2.4: version "3.2.4" From 8959f941fdb2623504953767df302a5271e4dc3e Mon Sep 17 00:00:00 2001 From: Alex Dima Date: Wed, 25 Jul 2018 10:45:57 +0200 Subject: [PATCH 0076/1276] Wrap up menu bar registration migration (#54510) --- .../browser/parts/menubar/menubarPart.ts | 14 ----- .../codeEditor/codeEditor.contribution.ts | 1 - .../electron-browser/menubarRegistrations.ts | 23 -------- .../toggleMultiCursorModifier.ts | 56 ++++++++++++++++++- 4 files changed, 55 insertions(+), 39 deletions(-) delete mode 100644 src/vs/workbench/parts/codeEditor/electron-browser/menubarRegistrations.ts diff --git a/src/vs/workbench/browser/parts/menubar/menubarPart.ts b/src/vs/workbench/browser/parts/menubar/menubarPart.ts index 08e654839f5..b204fb7626c 100644 --- a/src/vs/workbench/browser/parts/menubar/menubarPart.ts +++ b/src/vs/workbench/browser/parts/menubar/menubarPart.ts @@ -183,10 +183,6 @@ export class MenubarPart extends Part { return enableMenuBarMnemonics; } - private get currentMultiCursorSetting(): string { - return this.configurationService.getValue('editor.multiCursorModifier'); - } - private get currentAutoSaveSetting(): string { return this.configurationService.getValue('files.autoSave'); } @@ -463,16 +459,6 @@ export class MenubarPart extends Part { private calculateActionLabel(action: IAction | IMenubarMenuItemAction): string { let label = action.label; switch (action.id) { - case 'workbench.action.toggleMultiCursorModifier': - if (this.currentMultiCursorSetting === 'ctrlCmd') { - label = nls.localize('miMultiCursorAlt', "Switch to Alt+Click for Multi-Cursor"); - } else { - label = isMacintosh - ? nls.localize('miMultiCursorCmd', "Switch to Cmd+Click for Multi-Cursor") - : nls.localize('miMultiCursorCtrl', "Switch to Ctrl+Click for Multi-Cursor"); - } - break; - case 'workbench.action.toggleSidebarPosition': if (this.currentSidebarPosition !== 'right') { label = nls.localize({ key: 'miMoveSidebarRight', comment: ['&& denotes a mnemonic'] }, "&&Move Side Bar Right"); diff --git a/src/vs/workbench/parts/codeEditor/codeEditor.contribution.ts b/src/vs/workbench/parts/codeEditor/codeEditor.contribution.ts index a4085223ade..cc4c07f981a 100644 --- a/src/vs/workbench/parts/codeEditor/codeEditor.contribution.ts +++ b/src/vs/workbench/parts/codeEditor/codeEditor.contribution.ts @@ -6,7 +6,6 @@ import './electron-browser/accessibility'; import './electron-browser/inspectKeybindings'; import './electron-browser/largeFileOptimizations'; -import './electron-browser/menubarRegistrations'; import './electron-browser/menuPreventer'; import './electron-browser/selectionClipboard'; import './electron-browser/textMate/inspectTMScopes'; diff --git a/src/vs/workbench/parts/codeEditor/electron-browser/menubarRegistrations.ts b/src/vs/workbench/parts/codeEditor/electron-browser/menubarRegistrations.ts deleted file mode 100644 index 4a47f3ee656..00000000000 --- a/src/vs/workbench/parts/codeEditor/electron-browser/menubarRegistrations.ts +++ /dev/null @@ -1,23 +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'; - -import * as nls from 'vs/nls'; -import { MenuRegistry, MenuId } from 'vs/platform/actions/common/actions'; - -selectionMenuRegistration(); - -function selectionMenuRegistration() { - - MenuRegistry.appendMenuItem(MenuId.MenubarSelectionMenu, { - group: '3_multi', - command: { - id: 'workbench.action.toggleMultiCursorModifier', - title: nls.localize('miMultiCursorAlt', "Switch to Alt+Click for Multi-Cursor") - }, - order: 1 - }); - -} diff --git a/src/vs/workbench/parts/codeEditor/electron-browser/toggleMultiCursorModifier.ts b/src/vs/workbench/parts/codeEditor/electron-browser/toggleMultiCursorModifier.ts index e7b79739e01..608554450f8 100644 --- a/src/vs/workbench/parts/codeEditor/electron-browser/toggleMultiCursorModifier.ts +++ b/src/vs/workbench/parts/codeEditor/electron-browser/toggleMultiCursorModifier.ts @@ -6,11 +6,15 @@ import { TPromise } from 'vs/base/common/winjs.base'; import * as nls from 'vs/nls'; +import * as platform from 'vs/base/common/platform'; import { Registry } from 'vs/platform/registry/common/platform'; import { Action } from 'vs/base/common/actions'; -import { SyncActionDescriptor } from 'vs/platform/actions/common/actions'; +import { SyncActionDescriptor, MenuRegistry, MenuId } from 'vs/platform/actions/common/actions'; import { IWorkbenchActionRegistry, Extensions } from 'vs/workbench/common/actions'; import { IConfigurationService, ConfigurationTarget } from 'vs/platform/configuration/common/configuration'; +import { IWorkbenchContributionsRegistry, Extensions as WorkbenchExtensions, IWorkbenchContribution } from 'vs/workbench/common/contributions'; +import { LifecyclePhase } from 'vs/platform/lifecycle/common/lifecycle'; +import { RawContextKey, IContextKeyService, IContextKey } from 'vs/platform/contextkey/common/contextkey'; export class ToggleMultiCursorModifierAction extends Action { @@ -35,5 +39,55 @@ export class ToggleMultiCursorModifierAction extends Action { } } +const multiCursorModifier = new RawContextKey('multiCursorModifier', 'altKey'); + +class MultiCursorModifierContextKeyController implements IWorkbenchContribution { + + private readonly _multiCursorModifier: IContextKey; + + constructor( + @IConfigurationService private readonly configurationService: IConfigurationService, + @IContextKeyService contextKeyService: IContextKeyService + ) { + this._multiCursorModifier = multiCursorModifier.bindTo(contextKeyService); + configurationService.onDidChangeConfiguration((e) => { + if (e.affectsConfiguration('editor.multiCursorModifier')) { + this._update(); + } + }); + } + + private _update(): void { + const editorConf = this.configurationService.getValue<{ multiCursorModifier: 'ctrlCmd' | 'alt' }>('editor'); + const value = (editorConf.multiCursorModifier === 'ctrlCmd' ? 'ctrlCmd' : 'altKey'); + this._multiCursorModifier.set(value); + } +} + +Registry.as(WorkbenchExtensions.Workbench).registerWorkbenchContribution(MultiCursorModifierContextKeyController, LifecyclePhase.Running); + + const registry = Registry.as(Extensions.WorkbenchActions); registry.registerWorkbenchAction(new SyncActionDescriptor(ToggleMultiCursorModifierAction, ToggleMultiCursorModifierAction.ID, ToggleMultiCursorModifierAction.LABEL), 'Toggle Multi-Cursor Modifier'); +MenuRegistry.appendMenuItem(MenuId.MenubarSelectionMenu, { + group: '3_multi', + command: { + id: ToggleMultiCursorModifierAction.ID, + title: nls.localize('miMultiCursorAlt', "Switch to Alt+Click for Multi-Cursor") + }, + when: multiCursorModifier.isEqualTo('ctrlCmd'), + order: 1 +}); +MenuRegistry.appendMenuItem(MenuId.MenubarSelectionMenu, { + group: '3_multi', + command: { + id: ToggleMultiCursorModifierAction.ID, + title: ( + platform.isMacintosh + ? nls.localize('miMultiCursorCmd', "Switch to Cmd+Click for Multi-Cursor") + : nls.localize('miMultiCursorCtrl', "Switch to Ctrl+Click for Multi-Cursor") + ) + }, + when: multiCursorModifier.isEqualTo('altKey'), + order: 1 +}); \ No newline at end of file From 3b23fa955679f48cdf1b805d9d5d3a0512566804 Mon Sep 17 00:00:00 2001 From: Johannes Rieken Date: Wed, 25 Jul 2018 11:06:08 +0200 Subject: [PATCH 0077/1276] fix #54995 --- src/vs/workbench/browser/parts/editor/breadcrumbsControl.ts | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/vs/workbench/browser/parts/editor/breadcrumbsControl.ts b/src/vs/workbench/browser/parts/editor/breadcrumbsControl.ts index 14ab5ecc5b8..5777120a0f6 100644 --- a/src/vs/workbench/browser/parts/editor/breadcrumbsControl.ts +++ b/src/vs/workbench/browser/parts/editor/breadcrumbsControl.ts @@ -357,6 +357,12 @@ MenuRegistry.appendMenuItem(MenuId.CommandPalette, { title: localize('cmd.focus', "Focus Breadcrumbs") } }); +MenuRegistry.appendMenuItem(MenuId.CommandPalette, { + command: { + id: 'breadcrumbs.toggle', + title: localize('cmd.toggle', "Toggle Breadcrumbs") + } +}); MenuRegistry.appendMenuItem(MenuId.MenubarViewMenu, { group: '5_editor', order: 99, From 04129e96fe63f088644f9c4fcd80fb07de07f5d7 Mon Sep 17 00:00:00 2001 From: Christof Marti Date: Wed, 25 Jul 2018 09:36:16 +0200 Subject: [PATCH 0078/1276] Fix extension-editing display name and description --- extensions/extension-editing/package.nls.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/extensions/extension-editing/package.nls.json b/extensions/extension-editing/package.nls.json index 9265e6a3c9d..263fb6bc870 100644 --- a/extensions/extension-editing/package.nls.json +++ b/extensions/extension-editing/package.nls.json @@ -1,4 +1,4 @@ { - "displayName": "Package File Editing", - "description": "Provides IntelliSense for VS Code extension points and linting capabilities in package.json files." + "displayName": "Extension Authoring", + "description": "Provides linting capabilities for authoring extensions." } \ No newline at end of file From 8699a313cd3ea03f2d9f4fced4f47d377fc87353 Mon Sep 17 00:00:00 2001 From: Sandeep Somavarapu Date: Wed, 25 Jul 2018 12:03:29 +0200 Subject: [PATCH 0079/1276] Fix #55005 --- src/vs/workbench/browser/parts/views/media/views.css | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/vs/workbench/browser/parts/views/media/views.css b/src/vs/workbench/browser/parts/views/media/views.css index 597a1fcc597..2bffac61f30 100644 --- a/src/vs/workbench/browser/parts/views/media/views.css +++ b/src/vs/workbench/browser/parts/views/media/views.css @@ -88,13 +88,16 @@ -webkit-font-smoothing: antialiased; } +.tree-explorer-viewlet-tree-view .monaco-tree .monaco-tree-row .custom-view-tree-node-item > .custom-view-tree-node-item-resourceLabel .monaco-icon-label-description-container { + flex: 1; +} + .tree-explorer-viewlet-tree-view .monaco-tree .monaco-tree-row .custom-view-tree-node-item > .custom-view-tree-node-item-resourceLabel::after { padding-right: 0px; } .tree-explorer-viewlet-tree-view .monaco-tree .monaco-tree-row .custom-view-tree-node-item > .custom-view-tree-node-item-resourceLabel > .actions { display: none; - flex-grow: 100; } .tree-explorer-viewlet-tree-view .monaco-tree .monaco-tree-row:hover .custom-view-tree-node-item > .custom-view-tree-node-item-resourceLabel > .actions, From 21c22840c58a16cee46673cc663c54b7bcf900fa Mon Sep 17 00:00:00 2001 From: Martin Aeschlimann Date: Wed, 25 Jul 2018 12:18:56 +0200 Subject: [PATCH 0080/1276] [html] adopt lsp (folding, colors) --- .../client/src/htmlMain.ts | 54 +-------------- .../html-language-features/package.json | 3 +- .../server/package.json | 11 ++-- .../server/src/htmlServerMain.ts | 5 +- .../server/src/modes/htmlFolding.ts | 2 +- .../server/src/modes/htmlMode.ts | 4 +- .../server/src/modes/javascriptMode.ts | 7 +- .../server/src/modes/languageModes.ts | 3 +- .../html-language-features/server/yarn.lock | 65 ++++++++----------- extensions/html-language-features/yarn.lock | 29 ++++----- 10 files changed, 56 insertions(+), 127 deletions(-) diff --git a/extensions/html-language-features/client/src/htmlMain.ts b/extensions/html-language-features/client/src/htmlMain.ts index f463ff2ba8a..68f8b881d3b 100644 --- a/extensions/html-language-features/client/src/htmlMain.ts +++ b/extensions/html-language-features/client/src/htmlMain.ts @@ -8,14 +8,12 @@ import * as path from 'path'; import * as nls from 'vscode-nls'; const localize = nls.loadMessageBundle(); -import { languages, ExtensionContext, IndentAction, Position, TextDocument, Range, CompletionItem, CompletionItemKind, SnippetString, FoldingRangeKind, FoldingRange, FoldingContext } from 'vscode'; -import { LanguageClient, LanguageClientOptions, ServerOptions, TransportKind, RequestType, TextDocumentPositionParams, Disposable, CancellationToken } from 'vscode-languageclient'; +import { languages, ExtensionContext, IndentAction, Position, TextDocument, Range, CompletionItem, CompletionItemKind, SnippetString } from 'vscode'; +import { LanguageClient, LanguageClientOptions, ServerOptions, TransportKind, RequestType, TextDocumentPositionParams } from 'vscode-languageclient'; import { EMPTY_ELEMENTS } from './htmlEmptyTagsShared'; import { activateTagClosing } from './tagClosing'; import TelemetryReporter from 'vscode-extension-telemetry'; -import { FoldingRangeRequest, FoldingRangeRequestParam, FoldingRangeClientCapabilities, FoldingRangeKind as LSFoldingRangeKind } from 'vscode-languageserver-protocol-foldingprovider'; - namespace TagCloseRequest { export const type: RequestType = new RequestType('html/tag'); } @@ -64,21 +62,6 @@ export function activate(context: ExtensionContext) { // Create the language client and start the client. let client = new LanguageClient('html', localize('htmlserver.name', 'HTML Language Server'), serverOptions, clientOptions); client.registerProposedFeatures(); - client.registerFeature({ - fillClientCapabilities(capabilities: FoldingRangeClientCapabilities): void { - let textDocumentCap = capabilities.textDocument; - if (!textDocumentCap) { - textDocumentCap = capabilities.textDocument = {}; - } - textDocumentCap.foldingRange = { - dynamicRegistration: false, - rangeLimit: 5000, - lineFoldingOnly: true - }; - }, - initialize(capabilities, documentSelector): void { - } - }); let disposable = client.start(); toDispose.push(disposable); @@ -96,7 +79,6 @@ export function activate(context: ExtensionContext) { } }); toDispose.push(disposable); - toDispose.push(initFoldingProvider()); }); languages.setLanguageConfiguration('html', { @@ -172,38 +154,6 @@ export function activate(context: ExtensionContext) { return null; } }); - - function initFoldingProvider(): Disposable { - function getKind(kind: string | undefined): FoldingRangeKind | undefined { - if (kind) { - switch (kind) { - case LSFoldingRangeKind.Comment: - return FoldingRangeKind.Comment; - case LSFoldingRangeKind.Imports: - return FoldingRangeKind.Imports; - case LSFoldingRangeKind.Region: - return FoldingRangeKind.Region; - } - } - return void 0; - } - return languages.registerFoldingRangeProvider('html', { - provideFoldingRanges(document: TextDocument, context: FoldingContext, token: CancellationToken) { - const param: FoldingRangeRequestParam = { - textDocument: client.code2ProtocolConverter.asTextDocumentIdentifier(document) - }; - return client.sendRequest(FoldingRangeRequest.type, param, token).then(ranges => { - if (Array.isArray(ranges)) { - return ranges.map(r => new FoldingRange(r.startLine, r.endLine, getKind(r.kind))); - } - return null; - }, error => { - client.logFailedRequest(FoldingRangeRequest.type, error); - return null; - }); - } - }); - } } function getPackageInfo(context: ExtensionContext): IPackageInfo | null { diff --git a/extensions/html-language-features/package.json b/extensions/html-language-features/package.json index 9ac18e38fbb..fbe7c1f157b 100644 --- a/extensions/html-language-features/package.json +++ b/extensions/html-language-features/package.json @@ -174,8 +174,7 @@ }, "dependencies": { "vscode-extension-telemetry": "0.0.17", - "vscode-languageclient": "^4.1.4", - "vscode-languageserver-protocol-foldingprovider": "^2.0.1", + "vscode-languageclient": "^4.4.0", "vscode-nls": "^3.2.4" }, "devDependencies": { diff --git a/extensions/html-language-features/server/package.json b/extensions/html-language-features/server/package.json index e9586c7ad34..5db8caf8ea8 100644 --- a/extensions/html-language-features/server/package.json +++ b/extensions/html-language-features/server/package.json @@ -8,13 +8,12 @@ "node": "*" }, "dependencies": { - "vscode-css-languageservice": "^3.0.9-next.20", - "vscode-html-languageservice": "^2.1.3-next.5", - "vscode-languageserver": "^4.1.3", - "vscode-languageserver-protocol-foldingprovider": "^2.0.1", - "vscode-languageserver-types": "^3.7.2", + "vscode-css-languageservice": "^3.0.9", + "vscode-html-languageservice": "^2.1.3", + "vscode-languageserver": "^4.4.0", + "vscode-languageserver-types": "^3.10.0", "vscode-nls": "^3.2.4", - "vscode-uri": "^1.0.3" + "vscode-uri": "^1.0.5" }, "devDependencies": { "@types/mocha": "2.2.33", diff --git a/extensions/html-language-features/server/src/htmlServerMain.ts b/extensions/html-language-features/server/src/htmlServerMain.ts index b4e4dc827bd..ffe5c18df41 100644 --- a/extensions/html-language-features/server/src/htmlServerMain.ts +++ b/extensions/html-language-features/server/src/htmlServerMain.ts @@ -19,7 +19,6 @@ import { getDocumentContext } from './utils/documentContext'; import uri from 'vscode-uri'; import { formatError, runSafe, runSafeAsync } from './utils/runner'; -import { FoldingRangeRequest, FoldingRangeServerCapabilities } from 'vscode-languageserver-protocol-foldingprovider'; import { getFoldingRanges } from './modes/htmlFolding'; namespace TagCloseRequest { @@ -119,7 +118,7 @@ connection.onInitialize((params: InitializeParams): InitializeResult => { scopedSettingsSupport = getClientCapability('workspace.configuration', false); workspaceFoldersSupport = getClientCapability('workspace.workspaceFolders', false); foldingRangeLimit = getClientCapability('textDocument.foldingRange.rangeLimit', Number.MAX_VALUE); - const capabilities: ServerCapabilities & FoldingRangeServerCapabilities = { + const capabilities: ServerCapabilities = { // Tell the client that the server works in FULL text document sync mode textDocumentSync: documents.syncKind, completionProvider: clientSnippetSupport ? { resolveProvider: true, triggerCharacters: ['.', ':', '<', '"', '=', '/'] } : undefined, @@ -441,7 +440,7 @@ connection.onRequest(TagCloseRequest.type, (params, token) => { }, null, `Error while computing tag close actions for ${params.textDocument.uri}`, token); }); -connection.onRequest(FoldingRangeRequest.type, (params, token) => { +connection.onFoldingRanges((params, token) => { return runSafe(() => { const document = documents.get(params.textDocument.uri); if (document) { diff --git a/extensions/html-language-features/server/src/modes/htmlFolding.ts b/extensions/html-language-features/server/src/modes/htmlFolding.ts index c36b27ad3bf..aa63a24cf9a 100644 --- a/extensions/html-language-features/server/src/modes/htmlFolding.ts +++ b/extensions/html-language-features/server/src/modes/htmlFolding.ts @@ -4,7 +4,7 @@ *--------------------------------------------------------------------------------------------*/ 'use strict'; import { TextDocument, CancellationToken, Position, Range } from 'vscode-languageserver'; -import { FoldingRange } from 'vscode-languageserver-protocol-foldingprovider'; +import { FoldingRange } from 'vscode-languageserver-types'; import { LanguageModes } from './languageModes'; export function getFoldingRanges(languageModes: LanguageModes, document: TextDocument, maxRanges: number | undefined, cancellationToken: CancellationToken | null): FoldingRange[] { diff --git a/extensions/html-language-features/server/src/modes/htmlMode.ts b/extensions/html-language-features/server/src/modes/htmlMode.ts index cd3edbaed4b..29fb01d4cb8 100644 --- a/extensions/html-language-features/server/src/modes/htmlMode.ts +++ b/extensions/html-language-features/server/src/modes/htmlMode.ts @@ -6,10 +6,8 @@ import { getLanguageModelCache } from '../languageModelCache'; import { LanguageService as HTMLLanguageService, HTMLDocument, DocumentContext, FormattingOptions, HTMLFormatConfiguration } from 'vscode-html-languageservice'; -import { TextDocument, Position, Range, CompletionItem } from 'vscode-languageserver-types'; +import { TextDocument, Position, Range, CompletionItem, FoldingRange } from 'vscode-languageserver-types'; import { LanguageMode, Workspace } from './languageModes'; - -import { FoldingRange } from 'vscode-languageserver-protocol-foldingprovider'; import { getPathCompletionParticipant } from './pathCompletion'; export function getHTMLMode(htmlLanguageService: HTMLLanguageService, workspace: Workspace): LanguageMode { diff --git a/extensions/html-language-features/server/src/modes/javascriptMode.ts b/extensions/html-language-features/server/src/modes/javascriptMode.ts index 0c124f2d468..4148761e42f 100644 --- a/extensions/html-language-features/server/src/modes/javascriptMode.ts +++ b/extensions/html-language-features/server/src/modes/javascriptMode.ts @@ -5,14 +5,17 @@ 'use strict'; import { LanguageModelCache, getLanguageModelCache } from '../languageModelCache'; -import { SymbolInformation, SymbolKind, CompletionItem, Location, SignatureHelp, SignatureInformation, ParameterInformation, Definition, TextEdit, TextDocument, Diagnostic, DiagnosticSeverity, Range, CompletionItemKind, Hover, MarkedString, DocumentHighlight, DocumentHighlightKind, CompletionList, Position, FormattingOptions } from 'vscode-languageserver-types'; +import { + SymbolInformation, SymbolKind, CompletionItem, Location, SignatureHelp, SignatureInformation, ParameterInformation, + Definition, TextEdit, TextDocument, Diagnostic, DiagnosticSeverity, Range, CompletionItemKind, Hover, MarkedString, + DocumentHighlight, DocumentHighlightKind, CompletionList, Position, FormattingOptions, FoldingRange, FoldingRangeKind +} from 'vscode-languageserver-types'; import { LanguageMode, Settings, Workspace } from './languageModes'; import { getWordAtText, startsWith, isWhitespaceOnly, repeat } from '../utils/strings'; import { HTMLDocumentRegions } from './embeddedSupport'; import * as ts from 'typescript'; import { join } from 'path'; -import { FoldingRange, FoldingRangeKind } from 'vscode-languageserver-protocol-foldingprovider'; const FILE_NAME = 'vscode://javascript/1'; // the same 'file' is used for all contents const JQUERY_D_TS = join(__dirname, '../../lib/jquery.d.ts'); diff --git a/extensions/html-language-features/server/src/modes/languageModes.ts b/extensions/html-language-features/server/src/modes/languageModes.ts index 282c4f75ef4..6fcba8d24dc 100644 --- a/extensions/html-language-features/server/src/modes/languageModes.ts +++ b/extensions/html-language-features/server/src/modes/languageModes.ts @@ -7,10 +7,9 @@ import { getLanguageService as getHTMLLanguageService, DocumentContext } from 'vscode-html-languageservice'; import { CompletionItem, Location, SignatureHelp, Definition, TextEdit, TextDocument, Diagnostic, DocumentLink, Range, - Hover, DocumentHighlight, CompletionList, Position, FormattingOptions, SymbolInformation + Hover, DocumentHighlight, CompletionList, Position, FormattingOptions, SymbolInformation, FoldingRange } from 'vscode-languageserver-types'; import { ColorInformation, ColorPresentation, Color, WorkspaceFolder } from 'vscode-languageserver'; -import { FoldingRange } from 'vscode-languageserver-protocol-foldingprovider'; import { getLanguageModelCache, LanguageModelCache } from '../languageModelCache'; import { getDocumentRegions, HTMLDocumentRegions } from './embeddedSupport'; diff --git a/extensions/html-language-features/server/yarn.lock b/extensions/html-language-features/server/yarn.lock index 32e736c53c2..0fb9f113a5d 100644 --- a/extensions/html-language-features/server/yarn.lock +++ b/extensions/html-language-features/server/yarn.lock @@ -194,66 +194,55 @@ supports-color@5.4.0: dependencies: has-flag "^3.0.0" -vscode-css-languageservice@^3.0.9-next.20: - version "3.0.9-next.20" - resolved "https://registry.yarnpkg.com/vscode-css-languageservice/-/vscode-css-languageservice-3.0.9-next.20.tgz#8229aee66aa877929af5d2fd81a21731b415c92e" +vscode-css-languageservice@^3.0.9: + version "3.0.9" + resolved "https://registry.yarnpkg.com/vscode-css-languageservice/-/vscode-css-languageservice-3.0.9.tgz#770471350120c5bcf6918632a125638fc0ece3be" dependencies: - vscode-languageserver-types "^3.7.2" - vscode-nls "^3.2.2" + vscode-languageserver-types "^3.10.0" + vscode-nls "^3.2.4" -vscode-html-languageservice@^2.1.3-next.5: - version "2.1.3-next.5" - resolved "https://registry.yarnpkg.com/vscode-html-languageservice/-/vscode-html-languageservice-2.1.3-next.5.tgz#cfbf4ffed96845ad13999d572ce0b5c2aeee84af" +vscode-html-languageservice@^2.1.3: + version "2.1.3" + resolved "https://registry.yarnpkg.com/vscode-html-languageservice/-/vscode-html-languageservice-2.1.3.tgz#c999c39e37adc632be8003a5e82075cf75dbb9bc" dependencies: - vscode-languageserver-types "^3.7.2" - vscode-nls "^3.2.2" - vscode-uri "^1.0.3" + vscode-languageserver-types "^3.10.0" + vscode-nls "^3.2.4" + vscode-uri "^1.0.5" vscode-jsonrpc@^3.6.2: version "3.6.2" resolved "https://registry.yarnpkg.com/vscode-jsonrpc/-/vscode-jsonrpc-3.6.2.tgz#3b5eef691159a15556ecc500e9a8a0dd143470c8" -vscode-languageserver-protocol-foldingprovider@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/vscode-languageserver-protocol-foldingprovider/-/vscode-languageserver-protocol-foldingprovider-2.0.1.tgz#051d0d9e58d1b79dc4681acd48f21797f5515bfd" - dependencies: - vscode-languageserver-protocol "^3.7.2" - vscode-languageserver-types "^3.7.2" - -vscode-languageserver-protocol@^3.7.2: - version "3.7.2" - resolved "https://registry.yarnpkg.com/vscode-languageserver-protocol/-/vscode-languageserver-protocol-3.7.2.tgz#df58621c032139010888b6a9ddc969423f9ba9d6" +vscode-languageserver-protocol@^3.10.0: + version "3.10.0" + resolved "https://registry.yarnpkg.com/vscode-languageserver-protocol/-/vscode-languageserver-protocol-3.10.0.tgz#f8dcdf987687f64a26e7c32d498fc781a0e886dc" dependencies: vscode-jsonrpc "^3.6.2" - vscode-languageserver-types "^3.7.2" + vscode-languageserver-types "^3.10.0" -vscode-languageserver-types@^3.7.2: - version "3.7.2" - resolved "https://registry.yarnpkg.com/vscode-languageserver-types/-/vscode-languageserver-types-3.7.2.tgz#aad8846f8e3e27962648554de5a8417e358f34eb" +vscode-languageserver-types@^3.10.0: + version "3.10.0" + resolved "https://registry.yarnpkg.com/vscode-languageserver-types/-/vscode-languageserver-types-3.10.0.tgz#944e5308f3b36a3f372c766f1a344e903ec9c389" -vscode-languageserver@^4.1.3: - version "4.1.3" - resolved "https://registry.yarnpkg.com/vscode-languageserver/-/vscode-languageserver-4.1.3.tgz#937d37c955b6b9c2409388413cd6f54d1eb9fe7d" +vscode-languageserver@^4.4.0: + version "4.4.0" + resolved "https://registry.yarnpkg.com/vscode-languageserver/-/vscode-languageserver-4.4.0.tgz#b6e8b37a739ccb629d92f3635f0099d191c856fa" dependencies: - vscode-languageserver-protocol "^3.7.2" - vscode-uri "^1.0.1" - -vscode-nls@^3.2.2: - version "3.2.2" - resolved "https://registry.yarnpkg.com/vscode-nls/-/vscode-nls-3.2.2.tgz#3817eca5b985c2393de325197cf4e15eb2aa5350" + vscode-languageserver-protocol "^3.10.0" + vscode-uri "^1.0.3" vscode-nls@^3.2.4: version "3.2.4" resolved "https://registry.yarnpkg.com/vscode-nls/-/vscode-nls-3.2.4.tgz#2166b4183c8aea884d20727f5449e62be69fd398" -vscode-uri@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/vscode-uri/-/vscode-uri-1.0.1.tgz#11a86befeac3c4aa3ec08623651a3c81a6d0bbc8" - vscode-uri@^1.0.3: version "1.0.3" resolved "https://registry.yarnpkg.com/vscode-uri/-/vscode-uri-1.0.3.tgz#631bdbf716dccab0e65291a8dc25c23232085a52" +vscode-uri@^1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/vscode-uri/-/vscode-uri-1.0.5.tgz#3b899a8ef71c37f3054d79bdbdda31c7bf36f20d" + wrappy@1: version "1.0.2" resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" diff --git a/extensions/html-language-features/yarn.lock b/extensions/html-language-features/yarn.lock index 1e7214749f2..2ff934b3440 100644 --- a/extensions/html-language-features/yarn.lock +++ b/extensions/html-language-features/yarn.lock @@ -38,29 +38,22 @@ vscode-jsonrpc@^3.6.2: version "3.6.2" resolved "https://registry.yarnpkg.com/vscode-jsonrpc/-/vscode-jsonrpc-3.6.2.tgz#3b5eef691159a15556ecc500e9a8a0dd143470c8" -vscode-languageclient@^4.1.4: - version "4.1.4" - resolved "https://registry.yarnpkg.com/vscode-languageclient/-/vscode-languageclient-4.1.4.tgz#fff1a6bca4714835dca7fce35bc4ce81442fdf2c" +vscode-languageclient@^4.4.0: + version "4.4.0" + resolved "https://registry.yarnpkg.com/vscode-languageclient/-/vscode-languageclient-4.4.0.tgz#b05868f6477b6f0c9910b24daae4f3e8c4b65902" dependencies: - vscode-languageserver-protocol "^3.7.2" + vscode-languageserver-protocol "^3.10.0" -vscode-languageserver-protocol-foldingprovider@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/vscode-languageserver-protocol-foldingprovider/-/vscode-languageserver-protocol-foldingprovider-2.0.1.tgz#051d0d9e58d1b79dc4681acd48f21797f5515bfd" - dependencies: - vscode-languageserver-protocol "^3.7.2" - vscode-languageserver-types "^3.7.2" - -vscode-languageserver-protocol@^3.7.2: - version "3.7.2" - resolved "https://registry.yarnpkg.com/vscode-languageserver-protocol/-/vscode-languageserver-protocol-3.7.2.tgz#df58621c032139010888b6a9ddc969423f9ba9d6" +vscode-languageserver-protocol@^3.10.0: + version "3.10.0" + resolved "https://registry.yarnpkg.com/vscode-languageserver-protocol/-/vscode-languageserver-protocol-3.10.0.tgz#f8dcdf987687f64a26e7c32d498fc781a0e886dc" dependencies: vscode-jsonrpc "^3.6.2" - vscode-languageserver-types "^3.7.2" + vscode-languageserver-types "^3.10.0" -vscode-languageserver-types@^3.7.2: - version "3.7.2" - resolved "https://registry.yarnpkg.com/vscode-languageserver-types/-/vscode-languageserver-types-3.7.2.tgz#aad8846f8e3e27962648554de5a8417e358f34eb" +vscode-languageserver-types@^3.10.0: + version "3.10.0" + resolved "https://registry.yarnpkg.com/vscode-languageserver-types/-/vscode-languageserver-types-3.10.0.tgz#944e5308f3b36a3f372c766f1a344e903ec9c389" vscode-nls@^3.2.4: version "3.2.4" From 116948ef51a2fc0095aef1150afc422c45643e3e Mon Sep 17 00:00:00 2001 From: Martin Aeschlimann Date: Wed, 25 Jul 2018 12:19:06 +0200 Subject: [PATCH 0081/1276] [css] adopt lsp (folding, colors) --- .../client/src/cssMain.ts | 51 +----------------- extensions/css-language-features/package.json | 5 +- .../css-language-features/server/package.json | 5 +- .../server/src/cssServerMain.ts | 5 +- .../css-language-features/server/yarn.lock | 53 ++++++++----------- extensions/css-language-features/yarn.lock | 29 ++++------ 6 files changed, 41 insertions(+), 107 deletions(-) diff --git a/extensions/css-language-features/client/src/cssMain.ts b/extensions/css-language-features/client/src/cssMain.ts index a7a031bda3c..dce55982cb9 100644 --- a/extensions/css-language-features/client/src/cssMain.ts +++ b/extensions/css-language-features/client/src/cssMain.ts @@ -8,9 +8,8 @@ import * as path from 'path'; import * as nls from 'vscode-nls'; const localize = nls.loadMessageBundle(); -import { languages, window, commands, ExtensionContext, Range, Position, TextDocument, CompletionItem, CompletionItemKind, TextEdit, SnippetString, FoldingRangeKind, FoldingRange, FoldingContext, CancellationToken } from 'vscode'; +import { languages, window, commands, ExtensionContext, Range, Position, CompletionItem, CompletionItemKind, TextEdit, SnippetString } from 'vscode'; import { LanguageClient, LanguageClientOptions, ServerOptions, TransportKind, Disposable } from 'vscode-languageclient'; -import { FoldingRangeRequest, FoldingRangeRequestParam, FoldingRangeClientCapabilities, FoldingRangeKind as LSFoldingRangeKind } from 'vscode-languageserver-protocol-foldingprovider'; // this method is called when vs code is activated export function activate(context: ExtensionContext) { @@ -42,21 +41,6 @@ export function activate(context: ExtensionContext) { // Create the language client and start the client. let client = new LanguageClient('css', localize('cssserver.name', 'CSS Language Server'), serverOptions, clientOptions); client.registerProposedFeatures(); - client.registerFeature({ - fillClientCapabilities(capabilities: FoldingRangeClientCapabilities): void { - let textDocumentCap = capabilities.textDocument; - if (!textDocumentCap) { - textDocumentCap = capabilities.textDocument = {}; - } - textDocumentCap.foldingRange = { - dynamicRegistration: false, - rangeLimit: 5000, - lineFoldingOnly: true - }; - }, - initialize(capabilities, documentSelector): void { - } - }); let disposable = client.start(); // Push the disposable to the context's subscriptions so that the @@ -85,7 +69,6 @@ export function activate(context: ExtensionContext) { client.onReady().then(() => { context.subscriptions.push(initCompletionProvider()); - context.subscriptions.push(initFoldingProvider()); }); function initCompletionProvider(): Disposable { @@ -116,38 +99,6 @@ export function activate(context: ExtensionContext) { }); } - function initFoldingProvider(): Disposable { - function getKind(kind: string | undefined): FoldingRangeKind | undefined { - if (kind) { - switch (kind) { - case LSFoldingRangeKind.Comment: - return FoldingRangeKind.Comment; - case LSFoldingRangeKind.Imports: - return FoldingRangeKind.Imports; - case LSFoldingRangeKind.Region: - return FoldingRangeKind.Region; - } - } - return void 0; - } - return languages.registerFoldingRangeProvider(documentSelector, { - provideFoldingRanges(document: TextDocument, context: FoldingContext, token: CancellationToken) { - const param: FoldingRangeRequestParam = { - textDocument: client.code2ProtocolConverter.asTextDocumentIdentifier(document) - }; - return client.sendRequest(FoldingRangeRequest.type, param, token).then(ranges => { - if (Array.isArray(ranges)) { - return ranges.map(r => new FoldingRange(r.startLine, r.endLine, getKind(r.kind))); - } - return null; - }, error => { - client.logFailedRequest(FoldingRangeRequest.type, error); - return null; - }); - } - }); - } - commands.registerCommand('_css.applyCodeAction', applyCodeAction); function applyCodeAction(uri: string, documentVersion: number, edits: TextEdit[]) { diff --git a/extensions/css-language-features/package.json b/extensions/css-language-features/package.json index dc78673bf07..4c1b1a151c9 100644 --- a/extensions/css-language-features/package.json +++ b/extensions/css-language-features/package.json @@ -707,12 +707,11 @@ ] }, "dependencies": { - "vscode-languageclient": "^4.1.4", - "vscode-languageserver-protocol-foldingprovider": "^2.0.1", + "vscode-languageclient": "^4.4.0", "vscode-nls": "^3.2.4" }, "devDependencies": { "@types/node": "7.0.43", "mocha": "^5.2.0" } -} \ No newline at end of file +} diff --git a/extensions/css-language-features/server/package.json b/extensions/css-language-features/server/package.json index 59fb5eefee2..756396ae8fa 100644 --- a/extensions/css-language-features/server/package.json +++ b/extensions/css-language-features/server/package.json @@ -8,9 +8,8 @@ "node": "*" }, "dependencies": { - "vscode-css-languageservice": "^3.0.9-next.20", - "vscode-languageserver": "^4.1.3", - "vscode-languageserver-protocol-foldingprovider": "^2.0.1" + "vscode-css-languageservice": "^3.0.9", + "vscode-languageserver": "^4.4.0" }, "devDependencies": { "@types/mocha": "2.2.33", diff --git a/extensions/css-language-features/server/src/cssServerMain.ts b/extensions/css-language-features/server/src/cssServerMain.ts index 8778faf2b79..8a822ce8b64 100644 --- a/extensions/css-language-features/server/src/cssServerMain.ts +++ b/extensions/css-language-features/server/src/cssServerMain.ts @@ -15,7 +15,6 @@ import { getLanguageModelCache } from './languageModelCache'; import { formatError, runSafe } from './utils/runner'; import URI from 'vscode-uri'; import { getPathCompletionParticipant } from './pathCompletion'; -import { FoldingRangeServerCapabilities, FoldingRangeRequest } from 'vscode-languageserver-protocol-foldingprovider'; export interface Settings { css: LanguageSettings; @@ -78,7 +77,7 @@ connection.onInitialize((params: InitializeParams): InitializeResult => { scopedSettingsSupport = !!getClientCapability('workspace.configuration', false); foldingRangeLimit = getClientCapability('textDocument.foldingRange.rangeLimit', Number.MAX_VALUE); - const capabilities: ServerCapabilities & FoldingRangeServerCapabilities = { + const capabilities: ServerCapabilities = { // Tell the client that the server works in FULL text document sync mode textDocumentSync: documents.syncKind, completionProvider: snippetSupport ? { resolveProvider: false, triggerCharacters: ['/'] } : undefined, @@ -306,7 +305,7 @@ connection.onRenameRequest((renameParameters, token) => { }, null, `Error while computing renames for ${renameParameters.textDocument.uri}`, token); }); -connection.onRequest(FoldingRangeRequest.type, (params, token) => { +connection.onFoldingRanges((params, token) => { return runSafe(() => { const document = documents.get(params.textDocument.uri); if (document) { diff --git a/extensions/css-language-features/server/yarn.lock b/extensions/css-language-features/server/yarn.lock index dd17147de5b..c2025f27675 100644 --- a/extensions/css-language-features/server/yarn.lock +++ b/extensions/css-language-features/server/yarn.lock @@ -194,49 +194,42 @@ supports-color@5.4.0: dependencies: has-flag "^3.0.0" -vscode-css-languageservice@^3.0.9-next.20: - version "3.0.9-next.20" - resolved "https://registry.yarnpkg.com/vscode-css-languageservice/-/vscode-css-languageservice-3.0.9-next.20.tgz#8229aee66aa877929af5d2fd81a21731b415c92e" +vscode-css-languageservice@^3.0.9: + version "3.0.9" + resolved "https://registry.yarnpkg.com/vscode-css-languageservice/-/vscode-css-languageservice-3.0.9.tgz#770471350120c5bcf6918632a125638fc0ece3be" dependencies: - vscode-languageserver-types "^3.7.2" - vscode-nls "^3.2.2" + vscode-languageserver-types "^3.10.0" + vscode-nls "^3.2.4" vscode-jsonrpc@^3.6.2: version "3.6.2" resolved "https://registry.yarnpkg.com/vscode-jsonrpc/-/vscode-jsonrpc-3.6.2.tgz#3b5eef691159a15556ecc500e9a8a0dd143470c8" -vscode-languageserver-protocol-foldingprovider@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/vscode-languageserver-protocol-foldingprovider/-/vscode-languageserver-protocol-foldingprovider-2.0.1.tgz#051d0d9e58d1b79dc4681acd48f21797f5515bfd" - dependencies: - vscode-languageserver-protocol "^3.7.2" - vscode-languageserver-types "^3.7.2" - -vscode-languageserver-protocol@^3.7.2: - version "3.7.2" - resolved "https://registry.yarnpkg.com/vscode-languageserver-protocol/-/vscode-languageserver-protocol-3.7.2.tgz#df58621c032139010888b6a9ddc969423f9ba9d6" +vscode-languageserver-protocol@^3.10.0: + version "3.10.0" + resolved "https://registry.yarnpkg.com/vscode-languageserver-protocol/-/vscode-languageserver-protocol-3.10.0.tgz#f8dcdf987687f64a26e7c32d498fc781a0e886dc" dependencies: vscode-jsonrpc "^3.6.2" - vscode-languageserver-types "^3.7.2" + vscode-languageserver-types "^3.10.0" -vscode-languageserver-types@^3.7.2: - version "3.7.2" - resolved "https://registry.yarnpkg.com/vscode-languageserver-types/-/vscode-languageserver-types-3.7.2.tgz#aad8846f8e3e27962648554de5a8417e358f34eb" +vscode-languageserver-types@^3.10.0: + version "3.10.0" + resolved "https://registry.yarnpkg.com/vscode-languageserver-types/-/vscode-languageserver-types-3.10.0.tgz#944e5308f3b36a3f372c766f1a344e903ec9c389" -vscode-languageserver@^4.1.3: - version "4.1.3" - resolved "https://registry.yarnpkg.com/vscode-languageserver/-/vscode-languageserver-4.1.3.tgz#937d37c955b6b9c2409388413cd6f54d1eb9fe7d" +vscode-languageserver@^4.4.0: + version "4.4.0" + resolved "https://registry.yarnpkg.com/vscode-languageserver/-/vscode-languageserver-4.4.0.tgz#b6e8b37a739ccb629d92f3635f0099d191c856fa" dependencies: - vscode-languageserver-protocol "^3.7.2" - vscode-uri "^1.0.1" + vscode-languageserver-protocol "^3.10.0" + vscode-uri "^1.0.3" -vscode-nls@^3.2.2: - version "3.2.2" - resolved "https://registry.yarnpkg.com/vscode-nls/-/vscode-nls-3.2.2.tgz#3817eca5b985c2393de325197cf4e15eb2aa5350" +vscode-nls@^3.2.4: + version "3.2.4" + resolved "https://registry.yarnpkg.com/vscode-nls/-/vscode-nls-3.2.4.tgz#2166b4183c8aea884d20727f5449e62be69fd398" -vscode-uri@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/vscode-uri/-/vscode-uri-1.0.1.tgz#11a86befeac3c4aa3ec08623651a3c81a6d0bbc8" +vscode-uri@^1.0.3: + version "1.0.5" + resolved "https://registry.yarnpkg.com/vscode-uri/-/vscode-uri-1.0.5.tgz#3b899a8ef71c37f3054d79bdbdda31c7bf36f20d" wrappy@1: version "1.0.2" diff --git a/extensions/css-language-features/yarn.lock b/extensions/css-language-features/yarn.lock index ac76cfede80..6338d75b098 100644 --- a/extensions/css-language-features/yarn.lock +++ b/extensions/css-language-features/yarn.lock @@ -137,29 +137,22 @@ vscode-jsonrpc@^3.6.2: version "3.6.2" resolved "https://registry.yarnpkg.com/vscode-jsonrpc/-/vscode-jsonrpc-3.6.2.tgz#3b5eef691159a15556ecc500e9a8a0dd143470c8" -vscode-languageclient@^4.1.4: - version "4.1.4" - resolved "https://registry.yarnpkg.com/vscode-languageclient/-/vscode-languageclient-4.1.4.tgz#fff1a6bca4714835dca7fce35bc4ce81442fdf2c" +vscode-languageclient@^4.4.0: + version "4.4.0" + resolved "https://registry.yarnpkg.com/vscode-languageclient/-/vscode-languageclient-4.4.0.tgz#b05868f6477b6f0c9910b24daae4f3e8c4b65902" dependencies: - vscode-languageserver-protocol "^3.7.2" + vscode-languageserver-protocol "^3.10.0" -vscode-languageserver-protocol-foldingprovider@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/vscode-languageserver-protocol-foldingprovider/-/vscode-languageserver-protocol-foldingprovider-2.0.1.tgz#051d0d9e58d1b79dc4681acd48f21797f5515bfd" - dependencies: - vscode-languageserver-protocol "^3.7.2" - vscode-languageserver-types "^3.7.2" - -vscode-languageserver-protocol@^3.7.2: - version "3.7.2" - resolved "https://registry.yarnpkg.com/vscode-languageserver-protocol/-/vscode-languageserver-protocol-3.7.2.tgz#df58621c032139010888b6a9ddc969423f9ba9d6" +vscode-languageserver-protocol@^3.10.0: + version "3.10.0" + resolved "https://registry.yarnpkg.com/vscode-languageserver-protocol/-/vscode-languageserver-protocol-3.10.0.tgz#f8dcdf987687f64a26e7c32d498fc781a0e886dc" dependencies: vscode-jsonrpc "^3.6.2" - vscode-languageserver-types "^3.7.2" + vscode-languageserver-types "^3.10.0" -vscode-languageserver-types@^3.7.2: - version "3.7.2" - resolved "https://registry.yarnpkg.com/vscode-languageserver-types/-/vscode-languageserver-types-3.7.2.tgz#aad8846f8e3e27962648554de5a8417e358f34eb" +vscode-languageserver-types@^3.10.0: + version "3.10.0" + resolved "https://registry.yarnpkg.com/vscode-languageserver-types/-/vscode-languageserver-types-3.10.0.tgz#944e5308f3b36a3f372c766f1a344e903ec9c389" vscode-nls@^3.2.4: version "3.2.4" From 7fd6f1b1d46bd2223a902406fccd20cc7a539825 Mon Sep 17 00:00:00 2001 From: Martin Aeschlimann Date: Wed, 25 Jul 2018 12:21:52 +0200 Subject: [PATCH 0082/1276] [json] use onFoldingRanges --- .../json-language-features/server/src/jsonServerMain.ts | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/extensions/json-language-features/server/src/jsonServerMain.ts b/extensions/json-language-features/server/src/jsonServerMain.ts index b2be7c62132..8db215a72e9 100644 --- a/extensions/json-language-features/server/src/jsonServerMain.ts +++ b/extensions/json-language-features/server/src/jsonServerMain.ts @@ -19,8 +19,6 @@ import { formatError, runSafe, runSafeAsync } from './utils/runner'; import { JSONDocument, JSONSchema, getLanguageService, DocumentLanguageSettings, SchemaConfiguration } from 'vscode-json-languageservice'; import { getLanguageModelCache } from './languageModelCache'; -import { FoldingRangeRequest, FoldingRangeServerCapabilities } from 'vscode-languageserver-protocol'; - interface ISchemaAssociations { [pattern: string]: string[]; } @@ -81,7 +79,7 @@ connection.onInitialize((params: InitializeParams): InitializeResult => { clientSnippetSupport = getClientCapability('textDocument.completion.completionItem.snippetSupport', false); clientDynamicRegisterSupport = getClientCapability('workspace.symbol.dynamicRegistration', false); foldingRangeLimit = getClientCapability('textDocument.foldingRange.rangeLimit', Number.MAX_VALUE); - const capabilities: ServerCapabilities & FoldingRangeServerCapabilities = { + const capabilities: ServerCapabilities = { // Tell the client that the server works in FULL text document sync mode textDocumentSync: documents.syncKind, completionProvider: clientSnippetSupport ? { resolveProvider: true, triggerCharacters: ['"', ':'] } : void 0, @@ -382,7 +380,7 @@ connection.onColorPresentation((params, token) => { }, [], `Error while computing color presentations for ${params.textDocument.uri}`, token); }); -connection.onRequest(FoldingRangeRequest.type, (params, token) => { +connection.onFoldingRanges((params, token) => { return runSafe(() => { const document = documents.get(params.textDocument.uri); if (document) { From a704725e6c3ee0b274f717a0df15fe9a52c7a4c3 Mon Sep 17 00:00:00 2001 From: Sandeep Somavarapu Date: Wed, 25 Jul 2018 12:42:05 +0200 Subject: [PATCH 0083/1276] Fix #54994 --- src/vs/platform/windows/common/windowsIpc.ts | 10 ++++++-- src/vs/workbench/electron-browser/actions.ts | 24 +++++++------------- 2 files changed, 16 insertions(+), 18 deletions(-) diff --git a/src/vs/platform/windows/common/windowsIpc.ts b/src/vs/platform/windows/common/windowsIpc.ts index 7398b588718..572713c7498 100644 --- a/src/vs/platform/windows/common/windowsIpc.ts +++ b/src/vs/platform/windows/common/windowsIpc.ts @@ -9,7 +9,7 @@ import { TPromise } from 'vs/base/common/winjs.base'; import { Event, buffer } from 'vs/base/common/event'; import { IChannel } from 'vs/base/parts/ipc/common/ipc'; import { IWindowsService, INativeOpenDialogOptions, IEnterWorkspaceResult, CrashReporterStartOptions, IMessageBoxResult, MessageBoxOptions, SaveDialogOptions, OpenDialogOptions, IDevToolsOptions } from 'vs/platform/windows/common/windows'; -import { IWorkspaceIdentifier, IWorkspaceFolderCreationData, isSingleFolderWorkspaceIdentifier, ISingleFolderWorkspaceIdentifier, isWorkspaceIdentifier } from 'vs/platform/workspaces/common/workspaces'; +import { IWorkspaceIdentifier, IWorkspaceFolderCreationData, ISingleFolderWorkspaceIdentifier, isWorkspaceIdentifier } from 'vs/platform/workspaces/common/workspaces'; import { IRecentlyOpened } from 'vs/platform/history/common/history'; import { ISerializableCommandAction } from 'vs/platform/actions/common/actions'; import URI from 'vs/base/common/uri'; @@ -140,7 +140,13 @@ export class WindowsChannel implements IWindowsChannel { case 'toggleFullScreen': return this.service.toggleFullScreen(arg); case 'setRepresentedFilename': return this.service.setRepresentedFilename(arg[0], arg[1]); case 'addRecentlyOpened': return this.service.addRecentlyOpened(arg); - case 'removeFromRecentlyOpened': return this.service.removeFromRecentlyOpened(isSingleFolderWorkspaceIdentifier(arg) ? URI.revive(arg) : arg); + case 'removeFromRecentlyOpened': { + let paths: (IWorkspaceIdentifier | ISingleFolderWorkspaceIdentifier | string)[] = arg; + if (Array.isArray(paths)) { + paths = paths.map(path => isWorkspaceIdentifier(path) || typeof path === 'string' ? path : URI.revive(path)); + } + return this.service.removeFromRecentlyOpened(paths); + } case 'clearRecentlyOpened': return this.service.clearRecentlyOpened(); case 'showPreviousWindowTab': return this.service.showPreviousWindowTab(); case 'showNextWindowTab': return this.service.showNextWindowTab(); diff --git a/src/vs/workbench/electron-browser/actions.ts b/src/vs/workbench/electron-browser/actions.ts index 2a4764e9943..8bc31bd7219 100644 --- a/src/vs/workbench/electron-browser/actions.ts +++ b/src/vs/workbench/electron-browser/actions.ts @@ -9,7 +9,7 @@ import 'vs/css!./media/actions'; import URI from 'vs/base/common/uri'; import { TPromise } from 'vs/base/common/winjs.base'; -import { Action } from 'vs/base/common/actions'; +import { Action, IAction } from 'vs/base/common/actions'; import { IWindowService, IWindowsService, MenuBarVisibility } from 'vs/platform/windows/common/windows'; import * as nls from 'vs/nls'; import product from 'vs/platform/node/product'; @@ -697,7 +697,6 @@ export class QuickSwitchWindow extends BaseSwitchWindow { export const inRecentFilesPickerContextKey = 'inRecentFilesPicker'; export abstract class BaseOpenRecentAction extends Action { - private removeAction: RemoveFromRecentlyOpened; constructor( id: string, @@ -707,11 +706,9 @@ export abstract class BaseOpenRecentAction extends Action { private contextService: IWorkspaceContextService, private environmentService: IEnvironmentService, private keybindingService: IKeybindingService, - instantiationService: IInstantiationService + private instantiationService: IInstantiationService ) { super(id, label); - - this.removeAction = instantiationService.createInstance(RemoveFromRecentlyOpened); } protected abstract isQuickNavigate(): boolean; @@ -723,7 +720,7 @@ export abstract class BaseOpenRecentAction extends Action { private openRecent(recentWorkspaces: (IWorkspaceIdentifier | ISingleFolderWorkspaceIdentifier)[], recentFiles: string[]): void { - function toPick(workspace: IWorkspaceIdentifier | ISingleFolderWorkspaceIdentifier | string, separator: ISeparator, fileKind: FileKind, environmentService: IEnvironmentService, removeAction?: RemoveFromRecentlyOpened): IFilePickOpenEntry { + function toPick(workspace: IWorkspaceIdentifier | ISingleFolderWorkspaceIdentifier | string, separator: ISeparator, fileKind: FileKind, environmentService: IEnvironmentService, action: IAction): IFilePickOpenEntry { let resource: URI; let label: string; let description: string; @@ -754,7 +751,7 @@ export abstract class BaseOpenRecentAction extends Action { runPick(resource, fileKind === FileKind.FILE, context); }); }, - action: removeAction + action }; } @@ -763,8 +760,8 @@ export abstract class BaseOpenRecentAction extends Action { this.windowService.openWindow([resource], { forceNewWindow, forceOpenWorkspaceAsFile: isFile }); }; - const workspacePicks: IFilePickOpenEntry[] = recentWorkspaces.map((workspace, index) => toPick(workspace, index === 0 ? { label: nls.localize('workspaces', "workspaces") } : void 0, isSingleFolderWorkspaceIdentifier(workspace) ? FileKind.FOLDER : FileKind.ROOT_FOLDER, this.environmentService, !this.isQuickNavigate() ? this.removeAction : void 0)); - const filePicks: IFilePickOpenEntry[] = recentFiles.map((p, index) => toPick(p, index === 0 ? { label: nls.localize('files', "files"), border: true } : void 0, FileKind.FILE, this.environmentService, !this.isQuickNavigate() ? this.removeAction : void 0)); + const workspacePicks: IFilePickOpenEntry[] = recentWorkspaces.map((workspace, index) => toPick(workspace, index === 0 ? { label: nls.localize('workspaces', "workspaces") } : void 0, isSingleFolderWorkspaceIdentifier(workspace) ? FileKind.FOLDER : FileKind.ROOT_FOLDER, this.environmentService, !this.isQuickNavigate() ? this.instantiationService.createInstance(RemoveFromRecentlyOpened, workspace) : void 0)); + const filePicks: IFilePickOpenEntry[] = recentFiles.map((p, index) => toPick(p, index === 0 ? { label: nls.localize('files', "files"), border: true } : void 0, FileKind.FILE, this.environmentService, !this.isQuickNavigate() ? this.instantiationService.createInstance(RemoveFromRecentlyOpened, p) : void 0)); // focus second entry if the first recent workspace is the current workspace let autoFocusSecondEntry: boolean = recentWorkspaces[0] && this.contextService.isCurrentWorkspace(recentWorkspaces[0]); @@ -777,12 +774,6 @@ export abstract class BaseOpenRecentAction extends Action { quickNavigateConfiguration: this.isQuickNavigate() ? { keybindings: this.keybindingService.lookupKeybindings(this.id) } : void 0 }).done(null, errors.onUnexpectedError); } - - dispose(): void { - super.dispose(); - - this.removeAction.dispose(); - } } class RemoveFromRecentlyOpened extends Action implements IPickOpenAction { @@ -791,6 +782,7 @@ class RemoveFromRecentlyOpened extends Action implements IPickOpenAction { static readonly LABEL = nls.localize('remove', "Remove from Recently Opened"); constructor( + private path: (IWorkspaceIdentifier | ISingleFolderWorkspaceIdentifier | string), @IWindowsService private windowsService: IWindowsService ) { super(RemoveFromRecentlyOpened.ID, RemoveFromRecentlyOpened.LABEL); @@ -799,7 +791,7 @@ class RemoveFromRecentlyOpened extends Action implements IPickOpenAction { } run(item: IPickOpenItem): TPromise { - return this.windowsService.removeFromRecentlyOpened([item.getResource().fsPath]).then(() => { + return this.windowsService.removeFromRecentlyOpened([this.path]).then(() => { item.remove(); return true; From e89bc64537c86d2523450d8204a150fe567b19b9 Mon Sep 17 00:00:00 2001 From: Johannes Rieken Date: Wed, 25 Jul 2018 11:42:49 +0200 Subject: [PATCH 0084/1276] allow breadcrumbs to be tabbed to, #54745 --- .../ui/breadcrumbs/breadcrumbsWidget.css | 1 + .../ui/breadcrumbs/breadcrumbsWidget.ts | 25 +++++++++++++------ 2 files changed, 19 insertions(+), 7 deletions(-) diff --git a/src/vs/base/browser/ui/breadcrumbs/breadcrumbsWidget.css b/src/vs/base/browser/ui/breadcrumbs/breadcrumbsWidget.css index d268c209a15..da510856593 100644 --- a/src/vs/base/browser/ui/breadcrumbs/breadcrumbsWidget.css +++ b/src/vs/base/browser/ui/breadcrumbs/breadcrumbsWidget.css @@ -20,6 +20,7 @@ cursor: pointer; align-self: center; height: 100%; + outline: none; } .monaco-breadcrumbs .monaco-breadcrumb-item:not(:first-child)::before { diff --git a/src/vs/base/browser/ui/breadcrumbs/breadcrumbsWidget.ts b/src/vs/base/browser/ui/breadcrumbs/breadcrumbsWidget.ts index 0966ceca010..cdd4dee0819 100644 --- a/src/vs/base/browser/ui/breadcrumbs/breadcrumbsWidget.ts +++ b/src/vs/base/browser/ui/breadcrumbs/breadcrumbsWidget.ts @@ -13,7 +13,7 @@ import { IDisposable, dispose } from 'vs/base/common/lifecycle'; import { IMouseEvent } from 'vs/base/browser/mouseEvent'; import { Event, Emitter } from 'vs/base/common/event'; import { Color } from 'vs/base/common/color'; -import { commonPrefixLength, tail } from 'vs/base/common/arrays'; +import { commonPrefixLength } from 'vs/base/common/arrays'; export abstract class BreadcrumbsItem { dispose(): void { } @@ -86,7 +86,7 @@ export class BreadcrumbsWidget { ) { this._domNode = document.createElement('div'); this._domNode.className = 'monaco-breadcrumbs'; - this._domNode.tabIndex = -1; + this._domNode.tabIndex = 0; this._scrollable = new DomScrollableElement(this._domNode, { vertical: ScrollbarVisibility.Hidden, horizontal: ScrollbarVisibility.Auto, @@ -152,13 +152,23 @@ export class BreadcrumbsWidget { } domFocus(): void { - const focused = this.getFocused() || tail(this._items); - this.setFocused(focused); - this._domNode.focus(); + let idx = this._focusedItemIdx >= 0 ? this._focusedItemIdx : this._items.length - 1; + if (idx >= 0 && idx < this._items.length) { + this._focus(idx, undefined); + } else { + this._domNode.focus(); + } } isDOMFocused(): boolean { - return this._domNode === document.activeElement; + let candidate = document.activeElement; + while (candidate) { + if (this._domNode === candidate) { + return true; + } + candidate = candidate.parentElement; + } + return false; } getFocused(): BreadcrumbsItem { @@ -190,6 +200,7 @@ export class BreadcrumbsWidget { } else { this._focusedItemIdx = i; dom.addClass(node, 'focused'); + node.focus(); } } this._reveal(this._focusedItemIdx); @@ -274,7 +285,7 @@ export class BreadcrumbsWidget { dom.clearNode(container); container.className = ''; item.render(container); - dom.append(container); + container.tabIndex = -1; dom.addClass(container, 'monaco-breadcrumb-item'); } From 0b1ce5cc9e3b3f56572f2eeb10a8e8e03c47c93f Mon Sep 17 00:00:00 2001 From: Johannes Rieken Date: Wed, 25 Jul 2018 12:52:20 +0200 Subject: [PATCH 0085/1276] add perf marks, #55010 --- src/vs/workbench/electron-browser/bootstrap/index.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/vs/workbench/electron-browser/bootstrap/index.js b/src/vs/workbench/electron-browser/bootstrap/index.js index 51700d6f0b3..cfdd8d8e09f 100644 --- a/src/vs/workbench/electron-browser/bootstrap/index.js +++ b/src/vs/workbench/electron-browser/bootstrap/index.js @@ -82,7 +82,7 @@ function readFile(file) { } function showPartsSplash(configuration) { - + perf.mark('willShowPartsSplash'); let key; let keep = false; // this is the logic of StorageService#getWorkspaceKey and StorageService#toStorageKey @@ -110,6 +110,7 @@ function showPartsSplash(configuration) { if (!keep) { storage.removeItem(key); } + perf.mark('didShowPartsSplash'); } const writeFile = (file, content) => new Promise((c, e) => fs.writeFile(file, content, 'utf8', err => err ? e(err) : c())); From 4b68e117a1fab3c6652edb1fdadf85133acf7f9c Mon Sep 17 00:00:00 2001 From: Sandeep Somavarapu Date: Wed, 25 Jul 2018 12:51:52 +0200 Subject: [PATCH 0086/1276] Fix #55023 --- .../parts/markers/electron-browser/markersTreeController.ts | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/src/vs/workbench/parts/markers/electron-browser/markersTreeController.ts b/src/vs/workbench/parts/markers/electron-browser/markersTreeController.ts index 8fe527107df..9a8151b2f35 100644 --- a/src/vs/workbench/parts/markers/electron-browser/markersTreeController.ts +++ b/src/vs/workbench/parts/markers/electron-browser/markersTreeController.ts @@ -19,7 +19,6 @@ import { IBulkEditService } from 'vs/editor/browser/services/bulkEditService'; import { applyCodeAction } from 'vs/editor/contrib/codeAction/codeActionCommands'; import { ICommandService } from 'vs/platform/commands/common/commands'; import { IEditorService, ACTIVE_GROUP } from 'vs/workbench/services/editor/common/editorService'; -import { localize } from 'vs/nls'; export class Controller extends WorkbenchTreeController { @@ -85,10 +84,8 @@ export class Controller extends WorkbenchTreeController { const quickFixActions = await this._getQuickFixActions(tree, element); if (quickFixActions.length) { result.push(...quickFixActions); - } else { - result.push(new Action('problems.no.fixes', localize('no fixes available', "No fixes available"), void 0, false)); + result.push(new Separator()); } - result.push(new Separator()); } const menu = this.menuService.createMenu(MenuId.ProblemsPanelContext, tree.contextKeyService); From 068ffa1f6a515fd0eb1b884a643fde760de84acf Mon Sep 17 00:00:00 2001 From: Johannes Rieken Date: Wed, 25 Jul 2018 14:55:08 +0200 Subject: [PATCH 0087/1276] fix #55020 --- src/vs/platform/list/browser/listService.ts | 26 ++++++++++----------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/src/vs/platform/list/browser/listService.ts b/src/vs/platform/list/browser/listService.ts index 9bd6cae4587..3b58b30ea21 100644 --- a/src/vs/platform/list/browser/listService.ts +++ b/src/vs/platform/list/browser/listService.ts @@ -701,26 +701,26 @@ export class HighlightingWorkbenchTree extends WorkbenchTree { private updateHighlights(pattern: string): void { // remember old selection - let defaultSelection: any[]; + let defaultSelection: any[] = []; if (!this.lastSelection && pattern) { this.lastSelection = this.getSelection(); - defaultSelection = []; } else if (this.lastSelection && !pattern) { defaultSelection = this.lastSelection; this.lastSelection = []; } - let topElement = this.renderer.updateHighlights(this, pattern); - if (topElement && pattern) { - this.reveal(topElement).then(_ => { - this.setSelection([topElement], this); - this.setFocus(topElement, this); - return this.refresh(); - }, onUnexpectedError); - } else { - this.setSelection(defaultSelection, this); - this.refresh().then(undefined, onUnexpectedError); - } + const topElement = this.renderer.updateHighlights(this, pattern); + + this.refresh().then(() => { + if (topElement && pattern) { + this.reveal(topElement, .5).then(_ => { + this.setSelection([topElement], this); + this.setFocus(topElement, this); + }); + } else { + this.setSelection(defaultSelection, this); + } + }, onUnexpectedError); } } From 2f12e413432b228ffb006da72dc0d5e3fab3a1ca Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Wed, 25 Jul 2018 06:38:03 -0700 Subject: [PATCH 0088/1276] Require libnss3 >= 3.26 to match Chromium --- resources/linux/debian/control.template | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/resources/linux/debian/control.template b/resources/linux/debian/control.template index eeaf96e0751..d84aba31105 100644 --- a/resources/linux/debian/control.template +++ b/resources/linux/debian/control.template @@ -1,7 +1,7 @@ Package: @@NAME@@ Version: @@VERSION@@ Section: devel -Depends: libnotify4, libnss3, gnupg, apt, libxkbfile1, libgconf-2-4, libsecret-1-0, libgtk-3-0 (>= 3.10.0) +Depends: libnotify4, libnss3 (>= 3.26), gnupg, apt, libxkbfile1, libgconf-2-4, libsecret-1-0, libgtk-3-0 (>= 3.10.0) Priority: optional Architecture: @@ARCHITECTURE@@ Maintainer: Microsoft Corporation @@ -12,4 +12,3 @@ Conflicts: visual-studio-@@NAME@@ Replaces: visual-studio-@@NAME@@ Description: Code editing. Redefined. Visual Studio Code is a new choice of tool that combines the simplicity of a code editor with what developers need for the core edit-build-debug cycle. See https://code.visualstudio.com/docs/setup/linux for installation instructions and FAQ. - \ No newline at end of file From 338a6dd856eaa94126c4e9c94120f19a22a524fc Mon Sep 17 00:00:00 2001 From: Johannes Rieken Date: Wed, 25 Jul 2018 15:31:07 +0200 Subject: [PATCH 0089/1276] boost weight of Escape to close picker, #54491 --- 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 5777120a0f6..56bec8cb225 100644 --- a/src/vs/workbench/browser/parts/editor/breadcrumbsControl.ts +++ b/src/vs/workbench/browser/parts/editor/breadcrumbsControl.ts @@ -441,7 +441,7 @@ KeybindingsRegistry.registerCommandAndKeybindingRule({ }); KeybindingsRegistry.registerCommandAndKeybindingRule({ id: 'breadcrumbs.selectEditor', - weight: KeybindingWeight.WorkbenchContrib, + weight: KeybindingWeight.WorkbenchContrib + 1, primary: KeyCode.Escape, secondary: [KeyMod.Shift | KeyCode.Escape], when: ContextKeyExpr.and(BreadcrumbsControl.CK_BreadcrumbsVisible, BreadcrumbsControl.CK_BreadcrumbsActive), From 7c59c2f90fc08ac4aad2e794e44083350c09e25b Mon Sep 17 00:00:00 2001 From: Johannes Rieken Date: Wed, 25 Jul 2018 16:21:27 +0200 Subject: [PATCH 0090/1276] remove tab to select items from picker, #54745 --- src/vs/platform/list/browser/listService.ts | 6 ++++-- .../browser/parts/editor/breadcrumbsControl.ts | 14 -------------- 2 files changed, 4 insertions(+), 16 deletions(-) diff --git a/src/vs/platform/list/browser/listService.ts b/src/vs/platform/list/browser/listService.ts index 3b58b30ea21..19f6c28b08a 100644 --- a/src/vs/platform/list/browser/listService.ts +++ b/src/vs/platform/list/browser/listService.ts @@ -658,16 +658,18 @@ export class HighlightingWorkbenchTree extends WorkbenchTree { //todo@joh make this command/context-key based switch (event.keyCode) { case KeyCode.DownArrow: - case KeyCode.UpArrow: + case KeyCode.Tab: this.domFocus(); + event.preventDefault(); break; case KeyCode.Enter: - case KeyCode.Tab: this.setSelection(this.getSelection()); + event.preventDefault(); break; case KeyCode.Escape: this.input.value = ''; this.domFocus(); + event.preventDefault(); break; } })); diff --git a/src/vs/workbench/browser/parts/editor/breadcrumbsControl.ts b/src/vs/workbench/browser/parts/editor/breadcrumbsControl.ts index 56bec8cb225..635755b0412 100644 --- a/src/vs/workbench/browser/parts/editor/breadcrumbsControl.ts +++ b/src/vs/workbench/browser/parts/editor/breadcrumbsControl.ts @@ -37,8 +37,6 @@ import { IEditorService } from 'vs/workbench/services/editor/common/editorServic import { IEditorGroupsService } from 'vs/workbench/services/group/common/editorGroupsService'; import { MenuRegistry, MenuId } from 'vs/platform/actions/common/actions'; import { localize } from 'vs/nls'; -import { WorkbenchListFocusContextKey, IListService } from 'vs/platform/list/browser/listService'; -import { Tree } from 'vs/base/parts/tree/browser/treeImpl'; import { CommandsRegistry } from 'vs/platform/commands/common/commands'; class Item extends BreadcrumbsItem { @@ -453,16 +451,4 @@ KeybindingsRegistry.registerCommandAndKeybindingRule({ groups.activeGroup.activeControl.focus(); } }); -KeybindingsRegistry.registerCommandAndKeybindingRule({ - id: 'breadcrumbs.pickFromTree', - weight: KeybindingWeight.WorkbenchContrib, - primary: KeyCode.Tab, - when: ContextKeyExpr.and(BreadcrumbsControl.CK_BreadcrumbsVisible, BreadcrumbsControl.CK_BreadcrumbsActive, WorkbenchListFocusContextKey), - handler(accessor) { - const list = accessor.get(IListService).lastFocusedList; - if (list instanceof Tree) { - list.setSelection([list.getFocus()]); - } - } -}); //#endregion From 79acca172a735336d990fb3e135f9d16fb613012 Mon Sep 17 00:00:00 2001 From: SteVen Batten <6561887+sbatten@users.noreply.github.com> Date: Wed, 25 Jul 2018 07:36:51 -0700 Subject: [PATCH 0091/1276] updating menu behavior for when to select first entry (#54953) --- src/vs/base/browser/ui/actionbar/actionbar.ts | 2 ++ src/vs/base/browser/ui/menu/menu.ts | 16 ++++++++-------- .../contextview/browser/contextMenuHandler.ts | 2 +- .../browser/parts/menubar/menubarPart.ts | 10 +++++----- 4 files changed, 16 insertions(+), 14 deletions(-) diff --git a/src/vs/base/browser/ui/actionbar/actionbar.ts b/src/vs/base/browser/ui/actionbar/actionbar.ts index 72742b71751..9a121effc1e 100644 --- a/src/vs/base/browser/ui/actionbar/actionbar.ts +++ b/src/vs/base/browser/ui/actionbar/actionbar.ts @@ -408,6 +408,8 @@ export class ActionBar implements IActionRunner { this.domNode = document.createElement('div'); this.domNode.className = 'monaco-action-bar'; + this.domNode.tabIndex = 0; + if (options.animated !== false) { DOM.addClass(this.domNode, 'animated'); } diff --git a/src/vs/base/browser/ui/menu/menu.ts b/src/vs/base/browser/ui/menu/menu.ts index a2cb23d310e..f6698809a31 100644 --- a/src/vs/base/browser/ui/menu/menu.ts +++ b/src/vs/base/browser/ui/menu/menu.ts @@ -93,9 +93,9 @@ export class Menu { return this.actionBar.onDidBlur; } - public focus() { + public focus(selectFirst = true) { if (this.actionBar) { - this.actionBar.focus(true); + this.actionBar.focus(selectFirst); } } @@ -256,7 +256,7 @@ class SubmenuActionItem extends MenuActionItem { this.showScheduler = new RunOnceScheduler(() => { if (this.mouseOver) { this.cleanupExistingSubmenu(false); - this.createSubmenu(); + this.createSubmenu(false); } }, 250); @@ -280,7 +280,7 @@ class SubmenuActionItem extends MenuActionItem { if (event.equals(KeyCode.RightArrow)) { EventHelper.stop(e, true); - this.createSubmenu(); + this.createSubmenu(true); } }); @@ -310,7 +310,7 @@ class SubmenuActionItem extends MenuActionItem { // stop clicking from trying to run an action EventHelper.stop(e, true); - this.createSubmenu(); + this.createSubmenu(false); } private cleanupExistingSubmenu(force: boolean) { @@ -325,7 +325,7 @@ class SubmenuActionItem extends MenuActionItem { } } - private createSubmenu() { + private createSubmenu(selectFirstItem = true) { if (!this.parentData.submenu) { this.submenuContainer = $(this.builder).div({ class: 'monaco-submenu menubar-menu-items-holder context-view' }); @@ -356,11 +356,11 @@ class SubmenuActionItem extends MenuActionItem { this.parentData.submenu = new Menu(this.submenuContainer.getHTMLElement(), this.submenuActions, this.submenuOptions); - this.parentData.submenu.focus(); + this.parentData.submenu.focus(selectFirstItem); this.mysubmenu = this.parentData.submenu; } else { - this.parentData.submenu.focus(); + this.parentData.submenu.focus(false); } } diff --git a/src/vs/platform/contextview/browser/contextMenuHandler.ts b/src/vs/platform/contextview/browser/contextMenuHandler.ts index 05e1e4439dd..6a39c62dbc0 100644 --- a/src/vs/platform/contextview/browser/contextMenuHandler.ts +++ b/src/vs/platform/contextview/browser/contextMenuHandler.ts @@ -82,7 +82,7 @@ export class ContextMenuHandler { menu.onDidCancel(() => this.contextViewService.hideContextView(true), null, menuDisposables); menu.onDidBlur(() => this.contextViewService.hideContextView(true), null, menuDisposables); - menu.focus(); + menu.focus(!!delegate.autoSelectFirstItem); return combinedDisposable([...menuDisposables, menu]); }, diff --git a/src/vs/workbench/browser/parts/menubar/menubarPart.ts b/src/vs/workbench/browser/parts/menubar/menubarPart.ts index b204fb7626c..10b320cd478 100644 --- a/src/vs/workbench/browser/parts/menubar/menubarPart.ts +++ b/src/vs/workbench/browser/parts/menubar/menubarPart.ts @@ -298,7 +298,7 @@ export class MenubarPart extends Part { } if (this.focusedMenu) { - this.showCustomMenu(this.focusedMenu.index); + this.showCustomMenu(this.focusedMenu.index, !!this._modifierKeyStatus && this._modifierKeyStatus.altKey); } break; } @@ -664,7 +664,7 @@ export class MenubarPart extends Part { this.setUnfocusedState(); } else { this.cleanupCustomMenu(); - this.showCustomMenu(menuIndex); + this.showCustomMenu(menuIndex, !!this._modifierKeyStatus && this._modifierKeyStatus.altKey); } } else { this.focusedMenu = { index: menuIndex }; @@ -679,7 +679,7 @@ export class MenubarPart extends Part { if (this.isOpen && !this.isCurrentMenu(menuIndex)) { this.customMenus[menuIndex].buttonElement.domFocus(); this.cleanupCustomMenu(); - this.showCustomMenu(menuIndex); + this.showCustomMenu(menuIndex, false); } else if (this.isFocused && !this.isOpen) { this.focusedMenu = { index: menuIndex }; this.customMenus[menuIndex].buttonElement.domFocus(); @@ -881,7 +881,7 @@ export class MenubarPart extends Part { } } - private showCustomMenu(menuIndex: number): void { + private showCustomMenu(menuIndex: number, selectFirst = true): void { const customMenu = this.customMenus[menuIndex]; let menuHolder = $(customMenu.buttonElement).div({ class: 'menubar-menu-items-holder' }); @@ -911,7 +911,7 @@ export class MenubarPart extends Part { }, 100); })); - menuWidget.focus(); + menuWidget.focus(selectFirst); this.focusedMenu = { index: menuIndex, From aa6dd3f14f118812b98954180bea54943340f088 Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Wed, 25 Jul 2018 07:13:44 -0700 Subject: [PATCH 0092/1276] Label Windows key as super on Linux Fixes #53002 --- src/vs/base/common/keybindingLabels.ts | 14 ++++++++++++++ .../test/common/keybindingLabels.test.ts | 18 +++++++++--------- 2 files changed, 23 insertions(+), 9 deletions(-) diff --git a/src/vs/base/common/keybindingLabels.ts b/src/vs/base/common/keybindingLabels.ts index 29916e201d4..6cb492d858c 100644 --- a/src/vs/base/common/keybindingLabels.ts +++ b/src/vs/base/common/keybindingLabels.ts @@ -59,6 +59,13 @@ export const UILabelProvider = new ModifierLabelProvider( altKey: nls.localize({ key: 'altKey', comment: ['This is the short form for the Alt key on the keyboard'] }, "Alt"), metaKey: nls.localize({ key: 'windowsKey', comment: ['This is the short form for the Windows key on the keyboard'] }, "Windows"), separator: '+', + }, + { + ctrlKey: nls.localize({ key: 'ctrlKey', comment: ['This is the short form for the Control key on the keyboard'] }, "Ctrl"), + shiftKey: nls.localize({ key: 'shiftKey', comment: ['This is the short form for the Shift key on the keyboard'] }, "Shift"), + altKey: nls.localize({ key: 'altKey', comment: ['This is the short form for the Alt key on the keyboard'] }, "Alt"), + metaKey: nls.localize({ key: 'superKey', comment: ['This is the short form for the Super key on the keyboard'] }, "Super"), + separator: '+', } ); @@ -79,6 +86,13 @@ export const AriaLabelProvider = new ModifierLabelProvider( altKey: nls.localize({ key: 'altKey.long', comment: ['This is the long form for the Alt key on the keyboard'] }, "Alt"), metaKey: nls.localize({ key: 'windowsKey.long', comment: ['This is the long form for the Windows key on the keyboard'] }, "Windows"), separator: '+', + }, + { + ctrlKey: nls.localize({ key: 'ctrlKey.long', comment: ['This is the long form for the Control key on the keyboard'] }, "Control"), + shiftKey: nls.localize({ key: 'shiftKey.long', comment: ['This is the long form for the Shift key on the keyboard'] }, "Shift"), + altKey: nls.localize({ key: 'altKey.long', comment: ['This is the long form for the Alt key on the keyboard'] }, "Alt"), + metaKey: nls.localize({ key: 'superKey.long', comment: ['This is the long form for the Super key on the keyboard'] }, "Super"), + separator: '+', } ); diff --git a/src/vs/platform/keybinding/test/common/keybindingLabels.test.ts b/src/vs/platform/keybinding/test/common/keybindingLabels.test.ts index 19f285354cc..25dc83e6d4d 100644 --- a/src/vs/platform/keybinding/test/common/keybindingLabels.test.ts +++ b/src/vs/platform/keybinding/test/common/keybindingLabels.test.ts @@ -55,24 +55,24 @@ suite('KeybindingLabels', () => { assertUSLabel(OperatingSystem.Linux, KeyMod.CtrlCmd | KeyCode.KEY_A, 'Ctrl+A'); assertUSLabel(OperatingSystem.Linux, KeyMod.Shift | KeyCode.KEY_A, 'Shift+A'); assertUSLabel(OperatingSystem.Linux, KeyMod.Alt | KeyCode.KEY_A, 'Alt+A'); - assertUSLabel(OperatingSystem.Linux, KeyMod.WinCtrl | KeyCode.KEY_A, 'Windows+A'); + assertUSLabel(OperatingSystem.Linux, KeyMod.WinCtrl | KeyCode.KEY_A, 'Super+A'); // two modifiers assertUSLabel(OperatingSystem.Linux, KeyMod.CtrlCmd | KeyMod.Shift | KeyCode.KEY_A, 'Ctrl+Shift+A'); assertUSLabel(OperatingSystem.Linux, KeyMod.CtrlCmd | KeyMod.Alt | KeyCode.KEY_A, 'Ctrl+Alt+A'); - assertUSLabel(OperatingSystem.Linux, KeyMod.CtrlCmd | KeyMod.WinCtrl | KeyCode.KEY_A, 'Ctrl+Windows+A'); + assertUSLabel(OperatingSystem.Linux, KeyMod.CtrlCmd | KeyMod.WinCtrl | KeyCode.KEY_A, 'Ctrl+Super+A'); assertUSLabel(OperatingSystem.Linux, KeyMod.Shift | KeyMod.Alt | KeyCode.KEY_A, 'Shift+Alt+A'); - assertUSLabel(OperatingSystem.Linux, KeyMod.Shift | KeyMod.WinCtrl | KeyCode.KEY_A, 'Shift+Windows+A'); - assertUSLabel(OperatingSystem.Linux, KeyMod.Alt | KeyMod.WinCtrl | KeyCode.KEY_A, 'Alt+Windows+A'); + assertUSLabel(OperatingSystem.Linux, KeyMod.Shift | KeyMod.WinCtrl | KeyCode.KEY_A, 'Shift+Super+A'); + assertUSLabel(OperatingSystem.Linux, KeyMod.Alt | KeyMod.WinCtrl | KeyCode.KEY_A, 'Alt+Super+A'); // three modifiers assertUSLabel(OperatingSystem.Linux, KeyMod.CtrlCmd | KeyMod.Shift | KeyMod.Alt | KeyCode.KEY_A, 'Ctrl+Shift+Alt+A'); - assertUSLabel(OperatingSystem.Linux, KeyMod.CtrlCmd | KeyMod.Shift | KeyMod.WinCtrl | KeyCode.KEY_A, 'Ctrl+Shift+Windows+A'); - assertUSLabel(OperatingSystem.Linux, KeyMod.CtrlCmd | KeyMod.Alt | KeyMod.WinCtrl | KeyCode.KEY_A, 'Ctrl+Alt+Windows+A'); - assertUSLabel(OperatingSystem.Linux, KeyMod.Shift | KeyMod.Alt | KeyMod.WinCtrl | KeyCode.KEY_A, 'Shift+Alt+Windows+A'); + assertUSLabel(OperatingSystem.Linux, KeyMod.CtrlCmd | KeyMod.Shift | KeyMod.WinCtrl | KeyCode.KEY_A, 'Ctrl+Shift+Super+A'); + assertUSLabel(OperatingSystem.Linux, KeyMod.CtrlCmd | KeyMod.Alt | KeyMod.WinCtrl | KeyCode.KEY_A, 'Ctrl+Alt+Super+A'); + assertUSLabel(OperatingSystem.Linux, KeyMod.Shift | KeyMod.Alt | KeyMod.WinCtrl | KeyCode.KEY_A, 'Shift+Alt+Super+A'); // four modifiers - assertUSLabel(OperatingSystem.Linux, KeyMod.CtrlCmd | KeyMod.Shift | KeyMod.Alt | KeyMod.WinCtrl | KeyCode.KEY_A, 'Ctrl+Shift+Alt+Windows+A'); + assertUSLabel(OperatingSystem.Linux, KeyMod.CtrlCmd | KeyMod.Shift | KeyMod.Alt | KeyMod.WinCtrl | KeyCode.KEY_A, 'Ctrl+Shift+Alt+Super+A'); // chord assertUSLabel(OperatingSystem.Linux, KeyChord(KeyMod.CtrlCmd | KeyCode.KEY_A, KeyMod.CtrlCmd | KeyCode.KEY_B), 'Ctrl+A Ctrl+B'); @@ -122,7 +122,7 @@ suite('KeybindingLabels', () => { } assertAriaLabel(OperatingSystem.Windows, KeyMod.CtrlCmd | KeyMod.Shift | KeyMod.Alt | KeyMod.WinCtrl | KeyCode.KEY_A, 'Control+Shift+Alt+Windows+A'); - assertAriaLabel(OperatingSystem.Linux, KeyMod.CtrlCmd | KeyMod.Shift | KeyMod.Alt | KeyMod.WinCtrl | KeyCode.KEY_A, 'Control+Shift+Alt+Windows+A'); + assertAriaLabel(OperatingSystem.Linux, KeyMod.CtrlCmd | KeyMod.Shift | KeyMod.Alt | KeyMod.WinCtrl | KeyCode.KEY_A, 'Control+Shift+Alt+Super+A'); assertAriaLabel(OperatingSystem.Macintosh, KeyMod.CtrlCmd | KeyMod.Shift | KeyMod.Alt | KeyMod.WinCtrl | KeyCode.KEY_A, 'Control+Shift+Alt+Command+A'); }); From 0488fb21191cb3feefadfdb20a60afec195c911b Mon Sep 17 00:00:00 2001 From: Johannes Rieken Date: Wed, 25 Jul 2018 16:38:23 +0200 Subject: [PATCH 0093/1276] don't use Shift-keybindings but Alt (mac) and Ctrl (windows/linux), #54745 --- .../parts/editor/breadcrumbsControl.ts | 21 ++++++++++++++----- 1 file changed, 16 insertions(+), 5 deletions(-) diff --git a/src/vs/workbench/browser/parts/editor/breadcrumbsControl.ts b/src/vs/workbench/browser/parts/editor/breadcrumbsControl.ts index 635755b0412..d8ff4674fd9 100644 --- a/src/vs/workbench/browser/parts/editor/breadcrumbsControl.ts +++ b/src/vs/workbench/browser/parts/editor/breadcrumbsControl.ts @@ -391,7 +391,11 @@ KeybindingsRegistry.registerCommandAndKeybindingRule({ id: 'breadcrumbs.focusNext', weight: KeybindingWeight.WorkbenchContrib, primary: KeyCode.RightArrow, - secondary: [KeyMod.Shift | KeyCode.RightArrow], + secondary: [KeyMod.CtrlCmd | KeyCode.RightArrow], + mac: { + primary: KeyCode.RightArrow, + secondary: [KeyMod.Alt | KeyCode.RightArrow], + }, when: ContextKeyExpr.and(BreadcrumbsControl.CK_BreadcrumbsVisible, BreadcrumbsControl.CK_BreadcrumbsActive), handler(accessor) { const groups = accessor.get(IEditorGroupsService); @@ -403,7 +407,11 @@ KeybindingsRegistry.registerCommandAndKeybindingRule({ id: 'breadcrumbs.focusPrevious', weight: KeybindingWeight.WorkbenchContrib, primary: KeyCode.LeftArrow, - secondary: [KeyMod.Shift | KeyCode.LeftArrow], + secondary: [KeyMod.CtrlCmd | KeyCode.LeftArrow], + mac: { + primary: KeyCode.LeftArrow, + secondary: [KeyMod.Alt | KeyCode.LeftArrow], + }, when: ContextKeyExpr.and(BreadcrumbsControl.CK_BreadcrumbsVisible, BreadcrumbsControl.CK_BreadcrumbsActive), handler(accessor) { const groups = accessor.get(IEditorGroupsService); @@ -427,8 +435,12 @@ KeybindingsRegistry.registerCommandAndKeybindingRule({ KeybindingsRegistry.registerCommandAndKeybindingRule({ id: 'breadcrumbs.revealFocused', weight: KeybindingWeight.WorkbenchContrib, - primary: KeyMod.Shift | KeyCode.Enter, - secondary: [KeyCode.Space], + primary: KeyCode.Space, + secondary: [KeyMod.CtrlCmd | KeyCode.Enter], + mac: { + primary: KeyCode.Space, + secondary: [KeyMod.Alt | KeyCode.Enter], + }, when: ContextKeyExpr.and(BreadcrumbsControl.CK_BreadcrumbsVisible, BreadcrumbsControl.CK_BreadcrumbsActive), handler(accessor) { const groups = accessor.get(IEditorGroupsService); @@ -441,7 +453,6 @@ KeybindingsRegistry.registerCommandAndKeybindingRule({ id: 'breadcrumbs.selectEditor', weight: KeybindingWeight.WorkbenchContrib + 1, primary: KeyCode.Escape, - secondary: [KeyMod.Shift | KeyCode.Escape], when: ContextKeyExpr.and(BreadcrumbsControl.CK_BreadcrumbsVisible, BreadcrumbsControl.CK_BreadcrumbsActive), handler(accessor) { const groups = accessor.get(IEditorGroupsService); From 9c4e41fc6a5e9ada99cf699e588f3f241a3b659f Mon Sep 17 00:00:00 2001 From: Johannes Rieken Date: Wed, 25 Jul 2018 16:57:59 +0200 Subject: [PATCH 0094/1276] use underline for selected/focused items, #54745 --- .../browser/parts/editor/breadcrumbsControl.ts | 1 + .../browser/parts/editor/media/breadcrumbscontrol.css | 10 ++++++++++ 2 files changed, 11 insertions(+) diff --git a/src/vs/workbench/browser/parts/editor/breadcrumbsControl.ts b/src/vs/workbench/browser/parts/editor/breadcrumbsControl.ts index d8ff4674fd9..1fc3c36d00b 100644 --- a/src/vs/workbench/browser/parts/editor/breadcrumbsControl.ts +++ b/src/vs/workbench/browser/parts/editor/breadcrumbsControl.ts @@ -85,6 +85,7 @@ class Item extends BreadcrumbsItem { // has outline element but not in one let label = document.createElement('div'); label.innerHTML = '…'; + label.className = 'hint-more'; container.appendChild(label); } else if (this.element instanceof OutlineGroup) { diff --git a/src/vs/workbench/browser/parts/editor/media/breadcrumbscontrol.css b/src/vs/workbench/browser/parts/editor/media/breadcrumbscontrol.css index 7b80fb89d06..2aa84dbc6ec 100644 --- a/src/vs/workbench/browser/parts/editor/media/breadcrumbscontrol.css +++ b/src/vs/workbench/browser/parts/editor/media/breadcrumbscontrol.css @@ -11,6 +11,16 @@ opacity: .8; } +.monaco-workbench>.part.editor>.content .editor-group-container .breadcrumbs-control .monaco-breadcrumb-item.selected .monaco-icon-label, +.monaco-workbench>.part.editor>.content .editor-group-container .breadcrumbs-control .monaco-breadcrumb-item.focused .monaco-icon-label { + text-decoration-line: underline; +} + +.monaco-workbench>.part.editor>.content .editor-group-container .breadcrumbs-control .monaco-breadcrumb-item.selected .hint-more, +.monaco-workbench>.part.editor>.content .editor-group-container .breadcrumbs-control .monaco-breadcrumb-item.focused .hint-more { + text-decoration-line: underline; +} + /* todo@joh move somewhere else */ .monaco-workbench .monaco-breadcrumbs-picker .highlighting-tree { From 06b4624aa8f240a13ccabb896565e55f6444dc63 Mon Sep 17 00:00:00 2001 From: Miguel Solorio Date: Wed, 25 Jul 2018 08:02:01 -0700 Subject: [PATCH 0095/1276] Show the "method" icon for constructors --- .../contrib/documentSymbols/media/symbol-icons.css | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/vs/editor/contrib/documentSymbols/media/symbol-icons.css b/src/vs/editor/contrib/documentSymbols/media/symbol-icons.css index 3232bc55f4f..76d67d5efcc 100644 --- a/src/vs/editor/contrib/documentSymbols/media/symbol-icons.css +++ b/src/vs/editor/contrib/documentSymbols/media/symbol-icons.css @@ -111,6 +111,15 @@ background-image: url('Class_16x_darkp.svg'); } +/* constructor */ +.monaco-workbench .symbol-icon.constructor { + background-image: url('Method_16x.svg'); +} +.vs-dark .monaco-workbench .symbol-icon.constructor, +.hc-black .monaco-workbench .symbol-icon.constructor { + background-image: url('Method_16x_darkp.svg'); +} + /* file */ .monaco-workbench .symbol-icon.file { background-image: url('Document_16x.svg'); From dea477a64b3da5fff066f3051bba57478deffbe5 Mon Sep 17 00:00:00 2001 From: isidor Date: Wed, 25 Jul 2018 17:33:56 +0200 Subject: [PATCH 0096/1276] uriDisplayService --- src/vs/base/common/labels.ts | 64 +++-------- .../platform/uriDisplay/common/uriDisplay.ts | 104 ++++++++++++++++++ .../electron-browser/files.contribution.ts | 11 -- .../files/electron-browser/fileService.ts | 6 + 4 files changed, 124 insertions(+), 61 deletions(-) create mode 100644 src/vs/platform/uriDisplay/common/uriDisplay.ts diff --git a/src/vs/base/common/labels.ts b/src/vs/base/common/labels.ts index e88d8ea6ad7..15d9a56d269 100644 --- a/src/vs/base/common/labels.ts +++ b/src/vs/base/common/labels.ts @@ -5,8 +5,8 @@ 'use strict'; import URI from 'vs/base/common/uri'; -import { nativeSep, basename as pathsBasename, sep } from 'vs/base/common/paths'; -import { endsWith, startsWithIgnoreCase, rtrim, startsWith } from 'vs/base/common/strings'; +import { nativeSep, normalize, basename as pathsBasename, sep } from 'vs/base/common/paths'; +import { endsWith, ltrim, startsWithIgnoreCase, rtrim, startsWith } from 'vs/base/common/strings'; import { Schemas } from 'vs/base/common/network'; import { isLinux, isWindows, isMacintosh } from 'vs/base/common/platform'; import { isEqual } from 'vs/base/common/resources'; @@ -22,11 +22,6 @@ export interface IUserHomeProvider { userHome: string; } -function resourceToLabel(resource: URI, labelProvider: UriLabelProvider, ): string { - // TODO@Isidor take into account labelProvider.uriDisplay.label and convert the resource into string representation - return ''; -} - /** * @param resource for which to compute the path label * @param userHomeProvider if a resource has a file schema userHomeProvider is used for tildifiying the label @@ -41,11 +36,6 @@ export function getPathLabel(resource: URI | string, userHomeProvider: IUserHome resource = URI.file(resource); } - const labelProvider = UriLabelProviderRegistry.getUriLabelProvider(resource.scheme); - if (!labelProvider) { - return resource.with({ query: null, fragment: null }).toString(true); - } - // return early if we can resolve a relative path label from the root const baseResource = rootProvider ? rootProvider.getWorkspaceFolder(resource) : null; if (baseResource) { @@ -55,32 +45,34 @@ export function getPathLabel(resource: URI | string, userHomeProvider: IUserHome if (isEqual(baseResource.uri, resource, !isLinux)) { pathLabel = ''; // no label if paths are identical } else { - const baseResourceLabel = resourceToLabel(baseResource.uri, labelProvider); - pathLabel = resourceToLabel(resource, labelProvider).substr(baseResourceLabel.length); + pathLabel = normalize(ltrim(resource.path.substr(baseResource.uri.path.length), sep), true); } if (hasMultipleRoots) { - const rootName = (baseResource && baseResource.name) ? baseResource.name : pathsBasename(baseResource.uri.path); + const rootName = (baseResource && baseResource.name) ? baseResource.name : pathsBasename(baseResource.uri.fsPath); pathLabel = pathLabel ? (rootName + ' • ' + pathLabel) : rootName; // always show root basename if there are multiple } return pathLabel; } + // return if the resource is neither file:// nor untitled:// and no baseResource was provided + if (resource.scheme !== Schemas.file && resource.scheme !== Schemas.untitled) { + return resource.with({ query: null, fragment: null }).toString(true); + } - - let label = resourceToLabel(resource, labelProvider); // convert c:\something => C:\something - if (labelProvider.uriDisplay.normalizeDriveLetter && hasDriveLetter(label)) { - label = normalizeDriveLetter(label); + if (hasDriveLetter(resource.fsPath)) { + return normalize(normalizeDriveLetter(resource.fsPath), true); } // normalize and tildify (macOS, Linux only) - if (labelProvider.uriDisplay.tildify && userHomeProvider) { - label = tildify(label, userHomeProvider.userHome); + let res = normalize(resource.fsPath, true); + if (!isWindows && userHomeProvider) { + res = tildify(res, userHomeProvider.userHome); } - return label; + return res; } export function getBaseLabel(resource: URI | string): string { @@ -392,31 +384,3 @@ export function mnemonicButtonLabel(label: string): string { export function unmnemonicLabel(label: string): string { return label.replace(/&/g, '&&'); } - -export interface UriLabelProvider { - schema: string; - label?: string; - uriDisplay: { - label: string; - forwardSlash?: boolean; - tildify?: boolean; - normalizeDriveLetter?: boolean; - }; -} - -export interface IUriLabelProviderRegistry { - registerUriLabelProvider(descriptor: UriLabelProvider): void; - getUriLabelProvider(scheme: string): UriLabelProvider; -} - -export const UriLabelProviderRegistry: IUriLabelProviderRegistry = new class UriLabelProviderRegistry implements IUriLabelProviderRegistry { - private uriLabelProviders = new Map(); - - registerUriLabelProvider(descriptor: UriLabelProvider): void { - this.uriLabelProviders.set(descriptor.schema, descriptor); - } - - getUriLabelProvider(scheme: string): UriLabelProvider { - return this.uriLabelProviders.get(scheme); - } -}; diff --git a/src/vs/platform/uriDisplay/common/uriDisplay.ts b/src/vs/platform/uriDisplay/common/uriDisplay.ts new file mode 100644 index 00000000000..fcf10ee1a73 --- /dev/null +++ b/src/vs/platform/uriDisplay/common/uriDisplay.ts @@ -0,0 +1,104 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import URI from 'vs/base/common/uri'; +import { IDisposable } from 'vs/base/common/lifecycle'; +import { IEnvironmentService } from 'vs/platform/environment/common/environment'; +import { IWorkspaceContextService } from 'vs/platform/workspace/common/workspace'; +import { registerSingleton } from 'vs/platform/instantiation/common/extensions'; +import { createDecorator } from 'vs/platform/instantiation/common/instantiation'; +import { isEqual, basenameOrAuthority } from 'vs/base/common/resources'; +import { isLinux, isWindows } from 'vs/base/common/platform'; +import { tildify, normalizeDriveLetter } from 'vs/base/common/labels'; + +export interface IUriDisplayService { + getLabel(resource: URI, relative: boolean): string; + registerFormater(schema: string, formater: UriDisplayRules): IDisposable; +} + +export interface UriDisplayRules { + label: string; + forwardSlash?: boolean; + tildify?: boolean; + normalizeDriveLetter?: boolean; +} + +const URI_DISPLAY_SERVICE_ID = 'uriDisplay'; + +function hasDriveLetter(path: string): boolean { + return isWindows && path && path[1] === ':'; +} + +class UriDisplayService implements IUriDisplayService { + public _serviceBrand: any; + private formaters = new Map(); + + constructor( + @IEnvironmentService private environmentService: IEnvironmentService, + @IWorkspaceContextService private contextService: IWorkspaceContextService + ) { } + + getLabel(resource: URI, relative: boolean): string { + if (!resource) { + return undefined; + } + + if (relative) { + const hasMultipleRoots = this.contextService.getWorkspace().folders.length > 1; + const baseResource = this.contextService.getWorkspaceFolder(resource); + + let pathLabel: string; + if (isEqual(baseResource.uri, resource, !isLinux)) { + pathLabel = ''; // no label if paths are identical + } else { + const baseResourceLabel = this.formatUri(baseResource.uri); + pathLabel = this.formatUri(resource).substring(baseResourceLabel.length); + } + + if (hasMultipleRoots) { + const rootName = (baseResource && baseResource.name) ? baseResource.name : basenameOrAuthority(baseResource.uri); + pathLabel = pathLabel ? (rootName + ' • ' + pathLabel) : rootName; // always show root basename if there are multiple + } + + return pathLabel; + } + + return this.formatUri(resource); + } + + registerFormater(scheme: string, formater: UriDisplayRules): IDisposable { + this.formaters.set(scheme, formater); + + return { + dispose: () => this.formaters.delete(scheme) + }; + } + + private formatUri(resource: URI): string { + const formater = this.formaters.get(resource.scheme); + if (!formater) { + return resource.with({ query: null, fragment: null }).toString(true); + } + + // TODO@isidor transform + let label = resource.path; + + // convert c:\something => C:\something + if (formater.normalizeDriveLetter && hasDriveLetter(label)) { + label = normalizeDriveLetter(label); + } + + // normalize and tildify (macOS, Linux only) + if (formater.tildify) { + label = tildify(label, this.environmentService.userHome); + } + + return label; + } +} + +// register service +const IUriDisplayService = createDecorator(URI_DISPLAY_SERVICE_ID); +registerSingleton(IUriDisplayService, UriDisplayService); diff --git a/src/vs/workbench/parts/files/electron-browser/files.contribution.ts b/src/vs/workbench/parts/files/electron-browser/files.contribution.ts index 24a23202664..c684a9a1e73 100644 --- a/src/vs/workbench/parts/files/electron-browser/files.contribution.ts +++ b/src/vs/workbench/parts/files/electron-browser/files.contribution.ts @@ -34,7 +34,6 @@ import { DataUriEditorInput } from 'vs/workbench/common/editor/dataUriEditorInpu import { LifecyclePhase } from 'vs/platform/lifecycle/common/lifecycle'; import { IEditorService } from 'vs/workbench/services/editor/common/editorService'; import { IEditorGroupsService } from 'vs/workbench/services/group/common/editorGroupsService'; -import { UriLabelProviderRegistry } from 'vs/base/common/labels'; // Viewlet Action export class OpenExplorerViewletAction extends ToggleViewletAction { @@ -382,13 +381,3 @@ MenuRegistry.appendMenuItem(MenuId.MenubarViewMenu, { }, order: 1 }); - -UriLabelProviderRegistry.registerUriLabelProvider({ - schema: 'file', - uriDisplay: { - label: '${path}', - forwardSlash: !platform.isWindows, - tildify: !platform.isWindows, - normalizeDriveLetter: platform.isWindows - } -}); diff --git a/src/vs/workbench/services/files/electron-browser/fileService.ts b/src/vs/workbench/services/files/electron-browser/fileService.ts index b91d4371d27..3c9a106b404 100644 --- a/src/vs/workbench/services/files/electron-browser/fileService.ts +++ b/src/vs/workbench/services/files/electron-browser/fileService.ts @@ -121,6 +121,12 @@ export class FileService extends Disposable implements IFileService { this.fileChangesWatchDelayer = new ThrottledDelayer(FileService.FS_EVENT_DELAY); this.undeliveredRawFileChangesEvents = []; + // this.toDispose.push(uriDisplayService.registerFormater(Schemas.file, { + // label: '${path}', + // forwardSlash: !isWindows, + // tildify: !isWindows, + // normalizeDriveLetter: isWindows + // })); this._encoding = new ResourceEncodings(textResourceConfigurationService, environmentService, contextService, this.options.encodingOverride); this.registerListeners(); From 0d45ae7a334ba0398014a4afb02a19b5212f9e4c Mon Sep 17 00:00:00 2001 From: isidor Date: Wed, 25 Jul 2018 17:57:46 +0200 Subject: [PATCH 0097/1276] If the restart is automatic disconnect, otherwise send the terminate signal fixes #55064 --- .../debug/electron-browser/debugService.ts | 11 +++--- .../debug/electron-browser/rawDebugSession.ts | 36 +++++++++---------- 2 files changed, 24 insertions(+), 23 deletions(-) diff --git a/src/vs/workbench/parts/debug/electron-browser/debugService.ts b/src/vs/workbench/parts/debug/electron-browser/debugService.ts index 637e1aed9df..cdcc11ca1c2 100644 --- a/src/vs/workbench/parts/debug/electron-browser/debugService.ts +++ b/src/vs/workbench/parts/debug/electron-browser/debugService.ts @@ -166,7 +166,7 @@ export class DebugService implements debug.IDebugService { }); } else { const root = raw.root; - raw.dispose(); + raw.disconnect().done(undefined, errors.onUnexpectedError); this.doCreateSession(root, { resolved: session.configuration, unresolved: session.unresolvedConfiguration }, session.getId()); } @@ -291,7 +291,7 @@ export class DebugService implements debug.IDebugService { return raw.configurationDone().done(null, e => { // Disconnect the debug session on configuration done error #10596 if (raw) { - raw.dispose(); + raw.disconnect().done(undefined, errors.onUnexpectedError); } this.notificationService.error(e.message); }); @@ -341,7 +341,7 @@ export class DebugService implements debug.IDebugService { if (event.body && event.body.restart && session) { this.restartSession(session, event.body.restart).done(null, err => this.notificationService.error(err.message)); } else { - raw.dispose(); + raw.disconnect().done(undefined, errors.onUnexpectedError); } } })); @@ -973,7 +973,7 @@ export class DebugService implements debug.IDebugService { this.telemetryService.publicLog('debugMisconfiguration', { type: resolved ? resolved.type : undefined, error: errorMessage }); this.updateStateAndEmit(raw.getId(), debug.State.Inactive); if (!raw.disconnected) { - raw.dispose(); + raw.disconnect(); } else if (session) { this.model.removeSession(session.getId()); } @@ -1110,7 +1110,8 @@ export class DebugService implements debug.IDebugService { // Do not run preLaunch and postDebug tasks for automatic restarts this.skipRunningTask = !!restartData; - return session.raw.terminate(true).then(() => { + // If the restart is automatic disconnect, otherwise send the terminate signal #55064 + return (!restartData ? (session.raw).disconnect(true) : session.raw.terminate(true)).then(() => { if (strings.equalsIgnoreCase(session.configuration.type, 'extensionHost') && session.raw.root) { return this.broadcastService.broadcast({ channel: EXTENSION_RELOAD_BROADCAST_CHANNEL, diff --git a/src/vs/workbench/parts/debug/electron-browser/rawDebugSession.ts b/src/vs/workbench/parts/debug/electron-browser/rawDebugSession.ts index a2bf801d4cc..1e7a2fd9db2 100644 --- a/src/vs/workbench/parts/debug/electron-browser/rawDebugSession.ts +++ b/src/vs/workbench/parts/debug/electron-browser/rawDebugSession.ts @@ -348,8 +348,7 @@ export class RawDebugSession implements IRawSession { return this.send('terminate', { restart }); } - this.dispose(restart); - return TPromise.as(null); + return this.disconnect(restart); } public setBreakpoints(args: DebugProtocol.SetBreakpointsArguments): TPromise { @@ -475,24 +474,25 @@ export class RawDebugSession implements IRawSession { }); } - public dispose(restart = false): void { + public disconnect(restart = false): TPromise { if (this.disconnected) { - this.stopServer().done(undefined, errors.onUnexpectedError); - } else { - - // Cancel all sent promises on disconnect so debug trees are not left in a broken state #3666. - // Give a 1s timeout to give a chance for some promises to complete. - setTimeout(() => { - this.sentPromises.forEach(p => p && p.cancel()); - this.sentPromises = []; - }, 1000); - - if (this.debugAdapter && !this.disconnected) { - // point of no return: from now on don't report any errors - this.disconnected = true; - this.send('disconnect', { restart }, false).then(() => this.stopServer(), () => this.stopServer()).done(undefined, errors.onUnexpectedError); - } + return this.stopServer(); } + + // Cancel all sent promises on disconnect so debug trees are not left in a broken state #3666. + // Give a 1s timeout to give a chance for some promises to complete. + setTimeout(() => { + this.sentPromises.forEach(p => p && p.cancel()); + this.sentPromises = []; + }, 1000); + + if (this.debugAdapter && !this.disconnected) { + // point of no return: from now on don't report any errors + this.disconnected = true; + return this.send('disconnect', { restart }, false).then(() => this.stopServer(), () => this.stopServer()); + } + + return TPromise.as(null); } private stopServer(): TPromise { From 3175eab45bb8d1696e423d82198b27e089e97d1a Mon Sep 17 00:00:00 2001 From: Rob Lourens Date: Thu, 19 Jul 2018 10:08:50 -0700 Subject: [PATCH 0098/1276] Initial exclude control --- .../browser/media/action-remove-dark.svg | 1 + .../browser/media/action-remove.svg | 1 + .../browser/media/settingsEditor2.css | 99 +++++- .../parts/preferences/browser/settingsTree.ts | 323 +++++++++++++++++- 4 files changed, 417 insertions(+), 7 deletions(-) create mode 100644 src/vs/workbench/parts/preferences/browser/media/action-remove-dark.svg create mode 100644 src/vs/workbench/parts/preferences/browser/media/action-remove.svg diff --git a/src/vs/workbench/parts/preferences/browser/media/action-remove-dark.svg b/src/vs/workbench/parts/preferences/browser/media/action-remove-dark.svg new file mode 100644 index 00000000000..751e89b3b02 --- /dev/null +++ b/src/vs/workbench/parts/preferences/browser/media/action-remove-dark.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/vs/workbench/parts/preferences/browser/media/action-remove.svg b/src/vs/workbench/parts/preferences/browser/media/action-remove.svg new file mode 100644 index 00000000000..fde34404d4e --- /dev/null +++ b/src/vs/workbench/parts/preferences/browser/media/action-remove.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/vs/workbench/parts/preferences/browser/media/settingsEditor2.css b/src/vs/workbench/parts/preferences/browser/media/settingsEditor2.css index a9cefe54072..804c08ea254 100644 --- a/src/vs/workbench/parts/preferences/browser/media/settingsEditor2.css +++ b/src/vs/workbench/parts/preferences/browser/media/settingsEditor2.css @@ -302,7 +302,7 @@ border-radius: 3px; margin-right: 4px; margin-left: 0px; - margin-top: 4px; + margin-top: 2px; padding: 0px; background-size: 14px !important; } @@ -348,6 +348,103 @@ height: 26px; } +.settings-editor > .settings-body > .settings-tree-container .setting-item.setting-item-exclude .setting-item-value > .setting-item-control { + width: 100%; +} + +.settings-editor > .settings-body > .settings-tree-container .setting-item.setting-item-exclude .setting-exclude-pattern { + margin-right: 3px; +} + +.settings-editor > .settings-body > .settings-tree-container .setting-item.setting-item-exclude .setting-exclude-pattern, +.settings-editor > .settings-body > .settings-tree-container .setting-item.setting-item-exclude .setting-exclude-sibling { + display: inline-block; +} + +.settings-editor > .settings-body > .settings-tree-container .setting-item.setting-item-exclude .setting-exclude-sibling { + opacity: 0.7; + margin-left: 0.5em; + font-size: 0.9em; + white-space: pre; +} + +.settings-editor > .settings-body > .settings-tree-container .setting-item.setting-item-exclude .monaco-action-bar { + display: none; + position: absolute; + right: 0px; +} + +.settings-editor > .settings-body > .settings-tree-container .setting-item.setting-item-exclude .monaco-list-row:hover .monaco-action-bar, +.settings-editor > .settings-body > .settings-tree-container .setting-item.setting-item-exclude .monaco-list-row.focused .monaco-action-bar { + display: block; +} + +.settings-editor > .settings-body > .settings-tree-container .setting-item.setting-item-exclude .monaco-list-row .monaco-action-bar .action-label { + width: 16px; + height: 16px; + margin-top: 2px; +} + +.settings-editor > .settings-body > .settings-tree-container .setting-item.setting-item-exclude .monaco-list-row .monaco-action-bar .setting-excludeAction-edit { + margin-right: 7px; +} + +.vs .settings-editor > .settings-body > .settings-tree-container .setting-item.setting-item-exclude .monaco-list-row .monaco-action-bar .setting-excludeAction-edit { + background: url(edit.svg) center center no-repeat; +} + +.vs-dark .settings-editor > .settings-body > .settings-tree-container .setting-item.setting-item-exclude .monaco-list-row .monaco-action-bar .setting-excludeAction-edit { + background: url(edit_inverse.svg) center center no-repeat; +} + +.vs .settings-editor > .settings-body > .settings-tree-container .setting-item.setting-item-exclude .monaco-list-row .monaco-action-bar .setting-excludeAction-remove { + background: url(action-remove.svg) center center no-repeat; +} + +.vs-dark .settings-editor > .settings-body > .settings-tree-container .setting-item.setting-item-exclude .monaco-list-row .monaco-action-bar .setting-excludeAction-remove { + background: url(action-remove-dark.svg) center center no-repeat; +} + +.settings-editor > .settings-body > .settings-tree-container .setting-item.setting-item-exclude .monaco-text-button { + width: initial; +} + +.settings-editor > .settings-body > .settings-tree-container .setting-item.setting-item-exclude .monaco-text-button.setting-exclude-addPattern { + margin-right: 5px; +} + +.settings-editor > .settings-body > .settings-tree-container .setting-item.setting-item-exclude .monaco-text-button.setting-exclude-addButton { + display: none; +} + +.settings-editor > .settings-body > .settings-tree-container .setting-item.setting-item-exclude.is-expanded .monaco-text-button.setting-exclude-addButton { + display: inline-block; +} + +.settings-editor > .settings-body > .settings-tree-container .setting-item.setting-item-exclude .setting-exclude-checkbox { + height: 16px; + width: 16px; + border: 1px solid transparent; + border-radius: 3px; + margin-right: 4px; + margin-left: 0px; + margin-top: 4px; + padding: 0px; + background-size: 14px !important; +} + +.vs .settings-editor > .settings-body > .settings-tree-container .setting-item.setting-item-exclude .setting-exclude-checkbox.checked { + background: url('check.svg') center center no-repeat; +} + +.vs-dark .settings-editor > .settings-body > .settings-tree-container .setting-item.setting-item-exclude .setting-exclude-checkbox.checked { + background: url('check-inverse.svg') center center no-repeat; +} + +.settings-editor > .settings-body > .settings-tree-container .setting-item.setting-item-exclude .monaco-list { + margin-bottom: 10px +} + .settings-editor > .settings-body > .settings-tree-container .group-title, .settings-editor > .settings-body > .settings-tree-container .setting-item { padding-left: 9px; diff --git a/src/vs/workbench/parts/preferences/browser/settingsTree.ts b/src/vs/workbench/parts/preferences/browser/settingsTree.ts index d9b878efa05..df3f31df6f6 100644 --- a/src/vs/workbench/parts/preferences/browser/settingsTree.ts +++ b/src/vs/workbench/parts/preferences/browser/settingsTree.ts @@ -7,28 +7,31 @@ import * as DOM from 'vs/base/browser/dom'; import { renderMarkdown } from 'vs/base/browser/htmlContentRenderer'; import { StandardKeyboardEvent } from 'vs/base/browser/keyboardEvent'; import { IMouseEvent } from 'vs/base/browser/mouseEvent'; +import { ActionBar } from 'vs/base/browser/ui/actionbar/actionbar'; import { Button } from 'vs/base/browser/ui/button/button'; import { Checkbox } from 'vs/base/browser/ui/checkbox/checkbox'; import { InputBox } from 'vs/base/browser/ui/inputbox/inputBox'; +import { IRenderer, IVirtualDelegate } from 'vs/base/browser/ui/list/list'; import { SelectBox } from 'vs/base/browser/ui/selectBox/selectBox'; +import { Action } from 'vs/base/common/actions'; import * as arrays from 'vs/base/common/arrays'; import { Color, RGBA } from 'vs/base/common/color'; import { onUnexpectedError } from 'vs/base/common/errors'; import { Emitter, Event } from 'vs/base/common/event'; import { KeyCode } from 'vs/base/common/keyCodes'; -import { dispose, IDisposable } from 'vs/base/common/lifecycle'; +import { Disposable, dispose, IDisposable } from 'vs/base/common/lifecycle'; import * as objects from 'vs/base/common/objects'; import { escapeRegExpCharacters, startsWith } from 'vs/base/common/strings'; import URI from 'vs/base/common/uri'; import { TPromise } from 'vs/base/common/winjs.base'; -import { IAccessibilityProvider, IDataSource, IFilter, IRenderer, ITree, ITreeConfiguration } from 'vs/base/parts/tree/browser/tree'; +import { IAccessibilityProvider, IDataSource, IFilter, IRenderer as ITreeRenderer, ITree, ITreeConfiguration } from 'vs/base/parts/tree/browser/tree'; import { DefaultTreestyler } from 'vs/base/parts/tree/browser/treeDefaults'; import { localize } from 'vs/nls'; import { ConfigurationTarget, IConfigurationService } from 'vs/platform/configuration/common/configuration'; import { IContextKeyService } from 'vs/platform/contextkey/common/contextkey'; import { IContextViewService } from 'vs/platform/contextview/browser/contextView'; import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; -import { IListService, WorkbenchTree, WorkbenchTreeController } from 'vs/platform/list/browser/listService'; +import { IListService, WorkbenchList, WorkbenchTree, WorkbenchTreeController } from 'vs/platform/list/browser/listService'; import { IOpenerService } from 'vs/platform/opener/common/opener'; import { editorBackground, focusBorder, foreground, inputBackground, inputBorder, inputForeground, registerColor, selectBackground, selectBorder, selectForeground, textLinkForeground } from 'vs/platform/theme/common/colorRegistry'; import { attachButtonStyler, attachInputBoxStyler, attachSelectBoxStyler, attachStyler } from 'vs/platform/theme/common/styler'; @@ -474,6 +477,14 @@ interface ISettingComplexItemTemplate extends ISettingItemTemplate { button: Button; } +interface ISettingExcludeItemTemplate extends ISettingItemTemplate { + excludeWidget: ExcludeSettingWidget; +} + +function isExcludeSetting(element: SettingsTreeSettingElement): boolean { + return element.setting.key === 'files.exclude'; +} + interface IGroupTitleTemplate extends IDisposableTemplate { context?: SettingsTreeGroupElement; parent: HTMLElement; @@ -483,6 +494,7 @@ const SETTINGS_TEXT_TEMPLATE_ID = 'settings.text.template'; const SETTINGS_NUMBER_TEMPLATE_ID = 'settings.number.template'; const SETTINGS_ENUM_TEMPLATE_ID = 'settings.enum.template'; const SETTINGS_BOOL_TEMPLATE_ID = 'settings.bool.template'; +const SETTINGS_EXCLUDE_TEMPLATE_ID = 'settings.exclude.template'; const SETTINGS_COMPLEX_TEMPLATE_ID = 'settings.complex.template'; const SETTINGS_GROUP_ELEMENT_TEMPLATE_ID = 'settings.group.template'; @@ -491,7 +503,7 @@ export interface ISettingChangeEvent { value: any; // undefined => reset/unconfigure } -export class SettingsRenderer implements IRenderer { +export class SettingsRenderer implements ITreeRenderer { private static readonly SETTING_ROW_HEIGHT = 98; private static readonly SETTING_BOOL_ROW_HEIGHT = 65; @@ -513,6 +525,7 @@ export class SettingsRenderer implements IRenderer { @IThemeService private themeService: IThemeService, @IContextViewService private contextViewService: IContextViewService, @IOpenerService private readonly openerService: IOpenerService, + @IInstantiationService private readonly instantiationService: IInstantiationService, ) { this.measureContainer = DOM.append(_measureContainer, $('.setting-measure-container.monaco-tree-row')); } @@ -530,6 +543,10 @@ export class SettingsRenderer implements IRenderer { const isSelected = this.elementIsSelected(tree, element); if (isSelected) { return this.measureSettingElementHeight(tree, element); + } else if (isExcludeSetting(element)) { + // TODO@roblou measure or static calc? + // return this.measureSettingElementHeight(tree, element); + return Object.keys(element.value).length * 22 + 75; } else { return this._getUnexpandedSettingHeight(element); } @@ -581,6 +598,10 @@ export class SettingsRenderer implements IRenderer { return SETTINGS_ENUM_TEMPLATE_ID; } + if (isExcludeSetting(element)) { + return SETTINGS_EXCLUDE_TEMPLATE_ID; + } + return SETTINGS_COMPLEX_TEMPLATE_ID; } @@ -608,6 +629,10 @@ export class SettingsRenderer implements IRenderer { return this.renderSettingEnumTemplate(tree, container); } + if (templateId === SETTINGS_EXCLUDE_TEMPLATE_ID) { + return this.renderSettingExcludeTemplate(tree, container); + } + if (templateId === SETTINGS_COMPLEX_TEMPLATE_ID) { return this.renderSettingComplexTemplate(tree, container); } @@ -796,6 +821,29 @@ export class SettingsRenderer implements IRenderer { return template; } + private renderSettingExcludeTemplate(tree: ITree, container: HTMLElement): ISettingExcludeItemTemplate { + const common = this.renderCommonTemplate(tree, container, 'exclude'); + + const excludeWidget = this.instantiationService.createInstance(ExcludeSettingWidget, common.controlElement); + common.toDispose.push(excludeWidget); + // common.toDispose.push(excludeWidget.onDidClick(() => this._onDidOpenSettings.fire())); + // excludeWidget.label = localize('editInSettingsJson', "Edit in settings.json"); + // excludeWidget.element.classList.add('edit-in-settings-button'); + + // common.toDispose.push(attachButtonStyler(excludeWidget, this.themeService, { + // buttonBackground: Color.transparent.toString(), + // buttonHoverBackground: Color.transparent.toString(), + // buttonForeground: 'foreground' + // })); + + const template: ISettingExcludeItemTemplate = { + ...common, + excludeWidget + }; + + return template; + } + private renderSettingComplexTemplate(tree: ITree, container: HTMLElement): ISettingComplexItemTemplate { const common = this.renderCommonTemplate(tree, container, 'complex'); @@ -918,8 +966,10 @@ export class SettingsRenderer implements IRenderer { this.renderNumber(element, isSelected, template, onChange); } else if (templateId === SETTINGS_BOOL_TEMPLATE_ID) { this.renderBool(element, isSelected, template, onChange); + } else if (templateId === SETTINGS_EXCLUDE_TEMPLATE_ID) { + this.renderExcludeSetting(element, isSelected, template); } else if (templateId === SETTINGS_COMPLEX_TEMPLATE_ID) { - this.renderEditInSettingsJson(element, isSelected, template); + this.renderComplexSetting(element, isSelected, template); } } @@ -965,7 +1015,11 @@ export class SettingsRenderer implements IRenderer { const parseFn = dataElement.valueType === 'integer' ? parseInt : parseFloat; } - private renderEditInSettingsJson(dataElement: SettingsTreeSettingElement, isSelected: boolean, template: ISettingComplexItemTemplate): void { + private renderExcludeSetting(dataElement: SettingsTreeSettingElement, isSelected: boolean, template: ISettingExcludeItemTemplate): void { + template.excludeWidget.setValue(dataElement.value); + } + + private renderComplexSetting(dataElement: SettingsTreeSettingElement, isSelected: boolean, template: ISettingComplexItemTemplate): void { template.button.element.tabIndex = isSelected ? 0 : -1; template.onChange = () => this._onDidOpenSettings.fire(); @@ -1260,3 +1314,260 @@ export class SettingsTree extends NonExpandableTree { })); } } + +enum AddItemMode { + None, + Pattern, + PatternWithSibling +} + +export class ExcludeSettingListModel { + private _dataItems: IExcludeItem[]; + private _newItem: AddItemMode; + + get items(): IExcludeItem[] { + const items = [ + ...this._dataItems + ]; + if (this._newItem === AddItemMode.Pattern) { + items.push({ + id: 'newItem', + withSibling: false + }); + } + + return items; + } + + setValue(excludeValue: any): void { + this._dataItems = this.excludeValueToItems(excludeValue); + } + + private excludeValueToItems(excludeValue: any): IExcludeItem[] { + return Object.keys(excludeValue).map(key => { + const value = excludeValue[key]; + const enabled = !!value; + const sibling = typeof value === 'boolean' ? undefined : value.when; + + return { + id: key, + enabled, + pattern: key, + sibling + }; + }); + } +} + +export class ExcludeSettingWidget extends Disposable { + private list: WorkbenchList; + + private model = new ExcludeSettingListModel(); + + constructor( + container: HTMLElement, + @IThemeService private themeService: IThemeService, + @IInstantiationService private instantiationService: IInstantiationService + ) { + super(); + + const dataRenderer = new ExcludeDataItemRenderer(); + const newItemRenderer = this.instantiationService.createInstance(NewExcludeRenderer); + const delegate = new ExcludeSettingListDelegate(); + this.list = this.instantiationService.createInstance(WorkbenchList, container, delegate, [newItemRenderer, dataRenderer], { + identityProvider: element => element.id, + multipleSelectionSupport: false + }) as WorkbenchList; + this._register(this.list); + + const addPatternButton = this._register(new Button(container)); + addPatternButton.label = localize('addPattern', "Add Pattern"); + addPatternButton.element.classList.add('setting-exclude-addPattern', 'setting-exclude-addButton'); + this._register(attachButtonStyler(addPatternButton, this.themeService)); + + const addSiblingPatternButton = this._register(new Button(container)); + addSiblingPatternButton.label = localize('addSiblingPattern', "Add Sibling Pattern"); + addSiblingPatternButton.element.classList.add('setting-exclude-addButton'); + this._register(attachButtonStyler(addSiblingPatternButton, this.themeService)); + this._register(addSiblingPatternButton.onDidClick(() => { + })); + } + + setValue(excludeValue: any): void { + this.model.setValue(excludeValue); + this.list.splice(0, this.list.length, this.model.items); + + const listHeight = 22 * this.model.items.length; + this.list.layout(listHeight); + this.list.getHTMLElement().style.height = listHeight + 'px'; + } +} + +interface IExcludeDataItem { + id: string; + enabled: boolean; + pattern: string; + sibling?: string; +} + +interface INewExcludeItem { + id: string; + withSibling: boolean; +} + +type IExcludeItem = IExcludeDataItem | INewExcludeItem; + +function isExcludeDataItem(excludeItem: IExcludeItem): excludeItem is IExcludeDataItem { + return !!(excludeItem).pattern; +} + +interface IExcludeDataItemTemplate { + container: HTMLElement; + + checkbox: Checkbox; + actionBar: ActionBar; + patternElement: HTMLElement; + siblingElement: HTMLElement; + toDispose: IDisposable[]; +} + +class ExcludeDataItemRenderer implements IRenderer { + static readonly templateId: string = 'excludeDataItem'; + + get templateId(): string { + return ExcludeDataItemRenderer.templateId; + } + + renderTemplate(container: HTMLElement): IExcludeDataItemTemplate { + const toDispose = []; + + const checkbox = new Checkbox({ actionClassName: 'setting-exclude-checkbox', isChecked: true, title: '', inputActiveOptionBorder: null }); + container.appendChild(checkbox.domNode); + toDispose.push(checkbox); + toDispose.push(checkbox.onChange(() => { + // if (template.onChange) { + // template.onChange(checkbox.checked); + // } + })); + + const actionBar = new ActionBar(container); + toDispose.push(actionBar); + + const editAction = new EditExcludeItemAction(); + const removeAction = new RemoveExcludeItemAction(); + toDispose.push(editAction, removeAction); + actionBar.push([ + editAction, removeAction + ], { icon: true, label: false }); + + return { + container, + checkbox, + patternElement: DOM.append(container, $('.setting-exclude-pattern')), + siblingElement: DOM.append(container, $('.setting-exclude-sibling')), + toDispose, + actionBar + }; + } + + renderElement(element: IExcludeDataItem, index: number, templateData: IExcludeDataItemTemplate): void { + templateData.patternElement.textContent = element.pattern; + templateData.siblingElement.textContent = element.sibling; + } + + disposeElement(element: IExcludeDataItem, index: number, templateData: IExcludeDataItemTemplate): void { + } + + disposeTemplate(templateData: IExcludeDataItemTemplate): void { + dispose(templateData.toDispose); + } +} + +interface INewExcludeItemTemplate { + container: HTMLElement; + + patternInput: InputBox; + toDispose: IDisposable[]; +} + +class NewExcludeRenderer implements IRenderer { + static readonly templateId: string = 'newExcludeItem'; + + constructor( + @IContextViewService private contextViewService: IContextViewService + ) { + } + + get templateId(): string { + return ExcludeDataItemRenderer.templateId; + } + + renderTemplate(container: HTMLElement): INewExcludeItemTemplate { + const toDispose = []; + + const patternInput = new InputBox(container, this.contextViewService); + toDispose.push(patternInput); + + return { + container, + patternInput, + toDispose + }; + } + + renderElement(element: INewExcludeItem, index: number, templateData: INewExcludeItemTemplate): void { + } + + disposeElement(element: INewExcludeItem, index: number, templateData: INewExcludeItemTemplate): void { + } + + disposeTemplate(templateData: INewExcludeItemTemplate): void { + dispose(templateData.toDispose); + } +} + +class ExcludeSettingListDelegate implements IVirtualDelegate { + getHeight(element: IExcludeItem): number { + return 22; + } + + getTemplateId(element: IExcludeItem): string { + if (isExcludeDataItem(element)) { + return ExcludeDataItemRenderer.templateId; + } else { + return NewExcludeRenderer.templateId; + } + } +} + +class EditExcludeItemAction extends Action { + + static readonly ID = 'workbench.action.editExcludeItem'; + static readonly LABEL = localize('editExcludeItem', "Edit Exclude Item"); + + constructor() { + super(EditExcludeItemAction.ID, EditExcludeItemAction.LABEL); + + this.class = 'setting-excludeAction-edit'; + } + + run(item: IExcludeItem): TPromise { + return TPromise.wrap(true); + } +} + +class RemoveExcludeItemAction extends Action { + + static readonly ID = 'workbench.action.removeExcludeItem'; + static readonly LABEL = localize('removeExcludeItem', "Remove Exclude Item"); + + constructor() { + super(RemoveExcludeItemAction.ID, RemoveExcludeItemAction.LABEL); + + this.class = 'setting-excludeAction-remove'; + } + + run(item: IExcludeItem): TPromise { + return TPromise.wrap(true); + } +} From 0f90635fbb7bd0500532309e507a4f75403a650f Mon Sep 17 00:00:00 2001 From: Rob Lourens Date: Thu, 19 Jul 2018 10:17:13 -0700 Subject: [PATCH 0099/1276] Settings exclude control - move to own file --- .../browser/media/settingsEditor2.css | 97 ------ .../browser/media/settingsWidgets.css | 101 +++++++ .../parts/preferences/browser/settingsTree.ts | 265 +---------------- .../preferences/browser/settingsWidgets.ts | 280 ++++++++++++++++++ 4 files changed, 384 insertions(+), 359 deletions(-) create mode 100644 src/vs/workbench/parts/preferences/browser/media/settingsWidgets.css create mode 100644 src/vs/workbench/parts/preferences/browser/settingsWidgets.ts diff --git a/src/vs/workbench/parts/preferences/browser/media/settingsEditor2.css b/src/vs/workbench/parts/preferences/browser/media/settingsEditor2.css index 804c08ea254..410ca1bbcf3 100644 --- a/src/vs/workbench/parts/preferences/browser/media/settingsEditor2.css +++ b/src/vs/workbench/parts/preferences/browser/media/settingsEditor2.css @@ -348,103 +348,6 @@ height: 26px; } -.settings-editor > .settings-body > .settings-tree-container .setting-item.setting-item-exclude .setting-item-value > .setting-item-control { - width: 100%; -} - -.settings-editor > .settings-body > .settings-tree-container .setting-item.setting-item-exclude .setting-exclude-pattern { - margin-right: 3px; -} - -.settings-editor > .settings-body > .settings-tree-container .setting-item.setting-item-exclude .setting-exclude-pattern, -.settings-editor > .settings-body > .settings-tree-container .setting-item.setting-item-exclude .setting-exclude-sibling { - display: inline-block; -} - -.settings-editor > .settings-body > .settings-tree-container .setting-item.setting-item-exclude .setting-exclude-sibling { - opacity: 0.7; - margin-left: 0.5em; - font-size: 0.9em; - white-space: pre; -} - -.settings-editor > .settings-body > .settings-tree-container .setting-item.setting-item-exclude .monaco-action-bar { - display: none; - position: absolute; - right: 0px; -} - -.settings-editor > .settings-body > .settings-tree-container .setting-item.setting-item-exclude .monaco-list-row:hover .monaco-action-bar, -.settings-editor > .settings-body > .settings-tree-container .setting-item.setting-item-exclude .monaco-list-row.focused .monaco-action-bar { - display: block; -} - -.settings-editor > .settings-body > .settings-tree-container .setting-item.setting-item-exclude .monaco-list-row .monaco-action-bar .action-label { - width: 16px; - height: 16px; - margin-top: 2px; -} - -.settings-editor > .settings-body > .settings-tree-container .setting-item.setting-item-exclude .monaco-list-row .monaco-action-bar .setting-excludeAction-edit { - margin-right: 7px; -} - -.vs .settings-editor > .settings-body > .settings-tree-container .setting-item.setting-item-exclude .monaco-list-row .monaco-action-bar .setting-excludeAction-edit { - background: url(edit.svg) center center no-repeat; -} - -.vs-dark .settings-editor > .settings-body > .settings-tree-container .setting-item.setting-item-exclude .monaco-list-row .monaco-action-bar .setting-excludeAction-edit { - background: url(edit_inverse.svg) center center no-repeat; -} - -.vs .settings-editor > .settings-body > .settings-tree-container .setting-item.setting-item-exclude .monaco-list-row .monaco-action-bar .setting-excludeAction-remove { - background: url(action-remove.svg) center center no-repeat; -} - -.vs-dark .settings-editor > .settings-body > .settings-tree-container .setting-item.setting-item-exclude .monaco-list-row .monaco-action-bar .setting-excludeAction-remove { - background: url(action-remove-dark.svg) center center no-repeat; -} - -.settings-editor > .settings-body > .settings-tree-container .setting-item.setting-item-exclude .monaco-text-button { - width: initial; -} - -.settings-editor > .settings-body > .settings-tree-container .setting-item.setting-item-exclude .monaco-text-button.setting-exclude-addPattern { - margin-right: 5px; -} - -.settings-editor > .settings-body > .settings-tree-container .setting-item.setting-item-exclude .monaco-text-button.setting-exclude-addButton { - display: none; -} - -.settings-editor > .settings-body > .settings-tree-container .setting-item.setting-item-exclude.is-expanded .monaco-text-button.setting-exclude-addButton { - display: inline-block; -} - -.settings-editor > .settings-body > .settings-tree-container .setting-item.setting-item-exclude .setting-exclude-checkbox { - height: 16px; - width: 16px; - border: 1px solid transparent; - border-radius: 3px; - margin-right: 4px; - margin-left: 0px; - margin-top: 4px; - padding: 0px; - background-size: 14px !important; -} - -.vs .settings-editor > .settings-body > .settings-tree-container .setting-item.setting-item-exclude .setting-exclude-checkbox.checked { - background: url('check.svg') center center no-repeat; -} - -.vs-dark .settings-editor > .settings-body > .settings-tree-container .setting-item.setting-item-exclude .setting-exclude-checkbox.checked { - background: url('check-inverse.svg') center center no-repeat; -} - -.settings-editor > .settings-body > .settings-tree-container .setting-item.setting-item-exclude .monaco-list { - margin-bottom: 10px -} - .settings-editor > .settings-body > .settings-tree-container .group-title, .settings-editor > .settings-body > .settings-tree-container .setting-item { padding-left: 9px; diff --git a/src/vs/workbench/parts/preferences/browser/media/settingsWidgets.css b/src/vs/workbench/parts/preferences/browser/media/settingsWidgets.css new file mode 100644 index 00000000000..20c7961bfd5 --- /dev/null +++ b/src/vs/workbench/parts/preferences/browser/media/settingsWidgets.css @@ -0,0 +1,101 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +.settings-editor > .settings-body > .settings-tree-container .setting-item.setting-item-exclude .setting-item-value > .setting-item-control { + width: 100%; +} + +.settings-editor > .settings-body > .settings-tree-container .setting-item.setting-item-exclude .setting-exclude-pattern { + margin-right: 3px; +} + +.settings-editor > .settings-body > .settings-tree-container .setting-item.setting-item-exclude .setting-exclude-pattern, +.settings-editor > .settings-body > .settings-tree-container .setting-item.setting-item-exclude .setting-exclude-sibling { + display: inline-block; +} + +.settings-editor > .settings-body > .settings-tree-container .setting-item.setting-item-exclude .setting-exclude-sibling { + opacity: 0.7; + margin-left: 0.5em; + font-size: 0.9em; + white-space: pre; +} + +.settings-editor > .settings-body > .settings-tree-container .setting-item.setting-item-exclude .monaco-action-bar { + display: none; + position: absolute; + right: 0px; +} + +.settings-editor > .settings-body > .settings-tree-container .setting-item.setting-item-exclude .monaco-list-row:hover .monaco-action-bar, +.settings-editor > .settings-body > .settings-tree-container .setting-item.setting-item-exclude .monaco-list-row.focused .monaco-action-bar { + display: block; +} + +.settings-editor > .settings-body > .settings-tree-container .setting-item.setting-item-exclude .monaco-list-row .monaco-action-bar .action-label { + width: 16px; + height: 16px; + margin-top: 2px; +} + +.settings-editor > .settings-body > .settings-tree-container .setting-item.setting-item-exclude .monaco-list-row .monaco-action-bar .setting-excludeAction-edit { + margin-right: 7px; +} + +.vs .settings-editor > .settings-body > .settings-tree-container .setting-item.setting-item-exclude .monaco-list-row .monaco-action-bar .setting-excludeAction-edit { + background: url(edit.svg) center center no-repeat; +} + +.vs-dark .settings-editor > .settings-body > .settings-tree-container .setting-item.setting-item-exclude .monaco-list-row .monaco-action-bar .setting-excludeAction-edit { + background: url(edit_inverse.svg) center center no-repeat; +} + +.vs .settings-editor > .settings-body > .settings-tree-container .setting-item.setting-item-exclude .monaco-list-row .monaco-action-bar .setting-excludeAction-remove { + background: url(action-remove.svg) center center no-repeat; +} + +.vs-dark .settings-editor > .settings-body > .settings-tree-container .setting-item.setting-item-exclude .monaco-list-row .monaco-action-bar .setting-excludeAction-remove { + background: url(action-remove-dark.svg) center center no-repeat; +} + +.settings-editor > .settings-body > .settings-tree-container .setting-item.setting-item-exclude .monaco-text-button { + width: initial; +} + +.settings-editor > .settings-body > .settings-tree-container .setting-item.setting-item-exclude .monaco-text-button.setting-exclude-addPattern { + margin-right: 5px; +} + +.settings-editor > .settings-body > .settings-tree-container .setting-item.setting-item-exclude .monaco-text-button.setting-exclude-addButton { + display: none; +} + +.settings-editor > .settings-body > .settings-tree-container .setting-item.setting-item-exclude.is-expanded .monaco-text-button.setting-exclude-addButton { + display: inline-block; +} + +.settings-editor > .settings-body > .settings-tree-container .setting-item.setting-item-exclude .setting-exclude-checkbox { + height: 16px; + width: 16px; + border: 1px solid transparent; + border-radius: 3px; + margin-right: 4px; + margin-left: 0px; + margin-top: 4px; + padding: 0px; + background-size: 14px !important; +} + +.vs .settings-editor > .settings-body > .settings-tree-container .setting-item.setting-item-exclude .setting-exclude-checkbox.checked { + background: url('check.svg') center center no-repeat; +} + +.vs-dark .settings-editor > .settings-body > .settings-tree-container .setting-item.setting-item-exclude .setting-exclude-checkbox.checked { + background: url('check-inverse.svg') center center no-repeat; +} + +.settings-editor > .settings-body > .settings-tree-container .setting-item.setting-item-exclude .monaco-list { + margin-bottom: 10px; +} diff --git a/src/vs/workbench/parts/preferences/browser/settingsTree.ts b/src/vs/workbench/parts/preferences/browser/settingsTree.ts index df3f31df6f6..056bdcbbee3 100644 --- a/src/vs/workbench/parts/preferences/browser/settingsTree.ts +++ b/src/vs/workbench/parts/preferences/browser/settingsTree.ts @@ -7,19 +7,16 @@ import * as DOM from 'vs/base/browser/dom'; import { renderMarkdown } from 'vs/base/browser/htmlContentRenderer'; import { StandardKeyboardEvent } from 'vs/base/browser/keyboardEvent'; import { IMouseEvent } from 'vs/base/browser/mouseEvent'; -import { ActionBar } from 'vs/base/browser/ui/actionbar/actionbar'; import { Button } from 'vs/base/browser/ui/button/button'; import { Checkbox } from 'vs/base/browser/ui/checkbox/checkbox'; import { InputBox } from 'vs/base/browser/ui/inputbox/inputBox'; -import { IRenderer, IVirtualDelegate } from 'vs/base/browser/ui/list/list'; import { SelectBox } from 'vs/base/browser/ui/selectBox/selectBox'; -import { Action } from 'vs/base/common/actions'; import * as arrays from 'vs/base/common/arrays'; import { Color, RGBA } from 'vs/base/common/color'; import { onUnexpectedError } from 'vs/base/common/errors'; import { Emitter, Event } from 'vs/base/common/event'; import { KeyCode } from 'vs/base/common/keyCodes'; -import { Disposable, dispose, IDisposable } from 'vs/base/common/lifecycle'; +import { dispose, IDisposable } from 'vs/base/common/lifecycle'; import * as objects from 'vs/base/common/objects'; import { escapeRegExpCharacters, startsWith } from 'vs/base/common/strings'; import URI from 'vs/base/common/uri'; @@ -31,13 +28,14 @@ import { ConfigurationTarget, IConfigurationService } from 'vs/platform/configur import { IContextKeyService } from 'vs/platform/contextkey/common/contextkey'; import { IContextViewService } from 'vs/platform/contextview/browser/contextView'; import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; -import { IListService, WorkbenchList, WorkbenchTree, WorkbenchTreeController } from 'vs/platform/list/browser/listService'; +import { IListService, WorkbenchTree, WorkbenchTreeController } from 'vs/platform/list/browser/listService'; import { IOpenerService } from 'vs/platform/opener/common/opener'; import { editorBackground, focusBorder, foreground, inputBackground, inputBorder, inputForeground, registerColor, selectBackground, selectBorder, selectForeground, textLinkForeground } from 'vs/platform/theme/common/colorRegistry'; import { attachButtonStyler, attachInputBoxStyler, attachSelectBoxStyler, attachStyler } from 'vs/platform/theme/common/styler'; import { ICssStyleCollector, ITheme, IThemeService, registerThemingParticipant } from 'vs/platform/theme/common/themeService'; import { SettingsTarget } from 'vs/workbench/parts/preferences/browser/preferencesWidgets'; import { ITOCEntry } from 'vs/workbench/parts/preferences/browser/settingsLayout'; +import { ExcludeSettingWidget } from 'vs/workbench/parts/preferences/browser/settingsWidgets'; import { ISearchResult, ISetting, ISettingsGroup } from 'vs/workbench/services/preferences/common/preferences'; const $ = DOM.$; @@ -1314,260 +1312,3 @@ export class SettingsTree extends NonExpandableTree { })); } } - -enum AddItemMode { - None, - Pattern, - PatternWithSibling -} - -export class ExcludeSettingListModel { - private _dataItems: IExcludeItem[]; - private _newItem: AddItemMode; - - get items(): IExcludeItem[] { - const items = [ - ...this._dataItems - ]; - if (this._newItem === AddItemMode.Pattern) { - items.push({ - id: 'newItem', - withSibling: false - }); - } - - return items; - } - - setValue(excludeValue: any): void { - this._dataItems = this.excludeValueToItems(excludeValue); - } - - private excludeValueToItems(excludeValue: any): IExcludeItem[] { - return Object.keys(excludeValue).map(key => { - const value = excludeValue[key]; - const enabled = !!value; - const sibling = typeof value === 'boolean' ? undefined : value.when; - - return { - id: key, - enabled, - pattern: key, - sibling - }; - }); - } -} - -export class ExcludeSettingWidget extends Disposable { - private list: WorkbenchList; - - private model = new ExcludeSettingListModel(); - - constructor( - container: HTMLElement, - @IThemeService private themeService: IThemeService, - @IInstantiationService private instantiationService: IInstantiationService - ) { - super(); - - const dataRenderer = new ExcludeDataItemRenderer(); - const newItemRenderer = this.instantiationService.createInstance(NewExcludeRenderer); - const delegate = new ExcludeSettingListDelegate(); - this.list = this.instantiationService.createInstance(WorkbenchList, container, delegate, [newItemRenderer, dataRenderer], { - identityProvider: element => element.id, - multipleSelectionSupport: false - }) as WorkbenchList; - this._register(this.list); - - const addPatternButton = this._register(new Button(container)); - addPatternButton.label = localize('addPattern', "Add Pattern"); - addPatternButton.element.classList.add('setting-exclude-addPattern', 'setting-exclude-addButton'); - this._register(attachButtonStyler(addPatternButton, this.themeService)); - - const addSiblingPatternButton = this._register(new Button(container)); - addSiblingPatternButton.label = localize('addSiblingPattern', "Add Sibling Pattern"); - addSiblingPatternButton.element.classList.add('setting-exclude-addButton'); - this._register(attachButtonStyler(addSiblingPatternButton, this.themeService)); - this._register(addSiblingPatternButton.onDidClick(() => { - })); - } - - setValue(excludeValue: any): void { - this.model.setValue(excludeValue); - this.list.splice(0, this.list.length, this.model.items); - - const listHeight = 22 * this.model.items.length; - this.list.layout(listHeight); - this.list.getHTMLElement().style.height = listHeight + 'px'; - } -} - -interface IExcludeDataItem { - id: string; - enabled: boolean; - pattern: string; - sibling?: string; -} - -interface INewExcludeItem { - id: string; - withSibling: boolean; -} - -type IExcludeItem = IExcludeDataItem | INewExcludeItem; - -function isExcludeDataItem(excludeItem: IExcludeItem): excludeItem is IExcludeDataItem { - return !!(excludeItem).pattern; -} - -interface IExcludeDataItemTemplate { - container: HTMLElement; - - checkbox: Checkbox; - actionBar: ActionBar; - patternElement: HTMLElement; - siblingElement: HTMLElement; - toDispose: IDisposable[]; -} - -class ExcludeDataItemRenderer implements IRenderer { - static readonly templateId: string = 'excludeDataItem'; - - get templateId(): string { - return ExcludeDataItemRenderer.templateId; - } - - renderTemplate(container: HTMLElement): IExcludeDataItemTemplate { - const toDispose = []; - - const checkbox = new Checkbox({ actionClassName: 'setting-exclude-checkbox', isChecked: true, title: '', inputActiveOptionBorder: null }); - container.appendChild(checkbox.domNode); - toDispose.push(checkbox); - toDispose.push(checkbox.onChange(() => { - // if (template.onChange) { - // template.onChange(checkbox.checked); - // } - })); - - const actionBar = new ActionBar(container); - toDispose.push(actionBar); - - const editAction = new EditExcludeItemAction(); - const removeAction = new RemoveExcludeItemAction(); - toDispose.push(editAction, removeAction); - actionBar.push([ - editAction, removeAction - ], { icon: true, label: false }); - - return { - container, - checkbox, - patternElement: DOM.append(container, $('.setting-exclude-pattern')), - siblingElement: DOM.append(container, $('.setting-exclude-sibling')), - toDispose, - actionBar - }; - } - - renderElement(element: IExcludeDataItem, index: number, templateData: IExcludeDataItemTemplate): void { - templateData.patternElement.textContent = element.pattern; - templateData.siblingElement.textContent = element.sibling; - } - - disposeElement(element: IExcludeDataItem, index: number, templateData: IExcludeDataItemTemplate): void { - } - - disposeTemplate(templateData: IExcludeDataItemTemplate): void { - dispose(templateData.toDispose); - } -} - -interface INewExcludeItemTemplate { - container: HTMLElement; - - patternInput: InputBox; - toDispose: IDisposable[]; -} - -class NewExcludeRenderer implements IRenderer { - static readonly templateId: string = 'newExcludeItem'; - - constructor( - @IContextViewService private contextViewService: IContextViewService - ) { - } - - get templateId(): string { - return ExcludeDataItemRenderer.templateId; - } - - renderTemplate(container: HTMLElement): INewExcludeItemTemplate { - const toDispose = []; - - const patternInput = new InputBox(container, this.contextViewService); - toDispose.push(patternInput); - - return { - container, - patternInput, - toDispose - }; - } - - renderElement(element: INewExcludeItem, index: number, templateData: INewExcludeItemTemplate): void { - } - - disposeElement(element: INewExcludeItem, index: number, templateData: INewExcludeItemTemplate): void { - } - - disposeTemplate(templateData: INewExcludeItemTemplate): void { - dispose(templateData.toDispose); - } -} - -class ExcludeSettingListDelegate implements IVirtualDelegate { - getHeight(element: IExcludeItem): number { - return 22; - } - - getTemplateId(element: IExcludeItem): string { - if (isExcludeDataItem(element)) { - return ExcludeDataItemRenderer.templateId; - } else { - return NewExcludeRenderer.templateId; - } - } -} - -class EditExcludeItemAction extends Action { - - static readonly ID = 'workbench.action.editExcludeItem'; - static readonly LABEL = localize('editExcludeItem', "Edit Exclude Item"); - - constructor() { - super(EditExcludeItemAction.ID, EditExcludeItemAction.LABEL); - - this.class = 'setting-excludeAction-edit'; - } - - run(item: IExcludeItem): TPromise { - return TPromise.wrap(true); - } -} - -class RemoveExcludeItemAction extends Action { - - static readonly ID = 'workbench.action.removeExcludeItem'; - static readonly LABEL = localize('removeExcludeItem', "Remove Exclude Item"); - - constructor() { - super(RemoveExcludeItemAction.ID, RemoveExcludeItemAction.LABEL); - - this.class = 'setting-excludeAction-remove'; - } - - run(item: IExcludeItem): TPromise { - return TPromise.wrap(true); - } -} diff --git a/src/vs/workbench/parts/preferences/browser/settingsWidgets.ts b/src/vs/workbench/parts/preferences/browser/settingsWidgets.ts new file mode 100644 index 00000000000..abf0167ca55 --- /dev/null +++ b/src/vs/workbench/parts/preferences/browser/settingsWidgets.ts @@ -0,0 +1,280 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import * as DOM from 'vs/base/browser/dom'; +import { ActionBar } from 'vs/base/browser/ui/actionbar/actionbar'; +import { Button } from 'vs/base/browser/ui/button/button'; +import { Checkbox } from 'vs/base/browser/ui/checkbox/checkbox'; +import { InputBox } from 'vs/base/browser/ui/inputbox/inputBox'; +import { IRenderer, IVirtualDelegate } from 'vs/base/browser/ui/list/list'; +import { Action } from 'vs/base/common/actions'; +import { Disposable, dispose, IDisposable } from 'vs/base/common/lifecycle'; +import { TPromise } from 'vs/base/common/winjs.base'; +import 'vs/css!./media/settingsWidgets'; +import { localize } from 'vs/nls'; +import { IContextViewService } from 'vs/platform/contextview/browser/contextView'; +import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; +import { WorkbenchList } from 'vs/platform/list/browser/listService'; +import { attachButtonStyler } from 'vs/platform/theme/common/styler'; +import { IThemeService } from 'vs/platform/theme/common/themeService'; + +const $ = DOM.$; + +enum AddItemMode { + None, + Pattern, + PatternWithSibling +} + +export class ExcludeSettingListModel { + private _dataItems: IExcludeItem[]; + private _newItem: AddItemMode; + + get items(): IExcludeItem[] { + const items = [ + ...this._dataItems + ]; + if (this._newItem === AddItemMode.Pattern) { + items.push({ + id: 'newItem', + withSibling: false + }); + } + + return items; + } + + setValue(excludeValue: any): void { + this._dataItems = this.excludeValueToItems(excludeValue); + } + + private excludeValueToItems(excludeValue: any): IExcludeItem[] { + return Object.keys(excludeValue).map(key => { + const value = excludeValue[key]; + const enabled = !!value; + const sibling = typeof value === 'boolean' ? undefined : value.when; + + return { + id: key, + enabled, + pattern: key, + sibling + }; + }); + } +} + +export class ExcludeSettingWidget extends Disposable { + private list: WorkbenchList; + + private model = new ExcludeSettingListModel(); + + constructor( + container: HTMLElement, + @IThemeService private themeService: IThemeService, + @IInstantiationService private instantiationService: IInstantiationService + ) { + super(); + + const dataRenderer = new ExcludeDataItemRenderer(); + const newItemRenderer = this.instantiationService.createInstance(NewExcludeRenderer); + const delegate = new ExcludeSettingListDelegate(); + this.list = this.instantiationService.createInstance(WorkbenchList, container, delegate, [newItemRenderer, dataRenderer], { + identityProvider: element => element.id, + multipleSelectionSupport: false + }) as WorkbenchList; + this._register(this.list); + + const addPatternButton = this._register(new Button(container)); + addPatternButton.label = localize('addPattern', "Add Pattern"); + addPatternButton.element.classList.add('setting-exclude-addPattern', 'setting-exclude-addButton'); + this._register(attachButtonStyler(addPatternButton, this.themeService)); + + const addSiblingPatternButton = this._register(new Button(container)); + addSiblingPatternButton.label = localize('addSiblingPattern', "Add Sibling Pattern"); + addSiblingPatternButton.element.classList.add('setting-exclude-addButton'); + this._register(attachButtonStyler(addSiblingPatternButton, this.themeService)); + this._register(addSiblingPatternButton.onDidClick(() => { + })); + } + + setValue(excludeValue: any): void { + this.model.setValue(excludeValue); + this.list.splice(0, this.list.length, this.model.items); + + const listHeight = 22 * this.model.items.length; + this.list.layout(listHeight); + this.list.getHTMLElement().style.height = listHeight + 'px'; + } +} + +interface IExcludeDataItem { + id: string; + enabled: boolean; + pattern: string; + sibling?: string; +} + +interface INewExcludeItem { + id: string; + withSibling: boolean; +} + +type IExcludeItem = IExcludeDataItem | INewExcludeItem; + +function isExcludeDataItem(excludeItem: IExcludeItem): excludeItem is IExcludeDataItem { + return !!(excludeItem).pattern; +} + +interface IExcludeDataItemTemplate { + container: HTMLElement; + + checkbox: Checkbox; + actionBar: ActionBar; + patternElement: HTMLElement; + siblingElement: HTMLElement; + toDispose: IDisposable[]; +} + +class ExcludeDataItemRenderer implements IRenderer { + static readonly templateId: string = 'excludeDataItem'; + + get templateId(): string { + return ExcludeDataItemRenderer.templateId; + } + + renderTemplate(container: HTMLElement): IExcludeDataItemTemplate { + const toDispose = []; + + const checkbox = new Checkbox({ actionClassName: 'setting-exclude-checkbox', isChecked: true, title: '', inputActiveOptionBorder: null }); + container.appendChild(checkbox.domNode); + toDispose.push(checkbox); + toDispose.push(checkbox.onChange(() => { + // if (template.onChange) { + // template.onChange(checkbox.checked); + // } + })); + + const actionBar = new ActionBar(container); + toDispose.push(actionBar); + + const editAction = new EditExcludeItemAction(); + const removeAction = new RemoveExcludeItemAction(); + toDispose.push(editAction, removeAction); + actionBar.push([ + editAction, removeAction + ], { icon: true, label: false }); + + return { + container, + checkbox, + patternElement: DOM.append(container, $('.setting-exclude-pattern')), + siblingElement: DOM.append(container, $('.setting-exclude-sibling')), + toDispose, + actionBar + }; + } + + renderElement(element: IExcludeDataItem, index: number, templateData: IExcludeDataItemTemplate): void { + templateData.patternElement.textContent = element.pattern; + templateData.siblingElement.textContent = element.sibling; + } + + disposeElement(element: IExcludeDataItem, index: number, templateData: IExcludeDataItemTemplate): void { + } + + disposeTemplate(templateData: IExcludeDataItemTemplate): void { + dispose(templateData.toDispose); + } +} + +interface INewExcludeItemTemplate { + container: HTMLElement; + + patternInput: InputBox; + toDispose: IDisposable[]; +} + +class NewExcludeRenderer implements IRenderer { + static readonly templateId: string = 'newExcludeItem'; + + constructor( + @IContextViewService private contextViewService: IContextViewService + ) { + } + + get templateId(): string { + return ExcludeDataItemRenderer.templateId; + } + + renderTemplate(container: HTMLElement): INewExcludeItemTemplate { + const toDispose = []; + + const patternInput = new InputBox(container, this.contextViewService); + toDispose.push(patternInput); + + return { + container, + patternInput, + toDispose + }; + } + + renderElement(element: INewExcludeItem, index: number, templateData: INewExcludeItemTemplate): void { + } + + disposeElement(element: INewExcludeItem, index: number, templateData: INewExcludeItemTemplate): void { + } + + disposeTemplate(templateData: INewExcludeItemTemplate): void { + dispose(templateData.toDispose); + } +} + +class ExcludeSettingListDelegate implements IVirtualDelegate { + getHeight(element: IExcludeItem): number { + return 22; + } + + getTemplateId(element: IExcludeItem): string { + if (isExcludeDataItem(element)) { + return ExcludeDataItemRenderer.templateId; + } else { + return NewExcludeRenderer.templateId; + } + } +} + +class EditExcludeItemAction extends Action { + + static readonly ID = 'workbench.action.editExcludeItem'; + static readonly LABEL = localize('editExcludeItem', "Edit Exclude Item"); + + constructor() { + super(EditExcludeItemAction.ID, EditExcludeItemAction.LABEL); + + this.class = 'setting-excludeAction-edit'; + } + + run(item: IExcludeItem): TPromise { + return TPromise.wrap(true); + } +} + +class RemoveExcludeItemAction extends Action { + + static readonly ID = 'workbench.action.removeExcludeItem'; + static readonly LABEL = localize('removeExcludeItem', "Remove Exclude Item"); + + constructor() { + super(RemoveExcludeItemAction.ID, RemoveExcludeItemAction.LABEL); + + this.class = 'setting-excludeAction-remove'; + } + + run(item: IExcludeItem): TPromise { + return TPromise.wrap(true); + } +} From 5c9cae900ec97d21b49bfb8e08a9c5508a1f4325 Mon Sep 17 00:00:00 2001 From: Rob Lourens Date: Thu, 19 Jul 2018 10:30:26 -0700 Subject: [PATCH 0100/1276] Settings exclude control - add row title, sizing tweaks --- .../parts/preferences/browser/media/settingsWidgets.css | 9 ++++++--- .../workbench/parts/preferences/browser/settingsTree.ts | 4 +--- .../parts/preferences/browser/settingsWidgets.ts | 4 ++++ 3 files changed, 11 insertions(+), 6 deletions(-) diff --git a/src/vs/workbench/parts/preferences/browser/media/settingsWidgets.css b/src/vs/workbench/parts/preferences/browser/media/settingsWidgets.css index 20c7961bfd5..44d38f26b38 100644 --- a/src/vs/workbench/parts/preferences/browser/media/settingsWidgets.css +++ b/src/vs/workbench/parts/preferences/browser/media/settingsWidgets.css @@ -14,6 +14,7 @@ .settings-editor > .settings-body > .settings-tree-container .setting-item.setting-item-exclude .setting-exclude-pattern, .settings-editor > .settings-body > .settings-tree-container .setting-item.setting-item-exclude .setting-exclude-sibling { display: inline-block; + line-height: 22px; } .settings-editor > .settings-body > .settings-tree-container .setting-item.setting-item-exclude .setting-exclude-sibling { @@ -27,6 +28,7 @@ display: none; position: absolute; right: 0px; + margin-top: 1px; } .settings-editor > .settings-body > .settings-tree-container .setting-item.setting-item-exclude .monaco-list-row:hover .monaco-action-bar, @@ -37,11 +39,12 @@ .settings-editor > .settings-body > .settings-tree-container .setting-item.setting-item-exclude .monaco-list-row .monaco-action-bar .action-label { width: 16px; height: 16px; - margin-top: 2px; + padding: 2px; + margin-right: 2px; } .settings-editor > .settings-body > .settings-tree-container .setting-item.setting-item-exclude .monaco-list-row .monaco-action-bar .setting-excludeAction-edit { - margin-right: 7px; + margin-right: 4px; } .vs .settings-editor > .settings-body > .settings-tree-container .setting-item.setting-item-exclude .monaco-list-row .monaco-action-bar .setting-excludeAction-edit { @@ -83,7 +86,7 @@ border-radius: 3px; margin-right: 4px; margin-left: 0px; - margin-top: 4px; + margin-top: 3px; padding: 0px; background-size: 14px !important; } diff --git a/src/vs/workbench/parts/preferences/browser/settingsTree.ts b/src/vs/workbench/parts/preferences/browser/settingsTree.ts index 056bdcbbee3..c8d0ff4fff1 100644 --- a/src/vs/workbench/parts/preferences/browser/settingsTree.ts +++ b/src/vs/workbench/parts/preferences/browser/settingsTree.ts @@ -542,9 +542,7 @@ export class SettingsRenderer implements ITreeRenderer { if (isSelected) { return this.measureSettingElementHeight(tree, element); } else if (isExcludeSetting(element)) { - // TODO@roblou measure or static calc? - // return this.measureSettingElementHeight(tree, element); - return Object.keys(element.value).length * 22 + 75; + return Object.keys(element.value).length * 22 + 70; } else { return this._getUnexpandedSettingHeight(element); } diff --git a/src/vs/workbench/parts/preferences/browser/settingsWidgets.ts b/src/vs/workbench/parts/preferences/browser/settingsWidgets.ts index abf0167ca55..f559d24921e 100644 --- a/src/vs/workbench/parts/preferences/browser/settingsWidgets.ts +++ b/src/vs/workbench/parts/preferences/browser/settingsWidgets.ts @@ -180,6 +180,10 @@ class ExcludeDataItemRenderer implements IRenderer Date: Thu, 19 Jul 2018 11:23:21 -0700 Subject: [PATCH 0101/1276] Settings exclude control - add inputs for new item --- .../browser/media/settingsWidgets.css | 27 +++- .../parts/preferences/browser/settingsTree.ts | 64 +------- .../preferences/browser/settingsWidgets.ts | 148 ++++++++++++++++-- 3 files changed, 165 insertions(+), 74 deletions(-) diff --git a/src/vs/workbench/parts/preferences/browser/media/settingsWidgets.css b/src/vs/workbench/parts/preferences/browser/media/settingsWidgets.css index 44d38f26b38..782cf158b88 100644 --- a/src/vs/workbench/parts/preferences/browser/media/settingsWidgets.css +++ b/src/vs/workbench/parts/preferences/browser/media/settingsWidgets.css @@ -65,10 +65,11 @@ .settings-editor > .settings-body > .settings-tree-container .setting-item.setting-item-exclude .monaco-text-button { width: initial; + padding: 4px 10px; } .settings-editor > .settings-body > .settings-tree-container .setting-item.setting-item-exclude .monaco-text-button.setting-exclude-addPattern { - margin-right: 5px; + margin-right: 10px; } .settings-editor > .settings-body > .settings-tree-container .setting-item.setting-item-exclude .monaco-text-button.setting-exclude-addButton { @@ -79,6 +80,30 @@ display: inline-block; } +.settings-editor > .settings-body > .settings-tree-container .setting-item.setting-item-exclude .monaco-list-row.setting-exclude-newExcludeItem { + display: flex; +} + +.settings-editor > .settings-body > .settings-tree-container .setting-item.setting-item-exclude .monaco-list-row.setting-exclude-newExcludeItem .setting-exclude-patternInput, +.settings-editor > .settings-body > .settings-tree-container .setting-item.setting-item-exclude .monaco-list-row.setting-exclude-newExcludeItem .setting-exclude-siblingInput { + display: none; + flex: 1; + max-width: 200px; +} + +.settings-editor > .settings-body > .settings-tree-container .setting-item.setting-item-exclude .monaco-list-row.setting-exclude-newPattern .setting-exclude-patternInput { + display: inline-block; +} + +.settings-editor > .settings-body > .settings-tree-container .setting-item.setting-item-exclude .monaco-list-row.setting-exclude-newPatternWithSibling .setting-exclude-patternInput { + margin-right: 5px; +} + +.settings-editor > .settings-body > .settings-tree-container .setting-item.setting-item-exclude .monaco-list-row.setting-exclude-newPatternWithSibling .setting-exclude-patternInput, +.settings-editor > .settings-body > .settings-tree-container .setting-item.setting-item-exclude .monaco-list-row.setting-exclude-newPatternWithSibling .setting-exclude-siblingInput { + display: inline-block; +} + .settings-editor > .settings-body > .settings-tree-container .setting-item.setting-item-exclude .setting-exclude-checkbox { height: 16px; width: 16px; diff --git a/src/vs/workbench/parts/preferences/browser/settingsTree.ts b/src/vs/workbench/parts/preferences/browser/settingsTree.ts index c8d0ff4fff1..a7d5dd1ea7a 100644 --- a/src/vs/workbench/parts/preferences/browser/settingsTree.ts +++ b/src/vs/workbench/parts/preferences/browser/settingsTree.ts @@ -30,74 +30,16 @@ import { IContextViewService } from 'vs/platform/contextview/browser/contextView import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; import { IListService, WorkbenchTree, WorkbenchTreeController } from 'vs/platform/list/browser/listService'; import { IOpenerService } from 'vs/platform/opener/common/opener'; -import { editorBackground, focusBorder, foreground, inputBackground, inputBorder, inputForeground, registerColor, selectBackground, selectBorder, selectForeground, textLinkForeground } from 'vs/platform/theme/common/colorRegistry'; +import { editorBackground, focusBorder, foreground } from 'vs/platform/theme/common/colorRegistry'; import { attachButtonStyler, attachInputBoxStyler, attachSelectBoxStyler, attachStyler } from 'vs/platform/theme/common/styler'; import { ICssStyleCollector, ITheme, IThemeService, registerThemingParticipant } from 'vs/platform/theme/common/themeService'; import { SettingsTarget } from 'vs/workbench/parts/preferences/browser/preferencesWidgets'; import { ITOCEntry } from 'vs/workbench/parts/preferences/browser/settingsLayout'; -import { ExcludeSettingWidget } from 'vs/workbench/parts/preferences/browser/settingsWidgets'; +import { ExcludeSettingWidget, settingsNumberInputBackground, settingsNumberInputBorder, settingsNumberInputForeground, settingsSelectBackground, settingsSelectBorder, settingsSelectForeground, settingsTextInputBackground, settingsTextInputBorder, settingsTextInputForeground, settingItemInactiveSelectionBorder, settingsHeaderForeground } from 'vs/workbench/parts/preferences/browser/settingsWidgets'; import { ISearchResult, ISetting, ISettingsGroup } from 'vs/workbench/services/preferences/common/preferences'; const $ = DOM.$; -export const settingsHeaderForeground = registerColor('settings.headerForeground', { light: '#444444', dark: '#e7e7e7', hc: '#ffffff' }, localize('headerForeground', "(For settings editor preview) The foreground color for a section header or active title in the editor.")); -export const modifiedItemForeground = registerColor('settings.modifiedItemForeground', { light: '#019001', dark: '#73C991', hc: '#73C991' }, localize('modifiedItemForeground', "(For settings editor preview) The foreground color for a modified setting.")); -export const settingItemInactiveSelectionBorder = registerColor('settings.inactiveSelectedItemBorder', { dark: '#3F3F46', light: '#CCCEDB', hc: null }, localize('settingItemInactiveSelectionBorder', "(For settings editor preview) The color of the selected setting row border, when the settings list does not have focus.")); - -// Enum control colors -export const settingsSelectBackground = registerColor('settings.dropdownBackground', { dark: selectBackground, light: selectBackground, hc: selectBackground }, localize('settingsDropdownBackground', "(For settings editor preview) Settings editor dropdown background.")); -export const settingsSelectForeground = registerColor('settings.dropdownForeground', { dark: selectForeground, light: selectForeground, hc: selectForeground }, localize('settingsDropdownForeground', "(For settings editor preview) Settings editor dropdown foreground.")); -export const settingsSelectBorder = registerColor('settings.dropdownBorder', { dark: selectBorder, light: selectBorder, hc: selectBorder }, localize('settingsDropdownBorder', "(For settings editor preview) Settings editor dropdown border.")); - -// Bool control colors -export const settingsCheckboxBackground = registerColor('settings.checkboxBackground', { dark: selectBackground, light: selectBackground, hc: selectBackground }, localize('settingsCheckboxBackground', "(For settings editor preview) Settings editor checkbox background.")); -export const settingsCheckboxForeground = registerColor('settings.checkboxForeground', { dark: selectForeground, light: selectForeground, hc: selectForeground }, localize('settingsCheckboxForeground', "(For settings editor preview) Settings editor checkbox foreground.")); -export const settingsCheckboxBorder = registerColor('settings.checkboxBorder', { dark: selectBorder, light: selectBorder, hc: selectBorder }, localize('settingsCheckboxBorder', "(For settings editor preview) Settings editor checkbox border.")); - -// Text control colors -export const settingsTextInputBackground = registerColor('settings.textInputBackground', { dark: inputBackground, light: inputBackground, hc: inputBackground }, localize('textInputBoxBackground', "(For settings editor preview) Settings editor text input box background.")); -export const settingsTextInputForeground = registerColor('settings.textInputForeground', { dark: inputForeground, light: inputForeground, hc: inputForeground }, localize('textInputBoxForeground', "(For settings editor preview) Settings editor text input box foreground.")); -export const settingsTextInputBorder = registerColor('settings.textInputBorder', { dark: inputBorder, light: inputBorder, hc: inputBorder }, localize('textInputBoxBorder', "(For settings editor preview) Settings editor text input box border.")); - -// Number control colors -export const settingsNumberInputBackground = registerColor('settings.numberInputBackground', { dark: inputBackground, light: inputBackground, hc: inputBackground }, localize('numberInputBoxBackground', "(For settings editor preview) Settings editor number input box background.")); -export const settingsNumberInputForeground = registerColor('settings.numberInputForeground', { dark: inputForeground, light: inputForeground, hc: inputForeground }, localize('numberInputBoxForeground', "(For settings editor preview) Settings editor number input box foreground.")); -export const settingsNumberInputBorder = registerColor('settings.numberInputBorder', { dark: inputBorder, light: inputBorder, hc: inputBorder }, localize('numberInputBoxBorder', "(For settings editor preview) Settings editor number input box border.")); - -registerThemingParticipant((theme: ITheme, collector: ICssStyleCollector) => { - const modifiedItemForegroundColor = theme.getColor(modifiedItemForeground); - if (modifiedItemForegroundColor) { - collector.addRule(`.settings-editor > .settings-body > .settings-tree-container .setting-item.is-configured .setting-item-is-configured-label { color: ${modifiedItemForegroundColor}; }`); - collector.addRule(`.settings-editor > .settings-header > .settings-header-controls .settings-header-controls-right .toolbar-toggle-more::before { background-color: ${modifiedItemForegroundColor}; }`); - } - - const checkboxBackgroundColor = theme.getColor(settingsCheckboxBackground); - if (checkboxBackgroundColor) { - collector.addRule(`.settings-editor > .settings-body > .settings-tree-container .setting-item-bool .setting-value-checkbox { background-color: ${checkboxBackgroundColor} !important; }`); - } - - const checkboxBorderColor = theme.getColor(settingsCheckboxBorder); - if (checkboxBorderColor) { - collector.addRule(`.settings-editor > .settings-body > .settings-tree-container .setting-item-bool .setting-value-checkbox { border-color: ${checkboxBorderColor} !important; }`); - } - - const link = theme.getColor(textLinkForeground); - if (link) { - collector.addRule(`.settings-editor > .settings-body > .settings-tree-container .setting-item .setting-item-description a { color: ${link}; }`); - collector.addRule(`.settings-editor > .settings-body > .settings-tree-container .setting-item .setting-item-description a > code { color: ${link}; }`); - } - - const headerForegroundColor = theme.getColor(settingsHeaderForeground); - if (headerForegroundColor) { - collector.addRule(`.settings-editor > .settings-header > .settings-header-controls .settings-tabs-widget .action-label.checked { color: ${headerForegroundColor}; border-bottom-color: ${headerForegroundColor}; }`); - } - - const foregroundColor = theme.getColor(foreground); - if (foregroundColor) { - collector.addRule(`.settings-editor > .settings-header > .settings-header-controls .settings-tabs-widget .action-label { color: ${foregroundColor}; };`); - } -}); - export abstract class SettingsTreeElement { id: string; parent: any; // SearchResultModel or group element... TODO search should be more similar to the normal case @@ -542,7 +484,7 @@ export class SettingsRenderer implements ITreeRenderer { if (isSelected) { return this.measureSettingElementHeight(tree, element); } else if (isExcludeSetting(element)) { - return Object.keys(element.value).length * 22 + 70; + return (Object.keys(element.value).length + 1) * 22 + 70; } else { return this._getUnexpandedSettingHeight(element); } diff --git a/src/vs/workbench/parts/preferences/browser/settingsWidgets.ts b/src/vs/workbench/parts/preferences/browser/settingsWidgets.ts index f559d24921e..2e5e3a61141 100644 --- a/src/vs/workbench/parts/preferences/browser/settingsWidgets.ts +++ b/src/vs/workbench/parts/preferences/browser/settingsWidgets.ts @@ -4,12 +4,15 @@ *--------------------------------------------------------------------------------------------*/ import * as DOM from 'vs/base/browser/dom'; +import { StandardKeyboardEvent } from 'vs/base/browser/keyboardEvent'; import { ActionBar } from 'vs/base/browser/ui/actionbar/actionbar'; import { Button } from 'vs/base/browser/ui/button/button'; import { Checkbox } from 'vs/base/browser/ui/checkbox/checkbox'; import { InputBox } from 'vs/base/browser/ui/inputbox/inputBox'; import { IRenderer, IVirtualDelegate } from 'vs/base/browser/ui/list/list'; import { Action } from 'vs/base/common/actions'; +import { Emitter, Event } from 'vs/base/common/event'; +import { KeyCode } from 'vs/base/common/keyCodes'; import { Disposable, dispose, IDisposable } from 'vs/base/common/lifecycle'; import { TPromise } from 'vs/base/common/winjs.base'; import 'vs/css!./media/settingsWidgets'; @@ -17,10 +20,68 @@ import { localize } from 'vs/nls'; import { IContextViewService } from 'vs/platform/contextview/browser/contextView'; import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; import { WorkbenchList } from 'vs/platform/list/browser/listService'; -import { attachButtonStyler } from 'vs/platform/theme/common/styler'; -import { IThemeService } from 'vs/platform/theme/common/themeService'; +import { foreground, inputBackground, inputBorder, inputForeground, registerColor, selectBackground, selectBorder, selectForeground, textLinkForeground } from 'vs/platform/theme/common/colorRegistry'; +import { attachButtonStyler, attachInputBoxStyler } from 'vs/platform/theme/common/styler'; +import { ICssStyleCollector, ITheme, IThemeService, registerThemingParticipant } from 'vs/platform/theme/common/themeService'; const $ = DOM.$; +export const settingsHeaderForeground = registerColor('settings.headerForeground', { light: '#444444', dark: '#e7e7e7', hc: '#ffffff' }, localize('headerForeground', "(For settings editor preview) The foreground color for a section header or active title in the editor.")); +export const modifiedItemForeground = registerColor('settings.modifiedItemForeground', { light: '#019001', dark: '#73C991', hc: '#73C991' }, localize('modifiedItemForeground', "(For settings editor preview) The foreground color for a modified setting.")); +export const settingItemInactiveSelectionBorder = registerColor('settings.inactiveSelectedItemBorder', { dark: '#3F3F46', light: '#CCCEDB', hc: null }, localize('settingItemInactiveSelectionBorder', "(For settings editor preview) The color of the selected setting row border, when the settings list does not have focus.")); + +// Enum control colors +export const settingsSelectBackground = registerColor('settings.dropdownBackground', { dark: selectBackground, light: selectBackground, hc: selectBackground }, localize('settingsDropdownBackground', "(For settings editor preview) Settings editor dropdown background.")); +export const settingsSelectForeground = registerColor('settings.dropdownForeground', { dark: selectForeground, light: selectForeground, hc: selectForeground }, localize('settingsDropdownForeground', "(For settings editor preview) Settings editor dropdown foreground.")); +export const settingsSelectBorder = registerColor('settings.dropdownBorder', { dark: selectBorder, light: selectBorder, hc: selectBorder }, localize('settingsDropdownBorder', "(For settings editor preview) Settings editor dropdown border.")); + +// Bool control colors +export const settingsCheckboxBackground = registerColor('settings.checkboxBackground', { dark: selectBackground, light: selectBackground, hc: selectBackground }, localize('settingsCheckboxBackground', "(For settings editor preview) Settings editor checkbox background.")); +export const settingsCheckboxForeground = registerColor('settings.checkboxForeground', { dark: selectForeground, light: selectForeground, hc: selectForeground }, localize('settingsCheckboxForeground', "(For settings editor preview) Settings editor checkbox foreground.")); +export const settingsCheckboxBorder = registerColor('settings.checkboxBorder', { dark: selectBorder, light: selectBorder, hc: selectBorder }, localize('settingsCheckboxBorder', "(For settings editor preview) Settings editor checkbox border.")); + +// Text control colors +export const settingsTextInputBackground = registerColor('settings.textInputBackground', { dark: inputBackground, light: inputBackground, hc: inputBackground }, localize('textInputBoxBackground', "(For settings editor preview) Settings editor text input box background.")); +export const settingsTextInputForeground = registerColor('settings.textInputForeground', { dark: inputForeground, light: inputForeground, hc: inputForeground }, localize('textInputBoxForeground', "(For settings editor preview) Settings editor text input box foreground.")); +export const settingsTextInputBorder = registerColor('settings.textInputBorder', { dark: inputBorder, light: inputBorder, hc: inputBorder }, localize('textInputBoxBorder', "(For settings editor preview) Settings editor text input box border.")); + +// Number control colors +export const settingsNumberInputBackground = registerColor('settings.numberInputBackground', { dark: inputBackground, light: inputBackground, hc: inputBackground }, localize('numberInputBoxBackground', "(For settings editor preview) Settings editor number input box background.")); +export const settingsNumberInputForeground = registerColor('settings.numberInputForeground', { dark: inputForeground, light: inputForeground, hc: inputForeground }, localize('numberInputBoxForeground', "(For settings editor preview) Settings editor number input box foreground.")); +export const settingsNumberInputBorder = registerColor('settings.numberInputBorder', { dark: inputBorder, light: inputBorder, hc: inputBorder }, localize('numberInputBoxBorder', "(For settings editor preview) Settings editor number input box border.")); + +registerThemingParticipant((theme: ITheme, collector: ICssStyleCollector) => { + const modifiedItemForegroundColor = theme.getColor(modifiedItemForeground); + if (modifiedItemForegroundColor) { + collector.addRule(`.settings-editor > .settings-body > .settings-tree-container .setting-item.is-configured .setting-item-is-configured-label { color: ${modifiedItemForegroundColor}; }`); + collector.addRule(`.settings-editor > .settings-header > .settings-header-controls .settings-header-controls-right .toolbar-toggle-more::before { background-color: ${modifiedItemForegroundColor}; }`); + } + + const checkboxBackgroundColor = theme.getColor(settingsCheckboxBackground); + if (checkboxBackgroundColor) { + collector.addRule(`.settings-editor > .settings-body > .settings-tree-container .setting-item-bool .setting-value-checkbox { background-color: ${checkboxBackgroundColor} !important; }`); + } + + const checkboxBorderColor = theme.getColor(settingsCheckboxBorder); + if (checkboxBorderColor) { + collector.addRule(`.settings-editor > .settings-body > .settings-tree-container .setting-item-bool .setting-value-checkbox { border-color: ${checkboxBorderColor} !important; }`); + } + + const link = theme.getColor(textLinkForeground); + if (link) { + collector.addRule(`.settings-editor > .settings-body > .settings-tree-container .setting-item .setting-item-description a { color: ${link}; }`); + collector.addRule(`.settings-editor > .settings-body > .settings-tree-container .setting-item .setting-item-description a > code { color: ${link}; }`); + } + + const headerForegroundColor = theme.getColor(settingsHeaderForeground); + if (headerForegroundColor) { + collector.addRule(`.settings-editor > .settings-header > .settings-header-controls .settings-tabs-widget .action-label.checked { color: ${headerForegroundColor}; border-bottom-color: ${headerForegroundColor}; }`); + } + + const foregroundColor = theme.getColor(foreground); + if (foregroundColor) { + collector.addRule(`.settings-editor > .settings-header > .settings-header-controls .settings-tabs-widget .action-label { color: ${foregroundColor}; };`); + } +}); enum AddItemMode { None, @@ -36,16 +97,19 @@ export class ExcludeSettingListModel { const items = [ ...this._dataItems ]; - if (this._newItem === AddItemMode.Pattern) { - items.push({ - id: 'newItem', - withSibling: false - }); - } + + items.push({ + id: 'newItem', + mode: this._newItem + }); return items; } + setAddItemMode(mode: AddItemMode): void { + this._newItem = mode; + } + setValue(excludeValue: any): void { this._dataItems = this.excludeValueToItems(excludeValue); } @@ -91,17 +155,27 @@ export class ExcludeSettingWidget extends Disposable { addPatternButton.label = localize('addPattern', "Add Pattern"); addPatternButton.element.classList.add('setting-exclude-addPattern', 'setting-exclude-addButton'); this._register(attachButtonStyler(addPatternButton, this.themeService)); + this._register(addPatternButton.onDidClick(() => { + this.model.setAddItemMode(AddItemMode.Pattern); + this.update(); + })); const addSiblingPatternButton = this._register(new Button(container)); addSiblingPatternButton.label = localize('addSiblingPattern', "Add Sibling Pattern"); addSiblingPatternButton.element.classList.add('setting-exclude-addButton'); this._register(attachButtonStyler(addSiblingPatternButton, this.themeService)); this._register(addSiblingPatternButton.onDidClick(() => { + this.model.setAddItemMode(AddItemMode.PatternWithSibling); + this.update(); })); } setValue(excludeValue: any): void { this.model.setValue(excludeValue); + this.update(); + } + + private update(): void { this.list.splice(0, this.list.length, this.model.items); const listHeight = 22 * this.model.items.length; @@ -119,7 +193,7 @@ interface IExcludeDataItem { interface INewExcludeItem { id: string; - withSibling: boolean; + mode: AddItemMode; } type IExcludeItem = IExcludeDataItem | INewExcludeItem; @@ -198,35 +272,85 @@ interface INewExcludeItemTemplate { container: HTMLElement; patternInput: InputBox; + siblingInput: InputBox; toDispose: IDisposable[]; } +interface INewExcludeItemEvent { + pattern: string; + sibling?: string; +} + class NewExcludeRenderer implements IRenderer { static readonly templateId: string = 'newExcludeItem'; + private readonly _onNewExcludeItem: Emitter = new Emitter(); + public readonly onNewExcludeItem: Event = this._onNewExcludeItem.event; + constructor( - @IContextViewService private contextViewService: IContextViewService + @IContextViewService private contextViewService: IContextViewService, + @IThemeService private themeService: IThemeService ) { } get templateId(): string { - return ExcludeDataItemRenderer.templateId; + return NewExcludeRenderer.templateId; } renderTemplate(container: HTMLElement): INewExcludeItemTemplate { const toDispose = []; - const patternInput = new InputBox(container, this.contextViewService); + const onKeydown = (e: StandardKeyboardEvent) => { + if (e.equals(KeyCode.Enter)) { + this._onNewExcludeItem.fire({ + pattern: patternInput.value, + sibling: siblingInput.value + }); + } + }; + + const patternInput = new InputBox(container, this.contextViewService, { + placeholder: localize('excludePatternInputPlaceholder', "Exclude Pattern...") + }); + patternInput.element.classList.add('setting-exclude-patternInput'); + toDispose.push(attachInputBoxStyler(patternInput, this.themeService, { + inputBackground: settingsTextInputBackground, + inputForeground: settingsTextInputForeground, + inputBorder: settingsTextInputBorder + })); toDispose.push(patternInput); + toDispose.push(DOM.addStandardDisposableListener(patternInput.inputElement, DOM.EventType.KEY_DOWN, onKeydown)); + + const siblingInput = new InputBox(container, this.contextViewService, { + placeholder: localize('excludeSiblingInputPlaceholder', "When Pattern Is Present...") + }); + siblingInput.element.classList.add('setting-exclude-siblingInput'); + toDispose.push(siblingInput); + toDispose.push(attachInputBoxStyler(siblingInput, this.themeService, { + inputBackground: settingsTextInputBackground, + inputForeground: settingsTextInputForeground, + inputBorder: settingsTextInputBorder + })); + toDispose.push(DOM.addStandardDisposableListener(siblingInput.inputElement, DOM.EventType.KEY_DOWN, onKeydown)); return { container, patternInput, + siblingInput, toDispose }; } renderElement(element: INewExcludeItem, index: number, templateData: INewExcludeItemTemplate): void { + templateData.container.classList.add('setting-exclude-newExcludeItem'); + + templateData.container.classList.remove('setting-exclude-newPattern'); + templateData.container.classList.remove('setting-exclude-newPatternWithSibling'); + if (element.mode === AddItemMode.Pattern) { + templateData.container.classList.add('setting-exclude-newPattern'); + } else if (element.mode === AddItemMode.PatternWithSibling) { + templateData.container.classList.add('setting-exclude-newPatternWithSibling'); + } } disposeElement(element: INewExcludeItem, index: number, templateData: INewExcludeItemTemplate): void { From 8d14a78c756b1ffd46c6f01cf922031f0f70db22 Mon Sep 17 00:00:00 2001 From: Rob Lourens Date: Tue, 24 Jul 2018 20:38:18 -0700 Subject: [PATCH 0102/1276] Settings editor - implement 'delete' in files.exclude control --- .../browser/media/settingsWidgets.css | 22 +-- .../parts/preferences/browser/settingsTree.ts | 126 +++++++++++++-- .../preferences/browser/settingsWidgets.ts | 144 +++++++++--------- 3 files changed, 185 insertions(+), 107 deletions(-) diff --git a/src/vs/workbench/parts/preferences/browser/media/settingsWidgets.css b/src/vs/workbench/parts/preferences/browser/media/settingsWidgets.css index 782cf158b88..c57b7fa82ed 100644 --- a/src/vs/workbench/parts/preferences/browser/media/settingsWidgets.css +++ b/src/vs/workbench/parts/preferences/browser/media/settingsWidgets.css @@ -9,12 +9,14 @@ .settings-editor > .settings-body > .settings-tree-container .setting-item.setting-item-exclude .setting-exclude-pattern { margin-right: 3px; + margin-left: 2px; } .settings-editor > .settings-body > .settings-tree-container .setting-item.setting-item-exclude .setting-exclude-pattern, .settings-editor > .settings-body > .settings-tree-container .setting-item.setting-item-exclude .setting-exclude-sibling { display: inline-block; line-height: 22px; + font-family: Menlo, Monaco, Consolas, "Droid Sans Mono", "Courier New", monospace, "Droid Sans Fallback"; } .settings-editor > .settings-body > .settings-tree-container .setting-item.setting-item-exclude .setting-exclude-sibling { @@ -104,26 +106,6 @@ display: inline-block; } -.settings-editor > .settings-body > .settings-tree-container .setting-item.setting-item-exclude .setting-exclude-checkbox { - height: 16px; - width: 16px; - border: 1px solid transparent; - border-radius: 3px; - margin-right: 4px; - margin-left: 0px; - margin-top: 3px; - padding: 0px; - background-size: 14px !important; -} - -.vs .settings-editor > .settings-body > .settings-tree-container .setting-item.setting-item-exclude .setting-exclude-checkbox.checked { - background: url('check.svg') center center no-repeat; -} - -.vs-dark .settings-editor > .settings-body > .settings-tree-container .setting-item.setting-item-exclude .setting-exclude-checkbox.checked { - background: url('check-inverse.svg') center center no-repeat; -} - .settings-editor > .settings-body > .settings-tree-container .setting-item.setting-item-exclude .monaco-list { margin-bottom: 10px; } diff --git a/src/vs/workbench/parts/preferences/browser/settingsTree.ts b/src/vs/workbench/parts/preferences/browser/settingsTree.ts index a7d5dd1ea7a..b44337c439b 100644 --- a/src/vs/workbench/parts/preferences/browser/settingsTree.ts +++ b/src/vs/workbench/parts/preferences/browser/settingsTree.ts @@ -57,11 +57,30 @@ export class SettingsTreeSettingElement extends SettingsTreeElement { displayCategory: string; displayLabel: string; + + /** + * scopeValue || defaultValue, for rendering convenience. + */ value: any; + + /** + * The value in the current settings scope. + */ + scopeValue: any; + + /** + * The default value + */ + defaultValue?: any; + + /** + * Whether the setting is configured in the selected scope. + */ isConfigured: boolean; + overriddenScopeList: string[]; description: string; - valueType: 'enum' | 'string' | 'integer' | 'number' | 'boolean' | 'complex'; + valueType: 'enum' | 'string' | 'integer' | 'number' | 'boolean' | 'exclude' | 'complex'; } export interface ITOCEntry { @@ -149,7 +168,8 @@ function createSettingsTreeSettingElement(setting: ISetting, parent: any, settin element.id = sanitizeId(parent.id + '_' + setting.key); element.parent = parent; - const { isConfigured, inspected, targetSelector } = inspectSetting(setting.key, settingsTarget, configurationService); + const inspectResult = inspectSetting(setting.key, settingsTarget, configurationService); + const { isConfigured, inspected, targetSelector } = inspectResult; const displayValue = isConfigured ? inspected[targetSelector] : inspected.default; const overriddenScopeList = []; @@ -167,21 +187,56 @@ function createSettingsTreeSettingElement(setting: ISetting, parent: any, settin element.displayCategory = displayKeyFormat.category; element.value = displayValue; + element.scopeValue = isConfigured && inspected[targetSelector]; + element.defaultValue = inspected.default; + element.isConfigured = isConfigured; element.overriddenScopeList = overriddenScopeList; element.description = setting.description.join('\n'); - element.valueType = (setting.enum && (setting.type === 'string' || !setting.type)) ? 'enum' : - setting.type === 'string' ? 'string' : - setting.type === 'integer' ? 'integer' : - setting.type === 'number' ? 'number' : - setting.type === 'boolean' ? 'boolean' : - 'complex'; + if (setting.enum && (setting.type === 'string' || !setting.type)) { + element.valueType = 'enum'; + } else if (setting.type === 'string') { + element.valueType = 'string'; + } else if (isExcludeSetting(setting)) { + element.valueType = 'exclude'; + } else if (setting.type === 'integer') { + element.valueType = 'integer'; + } else if (setting.type === 'number') { + element.valueType = 'number'; + } else if (setting.type === 'boolean') { + element.valueType = 'boolean'; + } else { + element.valueType = 'complex'; + } return element; } -function inspectSetting(key: string, target: SettingsTarget, configurationService: IConfigurationService): { isConfigured: boolean, inspected: any, targetSelector: string } { +function getExcludeDisplayValue(element: SettingsTreeSettingElement): any { + const data = element.isConfigured ? + { + ...element.defaultValue, + ...element.value + } : + element.defaultValue; + + for (let key in data) { + if (!data[key]) { + delete data[key]; + } + } + + return data; +} + +interface IInspectResult { + isConfigured: boolean; + inspected: any; + targetSelector: string; +} + +function inspectSetting(key: string, target: SettingsTarget, configurationService: IConfigurationService): IInspectResult { const inspectOverrides = URI.isUri(target) ? { resource: target } : undefined; const inspected = configurationService.inspect(key, inspectOverrides); const targetSelector = target === ConfigurationTarget.USER ? 'user' : @@ -419,10 +474,11 @@ interface ISettingComplexItemTemplate extends ISettingItemTemplate { interface ISettingExcludeItemTemplate extends ISettingItemTemplate { excludeWidget: ExcludeSettingWidget; + context?: SettingsTreeSettingElement; } -function isExcludeSetting(element: SettingsTreeSettingElement): boolean { - return element.setting.key === 'files.exclude'; +function isExcludeSetting(setting: ISetting): boolean { + return setting.key === 'files.exclude'; } interface IGroupTitleTemplate extends IDisposableTemplate { @@ -483,8 +539,8 @@ export class SettingsRenderer implements ITreeRenderer { const isSelected = this.elementIsSelected(tree, element); if (isSelected) { return this.measureSettingElementHeight(tree, element); - } else if (isExcludeSetting(element)) { - return (Object.keys(element.value).length + 1) * 22 + 70; + } else if (isExcludeSetting(element.setting)) { + return this._getExcludeSettingHeight(element); } else { return this._getUnexpandedSettingHeight(element); } @@ -493,6 +549,11 @@ export class SettingsRenderer implements ITreeRenderer { return 0; } + _getExcludeSettingHeight(element: SettingsTreeSettingElement): number { + const displayValue = getExcludeDisplayValue(element); + return (Object.keys(displayValue).length + 1) * 22 + 70; + } + _getUnexpandedSettingHeight(element: SettingsTreeSettingElement): number { if (element.valueType === 'boolean') { return SettingsRenderer.SETTING_BOOL_ROW_HEIGHT; @@ -536,7 +597,7 @@ export class SettingsRenderer implements ITreeRenderer { return SETTINGS_ENUM_TEMPLATE_ID; } - if (isExcludeSetting(element)) { + if (element.valueType === 'exclude') { return SETTINGS_EXCLUDE_TEMPLATE_ID; } @@ -779,6 +840,39 @@ export class SettingsRenderer implements ITreeRenderer { excludeWidget }; + common.toDispose.push(excludeWidget.onDidChangeExclude(e => { + if (template.context) { + const newValue = { + ...template.context.scopeValue + }; + + if (e.pattern) { + if (e.originalPattern in newValue) { + // editing something present in the value + newValue[e.pattern] = newValue[e.originalPattern]; + delete newValue[e.originalPattern]; + } else { + // editing a default + newValue[e.originalPattern] = false; + newValue[e.pattern] = template.context.defaultValue[e.originalPattern]; + } + } else { + if (e.originalPattern in newValue) { + // deleting a configured pattern + delete newValue[e.originalPattern]; + } else { + // "deleting" a default by overriding it + newValue[e.originalPattern] = false; + } + } + + this._onDidChangeSetting.fire({ + key: template.context.setting.key, + value: newValue + }); + } + })); + return template; } @@ -954,7 +1048,9 @@ export class SettingsRenderer implements ITreeRenderer { } private renderExcludeSetting(dataElement: SettingsTreeSettingElement, isSelected: boolean, template: ISettingExcludeItemTemplate): void { - template.excludeWidget.setValue(dataElement.value); + const value = getExcludeDisplayValue(dataElement); + template.excludeWidget.setValue(value); + template.context = dataElement; } private renderComplexSetting(dataElement: SettingsTreeSettingElement, isSelected: boolean, template: ISettingComplexItemTemplate): void { diff --git a/src/vs/workbench/parts/preferences/browser/settingsWidgets.ts b/src/vs/workbench/parts/preferences/browser/settingsWidgets.ts index 2e5e3a61141..bbb79af5539 100644 --- a/src/vs/workbench/parts/preferences/browser/settingsWidgets.ts +++ b/src/vs/workbench/parts/preferences/browser/settingsWidgets.ts @@ -7,14 +7,12 @@ import * as DOM from 'vs/base/browser/dom'; import { StandardKeyboardEvent } from 'vs/base/browser/keyboardEvent'; import { ActionBar } from 'vs/base/browser/ui/actionbar/actionbar'; import { Button } from 'vs/base/browser/ui/button/button'; -import { Checkbox } from 'vs/base/browser/ui/checkbox/checkbox'; import { InputBox } from 'vs/base/browser/ui/inputbox/inputBox'; import { IRenderer, IVirtualDelegate } from 'vs/base/browser/ui/list/list'; -import { Action } from 'vs/base/common/actions'; +import { IAction } from 'vs/base/common/actions'; import { Emitter, Event } from 'vs/base/common/event'; import { KeyCode } from 'vs/base/common/keyCodes'; import { Disposable, dispose, IDisposable } from 'vs/base/common/lifecycle'; -import { TPromise } from 'vs/base/common/winjs.base'; import 'vs/css!./media/settingsWidgets'; import { localize } from 'vs/nls'; import { IContextViewService } from 'vs/platform/contextview/browser/contextView'; @@ -110,31 +108,38 @@ export class ExcludeSettingListModel { this._newItem = mode; } - setValue(excludeValue: any): void { + setValue(excludeValue: any, defaultValue: any): void { this._dataItems = this.excludeValueToItems(excludeValue); } private excludeValueToItems(excludeValue: any): IExcludeItem[] { - return Object.keys(excludeValue).map(key => { - const value = excludeValue[key]; - const enabled = !!value; - const sibling = typeof value === 'boolean' ? undefined : value.when; + return Object.keys(excludeValue) + .map(key => { + const value = excludeValue[key]; + const sibling = typeof value === 'boolean' ? undefined : value.when; - return { - id: key, - enabled, - pattern: key, - sibling - }; - }); + return { + id: key, + pattern: key, + sibling + }; + }); } } +interface IExcludeChangeEvent { + originalPattern: string; + pattern: string; +} + export class ExcludeSettingWidget extends Disposable { private list: WorkbenchList; private model = new ExcludeSettingListModel(); + private readonly _onDidChangeExclude: Emitter = new Emitter(); + public readonly onDidChangeExclude: Event = this._onDidChangeExclude.event; + constructor( container: HTMLElement, @IThemeService private themeService: IThemeService, @@ -143,6 +148,11 @@ export class ExcludeSettingWidget extends Disposable { super(); const dataRenderer = new ExcludeDataItemRenderer(); + this._register(dataRenderer.onDidRemoveExclude(key => this._onDidChangeExclude.fire({ originalPattern: key, pattern: undefined }))); + this._register(dataRenderer.onEditExclude(key => { + // this.model + })); + const newItemRenderer = this.instantiationService.createInstance(NewExcludeRenderer); const delegate = new ExcludeSettingListDelegate(); this.list = this.instantiationService.createInstance(WorkbenchList, container, delegate, [newItemRenderer, dataRenderer], { @@ -159,19 +169,10 @@ export class ExcludeSettingWidget extends Disposable { this.model.setAddItemMode(AddItemMode.Pattern); this.update(); })); - - const addSiblingPatternButton = this._register(new Button(container)); - addSiblingPatternButton.label = localize('addSiblingPattern', "Add Sibling Pattern"); - addSiblingPatternButton.element.classList.add('setting-exclude-addButton'); - this._register(attachButtonStyler(addSiblingPatternButton, this.themeService)); - this._register(addSiblingPatternButton.onDidClick(() => { - this.model.setAddItemMode(AddItemMode.PatternWithSibling); - this.update(); - })); } setValue(excludeValue: any): void { - this.model.setValue(excludeValue); + this.model.setValue(excludeValue, void 0); this.update(); } @@ -186,7 +187,6 @@ export class ExcludeSettingWidget extends Disposable { interface IExcludeDataItem { id: string; - enabled: boolean; pattern: string; sibling?: string; } @@ -205,7 +205,6 @@ function isExcludeDataItem(excludeItem: IExcludeItem): excludeItem is IExcludeDa interface IExcludeDataItemTemplate { container: HTMLElement; - checkbox: Checkbox; actionBar: ActionBar; patternElement: HTMLElement; siblingElement: HTMLElement; @@ -215,6 +214,12 @@ interface IExcludeDataItemTemplate { class ExcludeDataItemRenderer implements IRenderer { static readonly templateId: string = 'excludeDataItem'; + private readonly _onDidRemoveExclude: Emitter = new Emitter(); + public readonly onDidRemoveExclude: Event = this._onDidRemoveExclude.event; + + private readonly _onEditExclude: Emitter = new Emitter(); + public readonly onEditExclude: Event = this._onEditExclude.event; + get templateId(): string { return ExcludeDataItemRenderer.templateId; } @@ -222,28 +227,11 @@ class ExcludeDataItemRenderer implements IRenderer { - // if (template.onChange) { - // template.onChange(checkbox.checked); - // } - })); - const actionBar = new ActionBar(container); toDispose.push(actionBar); - const editAction = new EditExcludeItemAction(); - const removeAction = new RemoveExcludeItemAction(); - toDispose.push(editAction, removeAction); - actionBar.push([ - editAction, removeAction - ], { icon: true, label: false }); - return { container, - checkbox, patternElement: DOM.append(container, $('.setting-exclude-pattern')), siblingElement: DOM.append(container, $('.setting-exclude-sibling')), toDispose, @@ -251,9 +239,35 @@ class ExcludeDataItemRenderer implements IRenderer{ + class: 'setting-excludeAction-remove', + enabled: true, + id: 'workbench.action.removeExcludeItem', + tooltip: localize('removeExcludeItem', "Remove Exclude Item"), + run: () => this._onDidRemoveExclude.fire(key) + }; + } + + private createEditAction(key: string): IAction { + return { + class: 'setting-excludeAction-edit', + enabled: true, + id: 'workbench.action.editExcludeItem', + tooltip: localize('editExcludeItem', "Edit Exclude Item"), + run: () => this._onEditExclude.fire(key) + }; + } + renderElement(element: IExcludeDataItem, index: number, templateData: IExcludeDataItemTemplate): void { templateData.patternElement.textContent = element.pattern; - templateData.siblingElement.textContent = element.sibling; + templateData.siblingElement.textContent = element.sibling && ('when: ' + element.sibling); + + templateData.actionBar.clear(); + templateData.actionBar.push([ + this.createEditAction(element.pattern), + this.createDeleteAction(element.pattern) + ], { icon: true, label: false }); templateData.container.title = element.sibling ? localize('excludeSiblingHintLabel', "Exclude files matching `{0}`, only when a file matching `{1}` is present", element.pattern, element.sibling) : @@ -348,6 +362,8 @@ class NewExcludeRenderer implements IRenderer { } } -class EditExcludeItemAction extends Action { +// class EditExcludeItemAction extends Action { - static readonly ID = 'workbench.action.editExcludeItem'; - static readonly LABEL = localize('editExcludeItem', "Edit Exclude Item"); +// static readonly ID = 'workbench.action.editExcludeItem'; +// static readonly LABEL = localize('editExcludeItem', "Edit Exclude Item"); - constructor() { - super(EditExcludeItemAction.ID, EditExcludeItemAction.LABEL); +// constructor() { +// super(EditExcludeItemAction.ID, EditExcludeItemAction.LABEL); - this.class = 'setting-excludeAction-edit'; - } +// this.class = 'setting-excludeAction-edit'; +// } - run(item: IExcludeItem): TPromise { - return TPromise.wrap(true); - } -} - -class RemoveExcludeItemAction extends Action { - - static readonly ID = 'workbench.action.removeExcludeItem'; - static readonly LABEL = localize('removeExcludeItem', "Remove Exclude Item"); - - constructor() { - super(RemoveExcludeItemAction.ID, RemoveExcludeItemAction.LABEL); - - this.class = 'setting-excludeAction-remove'; - } - - run(item: IExcludeItem): TPromise { - return TPromise.wrap(true); - } -} +// run(item: IExcludeItem): TPromise { +// return TPromise.wrap(true); +// } +// } From 4f053d820d29a752145cb9b9c3ff23909f22fe88 Mon Sep 17 00:00:00 2001 From: Rob Lourens Date: Tue, 24 Jul 2018 21:27:49 -0700 Subject: [PATCH 0103/1276] Settings exclude control - replace fancypants List with basic dom manipulation --- .../browser/media/settingsWidgets.css | 36 +- .../preferences/browser/settingsWidgets.ts | 341 +++++++----------- 2 files changed, 147 insertions(+), 230 deletions(-) diff --git a/src/vs/workbench/parts/preferences/browser/media/settingsWidgets.css b/src/vs/workbench/parts/preferences/browser/media/settingsWidgets.css index c57b7fa82ed..eb6dfcb6401 100644 --- a/src/vs/workbench/parts/preferences/browser/media/settingsWidgets.css +++ b/src/vs/workbench/parts/preferences/browser/media/settingsWidgets.css @@ -33,35 +33,39 @@ margin-top: 1px; } -.settings-editor > .settings-body > .settings-tree-container .setting-item.setting-item-exclude .monaco-list-row:hover .monaco-action-bar, -.settings-editor > .settings-body > .settings-tree-container .setting-item.setting-item-exclude .monaco-list-row.focused .monaco-action-bar { +.settings-editor > .settings-body > .settings-tree-container .setting-item.setting-item-exclude .setting-exclude-row { + position: relative; +} + +.settings-editor > .settings-body > .settings-tree-container .setting-item.setting-item-exclude .setting-exclude-row:hover .monaco-action-bar, +.settings-editor > .settings-body > .settings-tree-container .setting-item.setting-item-exclude .setting-exclude-row.focused .monaco-action-bar { display: block; } -.settings-editor > .settings-body > .settings-tree-container .setting-item.setting-item-exclude .monaco-list-row .monaco-action-bar .action-label { +.settings-editor > .settings-body > .settings-tree-container .setting-item.setting-item-exclude .setting-exclude-row .monaco-action-bar .action-label { width: 16px; height: 16px; padding: 2px; margin-right: 2px; } -.settings-editor > .settings-body > .settings-tree-container .setting-item.setting-item-exclude .monaco-list-row .monaco-action-bar .setting-excludeAction-edit { +.settings-editor > .settings-body > .settings-tree-container .setting-item.setting-item-exclude .setting-exclude-row .monaco-action-bar .setting-excludeAction-edit { margin-right: 4px; } -.vs .settings-editor > .settings-body > .settings-tree-container .setting-item.setting-item-exclude .monaco-list-row .monaco-action-bar .setting-excludeAction-edit { +.vs .settings-editor > .settings-body > .settings-tree-container .setting-item.setting-item-exclude .setting-exclude-row .monaco-action-bar .setting-excludeAction-edit { background: url(edit.svg) center center no-repeat; } -.vs-dark .settings-editor > .settings-body > .settings-tree-container .setting-item.setting-item-exclude .monaco-list-row .monaco-action-bar .setting-excludeAction-edit { +.vs-dark .settings-editor > .settings-body > .settings-tree-container .setting-item.setting-item-exclude .setting-exclude-row .monaco-action-bar .setting-excludeAction-edit { background: url(edit_inverse.svg) center center no-repeat; } -.vs .settings-editor > .settings-body > .settings-tree-container .setting-item.setting-item-exclude .monaco-list-row .monaco-action-bar .setting-excludeAction-remove { +.vs .settings-editor > .settings-body > .settings-tree-container .setting-item.setting-item-exclude .setting-exclude-row .monaco-action-bar .setting-excludeAction-remove { background: url(action-remove.svg) center center no-repeat; } -.vs-dark .settings-editor > .settings-body > .settings-tree-container .setting-item.setting-item-exclude .monaco-list-row .monaco-action-bar .setting-excludeAction-remove { +.vs-dark .settings-editor > .settings-body > .settings-tree-container .setting-item.setting-item-exclude .setting-exclude-row .monaco-action-bar .setting-excludeAction-remove { background: url(action-remove-dark.svg) center center no-repeat; } @@ -82,30 +86,30 @@ display: inline-block; } -.settings-editor > .settings-body > .settings-tree-container .setting-item.setting-item-exclude .monaco-list-row.setting-exclude-newExcludeItem { +.settings-editor > .settings-body > .settings-tree-container .setting-item.setting-item-exclude .setting-exclude-new-row.setting-exclude-newExcludeItem { display: flex; } -.settings-editor > .settings-body > .settings-tree-container .setting-item.setting-item-exclude .monaco-list-row.setting-exclude-newExcludeItem .setting-exclude-patternInput, -.settings-editor > .settings-body > .settings-tree-container .setting-item.setting-item-exclude .monaco-list-row.setting-exclude-newExcludeItem .setting-exclude-siblingInput { +.settings-editor > .settings-body > .settings-tree-container .setting-item.setting-item-exclude .setting-exclude-new-row.setting-exclude-newExcludeItem .setting-exclude-patternInput, +.settings-editor > .settings-body > .settings-tree-container .setting-item.setting-item-exclude .setting-exclude-new-row.setting-exclude-newExcludeItem .setting-exclude-siblingInput { display: none; flex: 1; max-width: 200px; } -.settings-editor > .settings-body > .settings-tree-container .setting-item.setting-item-exclude .monaco-list-row.setting-exclude-newPattern .setting-exclude-patternInput { +.settings-editor > .settings-body > .settings-tree-container .setting-item.setting-item-exclude .setting-exclude-new-row.setting-exclude-newPattern .setting-exclude-patternInput { display: inline-block; } -.settings-editor > .settings-body > .settings-tree-container .setting-item.setting-item-exclude .monaco-list-row.setting-exclude-newPatternWithSibling .setting-exclude-patternInput { +.settings-editor > .settings-body > .settings-tree-container .setting-item.setting-item-exclude .setting-exclude-new-row.setting-exclude-newPatternWithSibling .setting-exclude-patternInput { margin-right: 5px; } -.settings-editor > .settings-body > .settings-tree-container .setting-item.setting-item-exclude .monaco-list-row.setting-exclude-newPatternWithSibling .setting-exclude-patternInput, -.settings-editor > .settings-body > .settings-tree-container .setting-item.setting-item-exclude .monaco-list-row.setting-exclude-newPatternWithSibling .setting-exclude-siblingInput { +.settings-editor > .settings-body > .settings-tree-container .setting-item.setting-item-exclude .setting-exclude-new-row.setting-exclude-newPatternWithSibling .setting-exclude-patternInput, +.settings-editor > .settings-body > .settings-tree-container .setting-item.setting-item-exclude .setting-exclude-new-row.setting-exclude-newPatternWithSibling .setting-exclude-siblingInput { display: inline-block; } -.settings-editor > .settings-body > .settings-tree-container .setting-item.setting-item-exclude .monaco-list { +.settings-editor > .settings-body > .settings-tree-container .setting-item.setting-item-exclude .setting-exclude-widget { margin-bottom: 10px; } diff --git a/src/vs/workbench/parts/preferences/browser/settingsWidgets.ts b/src/vs/workbench/parts/preferences/browser/settingsWidgets.ts index bbb79af5539..675e598ac1c 100644 --- a/src/vs/workbench/parts/preferences/browser/settingsWidgets.ts +++ b/src/vs/workbench/parts/preferences/browser/settingsWidgets.ts @@ -8,7 +8,6 @@ import { StandardKeyboardEvent } from 'vs/base/browser/keyboardEvent'; import { ActionBar } from 'vs/base/browser/ui/actionbar/actionbar'; import { Button } from 'vs/base/browser/ui/button/button'; import { InputBox } from 'vs/base/browser/ui/inputbox/inputBox'; -import { IRenderer, IVirtualDelegate } from 'vs/base/browser/ui/list/list'; import { IAction } from 'vs/base/common/actions'; import { Emitter, Event } from 'vs/base/common/event'; import { KeyCode } from 'vs/base/common/keyCodes'; @@ -16,9 +15,7 @@ import { Disposable, dispose, IDisposable } from 'vs/base/common/lifecycle'; import 'vs/css!./media/settingsWidgets'; import { localize } from 'vs/nls'; import { IContextViewService } from 'vs/platform/contextview/browser/contextView'; -import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; -import { WorkbenchList } from 'vs/platform/list/browser/listService'; -import { foreground, inputBackground, inputBorder, inputForeground, registerColor, selectBackground, selectBorder, selectForeground, textLinkForeground } from 'vs/platform/theme/common/colorRegistry'; +import { foreground, inputBackground, inputBorder, inputForeground, listHoverBackground, registerColor, selectBackground, selectBorder, selectForeground, textLinkForeground } from 'vs/platform/theme/common/colorRegistry'; import { attachButtonStyler, attachInputBoxStyler } from 'vs/platform/theme/common/styler'; import { ICssStyleCollector, ITheme, IThemeService, registerThemingParticipant } from 'vs/platform/theme/common/themeService'; @@ -77,7 +74,12 @@ registerThemingParticipant((theme: ITheme, collector: ICssStyleCollector) => { const foregroundColor = theme.getColor(foreground); if (foregroundColor) { - collector.addRule(`.settings-editor > .settings-header > .settings-header-controls .settings-tabs-widget .action-label { color: ${foregroundColor}; };`); + collector.addRule(`.settings-editor > .settings-header > .settings-header-controls .settings-tabs-widget .action-label { color: ${foregroundColor}; }`); + } + + const listHoverBackgroundColor = theme.getColor(listHoverBackground); + if (listHoverBackgroundColor) { + collector.addRule(`.settings-editor > .settings-body > .settings-tree-container .setting-item.setting-item-exclude .setting-exclude-row:hover { background-color: ${listHoverBackgroundColor}; }`); } }); @@ -88,8 +90,8 @@ enum AddItemMode { } export class ExcludeSettingListModel { - private _dataItems: IExcludeItem[]; - private _newItem: AddItemMode; + private _dataItems: IExcludeItem[] = []; + private _newItem = AddItemMode.None; get items(): IExcludeItem[] { const items = [ @@ -133,7 +135,8 @@ interface IExcludeChangeEvent { } export class ExcludeSettingWidget extends Disposable { - private list: WorkbenchList; + private listElement: HTMLElement; + private renderedDisposables: IDisposable[] = []; private model = new ExcludeSettingListModel(); @@ -143,23 +146,11 @@ export class ExcludeSettingWidget extends Disposable { constructor( container: HTMLElement, @IThemeService private themeService: IThemeService, - @IInstantiationService private instantiationService: IInstantiationService + @IContextViewService private contextViewService: IContextViewService ) { super(); - const dataRenderer = new ExcludeDataItemRenderer(); - this._register(dataRenderer.onDidRemoveExclude(key => this._onDidChangeExclude.fire({ originalPattern: key, pattern: undefined }))); - this._register(dataRenderer.onEditExclude(key => { - // this.model - })); - - const newItemRenderer = this.instantiationService.createInstance(NewExcludeRenderer); - const delegate = new ExcludeSettingListDelegate(); - this.list = this.instantiationService.createInstance(WorkbenchList, container, delegate, [newItemRenderer, dataRenderer], { - identityProvider: element => element.id, - multipleSelectionSupport: false - }) as WorkbenchList; - this._register(this.list); + this.listElement = DOM.append(container, $('.setting-exclude-widget')); const addPatternButton = this._register(new Button(container)); addPatternButton.label = localize('addPattern', "Add Pattern"); @@ -169,6 +160,8 @@ export class ExcludeSettingWidget extends Disposable { this.model.setAddItemMode(AddItemMode.Pattern); this.update(); })); + + this.update(); } setValue(excludeValue: any): void { @@ -177,11 +170,120 @@ export class ExcludeSettingWidget extends Disposable { } private update(): void { - this.list.splice(0, this.list.length, this.model.items); + DOM.clearNode(this.listElement); + this.renderedDisposables = dispose(this.renderedDisposables); + + this.model.items + .map(item => this.renderItem(item)) + .forEach(itemElement => this.listElement.appendChild(itemElement)); const listHeight = 22 * this.model.items.length; - this.list.layout(listHeight); - this.list.getHTMLElement().style.height = listHeight + 'px'; + this.listElement.style.height = listHeight + 'px'; + } + + private createDeleteAction(key: string): IAction { + return { + class: 'setting-excludeAction-remove', + enabled: true, + id: 'workbench.action.removeExcludeItem', + tooltip: localize('removeExcludeItem', "Remove Exclude Item"), + run: () => this._onDidChangeExclude.fire({ originalPattern: key, pattern: undefined }) + }; + } + + private createEditAction(key: string): IAction { + return { + class: 'setting-excludeAction-edit', + enabled: true, + id: 'workbench.action.editExcludeItem', + tooltip: localize('editExcludeItem', "Edit Exclude Item"), + run: () => { } + }; + } + + private renderItem(item: IExcludeItem): HTMLElement { + return isExcludeDataItem(item) ? + this.renderDataItem(item) : + this.renderNewItem(item); + } + + private renderDataItem(item: IExcludeDataItem): HTMLElement { + const rowElement = $('.setting-exclude-row'); + const actionBar = new ActionBar(rowElement); + this.renderedDisposables.push(actionBar); + + const patternElement = DOM.append(rowElement, $('.setting-exclude-pattern')); + const siblingElement = DOM.append(rowElement, $('.setting-exclude-sibling')); + patternElement.textContent = item.pattern; + siblingElement.textContent = item.sibling && ('when: ' + item.sibling); + + actionBar.push([ + this.createEditAction(item.pattern), + this.createDeleteAction(item.pattern) + ], { icon: true, label: false }); + + rowElement.title = item.sibling ? + localize('excludeSiblingHintLabel', "Exclude files matching `{0}`, only when a file matching `{1}` is present", item.pattern, item.sibling) : + localize('excludePatternHintLabel', "Exclude files matching `{0}`", item.pattern); + + return rowElement; + } + + private renderNewItem(item: INewExcludeItem): HTMLElement { + const rowElement = $('.setting-exclude-new-row'); + + const onKeydown = (e: StandardKeyboardEvent) => { + if (e.equals(KeyCode.Enter)) { + this._onDidChangeExclude.fire({ + originalPattern: undefined, + pattern: patternInput.value, + // sibling: siblingInput.value + }); + } + }; + + const patternInput = new InputBox(rowElement, this.contextViewService, { + placeholder: localize('excludePatternInputPlaceholder', "Exclude Pattern...") + }); + patternInput.element.classList.add('setting-exclude-patternInput'); + this.renderedDisposables.push(attachInputBoxStyler(patternInput, this.themeService, { + inputBackground: settingsTextInputBackground, + inputForeground: settingsTextInputForeground, + inputBorder: settingsTextInputBorder + })); + this.renderedDisposables.push(patternInput); + this.renderedDisposables.push(DOM.addStandardDisposableListener(patternInput.inputElement, DOM.EventType.KEY_DOWN, onKeydown)); + + const siblingInput = new InputBox(rowElement, this.contextViewService, { + placeholder: localize('excludeSiblingInputPlaceholder', "When Pattern Is Present...") + }); + siblingInput.element.classList.add('setting-exclude-siblingInput'); + this.renderedDisposables.push(siblingInput); + this.renderedDisposables.push(attachInputBoxStyler(siblingInput, this.themeService, { + inputBackground: settingsTextInputBackground, + inputForeground: settingsTextInputForeground, + inputBorder: settingsTextInputBorder + })); + this.renderedDisposables.push(DOM.addStandardDisposableListener(siblingInput.inputElement, DOM.EventType.KEY_DOWN, onKeydown)); + + rowElement.classList.add('setting-exclude-newExcludeItem'); + + rowElement.classList.remove('setting-exclude-newPattern'); + rowElement.classList.remove('setting-exclude-newPatternWithSibling'); + if (item.mode === AddItemMode.Pattern) { + rowElement.classList.add('setting-exclude-newPattern'); + patternInput.focus(); + patternInput.select(); + } else if (item.mode === AddItemMode.PatternWithSibling) { + rowElement.classList.add('setting-exclude-newPatternWithSibling'); + } + + return rowElement; + } + + dispose() { + super.dispose(); + this.renderedDisposables = dispose(this.renderedDisposables); } } @@ -202,195 +304,6 @@ function isExcludeDataItem(excludeItem: IExcludeItem): excludeItem is IExcludeDa return !!(excludeItem).pattern; } -interface IExcludeDataItemTemplate { - container: HTMLElement; - - actionBar: ActionBar; - patternElement: HTMLElement; - siblingElement: HTMLElement; - toDispose: IDisposable[]; -} - -class ExcludeDataItemRenderer implements IRenderer { - static readonly templateId: string = 'excludeDataItem'; - - private readonly _onDidRemoveExclude: Emitter = new Emitter(); - public readonly onDidRemoveExclude: Event = this._onDidRemoveExclude.event; - - private readonly _onEditExclude: Emitter = new Emitter(); - public readonly onEditExclude: Event = this._onEditExclude.event; - - get templateId(): string { - return ExcludeDataItemRenderer.templateId; - } - - renderTemplate(container: HTMLElement): IExcludeDataItemTemplate { - const toDispose = []; - - const actionBar = new ActionBar(container); - toDispose.push(actionBar); - - return { - container, - patternElement: DOM.append(container, $('.setting-exclude-pattern')), - siblingElement: DOM.append(container, $('.setting-exclude-sibling')), - toDispose, - actionBar - }; - } - - private createDeleteAction(key: string): IAction { - return { - class: 'setting-excludeAction-remove', - enabled: true, - id: 'workbench.action.removeExcludeItem', - tooltip: localize('removeExcludeItem', "Remove Exclude Item"), - run: () => this._onDidRemoveExclude.fire(key) - }; - } - - private createEditAction(key: string): IAction { - return { - class: 'setting-excludeAction-edit', - enabled: true, - id: 'workbench.action.editExcludeItem', - tooltip: localize('editExcludeItem', "Edit Exclude Item"), - run: () => this._onEditExclude.fire(key) - }; - } - - renderElement(element: IExcludeDataItem, index: number, templateData: IExcludeDataItemTemplate): void { - templateData.patternElement.textContent = element.pattern; - templateData.siblingElement.textContent = element.sibling && ('when: ' + element.sibling); - - templateData.actionBar.clear(); - templateData.actionBar.push([ - this.createEditAction(element.pattern), - this.createDeleteAction(element.pattern) - ], { icon: true, label: false }); - - templateData.container.title = element.sibling ? - localize('excludeSiblingHintLabel', "Exclude files matching `{0}`, only when a file matching `{1}` is present", element.pattern, element.sibling) : - localize('excludePatternHintLabel', "Exclude files matching `{0}`", element.pattern); - } - - disposeElement(element: IExcludeDataItem, index: number, templateData: IExcludeDataItemTemplate): void { - } - - disposeTemplate(templateData: IExcludeDataItemTemplate): void { - dispose(templateData.toDispose); - } -} - -interface INewExcludeItemTemplate { - container: HTMLElement; - - patternInput: InputBox; - siblingInput: InputBox; - toDispose: IDisposable[]; -} - -interface INewExcludeItemEvent { - pattern: string; - sibling?: string; -} - -class NewExcludeRenderer implements IRenderer { - static readonly templateId: string = 'newExcludeItem'; - - private readonly _onNewExcludeItem: Emitter = new Emitter(); - public readonly onNewExcludeItem: Event = this._onNewExcludeItem.event; - - constructor( - @IContextViewService private contextViewService: IContextViewService, - @IThemeService private themeService: IThemeService - ) { - } - - get templateId(): string { - return NewExcludeRenderer.templateId; - } - - renderTemplate(container: HTMLElement): INewExcludeItemTemplate { - const toDispose = []; - - const onKeydown = (e: StandardKeyboardEvent) => { - if (e.equals(KeyCode.Enter)) { - this._onNewExcludeItem.fire({ - pattern: patternInput.value, - sibling: siblingInput.value - }); - } - }; - - const patternInput = new InputBox(container, this.contextViewService, { - placeholder: localize('excludePatternInputPlaceholder', "Exclude Pattern...") - }); - patternInput.element.classList.add('setting-exclude-patternInput'); - toDispose.push(attachInputBoxStyler(patternInput, this.themeService, { - inputBackground: settingsTextInputBackground, - inputForeground: settingsTextInputForeground, - inputBorder: settingsTextInputBorder - })); - toDispose.push(patternInput); - toDispose.push(DOM.addStandardDisposableListener(patternInput.inputElement, DOM.EventType.KEY_DOWN, onKeydown)); - - const siblingInput = new InputBox(container, this.contextViewService, { - placeholder: localize('excludeSiblingInputPlaceholder', "When Pattern Is Present...") - }); - siblingInput.element.classList.add('setting-exclude-siblingInput'); - toDispose.push(siblingInput); - toDispose.push(attachInputBoxStyler(siblingInput, this.themeService, { - inputBackground: settingsTextInputBackground, - inputForeground: settingsTextInputForeground, - inputBorder: settingsTextInputBorder - })); - toDispose.push(DOM.addStandardDisposableListener(siblingInput.inputElement, DOM.EventType.KEY_DOWN, onKeydown)); - - return { - container, - patternInput, - siblingInput, - toDispose - }; - } - - renderElement(element: INewExcludeItem, index: number, templateData: INewExcludeItemTemplate): void { - templateData.container.classList.add('setting-exclude-newExcludeItem'); - - templateData.container.classList.remove('setting-exclude-newPattern'); - templateData.container.classList.remove('setting-exclude-newPatternWithSibling'); - if (element.mode === AddItemMode.Pattern) { - templateData.container.classList.add('setting-exclude-newPattern'); - templateData.patternInput.focus(); - templateData.patternInput.select(); - } else if (element.mode === AddItemMode.PatternWithSibling) { - templateData.container.classList.add('setting-exclude-newPatternWithSibling'); - } - } - - disposeElement(element: INewExcludeItem, index: number, templateData: INewExcludeItemTemplate): void { - } - - disposeTemplate(templateData: INewExcludeItemTemplate): void { - dispose(templateData.toDispose); - } -} - -class ExcludeSettingListDelegate implements IVirtualDelegate { - getHeight(element: IExcludeItem): number { - return 22; - } - - getTemplateId(element: IExcludeItem): string { - if (isExcludeDataItem(element)) { - return ExcludeDataItemRenderer.templateId; - } else { - return NewExcludeRenderer.templateId; - } - } -} - // class EditExcludeItemAction extends Action { // static readonly ID = 'workbench.action.editExcludeItem'; From 1b3fdcf7f6d0abde6863c88a852858e6cd027cfb Mon Sep 17 00:00:00 2001 From: Rob Lourens Date: Wed, 25 Jul 2018 09:11:27 -0700 Subject: [PATCH 0104/1276] Settings exclude control - implement adding patterns --- .../browser/media/settingsWidgets.css | 23 ++--- .../parts/preferences/browser/settingsTree.ts | 20 ++--- .../preferences/browser/settingsWidgets.ts | 83 ++++++++++++------- 3 files changed, 71 insertions(+), 55 deletions(-) diff --git a/src/vs/workbench/parts/preferences/browser/media/settingsWidgets.css b/src/vs/workbench/parts/preferences/browser/media/settingsWidgets.css index eb6dfcb6401..a0df231835d 100644 --- a/src/vs/workbench/parts/preferences/browser/media/settingsWidgets.css +++ b/src/vs/workbench/parts/preferences/browser/media/settingsWidgets.css @@ -78,35 +78,30 @@ margin-right: 10px; } -.settings-editor > .settings-body > .settings-tree-container .setting-item.setting-item-exclude .monaco-text-button.setting-exclude-addButton { - display: none; -} - .settings-editor > .settings-body > .settings-tree-container .setting-item.setting-item-exclude.is-expanded .monaco-text-button.setting-exclude-addButton { display: inline-block; } -.settings-editor > .settings-body > .settings-tree-container .setting-item.setting-item-exclude .setting-exclude-new-row.setting-exclude-newExcludeItem { +.settings-editor > .settings-body > .settings-tree-container .setting-item.setting-item-exclude .setting-exclude-edit-row.setting-exclude-newExcludeItem { display: flex; } -.settings-editor > .settings-body > .settings-tree-container .setting-item.setting-item-exclude .setting-exclude-new-row.setting-exclude-newExcludeItem .setting-exclude-patternInput, -.settings-editor > .settings-body > .settings-tree-container .setting-item.setting-item-exclude .setting-exclude-new-row.setting-exclude-newExcludeItem .setting-exclude-siblingInput { - display: none; - flex: 1; - max-width: 200px; +.settings-editor > .settings-body > .settings-tree-container .setting-item.setting-item-exclude .setting-exclude-patternInput { + max-width: 300px; + display: inline-block; + margin-right: 10px; } -.settings-editor > .settings-body > .settings-tree-container .setting-item.setting-item-exclude .setting-exclude-new-row.setting-exclude-newPattern .setting-exclude-patternInput { +.settings-editor > .settings-body > .settings-tree-container .setting-item.setting-item-exclude .setting-exclude-edit-row.setting-exclude-newPattern .setting-exclude-patternInput { display: inline-block; } -.settings-editor > .settings-body > .settings-tree-container .setting-item.setting-item-exclude .setting-exclude-new-row.setting-exclude-newPatternWithSibling .setting-exclude-patternInput { +.settings-editor > .settings-body > .settings-tree-container .setting-item.setting-item-exclude .setting-exclude-edit-row.setting-exclude-newPatternWithSibling .setting-exclude-patternInput { margin-right: 5px; } -.settings-editor > .settings-body > .settings-tree-container .setting-item.setting-item-exclude .setting-exclude-new-row.setting-exclude-newPatternWithSibling .setting-exclude-patternInput, -.settings-editor > .settings-body > .settings-tree-container .setting-item.setting-item-exclude .setting-exclude-new-row.setting-exclude-newPatternWithSibling .setting-exclude-siblingInput { +.settings-editor > .settings-body > .settings-tree-container .setting-item.setting-item-exclude .setting-exclude-edit-row.setting-exclude-newPatternWithSibling .setting-exclude-patternInput, +.settings-editor > .settings-body > .settings-tree-container .setting-item.setting-item-exclude .setting-exclude-edit-row.setting-exclude-newPatternWithSibling .setting-exclude-siblingInput { display: inline-block; } diff --git a/src/vs/workbench/parts/preferences/browser/settingsTree.ts b/src/vs/workbench/parts/preferences/browser/settingsTree.ts index b44337c439b..3857625e1c6 100644 --- a/src/vs/workbench/parts/preferences/browser/settingsTree.ts +++ b/src/vs/workbench/parts/preferences/browser/settingsTree.ts @@ -35,7 +35,7 @@ import { attachButtonStyler, attachInputBoxStyler, attachSelectBoxStyler, attach import { ICssStyleCollector, ITheme, IThemeService, registerThemingParticipant } from 'vs/platform/theme/common/themeService'; import { SettingsTarget } from 'vs/workbench/parts/preferences/browser/preferencesWidgets'; import { ITOCEntry } from 'vs/workbench/parts/preferences/browser/settingsLayout'; -import { ExcludeSettingWidget, settingsNumberInputBackground, settingsNumberInputBorder, settingsNumberInputForeground, settingsSelectBackground, settingsSelectBorder, settingsSelectForeground, settingsTextInputBackground, settingsTextInputBorder, settingsTextInputForeground, settingItemInactiveSelectionBorder, settingsHeaderForeground } from 'vs/workbench/parts/preferences/browser/settingsWidgets'; +import { ExcludeSettingWidget, settingsNumberInputBackground, settingsNumberInputBorder, settingsNumberInputForeground, settingsSelectBackground, settingsSelectBorder, settingsSelectForeground, settingsTextInputBorder, settingsTextInputForeground, settingItemInactiveSelectionBorder, settingsHeaderForeground, settingsTextInputBackground } from 'vs/workbench/parts/preferences/browser/settingsWidgets'; import { ISearchResult, ISetting, ISettingsGroup } from 'vs/workbench/services/preferences/common/preferences'; const $ = DOM.$; @@ -551,7 +551,7 @@ export class SettingsRenderer implements ITreeRenderer { _getExcludeSettingHeight(element: SettingsTreeSettingElement): number { const displayValue = getExcludeDisplayValue(element); - return (Object.keys(displayValue).length + 1) * 22 + 70; + return (Object.keys(displayValue).length + 1) * 22 + 72; } _getUnexpandedSettingHeight(element: SettingsTreeSettingElement): number { @@ -825,15 +825,6 @@ export class SettingsRenderer implements ITreeRenderer { const excludeWidget = this.instantiationService.createInstance(ExcludeSettingWidget, common.controlElement); common.toDispose.push(excludeWidget); - // common.toDispose.push(excludeWidget.onDidClick(() => this._onDidOpenSettings.fire())); - // excludeWidget.label = localize('editInSettingsJson', "Edit in settings.json"); - // excludeWidget.element.classList.add('edit-in-settings-button'); - - // common.toDispose.push(attachButtonStyler(excludeWidget, this.themeService, { - // buttonBackground: Color.transparent.toString(), - // buttonHoverBackground: Color.transparent.toString(), - // buttonForeground: 'foreground' - // })); const template: ISettingExcludeItemTemplate = { ...common, @@ -851,16 +842,19 @@ export class SettingsRenderer implements ITreeRenderer { // editing something present in the value newValue[e.pattern] = newValue[e.originalPattern]; delete newValue[e.originalPattern]; - } else { + } else if (e.originalPattern) { // editing a default newValue[e.originalPattern] = false; newValue[e.pattern] = template.context.defaultValue[e.originalPattern]; + } else { + // adding a new pattern + newValue[e.pattern] = true; } } else { if (e.originalPattern in newValue) { // deleting a configured pattern delete newValue[e.originalPattern]; - } else { + } else if (e.originalPattern) { // "deleting" a default by overriding it newValue[e.originalPattern] = false; } diff --git a/src/vs/workbench/parts/preferences/browser/settingsWidgets.ts b/src/vs/workbench/parts/preferences/browser/settingsWidgets.ts index 675e598ac1c..94843baaeed 100644 --- a/src/vs/workbench/parts/preferences/browser/settingsWidgets.ts +++ b/src/vs/workbench/parts/preferences/browser/settingsWidgets.ts @@ -98,10 +98,10 @@ export class ExcludeSettingListModel { ...this._dataItems ]; - items.push({ - id: 'newItem', - mode: this._newItem - }); + // items.push({ + // id: 'newItem', + // mode: this._newItem + // }); return items; } @@ -136,7 +136,8 @@ interface IExcludeChangeEvent { export class ExcludeSettingWidget extends Disposable { private listElement: HTMLElement; - private renderedDisposables: IDisposable[] = []; + private listDisposables: IDisposable[] = []; + private patternInput: InputBox; private model = new ExcludeSettingListModel(); @@ -151,27 +152,19 @@ export class ExcludeSettingWidget extends Disposable { super(); this.listElement = DOM.append(container, $('.setting-exclude-widget')); - - const addPatternButton = this._register(new Button(container)); - addPatternButton.label = localize('addPattern', "Add Pattern"); - addPatternButton.element.classList.add('setting-exclude-addPattern', 'setting-exclude-addButton'); - this._register(attachButtonStyler(addPatternButton, this.themeService)); - this._register(addPatternButton.onDidClick(() => { - this.model.setAddItemMode(AddItemMode.Pattern); - this.update(); - })); - + DOM.append(container, this.renderAddItem()); this.update(); } setValue(excludeValue: any): void { this.model.setValue(excludeValue, void 0); + this.patternInput.value = ''; this.update(); } private update(): void { DOM.clearNode(this.listElement); - this.renderedDisposables = dispose(this.renderedDisposables); + this.listDisposables = dispose(this.listDisposables); this.model.items .map(item => this.renderItem(item)) @@ -204,13 +197,13 @@ export class ExcludeSettingWidget extends Disposable { private renderItem(item: IExcludeItem): HTMLElement { return isExcludeDataItem(item) ? this.renderDataItem(item) : - this.renderNewItem(item); + this.renderEditItem(item); } private renderDataItem(item: IExcludeDataItem): HTMLElement { const rowElement = $('.setting-exclude-row'); const actionBar = new ActionBar(rowElement); - this.renderedDisposables.push(actionBar); + this.listDisposables.push(actionBar); const patternElement = DOM.append(rowElement, $('.setting-exclude-pattern')); const siblingElement = DOM.append(rowElement, $('.setting-exclude-sibling')); @@ -229,15 +222,49 @@ export class ExcludeSettingWidget extends Disposable { return rowElement; } - private renderNewItem(item: INewExcludeItem): HTMLElement { + private renderAddItem(): HTMLElement { const rowElement = $('.setting-exclude-new-row'); + this.patternInput = new InputBox(rowElement, this.contextViewService, { + placeholder: localize('excludePatternInputPlaceholder', "Exclude Pattern...") + }); + this.patternInput.element.classList.add('setting-exclude-patternInput'); + this._register(attachInputBoxStyler(this.patternInput, this.themeService, { + inputBackground: settingsTextInputBackground, + inputForeground: settingsTextInputForeground, + inputBorder: settingsTextInputBorder + })); + this._register(this.patternInput); + + const addPatternButton = this._register(new Button(rowElement)); + addPatternButton.label = localize('addPattern', "Add Pattern"); + addPatternButton.element.classList.add('setting-exclude-addPattern', 'setting-exclude-addButton'); + this._register(attachButtonStyler(addPatternButton, this.themeService)); + + const addItem = () => this._onDidChangeExclude.fire({ + originalPattern: undefined, + pattern: this.patternInput.value + }); + + this._register(addPatternButton.onDidClick(addItem)); + + const onKeydown = (e: StandardKeyboardEvent) => { + if (e.equals(KeyCode.Enter)) { + addItem(); + } + }; + this._register(DOM.addStandardDisposableListener(this.patternInput.inputElement, DOM.EventType.KEY_DOWN, onKeydown)); + + return rowElement; + } + + private renderEditItem(item: INewExcludeItem): HTMLElement { + const rowElement = $('.setting-exclude-edit-row'); const onKeydown = (e: StandardKeyboardEvent) => { if (e.equals(KeyCode.Enter)) { this._onDidChangeExclude.fire({ originalPattern: undefined, - pattern: patternInput.value, - // sibling: siblingInput.value + pattern: patternInput.value }); } }; @@ -246,25 +273,25 @@ export class ExcludeSettingWidget extends Disposable { placeholder: localize('excludePatternInputPlaceholder', "Exclude Pattern...") }); patternInput.element.classList.add('setting-exclude-patternInput'); - this.renderedDisposables.push(attachInputBoxStyler(patternInput, this.themeService, { + this.listDisposables.push(attachInputBoxStyler(patternInput, this.themeService, { inputBackground: settingsTextInputBackground, inputForeground: settingsTextInputForeground, inputBorder: settingsTextInputBorder })); - this.renderedDisposables.push(patternInput); - this.renderedDisposables.push(DOM.addStandardDisposableListener(patternInput.inputElement, DOM.EventType.KEY_DOWN, onKeydown)); + this.listDisposables.push(patternInput); + this.listDisposables.push(DOM.addStandardDisposableListener(patternInput.inputElement, DOM.EventType.KEY_DOWN, onKeydown)); const siblingInput = new InputBox(rowElement, this.contextViewService, { placeholder: localize('excludeSiblingInputPlaceholder', "When Pattern Is Present...") }); siblingInput.element.classList.add('setting-exclude-siblingInput'); - this.renderedDisposables.push(siblingInput); - this.renderedDisposables.push(attachInputBoxStyler(siblingInput, this.themeService, { + this.listDisposables.push(siblingInput); + this.listDisposables.push(attachInputBoxStyler(siblingInput, this.themeService, { inputBackground: settingsTextInputBackground, inputForeground: settingsTextInputForeground, inputBorder: settingsTextInputBorder })); - this.renderedDisposables.push(DOM.addStandardDisposableListener(siblingInput.inputElement, DOM.EventType.KEY_DOWN, onKeydown)); + this.listDisposables.push(DOM.addStandardDisposableListener(siblingInput.inputElement, DOM.EventType.KEY_DOWN, onKeydown)); rowElement.classList.add('setting-exclude-newExcludeItem'); @@ -283,7 +310,7 @@ export class ExcludeSettingWidget extends Disposable { dispose() { super.dispose(); - this.renderedDisposables = dispose(this.renderedDisposables); + this.listDisposables = dispose(this.listDisposables); } } From 223e91c7f5080ef046a059ecc1337355eb2b692f Mon Sep 17 00:00:00 2001 From: Rob Lourens Date: Wed, 25 Jul 2018 09:14:23 -0700 Subject: [PATCH 0105/1276] Settings editor - fix unused reference --- src/vs/workbench/parts/preferences/browser/settingsEditor2.ts | 3 ++- src/vs/workbench/parts/preferences/browser/settingsWidgets.ts | 4 ++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/src/vs/workbench/parts/preferences/browser/settingsEditor2.ts b/src/vs/workbench/parts/preferences/browser/settingsEditor2.ts index 161504cd879..39955d76613 100644 --- a/src/vs/workbench/parts/preferences/browser/settingsEditor2.ts +++ b/src/vs/workbench/parts/preferences/browser/settingsEditor2.ts @@ -32,13 +32,14 @@ import { BaseEditor } from 'vs/workbench/browser/parts/editor/baseEditor'; import { EditorOptions, IEditor } from 'vs/workbench/common/editor'; import { SearchWidget, SettingsTarget, SettingsTargetsWidget } from 'vs/workbench/parts/preferences/browser/preferencesWidgets'; import { commonlyUsedData, tocData } from 'vs/workbench/parts/preferences/browser/settingsLayout'; -import { ISettingsEditorViewState, resolveExtensionsSettings, resolveSettingsTree, SearchResultIdx, SearchResultModel, SettingsRenderer, SettingsTree, SettingsTreeElement, SettingsTreeFilter, SettingsTreeGroupElement, SettingsTreeModel, SettingsTreeSettingElement, settingsHeaderForeground } from 'vs/workbench/parts/preferences/browser/settingsTree'; +import { ISettingsEditorViewState, resolveExtensionsSettings, resolveSettingsTree, SearchResultIdx, SearchResultModel, SettingsRenderer, SettingsTree, SettingsTreeElement, SettingsTreeFilter, SettingsTreeGroupElement, SettingsTreeModel, SettingsTreeSettingElement } from 'vs/workbench/parts/preferences/browser/settingsTree'; import { TOCDataSource, TOCRenderer, TOCTreeModel } from 'vs/workbench/parts/preferences/browser/tocTree'; import { CONTEXT_SETTINGS_EDITOR, CONTEXT_SETTINGS_FIRST_ROW_FOCUS, CONTEXT_SETTINGS_ROW_FOCUS, CONTEXT_SETTINGS_SEARCH_FOCUS, CONTEXT_TOC_ROW_FOCUS, IPreferencesSearchService, ISearchProvider } from 'vs/workbench/parts/preferences/common/preferences'; import { IPreferencesService, ISearchResult, ISettingsEditorModel } from 'vs/workbench/services/preferences/common/preferences'; import { SettingsEditor2Input } from 'vs/workbench/services/preferences/common/preferencesEditorInput'; import { DefaultSettingsEditorModel } from 'vs/workbench/services/preferences/common/preferencesModels'; import { editorBackground, foreground } from 'vs/platform/theme/common/colorRegistry'; +import { settingsHeaderForeground } from 'vs/workbench/parts/preferences/browser/settingsWidgets'; const $ = DOM.$; diff --git a/src/vs/workbench/parts/preferences/browser/settingsWidgets.ts b/src/vs/workbench/parts/preferences/browser/settingsWidgets.ts index 94843baaeed..cef0521ced0 100644 --- a/src/vs/workbench/parts/preferences/browser/settingsWidgets.ts +++ b/src/vs/workbench/parts/preferences/browser/settingsWidgets.ts @@ -91,7 +91,7 @@ enum AddItemMode { export class ExcludeSettingListModel { private _dataItems: IExcludeItem[] = []; - private _newItem = AddItemMode.None; + // private _newItem = AddItemMode.None; get items(): IExcludeItem[] { const items = [ @@ -107,7 +107,7 @@ export class ExcludeSettingListModel { } setAddItemMode(mode: AddItemMode): void { - this._newItem = mode; + // this._newItem = mode; } setValue(excludeValue: any, defaultValue: any): void { From 29967e4dd4f179aa119b1f5b68537238ba92aba6 Mon Sep 17 00:00:00 2001 From: Sandeep Somavarapu Date: Wed, 25 Jul 2018 18:17:59 +0200 Subject: [PATCH 0106/1276] Fix #55055 --- .../node/extensionManagementService.ts | 25 +++++----- .../node/extensionsWorkbenchService.ts | 49 ++++++++++++------- 2 files changed, 44 insertions(+), 30 deletions(-) diff --git a/src/vs/platform/extensionManagement/node/extensionManagementService.ts b/src/vs/platform/extensionManagement/node/extensionManagementService.ts index 84989938f78..2fdebb22f56 100644 --- a/src/vs/platform/extensionManagement/node/extensionManagementService.ts +++ b/src/vs/platform/extensionManagement/node/extensionManagementService.ts @@ -539,11 +539,14 @@ export class ExtensionManagementService extends Disposable implements IExtension return this.preUninstallExtension(extension) .then(() => { if (force) { - return this.uninstallExtensionAsPack(extension, installed); + return this.uninstallExtensionWithDependenciesAndPacked(extension, installed); + } + const dependencies = this.getDependenciesToUninstall(extension, installed); + if (dependencies.length) { + return this.promptForDependenciesAndUninstall(extension, installed); + } else { + return this.uninstallExtensionWithDependenciesAndPacked(extension, installed); } - const hasInstalledExtensionPack = extension.manifest.extensionPack && extension.manifest.extensionPack.length && installed.some(i => extension.manifest.extensionPack.some(dep => areSameExtensions({ id: dep }, i.galleryIdentifier))); - const hasDependencies = extension.manifest.extensionDependencies && extension.manifest.extensionDependencies.length > 0; - return hasInstalledExtensionPack || hasDependencies ? this.promptForPackAndUninstall(extension, installed) : this.uninstallExtensions(extension, [], installed); }) .then(() => this.postUninstallExtension(extension), error => { @@ -552,27 +555,27 @@ export class ExtensionManagementService extends Disposable implements IExtension }); } - private promptForPackAndUninstall(extension: ILocalExtension, installed: ILocalExtension[]): TPromise { - const message = nls.localize('uninstallExtensionPackConfirmation', "Would you like to uninstall '{0}' only or as a pack?", extension.manifest.displayName || extension.manifest.name); + private promptForDependenciesAndUninstall(extension: ILocalExtension, installed: ILocalExtension[]): TPromise { + const message = nls.localize('uninstallDependeciesConfirmation', "Would you like to uninstall '{0}' only or its dependencies also?", extension.manifest.displayName || extension.manifest.name); const buttons = [ - nls.localize('uninstallPack', "Uninstall Extension Pack"), - nls.localize('uninstallOnly', "Uninstall Extension Only"), + nls.localize('uninstallOnly', "Extension Only"), + nls.localize('uninstallAll', "Uninstall All"), nls.localize('cancel', "Cancel") ]; return this.dialogService.show(Severity.Info, message, buttons, { cancelId: 2 }) .then(value => { if (value === 0) { - return this.uninstallExtensionAsPack(extension, installed); + return this.uninstallExtensions(extension, [], installed); } if (value === 1) { - return this.uninstallExtensions(extension, [], installed); + return this.uninstallExtensionWithDependenciesAndPacked(extension, installed); } this.logService.info('Cancelled uninstalling extension:', extension.identifier.id); return TPromise.wrapError(errors.canceled()); }, error => TPromise.wrapError(errors.canceled())); } - private uninstallExtensionAsPack(extension: ILocalExtension, installed: ILocalExtension[]): TPromise { + private uninstallExtensionWithDependenciesAndPacked(extension: ILocalExtension, installed: ILocalExtension[]): TPromise { const extensionsToUninstall = this.getDependenciesToUninstall(extension, installed); for (const packExtensionToUninstall of this.getAllPackExtensionsToUninstall(extension, installed)) { if (extensionsToUninstall.indexOf(packExtensionToUninstall) === -1) { diff --git a/src/vs/workbench/parts/extensions/node/extensionsWorkbenchService.ts b/src/vs/workbench/parts/extensions/node/extensionsWorkbenchService.ts index a492f570789..576f2f54455 100644 --- a/src/vs/workbench/parts/extensions/node/extensionsWorkbenchService.ts +++ b/src/vs/workbench/parts/extensions/node/extensionsWorkbenchService.ts @@ -742,38 +742,45 @@ export class ExtensionsWorkbenchService implements IExtensionsWorkbenchService, } private promptAndSetEnablement(extensions: IExtension[], enablementState: EnablementState): TPromise { - const allDependenciesAndPackedExtensions = this.getDependenciesAndPackedExtensionsRecursively(extensions, this.local, enablementState); - if (allDependenciesAndPackedExtensions.length > 0) { - if (extensions.length === 1 && (enablementState === EnablementState.Disabled || enablementState === EnablementState.WorkspaceDisabled)) { - return this.promptForDependenciesAndDisable(extensions[0], allDependenciesAndPackedExtensions, enablementState); + const enable = enablementState === EnablementState.Enabled || enablementState === EnablementState.WorkspaceEnabled; + if (enable) { + return this.checkAndSetEnablementWithDependenciesAndPacked(extensions, enablementState); + } else { + const dependencies = this.getExtensionsRecursively(extensions, this.local, enablementState, { dependencies: true, pack: false }); + if (dependencies.length) { + return this.promptForDependenciesAndDisable(extensions, enablementState); } else { - return this.checkAndSetEnablement(extensions, allDependenciesAndPackedExtensions, enablementState); + return this.checkAndSetEnablementWithDependenciesAndPacked(extensions, enablementState); } } - return this.checkAndSetEnablement(extensions, [], enablementState); } - private promptForDependenciesAndDisable(extension: IExtension, dependencies: IExtension[], enablementState: EnablementState): TPromise { - const message = nls.localize('disableExtensionPackConfirmation', "Would you like to disable '{0}' only or as a pack?", extension.displayName); + private promptForDependenciesAndDisable(extensions: IExtension[], enablementState: EnablementState): TPromise { + const message = nls.localize('disableDependeciesConfirmation', "Would you like to disable the dependencies of the extensions also?"); const buttons = [ - nls.localize('disablePack', "Disable Extension Pack"), - nls.localize('disableOnly', "Disable Extension Only"), + nls.localize('yes', "Yes"), + nls.localize('no', "No"), nls.localize('cancel', "Cancel") ]; - return this.dialogService.show(Severity.Info, message, buttons) + return this.dialogService.show(Severity.Info, message, buttons, { cancelId: 2 }) .then(value => { if (value === 0) { - return this.checkAndSetEnablement([extension], dependencies, enablementState); + return this.checkAndSetEnablementWithDependenciesAndPacked(extensions, enablementState); } if (value === 1) { - return this.checkAndSetEnablement([extension], [], enablementState); + return this.checkAndSetEnablement(extensions, [], enablementState); } return TPromise.as(null); }); } - private checkAndSetEnablement(extensions: IExtension[], dependencies: IExtension[], enablementState: EnablementState): TPromise { - const allExtensions = [...extensions, ...dependencies]; + private checkAndSetEnablementWithDependenciesAndPacked(extensions: IExtension[], enablementState: EnablementState): TPromise { + const otherExtensions = this.getExtensionsRecursively(extensions, this.local, enablementState, { dependencies: true, pack: true }); + return this.checkAndSetEnablement(extensions, otherExtensions, enablementState); + } + + private checkAndSetEnablement(extensions: IExtension[], otherExtensions: IExtension[], enablementState: EnablementState): TPromise { + const allExtensions = [...extensions, ...otherExtensions]; const enable = enablementState === EnablementState.Enabled || enablementState === EnablementState.WorkspaceEnabled; if (!enable) { for (const extension of extensions) { @@ -786,7 +793,7 @@ export class ExtensionsWorkbenchService implements IExtensionsWorkbenchService, return TPromise.join(allExtensions.map(e => this.doSetEnablement(e, enablementState))); } - private getDependenciesAndPackedExtensionsRecursively(extensions: IExtension[], installed: IExtension[], enablementState: EnablementState, checked: IExtension[] = []): IExtension[] { + private getExtensionsRecursively(extensions: IExtension[], installed: IExtension[], enablementState: EnablementState, options: { dependencies: boolean, pack: boolean }, checked: IExtension[] = []): IExtension[] { const toCheck = extensions.filter(e => checked.indexOf(e) === -1); if (toCheck.length) { for (const extension of toCheck) { @@ -799,11 +806,15 @@ export class ExtensionsWorkbenchService implements IExtensionsWorkbenchService, if (i.enablementState === enablementState) { return false; } - return i.type === LocalExtensionType.User && - extensions.some(extension => extension.dependencies.some(id => areSameExtensions({ id }, i)) || extension.extensionPack.some(id => areSameExtensions({ id }, i))); + return i.type === LocalExtensionType.User + && (options.dependencies || options.pack) + && extensions.some(extension => + (options.dependencies && extension.dependencies.some(id => areSameExtensions({ id }, i))) + || (options.pack && extension.extensionPack.some(id => areSameExtensions({ id }, i))) + ); }); if (extensionsToDisable.length) { - extensionsToDisable.push(...this.getDependenciesAndPackedExtensionsRecursively(extensionsToDisable, installed, enablementState, checked)); + extensionsToDisable.push(...this.getExtensionsRecursively(extensionsToDisable, installed, enablementState, options, checked)); } return extensionsToDisable; } From 3c72037ed8d9790f08ae08d0a0f03539272a7965 Mon Sep 17 00:00:00 2001 From: Rob Lourens Date: Wed, 25 Jul 2018 09:17:32 -0700 Subject: [PATCH 0107/1276] Settings editor - change "Open settings.json" label, fix #55032 --- src/vs/workbench/parts/preferences/browser/settingsEditor2.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vs/workbench/parts/preferences/browser/settingsEditor2.ts b/src/vs/workbench/parts/preferences/browser/settingsEditor2.ts index 39955d76613..68999b878df 100644 --- a/src/vs/workbench/parts/preferences/browser/settingsEditor2.ts +++ b/src/vs/workbench/parts/preferences/browser/settingsEditor2.ts @@ -800,7 +800,7 @@ export class SettingsEditor2 extends BaseEditor { class OpenSettingsAction extends Action { static readonly ID = 'settings.openSettingsJson'; - static readonly LABEL = localize('openSettingsJsonLabel', "Open settings.json for advanced customizations"); + static readonly LABEL = localize('openSettingsJsonLabel', "Open settings.json"); constructor( @IPreferencesService private readonly preferencesService: IPreferencesService, From d86306d665716363d6776599e68032586fe0f5d0 Mon Sep 17 00:00:00 2001 From: Rob Lourens Date: Wed, 25 Jul 2018 09:23:38 -0700 Subject: [PATCH 0108/1276] Bump node-debug2 --- build/builtInExtensions.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build/builtInExtensions.json b/build/builtInExtensions.json index 499d1df761d..5c0deaea8b3 100644 --- a/build/builtInExtensions.json +++ b/build/builtInExtensions.json @@ -6,7 +6,7 @@ }, { "name": "ms-vscode.node-debug2", - "version": "1.26.5", + "version": "1.26.6", "repo": "https://github.com/Microsoft/vscode-node-debug2" } ] From 3245f89500cac87ec46c3534c3ecba2ec9766bfa Mon Sep 17 00:00:00 2001 From: Jackson Kearl Date: Wed, 25 Jul 2018 09:35:00 -0700 Subject: [PATCH 0109/1276] Refactor simple widget editor config files --- .../electron-browser/simpleWidgetEditor.ts | 90 +++++++++++++++++++ .../electron-browser/breakpointWidget.ts | 6 +- .../parts/debug/electron-browser/repl.ts | 4 +- .../electron-browser/simpleDebugEditor.ts | 57 ------------ .../electron-browser/extensionsViewlet.ts | 36 ++------ 5 files changed, 100 insertions(+), 93 deletions(-) create mode 100644 src/vs/workbench/parts/codeEditor/electron-browser/simpleWidgetEditor.ts delete mode 100644 src/vs/workbench/parts/debug/electron-browser/simpleDebugEditor.ts diff --git a/src/vs/workbench/parts/codeEditor/electron-browser/simpleWidgetEditor.ts b/src/vs/workbench/parts/codeEditor/electron-browser/simpleWidgetEditor.ts new file mode 100644 index 00000000000..c3d3f17b0aa --- /dev/null +++ b/src/vs/workbench/parts/codeEditor/electron-browser/simpleWidgetEditor.ts @@ -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. + *--------------------------------------------------------------------------------------------*/ + +import { IEditorOptions } from 'vs/editor/common/config/editorOptions'; +import { ICodeEditorWidgetOptions } from 'vs/editor/browser/widget/codeEditorWidget'; + +// Allowed Editor Contributions: +import { MenuPreventer } from 'vs/workbench/parts/codeEditor/electron-browser/menuPreventer'; +import { SelectionClipboard } from 'vs/workbench/parts/codeEditor/electron-browser/selectionClipboard'; +import { ContextMenuController } from 'vs/editor/contrib/contextmenu/contextmenu'; +import { SuggestController } from 'vs/editor/contrib/suggest/suggestController'; +import { SnippetController2 } from 'vs/editor/contrib/snippet/snippetController2'; +import { TabCompletionController } from 'vs/workbench/parts/snippets/electron-browser/tabCompletion'; + +export class SimpleWidgetEditorConfig { + + public static getCodeEditorWidgetOptions(): ICodeEditorWidgetOptions { + return { + isSimpleWidget: true, + contributions: [ + MenuPreventer, + SelectionClipboard, + ContextMenuController, + SuggestController, + SnippetController2, + TabCompletionController, + ] + }; + } + + public static getEditorOptions(style: 'editor' | 'htmlinput', ariaLabel?: string): IEditorOptions { + if (style === 'editor') { + return { + wordWrap: 'on', + overviewRulerLanes: 0, + glyphMargin: false, + lineNumbers: 'off', + folding: false, + selectOnLineNumbers: false, + hideCursorInOverviewRuler: true, + selectionHighlight: false, + scrollbar: { + horizontal: 'hidden' + }, + ariaLabel: ariaLabel || '', + lineDecorationsWidth: 0, + overviewRulerBorder: false, + scrollBeyondLastLine: false, + renderLineHighlight: 'none', + fixedOverflowWidgets: true, + acceptSuggestionOnEnter: 'smart', + minimap: { + enabled: false + } + }; + } + else { + return { + fontSize: 13, + lineHeight: 22, + wordWrap: 'off', + overviewRulerLanes: 0, + glyphMargin: false, + lineNumbers: 'off', + folding: false, + selectOnLineNumbers: false, + hideCursorInOverviewRuler: true, + selectionHighlight: false, + scrollbar: { + horizontal: 'hidden', + vertical: 'hidden' + }, + ariaLabel: ariaLabel || '', + cursorWidth: 1, + lineDecorationsWidth: 0, + overviewRulerBorder: false, + scrollBeyondLastLine: false, + renderLineHighlight: 'none', + fixedOverflowWidgets: true, + acceptSuggestionOnEnter: 'smart', + minimap: { + enabled: false + }, + fontFamily: ' -apple-system, BlinkMacSystemFont, "Segoe WPC", "Segoe UI", "HelveticaNeue-Light", "Ubuntu", "Droid Sans", sans-serif' + }; + } + } +} diff --git a/src/vs/workbench/parts/debug/electron-browser/breakpointWidget.ts b/src/vs/workbench/parts/debug/electron-browser/breakpointWidget.ts index c3f164601c0..3d1ad211ed5 100644 --- a/src/vs/workbench/parts/debug/electron-browser/breakpointWidget.ts +++ b/src/vs/workbench/parts/debug/electron-browser/breakpointWidget.ts @@ -17,7 +17,7 @@ import { IContextViewService } from 'vs/platform/contextview/browser/contextView import { IDebugService, IBreakpoint, BreakpointWidgetContext as Context, CONTEXT_BREAKPOINT_WIDGET_VISIBLE, DEBUG_SCHEME, IDebugEditorContribution, EDITOR_CONTRIBUTION_ID, CONTEXT_IN_BREAKPOINT_WIDGET } from 'vs/workbench/parts/debug/common/debug'; import { attachSelectBoxStyler } from 'vs/platform/theme/common/styler'; import { IThemeService } from 'vs/platform/theme/common/themeService'; -import { SimpleDebugEditor } from 'vs/workbench/parts/debug/electron-browser/simpleDebugEditor'; +import { SimpleWidgetEditorConfig } from 'vs/workbench/parts/codeEditor/electron-browser/simpleWidgetEditor'; import { createDecorator, IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; import { IContextKeyService } from 'vs/platform/contextkey/common/contextkey'; import { ServicesAccessor, EditorCommand, registerEditorCommand } from 'vs/editor/browser/editorExtensions'; @@ -200,8 +200,8 @@ export class BreakpointWidget extends ZoneWidget implements IPrivateBreakpointWi const scopedInstatiationService = this.instantiationService.createChild(new ServiceCollection( [IContextKeyService, scopedContextKeyService], [IPrivateBreakpointWidgetService, this])); - const options = SimpleDebugEditor.getEditorOptions(); - const codeEditorWidgetOptions = SimpleDebugEditor.getCodeEditorWidgetOptions(); + const options = SimpleWidgetEditorConfig.getEditorOptions('editor'); + const codeEditorWidgetOptions = SimpleWidgetEditorConfig.getCodeEditorWidgetOptions(); this.input = scopedInstatiationService.createInstance(CodeEditorWidget, container, options, codeEditorWidgetOptions); CONTEXT_IN_BREAKPOINT_WIDGET.bindTo(scopedContextKeyService).set(true); const model = this.modelService.createModel('', null, uri.parse(`${DEBUG_SCHEME}:${this.editor.getId()}:breakpointinput`), true); diff --git a/src/vs/workbench/parts/debug/electron-browser/repl.ts b/src/vs/workbench/parts/debug/electron-browser/repl.ts index 10bbf3327fa..1cc6bea977e 100644 --- a/src/vs/workbench/parts/debug/electron-browser/repl.ts +++ b/src/vs/workbench/parts/debug/electron-browser/repl.ts @@ -30,7 +30,7 @@ import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry'; import { IInstantiationService, createDecorator } from 'vs/platform/instantiation/common/instantiation'; import { IStorageService, StorageScope } from 'vs/platform/storage/common/storage'; import { ReplExpressionsRenderer, ReplExpressionsController, ReplExpressionsDataSource, ReplExpressionsActionProvider, ReplExpressionsAccessibilityProvider } from 'vs/workbench/parts/debug/electron-browser/replViewer'; -import { SimpleDebugEditor } from 'vs/workbench/parts/debug/electron-browser/simpleDebugEditor'; +import { SimpleWidgetEditorConfig } from 'vs/workbench/parts/codeEditor/electron-browser/simpleWidgetEditor'; import { ClearReplAction } from 'vs/workbench/parts/debug/browser/debugActions'; import { Panel } from 'vs/workbench/browser/panel'; import { IPanelService } from 'vs/workbench/services/panel/common/panelService'; @@ -173,7 +173,7 @@ export class Repl extends Panel implements IPrivateReplService, IHistoryNavigati const scopedInstantiationService = this.instantiationService.createChild(new ServiceCollection( [IContextKeyService, scopedContextKeyService], [IPrivateReplService, this])); - this.replInput = scopedInstantiationService.createInstance(CodeEditorWidget, this.replInputContainer, SimpleDebugEditor.getEditorOptions(), SimpleDebugEditor.getCodeEditorWidgetOptions()); + this.replInput = scopedInstantiationService.createInstance(CodeEditorWidget, this.replInputContainer, SimpleWidgetEditorConfig.getEditorOptions('editor'), SimpleWidgetEditorConfig.getCodeEditorWidgetOptions()); modes.SuggestRegistry.register({ scheme: DEBUG_SCHEME, pattern: '**/replinput', hasAccessToAllModels: true }, { triggerCharacters: ['.'], diff --git a/src/vs/workbench/parts/debug/electron-browser/simpleDebugEditor.ts b/src/vs/workbench/parts/debug/electron-browser/simpleDebugEditor.ts deleted file mode 100644 index 720b75f1cad..00000000000 --- a/src/vs/workbench/parts/debug/electron-browser/simpleDebugEditor.ts +++ /dev/null @@ -1,57 +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 { IEditorOptions } from 'vs/editor/common/config/editorOptions'; -import { ICodeEditorWidgetOptions } from 'vs/editor/browser/widget/codeEditorWidget'; - -// Allowed Editor Contributions: -import { MenuPreventer } from 'vs/workbench/parts/codeEditor/electron-browser/menuPreventer'; -import { SelectionClipboard } from 'vs/workbench/parts/codeEditor/electron-browser/selectionClipboard'; -import { ContextMenuController } from 'vs/editor/contrib/contextmenu/contextmenu'; -import { SuggestController } from 'vs/editor/contrib/suggest/suggestController'; -import { SnippetController2 } from 'vs/editor/contrib/snippet/snippetController2'; -import { TabCompletionController } from 'vs/workbench/parts/snippets/electron-browser/tabCompletion'; - -export class SimpleDebugEditor { - - public static getCodeEditorWidgetOptions(): ICodeEditorWidgetOptions { - return { - isSimpleWidget: true, - contributions: [ - MenuPreventer, - SelectionClipboard, - ContextMenuController, - SuggestController, - SnippetController2, - TabCompletionController, - ] - }; - } - - public static getEditorOptions(): IEditorOptions { - return { - wordWrap: 'on', - overviewRulerLanes: 0, - glyphMargin: false, - lineNumbers: 'off', - folding: false, - selectOnLineNumbers: false, - hideCursorInOverviewRuler: true, - selectionHighlight: false, - scrollbar: { - horizontal: 'hidden' - }, - lineDecorationsWidth: 0, - overviewRulerBorder: false, - scrollBeyondLastLine: false, - renderLineHighlight: 'none', - fixedOverflowWidgets: true, - acceptSuggestionOnEnter: 'smart', - minimap: { - enabled: false - } - }; - } -} diff --git a/src/vs/workbench/parts/extensions/electron-browser/extensionsViewlet.ts b/src/vs/workbench/parts/extensions/electron-browser/extensionsViewlet.ts index bc834b46f36..cd9a86f34bc 100644 --- a/src/vs/workbench/parts/extensions/electron-browser/extensionsViewlet.ts +++ b/src/vs/workbench/parts/extensions/electron-browser/extensionsViewlet.ts @@ -65,7 +65,7 @@ import { IEditorOptions } from 'vs/editor/common/config/editorOptions'; import { Range } from 'vs/editor/common/core/range'; import { Position } from 'vs/editor/common/core/position'; import { ITextModel } from 'vs/editor/common/model'; -import { SimpleDebugEditor } from 'vs/workbench/parts/debug/electron-browser/simpleDebugEditor'; +import { SimpleWidgetEditorConfig } from 'vs/workbench/parts/codeEditor/electron-browser/simpleWidgetEditor'; interface SearchInputEvent extends Event { target: HTMLInputElement; @@ -340,7 +340,10 @@ export class ExtensionsViewlet extends ViewContainerViewlet implements IExtensio const header = append(this.root, $('.header')); this.monacoStyleContainer = append(header, $('.monaco-container')); - this.searchBox = this.instantiationService.createInstance(CodeEditorWidget, this.monacoStyleContainer, SEARCH_INPUT_OPTIONS, SimpleDebugEditor.getCodeEditorWidgetOptions()); + this.searchBox = this.instantiationService.createInstance(CodeEditorWidget, this.monacoStyleContainer, + SimpleWidgetEditorConfig.getEditorOptions('htmlinput', localize('searchExtensions', "Search Extensions in Marketplace")), + SimpleWidgetEditorConfig.getCodeEditorWidgetOptions()); + this.placeholderText = append(this.monacoStyleContainer, $('.search-placeholder', null, localize('searchExtensions', "Search Extensions in Marketplace"))); this.extensionsBox = append(this.root, $('.extensions')); @@ -665,32 +668,3 @@ export class MaliciousExtensionChecker implements IWorkbenchContribution { } } -let SEARCH_INPUT_OPTIONS: IEditorOptions = -{ - fontSize: 13, - lineHeight: 22, - wordWrap: 'off', - overviewRulerLanes: 0, - glyphMargin: false, - lineNumbers: 'off', - folding: false, - selectOnLineNumbers: false, - hideCursorInOverviewRuler: true, - selectionHighlight: false, - scrollbar: { - horizontal: 'hidden', - vertical: 'hidden' - }, - ariaLabel: localize('searchExtensions', "Search Extensions in Marketplace"), - cursorWidth: 1, - lineDecorationsWidth: 0, - overviewRulerBorder: false, - scrollBeyondLastLine: false, - renderLineHighlight: 'none', - fixedOverflowWidgets: true, - acceptSuggestionOnEnter: 'smart', - minimap: { - enabled: false - }, - fontFamily: ' -apple-system, BlinkMacSystemFont, "Segoe WPC", "Segoe UI", "HelveticaNeue-Light", "Ubuntu", "Droid Sans", sans-serif' -}; From 6fb3e7a4d48b904b3b0596891ee805b095280277 Mon Sep 17 00:00:00 2001 From: Jackson Kearl Date: Wed, 25 Jul 2018 09:37:37 -0700 Subject: [PATCH 0110/1276] Remove unused --- .../parts/extensions/electron-browser/extensionsViewlet.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/src/vs/workbench/parts/extensions/electron-browser/extensionsViewlet.ts b/src/vs/workbench/parts/extensions/electron-browser/extensionsViewlet.ts index cd9a86f34bc..1a429eab473 100644 --- a/src/vs/workbench/parts/extensions/electron-browser/extensionsViewlet.ts +++ b/src/vs/workbench/parts/extensions/electron-browser/extensionsViewlet.ts @@ -61,7 +61,6 @@ import { SingleServerExtensionManagementServerService } from 'vs/workbench/servi import { Query } from 'vs/workbench/parts/extensions/common/extensionQuery'; import { CodeEditorWidget } from 'vs/editor/browser/widget/codeEditorWidget'; import { IModelService } from 'vs/editor/common/services/modelService'; -import { IEditorOptions } from 'vs/editor/common/config/editorOptions'; import { Range } from 'vs/editor/common/core/range'; import { Position } from 'vs/editor/common/core/position'; import { ITextModel } from 'vs/editor/common/model'; From 052cd3cecbcf2266a97d428b3c23d6c4f6b30783 Mon Sep 17 00:00:00 2001 From: Sandeep Somavarapu Date: Wed, 25 Jul 2018 18:44:48 +0200 Subject: [PATCH 0111/1276] #55055 Disable or uninstall only pack extensions but not dependencies --- .../node/extensionManagementService.ts | 27 ++++++++----------- .../node/extensionsWorkbenchService.ts | 20 +++++++------- 2 files changed, 21 insertions(+), 26 deletions(-) diff --git a/src/vs/platform/extensionManagement/node/extensionManagementService.ts b/src/vs/platform/extensionManagement/node/extensionManagementService.ts index 2fdebb22f56..74957144edb 100644 --- a/src/vs/platform/extensionManagement/node/extensionManagementService.ts +++ b/src/vs/platform/extensionManagement/node/extensionManagementService.ts @@ -538,14 +538,19 @@ export class ExtensionManagementService extends Disposable implements IExtension private checkForDependenciesAndUninstall(extension: ILocalExtension, installed: ILocalExtension[], force: boolean): TPromise { return this.preUninstallExtension(extension) .then(() => { - if (force) { - return this.uninstallExtensionWithDependenciesAndPacked(extension, installed); + const packedExtensions = this.getAllPackExtensionsToUninstall(extension, installed); + if (packedExtensions.length) { + return this.uninstallExtensions(extension, packedExtensions, installed); } const dependencies = this.getDependenciesToUninstall(extension, installed); if (dependencies.length) { - return this.promptForDependenciesAndUninstall(extension, installed); + if (force) { + return this.uninstallExtensions(extension, dependencies, installed); + } else { + return this.promptForDependenciesAndUninstall(extension, dependencies, installed); + } } else { - return this.uninstallExtensionWithDependenciesAndPacked(extension, installed); + return this.uninstallExtensions(extension, [], installed); } }) .then(() => this.postUninstallExtension(extension), @@ -555,7 +560,7 @@ export class ExtensionManagementService extends Disposable implements IExtension }); } - private promptForDependenciesAndUninstall(extension: ILocalExtension, installed: ILocalExtension[]): TPromise { + private promptForDependenciesAndUninstall(extension: ILocalExtension, dependencies: ILocalExtension[], installed: ILocalExtension[]): TPromise { const message = nls.localize('uninstallDependeciesConfirmation', "Would you like to uninstall '{0}' only or its dependencies also?", extension.manifest.displayName || extension.manifest.name); const buttons = [ nls.localize('uninstallOnly', "Extension Only"), @@ -568,23 +573,13 @@ export class ExtensionManagementService extends Disposable implements IExtension return this.uninstallExtensions(extension, [], installed); } if (value === 1) { - return this.uninstallExtensionWithDependenciesAndPacked(extension, installed); + return this.uninstallExtensions(extension, dependencies, installed); } this.logService.info('Cancelled uninstalling extension:', extension.identifier.id); return TPromise.wrapError(errors.canceled()); }, error => TPromise.wrapError(errors.canceled())); } - private uninstallExtensionWithDependenciesAndPacked(extension: ILocalExtension, installed: ILocalExtension[]): TPromise { - const extensionsToUninstall = this.getDependenciesToUninstall(extension, installed); - for (const packExtensionToUninstall of this.getAllPackExtensionsToUninstall(extension, installed)) { - if (extensionsToUninstall.indexOf(packExtensionToUninstall) === -1) { - extensionsToUninstall.push(packExtensionToUninstall); - } - } - return this.uninstallExtensions(extension, extensionsToUninstall, installed); - } - private uninstallExtensions(extension: ILocalExtension, otherExtensionsToUninstall: ILocalExtension[], installed: ILocalExtension[]): TPromise { const dependents = this.getDependents(extension, installed); if (dependents.length) { diff --git a/src/vs/workbench/parts/extensions/node/extensionsWorkbenchService.ts b/src/vs/workbench/parts/extensions/node/extensionsWorkbenchService.ts index 576f2f54455..75762a4bc44 100644 --- a/src/vs/workbench/parts/extensions/node/extensionsWorkbenchService.ts +++ b/src/vs/workbench/parts/extensions/node/extensionsWorkbenchService.ts @@ -744,18 +744,23 @@ export class ExtensionsWorkbenchService implements IExtensionsWorkbenchService, private promptAndSetEnablement(extensions: IExtension[], enablementState: EnablementState): TPromise { const enable = enablementState === EnablementState.Enabled || enablementState === EnablementState.WorkspaceEnabled; if (enable) { - return this.checkAndSetEnablementWithDependenciesAndPacked(extensions, enablementState); + const allDependenciesAndPackedExtensions = this.getExtensionsRecursively(extensions, this.local, enablementState, { dependencies: true, pack: true }); + return this.checkAndSetEnablement(extensions, allDependenciesAndPackedExtensions, enablementState); } else { + const packedExtensions = this.getExtensionsRecursively(extensions, this.local, enablementState, { dependencies: false, pack: true }); + if (packedExtensions.length) { + return this.checkAndSetEnablement(extensions, packedExtensions, enablementState); + } const dependencies = this.getExtensionsRecursively(extensions, this.local, enablementState, { dependencies: true, pack: false }); if (dependencies.length) { - return this.promptForDependenciesAndDisable(extensions, enablementState); + return this.promptForDependenciesAndDisable(extensions, dependencies, enablementState); } else { - return this.checkAndSetEnablementWithDependenciesAndPacked(extensions, enablementState); + return this.checkAndSetEnablement(extensions, [], enablementState); } } } - private promptForDependenciesAndDisable(extensions: IExtension[], enablementState: EnablementState): TPromise { + private promptForDependenciesAndDisable(extensions: IExtension[], dependencies: IExtension[], enablementState: EnablementState): TPromise { const message = nls.localize('disableDependeciesConfirmation', "Would you like to disable the dependencies of the extensions also?"); const buttons = [ nls.localize('yes', "Yes"), @@ -765,7 +770,7 @@ export class ExtensionsWorkbenchService implements IExtensionsWorkbenchService, return this.dialogService.show(Severity.Info, message, buttons, { cancelId: 2 }) .then(value => { if (value === 0) { - return this.checkAndSetEnablementWithDependenciesAndPacked(extensions, enablementState); + return this.checkAndSetEnablement(extensions, dependencies, enablementState); } if (value === 1) { return this.checkAndSetEnablement(extensions, [], enablementState); @@ -774,11 +779,6 @@ export class ExtensionsWorkbenchService implements IExtensionsWorkbenchService, }); } - private checkAndSetEnablementWithDependenciesAndPacked(extensions: IExtension[], enablementState: EnablementState): TPromise { - const otherExtensions = this.getExtensionsRecursively(extensions, this.local, enablementState, { dependencies: true, pack: true }); - return this.checkAndSetEnablement(extensions, otherExtensions, enablementState); - } - private checkAndSetEnablement(extensions: IExtension[], otherExtensions: IExtension[], enablementState: EnablementState): TPromise { const allExtensions = [...extensions, ...otherExtensions]; const enable = enablementState === EnablementState.Enabled || enablementState === EnablementState.WorkspaceEnabled; From 00821eaa6ab49876aefeaed891fd73630f756a09 Mon Sep 17 00:00:00 2001 From: Sandeep Somavarapu Date: Wed, 25 Jul 2018 18:57:31 +0200 Subject: [PATCH 0112/1276] Fix tests --- .../test/electron-browser/extensionsWorkbenchService.test.ts | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/vs/workbench/parts/extensions/test/electron-browser/extensionsWorkbenchService.test.ts b/src/vs/workbench/parts/extensions/test/electron-browser/extensionsWorkbenchService.test.ts index 704d31d312a..c003da371ef 100644 --- a/src/vs/workbench/parts/extensions/test/electron-browser/extensionsWorkbenchService.test.ts +++ b/src/vs/workbench/parts/extensions/test/electron-browser/extensionsWorkbenchService.test.ts @@ -851,7 +851,7 @@ suite('ExtensionsWorkbenchServiceTest', () => { }); }); - test('test disable extension pack disable only itself', () => { + test('test disable extension pack disables the pack', () => { const extensionA = aLocalExtension('a', { extensionPack: ['pub.b'] }); const extensionB = aLocalExtension('b'); const extensionC = aLocalExtension('c'); @@ -861,13 +861,12 @@ suite('ExtensionsWorkbenchServiceTest', () => { .then(() => instantiationService.get(IExtensionEnablementService).setEnablement(extensionC, EnablementState.Enabled)) .then(() => { instantiationService.stubPromise(IExtensionManagementService, 'getInstalled', [extensionA, extensionB, extensionC]); - instantiationService.stubPromise(IDialogService, 'show', 1); testObject = instantiationService.createInstance(ExtensionsWorkbenchService); return testObject.setEnablement(testObject.local[0], EnablementState.Disabled) .then(() => { assert.equal(testObject.local[0].enablementState, EnablementState.Disabled); - assert.equal(testObject.local[1].enablementState, EnablementState.Enabled); + assert.equal(testObject.local[1].enablementState, EnablementState.Disabled); }); }); }); From c75cb56572d99cb893ed4b472d4d4179e5efbfaa Mon Sep 17 00:00:00 2001 From: Jackson Kearl Date: Wed, 25 Jul 2018 10:28:19 -0700 Subject: [PATCH 0113/1276] Relax condition on select all --- src/vs/editor/browser/controller/coreCommands.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vs/editor/browser/controller/coreCommands.ts b/src/vs/editor/browser/controller/coreCommands.ts index 414cf185fe1..46a8671d6f4 100644 --- a/src/vs/editor/browser/controller/coreCommands.ts +++ b/src/vs/editor/browser/controller/coreCommands.ts @@ -1706,7 +1706,7 @@ registerCommand(new EditorOrNativeTextInputCommand({ editorHandler: CoreNavigationCommands.SelectAll, inputHandler: 'selectAll', id: 'editor.action.selectAll', - precondition: EditorContextKeys.focus, + precondition: EditorContextKeys.textInputFocus, kbOpts: { weight: CORE_WEIGHT, kbExpr: null, From e6e83fec4aef11c613900cbd91aac7b77d7eb624 Mon Sep 17 00:00:00 2001 From: Jackson Kearl Date: Wed, 25 Jul 2018 10:44:48 -0700 Subject: [PATCH 0114/1276] Refactoring --- .../electron-browser/simpleWidgetEditor.ts | 110 +++++++++--------- .../electron-browser/breakpointWidget.ts | 2 +- .../parts/debug/electron-browser/repl.ts | 2 +- .../electron-browser/extensionsViewlet.ts | 2 +- 4 files changed, 57 insertions(+), 59 deletions(-) diff --git a/src/vs/workbench/parts/codeEditor/electron-browser/simpleWidgetEditor.ts b/src/vs/workbench/parts/codeEditor/electron-browser/simpleWidgetEditor.ts index c3d3f17b0aa..4dece238fbd 100644 --- a/src/vs/workbench/parts/codeEditor/electron-browser/simpleWidgetEditor.ts +++ b/src/vs/workbench/parts/codeEditor/electron-browser/simpleWidgetEditor.ts @@ -30,61 +30,59 @@ export class SimpleWidgetEditorConfig { }; } - public static getEditorOptions(style: 'editor' | 'htmlinput', ariaLabel?: string): IEditorOptions { - if (style === 'editor') { - return { - wordWrap: 'on', - overviewRulerLanes: 0, - glyphMargin: false, - lineNumbers: 'off', - folding: false, - selectOnLineNumbers: false, - hideCursorInOverviewRuler: true, - selectionHighlight: false, - scrollbar: { - horizontal: 'hidden' - }, - ariaLabel: ariaLabel || '', - lineDecorationsWidth: 0, - overviewRulerBorder: false, - scrollBeyondLastLine: false, - renderLineHighlight: 'none', - fixedOverflowWidgets: true, - acceptSuggestionOnEnter: 'smart', - minimap: { - enabled: false - } - }; - } - else { - return { - fontSize: 13, - lineHeight: 22, - wordWrap: 'off', - overviewRulerLanes: 0, - glyphMargin: false, - lineNumbers: 'off', - folding: false, - selectOnLineNumbers: false, - hideCursorInOverviewRuler: true, - selectionHighlight: false, - scrollbar: { - horizontal: 'hidden', - vertical: 'hidden' - }, - ariaLabel: ariaLabel || '', - cursorWidth: 1, - lineDecorationsWidth: 0, - overviewRulerBorder: false, - scrollBeyondLastLine: false, - renderLineHighlight: 'none', - fixedOverflowWidgets: true, - acceptSuggestionOnEnter: 'smart', - minimap: { - enabled: false - }, - fontFamily: ' -apple-system, BlinkMacSystemFont, "Segoe WPC", "Segoe UI", "HelveticaNeue-Light", "Ubuntu", "Droid Sans", sans-serif' - }; - } + public static getEditorOptions(): IEditorOptions { + return { + wordWrap: 'on', + overviewRulerLanes: 0, + glyphMargin: false, + lineNumbers: 'off', + folding: false, + selectOnLineNumbers: false, + hideCursorInOverviewRuler: true, + selectionHighlight: false, + scrollbar: { + horizontal: 'hidden' + }, + lineDecorationsWidth: 0, + overviewRulerBorder: false, + scrollBeyondLastLine: false, + renderLineHighlight: 'none', + fixedOverflowWidgets: true, + acceptSuggestionOnEnter: 'smart', + minimap: { + enabled: false + } + }; + } + + public static getEditorAsInputBoxOptions(ariaLabel?: string): IEditorOptions { + return { + fontSize: 13, + lineHeight: 22, + wordWrap: 'off', + overviewRulerLanes: 0, + glyphMargin: false, + lineNumbers: 'off', + folding: false, + selectOnLineNumbers: false, + hideCursorInOverviewRuler: true, + selectionHighlight: false, + scrollbar: { + horizontal: 'hidden', + vertical: 'hidden' + }, + ariaLabel: ariaLabel || '', + cursorWidth: 1, + lineDecorationsWidth: 0, + overviewRulerBorder: false, + scrollBeyondLastLine: false, + renderLineHighlight: 'none', + fixedOverflowWidgets: true, + acceptSuggestionOnEnter: 'smart', + minimap: { + enabled: false + }, + fontFamily: ' -apple-system, BlinkMacSystemFont, "Segoe WPC", "Segoe UI", "HelveticaNeue-Light", "Ubuntu", "Droid Sans", sans-serif' + }; } } diff --git a/src/vs/workbench/parts/debug/electron-browser/breakpointWidget.ts b/src/vs/workbench/parts/debug/electron-browser/breakpointWidget.ts index 3d1ad211ed5..1c08b53c0e0 100644 --- a/src/vs/workbench/parts/debug/electron-browser/breakpointWidget.ts +++ b/src/vs/workbench/parts/debug/electron-browser/breakpointWidget.ts @@ -200,7 +200,7 @@ export class BreakpointWidget extends ZoneWidget implements IPrivateBreakpointWi const scopedInstatiationService = this.instantiationService.createChild(new ServiceCollection( [IContextKeyService, scopedContextKeyService], [IPrivateBreakpointWidgetService, this])); - const options = SimpleWidgetEditorConfig.getEditorOptions('editor'); + const options = SimpleWidgetEditorConfig.getEditorOptions(); const codeEditorWidgetOptions = SimpleWidgetEditorConfig.getCodeEditorWidgetOptions(); this.input = scopedInstatiationService.createInstance(CodeEditorWidget, container, options, codeEditorWidgetOptions); CONTEXT_IN_BREAKPOINT_WIDGET.bindTo(scopedContextKeyService).set(true); diff --git a/src/vs/workbench/parts/debug/electron-browser/repl.ts b/src/vs/workbench/parts/debug/electron-browser/repl.ts index 1cc6bea977e..521a6938e85 100644 --- a/src/vs/workbench/parts/debug/electron-browser/repl.ts +++ b/src/vs/workbench/parts/debug/electron-browser/repl.ts @@ -173,7 +173,7 @@ export class Repl extends Panel implements IPrivateReplService, IHistoryNavigati const scopedInstantiationService = this.instantiationService.createChild(new ServiceCollection( [IContextKeyService, scopedContextKeyService], [IPrivateReplService, this])); - this.replInput = scopedInstantiationService.createInstance(CodeEditorWidget, this.replInputContainer, SimpleWidgetEditorConfig.getEditorOptions('editor'), SimpleWidgetEditorConfig.getCodeEditorWidgetOptions()); + this.replInput = scopedInstantiationService.createInstance(CodeEditorWidget, this.replInputContainer, SimpleWidgetEditorConfig.getEditorOptions(), SimpleWidgetEditorConfig.getCodeEditorWidgetOptions()); modes.SuggestRegistry.register({ scheme: DEBUG_SCHEME, pattern: '**/replinput', hasAccessToAllModels: true }, { triggerCharacters: ['.'], diff --git a/src/vs/workbench/parts/extensions/electron-browser/extensionsViewlet.ts b/src/vs/workbench/parts/extensions/electron-browser/extensionsViewlet.ts index 1a429eab473..894e269a2f0 100644 --- a/src/vs/workbench/parts/extensions/electron-browser/extensionsViewlet.ts +++ b/src/vs/workbench/parts/extensions/electron-browser/extensionsViewlet.ts @@ -340,7 +340,7 @@ export class ExtensionsViewlet extends ViewContainerViewlet implements IExtensio const header = append(this.root, $('.header')); this.monacoStyleContainer = append(header, $('.monaco-container')); this.searchBox = this.instantiationService.createInstance(CodeEditorWidget, this.monacoStyleContainer, - SimpleWidgetEditorConfig.getEditorOptions('htmlinput', localize('searchExtensions', "Search Extensions in Marketplace")), + SimpleWidgetEditorConfig.getEditorAsInputBoxOptions(localize('searchExtensions', "Search Extensions in Marketplace")), SimpleWidgetEditorConfig.getCodeEditorWidgetOptions()); this.placeholderText = append(this.monacoStyleContainer, $('.search-placeholder', null, localize('searchExtensions', "Search Extensions in Marketplace"))); From 740d37d7dd06a7fc200819cb7598afe8a7c35633 Mon Sep 17 00:00:00 2001 From: Rachel Macfarlane Date: Wed, 25 Jul 2018 11:01:59 -0700 Subject: [PATCH 0115/1276] Some setting descriptions cleanup, #54690 --- extensions/git/package.json | 11 ++++++++++ extensions/git/package.nls.json | 21 ++++++++++++------- .../extensions.contribution.ts | 6 +++--- .../electron-browser/files.contribution.ts | 16 ++++++++------ 4 files changed, 38 insertions(+), 16 deletions(-) diff --git a/extensions/git/package.json b/extensions/git/package.json index e455ec699ad..a4afad8facb 100644 --- a/extensions/git/package.json +++ b/extensions/git/package.json @@ -925,6 +925,11 @@ "tracked", "off" ], + "enumDescriptions": [ + "%config.countBadge.all%", + "%config.countBadge.tracked%", + "%config.countBadge.off%" + ], "description": "%config.countBadge%", "default": "all" }, @@ -936,6 +941,12 @@ "tags", "remote" ], + "enumDescriptions": [ + "%config.checkoutType.all%", + "%config.checkoutType.local%", + "%config.checkoutType.tags%", + "%config.checkoutType.remote%" + ], "description": "%config.checkoutType%", "default": "all" }, diff --git a/extensions/git/package.nls.json b/extensions/git/package.nls.json index 7b56fd9e95a..38050ced547 100644 --- a/extensions/git/package.nls.json +++ b/extensions/git/package.nls.json @@ -50,23 +50,30 @@ "command.stash": "Stash", "command.stashPop": "Pop Stash...", "command.stashPopLatest": "Pop Latest Stash", - "config.enabled": "Whether git is enabled", + "config.enabled": "Whether git is enabled.", "config.path": "Path to the git executable.", "config.autoRepositoryDetection": "Configures when repositories should be automatically detected.", "config.autorefresh": "Whether auto refreshing is enabled", "config.autofetch": "Whether auto fetching is enabled", "config.enableLongCommitWarning": "Whether long commit messages should be warned about", - "config.confirmSync": "Confirm before synchronizing git repositories", - "config.countBadge": "Controls the git badge counter. `all` counts all changes. `tracked` counts only the tracked changes. `off` turns it off.", - "config.checkoutType": "Controls what type of branches are listed when running `Checkout to...`. `all` shows all refs, `local` shows only the local branches, `tags` shows only tags and `remote` shows only remote branches.", - "config.ignoreLegacyWarning": "Ignores the legacy Git warning", + "config.confirmSync": "Confirm before synchronizing git repositories.", + "config.countBadge": "Controls the git badge counter.", + "config.countBadge.all": "Count all changes.", + "config.countBadge.tracked": "Count only tracked changes.", + "config.countBadge.off": "Turn off counter.", + "config.checkoutType": "Controls what type of branches are listed when running `Checkout to...`.", + "config.checkoutType.all": "Show all references.", + "config.checkoutType.local": "Show only local branches.", + "config.checkoutType.tags": "Show only tags.", + "config.checkoutType.remote": "Show only remote branches.", + "config.ignoreLegacyWarning": "Ignores the legacy Git warning.", "config.ignoreMissingGitWarning": "Ignores the warning when Git is missing", "config.ignoreLimitWarning": "Ignores the warning when there are too many changes in a repository", - "config.defaultCloneDirectory": "The default location where to clone a git repository", + "config.defaultCloneDirectory": "The default location to clone a git repository.", "config.enableSmartCommit": "Commit all changes when there are no staged changes.", "config.enableCommitSigning": "Enables commit signing with GPG.", "config.discardAllScope": "Controls what changes are discarded by the `Discard all changes` command. `all` discards all changes. `tracked` discards only tracked files. `prompt` shows a prompt dialog every time the action is run.", - "config.decorations.enabled": "Controls if Git contributes colors and badges to the explorer and the open editors view.", + "config.decorations.enabled": "Controls whether Git contributes colors and badges to the explorer and the open editors view.", "config.promptToSaveFilesBeforeCommit": "Controls whether Git should check for unsaved files before committing.", "config.showInlineOpenFileAction": "Controls whether to show an inline Open File action in the Git changes view.", "config.showPushSuccessNotification": "Controls whether to show a notification when a push is successful.", diff --git a/src/vs/workbench/parts/extensions/electron-browser/extensions.contribution.ts b/src/vs/workbench/parts/extensions/electron-browser/extensions.contribution.ts index 1415dd8bcfa..38982094519 100644 --- a/src/vs/workbench/parts/extensions/electron-browser/extensions.contribution.ts +++ b/src/vs/workbench/parts/extensions/electron-browser/extensions.contribution.ts @@ -210,17 +210,17 @@ Registry.as(ConfigurationExtensions.Configuration) }, 'extensions.ignoreRecommendations': { type: 'boolean', - description: localize('extensionsIgnoreRecommendations', "If set to true, the notifications for extension recommendations will stop showing up."), + description: localize('extensionsIgnoreRecommendations', "When enabled, the notifications for extension recommendations will not be shown."), default: false }, 'extensions.showRecommendationsOnlyOnDemand': { type: 'boolean', - description: localize('extensionsShowRecommendationsOnlyOnDemand', "If set to true, recommendations will not be fetched or shown unless specifically requested by the user."), + description: localize('extensionsShowRecommendationsOnlyOnDemand', "When enabled, recommendations will not be fetched or shown unless specifically requested by the user."), default: false }, 'extensions.closeExtensionDetailsOnViewChange': { type: 'boolean', - description: localize('extensionsCloseExtensionDetailsOnViewChange', "If set to true, editors with extension details will be automatically closed upon navigating away from the Extensions View."), + description: localize('extensionsCloseExtensionDetailsOnViewChange', "When enabled, editors with extension details will be automatically closed upon navigating away from the Extensions View."), default: false } } diff --git a/src/vs/workbench/parts/files/electron-browser/files.contribution.ts b/src/vs/workbench/parts/files/electron-browser/files.contribution.ts index c684a9a1e73..c931f0ec43f 100644 --- a/src/vs/workbench/parts/files/electron-browser/files.contribution.ts +++ b/src/vs/workbench/parts/files/electron-browser/files.contribution.ts @@ -199,7 +199,7 @@ configurationRegistry.registerConfiguration({ 'overridable': true, 'enum': Object.keys(SUPPORTED_ENCODINGS), 'default': 'utf8', - 'description': nls.localize('encoding', "The default character set encoding to use when reading and writing files. This setting can be configured per language too."), + 'description': nls.localize('encoding', "The default character set encoding to use when reading and writing files. This setting can also be configured per language."), 'scope': ConfigurationScope.RESOURCE, 'enumDescriptions': Object.keys(SUPPORTED_ENCODINGS).map(key => SUPPORTED_ENCODINGS[key].labelLong) }, @@ -207,7 +207,7 @@ configurationRegistry.registerConfiguration({ 'type': 'boolean', 'overridable': true, 'default': false, - 'description': nls.localize('autoGuessEncoding', "When enabled, will attempt to guess the character set encoding when opening files. This setting can be configured per language too."), + 'description': nls.localize('autoGuessEncoding', "When enabled, the editor will attempt to guess the character set encoding when opening files. This setting can also be configured per language."), 'scope': ConfigurationScope.RESOURCE }, 'files.eol': { @@ -216,8 +216,12 @@ configurationRegistry.registerConfiguration({ '\n', '\r\n' ], + 'enumDescriptions': [ + nls.localize('eol.LF', "LF"), + nls.localize('eol.CRLF', "CRLF") + ], 'default': (platform.isLinux || platform.isMacintosh) ? '\n' : '\r\n', - 'description': nls.localize('eol', "The default end of line character. Use \\n for LF and \\r\\n for CRLF."), + 'description': nls.localize('eol', "The default end of line character."), 'scope': ConfigurationScope.RESOURCE }, 'files.trimTrailingWhitespace': { @@ -270,8 +274,8 @@ configurationRegistry.registerConfiguration({ 'default': HotExitConfiguration.ON_EXIT, 'enumDescriptions': [ nls.localize('hotExit.off', 'Disable hot exit.'), - nls.localize('hotExit.onExit', 'Hot exit will be triggered when the application is closed, that is 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.'), - nls.localize('hotExit.onExitAndWindowClose', 'Hot exit will be triggered when the application is closed, that is when the last window is closed on Windows/Linux or when the workbench.action.quit command is triggered (command palette, keybinding, menu), and also for any window with a folder opened regardless of whether it\'s the last window. All windows without folders opened will be restored upon next launch. To restore folder windows as they were before shutdown set "window.restoreWindows" to "all".') + 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.'), + nls.localize('hotExit.onExitAndWindowClose', '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), and also for any window with a folder opened regardless of whether it\'s the last window. All windows without folders opened will be restored upon next launch. To restore folder windows as they were before shutdown set `#window.restoreWindows#` to `all`.') ], 'description': nls.localize('hotExit', "Controls whether unsaved files are remembered between sessions, allowing the save prompt when exiting the editor to be skipped.", HotExitConfiguration.ON_EXIT, HotExitConfiguration.ON_EXIT_AND_WINDOW_CLOSE) }, @@ -287,7 +291,7 @@ configurationRegistry.registerConfiguration({ 'files.maxMemoryForLargeFilesMB': { 'type': 'number', 'default': 4096, - 'description': nls.localize('maxMemoryForLargeFilesMB', "Controls the memory available to VS Code after restart when trying to open large files. Same effect as specifying --max-memory=NEWSIZE on the command line.") + 'description': nls.localize('maxMemoryForLargeFilesMB', "Controls the memory available to VS Code after restart when trying to open large files. Same effect as specifying `--max-memory=NEWSIZE` on the command line.") } } }); From bf4a68a2b2f14ad675e2fee897704933715ee477 Mon Sep 17 00:00:00 2001 From: Rob Lourens Date: Wed, 25 Jul 2018 11:44:03 -0700 Subject: [PATCH 0116/1276] Settings exclude control - Implement editing --- .../browser/media/settingsWidgets.css | 23 +-- .../parts/preferences/browser/settingsTree.ts | 28 +-- .../preferences/browser/settingsWidgets.ts | 170 ++++++++---------- 3 files changed, 94 insertions(+), 127 deletions(-) diff --git a/src/vs/workbench/parts/preferences/browser/media/settingsWidgets.css b/src/vs/workbench/parts/preferences/browser/media/settingsWidgets.css index a0df231835d..f6b08e12198 100644 --- a/src/vs/workbench/parts/preferences/browser/media/settingsWidgets.css +++ b/src/vs/workbench/parts/preferences/browser/media/settingsWidgets.css @@ -74,35 +74,24 @@ padding: 4px 10px; } -.settings-editor > .settings-body > .settings-tree-container .setting-item.setting-item-exclude .monaco-text-button.setting-exclude-addPattern { +.settings-editor > .settings-body > .settings-tree-container .setting-item.setting-item-exclude .monaco-text-button.setting-exclude-addButton { margin-right: 10px; } -.settings-editor > .settings-body > .settings-tree-container .setting-item.setting-item-exclude.is-expanded .monaco-text-button.setting-exclude-addButton { - display: inline-block; -} - .settings-editor > .settings-body > .settings-tree-container .setting-item.setting-item-exclude .setting-exclude-edit-row.setting-exclude-newExcludeItem { display: flex; } -.settings-editor > .settings-body > .settings-tree-container .setting-item.setting-item-exclude .setting-exclude-patternInput { +.settings-editor > .settings-body > .settings-tree-container .setting-item.setting-item-exclude .setting-exclude-patternInput, +.settings-editor > .settings-body > .settings-tree-container .setting-item.setting-item-exclude .setting-exclude-siblingInput, +.settings-editor > .settings-body > .settings-tree-container .setting-item.setting-item-exclude .setting-exclude-newPatternInput { max-width: 300px; display: inline-block; margin-right: 10px; } -.settings-editor > .settings-body > .settings-tree-container .setting-item.setting-item-exclude .setting-exclude-edit-row.setting-exclude-newPattern .setting-exclude-patternInput { - display: inline-block; -} - -.settings-editor > .settings-body > .settings-tree-container .setting-item.setting-item-exclude .setting-exclude-edit-row.setting-exclude-newPatternWithSibling .setting-exclude-patternInput { - margin-right: 5px; -} - -.settings-editor > .settings-body > .settings-tree-container .setting-item.setting-item-exclude .setting-exclude-edit-row.setting-exclude-newPatternWithSibling .setting-exclude-patternInput, -.settings-editor > .settings-body > .settings-tree-container .setting-item.setting-item-exclude .setting-exclude-edit-row.setting-exclude-newPatternWithSibling .setting-exclude-siblingInput { - display: inline-block; +.settings-editor > .settings-body > .settings-tree-container .setting-item.setting-item-exclude .setting-exclude-okButton { + margin-right: 10px; } .settings-editor > .settings-body > .settings-tree-container .setting-item.setting-item-exclude .setting-exclude-widget { diff --git a/src/vs/workbench/parts/preferences/browser/settingsTree.ts b/src/vs/workbench/parts/preferences/browser/settingsTree.ts index 3857625e1c6..7e9536be013 100644 --- a/src/vs/workbench/parts/preferences/browser/settingsTree.ts +++ b/src/vs/workbench/parts/preferences/browser/settingsTree.ts @@ -35,7 +35,7 @@ import { attachButtonStyler, attachInputBoxStyler, attachSelectBoxStyler, attach import { ICssStyleCollector, ITheme, IThemeService, registerThemingParticipant } from 'vs/platform/theme/common/themeService'; import { SettingsTarget } from 'vs/workbench/parts/preferences/browser/preferencesWidgets'; import { ITOCEntry } from 'vs/workbench/parts/preferences/browser/settingsLayout'; -import { ExcludeSettingWidget, settingsNumberInputBackground, settingsNumberInputBorder, settingsNumberInputForeground, settingsSelectBackground, settingsSelectBorder, settingsSelectForeground, settingsTextInputBorder, settingsTextInputForeground, settingItemInactiveSelectionBorder, settingsHeaderForeground, settingsTextInputBackground } from 'vs/workbench/parts/preferences/browser/settingsWidgets'; +import { ExcludeSettingWidget, settingsNumberInputBackground, settingsNumberInputBorder, settingsNumberInputForeground, settingsSelectBackground, settingsSelectBorder, settingsSelectForeground, settingsTextInputBorder, settingsTextInputForeground, settingItemInactiveSelectionBorder, settingsHeaderForeground, settingsTextInputBackground, IExcludeDataItem } from 'vs/workbench/parts/preferences/browser/settingsWidgets'; import { ISearchResult, ISetting, ISettingsGroup } from 'vs/workbench/services/preferences/common/preferences'; const $ = DOM.$; @@ -213,21 +213,23 @@ function createSettingsTreeSettingElement(setting: ISetting, parent: any, settin return element; } -function getExcludeDisplayValue(element: SettingsTreeSettingElement): any { +function getExcludeDisplayValue(element: SettingsTreeSettingElement): IExcludeDataItem[] { const data = element.isConfigured ? - { - ...element.defaultValue, - ...element.value - } : + objects.mixin({ ...element.scopeValue }, element.defaultValue, false) : element.defaultValue; - for (let key in data) { - if (!data[key]) { - delete data[key]; - } - } + return Object.keys(data) + .filter(key => !!data[key]) + .map(key => { + const value = data[key]; + const sibling = typeof value === 'boolean' ? undefined : value.when; - return data; + return { + id: key, + pattern: key, + sibling + }; + }); } interface IInspectResult { @@ -551,7 +553,7 @@ export class SettingsRenderer implements ITreeRenderer { _getExcludeSettingHeight(element: SettingsTreeSettingElement): number { const displayValue = getExcludeDisplayValue(element); - return (Object.keys(displayValue).length + 1) * 22 + 72; + return (displayValue.length + 1) * 22 + 80; } _getUnexpandedSettingHeight(element: SettingsTreeSettingElement): number { diff --git a/src/vs/workbench/parts/preferences/browser/settingsWidgets.ts b/src/vs/workbench/parts/preferences/browser/settingsWidgets.ts index cef0521ced0..ac057a6d7c8 100644 --- a/src/vs/workbench/parts/preferences/browser/settingsWidgets.ts +++ b/src/vs/workbench/parts/preferences/browser/settingsWidgets.ts @@ -83,55 +83,32 @@ registerThemingParticipant((theme: ITheme, collector: ICssStyleCollector) => { } }); -enum AddItemMode { - None, - Pattern, - PatternWithSibling -} - export class ExcludeSettingListModel { - private _dataItems: IExcludeItem[] = []; - // private _newItem = AddItemMode.None; + private _dataItems: IExcludeDataItem[] = []; + private _editKey: string; - get items(): IExcludeItem[] { - const items = [ - ...this._dataItems - ]; - - // items.push({ - // id: 'newItem', - // mode: this._newItem - // }); - - return items; + get items(): IExcludeViewItem[] { + return this._dataItems.map(item => { + return { + ...item, + editing: item.pattern === this._editKey + }; + }); } - setAddItemMode(mode: AddItemMode): void { - // this._newItem = mode; + setEditKey(key: string): void { + this._editKey = key; } - setValue(excludeValue: any, defaultValue: any): void { - this._dataItems = this.excludeValueToItems(excludeValue); - } - - private excludeValueToItems(excludeValue: any): IExcludeItem[] { - return Object.keys(excludeValue) - .map(key => { - const value = excludeValue[key]; - const sibling = typeof value === 'boolean' ? undefined : value.when; - - return { - id: key, - pattern: key, - sibling - }; - }); + setValue(excludeData: IExcludeDataItem[]): void { + this._dataItems = excludeData; } } interface IExcludeChangeEvent { originalPattern: string; pattern: string; + sibling?: string; } export class ExcludeSettingWidget extends Disposable { @@ -156,8 +133,8 @@ export class ExcludeSettingWidget extends Disposable { this.update(); } - setValue(excludeValue: any): void { - this.model.setValue(excludeValue, void 0); + setValue(excludeData: IExcludeDataItem[]): void { + this.model.setValue(excludeData); this.patternInput.value = ''; this.update(); } @@ -190,14 +167,17 @@ export class ExcludeSettingWidget extends Disposable { enabled: true, id: 'workbench.action.editExcludeItem', tooltip: localize('editExcludeItem', "Edit Exclude Item"), - run: () => { } + run: () => { + this.model.setEditKey(key); + this.update(); + } }; } - private renderItem(item: IExcludeItem): HTMLElement { - return isExcludeDataItem(item) ? - this.renderDataItem(item) : - this.renderEditItem(item); + private renderItem(item: IExcludeViewItem): HTMLElement { + return item.editing ? + this.renderEditItem(item) : + this.renderDataItem(item); } private renderDataItem(item: IExcludeDataItem): HTMLElement { @@ -227,7 +207,7 @@ export class ExcludeSettingWidget extends Disposable { this.patternInput = new InputBox(rowElement, this.contextViewService, { placeholder: localize('excludePatternInputPlaceholder', "Exclude Pattern...") }); - this.patternInput.element.classList.add('setting-exclude-patternInput'); + this.patternInput.element.classList.add('setting-exclude-newPatternInput'); this._register(attachInputBoxStyler(this.patternInput, this.themeService, { inputBackground: settingsTextInputBackground, inputForeground: settingsTextInputForeground, @@ -237,7 +217,7 @@ export class ExcludeSettingWidget extends Disposable { const addPatternButton = this._register(new Button(rowElement)); addPatternButton.label = localize('addPattern', "Add Pattern"); - addPatternButton.element.classList.add('setting-exclude-addPattern', 'setting-exclude-addButton'); + addPatternButton.element.classList.add('setting-exclude-addButton'); this._register(attachButtonStyler(addPatternButton, this.themeService)); const addItem = () => this._onDidChangeExclude.fire({ @@ -257,15 +237,25 @@ export class ExcludeSettingWidget extends Disposable { return rowElement; } - private renderEditItem(item: INewExcludeItem): HTMLElement { + private renderEditItem(item: IExcludeViewItem): HTMLElement { const rowElement = $('.setting-exclude-edit-row'); + const onSubmit = edited => { + this.model.setEditKey(null); + if (edited) { + this._onDidChangeExclude.fire({ + originalPattern: item.pattern, + pattern: patternInput.value, + sibling: siblingInput && siblingInput.value + }); + } else { + this.update(); + } + }; + const onKeydown = (e: StandardKeyboardEvent) => { if (e.equals(KeyCode.Enter)) { - this._onDidChangeExclude.fire({ - originalPattern: undefined, - pattern: patternInput.value - }); + onSubmit(true); } }; @@ -279,31 +269,41 @@ export class ExcludeSettingWidget extends Disposable { inputBorder: settingsTextInputBorder })); this.listDisposables.push(patternInput); + patternInput.value = item.pattern; this.listDisposables.push(DOM.addStandardDisposableListener(patternInput.inputElement, DOM.EventType.KEY_DOWN, onKeydown)); - const siblingInput = new InputBox(rowElement, this.contextViewService, { - placeholder: localize('excludeSiblingInputPlaceholder', "When Pattern Is Present...") - }); - siblingInput.element.classList.add('setting-exclude-siblingInput'); - this.listDisposables.push(siblingInput); - this.listDisposables.push(attachInputBoxStyler(siblingInput, this.themeService, { - inputBackground: settingsTextInputBackground, - inputForeground: settingsTextInputForeground, - inputBorder: settingsTextInputBorder - })); - this.listDisposables.push(DOM.addStandardDisposableListener(siblingInput.inputElement, DOM.EventType.KEY_DOWN, onKeydown)); + let siblingInput: InputBox; + if (item.sibling) { + siblingInput = new InputBox(rowElement, this.contextViewService, { + placeholder: localize('excludeSiblingInputPlaceholder', "When Pattern Is Present...") + }); + siblingInput.element.classList.add('setting-exclude-siblingInput'); + this.listDisposables.push(siblingInput); + this.listDisposables.push(attachInputBoxStyler(siblingInput, this.themeService, { + inputBackground: settingsTextInputBackground, + inputForeground: settingsTextInputForeground, + inputBorder: settingsTextInputBorder + })); + siblingInput.value = item.sibling; + this.listDisposables.push(DOM.addStandardDisposableListener(siblingInput.inputElement, DOM.EventType.KEY_DOWN, onKeydown)); + } - rowElement.classList.add('setting-exclude-newExcludeItem'); + const okButton = this._register(new Button(rowElement)); + okButton.label = localize('okButton', "OK"); + okButton.element.classList.add('setting-exclude-okButton'); + this.listDisposables.push(attachButtonStyler(okButton, this.themeService)); + this.listDisposables.push(okButton.onDidClick(() => onSubmit(true))); - rowElement.classList.remove('setting-exclude-newPattern'); - rowElement.classList.remove('setting-exclude-newPatternWithSibling'); - if (item.mode === AddItemMode.Pattern) { - rowElement.classList.add('setting-exclude-newPattern'); + const cancelButton = this._register(new Button(rowElement)); + cancelButton.label = localize('cancelButton', "Cancel"); + cancelButton.element.classList.add('setting-exclude-cancelButton'); + this.listDisposables.push(attachButtonStyler(cancelButton, this.themeService)); + this.listDisposables.push(cancelButton.onDidClick(() => onSubmit(false))); + + setTimeout(() => { patternInput.focus(); patternInput.select(); - } else if (item.mode === AddItemMode.PatternWithSibling) { - rowElement.classList.add('setting-exclude-newPatternWithSibling'); - } + }, 0); return rowElement; } @@ -314,35 +314,11 @@ export class ExcludeSettingWidget extends Disposable { } } -interface IExcludeDataItem { - id: string; +export interface IExcludeDataItem { pattern: string; sibling?: string; } -interface INewExcludeItem { - id: string; - mode: AddItemMode; +interface IExcludeViewItem extends IExcludeDataItem { + editing?: boolean; } - -type IExcludeItem = IExcludeDataItem | INewExcludeItem; - -function isExcludeDataItem(excludeItem: IExcludeItem): excludeItem is IExcludeDataItem { - return !!(excludeItem).pattern; -} - -// class EditExcludeItemAction extends Action { - -// static readonly ID = 'workbench.action.editExcludeItem'; -// static readonly LABEL = localize('editExcludeItem', "Edit Exclude Item"); - -// constructor() { -// super(EditExcludeItemAction.ID, EditExcludeItemAction.LABEL); - -// this.class = 'setting-excludeAction-edit'; -// } - -// run(item: IExcludeItem): TPromise { -// return TPromise.wrap(true); -// } -// } From f8870d79d62d38b8587ff10ef226735891287815 Mon Sep 17 00:00:00 2001 From: Matt Bierner Date: Tue, 24 Jul 2018 15:17:14 -0700 Subject: [PATCH 0117/1276] Formatting and extration --- src/vs/workbench/api/node/extHost.api.impl.ts | 2 +- src/vs/workbench/api/node/extHostWebview.ts | 28 +++++++++++-------- 2 files changed, 18 insertions(+), 12 deletions(-) diff --git a/src/vs/workbench/api/node/extHost.api.impl.ts b/src/vs/workbench/api/node/extHost.api.impl.ts index 4ca5751ecef..7f33441ca83 100644 --- a/src/vs/workbench/api/node/extHost.api.impl.ts +++ b/src/vs/workbench/api/node/extHost.api.impl.ts @@ -425,7 +425,7 @@ export function createApiFactory( return extHostOutputService.createOutputChannel(name); }, createWebviewPanel(viewType: string, title: string, showOptions: vscode.ViewColumn | { viewColumn: vscode.ViewColumn, preserveFocus?: boolean }, options: vscode.WebviewPanelOptions & vscode.WebviewOptions): vscode.WebviewPanel { - return extHostWebviews.createWebview(viewType, title, showOptions, options, extension.extensionLocation); + return extHostWebviews.createWebview(extension.extensionLocation, viewType, title, showOptions, options); }, createTerminal(nameOrOptions: vscode.TerminalOptions | string, shellPath?: string, shellArgs?: string[]): vscode.Terminal { if (typeof nameOrOptions === 'object') { diff --git a/src/vs/workbench/api/node/extHostWebview.ts b/src/vs/workbench/api/node/extHostWebview.ts index 78fb98240ea..54a4f910bb3 100644 --- a/src/vs/workbench/api/node/extHostWebview.ts +++ b/src/vs/workbench/api/node/extHostWebview.ts @@ -12,7 +12,6 @@ import * as vscode from 'vscode'; import { ExtHostWebviewsShape, IMainContext, MainContext, MainThreadWebviewsShape, WebviewPanelHandle, WebviewPanelViewState } from './extHost.protocol'; import { Disposable } from './extHostTypes'; - type IconPath = URI | { light: URI, dark: URI }; export class ExtHostWebview implements vscode.Webview { @@ -224,8 +223,11 @@ export class ExtHostWebviewPanel implements vscode.WebviewPanel { export class ExtHostWebviews implements ExtHostWebviewsShape { private static webviewHandlePool = 1; - private readonly _proxy: MainThreadWebviewsShape; + private static newHandle(): WebviewPanelHandle { + return ExtHostWebviews.webviewHandlePool++ + ''; + } + private readonly _proxy: MainThreadWebviewsShape; private readonly _webviewPanels = new Map(); private readonly _serializers = new Map(); @@ -235,22 +237,20 @@ export class ExtHostWebviews implements ExtHostWebviewsShape { this._proxy = mainContext.getProxy(MainContext.MainThreadWebviews); } - createWebview( + public createWebview( + extensionLocation: URI, viewType: string, title: string, showOptions: vscode.ViewColumn | { viewColumn: vscode.ViewColumn, preserveFocus?: boolean }, - options: (vscode.WebviewPanelOptions & vscode.WebviewOptions) | undefined, - extensionLocation: URI + options: (vscode.WebviewPanelOptions & vscode.WebviewOptions) = {}, ): vscode.WebviewPanel { - options = options || {}; - const viewColumn = typeof showOptions === 'object' ? showOptions.viewColumn : showOptions; const webviewShowOptions = { viewColumn: typeConverters.ViewColumn.from(viewColumn), preserveFocus: typeof showOptions === 'object' && !!showOptions.preserveFocus }; - const handle = ExtHostWebviews.webviewHandlePool++ + ''; + const handle = ExtHostWebviews.newHandle(); this._proxy.$createWebviewPanel(handle, viewType, title, webviewShowOptions, options, extensionLocation); const webview = new ExtHostWebview(handle, this._proxy, options); @@ -259,7 +259,7 @@ export class ExtHostWebviews implements ExtHostWebviewsShape { return panel; } - registerWebviewPanelSerializer( + public registerWebviewPanelSerializer( viewType: string, serializer: vscode.WebviewPanelSerializer ): vscode.Disposable { @@ -276,14 +276,20 @@ export class ExtHostWebviews implements ExtHostWebviewsShape { }); } - $onMessage(handle: WebviewPanelHandle, message: any): void { + public $onMessage( + handle: WebviewPanelHandle, + message: any + ): void { const panel = this.getWebviewPanel(handle); if (panel) { panel.webview._onMessageEmitter.fire(message); } } - $onDidChangeWebviewPanelViewState(handle: WebviewPanelHandle, newState: WebviewPanelViewState): void { + public $onDidChangeWebviewPanelViewState( + handle: WebviewPanelHandle, + newState: WebviewPanelViewState + ): void { const panel = this.getWebviewPanel(handle); if (panel) { const viewColumn = typeConverters.ViewColumn.to(newState.position); From b297efad4022cf0d5a3bbd88698b2ef65c7037a0 Mon Sep 17 00:00:00 2001 From: Matt Bierner Date: Tue, 24 Jul 2018 15:55:03 -0700 Subject: [PATCH 0118/1276] Extract interface --- .../api/electron-browser/mainThreadWebview.ts | 8 +++---- src/vs/workbench/api/node/extHost.protocol.ts | 9 ++++++-- src/vs/workbench/api/node/extHostWebview.ts | 7 +++--- .../electron-browser/webviewFindWidget.ts | 22 +++++++++---------- 4 files changed, 26 insertions(+), 20 deletions(-) diff --git a/src/vs/workbench/api/electron-browser/mainThreadWebview.ts b/src/vs/workbench/api/electron-browser/mainThreadWebview.ts index 9e36bedbf59..8d3058803ca 100644 --- a/src/vs/workbench/api/electron-browser/mainThreadWebview.ts +++ b/src/vs/workbench/api/electron-browser/mainThreadWebview.ts @@ -10,7 +10,7 @@ import { TPromise } from 'vs/base/common/winjs.base'; import { localize } from 'vs/nls'; import { ILifecycleService } from 'vs/platform/lifecycle/common/lifecycle'; import { IOpenerService } from 'vs/platform/opener/common/opener'; -import { ExtHostContext, ExtHostWebviewsShape, IExtHostContext, MainContext, MainThreadWebviewsShape, WebviewPanelHandle } from 'vs/workbench/api/node/extHost.protocol'; +import { ExtHostContext, ExtHostWebviewsShape, IExtHostContext, MainContext, MainThreadWebviewsShape, WebviewPanelHandle, WebviewPanelShowOptions } from 'vs/workbench/api/node/extHost.protocol'; import { editorGroupToViewColumn, EditorViewColumn, viewColumnToEditorGroup } from 'vs/workbench/api/shared/editor'; import { WebviewEditor } from 'vs/workbench/parts/webview/electron-browser/webviewEditor'; import { WebviewEditorInput } from 'vs/workbench/parts/webview/electron-browser/webviewEditorInput'; @@ -145,15 +145,15 @@ export class MainThreadWebviews implements MainThreadWebviewsShape, WebviewReviv webview.setOptions(reviveWebviewOptions(options)); } - public $reveal(handle: WebviewPanelHandle, viewColumn: EditorViewColumn | null, preserveFocus: boolean): void { + public $reveal(handle: WebviewPanelHandle, showOptions: WebviewPanelShowOptions): void { const webview = this.getWebview(handle); if (webview.isDisposed()) { return; } - const targetGroup = this._editorGroupService.getGroup(viewColumnToEditorGroup(this._editorGroupService, viewColumn)); + const targetGroup = this._editorGroupService.getGroup(viewColumnToEditorGroup(this._editorGroupService, showOptions.viewColumn)); - this._webviewService.revealWebview(webview, targetGroup || this._editorGroupService.activeGroup, preserveFocus); + this._webviewService.revealWebview(webview, targetGroup || this._editorGroupService.activeGroup, showOptions.preserveFocus); } public $postMessage(handle: WebviewPanelHandle, message: any): TPromise { diff --git a/src/vs/workbench/api/node/extHost.protocol.ts b/src/vs/workbench/api/node/extHost.protocol.ts index dcccdfd0bf9..11e0707a346 100644 --- a/src/vs/workbench/api/node/extHost.protocol.ts +++ b/src/vs/workbench/api/node/extHost.protocol.ts @@ -425,10 +425,15 @@ export interface MainThreadTelemetryShape extends IDisposable { export type WebviewPanelHandle = string; +export interface WebviewPanelShowOptions { + readonly viewColumn?: EditorViewColumn; + readonly preserveFocus?: boolean; +} + export interface MainThreadWebviewsShape extends IDisposable { - $createWebviewPanel(handle: WebviewPanelHandle, viewType: string, title: string, viewOptions: { viewColumn: EditorViewColumn, preserveFocus: boolean }, options: vscode.WebviewPanelOptions & vscode.WebviewOptions, extensionLocation: UriComponents): void; + $createWebviewPanel(handle: WebviewPanelHandle, viewType: string, title: string, showOptions: WebviewPanelShowOptions, options: vscode.WebviewPanelOptions & vscode.WebviewOptions, extensionLocation: UriComponents): void; $disposeWebview(handle: WebviewPanelHandle): void; - $reveal(handle: WebviewPanelHandle, viewColumn: EditorViewColumn | null, preserveFocus: boolean): void; + $reveal(handle: WebviewPanelHandle, showOptions: WebviewPanelShowOptions): void; $setTitle(handle: WebviewPanelHandle, value: string): void; $setIconPath(handle: WebviewPanelHandle, value: { light: UriComponents, dark: UriComponents } | undefined): void; $setHtml(handle: WebviewPanelHandle, value: string): void; diff --git a/src/vs/workbench/api/node/extHostWebview.ts b/src/vs/workbench/api/node/extHostWebview.ts index 54a4f910bb3..89302f77670 100644 --- a/src/vs/workbench/api/node/extHostWebview.ts +++ b/src/vs/workbench/api/node/extHostWebview.ts @@ -208,9 +208,10 @@ export class ExtHostWebviewPanel implements vscode.WebviewPanel { public reveal(viewColumn?: vscode.ViewColumn, preserveFocus?: boolean): void { this.assertNotDisposed(); - this._proxy.$reveal(this._handle, - viewColumn ? typeConverters.ViewColumn.from(viewColumn) : undefined, - !!preserveFocus); + this._proxy.$reveal(this._handle, { + viewColumn: viewColumn ? typeConverters.ViewColumn.from(viewColumn) : undefined, + preserveFocus: !!preserveFocus + }); } private assertNotDisposed() { diff --git a/src/vs/workbench/parts/webview/electron-browser/webviewFindWidget.ts b/src/vs/workbench/parts/webview/electron-browser/webviewFindWidget.ts index 3529b7b8a10..4b0a2c6bbaa 100644 --- a/src/vs/workbench/parts/webview/electron-browser/webviewFindWidget.ts +++ b/src/vs/workbench/parts/webview/electron-browser/webviewFindWidget.ts @@ -11,7 +11,7 @@ import { IContextKeyService } from 'vs/platform/contextkey/common/contextkey'; export class WebviewFindWidget extends SimpleFindWidget { constructor( - private webview: WebviewElement, + private _webview: WebviewElement, @IContextViewService contextViewService: IContextViewService, @IContextKeyService contextKeyService: IContextKeyService ) { @@ -19,45 +19,45 @@ export class WebviewFindWidget extends SimpleFindWidget { } dispose() { - this.webview = undefined; + this._webview = undefined; super.dispose(); } public find(previous: boolean) { const val = this.inputValue; if (val) { - this.webview.find(val, { findNext: true, forward: !previous }); + this._webview.find(val, { findNext: true, forward: !previous }); } } public hide() { super.hide(); - this.webview.stopFind(true); - this.webview.focus(); + this._webview.stopFind(true); + this._webview.focus(); } public onInputChanged() { const val = this.inputValue; if (val) { - this.webview.startFind(val); + this._webview.startFind(val); } else { - this.webview.stopFind(false); + this._webview.stopFind(false); } } protected onFocusTrackerFocus() { - this.webview.notifyFindWidgetFocusChanged(true); + this._webview.notifyFindWidgetFocusChanged(true); } protected onFocusTrackerBlur() { - this.webview.notifyFindWidgetFocusChanged(false); + this._webview.notifyFindWidgetFocusChanged(false); } protected onFindInputFocusTrackerFocus() { - this.webview.notifyFindWidgetInputFocusChanged(true); + this._webview.notifyFindWidgetInputFocusChanged(true); } protected onFindInputFocusTrackerBlur() { - this.webview.notifyFindWidgetInputFocusChanged(false); + this._webview.notifyFindWidgetInputFocusChanged(false); } } \ No newline at end of file From bef7861415e71037b9ae8e3406bf545c6527b232 Mon Sep 17 00:00:00 2001 From: Matt Bierner Date: Tue, 24 Jul 2018 15:55:24 -0700 Subject: [PATCH 0119/1276] Extract webview protocol logic to own file --- .../electron-browser/webviewElement.ts | 54 ++---------------- .../electron-browser/webviewProtocols.ts | 56 +++++++++++++++++++ 2 files changed, 60 insertions(+), 50 deletions(-) create mode 100644 src/vs/workbench/parts/webview/electron-browser/webviewProtocols.ts diff --git a/src/vs/workbench/parts/webview/electron-browser/webviewElement.ts b/src/vs/workbench/parts/webview/electron-browser/webviewElement.ts index 330e72730c4..a82c36d8793 100644 --- a/src/vs/workbench/parts/webview/electron-browser/webviewElement.ts +++ b/src/vs/workbench/parts/webview/electron-browser/webviewElement.ts @@ -6,9 +6,6 @@ import { addClass, addDisposableListener } from 'vs/base/browser/dom'; import { Emitter } from 'vs/base/common/event'; import { Disposable } from 'vs/base/common/lifecycle'; -import { getMediaMime, guessMimeTypes } from 'vs/base/common/mime'; -import { extname, nativeSep } from 'vs/base/common/paths'; -import { startsWith } from 'vs/base/common/strings'; import URI from 'vs/base/common/uri'; import { IContextKey } from 'vs/platform/contextkey/common/contextkey'; import { IEnvironmentService } from 'vs/platform/environment/common/environment'; @@ -16,8 +13,9 @@ import { IFileService } from 'vs/platform/files/common/files'; import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; import * as colorRegistry from 'vs/platform/theme/common/colorRegistry'; import { DARK, ITheme, IThemeService, LIGHT } from 'vs/platform/theme/common/themeService'; -import { WebviewFindWidget } from './webviewFindWidget'; +import { registerFileProtocol, WebviewProtocol } from 'vs/workbench/parts/webview/electron-browser/webviewProtocols'; import { areWebviewInputOptionsEqual } from './webviewEditorService'; +import { WebviewFindWidget } from './webviewFindWidget'; export interface WebviewOptions { readonly allowScripts?: boolean; @@ -28,9 +26,6 @@ export interface WebviewOptions { readonly localResourceRoots?: ReadonlyArray; } -const CORE_RESOURCE_PROTOCOL = 'vscode-core-resource'; -const VSCODE_RESOURCE_PROTOCOL = 'vscode-resource'; - export class WebviewElement extends Disposable { private _webview: Electron.WebviewTag; private _ready: Promise; @@ -376,11 +371,11 @@ export class WebviewElement extends Disposable { const appRootUri = URI.file(this._environmentService.appRoot); - registerFileProtocol(contents, CORE_RESOURCE_PROTOCOL, this._fileService, () => [ + registerFileProtocol(contents, WebviewProtocol.CoreResource, this._fileService, () => [ appRootUri ]); - registerFileProtocol(contents, VSCODE_RESOURCE_PROTOCOL, this._fileService, () => + registerFileProtocol(contents, WebviewProtocol.VsCodeResource, this._fileService, () => (this._options.localResourceRoots || []) ); } @@ -467,44 +462,3 @@ namespace ApiThemeClassName { } } } - -function registerFileProtocol( - contents: Electron.WebContents, - protocol: string, - fileService: IFileService, - getRoots: () => ReadonlyArray -) { - contents.session.protocol.registerBufferProtocol(protocol, (request, callback: any) => { - const requestPath = URI.parse(request.url).path; - const normalizedPath = URI.file(requestPath); - for (const root of getRoots()) { - if (startsWith(normalizedPath.fsPath, root.fsPath + nativeSep)) { - fileService.resolveContent(normalizedPath, { encoding: 'binary' }).then(contents => { - const mime = getMimeType(normalizedPath); - callback({ - data: Buffer.from(contents.value, contents.encoding), - mimeType: mime - }); - }, () => { - callback({ error: -2 /* FAILED: https://cs.chromium.org/chromium/src/net/base/net_error_list.h */ }); - }); - return; - } - } - console.error('Webview: Cannot load resource outside of protocol root'); - callback({ error: -10 /* ACCESS_DENIED: https://cs.chromium.org/chromium/src/net/base/net_error_list.h */ }); - }, (error) => { - if (error) { - console.error('Failed to register protocol ' + protocol); - } - }); -} - -const webviewMimeTypes = { - '.svg': 'image/svg+xml' -}; - -function getMimeType(normalizedPath: URI) { - const ext = extname(normalizedPath.fsPath).toLowerCase(); - return webviewMimeTypes[ext] || getMediaMime(normalizedPath.fsPath) || guessMimeTypes(normalizedPath.fsPath)[0]; -} diff --git a/src/vs/workbench/parts/webview/electron-browser/webviewProtocols.ts b/src/vs/workbench/parts/webview/electron-browser/webviewProtocols.ts new file mode 100644 index 00000000000..0fa492620f8 --- /dev/null +++ b/src/vs/workbench/parts/webview/electron-browser/webviewProtocols.ts @@ -0,0 +1,56 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ +import { extname } from 'path'; +import { getMediaMime, guessMimeTypes } from 'vs/base/common/mime'; +import { nativeSep } from 'vs/base/common/paths'; +import { startsWith } from 'vs/base/common/strings'; +import URI from 'vs/base/common/uri'; +import { IFileService } from 'vs/platform/files/common/files'; + +export enum WebviewProtocol { + CoreResource = 'vscode-core-resource', + VsCodeResource = 'vscode-resource' +} + +export function registerFileProtocol( + contents: Electron.WebContents, + protocol: WebviewProtocol, + fileService: IFileService, + getRoots: () => ReadonlyArray +) { + contents.session.protocol.registerBufferProtocol(protocol, (request, callback: any) => { + const requestPath = URI.parse(request.url).path; + const normalizedPath = URI.file(requestPath); + for (const root of getRoots()) { + if (startsWith(normalizedPath.fsPath, root.fsPath + nativeSep)) { + fileService.resolveContent(normalizedPath, { encoding: 'binary' }).then(contents => { + const mime = getMimeType(normalizedPath); + callback({ + data: Buffer.from(contents.value, contents.encoding), + mimeType: mime + }); + }, () => { + callback({ error: -2 /* FAILED: https://cs.chromium.org/chromium/src/net/base/net_error_list.h */ }); + }); + return; + } + } + console.error('Webview: Cannot load resource outside of protocol root'); + callback({ error: -10 /* ACCESS_DENIED: https://cs.chromium.org/chromium/src/net/base/net_error_list.h */ }); + }, (error) => { + if (error) { + console.error('Failed to register protocol ' + protocol); + } + }); +} + +const webviewMimeTypes = { + '.svg': 'image/svg+xml' +}; + +function getMimeType(normalizedPath: URI) { + const ext = extname(normalizedPath.fsPath).toLowerCase(); + return webviewMimeTypes[ext] || getMediaMime(normalizedPath.fsPath) || guessMimeTypes(normalizedPath.fsPath)[0]; +} From 3ba2cf8716f15b279a2430e8e2e1ef596fa6a1ce Mon Sep 17 00:00:00 2001 From: Matt Bierner Date: Tue, 24 Jul 2018 16:58:29 -0700 Subject: [PATCH 0120/1276] Remove extension folder path Any webviews serialized in the past three months should now be using extensionLocation instead --- .../electron-browser/webviewEditorInputFactory.ts | 15 ++------------- 1 file changed, 2 insertions(+), 13 deletions(-) diff --git a/src/vs/workbench/parts/webview/electron-browser/webviewEditorInputFactory.ts b/src/vs/workbench/parts/webview/electron-browser/webviewEditorInputFactory.ts index 094c71d62a2..0bb8b9fbd71 100644 --- a/src/vs/workbench/parts/webview/electron-browser/webviewEditorInputFactory.ts +++ b/src/vs/workbench/parts/webview/electron-browser/webviewEditorInputFactory.ts @@ -13,10 +13,6 @@ interface SerializedWebview { readonly viewType: string; readonly title: string; readonly options: WebviewInputOptions; - /** - * compatibility with previous versions - */ - readonly extensionFolderPath?: string; readonly extensionLocation: string; readonly state: any; } @@ -53,18 +49,11 @@ export class WebviewEditorInputFactory implements IEditorInputFactory { } public deserialize( - instantiationService: IInstantiationService, + _instantiationService: IInstantiationService, serializedEditorInput: string ): WebviewEditorInput { const data: SerializedWebview = JSON.parse(serializedEditorInput); - let extensionLocation: URI; - if (typeof data.extensionLocation === 'string') { - extensionLocation = URI.parse(data.extensionLocation); - } - if (typeof data.extensionFolderPath === 'string') { - // compatibility with previous versions - extensionLocation = URI.file(data.extensionFolderPath); - } + const extensionLocation = URI.parse(data.extensionLocation); return this._webviewService.reviveWebview(data.viewType, data.title, data.state, data.options, extensionLocation); } } From 5bf1439036479064972f770c8ea7b7c57821205c Mon Sep 17 00:00:00 2001 From: Rob Lourens Date: Wed, 25 Jul 2018 12:00:07 -0700 Subject: [PATCH 0121/1276] Settings exclude control - enable for search.exclude --- src/vs/workbench/parts/preferences/browser/settingsTree.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/vs/workbench/parts/preferences/browser/settingsTree.ts b/src/vs/workbench/parts/preferences/browser/settingsTree.ts index 7e9536be013..5e97b6c4987 100644 --- a/src/vs/workbench/parts/preferences/browser/settingsTree.ts +++ b/src/vs/workbench/parts/preferences/browser/settingsTree.ts @@ -480,7 +480,8 @@ interface ISettingExcludeItemTemplate extends ISettingItemTemplate { } function isExcludeSetting(setting: ISetting): boolean { - return setting.key === 'files.exclude'; + return setting.key === 'files.exclude' || + setting.key === 'search.exclude'; } interface IGroupTitleTemplate extends IDisposableTemplate { From e95f36dca83350fe19e9049e432bf5285b48db7c Mon Sep 17 00:00:00 2001 From: Rob Lourens Date: Wed, 25 Jul 2018 14:04:24 -0700 Subject: [PATCH 0122/1276] Settings editor - remove 'img' and 'a' tags from description markdown --- .../parts/preferences/browser/settingsTree.ts | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/src/vs/workbench/parts/preferences/browser/settingsTree.ts b/src/vs/workbench/parts/preferences/browser/settingsTree.ts index 5e97b6c4987..7025d43a330 100644 --- a/src/vs/workbench/parts/preferences/browser/settingsTree.ts +++ b/src/vs/workbench/parts/preferences/browser/settingsTree.ts @@ -962,6 +962,7 @@ export class SettingsRenderer implements ITreeRenderer { disposeables: template.toDispose } }); + cleanRenderedMarkdown(renderedDescription); renderedDescription.classList.add('setting-item-description-markdown'); template.descriptionElement.innerHTML = ''; template.descriptionElement.appendChild(renderedDescription); @@ -1025,7 +1026,6 @@ export class SettingsRenderer implements ITreeRenderer { if (template.controlElement.firstElementChild) { template.controlElement.firstElementChild.setAttribute('tabindex', isSelected ? '0' : '-1'); } - } private renderText(dataElement: SettingsTreeSettingElement, isSelected: boolean, template: ISettingTextItemTemplate, onChange: (value: string) => void): void { @@ -1061,6 +1061,17 @@ export class SettingsRenderer implements ITreeRenderer { } } +function cleanRenderedMarkdown(element: Node): void { + element.childNodes.forEach(child => { + const tagName = (child).tagName && (child).tagName.toLowerCase(); + if (tagName === 'img' || tagName === 'a') { + element.removeChild(child); + } else { + cleanRenderedMarkdown(child); + } + }); +} + function getDisplayEnumOptions(setting: ISetting): string[] { if (setting.enum.length > SettingsRenderer.MAX_ENUM_DESCRIPTIONS && setting.enumDescriptions) { return setting.enum From 31eba9652dc6b31f3881b6a9ebb0eac5a850e5db Mon Sep 17 00:00:00 2001 From: Rob Lourens Date: Wed, 25 Jul 2018 14:40:13 -0700 Subject: [PATCH 0123/1276] Sweep setting descriptions for #54690 --- .../css-language-features/package.nls.json | 6 +++--- .../typescript-language-features/package.json | 6 ++++++ .../package.nls.json | 6 +++++- .../editor/common/config/commonEditorConfig.ts | 17 +++++++++++------ .../electron-browser/main.contribution.ts | 8 ++++---- .../electron-browser/extensions.contribution.ts | 2 +- .../electron-browser/files.contribution.ts | 2 +- .../electron-browser/search.contribution.ts | 6 +++--- 8 files changed, 34 insertions(+), 19 deletions(-) diff --git a/extensions/css-language-features/package.nls.json b/extensions/css-language-features/package.nls.json index b4078e7f5cd..ca6e4df4c2c 100644 --- a/extensions/css-language-features/package.nls.json +++ b/extensions/css-language-features/package.nls.json @@ -8,7 +8,7 @@ "css.lint.duplicateProperties.desc": "Do not use duplicate style definitions", "css.lint.emptyRules.desc": "Do not use empty rulesets", "css.lint.float.desc": "Avoid using 'float'. Floats lead to fragile CSS that is easy to break if one aspect of the layout changes.", - "css.lint.fontFaceProperties.desc": "@font-face rule must define 'src' and 'font-family' properties", + "css.lint.fontFaceProperties.desc": "`@font-face` rule must define `src` and `font-family` properties", "css.lint.hexColorLength.desc": "Hex colors must consist of three or six hex numbers", "css.lint.idSelector.desc": "Selectors should not contain IDs because these rules are too tightly coupled with the HTML.", "css.lint.ieHack.desc": "IE hacks are only necessary when supporting IE7 and older", @@ -31,7 +31,7 @@ "less.lint.duplicateProperties.desc": "Do not use duplicate style definitions", "less.lint.emptyRules.desc": "Do not use empty rulesets", "less.lint.float.desc": "Avoid using 'float'. Floats lead to fragile CSS that is easy to break if one aspect of the layout changes.", - "less.lint.fontFaceProperties.desc": "@font-face rule must define 'src' and 'font-family' properties", + "less.lint.fontFaceProperties.desc": "`@font-face` rule must define `src` and `font-family` properties", "less.lint.hexColorLength.desc": "Hex colors must consist of three or six hex numbers", "less.lint.idSelector.desc": "Selectors should not contain IDs because these rules are too tightly coupled with the HTML.", "less.lint.ieHack.desc": "IE hacks are only necessary when supporting IE7 and older", @@ -52,7 +52,7 @@ "scss.lint.duplicateProperties.desc": "Do not use duplicate style definitions", "scss.lint.emptyRules.desc": "Do not use empty rulesets", "scss.lint.float.desc": "Avoid using 'float'. Floats lead to fragile CSS that is easy to break if one aspect of the layout changes.", - "scss.lint.fontFaceProperties.desc": "@font-face rule must define 'src' and 'font-family' properties", + "scss.lint.fontFaceProperties.desc": "`@font-face` rule must define `src` and `font-family` properties", "scss.lint.hexColorLength.desc": "Hex colors must consist of three or six hex numbers", "scss.lint.idSelector.desc": "Selectors should not contain IDs because these rules are too tightly coupled with the HTML.", "scss.lint.ieHack.desc": "IE hacks are only necessary when supporting IE7 and older", diff --git a/extensions/typescript-language-features/package.json b/extensions/typescript-language-features/package.json index 3692fc231fa..78377f20166 100644 --- a/extensions/typescript-language-features/package.json +++ b/extensions/typescript-language-features/package.json @@ -384,6 +384,12 @@ "build", "watch" ], + "enumDescriptions": [ + "%typescript.tsc.autoDetect.on%", + "%typescript.tsc.autoDetect.off%", + "%typescript.tsc.autoDetect.build%", + "%typescript.tsc.autoDetect.watch%" + ], "description": "%typescript.tsc.autoDetect%", "scope": "window" }, diff --git a/extensions/typescript-language-features/package.nls.json b/extensions/typescript-language-features/package.nls.json index 737a4fe5e21..26b3c6e0bdf 100644 --- a/extensions/typescript-language-features/package.nls.json +++ b/extensions/typescript-language-features/package.nls.json @@ -42,7 +42,11 @@ "typescript.npm": "Specifies the path to the NPM executable used for Automatic Type Acquisition. Requires using TypeScript 2.3.4 or newer in the workspace.", "typescript.check.npmIsInstalled": "Check if NPM is installed for Automatic Type Acquisition.", "javascript.nameSuggestions": "Enable/disable including unique names from the file in JavaScript suggestion lists.", - "typescript.tsc.autoDetect": "Controls auto detection of tsc tasks. 'off' disables this feature. 'build' only creates single run compile tasks. 'watch' only creates compile and watch tasks. 'on' creates both build and watch tasks. Default is 'on'.", + "typescript.tsc.autoDetect": "Controls auto detection of tsc tasks.", + "typescript.tsc.autoDetect.off": "Disable this feature.", + "typescript.tsc.autoDetect.on": "Create both build and watch tasks.", + "typescript.tsc.autoDetect.build": "Only create single run compile tasks.", + "typescript.tsc.autoDetect.watch": "Only create compile and watch tasks.", "typescript.problemMatchers.tsc.label": "TypeScript problems", "typescript.problemMatchers.tscWatch.label": "TypeScript problems (watch mode)", "typescript.quickSuggestionsForPaths": "Enable/disable quick suggestions when typing out an import path.", diff --git a/src/vs/editor/common/config/commonEditorConfig.ts b/src/vs/editor/common/config/commonEditorConfig.ts index adaf242cb6f..3524620da5a 100644 --- a/src/vs/editor/common/config/commonEditorConfig.ts +++ b/src/vs/editor/common/config/commonEditorConfig.ts @@ -288,7 +288,7 @@ const editorConfiguration: IConfigurationNode = { 'editor.insertSpaces': { 'type': 'boolean', 'default': EDITOR_MODEL_DEFAULTS.insertSpaces, - 'description': nls.localize('insertSpaces', "Insert spaces when pressing Tab. This setting is overridden based on the file contents when `#editor.detectIndentation#` is on."), + 'description': nls.localize('insertSpaces', "Insert spaces when pressing `Tab`. This setting is overridden based on the file contents when `#editor.detectIndentation#` is on."), 'errorMessage': nls.localize('insertSpaces.errorMessage', "Expected 'boolean'. Note that the value \"auto\" has been replaced by the `editor.detectIndentation` setting.") }, 'editor.detectIndentation': { @@ -314,7 +314,7 @@ const editorConfiguration: IConfigurationNode = { 'editor.smoothScrolling': { 'type': 'boolean', 'default': EDITOR_DEFAULTS.viewInfo.smoothScrolling, - 'description': nls.localize('smoothScrolling', "Controls if the editor will scroll using an animation") + 'description': nls.localize('smoothScrolling', "Controls whether the editor will scroll using an animation.") }, 'editor.minimap.enabled': { 'type': 'boolean', @@ -522,12 +522,17 @@ const editorConfiguration: IConfigurationNode = { 'type': 'string', 'enum': ['on', 'smart', 'off'], 'default': EDITOR_DEFAULTS.contribInfo.acceptSuggestionOnEnter, - 'description': nls.localize('acceptSuggestionOnEnter', "Controls if suggestions should be accepted on 'Enter' - in addition to 'Tab'. Helps to avoid ambiguity between inserting new lines or accepting suggestions. The value 'smart' means only accept a suggestion with Enter when it makes a textual change.") + 'enumDescriptions': [ + '', + nls.localize('acceptSuggestionOnEnterSmart', "Only accept a suggestion with `Enter` when it makes a textual change."), + '' + ], + 'description': nls.localize('acceptSuggestionOnEnter', "Controls whether suggestions should be accepted on `Enter`, in addition to `Tab`. Helps to avoid ambiguity between inserting new lines or accepting suggestions.") }, 'editor.acceptSuggestionOnCommitCharacter': { 'type': 'boolean', 'default': EDITOR_DEFAULTS.contribInfo.acceptSuggestionOnCommitCharacter, - 'description': nls.localize('acceptSuggestionOnCommitCharacter', "Controls if suggestions should be accepted on commit characters. For instance in JavaScript the semi-colon (';') can be a commit character that accepts a suggestion and types that character.") + 'description': nls.localize('acceptSuggestionOnCommitCharacter', "Controls whether suggestions should be accepted on commit characters. For example, in JavaScript, the semi-colon (`;`) can be a commit character that accepts a suggestion and types that character.") }, 'editor.snippetSuggestions': { 'type': 'string', @@ -717,7 +722,7 @@ const editorConfiguration: IConfigurationNode = { 'editor.stablePeek': { 'type': 'boolean', 'default': false, - 'description': nls.localize('stablePeek', "Keep peek editors open even when double clicking their content or when hitting Escape.") + 'description': nls.localize('stablePeek', "Keep peek editors open even when double clicking their content or when hitting `Escape`.") }, 'editor.dragAndDrop': { 'type': 'boolean', @@ -783,7 +788,7 @@ const editorConfiguration: IConfigurationNode = { 'diffEditor.renderSideBySide': { 'type': 'boolean', 'default': true, - 'description': nls.localize('sideBySide', "Controls if the diff editor shows the diff side by side or inline") + 'description': nls.localize('sideBySide', "Controls whether the diff editor shows the diff side by side or inline.") }, 'diffEditor.ignoreTrimWhitespace': { 'type': 'boolean', diff --git a/src/vs/workbench/electron-browser/main.contribution.ts b/src/vs/workbench/electron-browser/main.contribution.ts index 7ba001d48e0..6ef42882159 100644 --- a/src/vs/workbench/electron-browser/main.contribution.ts +++ b/src/vs/workbench/electron-browser/main.contribution.ts @@ -387,7 +387,7 @@ configurationRegistry.registerConfiguration({ }, 'workbench.editor.closeOnFileDelete': { 'type': 'boolean', - 'description': nls.localize('closeOnFileDelete', "Controls if editors showing a file should close automatically when the file is deleted or renamed by some other process. Disabling this will keep the editor open as dirty on such an event. Note that deleting from within the application will always close the editor and that dirty files will never close to preserve your data."), + 'description': nls.localize('closeOnFileDelete', "Controls whether editors showing a file should close automatically when the file is deleted or renamed by some other process. Disabling this will keep the editor open as dirty on such an event. Note that deleting from within the application will always close the editor and that dirty files will never close to preserve your data."), 'default': true }, 'workbench.editor.openPositioning': { @@ -680,12 +680,12 @@ configurationRegistry.registerConfiguration({ 'zenMode.hideTabs': { 'type': 'boolean', 'default': true, - 'description': nls.localize('zenMode.hideTabs', "Controls if turning on Zen Mode also hides workbench tabs.") + 'description': nls.localize('zenMode.hideTabs', "Controls whether turning on Zen Mode also hides workbench tabs.") }, 'zenMode.hideStatusBar': { 'type': 'boolean', 'default': true, - 'description': nls.localize('zenMode.hideStatusBar', "Controls if turning on Zen Mode also hides the status bar at the bottom of the workbench.") + 'description': nls.localize('zenMode.hideStatusBar', "Controls whether turning on Zen Mode also hides the status bar at the bottom of the workbench.") }, 'zenMode.hideActivityBar': { 'type': 'boolean', @@ -695,7 +695,7 @@ configurationRegistry.registerConfiguration({ 'zenMode.restore': { 'type': 'boolean', 'default': false, - 'description': nls.localize('zenMode.restore', "Controls if a window should restore to zen mode if it was exited in zen mode.") + 'description': nls.localize('zenMode.restore', "Controls whether a window should restore to zen mode if it was exited in zen mode.") } } }); diff --git a/src/vs/workbench/parts/extensions/electron-browser/extensions.contribution.ts b/src/vs/workbench/parts/extensions/electron-browser/extensions.contribution.ts index 38982094519..3e42ab38486 100644 --- a/src/vs/workbench/parts/extensions/electron-browser/extensions.contribution.ts +++ b/src/vs/workbench/parts/extensions/electron-browser/extensions.contribution.ts @@ -204,7 +204,7 @@ Registry.as(ConfigurationExtensions.Configuration) properties: { 'extensions.autoUpdate': { type: 'boolean', - description: localize('extensionsAutoUpdate', "Automatically update extensions"), + description: localize('extensionsAutoUpdate', "Automatically update extensions."), default: true, scope: ConfigurationScope.APPLICATION }, diff --git a/src/vs/workbench/parts/files/electron-browser/files.contribution.ts b/src/vs/workbench/parts/files/electron-browser/files.contribution.ts index c931f0ec43f..baba48bded2 100644 --- a/src/vs/workbench/parts/files/electron-browser/files.contribution.ts +++ b/src/vs/workbench/parts/files/electron-browser/files.contribution.ts @@ -361,7 +361,7 @@ configurationRegistry.registerConfiguration({ nls.localize('sortOrder.type', 'Files and folders are sorted by their extensions, in alphabetical order. Folders are displayed before files.'), nls.localize('sortOrder.modified', 'Files and folders are sorted by last modified date, in descending order. Folders are displayed before files.') ], - 'description': nls.localize({ key: 'sortOrder', comment: ['This is the description for a setting. Values surrounded by single quotes are not to be translated.'] }, "Controls sorting order of files and folders in the explorer. In addition to the default sorting, you can set the order to 'mixed' (files and folders sorted combined), 'type' (by file type), 'modified' (by last modified date) or 'filesFirst' (sort files before folders).") + 'description': nls.localize('sortOrder', "Controls sorting order of files and folders in the explorer.") }, 'explorer.decorations.colors': { type: 'boolean', diff --git a/src/vs/workbench/parts/search/electron-browser/search.contribution.ts b/src/vs/workbench/parts/search/electron-browser/search.contribution.ts index af07196b912..110f0fd1a58 100644 --- a/src/vs/workbench/parts/search/electron-browser/search.contribution.ts +++ b/src/vs/workbench/parts/search/electron-browser/search.contribution.ts @@ -596,7 +596,7 @@ configurationRegistry.registerConfiguration({ }, 'search.quickOpen.includeSymbols': { type: 'boolean', - description: nls.localize('search.quickOpen.includeSymbols', "Configure to include results from a global symbol search in the file results for Quick Open."), + description: nls.localize('search.quickOpen.includeSymbols', "Whether to include results from a global symbol search in the file results for Quick Open."), default: false }, 'search.followSymlinks': { @@ -606,7 +606,7 @@ configurationRegistry.registerConfiguration({ }, 'search.smartCase': { type: 'boolean', - description: nls.localize('search.smartCase', "Searches case-insensitively if the pattern is all lowercase, otherwise, searches case-sensitively"), + description: nls.localize('search.smartCase', "Search case-insensitively if the pattern is all lowercase, otherwise, search case-sensitively."), default: false }, 'search.globalFindClipboard': { @@ -619,7 +619,7 @@ configurationRegistry.registerConfiguration({ type: 'string', enum: ['sidebar', 'panel'], default: 'sidebar', - description: nls.localize('search.location', "Controls if the search will be shown as a view in the sidebar or as a panel in the panel area for more horizontal space."), + description: nls.localize('search.location', "Controls whether the search will be shown as a view in the sidebar or as a panel in the panel area for more horizontal space."), } } }); From 38e17053d04a37981defd3170c19857e9700ef11 Mon Sep 17 00:00:00 2001 From: Rob Lourens Date: Wed, 25 Jul 2018 14:45:40 -0700 Subject: [PATCH 0124/1276] Fix childNodes.forEach - DOM api not in .d.ts --- .../workbench/parts/preferences/browser/settingsTree.ts | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/vs/workbench/parts/preferences/browser/settingsTree.ts b/src/vs/workbench/parts/preferences/browser/settingsTree.ts index 7025d43a330..001d69bfccf 100644 --- a/src/vs/workbench/parts/preferences/browser/settingsTree.ts +++ b/src/vs/workbench/parts/preferences/browser/settingsTree.ts @@ -1062,14 +1062,16 @@ export class SettingsRenderer implements ITreeRenderer { } function cleanRenderedMarkdown(element: Node): void { - element.childNodes.forEach(child => { + for (let i = 0; i < element.childNodes.length; i++) { + const child = element.childNodes.item(i); + const tagName = (child).tagName && (child).tagName.toLowerCase(); - if (tagName === 'img' || tagName === 'a') { + if (tagName === 'img') { element.removeChild(child); } else { cleanRenderedMarkdown(child); } - }); + } } function getDisplayEnumOptions(setting: ISetting): string[] { From 8899e43fb2a3446ea57976f28fe596b567f5c673 Mon Sep 17 00:00:00 2001 From: Rob Lourens Date: Wed, 25 Jul 2018 15:02:41 -0700 Subject: [PATCH 0125/1276] Settings editor - fix search.exclude link --- .../parts/search/electron-browser/search.contribution.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vs/workbench/parts/search/electron-browser/search.contribution.ts b/src/vs/workbench/parts/search/electron-browser/search.contribution.ts index 110f0fd1a58..03f9e4057c9 100644 --- a/src/vs/workbench/parts/search/electron-browser/search.contribution.ts +++ b/src/vs/workbench/parts/search/electron-browser/search.contribution.ts @@ -560,7 +560,7 @@ configurationRegistry.registerConfiguration({ properties: { 'search.exclude': { type: 'object', - description: nls.localize('exclude', "Configure glob patterns for excluding files and folders in searches. Inherits all glob patterns from the [`files.exclude`](#files-exclude) setting. Read more about glob patterns [here](https://code.visualstudio.com/docs/editor/codebasics#_advanced-search-options)."), + description: nls.localize('exclude', "Configure glob patterns for excluding files and folders in searches. Inherits all glob patterns from the `#files.exclude#` setting. Read more about glob patterns [here](https://code.visualstudio.com/docs/editor/codebasics#_advanced-search-options)."), default: { '**/node_modules': true, '**/bower_components': true }, additionalProperties: { anyOf: [ From f3caf387db41a1fe762514259800a5cb58742c71 Mon Sep 17 00:00:00 2001 From: Matt Bierner Date: Wed, 25 Jul 2018 14:56:05 -0700 Subject: [PATCH 0126/1276] Also serialize and restore webview icons --- .../api/electron-browser/mainThreadWebview.ts | 40 +--------------- .../electron-browser/webviewEditorInput.ts | 46 ++++++++++++++++++- .../webviewEditorInputFactory.ts | 7 ++- .../electron-browser/webviewEditorService.ts | 4 +- 4 files changed, 54 insertions(+), 43 deletions(-) diff --git a/src/vs/workbench/api/electron-browser/mainThreadWebview.ts b/src/vs/workbench/api/electron-browser/mainThreadWebview.ts index 8d3058803ca..e671f1e86b3 100644 --- a/src/vs/workbench/api/electron-browser/mainThreadWebview.ts +++ b/src/vs/workbench/api/electron-browser/mainThreadWebview.ts @@ -2,7 +2,6 @@ * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -import * as dom from 'vs/base/browser/dom'; import { dispose, IDisposable } from 'vs/base/common/lifecycle'; import * as map from 'vs/base/common/map'; import URI, { UriComponents } from 'vs/base/common/uri'; @@ -30,39 +29,6 @@ export class MainThreadWebviews implements MainThreadWebviewsShape, WebviewReviv private static revivalPool = 0; - private static _styleElement?: HTMLStyleElement; - - private static _icons = new Map(); - - private static updateStyleElement( - webview: WebviewEditorInput, - iconPath: { light: URI, dark: URI } | undefined - ) { - const id = webview.getId(); - if (!this._styleElement) { - this._styleElement = dom.createStyleSheet(); - this._styleElement.className = 'webview-icons'; - } - - if (!iconPath) { - this._icons.delete(id); - } else { - this._icons.set(id, iconPath); - } - - const cssRules: string[] = []; - this._icons.forEach((value, key) => { - const webviewSelector = `.show-file-icons .webview-${key}-name-file-icon::before`; - if (URI.isUri(value)) { - cssRules.push(`${webviewSelector} { content: ""; background-image: url(${value.toString()}); }`); - } else { - cssRules.push(`${webviewSelector} { content: ""; background-image: url(${value.light.toString()}); }`); - cssRules.push(`.vs-dark ${webviewSelector} { content: ""; background-image: url(${value.dark.toString()}); }`); - } - }); - this._styleElement.innerHTML = cssRules.join('\n'); - } - private _toDispose: IDisposable[] = []; private readonly _proxy: ExtHostWebviewsShape; @@ -132,7 +98,7 @@ export class MainThreadWebviews implements MainThreadWebviewsShape, WebviewReviv public $setIconPath(handle: WebviewPanelHandle, value: { light: UriComponents, dark: UriComponents } | undefined): void { const webview = this.getWebview(handle); - MainThreadWebviews.updateStyleElement(webview, reviveWebviewIcon(value)); + webview.iconPath = reviveWebviewIcon(value); } public $setHtml(handle: WebviewPanelHandle, value: string): void { @@ -225,10 +191,6 @@ export class MainThreadWebviews implements MainThreadWebviewsShape, WebviewReviv onMessage: message => this._proxy.$onMessage(handle, message), onDispose: () => { const cleanUp = () => { - const webview = this._webviews.get(handle); - if (webview) { - MainThreadWebviews.updateStyleElement(webview, undefined); - } this._webviews.delete(handle); }; this._proxy.$onDidDisposeWebviewPanel(handle).then( diff --git a/src/vs/workbench/parts/webview/electron-browser/webviewEditorInput.ts b/src/vs/workbench/parts/webview/electron-browser/webviewEditorInput.ts index 07f44326ef7..638ea70b328 100644 --- a/src/vs/workbench/parts/webview/electron-browser/webviewEditorInput.ts +++ b/src/vs/workbench/parts/webview/electron-browser/webviewEditorInput.ts @@ -2,7 +2,7 @@ * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ - +import * as dom from 'vs/base/browser/dom'; import { Emitter } from 'vs/base/common/event'; import { dispose, IDisposable } from 'vs/base/common/lifecycle'; import URI from 'vs/base/common/uri'; @@ -14,12 +14,47 @@ import * as vscode from 'vscode'; import { WebviewEvents, WebviewInputOptions, WebviewReviver } from './webviewEditorService'; import { WebviewElement } from './webviewElement'; + export class WebviewEditorInput extends EditorInput { private static handlePool = 0; + + private static _styleElement?: HTMLStyleElement; + + private static _icons = new Map(); + + private static updateStyleElement( + id: number, + iconPath: { light: URI, dark: URI } | undefined + ) { + if (!this._styleElement) { + this._styleElement = dom.createStyleSheet(); + this._styleElement.className = 'webview-icons'; + } + + if (!iconPath) { + this._icons.delete(id); + } else { + this._icons.set(id, iconPath); + } + + const cssRules: string[] = []; + this._icons.forEach((value, key) => { + const webviewSelector = `.show-file-icons .webview-${key}-name-file-icon::before`; + if (URI.isUri(value)) { + cssRules.push(`${webviewSelector} { content: ""; background-image: url(${value.toString()}); }`); + } else { + cssRules.push(`${webviewSelector} { content: ""; background-image: url(${value.light.toString()}); }`); + cssRules.push(`.vs-dark ${webviewSelector} { content: ""; background-image: url(${value.dark.toString()}); }`); + } + }); + this._styleElement.innerHTML = cssRules.join('\n'); + } + public static readonly typeId = 'workbench.editors.webviewInput'; private _name: string; + private _iconPath?: { light: URI, dark: URI }; private _options: WebviewInputOptions; private _html: string = ''; private _currentWebviewHtml: string = ''; @@ -109,6 +144,15 @@ export class WebviewEditorInput extends EditorInput { this._onDidChangeLabel.fire(); } + public get iconPath() { + return this._iconPath; + } + + public set iconPath(value: { light: URI, dark: URI } | undefined) { + this._iconPath = value; + WebviewEditorInput.updateStyleElement(this._id, value); + } + public matches(other: IEditorInput): boolean { return other && other === this; } diff --git a/src/vs/workbench/parts/webview/electron-browser/webviewEditorInputFactory.ts b/src/vs/workbench/parts/webview/electron-browser/webviewEditorInputFactory.ts index 0bb8b9fbd71..fc973d68479 100644 --- a/src/vs/workbench/parts/webview/electron-browser/webviewEditorInputFactory.ts +++ b/src/vs/workbench/parts/webview/electron-browser/webviewEditorInputFactory.ts @@ -15,6 +15,7 @@ interface SerializedWebview { readonly options: WebviewInputOptions; readonly extensionLocation: string; readonly state: any; + readonly iconPath: { light: string, dark: string } | undefined; } export class WebviewEditorInputFactory implements IEditorInputFactory { @@ -43,7 +44,8 @@ export class WebviewEditorInputFactory implements IEditorInputFactory { title: input.getName(), options: input.options, extensionLocation: input.extensionLocation.toString(), - state: input.state + state: input.state, + iconPath: input.iconPath ? { light: input.iconPath.light.toString(), dark: input.iconPath.dark.toString(), } : undefined, }; return JSON.stringify(data); } @@ -54,6 +56,7 @@ export class WebviewEditorInputFactory implements IEditorInputFactory { ): WebviewEditorInput { const data: SerializedWebview = JSON.parse(serializedEditorInput); const extensionLocation = URI.parse(data.extensionLocation); - return this._webviewService.reviveWebview(data.viewType, data.title, data.state, data.options, extensionLocation); + const iconPath = data.iconPath ? { light: URI.parse(data.iconPath.light), dark: URI.parse(data.iconPath.dark) } : undefined; + return this._webviewService.reviveWebview(data.viewType, data.title, iconPath, data.state, data.options, extensionLocation); } } diff --git a/src/vs/workbench/parts/webview/electron-browser/webviewEditorService.ts b/src/vs/workbench/parts/webview/electron-browser/webviewEditorService.ts index 3c4228078b6..99695243653 100644 --- a/src/vs/workbench/parts/webview/electron-browser/webviewEditorService.ts +++ b/src/vs/workbench/parts/webview/electron-browser/webviewEditorService.ts @@ -36,6 +36,7 @@ export interface IWebviewEditorService { reviveWebview( viewType: string, title: string, + iconPath: { light: URI, dark: URI } | undefined, state: any, options: WebviewInputOptions, extensionLocation: URI @@ -126,6 +127,7 @@ export class WebviewEditorService implements IWebviewEditorService { reviveWebview( viewType: string, title: string, + iconPath: { light: URI, dark: URI } | undefined, state: any, options: WebviewInputOptions, extensionLocation: URI @@ -148,7 +150,7 @@ export class WebviewEditorService implements IWebviewEditorService { }); } }); - + webviewInput.iconPath = iconPath; return webviewInput; } From 627d4596902c1f08394a69668208759f84157231 Mon Sep 17 00:00:00 2001 From: Matt Bierner Date: Wed, 25 Jul 2018 15:02:35 -0700 Subject: [PATCH 0127/1276] Fix release notes file icon --- .../update/electron-browser/media/update.contribution.css | 6 ------ .../parts/update/electron-browser/releaseNotesEditor.ts | 5 +++++ 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/src/vs/workbench/parts/update/electron-browser/media/update.contribution.css b/src/vs/workbench/parts/update/electron-browser/media/update.contribution.css index 4e602f932a2..54537cdcfa7 100644 --- a/src/vs/workbench/parts/update/electron-browser/media/update.contribution.css +++ b/src/vs/workbench/parts/update/electron-browser/media/update.contribution.css @@ -7,9 +7,3 @@ -webkit-mask: url('update.svg') no-repeat 50% 50%; -webkit-mask-size: 22px; } - -/* TODO@Ben this is a hack to overwrite the icon for release notes eitor */ -.file-icons-enabled .show-file-icons .release-notes-ext-file-icon.file-icon::before { - content: ' '; - background-image: url('code-icon.svg'); -} \ No newline at end of file diff --git a/src/vs/workbench/parts/update/electron-browser/releaseNotesEditor.ts b/src/vs/workbench/parts/update/electron-browser/releaseNotesEditor.ts index b50ecda1765..c81582ead3b 100644 --- a/src/vs/workbench/parts/update/electron-browser/releaseNotesEditor.ts +++ b/src/vs/workbench/parts/update/electron-browser/releaseNotesEditor.ts @@ -99,6 +99,11 @@ export class ReleaseNotesManager { onDispose: () => { this._currentReleaseNotes = undefined; } }); + const iconPath = URI.parse(require.toUrl('./media/code-icon.svg')); + this._currentReleaseNotes.iconPath = { + light: iconPath, + dark: iconPath + }; this._currentReleaseNotes.html = html; } From 37209a838e9f7e9abe6dc53ed73cdf1e03b72060 Mon Sep 17 00:00:00 2001 From: Matt Bierner Date: Wed, 25 Jul 2018 15:24:48 -0700 Subject: [PATCH 0128/1276] Don't include non-resource entries in history quick pick Makes sure webviews don't show up in the history quick pick. We already do this filtering properly when there is a query, just not when there is no query --- .../parts/quickopen/quickOpenController.ts | 23 +++++++++---------- 1 file changed, 11 insertions(+), 12 deletions(-) diff --git a/src/vs/workbench/browser/parts/quickopen/quickOpenController.ts b/src/vs/workbench/browser/parts/quickopen/quickOpenController.ts index 7cab9eec672..24699aff23e 100644 --- a/src/vs/workbench/browser/parts/quickopen/quickOpenController.ts +++ b/src/vs/workbench/browser/parts/quickopen/quickOpenController.ts @@ -1075,17 +1075,7 @@ class EditorHistoryHandler { // Massage search for scoring const query = prepareQuery(searchValue); - // Just return all if we are not searching - const history = this.historyService.getHistory(); - if (!query.value) { - return history.map(input => this.instantiationService.createInstance(EditorHistoryEntry, input)); - } - - // Otherwise filter by search value and sort by score. Include matches on description - // in case the user is explicitly including path separators. - const accessor = query.containsPathSeparator ? MatchOnDescription : DoNotMatchOnDescription; - return history - + const history = this.historyService.getHistory() // For now, only support to match on inputs that provide resource information .filter(input => { let resource: URI; @@ -1099,8 +1089,17 @@ class EditorHistoryHandler { }) // Conver to quick open entries - .map(input => this.instantiationService.createInstance(EditorHistoryEntry, input)) + .map(input => this.instantiationService.createInstance(EditorHistoryEntry, input)); + // Just return all if we are not searching + if (!query.value) { + return history; + } + + // Otherwise filter by search value and sort by score. Include matches on description + // in case the user is explicitly including path separators. + const accessor = query.containsPathSeparator ? MatchOnDescription : DoNotMatchOnDescription; + return history // Make sure the search value is matching .filter(e => { const itemScore = scoreItem(e, query, false, accessor, this.scorerCache); From ad9cc79cf5f639e6d42b17f7a563c81de15b1b58 Mon Sep 17 00:00:00 2001 From: Sandeep Somavarapu Date: Thu, 26 Jul 2018 00:32:21 +0200 Subject: [PATCH 0129/1276] Fix #55021 --- .../markers/electron-browser/markersPanel.ts | 7 +- .../electron-browser/markersPanelActions.ts | 70 ++++++++++++++++++- .../electron-browser/markersTreeController.ts | 55 ++++----------- .../electron-browser/markersTreeViewer.ts | 19 ++--- .../electron-browser/media/markers.css | 31 +++++--- .../markers/electron-browser/messages.ts | 1 + 6 files changed, 120 insertions(+), 63 deletions(-) diff --git a/src/vs/workbench/parts/markers/electron-browser/markersPanel.ts b/src/vs/workbench/parts/markers/electron-browser/markersPanel.ts index dde2adc6b77..804b805f657 100644 --- a/src/vs/workbench/parts/markers/electron-browser/markersPanel.ts +++ b/src/vs/workbench/parts/markers/electron-browser/markersPanel.ts @@ -19,7 +19,7 @@ import { Marker, ResourceMarkers, RelatedInformation } from 'vs/workbench/parts/ import { Controller } from 'vs/workbench/parts/markers/electron-browser/markersTreeController'; import * as Viewer from 'vs/workbench/parts/markers/electron-browser/markersTreeViewer'; import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; -import { CollapseAllAction, MarkersFilterActionItem, MarkersFilterAction } from 'vs/workbench/parts/markers/electron-browser/markersPanelActions'; +import { CollapseAllAction, MarkersFilterActionItem, MarkersFilterAction, QuickFixAction, QuickFixActionItem } from 'vs/workbench/parts/markers/electron-browser/markersPanelActions'; import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; import Messages from 'vs/workbench/parts/markers/electron-browser/messages'; import { RangeHighlightDecorations } from 'vs/workbench/browser/parts/editor/rangeDecorations'; @@ -196,7 +196,7 @@ export class MarkersPanel extends Panel { private createTree(parent: HTMLElement): void { this.treeContainer = dom.append(parent, dom.$('.tree-container.show-file-icons')); - const renderer = this.instantiationService.createInstance(Viewer.Renderer); + const renderer = this.instantiationService.createInstance(Viewer.Renderer, (action) => this.getActionItem(action)); const dnd = this.instantiationService.createInstance(SimpleFileResourceDragAndDrop, obj => obj instanceof ResourceMarkers ? obj.uri : void 0); const controller = this.instantiationService.createInstance(Controller); this.tree = this.instantiationService.createInstance(WorkbenchTree, this.treeContainer, { @@ -433,6 +433,9 @@ export class MarkersPanel extends Panel { if (action.id === MarkersFilterAction.ID) { return this.filterInputActionItem; } + if (action.id === QuickFixAction.ID) { + return this.instantiationService.createInstance(QuickFixActionItem, action); + } return super.getActionItem(action); } diff --git a/src/vs/workbench/parts/markers/electron-browser/markersPanelActions.ts b/src/vs/workbench/parts/markers/electron-browser/markersPanelActions.ts index fd918657fe9..56c76acfaf4 100644 --- a/src/vs/workbench/parts/markers/electron-browser/markersPanelActions.ts +++ b/src/vs/workbench/parts/markers/electron-browser/markersPanelActions.ts @@ -10,7 +10,7 @@ import { Action, IAction } from 'vs/base/common/actions'; import { HistoryInputBox } from 'vs/base/browser/ui/inputbox/inputBox'; import { KeyCode } from 'vs/base/common/keyCodes'; import { IKeyboardEvent } from 'vs/base/browser/keyboardEvent'; -import { IContextViewService } from 'vs/platform/contextview/browser/contextView'; +import { IContextViewService, IContextMenuService } from 'vs/platform/contextview/browser/contextView'; import { TogglePanelAction } from 'vs/workbench/browser/panel'; import Messages from 'vs/workbench/parts/markers/electron-browser/messages'; import Constants from 'vs/workbench/parts/markers/electron-browser/constants'; @@ -24,12 +24,17 @@ import { attachInputBoxStyler, attachStylerCallback, attachCheckboxStyler } from import { IMarkersWorkbenchService } from 'vs/workbench/parts/markers/electron-browser/markers'; import { Event, Emitter } from 'vs/base/common/event'; import { IDisposable } from 'vs/base/common/lifecycle'; -import { BaseActionItem } from 'vs/base/browser/ui/actionbar/actionbar'; +import { BaseActionItem, ActionItem } from 'vs/base/browser/ui/actionbar/actionbar'; import { badgeBackground, contrastBorder } from 'vs/platform/theme/common/colorRegistry'; import { localize } from 'vs/nls'; import { Checkbox } from 'vs/base/browser/ui/checkbox/checkbox'; import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; import { ContextScopedHistoryInputBox } from 'vs/platform/widget/browser/contextScopedHistoryWidget'; +import { Marker, ResourceMarkers } from 'vs/workbench/parts/markers/electron-browser/markersModel'; +import { applyCodeAction } from 'vs/editor/contrib/codeAction/codeActionCommands'; +import { IBulkEditService } from 'vs/editor/browser/services/bulkEditService'; +import { ICommandService } from 'vs/platform/commands/common/commands'; +import { IEditorService, ACTIVE_GROUP } from 'vs/workbench/services/editor/common/editorService'; export class ToggleMarkersPanelAction extends TogglePanelAction { @@ -269,4 +274,65 @@ export class MarkersFilterActionItem extends BaseActionItem { this._toDispose.push(t); return t; } +} + +export class QuickFixAction extends Action { + + public static readonly ID: string = 'workbench.actions.problems.quickfix'; + + constructor( + readonly marker: Marker, + readonly resourceMarkers: ResourceMarkers, + @IBulkEditService private bulkEditService: IBulkEditService, + @ICommandService private commandService: ICommandService, + @IEditorService private editorService: IEditorService + ) { + super(QuickFixAction.ID, Messages.MARKERS_PANEL_ACTION_TOOLTIP_QUICKFIX, 'markers-panel-action-quickfix', false); + resourceMarkers.hasFixes(marker).then(hasFixes => this.enabled = hasFixes); + } + + async getQuickFixActions(): Promise { + const codeActions = await this.resourceMarkers.getFixes(this.marker); + return codeActions.map(codeAction => new Action( + codeAction.command ? codeAction.command.id : codeAction.title, + codeAction.title, + void 0, + true, + () => { + return this.openFileAtMarker(this.marker) + .then(() => applyCodeAction(codeAction, this.bulkEditService, this.commandService)); + })); + } + + public openFileAtMarker(element: Marker): TPromise { + const { resource, selection } = { resource: element.resource, selection: element.range }; + return this.editorService.openEditor({ + resource, + options: { + selection, + preserveFocus: true, + pinned: false, + revealIfVisible: true + }, + }, ACTIVE_GROUP).then(() => null); + } +} + +export class QuickFixActionItem extends ActionItem { + + constructor(action: QuickFixAction, + @IContextMenuService private contextMenuService: IContextMenuService + ) { + super(null, action, { icon: true, label: false }); + } + + public onClick(event: DOM.EventLike): void { + DOM.EventHelper.stop(event, true); + const elementPosition = DOM.getDomNodePagePosition(this.builder.getHTMLElement()); + this.contextMenuService.showContextMenu({ + getAnchor: () => ({ x: elementPosition.left + 10, y: elementPosition.top + elementPosition.height }), + getActions: () => TPromise.wrap((this.getAction()).getQuickFixActions()), + }); + } + } \ No newline at end of file diff --git a/src/vs/workbench/parts/markers/electron-browser/markersTreeController.ts b/src/vs/workbench/parts/markers/electron-browser/markersTreeController.ts index 9a8151b2f35..142f95c65a2 100644 --- a/src/vs/workbench/parts/markers/electron-browser/markersTreeController.ts +++ b/src/vs/workbench/parts/markers/electron-browser/markersTreeController.ts @@ -10,15 +10,13 @@ import * as tree from 'vs/base/parts/tree/browser/tree'; import { MarkersModel, Marker, ResourceMarkers } from 'vs/workbench/parts/markers/electron-browser/markersModel'; import { IContextMenuService } from 'vs/platform/contextview/browser/contextView'; import { IMenuService, MenuId } from 'vs/platform/actions/common/actions'; -import { IAction, Action } from 'vs/base/common/actions'; +import { IAction } from 'vs/base/common/actions'; import { ActionItem, Separator } from 'vs/base/browser/ui/actionbar/actionbar'; import { IKeybindingService } from 'vs/platform/keybinding/common/keybinding'; import { WorkbenchTree, WorkbenchTreeController } from 'vs/platform/list/browser/listService'; import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; -import { IBulkEditService } from 'vs/editor/browser/services/bulkEditService'; -import { applyCodeAction } from 'vs/editor/contrib/codeAction/codeActionCommands'; -import { ICommandService } from 'vs/platform/commands/common/commands'; -import { IEditorService, ACTIVE_GROUP } from 'vs/workbench/services/editor/common/editorService'; +import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; +import { QuickFixAction } from 'vs/workbench/parts/markers/electron-browser/markersPanelActions'; export class Controller extends WorkbenchTreeController { @@ -27,9 +25,7 @@ export class Controller extends WorkbenchTreeController { @IMenuService private menuService: IMenuService, @IKeybindingService private readonly _keybindingService: IKeybindingService, @IConfigurationService configurationService: IConfigurationService, - @IBulkEditService private bulkEditService: IBulkEditService, - @ICommandService private commandService: ICommandService, - @IEditorService private editorService: IEditorService + @IInstantiationService private instantiationService: IInstantiationService ) { super({}, configurationService); } @@ -79,12 +75,15 @@ export class Controller extends WorkbenchTreeController { private async _getMenuActions(tree: WorkbenchTree, element: any): Promise { const result: IAction[] = []; - if (element instanceof Marker) { - const quickFixActions = await this._getQuickFixActions(tree, element); - if (quickFixActions.length) { - result.push(...quickFixActions); - result.push(new Separator()); + const parent = tree.getNavigator(element).parent(); + if (parent instanceof ResourceMarkers) { + const quickFixAction = this.instantiationService.createInstance(QuickFixAction, element, parent); + const quickFixActions = await quickFixAction.getQuickFixActions(); + if (quickFixActions.length) { + result.push(...quickFixActions); + result.push(new Separator()); + } } } @@ -101,34 +100,4 @@ export class Controller extends WorkbenchTreeController { result.pop(); // remove last separator return result; } - - private async _getQuickFixActions(tree: WorkbenchTree, element: Marker): Promise { - const parent = tree.getNavigator(element).parent(); - if (parent instanceof ResourceMarkers) { - const codeActions = await parent.getFixes(element); - return codeActions.map(codeAction => new Action( - codeAction.command ? codeAction.command.id : codeAction.title, - codeAction.title, - void 0, - true, - () => { - return this.openFileAtMarker(element) - .then(() => applyCodeAction(codeAction, this.bulkEditService, this.commandService)); - })); - } - return []; - } - - public openFileAtMarker(element: Marker): TPromise { - const { resource, selection } = { resource: element.resource, selection: element.range }; - return this.editorService.openEditor({ - resource, - options: { - selection, - preserveFocus: true, - pinned: false, - revealIfVisible: true - }, - }, ACTIVE_GROUP).then(() => null); - } } diff --git a/src/vs/workbench/parts/markers/electron-browser/markersTreeViewer.ts b/src/vs/workbench/parts/markers/electron-browser/markersTreeViewer.ts index 4b8f13c73de..2b65a817845 100644 --- a/src/vs/workbench/parts/markers/electron-browser/markersTreeViewer.ts +++ b/src/vs/workbench/parts/markers/electron-browser/markersTreeViewer.ts @@ -22,6 +22,8 @@ import { IDisposable } from 'vs/base/common/lifecycle'; import { getPathLabel } from 'vs/base/common/labels'; import { IEnvironmentService } from 'vs/platform/environment/common/environment'; import { IWorkspaceContextService } from 'vs/platform/workspace/common/workspace'; +import { ActionBar, IActionItemProvider } from 'vs/base/browser/ui/actionbar/actionbar'; +import { QuickFixAction } from 'vs/workbench/parts/markers/electron-browser/markersPanelActions'; interface IResourceMarkersTemplateData { resourceLabel: ResourceLabel; @@ -31,7 +33,7 @@ interface IResourceMarkersTemplateData { interface IMarkerTemplateData { icon: HTMLElement; - lightbulb: HTMLElement; + actionBar: ActionBar; source: HighlightedLabel; description: HighlightedLabel; lnCol: HTMLElement; @@ -96,6 +98,7 @@ export class Renderer implements IRenderer { private static readonly RELATED_INFO_TEMPLATE_ID = 'related-info-template'; constructor( + private actionItemProvider: IActionItemProvider, @IInstantiationService private instantiationService: IInstantiationService, @IThemeService private themeService: IThemeService, @IEnvironmentService private environmentService: IEnvironmentService, @@ -180,8 +183,9 @@ export class Renderer implements IRenderer { private renderMarkerTemplate(container: HTMLElement): IMarkerTemplateData { const data: IMarkerTemplateData = Object.create(null); + const actionsContainer = dom.append(container, dom.$('.actions')); + data.actionBar = new ActionBar(actionsContainer, { actionItemProvider: this.actionItemProvider }); data.icon = dom.append(container, dom.$('.marker-icon')); - data.lightbulb = dom.append(container, dom.$('.icon.lightbulb')); data.source = new HighlightedLabel(dom.append(container, dom.$(''))); data.description = new HighlightedLabel(dom.append(container, dom.$('.marker-description'))); data.lnCol = dom.append(container, dom.$('span.marker-line')); @@ -213,20 +217,19 @@ export class Renderer implements IRenderer { let marker = element.raw; templateData.icon.className = 'icon ' + Renderer.iconClassNameFor(marker); - dom.removeClass(templateData.lightbulb, 'quick-fixes'); templateData.source.set(marker.source, element.sourceMatches); dom.toggleClass(templateData.source.element, 'marker-source', !!marker.source); + templateData.actionBar.clear(); + const parent = tree.getNavigator(element).parent(); + const quickFixAction = this.instantiationService.createInstance(QuickFixAction, element, parent); + templateData.actionBar.push([quickFixAction], { icon: true, label: false }); + templateData.description.set(marker.message, element.messageMatches); templateData.description.element.title = marker.message; templateData.lnCol.textContent = Messages.MARKERS_PANEL_AT_LINE_COL_NUMBER(marker.startLineNumber, marker.startColumn); - - const parent = tree.getNavigator(element).parent(); - if (parent instanceof ResourceMarkers) { - parent.hasFixes(element).then(hasFixes => dom.toggleClass(templateData.lightbulb, 'quick-fixes', hasFixes)); - } } private renderRelatedInfoElement(tree: ITree, element: RelatedInformation, templateData: IRelatedInformationTemplateData) { diff --git a/src/vs/workbench/parts/markers/electron-browser/media/markers.css b/src/vs/workbench/parts/markers/electron-browser/media/markers.css index b351563aa6c..dbf159f8436 100644 --- a/src/vs/workbench/parts/markers/electron-browser/media/markers.css +++ b/src/vs/workbench/parts/markers/electron-browser/media/markers.css @@ -166,17 +166,32 @@ background: url('status-info-inverse.svg') center center no-repeat; } -.markers-panel .icon.lightbulb { - background: url('lightbulb.svg') center/40% no-repeat; - position: absolute; - width: 24px; - height: 30px; +.vs-dark .markers-panel .icon.markers-panel-action-quickfix { + background: url('lightbulb-dark.svg') center/80% no-repeat; + background-position: 50% 55%; } -.vs-dark .markers-panel .icon.lightbulb { - background: url('lightbulb-dark.svg') center/40% no-repeat; +.markers-panel .monaco-tree .monaco-tree-row .markers-panel-tree-entry > .actions { + width: 22px; } -.markers-panel .icon.lightbulb:not(.quick-fixes) { +.markers-panel .monaco-tree .monaco-tree-row .markers-panel-tree-entry > .actions .monaco-action-bar { + display: none; +} + +.markers-panel .monaco-tree .monaco-tree-row:hover .markers-panel-tree-entry > .actions .monaco-action-bar, +.markers-panel .monaco-tree .monaco-tree-row.selected .markers-panel-tree-entry > .actions .monaco-action-bar, +.markers-panel .monaco-tree .monaco-tree-row.focused .markers-panel-tree-entry > .actions .monaco-action-bar { + display: block; +} + +.markers-panel .monaco-tree .markers-panel-tree-entry .actions .action-label { + width: 16px; + height: 100%; + background-position: 50% 50%; + background-repeat: no-repeat; +} + +.markers-panel .monaco-tree .markers-panel-tree-entry .actions .action-item.disabled { display: none; } \ No newline at end of file diff --git a/src/vs/workbench/parts/markers/electron-browser/messages.ts b/src/vs/workbench/parts/markers/electron-browser/messages.ts index f54ddaea508..c5285fae726 100644 --- a/src/vs/workbench/parts/markers/electron-browser/messages.ts +++ b/src/vs/workbench/parts/markers/electron-browser/messages.ts @@ -28,6 +28,7 @@ export default class Messages { public static MARKERS_PANEL_ACTION_TOOLTIP_USE_FILES_EXCLUDE: string = nls.localize('markers.panel.action.useFilesExclude', "Filter using Files Exclude Setting"); public static MARKERS_PANEL_ACTION_TOOLTIP_DO_NOT_USE_FILES_EXCLUDE: string = nls.localize('markers.panel.action.donotUseFilesExclude', "Do not use Files Exclude Setting"); public static MARKERS_PANEL_ACTION_TOOLTIP_FILTER: string = nls.localize('markers.panel.action.filter', "Filter Problems"); + public static MARKERS_PANEL_ACTION_TOOLTIP_QUICKFIX: string = nls.localize('markers.panel.action.quickfix', "Show fixes"); public static MARKERS_PANEL_FILTER_ARIA_LABEL: string = nls.localize('markers.panel.filter.ariaLabel', "Filter Problems"); public static MARKERS_PANEL_FILTER_PLACEHOLDER: string = nls.localize('markers.panel.filter.placeholder', "Filter. Eg: text, **/*.ts, !**/node_modules/**"); public static MARKERS_PANEL_FILTER_ERRORS: string = nls.localize('markers.panel.filter.errors', "errors"); From d8bf1443cf193a366ad7a8b3207265ca3ce8a441 Mon Sep 17 00:00:00 2001 From: Ramya Rao Date: Wed, 25 Jul 2018 15:51:28 -0700 Subject: [PATCH 0130/1276] Support tags on settings to filter in settings editor (#55094) * Support tags on settings to filter in settings editor * Revert adding tags to api until we are ready --- extensions/git/package.json | 3 ++- extensions/typescript-language-features/package.json | 3 ++- .../configuration/common/configurationRegistry.ts | 1 + src/vs/platform/telemetry/common/telemetryService.ts | 3 ++- .../platform/update/node/update.config.contribution.ts | 9 ++++++--- src/vs/workbench/electron-browser/main.contribution.ts | 3 ++- .../electron-browser/extensions.contribution.ts | 6 ++++-- .../electron-browser/crashReporterService.ts | 3 ++- 8 files changed, 21 insertions(+), 10 deletions(-) diff --git a/extensions/git/package.json b/extensions/git/package.json index a4afad8facb..61575483e42 100644 --- a/extensions/git/package.json +++ b/extensions/git/package.json @@ -911,7 +911,8 @@ "git.autofetch": { "type": "boolean", "description": "%config.autofetch%", - "default": false + "default": false, + "tags": ["backgroundOnlineFeature"] }, "git.confirmSync": { "type": "boolean", diff --git a/extensions/typescript-language-features/package.json b/extensions/typescript-language-features/package.json index 78377f20166..46bca84de1a 100644 --- a/extensions/typescript-language-features/package.json +++ b/extensions/typescript-language-features/package.json @@ -73,7 +73,8 @@ "type": "boolean", "default": false, "description": "%typescript.disableAutomaticTypeAcquisition%", - "scope": "window" + "scope": "window", + "tags": ["backgroundOnlineFeature"] }, "typescript.npm": { "type": [ diff --git a/src/vs/platform/configuration/common/configurationRegistry.ts b/src/vs/platform/configuration/common/configurationRegistry.ts index ef37ffe80d5..0c63a065226 100644 --- a/src/vs/platform/configuration/common/configurationRegistry.ts +++ b/src/vs/platform/configuration/common/configurationRegistry.ts @@ -78,6 +78,7 @@ export interface IConfigurationPropertySchema extends IJSONSchema { scope?: ConfigurationScope; notMultiRootAdopted?: boolean; included?: boolean; + tags?: string[]; } export interface IConfigurationNode { diff --git a/src/vs/platform/telemetry/common/telemetryService.ts b/src/vs/platform/telemetry/common/telemetryService.ts index 0b8470198a3..0edfc7c942b 100644 --- a/src/vs/platform/telemetry/common/telemetryService.ts +++ b/src/vs/platform/telemetry/common/telemetryService.ts @@ -167,7 +167,8 @@ Registry.as(Extensions.Configuration).registerConfigurat 'telemetry.enableTelemetry': { 'type': 'boolean', 'description': localize('telemetry.enableTelemetry', "Enable usage data and errors to be sent to Microsoft."), - 'default': true + 'default': true, + 'tags': ['backgroundOnlineFeature'] } } }); \ No newline at end of file diff --git a/src/vs/platform/update/node/update.config.contribution.ts b/src/vs/platform/update/node/update.config.contribution.ts index 86ad52731dc..42e989b58e7 100644 --- a/src/vs/platform/update/node/update.config.contribution.ts +++ b/src/vs/platform/update/node/update.config.contribution.ts @@ -21,18 +21,21 @@ configurationRegistry.registerConfiguration({ 'enum': ['none', 'default'], 'default': 'default', 'scope': ConfigurationScope.APPLICATION, - 'description': nls.localize('updateChannel', "Configure whether you receive automatic updates from an update channel. Requires a restart after change.") + 'description': nls.localize('updateChannel', "Configure whether you receive automatic updates from an update channel. Requires a restart after change."), + 'tags': ['backgroundOnlineFeature'] }, 'update.enableWindowsBackgroundUpdates': { 'type': 'boolean', 'default': true, 'scope': ConfigurationScope.APPLICATION, - 'description': nls.localize('enableWindowsBackgroundUpdates', "Enables Windows background updates.") + 'description': nls.localize('enableWindowsBackgroundUpdates', "Enables Windows background updates."), + 'tags': ['backgroundOnlineFeature'] }, 'update.showReleaseNotes': { 'type': 'boolean', 'default': true, - 'description': nls.localize('showReleaseNotes', "Show Release Notes after an update.") + 'description': nls.localize('showReleaseNotes', "Show Release Notes after an update."), + 'tags': ['backgroundOnlineFeature'] } } }); diff --git a/src/vs/workbench/electron-browser/main.contribution.ts b/src/vs/workbench/electron-browser/main.contribution.ts index 6ef42882159..e6ed4bc6b2a 100644 --- a/src/vs/workbench/electron-browser/main.contribution.ts +++ b/src/vs/workbench/electron-browser/main.contribution.ts @@ -488,7 +488,8 @@ configurationRegistry.registerConfiguration({ 'type': 'boolean', 'description': nls.localize('enableNaturalLanguageSettingsSearch', "Controls whether to enable the natural language search mode for settings."), 'default': true, - 'scope': ConfigurationScope.WINDOW + 'scope': ConfigurationScope.WINDOW, + 'tags': ['backgroundOnlineFeature'] }, 'workbench.settings.settingsSearchTocBehavior': { 'type': 'string', diff --git a/src/vs/workbench/parts/extensions/electron-browser/extensions.contribution.ts b/src/vs/workbench/parts/extensions/electron-browser/extensions.contribution.ts index 3e42ab38486..51008b00d24 100644 --- a/src/vs/workbench/parts/extensions/electron-browser/extensions.contribution.ts +++ b/src/vs/workbench/parts/extensions/electron-browser/extensions.contribution.ts @@ -206,7 +206,8 @@ Registry.as(ConfigurationExtensions.Configuration) type: 'boolean', description: localize('extensionsAutoUpdate', "Automatically update extensions."), default: true, - scope: ConfigurationScope.APPLICATION + scope: ConfigurationScope.APPLICATION, + tags: ['backgroundOnlineFeature'] }, 'extensions.ignoreRecommendations': { type: 'boolean', @@ -216,7 +217,8 @@ Registry.as(ConfigurationExtensions.Configuration) 'extensions.showRecommendationsOnlyOnDemand': { type: 'boolean', description: localize('extensionsShowRecommendationsOnlyOnDemand', "When enabled, recommendations will not be fetched or shown unless specifically requested by the user."), - default: false + default: false, + tags: ['backgroundOnlineFeature'] }, 'extensions.closeExtensionDetailsOnViewChange': { type: 'boolean', diff --git a/src/vs/workbench/services/crashReporter/electron-browser/crashReporterService.ts b/src/vs/workbench/services/crashReporter/electron-browser/crashReporterService.ts index 2b63e252efb..b0997699777 100644 --- a/src/vs/workbench/services/crashReporter/electron-browser/crashReporterService.ts +++ b/src/vs/workbench/services/crashReporter/electron-browser/crashReporterService.ts @@ -37,7 +37,8 @@ configurationRegistry.registerConfiguration({ 'telemetry.enableCrashReporter': { 'type': 'boolean', 'description': nls.localize('telemetry.enableCrashReporting', "Enable crash reports to be sent to Microsoft.\nThis option requires restart to take effect."), - 'default': true + 'default': true, + 'tags': ['backgroundOnlineFeature'] } } }); From 5347a06a4674d35231620bee74f23fae8616758f Mon Sep 17 00:00:00 2001 From: Matt Bierner Date: Wed, 25 Jul 2018 16:24:00 -0700 Subject: [PATCH 0131/1276] Don't convert diagnostic set to array --- .../src/features/quickFix.ts | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/extensions/typescript-language-features/src/features/quickFix.ts b/extensions/typescript-language-features/src/features/quickFix.ts index 56232596b22..58dc8b3bd98 100644 --- a/extensions/typescript-language-features/src/features/quickFix.ts +++ b/extensions/typescript-language-features/src/features/quickFix.ts @@ -128,6 +128,10 @@ class DiagnosticsSet { public get values(): Iterable { return this._values.values(); } + + public get size() { + return this._values.size; + } } class SupportedCodeActionProvider { @@ -137,10 +141,9 @@ class SupportedCodeActionProvider { private readonly client: ITypeScriptServiceClient ) { } - public async getFixableDiagnosticsForContext(context: vscode.CodeActionContext): Promise { + public async getFixableDiagnosticsForContext(context: vscode.CodeActionContext): Promise { const supportedActions = await this.supportedCodeActions; - const fixableDiagnostics = DiagnosticsSet.from(context.diagnostics.filter(diagnostic => supportedActions.has(+(diagnostic.code!)))); - return Array.from(fixableDiagnostics.values); + return DiagnosticsSet.from(context.diagnostics.filter(diagnostic => supportedActions.has(+(diagnostic.code!)))); } private get supportedCodeActions(): Thenable> { @@ -187,7 +190,7 @@ class TypeScriptQuickFixProvider implements vscode.CodeActionProvider { } const fixableDiagnostics = await this.supportedCodeActionProvider.getFixableDiagnosticsForContext(context); - if (!fixableDiagnostics.length) { + if (!fixableDiagnostics.size) { return []; } @@ -198,7 +201,7 @@ class TypeScriptQuickFixProvider implements vscode.CodeActionProvider { await this.formattingConfigurationManager.ensureConfigurationForDocument(document, token); const results: vscode.CodeAction[] = []; - for (const diagnostic of fixableDiagnostics) { + for (const diagnostic of fixableDiagnostics.values) { results.push(...await this.getFixesForDiagnostic(document, file, diagnostic, token)); } return results; From ccf9f4baddb5fd786df1ed32bd0080b9bd43c3ba Mon Sep 17 00:00:00 2001 From: Matt Bierner Date: Wed, 25 Jul 2018 16:33:08 -0700 Subject: [PATCH 0132/1276] Use VersionDependentRegistration --- .../src/features/quickFix.ts | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/extensions/typescript-language-features/src/features/quickFix.ts b/extensions/typescript-language-features/src/features/quickFix.ts index 58dc8b3bd98..1e21c2dfcbe 100644 --- a/extensions/typescript-language-features/src/features/quickFix.ts +++ b/extensions/typescript-language-features/src/features/quickFix.ts @@ -10,6 +10,7 @@ import { ITypeScriptServiceClient } from '../typescriptService'; import API from '../utils/api'; import { applyCodeActionCommands, getEditForCodeAction } from '../utils/codeAction'; import { Command, CommandManager } from '../utils/commandManager'; +import { VersionDependentRegistration } from '../utils/dependentRegistration'; import TelemetryReporter from '../utils/telemetry'; import * as typeConverters from '../utils/typeConverters'; import { DiagnosticsManager } from './diagnostics'; @@ -180,10 +181,6 @@ class TypeScriptQuickFixProvider implements vscode.CodeActionProvider { context: vscode.CodeActionContext, token: vscode.CancellationToken ): Promise { - if (!this.client.apiVersion.gte(API.v213)) { - return []; - } - const file = this.client.toPath(document.uri); if (!file) { return []; @@ -293,6 +290,7 @@ export function register( diagnosticsManager: DiagnosticsManager, telemetryReporter: TelemetryReporter ) { - return vscode.languages.registerCodeActionsProvider(selector, - new TypeScriptQuickFixProvider(client, fileConfigurationManager, commandManager, diagnosticsManager, telemetryReporter)); + return new VersionDependentRegistration(client, API.v213, () => + vscode.languages.registerCodeActionsProvider(selector, + new TypeScriptQuickFixProvider(client, fileConfigurationManager, commandManager, diagnosticsManager, telemetryReporter))); } From 690744c3c6f7efbed589211dc8588ffc8e52a049 Mon Sep 17 00:00:00 2001 From: Matt Bierner Date: Wed, 25 Jul 2018 17:18:33 -0700 Subject: [PATCH 0133/1276] Only return a single all code action per quick fix fixId Fixes #55065 --- .../src/features/quickFix.ts | 91 ++++++++++++------- 1 file changed, 58 insertions(+), 33 deletions(-) diff --git a/extensions/typescript-language-features/src/features/quickFix.ts b/extensions/typescript-language-features/src/features/quickFix.ts index 1e21c2dfcbe..a00a5ee6b11 100644 --- a/extensions/typescript-language-features/src/features/quickFix.ts +++ b/extensions/typescript-language-features/src/features/quickFix.ts @@ -65,19 +65,17 @@ class ApplyFixAllCodeAction implements Command { return; } - if (tsAction.fixName) { - /* __GDPR__ - "quickFixAll.execute" : { - "fixName" : { "classification": "PublicNonPersonalData", "purpose": "FeatureInsight" }, - "${include}": [ - "${TypeScriptCommonProperties}" - ] - } - */ - this.telemetryReporter.logTelemetry('quickFixAll.execute', { - fixName: tsAction.fixName - }); - } + /* __GDPR__ + "quickFixAll.execute" : { + "fixName" : { "classification": "PublicNonPersonalData", "purpose": "FeatureInsight" }, + "${include}": [ + "${TypeScriptCommonProperties}" + ] + } + */ + this.telemetryReporter.logTelemetry('quickFixAll.execute', { + fixName: tsAction.fixName + }); const args: Proto.GetCombinedCodeFixRequestArgs = { scope: { @@ -135,6 +133,30 @@ class DiagnosticsSet { } } +class CodeActionSet { + private _actions: vscode.CodeAction[] = []; + private _fixAllActions = new Set<{}>(); + + public get values() { + return this._actions; + } + + public addAction(action: vscode.CodeAction) { + this._actions.push(action); + } + + public addFixAllAction(fixId: {}, action: vscode.CodeAction) { + if (!this.hasFixAllAction(fixId)) { + this.addAction(action); + this._fixAllActions.add(fixId); + } + } + + public hasFixAllAction(fixId: {}) { + return this._fixAllActions.has(fixId); + } +} + class SupportedCodeActionProvider { private _supportedCodeActions?: Thenable>; @@ -214,26 +236,28 @@ class TypeScriptQuickFixProvider implements vscode.CodeActionProvider { ...typeConverters.Range.toFileRangeRequestArgs(file, diagnostic.range), errorCodes: [+(diagnostic.code!)] }; - const codeFixesResponse = await this.client.execute('getCodeFixes', args, token); - if (codeFixesResponse.body) { - const results: vscode.CodeAction[] = []; - for (const tsCodeFix of codeFixesResponse.body) { - results.push(...await this.getAllFixesForTsCodeAction(document, file, diagnostic, tsCodeFix)); - } - return results; + const { body } = await this.client.execute('getCodeFixes', args, token); + if (!body) { + return []; } - return []; + + const results = new CodeActionSet(); + for (const tsCodeFix of body) { + this.addAllFixesForTsCodeAction(results, document, file, diagnostic, tsCodeFix); + } + return results.values; } - private async getAllFixesForTsCodeAction( + private addAllFixesForTsCodeAction( + results: CodeActionSet, document: vscode.TextDocument, file: string, diagnostic: vscode.Diagnostic, tsAction: Proto.CodeAction - ): Promise> { - const singleFix = this.getSingleFixForTsCodeAction(diagnostic, tsAction); - const fixAll = await this.getFixAllForTsCodeAction(document, file, diagnostic, tsAction as Proto.CodeFixAction); - return fixAll ? [singleFix, fixAll] : [singleFix]; + ): CodeActionSet { + results.addAction(this.getSingleFixForTsCodeAction(diagnostic, tsAction)); + this.addFixAllForTsCodeAction(results, document, file, diagnostic, tsAction as Proto.CodeFixAction); + return results; } private getSingleFixForTsCodeAction( @@ -253,32 +277,33 @@ class TypeScriptQuickFixProvider implements vscode.CodeActionProvider { return codeAction; } - private async getFixAllForTsCodeAction( + private addFixAllForTsCodeAction( + results: CodeActionSet, document: vscode.TextDocument, file: string, diagnostic: vscode.Diagnostic, tsAction: Proto.CodeFixAction, - ): Promise { - if (!tsAction.fixId || !this.client.apiVersion.gte(API.v270)) { - return undefined; + ): CodeActionSet { + if (!tsAction.fixId || !this.client.apiVersion.gte(API.v270) || results.hasFixAllAction(results)) { + return results; } // Make sure there are multiple diagnostics of the same type in the file if (!this.diagnosticsManager.getDiagnostics(document.uri).some(x => x.code === diagnostic.code && x !== diagnostic)) { - return; + return results; } const action = new vscode.CodeAction( tsAction.fixAllDescription || localize('fixAllInFileLabel', '{0} (Fix all in file)', tsAction.description), vscode.CodeActionKind.QuickFix); action.diagnostics = [diagnostic]; - action.command = { command: ApplyFixAllCodeAction.ID, arguments: [file, tsAction], title: '' }; - return action; + results.addFixAllAction(tsAction.fixId, action); + return results; } } From 9e6a525723dc7e429d32e8dca918ef8320092437 Mon Sep 17 00:00:00 2001 From: Matt Bierner Date: Wed, 25 Jul 2018 17:27:03 -0700 Subject: [PATCH 0134/1276] Fixing fix all not applying correct commands on edit --- .../src/features/quickFix.ts | 13 +++++-------- .../src/utils/codeAction.ts | 8 ++++---- 2 files changed, 9 insertions(+), 12 deletions(-) diff --git a/extensions/typescript-language-features/src/features/quickFix.ts b/extensions/typescript-language-features/src/features/quickFix.ts index a00a5ee6b11..e15edeb4b17 100644 --- a/extensions/typescript-language-features/src/features/quickFix.ts +++ b/extensions/typescript-language-features/src/features/quickFix.ts @@ -43,7 +43,7 @@ class ApplyCodeActionCommand implements Command { fixName: action.fixName }); } - return applyCodeActionCommands(this.client, action); + return applyCodeActionCommands(this.client, action.commands); } } @@ -86,17 +86,14 @@ class ApplyFixAllCodeAction implements Command { }; try { - const combinedCodeFixesResponse = await this.client.execute('getCombinedCodeFix', args); - if (!combinedCodeFixesResponse.body) { + const { body } = await this.client.execute('getCombinedCodeFix', args); + if (!body) { return; } - const edit = typeConverters.WorkspaceEdit.fromFileCodeEdits(this.client, combinedCodeFixesResponse.body.changes); + const edit = typeConverters.WorkspaceEdit.fromFileCodeEdits(this.client, body.changes); await vscode.workspace.applyEdit(edit); - - if (combinedCodeFixesResponse.command) { - await vscode.commands.executeCommand(ApplyCodeActionCommand.ID, combinedCodeFixesResponse.command); - } + await applyCodeActionCommands(this.client, body.commands); } catch { // noop } diff --git a/extensions/typescript-language-features/src/utils/codeAction.ts b/extensions/typescript-language-features/src/utils/codeAction.ts index f9dec3a7d4d..e2c71edb370 100644 --- a/extensions/typescript-language-features/src/utils/codeAction.ts +++ b/extensions/typescript-language-features/src/utils/codeAction.ts @@ -27,15 +27,15 @@ export async function applyCodeAction( return false; } } - return applyCodeActionCommands(client, action); + return applyCodeActionCommands(client, action.commands); } export async function applyCodeActionCommands( client: ITypeScriptServiceClient, - action: Proto.CodeAction + commands: ReadonlyArray<{}> | undefined ): Promise { - if (action.commands && action.commands.length) { - for (const command of action.commands) { + if (commands && commands.length) { + for (const command of commands) { const response = await client.execute('applyCodeActionCommand', { command }); if (!response || !response.body) { return false; From edc6b2acdd2950708f4c4f526b8b644f142168cb Mon Sep 17 00:00:00 2001 From: Matt Bierner Date: Wed, 25 Jul 2018 17:29:22 -0700 Subject: [PATCH 0135/1276] Always invoke quick fix command Make sure we always invoke the applyCodeActionCommand. This is needed for telemetry to be sent properly --- .../src/features/quickFix.ts | 37 +++++++++---------- 1 file changed, 17 insertions(+), 20 deletions(-) diff --git a/extensions/typescript-language-features/src/features/quickFix.ts b/extensions/typescript-language-features/src/features/quickFix.ts index e15edeb4b17..00679075cf9 100644 --- a/extensions/typescript-language-features/src/features/quickFix.ts +++ b/extensions/typescript-language-features/src/features/quickFix.ts @@ -30,19 +30,18 @@ class ApplyCodeActionCommand implements Command { public async execute( action: Proto.CodeFixAction ): Promise { - if (action.fixName) { - /* __GDPR__ - "quickFix.execute" : { - "fixName" : { "classification": "PublicNonPersonalData", "purpose": "FeatureInsight" }, - "${include}": [ - "${TypeScriptCommonProperties}" - ] - } - */ - this.telemetryReporter.logTelemetry('quickFix.execute', { - fixName: action.fixName - }); - } + /* __GDPR__ + "quickFix.execute" : { + "fixName" : { "classification": "PublicNonPersonalData", "purpose": "FeatureInsight" }, + "${include}": [ + "${TypeScriptCommonProperties}" + ] + } + */ + this.telemetryReporter.logTelemetry('quickFix.execute', { + fixName: action.fixName + }); + return applyCodeActionCommands(this.client, action.commands); } } @@ -264,13 +263,11 @@ class TypeScriptQuickFixProvider implements vscode.CodeActionProvider { const codeAction = new vscode.CodeAction(tsAction.description, vscode.CodeActionKind.QuickFix); codeAction.edit = getEditForCodeAction(this.client, tsAction); codeAction.diagnostics = [diagnostic]; - if (tsAction.commands) { - codeAction.command = { - command: ApplyCodeActionCommand.ID, - arguments: [tsAction], - title: tsAction.description - }; - } + codeAction.command = { + command: ApplyCodeActionCommand.ID, + arguments: [tsAction], + title: '' + }; return codeAction; } From 700ee37a240d3789dbc093f9e32758f2295ea694 Mon Sep 17 00:00:00 2001 From: Nikolas Date: Thu, 26 Jul 2018 02:31:04 +0200 Subject: [PATCH 0136/1276] Add underscores and asterisks to surrounding pairs (#55054) Same reasons as [here](https://github.com/silvenon/vscode-mdx/pull/6#issue-203819440) --- extensions/markdown-basics/language-configuration.json | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/extensions/markdown-basics/language-configuration.json b/extensions/markdown-basics/language-configuration.json index 23a25ede9cc..ccddf061e75 100644 --- a/extensions/markdown-basics/language-configuration.json +++ b/extensions/markdown-basics/language-configuration.json @@ -36,7 +36,9 @@ "surroundingPairs": [ ["(", ")"], ["[", "]"], - ["`", "`"] + ["`", "`"], + ["_", "_"], + ["*", "*"] ], "folding": { "offSide": true, From 42e0c43645196f9ece4a38c88ce7726ce4d459ef Mon Sep 17 00:00:00 2001 From: Matt Bierner Date: Wed, 25 Jul 2018 17:45:54 -0700 Subject: [PATCH 0137/1276] Use resource map for storing formatting options Try to normalize file cases on case-insensitive file systems --- .../src/features/definitionProviderBase.ts | 2 +- .../src/features/fileConfigurationManager.ts | 19 ++++++++----------- 2 files changed, 9 insertions(+), 12 deletions(-) diff --git a/extensions/typescript-language-features/src/features/definitionProviderBase.ts b/extensions/typescript-language-features/src/features/definitionProviderBase.ts index 8d958648799..029fe0fad64 100644 --- a/extensions/typescript-language-features/src/features/definitionProviderBase.ts +++ b/extensions/typescript-language-features/src/features/definitionProviderBase.ts @@ -32,7 +32,7 @@ export default class TypeScriptDefinitionProviderBase { return locations.map(location => typeConverters.Location.fromTextSpan(this.client.toResource(location.file), location)); } catch { - return []; + return undefined; } } } \ No newline at end of file diff --git a/extensions/typescript-language-features/src/features/fileConfigurationManager.ts b/extensions/typescript-language-features/src/features/fileConfigurationManager.ts index 1869ae9ae1b..8673f3a1c91 100644 --- a/extensions/typescript-language-features/src/features/fileConfigurationManager.ts +++ b/extensions/typescript-language-features/src/features/fileConfigurationManager.ts @@ -8,6 +8,7 @@ import * as Proto from '../protocol'; import { ITypeScriptServiceClient } from '../typescriptService'; import API from '../utils/api'; import { isTypeScriptDocument } from '../utils/languageModeIds'; +import { ResourceMap } from '../utils/resourceMap'; function objsAreEqual(a: T, b: T): boolean { @@ -22,8 +23,8 @@ function objsAreEqual(a: T, b: T): boolean { } interface FileConfiguration { - formatOptions: Proto.FormatCodeSettings; - preferences: Proto.UserPreferences; + readonly formatOptions: Proto.FormatCodeSettings; + readonly preferences: Proto.UserPreferences; } function areFileConfigurationsEqual(a: FileConfiguration, b: FileConfiguration): boolean { @@ -35,18 +36,17 @@ function areFileConfigurationsEqual(a: FileConfiguration, b: FileConfiguration): export default class FileConfigurationManager { private onDidCloseTextDocumentSub: Disposable | undefined; - private formatOptions: { [key: string]: FileConfiguration | undefined } = Object.create(null); + private formatOptions = new ResourceMap(); public constructor( private readonly client: ITypeScriptServiceClient ) { this.onDidCloseTextDocumentSub = Workspace.onDidCloseTextDocument((textDocument) => { - const key = textDocument.uri.toString(); // When a document gets closed delete the cached formatting options. // This is necessary since the tsserver now closed a project when its // last file in it closes which drops the stored formatting options // as well. - delete this.formatOptions[key]; + this.formatOptions.delete(textDocument.uri); }); } @@ -81,15 +81,13 @@ export default class FileConfigurationManager { return; } - const key = document.uri.toString(); - const cachedOptions = this.formatOptions[key]; + const cachedOptions = this.formatOptions.get(document.uri); const currentOptions = this.getFileOptions(document, options); - if (cachedOptions && areFileConfigurationsEqual(cachedOptions, currentOptions)) { return; } - this.formatOptions[key] = currentOptions; + this.formatOptions.set(document.uri, currentOptions); const args: Proto.ConfigureRequestArguments = { file, ...currentOptions, @@ -98,10 +96,9 @@ export default class FileConfigurationManager { } public reset() { - this.formatOptions = Object.create(null); + this.formatOptions.clear(); } - private getFileOptions( document: TextDocument, options: FormattingOptions From d5855b35b2f6f0e7df3c737171aae754111eeda6 Mon Sep 17 00:00:00 2001 From: Matt Bierner Date: Wed, 25 Jul 2018 17:51:05 -0700 Subject: [PATCH 0138/1276] Cleanup - Remove noop optional method - Use double quotes for strings - Mark fields readonly --- .../src/features/directiveCommentCompletions.ts | 17 +++++------------ 1 file changed, 5 insertions(+), 12 deletions(-) diff --git a/extensions/typescript-language-features/src/features/directiveCommentCompletions.ts b/extensions/typescript-language-features/src/features/directiveCommentCompletions.ts index 09a6fcf8c56..8ec98eefb8f 100644 --- a/extensions/typescript-language-features/src/features/directiveCommentCompletions.ts +++ b/extensions/typescript-language-features/src/features/directiveCommentCompletions.ts @@ -12,8 +12,8 @@ import { VersionDependentRegistration } from '../utils/dependentRegistration'; const localize = nls.loadMessageBundle(); interface Directive { - value: string; - description: string; + readonly value: string; + readonly description: string; } const directives: Directive[] = [ @@ -21,17 +21,17 @@ const directives: Directive[] = [ value: '@ts-check', description: localize( 'ts-check', - 'Enables semantic checking in a JavaScript file. Must be at the top of a file.') + "Enables semantic checking in a JavaScript file. Must be at the top of a file.") }, { value: '@ts-nocheck', description: localize( 'ts-nocheck', - 'Disables semantic checking in a JavaScript file. Must be at the top of a file.') + "Disables semantic checking in a JavaScript file. Must be at the top of a file.") }, { value: '@ts-ignore', description: localize( 'ts-ignore', - 'Suppresses @ts-check errors on the next line of a file.') + "Suppresses @ts-check errors on the next line of a file.") } ]; @@ -63,13 +63,6 @@ class DirectiveCommentCompletionProvider implements vscode.CompletionItemProvide } return []; } - - public resolveCompletionItem( - item: vscode.CompletionItem, - _token: vscode.CancellationToken - ) { - return item; - } } export function register( From f97c7435074bf495e7d3c19a6adbba5d3715ecf4 Mon Sep 17 00:00:00 2001 From: Matt Bierner Date: Wed, 25 Jul 2018 17:56:08 -0700 Subject: [PATCH 0139/1276] Use VersionDependentRegistration for update paths on rename Avoids registering class on unsupported ts versions --- .../src/features/updatePathsOnRename.ts | 15 ++++++++++----- .../src/typeScriptServiceClientHost.ts | 6 ++---- 2 files changed, 12 insertions(+), 9 deletions(-) diff --git a/extensions/typescript-language-features/src/features/updatePathsOnRename.ts b/extensions/typescript-language-features/src/features/updatePathsOnRename.ts index 9b2f3c3ce5f..def9ced477a 100644 --- a/extensions/typescript-language-features/src/features/updatePathsOnRename.ts +++ b/extensions/typescript-language-features/src/features/updatePathsOnRename.ts @@ -15,6 +15,7 @@ import { isTypeScriptDocument } from '../utils/languageModeIds'; import { escapeRegExp } from '../utils/regexp'; import * as typeConverters from '../utils/typeConverters'; import FileConfigurationManager from './fileConfigurationManager'; +import { VersionDependentRegistration } from '../utils/dependentRegistration'; const localize = nls.loadMessageBundle(); @@ -26,7 +27,7 @@ enum UpdateImportsOnFileMoveSetting { Never = 'never', } -export class UpdateImportsOnFileRenameHandler { +class UpdateImportsOnFileRenameHandler { private readonly _onDidRenameSub: vscode.Disposable; public constructor( @@ -47,10 +48,6 @@ export class UpdateImportsOnFileRenameHandler { oldResource: vscode.Uri, newResource: vscode.Uri, ): Promise { - if (!this.client.apiVersion.gte(API.v290)) { - return; - } - const targetResource = await this.getTargetResource(newResource); if (!targetResource) { return; @@ -304,3 +301,11 @@ export class UpdateImportsOnFileRenameHandler { } } +export function register( + client: ITypeScriptServiceClient, + fileConfigurationManager: FileConfigurationManager, + handles: (uri: vscode.Uri) => Promise, +) { + return new VersionDependentRegistration(client, API.v290, () => + new UpdateImportsOnFileRenameHandler(client, fileConfigurationManager, handles)); +} \ No newline at end of file diff --git a/extensions/typescript-language-features/src/typeScriptServiceClientHost.ts b/extensions/typescript-language-features/src/typeScriptServiceClientHost.ts index f675bd4f572..8b716b6dd68 100644 --- a/extensions/typescript-language-features/src/typeScriptServiceClientHost.ts +++ b/extensions/typescript-language-features/src/typeScriptServiceClientHost.ts @@ -11,7 +11,7 @@ import { Diagnostic, DiagnosticRelatedInformation, DiagnosticSeverity, DiagnosticTag, Disposable, Memento, Range, Uri, workspace } from 'vscode'; import { DiagnosticKind } from './features/diagnostics'; import FileConfigurationManager from './features/fileConfigurationManager'; -import { UpdateImportsOnFileRenameHandler } from './features/updatePathsOnRename'; +import { register as registerUpdatePathsOnRename } from './features/updatePathsOnRename'; import LanguageProvider from './languageProvider'; import * as Proto from './protocol'; import * as PConst from './protocol.const'; @@ -45,7 +45,6 @@ export default class TypeScriptServiceClientHost { private readonly disposables: Disposable[] = []; private readonly versionStatus: VersionStatus; private readonly fileConfigurationManager: FileConfigurationManager; - private readonly updateImportsOnFileRenameHandler: UpdateImportsOnFileRenameHandler; private reportStyleCheckAsWarnings: boolean = true; @@ -101,7 +100,7 @@ export default class TypeScriptServiceClientHost { this.languagePerId.set(description.id, manager); } - this.updateImportsOnFileRenameHandler = new UpdateImportsOnFileRenameHandler(this.client, this.fileConfigurationManager, uri => this.handles(uri)); + this.disposables.push(registerUpdatePathsOnRename(this.client, this.fileConfigurationManager, uri => this.handles(uri))); this.client.ensureServiceStarted(); this.client.onReady(() => { @@ -152,7 +151,6 @@ export default class TypeScriptServiceClientHost { this.typingsStatus.dispose(); this.ataProgressReporter.dispose(); this.fileConfigurationManager.dispose(); - this.updateImportsOnFileRenameHandler.dispose(); } public get serviceClient(): TypeScriptServiceClient { From 410509137b22c0411307be1256acda7347453bf4 Mon Sep 17 00:00:00 2001 From: Matt Bierner Date: Wed, 25 Jul 2018 18:17:56 -0700 Subject: [PATCH 0140/1276] Add base Disposable class to help manage disposables --- .../src/features/bufferSyncSupport.ts | 23 ++++---- .../src/features/languageConfiguration.ts | 12 ++--- .../src/features/tagClosing.ts | 20 +++---- .../src/languageProvider.ts | 53 +++++++++---------- .../src/typeScriptServiceClientHost.ts | 48 +++++++---------- .../src/typescriptServiceClient.ts | 45 ++++++---------- .../src/utils/dependentRegistration.ts | 14 ++--- .../src/utils/dispose.ts | 25 ++++++++- 8 files changed, 113 insertions(+), 127 deletions(-) diff --git a/extensions/typescript-language-features/src/features/bufferSyncSupport.ts b/extensions/typescript-language-features/src/features/bufferSyncSupport.ts index f6b4e8c174e..d4be308cfb0 100644 --- a/extensions/typescript-language-features/src/features/bufferSyncSupport.ts +++ b/extensions/typescript-language-features/src/features/bufferSyncSupport.ts @@ -4,12 +4,12 @@ *--------------------------------------------------------------------------------------------*/ import * as fs from 'fs'; -import { CancellationTokenSource, Disposable, EventEmitter, TextDocument, TextDocumentChangeEvent, TextDocumentContentChangeEvent, Uri, workspace } from 'vscode'; +import { CancellationTokenSource, EventEmitter, TextDocument, TextDocumentChangeEvent, TextDocumentContentChangeEvent, Uri, workspace } from 'vscode'; import * as Proto from '../protocol'; import { ITypeScriptServiceClient } from '../typescriptService'; import API from '../utils/api'; import { Delayer } from '../utils/async'; -import { disposeAll } from '../utils/dispose'; +import { Disposable } from '../utils/dispose'; import * as languageModeIds from '../utils/languageModeIds'; import { ResourceMap } from '../utils/resourceMap'; import * as typeConverters from '../utils/typeConverters'; @@ -168,14 +168,13 @@ class GetErrRequest { } } -export default class BufferSyncSupport { +export default class BufferSyncSupport extends Disposable { private readonly client: ITypeScriptServiceClient; private _validateJavaScript: boolean = true; private _validateTypeScript: boolean = true; private readonly modeIds: Set; - private readonly disposables: Disposable[] = []; private readonly syncedBuffers: SyncedBufferMap; private readonly pendingDiagnostics: PendingDiagnostics; private readonly diagnosticDelayer: Delayer; @@ -186,6 +185,7 @@ export default class BufferSyncSupport { client: ITypeScriptServiceClient, modeIds: string[] ) { + super(); this.client = client; this.modeIds = new Set(modeIds); @@ -196,10 +196,10 @@ export default class BufferSyncSupport { this.pendingDiagnostics = new PendingDiagnostics(pathNormalizer); this.updateConfiguration(); - workspace.onDidChangeConfiguration(this.updateConfiguration, this, this.disposables); + workspace.onDidChangeConfiguration(this.updateConfiguration, this, this._disposables); } - private readonly _onDelete = new EventEmitter(); + private readonly _onDelete = this._register(new EventEmitter()); public readonly onDelete = this._onDelete.event; public listen(): void { @@ -207,9 +207,9 @@ export default class BufferSyncSupport { return; } this.listening = true; - workspace.onDidOpenTextDocument(this.openTextDocument, this, this.disposables); - workspace.onDidCloseTextDocument(this.onDidCloseTextDocument, this, this.disposables); - workspace.onDidChangeTextDocument(this.onDidChangeTextDocument, this, this.disposables); + workspace.onDidOpenTextDocument(this.openTextDocument, this, this._disposables); + workspace.onDidCloseTextDocument(this.onDidCloseTextDocument, this, this._disposables); + workspace.onDidChangeTextDocument(this.onDidChangeTextDocument, this, this._disposables); workspace.textDocuments.forEach(this.openTextDocument, this); } @@ -231,11 +231,6 @@ export default class BufferSyncSupport { } } - public dispose(): void { - disposeAll(this.disposables); - this._onDelete.dispose(); - } - public openTextDocument(document: TextDocument): void { if (!this.modeIds.has(document.languageId)) { return; diff --git a/extensions/typescript-language-features/src/features/languageConfiguration.ts b/extensions/typescript-language-features/src/features/languageConfiguration.ts index b3eb4ef23dd..8ee1cfecdad 100644 --- a/extensions/typescript-language-features/src/features/languageConfiguration.ts +++ b/extensions/typescript-language-features/src/features/languageConfiguration.ts @@ -9,7 +9,7 @@ * ------------------------------------------------------------------------------------------ */ import * as vscode from 'vscode'; -import { disposeAll } from '../utils/dispose'; +import { Disposable } from '../utils/dispose'; import * as languageModeIds from '../utils/languageModeIds'; const jsTsLanguageConfiguration: vscode.LanguageConfiguration = { @@ -64,10 +64,10 @@ const jsxTagsLanguageConfiguration: vscode.LanguageConfiguration = { ], }; -export class LanguageConfigurationManager { - private readonly _registrations: vscode.Disposable[] = []; +export class LanguageConfigurationManager extends Disposable { constructor() { + super(); const standardLanguages = [ languageModeIds.javascript, languageModeIds.javascriptreact, @@ -82,10 +82,6 @@ export class LanguageConfigurationManager { } private registerConfiguration(language: string, config: vscode.LanguageConfiguration) { - this._registrations.push(vscode.languages.setLanguageConfiguration(language, config)); - } - - dispose() { - disposeAll(this._registrations); + this._register(vscode.languages.setLanguageConfiguration(language, config)); } } diff --git a/extensions/typescript-language-features/src/features/tagClosing.ts b/extensions/typescript-language-features/src/features/tagClosing.ts index 66af4920ef9..40839c30c65 100644 --- a/extensions/typescript-language-features/src/features/tagClosing.ts +++ b/extensions/typescript-language-features/src/features/tagClosing.ts @@ -8,19 +8,19 @@ import * as Proto from '../protocol'; import { ITypeScriptServiceClient } from '../typescriptService'; import API from '../utils/api'; import { ConditionalRegistration, ConfigurationDependentRegistration, VersionDependentRegistration } from '../utils/dependentRegistration'; -import { disposeAll } from '../utils/dispose'; +import { Disposable } from '../utils/dispose'; import * as typeConverters from '../utils/typeConverters'; -class TagClosing { +class TagClosing extends Disposable { private _disposed = false; private _timeout: NodeJS.Timer | undefined = undefined; private _cancel: vscode.CancellationTokenSource | undefined = undefined; - private readonly _disposables: vscode.Disposable[] = []; constructor( private readonly client: ITypeScriptServiceClient ) { + super(); vscode.workspace.onDidChangeTextDocument( event => this.onDidChangeTextDocument(event.document, event.contentChanges), null, @@ -28,10 +28,9 @@ class TagClosing { } public dispose() { + super.dispose(); this._disposed = true; - disposeAll(this._disposables); - if (this._timeout) { clearTimeout(this._timeout); this._timeout = undefined; @@ -136,24 +135,19 @@ class TagClosing { } } -export class ActiveDocumentDependentRegistration { +export class ActiveDocumentDependentRegistration extends Disposable { private readonly _registration: ConditionalRegistration; - private readonly _disposables: vscode.Disposable[] = []; constructor( private readonly selector: vscode.DocumentSelector, register: () => vscode.Disposable, ) { - this._registration = new ConditionalRegistration(register); + super(); + this._registration = this._register(new ConditionalRegistration(register)); vscode.window.onDidChangeActiveTextEditor(this.update, this, this._disposables); this.update(); } - public dispose() { - disposeAll(this._disposables); - this._registration.dispose(); - } - private update() { const editor = vscode.window.activeTextEditor; const enabled = !!(editor && vscode.languages.match(this.selector, editor.document)); diff --git a/extensions/typescript-language-features/src/languageProvider.ts b/extensions/typescript-language-features/src/languageProvider.ts index 31ba616b8c1..aad5f1a3a44 100644 --- a/extensions/typescript-language-features/src/languageProvider.ts +++ b/extensions/typescript-language-features/src/languageProvider.ts @@ -10,7 +10,7 @@ import { DiagnosticKind } from './features/diagnostics'; import FileConfigurationManager from './features/fileConfigurationManager'; import TypeScriptServiceClient from './typescriptServiceClient'; import { CommandManager } from './utils/commandManager'; -import { disposeAll } from './utils/dispose'; +import { Disposable } from './utils/dispose'; import * as fileSchemes from './utils/fileSchemes'; import { LanguageDescription } from './utils/languageDescription'; import { memoize } from './utils/memoize'; @@ -21,8 +21,7 @@ import TypingsStatus from './utils/typingsStatus'; const validateSetting = 'validate.enable'; const suggestionSetting = 'suggestionActions.enabled'; -export default class LanguageProvider { - private readonly disposables: vscode.Disposable[] = []; +export default class LanguageProvider extends Disposable { constructor( private readonly client: TypeScriptServiceClient, @@ -32,7 +31,8 @@ export default class LanguageProvider { private readonly typingsStatus: TypingsStatus, private readonly fileConfigurationManager: FileConfigurationManager ) { - vscode.workspace.onDidChangeConfiguration(this.configurationChanged, this, this.disposables); + super(); + vscode.workspace.onDidChangeConfiguration(this.configurationChanged, this, this._disposables); this.configurationChanged(); client.onReady(async () => { @@ -40,9 +40,6 @@ export default class LanguageProvider { }); } - public dispose(): void { - disposeAll(this.disposables); - } @memoize private get documentSelector(): vscode.DocumentFilter[] { @@ -60,27 +57,27 @@ export default class LanguageProvider { const cachedResponse = new CachedNavTreeResponse(); - this.disposables.push((await import('./features/completions')).register(selector, this.client, this.typingsStatus, this.fileConfigurationManager, this.commandManager)); - this.disposables.push((await import('./features/definitions')).register(selector, this.client)); - this.disposables.push((await import('./features/directiveCommentCompletions')).register(selector, this.client)); - this.disposables.push((await import('./features/documentHighlight')).register(selector, this.client)); - this.disposables.push((await import('./features/documentSymbol')).register(selector, this.client)); - this.disposables.push((await import('./features/folding')).register(selector, this.client)); - this.disposables.push((await import('./features/formatting')).register(selector, this.description.id, this.client, this.fileConfigurationManager)); - this.disposables.push((await import('./features/hover')).register(selector, this.client)); - this.disposables.push((await import('./features/implementations')).register(selector, this.client)); - this.disposables.push((await import('./features/implementationsCodeLens')).register(selector, this.description.id, this.client, cachedResponse)); - this.disposables.push((await import('./features/jsDocCompletions')).register(selector, this.client, this.commandManager)); - this.disposables.push((await import('./features/organizeImports')).register(selector, this.client, this.commandManager, this.fileConfigurationManager, this.telemetryReporter)); - this.disposables.push((await import('./features/quickFix')).register(selector, this.client, this.fileConfigurationManager, this.commandManager, this.client.diagnosticsManager, this.telemetryReporter)); - this.disposables.push((await import('./features/refactor')).register(selector, this.client, this.fileConfigurationManager, this.commandManager, this.telemetryReporter)); - this.disposables.push((await import('./features/references')).register(selector, this.client)); - this.disposables.push((await import('./features/referencesCodeLens')).register(selector, this.description.id, this.client, cachedResponse)); - this.disposables.push((await import('./features/rename')).register(selector, this.client)); - this.disposables.push((await import('./features/signatureHelp')).register(selector, this.client)); - this.disposables.push((await import('./features/tagClosing')).register(selector, this.description.id, this.client)); - this.disposables.push((await import('./features/typeDefinitions')).register(selector, this.client)); - this.disposables.push((await import('./features/workspaceSymbols')).register(this.client, this.description.modeIds)); + this._register((await import('./features/completions')).register(selector, this.client, this.typingsStatus, this.fileConfigurationManager, this.commandManager)); + this._register((await import('./features/definitions')).register(selector, this.client)); + this._register((await import('./features/directiveCommentCompletions')).register(selector, this.client)); + this._register((await import('./features/documentHighlight')).register(selector, this.client)); + this._register((await import('./features/documentSymbol')).register(selector, this.client)); + this._register((await import('./features/folding')).register(selector, this.client)); + this._register((await import('./features/formatting')).register(selector, this.description.id, this.client, this.fileConfigurationManager)); + this._register((await import('./features/hover')).register(selector, this.client)); + this._register((await import('./features/implementations')).register(selector, this.client)); + this._register((await import('./features/implementationsCodeLens')).register(selector, this.description.id, this.client, cachedResponse)); + this._register((await import('./features/jsDocCompletions')).register(selector, this.client, this.commandManager)); + this._register((await import('./features/organizeImports')).register(selector, this.client, this.commandManager, this.fileConfigurationManager, this.telemetryReporter)); + this._register((await import('./features/quickFix')).register(selector, this.client, this.fileConfigurationManager, this.commandManager, this.client.diagnosticsManager, this.telemetryReporter)); + this._register((await import('./features/refactor')).register(selector, this.client, this.fileConfigurationManager, this.commandManager, this.telemetryReporter)); + this._register((await import('./features/references')).register(selector, this.client)); + this._register((await import('./features/referencesCodeLens')).register(selector, this.description.id, this.client, cachedResponse)); + this._register((await import('./features/rename')).register(selector, this.client)); + this._register((await import('./features/signatureHelp')).register(selector, this.client)); + this._register((await import('./features/tagClosing')).register(selector, this.description.id, this.client)); + this._register((await import('./features/typeDefinitions')).register(selector, this.client)); + this._register((await import('./features/workspaceSymbols')).register(this.client, this.description.modeIds)); } private configurationChanged(): void { diff --git a/extensions/typescript-language-features/src/typeScriptServiceClientHost.ts b/extensions/typescript-language-features/src/typeScriptServiceClientHost.ts index 8b716b6dd68..522c1f8364e 100644 --- a/extensions/typescript-language-features/src/typeScriptServiceClientHost.ts +++ b/extensions/typescript-language-features/src/typeScriptServiceClientHost.ts @@ -8,7 +8,7 @@ * https://github.com/Microsoft/TypeScript-Sublime-Plugin/blob/master/TypeScript%20Indent.tmPreferences * ------------------------------------------------------------------------------------------ */ -import { Diagnostic, DiagnosticRelatedInformation, DiagnosticSeverity, DiagnosticTag, Disposable, Memento, Range, Uri, workspace } from 'vscode'; +import { Diagnostic, DiagnosticRelatedInformation, DiagnosticSeverity, DiagnosticTag, Memento, Range, Uri, workspace } from 'vscode'; import { DiagnosticKind } from './features/diagnostics'; import FileConfigurationManager from './features/fileConfigurationManager'; import { register as registerUpdatePathsOnRename } from './features/updatePathsOnRename'; @@ -18,7 +18,7 @@ import * as PConst from './protocol.const'; import TypeScriptServiceClient from './typescriptServiceClient'; import API from './utils/api'; import { CommandManager } from './utils/commandManager'; -import { disposeAll } from './utils/dispose'; +import { Disposable } from './utils/dispose'; import { LanguageDescription, DiagnosticLanguage } from './utils/languageDescription'; import LogDirectoryProvider from './utils/logDirectoryProvider'; import { TypeScriptServerPlugin } from './utils/plugins'; @@ -36,13 +36,11 @@ const styleCheckDiagnostics = [ 7030 // not all code paths return a value ]; -export default class TypeScriptServiceClientHost { - private readonly ataProgressReporter: AtaProgressReporter; +export default class TypeScriptServiceClientHost extends Disposable { private readonly typingsStatus: TypingsStatus; private readonly client: TypeScriptServiceClient; private readonly languages: LanguageProvider[] = []; private readonly languagePerId = new Map(); - private readonly disposables: Disposable[] = []; private readonly versionStatus: VersionStatus; private readonly fileConfigurationManager: FileConfigurationManager; @@ -55,6 +53,7 @@ export default class TypeScriptServiceClientHost { private readonly commandManager: CommandManager, logDirectoryProvider: LogDirectoryProvider ) { + super(); const handleProjectCreateOrDelete = () => { this.client.execute('reloadProjects', null, false); this.triggerAllDiagnostics(); @@ -65,10 +64,10 @@ export default class TypeScriptServiceClientHost { }, 1500); }; const configFileWatcher = workspace.createFileSystemWatcher('**/[tj]sconfig.json'); - this.disposables.push(configFileWatcher); - configFileWatcher.onDidCreate(handleProjectCreateOrDelete, this, this.disposables); - configFileWatcher.onDidDelete(handleProjectCreateOrDelete, this, this.disposables); - configFileWatcher.onDidChange(handleProjectChange, this, this.disposables); + this._register(configFileWatcher); + configFileWatcher.onDidCreate(handleProjectCreateOrDelete, this, this._disposables); + configFileWatcher.onDidDelete(handleProjectCreateOrDelete, this, this._disposables); + configFileWatcher.onDidChange(handleProjectChange, this, this._disposables); const allModeIds = this.getAllModeIds(descriptions); this.client = new TypeScriptServiceClient( @@ -77,30 +76,30 @@ export default class TypeScriptServiceClientHost { plugins, logDirectoryProvider, allModeIds); - this.disposables.push(this.client); + this._register(this.client); this.client.onDiagnosticsReceived(({ kind, resource, diagnostics }) => { this.diagnosticsReceived(kind, resource, diagnostics); - }, null, this.disposables); + }, null, this._disposables); - this.client.onConfigDiagnosticsReceived(diag => this.configFileDiagnosticsReceived(diag), null, this.disposables); - this.client.onResendModelsRequested(() => this.populateService(), null, this.disposables); + this.client.onConfigDiagnosticsReceived(diag => this.configFileDiagnosticsReceived(diag), null, this._disposables); + this.client.onResendModelsRequested(() => this.populateService(), null, this._disposables); this.versionStatus = new VersionStatus(resource => this.client.toPath(resource)); - this.disposables.push(this.versionStatus); + this._register(this.versionStatus); - this.typingsStatus = new TypingsStatus(this.client); - this.ataProgressReporter = new AtaProgressReporter(this.client); - this.fileConfigurationManager = new FileConfigurationManager(this.client); + this._register(new AtaProgressReporter(this.client)); + this.typingsStatus = this._register(new TypingsStatus(this.client)); + this.fileConfigurationManager = this._register(new FileConfigurationManager(this.client)); for (const description of descriptions) { const manager = new LanguageProvider(this.client, description, this.commandManager, this.client.telemetryReporter, this.typingsStatus, this.fileConfigurationManager); this.languages.push(manager); - this.disposables.push(manager); + this._register(manager); this.languagePerId.set(description.id, manager); } - this.disposables.push(registerUpdatePathsOnRename(this.client, this.fileConfigurationManager, uri => this.handles(uri))); + this._register(registerUpdatePathsOnRename(this.client, this.fileConfigurationManager, uri => this.handles(uri))); this.client.ensureServiceStarted(); this.client.onReady(() => { @@ -125,7 +124,7 @@ export default class TypeScriptServiceClientHost { }; const manager = new LanguageProvider(this.client, description, this.commandManager, this.client.telemetryReporter, this.typingsStatus, this.fileConfigurationManager); this.languages.push(manager); - this.disposables.push(manager); + this._register(manager); this.languagePerId.set(description.id, manager); } }); @@ -134,7 +133,7 @@ export default class TypeScriptServiceClientHost { this.triggerAllDiagnostics(); }); - workspace.onDidChangeConfiguration(this.configurationChanged, this, this.disposables); + workspace.onDidChangeConfiguration(this.configurationChanged, this, this._disposables); this.configurationChanged(); } @@ -146,13 +145,6 @@ export default class TypeScriptServiceClientHost { return allModeIds; } - public dispose(): void { - disposeAll(this.disposables); - this.typingsStatus.dispose(); - this.ataProgressReporter.dispose(); - this.fileConfigurationManager.dispose(); - } - public get serviceClient(): TypeScriptServiceClient { return this.client; } diff --git a/extensions/typescript-language-features/src/typescriptServiceClient.ts b/extensions/typescript-language-features/src/typescriptServiceClient.ts index 88ad494c3f6..1655c6b5419 100644 --- a/extensions/typescript-language-features/src/typescriptServiceClient.ts +++ b/extensions/typescript-language-features/src/typescriptServiceClient.ts @@ -6,7 +6,7 @@ import * as cp from 'child_process'; import * as fs from 'fs'; import * as path from 'path'; -import { CancellationToken, commands, Disposable, env, EventEmitter, Memento, MessageItem, Uri, window, workspace } from 'vscode'; +import { CancellationToken, commands, env, EventEmitter, Memento, MessageItem, Uri, window, workspace } from 'vscode'; import * as nls from 'vscode-nls'; import BufferSyncSupport from './features/bufferSyncSupport'; import { DiagnosticKind, DiagnosticsManager } from './features/diagnostics'; @@ -14,7 +14,7 @@ import * as Proto from './protocol'; import { ITypeScriptServiceClient } from './typescriptService'; import API from './utils/api'; import { TsServerLogLevel, TypeScriptServiceConfiguration } from './utils/configuration'; -import { disposeAll } from './utils/dispose'; +import { Disposable } from './utils/dispose'; import * as electron from './utils/electron'; import * as fileSchemes from './utils/fileSchemes'; import * as is from './utils/is'; @@ -30,9 +30,6 @@ import { TypeScriptVersion, TypeScriptVersionProvider } from './utils/versionPro import { ICallback, Reader } from './utils/wireProtocol'; - - - const localize = nls.loadMessageBundle(); interface CallbackItem { @@ -159,7 +156,7 @@ export interface TsDiagnostics { readonly diagnostics: Proto.Diagnostic[]; } -export default class TypeScriptServiceClient implements ITypeScriptServiceClient { +export default class TypeScriptServiceClient extends Disposable implements ITypeScriptServiceClient { private static readonly WALK_THROUGH_SNIPPET_SCHEME_COLON = `${fileSchemes.walkThroughSnippet}:`; private pathSeparator: string; @@ -194,8 +191,6 @@ export default class TypeScriptServiceClient implements ITypeScriptServiceClient */ private _tsserverVersion: string | undefined; - private readonly disposables: Disposable[] = []; - public readonly bufferSyncSupport: BufferSyncSupport; public readonly diagnosticsManager: DiagnosticsManager; @@ -206,6 +201,7 @@ export default class TypeScriptServiceClient implements ITypeScriptServiceClient private readonly logDirectoryProvider: LogDirectoryProvider, allModeIds: string[] ) { + super(); this.pathSeparator = path.sep; this.lastStart = Date.now(); @@ -235,7 +231,7 @@ export default class TypeScriptServiceClient implements ITypeScriptServiceClient this.diagnosticsManager = new DiagnosticsManager('typescript'); this.bufferSyncSupport.onDelete(resource => { this.diagnosticsManager.delete(resource); - }, null, this.disposables); + }, null, this._disposables); workspace.onDidChangeConfiguration(() => { const oldConfiguration = this._configuration; @@ -256,9 +252,9 @@ export default class TypeScriptServiceClient implements ITypeScriptServiceClient this.restartTsServer(); } } - }, this, this.disposables); + }, this, this._disposables); this.telemetryReporter = new TelemetryReporter(() => this._tsserverVersion || this._apiVersion.versionString); - this.disposables.push(this.telemetryReporter); + this._register(this.telemetryReporter); } public get configuration() { @@ -266,22 +262,15 @@ export default class TypeScriptServiceClient implements ITypeScriptServiceClient } public dispose() { + super.dispose(); + this.bufferSyncSupport.dispose(); - this._onTsServerStarted.dispose(); - this._onDidBeginInstallTypings.dispose(); - this._onDidEndInstallTypings.dispose(); - this._onTypesInstallerInitializationFailed.dispose(); if (this.servicePromise) { this.servicePromise.then(childProcess => { childProcess.kill(); }).then(undefined, () => void 0); } - - disposeAll(this.disposables); - this._onDiagnosticsReceived.dispose(); - this._onConfigDiagnosticsReceived.dispose(); - this._onResendModelsRequested.dispose(); } public restartTsServer(): void { @@ -302,28 +291,28 @@ export default class TypeScriptServiceClient implements ITypeScriptServiceClient } } - private readonly _onTsServerStarted = new EventEmitter(); + private readonly _onTsServerStarted = this._register(new EventEmitter()); public readonly onTsServerStarted = this._onTsServerStarted.event; - private readonly _onDiagnosticsReceived = new EventEmitter(); + private readonly _onDiagnosticsReceived = this._register(new EventEmitter()); public readonly onDiagnosticsReceived = this._onDiagnosticsReceived.event; - private readonly _onConfigDiagnosticsReceived = new EventEmitter(); + private readonly _onConfigDiagnosticsReceived = this._register(new EventEmitter()); public readonly onConfigDiagnosticsReceived = this._onConfigDiagnosticsReceived.event; - private readonly _onResendModelsRequested = new EventEmitter(); + private readonly _onResendModelsRequested = this._register(new EventEmitter()); public readonly onResendModelsRequested = this._onResendModelsRequested.event; - private readonly _onProjectLanguageServiceStateChanged = new EventEmitter(); + private readonly _onProjectLanguageServiceStateChanged = this._register(new EventEmitter()); public readonly onProjectLanguageServiceStateChanged = this._onProjectLanguageServiceStateChanged.event; - private readonly _onDidBeginInstallTypings = new EventEmitter(); + private readonly _onDidBeginInstallTypings = this._register(new EventEmitter()); public readonly onDidBeginInstallTypings = this._onDidBeginInstallTypings.event; - private readonly _onDidEndInstallTypings = new EventEmitter(); + private readonly _onDidEndInstallTypings = this._register(new EventEmitter()); public readonly onDidEndInstallTypings = this._onDidEndInstallTypings.event; - private readonly _onTypesInstallerInitializationFailed = new EventEmitter(); + private readonly _onTypesInstallerInitializationFailed = this._register(new EventEmitter()); public readonly onTypesInstallerInitializationFailed = this._onTypesInstallerInitializationFailed.event; public get apiVersion(): API { diff --git a/extensions/typescript-language-features/src/utils/dependentRegistration.ts b/extensions/typescript-language-features/src/utils/dependentRegistration.ts index 232d6b8e2cf..434379f57e1 100644 --- a/extensions/typescript-language-features/src/utils/dependentRegistration.ts +++ b/extensions/typescript-language-features/src/utils/dependentRegistration.ts @@ -6,7 +6,7 @@ import * as vscode from 'vscode'; import { ITypeScriptServiceClient } from '../typescriptService'; import API from './api'; -import { disposeAll } from './dispose'; +import { Disposable } from './dispose'; export class ConditionalRegistration { private registration: vscode.Disposable | undefined = undefined; @@ -36,15 +36,15 @@ export class ConditionalRegistration { } } -export class VersionDependentRegistration { +export class VersionDependentRegistration extends Disposable { private readonly _registration: ConditionalRegistration; - private readonly _disposables: vscode.Disposable[] = []; constructor( private readonly client: ITypeScriptServiceClient, private readonly minVersion: API, register: () => vscode.Disposable, ) { + super(); this._registration = new ConditionalRegistration(register); this.update(client.apiVersion); @@ -55,7 +55,7 @@ export class VersionDependentRegistration { } public dispose() { - disposeAll(this._disposables); + super.dispose(); this._registration.dispose(); } @@ -65,22 +65,22 @@ export class VersionDependentRegistration { } -export class ConfigurationDependentRegistration { +export class ConfigurationDependentRegistration extends Disposable { private readonly _registration: ConditionalRegistration; - private readonly _disposables: vscode.Disposable[] = []; constructor( private readonly language: string, private readonly configValue: string, register: () => vscode.Disposable, ) { + super(); this._registration = new ConditionalRegistration(register); this.update(); vscode.workspace.onDidChangeConfiguration(this.update, this, this._disposables); } public dispose() { - disposeAll(this._disposables); + super.dispose(); this._registration.dispose(); } diff --git a/extensions/typescript-language-features/src/utils/dispose.ts b/extensions/typescript-language-features/src/utils/dispose.ts index b7c72f8b8b4..a0b91f441b2 100644 --- a/extensions/typescript-language-features/src/utils/dispose.ts +++ b/extensions/typescript-language-features/src/utils/dispose.ts @@ -5,7 +5,7 @@ import * as vscode from 'vscode'; -export function disposeAll(disposables: vscode.Disposable[]) { +function disposeAll(disposables: vscode.Disposable[]) { while (disposables.length) { const item = disposables.pop(); if (item) { @@ -13,3 +13,26 @@ export function disposeAll(disposables: vscode.Disposable[]) { } } } + +export abstract class Disposable { + private _isDisposed = false; + + protected _disposables: vscode.Disposable[] = []; + + public dispose(): any { + if (this._isDisposed) { + return; + } + this._isDisposed = true; + disposeAll(this._disposables); + } + + protected _register(value: T): T { + if (this._isDisposed) { + value.dispose(); + } else { + this._disposables.push(value); + } + return value; + } +} \ No newline at end of file From a1af04f57110d6a6c791116ad1275c0090702bdc Mon Sep 17 00:00:00 2001 From: Matt Bierner Date: Wed, 25 Jul 2018 18:34:12 -0700 Subject: [PATCH 0141/1276] Prefer namespace imports for 'vscode' --- .../src/features/baseCodeLensProvider.ts | 38 ++++---- .../src/features/bufferSyncSupport.ts | 50 +++++----- .../src/features/definitionProviderBase.ts | 10 +- .../src/features/fileConfigurationManager.ts | 38 ++++---- .../src/features/jsDocCompletions.ts | 52 +++++------ .../src/typeScriptServiceClientHost.ts | 60 ++++++------ .../src/typescriptService.ts | 92 +++++++++---------- .../src/typescriptServiceClient.ts | 72 +++++++-------- .../src/utils/codeAction.ts | 6 +- .../src/utils/configuration.ts | 22 ++--- .../src/utils/logger.ts | 6 +- .../src/utils/pluginPathsProvider.ts | 4 +- .../src/utils/plugins.ts | 4 +- .../src/utils/previewer.ts | 10 +- .../src/utils/relativePathResolver.ts | 4 +- .../src/utils/resourceMap.ts | 14 +-- .../src/utils/tracer.ts | 6 +- .../src/utils/typingsStatus.ts | 22 ++--- .../src/utils/versionPicker.ts | 12 +-- .../src/utils/versionProvider.ts | 15 ++- 20 files changed, 266 insertions(+), 271 deletions(-) diff --git a/extensions/typescript-language-features/src/features/baseCodeLensProvider.ts b/extensions/typescript-language-features/src/features/baseCodeLensProvider.ts index 9576008eab4..6204d3521ac 100644 --- a/extensions/typescript-language-features/src/features/baseCodeLensProvider.ts +++ b/extensions/typescript-language-features/src/features/baseCodeLensProvider.ts @@ -3,18 +3,18 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -import { CancellationToken, CodeLens, CodeLensProvider, Event, EventEmitter, Position, Range, TextDocument, Uri } from 'vscode'; +import * as vscode from 'vscode'; import * as Proto from '../protocol'; import { ITypeScriptServiceClient } from '../typescriptService'; import { escapeRegExp } from '../utils/regexp'; import * as typeConverters from '../utils/typeConverters'; -export class ReferencesCodeLens extends CodeLens { +export class ReferencesCodeLens extends vscode.CodeLens { constructor( - public document: Uri, + public document: vscode.Uri, public file: string, - range: Range + range: vscode.Range ) { super(range); } @@ -26,7 +26,7 @@ export class CachedNavTreeResponse { private document: string = ''; public execute( - document: TextDocument, + document: vscode.TextDocument, f: () => Promise ) { if (this.matches(document)) { @@ -36,12 +36,12 @@ export class CachedNavTreeResponse { return this.update(document, f()); } - private matches(document: TextDocument): boolean { + private matches(document: vscode.TextDocument): boolean { return this.version === document.version && this.document === document.uri.toString(); } private update( - document: TextDocument, + document: vscode.TextDocument, response: Promise ): Promise { this.response = response; @@ -51,19 +51,19 @@ export class CachedNavTreeResponse { } } -export abstract class TypeScriptBaseCodeLensProvider implements CodeLensProvider { - private onDidChangeCodeLensesEmitter = new EventEmitter(); +export abstract class TypeScriptBaseCodeLensProvider implements vscode.CodeLensProvider { + private onDidChangeCodeLensesEmitter = new vscode.EventEmitter(); public constructor( protected client: ITypeScriptServiceClient, private cachedResponse: CachedNavTreeResponse ) { } - public get onDidChangeCodeLenses(): Event { + public get onDidChangeCodeLenses(): vscode.Event { return this.onDidChangeCodeLensesEmitter.event; } - async provideCodeLenses(document: TextDocument, token: CancellationToken): Promise { + async provideCodeLenses(document: vscode.TextDocument, token: vscode.CancellationToken): Promise { const filepath = this.client.toPath(document.uri); if (!filepath) { return []; @@ -76,7 +76,7 @@ export abstract class TypeScriptBaseCodeLensProvider implements CodeLensProvider } const tree = response.body; - const referenceableSpans: Range[] = []; + const referenceableSpans: vscode.Range[] = []; if (tree && tree.childItems) { tree.childItems.forEach(item => this.walkNavTree(document, item, null, referenceableSpans)); } @@ -87,16 +87,16 @@ export abstract class TypeScriptBaseCodeLensProvider implements CodeLensProvider } protected abstract extractSymbol( - document: TextDocument, + document: vscode.TextDocument, item: Proto.NavigationTree, parent: Proto.NavigationTree | null - ): Range | null; + ): vscode.Range | null; private walkNavTree( - document: TextDocument, + document: vscode.TextDocument, item: Proto.NavigationTree, parent: Proto.NavigationTree | null, - results: Range[] + results: vscode.Range[] ): void { if (!item) { return; @@ -109,7 +109,7 @@ export abstract class TypeScriptBaseCodeLensProvider implements CodeLensProvider (item.childItems || []).forEach(child => this.walkNavTree(document, child, item, results)); } - protected getSymbolRange(document: TextDocument, item: Proto.NavigationTree): Range | null { + protected getSymbolRange(document: vscode.TextDocument, item: Proto.NavigationTree): vscode.Range | null { if (!item) { return null; } @@ -131,8 +131,8 @@ export abstract class TypeScriptBaseCodeLensProvider implements CodeLensProvider const identifierMatch = new RegExp(`^(.*?(\\b|\\W))${escapeRegExp(item.text || '')}(\\b|\\W)`, 'gm'); const match = identifierMatch.exec(text); const prefixLength = match ? match.index + match[1].length : 0; - const startOffset = document.offsetAt(new Position(range.start.line, range.start.character)) + prefixLength; - return new Range( + const startOffset = document.offsetAt(new vscode.Position(range.start.line, range.start.character)) + prefixLength; + return new vscode.Range( document.positionAt(startOffset), document.positionAt(startOffset + item.text.length)); } diff --git a/extensions/typescript-language-features/src/features/bufferSyncSupport.ts b/extensions/typescript-language-features/src/features/bufferSyncSupport.ts index d4be308cfb0..f46c5e4c431 100644 --- a/extensions/typescript-language-features/src/features/bufferSyncSupport.ts +++ b/extensions/typescript-language-features/src/features/bufferSyncSupport.ts @@ -4,7 +4,7 @@ *--------------------------------------------------------------------------------------------*/ import * as fs from 'fs'; -import { CancellationTokenSource, EventEmitter, TextDocument, TextDocumentChangeEvent, TextDocumentContentChangeEvent, Uri, workspace } from 'vscode'; +import * as vscode from 'vscode'; import * as Proto from '../protocol'; import { ITypeScriptServiceClient } from '../typescriptService'; import API from '../utils/api'; @@ -32,7 +32,7 @@ function mode2ScriptKind(mode: string): 'TS' | 'TSX' | 'JS' | 'JSX' | undefined class SyncedBuffer { constructor( - private readonly document: TextDocument, + private readonly document: vscode.TextDocument, public readonly filepath: string, private readonly client: ITypeScriptServiceClient ) { } @@ -66,7 +66,7 @@ class SyncedBuffer { this.client.execute('open', args, false); } - public get resource(): Uri { + public get resource(): vscode.Uri { return this.document.uri; } @@ -94,7 +94,7 @@ class SyncedBuffer { this.client.execute('close', args, false); } - public onContentChanged(events: TextDocumentContentChangeEvent[]): void { + public onContentChanged(events: vscode.TextDocumentContentChangeEvent[]): void { for (const { range, text } of events) { const args: Proto.ChangeRequestArgs = { insertString: text, @@ -108,7 +108,7 @@ class SyncedBuffer { class SyncedBufferMap extends ResourceMap { public getForPath(filePath: string): SyncedBuffer | undefined { - return this.get(Uri.file(filePath)); + return this.get(vscode.Uri.file(filePath)); } public get allBuffers(): Iterable { @@ -131,7 +131,7 @@ class GetErrRequest { files: string[], onDone: () => void ) { - const token = new CancellationTokenSource(); + const token = new vscode.CancellationTokenSource(); return new GetErrRequest(client, files, token, onDone); } @@ -140,7 +140,7 @@ class GetErrRequest { private constructor( client: ITypeScriptServiceClient, public readonly files: string[], - private readonly _token: CancellationTokenSource, + private readonly _token: vscode.CancellationTokenSource, onDone: () => void ) { const args: Proto.GeterrRequestArgs = { @@ -191,15 +191,15 @@ export default class BufferSyncSupport extends Disposable { this.diagnosticDelayer = new Delayer(300); - const pathNormalizer = (path: Uri) => this.client.normalizedPath(path); + const pathNormalizer = (path: vscode.Uri) => this.client.normalizedPath(path); this.syncedBuffers = new SyncedBufferMap(pathNormalizer); this.pendingDiagnostics = new PendingDiagnostics(pathNormalizer); this.updateConfiguration(); - workspace.onDidChangeConfiguration(this.updateConfiguration, this, this._disposables); + vscode.workspace.onDidChangeConfiguration(this.updateConfiguration, this, this._disposables); } - private readonly _onDelete = this._register(new EventEmitter()); + private readonly _onDelete = this._register(new vscode.EventEmitter()); public readonly onDelete = this._onDelete.event; public listen(): void { @@ -207,22 +207,22 @@ export default class BufferSyncSupport extends Disposable { return; } this.listening = true; - workspace.onDidOpenTextDocument(this.openTextDocument, this, this._disposables); - workspace.onDidCloseTextDocument(this.onDidCloseTextDocument, this, this._disposables); - workspace.onDidChangeTextDocument(this.onDidChangeTextDocument, this, this._disposables); - workspace.textDocuments.forEach(this.openTextDocument, this); + vscode.workspace.onDidOpenTextDocument(this.openTextDocument, this, this._disposables); + vscode.workspace.onDidCloseTextDocument(this.onDidCloseTextDocument, this, this._disposables); + vscode.workspace.onDidChangeTextDocument(this.onDidChangeTextDocument, this, this._disposables); + vscode.workspace.textDocuments.forEach(this.openTextDocument, this); } - public handles(resource: Uri): boolean { + public handles(resource: vscode.Uri): boolean { return this.syncedBuffers.has(resource); } - public toResource(filePath: string): Uri { + public toResource(filePath: string): vscode.Uri { const buffer = this.syncedBuffers.getForPath(filePath); if (buffer) { return buffer.resource; } - return Uri.file(filePath); + return vscode.Uri.file(filePath); } public reOpenDocuments(): void { @@ -231,7 +231,7 @@ export default class BufferSyncSupport extends Disposable { } } - public openTextDocument(document: TextDocument): void { + public openTextDocument(document: vscode.TextDocument): void { if (!this.modeIds.has(document.languageId)) { return; } @@ -251,7 +251,7 @@ export default class BufferSyncSupport extends Disposable { this.requestDiagnostic(syncedBuffer); } - public closeResource(resource: Uri): void { + public closeResource(resource: vscode.Uri): void { const syncedBuffer = this.syncedBuffers.get(resource); if (!syncedBuffer) { return; @@ -264,11 +264,11 @@ export default class BufferSyncSupport extends Disposable { } } - private onDidCloseTextDocument(document: TextDocument): void { + private onDidCloseTextDocument(document: vscode.TextDocument): void { this.closeResource(document.uri); } - private onDidChangeTextDocument(e: TextDocumentChangeEvent): void { + private onDidChangeTextDocument(e: vscode.TextDocumentChangeEvent): void { const syncedBuffer = this.syncedBuffers.get(e.document.uri); if (!syncedBuffer) { return; @@ -294,7 +294,7 @@ export default class BufferSyncSupport extends Disposable { this.triggerDiagnostics(); } - public getErr(resources: Uri[]): any { + public getErr(resources: vscode.Uri[]): any { const handledResources = resources.filter(resource => this.handles(resource)); if (!handledResources.length) { return; @@ -325,7 +325,7 @@ export default class BufferSyncSupport extends Disposable { return true; } - public hasPendingDiagnostics(resource: Uri): boolean { + public hasPendingDiagnostics(resource: vscode.Uri): boolean { return this.pendingDiagnostics.has(resource); } @@ -361,8 +361,8 @@ export default class BufferSyncSupport extends Disposable { } private updateConfiguration() { - const jsConfig = workspace.getConfiguration('javascript', null); - const tsConfig = workspace.getConfiguration('typescript', null); + const jsConfig = vscode.workspace.getConfiguration('javascript', null); + const tsConfig = vscode.workspace.getConfiguration('typescript', null); this._validateJavaScript = jsConfig.get('validate.enable', true); this._validateTypeScript = tsConfig.get('validate.enable', true); diff --git a/extensions/typescript-language-features/src/features/definitionProviderBase.ts b/extensions/typescript-language-features/src/features/definitionProviderBase.ts index 029fe0fad64..88d61f56a87 100644 --- a/extensions/typescript-language-features/src/features/definitionProviderBase.ts +++ b/extensions/typescript-language-features/src/features/definitionProviderBase.ts @@ -3,7 +3,7 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -import { CancellationToken, Location, Position, TextDocument } from 'vscode'; +import * as vscode from 'vscode'; import * as Proto from '../protocol'; import { ITypeScriptServiceClient } from '../typescriptService'; import * as typeConverters from '../utils/typeConverters'; @@ -16,10 +16,10 @@ export default class TypeScriptDefinitionProviderBase { protected async getSymbolLocations( definitionType: 'definition' | 'implementation' | 'typeDefinition', - document: TextDocument, - position: Position, - token: CancellationToken | boolean - ): Promise { + document: vscode.TextDocument, + position: vscode.Position, + token: vscode.CancellationToken | boolean + ): Promise { const filepath = this.client.toPath(document.uri); if (!filepath) { return undefined; diff --git a/extensions/typescript-language-features/src/features/fileConfigurationManager.ts b/extensions/typescript-language-features/src/features/fileConfigurationManager.ts index 8673f3a1c91..90587ba4925 100644 --- a/extensions/typescript-language-features/src/features/fileConfigurationManager.ts +++ b/extensions/typescript-language-features/src/features/fileConfigurationManager.ts @@ -3,7 +3,7 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -import { CancellationToken, Disposable, FormattingOptions, TextDocument, window, workspace as Workspace, workspace, WorkspaceConfiguration } from 'vscode'; +import * as vscode from 'vscode'; import * as Proto from '../protocol'; import { ITypeScriptServiceClient } from '../typescriptService'; import API from '../utils/api'; @@ -35,13 +35,13 @@ function areFileConfigurationsEqual(a: FileConfiguration, b: FileConfiguration): } export default class FileConfigurationManager { - private onDidCloseTextDocumentSub: Disposable | undefined; + private onDidCloseTextDocumentSub: vscode.Disposable | undefined; private formatOptions = new ResourceMap(); public constructor( private readonly client: ITypeScriptServiceClient ) { - this.onDidCloseTextDocumentSub = Workspace.onDidCloseTextDocument((textDocument) => { + this.onDidCloseTextDocumentSub = vscode.workspace.onDidCloseTextDocument((textDocument) => { // When a document gets closed delete the cached formatting options. // This is necessary since the tsserver now closed a project when its // last file in it closes which drops the stored formatting options @@ -58,23 +58,23 @@ export default class FileConfigurationManager { } public async ensureConfigurationForDocument( - document: TextDocument, - token: CancellationToken | undefined + document: vscode.TextDocument, + token: vscode.CancellationToken | undefined ): Promise { - const editor = window.visibleTextEditors.find(editor => editor.document.fileName === document.fileName); + const editor = vscode.window.visibleTextEditors.find(editor => editor.document.fileName === document.fileName); if (editor) { const formattingOptions = { tabSize: editor.options.tabSize, insertSpaces: editor.options.insertSpaces - } as FormattingOptions; + } as vscode.FormattingOptions; return this.ensureConfigurationOptions(document, formattingOptions, token); } } public async ensureConfigurationOptions( - document: TextDocument, - options: FormattingOptions, - token: CancellationToken | undefined + document: vscode.TextDocument, + options: vscode.FormattingOptions, + token: vscode.CancellationToken | undefined ): Promise { const file = this.client.toPath(document.uri); if (!file) { @@ -100,8 +100,8 @@ export default class FileConfigurationManager { } private getFileOptions( - document: TextDocument, - options: FormattingOptions + document: vscode.TextDocument, + options: vscode.FormattingOptions ): FileConfiguration { return { formatOptions: this.getFormatOptions(document, options), @@ -110,10 +110,10 @@ export default class FileConfigurationManager { } private getFormatOptions( - document: TextDocument, - options: FormattingOptions + document: vscode.TextDocument, + options: vscode.FormattingOptions ): Proto.FormatCodeSettings { - const config = workspace.getConfiguration( + const config = vscode.workspace.getConfiguration( isTypeScriptDocument(document) ? 'typescript.format' : 'javascript.format', document.uri); @@ -141,12 +141,12 @@ export default class FileConfigurationManager { }; } - private getPreferences(document: TextDocument): Proto.UserPreferences { + private getPreferences(document: vscode.TextDocument): Proto.UserPreferences { if (!this.client.apiVersion.gte(API.v290)) { return {}; } - const preferences = workspace.getConfiguration( + const preferences = vscode.workspace.getConfiguration( isTypeScriptDocument(document) ? 'typescript.preferences' : 'javascript.preferences', document.uri); @@ -158,7 +158,7 @@ export default class FileConfigurationManager { } } -function getQuoteStylePreference(config: WorkspaceConfiguration) { +function getQuoteStylePreference(config: vscode.WorkspaceConfiguration) { switch (config.get('quoteStyle')) { case 'single': return 'single'; case 'double': return 'double'; @@ -166,7 +166,7 @@ function getQuoteStylePreference(config: WorkspaceConfiguration) { } } -function getImportModuleSpecifierPreference(config: WorkspaceConfiguration) { +function getImportModuleSpecifierPreference(config: vscode.WorkspaceConfiguration) { switch (config.get('importModuleSpecifier')) { case 'relative': return 'relative'; case 'non-relative': return 'non-relative'; diff --git a/extensions/typescript-language-features/src/features/jsDocCompletions.ts b/extensions/typescript-language-features/src/features/jsDocCompletions.ts index b8683b81e77..49a51c95807 100644 --- a/extensions/typescript-language-features/src/features/jsDocCompletions.ts +++ b/extensions/typescript-language-features/src/features/jsDocCompletions.ts @@ -3,7 +3,7 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -import { CancellationToken, CompletionItem, CompletionItemKind, CompletionItemProvider, Disposable, DocumentSelector, languages, Position, Range, SnippetString, TextDocument, TextEditor, Uri, window } from 'vscode'; +import * as vscode from 'vscode'; import * as nls from 'vscode-nls'; import * as Proto from '../protocol'; import { ITypeScriptServiceClient } from '../typescriptService'; @@ -14,12 +14,12 @@ import * as typeConverters from '../utils/typeConverters'; const localize = nls.loadMessageBundle(); -class JsDocCompletionItem extends CompletionItem { +class JsDocCompletionItem extends vscode.CompletionItem { constructor( - document: TextDocument, - position: Position + document: vscode.TextDocument, + position: vscode.Position ) { - super('/** */', CompletionItemKind.Snippet); + super('/** */', vscode.CompletionItemKind.Snippet); this.detail = localize('typescript.jsDocCompletionItem.documentation', 'JSDoc comment'); this.insertText = ''; this.sortText = '\0'; @@ -28,7 +28,7 @@ class JsDocCompletionItem extends CompletionItem { const prefix = line.slice(0, position.character).match(/\/\**\s*$/); const suffix = line.slice(position.character).match(/^\s*\**\//); const start = position.translate(0, prefix ? -prefix[0].length : 0); - this.range = new Range( + this.range = new vscode.Range( start, position.translate(0, suffix ? suffix[0].length : 0)); @@ -40,7 +40,7 @@ class JsDocCompletionItem extends CompletionItem { } } -class JsDocCompletionProvider implements CompletionItemProvider { +class JsDocCompletionProvider implements vscode.CompletionItemProvider { constructor( private readonly client: ITypeScriptServiceClient, @@ -50,10 +50,10 @@ class JsDocCompletionProvider implements CompletionItemProvider { } public async provideCompletionItems( - document: TextDocument, - position: Position, - token: CancellationToken - ): Promise { + document: vscode.TextDocument, + position: vscode.Position, + token: vscode.CancellationToken + ): Promise { const file = this.client.toPath(document.uri); if (!file) { return []; @@ -72,8 +72,8 @@ class JsDocCompletionProvider implements CompletionItemProvider { private async isCommentableLocation( file: string, - position: Position, - token: CancellationToken + position: vscode.Position, + token: vscode.CancellationToken ): Promise { const args: Proto.FileRequestArgs = { file @@ -104,7 +104,7 @@ class JsDocCompletionProvider implements CompletionItemProvider { return matchesPosition(body); } - private isValidCursorPosition(document: TextDocument, position: Position): boolean { + private isValidCursorPosition(document: vscode.TextDocument, position: vscode.Position): boolean { // Only show the JSdoc completion when the everything before the cursor is whitespace // or could be the opening of a comment const line = document.lineAt(position.line).text; @@ -112,7 +112,7 @@ class JsDocCompletionProvider implements CompletionItemProvider { return prefix.match(/^\s*$|\/\*\*\s*$|^\s*\/\*\*+\s*$/) !== null; } - public resolveCompletionItem(item: CompletionItem, _token: CancellationToken) { + public resolveCompletionItem(item: vscode.CompletionItem, _token: vscode.CancellationToken) { return item; } } @@ -129,13 +129,13 @@ class TryCompleteJsDocCommand implements Command { * Try to insert a jsdoc comment, using a template provide by typescript * if possible, otherwise falling back to a default comment format. */ - public async execute(resource: Uri, start: Position): Promise { + public async execute(resource: vscode.Uri, start: vscode.Position): Promise { const file = this.client.toPath(resource); if (!file) { return false; } - const editor = window.activeTextEditor; + const editor = vscode.window.activeTextEditor; if (!editor || editor.document.uri.fsPath !== resource.fsPath) { return false; } @@ -148,7 +148,7 @@ class TryCompleteJsDocCommand implements Command { return this.tryInsertDefaultDoc(editor, start); } - private async tryInsertJsDocFromTemplate(editor: TextEditor, file: string, position: Position): Promise { + private async tryInsertJsDocFromTemplate(editor: vscode.TextEditor, file: string, position: vscode.Position): Promise { const snippet = await TryCompleteJsDocCommand.getSnippetTemplate(this.client, file, position); if (!snippet) { return false; @@ -159,7 +159,7 @@ class TryCompleteJsDocCommand implements Command { { undoStopBefore: false, undoStopAfter: true }); } - public static getSnippetTemplate(client: ITypeScriptServiceClient, file: string, position: Position): Promise { + public static getSnippetTemplate(client: ITypeScriptServiceClient, file: string, position: vscode.Position): Promise { const args = typeConverters.Position.toFileLocationRequestArgs(file, position); return Promise.race([ client.execute('docCommentTemplate', args), @@ -181,14 +181,14 @@ class TryCompleteJsDocCommand implements Command { /** * Insert the default JSDoc */ - private tryInsertDefaultDoc(editor: TextEditor, position: Position): Thenable { - const snippet = new SnippetString(`/**\n * $0\n */`); + private tryInsertDefaultDoc(editor: vscode.TextEditor, position: vscode.Position): Thenable { + const snippet = new vscode.SnippetString(`/**\n * $0\n */`); return editor.insertSnippet(snippet, position, { undoStopBefore: false, undoStopAfter: true }); } } -export function templateToSnippet(template: string): SnippetString { +export function templateToSnippet(template: string): vscode.SnippetString { // TODO: use append placeholder let snippetIndex = 1; template = template.replace(/\$/g, '\\$'); @@ -204,16 +204,16 @@ export function templateToSnippet(template: string): SnippetString { out += post + ` \${${snippetIndex++}}`; return out; }); - return new SnippetString(template); + return new vscode.SnippetString(template); } export function register( - selector: DocumentSelector, + selector: vscode.DocumentSelector, client: ITypeScriptServiceClient, commandManager: CommandManager -): Disposable { +): vscode.Disposable { return new ConfigurationDependentRegistration('jsDocCompletion', 'enabled', () => { - return languages.registerCompletionItemProvider(selector, + return vscode.languages.registerCompletionItemProvider(selector, new JsDocCompletionProvider(client, commandManager), '*'); }); diff --git a/extensions/typescript-language-features/src/typeScriptServiceClientHost.ts b/extensions/typescript-language-features/src/typeScriptServiceClientHost.ts index 522c1f8364e..cea7c0a2bc4 100644 --- a/extensions/typescript-language-features/src/typeScriptServiceClientHost.ts +++ b/extensions/typescript-language-features/src/typeScriptServiceClientHost.ts @@ -8,7 +8,7 @@ * https://github.com/Microsoft/TypeScript-Sublime-Plugin/blob/master/TypeScript%20Indent.tmPreferences * ------------------------------------------------------------------------------------------ */ -import { Diagnostic, DiagnosticRelatedInformation, DiagnosticSeverity, DiagnosticTag, Memento, Range, Uri, workspace } from 'vscode'; +import * as vscode from 'vscode'; import { DiagnosticKind } from './features/diagnostics'; import FileConfigurationManager from './features/fileConfigurationManager'; import { register as registerUpdatePathsOnRename } from './features/updatePathsOnRename'; @@ -48,7 +48,7 @@ export default class TypeScriptServiceClientHost extends Disposable { constructor( descriptions: LanguageDescription[], - workspaceState: Memento, + workspaceState: vscode.Memento, plugins: TypeScriptServerPlugin[], private readonly commandManager: CommandManager, logDirectoryProvider: LogDirectoryProvider @@ -63,7 +63,7 @@ export default class TypeScriptServiceClientHost extends Disposable { this.triggerAllDiagnostics(); }, 1500); }; - const configFileWatcher = workspace.createFileSystemWatcher('**/[tj]sconfig.json'); + const configFileWatcher = vscode.workspace.createFileSystemWatcher('**/[tj]sconfig.json'); this._register(configFileWatcher); configFileWatcher.onDidCreate(handleProjectCreateOrDelete, this, this._disposables); configFileWatcher.onDidDelete(handleProjectCreateOrDelete, this, this._disposables); @@ -133,7 +133,7 @@ export default class TypeScriptServiceClientHost extends Disposable { this.triggerAllDiagnostics(); }); - workspace.onDidChangeConfiguration(this.configurationChanged, this, this._disposables); + vscode.workspace.onDidChangeConfiguration(this.configurationChanged, this, this._disposables); this.configurationChanged(); } @@ -154,7 +154,7 @@ export default class TypeScriptServiceClientHost extends Disposable { this.triggerAllDiagnostics(); } - public async handles(resource: Uri): Promise { + public async handles(resource: vscode.Uri): Promise { const provider = await this.findLanguage(resource); if (provider) { return true; @@ -163,14 +163,14 @@ export default class TypeScriptServiceClientHost extends Disposable { } private configurationChanged(): void { - const typescriptConfig = workspace.getConfiguration('typescript'); + const typescriptConfig = vscode.workspace.getConfiguration('typescript'); this.reportStyleCheckAsWarnings = typescriptConfig.get('reportStyleChecksAsWarnings', true); } - private async findLanguage(resource: Uri): Promise { + private async findLanguage(resource: vscode.Uri): Promise { try { - const doc = await workspace.openTextDocument(resource); + const doc = await vscode.workspace.openTextDocument(resource); return this.languages.find(language => language.handles(resource, doc)); } catch { return undefined; @@ -189,7 +189,7 @@ export default class TypeScriptServiceClientHost extends Disposable { this.client.bufferSyncSupport.requestAllDiagnostics(); // See https://github.com/Microsoft/TypeScript/issues/5530 - workspace.saveAll(false).then(() => { + vscode.workspace.saveAll(false).then(() => { for (const language of this.languagePerId.values()) { language.reInitialize(); } @@ -198,7 +198,7 @@ export default class TypeScriptServiceClientHost extends Disposable { private async diagnosticsReceived( kind: DiagnosticKind, - resource: Uri, + resource: vscode.Uri, diagnostics: Proto.Diagnostic[] ): Promise { const language = await this.findLanguage(resource); @@ -224,10 +224,10 @@ export default class TypeScriptServiceClientHost extends Disposable { if (body.diagnostics.length === 0) { language.configFileDiagnosticsReceived(this.client.toResource(body.configFile), []); } else if (body.diagnostics.length >= 1) { - workspace.openTextDocument(Uri.file(body.configFile)).then((document) => { + vscode.workspace.openTextDocument(vscode.Uri.file(body.configFile)).then((document) => { let curly: [number, number, number] | undefined = undefined; let nonCurly: [number, number, number] | undefined = undefined; - let diagnostic: Diagnostic; + let diagnostic: vscode.Diagnostic; for (let index = 0; index < document.lineCount; index++) { const line = document.lineAt(index); const text = line.text; @@ -246,16 +246,16 @@ export default class TypeScriptServiceClientHost extends Disposable { } const match = curly || nonCurly; if (match) { - diagnostic = new Diagnostic(new Range(match[0], match[1], match[0], match[2]), body.diagnostics[0].text); + diagnostic = new vscode.Diagnostic(new vscode.Range(match[0], match[1], match[0], match[2]), body.diagnostics[0].text); } else { - diagnostic = new Diagnostic(new Range(0, 0, 0, 0), body.diagnostics[0].text); + diagnostic = new vscode.Diagnostic(new vscode.Range(0, 0, 0, 0), body.diagnostics[0].text); } if (diagnostic) { diagnostic.source = language.diagnosticSource; language.configFileDiagnosticsReceived(this.client.toResource(body.configFile), [diagnostic]); } }, _error => { - language.configFileDiagnosticsReceived(this.client.toResource(body.configFile), [new Diagnostic(new Range(0, 0, 0, 0), body.diagnostics[0].text)]); + language.configFileDiagnosticsReceived(this.client.toResource(body.configFile), [new vscode.Diagnostic(new vscode.Range(0, 0, 0, 0), body.diagnostics[0].text)]); }); } }); @@ -264,14 +264,14 @@ export default class TypeScriptServiceClientHost extends Disposable { private createMarkerDatas( diagnostics: Proto.Diagnostic[], source: string - ): (Diagnostic & { reportUnnecessary: any })[] { + ): (vscode.Diagnostic & { reportUnnecessary: any })[] { return diagnostics.map(tsDiag => this.tsDiagnosticToVsDiagnostic(tsDiag, source)); } - private tsDiagnosticToVsDiagnostic(diagnostic: Proto.Diagnostic, source: string): Diagnostic & { reportUnnecessary: any } { + private tsDiagnosticToVsDiagnostic(diagnostic: Proto.Diagnostic, source: string): vscode.Diagnostic & { reportUnnecessary: any } { const { start, end, text } = diagnostic; - const range = new Range(typeConverters.Position.fromLocation(start), typeConverters.Position.fromLocation(end)); - const converted = new Diagnostic(range, text); + const range = new vscode.Range(typeConverters.Position.fromLocation(start), typeConverters.Position.fromLocation(end)); + const converted = new vscode.Diagnostic(range, text); converted.severity = this.getDiagnosticSeverity(diagnostic); converted.source = diagnostic.source || source; if (diagnostic.code) { @@ -284,36 +284,36 @@ export default class TypeScriptServiceClientHost extends Disposable { if (!span) { return undefined; } - return new DiagnosticRelatedInformation(typeConverters.Location.fromTextSpan(this.client.toResource(span.file), span), info.message); - }).filter((x: any) => !!x) as DiagnosticRelatedInformation[]; + return new vscode.DiagnosticRelatedInformation(typeConverters.Location.fromTextSpan(this.client.toResource(span.file), span), info.message); + }).filter((x: any) => !!x) as vscode.DiagnosticRelatedInformation[]; } if (diagnostic.reportsUnnecessary) { - converted.tags = [DiagnosticTag.Unnecessary]; + converted.tags = [vscode.DiagnosticTag.Unnecessary]; } - (converted as Diagnostic & { reportUnnecessary: any }).reportUnnecessary = diagnostic.reportsUnnecessary; - return converted as Diagnostic & { reportUnnecessary: any }; + (converted as vscode.Diagnostic & { reportUnnecessary: any }).reportUnnecessary = diagnostic.reportsUnnecessary; + return converted as vscode.Diagnostic & { reportUnnecessary: any }; } - private getDiagnosticSeverity(diagnostic: Proto.Diagnostic): DiagnosticSeverity { + private getDiagnosticSeverity(diagnostic: Proto.Diagnostic): vscode.DiagnosticSeverity { if (this.reportStyleCheckAsWarnings && this.isStyleCheckDiagnostic(diagnostic.code) && diagnostic.category === PConst.DiagnosticCategory.error ) { - return DiagnosticSeverity.Warning; + return vscode.DiagnosticSeverity.Warning; } switch (diagnostic.category) { case PConst.DiagnosticCategory.error: - return DiagnosticSeverity.Error; + return vscode.DiagnosticSeverity.Error; case PConst.DiagnosticCategory.warning: - return DiagnosticSeverity.Warning; + return vscode.DiagnosticSeverity.Warning; case PConst.DiagnosticCategory.suggestion: - return DiagnosticSeverity.Hint; + return vscode.DiagnosticSeverity.Hint; default: - return DiagnosticSeverity.Error; + return vscode.DiagnosticSeverity.Error; } } diff --git a/extensions/typescript-language-features/src/typescriptService.ts b/extensions/typescript-language-features/src/typescriptService.ts index 110f41d2658..bb6baa31915 100644 --- a/extensions/typescript-language-features/src/typescriptService.ts +++ b/extensions/typescript-language-features/src/typescriptService.ts @@ -3,7 +3,7 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -import { CancellationToken, Event, Uri } from 'vscode'; +import * as vscode from 'vscode'; import BufferSyncSupport from './features/bufferSyncSupport'; import * as Proto from './protocol'; import API from './utils/api'; @@ -17,27 +17,27 @@ export interface ITypeScriptServiceClient { * * Does not try handling case insensitivity. */ - normalizedPath(resource: Uri): string | null; + normalizedPath(resource: vscode.Uri): string | null; /** * Map a resource to a normalized path * * This will attempt to handle case insensitivity. */ - toPath(resource: Uri): string | null; + toPath(resource: vscode.Uri): string | null; /** * Convert a path to a resource. */ - toResource(filepath: string): Uri; + toResource(filepath: string): vscode.Uri; - getWorkspaceRootForResource(resource: Uri): string | undefined; + getWorkspaceRootForResource(resource: vscode.Uri): string | undefined; - readonly onTsServerStarted: Event; - readonly onProjectLanguageServiceStateChanged: Event; - readonly onDidBeginInstallTypings: Event; - readonly onDidEndInstallTypings: Event; - readonly onTypesInstallerInitializationFailed: Event; + readonly onTsServerStarted: vscode.Event; + readonly onProjectLanguageServiceStateChanged: vscode.Event; + readonly onDidBeginInstallTypings: vscode.Event; + readonly onDidEndInstallTypings: vscode.Event; + readonly onTypesInstallerInitializationFailed: vscode.Event; readonly apiVersion: API; readonly plugins: TypeScriptServerPlugin[]; @@ -45,42 +45,42 @@ export interface ITypeScriptServiceClient { readonly logger: Logger; readonly bufferSyncSupport: BufferSyncSupport; - execute(command: 'configure', args: Proto.ConfigureRequestArguments, token?: CancellationToken): Promise; - execute(command: 'open', args: Proto.OpenRequestArgs, expectedResult: boolean, token?: CancellationToken): Promise; - execute(command: 'close', args: Proto.FileRequestArgs, expectedResult: boolean, token?: CancellationToken): Promise; - execute(command: 'change', args: Proto.ChangeRequestArgs, expectedResult: boolean, token?: CancellationToken): Promise; - execute(command: 'quickinfo', args: Proto.FileLocationRequestArgs, token?: CancellationToken): Promise; - execute(command: 'completions', args: Proto.CompletionsRequestArgs, token?: CancellationToken): Promise; - execute(command: 'completionInfo', args: Proto.CompletionsRequestArgs, token?: CancellationToken): Promise; - execute(command: 'completionEntryDetails', args: Proto.CompletionDetailsRequestArgs, token?: CancellationToken): Promise; - execute(command: 'signatureHelp', args: Proto.SignatureHelpRequestArgs, token?: CancellationToken): Promise; - execute(command: 'definition', args: Proto.FileLocationRequestArgs, token?: CancellationToken): Promise; - execute(command: 'definitionAndBoundSpan', args: Proto.FileLocationRequestArgs, token?: CancellationToken): Promise; - execute(command: 'implementation', args: Proto.FileLocationRequestArgs, token?: CancellationToken): Promise; - execute(command: 'typeDefinition', args: Proto.FileLocationRequestArgs, token?: CancellationToken): Promise; - execute(command: 'references', args: Proto.FileLocationRequestArgs, token?: CancellationToken): Promise; - execute(command: 'navto', args: Proto.NavtoRequestArgs, token?: CancellationToken): Promise; - execute(command: 'format', args: Proto.FormatRequestArgs, token?: CancellationToken): Promise; - execute(command: 'formatonkey', args: Proto.FormatOnKeyRequestArgs, token?: CancellationToken): Promise; - execute(command: 'rename', args: Proto.RenameRequestArgs, token?: CancellationToken): Promise; - execute(command: 'occurrences', args: Proto.FileLocationRequestArgs, token?: CancellationToken): Promise; - execute(command: 'projectInfo', args: Proto.ProjectInfoRequestArgs, token?: CancellationToken): Promise; - execute(command: 'reloadProjects', args: any, expectedResult: boolean, token?: CancellationToken): Promise; - execute(command: 'reload', args: Proto.ReloadRequestArgs, expectedResult: boolean, token?: CancellationToken): Promise; - execute(command: 'compilerOptionsForInferredProjects', args: Proto.SetCompilerOptionsForInferredProjectsArgs, token?: CancellationToken): Promise; - execute(command: 'navtree', args: Proto.FileRequestArgs, token?: CancellationToken): Promise; - execute(command: 'getCodeFixes', args: Proto.CodeFixRequestArgs, token?: CancellationToken): Promise; - execute(command: 'getSupportedCodeFixes', args: null, token?: CancellationToken): Promise; - execute(command: 'getCombinedCodeFix', args: Proto.GetCombinedCodeFixRequestArgs, token?: CancellationToken): Promise; - execute(command: 'docCommentTemplate', args: Proto.FileLocationRequestArgs, token?: CancellationToken): Promise; - execute(command: 'getApplicableRefactors', args: Proto.GetApplicableRefactorsRequestArgs, token?: CancellationToken): Promise; - execute(command: 'getEditsForRefactor', args: Proto.GetEditsForRefactorRequestArgs, token?: CancellationToken): Promise; - execute(command: 'applyCodeActionCommand', args: Proto.ApplyCodeActionCommandRequestArgs, token?: CancellationToken): Promise; - execute(command: 'organizeImports', args: Proto.OrganizeImportsRequestArgs, token?: CancellationToken): Promise; - execute(command: 'getOutliningSpans', args: Proto.FileRequestArgs, token: CancellationToken): Promise; + execute(command: 'configure', args: Proto.ConfigureRequestArguments, token?: vscode.CancellationToken): Promise; + execute(command: 'open', args: Proto.OpenRequestArgs, expectedResult: boolean, token?: vscode.CancellationToken): Promise; + execute(command: 'close', args: Proto.FileRequestArgs, expectedResult: boolean, token?: vscode.CancellationToken): Promise; + execute(command: 'change', args: Proto.ChangeRequestArgs, expectedResult: boolean, token?: vscode.CancellationToken): Promise; + execute(command: 'quickinfo', args: Proto.FileLocationRequestArgs, token?: vscode.CancellationToken): Promise; + execute(command: 'completions', args: Proto.CompletionsRequestArgs, token?: vscode.CancellationToken): Promise; + execute(command: 'completionInfo', args: Proto.CompletionsRequestArgs, token?: vscode.CancellationToken): Promise; + execute(command: 'completionEntryDetails', args: Proto.CompletionDetailsRequestArgs, token?: vscode.CancellationToken): Promise; + execute(command: 'signatureHelp', args: Proto.SignatureHelpRequestArgs, token?: vscode.CancellationToken): Promise; + execute(command: 'definition', args: Proto.FileLocationRequestArgs, token?: vscode.CancellationToken): Promise; + execute(command: 'definitionAndBoundSpan', args: Proto.FileLocationRequestArgs, token?: vscode.CancellationToken): Promise; + execute(command: 'implementation', args: Proto.FileLocationRequestArgs, token?: vscode.CancellationToken): Promise; + execute(command: 'typeDefinition', args: Proto.FileLocationRequestArgs, token?: vscode.CancellationToken): Promise; + execute(command: 'references', args: Proto.FileLocationRequestArgs, token?: vscode.CancellationToken): Promise; + execute(command: 'navto', args: Proto.NavtoRequestArgs, token?: vscode.CancellationToken): Promise; + execute(command: 'format', args: Proto.FormatRequestArgs, token?: vscode.CancellationToken): Promise; + execute(command: 'formatonkey', args: Proto.FormatOnKeyRequestArgs, token?: vscode.CancellationToken): Promise; + execute(command: 'rename', args: Proto.RenameRequestArgs, token?: vscode.CancellationToken): Promise; + execute(command: 'occurrences', args: Proto.FileLocationRequestArgs, token?: vscode.CancellationToken): Promise; + execute(command: 'projectInfo', args: Proto.ProjectInfoRequestArgs, token?: vscode.CancellationToken): Promise; + execute(command: 'reloadProjects', args: any, expectedResult: boolean, token?: vscode.CancellationToken): Promise; + execute(command: 'reload', args: Proto.ReloadRequestArgs, expectedResult: boolean, token?: vscode.CancellationToken): Promise; + execute(command: 'compilerOptionsForInferredProjects', args: Proto.SetCompilerOptionsForInferredProjectsArgs, token?: vscode.CancellationToken): Promise; + execute(command: 'navtree', args: Proto.FileRequestArgs, token?: vscode.CancellationToken): Promise; + execute(command: 'getCodeFixes', args: Proto.CodeFixRequestArgs, token?: vscode.CancellationToken): Promise; + execute(command: 'getSupportedCodeFixes', args: null, token?: vscode.CancellationToken): Promise; + execute(command: 'getCombinedCodeFix', args: Proto.GetCombinedCodeFixRequestArgs, token?: vscode.CancellationToken): Promise; + execute(command: 'docCommentTemplate', args: Proto.FileLocationRequestArgs, token?: vscode.CancellationToken): Promise; + execute(command: 'getApplicableRefactors', args: Proto.GetApplicableRefactorsRequestArgs, token?: vscode.CancellationToken): Promise; + execute(command: 'getEditsForRefactor', args: Proto.GetEditsForRefactorRequestArgs, token?: vscode.CancellationToken): Promise; + execute(command: 'applyCodeActionCommand', args: Proto.ApplyCodeActionCommandRequestArgs, token?: vscode.CancellationToken): Promise; + execute(command: 'organizeImports', args: Proto.OrganizeImportsRequestArgs, token?: vscode.CancellationToken): Promise; + execute(command: 'getOutliningSpans', args: Proto.FileRequestArgs, token: vscode.CancellationToken): Promise; execute(command: 'getEditsForFileRename', args: Proto.GetEditsForFileRenameRequestArgs): Promise; - execute(command: 'jsxClosingTag', args: Proto.JsxClosingTagRequestArgs, token: CancellationToken): Promise; - execute(command: string, args: any, expectedResult: boolean | CancellationToken, token?: CancellationToken): Promise; + execute(command: 'jsxClosingTag', args: Proto.JsxClosingTagRequestArgs, token: vscode.CancellationToken): Promise; + execute(command: string, args: any, expectedResult: boolean | vscode.CancellationToken, token?: vscode.CancellationToken): Promise; - executeAsync(command: 'geterr', args: Proto.GeterrRequestArgs, token: CancellationToken): Promise; + executeAsync(command: 'geterr', args: Proto.GeterrRequestArgs, token: vscode.CancellationToken): Promise; } \ 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 1655c6b5419..adc73a29e3b 100644 --- a/extensions/typescript-language-features/src/typescriptServiceClient.ts +++ b/extensions/typescript-language-features/src/typescriptServiceClient.ts @@ -6,7 +6,7 @@ import * as cp from 'child_process'; import * as fs from 'fs'; import * as path from 'path'; -import { CancellationToken, commands, env, EventEmitter, Memento, MessageItem, Uri, window, workspace } from 'vscode'; +import * as vscode from 'vscode'; import * as nls from 'vscode-nls'; import BufferSyncSupport from './features/bufferSyncSupport'; import { DiagnosticKind, DiagnosticsManager } from './features/diagnostics'; @@ -152,7 +152,7 @@ class ForkedTsServerProcess { export interface TsDiagnostics { readonly kind: DiagnosticKind; - readonly resource: Uri; + readonly resource: vscode.Uri; readonly diagnostics: Proto.Diagnostic[]; } @@ -195,7 +195,7 @@ export default class TypeScriptServiceClient extends Disposable implements IType public readonly diagnosticsManager: DiagnosticsManager; constructor( - private readonly workspaceState: Memento, + private readonly workspaceState: vscode.Memento, private readonly onDidChangeTypeScriptVersion: (version: TypeScriptVersion) => void, public readonly plugins: TypeScriptServerPlugin[], private readonly logDirectoryProvider: LogDirectoryProvider, @@ -233,7 +233,7 @@ export default class TypeScriptServiceClient extends Disposable implements IType this.diagnosticsManager.delete(resource); }, null, this._disposables); - workspace.onDidChangeConfiguration(() => { + vscode.workspace.onDidChangeConfiguration(() => { const oldConfiguration = this._configuration; this._configuration = TypeScriptServiceConfiguration.loadFromWorkspace(); @@ -291,28 +291,28 @@ export default class TypeScriptServiceClient extends Disposable implements IType } } - private readonly _onTsServerStarted = this._register(new EventEmitter()); + private readonly _onTsServerStarted = this._register(new vscode.EventEmitter()); public readonly onTsServerStarted = this._onTsServerStarted.event; - private readonly _onDiagnosticsReceived = this._register(new EventEmitter()); + private readonly _onDiagnosticsReceived = this._register(new vscode.EventEmitter()); public readonly onDiagnosticsReceived = this._onDiagnosticsReceived.event; - private readonly _onConfigDiagnosticsReceived = this._register(new EventEmitter()); + private readonly _onConfigDiagnosticsReceived = this._register(new vscode.EventEmitter()); public readonly onConfigDiagnosticsReceived = this._onConfigDiagnosticsReceived.event; - private readonly _onResendModelsRequested = this._register(new EventEmitter()); + private readonly _onResendModelsRequested = this._register(new vscode.EventEmitter()); public readonly onResendModelsRequested = this._onResendModelsRequested.event; - private readonly _onProjectLanguageServiceStateChanged = this._register(new EventEmitter()); + private readonly _onProjectLanguageServiceStateChanged = this._register(new vscode.EventEmitter()); public readonly onProjectLanguageServiceStateChanged = this._onProjectLanguageServiceStateChanged.event; - private readonly _onDidBeginInstallTypings = this._register(new EventEmitter()); + private readonly _onDidBeginInstallTypings = this._register(new vscode.EventEmitter()); public readonly onDidBeginInstallTypings = this._onDidBeginInstallTypings.event; - private readonly _onDidEndInstallTypings = this._register(new EventEmitter()); + private readonly _onDidEndInstallTypings = this._register(new vscode.EventEmitter()); public readonly onDidEndInstallTypings = this._onDidEndInstallTypings.event; - private readonly _onTypesInstallerInitializationFailed = this._register(new EventEmitter()); + private readonly _onTypesInstallerInitializationFailed = this._register(new vscode.EventEmitter()); public readonly onTypesInstallerInitializationFailed = this._onTypesInstallerInitializationFailed.event; public get apiVersion(): API { @@ -360,7 +360,7 @@ export default class TypeScriptServiceClient extends Disposable implements IType this.info(`Using tsserver from: ${currentVersion.path}`); if (!fs.existsSync(currentVersion.tsServerPath)) { - window.showWarningMessage(localize('noServerFound', 'The path {0} doesn\'t point to a valid tsserver install. Falling back to bundled TypeScript version.', currentVersion.path)); + vscode.window.showWarningMessage(localize('noServerFound', 'The path {0} doesn\'t point to a valid tsserver install. Falling back to bundled TypeScript version.', currentVersion.path)); this.versionPicker.useBundledVersion(); currentVersion = this.versionPicker.currentVersion; @@ -384,7 +384,7 @@ export default class TypeScriptServiceClient extends Disposable implements IType if (err || !childProcess) { this.lastError = err; this.error('Starting TSServer failed with error.', err); - window.showErrorMessage(localize('serverCouldNotBeStarted', 'TypeScript language server couldn\'t be started. Error message is: {0}', err.message || err)); + vscode.window.showErrorMessage(localize('serverCouldNotBeStarted', 'TypeScript language server couldn\'t be started. Error message is: {0}', err.message || err)); /* __GDPR__ "error" : { "${include}": [ @@ -471,7 +471,7 @@ export default class TypeScriptServiceClient extends Disposable implements IType public async openTsServerLogFile(): Promise { if (!this.apiVersion.gte(API.v222)) { - window.showErrorMessage( + vscode.window.showErrorMessage( localize( 'typescript.openTsServerLog.notSupported', 'TS Server logging requires TS 2.2.2+')); @@ -479,7 +479,7 @@ export default class TypeScriptServiceClient extends Disposable implements IType } if (this._configuration.tsServerLogLevel === TsServerLogLevel.Off) { - window.showErrorMessage( + vscode.window.showErrorMessage( localize( 'typescript.openTsServerLog.loggingNotEnabled', 'TS Server logging is off. Please set `typescript.tsserver.log` and restart the TS server to enable logging'), @@ -490,7 +490,7 @@ export default class TypeScriptServiceClient extends Disposable implements IType }) .then(selection => { if (selection) { - return workspace.getConfiguration().update('typescript.tsserver.log', 'verbose', true).then(() => { + return vscode.workspace.getConfiguration().update('typescript.tsserver.log', 'verbose', true).then(() => { this.restartTsServer(); }); } @@ -500,17 +500,17 @@ export default class TypeScriptServiceClient extends Disposable implements IType } if (!this.tsServerLogFile) { - window.showWarningMessage(localize( + vscode.window.showWarningMessage(localize( 'typescript.openTsServerLog.noLogFile', 'TS Server has not started logging.')); return false; } try { - await commands.executeCommand('revealFileInOS', Uri.parse(this.tsServerLogFile)); + await vscode.commands.executeCommand('revealFileInOS', vscode.Uri.parse(this.tsServerLogFile)); return true; } catch { - window.showWarningMessage(localize( + vscode.window.showWarningMessage(localize( 'openTsServerLog.openFileFailedFailed', 'Could not open TS Server log file')); return false; @@ -553,7 +553,7 @@ export default class TypeScriptServiceClient extends Disposable implements IType reportIssue } - interface MyMessageItem extends MessageItem { + interface MyMessageItem extends vscode.MessageItem { id: MessageAction; } @@ -574,7 +574,7 @@ export default class TypeScriptServiceClient extends Disposable implements IType if (diff < 10 * 1000 /* 10 seconds */) { this.lastStart = Date.now(); startService = false; - prompt = window.showErrorMessage( + prompt = vscode.window.showErrorMessage( localize('serverDiedAfterStart', 'The TypeScript language service died 5 times right after it got started. The service will not be restarted.'), { title: localize('serverDiedReportIssue', 'Report Issue'), @@ -591,7 +591,7 @@ export default class TypeScriptServiceClient extends Disposable implements IType this.resetClientVersion(); } else if (diff < 60 * 1000 /* 1 Minutes */) { this.lastStart = Date.now(); - prompt = window.showWarningMessage( + prompt = vscode.window.showWarningMessage( localize('serverDied', 'The TypeScript language service died unexpectedly 5 times in the last 5 Minutes.'), { title: localize('serverDiedReportIssue', 'Report Issue'), @@ -601,7 +601,7 @@ export default class TypeScriptServiceClient extends Disposable implements IType if (prompt) { prompt.then(item => { if (item && item.id === MessageAction.reportIssue) { - return commands.executeCommand('workbench.action.reportIssues'); + return vscode.commands.executeCommand('workbench.action.reportIssues'); } return undefined; }); @@ -613,7 +613,7 @@ export default class TypeScriptServiceClient extends Disposable implements IType } } - public normalizedPath(resource: Uri): string | null { + public normalizedPath(resource: vscode.Uri): string | null { if (this._apiVersion.gte(API.v213)) { if (resource.scheme === fileSchemes.walkThroughSnippet || resource.scheme === fileSchemes.untitled) { const dirName = path.dirname(resource.path); @@ -635,7 +635,7 @@ export default class TypeScriptServiceClient extends Disposable implements IType return result.replace(new RegExp('\\' + this.pathSeparator, 'g'), '/'); } - public toPath(resource: Uri): string | null { + public toPath(resource: vscode.Uri): string | null { return this.normalizedPath(resource); } @@ -643,11 +643,11 @@ export default class TypeScriptServiceClient extends Disposable implements IType return this._apiVersion.gte(API.v270) ? '^' : ''; } - public toResource(filepath: string): Uri { + public toResource(filepath: string): vscode.Uri { if (this._apiVersion.gte(API.v213)) { if (filepath.startsWith(TypeScriptServiceClient.WALK_THROUGH_SNIPPET_SCHEME_COLON) || (filepath.startsWith(fileSchemes.untitled + ':')) ) { - let resource = Uri.parse(filepath); + let resource = vscode.Uri.parse(filepath); if (this.inMemoryResourcePrefix) { const dirName = path.dirname(resource.path); const fileName = path.basename(resource.path); @@ -661,8 +661,8 @@ export default class TypeScriptServiceClient extends Disposable implements IType return this.bufferSyncSupport.toResource(filepath); } - public getWorkspaceRootForResource(resource: Uri): string | undefined { - const roots = workspace.workspaceFolders; + public getWorkspaceRootForResource(resource: vscode.Uri): string | undefined { + const roots = vscode.workspace.workspaceFolders; if (!roots || !roots.length) { return undefined; } @@ -679,12 +679,12 @@ export default class TypeScriptServiceClient extends Disposable implements IType return undefined; } - public executeAsync(command: string, args: Proto.GeterrRequestArgs, token: CancellationToken): Promise { + public executeAsync(command: string, args: Proto.GeterrRequestArgs, token: vscode.CancellationToken): Promise { return this.executeImpl(command, args, { isAsync: true, token, expectsResult: true }); } - public execute(command: string, args: any, expectsResultOrToken?: boolean | CancellationToken): Promise { - let token: CancellationToken | undefined = undefined; + public execute(command: string, args: any, expectsResultOrToken?: boolean | vscode.CancellationToken): Promise { + let token: vscode.CancellationToken | undefined = undefined; let expectsResult = true; if (typeof expectsResultOrToken === 'boolean') { expectsResult = expectsResultOrToken; @@ -694,7 +694,7 @@ export default class TypeScriptServiceClient extends Disposable implements IType return this.executeImpl(command, args, { isAsync: false, token, expectsResult }); } - private executeImpl(command: string, args: any, executeInfo: { isAsync: boolean, token?: CancellationToken, expectsResult: boolean }): Promise { + private executeImpl(command: string, args: any, executeInfo: { isAsync: boolean, token?: vscode.CancellationToken, expectsResult: boolean }): Promise { const request = this.requestQueue.createRequest(command, args); const requestInfo: RequestItem = { request: request, @@ -874,7 +874,7 @@ export default class TypeScriptServiceClient extends Disposable implements IType case 'projectsUpdatedInBackground': if (event.body) { const body = (event as Proto.ProjectsUpdatedInBackgroundEvent).body; - const resources = body.openFiles.map(Uri.file); + const resources = body.openFiles.map(vscode.Uri.file); this.bufferSyncSupport.getErr(resources); } break; @@ -1048,7 +1048,7 @@ export default class TypeScriptServiceClient extends Disposable implements IType const getTsLocale = (configuration: TypeScriptServiceConfiguration): string | undefined => (configuration.locale ? configuration.locale - : env.language); + : vscode.env.language); function getDignosticsKind(event: Proto.Event) { switch (event.event) { diff --git a/extensions/typescript-language-features/src/utils/codeAction.ts b/extensions/typescript-language-features/src/utils/codeAction.ts index e2c71edb370..0271a93c8fb 100644 --- a/extensions/typescript-language-features/src/utils/codeAction.ts +++ b/extensions/typescript-language-features/src/utils/codeAction.ts @@ -3,7 +3,7 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -import { workspace, WorkspaceEdit } from 'vscode'; +import * as vscode from 'vscode'; import * as Proto from '../protocol'; import { ITypeScriptServiceClient } from '../typescriptService'; import * as typeConverters from './typeConverters'; @@ -11,7 +11,7 @@ import * as typeConverters from './typeConverters'; export function getEditForCodeAction( client: ITypeScriptServiceClient, action: Proto.CodeAction -): WorkspaceEdit | undefined { +): vscode.WorkspaceEdit | undefined { return action.changes && action.changes.length ? typeConverters.WorkspaceEdit.fromFileCodeEdits(client, action.changes) : undefined; @@ -23,7 +23,7 @@ export async function applyCodeAction( ): Promise { const workspaceEdit = getEditForCodeAction(client, action); if (workspaceEdit) { - if (!(await workspace.applyEdit(workspaceEdit))) { + if (!(await vscode.workspace.applyEdit(workspaceEdit))) { return false; } } diff --git a/extensions/typescript-language-features/src/utils/configuration.ts b/extensions/typescript-language-features/src/utils/configuration.ts index d5c0d00bdf3..adeb071062e 100644 --- a/extensions/typescript-language-features/src/utils/configuration.ts +++ b/extensions/typescript-language-features/src/utils/configuration.ts @@ -2,7 +2,7 @@ * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -import { workspace, WorkspaceConfiguration } from 'vscode'; +import * as vscode from 'vscode'; import * as arrays from './arrays'; export enum TsServerLogLevel { @@ -58,7 +58,7 @@ export class TypeScriptServiceConfiguration { } private constructor() { - const configuration = workspace.getConfiguration(); + const configuration = vscode.workspace.getConfiguration(); this.locale = TypeScriptServiceConfiguration.extractLocale(configuration); this.globalTsdk = TypeScriptServiceConfiguration.extractGlobalTsdk(configuration); @@ -83,7 +83,7 @@ export class TypeScriptServiceConfiguration { && arrays.equals(this.tsServerPluginPaths, other.tsServerPluginPaths); } - private static extractGlobalTsdk(configuration: WorkspaceConfiguration): string | null { + private static extractGlobalTsdk(configuration: vscode.WorkspaceConfiguration): string | null { const inspect = configuration.inspect('typescript.tsdk'); if (inspect && inspect.globalValue && 'string' === typeof inspect.globalValue) { return inspect.globalValue; @@ -91,7 +91,7 @@ export class TypeScriptServiceConfiguration { return null; } - private static extractLocalTsdk(configuration: WorkspaceConfiguration): string | null { + private static extractLocalTsdk(configuration: vscode.WorkspaceConfiguration): string | null { const inspect = configuration.inspect('typescript.tsdk'); if (inspect && inspect.workspaceValue && 'string' === typeof inspect.workspaceValue) { return inspect.workspaceValue; @@ -99,32 +99,32 @@ export class TypeScriptServiceConfiguration { return null; } - private static readTsServerLogLevel(configuration: WorkspaceConfiguration): TsServerLogLevel { + private static readTsServerLogLevel(configuration: vscode.WorkspaceConfiguration): TsServerLogLevel { const setting = configuration.get('typescript.tsserver.log', 'off'); return TsServerLogLevel.fromString(setting); } - private static readTsServerPluginPaths(configuration: WorkspaceConfiguration): string[] { + private static readTsServerPluginPaths(configuration: vscode.WorkspaceConfiguration): string[] { return configuration.get('typescript.tsserver.pluginPaths', []); } - private static readCheckJs(configuration: WorkspaceConfiguration): boolean { + private static readCheckJs(configuration: vscode.WorkspaceConfiguration): boolean { return configuration.get('javascript.implicitProjectConfig.checkJs', false); } - private static readExperimentalDecorators(configuration: WorkspaceConfiguration): boolean { + private static readExperimentalDecorators(configuration: vscode.WorkspaceConfiguration): boolean { return configuration.get('javascript.implicitProjectConfig.experimentalDecorators', false); } - private static readNpmLocation(configuration: WorkspaceConfiguration): string | null { + private static readNpmLocation(configuration: vscode.WorkspaceConfiguration): string | null { return configuration.get('typescript.npm', null); } - private static readDisableAutomaticTypeAcquisition(configuration: WorkspaceConfiguration): boolean { + private static readDisableAutomaticTypeAcquisition(configuration: vscode.WorkspaceConfiguration): boolean { return configuration.get('typescript.disableAutomaticTypeAcquisition', false); } - private static extractLocale(configuration: WorkspaceConfiguration): string | null { + private static extractLocale(configuration: vscode.WorkspaceConfiguration): string | null { return configuration.get('typescript.locale', null); } } diff --git a/extensions/typescript-language-features/src/utils/logger.ts b/extensions/typescript-language-features/src/utils/logger.ts index 782fe871fe3..7ba79adad12 100644 --- a/extensions/typescript-language-features/src/utils/logger.ts +++ b/extensions/typescript-language-features/src/utils/logger.ts @@ -3,7 +3,7 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -import { OutputChannel, window } from 'vscode'; +import * as vscode from 'vscode'; import * as nls from 'vscode-nls'; import * as is from './is'; import { memoize } from './memoize'; @@ -13,8 +13,8 @@ const localize = nls.loadMessageBundle(); export default class Logger { @memoize - private get output(): OutputChannel { - return window.createOutputChannel(localize('channelName', 'TypeScript')); + private get output(): vscode.OutputChannel { + return vscode.window.createOutputChannel(localize('channelName', 'TypeScript')); } private data2String(data: any): string { diff --git a/extensions/typescript-language-features/src/utils/pluginPathsProvider.ts b/extensions/typescript-language-features/src/utils/pluginPathsProvider.ts index d001512234b..547660f0649 100644 --- a/extensions/typescript-language-features/src/utils/pluginPathsProvider.ts +++ b/extensions/typescript-language-features/src/utils/pluginPathsProvider.ts @@ -3,7 +3,7 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ import * as path from 'path'; -import { workspace } from 'vscode'; +import * as vscode from 'vscode'; import { TypeScriptServiceConfiguration } from './configuration'; import { RelativeWorkspacePathResolver } from './relativePathResolver'; @@ -37,7 +37,7 @@ export class TypeScriptPluginPathsProvider { return [workspacePath]; } - return (workspace.workspaceFolders || []) + return (vscode.workspace.workspaceFolders || []) .map(workspaceFolder => path.join(workspaceFolder.uri.fsPath, pluginPath)); } } \ No newline at end of file diff --git a/extensions/typescript-language-features/src/utils/plugins.ts b/extensions/typescript-language-features/src/utils/plugins.ts index 13966dd0b06..e67df651b40 100644 --- a/extensions/typescript-language-features/src/utils/plugins.ts +++ b/extensions/typescript-language-features/src/utils/plugins.ts @@ -3,7 +3,7 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -import { extensions } from 'vscode'; +import * as vscode from 'vscode'; export interface TypeScriptServerPlugin { readonly path: string; @@ -13,7 +13,7 @@ export interface TypeScriptServerPlugin { export function getContributedTypeScriptServerPlugins(): TypeScriptServerPlugin[] { const plugins: TypeScriptServerPlugin[] = []; - for (const extension of extensions.all) { + for (const extension of vscode.extensions.all) { const pack = extension.packageJSON; if (pack.contributes && pack.contributes.typescriptServerPlugins && Array.isArray(pack.contributes.typescriptServerPlugins)) { for (const plugin of pack.contributes.typescriptServerPlugins) { diff --git a/extensions/typescript-language-features/src/utils/previewer.ts b/extensions/typescript-language-features/src/utils/previewer.ts index df0105ac287..aa698b2c163 100644 --- a/extensions/typescript-language-features/src/utils/previewer.ts +++ b/extensions/typescript-language-features/src/utils/previewer.ts @@ -3,7 +3,7 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -import { MarkdownString } from 'vscode'; +import * as vscode from 'vscode'; import * as Proto from '../protocol'; function getTagBodyText(tag: Proto.JSDocTagInfo): string | undefined { @@ -64,17 +64,17 @@ export function tagsMarkdownPreview(tags: Proto.JSDocTagInfo[]): string { export function markdownDocumentation( documentation: Proto.SymbolDisplayPart[], tags: Proto.JSDocTagInfo[] -): MarkdownString { - const out = new MarkdownString(); +): vscode.MarkdownString { + const out = new vscode.MarkdownString(); addMarkdownDocumentation(out, documentation, tags); return out; } export function addMarkdownDocumentation( - out: MarkdownString, + out: vscode.MarkdownString, documentation: Proto.SymbolDisplayPart[] | undefined, tags: Proto.JSDocTagInfo[] | undefined -): MarkdownString { +): vscode.MarkdownString { if (documentation) { out.appendMarkdown(plain(documentation)); } diff --git a/extensions/typescript-language-features/src/utils/relativePathResolver.ts b/extensions/typescript-language-features/src/utils/relativePathResolver.ts index e424fca126a..85b72a55d6b 100644 --- a/extensions/typescript-language-features/src/utils/relativePathResolver.ts +++ b/extensions/typescript-language-features/src/utils/relativePathResolver.ts @@ -3,11 +3,11 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ import * as path from 'path'; -import { workspace } from 'vscode'; +import * as vscode from 'vscode'; export class RelativeWorkspacePathResolver { public asAbsoluteWorkspacePath(relativePath: string): string | undefined { - for (const root of workspace.workspaceFolders || []) { + for (const root of vscode.workspace.workspaceFolders || []) { const rootPrefixes = [`./${root.name}/`, `${root.name}/`, `.\\${root.name}\\`, `${root.name}\\`]; for (const rootPrefix of rootPrefixes) { if (relativePath.startsWith(rootPrefix)) { diff --git a/extensions/typescript-language-features/src/utils/resourceMap.ts b/extensions/typescript-language-features/src/utils/resourceMap.ts index f59ab661f5a..73364c03207 100644 --- a/extensions/typescript-language-features/src/utils/resourceMap.ts +++ b/extensions/typescript-language-features/src/utils/resourceMap.ts @@ -4,7 +4,7 @@ *--------------------------------------------------------------------------------------------*/ import * as fs from 'fs'; -import { Uri } from 'vscode'; +import * as vscode from 'vscode'; import { memoize } from './memoize'; import { getTempFile } from './temp'; @@ -18,27 +18,27 @@ export class ResourceMap { private readonly _map = new Map(); constructor( - private readonly _normalizePath?: (resource: Uri) => string | null + private readonly _normalizePath?: (resource: vscode.Uri) => string | null ) { } - public has(resource: Uri): boolean { + public has(resource: vscode.Uri): boolean { const file = this.toKey(resource); return !!file && this._map.has(file); } - public get(resource: Uri): T | undefined { + public get(resource: vscode.Uri): T | undefined { const file = this.toKey(resource); return file ? this._map.get(file) : undefined; } - public set(resource: Uri, value: T) { + public set(resource: vscode.Uri, value: T) { const file = this.toKey(resource); if (file) { this._map.set(file, value); } } - public delete(resource: Uri): void { + public delete(resource: vscode.Uri): void { const file = this.toKey(resource); if (file) { this._map.delete(file); @@ -57,7 +57,7 @@ export class ResourceMap { return this._map.entries(); } - private toKey(resource: Uri): string | null { + private toKey(resource: vscode.Uri): string | null { const key = this._normalizePath ? this._normalizePath(resource) : resource.fsPath; if (!key) { return key; diff --git a/extensions/typescript-language-features/src/utils/tracer.ts b/extensions/typescript-language-features/src/utils/tracer.ts index 2c12e2bf15a..2f2394dcaa1 100644 --- a/extensions/typescript-language-features/src/utils/tracer.ts +++ b/extensions/typescript-language-features/src/utils/tracer.ts @@ -3,12 +3,10 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -import { workspace } from 'vscode'; +import * as vscode from 'vscode'; import * as Proto from '../protocol'; import Logger from './logger'; - - enum Trace { Off, Messages, @@ -45,7 +43,7 @@ export default class Tracer { } private static readTrace(): Trace { - let result: Trace = Trace.fromString(workspace.getConfiguration().get('typescript.tsserver.trace', 'off')); + let result: Trace = Trace.fromString(vscode.workspace.getConfiguration().get('typescript.tsserver.trace', 'off')); if (result === Trace.Off && !!process.env.TSS_TRACE) { result = Trace.Messages; } diff --git a/extensions/typescript-language-features/src/utils/typingsStatus.ts b/extensions/typescript-language-features/src/utils/typingsStatus.ts index 0113435deda..78f303f0f39 100644 --- a/extensions/typescript-language-features/src/utils/typingsStatus.ts +++ b/extensions/typescript-language-features/src/utils/typingsStatus.ts @@ -3,7 +3,7 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -import { Disposable, MessageItem, ProgressLocation, window, workspace } from 'vscode'; +import * as vscode from 'vscode'; import { loadMessageBundle } from 'vscode-nls'; import { ITypeScriptServiceClient } from '../typescriptService'; @@ -11,10 +11,10 @@ const localize = loadMessageBundle(); const typingsInstallTimeout = 30 * 1000; -export default class TypingsStatus extends Disposable { +export default class TypingsStatus extends vscode.Disposable { private _acquiringTypings: { [eventId: string]: NodeJS.Timer } = Object.create({}); private _client: ITypeScriptServiceClient; - private _subscriptions: Disposable[] = []; + private _subscriptions: vscode.Disposable[] = []; constructor(client: ITypeScriptServiceClient) { super(() => this.dispose()); @@ -60,10 +60,10 @@ export default class TypingsStatus extends Disposable { export class AtaProgressReporter { private _promises = new Map(); - private _disposable: Disposable; + private _disposable: vscode.Disposable; constructor(client: ITypeScriptServiceClient) { - this._disposable = Disposable.from( + this._disposable = vscode.Disposable.from( client.onDidBeginInstallTypings(e => this._onBegin(e.eventId)), client.onDidEndInstallTypings(e => this._onEndOrTimeout(e.eventId)), client.onTypesInstallerInitializationFailed(_ => this.onTypesInstallerInitializationFailed())); @@ -83,8 +83,8 @@ export class AtaProgressReporter { }); }); - window.withProgress({ - location: ProgressLocation.Window, + vscode.window.withProgress({ + location: vscode.ProgressLocation.Window, title: localize('installingPackages', "Fetching data for better TypeScript IntelliSense") }, () => promise); } @@ -98,12 +98,12 @@ export class AtaProgressReporter { } private onTypesInstallerInitializationFailed() { - interface MyMessageItem extends MessageItem { + interface MyMessageItem extends vscode.MessageItem { id: number; } - if (workspace.getConfiguration('typescript').get('check.npmIsInstalled', true)) { - window.showWarningMessage( + if (vscode.workspace.getConfiguration('typescript').get('check.npmIsInstalled', true)) { + vscode.window.showWarningMessage( localize( 'typesInstallerInitializationFailed.title', "Could not install typings files for JavaScript language features. Please ensure that NPM is installed or configure 'typescript.npm' in your user settings. Click [here]({0}) to learn more.", @@ -118,7 +118,7 @@ export class AtaProgressReporter { } switch (selected.id) { case 1: - const tsConfig = workspace.getConfiguration('typescript'); + const tsConfig = vscode.workspace.getConfiguration('typescript'); tsConfig.update('check.npmIsInstalled', false, true); break; } diff --git a/extensions/typescript-language-features/src/utils/versionPicker.ts b/extensions/typescript-language-features/src/utils/versionPicker.ts index 0702a60e533..bf81cb5c466 100644 --- a/extensions/typescript-language-features/src/utils/versionPicker.ts +++ b/extensions/typescript-language-features/src/utils/versionPicker.ts @@ -3,7 +3,7 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -import { commands, Memento, QuickPickItem, Uri, window, workspace } from 'vscode'; +import * as vscode from 'vscode'; import * as nls from 'vscode-nls'; import { TypeScriptVersion, TypeScriptVersionProvider } from './versionProvider'; @@ -11,7 +11,7 @@ const localize = nls.loadMessageBundle(); const useWorkspaceTsdkStorageKey = 'typescript.useWorkspaceTsdk'; -interface MyQuickPickItem extends QuickPickItem { +interface MyQuickPickItem extends vscode.QuickPickItem { id: MessageAction; version?: TypeScriptVersion; } @@ -27,7 +27,7 @@ export class TypeScriptVersionPicker { public constructor( private readonly versionProvider: TypeScriptVersionProvider, - private readonly workspaceState: Memento + private readonly workspaceState: vscode.Memento ) { this._currentVersion = this.versionProvider.defaultVersion; @@ -82,7 +82,7 @@ export class TypeScriptVersionPicker { id: MessageAction.learnMore }); - const selected = await window.showQuickPick(pickOptions, { + const selected = await vscode.window.showQuickPick(pickOptions, { placeHolder: localize( 'selectTsVersion', 'Select the TypeScript version used for JavaScript and TypeScript language features'), @@ -97,7 +97,7 @@ export class TypeScriptVersionPicker { case MessageAction.useLocal: await this.workspaceState.update(useWorkspaceTsdkStorageKey, true); if (selected.version) { - const tsConfig = workspace.getConfiguration('typescript'); + const tsConfig = vscode.workspace.getConfiguration('typescript'); await tsConfig.update('tsdk', selected.version.pathLabel, false); const previousVersion = this.currentVersion; @@ -114,7 +114,7 @@ export class TypeScriptVersionPicker { case MessageAction.learnMore: - commands.executeCommand('vscode.open', Uri.parse('https://go.microsoft.com/fwlink/?linkid=839919')); + vscode.commands.executeCommand('vscode.open', vscode.Uri.parse('https://go.microsoft.com/fwlink/?linkid=839919')); return { oldVersion: this.currentVersion }; default: diff --git a/extensions/typescript-language-features/src/utils/versionProvider.ts b/extensions/typescript-language-features/src/utils/versionProvider.ts index 27b2d9fdebe..3061f1576b9 100644 --- a/extensions/typescript-language-features/src/utils/versionProvider.ts +++ b/extensions/typescript-language-features/src/utils/versionProvider.ts @@ -4,7 +4,7 @@ *--------------------------------------------------------------------------------------------*/ import * as fs from 'fs'; import * as path from 'path'; -import { window, workspace } from 'vscode'; +import * as vscode from 'vscode'; import * as nls from 'vscode-nls'; import API from './api'; import { TypeScriptServiceConfiguration } from './configuration'; @@ -12,9 +12,6 @@ import { RelativeWorkspacePathResolver } from './relativePathResolver'; const localize = nls.loadMessageBundle(); - - - export class TypeScriptVersion { constructor( public readonly path: string, @@ -40,7 +37,7 @@ export class TypeScriptVersion { } // Allow TS developers to provide custom version - const tsdkVersion = workspace.getConfiguration().get('typescript.tsdk_version', undefined); + const tsdkVersion = vscode.workspace.getConfiguration().get('typescript.tsdk_version', undefined); if (tsdkVersion) { return API.fromVersionString(tsdkVersion); } @@ -152,7 +149,7 @@ export class TypeScriptVersionProvider { } catch (e) { // noop } - window.showErrorMessage(localize( + vscode.window.showErrorMessage(localize( 'noBundledServerFound', 'VS Code\'s tsserver was deleted by another application such as a misbehaving virus detection tool. Please reinstall VS Code.')); throw new Error('Could not find bundled tsserver.js'); @@ -182,14 +179,14 @@ export class TypeScriptVersionProvider { } private loadTypeScriptVersionsFromPath(relativePath: string): TypeScriptVersion[] { - if (!workspace.workspaceFolders) { + if (!vscode.workspace.workspaceFolders) { return []; } const versions: TypeScriptVersion[] = []; - for (const root of workspace.workspaceFolders) { + for (const root of vscode.workspace.workspaceFolders) { let label: string = relativePath; - if (workspace.workspaceFolders && workspace.workspaceFolders.length > 1) { + if (vscode.workspace.workspaceFolders && vscode.workspace.workspaceFolders.length > 1) { label = path.join(root.name, relativePath); } From e8b1ee0b4d016bc38bbc1cf06d6d1868760d5fe8 Mon Sep 17 00:00:00 2001 From: Matt Bierner Date: Wed, 25 Jul 2018 18:50:16 -0700 Subject: [PATCH 0142/1276] Use more standard scheme across providers for getting TS response body - Avoids extra checks when response cannot be null --- .../src/features/completions.ts | 9 ++++----- .../src/features/documentHighlight.ts | 13 ++++++------- .../src/features/documentSymbol.ts | 9 ++++++--- .../src/features/folding.ts | 6 +++--- .../src/features/formatting.ts | 17 ++++++++++------- .../src/features/hover.ts | 9 ++++----- .../src/features/implementationsCodeLens.ts | 6 +++--- .../src/features/organizeImports.ts | 8 ++------ .../src/features/refactor.ts | 9 ++++----- .../src/features/references.ts | 6 +++--- .../src/features/referencesCodeLens.ts | 2 +- .../src/features/rename.ts | 8 ++++---- .../src/features/signatureHelp.ts | 8 ++++---- .../src/features/tagClosing.ts | 8 ++++---- .../src/features/updatePathsOnRename.ts | 4 ++-- .../src/features/workspaceSymbols.ts | 6 +++--- .../src/utils/codeAction.ts | 5 +---- 17 files changed, 64 insertions(+), 69 deletions(-) diff --git a/extensions/typescript-language-features/src/features/completions.ts b/extensions/typescript-language-features/src/features/completions.ts index 54e6661cac4..5f7ab357636 100644 --- a/extensions/typescript-language-features/src/features/completions.ts +++ b/extensions/typescript-language-features/src/features/completions.ts @@ -366,8 +366,8 @@ class TypeScriptCompletionItemProvider implements vscode.CompletionItemProvider let details: Proto.CompletionEntryDetails[] | undefined; try { - const response = await this.client.execute('completionEntryDetails', args, token); - details = response.body; + const { body } = await this.client.execute('completionEntryDetails', args, token); + details = body; } catch { return item; } @@ -529,9 +529,8 @@ class TypeScriptCompletionItemProvider implements vscode.CompletionItemProvider // Workaround for https://github.com/Microsoft/TypeScript/issues/12677 // Don't complete function calls inside of destructive assigments or imports try { - const infoResponse = await this.client.execute('quickinfo', typeConverters.Position.toFileLocationRequestArgs(filepath, position)); - const info = infoResponse.body; - switch (info && info.kind) { + const { body } = await this.client.execute('quickinfo', typeConverters.Position.toFileLocationRequestArgs(filepath, position)); + switch (body && body.kind) { case 'var': case 'let': case 'const': diff --git a/extensions/typescript-language-features/src/features/documentHighlight.ts b/extensions/typescript-language-features/src/features/documentHighlight.ts index dd0fb76f735..d661e154fdd 100644 --- a/extensions/typescript-language-features/src/features/documentHighlight.ts +++ b/extensions/typescript-language-features/src/features/documentHighlight.ts @@ -26,15 +26,14 @@ class TypeScriptDocumentHighlightProvider implements vscode.DocumentHighlightPro } const args = typeConverters.Position.toFileLocationRequestArgs(file, position); - let items: Proto.OccurrencesResponseItem[] | undefined; + let items: Proto.OccurrencesResponseItem[]; try { - const response = await this.client.execute('occurrences', args, token); - items = response.body; + const { body } = await this.client.execute('occurrences', args, token); + if (!body) { + return []; + } + items = body; } catch { - // noop - } - - if (!items) { return []; } diff --git a/extensions/typescript-language-features/src/features/documentSymbol.ts b/extensions/typescript-language-features/src/features/documentSymbol.ts index 84fc9117b9a..7d3e198ffd3 100644 --- a/extensions/typescript-language-features/src/features/documentSymbol.ts +++ b/extensions/typescript-language-features/src/features/documentSymbol.ts @@ -41,11 +41,14 @@ class TypeScriptDocumentSymbolProvider implements vscode.DocumentSymbolProvider } - let tree: Proto.NavigationTree | undefined; + let tree: Proto.NavigationTree; try { const args: Proto.FileRequestArgs = { file }; - const response = await this.client.execute('navtree', args, token); - tree = response.body; + const { body } = await this.client.execute('navtree', args, token); + if (!body) { + return undefined; + } + tree = body; } catch { return undefined; } diff --git a/extensions/typescript-language-features/src/features/folding.ts b/extensions/typescript-language-features/src/features/folding.ts index 78f3193fe00..471cf26cff2 100644 --- a/extensions/typescript-language-features/src/features/folding.ts +++ b/extensions/typescript-language-features/src/features/folding.ts @@ -26,12 +26,12 @@ class TypeScriptFoldingProvider implements vscode.FoldingRangeProvider { } const args: Proto.FileRequestArgs = { file }; - const response: Proto.OutliningSpansResponse = await this.client.execute('getOutliningSpans', args, token); - if (!response || !response.body) { + const { body } = await this.client.execute('getOutliningSpans', args, token); + if (!body) { return; } - return response.body + return body .map(span => this.convertOutliningSpan(span, document)) .filter(foldingRange => !!foldingRange) as vscode.FoldingRange[]; } diff --git a/extensions/typescript-language-features/src/features/formatting.ts b/extensions/typescript-language-features/src/features/formatting.ts index 89f68500c5b..b3ecff09d17 100644 --- a/extensions/typescript-language-features/src/features/formatting.ts +++ b/extensions/typescript-language-features/src/features/formatting.ts @@ -29,16 +29,19 @@ class TypeScriptFormattingProvider implements vscode.DocumentRangeFormattingEdit await this.formattingOptionsManager.ensureConfigurationOptions(document, options, token); - let edits: Proto.CodeEdit[] | undefined; + let edits: Proto.CodeEdit[]; try { const args = typeConverters.Range.toFormattingRequestArgs(file, range); - const response = await this.client.execute('format', args, token); - edits = response.body; + const { body } = await this.client.execute('format', args, token); + if (!body) { + return undefined; + } + edits = body; } catch { - // noop + return undefined; } - return (edits || []).map(typeConverters.TextEdit.fromCodeEdit); + return edits.map(typeConverters.TextEdit.fromCodeEdit); } public async provideOnTypeFormattingEdits( @@ -60,8 +63,8 @@ class TypeScriptFormattingProvider implements vscode.DocumentRangeFormattingEdit key: ch }; try { - const response = await this.client.execute('formatonkey', args, token); - const edits = response.body; + const { body } = await this.client.execute('formatonkey', args, token); + const edits = body; const result: vscode.TextEdit[] = []; if (!edits) { return result; diff --git a/extensions/typescript-language-features/src/features/hover.ts b/extensions/typescript-language-features/src/features/hover.ts index fcc2b3401a8..78580d3dfdc 100644 --- a/extensions/typescript-language-features/src/features/hover.ts +++ b/extensions/typescript-language-features/src/features/hover.ts @@ -27,12 +27,11 @@ class TypeScriptHoverProvider implements vscode.HoverProvider { } const args = typeConverters.Position.toFileLocationRequestArgs(filepath, position); try { - const response = await this.client.execute('quickinfo', args, token); - if (response && response.body) { - const data = response.body; + const { body } = await this.client.execute('quickinfo', args, token); + if (body) { return new vscode.Hover( - TypeScriptHoverProvider.getContents(data), - typeConverters.Range.fromTextSpan(data)); + TypeScriptHoverProvider.getContents(body), + typeConverters.Range.fromTextSpan(body)); } } catch (e) { // noop diff --git a/extensions/typescript-language-features/src/features/implementationsCodeLens.ts b/extensions/typescript-language-features/src/features/implementationsCodeLens.ts index 1a205b8b7fb..5b4ef7b0eb0 100644 --- a/extensions/typescript-language-features/src/features/implementationsCodeLens.ts +++ b/extensions/typescript-language-features/src/features/implementationsCodeLens.ts @@ -23,9 +23,9 @@ export default class TypeScriptImplementationsCodeLensProvider extends TypeScrip const codeLens = inputCodeLens as ReferencesCodeLens; const args = typeConverters.Position.toFileLocationRequestArgs(codeLens.file, codeLens.range.start); try { - const response = await this.client.execute('implementation', args, token); - if (response && response.body) { - const locations = response.body + const { body } = await this.client.execute('implementation', args, token); + if (body) { + const locations = body .map(reference => // Only take first line on implementation: https://github.com/Microsoft/vscode/issues/23924 new vscode.Location(this.client.toResource(reference.file), diff --git a/extensions/typescript-language-features/src/features/organizeImports.ts b/extensions/typescript-language-features/src/features/organizeImports.ts index ecf080b313f..5465b989507 100644 --- a/extensions/typescript-language-features/src/features/organizeImports.ts +++ b/extensions/typescript-language-features/src/features/organizeImports.ts @@ -45,12 +45,8 @@ class OrganizeImportsCommand implements Command { } } }; - const response = await this.client.execute('organizeImports', args); - if (!response || !response.success) { - return false; - } - - const edits = typeconverts.WorkspaceEdit.fromFileCodeEdits(this.client, response.body); + const { body } = await this.client.execute('organizeImports', args); + const edits = typeconverts.WorkspaceEdit.fromFileCodeEdits(this.client, body); return vscode.workspace.applyEdit(edits); } } diff --git a/extensions/typescript-language-features/src/features/refactor.ts b/extensions/typescript-language-features/src/features/refactor.ts index fbb3a3b88ef..ccb5e2f12f8 100644 --- a/extensions/typescript-language-features/src/features/refactor.ts +++ b/extensions/typescript-language-features/src/features/refactor.ts @@ -47,8 +47,7 @@ class ApplyRefactoringCommand implements Command { refactor, action }; - const response = await this.client.execute('getEditsForRefactor', args); - const body = response && response.body; + const { body } = await this.client.execute('getEditsForRefactor', args); if (!body || !body.edits.length) { return false; } @@ -142,11 +141,11 @@ class TypeScriptRefactorProvider implements vscode.CodeActionProvider { const args: Proto.GetApplicableRefactorsRequestArgs = typeConverters.Range.toFileRangeRequestArgs(file, rangeOrSelection); let refactorings: Proto.ApplicableRefactorInfo[]; try { - const response = await this.client.execute('getApplicableRefactors', args, token); - if (!response.body) { + const { body } = await this.client.execute('getApplicableRefactors', args, token); + if (!body) { return undefined; } - refactorings = response.body; + refactorings = body; } catch { return undefined; } diff --git a/extensions/typescript-language-features/src/features/references.ts b/extensions/typescript-language-features/src/features/references.ts index a4b81e54f5b..50c62b3b722 100644 --- a/extensions/typescript-language-features/src/features/references.ts +++ b/extensions/typescript-language-features/src/features/references.ts @@ -26,13 +26,13 @@ class TypeScriptReferenceSupport implements vscode.ReferenceProvider { const args = typeConverters.Position.toFileLocationRequestArgs(filepath, position); try { - const msg = await this.client.execute('references', args, token); - if (!msg.body) { + const { body } = await this.client.execute('references', args, token); + if (!body) { return []; } const result: vscode.Location[] = []; const has203Features = this.client.apiVersion.gte(API.v203); - for (const ref of msg.body.refs) { + for (const ref of body.refs) { if (!options.includeDeclaration && has203Features && ref.isDefinition) { continue; } diff --git a/extensions/typescript-language-features/src/features/referencesCodeLens.ts b/extensions/typescript-language-features/src/features/referencesCodeLens.ts index 059d3e9e16e..e243e0d0e37 100644 --- a/extensions/typescript-language-features/src/features/referencesCodeLens.ts +++ b/extensions/typescript-language-features/src/features/referencesCodeLens.ts @@ -21,7 +21,7 @@ class TypeScriptReferencesCodeLensProvider extends TypeScriptBaseCodeLensProvide const codeLens = inputCodeLens as ReferencesCodeLens; const args = typeConverters.Position.toFileLocationRequestArgs(codeLens.file, codeLens.range.start); return this.client.execute('references', args, token).then(response => { - if (!response || !response.body) { + if (!response.body) { throw codeLens; } diff --git a/extensions/typescript-language-features/src/features/rename.ts b/extensions/typescript-language-features/src/features/rename.ts index c73539409fa..1e6f0070b1a 100644 --- a/extensions/typescript-language-features/src/features/rename.ts +++ b/extensions/typescript-language-features/src/features/rename.ts @@ -32,17 +32,17 @@ class TypeScriptRenameProvider implements vscode.RenameProvider { }; try { - const response = await this.client.execute('rename', args, token); - if (!response.body) { + const { body } = await this.client.execute('rename', args, token); + if (!body) { return null; } - const renameInfo = response.body.info; + const renameInfo = body.info; if (!renameInfo.canRename) { return Promise.reject(renameInfo.localizedErrorMessage); } - return this.toWorkspaceEdit(response.body.locs, newName); + return this.toWorkspaceEdit(body.locs, newName); } catch { // noop } diff --git a/extensions/typescript-language-features/src/features/signatureHelp.ts b/extensions/typescript-language-features/src/features/signatureHelp.ts index b682e0b0367..f3a9a3e5620 100644 --- a/extensions/typescript-language-features/src/features/signatureHelp.ts +++ b/extensions/typescript-language-features/src/features/signatureHelp.ts @@ -28,13 +28,13 @@ class TypeScriptSignatureHelpProvider implements vscode.SignatureHelpProvider { } const args: Proto.SignatureHelpRequestArgs = typeConverters.Position.toFileLocationRequestArgs(filepath, position); - let info: Proto.SignatureHelpItems | undefined = undefined; + let info: Proto.SignatureHelpItems; try { - const response = await this.client.execute('signatureHelp', args, token); - info = response.body; - if (!info) { + const { body } = await this.client.execute('signatureHelp', args, token); + if (!body) { return undefined; } + info = body; } catch { return undefined; } diff --git a/extensions/typescript-language-features/src/features/tagClosing.ts b/extensions/typescript-language-features/src/features/tagClosing.ts index 40839c30c65..838779848da 100644 --- a/extensions/typescript-language-features/src/features/tagClosing.ts +++ b/extensions/typescript-language-features/src/features/tagClosing.ts @@ -88,16 +88,16 @@ class TagClosing extends Disposable { } let position = new vscode.Position(rangeStart.line, rangeStart.character + lastChange.text.length); - let body: Proto.TextInsertion | undefined = undefined; + let insertion: Proto.TextInsertion; const args: Proto.JsxClosingTagRequestArgs = typeConverters.Position.toFileLocationRequestArgs(filepath, position); this._cancel = new vscode.CancellationTokenSource(); try { - const response = await this.client.execute('jsxClosingTag', args, this._cancel.token); - body = response && response.body; + const { body } = await this.client.execute('jsxClosingTag', args, this._cancel.token); if (!body) { return; } + insertion = body; } catch { return; } @@ -114,7 +114,7 @@ class TagClosing extends Disposable { const activeDocument = activeEditor.document; if (document === activeDocument && activeDocument.version === version) { activeEditor.insertSnippet( - this.getTagSnippet(body), + this.getTagSnippet(insertion), this.getInsertionPositions(activeEditor, position)); } }, 100); diff --git a/extensions/typescript-language-features/src/features/updatePathsOnRename.ts b/extensions/typescript-language-features/src/features/updatePathsOnRename.ts index def9ced477a..ba19b8da8aa 100644 --- a/extensions/typescript-language-features/src/features/updatePathsOnRename.ts +++ b/extensions/typescript-language-features/src/features/updatePathsOnRename.ts @@ -84,11 +84,11 @@ class UpdateImportsOnFileRenameHandler { // Workaround for https://github.com/Microsoft/vscode/issues/52967 // Never attempt to update import paths if the file does not contain something the looks like an export try { - const tree = await this.client.execute('navtree', { file: newFile }); + const { body } = await this.client.execute('navtree', { file: newFile }); const hasExport = (node: Proto.NavigationTree): boolean => { return !!node.kindModifiers.match(/\bexports?\b/g) || !!(node.childItems && node.childItems.some(hasExport)); }; - if (!tree.body || !tree.body || !hasExport(tree.body)) { + if (!body || !hasExport(body)) { return; } } catch { diff --git a/extensions/typescript-language-features/src/features/workspaceSymbols.ts b/extensions/typescript-language-features/src/features/workspaceSymbols.ts index 5d987b85133..4d06850baa0 100644 --- a/extensions/typescript-language-features/src/features/workspaceSymbols.ts +++ b/extensions/typescript-language-features/src/features/workspaceSymbols.ts @@ -44,13 +44,13 @@ class TypeScriptWorkspaceSymbolProvider implements vscode.WorkspaceSymbolProvide file: filepath, searchValue: search }; - const response = await this.client.execute('navto', args, token); - if (!response.body) { + const { body } = await this.client.execute('navto', args, token); + if (!body) { return []; } const result: vscode.SymbolInformation[] = []; - for (const item of response.body) { + for (const item of body) { if (!item.containerName && item.kind === 'alias') { continue; } diff --git a/extensions/typescript-language-features/src/utils/codeAction.ts b/extensions/typescript-language-features/src/utils/codeAction.ts index 0271a93c8fb..6109ed70051 100644 --- a/extensions/typescript-language-features/src/utils/codeAction.ts +++ b/extensions/typescript-language-features/src/utils/codeAction.ts @@ -36,10 +36,7 @@ export async function applyCodeActionCommands( ): Promise { if (commands && commands.length) { for (const command of commands) { - const response = await client.execute('applyCodeActionCommand', { command }); - if (!response || !response.body) { - return false; - } + await client.execute('applyCodeActionCommand', { command }); } } return true; From 8e8e8023ce8d5a11aca9e58c7f94a5facf4b3ebd Mon Sep 17 00:00:00 2001 From: Sandeep Somavarapu Date: Thu, 26 Jul 2018 09:40:24 +0200 Subject: [PATCH 0143/1276] Improve light bulb position in problems panel --- .../parts/markers/electron-browser/media/markers.css | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/src/vs/workbench/parts/markers/electron-browser/media/markers.css b/src/vs/workbench/parts/markers/electron-browser/media/markers.css index dbf159f8436..373b5718b2e 100644 --- a/src/vs/workbench/parts/markers/electron-browser/media/markers.css +++ b/src/vs/workbench/parts/markers/electron-browser/media/markers.css @@ -136,7 +136,7 @@ font-weight: bold; } -.markers-panel .icon { +.markers-panel .monaco-tree .markers-panel-tree-entry > .icon { height: 22px; margin-right: 6px; flex: 0 0 16px; @@ -166,13 +166,17 @@ background: url('status-info-inverse.svg') center center no-repeat; } -.vs-dark .markers-panel .icon.markers-panel-action-quickfix { +.markers-panel .monaco-tree .markers-panel-tree-entry .actions .action-label.icon.markers-panel-action-quickfix { + background: url('lightbulb.svg') center/80% no-repeat; + margin-right: 0px; +} + +.vs-dark .markers-panel .monaco-tree .markers-panel-tree-entry .actions .action-label.icon.markers-panel-action-quickfix { background: url('lightbulb-dark.svg') center/80% no-repeat; - background-position: 50% 55%; } .markers-panel .monaco-tree .monaco-tree-row .markers-panel-tree-entry > .actions { - width: 22px; + width: 16px; } .markers-panel .monaco-tree .monaco-tree-row .markers-panel-tree-entry > .actions .monaco-action-bar { From 73b72464b3f71db7ac3b763f37e84769bd411a7b Mon Sep 17 00:00:00 2001 From: Erich Gamma Date: Thu, 26 Jul 2018 09:10:55 +0200 Subject: [PATCH 0144/1276] Replace lenses with hover links --- extensions/npm/package.json | 6 -- extensions/npm/package.nls.json | 1 - extensions/npm/src/lenses.ts | 86 ----------------------- extensions/npm/src/main.ts | 17 ++--- extensions/npm/src/scriptHover.ts | 109 ++++++++++++++++++++++++++++++ extensions/npm/src/tasks.ts | 9 ++- 6 files changed, 122 insertions(+), 106 deletions(-) delete mode 100644 extensions/npm/src/lenses.ts create mode 100644 extensions/npm/src/scriptHover.ts diff --git a/extensions/npm/package.json b/extensions/npm/package.json index 434f7ea20b1..df9c903fcb4 100644 --- a/extensions/npm/package.json +++ b/extensions/npm/package.json @@ -178,12 +178,6 @@ "scope": "resource", "description": "%config.npm.runSilent%" }, - "npm.scriptCodeLens.enable": { - "type": "boolean", - "default": false, - "scope": "resource", - "description": "%config.scriptCodeLens.enable%" - }, "npm.packageManager": { "scope": "resource", "type": "string", diff --git a/extensions/npm/package.nls.json b/extensions/npm/package.nls.json index be9381e3377..92665d5f65a 100644 --- a/extensions/npm/package.nls.json +++ b/extensions/npm/package.nls.json @@ -7,7 +7,6 @@ "config.npm.exclude": "Configure glob patterns for folders that should be excluded from automatic script detection.", "config.npm.enableScriptExplorer": "Enable an explorer view for npm scripts.", "config.npm.scriptExplorerAction": "The default click action used in the scripts explorer: 'open' or 'run', the default is 'open'.", - "config.scriptCodeLens.enable": "Enable the code lens to 'Run' or 'Debug' an npm script.", "npm.parseError": "Npm task detection: failed to parse the file {0}", "taskdef.script": "The npm script to customize.", "taskdef.path": "The path to the folder of the package.json file that provides the script. Can be omitted.", diff --git a/extensions/npm/src/lenses.ts b/extensions/npm/src/lenses.ts deleted file mode 100644 index 6394fbad5b3..00000000000 --- a/extensions/npm/src/lenses.ts +++ /dev/null @@ -1,86 +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'; - -import { - ExtensionContext, CodeLensProvider, TextDocument, commands, ProviderResult, CodeLens, CancellationToken, - workspace, tasks, Range, Command, Event, EventEmitter -} from 'vscode'; -import { - createTask, startDebugging, findAllScriptRanges, extractDebugArgFromScript -} from './tasks'; -import * as nls from 'vscode-nls'; - -const localize = nls.loadMessageBundle(); - -export class NpmLensProvider implements CodeLensProvider { - private extensionContext: ExtensionContext; - private _onDidChangeCodeLenses: EventEmitter = new EventEmitter(); - readonly onDidChangeCodeLenses: Event = this._onDidChangeCodeLenses.event; - - constructor(context: ExtensionContext) { - this.extensionContext = context; - context.subscriptions.push(commands.registerCommand('npm.runScriptFromLens', this.runScriptFromLens, this)); - context.subscriptions.push(commands.registerCommand('npm.debugScriptFromLens', this.debugScriptFromLens, this)); - } - - public provideCodeLenses(document: TextDocument, _token: CancellationToken): ProviderResult { - let result = findAllScriptRanges(document.getText()); - let folder = workspace.getWorkspaceFolder(document.uri); - let lenses: CodeLens[] = []; - - - if (folder && !workspace.getConfiguration('npm', folder.uri).get('scriptCodeLens.enable', 'true')) { - return lenses; - } - - result.forEach((value, key) => { - let start = document.positionAt(value[0]); - let end = document.positionAt(value[0] + value[1]); - let range = new Range(start, end); - - let command: Command = { - command: 'npm.runScriptFromLens', - title: localize('run', "Run"), - arguments: [document, key] - }; - let lens: CodeLens = new CodeLens(range, command); - lenses.push(lens); - - let debugArgs = extractDebugArgFromScript(value[2]); - if (debugArgs) { - command = { - command: 'npm.debugScriptFromLens', - title: localize('debug', "Debug"), - arguments: [document, key, debugArgs[0], debugArgs[1]] - }; - lens = new CodeLens(range, command); - lenses.push(lens); - } - }); - return lenses; - } - - public refresh() { - this._onDidChangeCodeLenses.fire(); - } - - public runScriptFromLens(document: TextDocument, script: string) { - let uri = document.uri; - let folder = workspace.getWorkspaceFolder(uri); - if (folder) { - let task = createTask(script, `run ${script}`, folder, uri); - tasks.executeTask(task); - } - } - - public debugScriptFromLens(document: TextDocument, script: string, protocol: string, port: number) { - let uri = document.uri; - let folder = workspace.getWorkspaceFolder(uri); - if (folder) { - startDebugging(script, protocol, port, folder); - } - } -} diff --git a/extensions/npm/src/main.ts b/extensions/npm/src/main.ts index f2c80f5f476..be077371d0c 100644 --- a/extensions/npm/src/main.ts +++ b/extensions/npm/src/main.ts @@ -6,16 +6,15 @@ import * as httpRequest from 'request-light'; import * as vscode from 'vscode'; - import { addJSONProviders } from './features/jsonContributions'; import { NpmScriptsTreeDataProvider } from './npmView'; import { invalidateScriptsCache, NpmTaskProvider } from './tasks'; -import { NpmLensProvider } from './lenses'; +import { NpmScriptHoverProvider } from './scriptHover'; export async function activate(context: vscode.ExtensionContext): Promise { const taskProvider = registerTaskProvider(context); const treeDataProvider = registerExplorer(context); - const lensProvider = registerLensProvider(context); + const hoverProvider = registerHoverProvider(context); configureHttpRequest(); vscode.workspace.onDidChangeConfiguration((e) => { @@ -31,11 +30,6 @@ export async function activate(context: vscode.ExtensionContext): Promise treeDataProvider.refresh(); } } - if (e.affectsConfiguration('npm.scriptCodeLens.enable')) { - if (lensProvider) { - lensProvider.refresh(); - } - } }); context.subscriptions.push(addJSONProviders(httpRequest.xhr)); } @@ -66,20 +60,21 @@ function registerExplorer(context: vscode.ExtensionContext): NpmScriptsTreeDataP return undefined; } -function registerLensProvider(context: vscode.ExtensionContext): NpmLensProvider | undefined { +function registerHoverProvider(context: vscode.ExtensionContext): NpmScriptHoverProvider | undefined { if (vscode.workspace.workspaceFolders) { let npmSelector: vscode.DocumentSelector = { language: 'json', scheme: 'file', pattern: '**/package.json' }; - let provider = new NpmLensProvider(context); - context.subscriptions.push(vscode.languages.registerCodeLensProvider(npmSelector, provider)); + let provider = new NpmScriptHoverProvider(context); + context.subscriptions.push(vscode.languages.registerHoverProvider(npmSelector, provider)); return provider; } return undefined; } + function configureHttpRequest() { const httpSettings = vscode.workspace.getConfiguration('http'); httpRequest.configure(httpSettings.get('proxy', ''), httpSettings.get('proxyStrictSSL', true)); diff --git a/extensions/npm/src/scriptHover.ts b/extensions/npm/src/scriptHover.ts new file mode 100644 index 00000000000..5eafb19dfe1 --- /dev/null +++ b/extensions/npm/src/scriptHover.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 { + ExtensionContext, TextDocument, commands, ProviderResult, CancellationToken, + workspace, tasks, Range, HoverProvider, Hover, Position, MarkdownString, Uri +} from 'vscode'; +import { + createTask, startDebugging, findAllScriptRanges, extractDebugArgFromScript +} from './tasks'; +import * as nls from 'vscode-nls'; + +const localize = nls.loadMessageBundle(); + +export class NpmScriptHoverProvider implements HoverProvider { + private extensionContext: ExtensionContext; + + constructor(context: ExtensionContext) { + this.extensionContext = context; + context.subscriptions.push(commands.registerCommand('npm.runScriptFromHover', this.runScriptFromHover, this)); + context.subscriptions.push(commands.registerCommand('npm.debugScriptFromHover', this.debugScriptFromHover, this)); + } + + public provideHover(document: TextDocument, position: Position, _token: CancellationToken): ProviderResult { + let result = findAllScriptRanges(document.getText()); + let hover: Hover | undefined = undefined; + + result.forEach((value, key) => { + let start = document.positionAt(value[0]); + let end = document.positionAt(value[0] + value[1]); + let range = new Range(start, end); + + if (range.contains(position)) { + let contents: MarkdownString = new MarkdownString(); + contents.isTrusted = true; + contents.appendMarkdown(this.createRunScriptMarkdown(key, document.uri)); + + let debugArgs = extractDebugArgFromScript(value[2]); + if (debugArgs) { + contents.appendMarkdown(this.createDebugScriptMarkdown(key, document.uri, debugArgs[0], debugArgs[1])); + } + hover = new Hover(contents); + } + }); + return hover; + } + + private createRunScriptMarkdown(script: string, documentUri: Uri): string { + let args = { + documentUri: documentUri, + script: script, + }; + return this.createMarkdownLink( + localize('runScript', 'Run Script'), + 'npm.runScriptFromHover', + args, + localize('runScript.tooltip', 'Run the script as a task') + ); + } + + private createDebugScriptMarkdown(script: string, documentUri: Uri, protocol: string, port: number): string { + let args = { + documentUri: documentUri, + script: script, + protocol: protocol, + port: port + }; + return this.createMarkdownLink( + localize('debugScript', 'Debug Script'), + 'npm.debugScriptFromHover', + args, + localize('debugScript.tooltip', 'Runs the script under the debugger'), + '|' + ); + } + + private createMarkdownLink(label: string, cmd: string, args: any, tooltip: string, separator?: string): string { + let encodedArgs = encodeURIComponent(JSON.stringify(args)); + let prefix = ''; + if (separator) { + prefix = ` ${separator} `; + } + return `${prefix}[${label}](command:${cmd}?${encodedArgs} "${tooltip}")`; + } + + public runScriptFromHover(args: any) { + let script = args.script; + let documentUri = args.documentUri; + let folder = workspace.getWorkspaceFolder(documentUri); + if (folder) { + let task = createTask(script, `run ${script}`, folder, documentUri); + tasks.executeTask(task); + } + } + + public debugScriptFromHover(args: any) { + let script = args.script; + let documentUri = args.documentUri; + let protocol = args.protocol; + let port = args.port; + let folder = workspace.getWorkspaceFolder(documentUri); + if (folder) { + startDebugging(script, protocol, port, folder); + } + } +} diff --git a/extensions/npm/src/tasks.ts b/extensions/npm/src/tasks.ts index 5d19a4c4c00..b4b63e85f19 100644 --- a/extensions/npm/src/tasks.ts +++ b/extensions/npm/src/tasks.ts @@ -371,6 +371,9 @@ async function findAllScripts(buffer: string): Promise { export function findAllScriptRanges(buffer: string): Map { var scripts: Map = new Map(); let script: string | undefined = undefined; + let offset: number; + let length: number; + let inScripts = false; let visitor: JSONVisitor = { @@ -381,18 +384,20 @@ export function findAllScriptRanges(buffer: string): Map Date: Thu, 26 Jul 2018 09:41:23 +0200 Subject: [PATCH 0145/1276] cache the scripts for the hover --- extensions/npm/src/main.ts | 19 ++++++++++++------- extensions/npm/src/scriptHover.ts | 15 +++++++++++++-- extensions/npm/src/tasks.ts | 2 +- 3 files changed, 26 insertions(+), 10 deletions(-) diff --git a/extensions/npm/src/main.ts b/extensions/npm/src/main.ts index be077371d0c..a3c7dc03d9c 100644 --- a/extensions/npm/src/main.ts +++ b/extensions/npm/src/main.ts @@ -8,8 +8,8 @@ import * as httpRequest from 'request-light'; import * as vscode from 'vscode'; import { addJSONProviders } from './features/jsonContributions'; import { NpmScriptsTreeDataProvider } from './npmView'; -import { invalidateScriptsCache, NpmTaskProvider } from './tasks'; -import { NpmScriptHoverProvider } from './scriptHover'; +import { invalidateTasksCache, NpmTaskProvider } from './tasks'; +import { invalidateHoverScriptsCache, NpmScriptHoverProvider } from './scriptHover'; export async function activate(context: vscode.ExtensionContext): Promise { const taskProvider = registerTaskProvider(context); @@ -20,7 +20,7 @@ export async function activate(context: vscode.ExtensionContext): Promise vscode.workspace.onDidChangeConfiguration((e) => { configureHttpRequest(); if (e.affectsConfiguration('npm.exclude')) { - invalidateScriptsCache(); + invalidateTasksCache(); if (treeDataProvider) { treeDataProvider.refresh(); } @@ -35,11 +35,17 @@ export async function activate(context: vscode.ExtensionContext): Promise } function registerTaskProvider(context: vscode.ExtensionContext): vscode.Disposable | undefined { + + function invalidateScriptCaches() { + invalidateHoverScriptsCache(); + invalidateTasksCache(); + } + if (vscode.workspace.workspaceFolders) { let watcher = vscode.workspace.createFileSystemWatcher('**/package.json'); - watcher.onDidChange((_e) => invalidateScriptsCache()); - watcher.onDidDelete((_e) => invalidateScriptsCache()); - watcher.onDidCreate((_e) => invalidateScriptsCache()); + watcher.onDidChange((_e) => invalidateScriptCaches()); + watcher.onDidDelete((_e) => invalidateScriptCaches()); + watcher.onDidCreate((_e) => invalidateScriptCaches()); context.subscriptions.push(watcher); let provider: vscode.TaskProvider = new NpmTaskProvider(context); @@ -74,7 +80,6 @@ function registerHoverProvider(context: vscode.ExtensionContext): NpmScriptHover return undefined; } - function configureHttpRequest() { const httpSettings = vscode.workspace.getConfiguration('http'); httpRequest.configure(httpSettings.get('proxy', ''), httpSettings.get('proxyStrictSSL', true)); diff --git a/extensions/npm/src/scriptHover.ts b/extensions/npm/src/scriptHover.ts index 5eafb19dfe1..1349965a151 100644 --- a/extensions/npm/src/scriptHover.ts +++ b/extensions/npm/src/scriptHover.ts @@ -15,6 +15,13 @@ import * as nls from 'vscode-nls'; const localize = nls.loadMessageBundle(); +let cachedDocument: Uri | undefined = undefined; +let cachedScriptsMap: Map | undefined = undefined; + +export function invalidateHoverScriptsCache() { + cachedDocument = undefined; +} + export class NpmScriptHoverProvider implements HoverProvider { private extensionContext: ExtensionContext; @@ -25,10 +32,14 @@ export class NpmScriptHoverProvider implements HoverProvider { } public provideHover(document: TextDocument, position: Position, _token: CancellationToken): ProviderResult { - let result = findAllScriptRanges(document.getText()); let hover: Hover | undefined = undefined; - result.forEach((value, key) => { + if (!cachedDocument || cachedDocument.fsPath !== document.uri.fsPath) { + cachedScriptsMap = findAllScriptRanges(document.getText()); + cachedDocument = document.uri; + } + + cachedScriptsMap!.forEach((value, key) => { let start = document.positionAt(value[0]); let end = document.positionAt(value[0] + value[1]); let range = new Range(start, end); diff --git a/extensions/npm/src/tasks.ts b/extensions/npm/src/tasks.ts index b4b63e85f19..008d5ba7e70 100644 --- a/extensions/npm/src/tasks.ts +++ b/extensions/npm/src/tasks.ts @@ -41,7 +41,7 @@ export class NpmTaskProvider implements TaskProvider { } } -export function invalidateScriptsCache() { +export function invalidateTasksCache() { cachedTasks = undefined; } From 861f8dbe6db0b314830a85220122ba188994c0ec Mon Sep 17 00:00:00 2001 From: Sandeep Somavarapu Date: Thu, 26 Jul 2018 09:58:09 +0200 Subject: [PATCH 0146/1276] :lipstick: --- .../parts/extensions/node/extensionsWorkbenchService.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vs/workbench/parts/extensions/node/extensionsWorkbenchService.ts b/src/vs/workbench/parts/extensions/node/extensionsWorkbenchService.ts index 75762a4bc44..d4a83cbb15c 100644 --- a/src/vs/workbench/parts/extensions/node/extensionsWorkbenchService.ts +++ b/src/vs/workbench/parts/extensions/node/extensionsWorkbenchService.ts @@ -761,7 +761,7 @@ export class ExtensionsWorkbenchService implements IExtensionsWorkbenchService, } private promptForDependenciesAndDisable(extensions: IExtension[], dependencies: IExtension[], enablementState: EnablementState): TPromise { - const message = nls.localize('disableDependeciesConfirmation', "Would you like to disable the dependencies of the extensions also?"); + const message = extensions.length > 1 ? nls.localize('disableDependeciesConfirmation', "Would you like to disable the dependencies of the extensions also?") : nls.localize('disableDependeciesSingleExtensionConfirmation', "Would you like to disable the dependencies of the extension also?"); const buttons = [ nls.localize('yes', "Yes"), nls.localize('no', "No"), From c6466ed68bf3b812fe8d57eb73c1e63aac732c4f Mon Sep 17 00:00:00 2001 From: Sandeep Somavarapu Date: Thu, 26 Jul 2018 10:19:10 +0200 Subject: [PATCH 0147/1276] add space in the front to the related information entry --- .../markers/electron-browser/markersTreeViewer.ts | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/src/vs/workbench/parts/markers/electron-browser/markersTreeViewer.ts b/src/vs/workbench/parts/markers/electron-browser/markersTreeViewer.ts index 2b65a817845..fa7cc47b431 100644 --- a/src/vs/workbench/parts/markers/electron-browser/markersTreeViewer.ts +++ b/src/vs/workbench/parts/markers/electron-browser/markersTreeViewer.ts @@ -170,6 +170,9 @@ export class Renderer implements IRenderer { private renderRelatedInfoTemplate(container: HTMLElement): IRelatedInformationTemplateData { const data: IRelatedInformationTemplateData = Object.create(null); + dom.append(container, dom.$('.actions')); + dom.append(container, dom.$('.icon')); + data.resourceLabel = new HighlightedLabel(dom.append(container, dom.$('.related-info-resource'))); data.lnCol = dom.append(container, dom.$('span.marker-line')); @@ -185,7 +188,7 @@ export class Renderer implements IRenderer { const data: IMarkerTemplateData = Object.create(null); const actionsContainer = dom.append(container, dom.$('.actions')); data.actionBar = new ActionBar(actionsContainer, { actionItemProvider: this.actionItemProvider }); - data.icon = dom.append(container, dom.$('.marker-icon')); + data.icon = dom.append(container, dom.$('.icon')); data.source = new HighlightedLabel(dom.append(container, dom.$(''))); data.description = new HighlightedLabel(dom.append(container, dom.$('.marker-description'))); data.lnCol = dom.append(container, dom.$('span.marker-line')); @@ -222,14 +225,15 @@ export class Renderer implements IRenderer { dom.toggleClass(templateData.source.element, 'marker-source', !!marker.source); templateData.actionBar.clear(); - const parent = tree.getNavigator(element).parent(); - const quickFixAction = this.instantiationService.createInstance(QuickFixAction, element, parent); + const resourceMarkers: ResourceMarkers = tree.getNavigator(element).parent(); + const quickFixAction = this.instantiationService.createInstance(QuickFixAction, element, resourceMarkers); templateData.actionBar.push([quickFixAction], { icon: true, label: false }); templateData.description.set(marker.message, element.messageMatches); templateData.description.element.title = marker.message; templateData.lnCol.textContent = Messages.MARKERS_PANEL_AT_LINE_COL_NUMBER(marker.startLineNumber, marker.startColumn); + } private renderRelatedInfoElement(tree: ITree, element: RelatedInformation, templateData: IRelatedInformationTemplateData) { From 9341724f6d9e708e9b236657fe44c99522e4d06f Mon Sep 17 00:00:00 2001 From: isidor Date: Thu, 26 Jul 2018 10:25:49 +0200 Subject: [PATCH 0148/1276] fix #55064 --- src/vs/workbench/parts/debug/electron-browser/debugService.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vs/workbench/parts/debug/electron-browser/debugService.ts b/src/vs/workbench/parts/debug/electron-browser/debugService.ts index cdcc11ca1c2..3ec47d67994 100644 --- a/src/vs/workbench/parts/debug/electron-browser/debugService.ts +++ b/src/vs/workbench/parts/debug/electron-browser/debugService.ts @@ -1111,7 +1111,7 @@ export class DebugService implements debug.IDebugService { this.skipRunningTask = !!restartData; // If the restart is automatic disconnect, otherwise send the terminate signal #55064 - return (!restartData ? (session.raw).disconnect(true) : session.raw.terminate(true)).then(() => { + return (!!restartData ? (session.raw).disconnect(true) : session.raw.terminate(true)).then(() => { if (strings.equalsIgnoreCase(session.configuration.type, 'extensionHost') && session.raw.root) { return this.broadcastService.broadcast({ channel: EXTENSION_RELOAD_BROADCAST_CHANNEL, From 7c03ce156505cca6c60bd5afd9b2f33f25ec64ad Mon Sep 17 00:00:00 2001 From: Johannes Rieken Date: Thu, 26 Jul 2018 10:43:32 +0200 Subject: [PATCH 0149/1276] fix #54491 --- src/vs/base/common/arrays.ts | 2 +- .../parts/editor/breadcrumbsControl.ts | 20 +++++++++++++++++-- 2 files changed, 19 insertions(+), 3 deletions(-) diff --git a/src/vs/base/common/arrays.ts b/src/vs/base/common/arrays.ts index 7b2d7e3b563..4719c7c834d 100644 --- a/src/vs/base/common/arrays.ts +++ b/src/vs/base/common/arrays.ts @@ -12,7 +12,7 @@ import { ISplice } from 'vs/base/common/sequence'; * @param array The array. * @param n Which element from the end (default is zero). */ -export function tail(array: T[], n: number = 0): T { +export function tail(array: ArrayLike, n: number = 0): T { return array[array.length - (1 + n)]; } diff --git a/src/vs/workbench/browser/parts/editor/breadcrumbsControl.ts b/src/vs/workbench/browser/parts/editor/breadcrumbsControl.ts index 1fc3c36d00b..8f444b46e1c 100644 --- a/src/vs/workbench/browser/parts/editor/breadcrumbsControl.ts +++ b/src/vs/workbench/browser/parts/editor/breadcrumbsControl.ts @@ -38,6 +38,7 @@ import { IEditorGroupsService } from 'vs/workbench/services/group/common/editorG import { MenuRegistry, MenuId } from 'vs/platform/actions/common/actions'; import { localize } from 'vs/nls'; import { CommandsRegistry } from 'vs/platform/commands/common/commands'; +import { tail } from 'vs/base/common/arrays'; class Item extends BreadcrumbsItem { @@ -379,13 +380,28 @@ CommandsRegistry.registerCommand('breadcrumbs.toggle', accessor => { KeybindingsRegistry.registerCommandAndKeybindingRule({ id: 'breadcrumbs.focus', weight: KeybindingWeight.WorkbenchContrib, + primary: KeyMod.CtrlCmd | KeyMod.Shift | KeyCode.US_SEMICOLON, + when: BreadcrumbsControl.CK_BreadcrumbsVisible, + handler(accessor) { + const groups = accessor.get(IEditorGroupsService); + const breadcrumbs = accessor.get(IBreadcrumbsService); + const widget = breadcrumbs.getWidget(groups.activeGroup.id); + const item = tail(widget.getItems()); + widget.setFocused(item); + } +}); +KeybindingsRegistry.registerCommandAndKeybindingRule({ + id: 'breadcrumbs.focusAndSelect', + weight: KeybindingWeight.WorkbenchContrib, primary: KeyMod.CtrlCmd | KeyMod.Shift | KeyCode.US_DOT, when: BreadcrumbsControl.CK_BreadcrumbsVisible, handler(accessor) { const groups = accessor.get(IEditorGroupsService); const breadcrumbs = accessor.get(IBreadcrumbsService); - //todo@joh focus last? - breadcrumbs.getWidget(groups.activeGroup.id).domFocus(); + const widget = breadcrumbs.getWidget(groups.activeGroup.id); + const item = tail(widget.getItems()); + widget.setFocused(item); + widget.setSelection(item, BreadcrumbsControl.Payload_Pick); } }); KeybindingsRegistry.registerCommandAndKeybindingRule({ From 1256714392031b6303c96ee61216d2d254964f84 Mon Sep 17 00:00:00 2001 From: Johannes Rieken Date: Thu, 26 Jul 2018 11:05:44 +0200 Subject: [PATCH 0150/1276] bc - honor explorer decoration settings --- .../workbench/browser/parts/editor/breadcrumbsPicker.ts | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/vs/workbench/browser/parts/editor/breadcrumbsPicker.ts b/src/vs/workbench/browser/parts/editor/breadcrumbsPicker.ts index c29f3e10307..2e90c1f69ba 100644 --- a/src/vs/workbench/browser/parts/editor/breadcrumbsPicker.ts +++ b/src/vs/workbench/browser/parts/editor/breadcrumbsPicker.ts @@ -27,6 +27,7 @@ import { onUnexpectedError } from 'vs/base/common/errors'; import { breadcrumbsPickerBackground } from 'vs/platform/theme/common/colorRegistry'; import { FuzzyScore, createMatches, fuzzyScore } from 'vs/base/common/filters'; import { IWorkspaceContextService, IWorkspace, IWorkspaceFolder } from 'vs/platform/workspace/common/workspace'; +import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; export function createBreadcrumbsPicker(instantiationService: IInstantiationService, parent: HTMLElement, element: BreadcrumbElement): BreadcrumbsPicker { let ctor: IConstructorSignature1 = element instanceof FileElement ? BreadcrumbsFilePicker : BreadcrumbsOutlinePicker; @@ -194,7 +195,8 @@ export class FileRenderer implements IRenderer, IHighlightingRenderer { private readonly _scores = new Map(); constructor( - @IInstantiationService private readonly _instantiationService: IInstantiationService + @IInstantiationService private readonly _instantiationService: IInstantiationService, + @IConfigurationService private readonly _configService: IConfigurationService, ) { } getHeight(tree: ITree, element: any): number { @@ -210,18 +212,19 @@ export class FileRenderer implements IRenderer, IHighlightingRenderer { } renderElement(tree: ITree, element: IFileStat | IWorkspaceFolder, templateId: string, templateData: FileLabel): void { + let fileDecorations = this._configService.getValue<{ colors: boolean, badges: boolean }>('explorer.decorations'); if (IWorkspaceFolder.isIWorkspaceFolder(element)) { templateData.setFile(element.uri, { hidePath: true, fileKind: FileKind.ROOT_FOLDER, - fileDecorations: { colors: true, badges: true }, + fileDecorations: fileDecorations, matches: createMatches((this._scores.get(element) || [, []])[1]) }); } else { templateData.setFile(element.resource, { hidePath: true, fileKind: element.isDirectory ? FileKind.FOLDER : FileKind.FILE, - fileDecorations: { colors: true, badges: true }, + fileDecorations: fileDecorations, matches: createMatches((this._scores.get(element) || [, []])[1]) }); } From 40723965e05fa43222ada40dc2de956ee4c12aaa Mon Sep 17 00:00:00 2001 From: Johannes Rieken Date: Thu, 26 Jul 2018 11:18:45 +0200 Subject: [PATCH 0151/1276] bc - properly cleanup selection and focus when leaving breadcrumbs --- .../base/browser/ui/breadcrumbs/breadcrumbsWidget.ts | 12 +++++++++--- .../browser/parts/editor/breadcrumbsControl.ts | 12 +++++++----- 2 files changed, 16 insertions(+), 8 deletions(-) diff --git a/src/vs/base/browser/ui/breadcrumbs/breadcrumbsWidget.ts b/src/vs/base/browser/ui/breadcrumbs/breadcrumbsWidget.ts index cdd4dee0819..e18a0c04283 100644 --- a/src/vs/base/browser/ui/breadcrumbs/breadcrumbsWidget.ts +++ b/src/vs/base/browser/ui/breadcrumbs/breadcrumbsWidget.ts @@ -192,6 +192,7 @@ export class BreadcrumbsWidget { } private _focus(nth: number, payload: any): void { + const oldIdx = this._focusedItemIdx; this._focusedItemIdx = -1; for (let i = 0; i < this._nodes.length; i++) { const node = this._nodes[i]; @@ -203,8 +204,10 @@ export class BreadcrumbsWidget { node.focus(); } } - this._reveal(this._focusedItemIdx); - this._onDidFocusItem.fire({ type: 'focus', item: this._items[this._focusedItemIdx], node: this._nodes[this._focusedItemIdx], payload }); + if (this._focusedItemIdx !== oldIdx) { + this._reveal(this._focusedItemIdx); + this._onDidFocusItem.fire({ type: 'focus', item: this._items[this._focusedItemIdx], node: this._nodes[this._focusedItemIdx], payload }); + } } reveal(item: BreadcrumbsItem): void { @@ -232,6 +235,7 @@ export class BreadcrumbsWidget { } private _select(nth: number, payload: any): void { + const oldIdx = this._selectedItemIdx; this._selectedItemIdx = -1; for (let i = 0; i < this._nodes.length; i++) { const node = this._nodes[i]; @@ -242,7 +246,9 @@ export class BreadcrumbsWidget { dom.addClass(node, 'selected'); } } - this._onDidSelectItem.fire({ type: 'select', item: this._items[this._selectedItemIdx], node: this._nodes[this._selectedItemIdx], payload }); + if (this._selectedItemIdx !== oldIdx) { + this._onDidSelectItem.fire({ type: 'select', item: this._items[this._selectedItemIdx], node: this._nodes[this._selectedItemIdx], payload }); + } } getItems(): ReadonlyArray { diff --git a/src/vs/workbench/browser/parts/editor/breadcrumbsControl.ts b/src/vs/workbench/browser/parts/editor/breadcrumbsControl.ts index 8f444b46e1c..c0af94c3593 100644 --- a/src/vs/workbench/browser/parts/editor/breadcrumbsControl.ts +++ b/src/vs/workbench/browser/parts/editor/breadcrumbsControl.ts @@ -233,7 +233,7 @@ export class BreadcrumbsControl { this._breadcrumbsDisposables.push({ dispose: () => { if (this._breadcrumbsPickerShowing) { - this._contextViewService.hideContextView(); + this._contextViewService.hideContextView(this); } } }); @@ -277,9 +277,7 @@ export class BreadcrumbsControl { render: (parent: HTMLElement) => { picker = createBreadcrumbsPicker(this._instantiationService, parent, element); let listener = picker.onDidPickElement(data => { - this._contextViewService.hideContextView(); - this._widget.setFocused(undefined); - this._widget.setSelection(undefined); + this._contextViewService.hideContextView(this); this._revealInEditor(event, data); }); this._breadcrumbsPickerShowing = true; @@ -309,9 +307,13 @@ export class BreadcrumbsControl { picker.setInput(element); return { x, y }; }, - onHide: () => { + onHide: (data) => { this._breadcrumbsPickerShowing = false; this._updateCkBreadcrumbsActive(); + if (data === this) { + this._widget.setFocused(undefined); + this._widget.setSelection(undefined); + } } }); } From 742767ef9c249b3102fe59b7023221e21eb16afd Mon Sep 17 00:00:00 2001 From: isidor Date: Thu, 26 Jul 2018 11:35:47 +0200 Subject: [PATCH 0152/1276] files.contribution register uri display formater --- .../platform/uriDisplay/common/uriDisplay.ts | 10 +++++---- .../electron-browser/files.contribution.ts | 21 ++++++++++++++++++- .../files/electron-browser/fileService.ts | 6 ------ 3 files changed, 26 insertions(+), 11 deletions(-) diff --git a/src/vs/platform/uriDisplay/common/uriDisplay.ts b/src/vs/platform/uriDisplay/common/uriDisplay.ts index fcf10ee1a73..ac49935e2db 100644 --- a/src/vs/platform/uriDisplay/common/uriDisplay.ts +++ b/src/vs/platform/uriDisplay/common/uriDisplay.ts @@ -14,13 +14,14 @@ import { isLinux, isWindows } from 'vs/base/common/platform'; import { tildify, normalizeDriveLetter } from 'vs/base/common/labels'; export interface IUriDisplayService { + _serviceBrand: any; getLabel(resource: URI, relative: boolean): string; registerFormater(schema: string, formater: UriDisplayRules): IDisposable; } export interface UriDisplayRules { - label: string; - forwardSlash?: boolean; + label: string; // myLabel:/${path} + separator: '/' | '\\' | undefined; tildify?: boolean; normalizeDriveLetter?: boolean; } @@ -32,7 +33,8 @@ function hasDriveLetter(path: string): boolean { } class UriDisplayService implements IUriDisplayService { - public _serviceBrand: any; + _serviceBrand: any; + private formaters = new Map(); constructor( @@ -100,5 +102,5 @@ class UriDisplayService implements IUriDisplayService { } // register service -const IUriDisplayService = createDecorator(URI_DISPLAY_SERVICE_ID); +export const IUriDisplayService = createDecorator(URI_DISPLAY_SERVICE_ID); registerSingleton(IUriDisplayService, UriDisplayService); diff --git a/src/vs/workbench/parts/files/electron-browser/files.contribution.ts b/src/vs/workbench/parts/files/electron-browser/files.contribution.ts index baba48bded2..4c937a50456 100644 --- a/src/vs/workbench/parts/files/electron-browser/files.contribution.ts +++ b/src/vs/workbench/parts/files/electron-browser/files.contribution.ts @@ -12,7 +12,7 @@ import { SyncActionDescriptor, MenuId, MenuRegistry } from 'vs/platform/actions/ import { Registry } from 'vs/platform/registry/common/platform'; import { IConfigurationRegistry, Extensions as ConfigurationExtensions, ConfigurationScope } from 'vs/platform/configuration/common/configurationRegistry'; import { IWorkbenchActionRegistry, Extensions as ActionExtensions } from 'vs/workbench/common/actions'; -import { IWorkbenchContributionsRegistry, Extensions as WorkbenchExtensions } from 'vs/workbench/common/contributions'; +import { IWorkbenchContributionsRegistry, Extensions as WorkbenchExtensions, IWorkbenchContribution } from 'vs/workbench/common/contributions'; import { IEditorInputFactory, EditorInput, IFileEditorInput, IEditorInputFactoryRegistry, Extensions as EditorInputExtensions } from 'vs/workbench/common/editor'; import { AutoSaveConfiguration, HotExitConfiguration, SUPPORTED_ENCODINGS } from 'vs/platform/files/common/files'; import { VIEWLET_ID, SortOrderConfiguration, FILE_EDITOR_INPUT_ID } from 'vs/workbench/parts/files/common/files'; @@ -34,6 +34,9 @@ import { DataUriEditorInput } from 'vs/workbench/common/editor/dataUriEditorInpu import { LifecyclePhase } from 'vs/platform/lifecycle/common/lifecycle'; import { IEditorService } from 'vs/workbench/services/editor/common/editorService'; import { IEditorGroupsService } from 'vs/workbench/services/group/common/editorGroupsService'; +import { IUriDisplayService } from 'vs/platform/uriDisplay/common/uriDisplay'; +import { Schemas } from 'vs/base/common/network'; +import { nativeSep } from 'vs/base/common/paths'; // Viewlet Action export class OpenExplorerViewletAction extends ToggleViewletAction { @@ -50,6 +53,18 @@ export class OpenExplorerViewletAction extends ToggleViewletAction { } } +class FileUriDisplayContribution implements IWorkbenchContribution { + + constructor(@IUriDisplayService uriDisplayService: IUriDisplayService) { + uriDisplayService.registerFormater(Schemas.file, { + label: '${path}', + separator: nativeSep, + tildify: !platform.isWindows, + normalizeDriveLetter: platform.isWindows + }); + } +} + // Register Viewlet Registry.as(ViewletExtensions.Viewlets).registerViewlet(new ViewletDescriptor( ExplorerViewlet, @@ -156,6 +171,10 @@ Registry.as(WorkbenchExtensions.Workbench).regi // Register Dirty Files Tracker Registry.as(WorkbenchExtensions.Workbench).registerWorkbenchContribution(DirtyFilesTracker, LifecyclePhase.Starting); +// Register uri display for file uris +Registry.as(WorkbenchExtensions.Workbench).registerWorkbenchContribution(FileUriDisplayContribution, LifecyclePhase.Starting); + + // Configuration const configurationRegistry = Registry.as(ConfigurationExtensions.Configuration); diff --git a/src/vs/workbench/services/files/electron-browser/fileService.ts b/src/vs/workbench/services/files/electron-browser/fileService.ts index 3c9a106b404..b91d4371d27 100644 --- a/src/vs/workbench/services/files/electron-browser/fileService.ts +++ b/src/vs/workbench/services/files/electron-browser/fileService.ts @@ -121,12 +121,6 @@ export class FileService extends Disposable implements IFileService { this.fileChangesWatchDelayer = new ThrottledDelayer(FileService.FS_EVENT_DELAY); this.undeliveredRawFileChangesEvents = []; - // this.toDispose.push(uriDisplayService.registerFormater(Schemas.file, { - // label: '${path}', - // forwardSlash: !isWindows, - // tildify: !isWindows, - // normalizeDriveLetter: isWindows - // })); this._encoding = new ResourceEncodings(textResourceConfigurationService, environmentService, contextService, this.options.encodingOverride); this.registerListeners(); From 079dd3b6acafc2aafd86e36d03f92be585732fac Mon Sep 17 00:00:00 2001 From: Sandeep Somavarapu Date: Thu, 26 Jul 2018 11:37:50 +0200 Subject: [PATCH 0153/1276] #55057 Consider built in extensions if they are dependencies while enabling or disabling --- .../parts/extensions/node/extensionsWorkbenchService.ts | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/vs/workbench/parts/extensions/node/extensionsWorkbenchService.ts b/src/vs/workbench/parts/extensions/node/extensionsWorkbenchService.ts index d4a83cbb15c..342ba4d2957 100644 --- a/src/vs/workbench/parts/extensions/node/extensionsWorkbenchService.ts +++ b/src/vs/workbench/parts/extensions/node/extensionsWorkbenchService.ts @@ -806,8 +806,7 @@ export class ExtensionsWorkbenchService implements IExtensionsWorkbenchService, if (i.enablementState === enablementState) { return false; } - return i.type === LocalExtensionType.User - && (options.dependencies || options.pack) + return (options.dependencies || options.pack) && extensions.some(extension => (options.dependencies && extension.dependencies.some(id => areSameExtensions({ id }, i))) || (options.pack && extension.extensionPack.some(id => areSameExtensions({ id }, i))) From ff13d20dc488cc41e80f61c9525da21c89368af0 Mon Sep 17 00:00:00 2001 From: Christof Marti Date: Thu, 26 Jul 2018 11:49:55 +0200 Subject: [PATCH 0154/1276] Add context to "more" and "others" links. (fixes #51978) --- .../welcome/page/electron-browser/vs_code_welcome_page.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/vs/workbench/parts/welcome/page/electron-browser/vs_code_welcome_page.ts b/src/vs/workbench/parts/welcome/page/electron-browser/vs_code_welcome_page.ts index 27e73025e43..56ffc97bcb6 100644 --- a/src/vs/workbench/parts/welcome/page/electron-browser/vs_code_welcome_page.ts +++ b/src/vs/workbench/parts/welcome/page/electron-browser/vs_code_welcome_page.ts @@ -55,11 +55,11 @@ export default () => ` From d6f69db9660a330b15e003b5a830c1c41c944049 Mon Sep 17 00:00:00 2001 From: Sandeep Somavarapu Date: Thu, 26 Jul 2018 11:50:51 +0200 Subject: [PATCH 0155/1276] :lipstick: #55052 --- .../node/extensionManagementService.ts | 10 +++++----- .../extensions/node/extensionsWorkbenchService.ts | 6 +++--- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/vs/platform/extensionManagement/node/extensionManagementService.ts b/src/vs/platform/extensionManagement/node/extensionManagementService.ts index 74957144edb..2ff1e3bb3f2 100644 --- a/src/vs/platform/extensionManagement/node/extensionManagementService.ts +++ b/src/vs/platform/extensionManagement/node/extensionManagementService.ts @@ -561,19 +561,19 @@ export class ExtensionManagementService extends Disposable implements IExtension } private promptForDependenciesAndUninstall(extension: ILocalExtension, dependencies: ILocalExtension[], installed: ILocalExtension[]): TPromise { - const message = nls.localize('uninstallDependeciesConfirmation', "Would you like to uninstall '{0}' only or its dependencies also?", extension.manifest.displayName || extension.manifest.name); + const message = nls.localize('uninstallDependeciesConfirmation', "Also uninstall the dependencies of the extension '{0}'?", extension.manifest.displayName || extension.manifest.name); const buttons = [ - nls.localize('uninstallOnly', "Extension Only"), - nls.localize('uninstallAll', "Uninstall All"), + nls.localize('yes', "Yes"), + nls.localize('no', "No"), nls.localize('cancel', "Cancel") ]; return this.dialogService.show(Severity.Info, message, buttons, { cancelId: 2 }) .then(value => { if (value === 0) { - return this.uninstallExtensions(extension, [], installed); + return this.uninstallExtensions(extension, dependencies, installed); } if (value === 1) { - return this.uninstallExtensions(extension, dependencies, installed); + return this.uninstallExtensions(extension, [], installed); } this.logService.info('Cancelled uninstalling extension:', extension.identifier.id); return TPromise.wrapError(errors.canceled()); diff --git a/src/vs/workbench/parts/extensions/node/extensionsWorkbenchService.ts b/src/vs/workbench/parts/extensions/node/extensionsWorkbenchService.ts index 342ba4d2957..8804517eaa1 100644 --- a/src/vs/workbench/parts/extensions/node/extensionsWorkbenchService.ts +++ b/src/vs/workbench/parts/extensions/node/extensionsWorkbenchService.ts @@ -761,18 +761,18 @@ export class ExtensionsWorkbenchService implements IExtensionsWorkbenchService, } private promptForDependenciesAndDisable(extensions: IExtension[], dependencies: IExtension[], enablementState: EnablementState): TPromise { - const message = extensions.length > 1 ? nls.localize('disableDependeciesConfirmation', "Would you like to disable the dependencies of the extensions also?") : nls.localize('disableDependeciesSingleExtensionConfirmation', "Would you like to disable the dependencies of the extension also?"); + const message = extensions.length > 1 ? nls.localize('disableDependeciesConfirmation', "Also disable the dependencies of the extensions?") : nls.localize('disableDependeciesSingleExtensionConfirmation', "Also disable the dependencies of the extension '{0}'?", extensions[0].displayName); const buttons = [ nls.localize('yes', "Yes"), + nls.localize('cancel', "Cancel"), nls.localize('no', "No"), - nls.localize('cancel', "Cancel") ]; return this.dialogService.show(Severity.Info, message, buttons, { cancelId: 2 }) .then(value => { if (value === 0) { return this.checkAndSetEnablement(extensions, dependencies, enablementState); } - if (value === 1) { + if (value === 2) { return this.checkAndSetEnablement(extensions, [], enablementState); } return TPromise.as(null); From f3710619ea1e275a55b7f5fa9f86350372830fed Mon Sep 17 00:00:00 2001 From: Martin Aeschlimann Date: Thu, 26 Jul 2018 11:28:10 +0200 Subject: [PATCH 0156/1276] enumDescriptions should be included in extension package.json schema. Fixes #55095 --- .../configuration/common/configurationExtensionPoint.ts | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/vs/workbench/services/configuration/common/configurationExtensionPoint.ts b/src/vs/workbench/services/configuration/common/configurationExtensionPoint.ts index 6705a89acda..6b55d1b1930 100644 --- a/src/vs/workbench/services/configuration/common/configurationExtensionPoint.ts +++ b/src/vs/workbench/services/configuration/common/configurationExtensionPoint.ts @@ -46,6 +46,13 @@ const configurationEntrySchema: IJSONSchema = { nls.localize('scope.resource.description', "Resource specific configuration, which can be configured in the User, Workspace or Folder settings.") ], description: nls.localize('scope.description', "Scope in which the configuration is applicable. Available scopes are `window` and `resource`.") + }, + enumDescriptions: { + type: 'array', + items: { + type: 'string', + }, + description: nls.localize('scope.enumDescriptions', 'Descriptions for enum values') } } } From cbb51a099725ef243723ba593b92fbf0145f4478 Mon Sep 17 00:00:00 2001 From: Martin Aeschlimann Date: Thu, 26 Jul 2018 11:57:01 +0200 Subject: [PATCH 0157/1276] [loc][Query] Source text issue for "Provides syntax highlighting, bracket matching and folding Less files." Fixes #55115 --- extensions/less/package.nls.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/extensions/less/package.nls.json b/extensions/less/package.nls.json index 7010e123b8e..bad671bf059 100644 --- a/extensions/less/package.nls.json +++ b/extensions/less/package.nls.json @@ -1,4 +1,4 @@ { "displayName": "Less Language Basics", - "description": "Provides syntax highlighting, bracket matching and folding Less files." + "description": "Provides syntax highlighting, bracket matching and folding in Less files." } \ No newline at end of file From f7252175e0806846cd95ad04d2e5d040517a87dd Mon Sep 17 00:00:00 2001 From: Johannes Rieken Date: Thu, 26 Jul 2018 12:04:37 +0200 Subject: [PATCH 0158/1276] fix #54743 --- .../ui/breadcrumbs/breadcrumbsWidget.ts | 12 ++--- .../parts/editor/breadcrumbsControl.ts | 53 ++++++++++++------- .../browser/parts/editor/breadcrumbsPicker.ts | 25 +++++---- 3 files changed, 53 insertions(+), 37 deletions(-) diff --git a/src/vs/base/browser/ui/breadcrumbs/breadcrumbsWidget.ts b/src/vs/base/browser/ui/breadcrumbs/breadcrumbsWidget.ts index e18a0c04283..cdd4dee0819 100644 --- a/src/vs/base/browser/ui/breadcrumbs/breadcrumbsWidget.ts +++ b/src/vs/base/browser/ui/breadcrumbs/breadcrumbsWidget.ts @@ -192,7 +192,6 @@ export class BreadcrumbsWidget { } private _focus(nth: number, payload: any): void { - const oldIdx = this._focusedItemIdx; this._focusedItemIdx = -1; for (let i = 0; i < this._nodes.length; i++) { const node = this._nodes[i]; @@ -204,10 +203,8 @@ export class BreadcrumbsWidget { node.focus(); } } - if (this._focusedItemIdx !== oldIdx) { - this._reveal(this._focusedItemIdx); - this._onDidFocusItem.fire({ type: 'focus', item: this._items[this._focusedItemIdx], node: this._nodes[this._focusedItemIdx], payload }); - } + this._reveal(this._focusedItemIdx); + this._onDidFocusItem.fire({ type: 'focus', item: this._items[this._focusedItemIdx], node: this._nodes[this._focusedItemIdx], payload }); } reveal(item: BreadcrumbsItem): void { @@ -235,7 +232,6 @@ export class BreadcrumbsWidget { } private _select(nth: number, payload: any): void { - const oldIdx = this._selectedItemIdx; this._selectedItemIdx = -1; for (let i = 0; i < this._nodes.length; i++) { const node = this._nodes[i]; @@ -246,9 +242,7 @@ export class BreadcrumbsWidget { dom.addClass(node, 'selected'); } } - if (this._selectedItemIdx !== oldIdx) { - this._onDidSelectItem.fire({ type: 'select', item: this._items[this._selectedItemIdx], node: this._nodes[this._selectedItemIdx], payload }); - } + this._onDidSelectItem.fire({ type: 'select', item: this._items[this._selectedItemIdx], node: this._nodes[this._selectedItemIdx], payload }); } getItems(): ReadonlyArray { diff --git a/src/vs/workbench/browser/parts/editor/breadcrumbsControl.ts b/src/vs/workbench/browser/parts/editor/breadcrumbsControl.ts index c0af94c3593..a805e568e9c 100644 --- a/src/vs/workbench/browser/parts/editor/breadcrumbsControl.ts +++ b/src/vs/workbench/browser/parts/editor/breadcrumbsControl.ts @@ -33,12 +33,13 @@ import { BreadcrumbsConfig, IBreadcrumbsService } from 'vs/workbench/browser/par import { BreadcrumbElement, EditorBreadcrumbsModel, FileElement } from 'vs/workbench/browser/parts/editor/breadcrumbsModel'; import { createBreadcrumbsPicker, BreadcrumbsPicker } from 'vs/workbench/browser/parts/editor/breadcrumbsPicker'; import { EditorGroupView } from 'vs/workbench/browser/parts/editor/editorGroupView'; -import { IEditorService } from 'vs/workbench/services/editor/common/editorService'; +import { IEditorService, SIDE_GROUP, SIDE_GROUP_TYPE, ACTIVE_GROUP_TYPE, ACTIVE_GROUP } from 'vs/workbench/services/editor/common/editorService'; import { IEditorGroupsService } from 'vs/workbench/services/group/common/editorGroupsService'; import { MenuRegistry, MenuId } from 'vs/platform/actions/common/actions'; import { localize } from 'vs/nls'; import { CommandsRegistry } from 'vs/platform/commands/common/commands'; import { tail } from 'vs/base/common/arrays'; +import { WorkbenchListFocusContextKey } from 'vs/platform/list/browser/listService'; class Item extends BreadcrumbsItem { @@ -123,6 +124,7 @@ export class BreadcrumbsControl { static HEIGHT = 25; static readonly Payload_Reveal = {}; + static readonly Payload_RevealAside = {}; static readonly Payload_Pick = {}; static CK_BreadcrumbsVisible = new RawContextKey('breadcrumbsVisible', false); @@ -255,11 +257,12 @@ export class BreadcrumbsControl { this._editorGroup.focus(); const { element } = event.item as Item; - if (this._shouldRevealItem(event)) { + const group = this._getEditorGroup(event.payload); + if (group !== undefined) { // reveal the item this._widget.setFocused(undefined); this._widget.setSelection(undefined); - this._revealInEditor(event, element); + this._revealInEditor(event, element, group); return; } @@ -278,7 +281,7 @@ export class BreadcrumbsControl { picker = createBreadcrumbsPicker(this._instantiationService, parent, element); let listener = picker.onDidPickElement(data => { this._contextViewService.hideContextView(this); - this._revealInEditor(event, data); + this._revealInEditor(event, data.target, this._getEditorGroup(data.payload && data.payload.originalEvent)); }); this._breadcrumbsPickerShowing = true; this._updateCkBreadcrumbsActive(); @@ -323,11 +326,11 @@ export class BreadcrumbsControl { this._ckBreadcrumbsActive.set(value); } - private _revealInEditor(event: IBreadcrumbsItemEvent, data: any): void { - if (data instanceof FileElement) { - if (data.kind === FileKind.FILE) { + private _revealInEditor(event: IBreadcrumbsItemEvent, element: any, group: SIDE_GROUP_TYPE | ACTIVE_GROUP_TYPE): void { + if (element instanceof FileElement) { + if (element.kind === FileKind.FILE) { // open file in editor - this._editorService.openEditor({ resource: data.uri }); + this._editorService.openEditor({ resource: element.uri }, group); } else { // show next picker let items = this._widget.getItems(); @@ -336,18 +339,24 @@ export class BreadcrumbsControl { this._widget.setSelection(items[idx + 1], BreadcrumbsControl.Payload_Pick); } - } else if (data instanceof OutlineElement) { + } else if (element instanceof OutlineElement) { // open symbol in editor - let model = OutlineModel.get(data); + let model = OutlineModel.get(element); this._editorService.openEditor({ resource: model.textModel.uri, - options: { selection: Range.collapseToStart(data.symbol.selectionRange) } - }); + options: { selection: Range.collapseToStart(element.symbol.selectionRange) } + }, group); } } - private _shouldRevealItem({ payload }: IBreadcrumbsItemEvent): boolean { - return payload === BreadcrumbsControl.Payload_Reveal || (payload instanceof StandardMouseEvent && payload.metaKey); + private _getEditorGroup(data: StandardMouseEvent | object): SIDE_GROUP_TYPE | ACTIVE_GROUP_TYPE | undefined { + if (data === BreadcrumbsControl.Payload_RevealAside || (data instanceof StandardMouseEvent && data.altKey)) { + return SIDE_GROUP; + } else if (data === BreadcrumbsControl.Payload_Reveal || (data instanceof StandardMouseEvent && data.metaKey)) { + return ACTIVE_GROUP; + } else { + return undefined; + } } } @@ -456,10 +465,6 @@ KeybindingsRegistry.registerCommandAndKeybindingRule({ weight: KeybindingWeight.WorkbenchContrib, primary: KeyCode.Space, secondary: [KeyMod.CtrlCmd | KeyCode.Enter], - mac: { - primary: KeyCode.Space, - secondary: [KeyMod.Alt | KeyCode.Enter], - }, when: ContextKeyExpr.and(BreadcrumbsControl.CK_BreadcrumbsVisible, BreadcrumbsControl.CK_BreadcrumbsActive), handler(accessor) { const groups = accessor.get(IEditorGroupsService); @@ -481,4 +486,16 @@ KeybindingsRegistry.registerCommandAndKeybindingRule({ groups.activeGroup.activeControl.focus(); } }); +KeybindingsRegistry.registerCommandAndKeybindingRule({ + id: 'breadcrumbs.revealFocusedFromTreeAside', + weight: KeybindingWeight.WorkbenchContrib, + primary: KeyMod.CtrlCmd | KeyCode.Enter, + 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); + widget.setSelection(widget.getFocused(), BreadcrumbsControl.Payload_RevealAside); + } +}); //#endregion diff --git a/src/vs/workbench/browser/parts/editor/breadcrumbsPicker.ts b/src/vs/workbench/browser/parts/editor/breadcrumbsPicker.ts index 2e90c1f69ba..72b004f7abc 100644 --- a/src/vs/workbench/browser/parts/editor/breadcrumbsPicker.ts +++ b/src/vs/workbench/browser/parts/editor/breadcrumbsPicker.ts @@ -43,9 +43,8 @@ export abstract class BreadcrumbsPicker { protected readonly _tree: HighlightingWorkbenchTree; protected readonly _focus: dom.IFocusTracker; - protected readonly _onDidPickElement = new Emitter(); - - readonly onDidPickElement: Event = this._onDidPickElement.event; + private readonly _onDidPickElement = new Emitter<{ target: any, payload: any }>(); + readonly onDidPickElement: Event<{ target: any, payload: any }> = this._onDidPickElement.event; constructor( parent: HTMLElement, @@ -57,7 +56,7 @@ export abstract class BreadcrumbsPicker { parent.appendChild(this._domNode); this._focus = dom.trackFocus(this._domNode); - this._focus.onDidBlur(_ => this._onDidPickElement.fire(undefined), undefined, this._disposables); + this._focus.onDidBlur(_ => this._onDidPickElement.fire({ target: undefined, payload: undefined }), undefined, this._disposables); const theme = this._themeService.getTheme(); const color = theme.getColor(breadcrumbsPickerBackground); @@ -85,7 +84,13 @@ export abstract class BreadcrumbsPicker { ); this._disposables.push(this._tree.onDidChangeSelection(e => { if (e.payload !== this._tree) { - setTimeout(_ => this._onDidChangeSelection(e)); // need to debounce here because this disposes the tree and the tree doesn't like to be disposed on click + const target = this._getTargetFromSelectionEvent(e); + if (!target) { + return; + } + setTimeout(_ => {// need to debounce here because this disposes the tree and the tree doesn't like to be disposed on click + this._onDidPickElement.fire({ target, payload: e.payload }); + }, 0); } })); @@ -131,7 +136,7 @@ export abstract class BreadcrumbsPicker { protected abstract _getInput(input: BreadcrumbElement): any; protected abstract _getInitialSelection(tree: ITree, input: BreadcrumbElement): any; protected abstract _completeTreeConfiguration(config: IHighlightingTreeConfiguration): IHighlightingTreeConfiguration; - protected abstract _onDidChangeSelection(e: ISelectionEvent): void; + protected abstract _getTargetFromSelectionEvent(e: ISelectionEvent): any | undefined; } //#region - Files @@ -309,10 +314,10 @@ export class BreadcrumbsFilePicker extends BreadcrumbsPicker { return config; } - protected _onDidChangeSelection(e: ISelectionEvent): void { + protected _getTargetFromSelectionEvent(e: ISelectionEvent): any | undefined { let [first] = e.selection; if (first && !IWorkspaceFolder.isIWorkspaceFolder(first) && !(first as IFileStat).isDirectory) { - this._onDidPickElement.fire(new FileElement((first as IFileStat).resource, FileKind.FILE)); + return new FileElement((first as IFileStat).resource, FileKind.FILE); } } } @@ -348,13 +353,13 @@ export class BreadcrumbsOutlinePicker extends BreadcrumbsPicker { return config; } - protected _onDidChangeSelection(e: ISelectionEvent): void { + protected _getTargetFromSelectionEvent(e: ISelectionEvent): any | undefined { if (e.payload && e.payload.didClickOnTwistie) { return; } let [first] = e.selection; if (first instanceof OutlineElement) { - this._onDidPickElement.fire(first); + return first; } } } From adbf6e0f4129351db3275676180ed65ab1fce6f2 Mon Sep 17 00:00:00 2001 From: Christof Marti Date: Thu, 26 Jul 2018 12:26:56 +0200 Subject: [PATCH 0159/1276] Include description and details (fixes #52040) --- src/vs/base/parts/quickopen/browser/quickOpenModel.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/vs/base/parts/quickopen/browser/quickOpenModel.ts b/src/vs/base/parts/quickopen/browser/quickOpenModel.ts index d19657a3f92..08e0701b847 100644 --- a/src/vs/base/parts/quickopen/browser/quickOpenModel.ts +++ b/src/vs/base/parts/quickopen/browser/quickOpenModel.ts @@ -92,7 +92,9 @@ export class QuickOpenEntry { * The label of the entry to use when a screen reader wants to read about the entry */ getAriaLabel(): string { - return this.getLabel(); + return [this.getLabel(), this.getDescription(), this.getDetail()] + .filter(s => !!s) + .join(', '); } /** From 8271920c0f7e8c694170e3043662569df2fad3c9 Mon Sep 17 00:00:00 2001 From: Johannes Rieken Date: Thu, 26 Jul 2018 12:32:17 +0200 Subject: [PATCH 0160/1276] add aria roles #54745 --- src/vs/base/browser/ui/breadcrumbs/breadcrumbsWidget.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/vs/base/browser/ui/breadcrumbs/breadcrumbsWidget.ts b/src/vs/base/browser/ui/breadcrumbs/breadcrumbsWidget.ts index cdd4dee0819..faa5908492e 100644 --- a/src/vs/base/browser/ui/breadcrumbs/breadcrumbsWidget.ts +++ b/src/vs/base/browser/ui/breadcrumbs/breadcrumbsWidget.ts @@ -87,6 +87,7 @@ export class BreadcrumbsWidget { this._domNode = document.createElement('div'); this._domNode.className = 'monaco-breadcrumbs'; this._domNode.tabIndex = 0; + this._domNode.setAttribute('role', 'list'); this._scrollable = new DomScrollableElement(this._domNode, { vertical: ScrollbarVisibility.Hidden, horizontal: ScrollbarVisibility.Auto, @@ -286,6 +287,7 @@ export class BreadcrumbsWidget { container.className = ''; item.render(container); container.tabIndex = -1; + container.setAttribute('role', 'listitem'); dom.addClass(container, 'monaco-breadcrumb-item'); } From d983257e6f8db693962d0dba9a025678f50778fe Mon Sep 17 00:00:00 2001 From: Sandeep Somavarapu Date: Thu, 26 Jul 2018 13:33:34 +0200 Subject: [PATCH 0161/1276] fix tests --- .../test/electron-browser/extensionsWorkbenchService.test.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/vs/workbench/parts/extensions/test/electron-browser/extensionsWorkbenchService.test.ts b/src/vs/workbench/parts/extensions/test/electron-browser/extensionsWorkbenchService.test.ts index c003da371ef..eca3169eca8 100644 --- a/src/vs/workbench/parts/extensions/test/electron-browser/extensionsWorkbenchService.test.ts +++ b/src/vs/workbench/parts/extensions/test/electron-browser/extensionsWorkbenchService.test.ts @@ -840,7 +840,7 @@ suite('ExtensionsWorkbenchServiceTest', () => { .then(() => instantiationService.get(IExtensionEnablementService).setEnablement(extensionC, EnablementState.Enabled)) .then(() => { instantiationService.stubPromise(IExtensionManagementService, 'getInstalled', [extensionA, extensionB, extensionC]); - instantiationService.stubPromise(IDialogService, 'show', 1); + instantiationService.stubPromise(IDialogService, 'show', 2); testObject = instantiationService.createInstance(ExtensionsWorkbenchService); return testObject.setEnablement(testObject.local[0], EnablementState.Disabled) @@ -1002,7 +1002,7 @@ suite('ExtensionsWorkbenchServiceTest', () => { .then(() => instantiationService.get(IExtensionEnablementService).setEnablement(extensionC, EnablementState.Enabled)) .then(() => { instantiationService.stubPromise(IExtensionManagementService, 'getInstalled', [extensionA, extensionB, extensionC]); - instantiationService.stubPromise(IDialogService, 'show', 1); + instantiationService.stubPromise(IDialogService, 'show', 2); testObject = instantiationService.createInstance(ExtensionsWorkbenchService); return testObject.setEnablement(testObject.local[0], EnablementState.Disabled) From f604f1c85a73f702dc3ee4d8e6a4d1406604ee92 Mon Sep 17 00:00:00 2001 From: Johannes Rieken Date: Thu, 26 Jul 2018 14:53:17 +0200 Subject: [PATCH 0162/1276] store data globally #55033 --- package.json | 1 - .../electron-browser/bootstrap/index.js | 46 +++++++------ src/vs/workbench/electron-browser/shell.ts | 64 ++++++------------- yarn.lock | 4 -- 4 files changed, 45 insertions(+), 70 deletions(-) diff --git a/package.json b/package.json index 6968445d439..8d1b75d32d0 100644 --- a/package.json +++ b/package.json @@ -50,7 +50,6 @@ "vscode-nsfw": "1.0.17", "vscode-ripgrep": "^1.0.1", "vscode-textmate": "^4.0.1", - "vscode-uri": "1.0.5", "vscode-xterm": "3.6.0-beta5", "yauzl": "^2.9.1" }, diff --git a/src/vs/workbench/electron-browser/bootstrap/index.js b/src/vs/workbench/electron-browser/bootstrap/index.js index cfdd8d8e09f..a85853eaaa0 100644 --- a/src/vs/workbench/electron-browser/bootstrap/index.js +++ b/src/vs/workbench/electron-browser/bootstrap/index.js @@ -83,32 +83,40 @@ function readFile(file) { function showPartsSplash(configuration) { perf.mark('willShowPartsSplash'); - let key; - let keep = false; - // this is the logic of StorageService#getWorkspaceKey and StorageService#toStorageKey - if (configuration.folderUri) { - let workspaceKey = require('vscode-uri').default.revive(configuration.folderUri).toString().replace('file:///', '').replace(/^\//, ''); - key = `storage://workspace/${workspaceKey}/parts-splash`; - } else if (configuration.workspace) { - key = `storage://workspace/root:${configuration.workspace.id}/parts-splash`; - } else { - key = `storage://global/parts-splash`; - keep = true; - } // TODO@Ben remove me after a while perf.mark('willAccessLocalStorage'); let storage = window.localStorage; perf.mark('didAccessLocalStorage'); - let structure = storage.getItem(key); - if (structure) { - let splash = document.createElement('div'); - splash.innerHTML = structure; - document.body.appendChild(splash); + let data; + try { + let raw = storage.getItem('storage://global/parts-splash-data'); + data = JSON.parse(raw); + } catch (e) { + // ignore } - if (!keep) { - storage.removeItem(key); + + if (data) { + const splash = document.createElement('div'); + const { layoutInfo, colorInfo } = data; + if (configuration.folderUri || configuration.workspace) { + // folder or workspace -> status bar color, sidebar + splash.innerHTML = `
+
+
+
+
+
`; + } else { + // empty -> speical status bar color, no sidebar + splash.innerHTML = `
+
+
+
+
`; + } + document.body.appendChild(splash); } perf.mark('didShowPartsSplash'); } diff --git a/src/vs/workbench/electron-browser/shell.ts b/src/vs/workbench/electron-browser/shell.ts index 24e8b1f7cc7..280858ce306 100644 --- a/src/vs/workbench/electron-browser/shell.ts +++ b/src/vs/workbench/electron-browser/shell.ts @@ -79,7 +79,7 @@ import { IBroadcastService, BroadcastService } from 'vs/platform/broadcast/elect import { HashService } from 'vs/workbench/services/hash/node/hashService'; import { IHashService } from 'vs/workbench/services/hash/common/hashService'; import { ILogService } from 'vs/platform/log/common/log'; -import { WORKBENCH_BACKGROUND } from 'vs/workbench/common/theme'; +import { WORKBENCH_BACKGROUND, SIDE_BAR_BACKGROUND, ACTIVITY_BAR_BACKGROUND, STATUS_BAR_BACKGROUND, STATUS_BAR_NO_FOLDER_BACKGROUND, TITLE_BAR_ACTIVE_BACKGROUND } from 'vs/workbench/common/theme'; import { stat } from 'fs'; import { join } from 'path'; import { ILocalizationsChannel, LocalizationsChannelClient } from 'vs/platform/localizations/common/localizationsIpc'; @@ -524,51 +524,23 @@ export class WorkbenchShell extends Disposable { private _savePartsSplash() { - // capture html-structure - let state = this.contextService.getWorkbenchState(); - let html = `
`; - - // title part - let titleHeight: number; - { - let part = this.workbench.getContainer(Parts.TITLEBAR_PART); - let height = getTotalHeight(part); - let bg = part.style.backgroundColor || 'inhert'; - html += `
`; - titleHeight = height; - } - - // activitybar-part - let left = this.workbench.getSideBarPosition() === Position.LEFT; - let activityPartWidth: number; - { - let part = this.workbench.getContainer(Parts.ACTIVITYBAR_PART); - let width = getTotalWidth(part); - let bg = part.style.backgroundColor || 'inhert'; - html += `
`; - activityPartWidth = width; - } - - // sidebar-part (only for folder/workspace cases) - if (state !== WorkbenchState.EMPTY) { - let part = this.workbench.getContainer(Parts.SIDEBAR_PART); - let width = getTotalWidth(part); - let bg = part.style.backgroundColor || 'inhert'; - html += `
`; - } - - // statusbar-part - { - let part = this.workbench.getContainer(Parts.STATUSBAR_PART); - let height = getTotalHeight(part); - let bg = part.style.backgroundColor || 'inhert'; - html += `
`; - } - - html += '\n
'; - - // store per workspace or globally - this.storageService.store('parts-splash', html, state === WorkbenchState.EMPTY ? StorageScope.GLOBAL : StorageScope.WORKSPACE); + // capture color/layout data + const theme = this.themeService.getTheme(); + const colorInfo = { + titleBarBackground: theme.getColor(TITLE_BAR_ACTIVE_BACKGROUND).toString(), + activityBarBackground: theme.getColor(ACTIVITY_BAR_BACKGROUND).toString(), + sideBarBackground: theme.getColor(SIDE_BAR_BACKGROUND).toString(), + statusBarBackground: theme.getColor(STATUS_BAR_BACKGROUND).toString(), + statusBarNoFolderBackground: theme.getColor(STATUS_BAR_NO_FOLDER_BACKGROUND).toString(), + }; + const layoutInfo = { + titleBarHeight: getTotalHeight(this.workbench.getContainer(Parts.TITLEBAR_PART)), + sideBarSide: this.workbench.getSideBarPosition() === Position.RIGHT ? 'right' : 'left', + activityBarWidth: getTotalWidth(this.workbench.getContainer(Parts.ACTIVITYBAR_PART)), + sideBarWidth: getTotalWidth(this.workbench.getContainer(Parts.SIDEBAR_PART)), + statusBarHeight: getTotalHeight(this.workbench.getContainer(Parts.STATUSBAR_PART)), + }; + this.storageService.store('parts-splash-data', JSON.stringify({ id: WorkbenchShell.PARTS_SPLASH_ID, colorInfo, layoutInfo }), StorageScope.GLOBAL); } private _removePartsSplash(): void { diff --git a/yarn.lock b/yarn.lock index f3796744e72..9e322ec55d9 100644 --- a/yarn.lock +++ b/yarn.lock @@ -6256,10 +6256,6 @@ vscode-textmate@^4.0.1: dependencies: oniguruma "^7.0.0" -vscode-uri@1.0.5: - version "1.0.5" - resolved "https://registry.yarnpkg.com/vscode-uri/-/vscode-uri-1.0.5.tgz#3b899a8ef71c37f3054d79bdbdda31c7bf36f20d" - vscode-xterm@3.6.0-beta5: version "3.6.0-beta5" resolved "https://registry.yarnpkg.com/vscode-xterm/-/vscode-xterm-3.6.0-beta5.tgz#b44fd70451944624f148bd9f0be4925b52b7a7e0" From 62ba096511a1b83cd21a82cb410bd0664499165c Mon Sep 17 00:00:00 2001 From: Johannes Rieken Date: Thu, 26 Jul 2018 15:12:31 +0200 Subject: [PATCH 0163/1276] splash - move parts splash out of shell and into contribution --- .../electron-browser/bootstrap/index.js | 9 +-- src/vs/workbench/electron-browser/shell.ts | 42 +------------- .../partsSplash.contribution.ts | 58 +++++++++++++++++++ src/vs/workbench/workbench.main.ts | 2 + 4 files changed, 68 insertions(+), 43 deletions(-) create mode 100644 src/vs/workbench/parts/splash/electron-browser/partsSplash.contribution.ts diff --git a/src/vs/workbench/electron-browser/bootstrap/index.js b/src/vs/workbench/electron-browser/bootstrap/index.js index a85853eaaa0..2cb6af431ee 100644 --- a/src/vs/workbench/electron-browser/bootstrap/index.js +++ b/src/vs/workbench/electron-browser/bootstrap/index.js @@ -99,22 +99,23 @@ function showPartsSplash(configuration) { if (data) { const splash = document.createElement('div'); + splash.id = data.id; const { layoutInfo, colorInfo } = data; if (configuration.folderUri || configuration.workspace) { // folder or workspace -> status bar color, sidebar - splash.innerHTML = `
+ splash.innerHTML = `
-
`; + `; } else { // empty -> speical status bar color, no sidebar - splash.innerHTML = `
+ splash.innerHTML = `
-
`; + `; } document.body.appendChild(splash); } diff --git a/src/vs/workbench/electron-browser/shell.ts b/src/vs/workbench/electron-browser/shell.ts index 280858ce306..7ad21d04307 100644 --- a/src/vs/workbench/electron-browser/shell.ts +++ b/src/vs/workbench/electron-browser/shell.ts @@ -41,7 +41,7 @@ import { IIntegrityService } from 'vs/platform/integrity/common/integrity'; import { EditorWorkerServiceImpl } from 'vs/editor/common/services/editorWorkerServiceImpl'; import { IEditorWorkerService } from 'vs/editor/common/services/editorWorkerService'; import { ExtensionService } from 'vs/workbench/services/extensions/electron-browser/extensionService'; -import { IStorageService, StorageScope } from 'vs/platform/storage/common/storage'; +import { IStorageService } from 'vs/platform/storage/common/storage'; import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; import { ServiceCollection } from 'vs/platform/instantiation/common/serviceCollection'; import { InstantiationService } from 'vs/platform/instantiation/common/instantiationService'; @@ -79,7 +79,7 @@ import { IBroadcastService, BroadcastService } from 'vs/platform/broadcast/elect import { HashService } from 'vs/workbench/services/hash/node/hashService'; import { IHashService } from 'vs/workbench/services/hash/common/hashService'; import { ILogService } from 'vs/platform/log/common/log'; -import { WORKBENCH_BACKGROUND, SIDE_BAR_BACKGROUND, ACTIVITY_BAR_BACKGROUND, STATUS_BAR_BACKGROUND, STATUS_BAR_NO_FOLDER_BACKGROUND, TITLE_BAR_ACTIVE_BACKGROUND } from 'vs/workbench/common/theme'; +import { WORKBENCH_BACKGROUND } from 'vs/workbench/common/theme'; import { stat } from 'fs'; import { join } from 'path'; import { ILocalizationsChannel, LocalizationsChannelClient } from 'vs/platform/localizations/common/localizationsIpc'; @@ -91,13 +91,12 @@ import { NotificationService } from 'vs/workbench/services/notification/common/n import { IDialogService } from 'vs/platform/dialogs/common/dialogs'; import { DialogService } from 'vs/workbench/services/dialogs/electron-browser/dialogService'; import { DialogChannel } from 'vs/platform/dialogs/common/dialogIpc'; -import { EventType, addDisposableListener, addClass, getTotalHeight, getTotalWidth } from 'vs/base/browser/dom'; +import { EventType, addDisposableListener, addClass } from 'vs/base/browser/dom'; import { IOpenerService } from 'vs/platform/opener/common/opener'; import { OpenerService } from 'vs/editor/browser/services/openerService'; import { SearchHistoryService } from 'vs/workbench/services/search/node/searchHistoryService'; import { MulitExtensionManagementService } from 'vs/platform/extensionManagement/common/multiExtensionManagement'; import { ExtensionManagementServerService } from 'vs/workbench/services/extensions/node/extensionManagementServerService'; -import { Parts, Position } from 'vs/workbench/services/part/common/partService'; /** * Services that we require for the Shell @@ -189,9 +188,6 @@ export class WorkbenchShell extends Disposable { // Startup Workbench workbench.startup().done(startupInfos => { - // Remove splash screen - this._removePartsSplash(); - // Set lifecycle phase to `Runnning` so that other contributions can now do something this.lifecycleService.phase = LifecyclePhase.Running; @@ -512,43 +508,11 @@ export class WorkbenchShell extends Disposable { // Keep font info for next startup around saveFontInfo(this.storageService); - this._savePartsSplash(); - // Dispose Workbench if (this.workbench) { this.workbench.dispose(reason); } } - - private static readonly PARTS_SPLASH_ID = 'monaco-parts-splash'; - - private _savePartsSplash() { - - // capture color/layout data - const theme = this.themeService.getTheme(); - const colorInfo = { - titleBarBackground: theme.getColor(TITLE_BAR_ACTIVE_BACKGROUND).toString(), - activityBarBackground: theme.getColor(ACTIVITY_BAR_BACKGROUND).toString(), - sideBarBackground: theme.getColor(SIDE_BAR_BACKGROUND).toString(), - statusBarBackground: theme.getColor(STATUS_BAR_BACKGROUND).toString(), - statusBarNoFolderBackground: theme.getColor(STATUS_BAR_NO_FOLDER_BACKGROUND).toString(), - }; - const layoutInfo = { - titleBarHeight: getTotalHeight(this.workbench.getContainer(Parts.TITLEBAR_PART)), - sideBarSide: this.workbench.getSideBarPosition() === Position.RIGHT ? 'right' : 'left', - activityBarWidth: getTotalWidth(this.workbench.getContainer(Parts.ACTIVITYBAR_PART)), - sideBarWidth: getTotalWidth(this.workbench.getContainer(Parts.SIDEBAR_PART)), - statusBarHeight: getTotalHeight(this.workbench.getContainer(Parts.STATUSBAR_PART)), - }; - this.storageService.store('parts-splash-data', JSON.stringify({ id: WorkbenchShell.PARTS_SPLASH_ID, colorInfo, layoutInfo }), StorageScope.GLOBAL); - } - - private _removePartsSplash(): void { - let element = document.getElementById(WorkbenchShell.PARTS_SPLASH_ID); - if (element) { - element.remove(); - } - } } diff --git a/src/vs/workbench/parts/splash/electron-browser/partsSplash.contribution.ts b/src/vs/workbench/parts/splash/electron-browser/partsSplash.contribution.ts new file mode 100644 index 00000000000..a449280ea49 --- /dev/null +++ b/src/vs/workbench/parts/splash/electron-browser/partsSplash.contribution.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. + *--------------------------------------------------------------------------------------------*/ + +'use strict'; + +import { getTotalHeight, getTotalWidth } from 'vs/base/browser/dom'; +import { ILifecycleService, LifecyclePhase } from 'vs/platform/lifecycle/common/lifecycle'; +import { Registry } from 'vs/platform/registry/common/platform'; +import { IStorageService, StorageScope } from 'vs/platform/storage/common/storage'; +import { IThemeService } from 'vs/platform/theme/common/themeService'; +import { Extensions, IWorkbenchContributionsRegistry } from 'vs/workbench/common/contributions'; +import * as themes from 'vs/workbench/common/theme'; +import { IPartService, Parts, Position } from 'vs/workbench/services/part/common/partService'; + +class PartsSplash { + + private static readonly _splashElementId = 'monaco-parts-splash'; + + constructor( + @IThemeService private readonly _themeService: IThemeService, + @IPartService private readonly _partService: IPartService, + @IStorageService private readonly _storageService: IStorageService, + @ILifecycleService lifecycleService: ILifecycleService, + ) { + lifecycleService.when(LifecyclePhase.Running).then(_ => this._removePartsSplash()); + lifecycleService.onShutdown(() => this._savePartsSplash()); + } + + private _savePartsSplash() { + const theme = this._themeService.getTheme(); + const colorInfo = { + titleBarBackground: theme.getColor(themes.TITLE_BAR_ACTIVE_BACKGROUND).toString(), + activityBarBackground: theme.getColor(themes.ACTIVITY_BAR_BACKGROUND).toString(), + sideBarBackground: theme.getColor(themes.SIDE_BAR_BACKGROUND).toString(), + statusBarBackground: theme.getColor(themes.STATUS_BAR_BACKGROUND).toString(), + statusBarNoFolderBackground: theme.getColor(themes.STATUS_BAR_NO_FOLDER_BACKGROUND).toString(), + }; + const layoutInfo = { + titleBarHeight: getTotalHeight(this._partService.getContainer(Parts.TITLEBAR_PART)), + sideBarSide: this._partService.getSideBarPosition() === Position.RIGHT ? 'right' : 'left', + activityBarWidth: getTotalWidth(this._partService.getContainer(Parts.ACTIVITYBAR_PART)), + sideBarWidth: getTotalWidth(this._partService.getContainer(Parts.SIDEBAR_PART)), + statusBarHeight: getTotalHeight(this._partService.getContainer(Parts.STATUSBAR_PART)), + }; + this._storageService.store('parts-splash-data', JSON.stringify({ id: PartsSplash._splashElementId, colorInfo, layoutInfo }), StorageScope.GLOBAL); + } + + private _removePartsSplash(): void { + let element = document.getElementById(PartsSplash._splashElementId); + if (element) { + element.remove(); + } + } +} + +Registry.as(Extensions.Workbench).registerWorkbenchContribution(PartsSplash, LifecyclePhase.Starting); diff --git a/src/vs/workbench/workbench.main.ts b/src/vs/workbench/workbench.main.ts index 2df703e1c1f..a83b89a74e7 100644 --- a/src/vs/workbench/workbench.main.ts +++ b/src/vs/workbench/workbench.main.ts @@ -54,6 +54,8 @@ import 'vs/workbench/parts/backup/common/backup.contribution'; import 'vs/workbench/parts/stats/node/stats.contribution'; +import 'vs/workbench/parts/splash/electron-browser/partsSplash.contribution'; + import 'vs/workbench/parts/search/electron-browser/search.contribution'; import 'vs/workbench/parts/search/browser/searchView'; // can be packaged separately import 'vs/workbench/parts/search/browser/openAnythingHandler'; // can be packaged separately From 7697ef67117442ad6bb7e0451ff6ea5cb81094d8 Mon Sep 17 00:00:00 2001 From: Erich Gamma Date: Thu, 26 Jul 2018 13:57:37 +0200 Subject: [PATCH 0164/1276] Flush scripts cache when the document changes --- extensions/npm/src/main.ts | 9 ++++++++- extensions/npm/src/scriptHover.ts | 10 ++++++++-- 2 files changed, 16 insertions(+), 3 deletions(-) diff --git a/extensions/npm/src/main.ts b/extensions/npm/src/main.ts index a3c7dc03d9c..116852100dc 100644 --- a/extensions/npm/src/main.ts +++ b/extensions/npm/src/main.ts @@ -17,7 +17,7 @@ export async function activate(context: vscode.ExtensionContext): Promise const hoverProvider = registerHoverProvider(context); configureHttpRequest(); - vscode.workspace.onDidChangeConfiguration((e) => { + let d = vscode.workspace.onDidChangeConfiguration((e) => { configureHttpRequest(); if (e.affectsConfiguration('npm.exclude')) { invalidateTasksCache(); @@ -31,6 +31,13 @@ export async function activate(context: vscode.ExtensionContext): Promise } } }); + context.subscriptions.push(d); + + d = vscode.workspace.onDidChangeTextDocument((e) => { + invalidateHoverScriptsCache(e.document); + }); + context.subscriptions.push(d); + context.subscriptions.push(addJSONProviders(httpRequest.xhr)); } diff --git a/extensions/npm/src/scriptHover.ts b/extensions/npm/src/scriptHover.ts index 1349965a151..d81ceee0807 100644 --- a/extensions/npm/src/scriptHover.ts +++ b/extensions/npm/src/scriptHover.ts @@ -18,8 +18,14 @@ const localize = nls.loadMessageBundle(); let cachedDocument: Uri | undefined = undefined; let cachedScriptsMap: Map | undefined = undefined; -export function invalidateHoverScriptsCache() { - cachedDocument = undefined; +export function invalidateHoverScriptsCache(document?: TextDocument) { + if (!document) { + cachedDocument = undefined; + return; + } + if (document.uri === cachedDocument) { + cachedDocument = undefined; + } } export class NpmScriptHoverProvider implements HoverProvider { From 2da55bbc38a0326cf02b3cd4d4feb0bebcf552eb Mon Sep 17 00:00:00 2001 From: Sandeep Somavarapu Date: Thu, 26 Jul 2018 15:59:04 +0200 Subject: [PATCH 0165/1276] #54992 Temp fix --- src/vs/platform/history/electron-main/historyMainService.ts | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/vs/platform/history/electron-main/historyMainService.ts b/src/vs/platform/history/electron-main/historyMainService.ts index 2df1458fbd9..92ef9abe5dc 100644 --- a/src/vs/platform/history/electron-main/historyMainService.ts +++ b/src/vs/platform/history/electron-main/historyMainService.ts @@ -177,8 +177,9 @@ export class HistoryMainService implements IHistoryMainService { let maxEntries = HistoryMainService.MAX_MACOS_DOCK_RECENT_ENTRIES; // Take up to maxEntries/2 workspaces - for (let i = 0; i < mru.workspaces.length && i < HistoryMainService.MAX_MACOS_DOCK_RECENT_ENTRIES / 2; i++) { - const workspace = mru.workspaces[i]; + const workspaces = mru.workspaces.filter(w => !(isSingleFolderWorkspaceIdentifier(w) && w.scheme !== Schemas.file)); + for (let i = 0; i < workspaces.length && i < HistoryMainService.MAX_MACOS_DOCK_RECENT_ENTRIES / 2; i++) { + const workspace = workspaces[i]; app.addRecentDocument(isSingleFolderWorkspaceIdentifier(workspace) ? workspace.scheme === Schemas.file ? workspace.fsPath : workspace.toString() : workspace.configPath); maxEntries--; } From c412116fcb907d07c8825cf328db9156558704b7 Mon Sep 17 00:00:00 2001 From: Johannes Rieken Date: Thu, 26 Jul 2018 16:03:38 +0200 Subject: [PATCH 0166/1276] save parts splash on editor layout change #55017 --- .../workbench/electron-browser/bootstrap/index.js | 4 ++++ .../electron-browser/partsSplash.contribution.ts | 14 ++++++++++++-- 2 files changed, 16 insertions(+), 2 deletions(-) diff --git a/src/vs/workbench/electron-browser/bootstrap/index.js b/src/vs/workbench/electron-browser/bootstrap/index.js index 2cb6af431ee..8311ab796ae 100644 --- a/src/vs/workbench/electron-browser/bootstrap/index.js +++ b/src/vs/workbench/electron-browser/bootstrap/index.js @@ -101,6 +101,10 @@ function showPartsSplash(configuration) { const splash = document.createElement('div'); splash.id = data.id; const { layoutInfo, colorInfo } = data; + + // ensure there is enough space + layoutInfo.sideBarWidth = Math.min(layoutInfo.sideBarWidth, window.innerWidth - (layoutInfo.activityBarWidth + layoutInfo.editorPartMinWidth)); + if (configuration.folderUri || configuration.workspace) { // folder or workspace -> status bar color, sidebar splash.innerHTML = ` diff --git a/src/vs/workbench/parts/splash/electron-browser/partsSplash.contribution.ts b/src/vs/workbench/parts/splash/electron-browser/partsSplash.contribution.ts index a449280ea49..849d454f33d 100644 --- a/src/vs/workbench/parts/splash/electron-browser/partsSplash.contribution.ts +++ b/src/vs/workbench/parts/splash/electron-browser/partsSplash.contribution.ts @@ -13,11 +13,16 @@ import { IThemeService } from 'vs/platform/theme/common/themeService'; import { Extensions, IWorkbenchContributionsRegistry } from 'vs/workbench/common/contributions'; import * as themes from 'vs/workbench/common/theme'; import { IPartService, Parts, Position } from 'vs/workbench/services/part/common/partService'; +import { IDisposable, dispose } from 'vs/base/common/lifecycle'; +import { debounceEvent } from 'vs/base/common/event'; +import { DEFAULT_EDITOR_MIN_DIMENSIONS } from 'vs/workbench/browser/parts/editor/editor'; class PartsSplash { private static readonly _splashElementId = 'monaco-parts-splash'; + private readonly _disposables: IDisposable[] = []; + constructor( @IThemeService private readonly _themeService: IThemeService, @IPartService private readonly _partService: IPartService, @@ -25,7 +30,11 @@ class PartsSplash { @ILifecycleService lifecycleService: ILifecycleService, ) { lifecycleService.when(LifecyclePhase.Running).then(_ => this._removePartsSplash()); - lifecycleService.onShutdown(() => this._savePartsSplash()); + debounceEvent(_partService.onEditorLayout, () => { }, 50)(this._savePartsSplash, this, this._disposables); + } + + dispose(): void { + dispose(this._disposables); } private _savePartsSplash() { @@ -38,8 +47,9 @@ class PartsSplash { statusBarNoFolderBackground: theme.getColor(themes.STATUS_BAR_NO_FOLDER_BACKGROUND).toString(), }; const layoutInfo = { - titleBarHeight: getTotalHeight(this._partService.getContainer(Parts.TITLEBAR_PART)), sideBarSide: this._partService.getSideBarPosition() === Position.RIGHT ? 'right' : 'left', + editorPartMinWidth: DEFAULT_EDITOR_MIN_DIMENSIONS.width, + titleBarHeight: getTotalHeight(this._partService.getContainer(Parts.TITLEBAR_PART)), activityBarWidth: getTotalWidth(this._partService.getContainer(Parts.ACTIVITYBAR_PART)), sideBarWidth: getTotalWidth(this._partService.getContainer(Parts.SIDEBAR_PART)), statusBarHeight: getTotalHeight(this._partService.getContainer(Parts.STATUSBAR_PART)), From ef5c70c9ef968f6437a32e3d6a9cb81415980d3a Mon Sep 17 00:00:00 2001 From: Sandeep Somavarapu Date: Thu, 26 Jul 2018 16:11:48 +0200 Subject: [PATCH 0167/1276] Fix #51160 --- .../parts/markers/electron-browser/markersPanel.ts | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/vs/workbench/parts/markers/electron-browser/markersPanel.ts b/src/vs/workbench/parts/markers/electron-browser/markersPanel.ts index 804b805f657..c89d699c248 100644 --- a/src/vs/workbench/parts/markers/electron-browser/markersPanel.ts +++ b/src/vs/workbench/parts/markers/electron-browser/markersPanel.ts @@ -68,6 +68,7 @@ export class MarkersPanel extends Panel { this.delayedRefresh = new Delayer(500); this.autoExpanded = new Set(); this.panelSettings = this.getMemento(storageService, Scope.WORKSPACE); + this.setCurrentActiveEditor(); } public create(parent: HTMLElement): TPromise { @@ -269,9 +270,13 @@ export class MarkersPanel extends Panel { } private onActiveEditorChanged(): void { + this.setCurrentActiveEditor(); + this.autoReveal(); + } + + private setCurrentActiveEditor(): void { const activeEditor = this.editorService.activeEditor; this.currentActiveResource = activeEditor ? activeEditor.getResource() : void 0; - this.autoReveal(); } private onSelected(): void { From 53fd49b7de9770c318a861f99c5364e2e0a02b9e Mon Sep 17 00:00:00 2001 From: Sandeep Somavarapu Date: Thu, 26 Jul 2018 16:25:00 +0200 Subject: [PATCH 0168/1276] Fix #53116 --- .../parts/preferences/browser/preferencesRenderers.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/vs/workbench/parts/preferences/browser/preferencesRenderers.ts b/src/vs/workbench/parts/preferences/browser/preferencesRenderers.ts index 395c614d1d2..ecbf27ed23c 100644 --- a/src/vs/workbench/parts/preferences/browser/preferencesRenderers.ts +++ b/src/vs/workbench/parts/preferences/browser/preferencesRenderers.ts @@ -90,7 +90,6 @@ export class UserSettingsRenderer extends Disposable implements IPreferencesRend this._register(this.editSettingActionRenderer.onUpdateSetting(({ key, value, source }) => this._updatePreference(key, value, source))); this._register(this.editor.getModel().onDidChangeContent(() => this.modelChangeDelayer.trigger(() => this.onModelChanged()))); - this.createHeader(); } public getAssociatedPreferencesModel(): IPreferencesEditorModel { @@ -100,6 +99,9 @@ export class UserSettingsRenderer extends Disposable implements IPreferencesRend public setAssociatedPreferencesModel(associatedPreferencesModel: IPreferencesEditorModel): void { this.associatedPreferencesModel = associatedPreferencesModel; this.editSettingActionRenderer.associatedPreferencesModel = associatedPreferencesModel; + + // Create header only in Settings editor mode + this.createHeader(); } protected createHeader(): void { From f13106500dd1a7d61f7695cdfb2d8415b99c2389 Mon Sep 17 00:00:00 2001 From: Johannes Rieken Date: Thu, 26 Jul 2018 16:54:45 +0200 Subject: [PATCH 0169/1276] update doc comment #52927 --- src/vs/vscode.proposed.d.ts | 22 +++++++++++++--------- 1 file changed, 13 insertions(+), 9 deletions(-) diff --git a/src/vs/vscode.proposed.d.ts b/src/vs/vscode.proposed.d.ts index 59949ab60c9..e8d37bcf221 100644 --- a/src/vs/vscode.proposed.d.ts +++ b/src/vs/vscode.proposed.d.ts @@ -701,10 +701,9 @@ declare module 'vscode' { /** * A workspace edit is a collection of textual and files changes for - * multiple resources and documents. Use the [applyEdit](#workspace.applyEdit)-function - * to apply a workspace edit. Note that all changes are applied in the same order in which - * they have been added and that invalid sequences like 'delete file a' -> 'insert text in - * file a' causes failure of the operation. + * multiple resources and documents. + * + * Use the [applyEdit](#workspace.applyEdit)-function to apply a workspace edit. */ export interface WorkspaceEdit { @@ -739,13 +738,18 @@ declare module 'vscode' { } export namespace workspace { + /** - * Make changes to one or many resources as defined by the given - * [workspace edit](#WorkspaceEdit). + * Make changes to one or many resources or create, delete, and rename resources. * - * The editor implements an 'all-or-nothing'-strategy and that means failure to modify, - * delete, rename, or create one file will abort the operation. In that case, the thenable returned - * by this function resolves to `false`. + * All changes of a workspace edit are applied in the same order in which they have been added. If + * multiple textual inserts are made at the same position, these strings appear in the resulting text + * in the order the 'inserts' were made. Invalid sequences like 'delete file a' -> 'insert text in file a' + * cause failure of the operation. + * + * When applying a workspace edit that consists only of text edits an 'all-or-nothing'-strategy is used. + * A workspace edit with resource creations or deletions aborts the operation, e.g. consective edits will + * not be attempted, when a single edit fails. * * @param edit A workspace edit. * @return A thenable that resolves when the edit could be applied. From 501156e3c28ed2393485d93f8115b69bab7c1ded Mon Sep 17 00:00:00 2001 From: isidor Date: Thu, 26 Jul 2018 17:25:38 +0200 Subject: [PATCH 0170/1276] uriDisplayService with tests --- .../platform/uriDisplay/common/uriDisplay.ts | 72 ++++++++++--------- .../uriDisplay/test/uriDisplay.test.ts | 50 +++++++++++++ 2 files changed, 90 insertions(+), 32 deletions(-) create mode 100644 src/vs/platform/uriDisplay/test/uriDisplay.test.ts diff --git a/src/vs/platform/uriDisplay/common/uriDisplay.ts b/src/vs/platform/uriDisplay/common/uriDisplay.ts index ac49935e2db..c98168c7063 100644 --- a/src/vs/platform/uriDisplay/common/uriDisplay.ts +++ b/src/vs/platform/uriDisplay/common/uriDisplay.ts @@ -12,6 +12,7 @@ import { createDecorator } from 'vs/platform/instantiation/common/instantiation' import { isEqual, basenameOrAuthority } from 'vs/base/common/resources'; import { isLinux, isWindows } from 'vs/base/common/platform'; import { tildify, normalizeDriveLetter } from 'vs/base/common/labels'; +import { ltrim } from 'vs/base/common/strings'; export interface IUriDisplayService { _serviceBrand: any; @@ -21,18 +22,20 @@ export interface IUriDisplayService { export interface UriDisplayRules { label: string; // myLabel:/${path} - separator: '/' | '\\' | undefined; + separator: '/' | '\\' | ''; tildify?: boolean; normalizeDriveLetter?: boolean; } const URI_DISPLAY_SERVICE_ID = 'uriDisplay'; +const sepRegexp = /\//g; +const labelMatchingRegexp = /\$\{scheme\}|\$\{authority\}|\$\{path\}/g; function hasDriveLetter(path: string): boolean { return isWindows && path && path[1] === ':'; } -class UriDisplayService implements IUriDisplayService { +export class UriDisplayService implements IUriDisplayService { _serviceBrand: any; private formaters = new Map(); @@ -46,28 +49,33 @@ class UriDisplayService implements IUriDisplayService { if (!resource) { return undefined; } - - if (relative) { - const hasMultipleRoots = this.contextService.getWorkspace().folders.length > 1; - const baseResource = this.contextService.getWorkspaceFolder(resource); - - let pathLabel: string; - if (isEqual(baseResource.uri, resource, !isLinux)) { - pathLabel = ''; // no label if paths are identical - } else { - const baseResourceLabel = this.formatUri(baseResource.uri); - pathLabel = this.formatUri(resource).substring(baseResourceLabel.length); - } - - if (hasMultipleRoots) { - const rootName = (baseResource && baseResource.name) ? baseResource.name : basenameOrAuthority(baseResource.uri); - pathLabel = pathLabel ? (rootName + ' • ' + pathLabel) : rootName; // always show root basename if there are multiple - } - - return pathLabel; + const formater = this.formaters.get(resource.scheme); + if (!formater) { + return resource.with({ query: null, fragment: null }).toString(true); } - return this.formatUri(resource); + if (relative) { + const baseResource = this.contextService.getWorkspaceFolder(resource); + if (baseResource) { + let relativeLabel: string; + if (isEqual(baseResource.uri, resource, !isLinux)) { + relativeLabel = ''; // no label if resources are identical + } else { + const baseResourceLabel = this.formatUri(baseResource.uri, formater); + relativeLabel = ltrim(this.formatUri(resource, formater).substring(baseResourceLabel.length), formater.separator); + } + + const hasMultipleRoots = this.contextService.getWorkspace().folders.length > 1; + if (hasMultipleRoots) { + const rootName = (baseResource && baseResource.name) ? baseResource.name : basenameOrAuthority(baseResource.uri); + relativeLabel = relativeLabel ? (rootName + ' • ' + relativeLabel) : rootName; // always show root basename if there are multiple + } + + return relativeLabel; + } + } + + return this.formatUri(resource, formater); } registerFormater(scheme: string, formater: UriDisplayRules): IDisposable { @@ -78,26 +86,26 @@ class UriDisplayService implements IUriDisplayService { }; } - private formatUri(resource: URI): string { - const formater = this.formaters.get(resource.scheme); - if (!formater) { - return resource.with({ query: null, fragment: null }).toString(true); - } - - // TODO@isidor transform - let label = resource.path; + private formatUri(resource: URI, formater: UriDisplayRules): string { + let label = formater.label.replace(labelMatchingRegexp, match => { + switch (match) { + case '${scheme}': return resource.scheme; + case '${authority}': return resource.authority; + case '${path}': return resource.path; + default: return ''; + } + }); // convert c:\something => C:\something if (formater.normalizeDriveLetter && hasDriveLetter(label)) { label = normalizeDriveLetter(label); } - // normalize and tildify (macOS, Linux only) if (formater.tildify) { label = tildify(label, this.environmentService.userHome); } - return label; + return label.replace(sepRegexp, formater.separator); } } diff --git a/src/vs/platform/uriDisplay/test/uriDisplay.test.ts b/src/vs/platform/uriDisplay/test/uriDisplay.test.ts new file mode 100644 index 00000000000..f20db873bab --- /dev/null +++ b/src/vs/platform/uriDisplay/test/uriDisplay.test.ts @@ -0,0 +1,50 @@ +/*--------------------------------------------------------------------------------------------- + * 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 { IUriDisplayService, UriDisplayService } from 'vs/platform/uriDisplay/common/uriDisplay'; +import { TestEnvironmentService, TestContextService } from 'vs/workbench/test/workbenchTestServices'; +import { Schemas } from 'vs/base/common/network'; +import { TestWorkspace } from 'vs/platform/workspace/test/common/testWorkspace'; +import URI from 'vs/base/common/uri'; +import { nativeSep } from 'vs/base/common/paths'; +import { isWindows } from 'vs/base/common/platform'; + +suite('URI Display', () => { + + let uriDisplayService: IUriDisplayService; + + setup(() => { + uriDisplayService = new UriDisplayService(TestEnvironmentService, new TestContextService()); + }); + + test('file scheme', function () { + uriDisplayService.registerFormater(Schemas.file, { + label: '${path}', + separator: nativeSep, + tildify: !isWindows, + normalizeDriveLetter: isWindows + }); + + const uri1 = TestWorkspace.folders[0].uri.with({ path: TestWorkspace.folders[0].uri.path.concat('/a/b/c/d') }); + assert.equal(uriDisplayService.getLabel(uri1, true), isWindows ? 'a\\b\\c\\d' : 'a/b/c/d'); + assert.equal(uriDisplayService.getLabel(uri1, false), isWindows ? '\\testWorkspace\\a\\b\\c\\d' : '/testWorkspace/a/b/c/d'); + + const uri2 = URI.file('c:\\1/2/3'); + assert.equal(uriDisplayService.getLabel(uri2, false), isWindows ? 'C:\\1\\2\\3' : '/c:\\1/2/3'); + }); + + test('custom scheme', function () { + uriDisplayService.registerFormater(Schemas.vscode, { + label: 'LABEL/${path}/${authority}/END', + separator: '/', + tildify: true, + normalizeDriveLetter: true + }); + + const uri1 = URI.parse('vscode://microsoft.com/1/2/3/4/5'); + assert.equal(uriDisplayService.getLabel(uri1, false), 'LABEL//1/2/3/4/5/microsoft.com/END'); + }); +}); From a9e8d5a1b1030608da82ccccdfbb9d7de5a711ec Mon Sep 17 00:00:00 2001 From: Johannes Rieken Date: Thu, 26 Jul 2018 17:29:29 +0200 Subject: [PATCH 0171/1276] simplify QuickInputButton#iconPath --- 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 ac726df3447..1ef082e1c0b 100644 --- a/src/vs/vscode.d.ts +++ b/src/vs/vscode.d.ts @@ -6847,7 +6847,7 @@ declare module 'vscode' { /** * Icon for the button. */ - readonly iconPath: string | Uri | { light: string | Uri; dark: string | Uri } | ThemeIcon; + readonly iconPath: Uri | { light: Uri; dark: Uri } | ThemeIcon; /** * An optional tooltip. From d2c506038c72e080dd77e41b2e0bf28d9e4adfbf Mon Sep 17 00:00:00 2001 From: Johannes Rieken Date: Thu, 26 Jul 2018 17:34:46 +0200 Subject: [PATCH 0172/1276] add more jsdoc - fixes #52919 --- src/vs/vscode.proposed.d.ts | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/vs/vscode.proposed.d.ts b/src/vs/vscode.proposed.d.ts index e8d37bcf221..908e1fdce8e 100644 --- a/src/vs/vscode.proposed.d.ts +++ b/src/vs/vscode.proposed.d.ts @@ -716,7 +716,8 @@ declare module 'vscode' { * Create a regular file. * * @param uri Uri of the new file.. - * @param options Defines if an existing file should be overwritten or be ignored. + * @param options Defines if an existing file should be overwritten or be + * ignored. When overwrite and ignoreIfExists are both set overwrite wins. */ createFile(uri: Uri, options?: { overwrite?: boolean, ignoreIfExists?: boolean }): void; @@ -732,7 +733,8 @@ declare module 'vscode' { * * @param oldUri The existing file. * @param newUri The new location. - * @param options Defines if existing files should be overwritten. + * @param options Defines if existing files should be overwritten or be + * ignored. When overwrite and ignoreIfExists are both set overwrite wins. */ renameFile(oldUri: Uri, newUri: Uri, options?: { overwrite?: boolean, ignoreIfExists?: boolean }): void; } From f466647f9132d15cebfaf336b6d555ddd236fb1e Mon Sep 17 00:00:00 2001 From: isidor Date: Thu, 26 Jul 2018 17:38:21 +0200 Subject: [PATCH 0173/1276] uriDisplay: drive letter polish --- src/vs/platform/uriDisplay/common/uriDisplay.ts | 8 ++++---- src/vs/platform/uriDisplay/test/uriDisplay.test.ts | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/vs/platform/uriDisplay/common/uriDisplay.ts b/src/vs/platform/uriDisplay/common/uriDisplay.ts index c98168c7063..7e72ea0664c 100644 --- a/src/vs/platform/uriDisplay/common/uriDisplay.ts +++ b/src/vs/platform/uriDisplay/common/uriDisplay.ts @@ -11,7 +11,7 @@ import { registerSingleton } from 'vs/platform/instantiation/common/extensions'; import { createDecorator } from 'vs/platform/instantiation/common/instantiation'; import { isEqual, basenameOrAuthority } from 'vs/base/common/resources'; import { isLinux, isWindows } from 'vs/base/common/platform'; -import { tildify, normalizeDriveLetter } from 'vs/base/common/labels'; +import { tildify } from 'vs/base/common/labels'; import { ltrim } from 'vs/base/common/strings'; export interface IUriDisplayService { @@ -32,7 +32,7 @@ const sepRegexp = /\//g; const labelMatchingRegexp = /\$\{scheme\}|\$\{authority\}|\$\{path\}/g; function hasDriveLetter(path: string): boolean { - return isWindows && path && path[1] === ':'; + return isWindows && path && path[2] === ':'; } export class UriDisplayService implements IUriDisplayService { @@ -96,9 +96,9 @@ export class UriDisplayService implements IUriDisplayService { } }); - // convert c:\something => C:\something + // convert \c:\something => C:\something if (formater.normalizeDriveLetter && hasDriveLetter(label)) { - label = normalizeDriveLetter(label); + label = label.charAt(1).toUpperCase() + label.substr(2); } if (formater.tildify) { diff --git a/src/vs/platform/uriDisplay/test/uriDisplay.test.ts b/src/vs/platform/uriDisplay/test/uriDisplay.test.ts index f20db873bab..a54cc2318b4 100644 --- a/src/vs/platform/uriDisplay/test/uriDisplay.test.ts +++ b/src/vs/platform/uriDisplay/test/uriDisplay.test.ts @@ -30,7 +30,7 @@ suite('URI Display', () => { const uri1 = TestWorkspace.folders[0].uri.with({ path: TestWorkspace.folders[0].uri.path.concat('/a/b/c/d') }); assert.equal(uriDisplayService.getLabel(uri1, true), isWindows ? 'a\\b\\c\\d' : 'a/b/c/d'); - assert.equal(uriDisplayService.getLabel(uri1, false), isWindows ? '\\testWorkspace\\a\\b\\c\\d' : '/testWorkspace/a/b/c/d'); + assert.equal(uriDisplayService.getLabel(uri1, false), isWindows ? 'C:\\testWorkspace\\a\\b\\c\\d' : '/testWorkspace/a/b/c/d'); const uri2 = URI.file('c:\\1/2/3'); assert.equal(uriDisplayService.getLabel(uri2, false), isWindows ? 'C:\\1\\2\\3' : '/c:\\1/2/3'); From c99654e046d2295e2ffaf28785a1347a4827c244 Mon Sep 17 00:00:00 2001 From: isidor Date: Thu, 26 Jul 2018 17:53:49 +0200 Subject: [PATCH 0174/1276] debug: adopt uri display service --- src/vs/platform/uriDisplay/common/uriDisplay.ts | 2 +- .../workbench/parts/debug/browser/breakpointsView.ts | 12 ++++-------- .../parts/debug/electron-browser/callStackView.ts | 8 +++----- .../parts/debug/electron-browser/replViewer.ts | 7 +++---- 4 files changed, 11 insertions(+), 18 deletions(-) diff --git a/src/vs/platform/uriDisplay/common/uriDisplay.ts b/src/vs/platform/uriDisplay/common/uriDisplay.ts index 7e72ea0664c..f11cc9c54b6 100644 --- a/src/vs/platform/uriDisplay/common/uriDisplay.ts +++ b/src/vs/platform/uriDisplay/common/uriDisplay.ts @@ -16,7 +16,7 @@ import { ltrim } from 'vs/base/common/strings'; export interface IUriDisplayService { _serviceBrand: any; - getLabel(resource: URI, relative: boolean): string; + getLabel(resource: URI, relative?: boolean): string; registerFormater(schema: string, formater: UriDisplayRules): IDisposable; } diff --git a/src/vs/workbench/parts/debug/browser/breakpointsView.ts b/src/vs/workbench/parts/debug/browser/breakpointsView.ts index ef55c3cdac8..2a869ab101f 100644 --- a/src/vs/workbench/parts/debug/browser/breakpointsView.ts +++ b/src/vs/workbench/parts/debug/browser/breakpointsView.ts @@ -16,11 +16,7 @@ import { IInstantiationService } from 'vs/platform/instantiation/common/instanti import { IKeybindingService } from 'vs/platform/keybinding/common/keybinding'; import { IThemeService } from 'vs/platform/theme/common/themeService'; import { Constants } from 'vs/editor/common/core/uint'; -import { IWorkspaceContextService } from 'vs/platform/workspace/common/workspace'; -import { getPathLabel } from 'vs/base/common/labels'; import { dispose, IDisposable } from 'vs/base/common/lifecycle'; -import { basename } from 'vs/base/common/paths'; -import { IEnvironmentService } from 'vs/platform/environment/common/environment'; import { TPromise } from 'vs/base/common/winjs.base'; import { Separator } from 'vs/base/browser/ui/actionbar/actionbar'; import { IVirtualDelegate, IListContextMenuEvent, IRenderer } from 'vs/base/browser/ui/list/list'; @@ -36,6 +32,7 @@ import { IConfigurationService } from 'vs/platform/configuration/common/configur import { ITextFileService } from 'vs/workbench/services/textfile/common/textfiles'; import { IEditorService, SIDE_GROUP, ACTIVE_GROUP } from 'vs/workbench/services/editor/common/editorService'; import { ViewletPanel, IViewletPanelOptions } from 'vs/workbench/browser/parts/views/panelViewlet'; +import { IUriDisplayService } from 'vs/platform/uriDisplay/common/uriDisplay'; const $ = dom.$; @@ -287,8 +284,7 @@ class BreakpointsRenderer implements IRenderer element.sourceData; } From 2de99c112e56173fa54741bf5d46c4a4d13e229c Mon Sep 17 00:00:00 2001 From: isidor Date: Thu, 26 Jul 2018 18:08:41 +0200 Subject: [PATCH 0175/1276] register uri display service early in workbench since other services can depend on it --- src/vs/platform/uriDisplay/common/uriDisplay.ts | 3 --- src/vs/workbench/electron-browser/workbench.ts | 4 ++++ 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/src/vs/platform/uriDisplay/common/uriDisplay.ts b/src/vs/platform/uriDisplay/common/uriDisplay.ts index f11cc9c54b6..e78934fb6de 100644 --- a/src/vs/platform/uriDisplay/common/uriDisplay.ts +++ b/src/vs/platform/uriDisplay/common/uriDisplay.ts @@ -7,7 +7,6 @@ import URI from 'vs/base/common/uri'; import { IDisposable } from 'vs/base/common/lifecycle'; import { IEnvironmentService } from 'vs/platform/environment/common/environment'; import { IWorkspaceContextService } from 'vs/platform/workspace/common/workspace'; -import { registerSingleton } from 'vs/platform/instantiation/common/extensions'; import { createDecorator } from 'vs/platform/instantiation/common/instantiation'; import { isEqual, basenameOrAuthority } from 'vs/base/common/resources'; import { isLinux, isWindows } from 'vs/base/common/platform'; @@ -109,6 +108,4 @@ export class UriDisplayService implements IUriDisplayService { } } -// register service export const IUriDisplayService = createDecorator(URI_DISPLAY_SERVICE_ID); -registerSingleton(IUriDisplayService, UriDisplayService); diff --git a/src/vs/workbench/electron-browser/workbench.ts b/src/vs/workbench/electron-browser/workbench.ts index 00aae6933f9..365d20568b8 100644 --- a/src/vs/workbench/electron-browser/workbench.ts +++ b/src/vs/workbench/electron-browser/workbench.ts @@ -118,6 +118,7 @@ import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry'; import { TelemetryService } from 'vs/platform/telemetry/common/telemetryService'; import { WorkbenchThemeService } from 'vs/workbench/services/themes/electron-browser/workbenchThemeService'; import { IWorkbenchThemeService } from 'vs/workbench/services/themes/common/workbenchThemeService'; +import { IUriDisplayService, UriDisplayService } from 'vs/platform/uriDisplay/common/uriDisplay'; interface WorkbenchParams { configuration: IWindowConfiguration; @@ -334,6 +335,9 @@ export class Workbench extends Disposable implements IPartService { // Clipboard serviceCollection.set(IClipboardService, new ClipboardService()); + // Uri Display + serviceCollection.set(IUriDisplayService, new UriDisplayService(this.environmentService, this.contextService)); + // Status bar this.statusbarPart = this.instantiationService.createInstance(StatusbarPart, Identifiers.STATUSBAR_PART); this._register(toDisposable(() => this.statusbarPart.shutdown())); From 6673b5a9f9d464713f17381570ab402a66464ab9 Mon Sep 17 00:00:00 2001 From: isidor Date: Thu, 26 Jul 2018 18:08:49 +0200 Subject: [PATCH 0176/1276] editorService: adopt uri display service --- .../services/editor/browser/editorService.ts | 19 +++++++------------ 1 file changed, 7 insertions(+), 12 deletions(-) diff --git a/src/vs/workbench/services/editor/browser/editorService.ts b/src/vs/workbench/services/editor/browser/editorService.ts index 7b29d31a644..6250d63c405 100644 --- a/src/vs/workbench/services/editor/browser/editorService.ts +++ b/src/vs/workbench/services/editor/browser/editorService.ts @@ -13,11 +13,8 @@ import { DataUriEditorInput } from 'vs/workbench/common/editor/dataUriEditorInpu import { Registry } from 'vs/platform/registry/common/platform'; import { ResourceMap } from 'vs/base/common/map'; import { IUntitledEditorService } from 'vs/workbench/services/untitled/common/untitledEditorService'; -import { IWorkspaceContextService } from 'vs/platform/workspace/common/workspace'; -import { IEnvironmentService } from 'vs/platform/environment/common/environment'; import { IFileService } from 'vs/platform/files/common/files'; import { Schemas } from 'vs/base/common/network'; -import { getPathLabel } from 'vs/base/common/labels'; import { Event, once, Emitter } from 'vs/base/common/event'; import URI from 'vs/base/common/uri'; import { basename } from 'vs/base/common/paths'; @@ -31,6 +28,7 @@ import { Disposable, IDisposable, dispose, toDisposable } from 'vs/base/common/l import { coalesce } from 'vs/base/common/arrays'; import { isCodeEditor, isDiffEditor, ICodeEditor, IDiffEditor } from 'vs/editor/browser/editorBrowser'; import { IEditorGroupView, IEditorOpeningEvent, EditorGroupsServiceImpl, EditorServiceImpl } from 'vs/workbench/browser/parts/editor/editor'; +import { IUriDisplayService } from 'vs/platform/uriDisplay/common/uriDisplay'; type ICachedEditorInput = ResourceEditorInput | IFileEditorInput | DataUriEditorInput; @@ -65,9 +63,8 @@ export class EditorService extends Disposable implements EditorServiceImpl { constructor( @IEditorGroupsService private editorGroupService: EditorGroupsServiceImpl, @IUntitledEditorService private untitledEditorService: IUntitledEditorService, - @IWorkspaceContextService private workspaceContextService: IWorkspaceContextService, @IInstantiationService private instantiationService: IInstantiationService, - @IEnvironmentService private environmentService: IEnvironmentService, + @IUriDisplayService private uriDisplayService: IUriDisplayService, @IFileService private fileService: IFileService, @IConfigurationService private configurationService: IConfigurationService ) { @@ -489,7 +486,7 @@ export class EditorService extends Disposable implements EditorServiceImpl { if (resourceDiffInput.leftResource && resourceDiffInput.rightResource) { const leftInput = this.createInput({ resource: resourceDiffInput.leftResource }, options); const rightInput = this.createInput({ resource: resourceDiffInput.rightResource }, options); - const label = resourceDiffInput.label || localize('compareLabels', "{0} ↔ {1}", this.toDiffLabel(leftInput, this.workspaceContextService, this.environmentService), this.toDiffLabel(rightInput, this.workspaceContextService, this.environmentService)); + const label = resourceDiffInput.label || localize('compareLabels', "{0} ↔ {1}", this.toDiffLabel(leftInput), this.toDiffLabel(rightInput)); return new DiffEditorInput(label, resourceDiffInput.description, leftInput, rightInput); } @@ -557,7 +554,7 @@ export class EditorService extends Disposable implements EditorServiceImpl { return input; } - private toDiffLabel(input: EditorInput, context: IWorkspaceContextService, environment: IEnvironmentService): string { + private toDiffLabel(input: EditorInput): string { const res = input.getResource(); // Do not try to extract any paths from simple untitled editors @@ -566,7 +563,7 @@ export class EditorService extends Disposable implements EditorServiceImpl { } // Otherwise: for diff labels prefer to see the path as part of the label - return getPathLabel(res.fsPath, environment, context); + return this.uriDisplayService.getLabel(res, true); } //#endregion @@ -586,18 +583,16 @@ export class DelegatingEditorService extends EditorService { constructor( @IEditorGroupsService editorGroupService: EditorGroupsServiceImpl, @IUntitledEditorService untitledEditorService: IUntitledEditorService, - @IWorkspaceContextService workspaceContextService: IWorkspaceContextService, @IInstantiationService instantiationService: IInstantiationService, - @IEnvironmentService environmentService: IEnvironmentService, + @IUriDisplayService uriDisplayService: IUriDisplayService, @IFileService fileService: IFileService, @IConfigurationService configurationService: IConfigurationService ) { super( editorGroupService, untitledEditorService, - workspaceContextService, instantiationService, - environmentService, + uriDisplayService, fileService, configurationService ); From c7ab363b374a70eadde36ed384c5df0ab6cf21fb Mon Sep 17 00:00:00 2001 From: isidor Date: Thu, 26 Jul 2018 18:12:48 +0200 Subject: [PATCH 0177/1276] quickOpen: adopt to uri display service --- .../browser/parts/quickopen/quickOpenController.ts | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/src/vs/workbench/browser/parts/quickopen/quickOpenController.ts b/src/vs/workbench/browser/parts/quickopen/quickOpenController.ts index 24699aff23e..a63062b1035 100644 --- a/src/vs/workbench/browser/parts/quickopen/quickOpenController.ts +++ b/src/vs/workbench/browser/parts/quickopen/quickOpenController.ts @@ -21,7 +21,6 @@ import { Mode, IEntryRunContext, IAutoFocus, IQuickNavigateConfiguration, IModel import { QuickOpenEntry, QuickOpenModel, QuickOpenEntryGroup, compareEntries, QuickOpenItemAccessorClass } from 'vs/base/parts/quickopen/browser/quickOpenModel'; import { QuickOpenWidget, HideReason } from 'vs/base/parts/quickopen/browser/quickOpenWidget'; import { ContributableActionProvider } from 'vs/workbench/browser/actions'; -import * as labels from 'vs/base/common/labels'; import { ITextFileService, AutoSaveMode } from 'vs/workbench/services/textfile/common/textfiles'; import { Registry } from 'vs/platform/registry/common/platform'; import { IResourceInput } from 'vs/platform/editor/common/editor'; @@ -37,7 +36,6 @@ import * as errors from 'vs/base/common/errors'; import { IPickOpenEntry, IFilePickOpenEntry, IQuickOpenService, IShowOptions, IPickOpenItem, IStringPickOptions, ITypedPickOptions } from 'vs/platform/quickOpen/common/quickOpen'; import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; -import { IWorkspaceContextService } from 'vs/platform/workspace/common/workspace'; 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'; @@ -57,6 +55,7 @@ import { INotificationService } from 'vs/platform/notification/common/notificati import { Dimension, addClass } from 'vs/base/browser/dom'; import { IEditorService, ACTIVE_GROUP, SIDE_GROUP } from 'vs/workbench/services/editor/common/editorService'; import { IEditorGroupsService } from 'vs/workbench/services/group/common/editorGroupsService'; +import { IUriDisplayService } from 'vs/platform/uriDisplay/common/uriDisplay'; const HELP_PREFIX = '?'; @@ -1149,9 +1148,8 @@ export class EditorHistoryEntry extends EditorQuickOpenEntry { @IModeService private modeService: IModeService, @IModelService private modelService: IModelService, @ITextFileService private textFileService: ITextFileService, - @IWorkspaceContextService contextService: IWorkspaceContextService, @IConfigurationService private configurationService: IConfigurationService, - @IEnvironmentService environmentService: IEnvironmentService, + @IUriDisplayService uriDisplayService: IUriDisplayService, @IFileService fileService: IFileService ) { super(editorService); @@ -1166,8 +1164,8 @@ export class EditorHistoryEntry extends EditorQuickOpenEntry { } else { const resourceInput = input as IResourceInput; this.resource = resourceInput.resource; - this.label = labels.getBaseLabel(resourceInput.resource); - this.description = labels.getPathLabel(resources.dirname(this.resource), environmentService, contextService); + this.label = resources.basenameOrAuthority(resourceInput.resource); + this.description = uriDisplayService.getLabel(resources.dirname(this.resource), true); this.dirty = this.resource && this.textFileService.isDirty(this.resource); if (this.dirty && this.textFileService.getAutoSaveMode() === AutoSaveMode.AFTER_SHORT_DELAY) { From 5b3e00e68fbcbe8b0767c948cfe35b65a9d20ffe Mon Sep 17 00:00:00 2001 From: Rob Lourens Date: Thu, 26 Jul 2018 08:49:05 -0700 Subject: [PATCH 0178/1276] Implement "show online settings only" --- .../browser/media/settingsEditor2.css | 9 ++-- .../preferences/browser/settingsEditor2.ts | 45 +++++++++++++++++++ .../parts/preferences/browser/settingsTree.ts | 13 ++++++ .../preferences/common/preferences.ts | 1 + .../preferences/common/preferencesModels.ts | 18 +++++++- 5 files changed, 81 insertions(+), 5 deletions(-) diff --git a/src/vs/workbench/parts/preferences/browser/media/settingsEditor2.css b/src/vs/workbench/parts/preferences/browser/media/settingsEditor2.css index 410ca1bbcf3..adfaf32a2c8 100644 --- a/src/vs/workbench/parts/preferences/browser/media/settingsEditor2.css +++ b/src/vs/workbench/parts/preferences/browser/media/settingsEditor2.css @@ -113,15 +113,18 @@ background-image: url('configure-inverse.svg'); } -.vs .settings-editor.showing-modified-only > .settings-header > .settings-header-controls .settings-header-controls-right .toolbar-toggle-more::before { +.vs .settings-editor.showing-modified-only > .settings-header > .settings-header-controls .settings-header-controls-right .toolbar-toggle-more::before, +.vs .settings-editor.settings-filtered-by-tag > .settings-header > .settings-header-controls .settings-header-controls-right .toolbar-toggle-more::before { border-color : #fff; } -.vs-dark .settings-editor.showing-modified-only > .settings-header > .settings-header-controls .settings-header-controls-right .toolbar-toggle-more::before { +.vs-dark .settings-editor.showing-modified-only > .settings-header > .settings-header-controls .settings-header-controls-right .toolbar-toggle-more::before, +.vs-dark .settings-editor.settings-filtered-by-tag > .settings-header > .settings-header-controls .settings-header-controls-right .toolbar-toggle-more::before { border-color : #000; } -.settings-editor.showing-modified-only > .settings-header > .settings-header-controls .settings-header-controls-right .toolbar-toggle-more::before { +.settings-editor.showing-modified-only > .settings-header > .settings-header-controls .settings-header-controls-right .toolbar-toggle-more::before, +.settings-editor.settings-filtered-by-tag > .settings-header > .settings-header-controls .settings-header-controls-right .toolbar-toggle-more::before { content: ""; width: 6px; height: 6px; diff --git a/src/vs/workbench/parts/preferences/browser/settingsEditor2.ts b/src/vs/workbench/parts/preferences/browser/settingsEditor2.ts index 68999b878df..80eb59ea5b7 100644 --- a/src/vs/workbench/parts/preferences/browser/settingsEditor2.ts +++ b/src/vs/workbench/parts/preferences/browser/settingsEditor2.ts @@ -224,6 +224,12 @@ export class SettingsEditor2 extends BaseEditor { const actions = [ this.instantiationService.createInstance(ToggleShowModifiedOnlyAction, this, this.viewState), + this.instantiationService.createInstance( + ToggleFilterByTagAction, + localize('filterBackgroundOnlineLabel', "Show background online settings only"), + 'backgroundOnlineFeature', + this, + this.viewState), this.instantiationService.createInstance(OpenSettingsAction) ]; this.toolbar.setActions([], actions)(); @@ -408,6 +414,24 @@ export class SettingsEditor2 extends BaseEditor { }); } + toggleFilterByTag(tag: string): TPromise { + // Clear other filters + this.viewState.showConfiguredOnly = false; + + this.viewState.tagFilters = this.viewState.tagFilters || new Set(); + const wasFiltered = this.viewState.tagFilters.delete(tag); + const isFiltered = !wasFiltered; + if (isFiltered) { + this.viewState.tagFilters.add(tag); + } + + DOM.toggleClass(this.rootElement, 'settings-filtered-by-tag', isFiltered); + return this.refreshTreeAndMaintainFocus().then(() => { + this.settingsTree.setScrollPosition(0); + this.expandAll(this.settingsTree); + }); + } + private onDidChangeSetting(key: string, value: any): void { if (this.pendingSettingUpdate && this.pendingSettingUpdate.key !== key) { this.updateChangedSetting(key, value); @@ -846,3 +870,24 @@ class ToggleShowModifiedOnlyAction extends Action { return this.settingsEditor.toggleShowModifiedOnly(); } } + +class ToggleFilterByTagAction extends Action { + static readonly ID = 'settings.toggleFilterByTag'; + + get checked(): boolean { + return this.viewState.tagFilters && this.viewState.tagFilters.has(this.tag); + } + + constructor( + label: string, + private tag: string, + private settingsEditor: SettingsEditor2, + private viewState: ISettingsEditorViewState + ) { + super(ToggleFilterByTagAction.ID, label, 'toggle-filter-tag'); + } + + run(): TPromise { + return this.settingsEditor.toggleFilterByTag(this.tag); + } +} diff --git a/src/vs/workbench/parts/preferences/browser/settingsTree.ts b/src/vs/workbench/parts/preferences/browser/settingsTree.ts index 001d69bfccf..81d3410e379 100644 --- a/src/vs/workbench/parts/preferences/browser/settingsTree.ts +++ b/src/vs/workbench/parts/preferences/browser/settingsTree.ts @@ -437,6 +437,7 @@ function trimCategoryForGroup(category: string, groupId: string): string { export interface ISettingsEditorViewState { settingsTarget: SettingsTarget; showConfiguredOnly?: boolean; + tagFilters?: Set; filterToCategory?: SettingsTreeGroupElement; } @@ -1114,6 +1115,18 @@ export class SettingsTreeFilter implements IFilter { return this.groupHasConfiguredSetting(element); } + if (element instanceof SettingsTreeSettingElement && this.viewState.tagFilters && this.viewState.tagFilters.size) { + if (element.setting.tags) { + return element.setting.tags.some(tag => this.viewState.tagFilters.has(tag)); + } else { + return false; + } + } + + if (element instanceof SettingsTreeGroupElement && this.viewState.tagFilters && this.viewState.tagFilters.size) { + return element.children.some(child => this.isVisible(tree, child)); + } + return true; } diff --git a/src/vs/workbench/services/preferences/common/preferences.ts b/src/vs/workbench/services/preferences/common/preferences.ts index c3174c92663..ddfe928f57b 100644 --- a/src/vs/workbench/services/preferences/common/preferences.ts +++ b/src/vs/workbench/services/preferences/common/preferences.ts @@ -49,6 +49,7 @@ export interface ISetting { type?: string | string[]; enum?: string[]; enumDescriptions?: string[]; + tags?: string[]; } export interface IExtensionSetting extends ISetting { diff --git a/src/vs/workbench/services/preferences/common/preferencesModels.ts b/src/vs/workbench/services/preferences/common/preferencesModels.ts index bf319ad0d53..27fea8f112b 100644 --- a/src/vs/workbench/services/preferences/common/preferencesModels.ts +++ b/src/vs/workbench/services/preferences/common/preferencesModels.ts @@ -555,7 +555,20 @@ export class DefaultSettings extends Disposable { const value = prop.default; const description = (prop.description || '').split('\n'); const overrides = OVERRIDE_PROPERTY_PATTERN.test(key) ? this.parseOverrideSettings(prop.default) : []; - result.push({ key, value, description, range: null, keyRange: null, valueRange: null, descriptionRanges: [], overrides, type: prop.type, enum: prop.enum, enumDescriptions: prop.enumDescriptions }); + result.push({ + key, + value, + description, + range: null, + keyRange: null, + valueRange: null, + descriptionRanges: [], + overrides, + type: prop.type, + enum: prop.enum, + enumDescriptions: prop.enumDescriptions, + tags: prop.tags + }); } } return result; @@ -748,7 +761,8 @@ export class DefaultSettingsEditorModel extends AbstractSettingsModel implements value: setting.value, range: setting.range, overrides: [], - overrideOf: setting.overrideOf + overrideOf: setting.overrideOf, + tags: setting.tags }; } From 7e421ef110ca3a7db362d1b94648c6bfdd6f73d0 Mon Sep 17 00:00:00 2001 From: Rob Lourens Date: Thu, 26 Jul 2018 09:21:54 -0700 Subject: [PATCH 0179/1276] Settings editor - remove some 'modified' handling code, use 'tags' --- .../preferences/browser/settingsEditor2.ts | 49 +++++-------------- .../parts/preferences/browser/settingsTree.ts | 49 +++++++++---------- 2 files changed, 33 insertions(+), 65 deletions(-) diff --git a/src/vs/workbench/parts/preferences/browser/settingsEditor2.ts b/src/vs/workbench/parts/preferences/browser/settingsEditor2.ts index 80eb59ea5b7..982c1c9f709 100644 --- a/src/vs/workbench/parts/preferences/browser/settingsEditor2.ts +++ b/src/vs/workbench/parts/preferences/browser/settingsEditor2.ts @@ -32,7 +32,7 @@ import { BaseEditor } from 'vs/workbench/browser/parts/editor/baseEditor'; import { EditorOptions, IEditor } from 'vs/workbench/common/editor'; import { SearchWidget, SettingsTarget, SettingsTargetsWidget } from 'vs/workbench/parts/preferences/browser/preferencesWidgets'; import { commonlyUsedData, tocData } from 'vs/workbench/parts/preferences/browser/settingsLayout'; -import { ISettingsEditorViewState, resolveExtensionsSettings, resolveSettingsTree, SearchResultIdx, SearchResultModel, SettingsRenderer, SettingsTree, SettingsTreeElement, SettingsTreeFilter, SettingsTreeGroupElement, SettingsTreeModel, SettingsTreeSettingElement } from 'vs/workbench/parts/preferences/browser/settingsTree'; +import { ISettingsEditorViewState, resolveExtensionsSettings, resolveSettingsTree, SearchResultIdx, SearchResultModel, SettingsRenderer, SettingsTree, SettingsTreeElement, SettingsTreeFilter, SettingsTreeGroupElement, SettingsTreeModel, SettingsTreeSettingElement, MODIFIED_SETTING_TAG } from 'vs/workbench/parts/preferences/browser/settingsTree'; import { TOCDataSource, TOCRenderer, TOCTreeModel } from 'vs/workbench/parts/preferences/browser/tocTree'; import { CONTEXT_SETTINGS_EDITOR, CONTEXT_SETTINGS_FIRST_ROW_FOCUS, CONTEXT_SETTINGS_ROW_FOCUS, CONTEXT_SETTINGS_SEARCH_FOCUS, CONTEXT_TOC_ROW_FOCUS, IPreferencesSearchService, ISearchProvider } from 'vs/workbench/parts/preferences/common/preferences'; import { IPreferencesService, ISearchResult, ISettingsEditorModel } from 'vs/workbench/services/preferences/common/preferences'; @@ -223,10 +223,14 @@ export class SettingsEditor2 extends BaseEditor { }); const actions = [ - this.instantiationService.createInstance(ToggleShowModifiedOnlyAction, this, this.viewState), + this.instantiationService.createInstance(ToggleFilterByTagAction, + localize('filterModifiedLabel', "Show modified settings only"), + MODIFIED_SETTING_TAG, + this, + this.viewState), this.instantiationService.createInstance( ToggleFilterByTagAction, - localize('filterBackgroundOnlineLabel', "Show background online settings only"), + localize('filterBackgroundOnlineLabel', "Control background online features"), 'backgroundOnlineFeature', this, this.viewState), @@ -405,22 +409,11 @@ export class SettingsEditor2 extends BaseEditor { })); } - toggleShowModifiedOnly(): TPromise { - this.viewState.showConfiguredOnly = !this.viewState.showConfiguredOnly; - DOM.toggleClass(this.rootElement, 'showing-modified-only', this.viewState.showConfiguredOnly); - return this.refreshTreeAndMaintainFocus().then(() => { - this.settingsTree.setScrollPosition(0); - this.expandAll(this.settingsTree); - }); - } - toggleFilterByTag(tag: string): TPromise { - // Clear other filters - this.viewState.showConfiguredOnly = false; - - this.viewState.tagFilters = this.viewState.tagFilters || new Set(); - const wasFiltered = this.viewState.tagFilters.delete(tag); + // Reset other tags, toggle this tag + const wasFiltered = this.viewState.tagFilters && this.viewState.tagFilters.has(tag); const isFiltered = !wasFiltered; + this.viewState.tagFilters = new Set(); if (isFiltered) { this.viewState.tagFilters.add(tag); } @@ -498,7 +491,7 @@ export class SettingsEditor2 extends BaseEditor { query: this.searchWidget.getValue(), searchResults: this.searchResultModel && this.searchResultModel.getUniqueResults(), rawResults: this.searchResultModel && this.searchResultModel.getRawResults(), - showConfiguredOnly: this.viewState.showConfiguredOnly, + showConfiguredOnly: this.viewState.tagFilters && this.viewState.tagFilters.has(MODIFIED_SETTING_TAG), isReset: typeof value === 'undefined', settingsTarget: this.settingsTargetsWidget.settingsTarget as SettingsTarget }; @@ -851,26 +844,6 @@ class OpenSettingsAction extends Action { } } -class ToggleShowModifiedOnlyAction extends Action { - static readonly ID = 'settings.toggleShowModifiedOnly'; - static readonly LABEL = localize('showModifiedOnlyLabel', "Show modified settings only"); - - get checked(): boolean { - return this.viewState.showConfiguredOnly; - } - - constructor( - private settingsEditor: SettingsEditor2, - private viewState: ISettingsEditorViewState - ) { - super(ToggleShowModifiedOnlyAction.ID, ToggleShowModifiedOnlyAction.LABEL, 'show-modified-only'); - } - - run(): TPromise { - return this.settingsEditor.toggleShowModifiedOnly(); - } -} - class ToggleFilterByTagAction extends Action { static readonly ID = 'settings.toggleFilterByTag'; diff --git a/src/vs/workbench/parts/preferences/browser/settingsTree.ts b/src/vs/workbench/parts/preferences/browser/settingsTree.ts index 81d3410e379..d5fdb2a2ce2 100644 --- a/src/vs/workbench/parts/preferences/browser/settingsTree.ts +++ b/src/vs/workbench/parts/preferences/browser/settingsTree.ts @@ -40,6 +40,8 @@ import { ISearchResult, ISetting, ISettingsGroup } from 'vs/workbench/services/p const $ = DOM.$; +export const MODIFIED_SETTING_TAG = 'modified'; + export abstract class SettingsTreeElement { id: string; parent: any; // SearchResultModel or group element... TODO search should be more similar to the normal case @@ -78,6 +80,7 @@ export class SettingsTreeSettingElement extends SettingsTreeElement { */ isConfigured: boolean; + tags?: Set; overriddenScopeList: string[]; description: string; valueType: 'enum' | 'string' | 'integer' | 'number' | 'boolean' | 'exclude' | 'complex'; @@ -191,6 +194,17 @@ function createSettingsTreeSettingElement(setting: ISetting, parent: any, settin element.defaultValue = inspected.default; element.isConfigured = isConfigured; + if (isConfigured || setting.tags) { + element.tags = new Set(); + if (isConfigured) { + element.tags.add(MODIFIED_SETTING_TAG); + } + + if (setting.tags) { + setting.tags.forEach(tag => element.tags.add(tag)); + } + } + element.overriddenScopeList = overriddenScopeList; element.description = setting.description.join('\n'); @@ -436,7 +450,6 @@ function trimCategoryForGroup(category: string, groupId: string): string { export interface ISettingsEditorViewState { settingsTarget: SettingsTarget; - showConfiguredOnly?: boolean; tagFilters?: Set; filterToCategory?: SettingsTreeGroupElement; } @@ -1107,17 +1120,15 @@ export class SettingsTreeFilter implements IFilter { } } - if (element instanceof SettingsTreeSettingElement && this.viewState.showConfiguredOnly) { - return element.isConfigured; - } - - if (element instanceof SettingsTreeGroupElement && this.viewState.showConfiguredOnly) { - return this.groupHasConfiguredSetting(element); - } - if (element instanceof SettingsTreeSettingElement && this.viewState.tagFilters && this.viewState.tagFilters.size) { - if (element.setting.tags) { - return element.setting.tags.some(tag => this.viewState.tagFilters.has(tag)); + if (element.tags) { + let hasFilteredTag = false; + element.tags.forEach(tag => { + if (this.viewState.tagFilters.has(tag)) { + hasFilteredTag = true; + } + }); + return hasFilteredTag; } else { return false; } @@ -1141,22 +1152,6 @@ export class SettingsTreeFilter implements IFilter { } }); } - - private groupHasConfiguredSetting(element: SettingsTreeGroupElement): boolean { - for (let child of element.children) { - if (child instanceof SettingsTreeSettingElement) { - if (child.isConfigured) { - return true; - } - } else if (child instanceof SettingsTreeGroupElement) { - if (this.groupHasConfiguredSetting(child)) { - return true; - } - } - } - - return false; - } } export class SettingsTreeController extends WorkbenchTreeController { From 4c5c94185f872a41b78361a5cdf7c34ef0262e4d Mon Sep 17 00:00:00 2001 From: Johannes Rieken Date: Thu, 26 Jul 2018 18:43:09 +0200 Subject: [PATCH 0180/1276] move WorkspaceEdit api additions to vscode.d.ts #10659 --- src/vs/vscode.d.ts | 49 ++++++++++++++++++++++++---- src/vs/vscode.proposed.d.ts | 64 ------------------------------------- 2 files changed, 42 insertions(+), 71 deletions(-) diff --git a/src/vs/vscode.d.ts b/src/vs/vscode.d.ts index 1ef082e1c0b..85c30a83a6b 100644 --- a/src/vs/vscode.d.ts +++ b/src/vs/vscode.d.ts @@ -2707,13 +2707,15 @@ declare module 'vscode' { } /** - * A workspace edit represents textual and files changes for + * A workspace edit is a collection of textual and files changes for * multiple resources and documents. + * + * Use the [applyEdit](#workspace.applyEdit)-function to apply a workspace edit. */ export class WorkspaceEdit { /** - * The number of affected resources. + * The number of affected resources of textual or resource changes. */ readonly size: number; @@ -2744,7 +2746,8 @@ declare module 'vscode' { delete(uri: Uri, range: Range): void; /** - * Check if this edit affects the given resource. + * Check if a text edit for a resource exists. + * * @param uri A resource identifier. * @return `true` if the given resource will be touched by this edit. */ @@ -2766,6 +2769,33 @@ declare module 'vscode' { */ get(uri: Uri): TextEdit[]; + /** + * Create a regular file. + * + * @param uri Uri of the new file.. + * @param options Defines if an existing file should be overwritten or be + * ignored. When overwrite and ignoreIfExists are both set overwrite wins. + */ + createFile(uri: Uri, options?: { overwrite?: boolean, ignoreIfExists?: boolean }): void; + + /** + * Delete a file or folder. + * + * @param uri The uri of the file that is to be deleted. + */ + deleteFile(uri: Uri, options?: { recursive?: boolean, ignoreIfNotExists?: boolean }): void; + + /** + * Rename a file or folder. + * + * @param oldUri The existing file. + * @param newUri The new location. + * @param options Defines if existing files should be overwritten or be + * ignored. When overwrite and ignoreIfExists are both set overwrite wins. + */ + renameFile(oldUri: Uri, newUri: Uri, options?: { overwrite?: boolean, ignoreIfExists?: boolean }): void; + + /** * Get all text edits grouped by resource. * @@ -7173,12 +7203,17 @@ declare module 'vscode' { export function saveAll(includeUntitled?: boolean): Thenable; /** - * Make changes to one or many resources as defined by the given + * Make changes to one or many resources or create, delete, and rename resources as defined by the given * [workspace edit](#WorkspaceEdit). * - * When applying a workspace edit, the editor implements an 'all-or-nothing'-strategy, - * that means failure to load one document or make changes to one document will cause - * the edit to be rejected. + * All changes of a workspace edit are applied in the same order in which they have been added. If + * multiple textual inserts are made at the same position, these strings appear in the resulting text + * in the order the 'inserts' were made. Invalid sequences like 'delete file a' -> 'insert text in file a' + * cause failure of the operation. + * + * When applying a workspace edit that consists only of text edits an 'all-or-nothing'-strategy is used. + * A workspace edit with resource creations or deletions aborts the operation, e.g. consective edits will + * not be attempted, when a single edit fails. * * @param edit A workspace edit. * @return A thenable that resolves when the edit could be applied. diff --git a/src/vs/vscode.proposed.d.ts b/src/vs/vscode.proposed.d.ts index 908e1fdce8e..42cea59c678 100644 --- a/src/vs/vscode.proposed.d.ts +++ b/src/vs/vscode.proposed.d.ts @@ -697,70 +697,6 @@ declare module 'vscode' { //#endregion - //#region joh: https://github.com/Microsoft/vscode/issues/10659 - - /** - * A workspace edit is a collection of textual and files changes for - * multiple resources and documents. - * - * Use the [applyEdit](#workspace.applyEdit)-function to apply a workspace edit. - */ - export interface WorkspaceEdit { - - /** - * The number of affected resources of textual or resource changes. - */ - readonly size: number; - - /** - * Create a regular file. - * - * @param uri Uri of the new file.. - * @param options Defines if an existing file should be overwritten or be - * ignored. When overwrite and ignoreIfExists are both set overwrite wins. - */ - createFile(uri: Uri, options?: { overwrite?: boolean, ignoreIfExists?: boolean }): void; - - /** - * Delete a file or folder. - * - * @param uri The uri of the file that is to be deleted. - */ - deleteFile(uri: Uri, options?: { recursive?: boolean, ignoreIfNotExists?: boolean }): void; - - /** - * Rename a file or folder. - * - * @param oldUri The existing file. - * @param newUri The new location. - * @param options Defines if existing files should be overwritten or be - * ignored. When overwrite and ignoreIfExists are both set overwrite wins. - */ - renameFile(oldUri: Uri, newUri: Uri, options?: { overwrite?: boolean, ignoreIfExists?: boolean }): void; - } - - export namespace workspace { - - /** - * Make changes to one or many resources or create, delete, and rename resources. - * - * All changes of a workspace edit are applied in the same order in which they have been added. If - * multiple textual inserts are made at the same position, these strings appear in the resulting text - * in the order the 'inserts' were made. Invalid sequences like 'delete file a' -> 'insert text in file a' - * cause failure of the operation. - * - * When applying a workspace edit that consists only of text edits an 'all-or-nothing'-strategy is used. - * A workspace edit with resource creations or deletions aborts the operation, e.g. consective edits will - * not be attempted, when a single edit fails. - * - * @param edit A workspace edit. - * @return A thenable that resolves when the edit could be applied. - */ - export function applyEdit(edit: WorkspaceEdit): Thenable; - } - - //#endregion - //#region mjbvz,joh: https://github.com/Microsoft/vscode/issues/43768 export interface FileRenameEvent { readonly oldUri: Uri; From 9cc1fc914d182623009506daf36fc6141838d507 Mon Sep 17 00:00:00 2001 From: Johannes Rieken Date: Thu, 26 Jul 2018 19:10:58 +0200 Subject: [PATCH 0181/1276] fix #55163 --- .../workbench/api/node/extHostTextEditor.ts | 5 ++++ .../api/extHostTextEditor.test.ts | 28 ++++++++++++++++--- 2 files changed, 29 insertions(+), 4 deletions(-) diff --git a/src/vs/workbench/api/node/extHostTextEditor.ts b/src/vs/workbench/api/node/extHostTextEditor.ts index 0d9d7c2d9a7..eb8afcf4c06 100644 --- a/src/vs/workbench/api/node/extHostTextEditor.ts +++ b/src/vs/workbench/api/node/extHostTextEditor.ts @@ -497,6 +497,11 @@ export class ExtHostTextEditor implements vscode.TextEditor { private _applyEdit(editBuilder: TextEditorEdit): TPromise { let editData = editBuilder.finalize(); + // return when there is nothing to do + if (editData.edits.length === 0 && !editData.setEndOfLine) { + return TPromise.wrap(true); + } + // check that the edits are not overlapping (i.e. illegal) let editRanges = editData.edits.map(edit => edit.range); diff --git a/src/vs/workbench/test/electron-browser/api/extHostTextEditor.test.ts b/src/vs/workbench/test/electron-browser/api/extHostTextEditor.test.ts index ff187f60156..0c74b367c0a 100644 --- a/src/vs/workbench/test/electron-browser/api/extHostTextEditor.test.ts +++ b/src/vs/workbench/test/electron-browser/api/extHostTextEditor.test.ts @@ -6,21 +6,22 @@ import * as assert from 'assert'; import { TPromise } from 'vs/base/common/winjs.base'; -import { TextEditorLineNumbersStyle } from 'vs/workbench/api/node/extHostTypes'; +import { TextEditorLineNumbersStyle, Range } from 'vs/workbench/api/node/extHostTypes'; import { TextEditorCursorStyle } from 'vs/editor/common/config/editorOptions'; import { MainThreadTextEditorsShape, IResolvedTextEditorConfiguration, ITextEditorConfigurationUpdate } from 'vs/workbench/api/node/extHost.protocol'; import { ExtHostTextEditorOptions, ExtHostTextEditor } from 'vs/workbench/api/node/extHostTextEditor'; import { ExtHostDocumentData } from 'vs/workbench/api/node/extHostDocumentData'; import URI from 'vs/base/common/uri'; +import { mock } from 'vs/workbench/test/electron-browser/api/mock'; suite('ExtHostTextEditor', () => { let editor: ExtHostTextEditor; + let doc = new ExtHostDocumentData(undefined, URI.file(''), [ + 'aaaa bbbb+cccc abc' + ], '\n', 'text', 1, false); setup(() => { - let doc = new ExtHostDocumentData(undefined, URI.file(''), [ - 'aaaa bbbb+cccc abc' - ], '\n', 'text', 1, false); editor = new ExtHostTextEditor(null, 'fake', doc, [], { cursorStyle: 0, insertSpaces: true, lineNumbers: 1, tabSize: 4 }, [], 1); }); @@ -39,6 +40,25 @@ suite('ExtHostTextEditor', () => { assert.throws(() => editor._acceptOptions(null)); assert.throws(() => editor._acceptSelections([])); }); + + test('API [bug]: registerTextEditorCommand clears redo stack even if no edits are made #55163', async function () { + let applyCount = 0; + let editor = new ExtHostTextEditor(new class extends mock() { + $tryApplyEdits(): TPromise { + applyCount += 1; + return TPromise.wrap(true); + } + }, 'edt1', doc, [], { cursorStyle: 0, insertSpaces: true, lineNumbers: 1, tabSize: 4 }, [], 1); + + await editor.edit(edit => { }); + assert.equal(applyCount, 0); + + await editor.edit(edit => { edit.setEndOfLine(1); }); + assert.equal(applyCount, 1); + + await editor.edit(edit => { edit.delete(new Range(0, 0, 1, 1)); }); + assert.equal(applyCount, 2); + }); }); suite('ExtHostTextEditorOptions', () => { From aec78631e9db714cdb3639a194d7a45324ac9e79 Mon Sep 17 00:00:00 2001 From: Jackson Kearl Date: Thu, 26 Jul 2018 11:11:30 -0700 Subject: [PATCH 0182/1276] Renaming and pull text HTML style config out to extensions file --- ...tEditor.ts => simpleEditorWidgetConfig.ts} | 33 +------------------ .../electron-browser/breakpointWidget.ts | 6 ++-- .../parts/debug/electron-browser/repl.ts | 4 +-- .../electron-browser/extensionsViewlet.ts | 17 ++++++++-- 4 files changed, 20 insertions(+), 40 deletions(-) rename src/vs/workbench/parts/codeEditor/electron-browser/{simpleWidgetEditor.ts => simpleEditorWidgetConfig.ts} (68%) diff --git a/src/vs/workbench/parts/codeEditor/electron-browser/simpleWidgetEditor.ts b/src/vs/workbench/parts/codeEditor/electron-browser/simpleEditorWidgetConfig.ts similarity index 68% rename from src/vs/workbench/parts/codeEditor/electron-browser/simpleWidgetEditor.ts rename to src/vs/workbench/parts/codeEditor/electron-browser/simpleEditorWidgetConfig.ts index 4dece238fbd..c6f5a4eda1a 100644 --- a/src/vs/workbench/parts/codeEditor/electron-browser/simpleWidgetEditor.ts +++ b/src/vs/workbench/parts/codeEditor/electron-browser/simpleEditorWidgetConfig.ts @@ -14,7 +14,7 @@ import { SuggestController } from 'vs/editor/contrib/suggest/suggestController'; import { SnippetController2 } from 'vs/editor/contrib/snippet/snippetController2'; import { TabCompletionController } from 'vs/workbench/parts/snippets/electron-browser/tabCompletion'; -export class SimpleWidgetEditorConfig { +export class SimpleEditorWidgetConfig { public static getCodeEditorWidgetOptions(): ICodeEditorWidgetOptions { return { @@ -54,35 +54,4 @@ export class SimpleWidgetEditorConfig { } }; } - - public static getEditorAsInputBoxOptions(ariaLabel?: string): IEditorOptions { - return { - fontSize: 13, - lineHeight: 22, - wordWrap: 'off', - overviewRulerLanes: 0, - glyphMargin: false, - lineNumbers: 'off', - folding: false, - selectOnLineNumbers: false, - hideCursorInOverviewRuler: true, - selectionHighlight: false, - scrollbar: { - horizontal: 'hidden', - vertical: 'hidden' - }, - ariaLabel: ariaLabel || '', - cursorWidth: 1, - lineDecorationsWidth: 0, - overviewRulerBorder: false, - scrollBeyondLastLine: false, - renderLineHighlight: 'none', - fixedOverflowWidgets: true, - acceptSuggestionOnEnter: 'smart', - minimap: { - enabled: false - }, - fontFamily: ' -apple-system, BlinkMacSystemFont, "Segoe WPC", "Segoe UI", "HelveticaNeue-Light", "Ubuntu", "Droid Sans", sans-serif' - }; - } } diff --git a/src/vs/workbench/parts/debug/electron-browser/breakpointWidget.ts b/src/vs/workbench/parts/debug/electron-browser/breakpointWidget.ts index 1c08b53c0e0..b8ffd5ca34a 100644 --- a/src/vs/workbench/parts/debug/electron-browser/breakpointWidget.ts +++ b/src/vs/workbench/parts/debug/electron-browser/breakpointWidget.ts @@ -17,7 +17,7 @@ import { IContextViewService } from 'vs/platform/contextview/browser/contextView import { IDebugService, IBreakpoint, BreakpointWidgetContext as Context, CONTEXT_BREAKPOINT_WIDGET_VISIBLE, DEBUG_SCHEME, IDebugEditorContribution, EDITOR_CONTRIBUTION_ID, CONTEXT_IN_BREAKPOINT_WIDGET } from 'vs/workbench/parts/debug/common/debug'; import { attachSelectBoxStyler } from 'vs/platform/theme/common/styler'; import { IThemeService } from 'vs/platform/theme/common/themeService'; -import { SimpleWidgetEditorConfig } from 'vs/workbench/parts/codeEditor/electron-browser/simpleWidgetEditor'; +import { SimpleEditorWidgetConfig } from 'vs/workbench/parts/codeEditor/electron-browser/simpleEditorWidgetConfig'; import { createDecorator, IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; import { IContextKeyService } from 'vs/platform/contextkey/common/contextkey'; import { ServicesAccessor, EditorCommand, registerEditorCommand } from 'vs/editor/browser/editorExtensions'; @@ -200,8 +200,8 @@ export class BreakpointWidget extends ZoneWidget implements IPrivateBreakpointWi const scopedInstatiationService = this.instantiationService.createChild(new ServiceCollection( [IContextKeyService, scopedContextKeyService], [IPrivateBreakpointWidgetService, this])); - const options = SimpleWidgetEditorConfig.getEditorOptions(); - const codeEditorWidgetOptions = SimpleWidgetEditorConfig.getCodeEditorWidgetOptions(); + const options = SimpleEditorWidgetConfig.getEditorOptions(); + const codeEditorWidgetOptions = SimpleEditorWidgetConfig.getCodeEditorWidgetOptions(); this.input = scopedInstatiationService.createInstance(CodeEditorWidget, container, options, codeEditorWidgetOptions); CONTEXT_IN_BREAKPOINT_WIDGET.bindTo(scopedContextKeyService).set(true); const model = this.modelService.createModel('', null, uri.parse(`${DEBUG_SCHEME}:${this.editor.getId()}:breakpointinput`), true); diff --git a/src/vs/workbench/parts/debug/electron-browser/repl.ts b/src/vs/workbench/parts/debug/electron-browser/repl.ts index 521a6938e85..296b4869076 100644 --- a/src/vs/workbench/parts/debug/electron-browser/repl.ts +++ b/src/vs/workbench/parts/debug/electron-browser/repl.ts @@ -30,7 +30,7 @@ import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry'; import { IInstantiationService, createDecorator } from 'vs/platform/instantiation/common/instantiation'; import { IStorageService, StorageScope } from 'vs/platform/storage/common/storage'; import { ReplExpressionsRenderer, ReplExpressionsController, ReplExpressionsDataSource, ReplExpressionsActionProvider, ReplExpressionsAccessibilityProvider } from 'vs/workbench/parts/debug/electron-browser/replViewer'; -import { SimpleWidgetEditorConfig } from 'vs/workbench/parts/codeEditor/electron-browser/simpleWidgetEditor'; +import { SimpleEditorWidgetConfig } from 'vs/workbench/parts/codeEditor/electron-browser/simpleEditorWidgetConfig'; import { ClearReplAction } from 'vs/workbench/parts/debug/browser/debugActions'; import { Panel } from 'vs/workbench/browser/panel'; import { IPanelService } from 'vs/workbench/services/panel/common/panelService'; @@ -173,7 +173,7 @@ export class Repl extends Panel implements IPrivateReplService, IHistoryNavigati const scopedInstantiationService = this.instantiationService.createChild(new ServiceCollection( [IContextKeyService, scopedContextKeyService], [IPrivateReplService, this])); - this.replInput = scopedInstantiationService.createInstance(CodeEditorWidget, this.replInputContainer, SimpleWidgetEditorConfig.getEditorOptions(), SimpleWidgetEditorConfig.getCodeEditorWidgetOptions()); + this.replInput = scopedInstantiationService.createInstance(CodeEditorWidget, this.replInputContainer, SimpleEditorWidgetConfig.getEditorOptions(), SimpleEditorWidgetConfig.getCodeEditorWidgetOptions()); modes.SuggestRegistry.register({ scheme: DEBUG_SCHEME, pattern: '**/replinput', hasAccessToAllModels: true }, { triggerCharacters: ['.'], diff --git a/src/vs/workbench/parts/extensions/electron-browser/extensionsViewlet.ts b/src/vs/workbench/parts/extensions/electron-browser/extensionsViewlet.ts index 894e269a2f0..54cf64796f5 100644 --- a/src/vs/workbench/parts/extensions/electron-browser/extensionsViewlet.ts +++ b/src/vs/workbench/parts/extensions/electron-browser/extensionsViewlet.ts @@ -64,7 +64,8 @@ import { IModelService } from 'vs/editor/common/services/modelService'; import { Range } from 'vs/editor/common/core/range'; import { Position } from 'vs/editor/common/core/position'; import { ITextModel } from 'vs/editor/common/model'; -import { SimpleWidgetEditorConfig } from 'vs/workbench/parts/codeEditor/electron-browser/simpleWidgetEditor'; +import { SimpleEditorWidgetConfig } from 'vs/workbench/parts/codeEditor/electron-browser/simpleEditorWidgetConfig'; +import { IEditorOptions } from 'vs/editor/common/config/editorOptions'; interface SearchInputEvent extends Event { target: HTMLInputElement; @@ -340,8 +341,8 @@ export class ExtensionsViewlet extends ViewContainerViewlet implements IExtensio const header = append(this.root, $('.header')); this.monacoStyleContainer = append(header, $('.monaco-container')); this.searchBox = this.instantiationService.createInstance(CodeEditorWidget, this.monacoStyleContainer, - SimpleWidgetEditorConfig.getEditorAsInputBoxOptions(localize('searchExtensions', "Search Extensions in Marketplace")), - SimpleWidgetEditorConfig.getCodeEditorWidgetOptions()); + mixinHTMLInputStyleOptions(SimpleEditorWidgetConfig.getEditorOptions(), localize('searchExtensions', "Search Extensions in Marketplace")), + SimpleEditorWidgetConfig.getCodeEditorWidgetOptions()); this.placeholderText = append(this.monacoStyleContainer, $('.search-placeholder', null, localize('searchExtensions', "Search Extensions in Marketplace"))); @@ -667,3 +668,13 @@ export class MaliciousExtensionChecker implements IWorkbenchContribution { } } +function mixinHTMLInputStyleOptions(config: IEditorOptions, ariaLabel?: string): IEditorOptions { + config.fontSize = 13; + config.lineHeight = 22; + config.wordWrap = 'off'; + config.scrollbar.vertical = 'hidden'; + config.ariaLabel = ariaLabel || ''; + config.cursorWidth = 1; + config.fontFamily = ' -apple-system, BlinkMacSystemFont, "Segoe WPC", "Segoe UI", "HelveticaNeue-Light", "Ubuntu", "Droid Sans", sans-serif'; + return config; +} From 41df9793e0faa5b31d135e1bbe81c9468a770ba8 Mon Sep 17 00:00:00 2001 From: Miguel Solorio Date: Thu, 26 Jul 2018 11:12:12 -0700 Subject: [PATCH 0183/1276] Update opacity to meet color conrast ratio --- .../parts/preferences/browser/media/settingsEditor2.css | 7 +++---- src/vs/workbench/parts/preferences/browser/settingsTree.ts | 2 +- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/src/vs/workbench/parts/preferences/browser/media/settingsEditor2.css b/src/vs/workbench/parts/preferences/browser/media/settingsEditor2.css index 667a51eedb4..2451998bc5a 100644 --- a/src/vs/workbench/parts/preferences/browser/media/settingsEditor2.css +++ b/src/vs/workbench/parts/preferences/browser/media/settingsEditor2.css @@ -62,7 +62,7 @@ } .settings-editor > .settings-header > .settings-header-controls .settings-tabs-widget .action-label { - opacity: 0.7; + opacity: 0.9; } .settings-editor > .settings-header > .settings-header-controls .settings-tabs-widget .action-label:hover { @@ -198,11 +198,11 @@ overflow: hidden; text-overflow: ellipsis; line-height: 22px; - opacity: 0.7; + opacity: 0.9; } .settings-editor > .settings-body .settings-toc-container .monaco-tree-row.has-children > .content:before { - opacity: 0.7; + opacity: 0.9; } .settings-editor > .settings-body .settings-toc-container .monaco-tree-row.has-children.selected > .content:before { @@ -269,7 +269,6 @@ } .settings-editor > .settings-body > .settings-tree-container .setting-item .setting-item-description { - opacity: 0.9; margin-top: 3px; overflow: hidden; text-overflow: ellipsis; diff --git a/src/vs/workbench/parts/preferences/browser/settingsTree.ts b/src/vs/workbench/parts/preferences/browser/settingsTree.ts index d5fdb2a2ce2..221d1db1bac 100644 --- a/src/vs/workbench/parts/preferences/browser/settingsTree.ts +++ b/src/vs/workbench/parts/preferences/browser/settingsTree.ts @@ -1338,7 +1338,7 @@ export class SettingsTree extends NonExpandableTree { if (foregroundColor) { // Links appear inside other elements in markdown. CSS opacity acts like a mask. So we have to dynamically compute the description color to avoid // applying an opacity to the link color. - const fgWithOpacity = new Color(new RGBA(foregroundColor.rgba.r, foregroundColor.rgba.g, foregroundColor.rgba.b, .7)); + const fgWithOpacity = new Color(new RGBA(foregroundColor.rgba.r, foregroundColor.rgba.g, foregroundColor.rgba.b, .9)); collector.addRule(`.settings-editor > .settings-body > .settings-tree-container .setting-item .setting-item-description { color: ${fgWithOpacity}; }`); } From d770c8b2808a7a6ff9cdcc990572a920f06df956 Mon Sep 17 00:00:00 2001 From: Miguel Solorio Date: Thu, 26 Jul 2018 11:16:47 -0700 Subject: [PATCH 0184/1276] Update modified color to meet color contrast ratio --- src/vs/workbench/parts/preferences/browser/settingsWidgets.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vs/workbench/parts/preferences/browser/settingsWidgets.ts b/src/vs/workbench/parts/preferences/browser/settingsWidgets.ts index ac057a6d7c8..a36ca3d7a94 100644 --- a/src/vs/workbench/parts/preferences/browser/settingsWidgets.ts +++ b/src/vs/workbench/parts/preferences/browser/settingsWidgets.ts @@ -21,7 +21,7 @@ import { ICssStyleCollector, ITheme, IThemeService, registerThemingParticipant } const $ = DOM.$; export const settingsHeaderForeground = registerColor('settings.headerForeground', { light: '#444444', dark: '#e7e7e7', hc: '#ffffff' }, localize('headerForeground', "(For settings editor preview) The foreground color for a section header or active title in the editor.")); -export const modifiedItemForeground = registerColor('settings.modifiedItemForeground', { light: '#019001', dark: '#73C991', hc: '#73C991' }, localize('modifiedItemForeground', "(For settings editor preview) The foreground color for a modified setting.")); +export const modifiedItemForeground = registerColor('settings.modifiedItemForeground', { light: '#018101', dark: '#73C991', hc: '#73C991' }, localize('modifiedItemForeground', "(For settings editor preview) The foreground color for a modified setting.")); export const settingItemInactiveSelectionBorder = registerColor('settings.inactiveSelectedItemBorder', { dark: '#3F3F46', light: '#CCCEDB', hc: null }, localize('settingItemInactiveSelectionBorder', "(For settings editor preview) The color of the selected setting row border, when the settings list does not have focus.")); // Enum control colors From 9999dac54167e646ceeb15eab16ffa16a185880b Mon Sep 17 00:00:00 2001 From: Rob Lourens Date: Wed, 25 Jul 2018 16:04:20 -0700 Subject: [PATCH 0185/1276] SearchProvider - split out separate TextSearchProvider #47058 --- extensions/search-rg/src/extension.ts | 3 +- src/vs/vscode.proposed.d.ts | 39 ++++++++++++++----- src/vs/workbench/api/node/extHost.api.impl.ts | 3 ++ src/vs/workbench/api/node/extHostSearch.ts | 15 ++++++- .../api/extHostSearch.test.ts | 37 +++++++++++------- 5 files changed, 71 insertions(+), 26 deletions(-) diff --git a/extensions/search-rg/src/extension.ts b/extensions/search-rg/src/extension.ts index f999cb0cb6c..2a7baff9b32 100644 --- a/extensions/search-rg/src/extension.ts +++ b/extensions/search-rg/src/extension.ts @@ -13,12 +13,13 @@ export function activate(): void { const outputChannel = vscode.window.createOutputChannel('search-rg'); const provider = new RipgrepSearchProvider(outputChannel); vscode.workspace.registerSearchProvider('file', provider); + vscode.workspace.registerTextSearchProvider('file', provider); } } type SearchEngine = RipgrepFileSearchEngine | RipgrepTextSearchEngine; -class RipgrepSearchProvider implements vscode.SearchProvider { +class RipgrepSearchProvider implements vscode.SearchProvider, vscode.TextSearchProvider { private cachedProvider: CachedSearchProvider; private inProgress: Set = new Set(); diff --git a/src/vs/vscode.proposed.d.ts b/src/vs/vscode.proposed.d.ts index 42cea59c678..34941463e72 100644 --- a/src/vs/vscode.proposed.d.ts +++ b/src/vs/vscode.proposed.d.ts @@ -160,6 +160,25 @@ declare module 'vscode' { preview: TextSearchResultPreview; } + // interface FileIndexProvider { + // provideFileIndex(options: FileSearchOptions, token: CancellationToken): Thenable + // } + + // interface FileSearchProvider { + // provideFileSearchResults(query: FileSear, options, token): Thenable + // } + + interface TextSearchProvider { + /** + * Provide results that match the given text pattern. + * @param query The parameters for this query. + * @param options A set of options to consider while searching. + * @param progress A progress callback that must be invoked for all results. + * @param token A cancellation token. + */ + provideTextSearchResults?(query: TextSearchQuery, options: TextSearchOptions, progress: Progress, token: CancellationToken): Thenable; + } + /** * A SearchProvider provides search results for files or text in files. It can be invoked by quickopen, the search viewlet, and other extensions. */ @@ -178,15 +197,6 @@ declare module 'vscode' { * @param cacheKey The same key that was passed as `query.cacheKey`. */ clearCache?(cacheKey: string): void; - - /** - * Provide results that match the given text pattern. - * @param query The parameters for this query. - * @param options A set of options to consider while searching. - * @param progress A progress callback that must be invoked for all results. - * @param token A cancellation token. - */ - provideTextSearchResults?(query: TextSearchQuery, options: TextSearchOptions, progress: Progress, token: CancellationToken): Thenable; } /** @@ -243,6 +253,17 @@ declare module 'vscode' { */ export function registerSearchProvider(scheme: string, provider: SearchProvider): Disposable; + /** + * Register a text search provider. + * + * Only one provider can be registered per scheme. + * + * @param scheme The provider will be invoked for workspace folders that have this file scheme. + * @param provider The provider. + * @return A [disposable](#Disposable) that unregisters this provider when being disposed. + */ + export function registerTextSearchProvider(scheme: string, provider: TextSearchProvider): Disposable; + /** * Search text in files across all [workspace folders](#workspace.workspaceFolders) in the workspace. diff --git a/src/vs/workbench/api/node/extHost.api.impl.ts b/src/vs/workbench/api/node/extHost.api.impl.ts index 7f33441ca83..fefa5e6ebad 100644 --- a/src/vs/workbench/api/node/extHost.api.impl.ts +++ b/src/vs/workbench/api/node/extHost.api.impl.ts @@ -585,6 +585,9 @@ export function createApiFactory( registerSearchProvider: proposedApiFunction(extension, (scheme, provider) => { return extHostSearch.registerSearchProvider(scheme, provider); }), + registerTextSearchProvider: proposedApiFunction(extension, (scheme, provider) => { + return extHostSearch.registerTextSearchProvider(scheme, provider); + }), registerDocumentCommentProvider: proposedApiFunction(extension, (provider: vscode.DocumentCommentProvider) => { return exthostCommentProviders.registerDocumentCommentProvider(provider); }), diff --git a/src/vs/workbench/api/node/extHostSearch.ts b/src/vs/workbench/api/node/extHostSearch.ts index e7bcb39550d..dc0a664b713 100644 --- a/src/vs/workbench/api/node/extHostSearch.ts +++ b/src/vs/workbench/api/node/extHostSearch.ts @@ -25,6 +25,7 @@ export class ExtHostSearch implements ExtHostSearchShape { private readonly _proxy: MainThreadSearchShape; private readonly _searchProvider = new Map(); + private readonly _textSearchProvider = new Map(); private _handlePool: number = 0; private _fileSearchManager: FileSearchManager; @@ -51,6 +52,16 @@ export class ExtHostSearch implements ExtHostSearchShape { }); } + registerTextSearchProvider(scheme: string, provider: vscode.TextSearchProvider) { + const handle = this._handlePool++; + this._textSearchProvider.set(handle, provider); + this._proxy.$registerSearchProvider(handle, this._transformScheme(scheme)); + return toDisposable(() => { + this._searchProvider.delete(handle); + this._proxy.$unregisterProvider(handle); + }); + } + $provideFileSearchResults(handle: number, session: number, rawQuery: IRawSearchQuery): TPromise { const provider = this._searchProvider.get(handle); if (!provider.provideFileSearchResults) { @@ -74,7 +85,7 @@ export class ExtHostSearch implements ExtHostSearchShape { } $provideTextSearchResults(handle: number, session: number, pattern: IPatternInfo, rawQuery: IRawSearchQuery): TPromise { - const provider = this._searchProvider.get(handle); + const provider = this._textSearchProvider.get(handle); if (!provider.provideTextSearchResults) { return TPromise.as(undefined); } @@ -363,7 +374,7 @@ class TextSearchEngine { private resultCount = 0; private isCanceled: boolean; - constructor(private pattern: IPatternInfo, private config: ISearchQuery, private provider: vscode.SearchProvider, private _extfs: typeof extfs) { + constructor(private pattern: IPatternInfo, private config: ISearchQuery, private provider: vscode.TextSearchProvider, private _extfs: typeof extfs) { } public cancel(): void { diff --git a/src/vs/workbench/test/electron-browser/api/extHostSearch.test.ts b/src/vs/workbench/test/electron-browser/api/extHostSearch.test.ts index bad1d62b9d7..a0f9038ea06 100644 --- a/src/vs/workbench/test/electron-browser/api/extHostSearch.test.ts +++ b/src/vs/workbench/test/electron-browser/api/extHostSearch.test.ts @@ -32,6 +32,10 @@ class MockMainThreadSearch implements MainThreadSearchShape { this.lastHandle = handle; } + $registerTextSearchProvider(handle: number, scheme: string): void { + this.lastHandle = handle; + } + $unregisterProvider(handle: number): void { } @@ -53,6 +57,11 @@ class MockMainThreadSearch implements MainThreadSearchShape { let mockExtfs: Partial; suite('ExtHostSearch', () => { + async function registerTestTextSearchProvider(provider: vscode.TextSearchProvider, scheme = 'file'): Promise { + disposables.push(extHostSearch.registerTextSearchProvider(scheme, provider)); + await rpcProtocol.sync(); + } + async function registerTestSearchProvider(provider: vscode.SearchProvider, scheme = 'file'): Promise { disposables.push(extHostSearch.registerSearchProvider(scheme, provider)); await rpcProtocol.sync(); @@ -734,7 +743,7 @@ suite('ExtHostSearch', () => { } test('no results', async () => { - await registerTestSearchProvider({ + await registerTestTextSearchProvider({ provideTextSearchResults(query: vscode.TextSearchQuery, options: vscode.TextSearchOptions, progress: vscode.Progress, token: vscode.CancellationToken): Thenable { return TPromise.wrap(null); } @@ -751,7 +760,7 @@ suite('ExtHostSearch', () => { makeTextResult(rootFolderA, 'file2.ts') ]; - await registerTestSearchProvider({ + await registerTestTextSearchProvider({ provideTextSearchResults(query: vscode.TextSearchQuery, options: vscode.TextSearchOptions, progress: vscode.Progress, token: vscode.CancellationToken): Thenable { providedResults.forEach(r => progress.report(r)); return TPromise.wrap(null); @@ -764,7 +773,7 @@ suite('ExtHostSearch', () => { }); test('all provider calls get global include/excludes', async () => { - await registerTestSearchProvider({ + await registerTestTextSearchProvider({ provideTextSearchResults(query: vscode.TextSearchQuery, options: vscode.TextSearchOptions, progress: vscode.Progress, token: vscode.CancellationToken): Thenable { assert.equal(options.includes.length, 1); assert.equal(options.excludes.length, 1); @@ -793,7 +802,7 @@ suite('ExtHostSearch', () => { }); test('global/local include/excludes combined', async () => { - await registerTestSearchProvider({ + await registerTestTextSearchProvider({ provideTextSearchResults(query: vscode.TextSearchQuery, options: vscode.TextSearchOptions, progress: vscode.Progress, token: vscode.CancellationToken): Thenable { if (options.folder.toString() === rootFolderA.toString()) { assert.deepEqual(options.includes.sort(), ['*.ts', 'foo']); @@ -834,7 +843,7 @@ suite('ExtHostSearch', () => { }); test('include/excludes resolved correctly', async () => { - await registerTestSearchProvider({ + await registerTestTextSearchProvider({ provideTextSearchResults(query: vscode.TextSearchQuery, options: vscode.TextSearchOptions, progress: vscode.Progress, token: vscode.CancellationToken): Thenable { assert.deepEqual(options.includes.sort(), ['*.jsx', '*.ts']); assert.deepEqual(options.excludes.sort(), []); @@ -871,7 +880,7 @@ suite('ExtHostSearch', () => { }); test('provider fail', async () => { - await registerTestSearchProvider({ + await registerTestTextSearchProvider({ provideTextSearchResults(query: vscode.TextSearchQuery, options: vscode.TextSearchOptions, progress: vscode.Progress, token: vscode.CancellationToken): Thenable { throw new Error('Provider fail'); } @@ -902,7 +911,7 @@ suite('ExtHostSearch', () => { makeTextResult(rootFolderA, 'file1.ts') ]; - await registerTestSearchProvider({ + await registerTestTextSearchProvider({ provideTextSearchResults(query: vscode.TextSearchQuery, options: vscode.TextSearchOptions, progress: vscode.Progress, token: vscode.CancellationToken): Thenable { providedResults.forEach(r => progress.report(r)); return TPromise.wrap(null); @@ -946,7 +955,7 @@ suite('ExtHostSearch', () => { } }; - await registerTestSearchProvider({ + await registerTestTextSearchProvider({ provideTextSearchResults(query: vscode.TextSearchQuery, options: vscode.TextSearchOptions, progress: vscode.Progress, token: vscode.CancellationToken): Thenable { let reportedResults; if (options.folder.fsPath === rootFolderA.fsPath) { @@ -1010,7 +1019,7 @@ suite('ExtHostSearch', () => { makeTextResult(rootFolderA, 'file1.ts') ]; - await registerTestSearchProvider({ + await registerTestTextSearchProvider({ provideTextSearchResults(query: vscode.TextSearchQuery, options: vscode.TextSearchOptions, progress: vscode.Progress, token: vscode.CancellationToken): Thenable { providedResults.forEach(r => progress.report(r)); return TPromise.wrap(null); @@ -1040,7 +1049,7 @@ suite('ExtHostSearch', () => { ]; let wasCanceled = false; - await registerTestSearchProvider({ + await registerTestTextSearchProvider({ provideTextSearchResults(query: vscode.TextSearchQuery, options: vscode.TextSearchOptions, progress: vscode.Progress, token: vscode.CancellationToken): Thenable { token.onCancellationRequested(() => wasCanceled = true); providedResults.forEach(r => progress.report(r)); @@ -1072,7 +1081,7 @@ suite('ExtHostSearch', () => { ]; let wasCanceled = false; - await registerTestSearchProvider({ + await registerTestTextSearchProvider({ provideTextSearchResults(query: vscode.TextSearchQuery, options: vscode.TextSearchOptions, progress: vscode.Progress, token: vscode.CancellationToken): Thenable { token.onCancellationRequested(() => wasCanceled = true); providedResults.forEach(r => progress.report(r)); @@ -1103,7 +1112,7 @@ suite('ExtHostSearch', () => { ]; let wasCanceled = false; - await registerTestSearchProvider({ + await registerTestTextSearchProvider({ provideTextSearchResults(query: vscode.TextSearchQuery, options: vscode.TextSearchOptions, progress: vscode.Progress, token: vscode.CancellationToken): Thenable { token.onCancellationRequested(() => wasCanceled = true); providedResults.forEach(r => progress.report(r)); @@ -1129,7 +1138,7 @@ suite('ExtHostSearch', () => { test('multiroot max results', async () => { let cancels = 0; - await registerTestSearchProvider({ + await registerTestTextSearchProvider({ provideTextSearchResults(query: vscode.TextSearchQuery, options: vscode.TextSearchOptions, progress: vscode.Progress, token: vscode.CancellationToken): Thenable { token.onCancellationRequested(() => cancels++); return new TPromise(r => process.nextTick(r)) @@ -1166,7 +1175,7 @@ suite('ExtHostSearch', () => { makeTextResult(fancySchemeFolderA, 'file3.ts') ]; - await registerTestSearchProvider({ + await registerTestTextSearchProvider({ provideTextSearchResults(query: vscode.TextSearchQuery, options: vscode.TextSearchOptions, progress: vscode.Progress, token: vscode.CancellationToken): Thenable { providedResults.forEach(r => progress.report(r)); return TPromise.wrap(null); From d36a3d2395fe8d85d08e4c2de0612ca2b645d87c Mon Sep 17 00:00:00 2001 From: Rob Lourens Date: Wed, 25 Jul 2018 20:48:18 -0700 Subject: [PATCH 0186/1276] Search provider - implement FileIndexProvider --- .../search-rg/src/cachedSearchProvider.ts | 234 ------ extensions/search-rg/src/common/arrays.ts | 75 -- extensions/search-rg/src/common/charCode.ts | 422 ---------- extensions/search-rg/src/common/comparers.ts | 115 --- .../search-rg/src/common/fileSearchScorer.ts | 619 --------------- extensions/search-rg/src/common/filters.ts | 224 ------ extensions/search-rg/src/common/strings.ts | 143 ---- extensions/search-rg/src/extension.ts | 24 +- .../src/{common => }/normalization.ts | 0 extensions/search-rg/src/ripgrepFileSearch.ts | 7 +- src/vs/platform/search/common/search.ts | 11 +- src/vs/vscode.proposed.d.ts | 25 +- .../api/electron-browser/mainThreadSearch.ts | 27 +- src/vs/workbench/api/node/extHost.api.impl.ts | 7 +- src/vs/workbench/api/node/extHost.protocol.ts | 4 +- .../api/node/extHostSearch.fileIndex.ts | 728 ++++++++++++++++++ src/vs/workbench/api/node/extHostSearch.ts | 172 +---- .../services/search/node/searchService.ts | 89 ++- .../api/extHostSearch.test.ts | 42 +- 19 files changed, 899 insertions(+), 2069 deletions(-) delete mode 100644 extensions/search-rg/src/cachedSearchProvider.ts delete mode 100644 extensions/search-rg/src/common/arrays.ts delete mode 100644 extensions/search-rg/src/common/charCode.ts delete mode 100644 extensions/search-rg/src/common/comparers.ts delete mode 100644 extensions/search-rg/src/common/fileSearchScorer.ts delete mode 100644 extensions/search-rg/src/common/filters.ts delete mode 100644 extensions/search-rg/src/common/strings.ts rename extensions/search-rg/src/{common => }/normalization.ts (100%) create mode 100644 src/vs/workbench/api/node/extHostSearch.fileIndex.ts diff --git a/extensions/search-rg/src/cachedSearchProvider.ts b/extensions/search-rg/src/cachedSearchProvider.ts deleted file mode 100644 index ec28b6b6a81..00000000000 --- a/extensions/search-rg/src/cachedSearchProvider.ts +++ /dev/null @@ -1,234 +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 path from 'path'; -import * as vscode from 'vscode'; -import * as arrays from './common/arrays'; -import { compareItemsByScore, IItemAccessor, prepareQuery, ScorerCache } from './common/fileSearchScorer'; -import * as strings from './common/strings'; -import { joinPath } from './utils'; - -interface IProviderArgs { - query: vscode.FileSearchQuery; - options: vscode.FileSearchOptions; - progress: vscode.Progress; - token: vscode.CancellationToken; -} - -export interface IInternalFileSearchProvider { - provideFileSearchResults(options: vscode.FileSearchOptions, progress: vscode.Progress, token: vscode.CancellationToken): Thenable; -} - -export class CachedSearchProvider { - - private static readonly BATCH_SIZE = 512; - - private caches: { [cacheKey: string]: Cache; } = Object.create(null); - - provideFileSearchResults(provider: IInternalFileSearchProvider, query: vscode.FileSearchQuery, options: vscode.FileSearchOptions, progress: vscode.Progress, token: vscode.CancellationToken): Thenable { - const onResult = (result: IInternalFileMatch) => { - progress.report(joinPath(options.folder, result.relativePath)); - }; - - const providerArgs: IProviderArgs = { - query, options, progress, token - }; - - let sortedSearch = this.trySortedSearchFromCache(providerArgs, onResult); - if (!sortedSearch) { - const engineOpts = options.maxResults ? - { - ...options, - ...{ maxResults: 1e9 } - } : - options; - providerArgs.options = engineOpts; - - sortedSearch = this.doSortedSearch(providerArgs, provider); - } - - return sortedSearch.then(rawMatches => { - rawMatches.forEach(onResult); - }); - } - - private doSortedSearch(args: IProviderArgs, provider: IInternalFileSearchProvider): Promise { - const allResultsPromise = new Promise((c, e) => { - const results: IInternalFileMatch[] = []; - const onResult = (progress: IInternalFileMatch[]) => results.push(...progress); - - // TODO@roblou set maxResult = null - this.doSearch(args, provider, onResult, CachedSearchProvider.BATCH_SIZE) - .then(() => c(results), e); - }); - - let cache: Cache; - if (args.query.cacheKey) { - cache = this.getOrCreateCache(args.query.cacheKey); // TODO include folder in cache key - cache.resultsToSearchCache[args.query.pattern] = { finished: allResultsPromise }; - allResultsPromise.then(null, err => { - delete cache.resultsToSearchCache[args.query.pattern]; - }); - } - - return allResultsPromise.then(results => { - // TODO@roblou quickopen results are not scored until the first keypress - if (args.query.pattern) { - const scorerCache: ScorerCache = cache ? cache.scorerCache : Object.create(null); - return this.sortResults(args, results, scorerCache); - } else { - return results; - } - }); - } - - private getOrCreateCache(cacheKey: string): Cache { - const existing = this.caches[cacheKey]; - if (existing) { - return existing; - } - return this.caches[cacheKey] = new Cache(); - } - - private trySortedSearchFromCache(args: IProviderArgs, onResult: (result: IInternalFileMatch) => void): Promise { - const cache = args.query.cacheKey && this.caches[args.query.cacheKey]; - if (!cache) { - return undefined; - } - - const cached = this.getResultsFromCache(cache, args.query.pattern, onResult); - if (cached) { - return cached.then((results) => this.sortResults(args, results, cache.scorerCache)); - } - - return undefined; - } - - private sortResults(args: IProviderArgs, results: IInternalFileMatch[], scorerCache: ScorerCache): Promise { - // we use the same compare function that is used later when showing the results using fuzzy scoring - // this is very important because we are also limiting the number of results by config.maxResults - // and as such we want the top items to be included in this result set if the number of items - // exceeds config.maxResults. - const preparedQuery = prepareQuery(args.query.pattern); - const compare = (matchA: IInternalFileMatch, matchB: IInternalFileMatch) => compareItemsByScore(matchA, matchB, preparedQuery, true, FileMatchItemAccessor, scorerCache); - - return arrays.topAsync(results, compare, args.options.maxResults || 0, 10000); - } - - private getResultsFromCache(cache: Cache, searchValue: string, onResult: (results: IInternalFileMatch) => void): Promise { - // Find cache entries by prefix of search value - const hasPathSep = searchValue.indexOf(path.sep) >= 0; - let cached: CacheEntry; - let wasResolved: boolean; - for (let previousSearch in cache.resultsToSearchCache) { - // If we narrow down, we might be able to reuse the cached results - if (searchValue.startsWith(previousSearch)) { - if (hasPathSep && previousSearch.indexOf(path.sep) < 0) { - continue; // since a path character widens the search for potential more matches, require it in previous search too - } - - const c = cache.resultsToSearchCache[previousSearch]; - c.finished.then(() => { wasResolved = false; }); - cached = c; - wasResolved = true; - break; - } - } - - if (!cached) { - return null; - } - - return new Promise((c, e) => { - cached.finished.then(cachedEntries => { - const cacheFilterStartTime = Date.now(); - - // Pattern match on results - let results: IInternalFileMatch[] = []; - const normalizedSearchValueLowercase = strings.stripWildcards(searchValue).toLowerCase(); - for (let i = 0; i < cachedEntries.length; i++) { - let entry = cachedEntries[i]; - - // Check if this entry is a match for the search value - if (!strings.fuzzyContains(entry.relativePath, normalizedSearchValueLowercase)) { - continue; - } - - results.push(entry); - } - - c(results); - }, e); - }); - } - - private doSearch(args: IProviderArgs, provider: IInternalFileSearchProvider, onResult: (result: IInternalFileMatch[]) => void, batchSize: number): Promise { - return new Promise((c, e) => { - let batch: IInternalFileMatch[] = []; - const onProviderResult = (match: string) => { - if (match) { - const internalMatch: IInternalFileMatch = { - relativePath: match, - basename: path.basename(match) - }; - - batch.push(internalMatch); - if (batchSize > 0 && batch.length >= batchSize) { - onResult(batch); - batch = []; - } - } - }; - - provider.provideFileSearchResults(args.options, { report: onProviderResult }, args.token).then(() => { - if (batch.length) { - onResult(batch); - } - - c(); - }, error => { - if (batch.length) { - onResult(batch); - } - - e(error); - }); - }); - } - - public clearCache(cacheKey: string): Promise { - delete this.caches[cacheKey]; - return Promise.resolve(undefined); - } -} - -interface IInternalFileMatch { - relativePath?: string; // Not present for extraFiles or absolute path matches - basename: string; -} - -interface CacheEntry { - finished: Promise; -} - -class Cache { - public resultsToSearchCache: { [searchValue: string]: CacheEntry } = Object.create(null); - public scorerCache: ScorerCache = Object.create(null); -} - -const FileMatchItemAccessor = new class implements IItemAccessor { - - public getItemLabel(match: IInternalFileMatch): string { - return match.basename; // e.g. myFile.txt - } - - public getItemDescription(match: IInternalFileMatch): string { - return match.relativePath.substr(0, match.relativePath.length - match.basename.length - 1); // e.g. some/path/to/file - } - - public getItemPath(match: IInternalFileMatch): string { - return match.relativePath; // e.g. some/path/to/file/myFile.txt - } -}; diff --git a/extensions/search-rg/src/common/arrays.ts b/extensions/search-rg/src/common/arrays.ts deleted file mode 100644 index d06d185dfa5..00000000000 --- a/extensions/search-rg/src/common/arrays.ts +++ /dev/null @@ -1,75 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the MIT License. See License.txt in the project root for license information. - *--------------------------------------------------------------------------------------------*/ - -/** - * Asynchronous variant of `top()` allowing for splitting up work in batches between which the event loop can run. - * - * Returns the top N elements from the array. - * - * Faster than sorting the entire array when the array is a lot larger than N. - * - * @param array The unsorted array. - * @param compare A sort function for the elements. - * @param n The number of elements to return. - * @param batch The number of elements to examine before yielding to the event loop. - * @return The first n elemnts from array when sorted with compare. - */ -export function topAsync(array: T[], compare: (a: T, b: T) => number, n: number, batch: number): Promise { - // TODO@roblou cancellation - - if (n === 0) { - return Promise.resolve([]); - } - let canceled = false; - return new Promise((resolve, reject) => { - (async () => { - const o = array.length; - const result = array.slice(0, n).sort(compare); - for (let i = n, m = Math.min(n + batch, o); i < o; i = m, m = Math.min(m + batch, o)) { - if (i > n) { - await new Promise(resolve => setTimeout(resolve, 0)); // nextTick() would starve I/O. - } - if (canceled) { - throw new Error('canceled'); - } - topStep(array, compare, result, i, m); - } - return result; - })() - .then(resolve, reject); - }); -} - -function topStep(array: T[], compare: (a: T, b: T) => number, result: T[], i: number, m: number): void { - for (const n = result.length; i < m; i++) { - const element = array[i]; - if (compare(element, result[n - 1]) < 0) { - result.pop(); - const j = findFirstInSorted(result, e => compare(element, e) < 0); - result.splice(j, 0, element); - } - } -} - -/** - * Takes a sorted array and a function p. The array is sorted in such a way that all elements where p(x) is false - * are located before all elements where p(x) is true. - * @returns the least x for which p(x) is true or array.length if no element fullfills the given function. - */ -export function findFirstInSorted(array: T[], p: (x: T) => boolean): number { - let low = 0, high = array.length; - if (high === 0) { - return 0; // no children - } - while (low < high) { - let mid = Math.floor((low + high) / 2); - if (p(array[mid])) { - high = mid; - } else { - low = mid + 1; - } - } - return low; -} diff --git a/extensions/search-rg/src/common/charCode.ts b/extensions/search-rg/src/common/charCode.ts deleted file mode 100644 index dd1bc58f80b..00000000000 --- a/extensions/search-rg/src/common/charCode.ts +++ /dev/null @@ -1,422 +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'; - -// Names from https://blog.codinghorror.com/ascii-pronunciation-rules-for-programmers/ - -/** - * An inlined enum containing useful character codes (to be used with String.charCodeAt). - * Please leave the const keyword such that it gets inlined when compiled to JavaScript! - */ -export const enum CharCode { - Null = 0, - /** - * The `\t` character. - */ - Tab = 9, - /** - * The `\n` character. - */ - LineFeed = 10, - /** - * The `\r` character. - */ - CarriageReturn = 13, - Space = 32, - /** - * The `!` character. - */ - ExclamationMark = 33, - /** - * The `"` character. - */ - DoubleQuote = 34, - /** - * The `#` character. - */ - Hash = 35, - /** - * The `$` character. - */ - DollarSign = 36, - /** - * The `%` character. - */ - PercentSign = 37, - /** - * The `&` character. - */ - Ampersand = 38, - /** - * The `'` character. - */ - SingleQuote = 39, - /** - * The `(` character. - */ - OpenParen = 40, - /** - * The `)` character. - */ - CloseParen = 41, - /** - * The `*` character. - */ - Asterisk = 42, - /** - * The `+` character. - */ - Plus = 43, - /** - * The `,` character. - */ - Comma = 44, - /** - * The `-` character. - */ - Dash = 45, - /** - * The `.` character. - */ - Period = 46, - /** - * The `/` character. - */ - Slash = 47, - - Digit0 = 48, - Digit1 = 49, - Digit2 = 50, - Digit3 = 51, - Digit4 = 52, - Digit5 = 53, - Digit6 = 54, - Digit7 = 55, - Digit8 = 56, - Digit9 = 57, - - /** - * The `:` character. - */ - Colon = 58, - /** - * The `;` character. - */ - Semicolon = 59, - /** - * The `<` character. - */ - LessThan = 60, - /** - * The `=` character. - */ - Equals = 61, - /** - * The `>` character. - */ - GreaterThan = 62, - /** - * The `?` character. - */ - QuestionMark = 63, - /** - * The `@` character. - */ - AtSign = 64, - - A = 65, - B = 66, - C = 67, - D = 68, - E = 69, - F = 70, - G = 71, - H = 72, - I = 73, - J = 74, - K = 75, - L = 76, - M = 77, - N = 78, - O = 79, - P = 80, - Q = 81, - R = 82, - S = 83, - T = 84, - U = 85, - V = 86, - W = 87, - X = 88, - Y = 89, - Z = 90, - - /** - * The `[` character. - */ - OpenSquareBracket = 91, - /** - * The `\` character. - */ - Backslash = 92, - /** - * The `]` character. - */ - CloseSquareBracket = 93, - /** - * The `^` character. - */ - Caret = 94, - /** - * The `_` character. - */ - Underline = 95, - /** - * The ``(`)`` character. - */ - BackTick = 96, - - a = 97, - b = 98, - c = 99, - d = 100, - e = 101, - f = 102, - g = 103, - h = 104, - i = 105, - j = 106, - k = 107, - l = 108, - m = 109, - n = 110, - o = 111, - p = 112, - q = 113, - r = 114, - s = 115, - t = 116, - u = 117, - v = 118, - w = 119, - x = 120, - y = 121, - z = 122, - - /** - * The `{` character. - */ - OpenCurlyBrace = 123, - /** - * The `|` character. - */ - Pipe = 124, - /** - * The `}` character. - */ - CloseCurlyBrace = 125, - /** - * The `~` character. - */ - Tilde = 126, - - U_Combining_Grave_Accent = 0x0300, // U+0300 Combining Grave Accent - U_Combining_Acute_Accent = 0x0301, // U+0301 Combining Acute Accent - U_Combining_Circumflex_Accent = 0x0302, // U+0302 Combining Circumflex Accent - U_Combining_Tilde = 0x0303, // U+0303 Combining Tilde - U_Combining_Macron = 0x0304, // U+0304 Combining Macron - U_Combining_Overline = 0x0305, // U+0305 Combining Overline - U_Combining_Breve = 0x0306, // U+0306 Combining Breve - U_Combining_Dot_Above = 0x0307, // U+0307 Combining Dot Above - U_Combining_Diaeresis = 0x0308, // U+0308 Combining Diaeresis - U_Combining_Hook_Above = 0x0309, // U+0309 Combining Hook Above - U_Combining_Ring_Above = 0x030A, // U+030A Combining Ring Above - U_Combining_Double_Acute_Accent = 0x030B, // U+030B Combining Double Acute Accent - U_Combining_Caron = 0x030C, // U+030C Combining Caron - U_Combining_Vertical_Line_Above = 0x030D, // U+030D Combining Vertical Line Above - U_Combining_Double_Vertical_Line_Above = 0x030E, // U+030E Combining Double Vertical Line Above - U_Combining_Double_Grave_Accent = 0x030F, // U+030F Combining Double Grave Accent - U_Combining_Candrabindu = 0x0310, // U+0310 Combining Candrabindu - U_Combining_Inverted_Breve = 0x0311, // U+0311 Combining Inverted Breve - U_Combining_Turned_Comma_Above = 0x0312, // U+0312 Combining Turned Comma Above - U_Combining_Comma_Above = 0x0313, // U+0313 Combining Comma Above - U_Combining_Reversed_Comma_Above = 0x0314, // U+0314 Combining Reversed Comma Above - U_Combining_Comma_Above_Right = 0x0315, // U+0315 Combining Comma Above Right - U_Combining_Grave_Accent_Below = 0x0316, // U+0316 Combining Grave Accent Below - U_Combining_Acute_Accent_Below = 0x0317, // U+0317 Combining Acute Accent Below - U_Combining_Left_Tack_Below = 0x0318, // U+0318 Combining Left Tack Below - U_Combining_Right_Tack_Below = 0x0319, // U+0319 Combining Right Tack Below - U_Combining_Left_Angle_Above = 0x031A, // U+031A Combining Left Angle Above - U_Combining_Horn = 0x031B, // U+031B Combining Horn - U_Combining_Left_Half_Ring_Below = 0x031C, // U+031C Combining Left Half Ring Below - U_Combining_Up_Tack_Below = 0x031D, // U+031D Combining Up Tack Below - U_Combining_Down_Tack_Below = 0x031E, // U+031E Combining Down Tack Below - U_Combining_Plus_Sign_Below = 0x031F, // U+031F Combining Plus Sign Below - U_Combining_Minus_Sign_Below = 0x0320, // U+0320 Combining Minus Sign Below - U_Combining_Palatalized_Hook_Below = 0x0321, // U+0321 Combining Palatalized Hook Below - U_Combining_Retroflex_Hook_Below = 0x0322, // U+0322 Combining Retroflex Hook Below - U_Combining_Dot_Below = 0x0323, // U+0323 Combining Dot Below - U_Combining_Diaeresis_Below = 0x0324, // U+0324 Combining Diaeresis Below - U_Combining_Ring_Below = 0x0325, // U+0325 Combining Ring Below - U_Combining_Comma_Below = 0x0326, // U+0326 Combining Comma Below - U_Combining_Cedilla = 0x0327, // U+0327 Combining Cedilla - U_Combining_Ogonek = 0x0328, // U+0328 Combining Ogonek - U_Combining_Vertical_Line_Below = 0x0329, // U+0329 Combining Vertical Line Below - U_Combining_Bridge_Below = 0x032A, // U+032A Combining Bridge Below - U_Combining_Inverted_Double_Arch_Below = 0x032B, // U+032B Combining Inverted Double Arch Below - U_Combining_Caron_Below = 0x032C, // U+032C Combining Caron Below - U_Combining_Circumflex_Accent_Below = 0x032D, // U+032D Combining Circumflex Accent Below - U_Combining_Breve_Below = 0x032E, // U+032E Combining Breve Below - U_Combining_Inverted_Breve_Below = 0x032F, // U+032F Combining Inverted Breve Below - U_Combining_Tilde_Below = 0x0330, // U+0330 Combining Tilde Below - U_Combining_Macron_Below = 0x0331, // U+0331 Combining Macron Below - U_Combining_Low_Line = 0x0332, // U+0332 Combining Low Line - U_Combining_Double_Low_Line = 0x0333, // U+0333 Combining Double Low Line - U_Combining_Tilde_Overlay = 0x0334, // U+0334 Combining Tilde Overlay - U_Combining_Short_Stroke_Overlay = 0x0335, // U+0335 Combining Short Stroke Overlay - U_Combining_Long_Stroke_Overlay = 0x0336, // U+0336 Combining Long Stroke Overlay - U_Combining_Short_Solidus_Overlay = 0x0337, // U+0337 Combining Short Solidus Overlay - U_Combining_Long_Solidus_Overlay = 0x0338, // U+0338 Combining Long Solidus Overlay - U_Combining_Right_Half_Ring_Below = 0x0339, // U+0339 Combining Right Half Ring Below - U_Combining_Inverted_Bridge_Below = 0x033A, // U+033A Combining Inverted Bridge Below - U_Combining_Square_Below = 0x033B, // U+033B Combining Square Below - U_Combining_Seagull_Below = 0x033C, // U+033C Combining Seagull Below - U_Combining_X_Above = 0x033D, // U+033D Combining X Above - U_Combining_Vertical_Tilde = 0x033E, // U+033E Combining Vertical Tilde - U_Combining_Double_Overline = 0x033F, // U+033F Combining Double Overline - U_Combining_Grave_Tone_Mark = 0x0340, // U+0340 Combining Grave Tone Mark - U_Combining_Acute_Tone_Mark = 0x0341, // U+0341 Combining Acute Tone Mark - U_Combining_Greek_Perispomeni = 0x0342, // U+0342 Combining Greek Perispomeni - U_Combining_Greek_Koronis = 0x0343, // U+0343 Combining Greek Koronis - U_Combining_Greek_Dialytika_Tonos = 0x0344, // U+0344 Combining Greek Dialytika Tonos - U_Combining_Greek_Ypogegrammeni = 0x0345, // U+0345 Combining Greek Ypogegrammeni - U_Combining_Bridge_Above = 0x0346, // U+0346 Combining Bridge Above - U_Combining_Equals_Sign_Below = 0x0347, // U+0347 Combining Equals Sign Below - U_Combining_Double_Vertical_Line_Below = 0x0348, // U+0348 Combining Double Vertical Line Below - U_Combining_Left_Angle_Below = 0x0349, // U+0349 Combining Left Angle Below - U_Combining_Not_Tilde_Above = 0x034A, // U+034A Combining Not Tilde Above - U_Combining_Homothetic_Above = 0x034B, // U+034B Combining Homothetic Above - U_Combining_Almost_Equal_To_Above = 0x034C, // U+034C Combining Almost Equal To Above - U_Combining_Left_Right_Arrow_Below = 0x034D, // U+034D Combining Left Right Arrow Below - U_Combining_Upwards_Arrow_Below = 0x034E, // U+034E Combining Upwards Arrow Below - U_Combining_Grapheme_Joiner = 0x034F, // U+034F Combining Grapheme Joiner - U_Combining_Right_Arrowhead_Above = 0x0350, // U+0350 Combining Right Arrowhead Above - U_Combining_Left_Half_Ring_Above = 0x0351, // U+0351 Combining Left Half Ring Above - U_Combining_Fermata = 0x0352, // U+0352 Combining Fermata - U_Combining_X_Below = 0x0353, // U+0353 Combining X Below - U_Combining_Left_Arrowhead_Below = 0x0354, // U+0354 Combining Left Arrowhead Below - U_Combining_Right_Arrowhead_Below = 0x0355, // U+0355 Combining Right Arrowhead Below - U_Combining_Right_Arrowhead_And_Up_Arrowhead_Below = 0x0356, // U+0356 Combining Right Arrowhead And Up Arrowhead Below - U_Combining_Right_Half_Ring_Above = 0x0357, // U+0357 Combining Right Half Ring Above - U_Combining_Dot_Above_Right = 0x0358, // U+0358 Combining Dot Above Right - U_Combining_Asterisk_Below = 0x0359, // U+0359 Combining Asterisk Below - U_Combining_Double_Ring_Below = 0x035A, // U+035A Combining Double Ring Below - U_Combining_Zigzag_Above = 0x035B, // U+035B Combining Zigzag Above - U_Combining_Double_Breve_Below = 0x035C, // U+035C Combining Double Breve Below - U_Combining_Double_Breve = 0x035D, // U+035D Combining Double Breve - U_Combining_Double_Macron = 0x035E, // U+035E Combining Double Macron - U_Combining_Double_Macron_Below = 0x035F, // U+035F Combining Double Macron Below - U_Combining_Double_Tilde = 0x0360, // U+0360 Combining Double Tilde - U_Combining_Double_Inverted_Breve = 0x0361, // U+0361 Combining Double Inverted Breve - U_Combining_Double_Rightwards_Arrow_Below = 0x0362, // U+0362 Combining Double Rightwards Arrow Below - U_Combining_Latin_Small_Letter_A = 0x0363, // U+0363 Combining Latin Small Letter A - U_Combining_Latin_Small_Letter_E = 0x0364, // U+0364 Combining Latin Small Letter E - U_Combining_Latin_Small_Letter_I = 0x0365, // U+0365 Combining Latin Small Letter I - U_Combining_Latin_Small_Letter_O = 0x0366, // U+0366 Combining Latin Small Letter O - U_Combining_Latin_Small_Letter_U = 0x0367, // U+0367 Combining Latin Small Letter U - U_Combining_Latin_Small_Letter_C = 0x0368, // U+0368 Combining Latin Small Letter C - U_Combining_Latin_Small_Letter_D = 0x0369, // U+0369 Combining Latin Small Letter D - U_Combining_Latin_Small_Letter_H = 0x036A, // U+036A Combining Latin Small Letter H - U_Combining_Latin_Small_Letter_M = 0x036B, // U+036B Combining Latin Small Letter M - U_Combining_Latin_Small_Letter_R = 0x036C, // U+036C Combining Latin Small Letter R - U_Combining_Latin_Small_Letter_T = 0x036D, // U+036D Combining Latin Small Letter T - U_Combining_Latin_Small_Letter_V = 0x036E, // U+036E Combining Latin Small Letter V - U_Combining_Latin_Small_Letter_X = 0x036F, // U+036F Combining Latin Small Letter X - - /** - * Unicode Character 'LINE SEPARATOR' (U+2028) - * http://www.fileformat.info/info/unicode/char/2028/index.htm - */ - LINE_SEPARATOR_2028 = 8232, - - // http://www.fileformat.info/info/unicode/category/Sk/list.htm - U_CIRCUMFLEX = 0x005E, // U+005E CIRCUMFLEX - U_GRAVE_ACCENT = 0x0060, // U+0060 GRAVE ACCENT - U_DIAERESIS = 0x00A8, // U+00A8 DIAERESIS - U_MACRON = 0x00AF, // U+00AF MACRON - U_ACUTE_ACCENT = 0x00B4, // U+00B4 ACUTE ACCENT - U_CEDILLA = 0x00B8, // U+00B8 CEDILLA - U_MODIFIER_LETTER_LEFT_ARROWHEAD = 0x02C2, // U+02C2 MODIFIER LETTER LEFT ARROWHEAD - U_MODIFIER_LETTER_RIGHT_ARROWHEAD = 0x02C3, // U+02C3 MODIFIER LETTER RIGHT ARROWHEAD - U_MODIFIER_LETTER_UP_ARROWHEAD = 0x02C4, // U+02C4 MODIFIER LETTER UP ARROWHEAD - U_MODIFIER_LETTER_DOWN_ARROWHEAD = 0x02C5, // U+02C5 MODIFIER LETTER DOWN ARROWHEAD - U_MODIFIER_LETTER_CENTRED_RIGHT_HALF_RING = 0x02D2, // U+02D2 MODIFIER LETTER CENTRED RIGHT HALF RING - U_MODIFIER_LETTER_CENTRED_LEFT_HALF_RING = 0x02D3, // U+02D3 MODIFIER LETTER CENTRED LEFT HALF RING - U_MODIFIER_LETTER_UP_TACK = 0x02D4, // U+02D4 MODIFIER LETTER UP TACK - U_MODIFIER_LETTER_DOWN_TACK = 0x02D5, // U+02D5 MODIFIER LETTER DOWN TACK - U_MODIFIER_LETTER_PLUS_SIGN = 0x02D6, // U+02D6 MODIFIER LETTER PLUS SIGN - U_MODIFIER_LETTER_MINUS_SIGN = 0x02D7, // U+02D7 MODIFIER LETTER MINUS SIGN - U_BREVE = 0x02D8, // U+02D8 BREVE - U_DOT_ABOVE = 0x02D9, // U+02D9 DOT ABOVE - U_RING_ABOVE = 0x02DA, // U+02DA RING ABOVE - U_OGONEK = 0x02DB, // U+02DB OGONEK - U_SMALL_TILDE = 0x02DC, // U+02DC SMALL TILDE - U_DOUBLE_ACUTE_ACCENT = 0x02DD, // U+02DD DOUBLE ACUTE ACCENT - U_MODIFIER_LETTER_RHOTIC_HOOK = 0x02DE, // U+02DE MODIFIER LETTER RHOTIC HOOK - U_MODIFIER_LETTER_CROSS_ACCENT = 0x02DF, // U+02DF MODIFIER LETTER CROSS ACCENT - U_MODIFIER_LETTER_EXTRA_HIGH_TONE_BAR = 0x02E5, // U+02E5 MODIFIER LETTER EXTRA-HIGH TONE BAR - U_MODIFIER_LETTER_HIGH_TONE_BAR = 0x02E6, // U+02E6 MODIFIER LETTER HIGH TONE BAR - U_MODIFIER_LETTER_MID_TONE_BAR = 0x02E7, // U+02E7 MODIFIER LETTER MID TONE BAR - U_MODIFIER_LETTER_LOW_TONE_BAR = 0x02E8, // U+02E8 MODIFIER LETTER LOW TONE BAR - U_MODIFIER_LETTER_EXTRA_LOW_TONE_BAR = 0x02E9, // U+02E9 MODIFIER LETTER EXTRA-LOW TONE BAR - U_MODIFIER_LETTER_YIN_DEPARTING_TONE_MARK = 0x02EA, // U+02EA MODIFIER LETTER YIN DEPARTING TONE MARK - U_MODIFIER_LETTER_YANG_DEPARTING_TONE_MARK = 0x02EB, // U+02EB MODIFIER LETTER YANG DEPARTING TONE MARK - U_MODIFIER_LETTER_UNASPIRATED = 0x02ED, // U+02ED MODIFIER LETTER UNASPIRATED - U_MODIFIER_LETTER_LOW_DOWN_ARROWHEAD = 0x02EF, // U+02EF MODIFIER LETTER LOW DOWN ARROWHEAD - U_MODIFIER_LETTER_LOW_UP_ARROWHEAD = 0x02F0, // U+02F0 MODIFIER LETTER LOW UP ARROWHEAD - U_MODIFIER_LETTER_LOW_LEFT_ARROWHEAD = 0x02F1, // U+02F1 MODIFIER LETTER LOW LEFT ARROWHEAD - U_MODIFIER_LETTER_LOW_RIGHT_ARROWHEAD = 0x02F2, // U+02F2 MODIFIER LETTER LOW RIGHT ARROWHEAD - U_MODIFIER_LETTER_LOW_RING = 0x02F3, // U+02F3 MODIFIER LETTER LOW RING - U_MODIFIER_LETTER_MIDDLE_GRAVE_ACCENT = 0x02F4, // U+02F4 MODIFIER LETTER MIDDLE GRAVE ACCENT - U_MODIFIER_LETTER_MIDDLE_DOUBLE_GRAVE_ACCENT = 0x02F5, // U+02F5 MODIFIER LETTER MIDDLE DOUBLE GRAVE ACCENT - U_MODIFIER_LETTER_MIDDLE_DOUBLE_ACUTE_ACCENT = 0x02F6, // U+02F6 MODIFIER LETTER MIDDLE DOUBLE ACUTE ACCENT - U_MODIFIER_LETTER_LOW_TILDE = 0x02F7, // U+02F7 MODIFIER LETTER LOW TILDE - U_MODIFIER_LETTER_RAISED_COLON = 0x02F8, // U+02F8 MODIFIER LETTER RAISED COLON - U_MODIFIER_LETTER_BEGIN_HIGH_TONE = 0x02F9, // U+02F9 MODIFIER LETTER BEGIN HIGH TONE - U_MODIFIER_LETTER_END_HIGH_TONE = 0x02FA, // U+02FA MODIFIER LETTER END HIGH TONE - U_MODIFIER_LETTER_BEGIN_LOW_TONE = 0x02FB, // U+02FB MODIFIER LETTER BEGIN LOW TONE - U_MODIFIER_LETTER_END_LOW_TONE = 0x02FC, // U+02FC MODIFIER LETTER END LOW TONE - U_MODIFIER_LETTER_SHELF = 0x02FD, // U+02FD MODIFIER LETTER SHELF - U_MODIFIER_LETTER_OPEN_SHELF = 0x02FE, // U+02FE MODIFIER LETTER OPEN SHELF - U_MODIFIER_LETTER_LOW_LEFT_ARROW = 0x02FF, // U+02FF MODIFIER LETTER LOW LEFT ARROW - U_GREEK_LOWER_NUMERAL_SIGN = 0x0375, // U+0375 GREEK LOWER NUMERAL SIGN - U_GREEK_TONOS = 0x0384, // U+0384 GREEK TONOS - U_GREEK_DIALYTIKA_TONOS = 0x0385, // U+0385 GREEK DIALYTIKA TONOS - U_GREEK_KORONIS = 0x1FBD, // U+1FBD GREEK KORONIS - U_GREEK_PSILI = 0x1FBF, // U+1FBF GREEK PSILI - U_GREEK_PERISPOMENI = 0x1FC0, // U+1FC0 GREEK PERISPOMENI - U_GREEK_DIALYTIKA_AND_PERISPOMENI = 0x1FC1, // U+1FC1 GREEK DIALYTIKA AND PERISPOMENI - U_GREEK_PSILI_AND_VARIA = 0x1FCD, // U+1FCD GREEK PSILI AND VARIA - U_GREEK_PSILI_AND_OXIA = 0x1FCE, // U+1FCE GREEK PSILI AND OXIA - U_GREEK_PSILI_AND_PERISPOMENI = 0x1FCF, // U+1FCF GREEK PSILI AND PERISPOMENI - U_GREEK_DASIA_AND_VARIA = 0x1FDD, // U+1FDD GREEK DASIA AND VARIA - U_GREEK_DASIA_AND_OXIA = 0x1FDE, // U+1FDE GREEK DASIA AND OXIA - U_GREEK_DASIA_AND_PERISPOMENI = 0x1FDF, // U+1FDF GREEK DASIA AND PERISPOMENI - U_GREEK_DIALYTIKA_AND_VARIA = 0x1FED, // U+1FED GREEK DIALYTIKA AND VARIA - U_GREEK_DIALYTIKA_AND_OXIA = 0x1FEE, // U+1FEE GREEK DIALYTIKA AND OXIA - U_GREEK_VARIA = 0x1FEF, // U+1FEF GREEK VARIA - U_GREEK_OXIA = 0x1FFD, // U+1FFD GREEK OXIA - U_GREEK_DASIA = 0x1FFE, // U+1FFE GREEK DASIA - - - U_OVERLINE = 0x203E, // Unicode Character 'OVERLINE' - - /** - * UTF-8 BOM - * Unicode Character 'ZERO WIDTH NO-BREAK SPACE' (U+FEFF) - * http://www.fileformat.info/info/unicode/char/feff/index.htm - */ - UTF8_BOM = 65279 -} diff --git a/extensions/search-rg/src/common/comparers.ts b/extensions/search-rg/src/common/comparers.ts deleted file mode 100644 index fc6022526db..00000000000 --- a/extensions/search-rg/src/common/comparers.ts +++ /dev/null @@ -1,115 +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'; - -import * as strings from './strings'; - -let intlFileNameCollator: Intl.Collator; -let intlFileNameCollatorIsNumeric: boolean; - -setFileNameComparer(new Intl.Collator(undefined, { numeric: true, sensitivity: 'base' })); - -export function setFileNameComparer(collator: Intl.Collator): void { - intlFileNameCollator = collator; - intlFileNameCollatorIsNumeric = collator.resolvedOptions().numeric; -} - -export function compareFileNames(one: string, other: string, caseSensitive = false): number { - if (intlFileNameCollator) { - const a = one || ''; - const b = other || ''; - const result = intlFileNameCollator.compare(a, b); - - // Using the numeric option in the collator will - // make compare(`foo1`, `foo01`) === 0. We must disambiguate. - if (intlFileNameCollatorIsNumeric && result === 0 && a !== b) { - return a < b ? -1 : 1; - } - - return result; - } - - return noIntlCompareFileNames(one, other, caseSensitive); -} - -const FileNameMatch = /^(.*?)(\.([^.]*))?$/; - -export function noIntlCompareFileNames(one: string, other: string, caseSensitive = false): number { - if (!caseSensitive) { - one = one && one.toLowerCase(); - other = other && other.toLowerCase(); - } - - const [oneName, oneExtension] = extractNameAndExtension(one); - const [otherName, otherExtension] = extractNameAndExtension(other); - - if (oneName !== otherName) { - return oneName < otherName ? -1 : 1; - } - - if (oneExtension === otherExtension) { - return 0; - } - - return oneExtension < otherExtension ? -1 : 1; -} - -function extractNameAndExtension(str?: string): [string, string] { - const match = str ? FileNameMatch.exec(str) : [] as RegExpExecArray; - - return [(match && match[1]) || '', (match && match[3]) || '']; -} - -export function compareAnything(one: string, other: string, lookFor: string): number { - let elementAName = one.toLowerCase(); - let elementBName = other.toLowerCase(); - - // Sort prefix matches over non prefix matches - const prefixCompare = compareByPrefix(one, other, lookFor); - if (prefixCompare) { - return prefixCompare; - } - - // Sort suffix matches over non suffix matches - let elementASuffixMatch = strings.endsWith(elementAName, lookFor); - let elementBSuffixMatch = strings.endsWith(elementBName, lookFor); - if (elementASuffixMatch !== elementBSuffixMatch) { - return elementASuffixMatch ? -1 : 1; - } - - // Understand file names - let r = compareFileNames(elementAName, elementBName); - if (r !== 0) { - return r; - } - - // Compare by name - return elementAName.localeCompare(elementBName); -} - -export function compareByPrefix(one: string, other: string, lookFor: string): number { - let elementAName = one.toLowerCase(); - let elementBName = other.toLowerCase(); - - // Sort prefix matches over non prefix matches - let elementAPrefixMatch = strings.startsWith(elementAName, lookFor); - let elementBPrefixMatch = strings.startsWith(elementBName, lookFor); - if (elementAPrefixMatch !== elementBPrefixMatch) { - return elementAPrefixMatch ? -1 : 1; - } - - // Same prefix: Sort shorter matches to the top to have those on top that match more precisely - else if (elementAPrefixMatch && elementBPrefixMatch) { - if (elementAName.length < elementBName.length) { - return -1; - } - - if (elementAName.length > elementBName.length) { - return 1; - } - } - - return 0; -} diff --git a/extensions/search-rg/src/common/fileSearchScorer.ts b/extensions/search-rg/src/common/fileSearchScorer.ts deleted file mode 100644 index d73d7c77f41..00000000000 --- a/extensions/search-rg/src/common/fileSearchScorer.ts +++ /dev/null @@ -1,619 +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'; - -import { stripWildcards, equalsIgnoreCase } from './strings'; -import { matchesPrefix, matchesCamelCase, createMatches, IMatch, isUpper } from './filters'; -import { compareAnything } from './comparers'; -import { CharCode } from './charCode'; - -const isWindows = process.platform === 'win32'; -const isMacintosh = (process.platform === 'darwin'); -const isLinux = (process.platform === 'linux'); - -const nativeSep = isWindows ? '\\' : '/'; - -export type Score = [number /* score */, number[] /* match positions */]; -export type ScorerCache = { [key: string]: IItemScore }; - -const NO_MATCH = 0; -const NO_SCORE: Score = [NO_MATCH, []]; - -// const DEBUG = false; -// const DEBUG_MATRIX = false; - -export function score(target: string, query: string, queryLower: string, fuzzy: boolean): Score { - if (!target || !query) { - return NO_SCORE; // return early if target or query are undefined - } - - const targetLength = target.length; - const queryLength = query.length; - - if (targetLength < queryLength) { - return NO_SCORE; // impossible for query to be contained in target - } - - // if (DEBUG) { - // console.group(`Target: ${target}, Query: ${query}`); - // } - - const targetLower = target.toLowerCase(); - - // When not searching fuzzy, we require the query to be contained fully - // in the target string contiguously. - if (!fuzzy) { - const indexOfQueryInTarget = targetLower.indexOf(queryLower); - if (indexOfQueryInTarget === -1) { - // if (DEBUG) { - // console.log(`Characters not matching consecutively ${queryLower} within ${targetLower}`); - // } - - return NO_SCORE; - } - } - - const res = doScore(query, queryLower, queryLength, target, targetLower, targetLength); - - // if (DEBUG) { - // console.log(`%cFinal Score: ${res[0]}`, 'font-weight: bold'); - // console.groupEnd(); - // } - - return res; -} - -function doScore(query: string, queryLower: string, queryLength: number, target: string, targetLower: string, targetLength: number): [number, number[]] { - const scores = []; - const matches = []; - - // - // Build Scorer Matrix: - // - // The matrix is composed of query q and target t. For each index we score - // q[i] with t[i] and compare that with the previous score. If the score is - // equal or larger, we keep the match. In addition to the score, we also keep - // the length of the consecutive matches to use as boost for the score. - // - // t a r g e t - // q - // u - // e - // r - // y - // - for (let queryIndex = 0; queryIndex < queryLength; queryIndex++) { - for (let targetIndex = 0; targetIndex < targetLength; targetIndex++) { - const currentIndex = queryIndex * targetLength + targetIndex; - const leftIndex = currentIndex - 1; - const diagIndex = (queryIndex - 1) * targetLength + targetIndex - 1; - - const leftScore: number = targetIndex > 0 ? scores[leftIndex] : 0; - const diagScore: number = queryIndex > 0 && targetIndex > 0 ? scores[diagIndex] : 0; - - const matchesSequenceLength: number = queryIndex > 0 && targetIndex > 0 ? matches[diagIndex] : 0; - - // If we are not matching on the first query character any more, we only produce a - // score if we had a score previously for the last query index (by looking at the diagScore). - // This makes sure that the query always matches in sequence on the target. For example - // given a target of "ede" and a query of "de", we would otherwise produce a wrong high score - // for query[1] ("e") matching on target[0] ("e") because of the "beginning of word" boost. - let score: number; - if (!diagScore && queryIndex > 0) { - score = 0; - } else { - score = computeCharScore(query, queryLower, queryIndex, target, targetLower, targetIndex, matchesSequenceLength); - } - - // We have a score and its equal or larger than the left score - // Match: sequence continues growing from previous diag value - // Score: increases by diag score value - if (score && diagScore + score >= leftScore) { - matches[currentIndex] = matchesSequenceLength + 1; - scores[currentIndex] = diagScore + score; - } - - // We either have no score or the score is lower than the left score - // Match: reset to 0 - // Score: pick up from left hand side - else { - matches[currentIndex] = NO_MATCH; - scores[currentIndex] = leftScore; - } - } - } - - // Restore Positions (starting from bottom right of matrix) - const positions = []; - let queryIndex = queryLength - 1; - let targetIndex = targetLength - 1; - while (queryIndex >= 0 && targetIndex >= 0) { - const currentIndex = queryIndex * targetLength + targetIndex; - const match = matches[currentIndex]; - if (match === NO_MATCH) { - targetIndex--; // go left - } else { - positions.push(targetIndex); - - // go up and left - queryIndex--; - targetIndex--; - } - } - - // Print matrix - // if (DEBUG_MATRIX) { - // printMatrix(query, target, matches, scores); - // } - - return [scores[queryLength * targetLength - 1], positions.reverse()]; -} - -function computeCharScore(query: string, queryLower: string, queryIndex: number, target: string, targetLower: string, targetIndex: number, matchesSequenceLength: number): number { - let score = 0; - - if (queryLower[queryIndex] !== targetLower[targetIndex]) { - return score; // no match of characters - } - - // Character match bonus - score += 1; - - // if (DEBUG) { - // console.groupCollapsed(`%cCharacter match bonus: +1 (char: ${queryLower[queryIndex]} at index ${targetIndex}, total score: ${score})`, 'font-weight: normal'); - // } - - // Consecutive match bonus - if (matchesSequenceLength > 0) { - score += (matchesSequenceLength * 5); - - // if (DEBUG) { - // console.log('Consecutive match bonus: ' + (matchesSequenceLength * 5)); - // } - } - - // Same case bonus - if (query[queryIndex] === target[targetIndex]) { - score += 1; - - // if (DEBUG) { - // console.log('Same case bonus: +1'); - // } - } - - // Start of word bonus - if (targetIndex === 0) { - score += 8; - - // if (DEBUG) { - // console.log('Start of word bonus: +8'); - // } - } - - else { - - // After separator bonus - const separatorBonus = scoreSeparatorAtPos(target.charCodeAt(targetIndex - 1)); - if (separatorBonus) { - score += separatorBonus; - - // if (DEBUG) { - // console.log('After separtor bonus: +4'); - // } - } - - // Inside word upper case bonus (camel case) - else if (isUpper(target.charCodeAt(targetIndex))) { - score += 1; - - // if (DEBUG) { - // console.log('Inside word upper case bonus: +1'); - // } - } - } - - // if (DEBUG) { - // console.groupEnd(); - // } - - return score; -} - -function scoreSeparatorAtPos(charCode: number): number { - switch (charCode) { - case CharCode.Slash: - case CharCode.Backslash: - return 5; // prefer path separators... - case CharCode.Underline: - case CharCode.Dash: - case CharCode.Period: - case CharCode.Space: - case CharCode.SingleQuote: - case CharCode.DoubleQuote: - case CharCode.Colon: - return 4; // ...over other separators - default: - return 0; - } -} - -// function printMatrix(query: string, target: string, matches: number[], scores: number[]): void { -// console.log('\t' + target.split('').join('\t')); -// for (let queryIndex = 0; queryIndex < query.length; queryIndex++) { -// let line = query[queryIndex] + '\t'; -// for (let targetIndex = 0; targetIndex < target.length; targetIndex++) { -// const currentIndex = queryIndex * target.length + targetIndex; -// line = line + 'M' + matches[currentIndex] + '/' + 'S' + scores[currentIndex] + '\t'; -// } - -// console.log(line); -// } -// } - -/** - * Scoring on structural items that have a label and optional description. - */ -export interface IItemScore { - - /** - * Overall score. - */ - score: number; - - /** - * Matches within the label. - */ - labelMatch?: IMatch[]; - - /** - * Matches within the description. - */ - descriptionMatch?: IMatch[]; -} - -const NO_ITEM_SCORE: IItemScore = Object.freeze({ score: 0 }); - -export interface IItemAccessor { - - /** - * Just the label of the item to score on. - */ - getItemLabel(item: T): string; - - /** - * The optional description of the item to score on. Can be null. - */ - getItemDescription(item: T): string; - - /** - * If the item is a file, the path of the file to score on. Can be null. - */ - getItemPath(file: T): string; -} - -const PATH_IDENTITY_SCORE = 1 << 18; -const LABEL_PREFIX_SCORE = 1 << 17; -const LABEL_CAMELCASE_SCORE = 1 << 16; -const LABEL_SCORE_THRESHOLD = 1 << 15; - -export interface IPreparedQuery { - original: string; - value: string; - lowercase: string; - containsPathSeparator: boolean; -} - -/** - * Helper function to prepare a search value for scoring in quick open by removing unwanted characters. - */ -export function prepareQuery(original: string): IPreparedQuery { - let lowercase: string; - let containsPathSeparator: boolean; - let value: string; - - if (original) { - value = stripWildcards(original).replace(/\s/g, ''); // get rid of all wildcards and whitespace - if (isWindows) { - value = value.replace(/\//g, nativeSep); // Help Windows users to search for paths when using slash - } - - lowercase = value.toLowerCase(); - containsPathSeparator = value.indexOf(nativeSep) >= 0; - } - - return { original, value, lowercase, containsPathSeparator }; -} - -export function scoreItem(item: T, query: IPreparedQuery, fuzzy: boolean, accessor: IItemAccessor, cache: ScorerCache): IItemScore { - if (!item || !query.value) { - return NO_ITEM_SCORE; // we need an item and query to score on at least - } - - const label = accessor.getItemLabel(item); - if (!label) { - return NO_ITEM_SCORE; // we need a label at least - } - - const description = accessor.getItemDescription(item); - - let cacheHash: string; - if (description) { - cacheHash = `${label}${description}${query.value}${fuzzy}`; - } else { - cacheHash = `${label}${query.value}${fuzzy}`; - } - - const cached = cache[cacheHash]; - if (cached) { - return cached; - } - - const itemScore = doScoreItem(label, description, accessor.getItemPath(item), query, fuzzy); - cache[cacheHash] = itemScore; - - return itemScore; -} - -function doScoreItem(label: string, description: string, path: string, query: IPreparedQuery, fuzzy: boolean): IItemScore { - - // 1.) treat identity matches on full path highest - if (path && isLinux ? query.original === path : equalsIgnoreCase(query.original, path)) { - return { score: PATH_IDENTITY_SCORE, labelMatch: [{ start: 0, end: label.length }], descriptionMatch: description ? [{ start: 0, end: description.length }] : void 0 }; - } - - // We only consider label matches if the query is not including file path separators - const preferLabelMatches = !path || !query.containsPathSeparator; - if (preferLabelMatches) { - - // 2.) treat prefix matches on the label second highest - const prefixLabelMatch = matchesPrefix(query.value, label); - if (prefixLabelMatch) { - return { score: LABEL_PREFIX_SCORE, labelMatch: prefixLabelMatch }; - } - - // 3.) treat camelcase matches on the label third highest - const camelcaseLabelMatch = matchesCamelCase(query.value, label); - if (camelcaseLabelMatch) { - return { score: LABEL_CAMELCASE_SCORE, labelMatch: camelcaseLabelMatch }; - } - - // 4.) prefer scores on the label if any - const [labelScore, labelPositions] = score(label, query.value, query.lowercase, fuzzy); - if (labelScore) { - return { score: labelScore + LABEL_SCORE_THRESHOLD, labelMatch: createMatches(labelPositions) }; - } - } - - // 5.) finally compute description + label scores if we have a description - if (description) { - let descriptionPrefix = description; - if (!!path) { - descriptionPrefix = `${description}${nativeSep}`; // assume this is a file path - } - - const descriptionPrefixLength = descriptionPrefix.length; - const descriptionAndLabel = `${descriptionPrefix}${label}`; - - const [labelDescriptionScore, labelDescriptionPositions] = score(descriptionAndLabel, query.value, query.lowercase, fuzzy); - if (labelDescriptionScore) { - const labelDescriptionMatches = createMatches(labelDescriptionPositions); - const labelMatch: IMatch[] = []; - const descriptionMatch: IMatch[] = []; - - // We have to split the matches back onto the label and description portions - labelDescriptionMatches.forEach(h => { - - // Match overlaps label and description part, we need to split it up - if (h.start < descriptionPrefixLength && h.end > descriptionPrefixLength) { - labelMatch.push({ start: 0, end: h.end - descriptionPrefixLength }); - descriptionMatch.push({ start: h.start, end: descriptionPrefixLength }); - } - - // Match on label part - else if (h.start >= descriptionPrefixLength) { - labelMatch.push({ start: h.start - descriptionPrefixLength, end: h.end - descriptionPrefixLength }); - } - - // Match on description part - else { - descriptionMatch.push(h); - } - }); - - return { score: labelDescriptionScore, labelMatch, descriptionMatch }; - } - } - - return NO_ITEM_SCORE; -} - -export function compareItemsByScore(itemA: T, itemB: T, query: IPreparedQuery, fuzzy: boolean, accessor: IItemAccessor, cache: ScorerCache, fallbackComparer = fallbackCompare): number { - const itemScoreA = scoreItem(itemA, query, fuzzy, accessor, cache); - const itemScoreB = scoreItem(itemB, query, fuzzy, accessor, cache); - - const scoreA = itemScoreA.score; - const scoreB = itemScoreB.score; - - // 1.) prefer identity matches - if (scoreA === PATH_IDENTITY_SCORE || scoreB === PATH_IDENTITY_SCORE) { - if (scoreA !== scoreB) { - return scoreA === PATH_IDENTITY_SCORE ? -1 : 1; - } - } - - // 2.) prefer label prefix matches - if (scoreA === LABEL_PREFIX_SCORE || scoreB === LABEL_PREFIX_SCORE) { - if (scoreA !== scoreB) { - return scoreA === LABEL_PREFIX_SCORE ? -1 : 1; - } - - const labelA = accessor.getItemLabel(itemA); - const labelB = accessor.getItemLabel(itemB); - - // prefer shorter names when both match on label prefix - if (labelA.length !== labelB.length) { - return labelA.length - labelB.length; - } - } - - // 3.) prefer camelcase matches - if (scoreA === LABEL_CAMELCASE_SCORE || scoreB === LABEL_CAMELCASE_SCORE) { - if (scoreA !== scoreB) { - return scoreA === LABEL_CAMELCASE_SCORE ? -1 : 1; - } - - const labelA = accessor.getItemLabel(itemA); - const labelB = accessor.getItemLabel(itemB); - - // prefer more compact camel case matches over longer - const comparedByMatchLength = compareByMatchLength(itemScoreA.labelMatch, itemScoreB.labelMatch); - if (comparedByMatchLength !== 0) { - return comparedByMatchLength; - } - - // prefer shorter names when both match on label camelcase - if (labelA.length !== labelB.length) { - return labelA.length - labelB.length; - } - } - - // 4.) prefer label scores - if (scoreA > LABEL_SCORE_THRESHOLD || scoreB > LABEL_SCORE_THRESHOLD) { - if (scoreB < LABEL_SCORE_THRESHOLD) { - return -1; - } - - if (scoreA < LABEL_SCORE_THRESHOLD) { - return 1; - } - } - - // 5.) compare by score - if (scoreA !== scoreB) { - return scoreA > scoreB ? -1 : 1; - } - - // 6.) scores are identical, prefer more compact matches (label and description) - const itemAMatchDistance = computeLabelAndDescriptionMatchDistance(itemA, itemScoreA, accessor); - const itemBMatchDistance = computeLabelAndDescriptionMatchDistance(itemB, itemScoreB, accessor); - if (itemAMatchDistance && itemBMatchDistance && itemAMatchDistance !== itemBMatchDistance) { - return itemBMatchDistance > itemAMatchDistance ? -1 : 1; - } - - // 7.) at this point, scores are identical and match compactness as well - // for both items so we start to use the fallback compare - return fallbackComparer(itemA, itemB, query, accessor); -} - -function computeLabelAndDescriptionMatchDistance(item: T, score: IItemScore, accessor: IItemAccessor): number { - const hasLabelMatches = (score.labelMatch && score.labelMatch.length); - const hasDescriptionMatches = (score.descriptionMatch && score.descriptionMatch.length); - - let matchStart: number = -1; - let matchEnd: number = -1; - - // If we have description matches, the start is first of description match - if (hasDescriptionMatches) { - matchStart = score.descriptionMatch[0].start; - } - - // Otherwise, the start is the first label match - else if (hasLabelMatches) { - matchStart = score.labelMatch[0].start; - } - - // If we have label match, the end is the last label match - // If we had a description match, we add the length of the description - // as offset to the end to indicate this. - if (hasLabelMatches) { - matchEnd = score.labelMatch[score.labelMatch.length - 1].end; - if (hasDescriptionMatches) { - const itemDescription = accessor.getItemDescription(item); - if (itemDescription) { - matchEnd += itemDescription.length; - } - } - } - - // If we have just a description match, the end is the last description match - else if (hasDescriptionMatches) { - matchEnd = score.descriptionMatch[score.descriptionMatch.length - 1].end; - } - - return matchEnd - matchStart; -} - -function compareByMatchLength(matchesA?: IMatch[], matchesB?: IMatch[]): number { - if ((!matchesA && !matchesB) || (!matchesA.length && !matchesB.length)) { - return 0; // make sure to not cause bad comparing when matches are not provided - } - - if (!matchesB || !matchesB.length) { - return -1; - } - - if (!matchesA || !matchesA.length) { - return 1; - } - - // Compute match length of A (first to last match) - const matchStartA = matchesA[0].start; - const matchEndA = matchesA[matchesA.length - 1].end; - const matchLengthA = matchEndA - matchStartA; - - // Compute match length of B (first to last match) - const matchStartB = matchesB[0].start; - const matchEndB = matchesB[matchesB.length - 1].end; - const matchLengthB = matchEndB - matchStartB; - - // Prefer shorter match length - return matchLengthA === matchLengthB ? 0 : matchLengthB < matchLengthA ? 1 : -1; -} - -export function fallbackCompare(itemA: T, itemB: T, query: IPreparedQuery, accessor: IItemAccessor): number { - - // check for label + description length and prefer shorter - const labelA = accessor.getItemLabel(itemA); - const labelB = accessor.getItemLabel(itemB); - - const descriptionA = accessor.getItemDescription(itemA); - const descriptionB = accessor.getItemDescription(itemB); - - const labelDescriptionALength = labelA.length + (descriptionA ? descriptionA.length : 0); - const labelDescriptionBLength = labelB.length + (descriptionB ? descriptionB.length : 0); - - if (labelDescriptionALength !== labelDescriptionBLength) { - return labelDescriptionALength - labelDescriptionBLength; - } - - // check for path length and prefer shorter - const pathA = accessor.getItemPath(itemA); - const pathB = accessor.getItemPath(itemB); - - if (pathA && pathB && pathA.length !== pathB.length) { - return pathA.length - pathB.length; - } - - // 7.) finally we have equal scores and equal length, we fallback to comparer - - // compare by label - if (labelA !== labelB) { - return compareAnything(labelA, labelB, query.value); - } - - // compare by description - if (descriptionA && descriptionB && descriptionA !== descriptionB) { - return compareAnything(descriptionA, descriptionB, query.value); - } - - // compare by path - if (pathA && pathB && pathA !== pathB) { - return compareAnything(pathA, pathB, query.value); - } - - // equal - return 0; -} \ No newline at end of file diff --git a/extensions/search-rg/src/common/filters.ts b/extensions/search-rg/src/common/filters.ts deleted file mode 100644 index 63d4dcaeac3..00000000000 --- a/extensions/search-rg/src/common/filters.ts +++ /dev/null @@ -1,224 +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'; - -import * as strings from './strings'; -import { CharCode } from './charCode'; - -export interface IFilter { - // Returns null if word doesn't match. - (word: string, wordToMatchAgainst: string): IMatch[]; -} - -export interface IMatch { - start: number; - end: number; -} - -// Prefix - -export const matchesPrefix: IFilter = _matchesPrefix.bind(undefined, true); - -function _matchesPrefix(ignoreCase: boolean, word: string, wordToMatchAgainst: string): IMatch[] { - if (!wordToMatchAgainst || wordToMatchAgainst.length < word.length) { - return null; - } - - let matches: boolean; - if (ignoreCase) { - matches = strings.startsWithIgnoreCase(wordToMatchAgainst, word); - } else { - matches = wordToMatchAgainst.indexOf(word) === 0; - } - - if (!matches) { - return null; - } - - return word.length > 0 ? [{ start: 0, end: word.length }] : []; -} - -// CamelCase - -function isLower(code: number): boolean { - return CharCode.a <= code && code <= CharCode.z; -} - -export function isUpper(code: number): boolean { - return CharCode.A <= code && code <= CharCode.Z; -} - -function isNumber(code: number): boolean { - return CharCode.Digit0 <= code && code <= CharCode.Digit9; -} - -function isWhitespace(code: number): boolean { - return ( - code === CharCode.Space - || code === CharCode.Tab - || code === CharCode.LineFeed - || code === CharCode.CarriageReturn - ); -} - -function isAlphanumeric(code: number): boolean { - return isLower(code) || isUpper(code) || isNumber(code); -} - -function join(head: IMatch, tail: IMatch[]): IMatch[] { - if (tail.length === 0) { - tail = [head]; - } else if (head.end === tail[0].start) { - tail[0].start = head.start; - } else { - tail.unshift(head); - } - return tail; -} - -function nextAnchor(camelCaseWord: string, start: number): number { - for (let i = start; i < camelCaseWord.length; i++) { - let c = camelCaseWord.charCodeAt(i); - if (isUpper(c) || isNumber(c) || (i > 0 && !isAlphanumeric(camelCaseWord.charCodeAt(i - 1)))) { - return i; - } - } - return camelCaseWord.length; -} - -function _matchesCamelCase(word: string, camelCaseWord: string, i: number, j: number): IMatch[] { - if (i === word.length) { - return []; - } else if (j === camelCaseWord.length) { - return null; - } else if (word[i] !== camelCaseWord[j].toLowerCase()) { - return null; - } else { - let result: IMatch[] = null; - let nextUpperIndex = j + 1; - result = _matchesCamelCase(word, camelCaseWord, i + 1, j + 1); - while (!result && (nextUpperIndex = nextAnchor(camelCaseWord, nextUpperIndex)) < camelCaseWord.length) { - result = _matchesCamelCase(word, camelCaseWord, i + 1, nextUpperIndex); - nextUpperIndex++; - } - return result === null ? null : join({ start: j, end: j + 1 }, result); - } -} - -interface ICamelCaseAnalysis { - upperPercent: number; - lowerPercent: number; - alphaPercent: number; - numericPercent: number; -} - -// Heuristic to avoid computing camel case matcher for words that don't -// look like camelCaseWords. -function analyzeCamelCaseWord(word: string): ICamelCaseAnalysis { - let upper = 0, lower = 0, alpha = 0, numeric = 0, code = 0; - - for (let i = 0; i < word.length; i++) { - code = word.charCodeAt(i); - - if (isUpper(code)) { upper++; } - if (isLower(code)) { lower++; } - if (isAlphanumeric(code)) { alpha++; } - if (isNumber(code)) { numeric++; } - } - - let upperPercent = upper / word.length; - let lowerPercent = lower / word.length; - let alphaPercent = alpha / word.length; - let numericPercent = numeric / word.length; - - return { upperPercent, lowerPercent, alphaPercent, numericPercent }; -} - -function isUpperCaseWord(analysis: ICamelCaseAnalysis): boolean { - const { upperPercent, lowerPercent } = analysis; - return lowerPercent === 0 && upperPercent > 0.6; -} - -function isCamelCaseWord(analysis: ICamelCaseAnalysis): boolean { - const { upperPercent, lowerPercent, alphaPercent, numericPercent } = analysis; - return lowerPercent > 0.2 && upperPercent < 0.8 && alphaPercent > 0.6 && numericPercent < 0.2; -} - -// Heuristic to avoid computing camel case matcher for words that don't -// look like camel case patterns. -function isCamelCasePattern(word: string): boolean { - let upper = 0, lower = 0, code = 0, whitespace = 0; - - for (let i = 0; i < word.length; i++) { - code = word.charCodeAt(i); - - if (isUpper(code)) { upper++; } - if (isLower(code)) { lower++; } - if (isWhitespace(code)) { whitespace++; } - } - - if ((upper === 0 || lower === 0) && whitespace === 0) { - return word.length <= 30; - } else { - return upper <= 5; - } -} - -export function matchesCamelCase(word: string, camelCaseWord: string): IMatch[] { - if (!camelCaseWord) { - return null; - } - - camelCaseWord = camelCaseWord.trim(); - - if (camelCaseWord.length === 0) { - return null; - } - - if (!isCamelCasePattern(word)) { - return null; - } - - if (camelCaseWord.length > 60) { - return null; - } - - const analysis = analyzeCamelCaseWord(camelCaseWord); - - if (!isCamelCaseWord(analysis)) { - if (!isUpperCaseWord(analysis)) { - return null; - } - - camelCaseWord = camelCaseWord.toLowerCase(); - } - - let result: IMatch[] = null; - let i = 0; - - word = word.toLowerCase(); - while (i < camelCaseWord.length && (result = _matchesCamelCase(word, camelCaseWord, 0, i)) === null) { - i = nextAnchor(camelCaseWord, i + 1); - } - - return result; -} - -export function createMatches(position: number[]): IMatch[] { - let ret: IMatch[] = []; - if (!position) { - return ret; - } - let last: IMatch; - for (const pos of position) { - if (last && last.end === pos) { - last.end += 1; - } else { - last = { start: pos, end: pos + 1 }; - ret.push(last); - } - } - return ret; -} diff --git a/extensions/search-rg/src/common/strings.ts b/extensions/search-rg/src/common/strings.ts deleted file mode 100644 index 2678aff1e0f..00000000000 --- a/extensions/search-rg/src/common/strings.ts +++ /dev/null @@ -1,143 +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'; - -import { CharCode } from './charCode'; - -export function stripWildcards(pattern: string): string { - return pattern.replace(/\*/g, ''); -} - -/** - * Determines if haystack starts with needle. - */ -export function startsWith(haystack: string, needle: string): boolean { - if (haystack.length < needle.length) { - return false; - } - - if (haystack === needle) { - return true; - } - - for (let i = 0; i < needle.length; i++) { - if (haystack[i] !== needle[i]) { - return false; - } - } - - return true; -} - -export function startsWithIgnoreCase(str: string, candidate: string): boolean { - const candidateLength = candidate.length; - if (candidate.length > str.length) { - return false; - } - - return doEqualsIgnoreCase(str, candidate, candidateLength); -} - -/** - * Determines if haystack ends with needle. - */ -export function endsWith(haystack: string, needle: string): boolean { - let diff = haystack.length - needle.length; - if (diff > 0) { - return haystack.indexOf(needle, diff) === diff; - } else if (diff === 0) { - return haystack === needle; - } else { - return false; - } -} - -function isLowerAsciiLetter(code: number): boolean { - return code >= CharCode.a && code <= CharCode.z; -} - -function isUpperAsciiLetter(code: number): boolean { - return code >= CharCode.A && code <= CharCode.Z; -} - -function isAsciiLetter(code: number): boolean { - return isLowerAsciiLetter(code) || isUpperAsciiLetter(code); -} - -export function equalsIgnoreCase(a: string, b: string): boolean { - const len1 = a ? a.length : 0; - const len2 = b ? b.length : 0; - - if (len1 !== len2) { - return false; - } - - return doEqualsIgnoreCase(a, b); -} - -function doEqualsIgnoreCase(a: string, b: string, stopAt = a.length): boolean { - if (typeof a !== 'string' || typeof b !== 'string') { - return false; - } - - for (let i = 0; i < stopAt; i++) { - const codeA = a.charCodeAt(i); - const codeB = b.charCodeAt(i); - - if (codeA === codeB) { - continue; - } - - // a-z A-Z - if (isAsciiLetter(codeA) && isAsciiLetter(codeB)) { - let diff = Math.abs(codeA - codeB); - if (diff !== 0 && diff !== 32) { - return false; - } - } - - // Any other charcode - else { - if (String.fromCharCode(codeA).toLowerCase() !== String.fromCharCode(codeB).toLowerCase()) { - return false; - } - } - } - - return true; -} - -/** - * Checks if the characters of the provided query string are included in the - * target string. The characters do not have to be contiguous within the string. - */ -export function fuzzyContains(target: string, query: string): boolean { - if (!target || !query) { - return false; // return early if target or query are undefined - } - - if (target.length < query.length) { - return false; // impossible for query to be contained in target - } - - const queryLen = query.length; - const targetLower = target.toLowerCase(); - - let index = 0; - let lastIndexOf = -1; - while (index < queryLen) { - let indexOf = targetLower.indexOf(query[index], lastIndexOf + 1); - if (indexOf < 0) { - return false; - } - - lastIndexOf = indexOf; - - index++; - } - - return true; -} \ No newline at end of file diff --git a/extensions/search-rg/src/extension.ts b/extensions/search-rg/src/extension.ts index 2a7baff9b32..1447f03d331 100644 --- a/extensions/search-rg/src/extension.ts +++ b/extensions/search-rg/src/extension.ts @@ -4,27 +4,26 @@ *--------------------------------------------------------------------------------------------*/ import * as vscode from 'vscode'; -import { RipgrepTextSearchEngine } from './ripgrepTextSearch'; import { RipgrepFileSearchEngine } from './ripgrepFileSearch'; -import { CachedSearchProvider } from './cachedSearchProvider'; +import { RipgrepTextSearchEngine } from './ripgrepTextSearch'; +import { joinPath } from './utils'; export function activate(): void { if (vscode.workspace.getConfiguration('searchRipgrep').get('enable')) { const outputChannel = vscode.window.createOutputChannel('search-rg'); + const provider = new RipgrepSearchProvider(outputChannel); - vscode.workspace.registerSearchProvider('file', provider); + vscode.workspace.registerFileIndexProvider('file', provider); vscode.workspace.registerTextSearchProvider('file', provider); } } type SearchEngine = RipgrepFileSearchEngine | RipgrepTextSearchEngine; -class RipgrepSearchProvider implements vscode.SearchProvider, vscode.TextSearchProvider { - private cachedProvider: CachedSearchProvider; +class RipgrepSearchProvider implements vscode.FileIndexProvider, vscode.TextSearchProvider { private inProgress: Set = new Set(); constructor(private outputChannel: vscode.OutputChannel) { - this.cachedProvider = new CachedSearchProvider(); process.once('exit', () => this.dispose()); } @@ -33,13 +32,16 @@ class RipgrepSearchProvider implements vscode.SearchProvider, vscode.TextSearchP return this.withEngine(engine, () => engine.provideTextSearchResults(query, options, progress, token)); } - provideFileSearchResults(query: vscode.FileSearchQuery, options: vscode.SearchOptions, progress: vscode.Progress, token: vscode.CancellationToken): Thenable { + provideFileIndex(options: vscode.FileSearchOptions, token: vscode.CancellationToken): Thenable { const engine = new RipgrepFileSearchEngine(this.outputChannel); - return this.withEngine(engine, () => this.cachedProvider.provideFileSearchResults(engine, query, options, progress, token)); - } - clearCache(cacheKey: string): void { - this.cachedProvider.clearCache(cacheKey); + const results: vscode.Uri[] = []; + const onResult = relativePathMatch => { + results.push(joinPath(options.folder, relativePathMatch)); + }; + + return this.withEngine(engine, () => engine.provideFileSearchResults(options, { report: onResult }, token)) + .then(() => results); } private withEngine(engine: SearchEngine, fn: () => Thenable): Thenable { diff --git a/extensions/search-rg/src/common/normalization.ts b/extensions/search-rg/src/normalization.ts similarity index 100% rename from extensions/search-rg/src/common/normalization.ts rename to extensions/search-rg/src/normalization.ts diff --git a/extensions/search-rg/src/ripgrepFileSearch.ts b/extensions/search-rg/src/ripgrepFileSearch.ts index fd3b6acc99a..7bf41793435 100644 --- a/extensions/search-rg/src/ripgrepFileSearch.ts +++ b/extensions/search-rg/src/ripgrepFileSearch.ts @@ -7,18 +7,17 @@ import * as cp from 'child_process'; import { Readable } from 'stream'; import { NodeStringDecoder, StringDecoder } from 'string_decoder'; import * as vscode from 'vscode'; -import { normalizeNFC, normalizeNFD } from './common/normalization'; +import { normalizeNFC, normalizeNFD } from './normalization'; import { rgPath } from './ripgrep'; -import { anchorGlob } from './utils'; import { rgErrorMsgForDisplay } from './ripgrepTextSearch'; -import { IInternalFileSearchProvider } from './cachedSearchProvider'; +import { anchorGlob } from './utils'; const isMac = process.platform === 'darwin'; // If vscode-ripgrep is in an .asar file, then the binary is unpacked. const rgDiskPath = rgPath.replace(/\bnode_modules\.asar\b/, 'node_modules.asar.unpacked'); -export class RipgrepFileSearchEngine implements IInternalFileSearchProvider { +export class RipgrepFileSearchEngine { private rgProc: cp.ChildProcess; private isDone: boolean; diff --git a/src/vs/platform/search/common/search.ts b/src/vs/platform/search/common/search.ts index 7cacfe626a9..fff587381ba 100644 --- a/src/vs/platform/search/common/search.ts +++ b/src/vs/platform/search/common/search.ts @@ -27,7 +27,7 @@ export interface ISearchService { search(query: ISearchQuery, onProgress?: (result: ISearchProgressItem) => void): TPromise; extendQuery(query: ISearchQuery): void; clearCache(cacheKey: string): TPromise; - registerSearchResultProvider(scheme: string, provider: ISearchResultProvider): IDisposable; + registerSearchResultProvider(scheme: string, type: SearchProviderType, provider: ISearchResultProvider): IDisposable; } export interface ISearchHistoryValues { @@ -45,6 +45,15 @@ export interface ISearchHistoryService { save(history: ISearchHistoryValues): void; } +/** + * TODO@roblou - split text from file search entirely, or share code in a more natural way. + */ +export enum SearchProviderType { + file, + fileIndex, + text +} + export interface ISearchResultProvider { search(query: ISearchQuery, onProgress?: (p: ISearchProgressItem) => void): TPromise; clearCache(cacheKey: string): TPromise; diff --git a/src/vs/vscode.proposed.d.ts b/src/vs/vscode.proposed.d.ts index 34941463e72..9e0e661c312 100644 --- a/src/vs/vscode.proposed.d.ts +++ b/src/vs/vscode.proposed.d.ts @@ -160,15 +160,11 @@ declare module 'vscode' { preview: TextSearchResultPreview; } - // interface FileIndexProvider { - // provideFileIndex(options: FileSearchOptions, token: CancellationToken): Thenable - // } + export interface FileIndexProvider { + provideFileIndex(options: FileSearchOptions, token: CancellationToken): Thenable; + } - // interface FileSearchProvider { - // provideFileSearchResults(query: FileSear, options, token): Thenable - // } - - interface TextSearchProvider { + export interface TextSearchProvider { /** * Provide results that match the given text pattern. * @param query The parameters for this query. @@ -251,7 +247,7 @@ declare module 'vscode' { * @param provider The provider. * @return A [disposable](#Disposable) that unregisters this provider when being disposed. */ - export function registerSearchProvider(scheme: string, provider: SearchProvider): Disposable; + export function registerFileSearchProvider(scheme: string, provider: SearchProvider): Disposable; /** * Register a text search provider. @@ -264,6 +260,17 @@ declare module 'vscode' { */ export function registerTextSearchProvider(scheme: string, provider: TextSearchProvider): Disposable; + /** + * Register a file index provider. + * + * Only one provider can be registered per scheme. + * + * @param scheme The provider will be invoked for workspace folders that have this file scheme. + * @param provider The provider. + * @return A [disposable](#Disposable) that unregisters this provider when being disposed. + */ + export function registerFileIndexProvider(scheme: string, provider: FileIndexProvider): Disposable; + /** * Search text in files across all [workspace folders](#workspace.workspaceFolders) in the workspace. diff --git a/src/vs/workbench/api/electron-browser/mainThreadSearch.ts b/src/vs/workbench/api/electron-browser/mainThreadSearch.ts index caffd57767b..d88cda81686 100644 --- a/src/vs/workbench/api/electron-browser/mainThreadSearch.ts +++ b/src/vs/workbench/api/electron-browser/mainThreadSearch.ts @@ -9,7 +9,7 @@ import { dispose, IDisposable } from 'vs/base/common/lifecycle'; import { values } from 'vs/base/common/map'; import URI, { UriComponents } from 'vs/base/common/uri'; import { TPromise } from 'vs/base/common/winjs.base'; -import { IFileMatch, IRawFileMatch2, ISearchComplete, ISearchCompleteStats, ISearchProgressItem, ISearchQuery, ISearchResultProvider, ISearchService, QueryType } from 'vs/platform/search/common/search'; +import { IFileMatch, IRawFileMatch2, ISearchComplete, ISearchCompleteStats, ISearchProgressItem, ISearchQuery, ISearchResultProvider, ISearchService, QueryType, SearchProviderType } from 'vs/platform/search/common/search'; import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry'; import { extHostNamedCustomer } from 'vs/workbench/api/electron-browser/extHostCustomers'; import { ExtHostContext, ExtHostSearchShape, IExtHostContext, MainContext, MainThreadSearchShape } from '../node/extHost.protocol'; @@ -33,8 +33,16 @@ export class MainThreadSearch implements MainThreadSearchShape { this._searchProvider.clear(); } - $registerSearchProvider(handle: number, scheme: string): void { - this._searchProvider.set(handle, new RemoteSearchProvider(this._searchService, scheme, handle, this._proxy)); + $registerTextSearchProvider(handle: number, scheme: string): void { + this._searchProvider.set(handle, new RemoteSearchProvider(this._searchService, SearchProviderType.text, scheme, handle, this._proxy)); + } + + $registerFileSearchProvider(handle: number, scheme: string): void { + this._searchProvider.set(handle, new RemoteSearchProvider(this._searchService, SearchProviderType.file, scheme, handle, this._proxy)); + } + + $registerFileIndexProvider(handle: number, scheme: string): void { + this._searchProvider.set(handle, new RemoteSearchProvider(this._searchService, SearchProviderType.fileIndex, scheme, handle, this._proxy)); } $unregisterProvider(handle: number): void { @@ -86,11 +94,12 @@ class RemoteSearchProvider implements ISearchResultProvider, IDisposable { constructor( searchService: ISearchService, + type: SearchProviderType, private readonly _scheme: string, private readonly _handle: number, private readonly _proxy: ExtHostSearchShape ) { - this._registrations = [searchService.registerSearchResultProvider(this._scheme, this)]; + this._registrations = [searchService.registerSearchResultProvider(this._scheme, type, this)]; } dispose(): void { @@ -103,16 +112,6 @@ class RemoteSearchProvider implements ISearchResultProvider, IDisposable { return TPromise.as(undefined); } - const folderQueriesForScheme = query.folderQueries.filter(fq => fq.folder.scheme === this._scheme); - if (!folderQueriesForScheme.length) { - return TPromise.wrap(null); - } - - query = { - ...query, - folderQueries: folderQueriesForScheme - }; - let outer: TPromise; return new TPromise((resolve, reject) => { diff --git a/src/vs/workbench/api/node/extHost.api.impl.ts b/src/vs/workbench/api/node/extHost.api.impl.ts index fefa5e6ebad..504df828bc7 100644 --- a/src/vs/workbench/api/node/extHost.api.impl.ts +++ b/src/vs/workbench/api/node/extHost.api.impl.ts @@ -582,12 +582,15 @@ export function createApiFactory( registerFileSystemProvider(scheme, provider, options) { return extHostFileSystem.registerFileSystemProvider(scheme, provider, options); }, - registerSearchProvider: proposedApiFunction(extension, (scheme, provider) => { - return extHostSearch.registerSearchProvider(scheme, provider); + registerFileSearchProvider: proposedApiFunction(extension, (scheme, provider) => { + return extHostSearch.registerFileSearchProvider(scheme, provider); }), registerTextSearchProvider: proposedApiFunction(extension, (scheme, provider) => { return extHostSearch.registerTextSearchProvider(scheme, provider); }), + registerFileIndexProvider: proposedApiFunction(extension, (scheme, provider) => { + return extHostSearch.registerFileIndexProvider(scheme, provider); + }), registerDocumentCommentProvider: proposedApiFunction(extension, (provider: vscode.DocumentCommentProvider) => { return exthostCommentProviders.registerDocumentCommentProvider(provider); }), diff --git a/src/vs/workbench/api/node/extHost.protocol.ts b/src/vs/workbench/api/node/extHost.protocol.ts index 11e0707a346..ba37c355b35 100644 --- a/src/vs/workbench/api/node/extHost.protocol.ts +++ b/src/vs/workbench/api/node/extHost.protocol.ts @@ -486,7 +486,9 @@ export interface MainThreadFileSystemShape extends IDisposable { } export interface MainThreadSearchShape extends IDisposable { - $registerSearchProvider(handle: number, scheme: string): void; + $registerFileSearchProvider(handle: number, scheme: string): void; + $registerTextSearchProvider(handle: number, scheme: string): void; + $registerFileIndexProvider(handle: number, scheme: string): void; $unregisterProvider(handle: number): void; $handleFileMatch(handle: number, session: number, data: UriComponents[]): void; $handleTextMatch(handle: number, session: number, data: IRawFileMatch2[]): void; diff --git a/src/vs/workbench/api/node/extHostSearch.fileIndex.ts b/src/vs/workbench/api/node/extHostSearch.fileIndex.ts new file mode 100644 index 00000000000..1cfb58fc324 --- /dev/null +++ b/src/vs/workbench/api/node/extHostSearch.fileIndex.ts @@ -0,0 +1,728 @@ +/*--------------------------------------------------------------------------------------------- + * 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 * as path from 'path'; +import * as arrays from 'vs/base/common/arrays'; +import { CancellationTokenSource } from 'vs/base/common/cancellation'; +import { toErrorMessage } from 'vs/base/common/errorMessage'; +import * as glob from 'vs/base/common/glob'; +import * as resources from 'vs/base/common/resources'; +import * as strings from 'vs/base/common/strings'; +import URI from 'vs/base/common/uri'; +import { PPromise, TPromise } from 'vs/base/common/winjs.base'; +import { compareItemsByScore, IItemAccessor, prepareQuery, ScorerCache } from 'vs/base/parts/quickopen/common/quickOpenScorer'; +import { ICachedSearchStats, IFileMatch, IFolderQuery, IRawSearchQuery, ISearchCompleteStats, ISearchQuery } from 'vs/platform/search/common/search'; +import * as vscode from 'vscode'; + +export interface IInternalFileMatch { + base: URI; + relativePath?: string; // Not present for extraFiles or absolute path matches + basename: string; + size?: number; +} + +/** + * Computes the patterns that the provider handles. Discards sibling clauses and 'false' patterns + */ +export function resolvePatternsForProvider(globalPattern: glob.IExpression, folderPattern: glob.IExpression): string[] { + const merged = { + ...(globalPattern || {}), + ...(folderPattern || {}) + }; + + return Object.keys(merged) + .filter(key => { + const value = merged[key]; + return typeof value === 'boolean' && value; + }); +} + +export class QueryGlobTester { + + private _excludeExpression: glob.IExpression; + private _parsedExcludeExpression: glob.ParsedExpression; + + private _parsedIncludeExpression: glob.ParsedExpression; + + constructor(config: ISearchQuery, folderQuery: IFolderQuery) { + this._excludeExpression = { + ...(config.excludePattern || {}), + ...(folderQuery.excludePattern || {}) + }; + this._parsedExcludeExpression = glob.parse(this._excludeExpression); + + // Empty includeExpression means include nothing, so no {} shortcuts + let includeExpression: glob.IExpression = config.includePattern; + if (folderQuery.includePattern) { + if (includeExpression) { + includeExpression = { + ...includeExpression, + ...folderQuery.includePattern + }; + } else { + includeExpression = folderQuery.includePattern; + } + } + + if (includeExpression) { + this._parsedIncludeExpression = glob.parse(includeExpression); + } + } + + /** + * Guaranteed sync - siblingsFn should not return a promise. + */ + public includedInQuerySync(testPath: string, basename?: string, hasSibling?: (name: string) => boolean): boolean { + if (this._parsedExcludeExpression && this._parsedExcludeExpression(testPath, basename, hasSibling)) { + return false; + } + + if (this._parsedIncludeExpression && !this._parsedIncludeExpression(testPath, basename, hasSibling)) { + return false; + } + + return true; + } + + /** + * Guaranteed async. + */ + public includedInQuery(testPath: string, basename?: string, hasSibling?: (name: string) => boolean | TPromise): TPromise { + const excludeP = this._parsedExcludeExpression ? + TPromise.as(this._parsedExcludeExpression(testPath, basename, hasSibling)).then(result => !!result) : + TPromise.wrap(false); + + return excludeP.then(excluded => { + if (excluded) { + return false; + } + + return this._parsedIncludeExpression ? + TPromise.as(this._parsedIncludeExpression(testPath, basename, hasSibling)).then(result => !!result) : + TPromise.wrap(true); + }).then(included => { + return included; + }); + } + + public hasSiblingExcludeClauses(): boolean { + return hasSiblingClauses(this._excludeExpression); + } +} + +function hasSiblingClauses(pattern: glob.IExpression): boolean { + for (let key in pattern) { + if (typeof pattern[key] !== 'boolean') { + return true; + } + } + + return false; +} + +export interface IDirectoryEntry { + base: URI; + relativePath: string; + basename: string; +} + +export interface IDirectoryTree { + rootEntries: IDirectoryEntry[]; + pathToEntries: { [relativePath: string]: IDirectoryEntry[] }; +} + +export class FileIndexSearchEngine { + private filePattern: string; + private normalizedFilePatternLowercase: string; + private includePattern: glob.ParsedExpression; + private maxResults: number; + private exists: boolean; + // private maxFilesize: number; + private isLimitHit: boolean; + private resultCount: number; + private isCanceled: boolean; + + private activeCancellationTokens: Set; + + // private filesWalked: number; + // private directoriesWalked: number; + + private globalExcludePattern: glob.ParsedExpression; + + constructor(private config: ISearchQuery, private provider: vscode.FileIndexProvider) { + this.filePattern = config.filePattern; + this.includePattern = config.includePattern && glob.parse(config.includePattern); + this.maxResults = config.maxResults || null; + this.exists = config.exists; + // this.maxFilesize = config.maxFileSize || null; + this.resultCount = 0; + this.isLimitHit = false; + this.activeCancellationTokens = new Set(); + + // this.filesWalked = 0; + // this.directoriesWalked = 0; + + if (this.filePattern) { + this.normalizedFilePatternLowercase = strings.stripWildcards(this.filePattern).toLowerCase(); + } + + this.globalExcludePattern = config.excludePattern && glob.parse(config.excludePattern); + } + + public cancel(): void { + this.isCanceled = true; + this.activeCancellationTokens.forEach(t => t.cancel()); + this.activeCancellationTokens = new Set(); + } + + public search(): PPromise<{ isLimitHit: boolean }, IInternalFileMatch> { + const folderQueries = this.config.folderQueries; + + return new PPromise<{ isLimitHit: boolean }, IInternalFileMatch>((resolve, reject, _onResult) => { + const onResult = (match: IInternalFileMatch) => { + this.resultCount++; + _onResult(match); + }; + + if (this.isCanceled) { + return resolve({ isLimitHit: this.isLimitHit }); + } + + // For each extra file + if (this.config.extraFileResources) { + this.config.extraFileResources + .forEach(extraFile => { + const extraFileStr = extraFile.toString(); // ? + const basename = path.basename(extraFileStr); + if (this.globalExcludePattern && this.globalExcludePattern(extraFileStr, basename)) { + return; // excluded + } + + // File: Check for match on file pattern and include pattern + this.matchFile(onResult, { base: extraFile, basename }); + }); + } + + // For each root folder + PPromise.join(folderQueries.map(fq => { + return this.searchInFolder(fq).then(null, null, onResult); + })).then(() => { + resolve({ isLimitHit: this.isLimitHit }); + }, (errs: Error[]) => { + const errMsg = errs + .map(err => toErrorMessage(err)) + .filter(msg => !!msg)[0]; + + reject(new Error(errMsg)); + }); + }); + } + + private searchInFolder(fq: IFolderQuery): PPromise { + let cancellation = new CancellationTokenSource(); + return new PPromise((resolve, reject, onResult) => { + const options = this.getSearchOptionsForFolder(fq); + const tree = this.initDirectoryTree(); + + const queryTester = new QueryGlobTester(this.config, fq); + const noSiblingsClauses = !queryTester.hasSiblingExcludeClauses(); + + const onProviderResult = (uri: URI) => { + if (this.isCanceled) { + return; + } + + // TODO@rob - ??? + const relativePath = path.relative(fq.folder.path, uri.path); + if (noSiblingsClauses) { + const basename = path.basename(uri.path); + this.matchFile(onResult, { base: fq.folder, relativePath, basename }); + + return; + } + + // TODO: Optimize siblings clauses with ripgrep here. + this.addDirectoryEntries(tree, fq.folder, relativePath, onResult); + }; + + new TPromise(resolve => process.nextTick(resolve)) + .then(() => { + this.activeCancellationTokens.add(cancellation); + return this.provider.provideFileIndex(options, cancellation.token); + }) + .then(results => { + this.activeCancellationTokens.delete(cancellation); + if (this.isCanceled) { + return null; + } + + results.forEach(onProviderResult); + + this.matchDirectoryTree(tree, queryTester, onResult); + return null; + }).then( + () => { + cancellation.dispose(); + resolve(undefined); + }, + err => { + cancellation.dispose(); + reject(err); + }); + }); + } + + private getSearchOptionsForFolder(fq: IFolderQuery): vscode.FileSearchOptions { + const includes = resolvePatternsForProvider(this.config.includePattern, fq.includePattern); + const excludes = resolvePatternsForProvider(this.config.excludePattern, fq.excludePattern); + + return { + folder: fq.folder, + excludes, + includes, + useIgnoreFiles: !this.config.disregardIgnoreFiles, + followSymlinks: !this.config.ignoreSymlinks + }; + } + + private initDirectoryTree(): IDirectoryTree { + const tree: IDirectoryTree = { + rootEntries: [], + pathToEntries: Object.create(null) + }; + tree.pathToEntries['.'] = tree.rootEntries; + return tree; + } + + private addDirectoryEntries({ pathToEntries }: IDirectoryTree, base: URI, relativeFile: string, onResult: (result: IInternalFileMatch) => void) { + // Support relative paths to files from a root resource (ignores excludes) + if (relativeFile === this.filePattern) { + const basename = path.basename(this.filePattern); + this.matchFile(onResult, { base: base, relativePath: this.filePattern, basename }); + } + + function add(relativePath: string) { + const basename = path.basename(relativePath); + const dirname = path.dirname(relativePath); + let entries = pathToEntries[dirname]; + if (!entries) { + entries = pathToEntries[dirname] = []; + add(dirname); + } + entries.push({ + base, + relativePath, + basename + }); + } + + add(relativeFile); + } + + private matchDirectoryTree({ rootEntries, pathToEntries }: IDirectoryTree, queryTester: QueryGlobTester, onResult: (result: IInternalFileMatch) => void) { + const self = this; + const filePattern = this.filePattern; + function matchDirectory(entries: IDirectoryEntry[]) { + // self.directoriesWalked++; + for (let i = 0, n = entries.length; i < n; i++) { + const entry = entries[i]; + const { relativePath, basename } = entry; + + // Check exclude pattern + // If the user searches for the exact file name, we adjust the glob matching + // to ignore filtering by siblings because the user seems to know what she + // is searching for and we want to include the result in that case anyway + const hasSibling = glob.hasSiblingFn(() => entries.map(entry => entry.basename)); + if (!queryTester.includedInQuerySync(relativePath, basename, filePattern !== basename ? hasSibling : undefined)) { + continue; + } + + const sub = pathToEntries[relativePath]; + if (sub) { + matchDirectory(sub); + } else { + // self.filesWalked++; + if (relativePath === filePattern) { + continue; // ignore file if its path matches with the file pattern because that is already matched above + } + + self.matchFile(onResult, entry); + } + + if (self.isLimitHit) { + break; + } + } + } + matchDirectory(rootEntries); + } + + public getStats(): any { + return null; + // return { + // fromCache: false, + // traversal: Traversal[this.traversal], + // errors: this.errors, + // fileWalkStartTime: this.fileWalkStartTime, + // fileWalkResultTime: Date.now(), + // directoriesWalked: this.directoriesWalked, + // filesWalked: this.filesWalked, + // resultCount: this.resultCount, + // cmdForkResultTime: this.cmdForkResultTime, + // cmdResultCount: this.cmdResultCount + // }; + } + + private matchFile(onResult: (result: IInternalFileMatch) => void, candidate: IInternalFileMatch): void { + if (this.isFilePatternMatch(candidate.relativePath) && (!this.includePattern || this.includePattern(candidate.relativePath, candidate.basename))) { + if (this.exists || (this.maxResults && this.resultCount >= this.maxResults)) { + this.isLimitHit = true; + this.cancel(); + } + + if (!this.isLimitHit) { + onResult(candidate); + } + } + } + + private isFilePatternMatch(path: string): boolean { + // Check for search pattern + if (this.filePattern) { + if (this.filePattern === '*') { + return true; // support the all-matching wildcard + } + + return strings.fuzzyContains(path, this.normalizedFilePatternLowercase); + } + + // No patterns means we match all + return true; + } +} + +export class FileIndexSearchManager { + + private static readonly BATCH_SIZE = 512; + + private caches: { [cacheKey: string]: Cache; } = Object.create(null); + + public fileSearch(config: ISearchQuery, provider: vscode.FileIndexProvider, onResult: (matches: IFileMatch[]) => void): TPromise { + if (config.sortByScore) { + let sortedSearch = this.trySortedSearchFromCache(config); + if (!sortedSearch) { + const engineConfig = config.maxResults ? + { + ...config, + ...{ maxResults: null } + } : + config; + + const engine = new FileIndexSearchEngine(engineConfig, provider); + sortedSearch = this.doSortedSearch(engine, provider, config); + } + + return new TPromise((c, e) => { + process.nextTick(() => { // allow caller to register progress callback first + sortedSearch.then(([result, rawMatches]) => { + const serializedMatches = rawMatches.map(rawMatch => this.rawMatchToSearchItem(rawMatch)); + this.sendProgress(serializedMatches, onResult, FileIndexSearchManager.BATCH_SIZE); + c(result); + }, e, onResult); + }); + }, () => { + sortedSearch.cancel(); + }); + } + + let searchPromise: TPromise; + return new TPromise((c, e) => { + const engine = new FileIndexSearchEngine(config, provider); + searchPromise = this.doSearch(engine, provider, FileIndexSearchManager.BATCH_SIZE) + .then(c, e, progress => { + if (Array.isArray(progress)) { + onResult(progress.map(m => this.rawMatchToSearchItem(m))); + } else if ((progress).relativePath) { + onResult([this.rawMatchToSearchItem(progress)]); + } + }); + }, () => { + searchPromise.cancel(); + }); + } + + private rawMatchToSearchItem(match: IInternalFileMatch): IFileMatch { + return { + resource: resources.joinPath(match.base, match.relativePath) + }; + } + + private doSortedSearch(engine: FileIndexSearchEngine, provider: vscode.FileIndexProvider, config: IRawSearchQuery): PPromise<[ISearchCompleteStats, IInternalFileMatch[]]> { + let searchPromise: PPromise; + let allResultsPromise = new PPromise<[ISearchCompleteStats, IInternalFileMatch[]], IInternalFileMatch[]>((c, e, p) => { + let results: IInternalFileMatch[] = []; + searchPromise = this.doSearch(engine, provider, -1) + .then(result => { + c([result, results]); + }, e, progress => { + if (Array.isArray(progress)) { + results = progress; + } else { + p(progress); + } + }); + }, () => { + searchPromise.cancel(); + }); + + let cache: Cache; + if (config.cacheKey) { + cache = this.getOrCreateCache(config.cacheKey); + cache.resultsToSearchCache[config.filePattern] = allResultsPromise; + allResultsPromise.then(null, err => { + delete cache.resultsToSearchCache[config.filePattern]; + }); + allResultsPromise = this.preventCancellation(allResultsPromise); + } + + let chained: TPromise; + return new PPromise<[ISearchCompleteStats, IInternalFileMatch[]]>((c, e, p) => { + chained = allResultsPromise.then(([result, results]) => { + const scorerCache: ScorerCache = cache ? cache.scorerCache : Object.create(null); + const unsortedResultTime = Date.now(); + return this.sortResults(config, results, scorerCache) + .then(sortedResults => { + const sortedResultTime = Date.now(); + + c([{ + stats: { + ...result.stats, + ...{ unsortedResultTime, sortedResultTime } + }, + limitHit: result.limitHit || typeof config.maxResults === 'number' && results.length > config.maxResults + }, sortedResults]); + }); + }, e, p); + }, () => { + chained.cancel(); + }); + } + + private getOrCreateCache(cacheKey: string): Cache { + const existing = this.caches[cacheKey]; + if (existing) { + return existing; + } + return this.caches[cacheKey] = new Cache(); + } + + private trySortedSearchFromCache(config: IRawSearchQuery): TPromise<[ISearchCompleteStats, IInternalFileMatch[]]> { + const cache = config.cacheKey && this.caches[config.cacheKey]; + if (!cache) { + return undefined; + } + + const cacheLookupStartTime = Date.now(); + const cached = this.getResultsFromCache(cache, config.filePattern); + if (cached) { + let chained: TPromise; + return new TPromise<[ISearchCompleteStats, IInternalFileMatch[]]>((c, e) => { + chained = cached.then(([result, results, cacheStats]) => { + const cacheLookupResultTime = Date.now(); + return this.sortResults(config, results, cache.scorerCache) + .then(sortedResults => { + const sortedResultTime = Date.now(); + + const stats: ICachedSearchStats = { + fromCache: true, + cacheLookupStartTime: cacheLookupStartTime, + cacheFilterStartTime: cacheStats.cacheFilterStartTime, + cacheLookupResultTime: cacheLookupResultTime, + cacheEntryCount: cacheStats.cacheFilterResultCount, + resultCount: results.length + }; + if (config.sortByScore) { + stats.unsortedResultTime = cacheLookupResultTime; + stats.sortedResultTime = sortedResultTime; + } + if (!cacheStats.cacheWasResolved) { + stats.joined = result.stats; + } + c([ + { + limitHit: result.limitHit || typeof config.maxResults === 'number' && results.length > config.maxResults, + stats: stats + }, + sortedResults + ]); + }); + }, e); + }, () => { + chained.cancel(); + }); + } + return undefined; + } + + private sortResults(config: IRawSearchQuery, results: IInternalFileMatch[], scorerCache: ScorerCache): TPromise { + // we use the same compare function that is used later when showing the results using fuzzy scoring + // this is very important because we are also limiting the number of results by config.maxResults + // and as such we want the top items to be included in this result set if the number of items + // exceeds config.maxResults. + const query = prepareQuery(config.filePattern); + const compare = (matchA: IInternalFileMatch, matchB: IInternalFileMatch) => compareItemsByScore(matchA, matchB, query, true, FileMatchItemAccessor, scorerCache); + + return arrays.topAsync(results, compare, config.maxResults, 10000); + } + + private sendProgress(results: IFileMatch[], progressCb: (batch: IFileMatch[]) => void, batchSize: number) { + if (batchSize && batchSize > 0) { + for (let i = 0; i < results.length; i += batchSize) { + progressCb(results.slice(i, i + batchSize)); + } + } else { + progressCb(results); + } + } + + private getResultsFromCache(cache: Cache, searchValue: string): PPromise<[ISearchCompleteStats, IInternalFileMatch[], CacheStats]> { + if (path.isAbsolute(searchValue)) { + return null; // bypass cache if user looks up an absolute path where matching goes directly on disk + } + + // Find cache entries by prefix of search value + const hasPathSep = searchValue.indexOf(path.sep) >= 0; + let cached: PPromise<[ISearchCompleteStats, IInternalFileMatch[]], IInternalFileMatch[]>; + let wasResolved: boolean; + for (let previousSearch in cache.resultsToSearchCache) { + + // If we narrow down, we might be able to reuse the cached results + if (strings.startsWith(searchValue, previousSearch)) { + if (hasPathSep && previousSearch.indexOf(path.sep) < 0) { + continue; // since a path character widens the search for potential more matches, require it in previous search too + } + + const c = cache.resultsToSearchCache[previousSearch]; + c.then(() => { wasResolved = false; }); + wasResolved = true; + cached = this.preventCancellation(c); + break; + } + } + + if (!cached) { + return null; + } + + return new PPromise<[ISearchCompleteStats, IInternalFileMatch[], CacheStats]>((c, e, p) => { + cached.then(([complete, cachedEntries]) => { + const cacheFilterStartTime = Date.now(); + + // Pattern match on results + let results: IInternalFileMatch[] = []; + const normalizedSearchValueLowercase = strings.stripWildcards(searchValue).toLowerCase(); + for (let i = 0; i < cachedEntries.length; i++) { + let entry = cachedEntries[i]; + + // Check if this entry is a match for the search value + if (!strings.fuzzyContains(entry.relativePath, normalizedSearchValueLowercase)) { + continue; + } + + results.push(entry); + } + + c([complete, results, { + cacheWasResolved: wasResolved, + cacheFilterStartTime: cacheFilterStartTime, + cacheFilterResultCount: cachedEntries.length + }]); + }, e, p); + }, () => { + cached.cancel(); + }); + } + + private doSearch(engine: FileIndexSearchEngine, provider: vscode.FileIndexProvider, batchSize?: number): PPromise { + return new PPromise((c, e, p) => { + let batch: IInternalFileMatch[] = []; + engine.search().then(result => { + if (batch.length) { + p(batch); + } + + c({ + limitHit: result.isLimitHit, + stats: engine.getStats() // TODO@roblou + }); + }, error => { + if (batch.length) { + p(batch); + } + + e(error); + }, match => { + if (match) { + if (batchSize) { + batch.push(match); + if (batchSize > 0 && batch.length >= batchSize) { + p(batch); + batch = []; + } + } else { + p([match]); + } + } + }); + }, () => { + engine.cancel(); + }); + } + + public clearCache(cacheKey: string): TPromise { + delete this.caches[cacheKey]; + return TPromise.as(undefined); + } + + private preventCancellation(promise: PPromise): PPromise { + return new PPromise((c, e, p) => { + // Allow for piled up cancellations to come through first. + process.nextTick(() => { + promise.then(c, e, p); + }); + }, () => { + // Do not propagate. + }); + } +} + +class Cache { + + public resultsToSearchCache: { [searchValue: string]: PPromise<[ISearchCompleteStats, IInternalFileMatch[]], IInternalFileMatch[]>; } = Object.create(null); + + public scorerCache: ScorerCache = Object.create(null); +} + +const FileMatchItemAccessor = new class implements IItemAccessor { + + public getItemLabel(match: IInternalFileMatch): string { + return match.basename; // e.g. myFile.txt + } + + public getItemDescription(match: IInternalFileMatch): string { + return match.relativePath.substr(0, match.relativePath.length - match.basename.length - 1); // e.g. some/path/to/file + } + + public getItemPath(match: IInternalFileMatch): string { + return match.relativePath; // e.g. some/path/to/file/myFile.txt + } +}; + +interface CacheStats { + cacheWasResolved: boolean; + cacheFilterStartTime: number; + cacheFilterResultCount: number; +} diff --git a/src/vs/workbench/api/node/extHostSearch.ts b/src/vs/workbench/api/node/extHostSearch.ts index dc0a664b713..fa38ac0c8ca 100644 --- a/src/vs/workbench/api/node/extHostSearch.ts +++ b/src/vs/workbench/api/node/extHostSearch.ts @@ -16,6 +16,7 @@ import { IFileMatch, IFolderQuery, IPatternInfo, IRawSearchQuery, ISearchComplet import * as vscode from 'vscode'; import { ExtHostSearchShape, IMainContext, MainContext, MainThreadSearchShape } from './extHost.protocol'; import { toDisposable } from 'vs/base/common/lifecycle'; +import { IInternalFileMatch, QueryGlobTester, resolvePatternsForProvider, IDirectoryTree, IDirectoryEntry, FileIndexSearchManager } from 'vs/workbench/api/node/extHostSearch.fileIndex'; export interface ISchemeTransformer { transformOutgoing(scheme: string): string; @@ -24,15 +25,18 @@ export interface ISchemeTransformer { export class ExtHostSearch implements ExtHostSearchShape { private readonly _proxy: MainThreadSearchShape; - private readonly _searchProvider = new Map(); + private readonly _fileSearchProvider = new Map(); private readonly _textSearchProvider = new Map(); + private readonly _fileIndexProvider = new Map(); private _handlePool: number = 0; private _fileSearchManager: FileSearchManager; + private _fileIndexSearchManager: FileIndexSearchManager; constructor(mainContext: IMainContext, private _schemeTransformer: ISchemeTransformer, private _extfs = extfs) { this._proxy = mainContext.getProxy(MainContext.MainThreadSearch); this._fileSearchManager = new FileSearchManager(); + this._fileIndexSearchManager = new FileIndexSearchManager(); } private _transformScheme(scheme: string): string { @@ -42,12 +46,12 @@ export class ExtHostSearch implements ExtHostSearchShape { return scheme; } - registerSearchProvider(scheme: string, provider: vscode.SearchProvider) { + registerFileSearchProvider(scheme: string, provider: vscode.SearchProvider) { const handle = this._handlePool++; - this._searchProvider.set(handle, provider); - this._proxy.$registerSearchProvider(handle, this._transformScheme(scheme)); + this._fileSearchProvider.set(handle, provider); + this._proxy.$registerFileSearchProvider(handle, this._transformScheme(scheme)); return toDisposable(() => { - this._searchProvider.delete(handle); + this._fileSearchProvider.delete(handle); this._proxy.$unregisterProvider(handle); }); } @@ -55,27 +59,44 @@ export class ExtHostSearch implements ExtHostSearchShape { registerTextSearchProvider(scheme: string, provider: vscode.TextSearchProvider) { const handle = this._handlePool++; this._textSearchProvider.set(handle, provider); - this._proxy.$registerSearchProvider(handle, this._transformScheme(scheme)); + this._proxy.$registerTextSearchProvider(handle, this._transformScheme(scheme)); return toDisposable(() => { - this._searchProvider.delete(handle); + this._textSearchProvider.delete(handle); this._proxy.$unregisterProvider(handle); }); } - $provideFileSearchResults(handle: number, session: number, rawQuery: IRawSearchQuery): TPromise { - const provider = this._searchProvider.get(handle); - if (!provider.provideFileSearchResults) { - return TPromise.as(undefined); - } - - const query = reviveQuery(rawQuery); - return this._fileSearchManager.fileSearch(query, provider, progress => { - this._proxy.$handleFileMatch(handle, session, progress.map(p => p.resource)); + registerFileIndexProvider(scheme: string, provider: vscode.FileIndexProvider) { + const handle = this._handlePool++; + this._fileIndexProvider.set(handle, provider); + this._proxy.$registerFileIndexProvider(handle, this._transformScheme(scheme)); + return toDisposable(() => { + this._fileSearchProvider.delete(handle); + this._proxy.$unregisterProvider(handle); // TODO@roblou - unregisterFileIndexProvider }); } + $provideFileSearchResults(handle: number, session: number, rawQuery: IRawSearchQuery): TPromise { + const provider = this._fileSearchProvider.get(handle); + const query = reviveQuery(rawQuery); + if (provider) { + return this._fileSearchManager.fileSearch(query, provider, progress => { + this._proxy.$handleFileMatch(handle, session, progress.map(p => p.resource)); + }); + } else { + const indexProvider = this._fileIndexProvider.get(handle); + if (indexProvider) { + return this._fileIndexSearchManager.fileSearch(query, indexProvider, progress => { + this._proxy.$handleFileMatch(handle, session, progress.map(p => p.resource)); + }); + } else { + throw new Error('something went wrong'); + } + } + } + $clearCache(handle: number, cacheKey: string): TPromise { - const provider = this._searchProvider.get(handle); + const provider = this._fileSearchProvider.get(handle); if (!provider.clearCache) { return TPromise.as(undefined); } @@ -96,22 +117,6 @@ export class ExtHostSearch implements ExtHostSearchShape { } } -/** - * Computes the patterns that the provider handles. Discards sibling clauses and 'false' patterns - */ -function resolvePatternsForProvider(globalPattern: glob.IExpression, folderPattern: glob.IExpression): string[] { - const merged = { - ...(globalPattern || {}), - ...(folderPattern || {}) - }; - - return Object.keys(merged) - .filter(key => { - const value = merged[key]; - return typeof value === 'boolean' && value; - }); -} - function reviveQuery(rawQuery: IRawSearchQuery): ISearchQuery { return { ...rawQuery, @@ -264,107 +269,6 @@ class BatchedCollector { } } -interface IDirectoryEntry { - base: URI; - relativePath: string; - basename: string; -} - -interface IDirectoryTree { - rootEntries: IDirectoryEntry[]; - pathToEntries: { [relativePath: string]: IDirectoryEntry[] }; -} - -interface IInternalFileMatch { - base: URI; - relativePath?: string; // Not present for extraFiles or absolute path matches - basename: string; - size?: number; -} - -class QueryGlobTester { - - private _excludeExpression: glob.IExpression; - private _parsedExcludeExpression: glob.ParsedExpression; - - private _parsedIncludeExpression: glob.ParsedExpression; - - constructor(config: ISearchQuery, folderQuery: IFolderQuery) { - this._excludeExpression = { - ...(config.excludePattern || {}), - ...(folderQuery.excludePattern || {}) - }; - this._parsedExcludeExpression = glob.parse(this._excludeExpression); - - // Empty includeExpression means include nothing, so no {} shortcuts - let includeExpression: glob.IExpression = config.includePattern; - if (folderQuery.includePattern) { - if (includeExpression) { - includeExpression = { - ...includeExpression, - ...folderQuery.includePattern - }; - } else { - includeExpression = folderQuery.includePattern; - } - } - - if (includeExpression) { - this._parsedIncludeExpression = glob.parse(includeExpression); - } - } - - /** - * Guaranteed sync - siblingsFn should not return a promise. - */ - public includedInQuerySync(testPath: string, basename?: string, hasSibling?: (name: string) => boolean): boolean { - if (this._parsedExcludeExpression && this._parsedExcludeExpression(testPath, basename, hasSibling)) { - return false; - } - - if (this._parsedIncludeExpression && !this._parsedIncludeExpression(testPath, basename, hasSibling)) { - return false; - } - - return true; - } - - /** - * Guaranteed async. - */ - public includedInQuery(testPath: string, basename?: string, hasSibling?: (name: string) => boolean | TPromise): TPromise { - const excludeP = this._parsedExcludeExpression ? - TPromise.as(this._parsedExcludeExpression(testPath, basename, hasSibling)).then(result => !!result) : - TPromise.wrap(false); - - return excludeP.then(excluded => { - if (excluded) { - return false; - } - - return this._parsedIncludeExpression ? - TPromise.as(this._parsedIncludeExpression(testPath, basename, hasSibling)).then(result => !!result) : - TPromise.wrap(true); - }).then(included => { - return included; - }); - } - - public hasSiblingExcludeClauses(): boolean { - return hasSiblingClauses(this._excludeExpression); - } -} - -function hasSiblingClauses(pattern: glob.IExpression): boolean { - for (let key in pattern) { - if (typeof pattern[key] !== 'boolean') { - return true; - } - } - - return false; -} - class TextSearchEngine { private activeCancellationTokens = new Set(); diff --git a/src/vs/workbench/services/search/node/searchService.ts b/src/vs/workbench/services/search/node/searchService.ts index dad4ec17770..ff28bf7d56c 100644 --- a/src/vs/workbench/services/search/node/searchService.ts +++ b/src/vs/workbench/services/search/node/searchService.ts @@ -20,7 +20,7 @@ import { IModelService } from 'vs/editor/common/services/modelService'; import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; import { IDebugParams, IEnvironmentService } from 'vs/platform/environment/common/environment'; import { ILogService } from 'vs/platform/log/common/log'; -import { FileMatch, IFileMatch, IFolderQuery, IProgress, ISearchComplete, ISearchConfiguration, ISearchProgressItem, ISearchQuery, ISearchResultProvider, ISearchService, LineMatch, pathIncludedInQuery, QueryType } from 'vs/platform/search/common/search'; +import { FileMatch, IFileMatch, IFolderQuery, IProgress, ISearchComplete, ISearchConfiguration, ISearchProgressItem, ISearchQuery, ISearchResultProvider, ISearchService, LineMatch, pathIncludedInQuery, QueryType, SearchProviderType } from 'vs/platform/search/common/search'; import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry'; import { IExtensionService } from 'vs/workbench/services/extensions/common/extensions'; import { IUntitledEditorService } from 'vs/workbench/services/untitled/common/untitledEditorService'; @@ -31,8 +31,9 @@ export class SearchService extends Disposable implements ISearchService { public _serviceBrand: any; private diskSearch: DiskSearch; - private readonly searchProviders: ISearchResultProvider[] = []; - private fileSearchProvider: ISearchResultProvider; + private readonly fileSearchProviders = new Map(); + private readonly textSearchProviders = new Map(); + private readonly fileIndexProviders = new Map(); constructor( @IModelService private modelService: IModelService, @@ -50,22 +51,23 @@ export class SearchService extends Disposable implements ISearchService { })); } - public registerSearchResultProvider(scheme: string, provider: ISearchResultProvider): IDisposable { - if (scheme === 'file') { - this.fileSearchProvider = provider; - } else { - this.searchProviders.push(provider); + public registerSearchResultProvider(scheme: string, type: SearchProviderType, provider: ISearchResultProvider): IDisposable { + // if (scheme === 'file') { + // this.fileSearchProvider = provider; + + let list: Map; + if (type === SearchProviderType.file) { + list = this.fileSearchProviders; + } else if (type === SearchProviderType.text) { + list = this.textSearchProviders; + } else if (type === SearchProviderType.fileIndex) { + list = this.fileIndexProviders; } + list.set(scheme, provider); + return toDisposable(() => { - if (scheme === 'file') { - this.fileSearchProvider = null; - } else { - const idx = this.searchProviders.indexOf(provider); - if (idx >= 0) { - this.searchProviders.splice(idx, 1); - } - } + list.delete(scheme); }); } @@ -122,38 +124,43 @@ export class SearchService extends Disposable implements ISearchService { }; const startTime = Date.now(); - const searchWithProvider = (provider: ISearchResultProvider) => TPromise.as(provider.search(query, onProviderProgress)); const schemesInQuery = query.folderQueries.map(fq => fq.folder.scheme); const providerActivations = schemesInQuery.map(scheme => this.extensionService.activateByEvent(`onSearch:${scheme}`)); const providerPromise = TPromise.join(providerActivations).then(() => { - // TODO@roblou this is not properly waiting for search-rg to finish registering itself - // If no search provider has been registered for the 'file' schema, fall back on DiskSearch - const providers = [ - this.fileSearchProvider || this.diskSearch, - ...this.searchProviders - ]; - return TPromise.join(providers.map(p => searchWithProvider(p))) - .then(completes => { - completes = completes.filter(c => !!c); - if (!completes.length) { - return null; + return TPromise.join(query.folderQueries.map(fq => { + const oneFolderQuery = { + ...query, + ...{ + folderQueries: [fq] } + }; - return { - limitHit: completes[0] && completes[0].limitHit, - stats: completes[0].stats, - results: arrays.flatten(completes.map(c => c.results)) - }; - }, errs => { - if (!Array.isArray(errs)) { - errs = [errs]; - } + const provider = query.type === QueryType.File ? + this.fileSearchProviders.get(fq.folder.scheme) || this.fileIndexProviders.get(fq.folder.scheme) : + this.textSearchProviders.get(fq.folder.scheme); - errs = errs.filter(e => !!e); - return TPromise.wrapError(errs[0]); - }); + return TPromise.as(provider.search(oneFolderQuery, onProviderProgress)); + })).then(completes => { + completes = completes.filter(c => !!c); + if (!completes.length) { + return null; + } + + return { + limitHit: completes[0] && completes[0].limitHit, + stats: completes[0].stats, + results: arrays.flatten(completes.map(c => c.results)) + }; + }, errs => { + if (!Array.isArray(errs)) { + errs = [errs]; + } + + errs = errs.filter(e => !!e); + return TPromise.wrapError(errs[0]); + }); }); combinedPromise = providerPromise.then(value => { @@ -262,8 +269,6 @@ export class SearchService extends Disposable implements ISearchService { public clearCache(cacheKey: string): TPromise { return TPromise.join([ - ...this.searchProviders, - this.fileSearchProvider, this.diskSearch ].map(provider => provider && provider.clearCache(cacheKey))) .then(() => { }); diff --git a/src/vs/workbench/test/electron-browser/api/extHostSearch.test.ts b/src/vs/workbench/test/electron-browser/api/extHostSearch.test.ts index a0f9038ea06..f5bfd49e626 100644 --- a/src/vs/workbench/test/electron-browser/api/extHostSearch.test.ts +++ b/src/vs/workbench/test/electron-browser/api/extHostSearch.test.ts @@ -28,7 +28,11 @@ class MockMainThreadSearch implements MainThreadSearchShape { results: (UriComponents | IRawFileMatch2)[] = []; - $registerSearchProvider(handle: number, scheme: string): void { + $registerFileSearchProvider(handle: number, scheme: string): void { + this.lastHandle = handle; + } + + $registerFileIndexProvider(handle: number, scheme: string): void { this.lastHandle = handle; } @@ -62,8 +66,8 @@ suite('ExtHostSearch', () => { await rpcProtocol.sync(); } - async function registerTestSearchProvider(provider: vscode.SearchProvider, scheme = 'file'): Promise { - disposables.push(extHostSearch.registerSearchProvider(scheme, provider)); + async function registerTestFileSearchProvider(provider: vscode.SearchProvider, scheme = 'file'): Promise { + disposables.push(extHostSearch.registerFileSearchProvider(scheme, provider)); await rpcProtocol.sync(); } @@ -162,7 +166,7 @@ suite('ExtHostSearch', () => { } test('no results', async () => { - await registerTestSearchProvider({ + await registerTestFileSearchProvider({ provideFileSearchResults(query: vscode.FileSearchQuery, options: vscode.FileSearchOptions, progress: vscode.Progress, token: vscode.CancellationToken): Thenable { return TPromise.wrap(null); } @@ -180,7 +184,7 @@ suite('ExtHostSearch', () => { joinPath(rootFolderA, 'file3.ts') ]; - await registerTestSearchProvider({ + await registerTestFileSearchProvider({ provideFileSearchResults(query: vscode.FileSearchQuery, options: vscode.FileSearchOptions, progress: vscode.Progress, token: vscode.CancellationToken): Thenable { reportedResults.forEach(r => progress.report(r)); return TPromise.wrap(null); @@ -195,7 +199,7 @@ suite('ExtHostSearch', () => { test('Search canceled', async () => { let cancelRequested = false; - await registerTestSearchProvider({ + await registerTestFileSearchProvider({ provideFileSearchResults(query: vscode.FileSearchQuery, options: vscode.FileSearchOptions, progress: vscode.Progress, token: vscode.CancellationToken): Thenable { return new TPromise((resolve, reject) => { token.onCancellationRequested(() => { @@ -220,7 +224,7 @@ suite('ExtHostSearch', () => { 'file3.ts', ]; - await registerTestSearchProvider({ + await registerTestFileSearchProvider({ provideFileSearchResults(query: vscode.FileSearchQuery, options: vscode.FileSearchOptions, progress: vscode.Progress, token: vscode.CancellationToken): Thenable { reportedResults .map(relativePath => joinPath(options.folder, relativePath)) @@ -239,7 +243,7 @@ suite('ExtHostSearch', () => { }); test('provider returns null', async () => { - await registerTestSearchProvider({ + await registerTestFileSearchProvider({ provideFileSearchResults(query: vscode.FileSearchQuery, options: vscode.FileSearchOptions, progress: vscode.Progress, token: vscode.CancellationToken): Thenable { return null; } @@ -254,7 +258,7 @@ suite('ExtHostSearch', () => { }); test('all provider calls get global include/excludes', async () => { - await registerTestSearchProvider({ + await registerTestFileSearchProvider({ provideFileSearchResults(query: vscode.FileSearchQuery, options: vscode.FileSearchOptions, progress: vscode.Progress, token: vscode.CancellationToken): Thenable { assert(options.excludes.length === 2 && options.includes.length === 2, 'Missing global include/excludes'); return TPromise.wrap(null); @@ -283,7 +287,7 @@ suite('ExtHostSearch', () => { }); test('global/local include/excludes combined', async () => { - await registerTestSearchProvider({ + await registerTestFileSearchProvider({ provideFileSearchResults(query: vscode.FileSearchQuery, options: vscode.FileSearchOptions, progress: vscode.Progress, token: vscode.CancellationToken): Thenable { if (options.folder.toString() === rootFolderA.toString()) { assert.deepEqual(options.includes.sort(), ['*.ts', 'foo']); @@ -325,7 +329,7 @@ suite('ExtHostSearch', () => { }); test('include/excludes resolved correctly', async () => { - await registerTestSearchProvider({ + await registerTestFileSearchProvider({ provideFileSearchResults(query: vscode.FileSearchQuery, options: vscode.FileSearchOptions, progress: vscode.Progress, token: vscode.CancellationToken): Thenable { assert.deepEqual(options.includes.sort(), ['*.jsx', '*.ts']); assert.deepEqual(options.excludes.sort(), []); @@ -368,7 +372,7 @@ suite('ExtHostSearch', () => { 'file1.js', ]; - await registerTestSearchProvider({ + await registerTestFileSearchProvider({ provideFileSearchResults(query: vscode.FileSearchQuery, options: vscode.FileSearchOptions, progress: vscode.Progress, token: vscode.CancellationToken): Thenable { reportedResults .map(relativePath => joinPath(options.folder, relativePath)) @@ -401,7 +405,7 @@ suite('ExtHostSearch', () => { test('multiroot sibling exclude clause', async () => { - await registerTestSearchProvider({ + await registerTestFileSearchProvider({ provideFileSearchResults(query: vscode.FileSearchQuery, options: vscode.FileSearchOptions, progress: vscode.Progress, token: vscode.CancellationToken): Thenable { let reportedResults: URI[]; if (options.folder.fsPath === rootFolderA.fsPath) { @@ -472,7 +476,7 @@ suite('ExtHostSearch', () => { ]; let wasCanceled = false; - await registerTestSearchProvider({ + await registerTestFileSearchProvider({ provideFileSearchResults(query: vscode.FileSearchQuery, options: vscode.FileSearchOptions, progress: vscode.Progress, token: vscode.CancellationToken): Thenable { reportedResults .forEach(r => progress.report(r)); @@ -510,7 +514,7 @@ suite('ExtHostSearch', () => { ]; let wasCanceled = false; - await registerTestSearchProvider({ + await registerTestFileSearchProvider({ provideFileSearchResults(query: vscode.FileSearchQuery, options: vscode.FileSearchOptions, progress: vscode.Progress, token: vscode.CancellationToken): Thenable { reportedResults.forEach(r => progress.report(r)); token.onCancellationRequested(() => wasCanceled = true); @@ -546,7 +550,7 @@ suite('ExtHostSearch', () => { ]; let wasCanceled = false; - await registerTestSearchProvider({ + await registerTestFileSearchProvider({ provideFileSearchResults(query: vscode.FileSearchQuery, options: vscode.FileSearchOptions, progress: vscode.Progress, token: vscode.CancellationToken): Thenable { reportedResults.forEach(r => progress.report(r)); token.onCancellationRequested(() => wasCanceled = true); @@ -577,7 +581,7 @@ suite('ExtHostSearch', () => { test('multiroot max results', async () => { let cancels = 0; - await registerTestSearchProvider({ + await registerTestFileSearchProvider({ provideFileSearchResults(query: vscode.FileSearchQuery, options: vscode.FileSearchOptions, progress: vscode.Progress, token: vscode.CancellationToken): Thenable { token.onCancellationRequested(() => cancels++); @@ -623,7 +627,7 @@ suite('ExtHostSearch', () => { ]; - await registerTestSearchProvider({ + await registerTestFileSearchProvider({ provideFileSearchResults(query: vscode.FileSearchQuery, options: vscode.FileSearchOptions, progress: vscode.Progress, token: vscode.CancellationToken): Thenable { reportedResults.forEach(r => progress.report(r)); return TPromise.wrap(null); @@ -646,7 +650,7 @@ suite('ExtHostSearch', () => { test('uses different cache keys for different folders', async () => { const cacheKeys: string[] = []; - await registerTestSearchProvider({ + await registerTestFileSearchProvider({ provideFileSearchResults(query: vscode.FileSearchQuery, options: vscode.FileSearchOptions, progress: vscode.Progress, token: vscode.CancellationToken): Thenable { cacheKeys.push(query.cacheKey); return TPromise.wrap(null); From 28fd1cc00707e3958234cb347bd62efa873d132e Mon Sep 17 00:00:00 2001 From: Rob Lourens Date: Thu, 26 Jul 2018 11:20:59 -0700 Subject: [PATCH 0187/1276] Search provider - clean up file index search, remove PPromise --- .../api/node/extHostSearch.fileIndex.ts | 254 ++++++------------ src/vs/workbench/api/node/extHostSearch.ts | 8 +- 2 files changed, 93 insertions(+), 169 deletions(-) diff --git a/src/vs/workbench/api/node/extHostSearch.fileIndex.ts b/src/vs/workbench/api/node/extHostSearch.fileIndex.ts index 1cfb58fc324..0f45ba422ea 100644 --- a/src/vs/workbench/api/node/extHostSearch.fileIndex.ts +++ b/src/vs/workbench/api/node/extHostSearch.fileIndex.ts @@ -12,9 +12,9 @@ import * as glob from 'vs/base/common/glob'; import * as resources from 'vs/base/common/resources'; import * as strings from 'vs/base/common/strings'; import URI from 'vs/base/common/uri'; -import { PPromise, TPromise } from 'vs/base/common/winjs.base'; +import { TPromise } from 'vs/base/common/winjs.base'; import { compareItemsByScore, IItemAccessor, prepareQuery, ScorerCache } from 'vs/base/parts/quickopen/common/quickOpenScorer'; -import { ICachedSearchStats, IFileMatch, IFolderQuery, IRawSearchQuery, ISearchCompleteStats, ISearchQuery } from 'vs/platform/search/common/search'; +import { IFileMatch, IFolderQuery, IRawSearchQuery, ISearchCompleteStats, ISearchQuery } from 'vs/platform/search/common/search'; import * as vscode from 'vscode'; export interface IInternalFileMatch { @@ -134,22 +134,24 @@ export interface IDirectoryTree { pathToEntries: { [relativePath: string]: IDirectoryEntry[] }; } +// ??? +interface IInternalSearchComplete { + limitHit: boolean; + results: IInternalFileMatch[]; +} + export class FileIndexSearchEngine { private filePattern: string; private normalizedFilePatternLowercase: string; private includePattern: glob.ParsedExpression; private maxResults: number; private exists: boolean; - // private maxFilesize: number; private isLimitHit: boolean; private resultCount: number; private isCanceled: boolean; private activeCancellationTokens: Set; - // private filesWalked: number; - // private directoriesWalked: number; - private globalExcludePattern: glob.ParsedExpression; constructor(private config: ISearchQuery, private provider: vscode.FileIndexProvider) { @@ -157,14 +159,10 @@ export class FileIndexSearchEngine { this.includePattern = config.includePattern && glob.parse(config.includePattern); this.maxResults = config.maxResults || null; this.exists = config.exists; - // this.maxFilesize = config.maxFileSize || null; this.resultCount = 0; this.isLimitHit = false; this.activeCancellationTokens = new Set(); - // this.filesWalked = 0; - // this.directoriesWalked = 0; - if (this.filePattern) { this.normalizedFilePatternLowercase = strings.stripWildcards(this.filePattern).toLowerCase(); } @@ -178,10 +176,14 @@ export class FileIndexSearchEngine { this.activeCancellationTokens = new Set(); } - public search(): PPromise<{ isLimitHit: boolean }, IInternalFileMatch> { - const folderQueries = this.config.folderQueries; + public search(_onResult: (match: IInternalFileMatch) => void): TPromise<{ isLimitHit: boolean }> { + if (this.config.folderQueries.length !== 1) { + throw new Error('Searches just one folder'); + } - return new PPromise<{ isLimitHit: boolean }, IInternalFileMatch>((resolve, reject, _onResult) => { + const folderQuery = this.config.folderQueries[0]; + + return new TPromise<{ isLimitHit: boolean }>((resolve, reject) => { const onResult = (match: IInternalFileMatch) => { this.resultCount++; _onResult(match); @@ -206,24 +208,22 @@ export class FileIndexSearchEngine { }); } - // For each root folder - PPromise.join(folderQueries.map(fq => { - return this.searchInFolder(fq).then(null, null, onResult); - })).then(() => { - resolve({ isLimitHit: this.isLimitHit }); - }, (errs: Error[]) => { - const errMsg = errs - .map(err => toErrorMessage(err)) - .filter(msg => !!msg)[0]; + return this.searchInFolder(folderQuery, _onResult) + .then(() => { + resolve({ isLimitHit: this.isLimitHit }); + }, (errs: Error[]) => { + const errMsg = errs + .map(err => toErrorMessage(err)) + .filter(msg => !!msg)[0]; - reject(new Error(errMsg)); - }); + reject(new Error(errMsg)); + }); }); } - private searchInFolder(fq: IFolderQuery): PPromise { + private searchInFolder(fq: IFolderQuery, onResult: (match: IInternalFileMatch) => void): TPromise { let cancellation = new CancellationTokenSource(); - return new PPromise((resolve, reject, onResult) => { + return new TPromise((resolve, reject) => { const options = this.getSearchOptionsForFolder(fq); const tree = this.initDirectoryTree(); @@ -410,7 +410,9 @@ export class FileIndexSearchManager { private caches: { [cacheKey: string]: Cache; } = Object.create(null); - public fileSearch(config: ISearchQuery, provider: vscode.FileIndexProvider, onResult: (matches: IFileMatch[]) => void): TPromise { + public fileSearch(config: ISearchQuery, provider: vscode.FileIndexProvider, onBatch: (matches: IFileMatch[]) => void): TPromise { + // if (config.cacheKey) + if (config.sortByScore) { let sortedSearch = this.trySortedSearchFromCache(config); if (!sortedSearch) { @@ -422,36 +424,27 @@ export class FileIndexSearchManager { config; const engine = new FileIndexSearchEngine(engineConfig, provider); - sortedSearch = this.doSortedSearch(engine, provider, config); + sortedSearch = this.doSortedSearch(engine, config); } return new TPromise((c, e) => { - process.nextTick(() => { // allow caller to register progress callback first - sortedSearch.then(([result, rawMatches]) => { - const serializedMatches = rawMatches.map(rawMatch => this.rawMatchToSearchItem(rawMatch)); - this.sendProgress(serializedMatches, onResult, FileIndexSearchManager.BATCH_SIZE); - c(result); - }, e, onResult); - }); + sortedSearch.then(complete => { + this.sendAsBatches(complete.results, onBatch, FileIndexSearchManager.BATCH_SIZE); + c(complete); + }, e, onBatch); }, () => { sortedSearch.cancel(); }); } - let searchPromise: TPromise; - return new TPromise((c, e) => { - const engine = new FileIndexSearchEngine(config, provider); - searchPromise = this.doSearch(engine, provider, FileIndexSearchManager.BATCH_SIZE) - .then(c, e, progress => { - if (Array.isArray(progress)) { - onResult(progress.map(m => this.rawMatchToSearchItem(m))); - } else if ((progress).relativePath) { - onResult([this.rawMatchToSearchItem(progress)]); - } - }); - }, () => { - searchPromise.cancel(); - }); + const engine = new FileIndexSearchEngine(config, provider); + return this.doSearch(engine) + .then(complete => { + this.sendAsBatches(complete.results, onBatch, FileIndexSearchManager.BATCH_SIZE); + return { + limitHit: complete.limitHit + }; + }); } private rawMatchToSearchItem(match: IInternalFileMatch): IFileMatch { @@ -460,20 +453,10 @@ export class FileIndexSearchManager { }; } - private doSortedSearch(engine: FileIndexSearchEngine, provider: vscode.FileIndexProvider, config: IRawSearchQuery): PPromise<[ISearchCompleteStats, IInternalFileMatch[]]> { - let searchPromise: PPromise; - let allResultsPromise = new PPromise<[ISearchCompleteStats, IInternalFileMatch[]], IInternalFileMatch[]>((c, e, p) => { - let results: IInternalFileMatch[] = []; - searchPromise = this.doSearch(engine, provider, -1) - .then(result => { - c([result, results]); - }, e, progress => { - if (Array.isArray(progress)) { - results = progress; - } else { - p(progress); - } - }); + private doSortedSearch(engine: FileIndexSearchEngine, config: IRawSearchQuery): TPromise { + let searchPromise: TPromise; + let allResultsPromise = new TPromise((c, e) => { + searchPromise = this.doSearch(engine).then(c, e); }, () => { searchPromise.cancel(); }); @@ -489,23 +472,18 @@ export class FileIndexSearchManager { } let chained: TPromise; - return new PPromise<[ISearchCompleteStats, IInternalFileMatch[]]>((c, e, p) => { - chained = allResultsPromise.then(([result, results]) => { + return new TPromise((c, e) => { + chained = allResultsPromise.then(complete => { const scorerCache: ScorerCache = cache ? cache.scorerCache : Object.create(null); - const unsortedResultTime = Date.now(); - return this.sortResults(config, results, scorerCache) + return this.sortResults(config, complete.results, scorerCache) .then(sortedResults => { - const sortedResultTime = Date.now(); - c([{ - stats: { - ...result.stats, - ...{ unsortedResultTime, sortedResultTime } - }, - limitHit: result.limitHit || typeof config.maxResults === 'number' && results.length > config.maxResults - }, sortedResults]); + c({ + limitHit: complete.limitHit || typeof config.maxResults === 'number' && complete.results.length > config.maxResults, // ?? + results: sortedResults + }); }); - }, e, p); + }, e); }, () => { chained.cancel(); }); @@ -519,45 +497,23 @@ export class FileIndexSearchManager { return this.caches[cacheKey] = new Cache(); } - private trySortedSearchFromCache(config: IRawSearchQuery): TPromise<[ISearchCompleteStats, IInternalFileMatch[]]> { + private trySortedSearchFromCache(config: IRawSearchQuery): TPromise { const cache = config.cacheKey && this.caches[config.cacheKey]; if (!cache) { return undefined; } - const cacheLookupStartTime = Date.now(); const cached = this.getResultsFromCache(cache, config.filePattern); if (cached) { let chained: TPromise; - return new TPromise<[ISearchCompleteStats, IInternalFileMatch[]]>((c, e) => { - chained = cached.then(([result, results, cacheStats]) => { - const cacheLookupResultTime = Date.now(); - return this.sortResults(config, results, cache.scorerCache) + return new TPromise((c, e) => { + chained = cached.then(complete => { + return this.sortResults(config, complete.results, cache.scorerCache) .then(sortedResults => { - const sortedResultTime = Date.now(); - - const stats: ICachedSearchStats = { - fromCache: true, - cacheLookupStartTime: cacheLookupStartTime, - cacheFilterStartTime: cacheStats.cacheFilterStartTime, - cacheLookupResultTime: cacheLookupResultTime, - cacheEntryCount: cacheStats.cacheFilterResultCount, - resultCount: results.length - }; - if (config.sortByScore) { - stats.unsortedResultTime = cacheLookupResultTime; - stats.sortedResultTime = sortedResultTime; - } - if (!cacheStats.cacheWasResolved) { - stats.joined = result.stats; - } - c([ - { - limitHit: result.limitHit || typeof config.maxResults === 'number' && results.length > config.maxResults, - stats: stats - }, - sortedResults - ]); + c({ + limitHit: complete.limitHit || typeof config.maxResults === 'number' && complete.results.length > config.maxResults, + results: sortedResults + }); }); }, e); }, () => { @@ -578,25 +534,25 @@ export class FileIndexSearchManager { return arrays.topAsync(results, compare, config.maxResults, 10000); } - private sendProgress(results: IFileMatch[], progressCb: (batch: IFileMatch[]) => void, batchSize: number) { + private sendAsBatches(rawMatches: IInternalFileMatch[], onBatch: (batch: IFileMatch[]) => void, batchSize: number) { + const serializedMatches = rawMatches.map(rawMatch => this.rawMatchToSearchItem(rawMatch)); if (batchSize && batchSize > 0) { - for (let i = 0; i < results.length; i += batchSize) { - progressCb(results.slice(i, i + batchSize)); + for (let i = 0; i < serializedMatches.length; i += batchSize) { + onBatch(serializedMatches.slice(i, i + batchSize)); } } else { - progressCb(results); + onBatch(serializedMatches); } } - private getResultsFromCache(cache: Cache, searchValue: string): PPromise<[ISearchCompleteStats, IInternalFileMatch[], CacheStats]> { + private getResultsFromCache(cache: Cache, searchValue: string): TPromise { if (path.isAbsolute(searchValue)) { return null; // bypass cache if user looks up an absolute path where matching goes directly on disk } // Find cache entries by prefix of search value const hasPathSep = searchValue.indexOf(path.sep) >= 0; - let cached: PPromise<[ISearchCompleteStats, IInternalFileMatch[]], IInternalFileMatch[]>; - let wasResolved: boolean; + let cached: TPromise; for (let previousSearch in cache.resultsToSearchCache) { // If we narrow down, we might be able to reuse the cached results @@ -606,8 +562,6 @@ export class FileIndexSearchManager { } const c = cache.resultsToSearchCache[previousSearch]; - c.then(() => { wasResolved = false; }); - wasResolved = true; cached = this.preventCancellation(c); break; } @@ -617,15 +571,13 @@ export class FileIndexSearchManager { return null; } - return new PPromise<[ISearchCompleteStats, IInternalFileMatch[], CacheStats]>((c, e, p) => { - cached.then(([complete, cachedEntries]) => { - const cacheFilterStartTime = Date.now(); - + return new TPromise((c, e) => { + cached.then(complete => { // Pattern match on results let results: IInternalFileMatch[] = []; const normalizedSearchValueLowercase = strings.stripWildcards(searchValue).toLowerCase(); - for (let i = 0; i < cachedEntries.length; i++) { - let entry = cachedEntries[i]; + for (let i = 0; i < complete.results.length; i++) { + let entry = complete.results[i]; // Check if this entry is a match for the search value if (!strings.fuzzyContains(entry.relativePath, normalizedSearchValueLowercase)) { @@ -635,48 +587,26 @@ export class FileIndexSearchManager { results.push(entry); } - c([complete, results, { - cacheWasResolved: wasResolved, - cacheFilterStartTime: cacheFilterStartTime, - cacheFilterResultCount: cachedEntries.length - }]); - }, e, p); + c({ + limitHit: complete.limitHit, + results + }); + }, e); }, () => { cached.cancel(); }); } - private doSearch(engine: FileIndexSearchEngine, provider: vscode.FileIndexProvider, batchSize?: number): PPromise { - return new PPromise((c, e, p) => { - let batch: IInternalFileMatch[] = []; - engine.search().then(result => { - if (batch.length) { - p(batch); - } - + private doSearch(engine: FileIndexSearchEngine): TPromise { + const results: IInternalFileMatch[] = []; + const onResult = match => results.push(match); + return new TPromise((c, e) => { + engine.search(onResult).then(result => { c({ limitHit: result.isLimitHit, - stats: engine.getStats() // TODO@roblou + results }); - }, error => { - if (batch.length) { - p(batch); - } - - e(error); - }, match => { - if (match) { - if (batchSize) { - batch.push(match); - if (batchSize > 0 && batch.length >= batchSize) { - p(batch); - batch = []; - } - } else { - p([match]); - } - } - }); + }, e); }, () => { engine.cancel(); }); @@ -687,11 +617,11 @@ export class FileIndexSearchManager { return TPromise.as(undefined); } - private preventCancellation(promise: PPromise): PPromise { - return new PPromise((c, e, p) => { + private preventCancellation(promise: TPromise): TPromise { + return new TPromise((c, e) => { // Allow for piled up cancellations to come through first. process.nextTick(() => { - promise.then(c, e, p); + promise.then(c, e); }); }, () => { // Do not propagate. @@ -701,7 +631,7 @@ export class FileIndexSearchManager { class Cache { - public resultsToSearchCache: { [searchValue: string]: PPromise<[ISearchCompleteStats, IInternalFileMatch[]], IInternalFileMatch[]>; } = Object.create(null); + public resultsToSearchCache: { [searchValue: string]: TPromise; } = Object.create(null); public scorerCache: ScorerCache = Object.create(null); } @@ -720,9 +650,3 @@ const FileMatchItemAccessor = new class implements IItemAccessor { - this._proxy.$handleFileMatch(handle, session, progress.map(p => p.resource)); + return this._fileSearchManager.fileSearch(query, provider, batch => { + this._proxy.$handleFileMatch(handle, session, batch.map(p => p.resource)); }); } else { const indexProvider = this._fileIndexProvider.get(handle); if (indexProvider) { - return this._fileIndexSearchManager.fileSearch(query, indexProvider, progress => { - this._proxy.$handleFileMatch(handle, session, progress.map(p => p.resource)); + return this._fileIndexSearchManager.fileSearch(query, indexProvider, batch => { + this._proxy.$handleFileMatch(handle, session, batch.map(p => p.resource)); }); } else { throw new Error('something went wrong'); From aff77d278b8b38be34862169da15df067a48e197 Mon Sep 17 00:00:00 2001 From: Rob Lourens Date: Thu, 26 Jul 2018 12:27:46 -0700 Subject: [PATCH 0188/1276] SearchProvider - clean up FileSearchProvider, remove cacheKey --- src/vs/vscode.proposed.d.ts | 19 +------ .../api/electron-browser/mainThreadSearch.ts | 2 +- src/vs/workbench/api/node/extHost.protocol.ts | 2 +- src/vs/workbench/api/node/extHostSearch.ts | 55 +++++-------------- .../services/search/node/searchService.ts | 26 ++++++--- .../api/extHostSearch.test.ts | 30 +--------- 6 files changed, 38 insertions(+), 96 deletions(-) diff --git a/src/vs/vscode.proposed.d.ts b/src/vs/vscode.proposed.d.ts index 9e0e661c312..b56c7c4760d 100644 --- a/src/vs/vscode.proposed.d.ts +++ b/src/vs/vscode.proposed.d.ts @@ -113,13 +113,6 @@ declare module 'vscode' { * The search pattern to match against file paths. */ pattern: string; - - /** - * `cacheKey` has the same value when `provideFileSearchResults` is invoked multiple times during a single quickopen session. - * Providers can optionally use this to cache results at the beginning of a quickopen session and filter results as the user types. - * It will have a different value for each folder searched. - */ - cacheKey?: string; } /** @@ -176,9 +169,9 @@ declare module 'vscode' { } /** - * A SearchProvider provides search results for files or text in files. It can be invoked by quickopen, the search viewlet, and other extensions. + * A FileSearchProvider provides search results for files or text in files. It can be invoked by quickopen and other extensions. */ - export interface SearchProvider { + export interface FileSearchProvider { /** * Provide the set of files that match a certain file path pattern. * @param query The parameters for this query. @@ -187,12 +180,6 @@ declare module 'vscode' { * @param token A cancellation token. */ provideFileSearchResults?(query: FileSearchQuery, options: FileSearchOptions, progress: Progress, token: CancellationToken): Thenable; - - /** - * Optional - if the provider makes use of `query.cacheKey`, it can implement this method which is invoked when the cache can be cleared. - * @param cacheKey The same key that was passed as `query.cacheKey`. - */ - clearCache?(cacheKey: string): void; } /** @@ -247,7 +234,7 @@ declare module 'vscode' { * @param provider The provider. * @return A [disposable](#Disposable) that unregisters this provider when being disposed. */ - export function registerFileSearchProvider(scheme: string, provider: SearchProvider): Disposable; + export function registerFileSearchProvider(scheme: string, provider: FileSearchProvider): Disposable; /** * Register a text search provider. diff --git a/src/vs/workbench/api/electron-browser/mainThreadSearch.ts b/src/vs/workbench/api/electron-browser/mainThreadSearch.ts index d88cda81686..9028249c12b 100644 --- a/src/vs/workbench/api/electron-browser/mainThreadSearch.ts +++ b/src/vs/workbench/api/electron-browser/mainThreadSearch.ts @@ -138,7 +138,7 @@ class RemoteSearchProvider implements ISearchResultProvider, IDisposable { } clearCache(cacheKey: string): TPromise { - return this._proxy.$clearCache(this._handle, cacheKey); + return this._proxy.$clearCache(cacheKey); } handleFindMatch(session: number, dataOrUri: (UriComponents | IRawFileMatch2)[]): void { diff --git a/src/vs/workbench/api/node/extHost.protocol.ts b/src/vs/workbench/api/node/extHost.protocol.ts index ba37c355b35..3d55724ba44 100644 --- a/src/vs/workbench/api/node/extHost.protocol.ts +++ b/src/vs/workbench/api/node/extHost.protocol.ts @@ -689,7 +689,7 @@ export interface ExtHostFileSystemShape { export interface ExtHostSearchShape { $provideFileSearchResults(handle: number, session: number, query: IRawSearchQuery): TPromise; - $clearCache(handle: number, cacheKey: string): TPromise; + $clearCache(cacheKey: string): TPromise; $provideTextSearchResults(handle: number, session: number, pattern: IPatternInfo, query: IRawSearchQuery): TPromise; } diff --git a/src/vs/workbench/api/node/extHostSearch.ts b/src/vs/workbench/api/node/extHostSearch.ts index c946a61d065..8aaf7982ddc 100644 --- a/src/vs/workbench/api/node/extHostSearch.ts +++ b/src/vs/workbench/api/node/extHostSearch.ts @@ -25,7 +25,7 @@ export interface ISchemeTransformer { export class ExtHostSearch implements ExtHostSearchShape { private readonly _proxy: MainThreadSearchShape; - private readonly _fileSearchProvider = new Map(); + private readonly _fileSearchProvider = new Map(); private readonly _textSearchProvider = new Map(); private readonly _fileIndexProvider = new Map(); private _handlePool: number = 0; @@ -46,7 +46,7 @@ export class ExtHostSearch implements ExtHostSearchShape { return scheme; } - registerFileSearchProvider(scheme: string, provider: vscode.SearchProvider) { + registerFileSearchProvider(scheme: string, provider: vscode.FileSearchProvider) { const handle = this._handlePool++; this._fileSearchProvider.set(handle, provider); this._proxy.$registerFileSearchProvider(handle, this._transformScheme(scheme)); @@ -95,14 +95,9 @@ export class ExtHostSearch implements ExtHostSearchShape { } } - $clearCache(handle: number, cacheKey: string): TPromise { - const provider = this._fileSearchProvider.get(handle); - if (!provider.clearCache) { - return TPromise.as(undefined); - } - - return TPromise.as( - this._fileSearchManager.clearCache(cacheKey, provider)); + $clearCache(cacheKey: string): TPromise { + // Only relevant to file index search + return this._fileIndexSearchManager.clearCache(cacheKey); } $provideTextSearchResults(handle: number, session: number, pattern: IPatternInfo, rawQuery: IRawSearchQuery): TPromise { @@ -421,7 +416,7 @@ class FileSearchEngine { private globalExcludePattern: glob.ParsedExpression; - constructor(private config: ISearchQuery, private provider: vscode.SearchProvider) { + constructor(private config: ISearchQuery, private provider: vscode.FileSearchProvider) { this.filePattern = config.filePattern; this.includePattern = config.includePattern && glob.parse(config.includePattern); this.maxResults = config.maxResults || null; @@ -450,7 +445,7 @@ class FileSearchEngine { // Support that the file pattern is a full path to a file that exists if (this.isCanceled) { - return resolve({ limitHit: this.isLimitHit, cacheKeys: [] }); + return resolve({ limitHit: this.isLimitHit }); } // For each extra file @@ -471,8 +466,8 @@ class FileSearchEngine { // For each root folder TPromise.join(folderQueries.map(fq => { return this.searchInFolder(fq, onResult); - })).then(cacheKeys => { - resolve({ limitHit: this.isLimitHit, cacheKeys }); + })).then(() => { + resolve({ limitHit: this.isLimitHit }); }, (errs: Error[]) => { const errMsg = errs .map(err => toErrorMessage(err)) @@ -483,7 +478,7 @@ class FileSearchEngine { }); } - private searchInFolder(fq: IFolderQuery, onResult: (match: IInternalFileMatch) => void): TPromise { + private searchInFolder(fq: IFolderQuery, onResult: (match: IInternalFileMatch) => void): TPromise { let cancellation = new CancellationTokenSource(); return new TPromise((resolve, reject) => { const options = this.getSearchOptionsForFolder(fq); @@ -510,17 +505,13 @@ class FileSearchEngine { this.addDirectoryEntries(tree, fq.folder, relativePath, onResult); }; - let folderCacheKey: string; new TPromise(_resolve => process.nextTick(_resolve)) .then(() => { this.activeCancellationTokens.add(cancellation); - folderCacheKey = this.config.cacheKey && (this.config.cacheKey + '_' + fq.folder.fsPath); - return this.provider.provideFileSearchResults( { - pattern: this.config.filePattern || '', - cacheKey: folderCacheKey + pattern: this.config.filePattern || '' }, options, { report: onProviderResult }, @@ -537,7 +528,7 @@ class FileSearchEngine { }).then( () => { cancellation.dispose(); - resolve(folderCacheKey); + resolve(null); }, err => { cancellation.dispose(); @@ -646,30 +637,23 @@ class FileSearchEngine { interface IInternalSearchComplete { limitHit: boolean; - cacheKeys: string[]; } class FileSearchManager { private static readonly BATCH_SIZE = 512; - private readonly expandedCacheKeys = new Map(); - - fileSearch(config: ISearchQuery, provider: vscode.SearchProvider, onResult: (matches: IFileMatch[]) => void): TPromise { + fileSearch(config: ISearchQuery, provider: vscode.FileSearchProvider, onBatch: (matches: IFileMatch[]) => void): TPromise { let searchP: TPromise; return new TPromise((c, e) => { const engine = new FileSearchEngine(config, provider); - const onInternalResult = (progress: IInternalFileMatch[]) => { - onResult(progress.map(m => this.rawMatchToSearchItem(m))); + const onInternalResult = (batch: IInternalFileMatch[]) => { + onBatch(batch.map(m => this.rawMatchToSearchItem(m))); }; searchP = this.doSearch(engine, FileSearchManager.BATCH_SIZE, onInternalResult).then( result => { - if (config.cacheKey) { - this.expandedCacheKeys.set(config.cacheKey, result.cacheKeys); - } - c({ limitHit: result.limitHit }); @@ -682,15 +666,6 @@ class FileSearchManager { }); } - clearCache(cacheKey: string, provider: vscode.SearchProvider): void { - if (!this.expandedCacheKeys.has(cacheKey)) { - return; - } - - this.expandedCacheKeys.get(cacheKey).forEach(key => provider.clearCache(key)); - this.expandedCacheKeys.delete(cacheKey); - } - private rawMatchToSearchItem(match: IInternalFileMatch): IFileMatch { return { resource: resources.joinPath(match.base, match.relativePath) diff --git a/src/vs/workbench/services/search/node/searchService.ts b/src/vs/workbench/services/search/node/searchService.ts index ff28bf7d56c..e1ae90bb784 100644 --- a/src/vs/workbench/services/search/node/searchService.ts +++ b/src/vs/workbench/services/search/node/searchService.ts @@ -7,7 +7,7 @@ import * as arrays from 'vs/base/common/arrays'; import { Event } from 'vs/base/common/event'; import { Disposable, IDisposable, toDisposable } from 'vs/base/common/lifecycle'; -import { ResourceMap } from 'vs/base/common/map'; +import { ResourceMap, values } from 'vs/base/common/map'; import { Schemas } from 'vs/base/common/network'; import * as objects from 'vs/base/common/objects'; import * as strings from 'vs/base/common/strings'; @@ -52,9 +52,6 @@ export class SearchService extends Disposable implements ISearchService { } public registerSearchResultProvider(scheme: string, type: SearchProviderType, provider: ISearchResultProvider): IDisposable { - // if (scheme === 'file') { - // this.fileSearchProvider = provider; - let list: Map; if (type === SearchProviderType.file) { list = this.fileSearchProviders; @@ -137,11 +134,19 @@ export class SearchService extends Disposable implements ISearchService { } }; - const provider = query.type === QueryType.File ? + let provider = query.type === QueryType.File ? this.fileSearchProviders.get(fq.folder.scheme) || this.fileIndexProviders.get(fq.folder.scheme) : this.textSearchProviders.get(fq.folder.scheme); - return TPromise.as(provider.search(oneFolderQuery, onProviderProgress)); + if (!provider && fq.folder.scheme === 'file') { + provider = this.diskSearch; + } + + if (!provider) { + return TPromise.wrapError(new Error('No search provider registered for scheme: ' + fq.folder.scheme)); + } + + return provider.search(oneFolderQuery, onProviderProgress); })).then(completes => { completes = completes.filter(c => !!c); if (!completes.length) { @@ -268,9 +273,12 @@ export class SearchService extends Disposable implements ISearchService { } public clearCache(cacheKey: string): TPromise { - return TPromise.join([ - this.diskSearch - ].map(provider => provider && provider.clearCache(cacheKey))) + const clearPs = [ + this.diskSearch, + ...values(this.fileIndexProviders) + ].map(provider => provider && provider.clearCache(cacheKey)); + + return TPromise.join(clearPs) .then(() => { }); } } diff --git a/src/vs/workbench/test/electron-browser/api/extHostSearch.test.ts b/src/vs/workbench/test/electron-browser/api/extHostSearch.test.ts index f5bfd49e626..bd3d303ad19 100644 --- a/src/vs/workbench/test/electron-browser/api/extHostSearch.test.ts +++ b/src/vs/workbench/test/electron-browser/api/extHostSearch.test.ts @@ -66,7 +66,7 @@ suite('ExtHostSearch', () => { await rpcProtocol.sync(); } - async function registerTestFileSearchProvider(provider: vscode.SearchProvider, scheme = 'file'): Promise { + async function registerTestFileSearchProvider(provider: vscode.FileSearchProvider, scheme = 'file'): Promise { disposables.push(extHostSearch.registerFileSearchProvider(scheme, provider)); await rpcProtocol.sync(); } @@ -647,34 +647,6 @@ suite('ExtHostSearch', () => { const { results } = await runFileSearch(query); compareURIs(results, reportedResults); }); - - test('uses different cache keys for different folders', async () => { - const cacheKeys: string[] = []; - await registerTestFileSearchProvider({ - provideFileSearchResults(query: vscode.FileSearchQuery, options: vscode.FileSearchOptions, progress: vscode.Progress, token: vscode.CancellationToken): Thenable { - cacheKeys.push(query.cacheKey); - return TPromise.wrap(null); - } - }); - - const query: ISearchQuery = { - type: QueryType.File, - filePattern: '', - cacheKey: 'cacheKey', - folderQueries: [ - { - folder: rootFolderA - }, - { - folder: rootFolderB - } - ] - }; - - await runFileSearch(query); - assert.equal(cacheKeys.length, 2); - assert.notEqual(cacheKeys[0], cacheKeys[1]); - }); }); suite('Text:', () => { From 341013c0ef9e5e7783ce25859c1715c390765122 Mon Sep 17 00:00:00 2001 From: Matt Bierner Date: Thu, 26 Jul 2018 15:14:16 -0700 Subject: [PATCH 0189/1276] Log warning when returned code action will be dropped (#55090) * Add extension logging when returned code action will be dropped Fixes #54803 Adds a loggin warning when a code action provider returns code actions that will be dropped. Warn in the the following cases: - A provider returns code actions (not commands) - And a specific code action type is requested. - And the returned code actions either don't set kind or are of the wrong kind * Use log service * Include extension id in warning --- .../src/features/organizeImports.ts | 6 ++++- src/vs/workbench/api/node/extHost.api.impl.ts | 4 ++-- .../api/node/extHostLanguageFeatures.ts | 22 +++++++++++++++---- .../api/extHostApiCommands.test.ts | 2 +- .../api/extHostLanguageFeatures.test.ts | 2 +- 5 files changed, 27 insertions(+), 9 deletions(-) diff --git a/extensions/typescript-language-features/src/features/organizeImports.ts b/extensions/typescript-language-features/src/features/organizeImports.ts index 5465b989507..2803d645d0a 100644 --- a/extensions/typescript-language-features/src/features/organizeImports.ts +++ b/extensions/typescript-language-features/src/features/organizeImports.ts @@ -69,7 +69,7 @@ export class OrganizeImportsCodeActionProvider implements vscode.CodeActionProvi public provideCodeActions( document: vscode.TextDocument, _range: vscode.Range, - _context: vscode.CodeActionContext, + context: vscode.CodeActionContext, token: vscode.CancellationToken ): vscode.CodeAction[] { const file = this.client.toPath(document.uri); @@ -77,6 +77,10 @@ export class OrganizeImportsCodeActionProvider implements vscode.CodeActionProvi return []; } + if (!context.only || !context.only.contains(vscode.CodeActionKind.SourceOrganizeImports)) { + return []; + } + this.fileConfigManager.ensureConfigurationForDocument(document, token); const action = new vscode.CodeAction( diff --git a/src/vs/workbench/api/node/extHost.api.impl.ts b/src/vs/workbench/api/node/extHost.api.impl.ts index 504df828bc7..df5b02f02c5 100644 --- a/src/vs/workbench/api/node/extHost.api.impl.ts +++ b/src/vs/workbench/api/node/extHost.api.impl.ts @@ -114,7 +114,7 @@ export function createApiFactory( rpcProtocol.set(ExtHostContext.ExtHostWorkspace, extHostWorkspace); rpcProtocol.set(ExtHostContext.ExtHostConfiguration, extHostConfiguration); const extHostDiagnostics = rpcProtocol.set(ExtHostContext.ExtHostDiagnostics, new ExtHostDiagnostics(rpcProtocol)); - const extHostLanguageFeatures = rpcProtocol.set(ExtHostContext.ExtHostLanguageFeatures, new ExtHostLanguageFeatures(rpcProtocol, schemeTransformer, extHostDocuments, extHostCommands, extHostHeapService, extHostDiagnostics)); + const extHostLanguageFeatures = rpcProtocol.set(ExtHostContext.ExtHostLanguageFeatures, new ExtHostLanguageFeatures(rpcProtocol, schemeTransformer, extHostDocuments, extHostCommands, extHostHeapService, extHostDiagnostics, extHostLogService)); const extHostFileSystem = rpcProtocol.set(ExtHostContext.ExtHostFileSystem, new ExtHostFileSystem(rpcProtocol, extHostLanguageFeatures)); const extHostFileSystemEvent = rpcProtocol.set(ExtHostContext.ExtHostFileSystemEventService, new ExtHostFileSystemEventService(rpcProtocol, extHostDocumentsAndEditors)); const extHostQuickOpen = rpcProtocol.set(ExtHostContext.ExtHostQuickOpen, new ExtHostQuickOpen(rpcProtocol, extHostWorkspace, extHostCommands)); @@ -262,7 +262,7 @@ export function createApiFactory( return score(typeConverters.LanguageSelector.from(selector), document.uri, document.languageId, true); }, registerCodeActionsProvider(selector: vscode.DocumentSelector, provider: vscode.CodeActionProvider, metadata?: vscode.CodeActionProviderMetadata): vscode.Disposable { - return extHostLanguageFeatures.registerCodeActionProvider(checkSelector(selector), provider, metadata); + return extHostLanguageFeatures.registerCodeActionProvider(checkSelector(selector), provider, extension, metadata); }, registerCodeLensProvider(selector: vscode.DocumentSelector, provider: vscode.CodeLensProvider): vscode.Disposable { return extHostLanguageFeatures.registerCodeLensProvider(checkSelector(selector), provider); diff --git a/src/vs/workbench/api/node/extHostLanguageFeatures.ts b/src/vs/workbench/api/node/extHostLanguageFeatures.ts index 8dc9a268ce5..e9dbb137a6e 100644 --- a/src/vs/workbench/api/node/extHostLanguageFeatures.ts +++ b/src/vs/workbench/api/node/extHostLanguageFeatures.ts @@ -25,6 +25,7 @@ import { isFalsyOrEmpty } from 'vs/base/common/arrays'; import { isObject } from 'vs/base/common/types'; import { ISelection, Selection } from 'vs/editor/common/core/selection'; import { IExtensionDescription } from 'vs/workbench/services/extensions/common/extensions'; +import { ILogService } from 'vs/platform/log/common/log'; // --- adapter @@ -273,7 +274,9 @@ class CodeActionAdapter { private readonly _documents: ExtHostDocuments, private readonly _commands: CommandsConverter, private readonly _diagnostics: ExtHostDiagnostics, - private readonly _provider: vscode.CodeActionProvider + private readonly _provider: vscode.CodeActionProvider, + private readonly _logService: ILogService, + private readonly _extensionId: string ) { } provideCodeActions(resource: URI, rangeOrSelection: IRange | ISelection, context: modes.CodeActionContext): TPromise { @@ -314,6 +317,14 @@ class CodeActionAdapter { command: this._commands.toInternal(candidate), }); } else { + if (codeActionContext.only) { + if (!candidate.kind) { + this._logService.warn(`${this._extensionId} - Code actions of kind '${codeActionContext.only.value} 'requested but returned code action does not have a 'kind'. Code action will be dropped. Please set 'CodeAction.kind'.`); + } else if (!codeActionContext.only.contains(candidate.kind)) { + this._logService.warn(`${this._extensionId} -Code actions of kind '${codeActionContext.only.value} 'requested but returned code action is of kind '${candidate.kind.value}'. Code action will be dropped. Please check 'CodeActionContext.only' to only return requested code actions.`); + } + } + // new school: convert code action result.push({ title: candidate.title, @@ -838,6 +849,7 @@ export class ExtHostLanguageFeatures implements ExtHostLanguageFeaturesShape { private _heapService: ExtHostHeapService; private _diagnostics: ExtHostDiagnostics; private _adapter = new Map(); + private readonly _logService: ILogService; constructor( mainContext: IMainContext, @@ -845,7 +857,8 @@ export class ExtHostLanguageFeatures implements ExtHostLanguageFeaturesShape { documents: ExtHostDocuments, commands: ExtHostCommands, heapMonitor: ExtHostHeapService, - diagnostics: ExtHostDiagnostics + diagnostics: ExtHostDiagnostics, + logService: ILogService ) { this._schemeTransformer = schemeTransformer; this._proxy = mainContext.getProxy(MainContext.MainThreadLanguageFeatures); @@ -853,6 +866,7 @@ export class ExtHostLanguageFeatures implements ExtHostLanguageFeaturesShape { this._commands = commands; this._heapService = heapMonitor; this._diagnostics = diagnostics; + this._logService = logService; } private _transformDocumentSelector(selector: vscode.DocumentSelector): ISerializedDocumentFilter[] { @@ -1024,8 +1038,8 @@ export class ExtHostLanguageFeatures implements ExtHostLanguageFeaturesShape { // --- quick fix - registerCodeActionProvider(selector: vscode.DocumentSelector, provider: vscode.CodeActionProvider, metadata?: vscode.CodeActionProviderMetadata): vscode.Disposable { - const handle = this._addNewAdapter(new CodeActionAdapter(this._documents, this._commands.converter, this._diagnostics, provider)); + registerCodeActionProvider(selector: vscode.DocumentSelector, provider: vscode.CodeActionProvider, extension?: IExtensionDescription, metadata?: vscode.CodeActionProviderMetadata): vscode.Disposable { + const handle = this._addNewAdapter(new CodeActionAdapter(this._documents, this._commands.converter, this._diagnostics, provider, this._logService, extension.id)); this._proxy.$registerQuickFixSupport(handle, this._transformDocumentSelector(selector), metadata && metadata.providedCodeActionKinds ? metadata.providedCodeActionKinds.map(kind => kind.value) : undefined); return this._createDisposable(handle); } 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 ef672a49dd1..cd4ed9a20d7 100644 --- a/src/vs/workbench/test/electron-browser/api/extHostApiCommands.test.ts +++ b/src/vs/workbench/test/electron-browser/api/extHostApiCommands.test.ts @@ -122,7 +122,7 @@ suite('ExtHostLanguageFeatureCommands', function () { const diagnostics = new ExtHostDiagnostics(rpcProtocol); rpcProtocol.set(ExtHostContext.ExtHostDiagnostics, diagnostics); - extHost = new ExtHostLanguageFeatures(rpcProtocol, null, extHostDocuments, commands, heapService, diagnostics); + extHost = new ExtHostLanguageFeatures(rpcProtocol, null, extHostDocuments, commands, heapService, diagnostics, new NullLogService()); rpcProtocol.set(ExtHostContext.ExtHostLanguageFeatures, extHost); mainThread = rpcProtocol.set(MainContext.MainThreadLanguageFeatures, inst.createInstance(MainThreadLanguageFeatures, rpcProtocol)); diff --git a/src/vs/workbench/test/electron-browser/api/extHostLanguageFeatures.test.ts b/src/vs/workbench/test/electron-browser/api/extHostLanguageFeatures.test.ts index 3b96a8f3c01..74c35400db8 100644 --- a/src/vs/workbench/test/electron-browser/api/extHostLanguageFeatures.test.ts +++ b/src/vs/workbench/test/electron-browser/api/extHostLanguageFeatures.test.ts @@ -112,7 +112,7 @@ suite('ExtHostLanguageFeatures', function () { const diagnostics = new ExtHostDiagnostics(rpcProtocol); rpcProtocol.set(ExtHostContext.ExtHostDiagnostics, diagnostics); - extHost = new ExtHostLanguageFeatures(rpcProtocol, null, extHostDocuments, commands, heapService, diagnostics); + extHost = new ExtHostLanguageFeatures(rpcProtocol, null, extHostDocuments, commands, heapService, diagnostics, new NullLogService()); rpcProtocol.set(ExtHostContext.ExtHostLanguageFeatures, extHost); mainThread = rpcProtocol.set(MainContext.MainThreadLanguageFeatures, inst.createInstance(MainThreadLanguageFeatures, rpcProtocol)); From 1e10fa5163cc63b4dd7ebc047bf0a3a1f255aed2 Mon Sep 17 00:00:00 2001 From: Matt Bierner Date: Thu, 26 Jul 2018 14:25:43 -0700 Subject: [PATCH 0190/1276] Update ts/js grammars --- .../syntaxes/JavaScript.tmLanguage.json | 38 +++++++++---------- .../syntaxes/JavaScriptReact.tmLanguage.json | 38 +++++++++---------- .../syntaxes/TypeScript.tmLanguage.json | 18 ++++----- .../syntaxes/TypeScriptReact.tmLanguage.json | 38 +++++++++---------- 4 files changed, 66 insertions(+), 66 deletions(-) diff --git a/extensions/javascript/syntaxes/JavaScript.tmLanguage.json b/extensions/javascript/syntaxes/JavaScript.tmLanguage.json index 50bb5f619c5..aa6c9971e8d 100644 --- a/extensions/javascript/syntaxes/JavaScript.tmLanguage.json +++ b/extensions/javascript/syntaxes/JavaScript.tmLanguage.json @@ -4,7 +4,7 @@ "If you want to provide a fix or improvement, please create a pull request against the original repository.", "Once accepted there, we are happy to receive an update request." ], - "version": "https://github.com/Microsoft/TypeScript-TmLanguage/commit/27425437b2144f43607047ae7ee9b826e36856a5", + "version": "https://github.com/Microsoft/TypeScript-TmLanguage/commit/32208c2b11569d08a925f56fd69d28b18a5cc308", "name": "JavaScript (with React support)", "scopeName": "source.js", "patterns": [ @@ -295,7 +295,7 @@ "name": "storage.type.js" } }, - "end": "(?=$|^|;|}|(\\s+(of|in)\\s+))", + "end": "((?=;|}|(\\s+(of|in)\\s+)|^\\s*$|;|^\\s*abstract\\b|^\\s*async\\b|^\\s*class\\b|^\\s*const\\b|^\\s*declare\\b|^\\s*enum\\b|^\\s*export\\b|^\\s*function\\b|^\\s*import\\b|^\\s*interface\\b|^\\s*let\\b|^\\s*module\\b|^\\s*namespace\\b|^\\s*return\\b|^\\s*type\\b|^\\s*var\\b)|((?<=\\S)(?|&&|\\|\\||\\*\\/)\\s*(\\/)(?![\\/*])(?=(?:[^\\/\\\\\\[]|\\\\.|\\[([^\\]\\\\]|\\\\.)+\\])+\\/[gimsuy]*(?!\\s*[a-zA-Z0-9_$]))", + "begin": "(?|&&|\\|\\||\\*\\/)\\s*(\\/)(?![\\/*])(?=(?:[^\\/\\\\\\[]|\\\\.|\\[([^\\]\\\\]|\\\\.)+\\])+\\/[gimsuy]*(?!\\s*[a-zA-Z0-9_$]))", "beginCaptures": { "1": { "name": "punctuation.definition.string.begin.js" @@ -3869,7 +3869,7 @@ }, { "name": "string.regexp.js", - "begin": "(?:*]|&&|\\|\\||\\?|^await|[^\\._$[:alnum:]]await|^return|[^\\._$[:alnum:]]return|^default|[^\\._$[:alnum:]]default|^yield|[^\\._$[:alnum:]]yield|^)\\s*(?=(<)\\s*(?:([_$a-zA-Z][-$\\w.]*)(?))", - "end": "(?!(<)\\s*(?:([_$a-zA-Z][-$\\w.]*)(?))", + "begin": "(?:*]|&&|\\|\\||\\?|^await|[^\\._$[:alnum:]]await|^return|[^\\._$[:alnum:]]return|^default|[^\\._$[:alnum:]]default|^yield|[^\\._$[:alnum:]]yield|^)\\s*(?=(<)\\s*(?:([_$[:alpha:]][-$[:alnum:].]*)(?))", + "end": "(?!(<)\\s*(?:([_$[:alpha:]][-$[:alnum:].]*)(?))", "patterns": [ { "include": "#jsx-tag-without-attributes" @@ -4618,8 +4618,8 @@ }, "jsx-tag-without-attributes": { "name": "meta.tag.without-attributes.js", - "begin": "(<)\\s*(?:([_$a-zA-Z][-$\\w.]*)(?)", - "end": "()", + "begin": "(<)\\s*(?:([_$[:alpha:]][-$[:alnum:].]*)(?)", + "end": "()", "beginCaptures": { "1": { "name": "punctuation.definition.tag.begin.js" @@ -4668,8 +4668,8 @@ ] }, "jsx-tag-in-expression": { - "begin": "(?x)\n (?:*]|&&|\\|\\||\\?|^await|[^\\._$[:alnum:]]await|^return|[^\\._$[:alnum:]]return|^default|[^\\._$[:alnum:]]default|^yield|[^\\._$[:alnum:]]yield|^)\\s*\n (?!<\\s*[_$[:alpha:]][_$[:alnum:]]*((\\s+extends\\s+[^=>])|,)) # look ahead is not type parameter of arrow\n (?=(<)\\s*(?:([_$a-zA-Z][-$\\w.]*)(?))", - "end": "(?!(<)\\s*(?:([_$a-zA-Z][-$\\w.]*)(?))", + "begin": "(?x)\n (?:*]|&&|\\|\\||\\?|^await|[^\\._$[:alnum:]]await|^return|[^\\._$[:alnum:]]return|^default|[^\\._$[:alnum:]]default|^yield|[^\\._$[:alnum:]]yield|^)\\s*\n (?!<\\s*[_$[:alpha:]][_$[:alnum:]]*((\\s+extends\\s+[^=>])|,)) # look ahead is not type parameter of arrow\n (?=(<)\\s*(?:([_$[:alpha:]][-$[:alnum:].]*)(?))", + "end": "(?!(<)\\s*(?:([_$[:alpha:]][-$[:alnum:].]*)(?))", "patterns": [ { "include": "#jsx-tag" @@ -4678,8 +4678,8 @@ }, "jsx-tag": { "name": "meta.tag.js", - "begin": "(?=(<)\\s*(?:([_$a-zA-Z][-$\\w.]*)(?))", - "end": "(/>)|(?:())", + "begin": "(?=(<)\\s*(?:([_$[:alpha:]][-$[:alnum:].]*)(?))", + "end": "(/>)|(?:())", "endCaptures": { "1": { "name": "punctuation.definition.tag.end.js" @@ -4705,7 +4705,7 @@ }, "patterns": [ { - "begin": "(<)\\s*(?:([_$a-zA-Z][-$\\w.]*)(?)", + "begin": "(<)\\s*(?:([_$[:alpha:]][-$[:alnum:].]*)(?)", "beginCaptures": { "1": { "name": "punctuation.definition.tag.begin.js" @@ -4838,7 +4838,7 @@ ] }, "jsx-tag-attribute-name": { - "match": "(?x)\n \\s*\n (?:([_$a-zA-Z][-$\\w.]*)(:))?\n ([_$a-zA-Z][-$\\w]*)\n (?=\\s|=|/?>|/\\*|//)", + "match": "(?x)\n \\s*\n (?:([_$[:alpha:]][-$[:alnum:].]*)(:))?\n ([_$[:alpha:]][-$[:alnum:]]*)\n (?=\\s|=|/?>|/\\*|//)", "captures": { "1": { "name": "entity.other.attribute-name.namespace.js" diff --git a/extensions/javascript/syntaxes/JavaScriptReact.tmLanguage.json b/extensions/javascript/syntaxes/JavaScriptReact.tmLanguage.json index 8015ed5e8ed..7f3aae9ae44 100644 --- a/extensions/javascript/syntaxes/JavaScriptReact.tmLanguage.json +++ b/extensions/javascript/syntaxes/JavaScriptReact.tmLanguage.json @@ -4,7 +4,7 @@ "If you want to provide a fix or improvement, please create a pull request against the original repository.", "Once accepted there, we are happy to receive an update request." ], - "version": "https://github.com/Microsoft/TypeScript-TmLanguage/commit/27425437b2144f43607047ae7ee9b826e36856a5", + "version": "https://github.com/Microsoft/TypeScript-TmLanguage/commit/32208c2b11569d08a925f56fd69d28b18a5cc308", "name": "JavaScript (with React support)", "scopeName": "source.js.jsx", "patterns": [ @@ -295,7 +295,7 @@ "name": "storage.type.js.jsx" } }, - "end": "(?=$|^|;|}|(\\s+(of|in)\\s+))", + "end": "((?=;|}|(\\s+(of|in)\\s+)|^\\s*$|;|^\\s*abstract\\b|^\\s*async\\b|^\\s*class\\b|^\\s*const\\b|^\\s*declare\\b|^\\s*enum\\b|^\\s*export\\b|^\\s*function\\b|^\\s*import\\b|^\\s*interface\\b|^\\s*let\\b|^\\s*module\\b|^\\s*namespace\\b|^\\s*return\\b|^\\s*type\\b|^\\s*var\\b)|((?<=\\S)(?|&&|\\|\\||\\*\\/)\\s*(\\/)(?![\\/*])(?=(?:[^\\/\\\\\\[]|\\\\.|\\[([^\\]\\\\]|\\\\.)+\\])+\\/[gimsuy]*(?!\\s*[a-zA-Z0-9_$]))", + "begin": "(?|&&|\\|\\||\\*\\/)\\s*(\\/)(?![\\/*])(?=(?:[^\\/\\\\\\[]|\\\\.|\\[([^\\]\\\\]|\\\\.)+\\])+\\/[gimsuy]*(?!\\s*[a-zA-Z0-9_$]))", "beginCaptures": { "1": { "name": "punctuation.definition.string.begin.js.jsx" @@ -3869,7 +3869,7 @@ }, { "name": "string.regexp.js.jsx", - "begin": "(?:*]|&&|\\|\\||\\?|^await|[^\\._$[:alnum:]]await|^return|[^\\._$[:alnum:]]return|^default|[^\\._$[:alnum:]]default|^yield|[^\\._$[:alnum:]]yield|^)\\s*(?=(<)\\s*(?:([_$a-zA-Z][-$\\w.]*)(?))", - "end": "(?!(<)\\s*(?:([_$a-zA-Z][-$\\w.]*)(?))", + "begin": "(?:*]|&&|\\|\\||\\?|^await|[^\\._$[:alnum:]]await|^return|[^\\._$[:alnum:]]return|^default|[^\\._$[:alnum:]]default|^yield|[^\\._$[:alnum:]]yield|^)\\s*(?=(<)\\s*(?:([_$[:alpha:]][-$[:alnum:].]*)(?))", + "end": "(?!(<)\\s*(?:([_$[:alpha:]][-$[:alnum:].]*)(?))", "patterns": [ { "include": "#jsx-tag-without-attributes" @@ -4618,8 +4618,8 @@ }, "jsx-tag-without-attributes": { "name": "meta.tag.without-attributes.js.jsx", - "begin": "(<)\\s*(?:([_$a-zA-Z][-$\\w.]*)(?)", - "end": "()", + "begin": "(<)\\s*(?:([_$[:alpha:]][-$[:alnum:].]*)(?)", + "end": "()", "beginCaptures": { "1": { "name": "punctuation.definition.tag.begin.js.jsx" @@ -4668,8 +4668,8 @@ ] }, "jsx-tag-in-expression": { - "begin": "(?x)\n (?:*]|&&|\\|\\||\\?|^await|[^\\._$[:alnum:]]await|^return|[^\\._$[:alnum:]]return|^default|[^\\._$[:alnum:]]default|^yield|[^\\._$[:alnum:]]yield|^)\\s*\n (?!<\\s*[_$[:alpha:]][_$[:alnum:]]*((\\s+extends\\s+[^=>])|,)) # look ahead is not type parameter of arrow\n (?=(<)\\s*(?:([_$a-zA-Z][-$\\w.]*)(?))", - "end": "(?!(<)\\s*(?:([_$a-zA-Z][-$\\w.]*)(?))", + "begin": "(?x)\n (?:*]|&&|\\|\\||\\?|^await|[^\\._$[:alnum:]]await|^return|[^\\._$[:alnum:]]return|^default|[^\\._$[:alnum:]]default|^yield|[^\\._$[:alnum:]]yield|^)\\s*\n (?!<\\s*[_$[:alpha:]][_$[:alnum:]]*((\\s+extends\\s+[^=>])|,)) # look ahead is not type parameter of arrow\n (?=(<)\\s*(?:([_$[:alpha:]][-$[:alnum:].]*)(?))", + "end": "(?!(<)\\s*(?:([_$[:alpha:]][-$[:alnum:].]*)(?))", "patterns": [ { "include": "#jsx-tag" @@ -4678,8 +4678,8 @@ }, "jsx-tag": { "name": "meta.tag.js.jsx", - "begin": "(?=(<)\\s*(?:([_$a-zA-Z][-$\\w.]*)(?))", - "end": "(/>)|(?:())", + "begin": "(?=(<)\\s*(?:([_$[:alpha:]][-$[:alnum:].]*)(?))", + "end": "(/>)|(?:())", "endCaptures": { "1": { "name": "punctuation.definition.tag.end.js.jsx" @@ -4705,7 +4705,7 @@ }, "patterns": [ { - "begin": "(<)\\s*(?:([_$a-zA-Z][-$\\w.]*)(?)", + "begin": "(<)\\s*(?:([_$[:alpha:]][-$[:alnum:].]*)(?)", "beginCaptures": { "1": { "name": "punctuation.definition.tag.begin.js.jsx" @@ -4838,7 +4838,7 @@ ] }, "jsx-tag-attribute-name": { - "match": "(?x)\n \\s*\n (?:([_$a-zA-Z][-$\\w.]*)(:))?\n ([_$a-zA-Z][-$\\w]*)\n (?=\\s|=|/?>|/\\*|//)", + "match": "(?x)\n \\s*\n (?:([_$[:alpha:]][-$[:alnum:].]*)(:))?\n ([_$[:alpha:]][-$[:alnum:]]*)\n (?=\\s|=|/?>|/\\*|//)", "captures": { "1": { "name": "entity.other.attribute-name.namespace.js.jsx" diff --git a/extensions/typescript-basics/syntaxes/TypeScript.tmLanguage.json b/extensions/typescript-basics/syntaxes/TypeScript.tmLanguage.json index efd1eed74e0..df7dcb87994 100644 --- a/extensions/typescript-basics/syntaxes/TypeScript.tmLanguage.json +++ b/extensions/typescript-basics/syntaxes/TypeScript.tmLanguage.json @@ -4,7 +4,7 @@ "If you want to provide a fix or improvement, please create a pull request against the original repository.", "Once accepted there, we are happy to receive an update request." ], - "version": "https://github.com/Microsoft/TypeScript-TmLanguage/commit/27425437b2144f43607047ae7ee9b826e36856a5", + "version": "https://github.com/Microsoft/TypeScript-TmLanguage/commit/32208c2b11569d08a925f56fd69d28b18a5cc308", "name": "TypeScript", "scopeName": "source.ts", "patterns": [ @@ -292,7 +292,7 @@ "name": "storage.type.ts" } }, - "end": "(?=$|^|;|}|(\\s+(of|in)\\s+))", + "end": "((?=;|}|(\\s+(of|in)\\s+)|^\\s*$|;|^\\s*abstract\\b|^\\s*async\\b|^\\s*class\\b|^\\s*const\\b|^\\s*declare\\b|^\\s*enum\\b|^\\s*export\\b|^\\s*function\\b|^\\s*import\\b|^\\s*interface\\b|^\\s*let\\b|^\\s*module\\b|^\\s*namespace\\b|^\\s*return\\b|^\\s*type\\b|^\\s*var\\b)|((?<=\\S)(?|&&|\\|\\||\\*\\/)\\s*(\\/)(?![\\/*])(?=(?:[^\\/\\\\\\[]|\\\\.|\\[([^\\]\\\\]|\\\\.)+\\])+\\/[gimsuy]*(?!\\s*[a-zA-Z0-9_$]))", + "begin": "(?|&&|\\|\\||\\*\\/)\\s*(\\/)(?![\\/*])(?=(?:[^\\/\\\\\\[]|\\\\.|\\[([^\\]\\\\]|\\\\.)+\\])+\\/[gimsuy]*(?!\\s*[a-zA-Z0-9_$]))", "beginCaptures": { "1": { "name": "punctuation.definition.string.begin.ts" @@ -3903,7 +3903,7 @@ }, { "name": "string.regexp.ts", - "begin": "(?|&&|\\|\\||\\*\\/)\\s*(\\/)(?![\\/*])(?=(?:[^\\/\\\\\\[]|\\\\.|\\[([^\\]\\\\]|\\\\.)+\\])+\\/[gimsuy]*(?!\\s*[a-zA-Z0-9_$]))", + "begin": "(?|&&|\\|\\||\\*\\/)\\s*(\\/)(?![\\/*])(?=(?:[^\\/\\\\\\[]|\\\\.|\\[([^\\]\\\\]|\\\\.)+\\])+\\/[gimsuy]*(?!\\s*[a-zA-Z0-9_$]))", "beginCaptures": { "1": { "name": "punctuation.definition.string.begin.tsx" @@ -3869,7 +3869,7 @@ }, { "name": "string.regexp.tsx", - "begin": "(?:*]|&&|\\|\\||\\?|^await|[^\\._$[:alnum:]]await|^return|[^\\._$[:alnum:]]return|^default|[^\\._$[:alnum:]]default|^yield|[^\\._$[:alnum:]]yield|^)\\s*(?=(<)\\s*(?:([_$a-zA-Z][-$\\w.]*)(?))", - "end": "(?!(<)\\s*(?:([_$a-zA-Z][-$\\w.]*)(?))", + "begin": "(?:*]|&&|\\|\\||\\?|^await|[^\\._$[:alnum:]]await|^return|[^\\._$[:alnum:]]return|^default|[^\\._$[:alnum:]]default|^yield|[^\\._$[:alnum:]]yield|^)\\s*(?=(<)\\s*(?:([_$[:alpha:]][-$[:alnum:].]*)(?))", + "end": "(?!(<)\\s*(?:([_$[:alpha:]][-$[:alnum:].]*)(?))", "patterns": [ { "include": "#jsx-tag-without-attributes" @@ -4618,8 +4618,8 @@ }, "jsx-tag-without-attributes": { "name": "meta.tag.without-attributes.tsx", - "begin": "(<)\\s*(?:([_$a-zA-Z][-$\\w.]*)(?)", - "end": "()", + "begin": "(<)\\s*(?:([_$[:alpha:]][-$[:alnum:].]*)(?)", + "end": "()", "beginCaptures": { "1": { "name": "punctuation.definition.tag.begin.tsx" @@ -4668,8 +4668,8 @@ ] }, "jsx-tag-in-expression": { - "begin": "(?x)\n (?:*]|&&|\\|\\||\\?|^await|[^\\._$[:alnum:]]await|^return|[^\\._$[:alnum:]]return|^default|[^\\._$[:alnum:]]default|^yield|[^\\._$[:alnum:]]yield|^)\\s*\n (?!<\\s*[_$[:alpha:]][_$[:alnum:]]*((\\s+extends\\s+[^=>])|,)) # look ahead is not type parameter of arrow\n (?=(<)\\s*(?:([_$a-zA-Z][-$\\w.]*)(?))", - "end": "(?!(<)\\s*(?:([_$a-zA-Z][-$\\w.]*)(?))", + "begin": "(?x)\n (?:*]|&&|\\|\\||\\?|^await|[^\\._$[:alnum:]]await|^return|[^\\._$[:alnum:]]return|^default|[^\\._$[:alnum:]]default|^yield|[^\\._$[:alnum:]]yield|^)\\s*\n (?!<\\s*[_$[:alpha:]][_$[:alnum:]]*((\\s+extends\\s+[^=>])|,)) # look ahead is not type parameter of arrow\n (?=(<)\\s*(?:([_$[:alpha:]][-$[:alnum:].]*)(?))", + "end": "(?!(<)\\s*(?:([_$[:alpha:]][-$[:alnum:].]*)(?))", "patterns": [ { "include": "#jsx-tag" @@ -4678,8 +4678,8 @@ }, "jsx-tag": { "name": "meta.tag.tsx", - "begin": "(?=(<)\\s*(?:([_$a-zA-Z][-$\\w.]*)(?))", - "end": "(/>)|(?:())", + "begin": "(?=(<)\\s*(?:([_$[:alpha:]][-$[:alnum:].]*)(?))", + "end": "(/>)|(?:())", "endCaptures": { "1": { "name": "punctuation.definition.tag.end.tsx" @@ -4705,7 +4705,7 @@ }, "patterns": [ { - "begin": "(<)\\s*(?:([_$a-zA-Z][-$\\w.]*)(?)", + "begin": "(<)\\s*(?:([_$[:alpha:]][-$[:alnum:].]*)(?)", "beginCaptures": { "1": { "name": "punctuation.definition.tag.begin.tsx" @@ -4838,7 +4838,7 @@ ] }, "jsx-tag-attribute-name": { - "match": "(?x)\n \\s*\n (?:([_$a-zA-Z][-$\\w.]*)(:))?\n ([_$a-zA-Z][-$\\w]*)\n (?=\\s|=|/?>|/\\*|//)", + "match": "(?x)\n \\s*\n (?:([_$[:alpha:]][-$[:alnum:].]*)(:))?\n ([_$[:alpha:]][-$[:alnum:]]*)\n (?=\\s|=|/?>|/\\*|//)", "captures": { "1": { "name": "entity.other.attribute-name.namespace.tsx" From bd1e8d40fd27e32e4e984571a4a1efcc71256e70 Mon Sep 17 00:00:00 2001 From: Matt Bierner Date: Thu, 26 Jul 2018 15:42:24 -0700 Subject: [PATCH 0191/1276] Fix unit test --- src/vs/workbench/api/node/extHostLanguageFeatures.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vs/workbench/api/node/extHostLanguageFeatures.ts b/src/vs/workbench/api/node/extHostLanguageFeatures.ts index e9dbb137a6e..1742acf2378 100644 --- a/src/vs/workbench/api/node/extHostLanguageFeatures.ts +++ b/src/vs/workbench/api/node/extHostLanguageFeatures.ts @@ -1039,7 +1039,7 @@ export class ExtHostLanguageFeatures implements ExtHostLanguageFeaturesShape { // --- quick fix registerCodeActionProvider(selector: vscode.DocumentSelector, provider: vscode.CodeActionProvider, extension?: IExtensionDescription, metadata?: vscode.CodeActionProviderMetadata): vscode.Disposable { - const handle = this._addNewAdapter(new CodeActionAdapter(this._documents, this._commands.converter, this._diagnostics, provider, this._logService, extension.id)); + const handle = this._addNewAdapter(new CodeActionAdapter(this._documents, this._commands.converter, this._diagnostics, provider, this._logService, extension ? extension.id : '')); this._proxy.$registerQuickFixSupport(handle, this._transformDocumentSelector(selector), metadata && metadata.providedCodeActionKinds ? metadata.providedCodeActionKinds.map(kind => kind.value) : undefined); return this._createDisposable(handle); } From 5e40bd7df9ff3226939a21a94f318d1633389aca Mon Sep 17 00:00:00 2001 From: Matt Bierner Date: Thu, 26 Jul 2018 16:01:34 -0700 Subject: [PATCH 0192/1276] Expand js/ts document symbols to have entries for each span Fixes #54855 --- .../src/features/documentSymbol.ts | 38 +++++++++++-------- 1 file changed, 22 insertions(+), 16 deletions(-) diff --git a/extensions/typescript-language-features/src/features/documentSymbol.ts b/extensions/typescript-language-features/src/features/documentSymbol.ts index 7d3e198ffd3..506aaa676a7 100644 --- a/extensions/typescript-language-features/src/features/documentSymbol.ts +++ b/extensions/typescript-language-features/src/features/documentSymbol.ts @@ -40,7 +40,6 @@ class TypeScriptDocumentSymbolProvider implements vscode.DocumentSymbolProvider return undefined; } - let tree: Proto.NavigationTree; try { const args: Proto.FileRequestArgs = { file }; @@ -64,26 +63,33 @@ class TypeScriptDocumentSymbolProvider implements vscode.DocumentSymbolProvider } private static convertNavTree(resource: vscode.Uri, bucket: vscode.DocumentSymbol[], item: Proto.NavigationTree): boolean { - const symbolInfo = new vscode.DocumentSymbol( - item.text, - '', - getSymbolKind(item.kind), - typeConverters.Range.fromTextSpan(item.spans[0]), - typeConverters.Range.fromTextSpan(item.spans[0]), - ); - let shouldInclude = TypeScriptDocumentSymbolProvider.shouldInclueEntry(item); - if (item.childItems) { - for (const child of item.childItems) { - const includedChild = TypeScriptDocumentSymbolProvider.convertNavTree(resource, symbolInfo.children, child); - shouldInclude = shouldInclude || includedChild; + const children = new Set(item.childItems || []); + for (const span of item.spans) { + const range = typeConverters.Range.fromTextSpan(span); + const symbolInfo = new vscode.DocumentSymbol( + item.text, + '', + getSymbolKind(item.kind), + range, + range); + + if (item.childItems) { + for (const child of children) { + if (child.spans.some(span => !!range.intersection(typeConverters.Range.fromTextSpan(span)))) { + const includedChild = TypeScriptDocumentSymbolProvider.convertNavTree(resource, symbolInfo.children, child); + shouldInclude = shouldInclude || includedChild; + children.delete(child); + } + } + } + + if (shouldInclude) { + bucket.push(symbolInfo); } } - if (shouldInclude) { - bucket.push(symbolInfo); - } return shouldInclude; } From 633e386b18262b39172c612506c4287fccd5a155 Mon Sep 17 00:00:00 2001 From: Matt Bierner Date: Thu, 26 Jul 2018 16:06:05 -0700 Subject: [PATCH 0193/1276] Remove extra conditional --- .../src/features/documentSymbol.ts | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/extensions/typescript-language-features/src/features/documentSymbol.ts b/extensions/typescript-language-features/src/features/documentSymbol.ts index 506aaa676a7..8925d2fb3b1 100644 --- a/extensions/typescript-language-features/src/features/documentSymbol.ts +++ b/extensions/typescript-language-features/src/features/documentSymbol.ts @@ -75,13 +75,11 @@ class TypeScriptDocumentSymbolProvider implements vscode.DocumentSymbolProvider range, range); - if (item.childItems) { - for (const child of children) { - if (child.spans.some(span => !!range.intersection(typeConverters.Range.fromTextSpan(span)))) { - const includedChild = TypeScriptDocumentSymbolProvider.convertNavTree(resource, symbolInfo.children, child); - shouldInclude = shouldInclude || includedChild; - children.delete(child); - } + for (const child of children) { + if (child.spans.some(span => !!range.intersection(typeConverters.Range.fromTextSpan(span)))) { + const includedChild = TypeScriptDocumentSymbolProvider.convertNavTree(resource, symbolInfo.children, child); + shouldInclude = shouldInclude || includedChild; + children.delete(child); } } From b4ab206963ce8d4fd87d8fd0d26bbbe0e4853225 Mon Sep 17 00:00:00 2001 From: Matt Bierner Date: Thu, 26 Jul 2018 16:07:02 -0700 Subject: [PATCH 0194/1276] Pick up new ts insiders --- extensions/package.json | 2 +- extensions/yarn.lock | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/extensions/package.json b/extensions/package.json index 1c3a19a4f02..7483338ab01 100644 --- a/extensions/package.json +++ b/extensions/package.json @@ -3,7 +3,7 @@ "version": "0.0.1", "description": "Dependencies shared by all extensions", "dependencies": { - "typescript": "3.0.1-insiders.20180723" + "typescript": "3.0.1-insiders.20180726" }, "scripts": { "postinstall": "node ./postinstall" diff --git a/extensions/yarn.lock b/extensions/yarn.lock index 1d5962931ac..a9d7e2b8a70 100644 --- a/extensions/yarn.lock +++ b/extensions/yarn.lock @@ -2,6 +2,6 @@ # yarn lockfile v1 -typescript@3.0.1-insiders.20180723: - version "3.0.1-insiders.20180723" - resolved "https://registry.yarnpkg.com/typescript/-/typescript-3.0.1-insiders.20180723.tgz#266fbafb349a6429777ab3525cda3bb0a2adc661" +typescript@3.0.1-insiders.20180726: + version "3.0.1-insiders.20180726" + resolved "https://registry.yarnpkg.com/typescript/-/typescript-3.0.1-insiders.20180726.tgz#3f921f23c8768b6fb665ee8a6895b5fca14b0c5f" From dbbfaf411021e216f807e4fc9d69dd19675b2f17 Mon Sep 17 00:00:00 2001 From: Ramya Rao Date: Thu, 26 Jul 2018 17:15:42 -0700 Subject: [PATCH 0195/1276] Use tags for filtering settings (#55198) * Use tags for filtering settings * Separator --- .../browser/media/settingsEditor2.css | 22 ------ .../preferences/browser/settingsEditor2.ts | 72 ++++++++----------- .../parts/preferences/browser/settingsTree.ts | 1 + .../preferences/browser/settingsWidgets.ts | 1 - 4 files changed, 30 insertions(+), 66 deletions(-) diff --git a/src/vs/workbench/parts/preferences/browser/media/settingsEditor2.css b/src/vs/workbench/parts/preferences/browser/media/settingsEditor2.css index adfaf32a2c8..0330afa402b 100644 --- a/src/vs/workbench/parts/preferences/browser/media/settingsEditor2.css +++ b/src/vs/workbench/parts/preferences/browser/media/settingsEditor2.css @@ -113,28 +113,6 @@ background-image: url('configure-inverse.svg'); } -.vs .settings-editor.showing-modified-only > .settings-header > .settings-header-controls .settings-header-controls-right .toolbar-toggle-more::before, -.vs .settings-editor.settings-filtered-by-tag > .settings-header > .settings-header-controls .settings-header-controls-right .toolbar-toggle-more::before { - border-color : #fff; -} - -.vs-dark .settings-editor.showing-modified-only > .settings-header > .settings-header-controls .settings-header-controls-right .toolbar-toggle-more::before, -.vs-dark .settings-editor.settings-filtered-by-tag > .settings-header > .settings-header-controls .settings-header-controls-right .toolbar-toggle-more::before { - border-color : #000; -} - -.settings-editor.showing-modified-only > .settings-header > .settings-header-controls .settings-header-controls-right .toolbar-toggle-more::before, -.settings-editor.settings-filtered-by-tag > .settings-header > .settings-header-controls .settings-header-controls-right .toolbar-toggle-more::before { - content: ""; - width: 6px; - height: 6px; - position: absolute; - top: 3px; - right: 3px; - border-radius: 10px; - border: 1px solid; -} - .settings-editor > .settings-header > .settings-header-controls .settings-tabs-widget > .monaco-action-bar .action-item { padding: 0px; /* padding must be on action-label because it has the bottom-border, because that's where the .checked class is */ } diff --git a/src/vs/workbench/parts/preferences/browser/settingsEditor2.ts b/src/vs/workbench/parts/preferences/browser/settingsEditor2.ts index 982c1c9f709..6f6406e04b0 100644 --- a/src/vs/workbench/parts/preferences/browser/settingsEditor2.ts +++ b/src/vs/workbench/parts/preferences/browser/settingsEditor2.ts @@ -14,7 +14,7 @@ import * as collections from 'vs/base/common/collections'; import { getErrorMessage, isPromiseCanceledError } from 'vs/base/common/errors'; import URI from 'vs/base/common/uri'; import { TPromise } from 'vs/base/common/winjs.base'; -import { ITree, ITreeConfiguration } from 'vs/base/parts/tree/browser/tree'; +import { ITreeConfiguration } from 'vs/base/parts/tree/browser/tree'; import { OpenMode, DefaultTreestyler } from 'vs/base/parts/tree/browser/treeDefaults'; import 'vs/css!./media/settingsEditor2'; import { localize } from 'vs/nls'; @@ -32,7 +32,7 @@ import { BaseEditor } from 'vs/workbench/browser/parts/editor/baseEditor'; import { EditorOptions, IEditor } from 'vs/workbench/common/editor'; import { SearchWidget, SettingsTarget, SettingsTargetsWidget } from 'vs/workbench/parts/preferences/browser/preferencesWidgets'; import { commonlyUsedData, tocData } from 'vs/workbench/parts/preferences/browser/settingsLayout'; -import { ISettingsEditorViewState, resolveExtensionsSettings, resolveSettingsTree, SearchResultIdx, SearchResultModel, SettingsRenderer, SettingsTree, SettingsTreeElement, SettingsTreeFilter, SettingsTreeGroupElement, SettingsTreeModel, SettingsTreeSettingElement, MODIFIED_SETTING_TAG } from 'vs/workbench/parts/preferences/browser/settingsTree'; +import { ISettingsEditorViewState, resolveExtensionsSettings, resolveSettingsTree, SearchResultIdx, SearchResultModel, SettingsRenderer, SettingsTree, SettingsTreeElement, SettingsTreeFilter, SettingsTreeGroupElement, SettingsTreeModel, SettingsTreeSettingElement, MODIFIED_SETTING_TAG, BACKGROUND_ONLINE_TAG } from 'vs/workbench/parts/preferences/browser/settingsTree'; import { TOCDataSource, TOCRenderer, TOCTreeModel } from 'vs/workbench/parts/preferences/browser/tocTree'; import { CONTEXT_SETTINGS_EDITOR, CONTEXT_SETTINGS_FIRST_ROW_FOCUS, CONTEXT_SETTINGS_ROW_FOCUS, CONTEXT_SETTINGS_SEARCH_FOCUS, CONTEXT_TOC_ROW_FOCUS, IPreferencesSearchService, ISearchProvider } from 'vs/workbench/parts/preferences/common/preferences'; import { IPreferencesService, ISearchResult, ISettingsEditorModel } from 'vs/workbench/services/preferences/common/preferences'; @@ -40,6 +40,7 @@ import { SettingsEditor2Input } from 'vs/workbench/services/preferences/common/p import { DefaultSettingsEditorModel } from 'vs/workbench/services/preferences/common/preferencesModels'; import { editorBackground, foreground } from 'vs/platform/theme/common/colorRegistry'; import { settingsHeaderForeground } from 'vs/workbench/parts/preferences/browser/settingsWidgets'; +import { Separator } from 'vs/base/browser/ui/actionbar/actionbar'; const $ = DOM.$; @@ -179,6 +180,12 @@ export class SettingsEditor2 extends BaseEditor { this.searchWidget.clear(); } + filterByTag(tag: string): void { + if (this.searchWidget) { + this.searchWidget.setValue(`@tag:${tag}`); + } + } + private createHeader(parent: HTMLElement): void { this.headerContainer = DOM.append(parent, $('.settings-header')); @@ -223,17 +230,16 @@ export class SettingsEditor2 extends BaseEditor { }); const actions = [ - this.instantiationService.createInstance(ToggleFilterByTagAction, + this.instantiationService.createInstance(FilterByTagAction, localize('filterModifiedLabel', "Show modified settings only"), MODIFIED_SETTING_TAG, - this, - this.viewState), + this), this.instantiationService.createInstance( - ToggleFilterByTagAction, + FilterByTagAction, localize('filterBackgroundOnlineLabel', "Control background online features"), - 'backgroundOnlineFeature', - this, - this.viewState), + BACKGROUND_ONLINE_TAG, + this), + new Separator(), this.instantiationService.createInstance(OpenSettingsAction) ]; this.toolbar.setActions([], actions)(); @@ -409,22 +415,6 @@ export class SettingsEditor2 extends BaseEditor { })); } - toggleFilterByTag(tag: string): TPromise { - // Reset other tags, toggle this tag - const wasFiltered = this.viewState.tagFilters && this.viewState.tagFilters.has(tag); - const isFiltered = !wasFiltered; - this.viewState.tagFilters = new Set(); - if (isFiltered) { - this.viewState.tagFilters.add(tag); - } - - DOM.toggleClass(this.rootElement, 'settings-filtered-by-tag', isFiltered); - return this.refreshTreeAndMaintainFocus().then(() => { - this.settingsTree.setScrollPosition(0); - this.expandAll(this.settingsTree); - }); - } - private onDidChangeSetting(key: string, value: any): void { if (this.pendingSettingUpdate && this.pendingSettingUpdate.key !== key) { this.updateChangedSetting(key, value); @@ -664,6 +654,14 @@ export class SettingsEditor2 extends BaseEditor { } private triggerSearch(query: string): TPromise { + this.viewState.tagFilters = new Set(); + if (query) { + const tagMatches = query.match(/\s*@tag:(\S+)(.*)/); // For now, we support single tag at a time. + if (tagMatches) { + this.viewState.tagFilters.add(tagMatches[1]); + query = tagMatches[2]; + } + } if (query) { return this.searchInProgress = TPromise.join([ this.localSearchDelayer.trigger(() => this.localFilterPreferences(query)), @@ -689,14 +687,6 @@ export class SettingsEditor2 extends BaseEditor { } } - private expandAll(tree: ITree): void { - const nav = tree.getNavigator(); - let cur; - while (cur = nav.next()) { - tree.expand(cur); - } - } - private reportFilteringUsed(query: string, results: ISearchResult[]): void { const nlpResult = results[SearchResultIdx.Remote]; const nlpMetadata = nlpResult && nlpResult.metadata; @@ -844,23 +834,19 @@ class OpenSettingsAction extends Action { } } -class ToggleFilterByTagAction extends Action { - static readonly ID = 'settings.toggleFilterByTag'; - - get checked(): boolean { - return this.viewState.tagFilters && this.viewState.tagFilters.has(this.tag); - } +class FilterByTagAction extends Action { + static readonly ID = 'settings.filterByTag'; constructor( label: string, private tag: string, - private settingsEditor: SettingsEditor2, - private viewState: ISettingsEditorViewState + private settingsEditor: SettingsEditor2 ) { - super(ToggleFilterByTagAction.ID, label, 'toggle-filter-tag'); + super(FilterByTagAction.ID, label, 'toggle-filter-tag'); } run(): TPromise { - return this.settingsEditor.toggleFilterByTag(this.tag); + this.settingsEditor.filterByTag(this.tag); + return TPromise.as(null); } } diff --git a/src/vs/workbench/parts/preferences/browser/settingsTree.ts b/src/vs/workbench/parts/preferences/browser/settingsTree.ts index d5fdb2a2ce2..282ed7f0c7e 100644 --- a/src/vs/workbench/parts/preferences/browser/settingsTree.ts +++ b/src/vs/workbench/parts/preferences/browser/settingsTree.ts @@ -41,6 +41,7 @@ import { ISearchResult, ISetting, ISettingsGroup } from 'vs/workbench/services/p const $ = DOM.$; export const MODIFIED_SETTING_TAG = 'modified'; +export const BACKGROUND_ONLINE_TAG = 'backgroundOnlineFeature'; export abstract class SettingsTreeElement { id: string; diff --git a/src/vs/workbench/parts/preferences/browser/settingsWidgets.ts b/src/vs/workbench/parts/preferences/browser/settingsWidgets.ts index ac057a6d7c8..0e73986d805 100644 --- a/src/vs/workbench/parts/preferences/browser/settingsWidgets.ts +++ b/src/vs/workbench/parts/preferences/browser/settingsWidgets.ts @@ -48,7 +48,6 @@ registerThemingParticipant((theme: ITheme, collector: ICssStyleCollector) => { const modifiedItemForegroundColor = theme.getColor(modifiedItemForeground); if (modifiedItemForegroundColor) { collector.addRule(`.settings-editor > .settings-body > .settings-tree-container .setting-item.is-configured .setting-item-is-configured-label { color: ${modifiedItemForegroundColor}; }`); - collector.addRule(`.settings-editor > .settings-header > .settings-header-controls .settings-header-controls-right .toolbar-toggle-more::before { background-color: ${modifiedItemForegroundColor}; }`); } const checkboxBackgroundColor = theme.getColor(settingsCheckboxBackground); From 9e411a5fd3026e1a42f1b1a303bab376746d8ee5 Mon Sep 17 00:00:00 2001 From: Ramya Achutha Rao Date: Thu, 26 Jul 2018 17:21:32 -0700 Subject: [PATCH 0196/1276] Renaming tag for settings for online services #54354 --- extensions/git/package.json | 2 +- extensions/typescript-language-features/package.json | 2 +- src/vs/platform/telemetry/common/telemetryService.ts | 2 +- src/vs/platform/update/node/update.config.contribution.ts | 6 +++--- src/vs/workbench/electron-browser/main.contribution.ts | 2 +- .../extensions/electron-browser/extensions.contribution.ts | 4 ++-- .../workbench/parts/preferences/browser/settingsEditor2.ts | 6 +++--- src/vs/workbench/parts/preferences/browser/settingsTree.ts | 2 +- .../crashReporter/electron-browser/crashReporterService.ts | 2 +- 9 files changed, 14 insertions(+), 14 deletions(-) diff --git a/extensions/git/package.json b/extensions/git/package.json index 61575483e42..efe0d50e2e1 100644 --- a/extensions/git/package.json +++ b/extensions/git/package.json @@ -912,7 +912,7 @@ "type": "boolean", "description": "%config.autofetch%", "default": false, - "tags": ["backgroundOnlineFeature"] + "tags": ["usesOnlineServices"] }, "git.confirmSync": { "type": "boolean", diff --git a/extensions/typescript-language-features/package.json b/extensions/typescript-language-features/package.json index 46bca84de1a..6ba67c823ab 100644 --- a/extensions/typescript-language-features/package.json +++ b/extensions/typescript-language-features/package.json @@ -74,7 +74,7 @@ "default": false, "description": "%typescript.disableAutomaticTypeAcquisition%", "scope": "window", - "tags": ["backgroundOnlineFeature"] + "tags": ["usesOnlineServices"] }, "typescript.npm": { "type": [ diff --git a/src/vs/platform/telemetry/common/telemetryService.ts b/src/vs/platform/telemetry/common/telemetryService.ts index 0edfc7c942b..f30292529f7 100644 --- a/src/vs/platform/telemetry/common/telemetryService.ts +++ b/src/vs/platform/telemetry/common/telemetryService.ts @@ -168,7 +168,7 @@ Registry.as(Extensions.Configuration).registerConfigurat 'type': 'boolean', 'description': localize('telemetry.enableTelemetry', "Enable usage data and errors to be sent to Microsoft."), 'default': true, - 'tags': ['backgroundOnlineFeature'] + 'tags': ['usesOnlineServices'] } } }); \ No newline at end of file diff --git a/src/vs/platform/update/node/update.config.contribution.ts b/src/vs/platform/update/node/update.config.contribution.ts index 42e989b58e7..7c4cc968e67 100644 --- a/src/vs/platform/update/node/update.config.contribution.ts +++ b/src/vs/platform/update/node/update.config.contribution.ts @@ -22,20 +22,20 @@ configurationRegistry.registerConfiguration({ 'default': 'default', 'scope': ConfigurationScope.APPLICATION, 'description': nls.localize('updateChannel', "Configure whether you receive automatic updates from an update channel. Requires a restart after change."), - 'tags': ['backgroundOnlineFeature'] + 'tags': ['usesOnlineServices'] }, 'update.enableWindowsBackgroundUpdates': { 'type': 'boolean', 'default': true, 'scope': ConfigurationScope.APPLICATION, 'description': nls.localize('enableWindowsBackgroundUpdates', "Enables Windows background updates."), - 'tags': ['backgroundOnlineFeature'] + 'tags': ['usesOnlineServices'] }, 'update.showReleaseNotes': { 'type': 'boolean', 'default': true, 'description': nls.localize('showReleaseNotes', "Show Release Notes after an update."), - 'tags': ['backgroundOnlineFeature'] + 'tags': ['usesOnlineServices'] } } }); diff --git a/src/vs/workbench/electron-browser/main.contribution.ts b/src/vs/workbench/electron-browser/main.contribution.ts index e6ed4bc6b2a..3753a536e3c 100644 --- a/src/vs/workbench/electron-browser/main.contribution.ts +++ b/src/vs/workbench/electron-browser/main.contribution.ts @@ -489,7 +489,7 @@ configurationRegistry.registerConfiguration({ 'description': nls.localize('enableNaturalLanguageSettingsSearch', "Controls whether to enable the natural language search mode for settings."), 'default': true, 'scope': ConfigurationScope.WINDOW, - 'tags': ['backgroundOnlineFeature'] + 'tags': ['usesOnlineServices'] }, 'workbench.settings.settingsSearchTocBehavior': { 'type': 'string', diff --git a/src/vs/workbench/parts/extensions/electron-browser/extensions.contribution.ts b/src/vs/workbench/parts/extensions/electron-browser/extensions.contribution.ts index 51008b00d24..cccfee273b8 100644 --- a/src/vs/workbench/parts/extensions/electron-browser/extensions.contribution.ts +++ b/src/vs/workbench/parts/extensions/electron-browser/extensions.contribution.ts @@ -207,7 +207,7 @@ Registry.as(ConfigurationExtensions.Configuration) description: localize('extensionsAutoUpdate', "Automatically update extensions."), default: true, scope: ConfigurationScope.APPLICATION, - tags: ['backgroundOnlineFeature'] + tags: ['usesOnlineServices'] }, 'extensions.ignoreRecommendations': { type: 'boolean', @@ -218,7 +218,7 @@ Registry.as(ConfigurationExtensions.Configuration) type: 'boolean', description: localize('extensionsShowRecommendationsOnlyOnDemand', "When enabled, recommendations will not be fetched or shown unless specifically requested by the user."), default: false, - tags: ['backgroundOnlineFeature'] + tags: ['usesOnlineServices'] }, 'extensions.closeExtensionDetailsOnViewChange': { type: 'boolean', diff --git a/src/vs/workbench/parts/preferences/browser/settingsEditor2.ts b/src/vs/workbench/parts/preferences/browser/settingsEditor2.ts index 6f6406e04b0..fa7fc7390ca 100644 --- a/src/vs/workbench/parts/preferences/browser/settingsEditor2.ts +++ b/src/vs/workbench/parts/preferences/browser/settingsEditor2.ts @@ -32,7 +32,7 @@ import { BaseEditor } from 'vs/workbench/browser/parts/editor/baseEditor'; import { EditorOptions, IEditor } from 'vs/workbench/common/editor'; import { SearchWidget, SettingsTarget, SettingsTargetsWidget } from 'vs/workbench/parts/preferences/browser/preferencesWidgets'; import { commonlyUsedData, tocData } from 'vs/workbench/parts/preferences/browser/settingsLayout'; -import { ISettingsEditorViewState, resolveExtensionsSettings, resolveSettingsTree, SearchResultIdx, SearchResultModel, SettingsRenderer, SettingsTree, SettingsTreeElement, SettingsTreeFilter, SettingsTreeGroupElement, SettingsTreeModel, SettingsTreeSettingElement, MODIFIED_SETTING_TAG, BACKGROUND_ONLINE_TAG } from 'vs/workbench/parts/preferences/browser/settingsTree'; +import { ISettingsEditorViewState, resolveExtensionsSettings, resolveSettingsTree, SearchResultIdx, SearchResultModel, SettingsRenderer, SettingsTree, SettingsTreeElement, SettingsTreeFilter, SettingsTreeGroupElement, SettingsTreeModel, SettingsTreeSettingElement, MODIFIED_SETTING_TAG, ONLINE_SERVICES_SETTING_TAG } from 'vs/workbench/parts/preferences/browser/settingsTree'; import { TOCDataSource, TOCRenderer, TOCTreeModel } from 'vs/workbench/parts/preferences/browser/tocTree'; import { CONTEXT_SETTINGS_EDITOR, CONTEXT_SETTINGS_FIRST_ROW_FOCUS, CONTEXT_SETTINGS_ROW_FOCUS, CONTEXT_SETTINGS_SEARCH_FOCUS, CONTEXT_TOC_ROW_FOCUS, IPreferencesSearchService, ISearchProvider } from 'vs/workbench/parts/preferences/common/preferences'; import { IPreferencesService, ISearchResult, ISettingsEditorModel } from 'vs/workbench/services/preferences/common/preferences'; @@ -236,8 +236,8 @@ export class SettingsEditor2 extends BaseEditor { this), this.instantiationService.createInstance( FilterByTagAction, - localize('filterBackgroundOnlineLabel', "Control background online features"), - BACKGROUND_ONLINE_TAG, + localize('filterOnlineServicesLabel', "Show settings for online services"), + ONLINE_SERVICES_SETTING_TAG, this), new Separator(), this.instantiationService.createInstance(OpenSettingsAction) diff --git a/src/vs/workbench/parts/preferences/browser/settingsTree.ts b/src/vs/workbench/parts/preferences/browser/settingsTree.ts index 282ed7f0c7e..bca419d84bc 100644 --- a/src/vs/workbench/parts/preferences/browser/settingsTree.ts +++ b/src/vs/workbench/parts/preferences/browser/settingsTree.ts @@ -41,7 +41,7 @@ import { ISearchResult, ISetting, ISettingsGroup } from 'vs/workbench/services/p const $ = DOM.$; export const MODIFIED_SETTING_TAG = 'modified'; -export const BACKGROUND_ONLINE_TAG = 'backgroundOnlineFeature'; +export const ONLINE_SERVICES_SETTING_TAG = 'usesOnlineServices'; export abstract class SettingsTreeElement { id: string; diff --git a/src/vs/workbench/services/crashReporter/electron-browser/crashReporterService.ts b/src/vs/workbench/services/crashReporter/electron-browser/crashReporterService.ts index b0997699777..6df2345bd64 100644 --- a/src/vs/workbench/services/crashReporter/electron-browser/crashReporterService.ts +++ b/src/vs/workbench/services/crashReporter/electron-browser/crashReporterService.ts @@ -38,7 +38,7 @@ configurationRegistry.registerConfiguration({ 'type': 'boolean', 'description': nls.localize('telemetry.enableCrashReporting', "Enable crash reports to be sent to Microsoft.\nThis option requires restart to take effect."), 'default': true, - 'tags': ['backgroundOnlineFeature'] + 'tags': ['usesOnlineServices'] } } }); From 74b52475049d7bae092ca0890909b932d62b543c Mon Sep 17 00:00:00 2001 From: Matt Bierner Date: Thu, 26 Jul 2018 17:04:59 -0700 Subject: [PATCH 0197/1276] Use more explicit types for ts server execute - Only allow known strings to be used as commands - Simplify overloading. Introduce new `executeWithoutWaitingForResponse` function for calls that are fire and forget - Always require a token for execture calls --- .../src/features/bufferSyncSupport.ts | 6 +- .../src/features/completions.ts | 12 +- .../src/features/definitionProviderBase.ts | 2 +- .../src/features/definitions.ts | 12 +- .../src/features/fileConfigurationManager.ts | 4 +- .../src/features/implementations.ts | 2 +- .../src/features/jsDocCompletions.ts | 8 +- .../src/features/organizeImports.ts | 3 +- .../src/features/quickFix.ts | 9 +- .../src/features/refactor.ts | 5 +- .../src/features/typeDefinitions.ts | 2 +- .../src/features/updatePathsOnRename.ts | 7 +- .../src/typeScriptServiceClientHost.ts | 4 +- .../src/typescriptService.ts | 111 ++++++++++++------ .../src/typescriptServiceClient.ts | 35 ++++-- .../src/utils/cancellation.ts | 10 ++ .../src/utils/codeAction.ts | 10 +- 17 files changed, 155 insertions(+), 87 deletions(-) create mode 100644 extensions/typescript-language-features/src/utils/cancellation.ts diff --git a/extensions/typescript-language-features/src/features/bufferSyncSupport.ts b/extensions/typescript-language-features/src/features/bufferSyncSupport.ts index f46c5e4c431..ddbccd3a27d 100644 --- a/extensions/typescript-language-features/src/features/bufferSyncSupport.ts +++ b/extensions/typescript-language-features/src/features/bufferSyncSupport.ts @@ -63,7 +63,7 @@ class SyncedBuffer { } } - this.client.execute('open', args, false); + this.client.executeWithoutWaitingForResponse('open', args); } public get resource(): vscode.Uri { @@ -91,7 +91,7 @@ class SyncedBuffer { const args: Proto.FileRequestArgs = { file: this.filepath }; - this.client.execute('close', args, false); + this.client.executeWithoutWaitingForResponse('close', args); } public onContentChanged(events: vscode.TextDocumentContentChangeEvent[]): void { @@ -100,7 +100,7 @@ class SyncedBuffer { insertString: text, ...typeConverters.Range.toFormattingRequestArgs(this.filepath, range) }; - this.client.execute('change', args, false); + this.client.executeWithoutWaitingForResponse('change', args); } } } diff --git a/extensions/typescript-language-features/src/features/completions.ts b/extensions/typescript-language-features/src/features/completions.ts index 5f7ab357636..e1eb9121f13 100644 --- a/extensions/typescript-language-features/src/features/completions.ts +++ b/extensions/typescript-language-features/src/features/completions.ts @@ -16,6 +16,7 @@ import * as typeConverters from '../utils/typeConverters'; import TypingsStatus from '../utils/typingsStatus'; import FileConfigurationManager from './fileConfigurationManager'; import { memoize } from '../utils/memoize'; +import { nulToken } from '../utils/cancellation'; const localize = nls.loadMessageBundle(); @@ -205,7 +206,7 @@ class ApplyCompletionCodeActionCommand implements Command { } if (codeActions.length === 1) { - return applyCodeAction(this.client, codeActions[0]); + return applyCodeAction(this.client, codeActions[0], nulToken); } interface MyQuickPickItem extends vscode.QuickPickItem { @@ -230,7 +231,7 @@ class ApplyCompletionCodeActionCommand implements Command { if (!action) { return false; } - return applyCodeAction(this.client, action); + return applyCodeAction(this.client, action, nulToken); } } @@ -384,7 +385,7 @@ class TypeScriptCompletionItemProvider implements vscode.CompletionItemProvider item.additionalTextEdits = additionalTextEdits; if (detail && item.useCodeSnippet) { - const shouldCompleteFunction = await this.isValidFunctionCompletionContext(filepath, item.position); + const shouldCompleteFunction = await this.isValidFunctionCompletionContext(filepath, item.position, token); if (shouldCompleteFunction) { item.insertText = this.snippetForFunctionCall(item, detail); } @@ -524,12 +525,13 @@ class TypeScriptCompletionItemProvider implements vscode.CompletionItemProvider private async isValidFunctionCompletionContext( filepath: string, - position: vscode.Position + position: vscode.Position, + token: vscode.CancellationToken ): Promise { // Workaround for https://github.com/Microsoft/TypeScript/issues/12677 // Don't complete function calls inside of destructive assigments or imports try { - const { body } = await this.client.execute('quickinfo', typeConverters.Position.toFileLocationRequestArgs(filepath, position)); + const { body } = await this.client.execute('quickinfo', typeConverters.Position.toFileLocationRequestArgs(filepath, position), token); switch (body && body.kind) { case 'var': case 'let': diff --git a/extensions/typescript-language-features/src/features/definitionProviderBase.ts b/extensions/typescript-language-features/src/features/definitionProviderBase.ts index 88d61f56a87..186d3e711dd 100644 --- a/extensions/typescript-language-features/src/features/definitionProviderBase.ts +++ b/extensions/typescript-language-features/src/features/definitionProviderBase.ts @@ -18,7 +18,7 @@ export default class TypeScriptDefinitionProviderBase { definitionType: 'definition' | 'implementation' | 'typeDefinition', document: vscode.TextDocument, position: vscode.Position, - token: vscode.CancellationToken | boolean + token: vscode.CancellationToken ): Promise { const filepath = this.client.toPath(document.uri); if (!filepath) { diff --git a/extensions/typescript-language-features/src/features/definitions.ts b/extensions/typescript-language-features/src/features/definitions.ts index 99b9c366247..6e260d5d089 100644 --- a/extensions/typescript-language-features/src/features/definitions.ts +++ b/extensions/typescript-language-features/src/features/definitions.ts @@ -4,7 +4,6 @@ *--------------------------------------------------------------------------------------------*/ import * as vscode from 'vscode'; -import * as Proto from '../protocol'; import { ITypeScriptServiceClient } from '../typescriptService'; import API from '../utils/api'; import * as typeConverters from '../utils/typeConverters'; @@ -20,7 +19,7 @@ export default class TypeScriptDefinitionProvider extends DefinitionProviderBase public async provideDefinition( document: vscode.TextDocument, position: vscode.Position, - token: vscode.CancellationToken | boolean + token: vscode.CancellationToken ): Promise { if (this.client.apiVersion.gte(API.v270)) { const filepath = this.client.toPath(document.uri); @@ -30,14 +29,13 @@ export default class TypeScriptDefinitionProvider extends DefinitionProviderBase const args = typeConverters.Position.toFileLocationRequestArgs(filepath, position); try { - const response = await this.client.execute('definitionAndBoundSpan', args, token); - const locations: Proto.FileSpan[] = (response && response.body && response.body.definitions) || []; - if (!locations) { + const { body } = await this.client.execute('definitionAndBoundSpan', args, token); + if (!body) { return undefined; } - const span = response.body.textSpan ? typeConverters.Range.fromTextSpan(response.body.textSpan) : undefined; - return locations + const span = body.textSpan ? typeConverters.Range.fromTextSpan(body.textSpan) : undefined; + return body.definitions .map(location => { const target = typeConverters.Location.fromTextSpan(this.client.toResource(location.file), location); return { diff --git a/extensions/typescript-language-features/src/features/fileConfigurationManager.ts b/extensions/typescript-language-features/src/features/fileConfigurationManager.ts index 90587ba4925..f7b77cb35f6 100644 --- a/extensions/typescript-language-features/src/features/fileConfigurationManager.ts +++ b/extensions/typescript-language-features/src/features/fileConfigurationManager.ts @@ -59,7 +59,7 @@ export default class FileConfigurationManager { public async ensureConfigurationForDocument( document: vscode.TextDocument, - token: vscode.CancellationToken | undefined + token: vscode.CancellationToken ): Promise { const editor = vscode.window.visibleTextEditors.find(editor => editor.document.fileName === document.fileName); if (editor) { @@ -74,7 +74,7 @@ export default class FileConfigurationManager { public async ensureConfigurationOptions( document: vscode.TextDocument, options: vscode.FormattingOptions, - token: vscode.CancellationToken | undefined + token: vscode.CancellationToken ): Promise { const file = this.client.toPath(document.uri); if (!file) { diff --git a/extensions/typescript-language-features/src/features/implementations.ts b/extensions/typescript-language-features/src/features/implementations.ts index c2627a35244..d750587ea8d 100644 --- a/extensions/typescript-language-features/src/features/implementations.ts +++ b/extensions/typescript-language-features/src/features/implementations.ts @@ -10,7 +10,7 @@ import { VersionDependentRegistration } from '../utils/dependentRegistration'; import DefinitionProviderBase from './definitionProviderBase'; class TypeScriptImplementationProvider extends DefinitionProviderBase implements vscode.ImplementationProvider { - public provideImplementation(document: vscode.TextDocument, position: vscode.Position, token: vscode.CancellationToken | boolean): Promise { + public provideImplementation(document: vscode.TextDocument, position: vscode.Position, token: vscode.CancellationToken): Promise { return this.getSymbolLocations('implementation', document, position, token); } } diff --git a/extensions/typescript-language-features/src/features/jsDocCompletions.ts b/extensions/typescript-language-features/src/features/jsDocCompletions.ts index 49a51c95807..02eb7439d95 100644 --- a/extensions/typescript-language-features/src/features/jsDocCompletions.ts +++ b/extensions/typescript-language-features/src/features/jsDocCompletions.ts @@ -161,9 +161,13 @@ class TryCompleteJsDocCommand implements Command { public static getSnippetTemplate(client: ITypeScriptServiceClient, file: string, position: vscode.Position): Promise { const args = typeConverters.Position.toFileLocationRequestArgs(file, position); + const tokenSource = new vscode.CancellationTokenSource(); return Promise.race([ - client.execute('docCommentTemplate', args), - new Promise((_, reject) => setTimeout(reject, 250)) + client.execute('docCommentTemplate', args, tokenSource.token), + new Promise((_, reject) => setTimeout(() => { + tokenSource.cancel(); + reject(); + }, 250)) ]).then((res: Proto.DocCommandTemplateResponse) => { if (!res || !res.body) { return undefined; diff --git a/extensions/typescript-language-features/src/features/organizeImports.ts b/extensions/typescript-language-features/src/features/organizeImports.ts index 2803d645d0a..302da37e8fe 100644 --- a/extensions/typescript-language-features/src/features/organizeImports.ts +++ b/extensions/typescript-language-features/src/features/organizeImports.ts @@ -13,6 +13,7 @@ import { VersionDependentRegistration } from '../utils/dependentRegistration'; import * as typeconverts from '../utils/typeConverters'; import FileConfigurationManager from './fileConfigurationManager'; import TelemetryReporter from '../utils/telemetry'; +import { nulToken } from '../utils/cancellation'; const localize = nls.loadMessageBundle(); @@ -45,7 +46,7 @@ class OrganizeImportsCommand implements Command { } } }; - const { body } = await this.client.execute('organizeImports', args); + const { body } = await this.client.execute('organizeImports', args, nulToken); const edits = typeconverts.WorkspaceEdit.fromFileCodeEdits(this.client, body); return vscode.workspace.applyEdit(edits); } diff --git a/extensions/typescript-language-features/src/features/quickFix.ts b/extensions/typescript-language-features/src/features/quickFix.ts index 00679075cf9..78af910606b 100644 --- a/extensions/typescript-language-features/src/features/quickFix.ts +++ b/extensions/typescript-language-features/src/features/quickFix.ts @@ -15,6 +15,7 @@ import TelemetryReporter from '../utils/telemetry'; import * as typeConverters from '../utils/typeConverters'; import { DiagnosticsManager } from './diagnostics'; import FileConfigurationManager from './fileConfigurationManager'; +import { nulToken } from '../utils/cancellation'; const localize = nls.loadMessageBundle(); @@ -42,7 +43,7 @@ class ApplyCodeActionCommand implements Command { fixName: action.fixName }); - return applyCodeActionCommands(this.client, action.commands); + return applyCodeActionCommands(this.client, action.commands, nulToken); } } @@ -85,14 +86,14 @@ class ApplyFixAllCodeAction implements Command { }; try { - const { body } = await this.client.execute('getCombinedCodeFix', args); + const { body } = await this.client.execute('getCombinedCodeFix', args, nulToken); if (!body) { return; } const edit = typeConverters.WorkspaceEdit.fromFileCodeEdits(this.client, body.changes); await vscode.workspace.applyEdit(edit); - await applyCodeActionCommands(this.client, body.commands); + await applyCodeActionCommands(this.client, body.commands, nulToken); } catch { // noop } @@ -167,7 +168,7 @@ class SupportedCodeActionProvider { private get supportedCodeActions(): Thenable> { if (!this._supportedCodeActions) { - this._supportedCodeActions = this.client.execute('getSupportedCodeFixes', null, undefined) + this._supportedCodeActions = this.client.execute('getSupportedCodeFixes', null, nulToken) .then(response => response.body || []) .then(codes => codes.map(code => +code).filter(code => !isNaN(code))) .then(codes => new Set(codes)); diff --git a/extensions/typescript-language-features/src/features/refactor.ts b/extensions/typescript-language-features/src/features/refactor.ts index ccb5e2f12f8..bdc5d4eb25e 100644 --- a/extensions/typescript-language-features/src/features/refactor.ts +++ b/extensions/typescript-language-features/src/features/refactor.ts @@ -12,6 +12,7 @@ import { VersionDependentRegistration } from '../utils/dependentRegistration'; import TelemetryReporter from '../utils/telemetry'; import * as typeConverters from '../utils/typeConverters'; import FormattingOptionsManager from './fileConfigurationManager'; +import { nulToken } from '../utils/cancellation'; class ApplyRefactoringCommand implements Command { @@ -47,7 +48,7 @@ class ApplyRefactoringCommand implements Command { refactor, action }; - const { body } = await this.client.execute('getEditsForRefactor', args); + const { body } = await this.client.execute('getEditsForRefactor', args, nulToken); if (!body || !body.edits.length) { return false; } @@ -136,7 +137,7 @@ class TypeScriptRefactorProvider implements vscode.CodeActionProvider { return undefined; } - await this.formattingOptionsManager.ensureConfigurationForDocument(document, undefined); + await this.formattingOptionsManager.ensureConfigurationForDocument(document, token); const args: Proto.GetApplicableRefactorsRequestArgs = typeConverters.Range.toFileRangeRequestArgs(file, rangeOrSelection); let refactorings: Proto.ApplicableRefactorInfo[]; diff --git a/extensions/typescript-language-features/src/features/typeDefinitions.ts b/extensions/typescript-language-features/src/features/typeDefinitions.ts index 23f8b18af39..45d89aeaedd 100644 --- a/extensions/typescript-language-features/src/features/typeDefinitions.ts +++ b/extensions/typescript-language-features/src/features/typeDefinitions.ts @@ -10,7 +10,7 @@ import { VersionDependentRegistration } from '../utils/dependentRegistration'; import DefinitionProviderBase from './definitionProviderBase'; export default class TypeScriptTypeDefinitionProvider extends DefinitionProviderBase implements vscode.TypeDefinitionProvider { - public provideTypeDefinition(document: vscode.TextDocument, position: vscode.Position, token: vscode.CancellationToken | boolean): Promise { + public provideTypeDefinition(document: vscode.TextDocument, position: vscode.Position, token: vscode.CancellationToken): Promise { return this.getSymbolLocations('typeDefinition', document, position, token); } } diff --git a/extensions/typescript-language-features/src/features/updatePathsOnRename.ts b/extensions/typescript-language-features/src/features/updatePathsOnRename.ts index ba19b8da8aa..6d12999aa92 100644 --- a/extensions/typescript-language-features/src/features/updatePathsOnRename.ts +++ b/extensions/typescript-language-features/src/features/updatePathsOnRename.ts @@ -16,6 +16,7 @@ import { escapeRegExp } from '../utils/regexp'; import * as typeConverters from '../utils/typeConverters'; import FileConfigurationManager from './fileConfigurationManager'; import { VersionDependentRegistration } from '../utils/dependentRegistration'; +import { nulToken } from '../utils/cancellation'; const localize = nls.loadMessageBundle(); @@ -84,7 +85,7 @@ class UpdateImportsOnFileRenameHandler { // Workaround for https://github.com/Microsoft/vscode/issues/52967 // Never attempt to update import paths if the file does not contain something the looks like an export try { - const { body } = await this.client.execute('navtree', { file: newFile }); + const { body } = await this.client.execute('navtree', { file: newFile }, nulToken); const hasExport = (node: Proto.NavigationTree): boolean => { return !!node.kindModifiers.match(/\bexports?\b/g) || !!(node.childItems && node.childItems.some(hasExport)); }; @@ -229,14 +230,14 @@ class UpdateImportsOnFileRenameHandler { newFile: string, ) { const isDirectoryRename = fs.lstatSync(newFile).isDirectory(); - await this.fileConfigurationManager.ensureConfigurationForDocument(document, undefined); + await this.fileConfigurationManager.ensureConfigurationForDocument(document, nulToken); const args: Proto.GetEditsForFileRenameRequestArgs & { file: string } = { file: targetResource, oldFilePath: oldFile, newFilePath: newFile, }; - const response = await this.client.execute('getEditsForFileRename', args); + const response = await this.client.execute('getEditsForFileRename', args, nulToken); if (!response || !response.body) { return; } diff --git a/extensions/typescript-language-features/src/typeScriptServiceClientHost.ts b/extensions/typescript-language-features/src/typeScriptServiceClientHost.ts index cea7c0a2bc4..afff7001672 100644 --- a/extensions/typescript-language-features/src/typeScriptServiceClientHost.ts +++ b/extensions/typescript-language-features/src/typeScriptServiceClientHost.ts @@ -55,7 +55,7 @@ export default class TypeScriptServiceClientHost extends Disposable { ) { super(); const handleProjectCreateOrDelete = () => { - this.client.execute('reloadProjects', null, false); + this.client.executeWithoutWaitingForResponse('reloadProjects', null); this.triggerAllDiagnostics(); }; const handleProjectChange = () => { @@ -150,7 +150,7 @@ export default class TypeScriptServiceClientHost extends Disposable { } public reloadProjects(): void { - this.client.execute('reloadProjects', null, false); + this.client.executeWithoutWaitingForResponse('reloadProjects', null); this.triggerAllDiagnostics(); } diff --git a/extensions/typescript-language-features/src/typescriptService.ts b/extensions/typescript-language-features/src/typescriptService.ts index bb6baa31915..b31f39659fb 100644 --- a/extensions/typescript-language-features/src/typescriptService.ts +++ b/extensions/typescript-language-features/src/typescriptService.ts @@ -11,6 +11,70 @@ import { TypeScriptServiceConfiguration } from './utils/configuration'; import Logger from './utils/logger'; import { TypeScriptServerPlugin } from './utils/plugins'; +interface TypeScriptArgsMap { + 'configure': Proto.ConfigureRequestArguments; + 'quickinfo': Proto.FileLocationRequestArgs; + 'completions': Proto.CompletionsRequestArgs; + 'completionInfo': Proto.CompletionsRequestArgs; + 'completionEntryDetails': Proto.CompletionDetailsRequestArgs; + 'signatureHelp': Proto.SignatureHelpRequestArgs; + 'definition': Proto.FileLocationRequestArgs; + 'definitionAndBoundSpan': Proto.FileLocationRequestArgs; + 'implementation': Proto.FileLocationRequestArgs; + 'typeDefinition': Proto.FileLocationRequestArgs; + 'references': Proto.FileLocationRequestArgs; + 'navto': Proto.NavtoRequestArgs; + 'format': Proto.FormatRequestArgs; + 'formatonkey': Proto.FormatOnKeyRequestArgs; + 'rename': Proto.RenameRequestArgs; + 'occurrences': Proto.FileLocationRequestArgs; + 'projectInfo': Proto.ProjectInfoRequestArgs; + 'navtree': Proto.FileRequestArgs; + 'getCodeFixes': Proto.CodeFixRequestArgs; + 'getSupportedCodeFixes': null; + 'getCombinedCodeFix': Proto.GetCombinedCodeFixRequestArgs; + 'docCommentTemplate': Proto.FileLocationRequestArgs; + 'getApplicableRefactors': Proto.GetApplicableRefactorsRequestArgs; + 'getEditsForRefactor': Proto.GetEditsForRefactorRequestArgs; + 'applyCodeActionCommand': Proto.ApplyCodeActionCommandRequestArgs; + 'organizeImports': Proto.OrganizeImportsRequestArgs; + 'getOutliningSpans': Proto.FileRequestArgs; + 'getEditsForFileRename': Proto.GetEditsForFileRenameRequestArgs; + 'jsxClosingTag': Proto.JsxClosingTagRequestArgs; +} + +interface TypeScriptResultMap { + 'configure': Proto.ConfigureResponse; + 'quickinfo': Proto.QuickInfoResponse; + 'completions': Proto.CompletionsResponse; + 'completionInfo': Proto.CompletionInfoResponse; + 'completionEntryDetails': Proto.CompletionDetailsResponse; + 'signatureHelp': Proto.SignatureHelpResponse; + 'definition': Proto.DefinitionResponse; + 'definitionAndBoundSpan': Proto.DefinitionInfoAndBoundSpanReponse; + 'implementation': Proto.ImplementationResponse; + 'typeDefinition': Proto.TypeDefinitionResponse; + 'references': Proto.ReferencesResponse; + 'navto': Proto.NavtoResponse; + 'format': Proto.FormatResponse; + 'formatonkey': Proto.FormatResponse; + 'rename': Proto.RenameResponse; + 'occurrences': Proto.OccurrencesResponse; + 'projectInfo': Proto.ProjectInfoResponse; + 'navtree': Proto.NavTreeResponse; + 'getCodeFixes': Proto.GetCodeFixesResponse; + 'getSupportedCodeFixes': Proto.GetSupportedCodeFixesResponse; + 'getCombinedCodeFix': Proto.GetCombinedCodeFixResponse; + 'docCommentTemplate': Proto.DocCommandTemplateResponse; + 'getApplicableRefactors': Proto.GetApplicableRefactorsResponse; + 'getEditsForRefactor': Proto.GetEditsForRefactorResponse; + 'applyCodeActionCommand': Proto.ApplyCodeActionCommandResponse; + 'organizeImports': Proto.OrganizeImportsResponse; + 'getOutliningSpans': Proto.OutliningSpansResponse; + 'getEditsForFileRename': Proto.GetEditsForFileRenameResponse; + 'jsxClosingTag': Proto.JsxClosingTagResponse; +} + export interface ITypeScriptServiceClient { /** * Convert a resource (VS Code) to a normalized path (TypeScript). @@ -45,42 +109,17 @@ export interface ITypeScriptServiceClient { readonly logger: Logger; readonly bufferSyncSupport: BufferSyncSupport; - execute(command: 'configure', args: Proto.ConfigureRequestArguments, token?: vscode.CancellationToken): Promise; - execute(command: 'open', args: Proto.OpenRequestArgs, expectedResult: boolean, token?: vscode.CancellationToken): Promise; - execute(command: 'close', args: Proto.FileRequestArgs, expectedResult: boolean, token?: vscode.CancellationToken): Promise; - execute(command: 'change', args: Proto.ChangeRequestArgs, expectedResult: boolean, token?: vscode.CancellationToken): Promise; - execute(command: 'quickinfo', args: Proto.FileLocationRequestArgs, token?: vscode.CancellationToken): Promise; - execute(command: 'completions', args: Proto.CompletionsRequestArgs, token?: vscode.CancellationToken): Promise; - execute(command: 'completionInfo', args: Proto.CompletionsRequestArgs, token?: vscode.CancellationToken): Promise; - execute(command: 'completionEntryDetails', args: Proto.CompletionDetailsRequestArgs, token?: vscode.CancellationToken): Promise; - execute(command: 'signatureHelp', args: Proto.SignatureHelpRequestArgs, token?: vscode.CancellationToken): Promise; - execute(command: 'definition', args: Proto.FileLocationRequestArgs, token?: vscode.CancellationToken): Promise; - execute(command: 'definitionAndBoundSpan', args: Proto.FileLocationRequestArgs, token?: vscode.CancellationToken): Promise; - execute(command: 'implementation', args: Proto.FileLocationRequestArgs, token?: vscode.CancellationToken): Promise; - execute(command: 'typeDefinition', args: Proto.FileLocationRequestArgs, token?: vscode.CancellationToken): Promise; - execute(command: 'references', args: Proto.FileLocationRequestArgs, token?: vscode.CancellationToken): Promise; - execute(command: 'navto', args: Proto.NavtoRequestArgs, token?: vscode.CancellationToken): Promise; - execute(command: 'format', args: Proto.FormatRequestArgs, token?: vscode.CancellationToken): Promise; - execute(command: 'formatonkey', args: Proto.FormatOnKeyRequestArgs, token?: vscode.CancellationToken): Promise; - execute(command: 'rename', args: Proto.RenameRequestArgs, token?: vscode.CancellationToken): Promise; - execute(command: 'occurrences', args: Proto.FileLocationRequestArgs, token?: vscode.CancellationToken): Promise; - execute(command: 'projectInfo', args: Proto.ProjectInfoRequestArgs, token?: vscode.CancellationToken): Promise; - execute(command: 'reloadProjects', args: any, expectedResult: boolean, token?: vscode.CancellationToken): Promise; - execute(command: 'reload', args: Proto.ReloadRequestArgs, expectedResult: boolean, token?: vscode.CancellationToken): Promise; - execute(command: 'compilerOptionsForInferredProjects', args: Proto.SetCompilerOptionsForInferredProjectsArgs, token?: vscode.CancellationToken): Promise; - execute(command: 'navtree', args: Proto.FileRequestArgs, token?: vscode.CancellationToken): Promise; - execute(command: 'getCodeFixes', args: Proto.CodeFixRequestArgs, token?: vscode.CancellationToken): Promise; - execute(command: 'getSupportedCodeFixes', args: null, token?: vscode.CancellationToken): Promise; - execute(command: 'getCombinedCodeFix', args: Proto.GetCombinedCodeFixRequestArgs, token?: vscode.CancellationToken): Promise; - execute(command: 'docCommentTemplate', args: Proto.FileLocationRequestArgs, token?: vscode.CancellationToken): Promise; - execute(command: 'getApplicableRefactors', args: Proto.GetApplicableRefactorsRequestArgs, token?: vscode.CancellationToken): Promise; - execute(command: 'getEditsForRefactor', args: Proto.GetEditsForRefactorRequestArgs, token?: vscode.CancellationToken): Promise; - execute(command: 'applyCodeActionCommand', args: Proto.ApplyCodeActionCommandRequestArgs, token?: vscode.CancellationToken): Promise; - execute(command: 'organizeImports', args: Proto.OrganizeImportsRequestArgs, token?: vscode.CancellationToken): Promise; - execute(command: 'getOutliningSpans', args: Proto.FileRequestArgs, token: vscode.CancellationToken): Promise; - execute(command: 'getEditsForFileRename', args: Proto.GetEditsForFileRenameRequestArgs): Promise; - execute(command: 'jsxClosingTag', args: Proto.JsxClosingTagRequestArgs, token: vscode.CancellationToken): Promise; - execute(command: string, args: any, expectedResult: boolean | vscode.CancellationToken, token?: vscode.CancellationToken): Promise; + execute( + command: K, + args: TypeScriptArgsMap[K], + token: vscode.CancellationToken + ): Promise; + + executeWithoutWaitingForResponse(command: 'open', args: Proto.OpenRequestArgs): void; + executeWithoutWaitingForResponse(command: 'close', args: Proto.FileRequestArgs): void; + executeWithoutWaitingForResponse(command: 'change', args: Proto.ChangeRequestArgs): void; + executeWithoutWaitingForResponse(command: 'compilerOptionsForInferredProjects', args: Proto.SetCompilerOptionsForInferredProjectsArgs): void; + executeWithoutWaitingForResponse(command: 'reloadProjects', args: null): void; executeAsync(command: 'geterr', args: Proto.GeterrRequestArgs, token: vscode.CancellationToken): Promise; } \ 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 adc73a29e3b..2d20a3c0a64 100644 --- a/extensions/typescript-language-features/src/typescriptServiceClient.ts +++ b/extensions/typescript-language-features/src/typescriptServiceClient.ts @@ -521,7 +521,7 @@ export default class TypeScriptServiceClient extends Disposable implements IType const configureOptions: Proto.ConfigureRequestArguments = { hostInfo: 'vscode' }; - this.execute('configure', configureOptions); + this.executeWithoutWaitingForResponse('configure', configureOptions); this.setCompilerOptionsForInferredProjects(this._configuration); if (resendModels) { this._onResendModelsRequested.fire(); @@ -536,7 +536,7 @@ export default class TypeScriptServiceClient extends Disposable implements IType const args: Proto.SetCompilerOptionsForInferredProjectsArgs = { options: this.getCompilerOptionsForInferredProjects(configuration) }; - this.execute('compilerOptionsForInferredProjects', args, true); + this.executeWithoutWaitingForResponse('compilerOptionsForInferredProjects', args); } private getCompilerOptionsForInferredProjects(configuration: TypeScriptServiceConfiguration): Proto.ExternalProjectCompilerOptions { @@ -679,19 +679,28 @@ export default class TypeScriptServiceClient extends Disposable implements IType return undefined; } - public executeAsync(command: string, args: Proto.GeterrRequestArgs, token: vscode.CancellationToken): Promise { - return this.executeImpl(command, args, { isAsync: true, token, expectsResult: true }); + public execute(command: string, args: any, token: vscode.CancellationToken): Promise { + return this.executeImpl(command, args, { + isAsync: false, + token, + expectsResult: true + }); } - public execute(command: string, args: any, expectsResultOrToken?: boolean | vscode.CancellationToken): Promise { - let token: vscode.CancellationToken | undefined = undefined; - let expectsResult = true; - if (typeof expectsResultOrToken === 'boolean') { - expectsResult = expectsResultOrToken; - } else { - token = expectsResultOrToken; - } - return this.executeImpl(command, args, { isAsync: false, token, expectsResult }); + public executeWithoutWaitingForResponse(command: string, args: any): void { + this.executeImpl(command, args, { + isAsync: false, + token: undefined, + expectsResult: false + }); + } + + public executeAsync(command: string, args: Proto.GeterrRequestArgs, token: vscode.CancellationToken): Promise { + return this.executeImpl(command, args, { + isAsync: true, + token, + expectsResult: true + }); } private executeImpl(command: string, args: any, executeInfo: { isAsync: boolean, token?: vscode.CancellationToken, expectsResult: boolean }): Promise { diff --git a/extensions/typescript-language-features/src/utils/cancellation.ts b/extensions/typescript-language-features/src/utils/cancellation.ts new file mode 100644 index 00000000000..10933baa939 --- /dev/null +++ b/extensions/typescript-language-features/src/utils/cancellation.ts @@ -0,0 +1,10 @@ +/*--------------------------------------------------------------------------------------------- + * 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 nulTokenSource = new vscode.CancellationTokenSource(); + +export const nulToken = nulTokenSource.token; \ No newline at end of file diff --git a/extensions/typescript-language-features/src/utils/codeAction.ts b/extensions/typescript-language-features/src/utils/codeAction.ts index 6109ed70051..c45379e611a 100644 --- a/extensions/typescript-language-features/src/utils/codeAction.ts +++ b/extensions/typescript-language-features/src/utils/codeAction.ts @@ -19,7 +19,8 @@ export function getEditForCodeAction( export async function applyCodeAction( client: ITypeScriptServiceClient, - action: Proto.CodeAction + action: Proto.CodeAction, + token: vscode.CancellationToken ): Promise { const workspaceEdit = getEditForCodeAction(client, action); if (workspaceEdit) { @@ -27,16 +28,17 @@ export async function applyCodeAction( return false; } } - return applyCodeActionCommands(client, action.commands); + return applyCodeActionCommands(client, action.commands, token); } export async function applyCodeActionCommands( client: ITypeScriptServiceClient, - commands: ReadonlyArray<{}> | undefined + commands: ReadonlyArray<{}> | undefined, + token: vscode.CancellationToken, ): Promise { if (commands && commands.length) { for (const command of commands) { - await client.execute('applyCodeActionCommand', { command }); + await client.execute('applyCodeActionCommand', { command }, token); } } return true; From 52db14c9e68abae4280a8d4f7ddc52d868901e3a Mon Sep 17 00:00:00 2001 From: Matt Bierner Date: Thu, 26 Jul 2018 17:05:48 -0700 Subject: [PATCH 0198/1276] Sort definitions --- .../src/typescriptService.ts | 84 +++++++++---------- 1 file changed, 42 insertions(+), 42 deletions(-) diff --git a/extensions/typescript-language-features/src/typescriptService.ts b/extensions/typescript-language-features/src/typescriptService.ts index b31f39659fb..064567be476 100644 --- a/extensions/typescript-language-features/src/typescriptService.ts +++ b/extensions/typescript-language-features/src/typescriptService.ts @@ -12,67 +12,67 @@ import Logger from './utils/logger'; import { TypeScriptServerPlugin } from './utils/plugins'; interface TypeScriptArgsMap { - 'configure': Proto.ConfigureRequestArguments; - 'quickinfo': Proto.FileLocationRequestArgs; - 'completions': Proto.CompletionsRequestArgs; - 'completionInfo': Proto.CompletionsRequestArgs; + 'applyCodeActionCommand': Proto.ApplyCodeActionCommandRequestArgs; 'completionEntryDetails': Proto.CompletionDetailsRequestArgs; - 'signatureHelp': Proto.SignatureHelpRequestArgs; + 'completionInfo': Proto.CompletionsRequestArgs; + 'completions': Proto.CompletionsRequestArgs; + 'configure': Proto.ConfigureRequestArguments; 'definition': Proto.FileLocationRequestArgs; 'definitionAndBoundSpan': Proto.FileLocationRequestArgs; - 'implementation': Proto.FileLocationRequestArgs; - 'typeDefinition': Proto.FileLocationRequestArgs; - 'references': Proto.FileLocationRequestArgs; - 'navto': Proto.NavtoRequestArgs; + 'docCommentTemplate': Proto.FileLocationRequestArgs; 'format': Proto.FormatRequestArgs; 'formatonkey': Proto.FormatOnKeyRequestArgs; - 'rename': Proto.RenameRequestArgs; - 'occurrences': Proto.FileLocationRequestArgs; - 'projectInfo': Proto.ProjectInfoRequestArgs; - 'navtree': Proto.FileRequestArgs; - 'getCodeFixes': Proto.CodeFixRequestArgs; - 'getSupportedCodeFixes': null; - 'getCombinedCodeFix': Proto.GetCombinedCodeFixRequestArgs; - 'docCommentTemplate': Proto.FileLocationRequestArgs; 'getApplicableRefactors': Proto.GetApplicableRefactorsRequestArgs; - 'getEditsForRefactor': Proto.GetEditsForRefactorRequestArgs; - 'applyCodeActionCommand': Proto.ApplyCodeActionCommandRequestArgs; - 'organizeImports': Proto.OrganizeImportsRequestArgs; - 'getOutliningSpans': Proto.FileRequestArgs; + 'getCodeFixes': Proto.CodeFixRequestArgs; + 'getCombinedCodeFix': Proto.GetCombinedCodeFixRequestArgs; 'getEditsForFileRename': Proto.GetEditsForFileRenameRequestArgs; + 'getEditsForRefactor': Proto.GetEditsForRefactorRequestArgs; + 'getOutliningSpans': Proto.FileRequestArgs; + 'getSupportedCodeFixes': null; + 'implementation': Proto.FileLocationRequestArgs; 'jsxClosingTag': Proto.JsxClosingTagRequestArgs; + 'navto': Proto.NavtoRequestArgs; + 'navtree': Proto.FileRequestArgs; + 'occurrences': Proto.FileLocationRequestArgs; + 'organizeImports': Proto.OrganizeImportsRequestArgs; + 'projectInfo': Proto.ProjectInfoRequestArgs; + 'quickinfo': Proto.FileLocationRequestArgs; + 'references': Proto.FileLocationRequestArgs; + 'rename': Proto.RenameRequestArgs; + 'signatureHelp': Proto.SignatureHelpRequestArgs; + 'typeDefinition': Proto.FileLocationRequestArgs; } interface TypeScriptResultMap { - 'configure': Proto.ConfigureResponse; - 'quickinfo': Proto.QuickInfoResponse; - 'completions': Proto.CompletionsResponse; - 'completionInfo': Proto.CompletionInfoResponse; + 'applyCodeActionCommand': Proto.ApplyCodeActionCommandResponse; 'completionEntryDetails': Proto.CompletionDetailsResponse; - 'signatureHelp': Proto.SignatureHelpResponse; + 'completionInfo': Proto.CompletionInfoResponse; + 'completions': Proto.CompletionsResponse; + 'configure': Proto.ConfigureResponse; 'definition': Proto.DefinitionResponse; 'definitionAndBoundSpan': Proto.DefinitionInfoAndBoundSpanReponse; - 'implementation': Proto.ImplementationResponse; - 'typeDefinition': Proto.TypeDefinitionResponse; - 'references': Proto.ReferencesResponse; - 'navto': Proto.NavtoResponse; + 'docCommentTemplate': Proto.DocCommandTemplateResponse; 'format': Proto.FormatResponse; 'formatonkey': Proto.FormatResponse; - 'rename': Proto.RenameResponse; - 'occurrences': Proto.OccurrencesResponse; - 'projectInfo': Proto.ProjectInfoResponse; - 'navtree': Proto.NavTreeResponse; - 'getCodeFixes': Proto.GetCodeFixesResponse; - 'getSupportedCodeFixes': Proto.GetSupportedCodeFixesResponse; - 'getCombinedCodeFix': Proto.GetCombinedCodeFixResponse; - 'docCommentTemplate': Proto.DocCommandTemplateResponse; 'getApplicableRefactors': Proto.GetApplicableRefactorsResponse; - 'getEditsForRefactor': Proto.GetEditsForRefactorResponse; - 'applyCodeActionCommand': Proto.ApplyCodeActionCommandResponse; - 'organizeImports': Proto.OrganizeImportsResponse; - 'getOutliningSpans': Proto.OutliningSpansResponse; + 'getCodeFixes': Proto.GetCodeFixesResponse; + 'getCombinedCodeFix': Proto.GetCombinedCodeFixResponse; 'getEditsForFileRename': Proto.GetEditsForFileRenameResponse; + 'getEditsForRefactor': Proto.GetEditsForRefactorResponse; + 'getOutliningSpans': Proto.OutliningSpansResponse; + 'getSupportedCodeFixes': Proto.GetSupportedCodeFixesResponse; + 'implementation': Proto.ImplementationResponse; 'jsxClosingTag': Proto.JsxClosingTagResponse; + 'navto': Proto.NavtoResponse; + 'navtree': Proto.NavTreeResponse; + 'occurrences': Proto.OccurrencesResponse; + 'organizeImports': Proto.OrganizeImportsResponse; + 'projectInfo': Proto.ProjectInfoResponse; + 'quickinfo': Proto.QuickInfoResponse; + 'references': Proto.ReferencesResponse; + 'rename': Proto.RenameResponse; + 'signatureHelp': Proto.SignatureHelpResponse; + 'typeDefinition': Proto.TypeDefinitionResponse; } export interface ITypeScriptServiceClient { From e49f6543a669ee54d6cee57ea3de845001ae262d Mon Sep 17 00:00:00 2001 From: Matt Bierner Date: Thu, 26 Jul 2018 17:15:59 -0700 Subject: [PATCH 0199/1276] Reduce duplication and improve errors around TypeScript execute types --- .../src/typescriptService.ts | 97 +++++++------------ 1 file changed, 33 insertions(+), 64 deletions(-) diff --git a/extensions/typescript-language-features/src/typescriptService.ts b/extensions/typescript-language-features/src/typescriptService.ts index 064567be476..990ab8c6384 100644 --- a/extensions/typescript-language-features/src/typescriptService.ts +++ b/extensions/typescript-language-features/src/typescriptService.ts @@ -11,69 +11,38 @@ import { TypeScriptServiceConfiguration } from './utils/configuration'; import Logger from './utils/logger'; import { TypeScriptServerPlugin } from './utils/plugins'; -interface TypeScriptArgsMap { - 'applyCodeActionCommand': Proto.ApplyCodeActionCommandRequestArgs; - 'completionEntryDetails': Proto.CompletionDetailsRequestArgs; - 'completionInfo': Proto.CompletionsRequestArgs; - 'completions': Proto.CompletionsRequestArgs; - 'configure': Proto.ConfigureRequestArguments; - 'definition': Proto.FileLocationRequestArgs; - 'definitionAndBoundSpan': Proto.FileLocationRequestArgs; - 'docCommentTemplate': Proto.FileLocationRequestArgs; - 'format': Proto.FormatRequestArgs; - 'formatonkey': Proto.FormatOnKeyRequestArgs; - 'getApplicableRefactors': Proto.GetApplicableRefactorsRequestArgs; - 'getCodeFixes': Proto.CodeFixRequestArgs; - 'getCombinedCodeFix': Proto.GetCombinedCodeFixRequestArgs; - 'getEditsForFileRename': Proto.GetEditsForFileRenameRequestArgs; - 'getEditsForRefactor': Proto.GetEditsForRefactorRequestArgs; - 'getOutliningSpans': Proto.FileRequestArgs; - 'getSupportedCodeFixes': null; - 'implementation': Proto.FileLocationRequestArgs; - 'jsxClosingTag': Proto.JsxClosingTagRequestArgs; - 'navto': Proto.NavtoRequestArgs; - 'navtree': Proto.FileRequestArgs; - 'occurrences': Proto.FileLocationRequestArgs; - 'organizeImports': Proto.OrganizeImportsRequestArgs; - 'projectInfo': Proto.ProjectInfoRequestArgs; - 'quickinfo': Proto.FileLocationRequestArgs; - 'references': Proto.FileLocationRequestArgs; - 'rename': Proto.RenameRequestArgs; - 'signatureHelp': Proto.SignatureHelpRequestArgs; - 'typeDefinition': Proto.FileLocationRequestArgs; +interface TypeScriptRequestTypes { + 'applyCodeActionCommand': [Proto.ApplyCodeActionCommandRequestArgs, Proto.ApplyCodeActionCommandResponse]; + 'completionEntryDetails': [Proto.CompletionDetailsRequestArgs, Proto.CompletionDetailsResponse]; + 'completionInfo': [Proto.CompletionsRequestArgs, Proto.CompletionInfoResponse]; + 'completions': [Proto.CompletionsRequestArgs, Proto.CompletionsResponse]; + 'configure': [Proto.ConfigureRequestArguments, Proto.ConfigureResponse]; + 'definition': [Proto.FileLocationRequestArgs, Proto.DefinitionResponse]; + 'definitionAndBoundSpan': [Proto.FileLocationRequestArgs, Proto.DefinitionInfoAndBoundSpanReponse]; + 'docCommentTemplate': [Proto.FileLocationRequestArgs, Proto.DocCommandTemplateResponse]; + 'format': [Proto.FormatRequestArgs, Proto.FormatResponse]; + 'formatonkey': [Proto.FormatOnKeyRequestArgs, Proto.FormatResponse]; + 'getApplicableRefactors': [Proto.GetApplicableRefactorsRequestArgs, Proto.GetApplicableRefactorsResponse]; + 'getCodeFixes': [Proto.CodeFixRequestArgs, Proto.GetCodeFixesResponse]; + 'getCombinedCodeFix': [Proto.GetCombinedCodeFixRequestArgs, Proto.GetCombinedCodeFixResponse]; + 'getEditsForFileRename': [Proto.GetEditsForFileRenameRequestArgs, Proto.GetEditsForFileRenameResponse]; + 'getEditsForRefactor': [Proto.GetEditsForRefactorRequestArgs, Proto.GetEditsForRefactorResponse]; + 'getOutliningSpans': [Proto.FileRequestArgs, Proto.OutliningSpansResponse]; + 'getSupportedCodeFixes': [null, Proto.GetSupportedCodeFixesResponse]; + 'implementation': [Proto.FileLocationRequestArgs, Proto.ImplementationResponse]; + 'jsxClosingTag': [Proto.JsxClosingTagRequestArgs, Proto.JsxClosingTagResponse]; + 'navto': [Proto.NavtoRequestArgs, Proto.NavtoResponse]; + 'navtree': [Proto.FileRequestArgs, Proto.NavTreeResponse]; + 'occurrences': [Proto.FileLocationRequestArgs, Proto.OccurrencesResponse]; + 'organizeImports': [Proto.OrganizeImportsRequestArgs, Proto.OrganizeImportsResponse]; + 'projectInfo': [Proto.ProjectInfoRequestArgs, Proto.ProjectInfoResponse]; + 'quickinfo': [Proto.FileLocationRequestArgs, Proto.QuickInfoResponse]; + 'references': [Proto.FileLocationRequestArgs, Proto.ReferencesResponse]; + 'rename': [Proto.RenameRequestArgs, Proto.RenameResponse]; + 'signatureHelp': [Proto.SignatureHelpRequestArgs, Proto.SignatureHelpResponse]; + 'typeDefinition': [Proto.FileLocationRequestArgs, Proto.TypeDefinitionResponse]; } -interface TypeScriptResultMap { - 'applyCodeActionCommand': Proto.ApplyCodeActionCommandResponse; - 'completionEntryDetails': Proto.CompletionDetailsResponse; - 'completionInfo': Proto.CompletionInfoResponse; - 'completions': Proto.CompletionsResponse; - 'configure': Proto.ConfigureResponse; - 'definition': Proto.DefinitionResponse; - 'definitionAndBoundSpan': Proto.DefinitionInfoAndBoundSpanReponse; - 'docCommentTemplate': Proto.DocCommandTemplateResponse; - 'format': Proto.FormatResponse; - 'formatonkey': Proto.FormatResponse; - 'getApplicableRefactors': Proto.GetApplicableRefactorsResponse; - 'getCodeFixes': Proto.GetCodeFixesResponse; - 'getCombinedCodeFix': Proto.GetCombinedCodeFixResponse; - 'getEditsForFileRename': Proto.GetEditsForFileRenameResponse; - 'getEditsForRefactor': Proto.GetEditsForRefactorResponse; - 'getOutliningSpans': Proto.OutliningSpansResponse; - 'getSupportedCodeFixes': Proto.GetSupportedCodeFixesResponse; - 'implementation': Proto.ImplementationResponse; - 'jsxClosingTag': Proto.JsxClosingTagResponse; - 'navto': Proto.NavtoResponse; - 'navtree': Proto.NavTreeResponse; - 'occurrences': Proto.OccurrencesResponse; - 'organizeImports': Proto.OrganizeImportsResponse; - 'projectInfo': Proto.ProjectInfoResponse; - 'quickinfo': Proto.QuickInfoResponse; - 'references': Proto.ReferencesResponse; - 'rename': Proto.RenameResponse; - 'signatureHelp': Proto.SignatureHelpResponse; - 'typeDefinition': Proto.TypeDefinitionResponse; -} export interface ITypeScriptServiceClient { /** @@ -109,11 +78,11 @@ export interface ITypeScriptServiceClient { readonly logger: Logger; readonly bufferSyncSupport: BufferSyncSupport; - execute( + execute( command: K, - args: TypeScriptArgsMap[K], + args: TypeScriptRequestTypes[K][0], token: vscode.CancellationToken - ): Promise; + ): Promise; executeWithoutWaitingForResponse(command: 'open', args: Proto.OpenRequestArgs): void; executeWithoutWaitingForResponse(command: 'close', args: Proto.FileRequestArgs): void; From 21bb4026551bb500a198f5ffd3ea4c64b0309c0b Mon Sep 17 00:00:00 2001 From: Matt Bierner Date: Thu, 26 Jul 2018 17:20:53 -0700 Subject: [PATCH 0200/1276] Fix projectInfo call signature for TS 3.0 --- extensions/typescript-language-features/src/commands.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/extensions/typescript-language-features/src/commands.ts b/extensions/typescript-language-features/src/commands.ts index fce4da698a2..2c40c512e18 100644 --- a/extensions/typescript-language-features/src/commands.ts +++ b/extensions/typescript-language-features/src/commands.ts @@ -9,6 +9,7 @@ import TypeScriptServiceClientHost from './typeScriptServiceClientHost'; import { Command } from './utils/commandManager'; import { Lazy } from './utils/lazy'; import { isImplicitProjectConfigFile, openOrCreateConfigFile } from './utils/tsconfig'; +import { nulToken } from './utils/cancellation'; const localize = nls.loadMessageBundle(); @@ -131,7 +132,7 @@ async function goToProjectConfig( let res: protocol.ProjectInfoResponse | undefined = undefined; try { - res = await client.execute('projectInfo', { file, needFileNameList: false } as protocol.ProjectInfoRequestArgs); + res = await client.execute('projectInfo', { file, needFileNameList: false }, nulToken); } catch { // noop } From 01989b1c67454861883ead850a7326397f45e721 Mon Sep 17 00:00:00 2001 From: Matt Bierner Date: Thu, 26 Jul 2018 17:35:04 -0700 Subject: [PATCH 0201/1276] Set global user preferences on updatePaths https://github.com/Microsoft/TypeScript/issues/25739 --- .../src/features/fileConfigurationManager.ts | 36 +++++++++++++++---- .../src/features/updatePathsOnRename.ts | 2 +- 2 files changed, 31 insertions(+), 7 deletions(-) diff --git a/extensions/typescript-language-features/src/features/fileConfigurationManager.ts b/extensions/typescript-language-features/src/features/fileConfigurationManager.ts index f7b77cb35f6..3068e8df5e1 100644 --- a/extensions/typescript-language-features/src/features/fileConfigurationManager.ts +++ b/extensions/typescript-language-features/src/features/fileConfigurationManager.ts @@ -61,16 +61,24 @@ export default class FileConfigurationManager { document: vscode.TextDocument, token: vscode.CancellationToken ): Promise { - const editor = vscode.window.visibleTextEditors.find(editor => editor.document.fileName === document.fileName); - if (editor) { - const formattingOptions = { - tabSize: editor.options.tabSize, - insertSpaces: editor.options.insertSpaces - } as vscode.FormattingOptions; + const formattingOptions = this.getFormattingOptions(document); + if (formattingOptions) { return this.ensureConfigurationOptions(document, formattingOptions, token); } } + private getFormattingOptions( + document: vscode.TextDocument + ): vscode.FormattingOptions | undefined { + const editor = vscode.window.visibleTextEditors.find(editor => editor.document.fileName === document.fileName); + return editor + ? { + tabSize: editor.options.tabSize, + insertSpaces: editor.options.insertSpaces + } as vscode.FormattingOptions + : undefined; + } + public async ensureConfigurationOptions( document: vscode.TextDocument, options: vscode.FormattingOptions, @@ -95,6 +103,22 @@ export default class FileConfigurationManager { await this.client.execute('configure', args, token); } + public async setGlobalConfigurationFromDocument( + document: vscode.TextDocument, + token: vscode.CancellationToken, + ): Promise { + const formattingOptions = this.getFormattingOptions(document); + if (!formattingOptions) { + return; + } + + const args: Proto.ConfigureRequestArguments = { + file: undefined /*global*/, + ...this.getFileOptions(document, formattingOptions), + }; + await this.client.execute('configure', args, token); + } + public reset() { this.formatOptions.clear(); } diff --git a/extensions/typescript-language-features/src/features/updatePathsOnRename.ts b/extensions/typescript-language-features/src/features/updatePathsOnRename.ts index 6d12999aa92..44c05cd7b4a 100644 --- a/extensions/typescript-language-features/src/features/updatePathsOnRename.ts +++ b/extensions/typescript-language-features/src/features/updatePathsOnRename.ts @@ -230,7 +230,7 @@ class UpdateImportsOnFileRenameHandler { newFile: string, ) { const isDirectoryRename = fs.lstatSync(newFile).isDirectory(); - await this.fileConfigurationManager.ensureConfigurationForDocument(document, nulToken); + await this.fileConfigurationManager.setGlobalConfigurationFromDocument(document, nulToken); const args: Proto.GetEditsForFileRenameRequestArgs & { file: string } = { file: targetResource, From 1cbd30833bed21658bd953639abe9423f8446b36 Mon Sep 17 00:00:00 2001 From: Rob Lourens Date: Thu, 26 Jul 2018 17:58:58 -0700 Subject: [PATCH 0202/1276] Settings editor - use ellipsis instead of gear --- .../parts/preferences/browser/media/configure-inverse.svg | 1 - .../workbench/parts/preferences/browser/media/configure.svg | 1 - .../parts/preferences/browser/media/ellipsis-inverse.svg | 1 + .../workbench/parts/preferences/browser/media/ellipsis.svg | 1 + .../parts/preferences/browser/media/settingsEditor2.css | 5 +++-- 5 files changed, 5 insertions(+), 4 deletions(-) delete mode 100644 src/vs/workbench/parts/preferences/browser/media/configure-inverse.svg delete mode 100644 src/vs/workbench/parts/preferences/browser/media/configure.svg create mode 100644 src/vs/workbench/parts/preferences/browser/media/ellipsis-inverse.svg create mode 100644 src/vs/workbench/parts/preferences/browser/media/ellipsis.svg diff --git a/src/vs/workbench/parts/preferences/browser/media/configure-inverse.svg b/src/vs/workbench/parts/preferences/browser/media/configure-inverse.svg deleted file mode 100644 index 61baaea2b8b..00000000000 --- a/src/vs/workbench/parts/preferences/browser/media/configure-inverse.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/vs/workbench/parts/preferences/browser/media/configure.svg b/src/vs/workbench/parts/preferences/browser/media/configure.svg deleted file mode 100644 index 3dec2ba50fd..00000000000 --- a/src/vs/workbench/parts/preferences/browser/media/configure.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/vs/workbench/parts/preferences/browser/media/ellipsis-inverse.svg b/src/vs/workbench/parts/preferences/browser/media/ellipsis-inverse.svg new file mode 100644 index 00000000000..e3337557a23 --- /dev/null +++ b/src/vs/workbench/parts/preferences/browser/media/ellipsis-inverse.svg @@ -0,0 +1 @@ +Ellipsis_bold_16x \ No newline at end of file diff --git a/src/vs/workbench/parts/preferences/browser/media/ellipsis.svg b/src/vs/workbench/parts/preferences/browser/media/ellipsis.svg new file mode 100644 index 00000000000..e3f85623356 --- /dev/null +++ b/src/vs/workbench/parts/preferences/browser/media/ellipsis.svg @@ -0,0 +1 @@ +Ellipsis_bold_16x \ No newline at end of file diff --git a/src/vs/workbench/parts/preferences/browser/media/settingsEditor2.css b/src/vs/workbench/parts/preferences/browser/media/settingsEditor2.css index 0330afa402b..0463bc2bf40 100644 --- a/src/vs/workbench/parts/preferences/browser/media/settingsEditor2.css +++ b/src/vs/workbench/parts/preferences/browser/media/settingsEditor2.css @@ -103,14 +103,15 @@ height: 22px; background-position: center; background-repeat: no-repeat; + background-size: 16px; } .vs .settings-editor > .settings-header > .settings-header-controls .settings-header-controls-right .toolbar-toggle-more { - background-image: url('configure.svg'); + background-image: url('ellipsis.svg'); } .vs-dark .settings-editor > .settings-header > .settings-header-controls .settings-header-controls-right .toolbar-toggle-more { - background-image: url('configure-inverse.svg'); + background-image: url('ellipsis-inverse.svg'); } .settings-editor > .settings-header > .settings-header-controls .settings-tabs-widget > .monaco-action-bar .action-item { From d96cf918b7440d3648a7fd4cd9d2b4f2afe15974 Mon Sep 17 00:00:00 2001 From: Matt Bierner Date: Thu, 26 Jul 2018 18:34:09 -0700 Subject: [PATCH 0203/1276] Try to interupt getErr request for user opetions --- .../src/features/bufferSyncSupport.ts | 14 ++++++++++++++ .../src/features/completions.ts | 7 +++---- .../src/features/hover.ts | 3 ++- .../src/typescriptService.ts | 5 +++++ .../src/typescriptServiceClient.ts | 4 ++++ 5 files changed, 28 insertions(+), 5 deletions(-) diff --git a/extensions/typescript-language-features/src/features/bufferSyncSupport.ts b/extensions/typescript-language-features/src/features/bufferSyncSupport.ts index ddbccd3a27d..b44ec9fa0a0 100644 --- a/extensions/typescript-language-features/src/features/bufferSyncSupport.ts +++ b/extensions/typescript-language-features/src/features/bufferSyncSupport.ts @@ -256,6 +256,7 @@ export default class BufferSyncSupport extends Disposable { if (!syncedBuffer) { return; } + this.pendingDiagnostics.delete(resource); this.syncedBuffers.delete(resource); syncedBuffer.close(); if (!fs.existsSync(resource.fsPath)) { @@ -264,6 +265,19 @@ export default class BufferSyncSupport extends Disposable { } } + public interuptGetErr(f: () => R): R { + console.log('try inter'); + if (!this.pendingGetErr) { + return f(); + } + + this.pendingGetErr.cancel(); + this.pendingGetErr = undefined; + const result = f(); + this.triggerDiagnostics(); + return result; + } + private onDidCloseTextDocument(document: vscode.TextDocument): void { this.closeResource(document.uri); } diff --git a/extensions/typescript-language-features/src/features/completions.ts b/extensions/typescript-language-features/src/features/completions.ts index e1eb9121f13..063bd8cbbc6 100644 --- a/extensions/typescript-language-features/src/features/completions.ts +++ b/extensions/typescript-language-features/src/features/completions.ts @@ -304,7 +304,7 @@ class TypeScriptCompletionItemProvider implements vscode.CompletionItemProvider return null; } - await this.fileConfigurationManager.ensureConfigurationForDocument(document, token); + await this.client.interuptGetErr(() => this.fileConfigurationManager.ensureConfigurationForDocument(document, token)); const args: Proto.CompletionsRequestArgs = { ...typeConverters.Position.toFileLocationRequestArgs(file, position), @@ -313,19 +313,18 @@ class TypeScriptCompletionItemProvider implements vscode.CompletionItemProvider triggerCharacter: context.triggerCharacter as Proto.CompletionsTriggerCharacter }; - let enableCommitCharacters = true; let msg: ReadonlyArray | undefined = undefined; try { if (this.client.apiVersion.gte(API.v300)) { - const { body } = await this.client.execute('completionInfo', args, token); + const { body } = await this.client.interuptGetErr(() => this.client.execute('completionInfo', args, token)); if (!body) { return null; } enableCommitCharacters = !body.isNewIdentifierLocation; msg = body.entries; } else { - const { body } = await this.client.execute('completions', args, token); + const { body } = await this.client.interuptGetErr(() => this.client.execute('completions', args, token)); if (!body) { return null; } diff --git a/extensions/typescript-language-features/src/features/hover.ts b/extensions/typescript-language-features/src/features/hover.ts index 78580d3dfdc..19f78ee5f33 100644 --- a/extensions/typescript-language-features/src/features/hover.ts +++ b/extensions/typescript-language-features/src/features/hover.ts @@ -25,9 +25,10 @@ class TypeScriptHoverProvider implements vscode.HoverProvider { if (!filepath) { return undefined; } + const args = typeConverters.Position.toFileLocationRequestArgs(filepath, position); try { - const { body } = await this.client.execute('quickinfo', args, token); + const { body } = await this.client.interuptGetErr(() => this.client.execute('quickinfo', args, token)); if (body) { return new vscode.Hover( TypeScriptHoverProvider.getContents(body), diff --git a/extensions/typescript-language-features/src/typescriptService.ts b/extensions/typescript-language-features/src/typescriptService.ts index 990ab8c6384..aff38d6a44c 100644 --- a/extensions/typescript-language-features/src/typescriptService.ts +++ b/extensions/typescript-language-features/src/typescriptService.ts @@ -91,4 +91,9 @@ export interface ITypeScriptServiceClient { executeWithoutWaitingForResponse(command: 'reloadProjects', args: null): void; executeAsync(command: 'geterr', args: Proto.GeterrRequestArgs, token: vscode.CancellationToken): Promise; + + /** + * Cancel on going geterr requests and re-queue them after `f` has been evaluated. + */ + interuptGetErr(f: () => R): R; } \ 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 2d20a3c0a64..016f533b6e2 100644 --- a/extensions/typescript-language-features/src/typescriptServiceClient.ts +++ b/extensions/typescript-language-features/src/typescriptServiceClient.ts @@ -738,6 +738,10 @@ export default class TypeScriptServiceClient extends Disposable implements IType return result; } + public interuptGetErr(f: () => R): R { + return this.bufferSyncSupport.interuptGetErr(f); + } + /** * Given a `errorText` from a tsserver request indicating failure in handling a request, * prepares a payload for telemetry-logging. From 7e9474edbe58551694b4e7b5aba5a08e50c83e03 Mon Sep 17 00:00:00 2001 From: Ramya Achutha Rao Date: Thu, 26 Jul 2018 19:44:35 -0700 Subject: [PATCH 0204/1276] Run extension queries in sections only if applicable --- .../electron-browser/extensionsViews.ts | 37 +++++++++++-------- 1 file changed, 21 insertions(+), 16 deletions(-) diff --git a/src/vs/workbench/parts/extensions/electron-browser/extensionsViews.ts b/src/vs/workbench/parts/extensions/electron-browser/extensionsViews.ts index 02ba5fd8a6d..165adf81320 100644 --- a/src/vs/workbench/parts/extensions/electron-browser/extensionsViews.ts +++ b/src/vs/workbench/parts/extensions/electron-browser/extensionsViews.ts @@ -144,6 +144,12 @@ export class ExtensionsListView extends ViewletPanel { return this.list.length; } + protected showEmptyModel(): TPromise> { + const emptyModel = new PagedModel([]); + this.setModel(emptyModel); + return TPromise.as(emptyModel); + } + private async query(value: string): Promise> { const query = Query.parse(value); @@ -686,42 +692,41 @@ export class GroupByServerExtensionsView extends ExtensionsListView { } export class EnabledExtensionsView extends ExtensionsListView { + private readonly enabledExtensionsQuery = '@enabled'; async show(query: string): Promise> { - return super.show('@enabled'); + return (query && query.trim() !== this.enabledExtensionsQuery) ? this.showEmptyModel() : super.show(this.enabledExtensionsQuery); } } export class DisabledExtensionsView extends ExtensionsListView { + private readonly disabledExtensionsQuery = '@disabled'; async show(query: string): Promise> { - return super.show('@disabled'); + return (query && query.trim() !== this.disabledExtensionsQuery) ? this.showEmptyModel() : super.show(this.disabledExtensionsQuery); } } export class BuiltInExtensionsView extends ExtensionsListView { - async show(query: string): Promise> { - return super.show(query.replace('@builtin', '@builtin:features')); + return (query && query.trim() !== '@builtin') ? this.showEmptyModel() : super.show('@builtin:features'); } - } export class BuiltInThemesExtensionsView extends ExtensionsListView { - async show(query: string): Promise> { - return super.show(query.replace('@builtin', '@builtin:themes')); + return (query && query.trim() !== '@builtin') ? this.showEmptyModel() : super.show('@builtin:themes'); } } export class BuiltInBasicsExtensionsView extends ExtensionsListView { - async show(query: string): Promise> { - return super.show(query.replace('@builtin', '@builtin:basics')); + return (query && query.trim() !== '@builtin') ? this.showEmptyModel() : super.show('@builtin:basics'); } } export class DefaultRecommendedExtensionsView extends ExtensionsListView { + private readonly recommendedExtensionsQuery = '@recommended:all'; renderBody(container: HTMLElement): void { super.renderBody(container); @@ -732,13 +737,13 @@ export class DefaultRecommendedExtensionsView extends ExtensionsListView { } async show(query: string): Promise> { - return super.show('@recommended:all'); + return (query && query.trim() !== this.recommendedExtensionsQuery) ? this.showEmptyModel() : super.show(this.recommendedExtensionsQuery); } } export class RecommendedExtensionsView extends ExtensionsListView { - + private readonly recommendedExtensionsQuery = '@recommended'; renderBody(container: HTMLElement): void { super.renderBody(container); @@ -749,12 +754,12 @@ export class RecommendedExtensionsView extends ExtensionsListView { } async show(query: string): Promise> { - return super.show('@recommended'); + return (query && query.trim() !== this.recommendedExtensionsQuery) ? this.showEmptyModel() : super.show(this.recommendedExtensionsQuery); } } export class WorkspaceRecommendedExtensionsView extends ExtensionsListView { - + private readonly recommendedExtensionsQuery = '@recommended:workspace'; private installAllAction: InstallWorkspaceRecommendedExtensionsAction; renderBody(container: HTMLElement): void { @@ -788,14 +793,14 @@ export class WorkspaceRecommendedExtensionsView extends ExtensionsListView { this.disposables.push(...[this.installAllAction, configureWorkspaceFolderAction, actionbar]); } - async show(): Promise> { - let model = await super.show('@recommended:workspace'); + async show(query: string): Promise> { + let model = await ((query && query.trim() !== '@recommended') ? this.showEmptyModel() : super.show(this.recommendedExtensionsQuery)); this.setExpanded(model.length > 0); return model; } private update(): void { - this.show(); + this.show(this.recommendedExtensionsQuery); this.setRecommendationsToInstall(); } From f303b02376dde44819f297c368a5512f4d07a3e2 Mon Sep 17 00:00:00 2001 From: Rob Lourens Date: Thu, 26 Jul 2018 19:43:36 -0700 Subject: [PATCH 0205/1276] Remove old extension settings code --- .../browser/preferencesRenderers.ts | 117 +++++------------- 1 file changed, 33 insertions(+), 84 deletions(-) diff --git a/src/vs/workbench/parts/preferences/browser/preferencesRenderers.ts b/src/vs/workbench/parts/preferences/browser/preferencesRenderers.ts index ecbf27ed23c..fc9229b091f 100644 --- a/src/vs/workbench/parts/preferences/browser/preferencesRenderers.ts +++ b/src/vs/workbench/parts/preferences/browser/preferencesRenderers.ts @@ -3,43 +3,41 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -import { TPromise } from 'vs/base/common/winjs.base'; -import * as nls from 'vs/nls'; -import { Delayer } from 'vs/base/common/async'; -import * as arrays from 'vs/base/common/arrays'; -import { Disposable, IDisposable, dispose } from 'vs/base/common/lifecycle'; -import { Position } from 'vs/editor/common/core/position'; -import { IAction } from 'vs/base/common/actions'; -import { IJSONSchema } from 'vs/base/common/jsonSchema'; -import { Event, Emitter } from 'vs/base/common/event'; -import { Registry } from 'vs/platform/registry/common/platform'; -import * as editorCommon from 'vs/editor/common/editorCommon'; -import { Range, IRange } from 'vs/editor/common/core/range'; -import { IConfigurationRegistry, Extensions as ConfigurationExtensions, ConfigurationScope, IConfigurationPropertySchema } from 'vs/platform/configuration/common/configurationRegistry'; -import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; -import { IPreferencesService, ISettingsGroup, ISetting, IPreferencesEditorModel, IFilterResult, ISettingsEditorModel, IExtensionSetting, IScoredResults } from 'vs/workbench/services/preferences/common/preferences'; -import { SettingsEditorModel, DefaultSettingsEditorModel, WorkspaceConfigurationEditorModel } from 'vs/workbench/services/preferences/common/preferencesModels'; -import { ICodeEditor, IEditorMouseEvent, MouseTargetType } from 'vs/editor/browser/editorBrowser'; -import { IContextMenuService } from 'vs/platform/contextview/browser/contextView'; -import { SettingsGroupTitleWidget, EditPreferenceWidget, SettingsHeaderWidget, DefaultSettingsHeaderWidget, FloatingClickWidget } from 'vs/workbench/parts/preferences/browser/preferencesWidgets'; -import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry'; -import { RangeHighlightDecorations } from 'vs/workbench/browser/parts/editor/rangeDecorations'; -import { ICursorPositionChangedEvent } from 'vs/editor/common/controller/cursorEvents'; -import { ModelDecorationOptions } from 'vs/editor/common/model/textModel'; -import { IWorkspaceContextService, WorkbenchState } from 'vs/platform/workspace/common/workspace'; -import { overrideIdentifierFromKey, IConfigurationService, ConfigurationTarget } from 'vs/platform/configuration/common/configuration'; -import { IEnvironmentService } from 'vs/platform/environment/common/environment'; -import { ITextModel, IModelDeltaDecoration, TrackedRangeStickiness } from 'vs/editor/common/model'; -import { CodeLensProviderRegistry, CodeLensProvider, ICodeLensSymbol } from 'vs/editor/common/modes'; -import { CancellationToken } from 'vs/base/common/cancellation'; -import { getDomNodePagePosition } from 'vs/base/browser/dom'; -import { IssueType, ISettingsSearchIssueReporterData, ISettingSearchResult } from 'vs/platform/issue/common/issue'; -import { ILocalExtension } from 'vs/platform/extensionManagement/common/extensionManagement'; -import { IWorkbenchIssueService } from 'vs/workbench/services/issue/common/issue'; -import { IEditorService, SIDE_GROUP } from 'vs/workbench/services/editor/common/editorService'; -import { INotificationService } from 'vs/platform/notification/common/notification'; import { ContextSubMenu } from 'vs/base/browser/contextmenu'; +import { getDomNodePagePosition } from 'vs/base/browser/dom'; +import { IAction } from 'vs/base/common/actions'; +import * as arrays from 'vs/base/common/arrays'; +import { Delayer } from 'vs/base/common/async'; +import { Emitter, Event } from 'vs/base/common/event'; +import { IJSONSchema } from 'vs/base/common/jsonSchema'; +import { Disposable, dispose, IDisposable } from 'vs/base/common/lifecycle'; +import { TPromise } from 'vs/base/common/winjs.base'; +import { ICodeEditor, IEditorMouseEvent, MouseTargetType } from 'vs/editor/browser/editorBrowser'; +import { ICursorPositionChangedEvent } from 'vs/editor/common/controller/cursorEvents'; +import { Position } from 'vs/editor/common/core/position'; +import { IRange, Range } from 'vs/editor/common/core/range'; +import * as editorCommon from 'vs/editor/common/editorCommon'; +import { IModelDeltaDecoration, ITextModel, TrackedRangeStickiness } from 'vs/editor/common/model'; +import { ModelDecorationOptions } from 'vs/editor/common/model/textModel'; +import * as nls from 'vs/nls'; +import { ConfigurationTarget, IConfigurationService, overrideIdentifierFromKey } from 'vs/platform/configuration/common/configuration'; +import { ConfigurationScope, Extensions as ConfigurationExtensions, IConfigurationPropertySchema, IConfigurationRegistry } from 'vs/platform/configuration/common/configurationRegistry'; +import { IContextMenuService } from 'vs/platform/contextview/browser/contextView'; +import { IEnvironmentService } from 'vs/platform/environment/common/environment'; +import { ILocalExtension } from 'vs/platform/extensionManagement/common/extensionManagement'; +import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; +import { ISettingSearchResult, ISettingsSearchIssueReporterData, IssueType } from 'vs/platform/issue/common/issue'; +import { INotificationService } from 'vs/platform/notification/common/notification'; +import { Registry } from 'vs/platform/registry/common/platform'; +import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry'; +import { IWorkspaceContextService, WorkbenchState } from 'vs/platform/workspace/common/workspace'; +import { RangeHighlightDecorations } from 'vs/workbench/browser/parts/editor/rangeDecorations'; +import { DefaultSettingsHeaderWidget, EditPreferenceWidget, FloatingClickWidget, SettingsGroupTitleWidget, SettingsHeaderWidget } from 'vs/workbench/parts/preferences/browser/preferencesWidgets'; import { IWorkbenchSettingsConfiguration } from 'vs/workbench/parts/preferences/common/preferences'; +import { IEditorService, SIDE_GROUP } from 'vs/workbench/services/editor/common/editorService'; +import { IWorkbenchIssueService } from 'vs/workbench/services/issue/common/issue'; +import { IFilterResult, IPreferencesEditorModel, IPreferencesService, IScoredResults, ISetting, ISettingsEditorModel, ISettingsGroup } from 'vs/workbench/services/preferences/common/preferences'; +import { DefaultSettingsEditorModel, SettingsEditorModel, WorkspaceConfigurationEditorModel } from 'vs/workbench/services/preferences/common/preferencesModels'; export interface IPreferencesRenderer extends IDisposable { readonly preferencesModel: IPreferencesEditorModel; @@ -244,7 +242,6 @@ export class DefaultSettingsRenderer extends Disposable implements IPreferencesR private issueWidgetRenderer: IssueWidgetRenderer; private feedbackWidgetRenderer: FeedbackWidgetRenderer; private bracesHidingRenderer: BracesHidingRenderer; - private extensionCodelensRenderer: ExtensionCodelensRenderer; private filterResult: IFilterResult; private readonly _onUpdatePreference: Emitter<{ key: string, value: any, source: IIndexedSetting }> = new Emitter<{ key: string, value: any, source: IIndexedSetting }>(); @@ -271,7 +268,6 @@ export class DefaultSettingsRenderer extends Disposable implements IPreferencesR this.feedbackWidgetRenderer = this._register(instantiationService.createInstance(FeedbackWidgetRenderer, editor)); this.bracesHidingRenderer = this._register(instantiationService.createInstance(BracesHidingRenderer, editor, preferencesModel)); this.hiddenAreasRenderer = this._register(instantiationService.createInstance(HiddenAreasRenderer, editor, [this.settingsGroupTitleRenderer, this.filteredMatchesRenderer, this.bracesHidingRenderer])); - this.extensionCodelensRenderer = this._register(instantiationService.createInstance(ExtensionCodelensRenderer, editor)); this._register(this.editSettingActionRenderer.onUpdateSetting(e => this._onUpdatePreference.fire(e))); this._register(this.settingsGroupTitleRenderer.onHiddenAreasChanged(() => this.hiddenAreasRenderer.render())); @@ -309,7 +305,6 @@ export class DefaultSettingsRenderer extends Disposable implements IPreferencesR this.settingHighlighter.clear(true); this.bracesHidingRenderer.render(filterResult, this.preferencesModel.settingsGroups); this.editSettingActionRenderer.render(filterResult.filteredGroups, this._associatedPreferencesModel); - this.extensionCodelensRenderer.render(filterResult); } else { this.settingHighlighter.clear(true); this.filteredMatchesRenderer.render(null, this.preferencesModel.settingsGroups); @@ -319,7 +314,6 @@ export class DefaultSettingsRenderer extends Disposable implements IPreferencesR this.settingsGroupTitleRenderer.showGroup(0); this.bracesHidingRenderer.render(null, this.preferencesModel.settingsGroups); this.editSettingActionRenderer.render(this.preferencesModel.settingsGroups, this._associatedPreferencesModel); - this.extensionCodelensRenderer.render(null); } this.hiddenAreasRenderer.render(); @@ -948,51 +942,6 @@ export class HighlightMatchesRenderer extends Disposable { } } -export class ExtensionCodelensRenderer extends Disposable implements CodeLensProvider { - private filterResult: IFilterResult; - - constructor() { - super(); - this._register(CodeLensProviderRegistry.register({ pattern: '**/settings.json' }, this)); - } - - public render(filterResult: IFilterResult): void { - this.filterResult = filterResult; - } - - public provideCodeLenses(model: ITextModel, token: CancellationToken): ICodeLensSymbol[] { - if (!this.filterResult || !this.filterResult.filteredGroups) { - return []; - } - - const newExtensionGroup = arrays.first(this.filterResult.filteredGroups, g => g.id === 'newExtensionsResult'); - if (!newExtensionGroup) { - return []; - } - - return newExtensionGroup.sections[0].settings - .filter((s: IExtensionSetting) => { - // Skip any non IExtensionSettings that somehow got in here - return s.extensionName && s.extensionPublisher; - }) - .map((s: IExtensionSetting) => { - const extId = s.extensionPublisher + '.' + s.extensionName; - return { - command: { - title: nls.localize('newExtensionLabel', "Show Extension \"{0}\"", extId), - id: 'workbench.extensions.action.showExtensionsWithId', - arguments: [extId.toLowerCase()] - }, - range: new Range(s.keyRange.startLineNumber, 1, s.keyRange.startLineNumber, 1) - }; - }); - } - - public resolveCodeLens(model: ITextModel, codeLens: ICodeLensSymbol, token: CancellationToken): ICodeLensSymbol { - return codeLens; - } -} - export interface IIndexedSetting extends ISetting { index: number; groupId: string; From a9589652c136c0955a4c84a79240aff5579d9948 Mon Sep 17 00:00:00 2001 From: Rob Lourens Date: Thu, 26 Jul 2018 19:47:08 -0700 Subject: [PATCH 0206/1276] Add "new extensions" settings results button for #49474, but disabled for now --- .../electron-browser/extensionsActions.ts | 7 +- .../electron-browser/extensionsViews.ts | 12 ++- .../browser/media/settingsEditor2.css | 16 +++- .../preferences/browser/settingsEditor2.ts | 9 +- .../parts/preferences/browser/settingsTree.ts | 82 +++++++++++++++++-- .../parts/preferences/browser/tocTree.ts | 2 +- 6 files changed, 106 insertions(+), 22 deletions(-) diff --git a/src/vs/workbench/parts/extensions/electron-browser/extensionsActions.ts b/src/vs/workbench/parts/extensions/electron-browser/extensionsActions.ts index ce4e5210290..35077d1000f 100644 --- a/src/vs/workbench/parts/extensions/electron-browser/extensionsActions.ts +++ b/src/vs/workbench/parts/extensions/electron-browser/extensionsActions.ts @@ -2752,13 +2752,16 @@ CommandsRegistry.registerCommand('workbench.extensions.action.showExtensionsForL }); }); -CommandsRegistry.registerCommand('workbench.extensions.action.showExtensionsWithId', function (accessor: ServicesAccessor, extensionId: string) { +CommandsRegistry.registerCommand('workbench.extensions.action.showExtensionsWithIds', function (accessor: ServicesAccessor, extensionIds: string[]) { const viewletService = accessor.get(IViewletService); return viewletService.openViewlet(VIEWLET_ID, true) .then(viewlet => viewlet as IExtensionsViewlet) .then(viewlet => { - viewlet.search(`@id:${extensionId}`); + const query = extensionIds + .map(id => `@id:${id}`) + .join(' '); + viewlet.search(query); viewlet.focus(); }); }); diff --git a/src/vs/workbench/parts/extensions/electron-browser/extensionsViews.ts b/src/vs/workbench/parts/extensions/electron-browser/extensionsViews.ts index 165adf81320..e057216762f 100644 --- a/src/vs/workbench/parts/extensions/electron-browser/extensionsViews.ts +++ b/src/vs/workbench/parts/extensions/electron-browser/extensionsViews.ts @@ -227,12 +227,16 @@ export class ExtensionsListView extends ViewletPanel { return new PagedModel(this.sortExtensions(result, options)); } - const idMatch = /@id:(([a-z0-9A-Z][a-z0-9\-A-Z]*)\.([a-z0-9A-Z][a-z0-9\-A-Z]*))/.exec(value); - - if (idMatch) { + const idRegex = /@id:(([a-z0-9A-Z][a-z0-9\-A-Z]*)\.([a-z0-9A-Z][a-z0-9\-A-Z]*))/g; + let idMatch; + const names: string[] = []; + while ((idMatch = idRegex.exec(value)) !== null) { const name = idMatch[1]; + names.push(name); + } - return this.extensionsWorkbenchService.queryGallery({ names: [name], source: 'queryById' }) + if (names.length) { + return this.extensionsWorkbenchService.queryGallery({ names, source: 'queryById' }) .then(pager => new PagedModel(pager)); } diff --git a/src/vs/workbench/parts/preferences/browser/media/settingsEditor2.css b/src/vs/workbench/parts/preferences/browser/media/settingsEditor2.css index 0463bc2bf40..c760c377f6a 100644 --- a/src/vs/workbench/parts/preferences/browser/media/settingsEditor2.css +++ b/src/vs/workbench/parts/preferences/browser/media/settingsEditor2.css @@ -148,9 +148,8 @@ .settings-editor > .settings-body .settings-toc-container { width: 160px; - padding-top: 5px; + margin-top: 5px; padding-left: 5px; - box-sizing: border-box; } .settings-editor > .settings-body .settings-toc-container.hidden { @@ -201,8 +200,7 @@ flex: 1; max-width: 792px; margin-right: 1px; /* So the item doesn't blend into the edge of the view container */ - padding-top: 8px; - box-sizing: border-box; + margin-top: 8px; border-spacing: 0; border-collapse: separate; position: relative; @@ -330,6 +328,16 @@ height: 26px; } +.settings-editor > .settings-body > .settings-tree-container .setting-item-new-extensions { + display: flex; +} + +.settings-editor > .settings-body > .settings-tree-container .setting-item-new-extensions .settings-new-extensions-button { + margin: auto; + width: initial; + padding: 4px 10px; +} + .settings-editor > .settings-body > .settings-tree-container .group-title, .settings-editor > .settings-body > .settings-tree-container .setting-item { padding-left: 9px; diff --git a/src/vs/workbench/parts/preferences/browser/settingsEditor2.ts b/src/vs/workbench/parts/preferences/browser/settingsEditor2.ts index fa7fc7390ca..5d6ed7375b6 100644 --- a/src/vs/workbench/parts/preferences/browser/settingsEditor2.ts +++ b/src/vs/workbench/parts/preferences/browser/settingsEditor2.ts @@ -737,17 +737,14 @@ export class SettingsEditor2 extends BaseEditor { } private filterOrSearchPreferences(query: string, type: SearchResultIdx, searchProvider: ISearchProvider): TPromise { - const filterPs: TPromise[] = [this._filterOrSearchPreferencesModel(query, this.defaultSettingsEditorModel, searchProvider)]; - let isCanceled = false; return new TPromise(resolve => { - return TPromise.join(filterPs).then(results => { + return this._filterOrSearchPreferencesModel(query, this.defaultSettingsEditorModel, searchProvider).then(result => { if (isCanceled) { // Handle cancellation like this because cancellation is lost inside the search provider due to async/await return null; } - const [result] = results; if (!this.searchResultModel) { this.searchResultModel = this.instantiationService.createInstance(SearchResultModel, this.viewState); this.searchResultModel.setResult(type, result); @@ -793,7 +790,7 @@ export class SettingsEditor2 extends BaseEditor { private layoutTrees(dimension: DOM.Dimension): void { const listHeight = dimension.height - (DOM.getDomNodePagePosition(this.headerContainer).height + 11 /*padding*/); this.settingsTreeContainer.style.height = `${listHeight}px`; - this.settingsTree.layout(listHeight, 800); + this.settingsTree.layout(listHeight - 8, 800); const selectedSetting = this.settingsTree.getSelection()[0]; if (selectedSetting) { @@ -801,7 +798,7 @@ export class SettingsEditor2 extends BaseEditor { } this.tocTreeContainer.style.height = `${listHeight}px`; - this.tocTree.layout(listHeight, 175); + this.tocTree.layout(listHeight - 5, 175); } } diff --git a/src/vs/workbench/parts/preferences/browser/settingsTree.ts b/src/vs/workbench/parts/preferences/browser/settingsTree.ts index bca419d84bc..8d020b1c9cb 100644 --- a/src/vs/workbench/parts/preferences/browser/settingsTree.ts +++ b/src/vs/workbench/parts/preferences/browser/settingsTree.ts @@ -24,6 +24,7 @@ import { TPromise } from 'vs/base/common/winjs.base'; import { IAccessibilityProvider, IDataSource, IFilter, IRenderer as ITreeRenderer, ITree, ITreeConfiguration } from 'vs/base/parts/tree/browser/tree'; import { DefaultTreestyler } from 'vs/base/parts/tree/browser/treeDefaults'; import { localize } from 'vs/nls'; +import { ICommandService } from 'vs/platform/commands/common/commands'; import { ConfigurationTarget, IConfigurationService } from 'vs/platform/configuration/common/configuration'; import { IContextKeyService } from 'vs/platform/contextkey/common/contextkey'; import { IContextViewService } from 'vs/platform/contextview/browser/contextView'; @@ -35,8 +36,8 @@ import { attachButtonStyler, attachInputBoxStyler, attachSelectBoxStyler, attach import { ICssStyleCollector, ITheme, IThemeService, registerThemingParticipant } from 'vs/platform/theme/common/themeService'; import { SettingsTarget } from 'vs/workbench/parts/preferences/browser/preferencesWidgets'; import { ITOCEntry } from 'vs/workbench/parts/preferences/browser/settingsLayout'; -import { ExcludeSettingWidget, settingsNumberInputBackground, settingsNumberInputBorder, settingsNumberInputForeground, settingsSelectBackground, settingsSelectBorder, settingsSelectForeground, settingsTextInputBorder, settingsTextInputForeground, settingItemInactiveSelectionBorder, settingsHeaderForeground, settingsTextInputBackground, IExcludeDataItem } from 'vs/workbench/parts/preferences/browser/settingsWidgets'; -import { ISearchResult, ISetting, ISettingsGroup } from 'vs/workbench/services/preferences/common/preferences'; +import { ExcludeSettingWidget, IExcludeDataItem, settingItemInactiveSelectionBorder, settingsHeaderForeground, settingsNumberInputBackground, settingsNumberInputBorder, settingsNumberInputForeground, settingsSelectBackground, settingsSelectBorder, settingsSelectForeground, settingsTextInputBackground, settingsTextInputBorder, settingsTextInputForeground } from 'vs/workbench/parts/preferences/browser/settingsWidgets'; +import { IExtensionSetting, ISearchResult, ISetting, ISettingsGroup } from 'vs/workbench/services/preferences/common/preferences'; const $ = DOM.$; @@ -55,6 +56,10 @@ export class SettingsTreeGroupElement extends SettingsTreeElement { isFirstGroup: boolean; } +export class SettingsTreeNewExtensionsElement extends SettingsTreeElement { + extensionIds: string[]; +} + export class SettingsTreeSettingElement extends SettingsTreeElement { setting: ISetting; @@ -494,6 +499,11 @@ interface ISettingExcludeItemTemplate extends ISettingItemTemplate { context?: SettingsTreeSettingElement; } +interface ISettingNewExtensionsTemplate extends IDisposableTemplate { + button: Button; + context?: SettingsTreeNewExtensionsElement; +} + function isExcludeSetting(setting: ISetting): boolean { return setting.key === 'files.exclude' || setting.key === 'search.exclude'; @@ -510,6 +520,7 @@ const SETTINGS_ENUM_TEMPLATE_ID = 'settings.enum.template'; const SETTINGS_BOOL_TEMPLATE_ID = 'settings.bool.template'; const SETTINGS_EXCLUDE_TEMPLATE_ID = 'settings.exclude.template'; const SETTINGS_COMPLEX_TEMPLATE_ID = 'settings.complex.template'; +const SETTINGS_NEW_EXTENSIONS_TEMPLATE_ID = 'settings.newExtensions.template'; const SETTINGS_GROUP_ELEMENT_TEMPLATE_ID = 'settings.group.template'; export interface ISettingChangeEvent { @@ -540,6 +551,7 @@ export class SettingsRenderer implements ITreeRenderer { @IContextViewService private contextViewService: IContextViewService, @IOpenerService private readonly openerService: IOpenerService, @IInstantiationService private readonly instantiationService: IInstantiationService, + @ICommandService private readonly commandService: ICommandService, ) { this.measureContainer = DOM.append(_measureContainer, $('.setting-measure-container.monaco-tree-row')); } @@ -564,6 +576,10 @@ export class SettingsRenderer implements ITreeRenderer { } } + if (element instanceof SettingsTreeNewExtensionsElement) { + return 40; + } + return 0; } @@ -622,6 +638,10 @@ export class SettingsRenderer implements ITreeRenderer { return SETTINGS_COMPLEX_TEMPLATE_ID; } + if (element instanceof SettingsTreeNewExtensionsElement) { + return SETTINGS_NEW_EXTENSIONS_TEMPLATE_ID; + } + return ''; } @@ -654,6 +674,10 @@ export class SettingsRenderer implements ITreeRenderer { return this.renderSettingComplexTemplate(tree, container); } + if (templateId === SETTINGS_NEW_EXTENSIONS_TEMPLATE_ID) { + return this.renderNewExtensionsTemplate(container); + } + return null; } @@ -911,11 +935,39 @@ export class SettingsRenderer implements ITreeRenderer { return template; } + private renderNewExtensionsTemplate(container: HTMLElement): ISettingNewExtensionsTemplate { + const toDispose = []; + + container.classList.add('setting-item-new-extensions'); + + const button = new Button(container, { title: true, buttonBackground: null, buttonHoverBackground: null }); + toDispose.push(button); + toDispose.push(button.onDidClick(() => { + if (template.context) { + this.commandService.executeCommand('workbench.extensions.action.showExtensionsWithIds', template.context.extensionIds); + } + })); + button.label = localize('newExtensionsButtonLabel', "Show other matching extensions"); + button.element.classList.add('settings-new-extensions-button'); + toDispose.push(attachButtonStyler(button, this.themeService)); + + const template: ISettingNewExtensionsTemplate = { + button, + toDispose + }; + + return template; + } + renderElement(tree: ITree, element: SettingsTreeElement, templateId: string, template: any): void { if (templateId === SETTINGS_GROUP_ELEMENT_TEMPLATE_ID) { return this.renderGroupElement(element, template); } + if (templateId === SETTINGS_NEW_EXTENSIONS_TEMPLATE_ID) { + return this.renderNewExtensionsElement(element, template); + } + return this.renderSettingElement(tree, element, templateId, template); } @@ -936,6 +988,10 @@ export class SettingsRenderer implements ITreeRenderer { return selectedElement && selectedElement.id === element.id; } + private renderNewExtensionsElement(element: SettingsTreeNewExtensionsElement, template: ISettingNewExtensionsTemplate): void { + template.context = element; + } + private renderSettingElement(tree: ITree, element: SettingsTreeSettingElement, templateId: string, template: ISettingItemTemplate | ISettingBoolItemTemplate): void { const isSelected = !!this.elementIsSelected(tree, element); const setting = element.setting; @@ -1198,13 +1254,15 @@ export class SettingsAccessibilityProvider implements IAccessibilityProvider { export enum SearchResultIdx { Local = 0, - Remote = 1 + Remote = 1, + NewExtensions = 2 } export class SearchResultModel { private rawSearchResults: ISearchResult[]; private cachedUniqueSearchResults: ISearchResult[]; - private children: SettingsTreeSettingElement[]; + private newExtensionSearchResults: ISearchResult; + private children: (SettingsTreeSettingElement | SettingsTreeNewExtensionsElement)[]; readonly id = 'searchResultModel'; @@ -1213,7 +1271,7 @@ export class SearchResultModel { @IConfigurationService private _configurationService: IConfigurationService ) { } - getChildren(): SettingsTreeSettingElement[] { + getChildren(): (SettingsTreeSettingElement | SettingsTreeNewExtensionsElement)[] { return this.children; } @@ -1237,6 +1295,8 @@ export class SearchResultModel { remoteResult.filterMatches = remoteResult.filterMatches.filter(m => !localMatchKeys.has(m.setting.key)); } + this.newExtensionSearchResults = objects.deepClone(this.rawSearchResults[SearchResultIdx.NewExtensions]); + this.cachedUniqueSearchResults = [localResult, remoteResult]; return this.cachedUniqueSearchResults; } @@ -1260,6 +1320,18 @@ export class SearchResultModel { updateChildren(): void { this.children = this.getFlatSettings() .map(s => createSettingsTreeSettingElement(s, this, this._viewState.settingsTarget, this._configurationService)); + + if (this.newExtensionSearchResults) { + const newExtElement = new SettingsTreeNewExtensionsElement(); + newExtElement.parent = this; + newExtElement.id = 'newExtensions'; + const resultExtensionIds = this.newExtensionSearchResults.filterMatches + .map(result => (result.setting)) + .filter(setting => setting.extensionName && setting.extensionPublisher) + .map(setting => `${setting.extensionPublisher}.${setting.extensionName}`); + newExtElement.extensionIds = arrays.distinct(resultExtensionIds); + this.children.push(newExtElement); + } } private getFlatSettings(): ISetting[] { diff --git a/src/vs/workbench/parts/preferences/browser/tocTree.ts b/src/vs/workbench/parts/preferences/browser/tocTree.ts index 54c4d4297e8..4863ba7c612 100644 --- a/src/vs/workbench/parts/preferences/browser/tocTree.ts +++ b/src/vs/workbench/parts/preferences/browser/tocTree.ts @@ -49,7 +49,7 @@ export class TOCTreeModel { private getSearchResultChildrenCount(group: SettingsTreeGroupElement): number { return this._currentSearchModel.getChildren().filter(child => { - return this.groupContainsSetting(group, child.setting); + return child instanceof SettingsTreeSettingElement && this.groupContainsSetting(group, child.setting); }).length; } From c348736137514ec60281ae9caeeedcfed82bc7bf Mon Sep 17 00:00:00 2001 From: Rob Lourens Date: Thu, 26 Jul 2018 21:29:40 -0700 Subject: [PATCH 0207/1276] Add temp registerSearchProvider stub to avoid breaking live share in Insiders --- src/vs/vscode.proposed.d.ts | 5 +++++ src/vs/workbench/api/node/extHost.api.impl.ts | 4 ++++ 2 files changed, 9 insertions(+) diff --git a/src/vs/vscode.proposed.d.ts b/src/vs/vscode.proposed.d.ts index b56c7c4760d..70e0640de35 100644 --- a/src/vs/vscode.proposed.d.ts +++ b/src/vs/vscode.proposed.d.ts @@ -225,6 +225,11 @@ declare module 'vscode' { } export namespace workspace { + /** + * DEPRECATED + */ + export function registerSearchProvider(): Disposable; + /** * Register a search provider. * diff --git a/src/vs/workbench/api/node/extHost.api.impl.ts b/src/vs/workbench/api/node/extHost.api.impl.ts index df5b02f02c5..c6daee8c6ca 100644 --- a/src/vs/workbench/api/node/extHost.api.impl.ts +++ b/src/vs/workbench/api/node/extHost.api.impl.ts @@ -585,6 +585,10 @@ export function createApiFactory( registerFileSearchProvider: proposedApiFunction(extension, (scheme, provider) => { return extHostSearch.registerFileSearchProvider(scheme, provider); }), + registerSearchProvider: proposedApiFunction(extension, () => { + // Temp for live share in Insiders + return { dispose: () => { } }; + }), registerTextSearchProvider: proposedApiFunction(extension, (scheme, provider) => { return extHostSearch.registerTextSearchProvider(scheme, provider); }), From 0dea26f6e708f59c27973b0ce96c2e941aa8dc6f Mon Sep 17 00:00:00 2001 From: Rob Lourens Date: Thu, 26 Jul 2018 21:42:24 -0700 Subject: [PATCH 0208/1276] Search provider - avoid unnecessary joinPath in some cases Maybe fixes liveshare issue --- .../api/node/extHostSearch.fileIndex.ts | 25 +++---------------- 1 file changed, 4 insertions(+), 21 deletions(-) diff --git a/src/vs/workbench/api/node/extHostSearch.fileIndex.ts b/src/vs/workbench/api/node/extHostSearch.fileIndex.ts index 0f45ba422ea..81241f49dde 100644 --- a/src/vs/workbench/api/node/extHostSearch.fileIndex.ts +++ b/src/vs/workbench/api/node/extHostSearch.fileIndex.ts @@ -19,6 +19,7 @@ import * as vscode from 'vscode'; export interface IInternalFileMatch { base: URI; + original?: URI; relativePath?: string; // Not present for extraFiles or absolute path matches basename: string; size?: number; @@ -239,7 +240,7 @@ export class FileIndexSearchEngine { const relativePath = path.relative(fq.folder.path, uri.path); if (noSiblingsClauses) { const basename = path.basename(uri.path); - this.matchFile(onResult, { base: fq.folder, relativePath, basename }); + this.matchFile(onResult, { base: fq.folder, relativePath, basename, original: uri }); return; } @@ -360,22 +361,6 @@ export class FileIndexSearchEngine { matchDirectory(rootEntries); } - public getStats(): any { - return null; - // return { - // fromCache: false, - // traversal: Traversal[this.traversal], - // errors: this.errors, - // fileWalkStartTime: this.fileWalkStartTime, - // fileWalkResultTime: Date.now(), - // directoriesWalked: this.directoriesWalked, - // filesWalked: this.filesWalked, - // resultCount: this.resultCount, - // cmdForkResultTime: this.cmdForkResultTime, - // cmdResultCount: this.cmdResultCount - // }; - } - private matchFile(onResult: (result: IInternalFileMatch) => void, candidate: IInternalFileMatch): void { if (this.isFilePatternMatch(candidate.relativePath) && (!this.includePattern || this.includePattern(candidate.relativePath, candidate.basename))) { if (this.exists || (this.maxResults && this.resultCount >= this.maxResults)) { @@ -411,8 +396,6 @@ export class FileIndexSearchManager { private caches: { [cacheKey: string]: Cache; } = Object.create(null); public fileSearch(config: ISearchQuery, provider: vscode.FileIndexProvider, onBatch: (matches: IFileMatch[]) => void): TPromise { - // if (config.cacheKey) - if (config.sortByScore) { let sortedSearch = this.trySortedSearchFromCache(config); if (!sortedSearch) { @@ -449,7 +432,7 @@ export class FileIndexSearchManager { private rawMatchToSearchItem(match: IInternalFileMatch): IFileMatch { return { - resource: resources.joinPath(match.base, match.relativePath) + resource: match.original || resources.joinPath(match.base, match.relativePath) }; } @@ -617,7 +600,7 @@ export class FileIndexSearchManager { return TPromise.as(undefined); } - private preventCancellation(promise: TPromise): TPromise { + private preventCancellation(promise: TPromise): TPromise { return new TPromise((c, e) => { // Allow for piled up cancellations to come through first. process.nextTick(() => { From dae69dbf00357ff8a3fe740a1f211d66b0b4681c Mon Sep 17 00:00:00 2001 From: Rob Lourens Date: Thu, 26 Jul 2018 21:52:32 -0700 Subject: [PATCH 0209/1276] Settings editors - fix \n enum value breaking json syntax --- .../parts/preferences/browser/settingsTree.ts | 9 ++++++--- .../services/preferences/common/preferencesModels.ts | 11 +++++++++-- 2 files changed, 15 insertions(+), 5 deletions(-) diff --git a/src/vs/workbench/parts/preferences/browser/settingsTree.ts b/src/vs/workbench/parts/preferences/browser/settingsTree.ts index 8d020b1c9cb..f63e27c5d94 100644 --- a/src/vs/workbench/parts/preferences/browser/settingsTree.ts +++ b/src/vs/workbench/parts/preferences/browser/settingsTree.ts @@ -1010,9 +1010,12 @@ export class SettingsRenderer implements ITreeRenderer { let enumDescriptionText = ''; if (element.valueType === 'enum' && element.setting.enumDescriptions && element.setting.enum && element.setting.enum.length < SettingsRenderer.MAX_ENUM_DESCRIPTIONS) { enumDescriptionText = '\n' + element.setting.enumDescriptions - .map((desc, i) => desc ? - ` - \`${element.setting.enum[i]}\`: ${desc}` : - ` - \`${element.setting.enum[i]}\``) + .map((desc, i) => { + const displayEnum = escapeInvisibleChars(setting.enum[i]); + return desc ? + ` - \`${displayEnum}\`: ${desc}` : + ` - \`${setting.enum[i]}\``; + }) .filter(desc => !!desc) .join('\n'); } diff --git a/src/vs/workbench/services/preferences/common/preferencesModels.ts b/src/vs/workbench/services/preferences/common/preferencesModels.ts index 27fea8f112b..2bb3302a828 100644 --- a/src/vs/workbench/services/preferences/common/preferencesModels.ts +++ b/src/vs/workbench/services/preferences/common/preferencesModels.ts @@ -899,9 +899,10 @@ class SettingsContentBuilder { if (setting.enumDescriptions && setting.enumDescriptions.some(desc => !!desc)) { setting.enumDescriptions.forEach((desc, i) => { + const displayEnum = escapeInvisibleChars(setting.enum[i]); const line = desc ? - `${setting.enum[i]}: ${fixSettingLink(desc)}` : - setting.enum[i]; + `${displayEnum}: ${fixSettingLink(desc)}` : + displayEnum; this._contentByLines.push(` // - ${line}`); @@ -942,6 +943,12 @@ class SettingsContentBuilder { } } +function escapeInvisibleChars(enumValue: string): string { + return enumValue && enumValue + .replace(/\n/g, '\\n') + .replace(/\r/g, '\\r'); +} + export function defaultKeybindingsContents(keybindingService: IKeybindingService): string { const defaultsHeader = '// ' + nls.localize('defaultKeybindingsHeader', "Overwrite key bindings by placing them into your key bindings file."); return defaultsHeader + '\n' + keybindingService.getDefaultKeybindingsContent(); From bcfc2b81195a05b85fa094ade64025d511f269d9 Mon Sep 17 00:00:00 2001 From: Christof Marti Date: Fri, 27 Jul 2018 08:51:38 +0200 Subject: [PATCH 0210/1276] Announce number of results in QuickPick for screen readers (fixes #52542) --- .../quickopen/browser/quickOpenWidget.ts | 29 ++++++++++++++----- .../parts/quickopen/browser/quickopen.css | 5 ++++ .../browser/parts/quickinput/quickInput.css | 5 ++++ .../browser/parts/quickinput/quickInput.ts | 17 ++++++++++- .../parts/quickinput/quickInputList.ts | 15 ++++++++++ 5 files changed, 63 insertions(+), 8 deletions(-) diff --git a/src/vs/base/parts/quickopen/browser/quickOpenWidget.ts b/src/vs/base/parts/quickopen/browser/quickOpenWidget.ts index 8341fd31256..ca63a6398d1 100644 --- a/src/vs/base/parts/quickopen/browser/quickOpenWidget.ts +++ b/src/vs/base/parts/quickopen/browser/quickOpenWidget.ts @@ -103,6 +103,7 @@ export class QuickOpenWidget extends Disposable implements IModelProvider { private inputBox: InputBox; private inputContainer: Builder; private helpText: Builder; + private resultCount: Builder; private treeContainer: Builder; private progressBar: ProgressBar; private visible: boolean; @@ -232,6 +233,12 @@ export class QuickOpenWidget extends Disposable implements IModelProvider { }); }); + // Result count for screen readers + this.resultCount = div.div({ + 'class': 'quick-open-result-count', + 'aria-live': 'polite' + }).clone(); + // Tree this.treeContainer = div.div({ 'class': 'quick-open-tree' @@ -628,9 +635,12 @@ export class QuickOpenWidget extends Disposable implements IModelProvider { // Indicate entries to tree this.tree.layout(); + const entries = input ? input.entries.filter(e => this.isElementVisible(input, e)) : []; + this.updateResultCount(entries.length); + // Handle auto focus - if (input && input.entries.some(e => this.isElementVisible(input, e))) { - this.autoFocus(input, autoFocus); + if (entries.length) { + this.autoFocus(input, entries, autoFocus); } }, errors.onUnexpectedError); } @@ -643,8 +653,7 @@ export class QuickOpenWidget extends Disposable implements IModelProvider { return input.filter.isVisible(e); } - private autoFocus(input: IModel, autoFocus: IAutoFocus = {}): void { - const entries = input.entries.filter(e => this.isElementVisible(input, e)); + private autoFocus(input: IModel, entries: any[], autoFocus: IAutoFocus = {}): void { // First check for auto focus of prefix matches if (autoFocus.autoFocusPrefixMatch) { @@ -725,11 +734,13 @@ export class QuickOpenWidget extends Disposable implements IModelProvider { // Indicate entries to tree this.tree.layout(); + const entries = input ? input.entries.filter(e => this.isElementVisible(input, e)) : []; + this.updateResultCount(entries.length); + // Handle auto focus if (autoFocus) { - let doAutoFocus = autoFocus && input && input.entries.some(e => this.isElementVisible(input, e)); - if (doAutoFocus) { - this.autoFocus(input, autoFocus); + if (entries.length) { + this.autoFocus(input, entries, autoFocus); } } }, errors.onUnexpectedError); @@ -769,6 +780,10 @@ export class QuickOpenWidget extends Disposable implements IModelProvider { return height; } + updateResultCount(count: number) { + this.resultCount.text(nls.localize({ key: 'quickInput.visibleCount', comment: ['This tells the user how many items are shown in a list of items to select from. The items can be anything. Currently not visible, but read by screen readers.'] }, "{0} Results", count)); + } + hide(reason?: HideReason): void { if (!this.isVisible()) { return; diff --git a/src/vs/base/parts/quickopen/browser/quickopen.css b/src/vs/base/parts/quickopen/browser/quickopen.css index 97ef9224d98..97ddd6aab12 100644 --- a/src/vs/base/parts/quickopen/browser/quickopen.css +++ b/src/vs/base/parts/quickopen/browser/quickopen.css @@ -35,6 +35,11 @@ height: 25px; } +.monaco-quick-open-widget .quick-open-result-count { + position: absolute; + left: -10000px; +} + .monaco-quick-open-widget .quick-open-tree { line-height: 22px; } diff --git a/src/vs/workbench/browser/parts/quickinput/quickInput.css b/src/vs/workbench/browser/parts/quickinput/quickInput.css index fbcdcbe684c..133ce19e8fc 100644 --- a/src/vs/workbench/browser/parts/quickinput/quickInput.css +++ b/src/vs/workbench/browser/parts/quickinput/quickInput.css @@ -69,6 +69,11 @@ margin-left: 5px; } +.quick-input-visible-count { + position: absolute; + left: -10000px; +} + .quick-input-count { align-self: center; position: absolute; diff --git a/src/vs/workbench/browser/parts/quickinput/quickInput.ts b/src/vs/workbench/browser/parts/quickinput/quickInput.ts index b0b274f92e1..0f0b4dd4fca 100644 --- a/src/vs/workbench/browser/parts/quickinput/quickInput.ts +++ b/src/vs/workbench/browser/parts/quickinput/quickInput.ts @@ -62,6 +62,7 @@ interface QuickInputUI { rightActionBar: ActionBar; checkAll: HTMLInputElement; inputBox: QuickInputBox; + visibleCount: CountBadge; count: CountBadge; message: HTMLElement; progressBar: ProgressBar; @@ -79,6 +80,7 @@ type Visibilities = { title?: boolean; checkAll?: boolean; inputBox?: boolean; + visibleCount?: boolean; count?: boolean; message?: boolean; list?: boolean; @@ -481,6 +483,7 @@ class QuickPick extends QuickInput implements IQuickPi this.ui.list.setElements(this.items); this.ui.list.filter(this.ui.inputBox.value); this.ui.checkAll.checked = this.ui.list.getAllVisibleChecked(); + this.ui.visibleCount.setCount(this.ui.list.getVisibleCount()); this.ui.count.setCount(this.ui.list.getCheckedCount()); if (!this.canSelectMany) { this.ui.list.focus('First'); @@ -515,7 +518,7 @@ class QuickPick extends QuickInput implements IQuickPi } this.ui.list.matchOnDescription = this.matchOnDescription; this.ui.list.matchOnDetail = this.matchOnDetail; - this.ui.setVisibilities(this.canSelectMany ? { title: !!this.title || !!this.step, checkAll: true, inputBox: true, count: true, ok: true, list: true } : { title: !!this.title || !!this.step, inputBox: true, list: true }); + this.ui.setVisibilities(this.canSelectMany ? { title: !!this.title || !!this.step, checkAll: true, inputBox: true, visibleCount: true, count: true, ok: true, list: true } : { title: !!this.title || !!this.step, inputBox: true, visibleCount: true, list: true }); } configureQuickNavigate(quickNavigate: IQuickNavigateConfiguration) { @@ -705,6 +708,7 @@ export class QuickInputService extends Component implements IQuickInputService { private layoutDimensions: dom.Dimension; private titleBar: HTMLElement; private filterContainer: HTMLElement; + private visibleCountContainer: HTMLElement; private countContainer: HTMLElement; private okContainer: HTMLElement; private ok: Button; @@ -789,7 +793,12 @@ export class QuickInputService extends Component implements IQuickInputService { const inputBox = this._register(new QuickInputBox(this.filterContainer)); + this.visibleCountContainer = dom.append(this.filterContainer, $('.quick-input-visible-count')); + this.visibleCountContainer.setAttribute('aria-live', 'polite'); + const visibleCount = new CountBadge(this.visibleCountContainer, { countFormat: localize({ key: 'quickInput.visibleCount', comment: ['This tells the user how many items are shown in a list of items to select from. The items can be anything. Currently not visible, but read by screen readers.'] }, "{0} Results") }); + this.countContainer = dom.append(this.filterContainer, $('.quick-input-count')); + this.countContainer.setAttribute('aria-live', 'polite'); const count = new CountBadge(this.countContainer, { countFormat: localize({ key: 'quickInput.countSelected', comment: ['This tells the user how many items are selected in a list of items to select from. The items can be anything.'] }, "{0} Selected") }); this._register(attachBadgeStyler(count, this.themeService)); @@ -811,6 +820,9 @@ export class QuickInputService extends Component implements IQuickInputService { this._register(list.onChangedAllVisibleChecked(checked => { checkAll.checked = checked; })); + this._register(list.onChangedVisibleCount(c => { + visibleCount.setCount(c); + })); this._register(list.onChangedCheckedCount(c => { count.setCount(c); })); @@ -880,6 +892,7 @@ export class QuickInputService extends Component implements IQuickInputService { rightActionBar, checkAll, inputBox, + visibleCount, count, message, progressBar, @@ -1047,6 +1060,7 @@ export class QuickInputService extends Component implements IQuickInputService { this.ui.inputBox.placeholder = ''; this.ui.inputBox.password = false; this.ui.inputBox.showDecoration(Severity.Ignore); + this.ui.visibleCount.setCount(0); this.ui.count.setCount(0); this.ui.message.textContent = ''; this.ui.progressBar.stop(); @@ -1069,6 +1083,7 @@ export class QuickInputService extends Component implements IQuickInputService { this.ui.title.style.display = visibilities.title ? '' : 'none'; this.ui.checkAll.style.display = visibilities.checkAll ? '' : 'none'; this.filterContainer.style.display = visibilities.inputBox ? '' : 'none'; + this.visibleCountContainer.style.display = visibilities.visibleCount ? '' : 'none'; this.countContainer.style.display = visibilities.count ? '' : 'none'; this.okContainer.style.display = visibilities.ok ? '' : 'none'; this.ui.message.style.display = visibilities.message ? '' : 'none'; diff --git a/src/vs/workbench/browser/parts/quickinput/quickInputList.ts b/src/vs/workbench/browser/parts/quickinput/quickInputList.ts index 6655db6f7bf..39ea74dde46 100644 --- a/src/vs/workbench/browser/parts/quickinput/quickInputList.ts +++ b/src/vs/workbench/browser/parts/quickinput/quickInputList.ts @@ -160,6 +160,8 @@ export class QuickInputList { onChangedAllVisibleChecked: Event = this._onChangedAllVisibleChecked.event; private _onChangedCheckedCount = new Emitter(); onChangedCheckedCount: Event = this._onChangedCheckedCount.event; + private _onChangedVisibleCount = new Emitter(); + onChangedVisibleCount: Event = this._onChangedVisibleCount.event; private _onChangedCheckedElements = new Emitter(); onChangedCheckedElements: Event = this._onChangedCheckedElements.event; private _onLeave = new Emitter(); @@ -255,6 +257,17 @@ export class QuickInputList { return count; } + getVisibleCount() { + let count = 0; + const elements = this.elements; + for (let i = 0, n = elements.length; i < n; i++) { + if (!elements[i].hidden) { + count++; + } + } + return count; + } + setAllVisibleChecked(checked: boolean) { try { this._fireCheckedEvents = false; @@ -284,6 +297,7 @@ export class QuickInputList { }, new Map()); this.list.splice(0, this.list.length, this.elements); this.list.setFocus([]); + this._onChangedVisibleCount.fire(this.elements.length); } getFocusedElements() { @@ -415,6 +429,7 @@ export class QuickInputList { this.list.layout(); this._onChangedAllVisibleChecked.fire(this.getAllVisibleChecked()); + this._onChangedVisibleCount.fire(shownElements.length); } toggleCheckbox() { From 364c454e9c47c244aaa08633846502e7dbfb1178 Mon Sep 17 00:00:00 2001 From: Christof Marti Date: Fri, 27 Jul 2018 09:21:02 +0200 Subject: [PATCH 0211/1276] Use focus tracker (fixes #53867) --- .../browser/parts/quickinput/quickInput.ts | 13 +++---------- 1 file changed, 3 insertions(+), 10 deletions(-) diff --git a/src/vs/workbench/browser/parts/quickinput/quickInput.ts b/src/vs/workbench/browser/parts/quickinput/quickInput.ts index 0f0b4dd4fca..4d5a8fff65e 100644 --- a/src/vs/workbench/browser/parts/quickinput/quickInput.ts +++ b/src/vs/workbench/browser/parts/quickinput/quickInput.ts @@ -834,16 +834,9 @@ export class QuickInputService extends Component implements IQuickInputService { }, 0); })); - this._register(dom.addDisposableListener(container, 'focusout', (e: FocusEvent) => { - if (e.relatedTarget === container) { - (e.target).focus(); - return; - } - for (let element = e.relatedTarget; element; element = element.parentElement) { - if (element === container) { - return; - } - } + const focusTracker = dom.trackFocus(container); + this._register(focusTracker); + this._register(focusTracker.onDidBlur(() => { if (!this.ui.ignoreFocusOut && !this.environmentService.args['sticky-quickopen'] && this.configurationService.getValue(CLOSE_ON_FOCUS_LOST_CONFIG)) { this.hide(true); } From b2c8d97d9b8817ded0eaf8419ee24905889a9edc Mon Sep 17 00:00:00 2001 From: Johannes Rieken Date: Fri, 27 Jul 2018 09:23:46 +0200 Subject: [PATCH 0212/1276] bc - Focus Breadcrumbs command should focus and select the last item --- 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 a805e568e9c..555823a6d83 100644 --- a/src/vs/workbench/browser/parts/editor/breadcrumbsControl.ts +++ b/src/vs/workbench/browser/parts/editor/breadcrumbsControl.ts @@ -364,7 +364,7 @@ export class BreadcrumbsControl { MenuRegistry.appendMenuItem(MenuId.CommandPalette, { command: { - id: 'breadcrumbs.focus', + id: 'breadcrumbs.focusAndSelect', title: localize('cmd.focus', "Focus Breadcrumbs") } }); From d397db1b1ab6a15e4e6704b0dc9f2e7645e3e0ea Mon Sep 17 00:00:00 2001 From: Christof Marti Date: Fri, 27 Jul 2018 10:32:02 +0200 Subject: [PATCH 0213/1276] Fix PageUp/Down (fixes #54457) --- .../browser/parts/quickinput/quickInput.ts | 30 +++++++++++++++++-- .../parts/quickinput/quickInputList.ts | 6 ++-- 2 files changed, 32 insertions(+), 4 deletions(-) diff --git a/src/vs/workbench/browser/parts/quickinput/quickInput.ts b/src/vs/workbench/browser/parts/quickinput/quickInput.ts index 4d5a8fff65e..83145223bde 100644 --- a/src/vs/workbench/browser/parts/quickinput/quickInput.ts +++ b/src/vs/workbench/browser/parts/quickinput/quickInput.ts @@ -417,7 +417,31 @@ class QuickPick extends QuickInput implements IQuickPi } break; case KeyCode.UpArrow: - this.ui.list.focus('Previous'); + if (this.ui.list.getFocusedElements().length) { + this.ui.list.focus('Previous'); + } else { + this.ui.list.focus('Last'); + } + if (this.canSelectMany) { + this.ui.list.domFocus(); + } + break; + case KeyCode.PageDown: + if (this.ui.list.getFocusedElements().length) { + this.ui.list.focus('NextPage'); + } else { + this.ui.list.focus('First'); + } + if (this.canSelectMany) { + this.ui.list.domFocus(); + } + break; + case KeyCode.PageUp: + if (this.ui.list.getFocusedElements().length) { + this.ui.list.focus('PreviousPage'); + } else { + this.ui.list.focus('Last'); + } if (this.canSelectMany) { this.ui.list.domFocus(); } @@ -830,7 +854,9 @@ export class QuickInputService extends Component implements IQuickInputService { // Defer to avoid the input field reacting to the triggering key. setTimeout(() => { inputBox.setFocus(); - list.clearFocus(); + if (this.controller instanceof QuickPick && this.controller.canSelectMany) { + list.clearFocus(); + } }, 0); })); diff --git a/src/vs/workbench/browser/parts/quickinput/quickInputList.ts b/src/vs/workbench/browser/parts/quickinput/quickInputList.ts index 39ea74dde46..f4a3a8fdf99 100644 --- a/src/vs/workbench/browser/parts/quickinput/quickInputList.ts +++ b/src/vs/workbench/browser/parts/quickinput/quickInputList.ts @@ -193,12 +193,14 @@ export class QuickInputList { } break; case KeyCode.UpArrow: + case KeyCode.PageUp: const focus1 = this.list.getFocus(); if (focus1.length === 1 && focus1[0] === 0) { this._onLeave.fire(); } break; case KeyCode.DownArrow: + case KeyCode.PageDown: const focus2 = this.list.getFocus(); if (focus2.length === 1 && focus2[0] === this.list.length - 1) { this._onLeave.fire(); @@ -352,10 +354,10 @@ export class QuickInputList { return; } - if (what === 'Next' && this.list.getFocus()[0] === this.list.length - 1) { + if ((what === 'Next' || what === 'NextPage') && this.list.getFocus()[0] === this.list.length - 1) { what = 'First'; } - if (what === 'Previous' && this.list.getFocus()[0] === 0) { + if ((what === 'Previous' || what === 'PreviousPage') && this.list.getFocus()[0] === 0) { what = 'Last'; } From 86c743c28e359fb0d4992e6bcf7d36a459a6f53b Mon Sep 17 00:00:00 2001 From: isidor Date: Fri, 27 Jul 2018 10:53:53 +0200 Subject: [PATCH 0214/1276] simpleEditor: minor renames --- ...WidgetConfig.ts => simpleEditorOptions.ts} | 79 +++++++++---------- .../electron-browser/breakpointWidget.ts | 6 +- .../parts/debug/electron-browser/repl.ts | 4 +- .../electron-browser/extensionsViewlet.ts | 6 +- 4 files changed, 45 insertions(+), 50 deletions(-) rename src/vs/workbench/parts/codeEditor/electron-browser/{simpleEditorWidgetConfig.ts => simpleEditorOptions.ts} (53%) diff --git a/src/vs/workbench/parts/codeEditor/electron-browser/simpleEditorWidgetConfig.ts b/src/vs/workbench/parts/codeEditor/electron-browser/simpleEditorOptions.ts similarity index 53% rename from src/vs/workbench/parts/codeEditor/electron-browser/simpleEditorWidgetConfig.ts rename to src/vs/workbench/parts/codeEditor/electron-browser/simpleEditorOptions.ts index c6f5a4eda1a..809dbd0584d 100644 --- a/src/vs/workbench/parts/codeEditor/electron-browser/simpleEditorWidgetConfig.ts +++ b/src/vs/workbench/parts/codeEditor/electron-browser/simpleEditorOptions.ts @@ -5,8 +5,6 @@ import { IEditorOptions } from 'vs/editor/common/config/editorOptions'; import { ICodeEditorWidgetOptions } from 'vs/editor/browser/widget/codeEditorWidget'; - -// Allowed Editor Contributions: import { MenuPreventer } from 'vs/workbench/parts/codeEditor/electron-browser/menuPreventer'; import { SelectionClipboard } from 'vs/workbench/parts/codeEditor/electron-browser/selectionClipboard'; import { ContextMenuController } from 'vs/editor/contrib/contextmenu/contextmenu'; @@ -14,44 +12,41 @@ import { SuggestController } from 'vs/editor/contrib/suggest/suggestController'; import { SnippetController2 } from 'vs/editor/contrib/snippet/snippetController2'; import { TabCompletionController } from 'vs/workbench/parts/snippets/electron-browser/tabCompletion'; -export class SimpleEditorWidgetConfig { - - public static getCodeEditorWidgetOptions(): ICodeEditorWidgetOptions { - return { - isSimpleWidget: true, - contributions: [ - MenuPreventer, - SelectionClipboard, - ContextMenuController, - SuggestController, - SnippetController2, - TabCompletionController, - ] - }; - } - - public static getEditorOptions(): IEditorOptions { - return { - wordWrap: 'on', - overviewRulerLanes: 0, - glyphMargin: false, - lineNumbers: 'off', - folding: false, - selectOnLineNumbers: false, - hideCursorInOverviewRuler: true, - selectionHighlight: false, - scrollbar: { - horizontal: 'hidden' - }, - lineDecorationsWidth: 0, - overviewRulerBorder: false, - scrollBeyondLastLine: false, - renderLineHighlight: 'none', - fixedOverflowWidgets: true, - acceptSuggestionOnEnter: 'smart', - minimap: { - enabled: false - } - }; - } +export function getSimpleCodeEditorWidgetOptions(): ICodeEditorWidgetOptions { + return { + isSimpleWidget: true, + contributions: [ + MenuPreventer, + SelectionClipboard, + ContextMenuController, + SuggestController, + SnippetController2, + TabCompletionController, + ] + }; +} + +export function getSimpleEditorOptions(): IEditorOptions { + return { + wordWrap: 'on', + overviewRulerLanes: 0, + glyphMargin: false, + lineNumbers: 'off', + folding: false, + selectOnLineNumbers: false, + hideCursorInOverviewRuler: true, + selectionHighlight: false, + scrollbar: { + horizontal: 'hidden' + }, + lineDecorationsWidth: 0, + overviewRulerBorder: false, + scrollBeyondLastLine: false, + renderLineHighlight: 'none', + fixedOverflowWidgets: true, + acceptSuggestionOnEnter: 'smart', + minimap: { + enabled: false + } + }; } diff --git a/src/vs/workbench/parts/debug/electron-browser/breakpointWidget.ts b/src/vs/workbench/parts/debug/electron-browser/breakpointWidget.ts index b8ffd5ca34a..d9bc400ab10 100644 --- a/src/vs/workbench/parts/debug/electron-browser/breakpointWidget.ts +++ b/src/vs/workbench/parts/debug/electron-browser/breakpointWidget.ts @@ -17,7 +17,6 @@ import { IContextViewService } from 'vs/platform/contextview/browser/contextView import { IDebugService, IBreakpoint, BreakpointWidgetContext as Context, CONTEXT_BREAKPOINT_WIDGET_VISIBLE, DEBUG_SCHEME, IDebugEditorContribution, EDITOR_CONTRIBUTION_ID, CONTEXT_IN_BREAKPOINT_WIDGET } from 'vs/workbench/parts/debug/common/debug'; import { attachSelectBoxStyler } from 'vs/platform/theme/common/styler'; import { IThemeService } from 'vs/platform/theme/common/themeService'; -import { SimpleEditorWidgetConfig } from 'vs/workbench/parts/codeEditor/electron-browser/simpleEditorWidgetConfig'; import { createDecorator, IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; import { IContextKeyService } from 'vs/platform/contextkey/common/contextkey'; import { ServicesAccessor, EditorCommand, registerEditorCommand } from 'vs/editor/browser/editorExtensions'; @@ -34,6 +33,7 @@ import { ServiceCollection } from 'vs/platform/instantiation/common/serviceColle import { IDecorationOptions } from 'vs/editor/common/editorCommon'; import { CodeEditorWidget } from 'vs/editor/browser/widget/codeEditorWidget'; import { KeybindingWeight } from 'vs/platform/keybinding/common/keybindingsRegistry'; +import { getSimpleEditorOptions, getSimpleCodeEditorWidgetOptions } from 'vs/workbench/parts/codeEditor/electron-browser/simpleEditorOptions'; const $ = dom.$; const IPrivateBreakpointWidgetService = createDecorator('privateBreakopintWidgetService'); @@ -200,8 +200,8 @@ export class BreakpointWidget extends ZoneWidget implements IPrivateBreakpointWi const scopedInstatiationService = this.instantiationService.createChild(new ServiceCollection( [IContextKeyService, scopedContextKeyService], [IPrivateBreakpointWidgetService, this])); - const options = SimpleEditorWidgetConfig.getEditorOptions(); - const codeEditorWidgetOptions = SimpleEditorWidgetConfig.getCodeEditorWidgetOptions(); + const options = getSimpleEditorOptions(); + const codeEditorWidgetOptions = getSimpleCodeEditorWidgetOptions(); this.input = scopedInstatiationService.createInstance(CodeEditorWidget, container, options, codeEditorWidgetOptions); CONTEXT_IN_BREAKPOINT_WIDGET.bindTo(scopedContextKeyService).set(true); const model = this.modelService.createModel('', null, uri.parse(`${DEBUG_SCHEME}:${this.editor.getId()}:breakpointinput`), true); diff --git a/src/vs/workbench/parts/debug/electron-browser/repl.ts b/src/vs/workbench/parts/debug/electron-browser/repl.ts index 296b4869076..453e622d41e 100644 --- a/src/vs/workbench/parts/debug/electron-browser/repl.ts +++ b/src/vs/workbench/parts/debug/electron-browser/repl.ts @@ -30,7 +30,6 @@ import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry'; import { IInstantiationService, createDecorator } from 'vs/platform/instantiation/common/instantiation'; import { IStorageService, StorageScope } from 'vs/platform/storage/common/storage'; import { ReplExpressionsRenderer, ReplExpressionsController, ReplExpressionsDataSource, ReplExpressionsActionProvider, ReplExpressionsAccessibilityProvider } from 'vs/workbench/parts/debug/electron-browser/replViewer'; -import { SimpleEditorWidgetConfig } from 'vs/workbench/parts/codeEditor/electron-browser/simpleEditorWidgetConfig'; import { ClearReplAction } from 'vs/workbench/parts/debug/browser/debugActions'; import { Panel } from 'vs/workbench/browser/panel'; import { IPanelService } from 'vs/workbench/services/panel/common/panelService'; @@ -48,6 +47,7 @@ import { HistoryNavigator } from 'vs/base/common/history'; import { IHistoryNavigationWidget } from 'vs/base/browser/history'; import { createAndBindHistoryNavigationWidgetScopedContextKeyService } from 'vs/platform/widget/browser/contextScopedHistoryWidget'; import { KeybindingWeight } from 'vs/platform/keybinding/common/keybindingsRegistry'; +import { getSimpleEditorOptions, getSimpleCodeEditorWidgetOptions } from 'vs/workbench/parts/codeEditor/electron-browser/simpleEditorOptions'; const $ = dom.$; @@ -173,7 +173,7 @@ export class Repl extends Panel implements IPrivateReplService, IHistoryNavigati const scopedInstantiationService = this.instantiationService.createChild(new ServiceCollection( [IContextKeyService, scopedContextKeyService], [IPrivateReplService, this])); - this.replInput = scopedInstantiationService.createInstance(CodeEditorWidget, this.replInputContainer, SimpleEditorWidgetConfig.getEditorOptions(), SimpleEditorWidgetConfig.getCodeEditorWidgetOptions()); + this.replInput = scopedInstantiationService.createInstance(CodeEditorWidget, this.replInputContainer, getSimpleEditorOptions(), getSimpleCodeEditorWidgetOptions()); modes.SuggestRegistry.register({ scheme: DEBUG_SCHEME, pattern: '**/replinput', hasAccessToAllModels: true }, { triggerCharacters: ['.'], diff --git a/src/vs/workbench/parts/extensions/electron-browser/extensionsViewlet.ts b/src/vs/workbench/parts/extensions/electron-browser/extensionsViewlet.ts index 54cf64796f5..1154cc6cb8e 100644 --- a/src/vs/workbench/parts/extensions/electron-browser/extensionsViewlet.ts +++ b/src/vs/workbench/parts/extensions/electron-browser/extensionsViewlet.ts @@ -64,8 +64,8 @@ import { IModelService } from 'vs/editor/common/services/modelService'; import { Range } from 'vs/editor/common/core/range'; import { Position } from 'vs/editor/common/core/position'; import { ITextModel } from 'vs/editor/common/model'; -import { SimpleEditorWidgetConfig } from 'vs/workbench/parts/codeEditor/electron-browser/simpleEditorWidgetConfig'; import { IEditorOptions } from 'vs/editor/common/config/editorOptions'; +import { getSimpleEditorOptions, getSimpleCodeEditorWidgetOptions } from 'vs/workbench/parts/codeEditor/electron-browser/simpleEditorOptions'; interface SearchInputEvent extends Event { target: HTMLInputElement; @@ -341,8 +341,8 @@ export class ExtensionsViewlet extends ViewContainerViewlet implements IExtensio const header = append(this.root, $('.header')); this.monacoStyleContainer = append(header, $('.monaco-container')); this.searchBox = this.instantiationService.createInstance(CodeEditorWidget, this.monacoStyleContainer, - mixinHTMLInputStyleOptions(SimpleEditorWidgetConfig.getEditorOptions(), localize('searchExtensions', "Search Extensions in Marketplace")), - SimpleEditorWidgetConfig.getCodeEditorWidgetOptions()); + mixinHTMLInputStyleOptions(getSimpleEditorOptions(), localize('searchExtensions', "Search Extensions in Marketplace")), + getSimpleCodeEditorWidgetOptions()); this.placeholderText = append(this.monacoStyleContainer, $('.search-placeholder', null, localize('searchExtensions', "Search Extensions in Marketplace"))); From c640a0ed5c5c8a4242a6ab7e43659b314c6a4ffa Mon Sep 17 00:00:00 2001 From: Martin Aeschlimann Date: Fri, 27 Jul 2018 10:57:26 +0200 Subject: [PATCH 0215/1276] adopt color changes in colorizer tests --- .../bat/test/colorize-results/test_bat.json | 32 +- .../test/colorize-results/test_clj.json | 128 ++-- .../colorize-results/test-regex_coffee.json | 24 +- .../test/colorize-results/test_coffee.json | 24 +- .../cpp/test/colorize-results/test_c.json | 36 +- .../cpp/test/colorize-results/test_cc.json | 32 +- .../cpp/test/colorize-results/test_cpp.json | 8 +- .../csharp/test/colorize-results/test_cs.json | 8 +- .../css/test/colorize-results/test_css.json | 96 +-- .../test/colorize-results/Dockerfile.json | 8 +- .../fsharp/test/colorize-results/test_fs.json | 12 +- .../test/colorize-results/COMMIT_EDITMSG.json | 72 +-- .../colorize-results/git-rebase-todo.json | 56 +- .../test/colorize-results/test-13777_go.json | 8 +- .../go/test/colorize-results/test_go.json | 8 +- .../test/colorize-results/test_groovy.json | 376 ++++++------ .../test/colorize-results/test_hbs.json | 4 +- .../ini/test/colorize-results/test_ini.json | 16 +- .../test/colorize-results/basic_java.json | 66 +-- .../test/colorize-results/test_js.json | 24 +- .../test/colorize-results/test_jsx.json | 40 +- .../json/test/colorize-results/test_json.json | 8 +- .../log/test/colorize-results/test_log.json | 72 +-- .../lua/test/colorize-results/test_lua.json | 16 +- .../make/test/colorize-results/makefile.json | 28 +- .../test/colorize-results/test_m.json | 44 +- .../perl/test/colorize-results/test_pl.json | 56 +- .../test/colorize-results/test_ps1.json | 16 +- .../python/test/colorize-results/test_py.json | 72 +-- .../r/test/colorize-results/test_r.json | 92 +-- .../test/colorize-results/test_cshtml.json | 486 +++++++++------- .../ruby/test/colorize-results/test_rb.json | 96 +-- .../scss/test/colorize-results/test_scss.json | 548 +++++++++--------- .../test/colorize-results/test_sh.json | 32 +- .../colorize-results/test-brackets_tsx.json | 8 +- .../test/colorize-results/test_ts.json | 24 +- .../vb/test/colorize-results/test_vb.json | 48 +- .../xml/test/colorize-results/test_xml.json | 12 +- .../yaml/test/colorize-results/test_yaml.json | 24 +- 39 files changed, 1413 insertions(+), 1347 deletions(-) diff --git a/extensions/bat/test/colorize-results/test_bat.json b/extensions/bat/test/colorize-results/test_bat.json index 3c2abc5d2dc..97155fafc8b 100644 --- a/extensions/bat/test/colorize-results/test_bat.json +++ b/extensions/bat/test/colorize-results/test_bat.json @@ -135,9 +135,9 @@ "c": "::", "t": "source.batchfile comment.line.colon.batchfile punctuation.definition.comment.batchfile", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -146,9 +146,9 @@ "c": " Node modules", "t": "source.batchfile comment.line.colon.batchfile", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -245,9 +245,9 @@ "c": "::", "t": "source.batchfile comment.line.colon.batchfile punctuation.definition.comment.batchfile", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -256,9 +256,9 @@ "c": " Get electron", "t": "source.batchfile comment.line.colon.batchfile", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -278,9 +278,9 @@ "c": "::", "t": "source.batchfile comment.line.colon.batchfile punctuation.definition.comment.batchfile", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -289,9 +289,9 @@ "c": " Build", "t": "source.batchfile comment.line.colon.batchfile", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -366,9 +366,9 @@ "c": "::", "t": "source.batchfile comment.line.colon.batchfile punctuation.definition.comment.batchfile", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -377,9 +377,9 @@ "c": " Configuration", "t": "source.batchfile comment.line.colon.batchfile", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } diff --git a/extensions/clojure/test/colorize-results/test_clj.json b/extensions/clojure/test/colorize-results/test_clj.json index 8a704fb9683..b7dd17d91e8 100644 --- a/extensions/clojure/test/colorize-results/test_clj.json +++ b/extensions/clojure/test/colorize-results/test_clj.json @@ -3,9 +3,9 @@ "c": ";", "t": "source.clojure comment.line.semicolon.clojure punctuation.definition.comment.clojure", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -14,9 +14,9 @@ "c": "; from http://clojure-doc.org/articles/tutorials/introduction.html", "t": "source.clojure comment.line.semicolon.clojure", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -311,9 +311,9 @@ "c": ";", "t": "source.clojure comment.line.semicolon.clojure punctuation.definition.comment.clojure", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -322,9 +322,9 @@ "c": " A vector", "t": "source.clojure comment.line.semicolon.clojure", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -905,9 +905,9 @@ "c": ";", "t": "source.clojure comment.line.semicolon.clojure punctuation.definition.comment.clojure", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -916,9 +916,9 @@ "c": " this is more typical usage.", "t": "source.clojure comment.line.semicolon.clojure", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -1433,9 +1433,9 @@ "c": ";", "t": "source.clojure comment.line.semicolon.clojure punctuation.definition.comment.clojure", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -1444,9 +1444,9 @@ "c": "; ⇒ (+ 1 2 3)", "t": "source.clojure comment.line.semicolon.clojure", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -1840,9 +1840,9 @@ "c": ";", "t": "source.clojure comment.line.semicolon.clojure punctuation.definition.comment.clojure", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -1851,9 +1851,9 @@ "c": "; Vectors", "t": "source.clojure comment.line.semicolon.clojure", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -2236,9 +2236,9 @@ "c": ";", "t": "source.clojure comment.line.semicolon.clojure punctuation.definition.comment.clojure", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -2247,9 +2247,9 @@ "c": " ⇒ [:a :b :c :d]", "t": "source.clojure comment.line.semicolon.clojure", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -2346,9 +2346,9 @@ "c": ";", "t": "source.clojure comment.line.semicolon.clojure punctuation.definition.comment.clojure", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -2357,9 +2357,9 @@ "c": " ⇒ (:d :a :b :c)", "t": "source.clojure comment.line.semicolon.clojure", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -2390,9 +2390,9 @@ "c": ";", "t": "source.clojure comment.line.semicolon.clojure punctuation.definition.comment.clojure", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -2401,9 +2401,9 @@ "c": " ⇒ is still [:a :b :c]", "t": "source.clojure comment.line.semicolon.clojure", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -2434,9 +2434,9 @@ "c": ";", "t": "source.clojure comment.line.semicolon.clojure punctuation.definition.comment.clojure", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -2445,9 +2445,9 @@ "c": " ⇒ is still (:a :b :c)", "t": "source.clojure comment.line.semicolon.clojure", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -2456,9 +2456,9 @@ "c": ";", "t": "source.clojure comment.line.semicolon.clojure punctuation.definition.comment.clojure", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -2467,9 +2467,9 @@ "c": "; Maps", "t": "source.clojure comment.line.semicolon.clojure", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -2753,9 +2753,9 @@ "c": ";", "t": "source.clojure comment.line.semicolon.clojure punctuation.definition.comment.clojure", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -2764,9 +2764,9 @@ "c": " ⇒ {:a 1 :c 3 :b 2}", "t": "source.clojure comment.line.semicolon.clojure", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -2863,9 +2863,9 @@ "c": ";", "t": "source.clojure comment.line.semicolon.clojure punctuation.definition.comment.clojure", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -2874,9 +2874,9 @@ "c": " ⇒ {:a 1}", "t": "source.clojure comment.line.semicolon.clojure", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -3050,9 +3050,9 @@ "c": ";", "t": "source.clojure comment.line.semicolon.clojure punctuation.definition.comment.clojure", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -3061,9 +3061,9 @@ "c": "; ⇒ #'user/my-atom", "t": "source.clojure comment.line.semicolon.clojure", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -3094,9 +3094,9 @@ "c": ";", "t": "source.clojure comment.line.semicolon.clojure punctuation.definition.comment.clojure", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -3105,9 +3105,9 @@ "c": "; ⇒ {:foo 1}", "t": "source.clojure comment.line.semicolon.clojure", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -3259,9 +3259,9 @@ "c": ";", "t": "source.clojure comment.line.semicolon.clojure punctuation.definition.comment.clojure", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -3270,9 +3270,9 @@ "c": "; ⇒ {:foo 2}", "t": "source.clojure comment.line.semicolon.clojure", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -3303,9 +3303,9 @@ "c": ";", "t": "source.clojure comment.line.semicolon.clojure punctuation.definition.comment.clojure", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -3314,9 +3314,9 @@ "c": "; ⇒ {:foo 2}", "t": "source.clojure comment.line.semicolon.clojure", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } diff --git a/extensions/coffeescript/test/colorize-results/test-regex_coffee.json b/extensions/coffeescript/test/colorize-results/test-regex_coffee.json index ad11ba9d687..9daab0d5533 100644 --- a/extensions/coffeescript/test/colorize-results/test-regex_coffee.json +++ b/extensions/coffeescript/test/colorize-results/test-regex_coffee.json @@ -575,9 +575,9 @@ "c": "#", "t": "source.coffee comment.line.number-sign.coffee punctuation.definition.comment.coffee", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -586,9 +586,9 @@ "c": " numbers", "t": "source.coffee comment.line.number-sign.coffee", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -663,9 +663,9 @@ "c": "#", "t": "source.coffee comment.line.number-sign.coffee punctuation.definition.comment.coffee", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -674,9 +674,9 @@ "c": " letters", "t": "source.coffee comment.line.number-sign.coffee", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -696,9 +696,9 @@ "c": "#", "t": "source.coffee comment.line.number-sign.coffee punctuation.definition.comment.coffee", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -707,9 +707,9 @@ "c": " the end", "t": "source.coffee comment.line.number-sign.coffee", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } diff --git a/extensions/coffeescript/test/colorize-results/test_coffee.json b/extensions/coffeescript/test/colorize-results/test_coffee.json index e7eae7d047f..d3de07d3f82 100644 --- a/extensions/coffeescript/test/colorize-results/test_coffee.json +++ b/extensions/coffeescript/test/colorize-results/test_coffee.json @@ -1433,9 +1433,9 @@ "c": "#", "t": "source.coffee string.regexp.multiline.coffee comment.line.number-sign.coffee punctuation.definition.comment.coffee", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -1444,9 +1444,9 @@ "c": " numbers", "t": "source.coffee string.regexp.multiline.coffee comment.line.number-sign.coffee", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -1521,9 +1521,9 @@ "c": "#", "t": "source.coffee string.regexp.multiline.coffee comment.line.number-sign.coffee punctuation.definition.comment.coffee", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -1532,9 +1532,9 @@ "c": " letters", "t": "source.coffee string.regexp.multiline.coffee comment.line.number-sign.coffee", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -1576,9 +1576,9 @@ "c": "#", "t": "source.coffee string.regexp.multiline.coffee comment.line.number-sign.coffee punctuation.definition.comment.coffee", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -1587,9 +1587,9 @@ "c": " the end", "t": "source.coffee string.regexp.multiline.coffee comment.line.number-sign.coffee", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } diff --git a/extensions/cpp/test/colorize-results/test_c.json b/extensions/cpp/test/colorize-results/test_c.json index d3bac881c43..0725010d8c2 100644 --- a/extensions/cpp/test/colorize-results/test_c.json +++ b/extensions/cpp/test/colorize-results/test_c.json @@ -3,9 +3,9 @@ "c": "/*", "t": "source.c comment.block.c punctuation.definition.comment.begin.c", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -14,9 +14,9 @@ "c": " C Program to find roots of a quadratic equation when coefficients are entered by user. ", "t": "source.c comment.block.c", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -25,9 +25,9 @@ "c": "*/", "t": "source.c comment.block.c punctuation.definition.comment.end.c", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -36,9 +36,9 @@ "c": "/*", "t": "source.c comment.block.c punctuation.definition.comment.begin.c", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -47,9 +47,9 @@ "c": " Library function sqrt() computes the square root. ", "t": "source.c comment.block.c", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -58,9 +58,9 @@ "c": "*/", "t": "source.c comment.block.c punctuation.definition.comment.end.c", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -212,9 +212,9 @@ "c": "/*", "t": "source.c comment.block.c punctuation.definition.comment.begin.c", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -223,9 +223,9 @@ "c": " This is needed to use sqrt() function.", "t": "source.c comment.block.c", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -234,9 +234,9 @@ "c": "*/", "t": "source.c comment.block.c punctuation.definition.comment.end.c", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } diff --git a/extensions/cpp/test/colorize-results/test_cc.json b/extensions/cpp/test/colorize-results/test_cc.json index 845a693b3ab..f3f72320fb5 100644 --- a/extensions/cpp/test/colorize-results/test_cc.json +++ b/extensions/cpp/test/colorize-results/test_cc.json @@ -1114,9 +1114,9 @@ "c": "//", "t": "source.cpp meta.block.c comment.line.double-slash.cpp punctuation.definition.comment.cpp", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -1125,9 +1125,9 @@ "c": " everything from this point on is interpeted as a string literal...", "t": "source.cpp meta.block.c comment.line.double-slash.cpp", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -1312,9 +1312,9 @@ "c": "//", "t": "source.cpp meta.block.c comment.line.double-slash.cpp punctuation.definition.comment.cpp", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -1323,9 +1323,9 @@ "c": " sadness.", "t": "source.cpp meta.block.c comment.line.double-slash.cpp", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -1708,9 +1708,9 @@ "c": "//", "t": "source.cpp meta.block.c comment.line.double-slash.cpp punctuation.definition.comment.cpp", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -1719,9 +1719,9 @@ "c": " the rest of", "t": "source.cpp meta.block.c comment.line.double-slash.cpp", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -1961,9 +1961,9 @@ "c": "//", "t": "source.cpp meta.block.c comment.line.double-slash.cpp punctuation.definition.comment.cpp", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -1972,9 +1972,9 @@ "c": " the rest of", "t": "source.cpp meta.block.c comment.line.double-slash.cpp", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } diff --git a/extensions/cpp/test/colorize-results/test_cpp.json b/extensions/cpp/test/colorize-results/test_cpp.json index 8527e98a4f2..b3c9a841cc4 100644 --- a/extensions/cpp/test/colorize-results/test_cpp.json +++ b/extensions/cpp/test/colorize-results/test_cpp.json @@ -3,9 +3,9 @@ "c": "//", "t": "source.cpp comment.line.double-slash.cpp punctuation.definition.comment.cpp", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -14,9 +14,9 @@ "c": " classes example", "t": "source.cpp comment.line.double-slash.cpp", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } diff --git a/extensions/csharp/test/colorize-results/test_cs.json b/extensions/csharp/test/colorize-results/test_cs.json index 6b56bff9935..1fc73fb341c 100644 --- a/extensions/csharp/test/colorize-results/test_cs.json +++ b/extensions/csharp/test/colorize-results/test_cs.json @@ -1114,9 +1114,9 @@ "c": "//", "t": "source.cs comment.line.double-slash.cs punctuation.definition.comment.cs", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -1125,9 +1125,9 @@ "c": " Display the number of command line arguments:", "t": "source.cs comment.line.double-slash.cs", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } diff --git a/extensions/css/test/colorize-results/test_css.json b/extensions/css/test/colorize-results/test_css.json index 6daa830028e..f4abc368d09 100644 --- a/extensions/css/test/colorize-results/test_css.json +++ b/extensions/css/test/colorize-results/test_css.json @@ -3,9 +3,9 @@ "c": "/*", "t": "source.css comment.block.css punctuation.definition.comment.begin.css", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -14,9 +14,9 @@ "c": " css Zen Garden default style v1.02 ", "t": "source.css comment.block.css", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -25,9 +25,9 @@ "c": "*/", "t": "source.css comment.block.css punctuation.definition.comment.end.css", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -36,9 +36,9 @@ "c": "/*", "t": "source.css comment.block.css punctuation.definition.comment.begin.css", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -47,9 +47,9 @@ "c": " css released under Creative Commons License - http://creativecommons.org/licenses/by-nc-sa/1.0/ ", "t": "source.css comment.block.css", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -58,9 +58,9 @@ "c": "*/", "t": "source.css comment.block.css punctuation.definition.comment.end.css", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -69,9 +69,9 @@ "c": "/*", "t": "source.css comment.block.css punctuation.definition.comment.begin.css", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -80,9 +80,9 @@ "c": " This file based on 'Tranquille' by Dave Shea ", "t": "source.css comment.block.css", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -91,9 +91,9 @@ "c": "*/", "t": "source.css comment.block.css punctuation.definition.comment.end.css", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -102,9 +102,9 @@ "c": "/*", "t": "source.css comment.block.css punctuation.definition.comment.begin.css", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -113,9 +113,9 @@ "c": " You may use this file as a foundation for any new work, but you may find it easier to start from scratch. ", "t": "source.css comment.block.css", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -124,9 +124,9 @@ "c": "*/", "t": "source.css comment.block.css punctuation.definition.comment.end.css", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -135,9 +135,9 @@ "c": "/*", "t": "source.css comment.block.css punctuation.definition.comment.begin.css", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -146,9 +146,9 @@ "c": " Not all elements are defined in this file, so you'll most likely want to refer to the xhtml as well. ", "t": "source.css comment.block.css", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -157,9 +157,9 @@ "c": "*/", "t": "source.css comment.block.css punctuation.definition.comment.end.css", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -168,9 +168,9 @@ "c": "/*", "t": "source.css comment.block.css punctuation.definition.comment.begin.css", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -179,9 +179,9 @@ "c": " Your images should be linked as if the CSS file sits in the same folder as the images. ie. no paths. ", "t": "source.css comment.block.css", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -190,9 +190,9 @@ "c": "*/", "t": "source.css comment.block.css punctuation.definition.comment.end.css", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -201,9 +201,9 @@ "c": "/*", "t": "source.css comment.block.css punctuation.definition.comment.begin.css", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -212,9 +212,9 @@ "c": " basic elements ", "t": "source.css comment.block.css", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -223,9 +223,9 @@ "c": "*/", "t": "source.css comment.block.css punctuation.definition.comment.end.css", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -3842,9 +3842,9 @@ "c": "/*", "t": "source.css comment.block.css punctuation.definition.comment.begin.css", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -3853,9 +3853,9 @@ "c": " specific divs ", "t": "source.css comment.block.css", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -3864,9 +3864,9 @@ "c": "*/", "t": "source.css comment.block.css punctuation.definition.comment.end.css", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } diff --git a/extensions/docker/test/colorize-results/Dockerfile.json b/extensions/docker/test/colorize-results/Dockerfile.json index a18ec445c04..fcb2e004c16 100644 --- a/extensions/docker/test/colorize-results/Dockerfile.json +++ b/extensions/docker/test/colorize-results/Dockerfile.json @@ -179,9 +179,9 @@ "c": "#", "t": "source.dockerfile comment.line.number-sign.dockerfile punctuation.definition.comment.dockerfile", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -190,9 +190,9 @@ "c": "RUN apt-get install -y nodejs=0.6.12~dfsg1-1ubuntu1", "t": "source.dockerfile comment.line.number-sign.dockerfile", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } diff --git a/extensions/fsharp/test/colorize-results/test_fs.json b/extensions/fsharp/test/colorize-results/test_fs.json index ecc06e7991f..328557e57b3 100644 --- a/extensions/fsharp/test/colorize-results/test_fs.json +++ b/extensions/fsharp/test/colorize-results/test_fs.json @@ -3,9 +3,9 @@ "c": "// from https://msdn.microsoft.com/en-us/library/dd233160.aspx", "t": "source.fsharp comment.line.double-slash.fsharp", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -14,9 +14,9 @@ "c": "// The declaration creates a constructor that takes two values, name and age.", "t": "source.fsharp comment.line.double-slash.fsharp", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -520,9 +520,9 @@ "c": "// A read/write property.", "t": "source.fsharp comment.line.double-slash.fsharp", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } diff --git a/extensions/git/test/colorize-results/COMMIT_EDITMSG.json b/extensions/git/test/colorize-results/COMMIT_EDITMSG.json index b5457404c8e..508e3ee199c 100644 --- a/extensions/git/test/colorize-results/COMMIT_EDITMSG.json +++ b/extensions/git/test/colorize-results/COMMIT_EDITMSG.json @@ -25,9 +25,9 @@ "c": "#", "t": "text.git-commit meta.scope.metadata.git-commit comment.line.number-sign.git-commit punctuation.definition.comment.git-commit", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -36,9 +36,9 @@ "c": " Please enter the commit message for your changes. Lines starting", "t": "text.git-commit meta.scope.metadata.git-commit comment.line.number-sign.git-commit", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -47,9 +47,9 @@ "c": "#", "t": "text.git-commit meta.scope.metadata.git-commit comment.line.number-sign.git-commit punctuation.definition.comment.git-commit", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -58,9 +58,9 @@ "c": " with '#' will be ignored, and an empty message aborts the commit.", "t": "text.git-commit meta.scope.metadata.git-commit comment.line.number-sign.git-commit", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -69,9 +69,9 @@ "c": "#", "t": "text.git-commit meta.scope.metadata.git-commit comment.line.number-sign.git-commit punctuation.definition.comment.git-commit", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -80,9 +80,9 @@ "c": " On branch master", "t": "text.git-commit meta.scope.metadata.git-commit comment.line.number-sign.git-commit", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -91,9 +91,9 @@ "c": "#", "t": "text.git-commit meta.scope.metadata.git-commit comment.line.number-sign.git-commit punctuation.definition.comment.git-commit", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -102,9 +102,9 @@ "c": " Your branch is up-to-date with 'origin/master'.", "t": "text.git-commit meta.scope.metadata.git-commit comment.line.number-sign.git-commit", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -113,9 +113,9 @@ "c": "#", "t": "text.git-commit meta.scope.metadata.git-commit comment.line.number-sign.git-commit punctuation.definition.comment.git-commit", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -124,9 +124,9 @@ "c": "#", "t": "text.git-commit meta.scope.metadata.git-commit comment.line.number-sign.git-commit punctuation.definition.comment.git-commit", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -135,9 +135,9 @@ "c": " Changes to be committed:", "t": "text.git-commit meta.scope.metadata.git-commit comment.line.number-sign.git-commit", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -146,9 +146,9 @@ "c": "#", "t": "text.git-commit meta.scope.metadata.git-commit comment.line.number-sign.git-commit punctuation.definition.comment.git-commit", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -157,9 +157,9 @@ "c": "\t", "t": "text.git-commit meta.scope.metadata.git-commit comment.line.number-sign.git-commit", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -179,9 +179,9 @@ "c": "#", "t": "text.git-commit meta.scope.metadata.git-commit comment.line.number-sign.git-commit punctuation.definition.comment.git-commit", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -190,9 +190,9 @@ "c": "\t", "t": "text.git-commit meta.scope.metadata.git-commit comment.line.number-sign.git-commit", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -212,9 +212,9 @@ "c": "#", "t": "text.git-commit meta.scope.metadata.git-commit comment.line.number-sign.git-commit punctuation.definition.comment.git-commit", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -223,9 +223,9 @@ "c": "\t", "t": "text.git-commit meta.scope.metadata.git-commit comment.line.number-sign.git-commit", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -245,9 +245,9 @@ "c": "#", "t": "text.git-commit meta.scope.metadata.git-commit comment.line.number-sign.git-commit punctuation.definition.comment.git-commit", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } diff --git a/extensions/git/test/colorize-results/git-rebase-todo.json b/extensions/git/test/colorize-results/git-rebase-todo.json index 87781fdbe05..d21bab17094 100644 --- a/extensions/git/test/colorize-results/git-rebase-todo.json +++ b/extensions/git/test/colorize-results/git-rebase-todo.json @@ -388,9 +388,9 @@ "c": "#", "t": "text.git-rebase comment.line.number-sign.git-rebase punctuation.definition.comment.git-rebase", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -399,9 +399,9 @@ "c": " Commands:", "t": "text.git-rebase comment.line.number-sign.git-rebase", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -410,9 +410,9 @@ "c": "#", "t": "text.git-rebase comment.line.number-sign.git-rebase punctuation.definition.comment.git-rebase", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -421,9 +421,9 @@ "c": " p, pick = use commit", "t": "text.git-rebase comment.line.number-sign.git-rebase", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -432,9 +432,9 @@ "c": "#", "t": "text.git-rebase comment.line.number-sign.git-rebase punctuation.definition.comment.git-rebase", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -443,9 +443,9 @@ "c": " r, reword = use commit, but edit the commit message", "t": "text.git-rebase comment.line.number-sign.git-rebase", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -454,9 +454,9 @@ "c": "#", "t": "text.git-rebase comment.line.number-sign.git-rebase punctuation.definition.comment.git-rebase", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -465,9 +465,9 @@ "c": " e, edit = use commit, but stop for amending", "t": "text.git-rebase comment.line.number-sign.git-rebase", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -476,9 +476,9 @@ "c": "#", "t": "text.git-rebase comment.line.number-sign.git-rebase punctuation.definition.comment.git-rebase", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -487,9 +487,9 @@ "c": " s, squash = use commit, but meld into previous commit", "t": "text.git-rebase comment.line.number-sign.git-rebase", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -498,9 +498,9 @@ "c": "#", "t": "text.git-rebase comment.line.number-sign.git-rebase punctuation.definition.comment.git-rebase", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -509,9 +509,9 @@ "c": " f, fixup = like \"squash\", but discard this commit's log message", "t": "text.git-rebase comment.line.number-sign.git-rebase", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -520,9 +520,9 @@ "c": "#", "t": "text.git-rebase comment.line.number-sign.git-rebase punctuation.definition.comment.git-rebase", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -531,9 +531,9 @@ "c": " x, exec = run command (the rest of the line) using shell", "t": "text.git-rebase comment.line.number-sign.git-rebase", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } diff --git a/extensions/go/test/colorize-results/test-13777_go.json b/extensions/go/test/colorize-results/test-13777_go.json index 7012da53227..ba7b1bd76fc 100644 --- a/extensions/go/test/colorize-results/test-13777_go.json +++ b/extensions/go/test/colorize-results/test-13777_go.json @@ -80,9 +80,9 @@ "c": "//", "t": "source.go comment.line.double-slash.go punctuation.definition.comment.go", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -91,9 +91,9 @@ "c": " ( comments after var are now green )", "t": "source.go comment.line.double-slash.go", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } diff --git a/extensions/go/test/colorize-results/test_go.json b/extensions/go/test/colorize-results/test_go.json index 6916ec49cd2..14cd6ef4230 100644 --- a/extensions/go/test/colorize-results/test_go.json +++ b/extensions/go/test/colorize-results/test_go.json @@ -927,9 +927,9 @@ "c": "//", "t": "source.go comment.line.double-slash.go punctuation.definition.comment.go", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -938,9 +938,9 @@ "c": " create virtual machine", "t": "source.go comment.line.double-slash.go", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } diff --git a/extensions/groovy/test/colorize-results/test_groovy.json b/extensions/groovy/test/colorize-results/test_groovy.json index 8d1191aa367..13aa74462a8 100644 --- a/extensions/groovy/test/colorize-results/test_groovy.json +++ b/extensions/groovy/test/colorize-results/test_groovy.json @@ -3,9 +3,9 @@ "c": "//", "t": "source.groovy comment.line.double-slash.groovy punctuation.definition.comment.groovy", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -14,9 +14,9 @@ "c": " Hello World", "t": "source.groovy comment.line.double-slash.groovy", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -80,9 +80,9 @@ "c": "/*", "t": "source.groovy comment.block.groovy punctuation.definition.comment.groovy", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -91,9 +91,9 @@ "c": " Variables:", "t": "source.groovy comment.block.groovy", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -102,9 +102,9 @@ "c": " You can assign values to variables for later use", "t": "source.groovy comment.block.groovy", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -113,9 +113,9 @@ "c": "*/", "t": "source.groovy comment.block.groovy punctuation.definition.comment.groovy", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -542,9 +542,9 @@ "c": "/*", "t": "source.groovy comment.block.groovy punctuation.definition.comment.groovy", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -553,9 +553,9 @@ "c": " Collections and maps", "t": "source.groovy comment.block.groovy", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -564,9 +564,9 @@ "c": "*/", "t": "source.groovy comment.block.groovy punctuation.definition.comment.groovy", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -575,9 +575,9 @@ "c": "//", "t": "source.groovy comment.line.double-slash.groovy punctuation.definition.comment.groovy", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -586,9 +586,9 @@ "c": "Creating an empty list", "t": "source.groovy comment.line.double-slash.groovy", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -685,9 +685,9 @@ "c": "/*", "t": "source.groovy comment.block.groovy punctuation.definition.comment.groovy", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -696,9 +696,9 @@ "c": "** Adding a elements to the list **", "t": "source.groovy comment.block.groovy", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -707,9 +707,9 @@ "c": "*/", "t": "source.groovy comment.block.groovy punctuation.definition.comment.groovy", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -718,9 +718,9 @@ "c": "//", "t": "source.groovy comment.line.double-slash.groovy punctuation.definition.comment.groovy", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -729,9 +729,9 @@ "c": " As with Java", "t": "source.groovy comment.line.double-slash.groovy", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -828,9 +828,9 @@ "c": "//", "t": "source.groovy comment.line.double-slash.groovy punctuation.definition.comment.groovy", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -839,9 +839,9 @@ "c": " Left shift adds, and returns the list", "t": "source.groovy comment.line.double-slash.groovy", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -916,9 +916,9 @@ "c": "//", "t": "source.groovy comment.line.double-slash.groovy punctuation.definition.comment.groovy", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -927,9 +927,9 @@ "c": " Add multiple elements", "t": "source.groovy comment.line.double-slash.groovy", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -1092,9 +1092,9 @@ "c": "/*", "t": "source.groovy comment.block.groovy punctuation.definition.comment.groovy", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -1103,9 +1103,9 @@ "c": "** Removing elements from the list **", "t": "source.groovy comment.block.groovy", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -1114,9 +1114,9 @@ "c": "*/", "t": "source.groovy comment.block.groovy punctuation.definition.comment.groovy", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -1125,9 +1125,9 @@ "c": "//", "t": "source.groovy comment.line.double-slash.groovy punctuation.definition.comment.groovy", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -1136,9 +1136,9 @@ "c": " As with Java", "t": "source.groovy comment.line.double-slash.groovy", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -1235,9 +1235,9 @@ "c": "//", "t": "source.groovy comment.line.double-slash.groovy punctuation.definition.comment.groovy", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -1246,9 +1246,9 @@ "c": " Subtraction works also", "t": "source.groovy comment.line.double-slash.groovy", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -1345,9 +1345,9 @@ "c": "/*", "t": "source.groovy comment.block.groovy punctuation.definition.comment.groovy", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -1356,9 +1356,9 @@ "c": "** Iterating Lists **", "t": "source.groovy comment.block.groovy", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -1367,9 +1367,9 @@ "c": "*/", "t": "source.groovy comment.block.groovy punctuation.definition.comment.groovy", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -1378,9 +1378,9 @@ "c": "//", "t": "source.groovy comment.line.double-slash.groovy punctuation.definition.comment.groovy", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -1389,9 +1389,9 @@ "c": " Iterate over elements of a list", "t": "source.groovy comment.line.double-slash.groovy", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -1741,9 +1741,9 @@ "c": "/*", "t": "source.groovy comment.block.groovy punctuation.definition.comment.groovy", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -1752,9 +1752,9 @@ "c": "** Checking List contents **", "t": "source.groovy comment.block.groovy", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -1763,9 +1763,9 @@ "c": "*/", "t": "source.groovy comment.block.groovy punctuation.definition.comment.groovy", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -1774,9 +1774,9 @@ "c": "//", "t": "source.groovy comment.line.double-slash.groovy punctuation.definition.comment.groovy", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -1785,9 +1785,9 @@ "c": "Evaluate if a list contains element(s) (boolean)", "t": "source.groovy comment.line.double-slash.groovy", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -1928,9 +1928,9 @@ "c": "//", "t": "source.groovy comment.line.double-slash.groovy punctuation.definition.comment.groovy", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -1939,9 +1939,9 @@ "c": " Or", "t": "source.groovy comment.line.double-slash.groovy", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -2049,9 +2049,9 @@ "c": "//", "t": "source.groovy comment.line.double-slash.groovy punctuation.definition.comment.groovy", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -2060,9 +2060,9 @@ "c": " To sort without mutating original, you can do:", "t": "source.groovy comment.line.double-slash.groovy", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -2181,9 +2181,9 @@ "c": "//", "t": "source.groovy comment.line.double-slash.groovy punctuation.definition.comment.groovy", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -2192,9 +2192,9 @@ "c": "Replace all elements in the list", "t": "source.groovy comment.line.double-slash.groovy", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -2379,9 +2379,9 @@ "c": "//", "t": "source.groovy comment.line.double-slash.groovy punctuation.definition.comment.groovy", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -2390,9 +2390,9 @@ "c": "Shuffle a list", "t": "source.groovy comment.line.double-slash.groovy", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -2533,9 +2533,9 @@ "c": "//", "t": "source.groovy comment.line.double-slash.groovy punctuation.definition.comment.groovy", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -2544,9 +2544,9 @@ "c": "Clear a list", "t": "source.groovy comment.line.double-slash.groovy", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -2610,9 +2610,9 @@ "c": "//", "t": "source.groovy comment.line.double-slash.groovy punctuation.definition.comment.groovy", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -2621,9 +2621,9 @@ "c": "Creating an empty map", "t": "source.groovy comment.line.double-slash.groovy", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -2731,9 +2731,9 @@ "c": "//", "t": "source.groovy comment.line.double-slash.groovy punctuation.definition.comment.groovy", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -2742,9 +2742,9 @@ "c": "Add values", "t": "source.groovy comment.line.double-slash.groovy", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -3215,9 +3215,9 @@ "c": "//", "t": "source.groovy comment.line.double-slash.groovy punctuation.definition.comment.groovy", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -3226,9 +3226,9 @@ "c": "Iterate over elements of a map", "t": "source.groovy comment.line.double-slash.groovy", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -3644,9 +3644,9 @@ "c": "//", "t": "source.groovy comment.line.double-slash.groovy punctuation.definition.comment.groovy", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -3655,9 +3655,9 @@ "c": "Evaluate if a map contains a key", "t": "source.groovy comment.line.double-slash.groovy", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -3765,9 +3765,9 @@ "c": "//", "t": "source.groovy comment.line.double-slash.groovy punctuation.definition.comment.groovy", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -3776,9 +3776,9 @@ "c": "Get the keys of a map", "t": "source.groovy comment.line.double-slash.groovy", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -3919,9 +3919,9 @@ "c": "//", "t": "source.groovy meta.definition.class.groovy meta.class.body.groovy comment.line.double-slash.groovy punctuation.definition.comment.groovy", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -3930,9 +3930,9 @@ "c": " read only property", "t": "source.groovy meta.definition.class.groovy meta.class.body.groovy comment.line.double-slash.groovy", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -4084,9 +4084,9 @@ "c": "//", "t": "source.groovy meta.definition.class.groovy meta.class.body.groovy comment.line.double-slash.groovy punctuation.definition.comment.groovy", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -4095,9 +4095,9 @@ "c": " read only property with public getter and protected setter", "t": "source.groovy meta.definition.class.groovy meta.class.body.groovy comment.line.double-slash.groovy", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -4370,9 +4370,9 @@ "c": "//", "t": "source.groovy meta.definition.class.groovy meta.class.body.groovy comment.line.double-slash.groovy punctuation.definition.comment.groovy", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -4381,9 +4381,9 @@ "c": " dynamically typed property", "t": "source.groovy meta.definition.class.groovy meta.class.body.groovy comment.line.double-slash.groovy", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -4447,9 +4447,9 @@ "c": "/*", "t": "source.groovy comment.block.groovy punctuation.definition.comment.groovy", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -4458,9 +4458,9 @@ "c": " Logical Branching and Looping", "t": "source.groovy comment.block.groovy", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -4469,9 +4469,9 @@ "c": "*/", "t": "source.groovy comment.block.groovy punctuation.definition.comment.groovy", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -4480,9 +4480,9 @@ "c": "//", "t": "source.groovy comment.line.double-slash.groovy punctuation.definition.comment.groovy", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -4491,9 +4491,9 @@ "c": "Groovy supports the usual if - else syntax", "t": "source.groovy comment.line.double-slash.groovy", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -4964,9 +4964,9 @@ "c": "//", "t": "source.groovy comment.line.double-slash.groovy punctuation.definition.comment.groovy", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -4975,9 +4975,9 @@ "c": "Groovy also supports the ternary operator:", "t": "source.groovy comment.line.double-slash.groovy", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -5371,9 +5371,9 @@ "c": "//", "t": "source.groovy comment.line.double-slash.groovy punctuation.definition.comment.groovy", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -5382,9 +5382,9 @@ "c": "Groovy supports 'The Elvis Operator' too!", "t": "source.groovy comment.line.double-slash.groovy", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -5393,9 +5393,9 @@ "c": "//", "t": "source.groovy comment.line.double-slash.groovy punctuation.definition.comment.groovy", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -5404,9 +5404,9 @@ "c": "Instead of using the ternary operator:", "t": "source.groovy comment.line.double-slash.groovy", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -5569,9 +5569,9 @@ "c": "//", "t": "source.groovy comment.line.double-slash.groovy punctuation.definition.comment.groovy", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -5580,9 +5580,9 @@ "c": "We can write it:", "t": "source.groovy comment.line.double-slash.groovy", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -5701,9 +5701,9 @@ "c": "//", "t": "source.groovy comment.line.double-slash.groovy punctuation.definition.comment.groovy", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -5712,9 +5712,9 @@ "c": "For loop", "t": "source.groovy comment.line.double-slash.groovy", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -5723,9 +5723,9 @@ "c": "//", "t": "source.groovy comment.line.double-slash.groovy punctuation.definition.comment.groovy", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -5734,9 +5734,9 @@ "c": "Iterate over a range", "t": "source.groovy comment.line.double-slash.groovy", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -5987,9 +5987,9 @@ "c": "//", "t": "source.groovy comment.line.double-slash.groovy punctuation.definition.comment.groovy", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -5998,9 +5998,9 @@ "c": "Iterate over a list", "t": "source.groovy comment.line.double-slash.groovy", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -6262,9 +6262,9 @@ "c": "//", "t": "source.groovy comment.line.double-slash.groovy punctuation.definition.comment.groovy", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -6273,9 +6273,9 @@ "c": "Iterate over an array", "t": "source.groovy comment.line.double-slash.groovy", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -6548,9 +6548,9 @@ "c": "//", "t": "source.groovy comment.line.double-slash.groovy punctuation.definition.comment.groovy", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -6559,9 +6559,9 @@ "c": "Iterate over a map", "t": "source.groovy comment.line.double-slash.groovy", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -7384,9 +7384,9 @@ "c": "//", "t": "source.groovy comment.line.double-slash.groovy punctuation.definition.comment.groovy", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -7395,9 +7395,9 @@ "c": " = to technologies.collect { it?.toUpperCase() }", "t": "source.groovy comment.line.double-slash.groovy", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -8682,9 +8682,9 @@ "c": "//", "t": "source.groovy meta.definition.variable.groovy comment.line.double-slash.groovy punctuation.definition.comment.groovy", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -8693,9 +8693,9 @@ "c": " simulate some time consuming processing", "t": "source.groovy meta.definition.variable.groovy comment.line.double-slash.groovy", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -9375,9 +9375,9 @@ "c": "//", "t": "source.groovy comment.line.double-slash.groovy punctuation.definition.comment.groovy", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -9386,9 +9386,9 @@ "c": "Another example:", "t": "source.groovy comment.line.double-slash.groovy", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -9980,9 +9980,9 @@ "c": "//", "t": "source.groovy comment.line.double-slash.groovy punctuation.definition.comment.groovy", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -9991,9 +9991,9 @@ "c": "CompileStatic example:", "t": "source.groovy comment.line.double-slash.groovy", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } diff --git a/extensions/handlebars/test/colorize-results/test_hbs.json b/extensions/handlebars/test/colorize-results/test_hbs.json index 8774d4f3885..f818a57b51e 100644 --- a/extensions/handlebars/test/colorize-results/test_hbs.json +++ b/extensions/handlebars/test/colorize-results/test_hbs.json @@ -1059,9 +1059,9 @@ "c": "{{!-- only output author name if an author exists --}}", "t": "text.html.handlebars comment.block.handlebars", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } diff --git a/extensions/ini/test/colorize-results/test_ini.json b/extensions/ini/test/colorize-results/test_ini.json index 5b001c68246..39c089f5cef 100644 --- a/extensions/ini/test/colorize-results/test_ini.json +++ b/extensions/ini/test/colorize-results/test_ini.json @@ -3,9 +3,9 @@ "c": ";", "t": "source.ini comment.line.semicolon.ini punctuation.definition.comment.ini", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -14,9 +14,9 @@ "c": " last modified 1 April 2001 by John Doe", "t": "source.ini comment.line.semicolon.ini", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -157,9 +157,9 @@ "c": ";", "t": "source.ini comment.line.semicolon.ini punctuation.definition.comment.ini", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -168,9 +168,9 @@ "c": " use IP address in case network name resolution is not working", "t": "source.ini comment.line.semicolon.ini", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } diff --git a/extensions/java/test/colorize-results/basic_java.json b/extensions/java/test/colorize-results/basic_java.json index 665268f9e6a..ce736eb21d2 100644 --- a/extensions/java/test/colorize-results/basic_java.json +++ b/extensions/java/test/colorize-results/basic_java.json @@ -245,9 +245,9 @@ "c": "/*", "t": "source.java comment.block.java punctuation.definition.comment.java", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -256,9 +256,9 @@ "c": " * Multi line comment", "t": "source.java comment.block.java", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -267,9 +267,9 @@ "c": " ", "t": "source.java comment.block.java", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -278,9 +278,9 @@ "c": "*/", "t": "source.java comment.block.java punctuation.definition.comment.java", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -443,9 +443,9 @@ "c": "\t/**", "t": "source.java meta.class.java meta.class.body.java comment.block.javadoc.java punctuation.definition.comment.java", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -454,9 +454,9 @@ "c": "\t *

Note:

Hello", "t": "source.java meta.class.java meta.class.body.java comment.block.javadoc.java", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -465,9 +465,9 @@ "c": "\t * ", "t": "source.java meta.class.java meta.class.body.java comment.block.javadoc.java", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -487,9 +487,9 @@ "c": " ", "t": "source.java meta.class.java meta.class.body.java comment.block.javadoc.java", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -500,7 +500,7 @@ "r": { "dark_plus": "variable: #9CDCFE", "light_plus": "variable: #001080", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "variable: #9CDCFE" } @@ -509,9 +509,9 @@ "c": "\t ", "t": "source.java meta.class.java meta.class.body.java comment.block.javadoc.java", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -520,9 +520,9 @@ "c": "*/", "t": "source.java meta.class.java meta.class.body.java comment.block.javadoc.java punctuation.definition.comment.java", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -1004,9 +1004,9 @@ "c": "/*", "t": "source.java meta.class.java meta.class.body.java comment.block.java punctuation.definition.comment.java", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -1015,9 +1015,9 @@ "c": "\t * multiline comment", "t": "source.java meta.class.java meta.class.body.java comment.block.java", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -1026,9 +1026,9 @@ "c": "\t ", "t": "source.java meta.class.java meta.class.body.java comment.block.java", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -1037,9 +1037,9 @@ "c": "*/", "t": "source.java meta.class.java meta.class.body.java comment.block.java punctuation.definition.comment.java", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -1829,9 +1829,9 @@ "c": "//", "t": "source.java meta.class.java meta.class.body.java comment.line.double-slash.java punctuation.definition.comment.java", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -1840,9 +1840,9 @@ "c": "single line comment", "t": "source.java meta.class.java meta.class.body.java comment.line.double-slash.java", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } diff --git a/extensions/javascript/test/colorize-results/test_js.json b/extensions/javascript/test/colorize-results/test_js.json index 4a05d177de3..6ba00939cdf 100644 --- a/extensions/javascript/test/colorize-results/test_js.json +++ b/extensions/javascript/test/colorize-results/test_js.json @@ -3,9 +3,9 @@ "c": "/*", "t": "source.js comment.block.js punctuation.definition.comment.js", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -14,9 +14,9 @@ "c": "---------------------------------------------------------------------------------------------", "t": "source.js comment.block.js", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -25,9 +25,9 @@ "c": " * Copyright (c) Microsoft Corporation. All rights reserved.", "t": "source.js comment.block.js", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -36,9 +36,9 @@ "c": " * Licensed under the MIT License. See License.txt in the project root for license information.", "t": "source.js comment.block.js", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -47,9 +47,9 @@ "c": " *--------------------------------------------------------------------------------------------", "t": "source.js comment.block.js", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -58,9 +58,9 @@ "c": "*/", "t": "source.js comment.block.js punctuation.definition.comment.js", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } diff --git a/extensions/javascript/test/colorize-results/test_jsx.json b/extensions/javascript/test/colorize-results/test_jsx.json index a375d5d7b9d..cdd8b8cdfa4 100644 --- a/extensions/javascript/test/colorize-results/test_jsx.json +++ b/extensions/javascript/test/colorize-results/test_jsx.json @@ -520,9 +520,9 @@ "c": "//", "t": "source.js.jsx meta.var.expr.js.jsx meta.objectliteral.js.jsx meta.object.member.js.jsx meta.function.expression.js.jsx meta.block.js.jsx comment.line.double-slash.js.jsx punctuation.definition.comment.js.jsx", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -531,9 +531,9 @@ "c": " Prevent following the link.", "t": "source.js.jsx meta.var.expr.js.jsx meta.objectliteral.js.jsx meta.object.member.js.jsx meta.function.expression.js.jsx meta.block.js.jsx comment.line.double-slash.js.jsx", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -619,9 +619,9 @@ "c": "//", "t": "source.js.jsx meta.var.expr.js.jsx meta.objectliteral.js.jsx meta.object.member.js.jsx meta.function.expression.js.jsx meta.block.js.jsx comment.line.double-slash.js.jsx punctuation.definition.comment.js.jsx", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -630,9 +630,9 @@ "c": " Invert the chosen default.", "t": "source.js.jsx meta.var.expr.js.jsx meta.objectliteral.js.jsx meta.object.member.js.jsx meta.function.expression.js.jsx meta.block.js.jsx comment.line.double-slash.js.jsx", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -652,9 +652,9 @@ "c": "//", "t": "source.js.jsx meta.var.expr.js.jsx meta.objectliteral.js.jsx meta.object.member.js.jsx meta.function.expression.js.jsx meta.block.js.jsx comment.line.double-slash.js.jsx punctuation.definition.comment.js.jsx", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -663,9 +663,9 @@ "c": " This will trigger an intelligent re-render of the component.", "t": "source.js.jsx meta.var.expr.js.jsx meta.objectliteral.js.jsx meta.object.member.js.jsx meta.function.expression.js.jsx meta.block.js.jsx comment.line.double-slash.js.jsx", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -1037,9 +1037,9 @@ "c": "//", "t": "source.js.jsx meta.var.expr.js.jsx meta.objectliteral.js.jsx meta.object.member.js.jsx meta.function.expression.js.jsx meta.block.js.jsx comment.line.double-slash.js.jsx punctuation.definition.comment.js.jsx", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -1048,9 +1048,9 @@ "c": " Default to the default message.", "t": "source.js.jsx meta.var.expr.js.jsx meta.objectliteral.js.jsx meta.object.member.js.jsx meta.function.expression.js.jsx meta.block.js.jsx comment.line.double-slash.js.jsx", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -1213,9 +1213,9 @@ "c": "//", "t": "source.js.jsx meta.var.expr.js.jsx meta.objectliteral.js.jsx meta.object.member.js.jsx meta.function.expression.js.jsx meta.block.js.jsx comment.line.double-slash.js.jsx punctuation.definition.comment.js.jsx", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -1224,9 +1224,9 @@ "c": " If toggled, show the alternate message.", "t": "source.js.jsx meta.var.expr.js.jsx meta.objectliteral.js.jsx meta.object.member.js.jsx meta.function.expression.js.jsx meta.block.js.jsx comment.line.double-slash.js.jsx", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } diff --git a/extensions/json/test/colorize-results/test_json.json b/extensions/json/test/colorize-results/test_json.json index 19641069faa..75561c366d7 100644 --- a/extensions/json/test/colorize-results/test_json.json +++ b/extensions/json/test/colorize-results/test_json.json @@ -25,9 +25,9 @@ "c": "//", "t": "source.json meta.structure.dictionary.json comment.line.double-slash.js punctuation.definition.comment.json", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -36,9 +36,9 @@ "c": " a comment", "t": "source.json meta.structure.dictionary.json comment.line.double-slash.js", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } diff --git a/extensions/log/test/colorize-results/test_log.json b/extensions/log/test/colorize-results/test_log.json index 0b295cad127..2057a5b8764 100644 --- a/extensions/log/test/colorize-results/test_log.json +++ b/extensions/log/test/colorize-results/test_log.json @@ -14,9 +14,9 @@ "c": "2017-12-21", "t": "text.log comment log.date", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -36,9 +36,9 @@ "c": "12:47:29.584", "t": "text.log comment log.date", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -80,9 +80,9 @@ "c": "2017-12-21", "t": "text.log comment log.date", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -102,9 +102,9 @@ "c": "12:47:29.614", "t": "text.log comment log.date", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -135,9 +135,9 @@ "c": "2017-12-21", "t": "text.log comment log.date", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -157,9 +157,9 @@ "c": "12:47:29.632", "t": "text.log comment log.date", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -190,9 +190,9 @@ "c": "2017-12-21", "t": "text.log comment log.date", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -212,9 +212,9 @@ "c": "12:47:29.636", "t": "text.log comment log.date", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -245,9 +245,9 @@ "c": "2017-12-21", "t": "text.log comment log.date", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -267,9 +267,9 @@ "c": "12:47:32.164", "t": "text.log comment log.date", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -311,9 +311,9 @@ "c": "2017-12-21", "t": "text.log comment log.date", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -333,9 +333,9 @@ "c": "12:47:33.122", "t": "text.log comment log.date", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -377,9 +377,9 @@ "c": "2017-12-21", "t": "text.log comment log.date", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -399,9 +399,9 @@ "c": "12:47:34.249", "t": "text.log comment log.date", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -443,9 +443,9 @@ "c": "2017-12-21", "t": "text.log comment log.date", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -465,9 +465,9 @@ "c": "12:47:48.078", "t": "text.log comment log.date", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -509,9 +509,9 @@ "c": "2017-12-21", "t": "text.log comment log.date", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -531,9 +531,9 @@ "c": "12:47:49.294", "t": "text.log comment log.date", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } diff --git a/extensions/lua/test/colorize-results/test_lua.json b/extensions/lua/test/colorize-results/test_lua.json index c1495f2253e..21c3d794e5b 100644 --- a/extensions/lua/test/colorize-results/test_lua.json +++ b/extensions/lua/test/colorize-results/test_lua.json @@ -14,9 +14,9 @@ "c": "--", "t": "source.lua comment.line.double-dash.lua punctuation.definition.comment.lua", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -25,9 +25,9 @@ "c": " defines a factorial function", "t": "source.lua comment.line.double-dash.lua", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -608,9 +608,9 @@ "c": "--", "t": "source.lua comment.line.double-dash.lua punctuation.definition.comment.lua", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -619,9 +619,9 @@ "c": " read a number", "t": "source.lua comment.line.double-dash.lua", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } diff --git a/extensions/make/test/colorize-results/makefile.json b/extensions/make/test/colorize-results/makefile.json index 03fbc6814fb..6fbce98489a 100644 --- a/extensions/make/test/colorize-results/makefile.json +++ b/extensions/make/test/colorize-results/makefile.json @@ -300,9 +300,9 @@ "c": "#", "t": "source.makefile meta.scope.target.makefile meta.scope.prerequisites.makefile comment.line.number-sign.makefile punctuation.definition.comment.makefile", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -311,9 +311,9 @@ "c": " This is a long ", "t": "source.makefile meta.scope.target.makefile meta.scope.prerequisites.makefile comment.line.number-sign.makefile", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -324,7 +324,7 @@ "r": { "dark_plus": "constant.character.escape: #D7BA7D", "light_plus": "constant.character.escape: #FF0000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "constant.character: #569CD6" } @@ -333,9 +333,9 @@ "c": " comment inside prerequisites.", "t": "source.makefile meta.scope.target.makefile meta.scope.prerequisites.makefile comment.line.number-sign.makefile", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -355,9 +355,9 @@ "c": "#", "t": "source.makefile comment.line.number-sign.makefile punctuation.definition.comment.makefile", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -366,9 +366,9 @@ "c": " There are a building steps ", "t": "source.makefile comment.line.number-sign.makefile", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -379,7 +379,7 @@ "r": { "dark_plus": "constant.character.escape: #D7BA7D", "light_plus": "constant.character.escape: #FF0000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "constant.character: #569CD6" } @@ -388,9 +388,9 @@ "c": "\tbelow. And the tab is at the beginning of this line.", "t": "source.makefile comment.line.number-sign.makefile", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } diff --git a/extensions/objective-c/test/colorize-results/test_m.json b/extensions/objective-c/test/colorize-results/test_m.json index ed1bda084e3..691fe71e9a5 100644 --- a/extensions/objective-c/test/colorize-results/test_m.json +++ b/extensions/objective-c/test/colorize-results/test_m.json @@ -3,9 +3,9 @@ "c": "//", "t": "source.objc comment.line.double-slash.cpp punctuation.definition.comment.cpp", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -14,9 +14,9 @@ "c": "//", "t": "source.objc comment.line.double-slash.cpp punctuation.definition.comment.cpp", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -25,9 +25,9 @@ "c": " Copyright (c) Microsoft Corporation. All rights reserved.", "t": "source.objc comment.line.double-slash.cpp", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -36,9 +36,9 @@ "c": "//", "t": "source.objc comment.line.double-slash.cpp punctuation.definition.comment.cpp", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -179,9 +179,9 @@ "c": "/*", "t": "source.objc comment.block.c punctuation.definition.comment.begin.c", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -190,9 +190,9 @@ "c": "\tMulti", "t": "source.objc comment.block.c", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -201,9 +201,9 @@ "c": "\tLine", "t": "source.objc comment.block.c", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -212,9 +212,9 @@ "c": "\tComments", "t": "source.objc comment.block.c", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -223,9 +223,9 @@ "c": "*/", "t": "source.objc comment.block.c punctuation.definition.comment.end.c", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -2225,9 +2225,9 @@ "c": "//", "t": "source.objc meta.implementation.objc meta.scope.implementation.objc meta.function-with-body.objc meta.block.c comment.line.double-slash.cpp punctuation.definition.comment.cpp", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -2236,9 +2236,9 @@ "c": " add a tap gesture recognizer", "t": "source.objc meta.implementation.objc meta.scope.implementation.objc meta.function-with-body.objc meta.block.c comment.line.double-slash.cpp", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } diff --git a/extensions/perl/test/colorize-results/test_pl.json b/extensions/perl/test/colorize-results/test_pl.json index 7e575aa4652..ecfd9660ad8 100644 --- a/extensions/perl/test/colorize-results/test_pl.json +++ b/extensions/perl/test/colorize-results/test_pl.json @@ -278,9 +278,9 @@ "c": "#", "t": "source.perl comment.line.number-sign.perl punctuation.definition.comment.perl", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -289,9 +289,9 @@ "c": " Check for that =.", "t": "source.perl comment.line.number-sign.perl", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -1015,9 +1015,9 @@ "c": "#", "t": "source.perl comment.line.number-sign.perl punctuation.definition.comment.perl", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -1026,9 +1026,9 @@ "c": "#", "t": "source.perl comment.line.number-sign.perl punctuation.definition.comment.perl", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -1037,9 +1037,9 @@ "c": " This function opens and reads one file, and calls", "t": "source.perl comment.line.number-sign.perl", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -1048,9 +1048,9 @@ "c": "#", "t": "source.perl comment.line.number-sign.perl punctuation.definition.comment.perl", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -1059,9 +1059,9 @@ "c": " check_line to analyze each line. Call it with the", "t": "source.perl comment.line.number-sign.perl", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -1070,9 +1070,9 @@ "c": "#", "t": "source.perl comment.line.number-sign.perl punctuation.definition.comment.perl", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -1081,9 +1081,9 @@ "c": " file name.", "t": "source.perl comment.line.number-sign.perl", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -1092,9 +1092,9 @@ "c": "#", "t": "source.perl comment.line.number-sign.perl punctuation.definition.comment.perl", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -1939,9 +1939,9 @@ "c": "#", "t": "source.perl comment.line.number-sign.perl punctuation.definition.comment.perl", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -1950,9 +1950,9 @@ "c": "#", "t": "source.perl comment.line.number-sign.perl punctuation.definition.comment.perl", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -1961,9 +1961,9 @@ "c": " Go through the argument list and check each file", "t": "source.perl comment.line.number-sign.perl", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -1972,9 +1972,9 @@ "c": "#", "t": "source.perl comment.line.number-sign.perl punctuation.definition.comment.perl", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } diff --git a/extensions/powershell/test/colorize-results/test_ps1.json b/extensions/powershell/test/colorize-results/test_ps1.json index 15d677e1b95..fd82cda536b 100644 --- a/extensions/powershell/test/colorize-results/test_ps1.json +++ b/extensions/powershell/test/colorize-results/test_ps1.json @@ -3,9 +3,9 @@ "c": "#", "t": "source.powershell comment.line.powershell punctuation.definition.comment.powershell", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -14,9 +14,9 @@ "c": " Copyright Microsoft Corporation", "t": "source.powershell comment.line.powershell", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -1774,9 +1774,9 @@ "c": "#", "t": "source.powershell comment.line.powershell punctuation.definition.comment.powershell", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -1785,9 +1785,9 @@ "c": " PowerShell commands need elevation for dependencies installation and running tests", "t": "source.powershell comment.line.powershell", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } diff --git a/extensions/python/test/colorize-results/test_py.json b/extensions/python/test/colorize-results/test_py.json index 235958f078f..21d185717d4 100644 --- a/extensions/python/test/colorize-results/test_py.json +++ b/extensions/python/test/colorize-results/test_py.json @@ -113,9 +113,9 @@ "c": "#", "t": "source.python comment.line.number-sign.python punctuation.definition.comment.python", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -124,9 +124,9 @@ "c": " Bananas the monkey can eat.", "t": "source.python comment.line.number-sign.python", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -1906,9 +1906,9 @@ "c": "#", "t": "source.python comment.line.number-sign.python punctuation.definition.comment.python", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -1917,9 +1917,9 @@ "c": " Looks like a valid date", "t": "source.python comment.line.number-sign.python", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -3017,9 +3017,9 @@ "c": "#", "t": "source.python comment.line.number-sign.python punctuation.definition.comment.python", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -3028,9 +3028,9 @@ "c": "comment", "t": "source.python comment.line.number-sign.python", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -3149,9 +3149,9 @@ "c": "#", "t": "source.python comment.line.number-sign.python punctuation.definition.comment.python", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -3160,9 +3160,9 @@ "c": "sqadsad", "t": "source.python comment.line.number-sign.python", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -6108,9 +6108,9 @@ "c": "#", "t": "source.python comment.line.number-sign.python punctuation.definition.comment.python", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -6119,9 +6119,9 @@ "c": " Comments in dictionary items should be colorized accordingly", "t": "source.python comment.line.number-sign.python", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -6262,9 +6262,9 @@ "c": "#", "t": "source.python comment.line.number-sign.python punctuation.definition.comment.python", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -6273,9 +6273,9 @@ "c": " this should be colorized as comment", "t": "source.python comment.line.number-sign.python", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -6383,9 +6383,9 @@ "c": "#", "t": "source.python comment.line.number-sign.python punctuation.definition.comment.python", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -6394,9 +6394,9 @@ "c": "this should be colorized as comment", "t": "source.python comment.line.number-sign.python", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -6416,9 +6416,9 @@ "c": "#", "t": "source.python comment.line.number-sign.python punctuation.definition.comment.python", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -6427,9 +6427,9 @@ "c": " test raw strings", "t": "source.python comment.line.number-sign.python", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -6581,9 +6581,9 @@ "c": "#", "t": "source.python comment.line.number-sign.python punctuation.definition.comment.python", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -6592,9 +6592,9 @@ "c": " highlight doctests", "t": "source.python comment.line.number-sign.python", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } diff --git a/extensions/r/test/colorize-results/test_r.json b/extensions/r/test/colorize-results/test_r.json index d9dfb68a0e5..2cba70d079b 100644 --- a/extensions/r/test/colorize-results/test_r.json +++ b/extensions/r/test/colorize-results/test_r.json @@ -3,9 +3,9 @@ "c": "#", "t": "source.r comment.line.number-sign.r punctuation.definition.comment.r", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -14,9 +14,9 @@ "c": " © Microsoft. All rights reserved.", "t": "source.r comment.line.number-sign.r", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -25,9 +25,9 @@ "c": "#'", "t": "source.r comment.line.roxygen.r punctuation.definition.comment.r", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -36,9 +36,9 @@ "c": " Add together two numbers.", "t": "source.r comment.line.roxygen.r", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -47,9 +47,9 @@ "c": "#'", "t": "source.r comment.line.roxygen.r punctuation.definition.comment.r", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -58,9 +58,9 @@ "c": "#'", "t": "source.r comment.line.roxygen.r punctuation.definition.comment.r", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -69,9 +69,9 @@ "c": " ", "t": "source.r comment.line.roxygen.r", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -91,9 +91,9 @@ "c": " ", "t": "source.r comment.line.roxygen.r", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -104,7 +104,7 @@ "r": { "dark_plus": "variable: #9CDCFE", "light_plus": "variable: #001080", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "variable: #9CDCFE" } @@ -113,9 +113,9 @@ "c": " A number.", "t": "source.r comment.line.roxygen.r", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -124,9 +124,9 @@ "c": "#'", "t": "source.r comment.line.roxygen.r punctuation.definition.comment.r", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -135,9 +135,9 @@ "c": " ", "t": "source.r comment.line.roxygen.r", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -157,9 +157,9 @@ "c": " ", "t": "source.r comment.line.roxygen.r", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -170,7 +170,7 @@ "r": { "dark_plus": "variable: #9CDCFE", "light_plus": "variable: #001080", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "variable: #9CDCFE" } @@ -179,9 +179,9 @@ "c": " A number.", "t": "source.r comment.line.roxygen.r", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -190,9 +190,9 @@ "c": "#'", "t": "source.r comment.line.roxygen.r punctuation.definition.comment.r", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -201,9 +201,9 @@ "c": " ", "t": "source.r comment.line.roxygen.r", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -223,9 +223,9 @@ "c": " The sum of \\code{x} and \\code{y}.", "t": "source.r comment.line.roxygen.r", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -234,9 +234,9 @@ "c": "#'", "t": "source.r comment.line.roxygen.r punctuation.definition.comment.r", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -245,9 +245,9 @@ "c": " ", "t": "source.r comment.line.roxygen.r", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -267,9 +267,9 @@ "c": "#'", "t": "source.r comment.line.roxygen.r punctuation.definition.comment.r", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -278,9 +278,9 @@ "c": " add(1, 1)", "t": "source.r comment.line.roxygen.r", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -289,9 +289,9 @@ "c": "#'", "t": "source.r comment.line.roxygen.r punctuation.definition.comment.r", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -300,9 +300,9 @@ "c": " add(10, 1)", "t": "source.r comment.line.roxygen.r", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } diff --git a/extensions/razor/test/colorize-results/test_cshtml.json b/extensions/razor/test/colorize-results/test_cshtml.json index a0988149bbf..37e1a3d66d1 100644 --- a/extensions/razor/test/colorize-results/test_cshtml.json +++ b/extensions/razor/test/colorize-results/test_cshtml.json @@ -531,9 +531,9 @@ "c": "//", "t": "text.html.cshtml comment.line.double-slash.cs punctuation.definition.comment.cs", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -542,9 +542,9 @@ "c": " Retrieve the numbers that the user entered.", "t": "text.html.cshtml comment.line.double-slash.cs", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -872,9 +872,9 @@ "c": "//", "t": "text.html.cshtml comment.line.double-slash.cs punctuation.definition.comment.cs", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -883,9 +883,9 @@ "c": " Convert the entered strings into integers numbers and add.", "t": "text.html.cshtml comment.line.double-slash.cs", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -1409,7 +1409,7 @@ }, { "c": "", - "t": "text.html.cshtml meta.tag.sgml.html punctuation.definition.tag.html", - "r": { - "dark_plus": "punctuation.definition.tag: #808080", - "light_plus": "punctuation.definition.tag: #800000", - "dark_vs": "punctuation.definition.tag: #808080", - "light_vs": "punctuation.definition.tag: #800000", - "hc_black": "punctuation.definition.tag: #808080" - } - }, - { - "c": "<", - "t": "text.html.cshtml meta.tag.structure.any.html punctuation.definition.tag.html", - "r": { - "dark_plus": "punctuation.definition.tag: #808080", - "light_plus": "punctuation.definition.tag: #800000", - "dark_vs": "punctuation.definition.tag: #808080", - "light_vs": "punctuation.definition.tag: #800000", - "hc_black": "punctuation.definition.tag: #808080" - } - }, - { - "c": "html", - "t": "text.html.cshtml meta.tag.structure.any.html entity.name.tag.structure.any.html", + "c": "DOCTYPE", + "t": "text.html.cshtml meta.tag.metadata.doctype.html entity.name.tag.html", "r": { "dark_plus": "entity.name.tag: #569CD6", "light_plus": "entity.name.tag: #800000", @@ -1464,7 +1431,62 @@ }, { "c": " ", - "t": "text.html.cshtml meta.tag.structure.any.html", + "t": "text.html.cshtml meta.tag.metadata.doctype.html", + "r": { + "dark_plus": "default: #D4D4D4", + "light_plus": "default: #000000", + "dark_vs": "default: #D4D4D4", + "light_vs": "default: #000000", + "hc_black": "default: #FFFFFF" + } + }, + { + "c": "html", + "t": "text.html.cshtml meta.tag.metadata.doctype.html entity.other.attribute-name.html", + "r": { + "dark_plus": "entity.other.attribute-name: #9CDCFE", + "light_plus": "entity.other.attribute-name: #FF0000", + "dark_vs": "entity.other.attribute-name: #9CDCFE", + "light_vs": "entity.other.attribute-name: #FF0000", + "hc_black": "entity.other.attribute-name: #9CDCFE" + } + }, + { + "c": ">", + "t": "text.html.cshtml meta.tag.metadata.doctype.html punctuation.definition.tag.end.html", + "r": { + "dark_plus": "punctuation.definition.tag: #808080", + "light_plus": "punctuation.definition.tag: #800000", + "dark_vs": "punctuation.definition.tag: #808080", + "light_vs": "punctuation.definition.tag: #800000", + "hc_black": "punctuation.definition.tag: #808080" + } + }, + { + "c": "<", + "t": "text.html.cshtml meta.tag.structure.html.start.html punctuation.definition.tag.begin.html", + "r": { + "dark_plus": "punctuation.definition.tag: #808080", + "light_plus": "punctuation.definition.tag: #800000", + "dark_vs": "punctuation.definition.tag: #808080", + "light_vs": "punctuation.definition.tag: #800000", + "hc_black": "punctuation.definition.tag: #808080" + } + }, + { + "c": "html", + "t": "text.html.cshtml meta.tag.structure.html.start.html entity.name.tag.html", + "r": { + "dark_plus": "entity.name.tag: #569CD6", + "light_plus": "entity.name.tag: #800000", + "dark_vs": "entity.name.tag: #569CD6", + "light_vs": "entity.name.tag: #800000", + "hc_black": "entity.name.tag: #569CD6" + } + }, + { + "c": " ", + "t": "text.html.cshtml meta.tag.structure.html.start.html", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -1475,7 +1497,7 @@ }, { "c": "lang", - "t": "text.html.cshtml meta.tag.structure.any.html entity.other.attribute-name.html", + "t": "text.html.cshtml meta.tag.structure.html.start.html meta.attribute.lang.html entity.other.attribute-name.html", "r": { "dark_plus": "entity.other.attribute-name: #9CDCFE", "light_plus": "entity.other.attribute-name: #FF0000", @@ -1486,7 +1508,7 @@ }, { "c": "=", - "t": "text.html.cshtml meta.tag.structure.any.html", + "t": "text.html.cshtml meta.tag.structure.html.start.html meta.attribute.lang.html punctuation.separator.key-value.html", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -1497,7 +1519,7 @@ }, { "c": "\"", - "t": "text.html.cshtml meta.tag.structure.any.html string.quoted.double.html punctuation.definition.string.begin.html", + "t": "text.html.cshtml meta.tag.structure.html.start.html meta.attribute.lang.html string.quoted.double.html punctuation.definition.string.begin.html", "r": { "dark_plus": "string: #CE9178", "light_plus": "string.quoted.double.html: #0000FF", @@ -1508,7 +1530,7 @@ }, { "c": "en", - "t": "text.html.cshtml meta.tag.structure.any.html string.quoted.double.html", + "t": "text.html.cshtml meta.tag.structure.html.start.html meta.attribute.lang.html string.quoted.double.html", "r": { "dark_plus": "string: #CE9178", "light_plus": "string.quoted.double.html: #0000FF", @@ -1519,7 +1541,7 @@ }, { "c": "\"", - "t": "text.html.cshtml meta.tag.structure.any.html string.quoted.double.html punctuation.definition.string.end.html", + "t": "text.html.cshtml meta.tag.structure.html.start.html meta.attribute.lang.html string.quoted.double.html punctuation.definition.string.end.html", "r": { "dark_plus": "string: #CE9178", "light_plus": "string.quoted.double.html: #0000FF", @@ -1530,7 +1552,7 @@ }, { "c": ">", - "t": "text.html.cshtml meta.tag.structure.any.html punctuation.definition.tag.html", + "t": "text.html.cshtml meta.tag.structure.html.start.html punctuation.definition.tag.end.html", "r": { "dark_plus": "punctuation.definition.tag: #808080", "light_plus": "punctuation.definition.tag: #800000", @@ -1552,7 +1574,7 @@ }, { "c": "<", - "t": "text.html.cshtml meta.tag.structure.any.html punctuation.definition.tag.html", + "t": "text.html.cshtml meta.tag.structure.head.start.html punctuation.definition.tag.begin.html", "r": { "dark_plus": "punctuation.definition.tag: #808080", "light_plus": "punctuation.definition.tag: #800000", @@ -1563,7 +1585,7 @@ }, { "c": "head", - "t": "text.html.cshtml meta.tag.structure.any.html entity.name.tag.structure.any.html", + "t": "text.html.cshtml meta.tag.structure.head.start.html entity.name.tag.html", "r": { "dark_plus": "entity.name.tag: #569CD6", "light_plus": "entity.name.tag: #800000", @@ -1574,7 +1596,7 @@ }, { "c": ">", - "t": "text.html.cshtml meta.tag.structure.any.html punctuation.definition.tag.html", + "t": "text.html.cshtml meta.tag.structure.head.start.html punctuation.definition.tag.end.html", "r": { "dark_plus": "punctuation.definition.tag: #808080", "light_plus": "punctuation.definition.tag: #800000", @@ -1596,7 +1618,7 @@ }, { "c": "<", - "t": "text.html.cshtml meta.tag.inline.any.html punctuation.definition.tag.begin.html", + "t": "text.html.cshtml meta.tag.metadata.title.start.html punctuation.definition.tag.begin.html", "r": { "dark_plus": "punctuation.definition.tag: #808080", "light_plus": "punctuation.definition.tag: #800000", @@ -1607,7 +1629,7 @@ }, { "c": "title", - "t": "text.html.cshtml meta.tag.inline.any.html entity.name.tag.inline.any.html", + "t": "text.html.cshtml meta.tag.metadata.title.start.html entity.name.tag.html", "r": { "dark_plus": "entity.name.tag: #569CD6", "light_plus": "entity.name.tag: #800000", @@ -1618,7 +1640,7 @@ }, { "c": ">", - "t": "text.html.cshtml meta.tag.inline.any.html punctuation.definition.tag.end.html", + "t": "text.html.cshtml meta.tag.metadata.title.start.html punctuation.definition.tag.end.html", "r": { "dark_plus": "punctuation.definition.tag: #808080", "light_plus": "punctuation.definition.tag: #800000", @@ -1640,7 +1662,7 @@ }, { "c": "", - "t": "text.html.cshtml meta.tag.inline.any.html punctuation.definition.tag.end.html", + "t": "text.html.cshtml meta.tag.metadata.title.end.html punctuation.definition.tag.end.html", "r": { "dark_plus": "punctuation.definition.tag: #808080", "light_plus": "punctuation.definition.tag: #800000", @@ -1684,7 +1706,7 @@ }, { "c": "<", - "t": "text.html.cshtml meta.tag.inline.any.html punctuation.definition.tag.begin.html", + "t": "text.html.cshtml meta.tag.metadata.meta.void.html punctuation.definition.tag.begin.html", "r": { "dark_plus": "punctuation.definition.tag: #808080", "light_plus": "punctuation.definition.tag: #800000", @@ -1695,7 +1717,7 @@ }, { "c": "meta", - "t": "text.html.cshtml meta.tag.inline.any.html entity.name.tag.inline.any.html", + "t": "text.html.cshtml meta.tag.metadata.meta.void.html entity.name.tag.html", "r": { "dark_plus": "entity.name.tag: #569CD6", "light_plus": "entity.name.tag: #800000", @@ -1706,7 +1728,7 @@ }, { "c": " ", - "t": "text.html.cshtml meta.tag.inline.any.html", + "t": "text.html.cshtml meta.tag.metadata.meta.void.html", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -1717,7 +1739,7 @@ }, { "c": "charset", - "t": "text.html.cshtml meta.tag.inline.any.html entity.other.attribute-name.html", + "t": "text.html.cshtml meta.tag.metadata.meta.void.html meta.attribute.charset.html entity.other.attribute-name.html", "r": { "dark_plus": "entity.other.attribute-name: #9CDCFE", "light_plus": "entity.other.attribute-name: #FF0000", @@ -1728,7 +1750,7 @@ }, { "c": "=", - "t": "text.html.cshtml meta.tag.inline.any.html", + "t": "text.html.cshtml meta.tag.metadata.meta.void.html meta.attribute.charset.html punctuation.separator.key-value.html", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -1739,7 +1761,7 @@ }, { "c": "\"", - "t": "text.html.cshtml meta.tag.inline.any.html string.quoted.double.html punctuation.definition.string.begin.html", + "t": "text.html.cshtml meta.tag.metadata.meta.void.html meta.attribute.charset.html string.quoted.double.html punctuation.definition.string.begin.html", "r": { "dark_plus": "string: #CE9178", "light_plus": "string.quoted.double.html: #0000FF", @@ -1750,7 +1772,7 @@ }, { "c": "utf-8", - "t": "text.html.cshtml meta.tag.inline.any.html string.quoted.double.html", + "t": "text.html.cshtml meta.tag.metadata.meta.void.html meta.attribute.charset.html string.quoted.double.html", "r": { "dark_plus": "string: #CE9178", "light_plus": "string.quoted.double.html: #0000FF", @@ -1761,7 +1783,7 @@ }, { "c": "\"", - "t": "text.html.cshtml meta.tag.inline.any.html string.quoted.double.html punctuation.definition.string.end.html", + "t": "text.html.cshtml meta.tag.metadata.meta.void.html meta.attribute.charset.html string.quoted.double.html punctuation.definition.string.end.html", "r": { "dark_plus": "string: #CE9178", "light_plus": "string.quoted.double.html: #0000FF", @@ -1771,8 +1793,19 @@ } }, { - "c": " />", - "t": "text.html.cshtml meta.tag.inline.any.html punctuation.definition.tag.end.html", + "c": " ", + "t": "text.html.cshtml meta.tag.metadata.meta.void.html", + "r": { + "dark_plus": "default: #D4D4D4", + "light_plus": "default: #000000", + "dark_vs": "default: #D4D4D4", + "light_vs": "default: #000000", + "hc_black": "default: #FFFFFF" + } + }, + { + "c": "/>", + "t": "text.html.cshtml meta.tag.metadata.meta.void.html punctuation.definition.tag.end.html", "r": { "dark_plus": "punctuation.definition.tag: #808080", "light_plus": "punctuation.definition.tag: #800000", @@ -1794,7 +1827,7 @@ }, { "c": "", - "t": "text.html.cshtml meta.tag.structure.any.html punctuation.definition.tag.html", + "t": "text.html.cshtml meta.tag.structure.head.end.html punctuation.definition.tag.end.html", "r": { "dark_plus": "punctuation.definition.tag: #808080", "light_plus": "punctuation.definition.tag: #800000", @@ -1827,7 +1860,7 @@ }, { "c": "<", - "t": "text.html.cshtml meta.tag.structure.any.html punctuation.definition.tag.html", + "t": "text.html.cshtml meta.tag.structure.body.start.html punctuation.definition.tag.begin.html", "r": { "dark_plus": "punctuation.definition.tag: #808080", "light_plus": "punctuation.definition.tag: #800000", @@ -1838,7 +1871,7 @@ }, { "c": "body", - "t": "text.html.cshtml meta.tag.structure.any.html entity.name.tag.structure.any.html", + "t": "text.html.cshtml meta.tag.structure.body.start.html entity.name.tag.html", "r": { "dark_plus": "entity.name.tag: #569CD6", "light_plus": "entity.name.tag: #800000", @@ -1849,7 +1882,7 @@ }, { "c": ">", - "t": "text.html.cshtml meta.tag.structure.any.html punctuation.definition.tag.html", + "t": "text.html.cshtml meta.tag.structure.body.start.html punctuation.definition.tag.end.html", "r": { "dark_plus": "punctuation.definition.tag: #808080", "light_plus": "punctuation.definition.tag: #800000", @@ -1871,7 +1904,7 @@ }, { "c": "<", - "t": "text.html.cshtml meta.tag.block.any.html punctuation.definition.tag.begin.html", + "t": "text.html.cshtml meta.tag.structure.p.start.html punctuation.definition.tag.begin.html", "r": { "dark_plus": "punctuation.definition.tag: #808080", "light_plus": "punctuation.definition.tag: #800000", @@ -1882,7 +1915,7 @@ }, { "c": "p", - "t": "text.html.cshtml meta.tag.block.any.html entity.name.tag.block.any.html", + "t": "text.html.cshtml meta.tag.structure.p.start.html entity.name.tag.html", "r": { "dark_plus": "entity.name.tag: #569CD6", "light_plus": "entity.name.tag: #800000", @@ -1893,7 +1926,7 @@ }, { "c": ">", - "t": "text.html.cshtml meta.tag.block.any.html punctuation.definition.tag.end.html", + "t": "text.html.cshtml meta.tag.structure.p.start.html punctuation.definition.tag.end.html", "r": { "dark_plus": "punctuation.definition.tag: #808080", "light_plus": "punctuation.definition.tag: #800000", @@ -1915,7 +1948,7 @@ }, { "c": "<", - "t": "text.html.cshtml meta.tag.inline.any.html punctuation.definition.tag.begin.html", + "t": "text.html.cshtml meta.tag.inline.strong.start.html punctuation.definition.tag.begin.html", "r": { "dark_plus": "punctuation.definition.tag: #808080", "light_plus": "punctuation.definition.tag: #800000", @@ -1926,7 +1959,7 @@ }, { "c": "strong", - "t": "text.html.cshtml meta.tag.inline.any.html entity.name.tag.inline.any.html", + "t": "text.html.cshtml meta.tag.inline.strong.start.html entity.name.tag.html", "r": { "dark_plus": "entity.name.tag: #569CD6", "light_plus": "entity.name.tag: #800000", @@ -1937,7 +1970,7 @@ }, { "c": ">", - "t": "text.html.cshtml meta.tag.inline.any.html punctuation.definition.tag.end.html", + "t": "text.html.cshtml meta.tag.inline.strong.start.html punctuation.definition.tag.end.html", "r": { "dark_plus": "punctuation.definition.tag: #808080", "light_plus": "punctuation.definition.tag: #800000", @@ -1959,7 +1992,7 @@ }, { "c": "", - "t": "text.html.cshtml meta.tag.inline.any.html punctuation.definition.tag.end.html", + "t": "text.html.cshtml meta.tag.inline.strong.end.html punctuation.definition.tag.end.html", "r": { "dark_plus": "punctuation.definition.tag: #808080", "light_plus": "punctuation.definition.tag: #800000", @@ -2003,7 +2036,7 @@ }, { "c": "", - "t": "text.html.cshtml meta.tag.block.any.html punctuation.definition.tag.end.html", + "t": "text.html.cshtml meta.tag.structure.p.end.html punctuation.definition.tag.end.html", "r": { "dark_plus": "punctuation.definition.tag: #808080", "light_plus": "punctuation.definition.tag: #800000", @@ -2047,7 +2080,7 @@ }, { "c": "<", - "t": "text.html.cshtml meta.tag.block.any.html punctuation.definition.tag.begin.html", + "t": "text.html.cshtml meta.tag.structure.form.start.html punctuation.definition.tag.begin.html", "r": { "dark_plus": "punctuation.definition.tag: #808080", "light_plus": "punctuation.definition.tag: #800000", @@ -2058,7 +2091,7 @@ }, { "c": "form", - "t": "text.html.cshtml meta.tag.block.any.html entity.name.tag.block.any.html", + "t": "text.html.cshtml meta.tag.structure.form.start.html entity.name.tag.html", "r": { "dark_plus": "entity.name.tag: #569CD6", "light_plus": "entity.name.tag: #800000", @@ -2069,7 +2102,7 @@ }, { "c": " ", - "t": "text.html.cshtml meta.tag.block.any.html", + "t": "text.html.cshtml meta.tag.structure.form.start.html", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -2080,7 +2113,7 @@ }, { "c": "action", - "t": "text.html.cshtml meta.tag.block.any.html entity.other.attribute-name.html", + "t": "text.html.cshtml meta.tag.structure.form.start.html meta.attribute.action.html entity.other.attribute-name.html", "r": { "dark_plus": "entity.other.attribute-name: #9CDCFE", "light_plus": "entity.other.attribute-name: #FF0000", @@ -2091,7 +2124,7 @@ }, { "c": "=", - "t": "text.html.cshtml meta.tag.block.any.html", + "t": "text.html.cshtml meta.tag.structure.form.start.html meta.attribute.action.html punctuation.separator.key-value.html", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -2102,7 +2135,7 @@ }, { "c": "\"", - "t": "text.html.cshtml meta.tag.block.any.html string.quoted.double.html punctuation.definition.string.begin.html", + "t": "text.html.cshtml meta.tag.structure.form.start.html meta.attribute.action.html string.quoted.double.html punctuation.definition.string.begin.html", "r": { "dark_plus": "string: #CE9178", "light_plus": "string.quoted.double.html: #0000FF", @@ -2113,7 +2146,7 @@ }, { "c": "\"", - "t": "text.html.cshtml meta.tag.block.any.html string.quoted.double.html punctuation.definition.string.end.html", + "t": "text.html.cshtml meta.tag.structure.form.start.html meta.attribute.action.html string.quoted.double.html punctuation.definition.string.end.html", "r": { "dark_plus": "string: #CE9178", "light_plus": "string.quoted.double.html: #0000FF", @@ -2124,7 +2157,7 @@ }, { "c": " ", - "t": "text.html.cshtml meta.tag.block.any.html", + "t": "text.html.cshtml meta.tag.structure.form.start.html", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -2135,7 +2168,7 @@ }, { "c": "method", - "t": "text.html.cshtml meta.tag.block.any.html entity.other.attribute-name.html", + "t": "text.html.cshtml meta.tag.structure.form.start.html meta.attribute.method.html entity.other.attribute-name.html", "r": { "dark_plus": "entity.other.attribute-name: #9CDCFE", "light_plus": "entity.other.attribute-name: #FF0000", @@ -2146,7 +2179,7 @@ }, { "c": "=", - "t": "text.html.cshtml meta.tag.block.any.html", + "t": "text.html.cshtml meta.tag.structure.form.start.html meta.attribute.method.html punctuation.separator.key-value.html", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -2157,7 +2190,7 @@ }, { "c": "\"", - "t": "text.html.cshtml meta.tag.block.any.html string.quoted.double.html punctuation.definition.string.begin.html", + "t": "text.html.cshtml meta.tag.structure.form.start.html meta.attribute.method.html string.quoted.double.html punctuation.definition.string.begin.html", "r": { "dark_plus": "string: #CE9178", "light_plus": "string.quoted.double.html: #0000FF", @@ -2168,7 +2201,7 @@ }, { "c": "post", - "t": "text.html.cshtml meta.tag.block.any.html string.quoted.double.html", + "t": "text.html.cshtml meta.tag.structure.form.start.html meta.attribute.method.html string.quoted.double.html", "r": { "dark_plus": "string: #CE9178", "light_plus": "string.quoted.double.html: #0000FF", @@ -2179,7 +2212,7 @@ }, { "c": "\"", - "t": "text.html.cshtml meta.tag.block.any.html string.quoted.double.html punctuation.definition.string.end.html", + "t": "text.html.cshtml meta.tag.structure.form.start.html meta.attribute.method.html string.quoted.double.html punctuation.definition.string.end.html", "r": { "dark_plus": "string: #CE9178", "light_plus": "string.quoted.double.html: #0000FF", @@ -2190,7 +2223,7 @@ }, { "c": ">", - "t": "text.html.cshtml meta.tag.block.any.html punctuation.definition.tag.end.html", + "t": "text.html.cshtml meta.tag.structure.form.start.html punctuation.definition.tag.end.html", "r": { "dark_plus": "punctuation.definition.tag: #808080", "light_plus": "punctuation.definition.tag: #800000", @@ -2212,7 +2245,7 @@ }, { "c": "<", - "t": "text.html.cshtml meta.tag.block.any.html punctuation.definition.tag.begin.html", + "t": "text.html.cshtml meta.tag.structure.p.start.html punctuation.definition.tag.begin.html", "r": { "dark_plus": "punctuation.definition.tag: #808080", "light_plus": "punctuation.definition.tag: #800000", @@ -2223,7 +2256,7 @@ }, { "c": "p", - "t": "text.html.cshtml meta.tag.block.any.html entity.name.tag.block.any.html", + "t": "text.html.cshtml meta.tag.structure.p.start.html entity.name.tag.html", "r": { "dark_plus": "entity.name.tag: #569CD6", "light_plus": "entity.name.tag: #800000", @@ -2234,7 +2267,7 @@ }, { "c": ">", - "t": "text.html.cshtml meta.tag.block.any.html punctuation.definition.tag.end.html", + "t": "text.html.cshtml meta.tag.structure.p.start.html punctuation.definition.tag.end.html", "r": { "dark_plus": "punctuation.definition.tag: #808080", "light_plus": "punctuation.definition.tag: #800000", @@ -2245,7 +2278,7 @@ }, { "c": "<", - "t": "text.html.cshtml meta.tag.inline.any.html punctuation.definition.tag.begin.html", + "t": "text.html.cshtml meta.tag.structure.label.start.html punctuation.definition.tag.begin.html", "r": { "dark_plus": "punctuation.definition.tag: #808080", "light_plus": "punctuation.definition.tag: #800000", @@ -2256,7 +2289,7 @@ }, { "c": "label", - "t": "text.html.cshtml meta.tag.inline.any.html entity.name.tag.inline.any.html", + "t": "text.html.cshtml meta.tag.structure.label.start.html entity.name.tag.html", "r": { "dark_plus": "entity.name.tag: #569CD6", "light_plus": "entity.name.tag: #800000", @@ -2267,7 +2300,7 @@ }, { "c": " ", - "t": "text.html.cshtml meta.tag.inline.any.html", + "t": "text.html.cshtml meta.tag.structure.label.start.html", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -2278,7 +2311,7 @@ }, { "c": "for", - "t": "text.html.cshtml meta.tag.inline.any.html entity.other.attribute-name.html", + "t": "text.html.cshtml meta.tag.structure.label.start.html meta.attribute.for.html entity.other.attribute-name.html", "r": { "dark_plus": "entity.other.attribute-name: #9CDCFE", "light_plus": "entity.other.attribute-name: #FF0000", @@ -2289,7 +2322,7 @@ }, { "c": "=", - "t": "text.html.cshtml meta.tag.inline.any.html", + "t": "text.html.cshtml meta.tag.structure.label.start.html meta.attribute.for.html punctuation.separator.key-value.html", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -2300,7 +2333,7 @@ }, { "c": "\"", - "t": "text.html.cshtml meta.tag.inline.any.html string.quoted.double.html punctuation.definition.string.begin.html", + "t": "text.html.cshtml meta.tag.structure.label.start.html meta.attribute.for.html string.quoted.double.html punctuation.definition.string.begin.html", "r": { "dark_plus": "string: #CE9178", "light_plus": "string.quoted.double.html: #0000FF", @@ -2311,7 +2344,7 @@ }, { "c": "text1", - "t": "text.html.cshtml meta.tag.inline.any.html string.quoted.double.html", + "t": "text.html.cshtml meta.tag.structure.label.start.html meta.attribute.for.html string.quoted.double.html", "r": { "dark_plus": "string: #CE9178", "light_plus": "string.quoted.double.html: #0000FF", @@ -2322,7 +2355,7 @@ }, { "c": "\"", - "t": "text.html.cshtml meta.tag.inline.any.html string.quoted.double.html punctuation.definition.string.end.html", + "t": "text.html.cshtml meta.tag.structure.label.start.html meta.attribute.for.html string.quoted.double.html punctuation.definition.string.end.html", "r": { "dark_plus": "string: #CE9178", "light_plus": "string.quoted.double.html: #0000FF", @@ -2333,7 +2366,7 @@ }, { "c": ">", - "t": "text.html.cshtml meta.tag.inline.any.html punctuation.definition.tag.end.html", + "t": "text.html.cshtml meta.tag.structure.label.start.html punctuation.definition.tag.end.html", "r": { "dark_plus": "punctuation.definition.tag: #808080", "light_plus": "punctuation.definition.tag: #800000", @@ -2355,7 +2388,7 @@ }, { "c": "", - "t": "text.html.cshtml meta.tag.inline.any.html punctuation.definition.tag.end.html", + "t": "text.html.cshtml meta.tag.structure.label.end.html punctuation.definition.tag.end.html", "r": { "dark_plus": "punctuation.definition.tag: #808080", "light_plus": "punctuation.definition.tag: #800000", @@ -2399,7 +2432,7 @@ }, { "c": "<", - "t": "text.html.cshtml meta.tag.inline.any.html punctuation.definition.tag.begin.html", + "t": "text.html.cshtml meta.tag.structure.input.void.html punctuation.definition.tag.begin.html", "r": { "dark_plus": "punctuation.definition.tag: #808080", "light_plus": "punctuation.definition.tag: #800000", @@ -2410,7 +2443,7 @@ }, { "c": "input", - "t": "text.html.cshtml meta.tag.inline.any.html entity.name.tag.inline.any.html", + "t": "text.html.cshtml meta.tag.structure.input.void.html entity.name.tag.html", "r": { "dark_plus": "entity.name.tag: #569CD6", "light_plus": "entity.name.tag: #800000", @@ -2421,7 +2454,7 @@ }, { "c": " ", - "t": "text.html.cshtml meta.tag.inline.any.html", + "t": "text.html.cshtml meta.tag.structure.input.void.html", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -2432,7 +2465,7 @@ }, { "c": "type", - "t": "text.html.cshtml meta.tag.inline.any.html entity.other.attribute-name.html", + "t": "text.html.cshtml meta.tag.structure.input.void.html meta.attribute.type.html entity.other.attribute-name.html", "r": { "dark_plus": "entity.other.attribute-name: #9CDCFE", "light_plus": "entity.other.attribute-name: #FF0000", @@ -2443,7 +2476,7 @@ }, { "c": "=", - "t": "text.html.cshtml meta.tag.inline.any.html", + "t": "text.html.cshtml meta.tag.structure.input.void.html meta.attribute.type.html punctuation.separator.key-value.html", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -2454,7 +2487,7 @@ }, { "c": "\"", - "t": "text.html.cshtml meta.tag.inline.any.html string.quoted.double.html punctuation.definition.string.begin.html", + "t": "text.html.cshtml meta.tag.structure.input.void.html meta.attribute.type.html string.quoted.double.html punctuation.definition.string.begin.html", "r": { "dark_plus": "string: #CE9178", "light_plus": "string.quoted.double.html: #0000FF", @@ -2465,7 +2498,7 @@ }, { "c": "text", - "t": "text.html.cshtml meta.tag.inline.any.html string.quoted.double.html", + "t": "text.html.cshtml meta.tag.structure.input.void.html meta.attribute.type.html string.quoted.double.html", "r": { "dark_plus": "string: #CE9178", "light_plus": "string.quoted.double.html: #0000FF", @@ -2476,7 +2509,7 @@ }, { "c": "\"", - "t": "text.html.cshtml meta.tag.inline.any.html string.quoted.double.html punctuation.definition.string.end.html", + "t": "text.html.cshtml meta.tag.structure.input.void.html meta.attribute.type.html string.quoted.double.html punctuation.definition.string.end.html", "r": { "dark_plus": "string: #CE9178", "light_plus": "string.quoted.double.html: #0000FF", @@ -2487,7 +2520,7 @@ }, { "c": " ", - "t": "text.html.cshtml meta.tag.inline.any.html", + "t": "text.html.cshtml meta.tag.structure.input.void.html", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -2498,7 +2531,7 @@ }, { "c": "name", - "t": "text.html.cshtml meta.tag.inline.any.html entity.other.attribute-name.html", + "t": "text.html.cshtml meta.tag.structure.input.void.html meta.attribute.name.html entity.other.attribute-name.html", "r": { "dark_plus": "entity.other.attribute-name: #9CDCFE", "light_plus": "entity.other.attribute-name: #FF0000", @@ -2509,7 +2542,7 @@ }, { "c": "=", - "t": "text.html.cshtml meta.tag.inline.any.html", + "t": "text.html.cshtml meta.tag.structure.input.void.html meta.attribute.name.html punctuation.separator.key-value.html", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -2520,7 +2553,7 @@ }, { "c": "\"", - "t": "text.html.cshtml meta.tag.inline.any.html string.quoted.double.html punctuation.definition.string.begin.html", + "t": "text.html.cshtml meta.tag.structure.input.void.html meta.attribute.name.html string.quoted.double.html punctuation.definition.string.begin.html", "r": { "dark_plus": "string: #CE9178", "light_plus": "string.quoted.double.html: #0000FF", @@ -2531,7 +2564,7 @@ }, { "c": "text1", - "t": "text.html.cshtml meta.tag.inline.any.html string.quoted.double.html", + "t": "text.html.cshtml meta.tag.structure.input.void.html meta.attribute.name.html string.quoted.double.html", "r": { "dark_plus": "string: #CE9178", "light_plus": "string.quoted.double.html: #0000FF", @@ -2542,7 +2575,7 @@ }, { "c": "\"", - "t": "text.html.cshtml meta.tag.inline.any.html string.quoted.double.html punctuation.definition.string.end.html", + "t": "text.html.cshtml meta.tag.structure.input.void.html meta.attribute.name.html string.quoted.double.html punctuation.definition.string.end.html", "r": { "dark_plus": "string: #CE9178", "light_plus": "string.quoted.double.html: #0000FF", @@ -2552,8 +2585,19 @@ } }, { - "c": " />", - "t": "text.html.cshtml meta.tag.inline.any.html punctuation.definition.tag.end.html", + "c": " ", + "t": "text.html.cshtml meta.tag.structure.input.void.html", + "r": { + "dark_plus": "default: #D4D4D4", + "light_plus": "default: #000000", + "dark_vs": "default: #D4D4D4", + "light_vs": "default: #000000", + "hc_black": "default: #FFFFFF" + } + }, + { + "c": "/>", + "t": "text.html.cshtml meta.tag.structure.input.void.html punctuation.definition.tag.end.html", "r": { "dark_plus": "punctuation.definition.tag: #808080", "light_plus": "punctuation.definition.tag: #800000", @@ -2575,7 +2619,7 @@ }, { "c": "", - "t": "text.html.cshtml meta.tag.block.any.html punctuation.definition.tag.end.html", + "t": "text.html.cshtml meta.tag.structure.p.end.html punctuation.definition.tag.end.html", "r": { "dark_plus": "punctuation.definition.tag: #808080", "light_plus": "punctuation.definition.tag: #800000", @@ -2619,7 +2663,7 @@ }, { "c": "<", - "t": "text.html.cshtml meta.tag.block.any.html punctuation.definition.tag.begin.html", + "t": "text.html.cshtml meta.tag.structure.p.start.html punctuation.definition.tag.begin.html", "r": { "dark_plus": "punctuation.definition.tag: #808080", "light_plus": "punctuation.definition.tag: #800000", @@ -2630,7 +2674,7 @@ }, { "c": "p", - "t": "text.html.cshtml meta.tag.block.any.html entity.name.tag.block.any.html", + "t": "text.html.cshtml meta.tag.structure.p.start.html entity.name.tag.html", "r": { "dark_plus": "entity.name.tag: #569CD6", "light_plus": "entity.name.tag: #800000", @@ -2641,7 +2685,7 @@ }, { "c": ">", - "t": "text.html.cshtml meta.tag.block.any.html punctuation.definition.tag.end.html", + "t": "text.html.cshtml meta.tag.structure.p.start.html punctuation.definition.tag.end.html", "r": { "dark_plus": "punctuation.definition.tag: #808080", "light_plus": "punctuation.definition.tag: #800000", @@ -2652,7 +2696,7 @@ }, { "c": "<", - "t": "text.html.cshtml meta.tag.inline.any.html punctuation.definition.tag.begin.html", + "t": "text.html.cshtml meta.tag.structure.label.start.html punctuation.definition.tag.begin.html", "r": { "dark_plus": "punctuation.definition.tag: #808080", "light_plus": "punctuation.definition.tag: #800000", @@ -2663,7 +2707,7 @@ }, { "c": "label", - "t": "text.html.cshtml meta.tag.inline.any.html entity.name.tag.inline.any.html", + "t": "text.html.cshtml meta.tag.structure.label.start.html entity.name.tag.html", "r": { "dark_plus": "entity.name.tag: #569CD6", "light_plus": "entity.name.tag: #800000", @@ -2674,7 +2718,7 @@ }, { "c": " ", - "t": "text.html.cshtml meta.tag.inline.any.html", + "t": "text.html.cshtml meta.tag.structure.label.start.html", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -2685,7 +2729,7 @@ }, { "c": "for", - "t": "text.html.cshtml meta.tag.inline.any.html entity.other.attribute-name.html", + "t": "text.html.cshtml meta.tag.structure.label.start.html meta.attribute.for.html entity.other.attribute-name.html", "r": { "dark_plus": "entity.other.attribute-name: #9CDCFE", "light_plus": "entity.other.attribute-name: #FF0000", @@ -2696,7 +2740,7 @@ }, { "c": "=", - "t": "text.html.cshtml meta.tag.inline.any.html", + "t": "text.html.cshtml meta.tag.structure.label.start.html meta.attribute.for.html punctuation.separator.key-value.html", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -2707,7 +2751,7 @@ }, { "c": "\"", - "t": "text.html.cshtml meta.tag.inline.any.html string.quoted.double.html punctuation.definition.string.begin.html", + "t": "text.html.cshtml meta.tag.structure.label.start.html meta.attribute.for.html string.quoted.double.html punctuation.definition.string.begin.html", "r": { "dark_plus": "string: #CE9178", "light_plus": "string.quoted.double.html: #0000FF", @@ -2718,7 +2762,7 @@ }, { "c": "text2", - "t": "text.html.cshtml meta.tag.inline.any.html string.quoted.double.html", + "t": "text.html.cshtml meta.tag.structure.label.start.html meta.attribute.for.html string.quoted.double.html", "r": { "dark_plus": "string: #CE9178", "light_plus": "string.quoted.double.html: #0000FF", @@ -2729,7 +2773,7 @@ }, { "c": "\"", - "t": "text.html.cshtml meta.tag.inline.any.html string.quoted.double.html punctuation.definition.string.end.html", + "t": "text.html.cshtml meta.tag.structure.label.start.html meta.attribute.for.html string.quoted.double.html punctuation.definition.string.end.html", "r": { "dark_plus": "string: #CE9178", "light_plus": "string.quoted.double.html: #0000FF", @@ -2740,7 +2784,7 @@ }, { "c": ">", - "t": "text.html.cshtml meta.tag.inline.any.html punctuation.definition.tag.end.html", + "t": "text.html.cshtml meta.tag.structure.label.start.html punctuation.definition.tag.end.html", "r": { "dark_plus": "punctuation.definition.tag: #808080", "light_plus": "punctuation.definition.tag: #800000", @@ -2762,7 +2806,7 @@ }, { "c": "", - "t": "text.html.cshtml meta.tag.inline.any.html punctuation.definition.tag.end.html", + "t": "text.html.cshtml meta.tag.structure.label.end.html punctuation.definition.tag.end.html", "r": { "dark_plus": "punctuation.definition.tag: #808080", "light_plus": "punctuation.definition.tag: #800000", @@ -2806,7 +2850,7 @@ }, { "c": "<", - "t": "text.html.cshtml meta.tag.inline.any.html punctuation.definition.tag.begin.html", + "t": "text.html.cshtml meta.tag.structure.input.void.html punctuation.definition.tag.begin.html", "r": { "dark_plus": "punctuation.definition.tag: #808080", "light_plus": "punctuation.definition.tag: #800000", @@ -2817,7 +2861,7 @@ }, { "c": "input", - "t": "text.html.cshtml meta.tag.inline.any.html entity.name.tag.inline.any.html", + "t": "text.html.cshtml meta.tag.structure.input.void.html entity.name.tag.html", "r": { "dark_plus": "entity.name.tag: #569CD6", "light_plus": "entity.name.tag: #800000", @@ -2828,7 +2872,7 @@ }, { "c": " ", - "t": "text.html.cshtml meta.tag.inline.any.html", + "t": "text.html.cshtml meta.tag.structure.input.void.html", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -2839,7 +2883,7 @@ }, { "c": "type", - "t": "text.html.cshtml meta.tag.inline.any.html entity.other.attribute-name.html", + "t": "text.html.cshtml meta.tag.structure.input.void.html meta.attribute.type.html entity.other.attribute-name.html", "r": { "dark_plus": "entity.other.attribute-name: #9CDCFE", "light_plus": "entity.other.attribute-name: #FF0000", @@ -2850,7 +2894,7 @@ }, { "c": "=", - "t": "text.html.cshtml meta.tag.inline.any.html", + "t": "text.html.cshtml meta.tag.structure.input.void.html meta.attribute.type.html punctuation.separator.key-value.html", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -2861,7 +2905,7 @@ }, { "c": "\"", - "t": "text.html.cshtml meta.tag.inline.any.html string.quoted.double.html punctuation.definition.string.begin.html", + "t": "text.html.cshtml meta.tag.structure.input.void.html meta.attribute.type.html string.quoted.double.html punctuation.definition.string.begin.html", "r": { "dark_plus": "string: #CE9178", "light_plus": "string.quoted.double.html: #0000FF", @@ -2872,7 +2916,7 @@ }, { "c": "text", - "t": "text.html.cshtml meta.tag.inline.any.html string.quoted.double.html", + "t": "text.html.cshtml meta.tag.structure.input.void.html meta.attribute.type.html string.quoted.double.html", "r": { "dark_plus": "string: #CE9178", "light_plus": "string.quoted.double.html: #0000FF", @@ -2883,7 +2927,7 @@ }, { "c": "\"", - "t": "text.html.cshtml meta.tag.inline.any.html string.quoted.double.html punctuation.definition.string.end.html", + "t": "text.html.cshtml meta.tag.structure.input.void.html meta.attribute.type.html string.quoted.double.html punctuation.definition.string.end.html", "r": { "dark_plus": "string: #CE9178", "light_plus": "string.quoted.double.html: #0000FF", @@ -2894,7 +2938,7 @@ }, { "c": " ", - "t": "text.html.cshtml meta.tag.inline.any.html", + "t": "text.html.cshtml meta.tag.structure.input.void.html", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -2905,7 +2949,7 @@ }, { "c": "name", - "t": "text.html.cshtml meta.tag.inline.any.html entity.other.attribute-name.html", + "t": "text.html.cshtml meta.tag.structure.input.void.html meta.attribute.name.html entity.other.attribute-name.html", "r": { "dark_plus": "entity.other.attribute-name: #9CDCFE", "light_plus": "entity.other.attribute-name: #FF0000", @@ -2916,7 +2960,7 @@ }, { "c": "=", - "t": "text.html.cshtml meta.tag.inline.any.html", + "t": "text.html.cshtml meta.tag.structure.input.void.html meta.attribute.name.html punctuation.separator.key-value.html", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -2927,7 +2971,7 @@ }, { "c": "\"", - "t": "text.html.cshtml meta.tag.inline.any.html string.quoted.double.html punctuation.definition.string.begin.html", + "t": "text.html.cshtml meta.tag.structure.input.void.html meta.attribute.name.html string.quoted.double.html punctuation.definition.string.begin.html", "r": { "dark_plus": "string: #CE9178", "light_plus": "string.quoted.double.html: #0000FF", @@ -2938,7 +2982,7 @@ }, { "c": "text2", - "t": "text.html.cshtml meta.tag.inline.any.html string.quoted.double.html", + "t": "text.html.cshtml meta.tag.structure.input.void.html meta.attribute.name.html string.quoted.double.html", "r": { "dark_plus": "string: #CE9178", "light_plus": "string.quoted.double.html: #0000FF", @@ -2949,7 +2993,7 @@ }, { "c": "\"", - "t": "text.html.cshtml meta.tag.inline.any.html string.quoted.double.html punctuation.definition.string.end.html", + "t": "text.html.cshtml meta.tag.structure.input.void.html meta.attribute.name.html string.quoted.double.html punctuation.definition.string.end.html", "r": { "dark_plus": "string: #CE9178", "light_plus": "string.quoted.double.html: #0000FF", @@ -2959,8 +3003,19 @@ } }, { - "c": " />", - "t": "text.html.cshtml meta.tag.inline.any.html punctuation.definition.tag.end.html", + "c": " ", + "t": "text.html.cshtml meta.tag.structure.input.void.html", + "r": { + "dark_plus": "default: #D4D4D4", + "light_plus": "default: #000000", + "dark_vs": "default: #D4D4D4", + "light_vs": "default: #000000", + "hc_black": "default: #FFFFFF" + } + }, + { + "c": "/>", + "t": "text.html.cshtml meta.tag.structure.input.void.html punctuation.definition.tag.end.html", "r": { "dark_plus": "punctuation.definition.tag: #808080", "light_plus": "punctuation.definition.tag: #800000", @@ -2982,7 +3037,7 @@ }, { "c": "", - "t": "text.html.cshtml meta.tag.block.any.html punctuation.definition.tag.end.html", + "t": "text.html.cshtml meta.tag.structure.p.end.html punctuation.definition.tag.end.html", "r": { "dark_plus": "punctuation.definition.tag: #808080", "light_plus": "punctuation.definition.tag: #800000", @@ -3026,7 +3081,7 @@ }, { "c": "<", - "t": "text.html.cshtml meta.tag.block.any.html punctuation.definition.tag.begin.html", + "t": "text.html.cshtml meta.tag.structure.p.start.html punctuation.definition.tag.begin.html", "r": { "dark_plus": "punctuation.definition.tag: #808080", "light_plus": "punctuation.definition.tag: #800000", @@ -3037,7 +3092,7 @@ }, { "c": "p", - "t": "text.html.cshtml meta.tag.block.any.html entity.name.tag.block.any.html", + "t": "text.html.cshtml meta.tag.structure.p.start.html entity.name.tag.html", "r": { "dark_plus": "entity.name.tag: #569CD6", "light_plus": "entity.name.tag: #800000", @@ -3048,7 +3103,7 @@ }, { "c": ">", - "t": "text.html.cshtml meta.tag.block.any.html punctuation.definition.tag.end.html", + "t": "text.html.cshtml meta.tag.structure.p.start.html punctuation.definition.tag.end.html", "r": { "dark_plus": "punctuation.definition.tag: #808080", "light_plus": "punctuation.definition.tag: #800000", @@ -3059,7 +3114,7 @@ }, { "c": "<", - "t": "text.html.cshtml meta.tag.inline.any.html punctuation.definition.tag.begin.html", + "t": "text.html.cshtml meta.tag.structure.input.void.html punctuation.definition.tag.begin.html", "r": { "dark_plus": "punctuation.definition.tag: #808080", "light_plus": "punctuation.definition.tag: #800000", @@ -3070,7 +3125,7 @@ }, { "c": "input", - "t": "text.html.cshtml meta.tag.inline.any.html entity.name.tag.inline.any.html", + "t": "text.html.cshtml meta.tag.structure.input.void.html entity.name.tag.html", "r": { "dark_plus": "entity.name.tag: #569CD6", "light_plus": "entity.name.tag: #800000", @@ -3081,7 +3136,7 @@ }, { "c": " ", - "t": "text.html.cshtml meta.tag.inline.any.html", + "t": "text.html.cshtml meta.tag.structure.input.void.html", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -3092,7 +3147,7 @@ }, { "c": "type", - "t": "text.html.cshtml meta.tag.inline.any.html entity.other.attribute-name.html", + "t": "text.html.cshtml meta.tag.structure.input.void.html meta.attribute.type.html entity.other.attribute-name.html", "r": { "dark_plus": "entity.other.attribute-name: #9CDCFE", "light_plus": "entity.other.attribute-name: #FF0000", @@ -3103,7 +3158,7 @@ }, { "c": "=", - "t": "text.html.cshtml meta.tag.inline.any.html", + "t": "text.html.cshtml meta.tag.structure.input.void.html meta.attribute.type.html punctuation.separator.key-value.html", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -3114,7 +3169,7 @@ }, { "c": "\"", - "t": "text.html.cshtml meta.tag.inline.any.html string.quoted.double.html punctuation.definition.string.begin.html", + "t": "text.html.cshtml meta.tag.structure.input.void.html meta.attribute.type.html string.quoted.double.html punctuation.definition.string.begin.html", "r": { "dark_plus": "string: #CE9178", "light_plus": "string.quoted.double.html: #0000FF", @@ -3125,7 +3180,7 @@ }, { "c": "submit", - "t": "text.html.cshtml meta.tag.inline.any.html string.quoted.double.html", + "t": "text.html.cshtml meta.tag.structure.input.void.html meta.attribute.type.html string.quoted.double.html", "r": { "dark_plus": "string: #CE9178", "light_plus": "string.quoted.double.html: #0000FF", @@ -3136,7 +3191,7 @@ }, { "c": "\"", - "t": "text.html.cshtml meta.tag.inline.any.html string.quoted.double.html punctuation.definition.string.end.html", + "t": "text.html.cshtml meta.tag.structure.input.void.html meta.attribute.type.html string.quoted.double.html punctuation.definition.string.end.html", "r": { "dark_plus": "string: #CE9178", "light_plus": "string.quoted.double.html: #0000FF", @@ -3147,7 +3202,7 @@ }, { "c": " ", - "t": "text.html.cshtml meta.tag.inline.any.html", + "t": "text.html.cshtml meta.tag.structure.input.void.html", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -3158,7 +3213,7 @@ }, { "c": "value", - "t": "text.html.cshtml meta.tag.inline.any.html entity.other.attribute-name.html", + "t": "text.html.cshtml meta.tag.structure.input.void.html meta.attribute.value.html entity.other.attribute-name.html", "r": { "dark_plus": "entity.other.attribute-name: #9CDCFE", "light_plus": "entity.other.attribute-name: #FF0000", @@ -3169,7 +3224,7 @@ }, { "c": "=", - "t": "text.html.cshtml meta.tag.inline.any.html", + "t": "text.html.cshtml meta.tag.structure.input.void.html meta.attribute.value.html punctuation.separator.key-value.html", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -3180,7 +3235,7 @@ }, { "c": "\"", - "t": "text.html.cshtml meta.tag.inline.any.html string.quoted.double.html punctuation.definition.string.begin.html", + "t": "text.html.cshtml meta.tag.structure.input.void.html meta.attribute.value.html string.quoted.double.html punctuation.definition.string.begin.html", "r": { "dark_plus": "string: #CE9178", "light_plus": "string.quoted.double.html: #0000FF", @@ -3191,7 +3246,7 @@ }, { "c": "Add", - "t": "text.html.cshtml meta.tag.inline.any.html string.quoted.double.html", + "t": "text.html.cshtml meta.tag.structure.input.void.html meta.attribute.value.html string.quoted.double.html", "r": { "dark_plus": "string: #CE9178", "light_plus": "string.quoted.double.html: #0000FF", @@ -3202,7 +3257,7 @@ }, { "c": "\"", - "t": "text.html.cshtml meta.tag.inline.any.html string.quoted.double.html punctuation.definition.string.end.html", + "t": "text.html.cshtml meta.tag.structure.input.void.html meta.attribute.value.html string.quoted.double.html punctuation.definition.string.end.html", "r": { "dark_plus": "string: #CE9178", "light_plus": "string.quoted.double.html: #0000FF", @@ -3212,8 +3267,19 @@ } }, { - "c": " />", - "t": "text.html.cshtml meta.tag.inline.any.html punctuation.definition.tag.end.html", + "c": " ", + "t": "text.html.cshtml meta.tag.structure.input.void.html", + "r": { + "dark_plus": "default: #D4D4D4", + "light_plus": "default: #000000", + "dark_vs": "default: #D4D4D4", + "light_vs": "default: #000000", + "hc_black": "default: #FFFFFF" + } + }, + { + "c": "/>", + "t": "text.html.cshtml meta.tag.structure.input.void.html punctuation.definition.tag.end.html", "r": { "dark_plus": "punctuation.definition.tag: #808080", "light_plus": "punctuation.definition.tag: #800000", @@ -3224,7 +3290,7 @@ }, { "c": "", - "t": "text.html.cshtml meta.tag.block.any.html punctuation.definition.tag.end.html", + "t": "text.html.cshtml meta.tag.structure.p.end.html punctuation.definition.tag.end.html", "r": { "dark_plus": "punctuation.definition.tag: #808080", "light_plus": "punctuation.definition.tag: #800000", @@ -3268,7 +3334,7 @@ }, { "c": "", - "t": "text.html.cshtml meta.tag.block.any.html punctuation.definition.tag.end.html", + "t": "text.html.cshtml meta.tag.structure.form.end.html punctuation.definition.tag.end.html", "r": { "dark_plus": "punctuation.definition.tag: #808080", "light_plus": "punctuation.definition.tag: #800000", @@ -3334,7 +3400,7 @@ }, { "c": "<", - "t": "text.html.cshtml meta.tag.block.any.html punctuation.definition.tag.begin.html", + "t": "text.html.cshtml meta.tag.structure.p.start.html punctuation.definition.tag.begin.html", "r": { "dark_plus": "punctuation.definition.tag: #808080", "light_plus": "punctuation.definition.tag: #800000", @@ -3345,7 +3411,7 @@ }, { "c": "p", - "t": "text.html.cshtml meta.tag.block.any.html entity.name.tag.block.any.html", + "t": "text.html.cshtml meta.tag.structure.p.start.html entity.name.tag.html", "r": { "dark_plus": "entity.name.tag: #569CD6", "light_plus": "entity.name.tag: #800000", @@ -3356,7 +3422,7 @@ }, { "c": ">", - "t": "text.html.cshtml meta.tag.block.any.html punctuation.definition.tag.end.html", + "t": "text.html.cshtml meta.tag.structure.p.start.html punctuation.definition.tag.end.html", "r": { "dark_plus": "punctuation.definition.tag: #808080", "light_plus": "punctuation.definition.tag: #800000", @@ -3400,7 +3466,7 @@ }, { "c": "<", - "t": "text.html.cshtml meta.tag.block.any.html punctuation.definition.tag.begin.html", + "t": "text.html.cshtml meta.tag.structure.p.start.html punctuation.definition.tag.begin.html", "r": { "dark_plus": "punctuation.definition.tag: #808080", "light_plus": "punctuation.definition.tag: #800000", @@ -3411,7 +3477,7 @@ }, { "c": "p", - "t": "text.html.cshtml meta.tag.block.any.html entity.name.tag.block.any.html", + "t": "text.html.cshtml meta.tag.structure.p.start.html entity.name.tag.html", "r": { "dark_plus": "entity.name.tag: #569CD6", "light_plus": "entity.name.tag: #800000", @@ -3422,7 +3488,7 @@ }, { "c": ">", - "t": "text.html.cshtml meta.tag.block.any.html punctuation.definition.tag.end.html", + "t": "text.html.cshtml meta.tag.structure.p.start.html punctuation.definition.tag.end.html", "r": { "dark_plus": "punctuation.definition.tag: #808080", "light_plus": "punctuation.definition.tag: #800000", @@ -3510,7 +3576,7 @@ }, { "c": "", - "t": "text.html.cshtml meta.tag.block.any.html punctuation.definition.tag.end.html", + "t": "text.html.cshtml meta.tag.structure.p.end.html punctuation.definition.tag.end.html", "r": { "dark_plus": "punctuation.definition.tag: #808080", "light_plus": "punctuation.definition.tag: #800000", @@ -3565,7 +3631,7 @@ }, { "c": "", - "t": "text.html.cshtml meta.tag.structure.any.html punctuation.definition.tag.html", + "t": "text.html.cshtml meta.tag.structure.body.end.html punctuation.definition.tag.end.html", "r": { "dark_plus": "punctuation.definition.tag: #808080", "light_plus": "punctuation.definition.tag: #800000", @@ -3598,7 +3664,7 @@ }, { "c": "", - "t": "text.html.cshtml meta.tag.structure.any.html punctuation.definition.tag.html", + "t": "text.html.cshtml meta.tag.structure.html.end.html punctuation.definition.tag.end.html", "r": { "dark_plus": "punctuation.definition.tag: #808080", "light_plus": "punctuation.definition.tag: #800000", diff --git a/extensions/ruby/test/colorize-results/test_rb.json b/extensions/ruby/test/colorize-results/test_rb.json index 4a5fa89c87e..c53ee5970e2 100644 --- a/extensions/ruby/test/colorize-results/test_rb.json +++ b/extensions/ruby/test/colorize-results/test_rb.json @@ -3,9 +3,9 @@ "c": "#", "t": "source.ruby comment.line.number-sign.ruby punctuation.definition.comment.ruby", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -14,9 +14,9 @@ "c": " encoding: utf-8", "t": "source.ruby comment.line.number-sign.ruby", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -25,9 +25,9 @@ "c": "#", "t": "source.ruby comment.line.number-sign.ruby punctuation.definition.comment.ruby", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -36,9 +36,9 @@ "c": " Code generated by Microsoft (R) AutoRest Code Generator 0.16.0.0", "t": "source.ruby comment.line.number-sign.ruby", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -47,9 +47,9 @@ "c": "#", "t": "source.ruby comment.line.number-sign.ruby punctuation.definition.comment.ruby", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -58,9 +58,9 @@ "c": " Changes may cause incorrect behavior and will be lost if the code is", "t": "source.ruby comment.line.number-sign.ruby", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -69,9 +69,9 @@ "c": "#", "t": "source.ruby comment.line.number-sign.ruby punctuation.definition.comment.ruby", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -80,9 +80,9 @@ "c": " regenerated.", "t": "source.ruby comment.line.number-sign.ruby", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -179,9 +179,9 @@ "c": "#", "t": "source.ruby comment.line.number-sign.ruby punctuation.definition.comment.ruby", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -201,9 +201,9 @@ "c": "#", "t": "source.ruby comment.line.number-sign.ruby punctuation.definition.comment.ruby", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -212,9 +212,9 @@ "c": " A service client - single point of access to the REST API.", "t": "source.ruby comment.line.number-sign.ruby", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -234,9 +234,9 @@ "c": "#", "t": "source.ruby comment.line.number-sign.ruby punctuation.definition.comment.ruby", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -498,9 +498,9 @@ "c": "#", "t": "source.ruby comment.line.number-sign.ruby punctuation.definition.comment.ruby", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -509,9 +509,9 @@ "c": " @return job_collections", "t": "source.ruby comment.line.number-sign.ruby", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -586,9 +586,9 @@ "c": "#", "t": "source.ruby comment.line.number-sign.ruby punctuation.definition.comment.ruby", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -608,9 +608,9 @@ "c": "#", "t": "source.ruby comment.line.number-sign.ruby punctuation.definition.comment.ruby", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -619,9 +619,9 @@ "c": " Creates initializes a new instance of the SchedulerManagementClient class.", "t": "source.ruby comment.line.number-sign.ruby", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -641,9 +641,9 @@ "c": "#", "t": "source.ruby comment.line.number-sign.ruby punctuation.definition.comment.ruby", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -652,9 +652,9 @@ "c": " @param credentials [MsRest::ServiceClientCredentials] credentials to authorize HTTP requests made by the service client.", "t": "source.ruby comment.line.number-sign.ruby", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -674,9 +674,9 @@ "c": "#", "t": "source.ruby comment.line.number-sign.ruby punctuation.definition.comment.ruby", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -685,9 +685,9 @@ "c": " @param base_url [String] the base URI of the service.", "t": "source.ruby comment.line.number-sign.ruby", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -707,9 +707,9 @@ "c": "#", "t": "source.ruby comment.line.number-sign.ruby punctuation.definition.comment.ruby", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -718,9 +718,9 @@ "c": " @param options [Array] filters to be applied to the HTTP requests.", "t": "source.ruby comment.line.number-sign.ruby", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -740,9 +740,9 @@ "c": "#", "t": "source.ruby comment.line.number-sign.ruby punctuation.definition.comment.ruby", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } diff --git a/extensions/scss/test/colorize-results/test_scss.json b/extensions/scss/test/colorize-results/test_scss.json index 9528b311bae..497e8c13fd0 100644 --- a/extensions/scss/test/colorize-results/test_scss.json +++ b/extensions/scss/test/colorize-results/test_scss.json @@ -3,9 +3,9 @@ "c": "//", "t": "source.css.scss comment.line.scss punctuation.definition.comment.scss", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -14,9 +14,9 @@ "c": " snippets from the Sass documentation at http://sass-lang.com/", "t": "source.css.scss comment.line.scss", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -25,9 +25,9 @@ "c": "/*", "t": "source.css.scss comment.block.scss punctuation.definition.comment.scss", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -36,9 +36,9 @@ "c": " css stuff ", "t": "source.css.scss comment.block.scss", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -47,9 +47,9 @@ "c": "*/", "t": "source.css.scss comment.block.scss punctuation.definition.comment.scss", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -58,9 +58,9 @@ "c": "/*", "t": "source.css.scss comment.block.scss punctuation.definition.comment.scss", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -69,9 +69,9 @@ "c": " charset ", "t": "source.css.scss comment.block.scss", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -80,9 +80,9 @@ "c": "*/", "t": "source.css.scss comment.block.scss punctuation.definition.comment.scss", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -168,9 +168,9 @@ "c": "/*", "t": "source.css.scss comment.block.scss punctuation.definition.comment.scss", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -179,9 +179,9 @@ "c": " nested rules ", "t": "source.css.scss comment.block.scss", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -190,9 +190,9 @@ "c": "*/", "t": "source.css.scss comment.block.scss punctuation.definition.comment.scss", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -773,9 +773,9 @@ "c": "/*", "t": "source.css.scss comment.block.scss punctuation.definition.comment.scss", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -784,9 +784,9 @@ "c": " parent selector (&) ", "t": "source.css.scss comment.block.scss", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -795,9 +795,9 @@ "c": "*/", "t": "source.css.scss comment.block.scss punctuation.definition.comment.scss", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -1213,9 +1213,9 @@ "c": "/*", "t": "source.css.scss comment.block.scss punctuation.definition.comment.scss", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -1224,9 +1224,9 @@ "c": " nested properties ", "t": "source.css.scss comment.block.scss", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -1235,9 +1235,9 @@ "c": "*/", "t": "source.css.scss comment.block.scss punctuation.definition.comment.scss", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -1642,9 +1642,9 @@ "c": "/*", "t": "source.css.scss comment.block.scss punctuation.definition.comment.scss", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -1653,9 +1653,9 @@ "c": " nesting conflicts ", "t": "source.css.scss comment.block.scss", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -1664,9 +1664,9 @@ "c": "*/", "t": "source.css.scss comment.block.scss punctuation.definition.comment.scss", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -1785,9 +1785,9 @@ "c": "//", "t": "source.css.scss meta.property-list.scss meta.property-list.scss comment.line.scss punctuation.definition.comment.scss", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -1796,9 +1796,9 @@ "c": " properties", "t": "source.css.scss meta.property-list.scss meta.property-list.scss comment.line.scss", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -1994,9 +1994,9 @@ "c": "//", "t": "source.css.scss meta.property-list.scss comment.line.scss punctuation.definition.comment.scss", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -2005,9 +2005,9 @@ "c": " rule", "t": "source.css.scss meta.property-list.scss comment.line.scss", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -2093,9 +2093,9 @@ "c": "//", "t": "source.css.scss meta.property-list.scss meta.property-list.scss comment.line.scss punctuation.definition.comment.scss", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -2104,9 +2104,9 @@ "c": " selector", "t": "source.css.scss meta.property-list.scss meta.property-list.scss comment.line.scss", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -2258,9 +2258,9 @@ "c": "//", "t": "source.css.scss meta.property-list.scss meta.property-value.scss comment.line.scss punctuation.definition.comment.scss", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -2269,9 +2269,9 @@ "c": " selector", "t": "source.css.scss meta.property-list.scss meta.property-value.scss comment.line.scss", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -2368,9 +2368,9 @@ "c": "//", "t": "source.css.scss comment.line.scss punctuation.definition.comment.scss", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -2379,9 +2379,9 @@ "c": " rule", "t": "source.css.scss comment.line.scss", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -2401,9 +2401,9 @@ "c": "/*", "t": "source.css.scss comment.block.scss punctuation.definition.comment.scss", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -2412,9 +2412,9 @@ "c": " extended comment syntax ", "t": "source.css.scss comment.block.scss", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -2423,9 +2423,9 @@ "c": "*/", "t": "source.css.scss comment.block.scss punctuation.definition.comment.scss", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -2434,9 +2434,9 @@ "c": "/*", "t": "source.css.scss comment.block.scss punctuation.definition.comment.scss", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -2445,9 +2445,9 @@ "c": " This comment is", "t": "source.css.scss comment.block.scss", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -2456,9 +2456,9 @@ "c": " * several lines long.", "t": "source.css.scss comment.block.scss", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -2467,9 +2467,9 @@ "c": " * since it uses the CSS comment syntax,", "t": "source.css.scss comment.block.scss", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -2478,9 +2478,9 @@ "c": " * it will appear in the CSS output. ", "t": "source.css.scss comment.block.scss", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -2489,9 +2489,9 @@ "c": "*/", "t": "source.css.scss comment.block.scss punctuation.definition.comment.scss", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -2621,9 +2621,9 @@ "c": "//", "t": "source.css.scss comment.line.scss punctuation.definition.comment.scss", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -2632,9 +2632,9 @@ "c": " These comments are only one line long each.", "t": "source.css.scss comment.line.scss", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -2643,9 +2643,9 @@ "c": "//", "t": "source.css.scss comment.line.scss punctuation.definition.comment.scss", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -2654,9 +2654,9 @@ "c": " They won't appear in the CSS output,", "t": "source.css.scss comment.line.scss", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -2665,9 +2665,9 @@ "c": "//", "t": "source.css.scss comment.line.scss punctuation.definition.comment.scss", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -2676,9 +2676,9 @@ "c": " since they use the single-line comment syntax.", "t": "source.css.scss comment.line.scss", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -2808,9 +2808,9 @@ "c": "/*", "t": "source.css.scss comment.block.scss punctuation.definition.comment.scss", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -2819,9 +2819,9 @@ "c": " variables ", "t": "source.css.scss comment.block.scss", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -2830,9 +2830,9 @@ "c": "*/", "t": "source.css.scss comment.block.scss punctuation.definition.comment.scss", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -3776,9 +3776,9 @@ "c": "/*", "t": "source.css.scss comment.block.scss punctuation.definition.comment.scss", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -3787,9 +3787,9 @@ "c": " variable declaration with whitespaces ", "t": "source.css.scss comment.block.scss", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -3798,9 +3798,9 @@ "c": "*/", "t": "source.css.scss comment.block.scss punctuation.definition.comment.scss", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -3809,9 +3809,9 @@ "c": "//", "t": "source.css.scss comment.line.scss punctuation.definition.comment.scss", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -3820,9 +3820,9 @@ "c": " Set the color of your columns", "t": "source.css.scss comment.line.scss", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -4051,9 +4051,9 @@ "c": "/*", "t": "source.css.scss comment.block.scss punctuation.definition.comment.scss", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -4062,9 +4062,9 @@ "c": " operations", "t": "source.css.scss comment.block.scss", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -4073,9 +4073,9 @@ "c": "*/", "t": "source.css.scss comment.block.scss punctuation.definition.comment.scss", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -5382,9 +5382,9 @@ "c": "/*", "t": "source.css.scss comment.block.scss punctuation.definition.comment.scss", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -5393,9 +5393,9 @@ "c": " functions", "t": "source.css.scss comment.block.scss", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -5404,9 +5404,9 @@ "c": "*/", "t": "source.css.scss comment.block.scss punctuation.definition.comment.scss", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -6086,9 +6086,9 @@ "c": "/*", "t": "source.css.scss comment.block.scss punctuation.definition.comment.scss", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -6097,9 +6097,9 @@ "c": " @import ", "t": "source.css.scss comment.block.scss", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -6108,9 +6108,9 @@ "c": "*/", "t": "source.css.scss comment.block.scss punctuation.definition.comment.scss", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -6636,9 +6636,9 @@ "c": "/*", "t": "source.css.scss comment.block.scss punctuation.definition.comment.scss", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -6647,9 +6647,9 @@ "c": " @media ", "t": "source.css.scss comment.block.scss", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -6658,9 +6658,9 @@ "c": "*/", "t": "source.css.scss comment.block.scss punctuation.definition.comment.scss", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -7076,9 +7076,9 @@ "c": "/*", "t": "source.css.scss comment.block.scss punctuation.definition.comment.scss", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -7087,9 +7087,9 @@ "c": " @extend ", "t": "source.css.scss comment.block.scss", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -7098,9 +7098,9 @@ "c": "*/", "t": "source.css.scss comment.block.scss punctuation.definition.comment.scss", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -7989,9 +7989,9 @@ "c": "/*", "t": "source.css.scss comment.block.scss punctuation.definition.comment.scss", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -8000,9 +8000,9 @@ "c": " @debug and @warn ", "t": "source.css.scss comment.block.scss", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -8011,9 +8011,9 @@ "c": "*/", "t": "source.css.scss comment.block.scss punctuation.definition.comment.scss", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -9166,9 +9166,9 @@ "c": "/*", "t": "source.css.scss comment.block.scss punctuation.definition.comment.scss", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -9177,9 +9177,9 @@ "c": " control directives ", "t": "source.css.scss comment.block.scss", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -9188,9 +9188,9 @@ "c": "*/", "t": "source.css.scss comment.block.scss punctuation.definition.comment.scss", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -9199,9 +9199,9 @@ "c": "/*", "t": "source.css.scss comment.block.scss punctuation.definition.comment.scss", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -9210,9 +9210,9 @@ "c": " if statement ", "t": "source.css.scss comment.block.scss", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -9221,9 +9221,9 @@ "c": "*/", "t": "source.css.scss comment.block.scss punctuation.definition.comment.scss", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -9980,9 +9980,9 @@ "c": "/*", "t": "source.css.scss comment.block.scss punctuation.definition.comment.scss", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -9991,9 +9991,9 @@ "c": " if else statement ", "t": "source.css.scss comment.block.scss", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -10002,9 +10002,9 @@ "c": "*/", "t": "source.css.scss comment.block.scss punctuation.definition.comment.scss", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -10420,9 +10420,9 @@ "c": "/*", "t": "source.css.scss comment.block.scss punctuation.definition.comment.scss", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -10431,9 +10431,9 @@ "c": " for statement ", "t": "source.css.scss comment.block.scss", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -10442,9 +10442,9 @@ "c": "*/", "t": "source.css.scss comment.block.scss punctuation.definition.comment.scss", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -10849,9 +10849,9 @@ "c": "/*", "t": "source.css.scss comment.block.scss punctuation.definition.comment.scss", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -10860,9 +10860,9 @@ "c": " each statement ", "t": "source.css.scss comment.block.scss", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -10871,9 +10871,9 @@ "c": "*/", "t": "source.css.scss comment.block.scss punctuation.definition.comment.scss", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -11278,9 +11278,9 @@ "c": "/*", "t": "source.css.scss meta.at-rule.each.scss comment.block.scss punctuation.definition.comment.scss", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -11289,9 +11289,9 @@ "c": " while statement ", "t": "source.css.scss meta.at-rule.each.scss comment.block.scss", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -11300,9 +11300,9 @@ "c": "*/", "t": "source.css.scss meta.at-rule.each.scss comment.block.scss punctuation.definition.comment.scss", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -11817,9 +11817,9 @@ "c": "/*", "t": "source.css.scss meta.at-rule.each.scss meta.at-rule.while.scss comment.block.scss punctuation.definition.comment.scss", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -11828,9 +11828,9 @@ "c": " function with controlstatements ", "t": "source.css.scss meta.at-rule.each.scss meta.at-rule.while.scss comment.block.scss", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -11839,9 +11839,9 @@ "c": "*/", "t": "source.css.scss meta.at-rule.each.scss meta.at-rule.while.scss comment.block.scss punctuation.definition.comment.scss", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -12752,9 +12752,9 @@ "c": "/*", "t": "source.css.scss meta.at-rule.each.scss meta.at-rule.while.scss comment.block.scss punctuation.definition.comment.scss", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -12763,9 +12763,9 @@ "c": " @mixin simple", "t": "source.css.scss meta.at-rule.each.scss meta.at-rule.while.scss comment.block.scss", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -12774,9 +12774,9 @@ "c": "*/", "t": "source.css.scss meta.at-rule.each.scss meta.at-rule.while.scss comment.block.scss punctuation.definition.comment.scss", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -13412,9 +13412,9 @@ "c": "/*", "t": "source.css.scss meta.at-rule.each.scss meta.at-rule.while.scss comment.block.scss punctuation.definition.comment.scss", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -13423,9 +13423,9 @@ "c": " mixin with parameters ", "t": "source.css.scss meta.at-rule.each.scss meta.at-rule.while.scss comment.block.scss", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -13434,9 +13434,9 @@ "c": "*/", "t": "source.css.scss meta.at-rule.each.scss meta.at-rule.while.scss comment.block.scss punctuation.definition.comment.scss", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -14039,9 +14039,9 @@ "c": "/*", "t": "source.css.scss meta.at-rule.each.scss meta.at-rule.while.scss comment.block.scss punctuation.definition.comment.scss", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -14050,9 +14050,9 @@ "c": " mixin with varargs ", "t": "source.css.scss meta.at-rule.each.scss meta.at-rule.while.scss comment.block.scss", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -14061,9 +14061,9 @@ "c": "*/", "t": "source.css.scss meta.at-rule.each.scss meta.at-rule.while.scss comment.block.scss punctuation.definition.comment.scss", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -14787,9 +14787,9 @@ "c": "/*", "t": "source.css.scss meta.at-rule.each.scss meta.at-rule.while.scss comment.block.scss punctuation.definition.comment.scss", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -14798,9 +14798,9 @@ "c": " include with varargs ", "t": "source.css.scss meta.at-rule.each.scss meta.at-rule.while.scss comment.block.scss", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -14809,9 +14809,9 @@ "c": "*/", "t": "source.css.scss meta.at-rule.each.scss meta.at-rule.while.scss comment.block.scss punctuation.definition.comment.scss", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -15458,9 +15458,9 @@ "c": "/*", "t": "source.css.scss meta.at-rule.each.scss meta.at-rule.while.scss comment.block.scss punctuation.definition.comment.scss", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -15469,9 +15469,9 @@ "c": " include with body ", "t": "source.css.scss meta.at-rule.each.scss meta.at-rule.while.scss comment.block.scss", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -15480,9 +15480,9 @@ "c": "*/", "t": "source.css.scss meta.at-rule.each.scss meta.at-rule.while.scss comment.block.scss punctuation.definition.comment.scss", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -16129,9 +16129,9 @@ "c": "/*", "t": "source.css.scss meta.at-rule.each.scss meta.at-rule.while.scss comment.block.scss punctuation.definition.comment.scss", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -16140,9 +16140,9 @@ "c": " attributes ", "t": "source.css.scss meta.at-rule.each.scss meta.at-rule.while.scss comment.block.scss", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -16151,9 +16151,9 @@ "c": "*/", "t": "source.css.scss meta.at-rule.each.scss meta.at-rule.while.scss comment.block.scss punctuation.definition.comment.scss", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -16382,9 +16382,9 @@ "c": "/*", "t": "source.css.scss meta.at-rule.each.scss meta.at-rule.while.scss comment.block.scss punctuation.definition.comment.scss", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -16393,9 +16393,9 @@ "c": "page ", "t": "source.css.scss meta.at-rule.each.scss meta.at-rule.while.scss comment.block.scss", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -16404,9 +16404,9 @@ "c": "*/", "t": "source.css.scss meta.at-rule.each.scss meta.at-rule.while.scss comment.block.scss punctuation.definition.comment.scss", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -16646,9 +16646,9 @@ "c": "/*", "t": "source.css.scss meta.at-rule.each.scss meta.at-rule.while.scss comment.block.scss punctuation.definition.comment.scss", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -16657,9 +16657,9 @@ "c": " missing semicolons ", "t": "source.css.scss meta.at-rule.each.scss meta.at-rule.while.scss comment.block.scss", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -16668,9 +16668,9 @@ "c": "*/", "t": "source.css.scss meta.at-rule.each.scss meta.at-rule.while.scss comment.block.scss punctuation.definition.comment.scss", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -17603,9 +17603,9 @@ "c": "/*", "t": "source.css.scss meta.at-rule.each.scss meta.at-rule.while.scss meta.property-list.scss comment.block.scss punctuation.definition.comment.scss", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -17614,9 +17614,9 @@ "c": " extend with interpolation variable ", "t": "source.css.scss meta.at-rule.each.scss meta.at-rule.while.scss meta.property-list.scss comment.block.scss", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -17625,9 +17625,9 @@ "c": "*/", "t": "source.css.scss meta.at-rule.each.scss meta.at-rule.while.scss meta.property-list.scss comment.block.scss punctuation.definition.comment.scss", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -18351,9 +18351,9 @@ "c": "/*", "t": "source.css.scss meta.at-rule.each.scss meta.at-rule.while.scss meta.property-list.scss comment.block.scss punctuation.definition.comment.scss", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -18362,9 +18362,9 @@ "c": " css3: @font face ", "t": "source.css.scss meta.at-rule.each.scss meta.at-rule.while.scss meta.property-list.scss comment.block.scss", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -18373,9 +18373,9 @@ "c": "*/", "t": "source.css.scss meta.at-rule.each.scss meta.at-rule.while.scss meta.property-list.scss comment.block.scss punctuation.definition.comment.scss", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -18637,9 +18637,9 @@ "c": "/*", "t": "source.css.scss meta.at-rule.each.scss meta.at-rule.while.scss meta.property-list.scss comment.block.scss punctuation.definition.comment.scss", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -18648,9 +18648,9 @@ "c": " rule names with variables ", "t": "source.css.scss meta.at-rule.each.scss meta.at-rule.while.scss meta.property-list.scss comment.block.scss", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -18659,9 +18659,9 @@ "c": "*/", "t": "source.css.scss meta.at-rule.each.scss meta.at-rule.while.scss meta.property-list.scss comment.block.scss punctuation.definition.comment.scss", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -19209,9 +19209,9 @@ "c": "/*", "t": "source.css.scss meta.at-rule.each.scss meta.at-rule.while.scss meta.property-list.scss comment.block.scss punctuation.definition.comment.scss", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -19220,9 +19220,9 @@ "c": " keyframes ", "t": "source.css.scss meta.at-rule.each.scss meta.at-rule.while.scss meta.property-list.scss comment.block.scss", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -19231,9 +19231,9 @@ "c": "*/", "t": "source.css.scss meta.at-rule.each.scss meta.at-rule.while.scss meta.property-list.scss comment.block.scss punctuation.definition.comment.scss", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -20518,9 +20518,9 @@ "c": "/*", "t": "source.css.scss meta.at-rule.each.scss meta.at-rule.while.scss meta.property-list.scss comment.block.scss punctuation.definition.comment.scss", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -20529,9 +20529,9 @@ "c": " string escaping ", "t": "source.css.scss meta.at-rule.each.scss meta.at-rule.while.scss meta.property-list.scss comment.block.scss", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -20540,9 +20540,9 @@ "c": "*/", "t": "source.css.scss meta.at-rule.each.scss meta.at-rule.while.scss meta.property-list.scss comment.block.scss punctuation.definition.comment.scss", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -20760,9 +20760,9 @@ "c": "/*", "t": "source.css.scss meta.at-rule.each.scss meta.at-rule.while.scss meta.property-list.scss comment.block.scss punctuation.definition.comment.scss", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -20771,9 +20771,9 @@ "c": " a comment ", "t": "source.css.scss meta.at-rule.each.scss meta.at-rule.while.scss meta.property-list.scss comment.block.scss", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -20782,9 +20782,9 @@ "c": "*/", "t": "source.css.scss meta.at-rule.each.scss meta.at-rule.while.scss meta.property-list.scss comment.block.scss punctuation.definition.comment.scss", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -20947,9 +20947,9 @@ "c": "/*", "t": "source.css.scss meta.at-rule.each.scss meta.at-rule.while.scss meta.property-list.scss comment.block.scss punctuation.definition.comment.scss", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -20958,9 +20958,9 @@ "c": " another comment ", "t": "source.css.scss meta.at-rule.each.scss meta.at-rule.while.scss meta.property-list.scss comment.block.scss", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -20969,9 +20969,9 @@ "c": "*/", "t": "source.css.scss meta.at-rule.each.scss meta.at-rule.while.scss meta.property-list.scss comment.block.scss punctuation.definition.comment.scss", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } diff --git a/extensions/shellscript/test/colorize-results/test_sh.json b/extensions/shellscript/test/colorize-results/test_sh.json index 36a9ce993e4..6760e596443 100644 --- a/extensions/shellscript/test/colorize-results/test_sh.json +++ b/extensions/shellscript/test/colorize-results/test_sh.json @@ -3,9 +3,9 @@ "c": "#!", "t": "source.shell comment.line.number-sign.shebang.shell punctuation.definition.comment.shebang.shell", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -14,9 +14,9 @@ "c": "/usr/bin/env bash", "t": "source.shell comment.line.number-sign.shebang.shell", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -1246,9 +1246,9 @@ "c": "#", "t": "source.shell meta.function.shell meta.scope.group.shell comment.line.number-sign.shell punctuation.definition.comment.shell", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -1257,9 +1257,9 @@ "c": " Node modules", "t": "source.shell meta.function.shell meta.scope.group.shell comment.line.number-sign.shell", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -1334,9 +1334,9 @@ "c": "#", "t": "source.shell meta.function.shell meta.scope.group.shell comment.line.number-sign.shell punctuation.definition.comment.shell", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -1345,9 +1345,9 @@ "c": " Configuration", "t": "source.shell meta.function.shell meta.scope.group.shell comment.line.number-sign.shell", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -1400,9 +1400,9 @@ "c": "#", "t": "source.shell meta.function.shell meta.scope.group.shell comment.line.number-sign.shell punctuation.definition.comment.shell", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -1411,9 +1411,9 @@ "c": " Launch Code", "t": "source.shell meta.function.shell meta.scope.group.shell comment.line.number-sign.shell", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } diff --git a/extensions/typescript-basics/test/colorize-results/test-brackets_tsx.json b/extensions/typescript-basics/test/colorize-results/test-brackets_tsx.json index d0c675c716b..c7e165ae25e 100644 --- a/extensions/typescript-basics/test/colorize-results/test-brackets_tsx.json +++ b/extensions/typescript-basics/test/colorize-results/test-brackets_tsx.json @@ -146,9 +146,9 @@ "c": "//", "t": "source.tsx comment.line.double-slash.tsx punctuation.definition.comment.tsx", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -157,9 +157,9 @@ "c": " Highlight ok here", "t": "source.tsx comment.line.double-slash.tsx", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } diff --git a/extensions/typescript-basics/test/colorize-results/test_ts.json b/extensions/typescript-basics/test/colorize-results/test_ts.json index 36459b46419..3246facbff2 100644 --- a/extensions/typescript-basics/test/colorize-results/test_ts.json +++ b/extensions/typescript-basics/test/colorize-results/test_ts.json @@ -3,9 +3,9 @@ "c": "/*", "t": "source.ts comment.block.ts punctuation.definition.comment.ts", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -14,9 +14,9 @@ "c": " Game of Life", "t": "source.ts comment.block.ts", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -25,9 +25,9 @@ "c": " * Implemented in TypeScript", "t": "source.ts comment.block.ts", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -36,9 +36,9 @@ "c": " * To learn more about TypeScript, please visit http://www.typescriptlang.org/", "t": "source.ts comment.block.ts", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -47,9 +47,9 @@ "c": " ", "t": "source.ts comment.block.ts", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -58,9 +58,9 @@ "c": "*/", "t": "source.ts comment.block.ts punctuation.definition.comment.ts", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } diff --git a/extensions/vb/test/colorize-results/test_vb.json b/extensions/vb/test/colorize-results/test_vb.json index b4567db9c74..ee27f71ae6c 100644 --- a/extensions/vb/test/colorize-results/test_vb.json +++ b/extensions/vb/test/colorize-results/test_vb.json @@ -3,9 +3,9 @@ "c": "'", "t": "source.asp.vb.net comment.line.apostrophe.asp punctuation.definition.comment.asp", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -14,9 +14,9 @@ "c": " Copyright (c) Microsoft Corporation. All rights reserved.", "t": "source.asp.vb.net comment.line.apostrophe.asp", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -630,9 +630,9 @@ "c": "'", "t": "source.asp.vb.net comment.line.apostrophe.asp punctuation.definition.comment.asp", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -641,9 +641,9 @@ "c": " The Timer property of the DateAndTime object returns the seconds", "t": "source.asp.vb.net comment.line.apostrophe.asp", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -674,9 +674,9 @@ "c": "'", "t": "source.asp.vb.net comment.line.apostrophe.asp punctuation.definition.comment.asp", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -685,9 +685,9 @@ "c": " and milliseconds that have passed since midnight.", "t": "source.asp.vb.net comment.line.apostrophe.asp", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -1114,9 +1114,9 @@ "c": "'", "t": "source.asp.vb.net comment.line.apostrophe.asp punctuation.definition.comment.asp", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -1125,9 +1125,9 @@ "c": " In a real application, some unit of work would", "t": "source.asp.vb.net comment.line.apostrophe.asp", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -1180,9 +1180,9 @@ "c": "'", "t": "source.asp.vb.net comment.line.apostrophe.asp punctuation.definition.comment.asp", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -1191,9 +1191,9 @@ "c": " be done here each time through the loop.", "t": "source.asp.vb.net comment.line.apostrophe.asp", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -1763,9 +1763,9 @@ "c": "'", "t": "source.asp.vb.net comment.line.apostrophe.asp punctuation.definition.comment.asp", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -1774,9 +1774,9 @@ "c": " Check to see if the operation was canceled.", "t": "source.asp.vb.net comment.line.apostrophe.asp", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } diff --git a/extensions/xml/test/colorize-results/test_xml.json b/extensions/xml/test/colorize-results/test_xml.json index 80525b29179..b16beb8b122 100644 --- a/extensions/xml/test/colorize-results/test_xml.json +++ b/extensions/xml/test/colorize-results/test_xml.json @@ -795,9 +795,9 @@ "c": "", "t": "text.xml comment.block.xml punctuation.definition.comment.xml", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } diff --git a/extensions/yaml/test/colorize-results/test_yaml.json b/extensions/yaml/test/colorize-results/test_yaml.json index 6c0e70abaaf..6c871b32208 100644 --- a/extensions/yaml/test/colorize-results/test_yaml.json +++ b/extensions/yaml/test/colorize-results/test_yaml.json @@ -3,9 +3,9 @@ "c": "#", "t": "source.yaml comment.line.number-sign.yaml punctuation.definition.comment.yaml", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -14,9 +14,9 @@ "c": " sequencer protocols for Laser eye surgery", "t": "source.yaml comment.line.number-sign.yaml", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -124,9 +124,9 @@ "c": "#", "t": "source.yaml comment.line.number-sign.yaml punctuation.definition.comment.yaml", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -135,9 +135,9 @@ "c": " defines anchor label &id001", "t": "source.yaml comment.line.number-sign.yaml", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -399,9 +399,9 @@ "c": "#", "t": "source.yaml comment.line.number-sign.yaml punctuation.definition.comment.yaml", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -410,9 +410,9 @@ "c": " refers to the first step (with anchor &id001)", "t": "source.yaml comment.line.number-sign.yaml", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } From e4c54be876ae26b2badb73b7f3a40b97b1a2e108 Mon Sep 17 00:00:00 2001 From: Martin Aeschlimann Date: Fri, 27 Jul 2018 10:58:12 +0200 Subject: [PATCH 0216/1276] update TypeScript grammar --- .../syntaxes/JavaScript.tmLanguage.json | 300 ++++++++++++++++-- .../syntaxes/JavaScriptReact.tmLanguage.json | 300 ++++++++++++++++-- .../syntaxes/TypeScript.tmLanguage.json | 300 ++++++++++++++++-- .../syntaxes/TypeScriptReact.tmLanguage.json | 300 ++++++++++++++++-- .../colorize-results/test-issue11_ts.json | 2 +- .../colorize-results/test-issue5431_ts.json | 2 +- .../colorize-results/test-issue5566_ts.json | 2 +- 7 files changed, 1079 insertions(+), 127 deletions(-) diff --git a/extensions/javascript/syntaxes/JavaScript.tmLanguage.json b/extensions/javascript/syntaxes/JavaScript.tmLanguage.json index aa6c9971e8d..2b6ae46fe6d 100644 --- a/extensions/javascript/syntaxes/JavaScript.tmLanguage.json +++ b/extensions/javascript/syntaxes/JavaScript.tmLanguage.json @@ -4,7 +4,7 @@ "If you want to provide a fix or improvement, please create a pull request against the original repository.", "Once accepted there, we are happy to receive an update request." ], - "version": "https://github.com/Microsoft/TypeScript-TmLanguage/commit/32208c2b11569d08a925f56fd69d28b18a5cc308", + "version": "https://github.com/Microsoft/TypeScript-TmLanguage/commit/858d33f03943e4ec040e81cbabbc3f7892157c18", "name": "JavaScript (with React support)", "scopeName": "source.js", "patterns": [ @@ -285,55 +285,112 @@ ] }, "var-expr": { - "name": "meta.var.expr.js", - "begin": "(?)\n )) |\n ((async\\s*)?(\n ((<\\s*$)|([\\(]\\s*([\\{\\[]\\s*)?$)) |\n # sure shot arrow functions even if => is on new line\n(\n (<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<])*\\>)*>\\s*)?\n [(]\\s*\n (\n ([)]\\s*:) | # ():\n ((\\.\\.\\.\\s*)?[_$[:alpha:]][_$[:alnum:]]*\\s*:) # [(]param: | [(]...param:\n )\n) |\n(\n [<]\\s*[_$[:alpha:]][_$[:alnum:]]*\\s+extends\\s*[^=>] # < typeparam extends\n) |\n# arrow function possible to detect only with => on same line\n(\n (<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<])*\\>)*>\\s*)? # typeparameters\n \\(\\s*(([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\])|(\\.\\.\\.\\s*[_$[:alpha:]]))([^()]|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\)))*)?\\) # parameters\n (\\s*:\\s*([^<>\\(\\)]|\\<[^<>]+\\>|\\([^\\(\\)]+\\))+)? # return type\n \\s*=> # arrow operator\n)\n ))\n)) |\n# typeannotation is fn type: < | () | (... | (param: | (param, | (param? | (param= | (param) =>\n(:\\s*(\n (<) |\n ([(]\\s*(\n ([)]) |\n (\\.\\.\\.) |\n ([_$[:alnum:]]+\\s*(\n ([:,?=])|\n ([)]\\s*=>)\n ))\n ))\n)) |\n(:\\s*((<\\s*$)|([\\(]\\s*([\\{\\[]\\s*)?$))) |\n(:\\s*(=>|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(<[^<>]*>)|[^<>(),=])+=\\s*(\n ((async\\s+)?(\n (function\\s*[(<*]) |\n (function\\s+) |\n ([_$[:alpha:]][_$[:alnum:]]*\\s*=>)\n )) |\n ((async\\s*)?(\n ((<\\s*$)|([\\(]\\s*([\\{\\[]\\s*)?$)) |\n # sure shot arrow functions even if => is on new line\n(\n (<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<])*\\>)*>\\s*)?\n [(]\\s*\n (\n ([)]\\s*:) | # ():\n ((\\.\\.\\.\\s*)?[_$[:alpha:]][_$[:alnum:]]*\\s*:) # [(]param: | [(]...param:\n )\n) |\n(\n [<]\\s*[_$[:alpha:]][_$[:alnum:]]*\\s+extends\\s*[^=>] # < typeparam extends\n) |\n# arrow function possible to detect only with => on same line\n(\n (<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<])*\\>)*>\\s*)? # typeparameters\n \\(\\s*(([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\])|(\\.\\.\\.\\s*[_$[:alpha:]]))([^()]|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\)))*)?\\) # parameters\n (\\s*:\\s*([^<>\\(\\)]|\\<[^<>]+\\>|\\([^\\(\\)]+\\))+)? # return type\n \\s*=> # arrow operator\n)\n ))\n)))", + "beginCaptures": { + "1": { + "name": "meta.definition.variable.js variable.other.constant.js entity.name.function.js" + } + }, + "end": "(?=$|^|[;,=}]|(\\s+(of|in)\\s+))", + "patterns": [ + { + "include": "#var-single-variable-type-annotation" + } + ] + }, + { + "name": "meta.var-single-variable.expr.js", + "begin": "([_$[:alpha:]][_$[:alnum:]]*)", + "beginCaptures": { + "1": { + "name": "meta.definition.variable.js variable.other.constant.js" + } + }, + "end": "(?=$|^|[;,=}]|(\\s+(of|in)\\s+))", + "patterns": [ + { + "include": "#var-single-variable-type-annotation" + } + ] + } + ] + }, "var-single-variable-type-annotation": { "patterns": [ { @@ -435,6 +526,42 @@ } ] }, + "destructuring-const": { + "patterns": [ + { + "name": "meta.object-binding-pattern-variable.js", + "begin": "(?)\n )) |\n ((async\\s*)?(\n ((<\\s*$)|([\\(]\\s*([\\{\\[]\\s*)?$)) |\n # sure shot arrow functions even if => is on new line\n(\n (<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<])*\\>)*>\\s*)?\n [(]\\s*\n (\n ([)]\\s*:) | # ():\n ((\\.\\.\\.\\s*)?[_$[:alpha:]][_$[:alnum:]]*\\s*:) # [(]param: | [(]...param:\n )\n) |\n(\n [<]\\s*[_$[:alpha:]][_$[:alnum:]]*\\s+extends\\s*[^=>] # < typeparam extends\n) |\n# arrow function possible to detect only with => on same line\n(\n (<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<])*\\>)*>\\s*)? # typeparameters\n \\(\\s*(([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\])|(\\.\\.\\.\\s*[_$[:alpha:]]))([^()]|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\)))*)?\\) # parameters\n (\\s*:\\s*([^<>\\(\\)]|\\<[^<>]+\\>|\\([^\\(\\)]+\\))+)? # return type\n \\s*=> # arrow operator\n)\n ))\n)) |\n# typeannotation is fn type: < | () | (... | (param: | (param, | (param? | (param= | (param) =>\n(:\\s*(\n (<) |\n ([(]\\s*(\n ([)]) |\n (\\.\\.\\.) |\n ([_$[:alnum:]]+\\s*(\n ([:,?=])|\n ([)]\\s*=>)\n ))\n ))\n)) |\n(:\\s*((<\\s*$)|([\\(]\\s*([\\{\\[]\\s*)?$))) |\n(:\\s*(=>|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(<[^<>]*>)|[^<>(),=])+=\\s*(\n ((async\\s+)?(\n (function\\s*[(<*]) |\n (function\\s+) |\n ([_$[:alpha:]][_$[:alnum:]]*\\s*=>)\n )) |\n ((async\\s*)?(\n ((<\\s*$)|([\\(]\\s*([\\{\\[]\\s*)?$)) |\n # sure shot arrow functions even if => is on new line\n(\n (<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<])*\\>)*>\\s*)?\n [(]\\s*\n (\n ([)]\\s*:) | # ():\n ((\\.\\.\\.\\s*)?[_$[:alpha:]][_$[:alnum:]]*\\s*:) # [(]param: | [(]...param:\n )\n) |\n(\n [<]\\s*[_$[:alpha:]][_$[:alnum:]]*\\s+extends\\s*[^=>] # < typeparam extends\n) |\n# arrow function possible to detect only with => on same line\n(\n (<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<])*\\>)*>\\s*)? # typeparameters\n \\(\\s*(([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\])|(\\.\\.\\.\\s*[_$[:alpha:]]))([^()]|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\)))*)?\\) # parameters\n (\\s*:\\s*([^<>\\(\\)]|\\<[^<>]+\\>|\\([^\\(\\)]+\\))+)? # return type\n \\s*=> # arrow operator\n)\n ))\n)))", + "beginCaptures": { + "1": { + "name": "meta.definition.variable.js.jsx variable.other.constant.js.jsx entity.name.function.js.jsx" + } + }, + "end": "(?=$|^|[;,=}]|(\\s+(of|in)\\s+))", + "patterns": [ + { + "include": "#var-single-variable-type-annotation" + } + ] + }, + { + "name": "meta.var-single-variable.expr.js.jsx", + "begin": "([_$[:alpha:]][_$[:alnum:]]*)", + "beginCaptures": { + "1": { + "name": "meta.definition.variable.js.jsx variable.other.constant.js.jsx" + } + }, + "end": "(?=$|^|[;,=}]|(\\s+(of|in)\\s+))", + "patterns": [ + { + "include": "#var-single-variable-type-annotation" + } + ] + } + ] + }, "var-single-variable-type-annotation": { "patterns": [ { @@ -435,6 +526,42 @@ } ] }, + "destructuring-const": { + "patterns": [ + { + "name": "meta.object-binding-pattern-variable.js.jsx", + "begin": "(?)\n )) |\n ((async\\s*)?(\n ((<\\s*$)|((<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<])*\\>)*>\\s*)?[\\(]\\s*([\\{\\[]\\s*)?$)) |\n # sure shot arrow functions even if => is on new line\n(\n (<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<])*\\>)*>\\s*)?\n [(]\\s*\n (\n ([)]\\s*:) | # ():\n ((\\.\\.\\.\\s*)?[_$[:alpha:]][_$[:alnum:]]*\\s*:) # [(]param: | [(]...param:\n )\n) |\n(\n [<]\\s*[_$[:alpha:]][_$[:alnum:]]*\\s+extends\\s*[^=>] # < typeparam extends\n) |\n# arrow function possible to detect only with => on same line\n(\n (<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<])*\\>)*>\\s*)? # typeparameters\n \\(\\s*(([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\])|(\\.\\.\\.\\s*[_$[:alpha:]]))([^()]|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\)))*)?\\) # parameters\n (\\s*:\\s*([^<>\\(\\)]|\\<[^<>]+\\>|\\([^\\(\\)]+\\))+)? # return type\n \\s*=> # arrow operator\n)\n ))\n)) |\n# typeannotation is fn type: < | () | (... | (param: | (param, | (param? | (param= | (param) =>\n(:\\s*(\n (<) |\n ([(]\\s*(\n ([)]) |\n (\\.\\.\\.) |\n ([_$[:alnum:]]+\\s*(\n ([:,?=])|\n ([)]\\s*=>)\n ))\n ))\n)) |\n(:\\s*((<\\s*$)|((<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<])*\\>)*>\\s*)?[\\(]\\s*([\\{\\[]\\s*)?$))) |\n(:\\s*(=>|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(<[^<>]*>)|[^<>(),=])+=\\s*(\n ((async\\s+)?(\n (function\\s*[(<*]) |\n (function\\s+) |\n ([_$[:alpha:]][_$[:alnum:]]*\\s*=>)\n )) |\n ((async\\s*)?(\n ((<\\s*$)|((<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<])*\\>)*>\\s*)?[\\(]\\s*([\\{\\[]\\s*)?$)) |\n # sure shot arrow functions even if => is on new line\n(\n (<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<])*\\>)*>\\s*)?\n [(]\\s*\n (\n ([)]\\s*:) | # ():\n ((\\.\\.\\.\\s*)?[_$[:alpha:]][_$[:alnum:]]*\\s*:) # [(]param: | [(]...param:\n )\n) |\n(\n [<]\\s*[_$[:alpha:]][_$[:alnum:]]*\\s+extends\\s*[^=>] # < typeparam extends\n) |\n# arrow function possible to detect only with => on same line\n(\n (<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<])*\\>)*>\\s*)? # typeparameters\n \\(\\s*(([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\])|(\\.\\.\\.\\s*[_$[:alpha:]]))([^()]|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\)))*)?\\) # parameters\n (\\s*:\\s*([^<>\\(\\)]|\\<[^<>]+\\>|\\([^\\(\\)]+\\))+)? # return type\n \\s*=> # arrow operator\n)\n ))\n)))", + "beginCaptures": { + "1": { + "name": "meta.definition.variable.ts variable.other.constant.ts entity.name.function.ts" + } + }, + "end": "(?=$|^|[;,=}]|(\\s+(of|in)\\s+))", + "patterns": [ + { + "include": "#var-single-variable-type-annotation" + } + ] + }, + { + "name": "meta.var-single-variable.expr.ts", + "begin": "([_$[:alpha:]][_$[:alnum:]]*)", + "beginCaptures": { + "1": { + "name": "meta.definition.variable.ts variable.other.constant.ts" + } + }, + "end": "(?=$|^|[;,=}]|(\\s+(of|in)\\s+))", + "patterns": [ + { + "include": "#var-single-variable-type-annotation" + } + ] + } + ] + }, "var-single-variable-type-annotation": { "patterns": [ { @@ -432,6 +523,42 @@ } ] }, + "destructuring-const": { + "patterns": [ + { + "name": "meta.object-binding-pattern-variable.ts", + "begin": "(?)\n )) |\n ((async\\s*)?(\n ((<\\s*$)|([\\(]\\s*([\\{\\[]\\s*)?$)) |\n # sure shot arrow functions even if => is on new line\n(\n (<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<])*\\>)*>\\s*)?\n [(]\\s*\n (\n ([)]\\s*:) | # ():\n ((\\.\\.\\.\\s*)?[_$[:alpha:]][_$[:alnum:]]*\\s*:) # [(]param: | [(]...param:\n )\n) |\n(\n [<]\\s*[_$[:alpha:]][_$[:alnum:]]*\\s+extends\\s*[^=>] # < typeparam extends\n) |\n# arrow function possible to detect only with => on same line\n(\n (<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<])*\\>)*>\\s*)? # typeparameters\n \\(\\s*(([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\])|(\\.\\.\\.\\s*[_$[:alpha:]]))([^()]|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\)))*)?\\) # parameters\n (\\s*:\\s*([^<>\\(\\)]|\\<[^<>]+\\>|\\([^\\(\\)]+\\))+)? # return type\n \\s*=> # arrow operator\n)\n ))\n)) |\n# typeannotation is fn type: < | () | (... | (param: | (param, | (param? | (param= | (param) =>\n(:\\s*(\n (<) |\n ([(]\\s*(\n ([)]) |\n (\\.\\.\\.) |\n ([_$[:alnum:]]+\\s*(\n ([:,?=])|\n ([)]\\s*=>)\n ))\n ))\n)) |\n(:\\s*((<\\s*$)|([\\(]\\s*([\\{\\[]\\s*)?$))) |\n(:\\s*(=>|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(<[^<>]*>)|[^<>(),=])+=\\s*(\n ((async\\s+)?(\n (function\\s*[(<*]) |\n (function\\s+) |\n ([_$[:alpha:]][_$[:alnum:]]*\\s*=>)\n )) |\n ((async\\s*)?(\n ((<\\s*$)|([\\(]\\s*([\\{\\[]\\s*)?$)) |\n # sure shot arrow functions even if => is on new line\n(\n (<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<])*\\>)*>\\s*)?\n [(]\\s*\n (\n ([)]\\s*:) | # ():\n ((\\.\\.\\.\\s*)?[_$[:alpha:]][_$[:alnum:]]*\\s*:) # [(]param: | [(]...param:\n )\n) |\n(\n [<]\\s*[_$[:alpha:]][_$[:alnum:]]*\\s+extends\\s*[^=>] # < typeparam extends\n) |\n# arrow function possible to detect only with => on same line\n(\n (<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<])*\\>)*>\\s*)? # typeparameters\n \\(\\s*(([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\])|(\\.\\.\\.\\s*[_$[:alpha:]]))([^()]|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\)))*)?\\) # parameters\n (\\s*:\\s*([^<>\\(\\)]|\\<[^<>]+\\>|\\([^\\(\\)]+\\))+)? # return type\n \\s*=> # arrow operator\n)\n ))\n)))", + "beginCaptures": { + "1": { + "name": "meta.definition.variable.tsx variable.other.constant.tsx entity.name.function.tsx" + } + }, + "end": "(?=$|^|[;,=}]|(\\s+(of|in)\\s+))", + "patterns": [ + { + "include": "#var-single-variable-type-annotation" + } + ] + }, + { + "name": "meta.var-single-variable.expr.tsx", + "begin": "([_$[:alpha:]][_$[:alnum:]]*)", + "beginCaptures": { + "1": { + "name": "meta.definition.variable.tsx variable.other.constant.tsx" + } + }, + "end": "(?=$|^|[;,=}]|(\\s+(of|in)\\s+))", + "patterns": [ + { + "include": "#var-single-variable-type-annotation" + } + ] + } + ] + }, "var-single-variable-type-annotation": { "patterns": [ { @@ -435,6 +526,42 @@ } ] }, + "destructuring-const": { + "patterns": [ + { + "name": "meta.object-binding-pattern-variable.tsx", + "begin": "(? Date: Fri, 27 Jul 2018 10:58:52 +0200 Subject: [PATCH 0217/1276] update html grammar --- extensions/html/syntaxes/html.tmLanguage.json | 3122 +++++++++++++---- .../test/colorize-results/12750_html.json | 40 +- .../test/colorize-results/13448_html.json | 103 +- .../test/colorize-results/25920_html.json | 188 +- .../html/test/colorize-results/test_html.json | 403 ++- 5 files changed, 2818 insertions(+), 1038 deletions(-) diff --git a/extensions/html/syntaxes/html.tmLanguage.json b/extensions/html/syntaxes/html.tmLanguage.json index 6b9b1f58e7d..31f584840f6 100644 --- a/extensions/html/syntaxes/html.tmLanguage.json +++ b/extensions/html/syntaxes/html.tmLanguage.json @@ -4,12 +4,12 @@ "If you want to provide a fix or improvement, please create a pull request against the original repository.", "Once accepted there, we are happy to receive an update request." ], - "version": "https://github.com/textmate/html.tmbundle/commit/a723f08ebd49c67c22aca08dd8f17d0bf836ec93", + "version": "https://github.com/textmate/html.tmbundle/commit/6a6fb2967e2f562a634fca97d18018104d428f1c", "name": "HTML", "scopeName": "text.html.basic", "injections": { - "R:text.html - (comment.block, text.html source)": { - "comment": "Use R: to ensure this matches after any other injections.", + "R:text.html - (comment.block, text.html meta.embedded, meta.tag.*.*.html, meta.tag.*.*.*.html, meta.tag.*.*.*.*.html)": { + "comment": "Uses R: to ensure this matches after any other injections.", "patterns": [ { "match": "<", @@ -19,38 +19,6 @@ } }, "patterns": [ - { - "begin": "(<)([a-zA-Z][a-zA-Z0-9:-]*)(?=[^>]*>)", - "beginCaptures": { - "1": { - "name": "punctuation.definition.tag.html" - }, - "2": { - "name": "entity.name.tag.html" - } - }, - "end": "(>(<)/)(\\2)(>)", - "endCaptures": { - "1": { - "name": "punctuation.definition.tag.html" - }, - "2": { - "name": "meta.scope.between-tag-pair.html" - }, - "3": { - "name": "entity.name.tag.html" - }, - "4": { - "name": "punctuation.definition.tag.html" - } - }, - "name": "meta.tag.any.html", - "patterns": [ - { - "include": "#tag-stuff" - } - ] - }, { "begin": "(<\\?)(xml)", "captures": { @@ -58,481 +26,463 @@ "name": "punctuation.definition.tag.html" }, "2": { - "name": "entity.name.tag.xml.html" + "name": "entity.name.tag.html" } }, "end": "(\\?>)", - "name": "meta.tag.preprocessor.xml.html", + "name": "meta.tag.metadata.processing.xml.html", "patterns": [ { - "include": "#tag-generic-attribute" - }, - { - "include": "#string-double-quoted" - }, - { - "include": "#string-single-quoted" + "include": "#attribute" } ] }, { + "include": "#comment" + }, + { + "begin": "", + "endCaptures": { + "0": { + "name": "punctuation.definition.tag.end.html" + } + }, + "name": "meta.tag.metadata.doctype.html", + "patterns": [ + { + "match": "\\G(?i:DOCTYPE)", + "name": "entity.name.tag.html" + }, + { + "begin": "\"", + "end": "\"", + "name": "string.quoted.double.html" + }, + { + "match": "[^\\s>]+", + "name": "entity.other.attribute-name.html" + } + ] + }, + { + "include": "#cdata" + }, + { + "include": "#tags-valid" + }, + { + "include": "#tags-invalid" + }, + { + "include": "#entities" + } + ], + "repository": { + "attribute": { + "patterns": [ + { + "begin": "(s(hape|cope|t(ep|art)|ize(s)?|p(ellcheck|an)|elected|lot|andbox|rc(set|doc|lang)?)|h(ttp-equiv|i(dden|gh)|e(ight|aders)|ref(lang)?)|n(o(nce|validate|module)|ame)|c(h(ecked|arset)|ite|o(nt(ent(editable)?|rols)|ords|l(s(pan)?|or))|lass|rossorigin)|t(ype(mustmatch)?|itle|a(rget|bindex)|ranslate)|i(s(map)?|n(tegrity|putmode)|tem(scope|type|id|prop|ref)|d)|op(timum|en)|d(i(sabled|r(name)?)|ownload|e(coding|f(er|ault))|at(etime|a)|raggable)|usemap|p(ing|oster|la(ysinline|ceholder)|attern|reload)|enctype|value|kind|for(m(novalidate|target|enctype|action|method)?)?|w(idth|rap)|l(ist|o(op|w)|a(ng|bel))|a(s(ync)?|c(ce(sskey|pt(-charset)?)|tion)|uto(c(omplete|apitalize)|play|focus)|l(t|low(usermedia|paymentrequest|fullscreen))|bbr)|r(ows(pan)?|e(versed|quired|ferrerpolicy|l|adonly))|m(in(length)?|u(ted|ltiple)|e(thod|dia)|a(nifest|x(length)?)))(?![\\w:-])", + "beginCaptures": { + "0": { + "name": "entity.other.attribute-name.html" + } + }, + "comment": "HTML5 attributes, not event handlers", + "end": "(?=\\s*+[^=\\s])", + "name": "meta.attribute.$1.html", + "patterns": [ + { + "include": "#attribute-interior" + } + ] + }, + { + "begin": "style(?![\\w:-])", + "beginCaptures": { + "0": { + "name": "entity.other.attribute-name.html" + } + }, + "comment": "HTML5 style attribute", + "end": "(?=\\s*+[^=\\s])", + "name": "meta.attribute.style.html", + "patterns": [ + { + "begin": "=", + "beginCaptures": { + "0": { + "name": "punctuation.separator.key-value.html" + } + }, + "end": "(?<=[^\\s=])(?!\\s*=)|(?=/?>)", + "patterns": [ + { + "begin": "(?=[^\\s=<>`/]|/(?!>))", + "end": "(?!\\G)", + "name": "meta.embedded.line.css", + "patterns": [ + { + "captures": { + "0": { + "name": "source.css" + } + }, + "match": "([^\\s\"'=<>`/]|/(?!>))+", + "name": "string.unquoted.html" + }, + { + "begin": "\"", + "beginCaptures": { + "0": { + "name": "punctuation.definition.string.begin.html" + } + }, + "contentName": "source.css", + "end": "(\")", + "endCaptures": { + "0": { + "name": "punctuation.definition.string.end.html" + }, + "1": { + "name": "source.css" + } + }, + "name": "string.quoted.double.html", + "patterns": [ + { + "include": "#entities" + } + ] + }, + { + "begin": "'", + "beginCaptures": { + "0": { + "name": "punctuation.definition.string.begin.html" + } + }, + "contentName": "source.css", + "end": "(')", + "endCaptures": { + "0": { + "name": "punctuation.definition.string.end.html" + }, + "1": { + "name": "source.css" + } + }, + "name": "string.quoted.single.html", + "patterns": [ + { + "include": "#entities" + } + ] + } + ] + }, + { + "match": "=", + "name": "invalid.illegal.unexpected-equals-sign.html" + } + ] + } + ] + }, + { + "begin": "on(s(croll|t(orage|alled)|u(spend|bmit)|e(curitypolicyviolation|ek(ing|ed)|lect))|hashchange|c(hange|o(ntextmenu|py)|u(t|echange)|l(ick|ose)|an(cel|play(through)?))|t(imeupdate|oggle)|in(put|valid)|o(nline|ffline)|d(urationchange|r(op|ag(start|over|e(n(ter|d)|xit)|leave)?)|blclick)|un(handledrejection|load)|p(opstate|lay(ing)?|a(ste|use|ge(show|hide))|rogress)|e(nded|rror|mptied)|volumechange|key(down|up|press)|focus|w(heel|aiting)|l(oad(start|e(nd|d(data|metadata)))?|anguagechange)|a(uxclick|fterprint|bort)|r(e(s(ize|et)|jectionhandled)|atechange)|m(ouse(o(ut|ver)|down|up|enter|leave|move)|essage(error)?)|b(efore(unload|print)|lur))(?![\\w:-])", + "beginCaptures": { + "0": { + "name": "entity.other.attribute-name.html" + } + }, + "comment": "HTML5 attributes, event handlers", + "end": "(?=\\s*+[^=\\s])", + "name": "meta.attribute.event-handler.$1.html", + "patterns": [ + { + "begin": "=", + "beginCaptures": { + "0": { + "name": "punctuation.separator.key-value.html" + } + }, + "end": "(?<=[^\\s=])(?!\\s*=)|(?=/?>)", + "patterns": [ + { + "begin": "(?=[^\\s=<>`/]|/(?!>))", + "end": "(?!\\G)", + "name": "meta.embedded.line.js", + "patterns": [ + { + "captures": { + "0": { + "name": "source.js" + }, + "1": { + "patterns": [ + { + "include": "source.js" + } + ] + } + }, + "match": "(([^\\s\"'=<>`/]|/(?!>))+)", + "name": "string.unquoted.html" + }, + { + "begin": "\"", + "beginCaptures": { + "0": { + "name": "punctuation.definition.string.begin.html" + } + }, + "contentName": "source.js", + "end": "(\")", + "endCaptures": { + "0": { + "name": "punctuation.definition.string.end.html" + }, + "1": { + "name": "source.js" + } + }, + "name": "string.quoted.double.html", + "patterns": [ + { + "captures": { + "0": { + "patterns": [ + { + "include": "source.js" + } + ] + } + }, + "match": "[^\\n\"]+" + } + ] + }, + { + "begin": "'", + "beginCaptures": { + "0": { + "name": "punctuation.definition.string.begin.html" + } + }, + "contentName": "source.js", + "end": "(')", + "endCaptures": { + "0": { + "name": "punctuation.definition.string.end.html" + }, + "1": { + "name": "source.js" + } + }, + "name": "string.quoted.single.html", + "patterns": [ + { + "captures": { + "0": { + "patterns": [ + { + "include": "source.js" + } + ] + } + }, + "match": "[^\\n']+" + } + ] + } + ] + }, + { + "match": "=", + "name": "invalid.illegal.unexpected-equals-sign.html" + } + ] + } + ] + }, + { + "begin": "(data-[a-z\\-]+)(?![\\w:-])", + "beginCaptures": { + "0": { + "name": "entity.other.attribute-name.html" + } + }, + "comment": "HTML5 attributes, data-*", + "end": "(?=\\s*+[^=\\s])", + "name": "meta.attribute.data-x.$1.html", + "patterns": [ + { + "include": "#attribute-interior" + } + ] + }, + { + "begin": "(align|bgcolor|border)(?![\\w:-])", + "beginCaptures": { + "0": { + "name": "invalid.deprecated.entity.other.attribute-name.html" + } + }, + "comment": "HTML attributes, deprecated", + "end": "(?=\\s*+[^=\\s])", + "name": "meta.attribute.$1.html", + "patterns": [ + { + "include": "#attribute-interior" + } + ] + }, + { + "begin": "([^\\x{0020}\"'<>/=\\x{0000}-\\x{001F}\\x{007F}-\\x{009F}\\x{FDD0}-\\x{FDEF}\\x{FFFE}\\x{FFFF}\\x{1FFFE}\\x{1FFFF}\\x{2FFFE}\\x{2FFFF}\\x{3FFFE}\\x{3FFFF}\\x{4FFFE}\\x{4FFFF}\\x{5FFFE}\\x{5FFFF}\\x{6FFFE}\\x{6FFFF}\\x{7FFFE}\\x{7FFFF}\\x{8FFFE}\\x{8FFFF}\\x{9FFFE}\\x{9FFFF}\\x{AFFFE}\\x{AFFFF}\\x{BFFFE}\\x{BFFFF}\\x{CFFFE}\\x{CFFFF}\\x{DFFFE}\\x{DFFFF}\\x{EFFFE}\\x{EFFFF}\\x{FFFFE}\\x{FFFFF}\\x{10FFFE}\\x{10FFFF}]+)", + "beginCaptures": { + "0": { + "name": "entity.other.attribute-name.html" + } + }, + "comment": "Anything else that is valid", + "end": "(?=\\s*+[^=\\s])", + "name": "meta.attribute.unrecognized.$1.html", + "patterns": [ + { + "include": "#attribute-interior" + } + ] + }, + { + "match": "[^\\s>]+", + "name": "invalid.illegal.character-not-allowed-here.html" + } + ] + }, + "attribute-interior": { + "patterns": [ + { + "begin": "=", + "beginCaptures": { + "0": { + "name": "punctuation.separator.key-value.html" + } + }, + "end": "(?<=[^\\s=])(?!\\s*=)|(?=/?>)", + "patterns": [ + { + "match": "([^\\s\"'=<>`/]|/(?!>))+", + "name": "string.unquoted.html" + }, + { + "begin": "\"", + "beginCaptures": { + "0": { + "name": "punctuation.definition.string.begin.html" + } + }, + "end": "\"", + "endCaptures": { + "0": { + "name": "punctuation.definition.string.end.html" + } + }, + "name": "string.quoted.double.html", + "patterns": [ + { + "include": "#entities" + } + ] + }, + { + "begin": "'", + "beginCaptures": { + "0": { + "name": "punctuation.definition.string.begin.html" + } + }, + "end": "'", + "endCaptures": { + "0": { + "name": "punctuation.definition.string.end.html" + } + }, + "name": "string.quoted.single.html", + "patterns": [ + { + "include": "#entities" + } + ] + }, + { + "match": "=", + "name": "invalid.illegal.unexpected-equals-sign.html" + } + ] + } + ] + }, + "cdata": { + "begin": "", + "endCaptures": { + "0": { + "name": "punctuation.definition.tag.end.html" + } + }, + "name": "meta.tag.metadata.cdata.html" + }, + "comment": { "begin": "", "name": "comment.block.html", "patterns": [ { - "match": "--", - "name": "invalid.illegal.bad-comments-or-CDATA.html" + "match": "\\G-?>", + "name": "invalid.illegal.characters-not-allowed-here.html" }, { - "include": "#embedded-code" - } - ] - }, - { - "begin": "", - "name": "meta.tag.sgml.html", - "patterns": [ - { - "begin": "(?i:DOCTYPE)", - "captures": { - "1": { - "name": "entity.name.tag.doctype.html" - } - }, - "end": "(?=>)", - "name": "meta.tag.sgml.doctype.html", - "patterns": [ - { - "match": "\"[^\">]*\"", - "name": "string.quoted.double.doctype.identifiers-and-DTDs.html" - } - ] + "match": ")", + "name": "invalid.illegal.characters-not-allowed-here.html" }, { - "begin": "\\[CDATA\\[", - "end": "]](?=>)", - "name": "constant.other.inline-data.html" - }, - { - "match": "(\\s*)(?!--|>)\\S(\\s*)", - "name": "invalid.illegal.bad-comments-or-CDATA.html" - } - ] - }, - { - "include": "#embedded-code" - }, - { - "begin": "(^[ \\t]+)?(?=<(?i:style))", - "beginCaptures": { - "1": { - "name": "punctuation.whitespace.embedded.leading.html" - } - }, - "end": "(?!\\G)([ \\t]*$\\n?)?", - "endCaptures": { - "1": { - "name": "punctuation.whitespace.embedded.trailing.html" - } - }, - "patterns": [ - { - "begin": "(<)((?i:style))\\b", - "beginCaptures": { - "0": { - "name": "meta.tag.metadata.style.html" - }, - "1": { - "name": "punctuation.definition.tag.begin.html" - }, - "2": { - "name": "entity.name.tag.html" - } - }, - "end": "(/>)|((<)/)((?i:style))(>)", - "endCaptures": { - "0": { - "name": "meta.tag.metadata.style.html" - }, - "1": { - "name": "punctuation.definition.tag.end.html" - }, - "2": { - "name": "punctuation.definition.tag.begin.html" - }, - "3": { - "name": "source.css" - }, - "4": { - "name": "entity.name.tag.html" - }, - "5": { - "name": "punctuation.definition.tag.end.html" - } - }, - "name": "meta.embedded.block.html", - "patterns": [ - { - "begin": "\\G", - "captures": { - "1": { - "name": "punctuation.definition.tag.end.html" - } - }, - "end": "(?=/>)|(>)", - "name": "meta.tag.metadata.style.html", - "patterns": [ - { - "include": "#tag-stuff" - } - ] - }, - { - "begin": "(?!\\G)", - "end": "(?=)|(/)((?i:script))(>)", - "endCaptures": { - "0": { - "name": "meta.tag.metadata.script.html" - }, - "1": { - "name": "punctuation.definition.tag.end.html" - }, - "2": { - "name": "punctuation.definition.tag.begin.html" - }, - "3": { - "name": "entity.name.tag.html" - }, - "4": { - "name": "punctuation.definition.tag.end.html" - } - }, - "name": "meta.embedded.block.html", - "patterns": [ - { - "begin": "\\G", - "end": "(?=/>|/)", - "patterns": [ - { - "begin": "(>)", - "beginCaptures": { - "0": { - "name": "meta.tag.metadata.script.html" - }, - "1": { - "name": "punctuation.definition.tag.end.html" - } - }, - "end": "((<))(?=/(?i:script))", - "endCaptures": { - "0": { - "name": "meta.tag.metadata.script.html" - }, - "1": { - "name": "punctuation.definition.tag.begin.html" - }, - "2": { - "name": "source.js" - } - }, - "patterns": [ - { - "begin": "\\G", - "end": "(?=|type(?=[\\s=])(?!\\s*=\\s*('|\"|)(text/(javascript|ecmascript|babel)|application/((x-)?javascript|ecmascript|babel)|module)[\\s\"'>])))", - "name": "meta.tag.metadata.script.html", - "patterns": [ - { - "include": "#tag-stuff" - } - ] - }, - { - "begin": "(?=(?i:type\\s*=\\s*('|\"|)(text/(x-handlebars|(x-(handlebars-)?|ng-)?template|html)[\\s\"'>])))", - "end": "((<))(?=/(?i:script))", - "endCaptures": { - "0": { - "name": "meta.tag.metadata.script.html" - }, - "1": { - "name": "punctuation.definition.tag.begin.html" - }, - "2": { - "name": "text.html.basic" - } - }, - "patterns": [ - { - "begin": "\\G", - "end": "(>)|(?=/>)", - "endCaptures": { - "1": { - "name": "punctuation.definition.tag.end.html" - } - }, - "name": "meta.tag.metadata.script.html", - "patterns": [ - { - "include": "#tag-stuff" - } - ] - }, - { - "begin": "(?!\\G)", - "end": "(?=)|(?=/>)", - "endCaptures": { - "1": { - "name": "punctuation.definition.tag.end.html" - } - }, - "name": "meta.tag.metadata.script.html", - "patterns": [ - { - "include": "#tag-stuff" - } - ] - }, - { - "begin": "(?!\\G)", - "end": "(?=)", - "name": "meta.tag.structure.any.html", - "patterns": [ - { - "include": "#tag-stuff" - } - ] - }, - { - "begin": "()", - "endCaptures": { - "1": { - "name": "punctuation.definition.tag.end.html" - } - }, - "name": "meta.tag.block.any.html", - "patterns": [ - { - "include": "#tag-stuff" - } - ] - }, - { - "begin": "()", - "endCaptures": { - "1": { - "name": "punctuation.definition.tag.end.html" - } - }, - "name": "meta.tag.inline.any.html", - "patterns": [ - { - "include": "#tag-stuff" - } - ] - }, - { - "begin": "()", - "endCaptures": { - "1": { - "name": "punctuation.definition.tag.end.html" - } - }, - "name": "meta.tag.other.html", - "patterns": [ - { - "include": "#tag-stuff" - } - ] - }, - { - "include": "#entities" - }, - { - "match": "<>", - "name": "invalid.illegal.incomplete.html" - } - ], - "repository": { - "embedded-code": { - "patterns": [ - { - "include": "#smarty" - }, - { - "include": "#python" + "match": "--!>", + "name": "invalid.illegal.characters-not-allowed-here.html" } ] }, "entities": { "patterns": [ + { + "captures": { + "1": { + "name": "punctuation.definition.entity.html" + }, + "912": { + "name": "punctuation.definition.entity.html" + } + }, + "comment": "Yes this is a bit ridiculous, there are quite a lot of these", + "match": "(?x)\n\t\t\t\t\t\t(&)\t(?=[a-zA-Z])\n\t\t\t\t\t\t(\n\t\t\t\t\t\t\t(a(s(ymp(eq)?|cr|t)|n(d(slope|d|v|and)?|g(s(t|ph)|zarr|e|le|rt(vb(d)?)?|msd(a(h|c|d|e|f|a|g|b))?)?)|c(y|irc|d|ute|E)?|tilde|o(pf|gon)|uml|p(id|os|prox(eq)?|e|E|acir)?|elig|f(r)?|w(conint|int)|l(pha|e(ph|fsym))|acute|ring|grave|m(p|a(cr|lg))|breve)|A(s(sign|cr)|nd|MP|c(y|irc)|tilde|o(pf|gon)|uml|pplyFunction|fr|Elig|lpha|acute|ring|grave|macr|breve))\n\t\t\t\t\t\t | (B(scr|cy|opf|umpeq|e(cause|ta|rnoullis)|fr|a(ckslash|r(v|wed))|reve)|b(s(cr|im(e)?|ol(hsub|b)?|emi)|n(ot|e(quiv)?)|c(y|ong)|ig(s(tar|qcup)|c(irc|up|ap)|triangle(down|up)|o(times|dot|plus)|uplus|vee|wedge)|o(t(tom)?|pf|wtie|x(h(d|u|D|U)?|times|H(d|u|D|U)?|d(R|l|r|L)|u(R|l|r|L)|plus|D(R|l|r|L)|v(R|h|H|l|r|L)?|U(R|l|r|L)|V(R|h|H|l|r|L)?|minus|box))|Not|dquo|u(ll(et)?|mp(e(q)?|E)?)|prime|e(caus(e)?|t(h|ween|a)|psi|rnou|mptyv)|karow|fr|l(ock|k(1(2|4)|34)|a(nk|ck(square|triangle(down|left|right)?|lozenge)))|a(ck(sim(eq)?|cong|prime|epsilon)|r(vee|wed(ge)?))|r(eve|vbar)|brk(tbrk)?))\n\t\t\t\t\t\t | (c(s(cr|u(p(e)?|b(e)?))|h(cy|i|eck(mark)?)|ylcty|c(irc|ups(sm)?|edil|a(ps|ron))|tdot|ir(scir|c(eq|le(d(R|circ|S|dash|ast)|arrow(left|right)))?|e|fnint|E|mid)?|o(n(int|g(dot)?)|p(y(sr)?|f|rod)|lon(e(q)?)?|m(p(fn|le(xes|ment))?|ma(t)?))|dot|u(darr(l|r)|p(s|c(up|ap)|or|dot|brcap)?|e(sc|pr)|vee|wed|larr(p)?|r(vearrow(left|right)|ly(eq(succ|prec)|vee|wedge)|arr(m)?|ren))|e(nt(erdot)?|dil|mptyv)|fr|w(conint|int)|lubs(uit)?|a(cute|p(s|c(up|ap)|dot|and|brcup)?|r(on|et))|r(oss|arr))|C(scr|hi|c(irc|onint|edil|aron)|ircle(Minus|Times|Dot|Plus)|Hcy|o(n(tourIntegral|int|gruent)|unterClockwiseContourIntegral|p(f|roduct)|lon(e)?)|dot|up(Cap)?|OPY|e(nterDot|dilla)|fr|lo(seCurly(DoubleQuote|Quote)|ckwiseContourIntegral)|a(yleys|cute|p(italDifferentialD)?)|ross))\n\t\t\t\t\t\t | (d(s(c(y|r)|trok|ol)|har(l|r)|c(y|aron)|t(dot|ri(f)?)|i(sin|e|v(ide(ontimes)?|onx)?|am(s|ond(suit)?)?|gamma)|Har|z(cy|igrarr)|o(t(square|plus|eq(dot)?|minus)?|ublebarwedge|pf|wn(harpoon(left|right)|downarrows|arrow)|llar)|d(otseq|a(rr|gger))?|u(har|arr)|jcy|e(lta|g|mptyv)|f(isht|r)|wangle|lc(orn|rop)|a(sh(v)?|leth|rr|gger)|r(c(orn|rop)|bkarow)|b(karow|lac)|Arr)|D(s(cr|trok)|c(y|aron)|Scy|i(fferentialD|a(critical(Grave|Tilde|Do(t|ubleAcute)|Acute)|mond))|o(t(Dot|Equal)?|uble(Right(Tee|Arrow)|ContourIntegral|Do(t|wnArrow)|Up(DownArrow|Arrow)|VerticalBar|L(ong(RightArrow|Left(RightArrow|Arrow))|eft(RightArrow|Tee|Arrow)))|pf|wn(Right(TeeVector|Vector(Bar)?)|Breve|Tee(Arrow)?|arrow|Left(RightVector|TeeVector|Vector(Bar)?)|Arrow(Bar|UpArrow)?))|Zcy|el(ta)?|D(otrahd)?|Jcy|fr|a(shv|rr|gger)))\n\t\t\t\t\t\t | (e(s(cr|im|dot)|n(sp|g)|c(y|ir(c)?|olon|aron)|t(h|a)|o(pf|gon)|dot|u(ro|ml)|p(si(v|lon)?|lus|ar(sl)?)|e|D(ot|Dot)|q(s(im|lant(less|gtr))|c(irc|olon)|u(iv(DD)?|est|als)|vparsl)|f(Dot|r)|l(s(dot)?|inters|l)?|a(ster|cute)|r(Dot|arr)|g(s(dot)?|rave)?|x(cl|ist|p(onentiale|ectation))|m(sp(1(3|4))?|pty(set|v)?|acr))|E(s(cr|im)|c(y|irc|aron)|ta|o(pf|gon)|NG|dot|uml|TH|psilon|qu(ilibrium|al(Tilde)?)|fr|lement|acute|grave|x(ists|ponentialE)|m(pty(SmallSquare|VerySmallSquare)|acr)))\n\t\t\t\t\t\t | (f(scr|nof|cy|ilig|o(pf|r(k(v)?|all))|jlig|partint|emale|f(ilig|l(ig|lig)|r)|l(tns|lig|at)|allingdotseq|r(own|a(sl|c(1(2|8|3|4|5|6)|78|2(3|5)|3(8|4|5)|45|5(8|6)))))|F(scr|cy|illed(SmallSquare|VerySmallSquare)|o(uriertrf|pf|rAll)|fr))\n\t\t\t\t\t\t | (G(scr|c(y|irc|edil)|t|opf|dot|T|Jcy|fr|amma(d)?|reater(Greater|SlantEqual|Tilde|Equal(Less)?|FullEqual|Less)|g|breve)|g(s(cr|im(e|l)?)|n(sim|e(q(q)?)?|E|ap(prox)?)|c(y|irc)|t(c(c|ir)|dot|quest|lPar|r(sim|dot|eq(qless|less)|less|a(pprox|rr)))?|imel|opf|dot|jcy|e(s(cc|dot(o(l)?)?|l(es)?)?|q(slant|q)?|l)?|v(nE|ertneqq)|fr|E(l)?|l(j|E|a)?|a(cute|p|mma(d)?)|rave|g(g)?|breve))\n\t\t\t\t\t\t | (h(s(cr|trok|lash)|y(phen|bull)|circ|o(ok(leftarrow|rightarrow)|pf|arr|rbar|mtht)|e(llip|arts(uit)?|rcon)|ks(earow|warow)|fr|a(irsp|lf|r(dcy|r(cir|w)?)|milt)|bar|Arr)|H(s(cr|trok)|circ|ilbertSpace|o(pf|rizontalLine)|ump(DownHump|Equal)|fr|a(cek|t)|ARDcy))\n\t\t\t\t\t\t | (i(s(cr|in(s(v)?|dot|v|E)?)|n(care|t(cal|prod|e(rcal|gers)|larhk)?|odot|fin(tie)?)?|c(y|irc)?|t(ilde)?|i(nfin|i(nt|int)|ota)?|o(cy|ta|pf|gon)|u(kcy|ml)|jlig|prod|e(cy|xcl)|quest|f(f|r)|acute|grave|m(of|ped|a(cr|th|g(part|e|line))))|I(scr|n(t(e(rsection|gral))?|visible(Comma|Times))|c(y|irc)|tilde|o(ta|pf|gon)|dot|u(kcy|ml)|Ocy|Jlig|fr|Ecy|acute|grave|m(plies|a(cr|ginaryI))?))\n\t\t\t\t\t\t | (j(s(cr|ercy)|c(y|irc)|opf|ukcy|fr|math)|J(s(cr|ercy)|c(y|irc)|opf|ukcy|fr))\n\t\t\t\t\t\t | (k(scr|hcy|c(y|edil)|opf|jcy|fr|appa(v)?|green)|K(scr|c(y|edil)|Hcy|opf|Jcy|fr|appa))\n\t\t\t\t\t\t | (l(s(h|cr|trok|im(e|g)?|q(uo(r)?|b)|aquo)|h(ar(d|u(l)?)|blk)|n(sim|e(q(q)?)?|E|ap(prox)?)|c(y|ub|e(il|dil)|aron)|Barr|t(hree|c(c|ir)|imes|dot|quest|larr|r(i(e|f)?|Par))?|Har|o(ng(left(arrow|rightarrow)|rightarrow|mapsto)|times|z(enge|f)?|oparrow(left|right)|p(f|lus|ar)|w(ast|bar)|a(ng|rr)|brk)|d(sh|ca|quo(r)?|r(dhar|ushar))|ur(dshar|uhar)|jcy|par(lt)?|e(s(s(sim|dot|eq(qgtr|gtr)|approx|gtr)|cc|dot(o(r)?)?|g(es)?)?|q(slant|q)?|ft(harpoon(down|up)|threetimes|leftarrows|arrow(tail)?|right(squigarrow|harpoons|arrow(s)?))|g)?|v(nE|ertneqq)|f(isht|loor|r)|E(g)?|l(hard|corner|tri|arr)?|a(ng(d|le)?|cute|t(e(s)?|ail)?|p|emptyv|quo|rr(sim|hk|tl|pl|fs|lp|b(fs)?)?|gran|mbda)|r(har(d)?|corner|tri|arr|m)|g(E)?|m(idot|oust(ache)?)|b(arr|r(k(sl(d|u)|e)|ac(e|k))|brk)|A(tail|arr|rr))|L(s(h|cr|trok)|c(y|edil|aron)|t|o(ng(RightArrow|left(arrow|rightarrow)|rightarrow|Left(RightArrow|Arrow))|pf|wer(RightArrow|LeftArrow))|T|e(ss(Greater|SlantEqual|Tilde|EqualGreater|FullEqual|Less)|ft(Right(Vector|Arrow)|Ceiling|T(ee(Vector|Arrow)?|riangle(Bar|Equal)?)|Do(ubleBracket|wn(TeeVector|Vector(Bar)?))|Up(TeeVector|DownVector|Vector(Bar)?)|Vector(Bar)?|arrow|rightarrow|Floor|A(ngleBracket|rrow(RightArrow|Bar)?)))|Jcy|fr|l(eftarrow)?|a(ng|cute|placetrf|rr|mbda)|midot))\n\t\t\t\t\t\t | (M(scr|cy|inusPlus|opf|u|e(diumSpace|llintrf)|fr|ap)|m(s(cr|tpos)|ho|nplus|c(y|omma)|i(nus(d(u)?|b)?|cro|d(cir|dot|ast)?)|o(dels|pf)|dash|u(ltimap|map)?|p|easuredangle|DDot|fr|l(cp|dr)|a(cr|p(sto(down|up|left)?)?|l(t(ese)?|e)|rker)))\n\t\t\t\t\t\t | (n(s(hort(parallel|mid)|c(cue|e|r)?|im(e(q)?)?|u(cc(eq)?|p(set(eq(q)?)?|e|E)?|b(set(eq(q)?)?|e|E)?)|par|qsu(pe|be)|mid)|Rightarrow|h(par|arr|Arr)|G(t(v)?|g)|c(y|ong(dot)?|up|edil|a(p|ron))|t(ilde|lg|riangle(left(eq)?|right(eq)?)|gl)|i(s(d)?|v)?|o(t(ni(v(c|a|b))?|in(dot|v(c|a|b)|E)?)?|pf)|dash|u(m(sp|ero)?)?|jcy|p(olint|ar(sl|t|allel)?|r(cue|e(c(eq)?)?)?)|e(s(im|ear)|dot|quiv|ar(hk|r(ow)?)|xist(s)?|Arr)?|v(sim|infin|Harr|dash|Dash|l(t(rie)?|e|Arr)|ap|r(trie|Arr)|g(t|e))|fr|w(near|ar(hk|r(ow)?)|Arr)|V(dash|Dash)|l(sim|t(ri(e)?)?|dr|e(s(s)?|q(slant|q)?|ft(arrow|rightarrow))?|E|arr|Arr)|a(ng|cute|tur(al(s)?)?|p(id|os|prox|E)?|bla)|r(tri(e)?|ightarrow|arr(c|w)?|Arr)|g(sim|t(r)?|e(s|q(slant|q)?)?|E)|mid|L(t(v)?|eft(arrow|rightarrow)|l)|b(sp|ump(e)?))|N(scr|c(y|edil|aron)|tilde|o(nBreakingSpace|Break|t(R(ightTriangle(Bar|Equal)?|everseElement)|Greater(Greater|SlantEqual|Tilde|Equal|FullEqual|Less)?|S(u(cceeds(SlantEqual|Tilde|Equal)?|perset(Equal)?|bset(Equal)?)|quareSu(perset(Equal)?|bset(Equal)?))|Hump(DownHump|Equal)|Nested(GreaterGreater|LessLess)|C(ongruent|upCap)|Tilde(Tilde|Equal|FullEqual)?|DoubleVerticalBar|Precedes(SlantEqual|Equal)?|E(qual(Tilde)?|lement|xists)|VerticalBar|Le(ss(Greater|SlantEqual|Tilde|Equal|Less)?|ftTriangle(Bar|Equal)?))?|pf)|u|e(sted(GreaterGreater|LessLess)|wLine|gative(MediumSpace|Thi(nSpace|ckSpace)|VeryThinSpace))|Jcy|fr|acute))\n\t\t\t\t\t\t | (o(s(cr|ol|lash)|h(m|bar)|c(y|ir(c)?)|ti(lde|mes(as)?)|S|int|opf|d(sold|iv|ot|ash|blac)|uml|p(erp|lus|ar)|elig|vbar|f(cir|r)|l(c(ir|ross)|t|ine|arr)|a(st|cute)|r(slope|igof|or|d(er(of)?|f|m)?|v|arr)?|g(t|on|rave)|m(i(nus|cron|d)|ega|acr))|O(s(cr|lash)|c(y|irc)|ti(lde|mes)|opf|dblac|uml|penCurly(DoubleQuote|Quote)|ver(B(ar|rac(e|ket))|Parenthesis)|fr|Elig|acute|r|grave|m(icron|ega|acr)))\n\t\t\t\t\t\t | (p(s(cr|i)|h(i(v)?|one|mmat)|cy|i(tchfork|v)?|o(intint|und|pf)|uncsp|er(cnt|tenk|iod|p|mil)|fr|l(us(sim|cir|two|d(o|u)|e|acir|mn|b)?|an(ck(h)?|kv))|ar(s(im|l)|t|a(llel)?)?|r(sim|n(sim|E|ap)|cue|ime(s)?|o(d|p(to)?|f(surf|line|alar))|urel|e(c(sim|n(sim|eqq|approx)|curlyeq|eq|approx)?)?|E|ap)?|m)|P(s(cr|i)|hi|cy|i|o(incareplane|pf)|fr|lusMinus|artialD|r(ime|o(duct|portion(al)?)|ecedes(SlantEqual|Tilde|Equal)?)?))\n\t\t\t\t\t\t | (q(scr|int|opf|u(ot|est(eq)?|at(int|ernions))|prime|fr)|Q(scr|opf|UOT|fr))\n\t\t\t\t\t\t | (R(s(h|cr)|ho|c(y|edil|aron)|Barr|ight(Ceiling|T(ee(Vector|Arrow)?|riangle(Bar|Equal)?)|Do(ubleBracket|wn(TeeVector|Vector(Bar)?))|Up(TeeVector|DownVector|Vector(Bar)?)|Vector(Bar)?|arrow|Floor|A(ngleBracket|rrow(Bar|LeftArrow)?))|o(undImplies|pf)|uleDelayed|e(verse(UpEquilibrium|E(quilibrium|lement)))?|fr|EG|a(ng|cute|rr(tl)?)|rightarrow)|r(s(h|cr|q(uo(r)?|b)|aquo)|h(o(v)?|ar(d|u(l)?))|nmid|c(y|ub|e(il|dil)|aron)|Barr|t(hree|imes|ri(e|f|ltri)?)|i(singdotseq|ng|ght(squigarrow|harpoon(down|up)|threetimes|left(harpoons|arrows)|arrow(tail)?|rightarrows))|Har|o(times|p(f|lus|ar)|a(ng|rr)|brk)|d(sh|ca|quo(r)?|ldhar)|uluhar|p(polint|ar(gt)?)|e(ct|al(s|ine|part)?|g)|f(isht|loor|r)|l(har|arr|m)|a(ng(d|e|le)?|c(ute|e)|t(io(nals)?|ail)|dic|emptyv|quo|rr(sim|hk|c|tl|pl|fs|w|lp|ap|b(fs)?)?)|rarr|x|moust(ache)?|b(arr|r(k(sl(d|u)|e)|ac(e|k))|brk)|A(tail|arr|rr)))\n\t\t\t\t\t\t | (s(s(cr|tarf|etmn|mile)|h(y|c(hcy|y)|ort(parallel|mid)|arp)|c(sim|y|n(sim|E|ap)|cue|irc|polint|e(dil)?|E|a(p|ron))?|t(ar(f)?|r(ns|aight(phi|epsilon)))|i(gma(v|f)?|m(ne|dot|plus|e(q)?|l(E)?|rarr|g(E)?)?)|zlig|o(pf|ftcy|l(b(ar)?)?)|dot(e|b)?|u(ng|cc(sim|n(sim|eqq|approx)|curlyeq|eq|approx)?|p(s(im|u(p|b)|et(neq(q)?|eq(q)?)?)|hs(ol|ub)|1|n(e|E)|2|d(sub|ot)|3|plus|e(dot)?|E|larr|mult)?|m|b(s(im|u(p|b)|et(neq(q)?|eq(q)?)?)|n(e|E)|dot|plus|e(dot)?|E|rarr|mult)?)|pa(des(uit)?|r)|e(swar|ct|tm(n|inus)|ar(hk|r(ow)?)|xt|mi|Arr)|q(su(p(set(eq)?|e)?|b(set(eq)?|e)?)|c(up(s)?|ap(s)?)|u(f|ar(e|f))?)|fr(own)?|w(nwar|ar(hk|r(ow)?)|Arr)|larr|acute|rarr|m(t(e(s)?)?|i(d|le)|eparsl|a(shp|llsetminus))|bquo)|S(scr|hort(RightArrow|DownArrow|UpArrow|LeftArrow)|c(y|irc|edil|aron)?|tar|igma|H(cy|CHcy)|opf|u(c(hThat|ceeds(SlantEqual|Tilde|Equal)?)|p(set|erset(Equal)?)?|m|b(set(Equal)?)?)|OFTcy|q(uare(Su(perset(Equal)?|bset(Equal)?)|Intersection|Union)?|rt)|fr|acute|mallCircle))\n\t\t\t\t\t\t | (t(s(hcy|c(y|r)|trok)|h(i(nsp|ck(sim|approx))|orn|e(ta(sym|v)?|re(4|fore))|k(sim|ap))|c(y|edil|aron)|i(nt|lde|mes(d|b(ar)?)?)|o(sa|p(cir|f(ork)?|bot)?|ea)|dot|prime|elrec|fr|w(ixt|ohead(leftarrow|rightarrow))|a(u|rget)|r(i(sb|time|dot|plus|e|angle(down|q|left(eq)?|right(eq)?)?|minus)|pezium|ade)|brk)|T(s(cr|trok)|RADE|h(i(nSpace|ckSpace)|e(ta|refore))|c(y|edil|aron)|S(cy|Hcy)|ilde(Tilde|Equal|FullEqual)?|HORN|opf|fr|a(u|b)|ripleDot))\n\t\t\t\t\t\t | (u(scr|h(ar(l|r)|blk)|c(y|irc)|t(ilde|dot|ri(f)?)|Har|o(pf|gon)|d(har|arr|blac)|u(arr|ml)|p(si(h|lon)?|harpoon(left|right)|downarrow|uparrows|lus|arrow)|f(isht|r)|wangle|l(c(orn(er)?|rop)|tri)|a(cute|rr)|r(c(orn(er)?|rop)|tri|ing)|grave|m(l|acr)|br(cy|eve)|Arr)|U(scr|n(ion(Plus)?|der(B(ar|rac(e|ket))|Parenthesis))|c(y|irc)|tilde|o(pf|gon)|dblac|uml|p(si(lon)?|downarrow|Tee(Arrow)?|per(RightArrow|LeftArrow)|DownArrow|Equilibrium|arrow|Arrow(Bar|DownArrow)?)|fr|a(cute|rr(ocir)?)|ring|grave|macr|br(cy|eve)))\n\t\t\t\t\t\t | (v(s(cr|u(pn(e|E)|bn(e|E)))|nsu(p|b)|cy|Bar(v)?|zigzag|opf|dash|prop|e(e(eq|bar)?|llip|r(t|bar))|Dash|fr|ltri|a(ngrt|r(s(igma|u(psetneq(q)?|bsetneq(q)?))|nothing|t(heta|riangle(left|right))|p(hi|i|ropto)|epsilon|kappa|r(ho)?))|rtri|Arr)|V(scr|cy|opf|dash(l)?|e(e|r(yThinSpace|t(ical(Bar|Separator|Tilde|Line))?|bar))|Dash|vdash|fr|bar))\n\t\t\t\t\t\t | (w(scr|circ|opf|p|e(ierp|d(ge(q)?|bar))|fr|r(eath)?)|W(scr|circ|opf|edge|fr))\n\t\t\t\t\t\t | (X(scr|i|opf|fr)|x(s(cr|qcup)|h(arr|Arr)|nis|c(irc|up|ap)|i|o(time|dot|p(f|lus))|dtri|u(tri|plus)|vee|fr|wedge|l(arr|Arr)|r(arr|Arr)|map))\n\t\t\t\t\t\t | (y(scr|c(y|irc)|icy|opf|u(cy|ml)|en|fr|ac(y|ute))|Y(scr|c(y|irc)|opf|uml|Icy|Ucy|fr|acute|Acy))\n\t\t\t\t\t\t | (z(scr|hcy|c(y|aron)|igrarr|opf|dot|e(ta|etrf)|fr|w(nj|j)|acute)|Z(scr|c(y|aron)|Hcy|opf|dot|e(ta|roWidthSpace)|fr|acute))\n\t\t\t\t\t\t)\n\t\t\t\t\t\t(;)\n\t\t\t\t\t", + "name": "constant.character.entity.named.$2.html" + }, { "captures": { "1": { @@ -542,199 +492,2073 @@ "name": "punctuation.definition.entity.html" } }, - "match": "(&)([a-zA-Z0-9]+|#[0-9]+|#[xX][0-9a-fA-F]+)(;)", - "name": "constant.character.entity.html" + "match": "(&)#[0-9]+(;)", + "name": "constant.character.entity.numeric.decimal.html" }, { - "match": "&", - "name": "invalid.illegal.bad-ampersand.html" - } - ] - }, - "python": { - "begin": "(?:^\\s*)<\\?python(?!.*\\?>)", - "end": "\\?>(?:\\s*$\\n)?", - "name": "source.python.embedded.html", - "patterns": [ - { - "include": "source.python" - } - ] - }, - "smarty": { - "patterns": [ - { - "begin": "(\\{(literal)\\})", "captures": { "1": { - "name": "source.smarty.embedded.html" + "name": "punctuation.definition.entity.html" + }, + "3": { + "name": "punctuation.definition.entity.html" + } + }, + "match": "(&)#[xX][0-9a-fA-F]+(;)", + "name": "constant.character.entity.numeric.hexadecimal.html" + }, + { + "match": "&(?=[a-zA-Z0-9]+;)", + "name": "invalid.illegal.ambiguous-ampersand.html" + } + ] + }, + "math": { + "patterns": [ + { + "begin": "(?i)(<)(math)(?=\\s|/?>)(?:(([^\"'>]|\"[^\"]*\"|'[^']*')*)(>))?", + "beginCaptures": { + "0": { + "name": "meta.tag.structure.$2.start.html" + }, + "1": { + "name": "punctuation.definition.tag.begin.html" }, "2": { - "name": "support.function.built-in.smarty" + "name": "entity.name.tag.html" + }, + "3": { + "patterns": [ + { + "include": "#attribute" + } + ] + }, + "5": { + "name": "punctuation.definition.tag.end.html" } }, - "end": "(\\{/(literal)\\})" - }, - { - "begin": "{{|{", - "disabled": 1, - "end": "}}|}", - "name": "source.smarty.embedded.html", - "patterns": [ - { - "include": "source.smarty" - } - ] - } - ] - }, - "string-double-quoted": { - "begin": "\"", - "beginCaptures": { - "0": { - "name": "punctuation.definition.string.begin.html" - } - }, - "end": "\"", - "endCaptures": { - "0": { - "name": "punctuation.definition.string.end.html" - } - }, - "name": "string.quoted.double.html", - "patterns": [ - { - "include": "#embedded-code" - }, - { - "include": "#entities" - } - ] - }, - "string-single-quoted": { - "begin": "'", - "beginCaptures": { - "0": { - "name": "punctuation.definition.string.begin.html" - } - }, - "end": "'", - "endCaptures": { - "0": { - "name": "punctuation.definition.string.end.html" - } - }, - "name": "string.quoted.single.html", - "patterns": [ - { - "include": "#embedded-code" - }, - { - "include": "#entities" - } - ] - }, - "tag-generic-attribute": { - "match": "(?<=[^=])\\b([a-zA-Z0-9:-]+)", - "name": "entity.other.attribute-name.html" - }, - "tag-id-attribute": { - "begin": "\\b(id)\\b\\s*(=)", - "captures": { - "1": { - "name": "entity.other.attribute-name.id.html" - }, - "2": { - "name": "punctuation.separator.key-value.html" - } - }, - "end": "(?!\\G)(?<='|\"|[^\\s<>/])", - "name": "meta.attribute-with-value.id.html", - "patterns": [ - { - "begin": "\"", - "beginCaptures": { - "0": { - "name": "punctuation.definition.string.begin.html" - } - }, - "contentName": "meta.toc-list.id.html", - "end": "\"", + "end": "(?i)()", "endCaptures": { "0": { - "name": "punctuation.definition.string.end.html" + "name": "meta.tag.structure.$2.end.html" + }, + "1": { + "name": "punctuation.definition.tag.begin.html" + }, + "2": { + "name": "entity.name.tag.html" + }, + "3": { + "name": "punctuation.definition.tag.end.html" } }, - "name": "string.quoted.double.html", + "name": "meta.element.structure.$2.html", "patterns": [ { - "include": "#embedded-code" + "begin": "(?)\\G", + "end": ">", + "endCaptures": { + "0": { + "name": "punctuation.definition.tag.end.html" + } + }, + "name": "meta.tag.structure.start.html", + "patterns": [ + { + "include": "#attribute" + } + ] }, { - "include": "#entities" + "include": "#tags" } ] - }, - { - "begin": "'", - "beginCaptures": { - "0": { - "name": "punctuation.definition.string.begin.html" - } - }, - "contentName": "meta.toc-list.id.html", - "end": "'", - "endCaptures": { - "0": { - "name": "punctuation.definition.string.end.html" - } - }, - "name": "string.quoted.single.html", - "patterns": [ - { - "include": "#embedded-code" - }, - { - "include": "#entities" - } - ] - }, - { - "captures": { - "0": { - "name": "meta.toc-list.id.html" - } - }, - "match": "(?<==)(?:[^\\s<>/'\"]|/(?!>))+", - "name": "string.unquoted.html" } - ] + ], + "repository": { + "attribute": { + "patterns": [ + { + "begin": "(s(hift|ymmetric|cript(sizemultiplier|level|minsize)|t(ackalign|retchy)|ide|u(pscriptshift|bscriptshift)|e(parator(s)?|lection)|rc)|h(eight|ref)|n(otation|umalign)|c(haralign|olumn(spa(n|cing)|width|lines|align)|lose|rossout)|i(n(dent(shift(first|last)?|target|align(first|last)?)|fixlinebreakstyle)|d)|o(pen|verflow)|d(i(splay(style)?|r)|e(nomalign|cimalpoint|pth))|position|e(dge|qual(columns|rows))|voffset|f(orm|ence|rame(spacing)?)|width|l(space|ine(thickness|leading|break(style|multchar)?)|o(ngdivstyle|cation)|ength|quote|argeop)|a(c(cent(under)?|tiontype)|l(t(text|img(-(height|valign|width))?)|ign(mentscope)?))|r(space|ow(spa(n|cing)|lines|align)|quote)|groupalign|x(link:href|mlns)|m(in(size|labelspacing)|ovablelimits|a(th(size|color|variant|background)|xsize))|bevelled)(?![\\w:-])", + "beginCaptures": { + "0": { + "name": "entity.other.attribute-name.html" + } + }, + "end": "(?=\\s*+[^=\\s])", + "name": "meta.attribute.$1.html", + "patterns": [ + { + "include": "#attribute-interior" + } + ] + }, + { + "begin": "([^\\x{0020}\"'<>/=\\x{0000}-\\x{001F}\\x{007F}-\\x{009F}\\x{FDD0}-\\x{FDEF}\\x{FFFE}\\x{FFFF}\\x{1FFFE}\\x{1FFFF}\\x{2FFFE}\\x{2FFFF}\\x{3FFFE}\\x{3FFFF}\\x{4FFFE}\\x{4FFFF}\\x{5FFFE}\\x{5FFFF}\\x{6FFFE}\\x{6FFFF}\\x{7FFFE}\\x{7FFFF}\\x{8FFFE}\\x{8FFFF}\\x{9FFFE}\\x{9FFFF}\\x{AFFFE}\\x{AFFFF}\\x{BFFFE}\\x{BFFFF}\\x{CFFFE}\\x{CFFFF}\\x{DFFFE}\\x{DFFFF}\\x{EFFFE}\\x{EFFFF}\\x{FFFFE}\\x{FFFFF}\\x{10FFFE}\\x{10FFFF}]+)", + "beginCaptures": { + "0": { + "name": "entity.other.attribute-name.html" + } + }, + "comment": "Anything else that is valid", + "end": "(?=\\s*+[^=\\s])", + "name": "meta.attribute.unrecognized.$1.html", + "patterns": [ + { + "include": "#attribute-interior" + } + ] + }, + { + "match": "[^\\s>]+", + "name": "invalid.illegal.character-not-allowed-here.html" + } + ] + }, + "tags": { + "patterns": [ + { + "include": "#comment" + }, + { + "include": "#cdata" + }, + { + "captures": { + "0": { + "name": "meta.tag.structure.math.$2.void.html" + }, + "1": { + "name": "punctuation.definition.tag.begin.html" + }, + "2": { + "name": "entity.name.tag.html" + }, + "3": { + "patterns": [ + { + "include": "#attribute" + } + ] + }, + "5": { + "name": "punctuation.definition.tag.end.html" + } + }, + "match": "(?i)(<)(annotation|annotation-xml|semantics|menclose|merror|mfenced|mfrac|mpadded|mphantom|mroot|mrow|msqrt|mstyle|mmultiscripts|mover|mprescripts|msub|msubsup|msup|munder|munderover|none|mlabeledtr|mtable|mtd|mtr|mlongdiv|mscarries|mscarry|msgroup|msline|msrow|mstack|maction)(?=\\s|/?>)(?:(([^\"'>]|\"[^\"]*\"|'[^']*')*)(/>))", + "name": "meta.element.structure.math.$2.html" + }, + { + "begin": "(?i)(<)(annotation|annotation-xml|semantics|menclose|merror|mfenced|mfrac|mpadded|mphantom|mroot|mrow|msqrt|mstyle|mmultiscripts|mover|mprescripts|msub|msubsup|msup|munder|munderover|none|mlabeledtr|mtable|mtd|mtr|mlongdiv|mscarries|mscarry|msgroup|msline|msrow|mstack|maction)(?=\\s|/?>)(?:(([^\"'>]|\"[^\"]*\"|'[^']*')*)(>))?", + "beginCaptures": { + "0": { + "name": "meta.tag.structure.math.$2.start.html" + }, + "1": { + "name": "punctuation.definition.tag.begin.html" + }, + "2": { + "name": "entity.name.tag.html" + }, + "3": { + "patterns": [ + { + "include": "#attribute" + } + ] + }, + "5": { + "name": "punctuation.definition.tag.end.html" + } + }, + "end": "(?i)()|(/>)|(?=)\\G", + "end": "(?=/>)|>", + "endCaptures": { + "0": { + "name": "punctuation.definition.tag.end.html" + } + }, + "name": "meta.tag.structure.start.html", + "patterns": [ + { + "include": "#attribute" + } + ] + }, + { + "include": "#tags" + } + ] + }, + { + "captures": { + "0": { + "name": "meta.tag.inline.math.$2.void.html" + }, + "1": { + "name": "punctuation.definition.tag.begin.html" + }, + "2": { + "name": "entity.name.tag.html" + }, + "3": { + "patterns": [ + { + "include": "#attribute" + } + ] + }, + "5": { + "name": "punctuation.definition.tag.end.html" + } + }, + "match": "(?i)(<)(mi|mn|mo|ms|mspace|mtext|maligngroup|malignmark)(?=\\s|/?>)(?:(([^\"'>]|\"[^\"]*\"|'[^']*')*)(/>))", + "name": "meta.element.inline.math.$2.html" + }, + { + "begin": "(?i)(<)(mi|mn|mo|ms|mspace|mtext|maligngroup|malignmark)(?=\\s|/?>)(?:(([^\"'>]|\"[^\"]*\"|'[^']*')*)(>))?", + "beginCaptures": { + "0": { + "name": "meta.tag.inline.math.$2.start.html" + }, + "1": { + "name": "punctuation.definition.tag.begin.html" + }, + "2": { + "name": "entity.name.tag.html" + }, + "3": { + "patterns": [ + { + "include": "#attribute" + } + ] + }, + "5": { + "name": "punctuation.definition.tag.end.html" + } + }, + "end": "(?i)()|(/>)|(?=)\\G", + "end": "(?=/>)|>", + "endCaptures": { + "0": { + "name": "punctuation.definition.tag.end.html" + } + }, + "name": "meta.tag.inline.start.html", + "patterns": [ + { + "include": "#attribute" + } + ] + }, + { + "include": "#tags" + } + ] + }, + { + "captures": { + "0": { + "name": "meta.tag.object.math.$2.void.html" + }, + "1": { + "name": "punctuation.definition.tag.begin.html" + }, + "2": { + "name": "entity.name.tag.html" + }, + "3": { + "patterns": [ + { + "include": "#attribute" + } + ] + }, + "5": { + "name": "punctuation.definition.tag.end.html" + } + }, + "match": "(?i)(<)(mglyph)(?=\\s|/?>)(?:(([^\"'>]|\"[^\"]*\"|'[^']*')*)(/>))", + "name": "meta.element.object.math.$2.html" + }, + { + "begin": "(?i)(<)(mglyph)(?=\\s|/?>)(?:(([^\"'>]|\"[^\"]*\"|'[^']*')*)(>))?", + "beginCaptures": { + "0": { + "name": "meta.tag.object.math.$2.start.html" + }, + "1": { + "name": "punctuation.definition.tag.begin.html" + }, + "2": { + "name": "entity.name.tag.html" + }, + "3": { + "patterns": [ + { + "include": "#attribute" + } + ] + }, + "5": { + "name": "punctuation.definition.tag.end.html" + } + }, + "end": "(?i)()|(/>)|(?=)\\G", + "end": "(?=/>)|>", + "endCaptures": { + "0": { + "name": "punctuation.definition.tag.end.html" + } + }, + "name": "meta.tag.object.start.html", + "patterns": [ + { + "include": "#attribute" + } + ] + }, + { + "include": "#tags" + } + ] + }, + { + "captures": { + "0": { + "name": "meta.tag.other.invalid.void.html" + }, + "1": { + "name": "punctuation.definition.tag.begin.html" + }, + "2": { + "name": "entity.name.tag.html" + }, + "3": { + "name": "invalid.illegal.unrecognized-tag.html" + }, + "4": { + "patterns": [ + { + "include": "#attribute" + } + ] + }, + "6": { + "name": "punctuation.definition.tag.end.html" + } + }, + "match": "(?i)(<)(([\\w:]+))(?=\\s|/?>)(?:(([^\"'>]|\"[^\"]*\"|'[^']*')*)(/>))", + "name": "meta.element.other.invalid.html" + }, + { + "begin": "(?i)(<)((\\w[^\\s>]*))(?=\\s|/?>)(?:(([^\"'>]|\"[^\"]*\"|'[^']*')*)(>))?", + "beginCaptures": { + "0": { + "name": "meta.tag.other.invalid.start.html" + }, + "1": { + "name": "punctuation.definition.tag.begin.html" + }, + "2": { + "name": "entity.name.tag.html" + }, + "3": { + "name": "invalid.illegal.unrecognized-tag.html" + }, + "4": { + "patterns": [ + { + "include": "#attribute" + } + ] + }, + "6": { + "name": "punctuation.definition.tag.end.html" + } + }, + "end": "(?i)()|(/>)|(?=)\\G", + "end": "(?=/>)|>", + "endCaptures": { + "0": { + "name": "punctuation.definition.tag.end.html" + } + }, + "name": "meta.tag.other.invalid.start.html", + "patterns": [ + { + "include": "#attribute" + } + ] + }, + { + "include": "#tags" + } + ] + }, + { + "include": "#tags-invalid" + } + ] + } + } }, - "tag-stuff": { + "svg": { "patterns": [ { - "include": "#tag-id-attribute" + "begin": "(?i)(<)(svg)(?=\\s|/?>)(?:(([^\"'>]|\"[^\"]*\"|'[^']*')*)(>))?", + "beginCaptures": { + "0": { + "name": "meta.tag.structure.$2.start.html" + }, + "1": { + "name": "punctuation.definition.tag.begin.html" + }, + "2": { + "name": "entity.name.tag.html" + }, + "3": { + "patterns": [ + { + "include": "#attribute" + } + ] + }, + "5": { + "name": "punctuation.definition.tag.end.html" + } + }, + "end": "(?i)()", + "endCaptures": { + "0": { + "name": "meta.tag.structure.$2.end.html" + }, + "1": { + "name": "punctuation.definition.tag.begin.html" + }, + "2": { + "name": "entity.name.tag.html" + }, + "3": { + "name": "punctuation.definition.tag.end.html" + } + }, + "name": "meta.element.structure.$2.html", + "patterns": [ + { + "begin": "(?)\\G", + "end": ">", + "endCaptures": { + "0": { + "name": "punctuation.definition.tag.end.html" + } + }, + "name": "meta.tag.structure.start.html", + "patterns": [ + { + "include": "#attribute" + } + ] + }, + { + "include": "#tags" + } + ] + } + ], + "repository": { + "attribute": { + "patterns": [ + { + "begin": "(s(hape-rendering|ystemLanguage|cale|t(yle|itchTiles|op-(color|opacity)|dDeviation|em(h|v)|artOffset|r(i(ng|kethrough-(thickness|position))|oke(-(opacity|dash(offset|array)|width|line(cap|join)|miterlimit))?))|urfaceScale|p(e(cular(Constant|Exponent)|ed)|acing|readMethod)|eed|lope)|h(oriz-(origin-x|adv-x)|eight|anging|ref(lang)?)|y(1|2|ChannelSelector)?|n(umOctaves|ame)|c(y|o(ntentS(criptType|tyleType)|lor(-(interpolation(-filters)?|profile|rendering))?)|ursor|l(ip(-(path|rule)|PathUnits)?|ass)|a(p-height|lcMode)|x)|t(ype|o|ext(-(decoration|anchor|rendering)|Length)|a(rget(X|Y)?|b(index|leValues))|ransform)|i(n(tercept|2)?|d(eographic)?|mage-rendering)|z(oomAndPan)?|o(p(erator|acity)|ver(flow|line-(thickness|position))|ffset|r(i(ent(ation)?|gin)|der))|d(y|i(splay|visor|ffuseConstant|rection)|ominant-baseline|ur|e(scent|celerate)|x)?|u(1|n(i(code(-(range|bidi))?|ts-per-em)|derline-(thickness|position))|2)|p(ing|oint(s(At(X|Y|Z))?|er-events)|a(nose-1|t(h(Length)?|tern(ContentUnits|Transform|Units))|int-order)|r(imitiveUnits|eserveA(spectRatio|lpha)))|e(n(d|able-background)|dgeMode|levation|x(ternalResourcesRequired|ponent))|v(i(sibility|ew(Box|Target))|-(hanging|ideographic|alphabetic|mathematical)|e(ctor-effect|r(sion|t-(origin-(y|x)|adv-y)))|alues)|k(1|2|3|e(y(Splines|Times|Points)|rn(ing|el(Matrix|UnitLength)))|4)?|f(y|il(ter(Res|Units)?|l(-(opacity|rule))?)|o(nt-(s(t(yle|retch)|ize(-adjust)?)|variant|family|weight)|rmat)|lood-(color|opacity)|r(om)?|x)|w(idth(s)?|ord-spacing|riting-mode)|l(i(ghting-color|mitingConeAngle)|ocal|e(ngthAdjust|tter-spacing)|ang)|a(scent|cc(umulate|ent-height)|ttribute(Name|Type)|zimuth|dditive|utoReverse|l(ignment-baseline|phabetic|lowReorder)|rabic-form|mplitude)|r(y|otate|e(s(tart|ult)|ndering-intent|peat(Count|Dur)|quired(Extensions|Features)|f(X|Y|errerPolicy)|l)|adius|x)?|g(1|2|lyph(Ref|-(name|orientation-(horizontal|vertical)))|radient(Transform|Units))|x(1|2|ChannelSelector|-height|link:(show|href|t(ype|itle)|a(ctuate|rcrole)|role)|ml:(space|lang|base))?|m(in|ode|e(thod|dia)|a(sk(ContentUnits|Units)?|thematical|rker(Height|-(start|end|mid)|Units|Width)|x))|b(y|ias|egin|ase(Profile|line-shift|Frequency)|box))(?![\\w:-])", + "beginCaptures": { + "0": { + "name": "entity.other.attribute-name.html" + } + }, + "end": "(?=\\s*+[^=\\s])", + "name": "meta.attribute.$1.html", + "patterns": [ + { + "include": "#attribute-interior" + } + ] + }, + { + "begin": "([^\\x{0020}\"'<>/=\\x{0000}-\\x{001F}\\x{007F}-\\x{009F}\\x{FDD0}-\\x{FDEF}\\x{FFFE}\\x{FFFF}\\x{1FFFE}\\x{1FFFF}\\x{2FFFE}\\x{2FFFF}\\x{3FFFE}\\x{3FFFF}\\x{4FFFE}\\x{4FFFF}\\x{5FFFE}\\x{5FFFF}\\x{6FFFE}\\x{6FFFF}\\x{7FFFE}\\x{7FFFF}\\x{8FFFE}\\x{8FFFF}\\x{9FFFE}\\x{9FFFF}\\x{AFFFE}\\x{AFFFF}\\x{BFFFE}\\x{BFFFF}\\x{CFFFE}\\x{CFFFF}\\x{DFFFE}\\x{DFFFF}\\x{EFFFE}\\x{EFFFF}\\x{FFFFE}\\x{FFFFF}\\x{10FFFE}\\x{10FFFF}]+)", + "beginCaptures": { + "0": { + "name": "entity.other.attribute-name.html" + } + }, + "comment": "Anything else that is valid", + "end": "(?=\\s*+[^=\\s])", + "name": "meta.attribute.unrecognized.$1.html", + "patterns": [ + { + "include": "#attribute-interior" + } + ] + }, + { + "match": "[^\\s>]+", + "name": "invalid.illegal.character-not-allowed-here.html" + } + ] }, + "tags": { + "patterns": [ + { + "include": "#comment" + }, + { + "include": "#cdata" + }, + { + "captures": { + "0": { + "name": "meta.tag.metadata.svg.$2.void.html" + }, + "1": { + "name": "punctuation.definition.tag.begin.html" + }, + "2": { + "name": "entity.name.tag.html" + }, + "3": { + "patterns": [ + { + "include": "#attribute" + } + ] + }, + "5": { + "name": "punctuation.definition.tag.end.html" + } + }, + "match": "(?i)(<)(color-profile|desc|metadata|script|style|title)(?=\\s|/?>)(?:(([^\"'>]|\"[^\"]*\"|'[^']*')*)(/>))", + "name": "meta.element.metadata.svg.$2.html" + }, + { + "begin": "(?i)(<)(color-profile|desc|metadata|script|style|title)(?=\\s|/?>)(?:(([^\"'>]|\"[^\"]*\"|'[^']*')*)(>))?", + "beginCaptures": { + "0": { + "name": "meta.tag.metadata.svg.$2.start.html" + }, + "1": { + "name": "punctuation.definition.tag.begin.html" + }, + "2": { + "name": "entity.name.tag.html" + }, + "3": { + "patterns": [ + { + "include": "#attribute" + } + ] + }, + "5": { + "name": "punctuation.definition.tag.end.html" + } + }, + "end": "(?i)()|(/>)|(?=)\\G", + "end": "(?=/>)|>", + "endCaptures": { + "0": { + "name": "punctuation.definition.tag.end.html" + } + }, + "name": "meta.tag.metadata.start.html", + "patterns": [ + { + "include": "#attribute" + } + ] + }, + { + "include": "#tags" + } + ] + }, + { + "captures": { + "0": { + "name": "meta.tag.structure.svg.$2.void.html" + }, + "1": { + "name": "punctuation.definition.tag.begin.html" + }, + "2": { + "name": "entity.name.tag.html" + }, + "3": { + "patterns": [ + { + "include": "#attribute" + } + ] + }, + "5": { + "name": "punctuation.definition.tag.end.html" + } + }, + "match": "(?i)(<)(animateMotion|clipPath|defs|feComponentTransfer|feDiffuseLighting|feMerge|feSpecularLighting|filter|g|hatch|linearGradient|marker|mask|mesh|meshgradient|meshpatch|meshrow|pattern|radialGradient|switch|text|textPath)(?=\\s|/?>)(?:(([^\"'>]|\"[^\"]*\"|'[^']*')*)(/>))", + "name": "meta.element.structure.svg.$2.html" + }, + { + "begin": "(?i)(<)(animateMotion|clipPath|defs|feComponentTransfer|feDiffuseLighting|feMerge|feSpecularLighting|filter|g|hatch|linearGradient|marker|mask|mesh|meshgradient|meshpatch|meshrow|pattern|radialGradient|switch|text|textPath)(?=\\s|/?>)(?:(([^\"'>]|\"[^\"]*\"|'[^']*')*)(>))?", + "beginCaptures": { + "0": { + "name": "meta.tag.structure.svg.$2.start.html" + }, + "1": { + "name": "punctuation.definition.tag.begin.html" + }, + "2": { + "name": "entity.name.tag.html" + }, + "3": { + "patterns": [ + { + "include": "#attribute" + } + ] + }, + "5": { + "name": "punctuation.definition.tag.end.html" + } + }, + "end": "(?i)()|(/>)|(?=)\\G", + "end": "(?=/>)|>", + "endCaptures": { + "0": { + "name": "punctuation.definition.tag.end.html" + } + }, + "name": "meta.tag.structure.start.html", + "patterns": [ + { + "include": "#attribute" + } + ] + }, + { + "include": "#tags" + } + ] + }, + { + "captures": { + "0": { + "name": "meta.tag.inline.svg.$2.void.html" + }, + "1": { + "name": "punctuation.definition.tag.begin.html" + }, + "2": { + "name": "entity.name.tag.html" + }, + "3": { + "patterns": [ + { + "include": "#attribute" + } + ] + }, + "5": { + "name": "punctuation.definition.tag.end.html" + } + }, + "match": "(?i)(<)(a|animate|discard|feBlend|feColorMatrix|feComposite|feConvolveMatrix|feDisplacementMap|feDistantLight|feDropShadow|feFlood|feFuncA|feFuncB|feFuncG|feFuncR|feGaussianBlur|feMergeNode|feMorphology|feOffset|fePointLight|feSpotLight|feTile|feTurbulence|hatchPath|mpath|set|solidcolor|stop|tspan)(?=\\s|/?>)(?:(([^\"'>]|\"[^\"]*\"|'[^']*')*)(/>))", + "name": "meta.element.inline.svg.$2.html" + }, + { + "begin": "(?i)(<)(a|animate|discard|feBlend|feColorMatrix|feComposite|feConvolveMatrix|feDisplacementMap|feDistantLight|feDropShadow|feFlood|feFuncA|feFuncB|feFuncG|feFuncR|feGaussianBlur|feMergeNode|feMorphology|feOffset|fePointLight|feSpotLight|feTile|feTurbulence|hatchPath|mpath|set|solidcolor|stop|tspan)(?=\\s|/?>)(?:(([^\"'>]|\"[^\"]*\"|'[^']*')*)(>))?", + "beginCaptures": { + "0": { + "name": "meta.tag.inline.svg.$2.start.html" + }, + "1": { + "name": "punctuation.definition.tag.begin.html" + }, + "2": { + "name": "entity.name.tag.html" + }, + "3": { + "patterns": [ + { + "include": "#attribute" + } + ] + }, + "5": { + "name": "punctuation.definition.tag.end.html" + } + }, + "end": "(?i)()|(/>)|(?=)\\G", + "end": "(?=/>)|>", + "endCaptures": { + "0": { + "name": "punctuation.definition.tag.end.html" + } + }, + "name": "meta.tag.inline.start.html", + "patterns": [ + { + "include": "#attribute" + } + ] + }, + { + "include": "#tags" + } + ] + }, + { + "captures": { + "0": { + "name": "meta.tag.object.svg.$2.void.html" + }, + "1": { + "name": "punctuation.definition.tag.begin.html" + }, + "2": { + "name": "entity.name.tag.html" + }, + "3": { + "patterns": [ + { + "include": "#attribute" + } + ] + }, + "5": { + "name": "punctuation.definition.tag.end.html" + } + }, + "match": "(?i)(<)(circle|ellipse|feImage|foreignObject|image|line|path|polygon|polyline|rect|symbol|use|view)(?=\\s|/?>)(?:(([^\"'>]|\"[^\"]*\"|'[^']*')*)(/>))", + "name": "meta.element.object.svg.$2.html" + }, + { + "begin": "(?i)(<)(a|circle|ellipse|feImage|foreignObject|image|line|path|polygon|polyline|rect|symbol|use|view)(?=\\s|/?>)(?:(([^\"'>]|\"[^\"]*\"|'[^']*')*)(>))?", + "beginCaptures": { + "0": { + "name": "meta.tag.object.svg.$2.start.html" + }, + "1": { + "name": "punctuation.definition.tag.begin.html" + }, + "2": { + "name": "entity.name.tag.html" + }, + "3": { + "patterns": [ + { + "include": "#attribute" + } + ] + }, + "5": { + "name": "punctuation.definition.tag.end.html" + } + }, + "end": "(?i)()|(/>)|(?=)\\G", + "end": "(?=/>)|>", + "endCaptures": { + "0": { + "name": "punctuation.definition.tag.end.html" + } + }, + "name": "meta.tag.object.start.html", + "patterns": [ + { + "include": "#attribute" + } + ] + }, + { + "include": "#tags" + } + ] + }, + { + "captures": { + "0": { + "name": "meta.tag.other.svg.$2.void.html" + }, + "1": { + "name": "punctuation.definition.tag.begin.html" + }, + "2": { + "name": "entity.name.tag.html" + }, + "3": { + "name": "invalid.deprecated.html" + }, + "4": { + "patterns": [ + { + "include": "#attribute" + } + ] + }, + "6": { + "name": "punctuation.definition.tag.end.html" + } + }, + "match": "(?i)(<)((altGlyph|altGlyphDef|altGlyphItem|animateColor|animateTransform|cursor|font|font-face|font-face-format|font-face-name|font-face-src|font-face-uri|glyph|glyphRef|hkern|missing-glyph|tref|vkern))(?=\\s|/?>)(?:(([^\"'>]|\"[^\"]*\"|'[^']*')*)(/>))", + "name": "meta.element.other.svg.$2.html" + }, + { + "begin": "(?i)(<)((altGlyph|altGlyphDef|altGlyphItem|animateColor|animateTransform|cursor|font|font-face|font-face-format|font-face-name|font-face-src|font-face-uri|glyph|glyphRef|hkern|missing-glyph|tref|vkern))(?=\\s|/?>)(?:(([^\"'>]|\"[^\"]*\"|'[^']*')*)(>))?", + "beginCaptures": { + "0": { + "name": "meta.tag.other.svg.$2.start.html" + }, + "1": { + "name": "punctuation.definition.tag.begin.html" + }, + "2": { + "name": "entity.name.tag.html" + }, + "3": { + "name": "invalid.deprecated.html" + }, + "4": { + "patterns": [ + { + "include": "#attribute" + } + ] + }, + "6": { + "name": "punctuation.definition.tag.end.html" + } + }, + "end": "(?i)()|(/>)|(?=)\\G", + "end": "(?=/>)|>", + "endCaptures": { + "0": { + "name": "punctuation.definition.tag.end.html" + } + }, + "name": "meta.tag.other.start.html", + "patterns": [ + { + "include": "#attribute" + } + ] + }, + { + "include": "#tags" + } + ] + }, + { + "captures": { + "0": { + "name": "meta.tag.other.invalid.void.html" + }, + "1": { + "name": "punctuation.definition.tag.begin.html" + }, + "2": { + "name": "entity.name.tag.html" + }, + "3": { + "name": "invalid.illegal.unrecognized-tag.html" + }, + "4": { + "patterns": [ + { + "include": "#attribute" + } + ] + }, + "6": { + "name": "punctuation.definition.tag.end.html" + } + }, + "match": "(?i)(<)(([\\w:]+))(?=\\s|/?>)(?:(([^\"'>]|\"[^\"]*\"|'[^']*')*)(/>))", + "name": "meta.element.other.invalid.html" + }, + { + "begin": "(?i)(<)((\\w[^\\s>]*))(?=\\s|/?>)(?:(([^\"'>]|\"[^\"]*\"|'[^']*')*)(>))?", + "beginCaptures": { + "0": { + "name": "meta.tag.other.invalid.start.html" + }, + "1": { + "name": "punctuation.definition.tag.begin.html" + }, + "2": { + "name": "entity.name.tag.html" + }, + "3": { + "name": "invalid.illegal.unrecognized-tag.html" + }, + "4": { + "patterns": [ + { + "include": "#attribute" + } + ] + }, + "6": { + "name": "punctuation.definition.tag.end.html" + } + }, + "end": "(?i)()|(/>)|(?=)\\G", + "end": "(?=/>)|>", + "endCaptures": { + "0": { + "name": "punctuation.definition.tag.end.html" + } + }, + "name": "meta.tag.other.invalid.start.html", + "patterns": [ + { + "include": "#attribute" + } + ] + }, + { + "include": "#tags" + } + ] + }, + { + "include": "#tags-invalid" + } + ] + } + } + }, + "tags-invalid": { + "patterns": [ { - "include": "#tag-generic-attribute" - }, - { - "include": "#string-double-quoted" - }, - { - "include": "#string-single-quoted" - }, - { - "include": "#embedded-code" - }, - { - "include": "#unquoted-attribute" + "begin": "(]*))(?)", + "endCaptures": { + "1": { + "name": "punctuation.definition.tag.end.html" + } + }, + "name": "meta.tag.other.$2.html", + "patterns": [ + { + "include": "#attribute" + } + ] } ] }, - "unquoted-attribute": { - "match": "(?<==)(?:[^\\s<>/'\"]|/(?!>))+", - "name": "string.unquoted.html" + "tags-valid": { + "patterns": [ + { + "begin": "(^[ \\t]+)?(?=<(?i:style)\\b(?!-))", + "beginCaptures": { + "1": { + "name": "punctuation.whitespace.embedded.leading.html" + } + }, + "end": "(?!\\G)([ \\t]*$\\n?)?", + "endCaptures": { + "1": { + "name": "punctuation.whitespace.embedded.trailing.html" + } + }, + "patterns": [ + { + "begin": "(?i)(<)(style)(?=\\s|/?>)", + "beginCaptures": { + "0": { + "name": "meta.tag.metadata.style.start.html" + }, + "1": { + "name": "punctuation.definition.tag.begin.html" + }, + "2": { + "name": "entity.name.tag.html" + } + }, + "end": "(?i)((<)/)(style)\\s*(>)", + "endCaptures": { + "0": { + "name": "meta.tag.metadata.style.end.html" + }, + "1": { + "name": "punctuation.definition.tag.begin.html" + }, + "2": { + "name": "source.css" + }, + "3": { + "name": "entity.name.tag.html" + }, + "4": { + "name": "punctuation.definition.tag.end.html" + } + }, + "name": "meta.embedded.block.html", + "patterns": [ + { + "begin": "\\G", + "captures": { + "1": { + "name": "punctuation.definition.tag.end.html" + } + }, + "end": "(>)", + "name": "meta.tag.metadata.style.start.html", + "patterns": [ + { + "include": "#attribute" + } + ] + }, + { + "begin": "(?!\\G)", + "end": "(?=)", + "endCaptures": { + "0": { + "name": "meta.tag.metadata.script.end.html" + }, + "1": { + "name": "punctuation.definition.tag.begin.html" + }, + "2": { + "name": "entity.name.tag.html" + }, + "3": { + "name": "punctuation.definition.tag.end.html" + } + }, + "name": "meta.embedded.block.html", + "patterns": [ + { + "begin": "\\G", + "end": "(?=/)", + "patterns": [ + { + "begin": "(>)", + "beginCaptures": { + "0": { + "name": "meta.tag.metadata.script.start.html" + }, + "1": { + "name": "punctuation.definition.tag.end.html" + } + }, + "end": "((<))(?=/(?i:script))", + "endCaptures": { + "0": { + "name": "meta.tag.metadata.script.end.html" + }, + "1": { + "name": "punctuation.definition.tag.begin.html" + }, + "2": { + "name": "source.js" + } + }, + "patterns": [ + { + "begin": "\\G", + "end": "(?=\t\t\t\t\t\t\t\t\t\t\t# Tag without type attribute\n\t\t\t\t\t\t\t\t\t\t\t\t | type(?=[\\s=])\n\t\t\t\t\t\t\t\t\t\t\t\t \t(?!\\s*=\\s*\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t(\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t''\t\t\t\t\t\t\t\t# Empty\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t | \"\"\t\t\t\t\t\t\t\t\t# Values\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t | ('|\"|)\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t(\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\ttext/\t\t\t\t\t\t\t# Text mime-types\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t(\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tjavascript(1\\.[0-5])?\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t | x-javascript\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t | jscript\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t | livescript\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t | (x-)?ecmascript\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t | babel\t\t\t\t\t\t# Javascript variant currently\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t \t\t\t\t\t\t\t\t# recognized as such\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t \t)\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t | application/\t\t\t\t\t# Application mime-types\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t \t(\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t(x-)?javascript\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t | (x-)?ecmascript\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t | module\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t \t)\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t[\\s\"'>]\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\t\t\t\t\t)", + "name": "meta.tag.metadata.script.start.html", + "patterns": [ + { + "include": "#attribute" + } + ] + }, + { + "begin": "(?ix:\n\t\t\t\t\t\t\t\t\t\t\t\t(?=\n\t\t\t\t\t\t\t\t\t\t\t\t\ttype\\s*=\\s*\n\t\t\t\t\t\t\t\t\t\t\t\t\t('|\"|)\n\t\t\t\t\t\t\t\t\t\t\t\t\ttext/\n\t\t\t\t\t\t\t\t\t\t\t\t\t(\n\t\t\t\t\t\t\t\t\t\t\t\t\t\tx-handlebars\n\t\t\t\t\t\t\t\t\t\t\t\t\t | (x-(handlebars-)?|ng-)?template\n\t\t\t\t\t\t\t\t\t\t\t\t\t | html\n\t\t\t\t\t\t\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\t\t\t\t\t\t\t[\\s\"'>]\n\t\t\t\t\t\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\t\t\t\t\t)", + "end": "((<))(?=/(?i:script))", + "endCaptures": { + "0": { + "name": "meta.tag.metadata.script.end.html" + }, + "1": { + "name": "punctuation.definition.tag.begin.html" + }, + "2": { + "name": "text.html.basic" + } + }, + "patterns": [ + { + "begin": "\\G", + "end": "(>)", + "endCaptures": { + "1": { + "name": "punctuation.definition.tag.end.html" + } + }, + "name": "meta.tag.metadata.script.start.html", + "patterns": [ + { + "include": "#attribute" + } + ] + }, + { + "begin": "(?!\\G)", + "end": "(?=)", + "endCaptures": { + "1": { + "name": "punctuation.definition.tag.end.html" + } + }, + "name": "meta.tag.metadata.script.start.html", + "patterns": [ + { + "include": "#attribute" + } + ] + }, + { + "begin": "(?!\\G)", + "end": "(?=)", + "beginCaptures": { + "1": { + "name": "punctuation.definition.tag.begin.html" + }, + "2": { + "name": "entity.name.tag.html" + } + }, + "end": "/?>", + "endCaptures": { + "0": { + "name": "punctuation.definition.tag.end.html" + } + }, + "name": "meta.tag.metadata.$2.void.html", + "patterns": [ + { + "include": "#attribute" + } + ] + }, + { + "begin": "(?i)(<)(noscript|title)(?=\\s|/?>)", + "beginCaptures": { + "1": { + "name": "punctuation.definition.tag.begin.html" + }, + "2": { + "name": "entity.name.tag.html" + } + }, + "end": ">", + "endCaptures": { + "0": { + "name": "punctuation.definition.tag.end.html" + } + }, + "name": "meta.tag.metadata.$2.start.html", + "patterns": [ + { + "include": "#attribute" + } + ] + }, + { + "begin": "(?i)()", + "beginCaptures": { + "1": { + "name": "punctuation.definition.tag.begin.html" + }, + "2": { + "name": "entity.name.tag.html" + } + }, + "end": ">", + "endCaptures": { + "0": { + "name": "punctuation.definition.tag.end.html" + } + }, + "name": "meta.tag.metadata.$2.end.html", + "patterns": [ + { + "include": "#attribute" + } + ] + }, + { + "begin": "(?i)(<)(col|hr|input)(?=\\s|/?>)", + "beginCaptures": { + "1": { + "name": "punctuation.definition.tag.begin.html" + }, + "2": { + "name": "entity.name.tag.html" + } + }, + "end": "/?>", + "endCaptures": { + "0": { + "name": "punctuation.definition.tag.end.html" + } + }, + "name": "meta.tag.structure.$2.void.html", + "patterns": [ + { + "include": "#attribute" + } + ] + }, + { + "begin": "(?i)(<)(address|article|aside|blockquote|body|button|caption|colgroup|datalist|dd|details|dialog|div|dl|dt|fieldset|figcaption|figure|footer|form|head|header|hgroup|html|h[1-6]|label|legend|li|main|map|menu|meter|nav|ol|optgroup|option|output|p|pre|progress|section|select|slot|summary|table|tbody|td|template|textarea|tfoot|th|thead|tr|ul)(?=\\s|/?>)", + "beginCaptures": { + "1": { + "name": "punctuation.definition.tag.begin.html" + }, + "2": { + "name": "entity.name.tag.html" + } + }, + "end": ">", + "endCaptures": { + "0": { + "name": "punctuation.definition.tag.end.html" + } + }, + "name": "meta.tag.structure.$2.start.html", + "patterns": [ + { + "include": "#attribute" + } + ] + }, + { + "begin": "(?i)()", + "beginCaptures": { + "1": { + "name": "punctuation.definition.tag.begin.html" + }, + "2": { + "name": "entity.name.tag.html" + } + }, + "end": ">", + "endCaptures": { + "0": { + "name": "punctuation.definition.tag.end.html" + } + }, + "name": "meta.tag.structure.$2.end.html", + "patterns": [ + { + "include": "#attribute" + } + ] + }, + { + "begin": "(?i)(<)(area|br|wbr)(?=\\s|/?>)", + "beginCaptures": { + "1": { + "name": "punctuation.definition.tag.begin.html" + }, + "2": { + "name": "entity.name.tag.html" + } + }, + "end": "/?>", + "endCaptures": { + "0": { + "name": "punctuation.definition.tag.end.html" + } + }, + "name": "meta.tag.inline.$2.void.html", + "patterns": [ + { + "include": "#attribute" + } + ] + }, + { + "begin": "(?i)(<)(a|abbr|b|bdi|bdo|cite|code|data|del|dfn|em|i|ins|kbd|mark|q|rp|rt|ruby|s|samp|small|span|strong|sub|sup|time|u|var)(?=\\s|/?>)", + "beginCaptures": { + "1": { + "name": "punctuation.definition.tag.begin.html" + }, + "2": { + "name": "entity.name.tag.html" + } + }, + "end": ">", + "endCaptures": { + "0": { + "name": "punctuation.definition.tag.end.html" + } + }, + "name": "meta.tag.inline.$2.start.html", + "patterns": [ + { + "include": "#attribute" + } + ] + }, + { + "begin": "(?i)()", + "beginCaptures": { + "1": { + "name": "punctuation.definition.tag.begin.html" + }, + "2": { + "name": "entity.name.tag.html" + } + }, + "end": ">", + "endCaptures": { + "0": { + "name": "punctuation.definition.tag.end.html" + } + }, + "name": "meta.tag.inline.$2.end.html", + "patterns": [ + { + "include": "#attribute" + } + ] + }, + { + "begin": "(?i)(<)(embed|img|param|source|track)(?=\\s|/?>)", + "beginCaptures": { + "1": { + "name": "punctuation.definition.tag.begin.html" + }, + "2": { + "name": "entity.name.tag.html" + } + }, + "end": "/?>", + "endCaptures": { + "0": { + "name": "punctuation.definition.tag.end.html" + } + }, + "name": "meta.tag.object.$2.void.html", + "patterns": [ + { + "include": "#attribute" + } + ] + }, + { + "begin": "(?i)(<)(audio|canvas|iframe|object|picture|video)(?=\\s|/?>)", + "beginCaptures": { + "1": { + "name": "punctuation.definition.tag.begin.html" + }, + "2": { + "name": "entity.name.tag.html" + } + }, + "end": ">", + "endCaptures": { + "0": { + "name": "punctuation.definition.tag.end.html" + } + }, + "name": "meta.tag.object.$2.start.html", + "patterns": [ + { + "include": "#attribute" + } + ] + }, + { + "begin": "(?i)()", + "beginCaptures": { + "1": { + "name": "punctuation.definition.tag.begin.html" + }, + "2": { + "name": "entity.name.tag.html" + } + }, + "end": ">", + "endCaptures": { + "0": { + "name": "punctuation.definition.tag.end.html" + } + }, + "name": "meta.tag.object.$2.end.html", + "patterns": [ + { + "include": "#attribute" + } + ] + }, + { + "begin": "(?i)(<)((basefont|isindex))(?=\\s|/?>)", + "beginCaptures": { + "1": { + "name": "punctuation.definition.tag.begin.html" + }, + "2": { + "name": "entity.name.tag.html" + }, + "3": { + "name": "invalid.deprecated.html" + } + }, + "end": "/?>", + "endCaptures": { + "0": { + "name": "punctuation.definition.tag.end.html" + } + }, + "name": "meta.tag.metadata.$2.void.html", + "patterns": [ + { + "include": "#attribute" + } + ] + }, + { + "begin": "(?i)(<)((center|frameset|noembed|noframes))(?=\\s|/?>)", + "beginCaptures": { + "1": { + "name": "punctuation.definition.tag.begin.html" + }, + "2": { + "name": "entity.name.tag.html" + }, + "3": { + "name": "invalid.deprecated.html" + } + }, + "end": ">", + "endCaptures": { + "0": { + "name": "punctuation.definition.tag.end.html" + } + }, + "name": "meta.tag.structure.$2.start.html", + "patterns": [ + { + "include": "#attribute" + } + ] + }, + { + "begin": "(?i)()", + "beginCaptures": { + "1": { + "name": "punctuation.definition.tag.begin.html" + }, + "2": { + "name": "entity.name.tag.html" + }, + "3": { + "name": "invalid.deprecated.html" + } + }, + "end": ">", + "endCaptures": { + "0": { + "name": "punctuation.definition.tag.end.html" + } + }, + "name": "meta.tag.structure.$2.end.html", + "patterns": [ + { + "include": "#attribute" + } + ] + }, + { + "begin": "(?i)(<)((acronym|big|blink|font|strike|tt|xmp))(?=\\s|/?>)", + "beginCaptures": { + "1": { + "name": "punctuation.definition.tag.begin.html" + }, + "2": { + "name": "entity.name.tag.html" + }, + "3": { + "name": "invalid.deprecated.html" + } + }, + "end": ">", + "endCaptures": { + "0": { + "name": "punctuation.definition.tag.end.html" + } + }, + "name": "meta.tag.inline.$2.start.html", + "patterns": [ + { + "include": "#attribute" + } + ] + }, + { + "begin": "(?i)()", + "beginCaptures": { + "1": { + "name": "punctuation.definition.tag.begin.html" + }, + "2": { + "name": "entity.name.tag.html" + }, + "3": { + "name": "invalid.deprecated.html" + } + }, + "end": ">", + "endCaptures": { + "0": { + "name": "punctuation.definition.tag.end.html" + } + }, + "name": "meta.tag.inline.$2.end.html", + "patterns": [ + { + "include": "#attribute" + } + ] + }, + { + "begin": "(?i)(<)((frame))(?=\\s|/?>)", + "beginCaptures": { + "1": { + "name": "punctuation.definition.tag.begin.html" + }, + "2": { + "name": "entity.name.tag.html" + }, + "3": { + "name": "invalid.deprecated.html" + } + }, + "end": "/?>", + "endCaptures": { + "0": { + "name": "punctuation.definition.tag.end.html" + } + }, + "name": "meta.tag.object.$2.void.html", + "patterns": [ + { + "include": "#attribute" + } + ] + }, + { + "begin": "(?i)(<)((applet))(?=\\s|/?>)", + "beginCaptures": { + "1": { + "name": "punctuation.definition.tag.begin.html" + }, + "2": { + "name": "entity.name.tag.html" + }, + "3": { + "name": "invalid.deprecated.html" + } + }, + "end": ">", + "endCaptures": { + "0": { + "name": "punctuation.definition.tag.end.html" + } + }, + "name": "meta.tag.object.$2.start.html", + "patterns": [ + { + "include": "#attribute" + } + ] + }, + { + "begin": "(?i)()", + "beginCaptures": { + "1": { + "name": "punctuation.definition.tag.begin.html" + }, + "2": { + "name": "entity.name.tag.html" + }, + "3": { + "name": "invalid.deprecated.html" + } + }, + "end": ">", + "endCaptures": { + "0": { + "name": "punctuation.definition.tag.end.html" + } + }, + "name": "meta.tag.object.$2.end.html", + "patterns": [ + { + "include": "#attribute" + } + ] + }, + { + "begin": "(?i)(<)((dir|keygen|listing|menuitem|plaintext|spacer))(?=\\s|/?>)", + "beginCaptures": { + "1": { + "name": "punctuation.definition.tag.begin.html" + }, + "2": { + "name": "entity.name.tag.html" + }, + "3": { + "name": "invalid.illegal.no-longer-supported.html" + } + }, + "end": ">", + "endCaptures": { + "0": { + "name": "punctuation.definition.tag.end.html" + } + }, + "name": "meta.tag.other.$2.start.html", + "patterns": [ + { + "include": "#attribute" + } + ] + }, + { + "begin": "(?i)()", + "beginCaptures": { + "1": { + "name": "punctuation.definition.tag.begin.html" + }, + "2": { + "name": "entity.name.tag.html" + }, + "3": { + "name": "invalid.illegal.no-longer-supported.html" + } + }, + "end": ">", + "endCaptures": { + "0": { + "name": "punctuation.definition.tag.end.html" + } + }, + "name": "meta.tag.other.$2.end.html", + "patterns": [ + { + "include": "#attribute" + } + ] + }, + { + "include": "#math" + }, + { + "include": "#svg" + }, + { + "begin": "(<)([a-zA-Z][.0-9_a-zA-Z\\x{00B7}\\x{00C0}-\\x{00D6}\\x{00D8}-\\x{00F6}\\x{00F8}-\\x{037D}\\x{037F}-\\x{1FFF}\\x{200C}-\\x{200D}\\x{203F}-\\x{2040}\\x{2070}-\\x{218F}\\x{2C00}-\\x{2FEF}\\x{3001}-\\x{D7FF}\\x{F900}-\\x{FDCF}\\x{FDF0}-\\x{FFFD}\\x{10000}-\\x{EFFFF}]*-[\\-.0-9_a-zA-Z\\x{00B7}\\x{00C0}-\\x{00D6}\\x{00D8}-\\x{00F6}\\x{00F8}-\\x{037D}\\x{037F}-\\x{1FFF}\\x{200C}-\\x{200D}\\x{203F}-\\x{2040}\\x{2070}-\\x{218F}\\x{2C00}-\\x{2FEF}\\x{3001}-\\x{D7FF}\\x{F900}-\\x{FDCF}\\x{FDF0}-\\x{FFFD}\\x{10000}-\\x{EFFFF}]*)(?=\\s|/?>)", + "beginCaptures": { + "1": { + "name": "punctuation.definition.tag.begin.html" + }, + "2": { + "name": "entity.name.tag.html" + } + }, + "end": "/?>", + "endCaptures": { + "0": { + "name": "punctuation.definition.tag.end.html" + } + }, + "name": "meta.tag.custom.start.html", + "patterns": [ + { + "include": "#attribute" + } + ] + }, + { + "begin": "()", + "beginCaptures": { + "1": { + "name": "punctuation.definition.tag.begin.html" + }, + "2": { + "name": "entity.name.tag.html" + } + }, + "end": ">", + "endCaptures": { + "0": { + "name": "punctuation.definition.tag.end.html" + } + }, + "name": "meta.tag.custom.end.html", + "patterns": [ + { + "include": "#attribute" + } + ] + } + ] } } } \ No newline at end of file diff --git a/extensions/html/test/colorize-results/12750_html.json b/extensions/html/test/colorize-results/12750_html.json index a89b03aa84f..389ca104ac5 100644 --- a/extensions/html/test/colorize-results/12750_html.json +++ b/extensions/html/test/colorize-results/12750_html.json @@ -1,7 +1,7 @@ [ { "c": "<", - "t": "text.html.basic meta.embedded.block.html meta.tag.metadata.script.html punctuation.definition.tag.begin.html", + "t": "text.html.basic meta.embedded.block.html meta.tag.metadata.script.start.html punctuation.definition.tag.begin.html", "r": { "dark_plus": "punctuation.definition.tag: #808080", "light_plus": "punctuation.definition.tag: #800000", @@ -12,7 +12,7 @@ }, { "c": "script", - "t": "text.html.basic meta.embedded.block.html meta.tag.metadata.script.html entity.name.tag.html", + "t": "text.html.basic meta.embedded.block.html meta.tag.metadata.script.start.html entity.name.tag.html", "r": { "dark_plus": "entity.name.tag: #569CD6", "light_plus": "entity.name.tag: #800000", @@ -23,7 +23,7 @@ }, { "c": " ", - "t": "text.html.basic meta.embedded.block.html meta.tag.metadata.script.html", + "t": "text.html.basic meta.embedded.block.html meta.tag.metadata.script.start.html", "r": { "dark_plus": "meta.embedded: #D4D4D4", "light_plus": "meta.embedded: #000000", @@ -34,7 +34,7 @@ }, { "c": "type", - "t": "text.html.basic meta.embedded.block.html meta.tag.metadata.script.html entity.other.attribute-name.html", + "t": "text.html.basic meta.embedded.block.html meta.tag.metadata.script.start.html meta.attribute.type.html entity.other.attribute-name.html", "r": { "dark_plus": "entity.other.attribute-name: #9CDCFE", "light_plus": "entity.other.attribute-name: #FF0000", @@ -45,7 +45,7 @@ }, { "c": "=", - "t": "text.html.basic meta.embedded.block.html meta.tag.metadata.script.html", + "t": "text.html.basic meta.embedded.block.html meta.tag.metadata.script.start.html meta.attribute.type.html punctuation.separator.key-value.html", "r": { "dark_plus": "meta.embedded: #D4D4D4", "light_plus": "meta.embedded: #000000", @@ -56,7 +56,7 @@ }, { "c": "\"", - "t": "text.html.basic meta.embedded.block.html meta.tag.metadata.script.html string.quoted.double.html punctuation.definition.string.begin.html", + "t": "text.html.basic meta.embedded.block.html meta.tag.metadata.script.start.html meta.attribute.type.html string.quoted.double.html punctuation.definition.string.begin.html", "r": { "dark_plus": "string: #CE9178", "light_plus": "string.quoted.double.html: #0000FF", @@ -67,7 +67,7 @@ }, { "c": "text/javascript", - "t": "text.html.basic meta.embedded.block.html meta.tag.metadata.script.html string.quoted.double.html", + "t": "text.html.basic meta.embedded.block.html meta.tag.metadata.script.start.html meta.attribute.type.html string.quoted.double.html", "r": { "dark_plus": "string: #CE9178", "light_plus": "string.quoted.double.html: #0000FF", @@ -78,7 +78,7 @@ }, { "c": "\"", - "t": "text.html.basic meta.embedded.block.html meta.tag.metadata.script.html string.quoted.double.html punctuation.definition.string.end.html", + "t": "text.html.basic meta.embedded.block.html meta.tag.metadata.script.start.html meta.attribute.type.html string.quoted.double.html punctuation.definition.string.end.html", "r": { "dark_plus": "string: #CE9178", "light_plus": "string.quoted.double.html: #0000FF", @@ -89,7 +89,7 @@ }, { "c": ">", - "t": "text.html.basic meta.embedded.block.html meta.tag.metadata.script.html punctuation.definition.tag.end.html", + "t": "text.html.basic meta.embedded.block.html meta.tag.metadata.script.start.html punctuation.definition.tag.end.html", "r": { "dark_plus": "punctuation.definition.tag: #808080", "light_plus": "punctuation.definition.tag: #800000", @@ -210,7 +210,7 @@ }, { "c": "<", - "t": "text.html.basic meta.embedded.block.html meta.tag.metadata.script.html punctuation.definition.tag.begin.html source.js", + "t": "text.html.basic meta.embedded.block.html meta.tag.metadata.script.end.html punctuation.definition.tag.begin.html source.js", "r": { "dark_plus": "punctuation.definition.tag: #808080", "light_plus": "punctuation.definition.tag: #800000", @@ -221,7 +221,7 @@ }, { "c": "/", - "t": "text.html.basic meta.embedded.block.html meta.tag.metadata.script.html punctuation.definition.tag.begin.html", + "t": "text.html.basic meta.embedded.block.html meta.tag.metadata.script.end.html punctuation.definition.tag.begin.html", "r": { "dark_plus": "punctuation.definition.tag: #808080", "light_plus": "punctuation.definition.tag: #800000", @@ -232,7 +232,7 @@ }, { "c": "script", - "t": "text.html.basic meta.embedded.block.html meta.tag.metadata.script.html entity.name.tag.html", + "t": "text.html.basic meta.embedded.block.html meta.tag.metadata.script.end.html entity.name.tag.html", "r": { "dark_plus": "entity.name.tag: #569CD6", "light_plus": "entity.name.tag: #800000", @@ -243,7 +243,7 @@ }, { "c": ">", - "t": "text.html.basic meta.embedded.block.html meta.tag.metadata.script.html punctuation.definition.tag.end.html", + "t": "text.html.basic meta.embedded.block.html meta.tag.metadata.script.end.html punctuation.definition.tag.end.html", "r": { "dark_plus": "punctuation.definition.tag: #808080", "light_plus": "punctuation.definition.tag: #800000", @@ -254,7 +254,7 @@ }, { "c": "<", - "t": "text.html.basic meta.embedded.block.html meta.tag.metadata.script.html punctuation.definition.tag.begin.html", + "t": "text.html.basic meta.embedded.block.html meta.tag.metadata.script.start.html punctuation.definition.tag.begin.html", "r": { "dark_plus": "punctuation.definition.tag: #808080", "light_plus": "punctuation.definition.tag: #800000", @@ -265,7 +265,7 @@ }, { "c": "script", - "t": "text.html.basic meta.embedded.block.html meta.tag.metadata.script.html entity.name.tag.html", + "t": "text.html.basic meta.embedded.block.html meta.tag.metadata.script.start.html entity.name.tag.html", "r": { "dark_plus": "entity.name.tag: #569CD6", "light_plus": "entity.name.tag: #800000", @@ -276,7 +276,7 @@ }, { "c": ">", - "t": "text.html.basic meta.embedded.block.html meta.tag.metadata.script.html punctuation.definition.tag.end.html", + "t": "text.html.basic meta.embedded.block.html meta.tag.metadata.script.start.html punctuation.definition.tag.end.html", "r": { "dark_plus": "punctuation.definition.tag: #808080", "light_plus": "punctuation.definition.tag: #800000", @@ -397,7 +397,7 @@ }, { "c": "<", - "t": "text.html.basic meta.embedded.block.html meta.tag.metadata.script.html punctuation.definition.tag.begin.html source.js", + "t": "text.html.basic meta.embedded.block.html meta.tag.metadata.script.end.html punctuation.definition.tag.begin.html source.js", "r": { "dark_plus": "punctuation.definition.tag: #808080", "light_plus": "punctuation.definition.tag: #800000", @@ -408,7 +408,7 @@ }, { "c": "/", - "t": "text.html.basic meta.embedded.block.html meta.tag.metadata.script.html punctuation.definition.tag.begin.html", + "t": "text.html.basic meta.embedded.block.html meta.tag.metadata.script.end.html punctuation.definition.tag.begin.html", "r": { "dark_plus": "punctuation.definition.tag: #808080", "light_plus": "punctuation.definition.tag: #800000", @@ -419,7 +419,7 @@ }, { "c": "script", - "t": "text.html.basic meta.embedded.block.html meta.tag.metadata.script.html entity.name.tag.html", + "t": "text.html.basic meta.embedded.block.html meta.tag.metadata.script.end.html entity.name.tag.html", "r": { "dark_plus": "entity.name.tag: #569CD6", "light_plus": "entity.name.tag: #800000", @@ -430,7 +430,7 @@ }, { "c": ">", - "t": "text.html.basic meta.embedded.block.html meta.tag.metadata.script.html punctuation.definition.tag.end.html", + "t": "text.html.basic meta.embedded.block.html meta.tag.metadata.script.end.html punctuation.definition.tag.end.html", "r": { "dark_plus": "punctuation.definition.tag: #808080", "light_plus": "punctuation.definition.tag: #800000", diff --git a/extensions/html/test/colorize-results/13448_html.json b/extensions/html/test/colorize-results/13448_html.json index 1a442d66c0b..2be7fc0e698 100644 --- a/extensions/html/test/colorize-results/13448_html.json +++ b/extensions/html/test/colorize-results/13448_html.json @@ -1,7 +1,7 @@ [ { "c": "<", - "t": "text.html.basic meta.tag.other.html punctuation.definition.tag.begin.html", + "t": "text.html.basic meta.tag.custom.start.html punctuation.definition.tag.begin.html", "r": { "dark_plus": "punctuation.definition.tag: #808080", "light_plus": "punctuation.definition.tag: #800000", @@ -12,7 +12,7 @@ }, { "c": "ion-view", - "t": "text.html.basic meta.tag.other.html entity.name.tag.other.html", + "t": "text.html.basic meta.tag.custom.start.html entity.name.tag.html", "r": { "dark_plus": "entity.name.tag: #569CD6", "light_plus": "entity.name.tag: #800000", @@ -23,7 +23,7 @@ }, { "c": ">", - "t": "text.html.basic meta.tag.other.html punctuation.definition.tag.end.html", + "t": "text.html.basic meta.tag.custom.start.html punctuation.definition.tag.end.html", "r": { "dark_plus": "punctuation.definition.tag: #808080", "light_plus": "punctuation.definition.tag: #800000", @@ -34,7 +34,7 @@ }, { "c": "<", - "t": "text.html.basic meta.tag.other.html punctuation.definition.tag.begin.html", + "t": "text.html.basic meta.tag.custom.start.html punctuation.definition.tag.begin.html", "r": { "dark_plus": "punctuation.definition.tag: #808080", "light_plus": "punctuation.definition.tag: #800000", @@ -45,7 +45,7 @@ }, { "c": "button-view", - "t": "text.html.basic meta.tag.other.html entity.name.tag.other.html", + "t": "text.html.basic meta.tag.custom.start.html entity.name.tag.html", "r": { "dark_plus": "entity.name.tag: #569CD6", "light_plus": "entity.name.tag: #800000", @@ -56,7 +56,7 @@ }, { "c": "/>", - "t": "text.html.basic meta.tag.other.html punctuation.definition.tag.end.html", + "t": "text.html.basic meta.tag.custom.start.html punctuation.definition.tag.end.html", "r": { "dark_plus": "punctuation.definition.tag: #808080", "light_plus": "punctuation.definition.tag: #800000", @@ -67,7 +67,7 @@ }, { "c": "<", - "t": "text.html.basic meta.tag.any.html punctuation.definition.tag.html", + "t": "text.html.basic meta.tag.custom.start.html punctuation.definition.tag.begin.html", "r": { "dark_plus": "punctuation.definition.tag: #808080", "light_plus": "punctuation.definition.tag: #800000", @@ -78,7 +78,7 @@ }, { "c": "font-face", - "t": "text.html.basic meta.tag.any.html entity.name.tag.html", + "t": "text.html.basic meta.tag.custom.start.html entity.name.tag.html", "r": { "dark_plus": "entity.name.tag: #569CD6", "light_plus": "entity.name.tag: #800000", @@ -89,51 +89,7 @@ }, { "c": ">", - "t": "text.html.basic meta.tag.any.html punctuation.definition.tag.html", - "r": { - "dark_plus": "punctuation.definition.tag: #808080", - "light_plus": "punctuation.definition.tag: #800000", - "dark_vs": "punctuation.definition.tag: #808080", - "light_vs": "punctuation.definition.tag: #800000", - "hc_black": "punctuation.definition.tag: #808080" - } - }, - { - "c": "<", - "t": "text.html.basic meta.tag.any.html punctuation.definition.tag.html meta.scope.between-tag-pair.html", - "r": { - "dark_plus": "punctuation.definition.tag: #808080", - "light_plus": "punctuation.definition.tag: #800000", - "dark_vs": "punctuation.definition.tag: #808080", - "light_vs": "punctuation.definition.tag: #800000", - "hc_black": "punctuation.definition.tag: #808080" - } - }, - { - "c": "/", - "t": "text.html.basic meta.tag.any.html punctuation.definition.tag.html", - "r": { - "dark_plus": "punctuation.definition.tag: #808080", - "light_plus": "punctuation.definition.tag: #800000", - "dark_vs": "punctuation.definition.tag: #808080", - "light_vs": "punctuation.definition.tag: #800000", - "hc_black": "punctuation.definition.tag: #808080" - } - }, - { - "c": "font-face", - "t": "text.html.basic meta.tag.any.html entity.name.tag.html", - "r": { - "dark_plus": "entity.name.tag: #569CD6", - "light_plus": "entity.name.tag: #800000", - "dark_vs": "entity.name.tag: #569CD6", - "light_vs": "entity.name.tag: #800000", - "hc_black": "entity.name.tag: #569CD6" - } - }, - { - "c": ">", - "t": "text.html.basic meta.tag.any.html punctuation.definition.tag.html", + "t": "text.html.basic meta.tag.custom.start.html punctuation.definition.tag.end.html", "r": { "dark_plus": "punctuation.definition.tag: #808080", "light_plus": "punctuation.definition.tag: #800000", @@ -144,7 +100,7 @@ }, { "c": "", - "t": "text.html.basic meta.tag.other.html punctuation.definition.tag.end.html", + "t": "text.html.basic meta.tag.custom.end.html punctuation.definition.tag.end.html", + "r": { + "dark_plus": "punctuation.definition.tag: #808080", + "light_plus": "punctuation.definition.tag: #800000", + "dark_vs": "punctuation.definition.tag: #808080", + "light_vs": "punctuation.definition.tag: #800000", + "hc_black": "punctuation.definition.tag: #808080" + } + }, + { + "c": "", + "t": "text.html.basic meta.tag.custom.end.html punctuation.definition.tag.end.html", "r": { "dark_plus": "punctuation.definition.tag: #808080", "light_plus": "punctuation.definition.tag: #800000", diff --git a/extensions/html/test/colorize-results/25920_html.json b/extensions/html/test/colorize-results/25920_html.json index 16b71acbe88..81f4d3c143b 100644 --- a/extensions/html/test/colorize-results/25920_html.json +++ b/extensions/html/test/colorize-results/25920_html.json @@ -1,7 +1,7 @@ [ { "c": "<", - "t": "text.html.basic meta.tag.structure.any.html punctuation.definition.tag.html", + "t": "text.html.basic meta.tag.structure.html.start.html punctuation.definition.tag.begin.html", "r": { "dark_plus": "punctuation.definition.tag: #808080", "light_plus": "punctuation.definition.tag: #800000", @@ -12,7 +12,7 @@ }, { "c": "html", - "t": "text.html.basic meta.tag.structure.any.html entity.name.tag.structure.any.html", + "t": "text.html.basic meta.tag.structure.html.start.html entity.name.tag.html", "r": { "dark_plus": "entity.name.tag: #569CD6", "light_plus": "entity.name.tag: #800000", @@ -23,7 +23,7 @@ }, { "c": ">", - "t": "text.html.basic meta.tag.structure.any.html punctuation.definition.tag.html", + "t": "text.html.basic meta.tag.structure.html.start.html punctuation.definition.tag.end.html", "r": { "dark_plus": "punctuation.definition.tag: #808080", "light_plus": "punctuation.definition.tag: #800000", @@ -34,7 +34,7 @@ }, { "c": "<", - "t": "text.html.basic meta.embedded.block.html meta.tag.metadata.script.html punctuation.definition.tag.begin.html", + "t": "text.html.basic meta.embedded.block.html meta.tag.metadata.script.start.html punctuation.definition.tag.begin.html", "r": { "dark_plus": "punctuation.definition.tag: #808080", "light_plus": "punctuation.definition.tag: #800000", @@ -45,7 +45,7 @@ }, { "c": "script", - "t": "text.html.basic meta.embedded.block.html meta.tag.metadata.script.html entity.name.tag.html", + "t": "text.html.basic meta.embedded.block.html meta.tag.metadata.script.start.html entity.name.tag.html", "r": { "dark_plus": "entity.name.tag: #569CD6", "light_plus": "entity.name.tag: #800000", @@ -56,7 +56,7 @@ }, { "c": " ", - "t": "text.html.basic meta.embedded.block.html meta.tag.metadata.script.html", + "t": "text.html.basic meta.embedded.block.html meta.tag.metadata.script.start.html", "r": { "dark_plus": "meta.embedded: #D4D4D4", "light_plus": "meta.embedded: #000000", @@ -67,7 +67,7 @@ }, { "c": "type", - "t": "text.html.basic meta.embedded.block.html meta.tag.metadata.script.html entity.other.attribute-name.html", + "t": "text.html.basic meta.embedded.block.html meta.tag.metadata.script.start.html meta.attribute.type.html entity.other.attribute-name.html", "r": { "dark_plus": "entity.other.attribute-name: #9CDCFE", "light_plus": "entity.other.attribute-name: #FF0000", @@ -78,7 +78,7 @@ }, { "c": "=", - "t": "text.html.basic meta.embedded.block.html meta.tag.metadata.script.html", + "t": "text.html.basic meta.embedded.block.html meta.tag.metadata.script.start.html meta.attribute.type.html punctuation.separator.key-value.html", "r": { "dark_plus": "meta.embedded: #D4D4D4", "light_plus": "meta.embedded: #000000", @@ -89,7 +89,7 @@ }, { "c": "'", - "t": "text.html.basic meta.embedded.block.html meta.tag.metadata.script.html string.quoted.single.html punctuation.definition.string.begin.html", + "t": "text.html.basic meta.embedded.block.html meta.tag.metadata.script.start.html meta.attribute.type.html string.quoted.single.html punctuation.definition.string.begin.html", "r": { "dark_plus": "string: #CE9178", "light_plus": "string.quoted.single.html: #0000FF", @@ -100,7 +100,7 @@ }, { "c": "text/html", - "t": "text.html.basic meta.embedded.block.html meta.tag.metadata.script.html string.quoted.single.html", + "t": "text.html.basic meta.embedded.block.html meta.tag.metadata.script.start.html meta.attribute.type.html string.quoted.single.html", "r": { "dark_plus": "string: #CE9178", "light_plus": "string.quoted.single.html: #0000FF", @@ -111,7 +111,7 @@ }, { "c": "'", - "t": "text.html.basic meta.embedded.block.html meta.tag.metadata.script.html string.quoted.single.html punctuation.definition.string.end.html", + "t": "text.html.basic meta.embedded.block.html meta.tag.metadata.script.start.html meta.attribute.type.html string.quoted.single.html punctuation.definition.string.end.html", "r": { "dark_plus": "string: #CE9178", "light_plus": "string.quoted.single.html: #0000FF", @@ -122,7 +122,7 @@ }, { "c": ">", - "t": "text.html.basic meta.embedded.block.html meta.tag.metadata.script.html punctuation.definition.tag.end.html", + "t": "text.html.basic meta.embedded.block.html meta.tag.metadata.script.start.html punctuation.definition.tag.end.html", "r": { "dark_plus": "punctuation.definition.tag: #808080", "light_plus": "punctuation.definition.tag: #800000", @@ -144,7 +144,7 @@ }, { "c": "<", - "t": "text.html.basic meta.embedded.block.html text.html.basic meta.tag.any.html punctuation.definition.tag.html", + "t": "text.html.basic meta.embedded.block.html text.html.basic meta.tag.structure.div.start.html punctuation.definition.tag.begin.html", "r": { "dark_plus": "punctuation.definition.tag: #808080", "light_plus": "punctuation.definition.tag: #800000", @@ -155,7 +155,7 @@ }, { "c": "div", - "t": "text.html.basic meta.embedded.block.html text.html.basic meta.tag.any.html entity.name.tag.html", + "t": "text.html.basic meta.embedded.block.html text.html.basic meta.tag.structure.div.start.html entity.name.tag.html", "r": { "dark_plus": "entity.name.tag: #569CD6", "light_plus": "entity.name.tag: #800000", @@ -166,7 +166,7 @@ }, { "c": " ", - "t": "text.html.basic meta.embedded.block.html text.html.basic meta.tag.any.html", + "t": "text.html.basic meta.embedded.block.html text.html.basic meta.tag.structure.div.start.html", "r": { "dark_plus": "meta.embedded: #D4D4D4", "light_plus": "meta.embedded: #000000", @@ -177,7 +177,7 @@ }, { "c": "class", - "t": "text.html.basic meta.embedded.block.html text.html.basic meta.tag.any.html entity.other.attribute-name.html", + "t": "text.html.basic meta.embedded.block.html text.html.basic meta.tag.structure.div.start.html meta.attribute.class.html entity.other.attribute-name.html", "r": { "dark_plus": "entity.other.attribute-name: #9CDCFE", "light_plus": "entity.other.attribute-name: #FF0000", @@ -188,7 +188,7 @@ }, { "c": "=", - "t": "text.html.basic meta.embedded.block.html text.html.basic meta.tag.any.html", + "t": "text.html.basic meta.embedded.block.html text.html.basic meta.tag.structure.div.start.html meta.attribute.class.html punctuation.separator.key-value.html", "r": { "dark_plus": "meta.embedded: #D4D4D4", "light_plus": "meta.embedded: #000000", @@ -199,7 +199,7 @@ }, { "c": "'", - "t": "text.html.basic meta.embedded.block.html text.html.basic meta.tag.any.html string.quoted.single.html punctuation.definition.string.begin.html", + "t": "text.html.basic meta.embedded.block.html text.html.basic meta.tag.structure.div.start.html meta.attribute.class.html string.quoted.single.html punctuation.definition.string.begin.html", "r": { "dark_plus": "string: #CE9178", "light_plus": "string.quoted.single.html: #0000FF", @@ -210,7 +210,7 @@ }, { "c": "foo", - "t": "text.html.basic meta.embedded.block.html text.html.basic meta.tag.any.html string.quoted.single.html", + "t": "text.html.basic meta.embedded.block.html text.html.basic meta.tag.structure.div.start.html meta.attribute.class.html string.quoted.single.html", "r": { "dark_plus": "string: #CE9178", "light_plus": "string.quoted.single.html: #0000FF", @@ -221,7 +221,7 @@ }, { "c": "'", - "t": "text.html.basic meta.embedded.block.html text.html.basic meta.tag.any.html string.quoted.single.html punctuation.definition.string.end.html", + "t": "text.html.basic meta.embedded.block.html text.html.basic meta.tag.structure.div.start.html meta.attribute.class.html string.quoted.single.html punctuation.definition.string.end.html", "r": { "dark_plus": "string: #CE9178", "light_plus": "string.quoted.single.html: #0000FF", @@ -232,7 +232,7 @@ }, { "c": ">", - "t": "text.html.basic meta.embedded.block.html text.html.basic meta.tag.any.html punctuation.definition.tag.html", + "t": "text.html.basic meta.embedded.block.html text.html.basic meta.tag.structure.div.start.html punctuation.definition.tag.end.html", "r": { "dark_plus": "punctuation.definition.tag: #808080", "light_plus": "punctuation.definition.tag: #800000", @@ -242,19 +242,8 @@ } }, { - "c": "<", - "t": "text.html.basic meta.embedded.block.html text.html.basic meta.tag.any.html punctuation.definition.tag.html meta.scope.between-tag-pair.html", - "r": { - "dark_plus": "punctuation.definition.tag: #808080", - "light_plus": "punctuation.definition.tag: #800000", - "dark_vs": "punctuation.definition.tag: #808080", - "light_vs": "punctuation.definition.tag: #800000", - "hc_black": "punctuation.definition.tag: #808080" - } - }, - { - "c": "/", - "t": "text.html.basic meta.embedded.block.html text.html.basic meta.tag.any.html punctuation.definition.tag.html", + "c": "", - "t": "text.html.basic meta.embedded.block.html text.html.basic meta.tag.any.html punctuation.definition.tag.html", + "t": "text.html.basic meta.embedded.block.html text.html.basic meta.tag.structure.div.end.html punctuation.definition.tag.end.html", "r": { "dark_plus": "punctuation.definition.tag: #808080", "light_plus": "punctuation.definition.tag: #800000", @@ -287,7 +276,7 @@ }, { "c": "<", - "t": "text.html.basic meta.embedded.block.html meta.tag.metadata.script.html punctuation.definition.tag.begin.html text.html.basic", + "t": "text.html.basic meta.embedded.block.html meta.tag.metadata.script.end.html punctuation.definition.tag.begin.html text.html.basic", "r": { "dark_plus": "punctuation.definition.tag: #808080", "light_plus": "punctuation.definition.tag: #800000", @@ -298,7 +287,7 @@ }, { "c": "/", - "t": "text.html.basic meta.embedded.block.html meta.tag.metadata.script.html punctuation.definition.tag.begin.html", + "t": "text.html.basic meta.embedded.block.html meta.tag.metadata.script.end.html punctuation.definition.tag.begin.html", "r": { "dark_plus": "punctuation.definition.tag: #808080", "light_plus": "punctuation.definition.tag: #800000", @@ -309,7 +298,7 @@ }, { "c": "script", - "t": "text.html.basic meta.embedded.block.html meta.tag.metadata.script.html entity.name.tag.html", + "t": "text.html.basic meta.embedded.block.html meta.tag.metadata.script.end.html entity.name.tag.html", "r": { "dark_plus": "entity.name.tag: #569CD6", "light_plus": "entity.name.tag: #800000", @@ -320,7 +309,7 @@ }, { "c": ">", - "t": "text.html.basic meta.embedded.block.html meta.tag.metadata.script.html punctuation.definition.tag.end.html", + "t": "text.html.basic meta.embedded.block.html meta.tag.metadata.script.end.html punctuation.definition.tag.end.html", "r": { "dark_plus": "punctuation.definition.tag: #808080", "light_plus": "punctuation.definition.tag: #800000", @@ -331,7 +320,7 @@ }, { "c": "<", - "t": "text.html.basic meta.embedded.block.html meta.tag.metadata.script.html punctuation.definition.tag.begin.html", + "t": "text.html.basic meta.embedded.block.html meta.tag.metadata.script.start.html punctuation.definition.tag.begin.html", "r": { "dark_plus": "punctuation.definition.tag: #808080", "light_plus": "punctuation.definition.tag: #800000", @@ -342,7 +331,7 @@ }, { "c": "script", - "t": "text.html.basic meta.embedded.block.html meta.tag.metadata.script.html entity.name.tag.html", + "t": "text.html.basic meta.embedded.block.html meta.tag.metadata.script.start.html entity.name.tag.html", "r": { "dark_plus": "entity.name.tag: #569CD6", "light_plus": "entity.name.tag: #800000", @@ -353,7 +342,7 @@ }, { "c": " ", - "t": "text.html.basic meta.embedded.block.html meta.tag.metadata.script.html", + "t": "text.html.basic meta.embedded.block.html meta.tag.metadata.script.start.html", "r": { "dark_plus": "meta.embedded: #D4D4D4", "light_plus": "meta.embedded: #000000", @@ -364,7 +353,7 @@ }, { "c": "type", - "t": "text.html.basic meta.embedded.block.html meta.tag.metadata.script.html entity.other.attribute-name.html", + "t": "text.html.basic meta.embedded.block.html meta.tag.metadata.script.start.html meta.attribute.type.html entity.other.attribute-name.html", "r": { "dark_plus": "entity.other.attribute-name: #9CDCFE", "light_plus": "entity.other.attribute-name: #FF0000", @@ -375,7 +364,7 @@ }, { "c": "=", - "t": "text.html.basic meta.embedded.block.html meta.tag.metadata.script.html", + "t": "text.html.basic meta.embedded.block.html meta.tag.metadata.script.start.html meta.attribute.type.html punctuation.separator.key-value.html", "r": { "dark_plus": "meta.embedded: #D4D4D4", "light_plus": "meta.embedded: #000000", @@ -386,7 +375,7 @@ }, { "c": "'", - "t": "text.html.basic meta.embedded.block.html meta.tag.metadata.script.html string.quoted.single.html punctuation.definition.string.begin.html", + "t": "text.html.basic meta.embedded.block.html meta.tag.metadata.script.start.html meta.attribute.type.html string.quoted.single.html punctuation.definition.string.begin.html", "r": { "dark_plus": "string: #CE9178", "light_plus": "string.quoted.single.html: #0000FF", @@ -397,7 +386,7 @@ }, { "c": "module", - "t": "text.html.basic meta.embedded.block.html meta.tag.metadata.script.html string.quoted.single.html", + "t": "text.html.basic meta.embedded.block.html meta.tag.metadata.script.start.html meta.attribute.type.html string.quoted.single.html", "r": { "dark_plus": "string: #CE9178", "light_plus": "string.quoted.single.html: #0000FF", @@ -408,7 +397,7 @@ }, { "c": "'", - "t": "text.html.basic meta.embedded.block.html meta.tag.metadata.script.html string.quoted.single.html punctuation.definition.string.end.html", + "t": "text.html.basic meta.embedded.block.html meta.tag.metadata.script.start.html meta.attribute.type.html string.quoted.single.html punctuation.definition.string.end.html", "r": { "dark_plus": "string: #CE9178", "light_plus": "string.quoted.single.html: #0000FF", @@ -419,7 +408,7 @@ }, { "c": ">", - "t": "text.html.basic meta.embedded.block.html meta.tag.metadata.script.html punctuation.definition.tag.end.html", + "t": "text.html.basic meta.embedded.block.html meta.tag.metadata.script.start.html punctuation.definition.tag.end.html", "r": { "dark_plus": "punctuation.definition.tag: #808080", "light_plus": "punctuation.definition.tag: #800000", @@ -529,7 +518,7 @@ }, { "c": "<", - "t": "text.html.basic meta.embedded.block.html meta.tag.metadata.script.html punctuation.definition.tag.begin.html source.js", + "t": "text.html.basic meta.embedded.block.html meta.tag.metadata.script.end.html punctuation.definition.tag.begin.html source.js", "r": { "dark_plus": "punctuation.definition.tag: #808080", "light_plus": "punctuation.definition.tag: #800000", @@ -540,7 +529,7 @@ }, { "c": "/", - "t": "text.html.basic meta.embedded.block.html meta.tag.metadata.script.html punctuation.definition.tag.begin.html", + "t": "text.html.basic meta.embedded.block.html meta.tag.metadata.script.end.html punctuation.definition.tag.begin.html", "r": { "dark_plus": "punctuation.definition.tag: #808080", "light_plus": "punctuation.definition.tag: #800000", @@ -551,7 +540,7 @@ }, { "c": "script", - "t": "text.html.basic meta.embedded.block.html meta.tag.metadata.script.html entity.name.tag.html", + "t": "text.html.basic meta.embedded.block.html meta.tag.metadata.script.end.html entity.name.tag.html", "r": { "dark_plus": "entity.name.tag: #569CD6", "light_plus": "entity.name.tag: #800000", @@ -562,7 +551,7 @@ }, { "c": ">", - "t": "text.html.basic meta.embedded.block.html meta.tag.metadata.script.html punctuation.definition.tag.end.html", + "t": "text.html.basic meta.embedded.block.html meta.tag.metadata.script.end.html punctuation.definition.tag.end.html", "r": { "dark_plus": "punctuation.definition.tag: #808080", "light_plus": "punctuation.definition.tag: #800000", @@ -573,7 +562,7 @@ }, { "c": "<", - "t": "text.html.basic meta.embedded.block.html meta.tag.metadata.script.html punctuation.definition.tag.begin.html", + "t": "text.html.basic meta.embedded.block.html meta.tag.metadata.script.start.html punctuation.definition.tag.begin.html", "r": { "dark_plus": "punctuation.definition.tag: #808080", "light_plus": "punctuation.definition.tag: #800000", @@ -584,7 +573,7 @@ }, { "c": "script", - "t": "text.html.basic meta.embedded.block.html meta.tag.metadata.script.html entity.name.tag.html", + "t": "text.html.basic meta.embedded.block.html meta.tag.metadata.script.start.html entity.name.tag.html", "r": { "dark_plus": "entity.name.tag: #569CD6", "light_plus": "entity.name.tag: #800000", @@ -595,7 +584,7 @@ }, { "c": " ", - "t": "text.html.basic meta.embedded.block.html meta.tag.metadata.script.html", + "t": "text.html.basic meta.embedded.block.html meta.tag.metadata.script.start.html", "r": { "dark_plus": "meta.embedded: #D4D4D4", "light_plus": "meta.embedded: #000000", @@ -606,7 +595,7 @@ }, { "c": "type", - "t": "text.html.basic meta.embedded.block.html meta.tag.metadata.script.html entity.other.attribute-name.html", + "t": "text.html.basic meta.embedded.block.html meta.tag.metadata.script.start.html meta.attribute.type.html entity.other.attribute-name.html", "r": { "dark_plus": "entity.other.attribute-name: #9CDCFE", "light_plus": "entity.other.attribute-name: #FF0000", @@ -617,7 +606,7 @@ }, { "c": "=", - "t": "text.html.basic meta.embedded.block.html meta.tag.metadata.script.html", + "t": "text.html.basic meta.embedded.block.html meta.tag.metadata.script.start.html meta.attribute.type.html punctuation.separator.key-value.html", "r": { "dark_plus": "meta.embedded: #D4D4D4", "light_plus": "meta.embedded: #000000", @@ -628,7 +617,7 @@ }, { "c": "'", - "t": "text.html.basic meta.embedded.block.html meta.tag.metadata.script.html string.quoted.single.html punctuation.definition.string.begin.html", + "t": "text.html.basic meta.embedded.block.html meta.tag.metadata.script.start.html meta.attribute.type.html string.quoted.single.html punctuation.definition.string.begin.html", "r": { "dark_plus": "string: #CE9178", "light_plus": "string.quoted.single.html: #0000FF", @@ -639,7 +628,7 @@ }, { "c": "text/ng-template", - "t": "text.html.basic meta.embedded.block.html meta.tag.metadata.script.html string.quoted.single.html", + "t": "text.html.basic meta.embedded.block.html meta.tag.metadata.script.start.html meta.attribute.type.html string.quoted.single.html", "r": { "dark_plus": "string: #CE9178", "light_plus": "string.quoted.single.html: #0000FF", @@ -650,7 +639,7 @@ }, { "c": "'", - "t": "text.html.basic meta.embedded.block.html meta.tag.metadata.script.html string.quoted.single.html punctuation.definition.string.end.html", + "t": "text.html.basic meta.embedded.block.html meta.tag.metadata.script.start.html meta.attribute.type.html string.quoted.single.html punctuation.definition.string.end.html", "r": { "dark_plus": "string: #CE9178", "light_plus": "string.quoted.single.html: #0000FF", @@ -661,7 +650,7 @@ }, { "c": ">", - "t": "text.html.basic meta.embedded.block.html meta.tag.metadata.script.html punctuation.definition.tag.end.html", + "t": "text.html.basic meta.embedded.block.html meta.tag.metadata.script.start.html punctuation.definition.tag.end.html", "r": { "dark_plus": "punctuation.definition.tag: #808080", "light_plus": "punctuation.definition.tag: #800000", @@ -683,7 +672,7 @@ }, { "c": "<", - "t": "text.html.basic meta.embedded.block.html text.html.basic meta.tag.any.html punctuation.definition.tag.html", + "t": "text.html.basic meta.embedded.block.html text.html.basic meta.tag.structure.div.start.html punctuation.definition.tag.begin.html", "r": { "dark_plus": "punctuation.definition.tag: #808080", "light_plus": "punctuation.definition.tag: #800000", @@ -694,7 +683,7 @@ }, { "c": "div", - "t": "text.html.basic meta.embedded.block.html text.html.basic meta.tag.any.html entity.name.tag.html", + "t": "text.html.basic meta.embedded.block.html text.html.basic meta.tag.structure.div.start.html entity.name.tag.html", "r": { "dark_plus": "entity.name.tag: #569CD6", "light_plus": "entity.name.tag: #800000", @@ -705,7 +694,7 @@ }, { "c": " ", - "t": "text.html.basic meta.embedded.block.html text.html.basic meta.tag.any.html", + "t": "text.html.basic meta.embedded.block.html text.html.basic meta.tag.structure.div.start.html", "r": { "dark_plus": "meta.embedded: #D4D4D4", "light_plus": "meta.embedded: #000000", @@ -716,7 +705,7 @@ }, { "c": "class", - "t": "text.html.basic meta.embedded.block.html text.html.basic meta.tag.any.html entity.other.attribute-name.html", + "t": "text.html.basic meta.embedded.block.html text.html.basic meta.tag.structure.div.start.html meta.attribute.class.html entity.other.attribute-name.html", "r": { "dark_plus": "entity.other.attribute-name: #9CDCFE", "light_plus": "entity.other.attribute-name: #FF0000", @@ -727,7 +716,7 @@ }, { "c": "=", - "t": "text.html.basic meta.embedded.block.html text.html.basic meta.tag.any.html", + "t": "text.html.basic meta.embedded.block.html text.html.basic meta.tag.structure.div.start.html meta.attribute.class.html punctuation.separator.key-value.html", "r": { "dark_plus": "meta.embedded: #D4D4D4", "light_plus": "meta.embedded: #000000", @@ -738,7 +727,7 @@ }, { "c": "'", - "t": "text.html.basic meta.embedded.block.html text.html.basic meta.tag.any.html string.quoted.single.html punctuation.definition.string.begin.html", + "t": "text.html.basic meta.embedded.block.html text.html.basic meta.tag.structure.div.start.html meta.attribute.class.html string.quoted.single.html punctuation.definition.string.begin.html", "r": { "dark_plus": "string: #CE9178", "light_plus": "string.quoted.single.html: #0000FF", @@ -749,7 +738,7 @@ }, { "c": "foo", - "t": "text.html.basic meta.embedded.block.html text.html.basic meta.tag.any.html string.quoted.single.html", + "t": "text.html.basic meta.embedded.block.html text.html.basic meta.tag.structure.div.start.html meta.attribute.class.html string.quoted.single.html", "r": { "dark_plus": "string: #CE9178", "light_plus": "string.quoted.single.html: #0000FF", @@ -760,7 +749,7 @@ }, { "c": "'", - "t": "text.html.basic meta.embedded.block.html text.html.basic meta.tag.any.html string.quoted.single.html punctuation.definition.string.end.html", + "t": "text.html.basic meta.embedded.block.html text.html.basic meta.tag.structure.div.start.html meta.attribute.class.html string.quoted.single.html punctuation.definition.string.end.html", "r": { "dark_plus": "string: #CE9178", "light_plus": "string.quoted.single.html: #0000FF", @@ -771,7 +760,7 @@ }, { "c": ">", - "t": "text.html.basic meta.embedded.block.html text.html.basic meta.tag.any.html punctuation.definition.tag.html", + "t": "text.html.basic meta.embedded.block.html text.html.basic meta.tag.structure.div.start.html punctuation.definition.tag.end.html", "r": { "dark_plus": "punctuation.definition.tag: #808080", "light_plus": "punctuation.definition.tag: #800000", @@ -781,19 +770,8 @@ } }, { - "c": "<", - "t": "text.html.basic meta.embedded.block.html text.html.basic meta.tag.any.html punctuation.definition.tag.html meta.scope.between-tag-pair.html", - "r": { - "dark_plus": "punctuation.definition.tag: #808080", - "light_plus": "punctuation.definition.tag: #800000", - "dark_vs": "punctuation.definition.tag: #808080", - "light_vs": "punctuation.definition.tag: #800000", - "hc_black": "punctuation.definition.tag: #808080" - } - }, - { - "c": "/", - "t": "text.html.basic meta.embedded.block.html text.html.basic meta.tag.any.html punctuation.definition.tag.html", + "c": "", - "t": "text.html.basic meta.embedded.block.html text.html.basic meta.tag.any.html punctuation.definition.tag.html", + "t": "text.html.basic meta.embedded.block.html text.html.basic meta.tag.structure.div.end.html punctuation.definition.tag.end.html", "r": { "dark_plus": "punctuation.definition.tag: #808080", "light_plus": "punctuation.definition.tag: #800000", @@ -826,7 +804,7 @@ }, { "c": "<", - "t": "text.html.basic meta.embedded.block.html meta.tag.metadata.script.html punctuation.definition.tag.begin.html text.html.basic", + "t": "text.html.basic meta.embedded.block.html meta.tag.metadata.script.end.html punctuation.definition.tag.begin.html text.html.basic", "r": { "dark_plus": "punctuation.definition.tag: #808080", "light_plus": "punctuation.definition.tag: #800000", @@ -837,7 +815,7 @@ }, { "c": "/", - "t": "text.html.basic meta.embedded.block.html meta.tag.metadata.script.html punctuation.definition.tag.begin.html", + "t": "text.html.basic meta.embedded.block.html meta.tag.metadata.script.end.html punctuation.definition.tag.begin.html", "r": { "dark_plus": "punctuation.definition.tag: #808080", "light_plus": "punctuation.definition.tag: #800000", @@ -848,7 +826,7 @@ }, { "c": "script", - "t": "text.html.basic meta.embedded.block.html meta.tag.metadata.script.html entity.name.tag.html", + "t": "text.html.basic meta.embedded.block.html meta.tag.metadata.script.end.html entity.name.tag.html", "r": { "dark_plus": "entity.name.tag: #569CD6", "light_plus": "entity.name.tag: #800000", @@ -859,7 +837,7 @@ }, { "c": ">", - "t": "text.html.basic meta.embedded.block.html meta.tag.metadata.script.html punctuation.definition.tag.end.html", + "t": "text.html.basic meta.embedded.block.html meta.tag.metadata.script.end.html punctuation.definition.tag.end.html", "r": { "dark_plus": "punctuation.definition.tag: #808080", "light_plus": "punctuation.definition.tag: #800000", @@ -870,7 +848,7 @@ }, { "c": "<", - "t": "text.html.basic meta.tag.structure.any.html punctuation.definition.tag.html", + "t": "text.html.basic meta.tag.structure.body.start.html punctuation.definition.tag.begin.html", "r": { "dark_plus": "punctuation.definition.tag: #808080", "light_plus": "punctuation.definition.tag: #800000", @@ -881,7 +859,7 @@ }, { "c": "body", - "t": "text.html.basic meta.tag.structure.any.html entity.name.tag.structure.any.html", + "t": "text.html.basic meta.tag.structure.body.start.html entity.name.tag.html", "r": { "dark_plus": "entity.name.tag: #569CD6", "light_plus": "entity.name.tag: #800000", @@ -892,7 +870,7 @@ }, { "c": " ", - "t": "text.html.basic meta.tag.structure.any.html", + "t": "text.html.basic meta.tag.structure.body.start.html", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -903,7 +881,7 @@ }, { "c": "class", - "t": "text.html.basic meta.tag.structure.any.html entity.other.attribute-name.html", + "t": "text.html.basic meta.tag.structure.body.start.html meta.attribute.class.html entity.other.attribute-name.html", "r": { "dark_plus": "entity.other.attribute-name: #9CDCFE", "light_plus": "entity.other.attribute-name: #FF0000", @@ -914,7 +892,7 @@ }, { "c": "=", - "t": "text.html.basic meta.tag.structure.any.html", + "t": "text.html.basic meta.tag.structure.body.start.html meta.attribute.class.html punctuation.separator.key-value.html", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -925,7 +903,7 @@ }, { "c": "'", - "t": "text.html.basic meta.tag.structure.any.html string.quoted.single.html punctuation.definition.string.begin.html", + "t": "text.html.basic meta.tag.structure.body.start.html meta.attribute.class.html string.quoted.single.html punctuation.definition.string.begin.html", "r": { "dark_plus": "string: #CE9178", "light_plus": "string.quoted.single.html: #0000FF", @@ -936,7 +914,7 @@ }, { "c": "bar", - "t": "text.html.basic meta.tag.structure.any.html string.quoted.single.html", + "t": "text.html.basic meta.tag.structure.body.start.html meta.attribute.class.html string.quoted.single.html", "r": { "dark_plus": "string: #CE9178", "light_plus": "string.quoted.single.html: #0000FF", @@ -947,7 +925,7 @@ }, { "c": "'", - "t": "text.html.basic meta.tag.structure.any.html string.quoted.single.html punctuation.definition.string.end.html", + "t": "text.html.basic meta.tag.structure.body.start.html meta.attribute.class.html string.quoted.single.html punctuation.definition.string.end.html", "r": { "dark_plus": "string: #CE9178", "light_plus": "string.quoted.single.html: #0000FF", @@ -958,7 +936,7 @@ }, { "c": ">", - "t": "text.html.basic meta.tag.structure.any.html punctuation.definition.tag.html", + "t": "text.html.basic meta.tag.structure.body.start.html punctuation.definition.tag.end.html", "r": { "dark_plus": "punctuation.definition.tag: #808080", "light_plus": "punctuation.definition.tag: #800000", @@ -969,7 +947,7 @@ }, { "c": "", - "t": "text.html.basic meta.tag.structure.any.html punctuation.definition.tag.html", + "t": "text.html.basic meta.tag.structure.body.end.html punctuation.definition.tag.end.html", "r": { "dark_plus": "punctuation.definition.tag: #808080", "light_plus": "punctuation.definition.tag: #800000", @@ -1002,7 +980,7 @@ }, { "c": "", - "t": "text.html.basic meta.tag.structure.any.html punctuation.definition.tag.html", + "t": "text.html.basic meta.tag.structure.html.end.html punctuation.definition.tag.end.html", "r": { "dark_plus": "punctuation.definition.tag: #808080", "light_plus": "punctuation.definition.tag: #800000", diff --git a/extensions/html/test/colorize-results/test_html.json b/extensions/html/test/colorize-results/test_html.json index a1da5d2c393..20ca7fac857 100644 --- a/extensions/html/test/colorize-results/test_html.json +++ b/extensions/html/test/colorize-results/test_html.json @@ -1,7 +1,7 @@ [ { "c": "<", - "t": "text.html.basic meta.tag.structure.any.html punctuation.definition.tag.html", + "t": "text.html.basic meta.tag.structure.html.start.html punctuation.definition.tag.begin.html", "r": { "dark_plus": "punctuation.definition.tag: #808080", "light_plus": "punctuation.definition.tag: #800000", @@ -12,7 +12,7 @@ }, { "c": "html", - "t": "text.html.basic meta.tag.structure.any.html entity.name.tag.structure.any.html", + "t": "text.html.basic meta.tag.structure.html.start.html entity.name.tag.html", "r": { "dark_plus": "entity.name.tag: #569CD6", "light_plus": "entity.name.tag: #800000", @@ -23,7 +23,7 @@ }, { "c": ">", - "t": "text.html.basic meta.tag.structure.any.html punctuation.definition.tag.html", + "t": "text.html.basic meta.tag.structure.html.start.html punctuation.definition.tag.end.html", "r": { "dark_plus": "punctuation.definition.tag: #808080", "light_plus": "punctuation.definition.tag: #800000", @@ -34,7 +34,7 @@ }, { "c": "<", - "t": "text.html.basic meta.tag.structure.any.html punctuation.definition.tag.html", + "t": "text.html.basic meta.tag.structure.head.start.html punctuation.definition.tag.begin.html", "r": { "dark_plus": "punctuation.definition.tag: #808080", "light_plus": "punctuation.definition.tag: #800000", @@ -45,7 +45,7 @@ }, { "c": "head", - "t": "text.html.basic meta.tag.structure.any.html entity.name.tag.structure.any.html", + "t": "text.html.basic meta.tag.structure.head.start.html entity.name.tag.html", "r": { "dark_plus": "entity.name.tag: #569CD6", "light_plus": "entity.name.tag: #800000", @@ -56,7 +56,7 @@ }, { "c": ">", - "t": "text.html.basic meta.tag.structure.any.html punctuation.definition.tag.html", + "t": "text.html.basic meta.tag.structure.head.start.html punctuation.definition.tag.end.html", "r": { "dark_plus": "punctuation.definition.tag: #808080", "light_plus": "punctuation.definition.tag: #800000", @@ -78,7 +78,7 @@ }, { "c": "<", - "t": "text.html.basic meta.tag.inline.any.html punctuation.definition.tag.begin.html", + "t": "text.html.basic meta.tag.metadata.meta.void.html punctuation.definition.tag.begin.html", "r": { "dark_plus": "punctuation.definition.tag: #808080", "light_plus": "punctuation.definition.tag: #800000", @@ -89,7 +89,7 @@ }, { "c": "meta", - "t": "text.html.basic meta.tag.inline.any.html entity.name.tag.inline.any.html", + "t": "text.html.basic meta.tag.metadata.meta.void.html entity.name.tag.html", "r": { "dark_plus": "entity.name.tag: #569CD6", "light_plus": "entity.name.tag: #800000", @@ -100,7 +100,7 @@ }, { "c": " ", - "t": "text.html.basic meta.tag.inline.any.html", + "t": "text.html.basic meta.tag.metadata.meta.void.html", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -111,7 +111,7 @@ }, { "c": "charset", - "t": "text.html.basic meta.tag.inline.any.html entity.other.attribute-name.html", + "t": "text.html.basic meta.tag.metadata.meta.void.html meta.attribute.charset.html entity.other.attribute-name.html", "r": { "dark_plus": "entity.other.attribute-name: #9CDCFE", "light_plus": "entity.other.attribute-name: #FF0000", @@ -122,7 +122,7 @@ }, { "c": "=", - "t": "text.html.basic meta.tag.inline.any.html", + "t": "text.html.basic meta.tag.metadata.meta.void.html meta.attribute.charset.html punctuation.separator.key-value.html", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -133,7 +133,7 @@ }, { "c": "\"", - "t": "text.html.basic meta.tag.inline.any.html string.quoted.double.html punctuation.definition.string.begin.html", + "t": "text.html.basic meta.tag.metadata.meta.void.html meta.attribute.charset.html string.quoted.double.html punctuation.definition.string.begin.html", "r": { "dark_plus": "string: #CE9178", "light_plus": "string.quoted.double.html: #0000FF", @@ -144,7 +144,7 @@ }, { "c": "utf-8", - "t": "text.html.basic meta.tag.inline.any.html string.quoted.double.html", + "t": "text.html.basic meta.tag.metadata.meta.void.html meta.attribute.charset.html string.quoted.double.html", "r": { "dark_plus": "string: #CE9178", "light_plus": "string.quoted.double.html: #0000FF", @@ -155,7 +155,7 @@ }, { "c": "\"", - "t": "text.html.basic meta.tag.inline.any.html string.quoted.double.html punctuation.definition.string.end.html", + "t": "text.html.basic meta.tag.metadata.meta.void.html meta.attribute.charset.html string.quoted.double.html punctuation.definition.string.end.html", "r": { "dark_plus": "string: #CE9178", "light_plus": "string.quoted.double.html: #0000FF", @@ -166,7 +166,7 @@ }, { "c": ">", - "t": "text.html.basic meta.tag.inline.any.html punctuation.definition.tag.end.html", + "t": "text.html.basic meta.tag.metadata.meta.void.html punctuation.definition.tag.end.html", "r": { "dark_plus": "punctuation.definition.tag: #808080", "light_plus": "punctuation.definition.tag: #800000", @@ -188,7 +188,7 @@ }, { "c": "<", - "t": "text.html.basic meta.tag.inline.any.html punctuation.definition.tag.begin.html", + "t": "text.html.basic meta.tag.metadata.title.start.html punctuation.definition.tag.begin.html", "r": { "dark_plus": "punctuation.definition.tag: #808080", "light_plus": "punctuation.definition.tag: #800000", @@ -199,7 +199,7 @@ }, { "c": "title", - "t": "text.html.basic meta.tag.inline.any.html entity.name.tag.inline.any.html", + "t": "text.html.basic meta.tag.metadata.title.start.html entity.name.tag.html", "r": { "dark_plus": "entity.name.tag: #569CD6", "light_plus": "entity.name.tag: #800000", @@ -210,7 +210,7 @@ }, { "c": ">", - "t": "text.html.basic meta.tag.inline.any.html punctuation.definition.tag.end.html", + "t": "text.html.basic meta.tag.metadata.title.start.html punctuation.definition.tag.end.html", "r": { "dark_plus": "punctuation.definition.tag: #808080", "light_plus": "punctuation.definition.tag: #800000", @@ -232,7 +232,7 @@ }, { "c": "", - "t": "text.html.basic meta.tag.inline.any.html punctuation.definition.tag.end.html", + "t": "text.html.basic meta.tag.metadata.title.end.html punctuation.definition.tag.end.html", "r": { "dark_plus": "punctuation.definition.tag: #808080", "light_plus": "punctuation.definition.tag: #800000", @@ -276,7 +276,7 @@ }, { "c": "<", - "t": "text.html.basic meta.tag.inline.any.html punctuation.definition.tag.begin.html", + "t": "text.html.basic meta.tag.metadata.link.void.html punctuation.definition.tag.begin.html", "r": { "dark_plus": "punctuation.definition.tag: #808080", "light_plus": "punctuation.definition.tag: #800000", @@ -287,7 +287,7 @@ }, { "c": "link", - "t": "text.html.basic meta.tag.inline.any.html entity.name.tag.inline.any.html", + "t": "text.html.basic meta.tag.metadata.link.void.html entity.name.tag.html", "r": { "dark_plus": "entity.name.tag: #569CD6", "light_plus": "entity.name.tag: #800000", @@ -298,7 +298,7 @@ }, { "c": " ", - "t": "text.html.basic meta.tag.inline.any.html", + "t": "text.html.basic meta.tag.metadata.link.void.html", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -309,7 +309,7 @@ }, { "c": "href", - "t": "text.html.basic meta.tag.inline.any.html entity.other.attribute-name.html", + "t": "text.html.basic meta.tag.metadata.link.void.html meta.attribute.href.html entity.other.attribute-name.html", "r": { "dark_plus": "entity.other.attribute-name: #9CDCFE", "light_plus": "entity.other.attribute-name: #FF0000", @@ -320,7 +320,7 @@ }, { "c": "=", - "t": "text.html.basic meta.tag.inline.any.html", + "t": "text.html.basic meta.tag.metadata.link.void.html meta.attribute.href.html punctuation.separator.key-value.html", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -331,7 +331,7 @@ }, { "c": "\"", - "t": "text.html.basic meta.tag.inline.any.html string.quoted.double.html punctuation.definition.string.begin.html", + "t": "text.html.basic meta.tag.metadata.link.void.html meta.attribute.href.html string.quoted.double.html punctuation.definition.string.begin.html", "r": { "dark_plus": "string: #CE9178", "light_plus": "string.quoted.double.html: #0000FF", @@ -342,7 +342,7 @@ }, { "c": "https://cdn.rawgit.com/mochajs/mocha/2.2.5/mocha.css", - "t": "text.html.basic meta.tag.inline.any.html string.quoted.double.html", + "t": "text.html.basic meta.tag.metadata.link.void.html meta.attribute.href.html string.quoted.double.html", "r": { "dark_plus": "string: #CE9178", "light_plus": "string.quoted.double.html: #0000FF", @@ -353,7 +353,7 @@ }, { "c": "\"", - "t": "text.html.basic meta.tag.inline.any.html string.quoted.double.html punctuation.definition.string.end.html", + "t": "text.html.basic meta.tag.metadata.link.void.html meta.attribute.href.html string.quoted.double.html punctuation.definition.string.end.html", "r": { "dark_plus": "string: #CE9178", "light_plus": "string.quoted.double.html: #0000FF", @@ -364,7 +364,7 @@ }, { "c": " ", - "t": "text.html.basic meta.tag.inline.any.html", + "t": "text.html.basic meta.tag.metadata.link.void.html", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -375,7 +375,7 @@ }, { "c": "rel", - "t": "text.html.basic meta.tag.inline.any.html entity.other.attribute-name.html", + "t": "text.html.basic meta.tag.metadata.link.void.html meta.attribute.rel.html entity.other.attribute-name.html", "r": { "dark_plus": "entity.other.attribute-name: #9CDCFE", "light_plus": "entity.other.attribute-name: #FF0000", @@ -386,7 +386,7 @@ }, { "c": "=", - "t": "text.html.basic meta.tag.inline.any.html", + "t": "text.html.basic meta.tag.metadata.link.void.html meta.attribute.rel.html punctuation.separator.key-value.html", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -397,7 +397,7 @@ }, { "c": "\"", - "t": "text.html.basic meta.tag.inline.any.html string.quoted.double.html punctuation.definition.string.begin.html", + "t": "text.html.basic meta.tag.metadata.link.void.html meta.attribute.rel.html string.quoted.double.html punctuation.definition.string.begin.html", "r": { "dark_plus": "string: #CE9178", "light_plus": "string.quoted.double.html: #0000FF", @@ -408,7 +408,7 @@ }, { "c": "stylesheet", - "t": "text.html.basic meta.tag.inline.any.html string.quoted.double.html", + "t": "text.html.basic meta.tag.metadata.link.void.html meta.attribute.rel.html string.quoted.double.html", "r": { "dark_plus": "string: #CE9178", "light_plus": "string.quoted.double.html: #0000FF", @@ -419,7 +419,7 @@ }, { "c": "\"", - "t": "text.html.basic meta.tag.inline.any.html string.quoted.double.html punctuation.definition.string.end.html", + "t": "text.html.basic meta.tag.metadata.link.void.html meta.attribute.rel.html string.quoted.double.html punctuation.definition.string.end.html", "r": { "dark_plus": "string: #CE9178", "light_plus": "string.quoted.double.html: #0000FF", @@ -429,8 +429,19 @@ } }, { - "c": " />", - "t": "text.html.basic meta.tag.inline.any.html punctuation.definition.tag.end.html", + "c": " ", + "t": "text.html.basic meta.tag.metadata.link.void.html", + "r": { + "dark_plus": "default: #D4D4D4", + "light_plus": "default: #000000", + "dark_vs": "default: #D4D4D4", + "light_vs": "default: #000000", + "hc_black": "default: #FFFFFF" + } + }, + { + "c": "/>", + "t": "text.html.basic meta.tag.metadata.link.void.html punctuation.definition.tag.end.html", "r": { "dark_plus": "punctuation.definition.tag: #808080", "light_plus": "punctuation.definition.tag: #800000", @@ -452,7 +463,7 @@ }, { "c": "<", - "t": "text.html.basic meta.embedded.block.html meta.tag.metadata.style.html punctuation.definition.tag.begin.html", + "t": "text.html.basic meta.embedded.block.html meta.tag.metadata.style.start.html punctuation.definition.tag.begin.html", "r": { "dark_plus": "punctuation.definition.tag: #808080", "light_plus": "punctuation.definition.tag: #800000", @@ -463,7 +474,7 @@ }, { "c": "style", - "t": "text.html.basic meta.embedded.block.html meta.tag.metadata.style.html entity.name.tag.html", + "t": "text.html.basic meta.embedded.block.html meta.tag.metadata.style.start.html entity.name.tag.html", "r": { "dark_plus": "entity.name.tag: #569CD6", "light_plus": "entity.name.tag: #800000", @@ -474,7 +485,7 @@ }, { "c": " ", - "t": "text.html.basic meta.embedded.block.html meta.tag.metadata.style.html", + "t": "text.html.basic meta.embedded.block.html meta.tag.metadata.style.start.html", "r": { "dark_plus": "meta.embedded: #D4D4D4", "light_plus": "meta.embedded: #000000", @@ -485,7 +496,7 @@ }, { "c": "type", - "t": "text.html.basic meta.embedded.block.html meta.tag.metadata.style.html entity.other.attribute-name.html", + "t": "text.html.basic meta.embedded.block.html meta.tag.metadata.style.start.html meta.attribute.type.html entity.other.attribute-name.html", "r": { "dark_plus": "entity.other.attribute-name: #9CDCFE", "light_plus": "entity.other.attribute-name: #FF0000", @@ -496,7 +507,7 @@ }, { "c": "=", - "t": "text.html.basic meta.embedded.block.html meta.tag.metadata.style.html", + "t": "text.html.basic meta.embedded.block.html meta.tag.metadata.style.start.html meta.attribute.type.html punctuation.separator.key-value.html", "r": { "dark_plus": "meta.embedded: #D4D4D4", "light_plus": "meta.embedded: #000000", @@ -507,7 +518,7 @@ }, { "c": "\"", - "t": "text.html.basic meta.embedded.block.html meta.tag.metadata.style.html string.quoted.double.html punctuation.definition.string.begin.html", + "t": "text.html.basic meta.embedded.block.html meta.tag.metadata.style.start.html meta.attribute.type.html string.quoted.double.html punctuation.definition.string.begin.html", "r": { "dark_plus": "string: #CE9178", "light_plus": "string.quoted.double.html: #0000FF", @@ -518,7 +529,7 @@ }, { "c": "text/css", - "t": "text.html.basic meta.embedded.block.html meta.tag.metadata.style.html string.quoted.double.html", + "t": "text.html.basic meta.embedded.block.html meta.tag.metadata.style.start.html meta.attribute.type.html string.quoted.double.html", "r": { "dark_plus": "string: #CE9178", "light_plus": "string.quoted.double.html: #0000FF", @@ -529,7 +540,7 @@ }, { "c": "\"", - "t": "text.html.basic meta.embedded.block.html meta.tag.metadata.style.html string.quoted.double.html punctuation.definition.string.end.html", + "t": "text.html.basic meta.embedded.block.html meta.tag.metadata.style.start.html meta.attribute.type.html string.quoted.double.html punctuation.definition.string.end.html", "r": { "dark_plus": "string: #CE9178", "light_plus": "string.quoted.double.html: #0000FF", @@ -540,7 +551,7 @@ }, { "c": ">", - "t": "text.html.basic meta.embedded.block.html meta.tag.metadata.style.html punctuation.definition.tag.end.html", + "t": "text.html.basic meta.embedded.block.html meta.tag.metadata.style.start.html punctuation.definition.tag.end.html", "r": { "dark_plus": "punctuation.definition.tag: #808080", "light_plus": "punctuation.definition.tag: #800000", @@ -771,7 +782,7 @@ }, { "c": "<", - "t": "text.html.basic meta.embedded.block.html meta.tag.metadata.style.html punctuation.definition.tag.begin.html source.css", + "t": "text.html.basic meta.embedded.block.html meta.tag.metadata.style.end.html punctuation.definition.tag.begin.html source.css", "r": { "dark_plus": "punctuation.definition.tag: #808080", "light_plus": "punctuation.definition.tag: #800000", @@ -782,7 +793,7 @@ }, { "c": "/", - "t": "text.html.basic meta.embedded.block.html meta.tag.metadata.style.html punctuation.definition.tag.begin.html", + "t": "text.html.basic meta.embedded.block.html meta.tag.metadata.style.end.html punctuation.definition.tag.begin.html", "r": { "dark_plus": "punctuation.definition.tag: #808080", "light_plus": "punctuation.definition.tag: #800000", @@ -793,7 +804,7 @@ }, { "c": "style", - "t": "text.html.basic meta.embedded.block.html meta.tag.metadata.style.html entity.name.tag.html", + "t": "text.html.basic meta.embedded.block.html meta.tag.metadata.style.end.html entity.name.tag.html", "r": { "dark_plus": "entity.name.tag: #569CD6", "light_plus": "entity.name.tag: #800000", @@ -804,7 +815,7 @@ }, { "c": ">", - "t": "text.html.basic meta.embedded.block.html meta.tag.metadata.style.html punctuation.definition.tag.end.html", + "t": "text.html.basic meta.embedded.block.html meta.tag.metadata.style.end.html punctuation.definition.tag.end.html", "r": { "dark_plus": "punctuation.definition.tag: #808080", "light_plus": "punctuation.definition.tag: #800000", @@ -815,7 +826,7 @@ }, { "c": "", - "t": "text.html.basic meta.tag.structure.any.html punctuation.definition.tag.html", + "t": "text.html.basic meta.tag.structure.head.end.html punctuation.definition.tag.end.html", "r": { "dark_plus": "punctuation.definition.tag: #808080", "light_plus": "punctuation.definition.tag: #800000", @@ -848,7 +859,7 @@ }, { "c": "<", - "t": "text.html.basic meta.tag.structure.any.html punctuation.definition.tag.html", + "t": "text.html.basic meta.tag.structure.body.start.html punctuation.definition.tag.begin.html", "r": { "dark_plus": "punctuation.definition.tag: #808080", "light_plus": "punctuation.definition.tag: #800000", @@ -859,7 +870,7 @@ }, { "c": "body", - "t": "text.html.basic meta.tag.structure.any.html entity.name.tag.structure.any.html", + "t": "text.html.basic meta.tag.structure.body.start.html entity.name.tag.html", "r": { "dark_plus": "entity.name.tag: #569CD6", "light_plus": "entity.name.tag: #800000", @@ -870,7 +881,7 @@ }, { "c": ">", - "t": "text.html.basic meta.tag.structure.any.html punctuation.definition.tag.html", + "t": "text.html.basic meta.tag.structure.body.start.html punctuation.definition.tag.end.html", "r": { "dark_plus": "punctuation.definition.tag: #808080", "light_plus": "punctuation.definition.tag: #800000", @@ -892,7 +903,7 @@ }, { "c": "<", - "t": "text.html.basic meta.tag.any.html punctuation.definition.tag.html", + "t": "text.html.basic meta.tag.structure.div.start.html punctuation.definition.tag.begin.html", "r": { "dark_plus": "punctuation.definition.tag: #808080", "light_plus": "punctuation.definition.tag: #800000", @@ -903,7 +914,7 @@ }, { "c": "div", - "t": "text.html.basic meta.tag.any.html entity.name.tag.html", + "t": "text.html.basic meta.tag.structure.div.start.html entity.name.tag.html", "r": { "dark_plus": "entity.name.tag: #569CD6", "light_plus": "entity.name.tag: #800000", @@ -914,7 +925,7 @@ }, { "c": " ", - "t": "text.html.basic meta.tag.any.html", + "t": "text.html.basic meta.tag.structure.div.start.html", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -925,7 +936,7 @@ }, { "c": "id", - "t": "text.html.basic meta.tag.any.html meta.attribute-with-value.id.html entity.other.attribute-name.id.html", + "t": "text.html.basic meta.tag.structure.div.start.html meta.attribute.id.html entity.other.attribute-name.html", "r": { "dark_plus": "entity.other.attribute-name: #9CDCFE", "light_plus": "entity.other.attribute-name: #FF0000", @@ -936,7 +947,7 @@ }, { "c": "=", - "t": "text.html.basic meta.tag.any.html meta.attribute-with-value.id.html punctuation.separator.key-value.html", + "t": "text.html.basic meta.tag.structure.div.start.html meta.attribute.id.html punctuation.separator.key-value.html", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -947,7 +958,7 @@ }, { "c": "\"", - "t": "text.html.basic meta.tag.any.html meta.attribute-with-value.id.html string.quoted.double.html punctuation.definition.string.begin.html", + "t": "text.html.basic meta.tag.structure.div.start.html meta.attribute.id.html string.quoted.double.html punctuation.definition.string.begin.html", "r": { "dark_plus": "string: #CE9178", "light_plus": "string.quoted.double.html: #0000FF", @@ -958,7 +969,7 @@ }, { "c": "mocha", - "t": "text.html.basic meta.tag.any.html meta.attribute-with-value.id.html string.quoted.double.html meta.toc-list.id.html", + "t": "text.html.basic meta.tag.structure.div.start.html meta.attribute.id.html string.quoted.double.html", "r": { "dark_plus": "string: #CE9178", "light_plus": "string.quoted.double.html: #0000FF", @@ -969,7 +980,7 @@ }, { "c": "\"", - "t": "text.html.basic meta.tag.any.html meta.attribute-with-value.id.html string.quoted.double.html punctuation.definition.string.end.html", + "t": "text.html.basic meta.tag.structure.div.start.html meta.attribute.id.html string.quoted.double.html punctuation.definition.string.end.html", "r": { "dark_plus": "string: #CE9178", "light_plus": "string.quoted.double.html: #0000FF", @@ -980,7 +991,7 @@ }, { "c": ">", - "t": "text.html.basic meta.tag.any.html punctuation.definition.tag.html", + "t": "text.html.basic meta.tag.structure.div.start.html punctuation.definition.tag.end.html", "r": { "dark_plus": "punctuation.definition.tag: #808080", "light_plus": "punctuation.definition.tag: #800000", @@ -990,19 +1001,8 @@ } }, { - "c": "<", - "t": "text.html.basic meta.tag.any.html punctuation.definition.tag.html meta.scope.between-tag-pair.html", - "r": { - "dark_plus": "punctuation.definition.tag: #808080", - "light_plus": "punctuation.definition.tag: #800000", - "dark_vs": "punctuation.definition.tag: #808080", - "light_vs": "punctuation.definition.tag: #800000", - "hc_black": "punctuation.definition.tag: #808080" - } - }, - { - "c": "/", - "t": "text.html.basic meta.tag.any.html punctuation.definition.tag.html", + "c": "", - "t": "text.html.basic meta.tag.any.html punctuation.definition.tag.html", + "t": "text.html.basic meta.tag.structure.div.end.html punctuation.definition.tag.end.html", "r": { "dark_plus": "punctuation.definition.tag: #808080", "light_plus": "punctuation.definition.tag: #800000", @@ -1048,9 +1048,9 @@ "c": "", "t": "text.html.basic comment.block.html punctuation.definition.comment.html", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -1101,7 +1101,7 @@ }, { "c": "<", - "t": "text.html.basic meta.embedded.block.html meta.tag.metadata.script.html punctuation.definition.tag.begin.html", + "t": "text.html.basic meta.embedded.block.html meta.tag.metadata.script.start.html punctuation.definition.tag.begin.html", "r": { "dark_plus": "punctuation.definition.tag: #808080", "light_plus": "punctuation.definition.tag: #800000", @@ -1112,7 +1112,7 @@ }, { "c": "script", - "t": "text.html.basic meta.embedded.block.html meta.tag.metadata.script.html entity.name.tag.html", + "t": "text.html.basic meta.embedded.block.html meta.tag.metadata.script.start.html entity.name.tag.html", "r": { "dark_plus": "entity.name.tag: #569CD6", "light_plus": "entity.name.tag: #800000", @@ -1123,7 +1123,7 @@ }, { "c": " ", - "t": "text.html.basic meta.embedded.block.html meta.tag.metadata.script.html", + "t": "text.html.basic meta.embedded.block.html meta.tag.metadata.script.start.html", "r": { "dark_plus": "meta.embedded: #D4D4D4", "light_plus": "meta.embedded: #000000", @@ -1134,7 +1134,7 @@ }, { "c": "src", - "t": "text.html.basic meta.embedded.block.html meta.tag.metadata.script.html entity.other.attribute-name.html", + "t": "text.html.basic meta.embedded.block.html meta.tag.metadata.script.start.html meta.attribute.src.html entity.other.attribute-name.html", "r": { "dark_plus": "entity.other.attribute-name: #9CDCFE", "light_plus": "entity.other.attribute-name: #FF0000", @@ -1145,7 +1145,7 @@ }, { "c": "=", - "t": "text.html.basic meta.embedded.block.html meta.tag.metadata.script.html", + "t": "text.html.basic meta.embedded.block.html meta.tag.metadata.script.start.html meta.attribute.src.html punctuation.separator.key-value.html", "r": { "dark_plus": "meta.embedded: #D4D4D4", "light_plus": "meta.embedded: #000000", @@ -1156,7 +1156,7 @@ }, { "c": "\"", - "t": "text.html.basic meta.embedded.block.html meta.tag.metadata.script.html string.quoted.double.html punctuation.definition.string.begin.html", + "t": "text.html.basic meta.embedded.block.html meta.tag.metadata.script.start.html meta.attribute.src.html string.quoted.double.html punctuation.definition.string.begin.html", "r": { "dark_plus": "string: #CE9178", "light_plus": "string.quoted.double.html: #0000FF", @@ -1167,7 +1167,7 @@ }, { "c": "/out/vs/loader.js", - "t": "text.html.basic meta.embedded.block.html meta.tag.metadata.script.html string.quoted.double.html", + "t": "text.html.basic meta.embedded.block.html meta.tag.metadata.script.start.html meta.attribute.src.html string.quoted.double.html", "r": { "dark_plus": "string: #CE9178", "light_plus": "string.quoted.double.html: #0000FF", @@ -1178,7 +1178,7 @@ }, { "c": "\"", - "t": "text.html.basic meta.embedded.block.html meta.tag.metadata.script.html string.quoted.double.html punctuation.definition.string.end.html", + "t": "text.html.basic meta.embedded.block.html meta.tag.metadata.script.start.html meta.attribute.src.html string.quoted.double.html punctuation.definition.string.end.html", "r": { "dark_plus": "string: #CE9178", "light_plus": "string.quoted.double.html: #0000FF", @@ -1189,7 +1189,7 @@ }, { "c": ">", - "t": "text.html.basic meta.embedded.block.html meta.tag.metadata.script.html punctuation.definition.tag.end.html", + "t": "text.html.basic meta.embedded.block.html meta.tag.metadata.script.start.html punctuation.definition.tag.end.html", "r": { "dark_plus": "punctuation.definition.tag: #808080", "light_plus": "punctuation.definition.tag: #800000", @@ -1200,7 +1200,7 @@ }, { "c": "<", - "t": "text.html.basic meta.embedded.block.html meta.tag.metadata.script.html punctuation.definition.tag.begin.html source.js", + "t": "text.html.basic meta.embedded.block.html meta.tag.metadata.script.end.html punctuation.definition.tag.begin.html source.js", "r": { "dark_plus": "punctuation.definition.tag: #808080", "light_plus": "punctuation.definition.tag: #800000", @@ -1211,7 +1211,7 @@ }, { "c": "/", - "t": "text.html.basic meta.embedded.block.html meta.tag.metadata.script.html punctuation.definition.tag.begin.html", + "t": "text.html.basic meta.embedded.block.html meta.tag.metadata.script.end.html punctuation.definition.tag.begin.html", "r": { "dark_plus": "punctuation.definition.tag: #808080", "light_plus": "punctuation.definition.tag: #800000", @@ -1222,7 +1222,7 @@ }, { "c": "script", - "t": "text.html.basic meta.embedded.block.html meta.tag.metadata.script.html entity.name.tag.html", + "t": "text.html.basic meta.embedded.block.html meta.tag.metadata.script.end.html entity.name.tag.html", "r": { "dark_plus": "entity.name.tag: #569CD6", "light_plus": "entity.name.tag: #800000", @@ -1233,7 +1233,7 @@ }, { "c": ">", - "t": "text.html.basic meta.embedded.block.html meta.tag.metadata.script.html punctuation.definition.tag.end.html", + "t": "text.html.basic meta.embedded.block.html meta.tag.metadata.script.end.html punctuation.definition.tag.end.html", "r": { "dark_plus": "punctuation.definition.tag: #808080", "light_plus": "punctuation.definition.tag: #800000", @@ -1255,7 +1255,7 @@ }, { "c": "<", - "t": "text.html.basic meta.embedded.block.html meta.tag.metadata.script.html punctuation.definition.tag.begin.html", + "t": "text.html.basic meta.embedded.block.html meta.tag.metadata.script.start.html punctuation.definition.tag.begin.html", "r": { "dark_plus": "punctuation.definition.tag: #808080", "light_plus": "punctuation.definition.tag: #800000", @@ -1266,7 +1266,7 @@ }, { "c": "script", - "t": "text.html.basic meta.embedded.block.html meta.tag.metadata.script.html entity.name.tag.html", + "t": "text.html.basic meta.embedded.block.html meta.tag.metadata.script.start.html entity.name.tag.html", "r": { "dark_plus": "entity.name.tag: #569CD6", "light_plus": "entity.name.tag: #800000", @@ -1277,7 +1277,7 @@ }, { "c": " ", - "t": "text.html.basic meta.embedded.block.html meta.tag.metadata.script.html", + "t": "text.html.basic meta.embedded.block.html meta.tag.metadata.script.start.html", "r": { "dark_plus": "meta.embedded: #D4D4D4", "light_plus": "meta.embedded: #000000", @@ -1288,7 +1288,7 @@ }, { "c": "src", - "t": "text.html.basic meta.embedded.block.html meta.tag.metadata.script.html entity.other.attribute-name.html", + "t": "text.html.basic meta.embedded.block.html meta.tag.metadata.script.start.html meta.attribute.src.html entity.other.attribute-name.html", "r": { "dark_plus": "entity.other.attribute-name: #9CDCFE", "light_plus": "entity.other.attribute-name: #FF0000", @@ -1299,7 +1299,7 @@ }, { "c": "=", - "t": "text.html.basic meta.embedded.block.html meta.tag.metadata.script.html", + "t": "text.html.basic meta.embedded.block.html meta.tag.metadata.script.start.html meta.attribute.src.html punctuation.separator.key-value.html", "r": { "dark_plus": "meta.embedded: #D4D4D4", "light_plus": "meta.embedded: #000000", @@ -1310,7 +1310,7 @@ }, { "c": "\"", - "t": "text.html.basic meta.embedded.block.html meta.tag.metadata.script.html string.quoted.double.html punctuation.definition.string.begin.html", + "t": "text.html.basic meta.embedded.block.html meta.tag.metadata.script.start.html meta.attribute.src.html string.quoted.double.html punctuation.definition.string.begin.html", "r": { "dark_plus": "string: #CE9178", "light_plus": "string.quoted.double.html: #0000FF", @@ -1321,7 +1321,7 @@ }, { "c": "https://cdn.rawgit.com/mochajs/mocha/2.2.5/mocha.js", - "t": "text.html.basic meta.embedded.block.html meta.tag.metadata.script.html string.quoted.double.html", + "t": "text.html.basic meta.embedded.block.html meta.tag.metadata.script.start.html meta.attribute.src.html string.quoted.double.html", "r": { "dark_plus": "string: #CE9178", "light_plus": "string.quoted.double.html: #0000FF", @@ -1332,7 +1332,7 @@ }, { "c": "\"", - "t": "text.html.basic meta.embedded.block.html meta.tag.metadata.script.html string.quoted.double.html punctuation.definition.string.end.html", + "t": "text.html.basic meta.embedded.block.html meta.tag.metadata.script.start.html meta.attribute.src.html string.quoted.double.html punctuation.definition.string.end.html", "r": { "dark_plus": "string: #CE9178", "light_plus": "string.quoted.double.html: #0000FF", @@ -1343,7 +1343,7 @@ }, { "c": ">", - "t": "text.html.basic meta.embedded.block.html meta.tag.metadata.script.html punctuation.definition.tag.end.html", + "t": "text.html.basic meta.embedded.block.html meta.tag.metadata.script.start.html punctuation.definition.tag.end.html", "r": { "dark_plus": "punctuation.definition.tag: #808080", "light_plus": "punctuation.definition.tag: #800000", @@ -1354,7 +1354,7 @@ }, { "c": "<", - "t": "text.html.basic meta.embedded.block.html meta.tag.metadata.script.html punctuation.definition.tag.begin.html source.js", + "t": "text.html.basic meta.embedded.block.html meta.tag.metadata.script.end.html punctuation.definition.tag.begin.html source.js", "r": { "dark_plus": "punctuation.definition.tag: #808080", "light_plus": "punctuation.definition.tag: #800000", @@ -1365,7 +1365,7 @@ }, { "c": "/", - "t": "text.html.basic meta.embedded.block.html meta.tag.metadata.script.html punctuation.definition.tag.begin.html", + "t": "text.html.basic meta.embedded.block.html meta.tag.metadata.script.end.html punctuation.definition.tag.begin.html", "r": { "dark_plus": "punctuation.definition.tag: #808080", "light_plus": "punctuation.definition.tag: #800000", @@ -1376,7 +1376,7 @@ }, { "c": "script", - "t": "text.html.basic meta.embedded.block.html meta.tag.metadata.script.html entity.name.tag.html", + "t": "text.html.basic meta.embedded.block.html meta.tag.metadata.script.end.html entity.name.tag.html", "r": { "dark_plus": "entity.name.tag: #569CD6", "light_plus": "entity.name.tag: #800000", @@ -1387,7 +1387,7 @@ }, { "c": ">", - "t": "text.html.basic meta.embedded.block.html meta.tag.metadata.script.html punctuation.definition.tag.end.html", + "t": "text.html.basic meta.embedded.block.html meta.tag.metadata.script.end.html punctuation.definition.tag.end.html", "r": { "dark_plus": "punctuation.definition.tag: #808080", "light_plus": "punctuation.definition.tag: #800000", @@ -1409,7 +1409,7 @@ }, { "c": "<", - "t": "text.html.basic meta.embedded.block.html meta.tag.metadata.script.html punctuation.definition.tag.begin.html", + "t": "text.html.basic meta.embedded.block.html meta.tag.metadata.script.start.html punctuation.definition.tag.begin.html", "r": { "dark_plus": "punctuation.definition.tag: #808080", "light_plus": "punctuation.definition.tag: #800000", @@ -1420,7 +1420,7 @@ }, { "c": "script", - "t": "text.html.basic meta.embedded.block.html meta.tag.metadata.script.html entity.name.tag.html", + "t": "text.html.basic meta.embedded.block.html meta.tag.metadata.script.start.html entity.name.tag.html", "r": { "dark_plus": "entity.name.tag: #569CD6", "light_plus": "entity.name.tag: #800000", @@ -1431,7 +1431,7 @@ }, { "c": ">", - "t": "text.html.basic meta.embedded.block.html meta.tag.metadata.script.html punctuation.definition.tag.end.html", + "t": "text.html.basic meta.embedded.block.html meta.tag.metadata.script.start.html punctuation.definition.tag.end.html", "r": { "dark_plus": "punctuation.definition.tag: #808080", "light_plus": "punctuation.definition.tag: #800000", @@ -2212,7 +2212,7 @@ }, { "c": "<", - "t": "text.html.basic meta.embedded.block.html meta.tag.metadata.script.html punctuation.definition.tag.begin.html source.js", + "t": "text.html.basic meta.embedded.block.html meta.tag.metadata.script.end.html punctuation.definition.tag.begin.html source.js", "r": { "dark_plus": "punctuation.definition.tag: #808080", "light_plus": "punctuation.definition.tag: #800000", @@ -2223,7 +2223,7 @@ }, { "c": "/", - "t": "text.html.basic meta.embedded.block.html meta.tag.metadata.script.html punctuation.definition.tag.begin.html", + "t": "text.html.basic meta.embedded.block.html meta.tag.metadata.script.end.html punctuation.definition.tag.begin.html", "r": { "dark_plus": "punctuation.definition.tag: #808080", "light_plus": "punctuation.definition.tag: #800000", @@ -2234,7 +2234,7 @@ }, { "c": "script", - "t": "text.html.basic meta.embedded.block.html meta.tag.metadata.script.html entity.name.tag.html", + "t": "text.html.basic meta.embedded.block.html meta.tag.metadata.script.end.html entity.name.tag.html", "r": { "dark_plus": "entity.name.tag: #569CD6", "light_plus": "entity.name.tag: #800000", @@ -2245,7 +2245,7 @@ }, { "c": ">", - "t": "text.html.basic meta.embedded.block.html meta.tag.metadata.script.html punctuation.definition.tag.end.html", + "t": "text.html.basic meta.embedded.block.html meta.tag.metadata.script.end.html punctuation.definition.tag.end.html", "r": { "dark_plus": "punctuation.definition.tag: #808080", "light_plus": "punctuation.definition.tag: #800000", @@ -2267,7 +2267,7 @@ }, { "c": "<", - "t": "text.html.basic meta.tag.block.any.html punctuation.definition.tag.begin.html", + "t": "text.html.basic meta.tag.structure.div.start.html punctuation.definition.tag.begin.html", "r": { "dark_plus": "punctuation.definition.tag: #808080", "light_plus": "punctuation.definition.tag: #800000", @@ -2278,7 +2278,7 @@ }, { "c": "div", - "t": "text.html.basic meta.tag.block.any.html entity.name.tag.block.any.html", + "t": "text.html.basic meta.tag.structure.div.start.html entity.name.tag.html", "r": { "dark_plus": "entity.name.tag: #569CD6", "light_plus": "entity.name.tag: #800000", @@ -2289,7 +2289,7 @@ }, { "c": " ", - "t": "text.html.basic meta.tag.block.any.html", + "t": "text.html.basic meta.tag.structure.div.start.html", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -2300,7 +2300,7 @@ }, { "c": "class", - "t": "text.html.basic meta.tag.block.any.html entity.other.attribute-name.html", + "t": "text.html.basic meta.tag.structure.div.start.html meta.attribute.class.html entity.other.attribute-name.html", "r": { "dark_plus": "entity.other.attribute-name: #9CDCFE", "light_plus": "entity.other.attribute-name: #FF0000", @@ -2311,7 +2311,7 @@ }, { "c": "=", - "t": "text.html.basic meta.tag.block.any.html", + "t": "text.html.basic meta.tag.structure.div.start.html meta.attribute.class.html punctuation.separator.key-value.html", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -2322,7 +2322,7 @@ }, { "c": "\"", - "t": "text.html.basic meta.tag.block.any.html string.quoted.double.html punctuation.definition.string.begin.html", + "t": "text.html.basic meta.tag.structure.div.start.html meta.attribute.class.html string.quoted.double.html punctuation.definition.string.begin.html", "r": { "dark_plus": "string: #CE9178", "light_plus": "string.quoted.double.html: #0000FF", @@ -2333,7 +2333,7 @@ }, { "c": "js-stale-session-flash stale-session-flash flash flash-warn flash-banner hidden", - "t": "text.html.basic meta.tag.block.any.html string.quoted.double.html", + "t": "text.html.basic meta.tag.structure.div.start.html meta.attribute.class.html string.quoted.double.html", "r": { "dark_plus": "string: #CE9178", "light_plus": "string.quoted.double.html: #0000FF", @@ -2344,7 +2344,7 @@ }, { "c": "\"", - "t": "text.html.basic meta.tag.block.any.html string.quoted.double.html punctuation.definition.string.end.html", + "t": "text.html.basic meta.tag.structure.div.start.html meta.attribute.class.html string.quoted.double.html punctuation.definition.string.end.html", "r": { "dark_plus": "string: #CE9178", "light_plus": "string.quoted.double.html: #0000FF", @@ -2355,7 +2355,7 @@ }, { "c": ">", - "t": "text.html.basic meta.tag.block.any.html punctuation.definition.tag.end.html", + "t": "text.html.basic meta.tag.structure.div.start.html punctuation.definition.tag.end.html", "r": { "dark_plus": "punctuation.definition.tag: #808080", "light_plus": "punctuation.definition.tag: #800000", @@ -2377,7 +2377,7 @@ }, { "c": "<", - "t": "text.html.basic meta.tag.any.html punctuation.definition.tag.html", + "t": "text.html.basic meta.tag.inline.span.start.html punctuation.definition.tag.begin.html", "r": { "dark_plus": "punctuation.definition.tag: #808080", "light_plus": "punctuation.definition.tag: #800000", @@ -2388,7 +2388,7 @@ }, { "c": "span", - "t": "text.html.basic meta.tag.any.html entity.name.tag.html", + "t": "text.html.basic meta.tag.inline.span.start.html entity.name.tag.html", "r": { "dark_plus": "entity.name.tag: #569CD6", "light_plus": "entity.name.tag: #800000", @@ -2399,7 +2399,7 @@ }, { "c": " ", - "t": "text.html.basic meta.tag.any.html", + "t": "text.html.basic meta.tag.inline.span.start.html", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -2410,7 +2410,7 @@ }, { "c": "class", - "t": "text.html.basic meta.tag.any.html entity.other.attribute-name.html", + "t": "text.html.basic meta.tag.inline.span.start.html meta.attribute.class.html entity.other.attribute-name.html", "r": { "dark_plus": "entity.other.attribute-name: #9CDCFE", "light_plus": "entity.other.attribute-name: #FF0000", @@ -2421,7 +2421,7 @@ }, { "c": "=", - "t": "text.html.basic meta.tag.any.html", + "t": "text.html.basic meta.tag.inline.span.start.html meta.attribute.class.html punctuation.separator.key-value.html", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -2432,7 +2432,7 @@ }, { "c": "octicon", - "t": "text.html.basic meta.tag.any.html string.unquoted.html", + "t": "text.html.basic meta.tag.inline.span.start.html meta.attribute.class.html string.unquoted.html", "r": { "dark_plus": "string: #CE9178", "light_plus": "string.unquoted.html: #0000FF", @@ -2443,7 +2443,7 @@ }, { "c": ">", - "t": "text.html.basic meta.tag.any.html punctuation.definition.tag.html", + "t": "text.html.basic meta.tag.inline.span.start.html punctuation.definition.tag.end.html", "r": { "dark_plus": "punctuation.definition.tag: #808080", "light_plus": "punctuation.definition.tag: #800000", @@ -2453,19 +2453,8 @@ } }, { - "c": "<", - "t": "text.html.basic meta.tag.any.html punctuation.definition.tag.html meta.scope.between-tag-pair.html", - "r": { - "dark_plus": "punctuation.definition.tag: #808080", - "light_plus": "punctuation.definition.tag: #800000", - "dark_vs": "punctuation.definition.tag: #808080", - "light_vs": "punctuation.definition.tag: #800000", - "hc_black": "punctuation.definition.tag: #808080" - } - }, - { - "c": "/", - "t": "text.html.basic meta.tag.any.html punctuation.definition.tag.html", + "c": "", - "t": "text.html.basic meta.tag.any.html punctuation.definition.tag.html", + "t": "text.html.basic meta.tag.inline.span.end.html punctuation.definition.tag.end.html", "r": { "dark_plus": "punctuation.definition.tag: #808080", "light_plus": "punctuation.definition.tag: #800000", @@ -2509,7 +2498,7 @@ }, { "c": "<", - "t": "text.html.basic meta.tag.inline.any.html punctuation.definition.tag.begin.html", + "t": "text.html.basic meta.tag.inline.span.start.html punctuation.definition.tag.begin.html", "r": { "dark_plus": "punctuation.definition.tag: #808080", "light_plus": "punctuation.definition.tag: #800000", @@ -2520,7 +2509,7 @@ }, { "c": "span", - "t": "text.html.basic meta.tag.inline.any.html entity.name.tag.inline.any.html", + "t": "text.html.basic meta.tag.inline.span.start.html entity.name.tag.html", "r": { "dark_plus": "entity.name.tag: #569CD6", "light_plus": "entity.name.tag: #800000", @@ -2531,7 +2520,7 @@ }, { "c": " ", - "t": "text.html.basic meta.tag.inline.any.html", + "t": "text.html.basic meta.tag.inline.span.start.html", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -2542,7 +2531,7 @@ }, { "c": "class", - "t": "text.html.basic meta.tag.inline.any.html entity.other.attribute-name.html", + "t": "text.html.basic meta.tag.inline.span.start.html meta.attribute.class.html entity.other.attribute-name.html", "r": { "dark_plus": "entity.other.attribute-name: #9CDCFE", "light_plus": "entity.other.attribute-name: #FF0000", @@ -2553,7 +2542,7 @@ }, { "c": "=", - "t": "text.html.basic meta.tag.inline.any.html", + "t": "text.html.basic meta.tag.inline.span.start.html meta.attribute.class.html punctuation.separator.key-value.html", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -2564,7 +2553,7 @@ }, { "c": "\"", - "t": "text.html.basic meta.tag.inline.any.html string.quoted.double.html punctuation.definition.string.begin.html", + "t": "text.html.basic meta.tag.inline.span.start.html meta.attribute.class.html string.quoted.double.html punctuation.definition.string.begin.html", "r": { "dark_plus": "string: #CE9178", "light_plus": "string.quoted.double.html: #0000FF", @@ -2575,7 +2564,7 @@ }, { "c": "signed-in-tab-flash", - "t": "text.html.basic meta.tag.inline.any.html string.quoted.double.html", + "t": "text.html.basic meta.tag.inline.span.start.html meta.attribute.class.html string.quoted.double.html", "r": { "dark_plus": "string: #CE9178", "light_plus": "string.quoted.double.html: #0000FF", @@ -2586,7 +2575,7 @@ }, { "c": "\"", - "t": "text.html.basic meta.tag.inline.any.html string.quoted.double.html punctuation.definition.string.end.html", + "t": "text.html.basic meta.tag.inline.span.start.html meta.attribute.class.html string.quoted.double.html punctuation.definition.string.end.html", "r": { "dark_plus": "string: #CE9178", "light_plus": "string.quoted.double.html: #0000FF", @@ -2597,7 +2586,7 @@ }, { "c": ">", - "t": "text.html.basic meta.tag.inline.any.html punctuation.definition.tag.end.html", + "t": "text.html.basic meta.tag.inline.span.start.html punctuation.definition.tag.end.html", "r": { "dark_plus": "punctuation.definition.tag: #808080", "light_plus": "punctuation.definition.tag: #800000", @@ -2619,7 +2608,7 @@ }, { "c": "<", - "t": "text.html.basic meta.tag.inline.any.html punctuation.definition.tag.begin.html", + "t": "text.html.basic meta.tag.inline.a.start.html punctuation.definition.tag.begin.html", "r": { "dark_plus": "punctuation.definition.tag: #808080", "light_plus": "punctuation.definition.tag: #800000", @@ -2630,7 +2619,7 @@ }, { "c": "a", - "t": "text.html.basic meta.tag.inline.any.html entity.name.tag.inline.any.html", + "t": "text.html.basic meta.tag.inline.a.start.html entity.name.tag.html", "r": { "dark_plus": "entity.name.tag: #569CD6", "light_plus": "entity.name.tag: #800000", @@ -2641,7 +2630,7 @@ }, { "c": " ", - "t": "text.html.basic meta.tag.inline.any.html", + "t": "text.html.basic meta.tag.inline.a.start.html", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -2652,7 +2641,7 @@ }, { "c": "href", - "t": "text.html.basic meta.tag.inline.any.html entity.other.attribute-name.html", + "t": "text.html.basic meta.tag.inline.a.start.html meta.attribute.href.html entity.other.attribute-name.html", "r": { "dark_plus": "entity.other.attribute-name: #9CDCFE", "light_plus": "entity.other.attribute-name: #FF0000", @@ -2663,7 +2652,7 @@ }, { "c": "=", - "t": "text.html.basic meta.tag.inline.any.html", + "t": "text.html.basic meta.tag.inline.a.start.html meta.attribute.href.html punctuation.separator.key-value.html", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -2674,7 +2663,7 @@ }, { "c": "\"", - "t": "text.html.basic meta.tag.inline.any.html string.quoted.double.html punctuation.definition.string.begin.html", + "t": "text.html.basic meta.tag.inline.a.start.html meta.attribute.href.html string.quoted.double.html punctuation.definition.string.begin.html", "r": { "dark_plus": "string: #CE9178", "light_plus": "string.quoted.double.html: #0000FF", @@ -2685,7 +2674,7 @@ }, { "c": "\"", - "t": "text.html.basic meta.tag.inline.any.html string.quoted.double.html punctuation.definition.string.end.html", + "t": "text.html.basic meta.tag.inline.a.start.html meta.attribute.href.html string.quoted.double.html punctuation.definition.string.end.html", "r": { "dark_plus": "string: #CE9178", "light_plus": "string.quoted.double.html: #0000FF", @@ -2696,7 +2685,7 @@ }, { "c": ">", - "t": "text.html.basic meta.tag.inline.any.html punctuation.definition.tag.end.html", + "t": "text.html.basic meta.tag.inline.a.start.html punctuation.definition.tag.end.html", "r": { "dark_plus": "punctuation.definition.tag: #808080", "light_plus": "punctuation.definition.tag: #800000", @@ -2718,7 +2707,7 @@ }, { "c": "", - "t": "text.html.basic meta.tag.inline.any.html punctuation.definition.tag.end.html", + "t": "text.html.basic meta.tag.inline.a.end.html punctuation.definition.tag.end.html", "r": { "dark_plus": "punctuation.definition.tag: #808080", "light_plus": "punctuation.definition.tag: #800000", @@ -2762,7 +2751,7 @@ }, { "c": "", - "t": "text.html.basic meta.tag.inline.any.html punctuation.definition.tag.end.html", + "t": "text.html.basic meta.tag.inline.span.end.html punctuation.definition.tag.end.html", "r": { "dark_plus": "punctuation.definition.tag: #808080", "light_plus": "punctuation.definition.tag: #800000", @@ -2806,7 +2795,7 @@ }, { "c": "<", - "t": "text.html.basic meta.tag.inline.any.html punctuation.definition.tag.begin.html", + "t": "text.html.basic meta.tag.inline.span.start.html punctuation.definition.tag.begin.html", "r": { "dark_plus": "punctuation.definition.tag: #808080", "light_plus": "punctuation.definition.tag: #800000", @@ -2817,7 +2806,7 @@ }, { "c": "span", - "t": "text.html.basic meta.tag.inline.any.html entity.name.tag.inline.any.html", + "t": "text.html.basic meta.tag.inline.span.start.html entity.name.tag.html", "r": { "dark_plus": "entity.name.tag: #569CD6", "light_plus": "entity.name.tag: #800000", @@ -2828,7 +2817,7 @@ }, { "c": " ", - "t": "text.html.basic meta.tag.inline.any.html", + "t": "text.html.basic meta.tag.inline.span.start.html", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -2839,7 +2828,7 @@ }, { "c": "class", - "t": "text.html.basic meta.tag.inline.any.html entity.other.attribute-name.html", + "t": "text.html.basic meta.tag.inline.span.start.html meta.attribute.class.html entity.other.attribute-name.html", "r": { "dark_plus": "entity.other.attribute-name: #9CDCFE", "light_plus": "entity.other.attribute-name: #FF0000", @@ -2850,7 +2839,7 @@ }, { "c": "=", - "t": "text.html.basic meta.tag.inline.any.html", + "t": "text.html.basic meta.tag.inline.span.start.html meta.attribute.class.html punctuation.separator.key-value.html", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -2861,7 +2850,7 @@ }, { "c": "\"", - "t": "text.html.basic meta.tag.inline.any.html string.quoted.double.html punctuation.definition.string.begin.html", + "t": "text.html.basic meta.tag.inline.span.start.html meta.attribute.class.html string.quoted.double.html punctuation.definition.string.begin.html", "r": { "dark_plus": "string: #CE9178", "light_plus": "string.quoted.double.html: #0000FF", @@ -2872,7 +2861,7 @@ }, { "c": "signed-out-tab-flash", - "t": "text.html.basic meta.tag.inline.any.html string.quoted.double.html", + "t": "text.html.basic meta.tag.inline.span.start.html meta.attribute.class.html string.quoted.double.html", "r": { "dark_plus": "string: #CE9178", "light_plus": "string.quoted.double.html: #0000FF", @@ -2883,7 +2872,7 @@ }, { "c": "\"", - "t": "text.html.basic meta.tag.inline.any.html string.quoted.double.html punctuation.definition.string.end.html", + "t": "text.html.basic meta.tag.inline.span.start.html meta.attribute.class.html string.quoted.double.html punctuation.definition.string.end.html", "r": { "dark_plus": "string: #CE9178", "light_plus": "string.quoted.double.html: #0000FF", @@ -2894,7 +2883,7 @@ }, { "c": ">", - "t": "text.html.basic meta.tag.inline.any.html punctuation.definition.tag.end.html", + "t": "text.html.basic meta.tag.inline.span.start.html punctuation.definition.tag.end.html", "r": { "dark_plus": "punctuation.definition.tag: #808080", "light_plus": "punctuation.definition.tag: #800000", @@ -2916,7 +2905,7 @@ }, { "c": "<", - "t": "text.html.basic meta.tag.inline.any.html punctuation.definition.tag.begin.html", + "t": "text.html.basic meta.tag.inline.a.start.html punctuation.definition.tag.begin.html", "r": { "dark_plus": "punctuation.definition.tag: #808080", "light_plus": "punctuation.definition.tag: #800000", @@ -2927,7 +2916,7 @@ }, { "c": "a", - "t": "text.html.basic meta.tag.inline.any.html entity.name.tag.inline.any.html", + "t": "text.html.basic meta.tag.inline.a.start.html entity.name.tag.html", "r": { "dark_plus": "entity.name.tag: #569CD6", "light_plus": "entity.name.tag: #800000", @@ -2938,7 +2927,7 @@ }, { "c": " ", - "t": "text.html.basic meta.tag.inline.any.html", + "t": "text.html.basic meta.tag.inline.a.start.html", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -2949,7 +2938,7 @@ }, { "c": "href", - "t": "text.html.basic meta.tag.inline.any.html entity.other.attribute-name.html", + "t": "text.html.basic meta.tag.inline.a.start.html meta.attribute.href.html entity.other.attribute-name.html", "r": { "dark_plus": "entity.other.attribute-name: #9CDCFE", "light_plus": "entity.other.attribute-name: #FF0000", @@ -2960,7 +2949,7 @@ }, { "c": "=", - "t": "text.html.basic meta.tag.inline.any.html", + "t": "text.html.basic meta.tag.inline.a.start.html meta.attribute.href.html punctuation.separator.key-value.html", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -2971,7 +2960,7 @@ }, { "c": "\"", - "t": "text.html.basic meta.tag.inline.any.html string.quoted.double.html punctuation.definition.string.begin.html", + "t": "text.html.basic meta.tag.inline.a.start.html meta.attribute.href.html string.quoted.double.html punctuation.definition.string.begin.html", "r": { "dark_plus": "string: #CE9178", "light_plus": "string.quoted.double.html: #0000FF", @@ -2982,7 +2971,7 @@ }, { "c": "\"", - "t": "text.html.basic meta.tag.inline.any.html string.quoted.double.html punctuation.definition.string.end.html", + "t": "text.html.basic meta.tag.inline.a.start.html meta.attribute.href.html string.quoted.double.html punctuation.definition.string.end.html", "r": { "dark_plus": "string: #CE9178", "light_plus": "string.quoted.double.html: #0000FF", @@ -2993,7 +2982,7 @@ }, { "c": ">", - "t": "text.html.basic meta.tag.inline.any.html punctuation.definition.tag.end.html", + "t": "text.html.basic meta.tag.inline.a.start.html punctuation.definition.tag.end.html", "r": { "dark_plus": "punctuation.definition.tag: #808080", "light_plus": "punctuation.definition.tag: #800000", @@ -3015,7 +3004,7 @@ }, { "c": "", - "t": "text.html.basic meta.tag.inline.any.html punctuation.definition.tag.end.html", + "t": "text.html.basic meta.tag.inline.a.end.html punctuation.definition.tag.end.html", "r": { "dark_plus": "punctuation.definition.tag: #808080", "light_plus": "punctuation.definition.tag: #800000", @@ -3059,7 +3048,7 @@ }, { "c": "", - "t": "text.html.basic meta.tag.inline.any.html punctuation.definition.tag.end.html", + "t": "text.html.basic meta.tag.inline.span.end.html punctuation.definition.tag.end.html", "r": { "dark_plus": "punctuation.definition.tag: #808080", "light_plus": "punctuation.definition.tag: #800000", @@ -3103,7 +3092,7 @@ }, { "c": "", - "t": "text.html.basic meta.tag.block.any.html punctuation.definition.tag.end.html", + "t": "text.html.basic meta.tag.structure.div.end.html punctuation.definition.tag.end.html", "r": { "dark_plus": "punctuation.definition.tag: #808080", "light_plus": "punctuation.definition.tag: #800000", @@ -3136,7 +3125,7 @@ }, { "c": "", - "t": "text.html.basic meta.tag.structure.any.html punctuation.definition.tag.html", + "t": "text.html.basic meta.tag.structure.body.end.html punctuation.definition.tag.end.html", "r": { "dark_plus": "punctuation.definition.tag: #808080", "light_plus": "punctuation.definition.tag: #800000", @@ -3169,7 +3158,7 @@ }, { "c": "", - "t": "text.html.basic meta.tag.structure.any.html punctuation.definition.tag.html", + "t": "text.html.basic meta.tag.structure.html.end.html punctuation.definition.tag.end.html", "r": { "dark_plus": "punctuation.definition.tag: #808080", "light_plus": "punctuation.definition.tag: #800000", From de24a9026f4808f93dfe8914d65fa9e3b1aa7602 Mon Sep 17 00:00:00 2001 From: Martin Aeschlimann Date: Fri, 27 Jul 2018 10:59:43 +0200 Subject: [PATCH 0218/1276] [java] update grammar --- extensions/java/syntaxes/java.tmLanguage.json | 595 +++++++++--------- 1 file changed, 306 insertions(+), 289 deletions(-) diff --git a/extensions/java/syntaxes/java.tmLanguage.json b/extensions/java/syntaxes/java.tmLanguage.json index b19cc7b4754..d4477107155 100644 --- a/extensions/java/syntaxes/java.tmLanguage.json +++ b/extensions/java/syntaxes/java.tmLanguage.json @@ -4,7 +4,7 @@ "If you want to provide a fix or improvement, please create a pull request against the original repository.", "Once accepted there, we are happy to receive an update request." ], - "version": "https://github.com/atom/language-java/commit/2f20bc5a5b07686ec0139e2969431210d81b6991", + "version": "https://github.com/atom/language-java/commit/f213dfac7dc3726170046c8f0c174c9e9f13e4ce", "name": "Java", "scopeName": "source.java", "patterns": [ @@ -183,6 +183,25 @@ } ] }, + "anonymous-block-and-instance-initializer": { + "begin": "{", + "beginCaptures": { + "0": { + "name": "punctuation.section.block.begin.bracket.curly.java" + } + }, + "end": "}", + "endCaptures": { + "0": { + "name": "punctuation.section.block.end.bracket.curly.java" + } + }, + "patterns": [ + { + "include": "#code" + } + ] + }, "anonymous-classes-and-new": { "begin": "\\bnew\\b", "beginCaptures": { @@ -370,36 +389,6 @@ } ] }, - "anonymous-block-and-instance-initializer": { - "begin": "{", - "beginCaptures": { - "0": { - "name": "punctuation.section.block.begin.bracket.curly.java" - } - }, - "end": "}", - "endCaptures": { - "0": { - "name": "punctuation.section.block.end.bracket.curly.java" - } - }, - "patterns": [ - { - "include": "#code" - } - ] - }, - "static-initializer": { - "patterns": [ - { - "include": "#anonymous-block-and-instance-initializer" - }, - { - "match": "static", - "name": "storage.modifier.java" - } - ] - }, "code": { "patterns": [ { @@ -450,15 +439,15 @@ { "include": "#function-call" }, + { + "include": "#variables" + }, { "include": "#objects" }, { "include": "#properties" }, - { - "include": "#variables" - }, { "include": "#strings" }, @@ -594,161 +583,6 @@ } ] }, - "try-catch-finally": { - "patterns": [ - { - "begin": "\\btry\\b", - "beginCaptures": { - "0": { - "name": "keyword.control.try.java" - } - }, - "end": "}", - "endCaptures": { - "0": { - "name": "punctuation.section.try.end.bracket.curly.java" - } - }, - "name": "meta.try.java", - "patterns": [ - { - "begin": "\\(", - "beginCaptures": { - "0": { - "name": "punctuation.section.try.resources.begin.bracket.round.java" - } - }, - "end": "\\)", - "endCaptures": { - "0": { - "name": "punctuation.section.try.resources.end.bracket.round.java" - } - }, - "name": "meta.try.resources.java", - "patterns": [ - { - "include": "#code" - } - ] - }, - { - "begin": "{", - "beginCaptures": { - "0": { - "name": "punctuation.section.try.begin.bracket.curly.java" - } - }, - "end": "(?=})", - "contentName": "meta.try.body.java", - "patterns": [ - { - "include": "#code" - } - ] - } - ] - }, - { - "begin": "\\b(catch)\\b\\s*(?=\\(\\s*[^\\s]+\\s*[^)]+\\))", - "beginCaptures": { - "1": { - "name": "keyword.control.catch.java" - } - }, - "end": "}", - "endCaptures": { - "0": { - "name": "punctuation.section.catch.end.bracket.curly.java" - } - }, - "name": "meta.catch.java", - "patterns": [ - { - "begin": "\\(", - "beginCaptures": { - "0": { - "name": "punctuation.definition.parameters.begin.bracket.round.java" - } - }, - "end": "\\)", - "endCaptures": { - "0": { - "name": "punctuation.definition.parameters.end.bracket.round.java" - } - }, - "contentName": "meta.catch.parameters.java", - "patterns": [ - { - "include": "#comments" - }, - { - "match": "\\|", - "name": "punctuation.catch.separator.java" - }, - { - "match": "([a-zA-Z$_][\\.a-zA-Z0-9$_]*)\\s*(\\w+)?", - "captures": { - "1": { - "name": "storage.type.java" - }, - "2": { - "name": "variable.parameter.java" - } - } - } - ] - }, - { - "begin": "{", - "beginCaptures": { - "0": { - "name": "punctuation.section.catch.begin.bracket.curly.java" - } - }, - "end": "(?=})", - "contentName": "meta.catch.body.java", - "patterns": [ - { - "include": "#code" - } - ] - } - ] - }, - { - "begin": "\\bfinally\\b", - "beginCaptures": { - "0": { - "name": "keyword.control.finally.java" - } - }, - "end": "}", - "endCaptures": { - "0": { - "name": "punctuation.section.finally.end.bracket.curly.java" - } - }, - "name": "meta.finally.java", - "patterns": [ - { - "begin": "{", - "beginCaptures": { - "0": { - "name": "punctuation.section.finally.begin.bracket.curly.java" - } - }, - "end": "(?=})", - "contentName": "meta.finally.body.java", - "patterns": [ - { - "include": "#code" - } - ] - } - ] - } - ] - }, "constants-and-special-vars": { "patterns": [ { @@ -765,66 +599,6 @@ } ] }, - "generics": { - "begin": "<", - "beginCaptures": { - "0": { - "name": "punctuation.bracket.angle.java" - } - }, - "end": ">", - "endCaptures": { - "0": { - "name": "punctuation.bracket.angle.java" - } - }, - "patterns": [ - { - "match": "\\b(extends|super)\\b", - "name": "storage.modifier.$1.java" - }, - { - "match": "(?", + "endCaptures": { + "0": { + "name": "punctuation.bracket.angle.java" + } + }, + "patterns": [ + { + "match": "\\b(extends|super)\\b", + "name": "storage.modifier.$1.java" + }, + { + "match": "(?)|(?!;)", - "patterns": [ - { - "include": "#generics" - } - ] - }, - { - "match": "\\b(?:[A-Z]\\w*\\s*(\\.)\\s*)*[A-Z]\\w*\\b((?=\\s*[A-Za-z$_\\n])|(?=\\s*\\.\\.\\.))", - "name": "storage.type.java", + "match": "\\b((?:[A-Za-z]\\w*\\s*\\.\\s*)*[A-Z]\\w*)\\s*(?=<)", "captures": { "1": { - "name": "punctuation.separator.period.java" + "patterns": [ + { + "match": "[A-Za-z]\\w*", + "name": "storage.type.java" + }, + { + "match": "\\.", + "name": "punctuation.separator.period.java" + } + ] + } + } + }, + { + "match": "\\b((?:[A-Za-z]\\w*\\s*\\.\\s*)*[A-Z]\\w*)\\b((?=\\s*[A-Za-z$_\\n])|(?=\\s*\\.\\.\\.))", + "captures": { + "1": { + "patterns": [ + { + "match": "[A-Za-z]\\w*", + "name": "storage.type.java" + }, + { + "match": "\\.", + "name": "punctuation.separator.period.java" + } + ] } } } @@ -1352,6 +1221,17 @@ } ] }, + "static-initializer": { + "patterns": [ + { + "include": "#anonymous-block-and-instance-initializer" + }, + { + "match": "static", + "name": "storage.modifier.java" + } + ] + }, "storage-modifiers": { "match": "\\b(public|private|protected|static|final|native|synchronized|abstract|threadsafe|transient|volatile|default|strictfp)\\b", "name": "storage.modifier.java" @@ -1422,6 +1302,161 @@ } ] }, + "try-catch-finally": { + "patterns": [ + { + "begin": "\\btry\\b", + "beginCaptures": { + "0": { + "name": "keyword.control.try.java" + } + }, + "end": "}", + "endCaptures": { + "0": { + "name": "punctuation.section.try.end.bracket.curly.java" + } + }, + "name": "meta.try.java", + "patterns": [ + { + "begin": "\\(", + "beginCaptures": { + "0": { + "name": "punctuation.section.try.resources.begin.bracket.round.java" + } + }, + "end": "\\)", + "endCaptures": { + "0": { + "name": "punctuation.section.try.resources.end.bracket.round.java" + } + }, + "name": "meta.try.resources.java", + "patterns": [ + { + "include": "#code" + } + ] + }, + { + "begin": "{", + "beginCaptures": { + "0": { + "name": "punctuation.section.try.begin.bracket.curly.java" + } + }, + "end": "(?=})", + "contentName": "meta.try.body.java", + "patterns": [ + { + "include": "#code" + } + ] + } + ] + }, + { + "begin": "\\b(catch)\\b\\s*(?=\\(\\s*[^\\s]+\\s*[^)]+\\))", + "beginCaptures": { + "1": { + "name": "keyword.control.catch.java" + } + }, + "end": "}", + "endCaptures": { + "0": { + "name": "punctuation.section.catch.end.bracket.curly.java" + } + }, + "name": "meta.catch.java", + "patterns": [ + { + "begin": "\\(", + "beginCaptures": { + "0": { + "name": "punctuation.definition.parameters.begin.bracket.round.java" + } + }, + "end": "\\)", + "endCaptures": { + "0": { + "name": "punctuation.definition.parameters.end.bracket.round.java" + } + }, + "contentName": "meta.catch.parameters.java", + "patterns": [ + { + "include": "#comments" + }, + { + "match": "\\|", + "name": "punctuation.catch.separator.java" + }, + { + "match": "([a-zA-Z$_][\\.a-zA-Z0-9$_]*)\\s*(\\w+)?", + "captures": { + "1": { + "name": "storage.type.java" + }, + "2": { + "name": "variable.parameter.java" + } + } + } + ] + }, + { + "begin": "{", + "beginCaptures": { + "0": { + "name": "punctuation.section.catch.begin.bracket.curly.java" + } + }, + "end": "(?=})", + "contentName": "meta.catch.body.java", + "patterns": [ + { + "include": "#code" + } + ] + } + ] + }, + { + "begin": "\\bfinally\\b", + "beginCaptures": { + "0": { + "name": "keyword.control.finally.java" + } + }, + "end": "}", + "endCaptures": { + "0": { + "name": "punctuation.section.finally.end.bracket.curly.java" + } + }, + "name": "meta.finally.java", + "patterns": [ + { + "begin": "{", + "beginCaptures": { + "0": { + "name": "punctuation.section.finally.begin.bracket.curly.java" + } + }, + "end": "(?=})", + "contentName": "meta.finally.body.java", + "patterns": [ + { + "include": "#code" + } + ] + } + ] + } + ] + }, "variables": { "begin": "(?x)\n(?=\n (\n (void|boolean|byte|char|short|int|float|long|double)\n |\n (?>(\\w+\\.)*[A-Z]+\\w*) # e.g. `javax.ws.rs.Response`, or `String`\n )\n (\n <[\\w<>,\\.?\\s\\[\\]]*> # e.g. `HashMap`, or `List`\n )?\n (\n (\\[\\])* # int[][]\n )?\n \\s+\n [A-Za-z_$][\\w$]* # At least one identifier after space\n ([\\w\\[\\],$][\\w\\[\\],\\s]*)? # possibly primitive array or additional identifiers\n \\s*(=|;)\n)", "end": "(?=\\=|;)", @@ -1442,24 +1477,6 @@ "include": "#code" } ] - }, - "member-variables": { - "begin": "(?=private|protected|public|native|synchronized|abstract|threadsafe|transient|static|final)", - "end": "(?=\\=|;)", - "patterns": [ - { - "include": "#storage-modifiers" - }, - { - "include": "#variables" - }, - { - "include": "#primitive-arrays" - }, - { - "include": "#object-types" - } - ] } } } \ No newline at end of file From 54d183d2b7033b8d8de7918f9ef0ffaa649286e3 Mon Sep 17 00:00:00 2001 From: Martin Aeschlimann Date: Fri, 27 Jul 2018 11:01:14 +0200 Subject: [PATCH 0219/1276] update markdown colorizer tests --- .../test/colorize-results/test-33886_md.json | 36 ++-- .../test/colorize-results/test_md.json | 168 ++++++++---------- 2 files changed, 91 insertions(+), 113 deletions(-) diff --git a/extensions/markdown-basics/test/colorize-results/test-33886_md.json b/extensions/markdown-basics/test/colorize-results/test-33886_md.json index 185d172e8af..179172a5738 100644 --- a/extensions/markdown-basics/test/colorize-results/test-33886_md.json +++ b/extensions/markdown-basics/test/colorize-results/test-33886_md.json @@ -34,7 +34,7 @@ }, { "c": "<", - "t": "text.html.markdown meta.tag.block.any.html punctuation.definition.tag.begin.html", + "t": "text.html.markdown meta.tag.structure.pre.start.html punctuation.definition.tag.begin.html", "r": { "dark_plus": "punctuation.definition.tag: #808080", "light_plus": "punctuation.definition.tag: #800000", @@ -45,7 +45,7 @@ }, { "c": "pre", - "t": "text.html.markdown meta.tag.block.any.html entity.name.tag.block.any.html", + "t": "text.html.markdown meta.tag.structure.pre.start.html entity.name.tag.html", "r": { "dark_plus": "entity.name.tag: #569CD6", "light_plus": "entity.name.tag: #800000", @@ -56,7 +56,7 @@ }, { "c": ">", - "t": "text.html.markdown meta.tag.block.any.html punctuation.definition.tag.end.html", + "t": "text.html.markdown meta.tag.structure.pre.start.html punctuation.definition.tag.end.html", "r": { "dark_plus": "punctuation.definition.tag: #808080", "light_plus": "punctuation.definition.tag: #800000", @@ -67,7 +67,7 @@ }, { "c": "<", - "t": "text.html.markdown meta.tag.inline.any.html punctuation.definition.tag.begin.html", + "t": "text.html.markdown meta.tag.inline.code.start.html punctuation.definition.tag.begin.html", "r": { "dark_plus": "punctuation.definition.tag: #808080", "light_plus": "punctuation.definition.tag: #800000", @@ -78,7 +78,7 @@ }, { "c": "code", - "t": "text.html.markdown meta.tag.inline.any.html entity.name.tag.inline.any.html", + "t": "text.html.markdown meta.tag.inline.code.start.html entity.name.tag.html", "r": { "dark_plus": "entity.name.tag: #569CD6", "light_plus": "entity.name.tag: #800000", @@ -89,7 +89,7 @@ }, { "c": ">", - "t": "text.html.markdown meta.tag.inline.any.html punctuation.definition.tag.end.html", + "t": "text.html.markdown meta.tag.inline.code.start.html punctuation.definition.tag.end.html", "r": { "dark_plus": "punctuation.definition.tag: #808080", "light_plus": "punctuation.definition.tag: #800000", @@ -111,7 +111,7 @@ }, { "c": "", - "t": "text.html.markdown meta.paragraph.markdown meta.tag.inline.any.html punctuation.definition.tag.end.html", + "t": "text.html.markdown meta.paragraph.markdown meta.tag.inline.code.end.html punctuation.definition.tag.end.html", "r": { "dark_plus": "punctuation.definition.tag: #808080", "light_plus": "punctuation.definition.tag: #800000", @@ -144,7 +144,7 @@ }, { "c": "", - "t": "text.html.markdown meta.paragraph.markdown meta.tag.block.any.html punctuation.definition.tag.end.html", + "t": "text.html.markdown meta.paragraph.markdown meta.tag.structure.pre.end.html punctuation.definition.tag.end.html", "r": { "dark_plus": "punctuation.definition.tag: #808080", "light_plus": "punctuation.definition.tag: #800000", @@ -210,7 +210,7 @@ }, { "c": "<", - "t": "text.html.markdown meta.tag.block.any.html punctuation.definition.tag.begin.html", + "t": "text.html.markdown meta.tag.structure.pre.start.html punctuation.definition.tag.begin.html", "r": { "dark_plus": "punctuation.definition.tag: #808080", "light_plus": "punctuation.definition.tag: #800000", @@ -221,7 +221,7 @@ }, { "c": "pre", - "t": "text.html.markdown meta.tag.block.any.html entity.name.tag.block.any.html", + "t": "text.html.markdown meta.tag.structure.pre.start.html entity.name.tag.html", "r": { "dark_plus": "entity.name.tag: #569CD6", "light_plus": "entity.name.tag: #800000", @@ -232,7 +232,7 @@ }, { "c": ">", - "t": "text.html.markdown meta.tag.block.any.html punctuation.definition.tag.end.html", + "t": "text.html.markdown meta.tag.structure.pre.start.html punctuation.definition.tag.end.html", "r": { "dark_plus": "punctuation.definition.tag: #808080", "light_plus": "punctuation.definition.tag: #800000", @@ -265,7 +265,7 @@ }, { "c": "", - "t": "text.html.markdown meta.paragraph.markdown meta.tag.block.any.html punctuation.definition.tag.end.html", + "t": "text.html.markdown meta.paragraph.markdown meta.tag.structure.pre.end.html punctuation.definition.tag.end.html", "r": { "dark_plus": "punctuation.definition.tag: #808080", "light_plus": "punctuation.definition.tag: #800000", diff --git a/extensions/markdown-basics/test/colorize-results/test_md.json b/extensions/markdown-basics/test/colorize-results/test_md.json index eb09a71c815..dc9ce77ffe7 100644 --- a/extensions/markdown-basics/test/colorize-results/test_md.json +++ b/extensions/markdown-basics/test/colorize-results/test_md.json @@ -300,9 +300,9 @@ "c": "", "t": "text.html.markdown comment.block.html punctuation.definition.comment.html", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } }, { "c": "<", - "t": "text.html.markdown meta.tag.block.any.html punctuation.definition.tag.begin.html", + "t": "text.html.markdown meta.tag.structure.div.start.html punctuation.definition.tag.begin.html", "r": { "dark_plus": "punctuation.definition.tag: #808080", "light_plus": "punctuation.definition.tag: #800000", @@ -342,7 +342,7 @@ }, { "c": "div", - "t": "text.html.markdown meta.tag.block.any.html entity.name.tag.block.any.html", + "t": "text.html.markdown meta.tag.structure.div.start.html entity.name.tag.html", "r": { "dark_plus": "entity.name.tag: #569CD6", "light_plus": "entity.name.tag: #800000", @@ -353,7 +353,7 @@ }, { "c": " ", - "t": "text.html.markdown meta.tag.block.any.html", + "t": "text.html.markdown meta.tag.structure.div.start.html", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -364,7 +364,7 @@ }, { "c": "class", - "t": "text.html.markdown meta.tag.block.any.html entity.other.attribute-name.html", + "t": "text.html.markdown meta.tag.structure.div.start.html meta.attribute.class.html entity.other.attribute-name.html", "r": { "dark_plus": "entity.other.attribute-name: #9CDCFE", "light_plus": "entity.other.attribute-name: #FF0000", @@ -375,7 +375,7 @@ }, { "c": "=", - "t": "text.html.markdown meta.tag.block.any.html", + "t": "text.html.markdown meta.tag.structure.div.start.html meta.attribute.class.html punctuation.separator.key-value.html", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -386,7 +386,7 @@ }, { "c": "\"", - "t": "text.html.markdown meta.tag.block.any.html string.quoted.double.html punctuation.definition.string.begin.html", + "t": "text.html.markdown meta.tag.structure.div.start.html meta.attribute.class.html string.quoted.double.html punctuation.definition.string.begin.html", "r": { "dark_plus": "string: #CE9178", "light_plus": "string.quoted.double.html: #0000FF", @@ -397,7 +397,7 @@ }, { "c": "custom-class", - "t": "text.html.markdown meta.tag.block.any.html string.quoted.double.html", + "t": "text.html.markdown meta.tag.structure.div.start.html meta.attribute.class.html string.quoted.double.html", "r": { "dark_plus": "string: #CE9178", "light_plus": "string.quoted.double.html: #0000FF", @@ -408,7 +408,7 @@ }, { "c": "\"", - "t": "text.html.markdown meta.tag.block.any.html string.quoted.double.html punctuation.definition.string.end.html", + "t": "text.html.markdown meta.tag.structure.div.start.html meta.attribute.class.html string.quoted.double.html punctuation.definition.string.end.html", "r": { "dark_plus": "string: #CE9178", "light_plus": "string.quoted.double.html: #0000FF", @@ -419,7 +419,7 @@ }, { "c": " ", - "t": "text.html.markdown meta.tag.block.any.html", + "t": "text.html.markdown meta.tag.structure.div.start.html", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -430,7 +430,7 @@ }, { "c": "markdown", - "t": "text.html.markdown meta.tag.block.any.html entity.other.attribute-name.html", + "t": "text.html.markdown meta.tag.structure.div.start.html meta.attribute.unrecognized.markdown.html entity.other.attribute-name.html", "r": { "dark_plus": "entity.other.attribute-name: #9CDCFE", "light_plus": "entity.other.attribute-name: #FF0000", @@ -441,7 +441,7 @@ }, { "c": "=", - "t": "text.html.markdown meta.tag.block.any.html", + "t": "text.html.markdown meta.tag.structure.div.start.html meta.attribute.unrecognized.markdown.html punctuation.separator.key-value.html", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -452,7 +452,7 @@ }, { "c": "\"", - "t": "text.html.markdown meta.tag.block.any.html string.quoted.double.html punctuation.definition.string.begin.html", + "t": "text.html.markdown meta.tag.structure.div.start.html meta.attribute.unrecognized.markdown.html string.quoted.double.html punctuation.definition.string.begin.html", "r": { "dark_plus": "string: #CE9178", "light_plus": "string.quoted.double.html: #0000FF", @@ -463,7 +463,7 @@ }, { "c": "1", - "t": "text.html.markdown meta.tag.block.any.html string.quoted.double.html", + "t": "text.html.markdown meta.tag.structure.div.start.html meta.attribute.unrecognized.markdown.html string.quoted.double.html", "r": { "dark_plus": "string: #CE9178", "light_plus": "string.quoted.double.html: #0000FF", @@ -474,7 +474,7 @@ }, { "c": "\"", - "t": "text.html.markdown meta.tag.block.any.html string.quoted.double.html punctuation.definition.string.end.html", + "t": "text.html.markdown meta.tag.structure.div.start.html meta.attribute.unrecognized.markdown.html string.quoted.double.html punctuation.definition.string.end.html", "r": { "dark_plus": "string: #CE9178", "light_plus": "string.quoted.double.html: #0000FF", @@ -485,7 +485,7 @@ }, { "c": ">", - "t": "text.html.markdown meta.tag.block.any.html punctuation.definition.tag.end.html", + "t": "text.html.markdown meta.tag.structure.div.start.html punctuation.definition.tag.end.html", "r": { "dark_plus": "punctuation.definition.tag: #808080", "light_plus": "punctuation.definition.tag: #800000", @@ -507,7 +507,7 @@ }, { "c": "<", - "t": "text.html.markdown meta.tag.block.any.html punctuation.definition.tag.begin.html", + "t": "text.html.markdown meta.tag.structure.div.start.html punctuation.definition.tag.begin.html", "r": { "dark_plus": "punctuation.definition.tag: #808080", "light_plus": "punctuation.definition.tag: #800000", @@ -518,7 +518,7 @@ }, { "c": "div", - "t": "text.html.markdown meta.tag.block.any.html entity.name.tag.block.any.html", + "t": "text.html.markdown meta.tag.structure.div.start.html entity.name.tag.html", "r": { "dark_plus": "entity.name.tag: #569CD6", "light_plus": "entity.name.tag: #800000", @@ -529,7 +529,7 @@ }, { "c": ">", - "t": "text.html.markdown meta.tag.block.any.html punctuation.definition.tag.end.html", + "t": "text.html.markdown meta.tag.structure.div.start.html punctuation.definition.tag.end.html", "r": { "dark_plus": "punctuation.definition.tag: #808080", "light_plus": "punctuation.definition.tag: #800000", @@ -562,7 +562,7 @@ }, { "c": "", - "t": "text.html.markdown meta.tag.block.any.html punctuation.definition.tag.end.html", + "t": "text.html.markdown meta.tag.structure.div.end.html punctuation.definition.tag.end.html", "r": { "dark_plus": "punctuation.definition.tag: #808080", "light_plus": "punctuation.definition.tag: #800000", @@ -606,7 +606,7 @@ }, { "c": "<", - "t": "text.html.markdown meta.embedded.block.html meta.tag.metadata.script.html punctuation.definition.tag.begin.html", + "t": "text.html.markdown meta.embedded.block.html meta.tag.metadata.script.start.html punctuation.definition.tag.begin.html", "r": { "dark_plus": "punctuation.definition.tag: #808080", "light_plus": "punctuation.definition.tag: #800000", @@ -617,7 +617,7 @@ }, { "c": "script", - "t": "text.html.markdown meta.embedded.block.html meta.tag.metadata.script.html entity.name.tag.html", + "t": "text.html.markdown meta.embedded.block.html meta.tag.metadata.script.start.html entity.name.tag.html", "r": { "dark_plus": "entity.name.tag: #569CD6", "light_plus": "entity.name.tag: #800000", @@ -628,7 +628,7 @@ }, { "c": " ", - "t": "text.html.markdown meta.embedded.block.html meta.tag.metadata.script.html", + "t": "text.html.markdown meta.embedded.block.html meta.tag.metadata.script.start.html", "r": { "dark_plus": "meta.embedded: #D4D4D4", "light_plus": "meta.embedded: #000000", @@ -639,7 +639,7 @@ }, { "c": "type", - "t": "text.html.markdown meta.embedded.block.html meta.tag.metadata.script.html entity.other.attribute-name.html", + "t": "text.html.markdown meta.embedded.block.html meta.tag.metadata.script.start.html meta.attribute.type.html entity.other.attribute-name.html", "r": { "dark_plus": "entity.other.attribute-name: #9CDCFE", "light_plus": "entity.other.attribute-name: #FF0000", @@ -650,7 +650,7 @@ }, { "c": "=", - "t": "text.html.markdown meta.embedded.block.html meta.tag.metadata.script.html", + "t": "text.html.markdown meta.embedded.block.html meta.tag.metadata.script.start.html meta.attribute.type.html punctuation.separator.key-value.html", "r": { "dark_plus": "meta.embedded: #D4D4D4", "light_plus": "meta.embedded: #000000", @@ -661,7 +661,7 @@ }, { "c": "'", - "t": "text.html.markdown meta.embedded.block.html meta.tag.metadata.script.html string.quoted.single.html punctuation.definition.string.begin.html", + "t": "text.html.markdown meta.embedded.block.html meta.tag.metadata.script.start.html meta.attribute.type.html string.quoted.single.html punctuation.definition.string.begin.html", "r": { "dark_plus": "string: #CE9178", "light_plus": "string.quoted.single.html: #0000FF", @@ -672,7 +672,7 @@ }, { "c": "text/x-koka", - "t": "text.html.markdown meta.embedded.block.html meta.tag.metadata.script.html string.quoted.single.html", + "t": "text.html.markdown meta.embedded.block.html meta.tag.metadata.script.start.html meta.attribute.type.html string.quoted.single.html", "r": { "dark_plus": "string: #CE9178", "light_plus": "string.quoted.single.html: #0000FF", @@ -683,7 +683,7 @@ }, { "c": "'", - "t": "text.html.markdown meta.embedded.block.html meta.tag.metadata.script.html string.quoted.single.html punctuation.definition.string.end.html", + "t": "text.html.markdown meta.embedded.block.html meta.tag.metadata.script.start.html meta.attribute.type.html string.quoted.single.html punctuation.definition.string.end.html", "r": { "dark_plus": "string: #CE9178", "light_plus": "string.quoted.single.html: #0000FF", @@ -694,7 +694,7 @@ }, { "c": ">", - "t": "text.html.markdown meta.embedded.block.html meta.tag.metadata.script.html punctuation.definition.tag.end.html", + "t": "text.html.markdown meta.embedded.block.html meta.tag.metadata.script.start.html punctuation.definition.tag.end.html", "r": { "dark_plus": "punctuation.definition.tag: #808080", "light_plus": "punctuation.definition.tag: #800000", @@ -727,7 +727,7 @@ }, { "c": "", - "t": "text.html.markdown meta.embedded.block.html meta.tag.metadata.script.html punctuation.definition.tag.end.html", + "t": "text.html.markdown meta.embedded.block.html meta.tag.metadata.script.end.html punctuation.definition.tag.end.html", "r": { "dark_plus": "punctuation.definition.tag: #808080", "light_plus": "punctuation.definition.tag: #800000", @@ -770,29 +770,7 @@ } }, { - "c": " and a ", - "t": "text.html.markdown", - "r": { - "dark_plus": "default: #D4D4D4", - "light_plus": "default: #000000", - "dark_vs": "default: #D4D4D4", - "light_vs": "default: #000000", - "hc_black": "default: #FFFFFF" - } - }, - { - "c": "&", - "t": "text.html.markdown invalid.illegal.bad-ampersand.html", - "r": { - "dark_plus": "invalid: #F44747", - "light_plus": "invalid: #CD3131", - "dark_vs": "invalid: #F44747", - "light_vs": "invalid: #CD3131", - "hc_black": "invalid: #F44747" - } - }, - { - "c": " ", + "c": " and a & ", "t": "text.html.markdown", "r": { "dark_plus": "default: #D4D4D4", @@ -804,7 +782,7 @@ }, { "c": "<", - "t": "text.html.markdown meta.tag.inline.any.html punctuation.definition.tag.begin.html", + "t": "text.html.markdown meta.tag.inline.b.start.html punctuation.definition.tag.begin.html", "r": { "dark_plus": "punctuation.definition.tag: #808080", "light_plus": "punctuation.definition.tag: #800000", @@ -815,7 +793,7 @@ }, { "c": "b", - "t": "text.html.markdown meta.tag.inline.any.html entity.name.tag.inline.any.html", + "t": "text.html.markdown meta.tag.inline.b.start.html entity.name.tag.html", "r": { "dark_plus": "entity.name.tag: #569CD6", "light_plus": "entity.name.tag: #800000", @@ -826,7 +804,7 @@ }, { "c": " ", - "t": "text.html.markdown meta.tag.inline.any.html", + "t": "text.html.markdown meta.tag.inline.b.start.html", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -837,7 +815,7 @@ }, { "c": "class", - "t": "text.html.markdown meta.tag.inline.any.html entity.other.attribute-name.html", + "t": "text.html.markdown meta.tag.inline.b.start.html meta.attribute.class.html entity.other.attribute-name.html", "r": { "dark_plus": "entity.other.attribute-name: #9CDCFE", "light_plus": "entity.other.attribute-name: #FF0000", @@ -848,7 +826,7 @@ }, { "c": "=", - "t": "text.html.markdown meta.tag.inline.any.html", + "t": "text.html.markdown meta.tag.inline.b.start.html meta.attribute.class.html punctuation.separator.key-value.html", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -859,7 +837,7 @@ }, { "c": "\"", - "t": "text.html.markdown meta.tag.inline.any.html string.quoted.double.html punctuation.definition.string.begin.html", + "t": "text.html.markdown meta.tag.inline.b.start.html meta.attribute.class.html string.quoted.double.html punctuation.definition.string.begin.html", "r": { "dark_plus": "string: #CE9178", "light_plus": "string.quoted.double.html: #0000FF", @@ -870,7 +848,7 @@ }, { "c": "bold", - "t": "text.html.markdown meta.tag.inline.any.html string.quoted.double.html", + "t": "text.html.markdown meta.tag.inline.b.start.html meta.attribute.class.html string.quoted.double.html", "r": { "dark_plus": "string: #CE9178", "light_plus": "string.quoted.double.html: #0000FF", @@ -881,7 +859,7 @@ }, { "c": "\"", - "t": "text.html.markdown meta.tag.inline.any.html string.quoted.double.html punctuation.definition.string.end.html", + "t": "text.html.markdown meta.tag.inline.b.start.html meta.attribute.class.html string.quoted.double.html punctuation.definition.string.end.html", "r": { "dark_plus": "string: #CE9178", "light_plus": "string.quoted.double.html: #0000FF", @@ -892,7 +870,7 @@ }, { "c": ">", - "t": "text.html.markdown meta.tag.inline.any.html punctuation.definition.tag.end.html", + "t": "text.html.markdown meta.tag.inline.b.start.html punctuation.definition.tag.end.html", "r": { "dark_plus": "punctuation.definition.tag: #808080", "light_plus": "punctuation.definition.tag: #800000", @@ -914,7 +892,7 @@ }, { "c": "", - "t": "text.html.markdown meta.tag.inline.any.html punctuation.definition.tag.end.html", + "t": "text.html.markdown meta.tag.inline.b.end.html punctuation.definition.tag.end.html", "r": { "dark_plus": "punctuation.definition.tag: #808080", "light_plus": "punctuation.definition.tag: #800000", @@ -969,7 +947,7 @@ }, { "c": "<", - "t": "text.html.markdown meta.embedded.block.html meta.tag.metadata.style.html punctuation.definition.tag.begin.html", + "t": "text.html.markdown meta.embedded.block.html meta.tag.metadata.style.start.html punctuation.definition.tag.begin.html", "r": { "dark_plus": "punctuation.definition.tag: #808080", "light_plus": "punctuation.definition.tag: #800000", @@ -980,7 +958,7 @@ }, { "c": "style", - "t": "text.html.markdown meta.embedded.block.html meta.tag.metadata.style.html entity.name.tag.html", + "t": "text.html.markdown meta.embedded.block.html meta.tag.metadata.style.start.html entity.name.tag.html", "r": { "dark_plus": "entity.name.tag: #569CD6", "light_plus": "entity.name.tag: #800000", @@ -991,7 +969,7 @@ }, { "c": ">", - "t": "text.html.markdown meta.embedded.block.html meta.tag.metadata.style.html punctuation.definition.tag.end.html", + "t": "text.html.markdown meta.embedded.block.html meta.tag.metadata.style.start.html punctuation.definition.tag.end.html", "r": { "dark_plus": "punctuation.definition.tag: #808080", "light_plus": "punctuation.definition.tag: #800000", @@ -1156,7 +1134,7 @@ }, { "c": "<", - "t": "text.html.markdown meta.embedded.block.html meta.tag.metadata.style.html punctuation.definition.tag.begin.html source.css", + "t": "text.html.markdown meta.embedded.block.html meta.tag.metadata.style.end.html punctuation.definition.tag.begin.html source.css", "r": { "dark_plus": "punctuation.definition.tag: #808080", "light_plus": "punctuation.definition.tag: #800000", @@ -1167,7 +1145,7 @@ }, { "c": "/", - "t": "text.html.markdown meta.embedded.block.html meta.tag.metadata.style.html punctuation.definition.tag.begin.html", + "t": "text.html.markdown meta.embedded.block.html meta.tag.metadata.style.end.html punctuation.definition.tag.begin.html", "r": { "dark_plus": "punctuation.definition.tag: #808080", "light_plus": "punctuation.definition.tag: #800000", @@ -1178,7 +1156,7 @@ }, { "c": "style", - "t": "text.html.markdown meta.embedded.block.html meta.tag.metadata.style.html entity.name.tag.html", + "t": "text.html.markdown meta.embedded.block.html meta.tag.metadata.style.end.html entity.name.tag.html", "r": { "dark_plus": "entity.name.tag: #569CD6", "light_plus": "entity.name.tag: #800000", @@ -1189,7 +1167,7 @@ }, { "c": ">", - "t": "text.html.markdown meta.embedded.block.html meta.tag.metadata.style.html punctuation.definition.tag.end.html", + "t": "text.html.markdown meta.embedded.block.html meta.tag.metadata.style.end.html punctuation.definition.tag.end.html", "r": { "dark_plus": "punctuation.definition.tag: #808080", "light_plus": "punctuation.definition.tag: #800000", @@ -1200,7 +1178,7 @@ }, { "c": "", - "t": "text.html.markdown meta.tag.block.any.html punctuation.definition.tag.end.html", + "t": "text.html.markdown meta.tag.structure.div.end.html punctuation.definition.tag.end.html", "r": { "dark_plus": "punctuation.definition.tag: #808080", "light_plus": "punctuation.definition.tag: #800000", @@ -1620,9 +1598,9 @@ "c": ">", "t": "text.html.markdown markup.quote.markdown beginning.punctuation.definition.quote.markdown", "r": { - "dark_plus": "beginning.punctuation.definition.quote.markdown: #608B4E", + "dark_plus": "beginning.punctuation.definition.quote.markdown: #6A9955", "light_plus": "beginning.punctuation.definition.quote.markdown: #0451A5", - "dark_vs": "beginning.punctuation.definition.quote.markdown: #608B4E", + "dark_vs": "beginning.punctuation.definition.quote.markdown: #6A9955", "light_vs": "beginning.punctuation.definition.quote.markdown: #0451A5", "hc_black": "default: #FFFFFF" } @@ -1653,9 +1631,9 @@ "c": ">", "t": "text.html.markdown markup.quote.markdown beginning.punctuation.definition.quote.markdown", "r": { - "dark_plus": "beginning.punctuation.definition.quote.markdown: #608B4E", + "dark_plus": "beginning.punctuation.definition.quote.markdown: #6A9955", "light_plus": "beginning.punctuation.definition.quote.markdown: #0451A5", - "dark_vs": "beginning.punctuation.definition.quote.markdown: #608B4E", + "dark_vs": "beginning.punctuation.definition.quote.markdown: #6A9955", "light_vs": "beginning.punctuation.definition.quote.markdown: #0451A5", "hc_black": "default: #FFFFFF" } @@ -1664,9 +1642,9 @@ "c": ">", "t": "text.html.markdown markup.quote.markdown markup.quote.markdown beginning.punctuation.definition.quote.markdown", "r": { - "dark_plus": "beginning.punctuation.definition.quote.markdown: #608B4E", + "dark_plus": "beginning.punctuation.definition.quote.markdown: #6A9955", "light_plus": "beginning.punctuation.definition.quote.markdown: #0451A5", - "dark_vs": "beginning.punctuation.definition.quote.markdown: #608B4E", + "dark_vs": "beginning.punctuation.definition.quote.markdown: #6A9955", "light_vs": "beginning.punctuation.definition.quote.markdown: #0451A5", "hc_black": "default: #FFFFFF" } @@ -1741,9 +1719,9 @@ "c": ">", "t": "text.html.markdown markup.list.numbered.markdown markup.quote.markdown beginning.punctuation.definition.quote.markdown", "r": { - "dark_plus": "beginning.punctuation.definition.quote.markdown: #608B4E", + "dark_plus": "beginning.punctuation.definition.quote.markdown: #6A9955", "light_plus": "beginning.punctuation.definition.quote.markdown: #0451A5", - "dark_vs": "beginning.punctuation.definition.quote.markdown: #608B4E", + "dark_vs": "beginning.punctuation.definition.quote.markdown: #6A9955", "light_vs": "beginning.punctuation.definition.quote.markdown: #0451A5", "hc_black": "default: #FFFFFF" } @@ -2520,7 +2498,7 @@ }, { "c": "<", - "t": "text.html.markdown meta.paragraph.markdown meta.tag.inline.any.html punctuation.definition.tag.begin.html", + "t": "text.html.markdown meta.paragraph.markdown meta.tag.inline.abbr.start.html punctuation.definition.tag.begin.html", "r": { "dark_plus": "punctuation.definition.tag: #808080", "light_plus": "punctuation.definition.tag: #800000", @@ -2531,7 +2509,7 @@ }, { "c": "abbr", - "t": "text.html.markdown meta.paragraph.markdown meta.tag.inline.any.html entity.name.tag.inline.any.html", + "t": "text.html.markdown meta.paragraph.markdown meta.tag.inline.abbr.start.html entity.name.tag.html", "r": { "dark_plus": "entity.name.tag: #569CD6", "light_plus": "entity.name.tag: #800000", @@ -2542,7 +2520,7 @@ }, { "c": ">", - "t": "text.html.markdown meta.paragraph.markdown meta.tag.inline.any.html punctuation.definition.tag.end.html", + "t": "text.html.markdown meta.paragraph.markdown meta.tag.inline.abbr.start.html punctuation.definition.tag.end.html", "r": { "dark_plus": "punctuation.definition.tag: #808080", "light_plus": "punctuation.definition.tag: #800000", From 067a72787fca43da6d366b1b50bfed322d6e9c03 Mon Sep 17 00:00:00 2001 From: Martin Aeschlimann Date: Fri, 27 Jul 2018 11:01:36 +0200 Subject: [PATCH 0220/1276] [php] update colorizer tests --- .../colorize-results/issue-28354_php.json | 14 ++-- .../php/test/colorize-results/test_php.json | 84 +++++++++---------- 2 files changed, 49 insertions(+), 49 deletions(-) diff --git a/extensions/php/test/colorize-results/issue-28354_php.json b/extensions/php/test/colorize-results/issue-28354_php.json index cc9924d3945..12e439430fb 100644 --- a/extensions/php/test/colorize-results/issue-28354_php.json +++ b/extensions/php/test/colorize-results/issue-28354_php.json @@ -1,7 +1,7 @@ [ { "c": "<", - "t": "text.html.php meta.embedded.block.html meta.tag.metadata.script.html punctuation.definition.tag.begin.html", + "t": "text.html.php meta.embedded.block.html meta.tag.metadata.script.start.html punctuation.definition.tag.begin.html", "r": { "dark_plus": "punctuation.definition.tag: #808080", "light_plus": "punctuation.definition.tag: #800000", @@ -12,7 +12,7 @@ }, { "c": "script", - "t": "text.html.php meta.embedded.block.html meta.tag.metadata.script.html entity.name.tag.html", + "t": "text.html.php meta.embedded.block.html meta.tag.metadata.script.start.html entity.name.tag.html", "r": { "dark_plus": "entity.name.tag: #569CD6", "light_plus": "entity.name.tag: #800000", @@ -23,7 +23,7 @@ }, { "c": ">", - "t": "text.html.php meta.embedded.block.html meta.tag.metadata.script.html punctuation.definition.tag.end.html", + "t": "text.html.php meta.embedded.block.html meta.tag.metadata.script.start.html punctuation.definition.tag.end.html", "r": { "dark_plus": "punctuation.definition.tag: #808080", "light_plus": "punctuation.definition.tag: #800000", @@ -496,7 +496,7 @@ }, { "c": "<", - "t": "text.html.php meta.embedded.block.html meta.tag.metadata.script.html punctuation.definition.tag.begin.html source.js", + "t": "text.html.php meta.embedded.block.html meta.tag.metadata.script.end.html punctuation.definition.tag.begin.html source.js", "r": { "dark_plus": "punctuation.definition.tag: #808080", "light_plus": "punctuation.definition.tag: #800000", @@ -507,7 +507,7 @@ }, { "c": "/", - "t": "text.html.php meta.embedded.block.html meta.tag.metadata.script.html punctuation.definition.tag.begin.html", + "t": "text.html.php meta.embedded.block.html meta.tag.metadata.script.end.html punctuation.definition.tag.begin.html", "r": { "dark_plus": "punctuation.definition.tag: #808080", "light_plus": "punctuation.definition.tag: #800000", @@ -518,7 +518,7 @@ }, { "c": "script", - "t": "text.html.php meta.embedded.block.html meta.tag.metadata.script.html entity.name.tag.html", + "t": "text.html.php meta.embedded.block.html meta.tag.metadata.script.end.html entity.name.tag.html", "r": { "dark_plus": "entity.name.tag: #569CD6", "light_plus": "entity.name.tag: #800000", @@ -529,7 +529,7 @@ }, { "c": ">", - "t": "text.html.php meta.embedded.block.html meta.tag.metadata.script.html punctuation.definition.tag.end.html", + "t": "text.html.php meta.embedded.block.html meta.tag.metadata.script.end.html punctuation.definition.tag.end.html", "r": { "dark_plus": "punctuation.definition.tag: #808080", "light_plus": "punctuation.definition.tag: #800000", diff --git a/extensions/php/test/colorize-results/test_php.json b/extensions/php/test/colorize-results/test_php.json index 4cb58182b1a..277428ac11b 100644 --- a/extensions/php/test/colorize-results/test_php.json +++ b/extensions/php/test/colorize-results/test_php.json @@ -1,7 +1,7 @@ [ { "c": "<", - "t": "text.html.php meta.tag.structure.any.html punctuation.definition.tag.html", + "t": "text.html.php meta.tag.structure.html.start.html punctuation.definition.tag.begin.html", "r": { "dark_plus": "punctuation.definition.tag: #808080", "light_plus": "punctuation.definition.tag: #800000", @@ -12,7 +12,7 @@ }, { "c": "html", - "t": "text.html.php meta.tag.structure.any.html entity.name.tag.structure.any.html", + "t": "text.html.php meta.tag.structure.html.start.html entity.name.tag.html", "r": { "dark_plus": "entity.name.tag: #569CD6", "light_plus": "entity.name.tag: #800000", @@ -23,7 +23,7 @@ }, { "c": ">", - "t": "text.html.php meta.tag.structure.any.html punctuation.definition.tag.html", + "t": "text.html.php meta.tag.structure.html.start.html punctuation.definition.tag.end.html", "r": { "dark_plus": "punctuation.definition.tag: #808080", "light_plus": "punctuation.definition.tag: #800000", @@ -34,7 +34,7 @@ }, { "c": "<", - "t": "text.html.php meta.tag.structure.any.html punctuation.definition.tag.html", + "t": "text.html.php meta.tag.structure.head.start.html punctuation.definition.tag.begin.html", "r": { "dark_plus": "punctuation.definition.tag: #808080", "light_plus": "punctuation.definition.tag: #800000", @@ -45,7 +45,7 @@ }, { "c": "head", - "t": "text.html.php meta.tag.structure.any.html entity.name.tag.structure.any.html", + "t": "text.html.php meta.tag.structure.head.start.html entity.name.tag.html", "r": { "dark_plus": "entity.name.tag: #569CD6", "light_plus": "entity.name.tag: #800000", @@ -56,7 +56,7 @@ }, { "c": ">", - "t": "text.html.php meta.tag.structure.any.html punctuation.definition.tag.html", + "t": "text.html.php meta.tag.structure.head.start.html punctuation.definition.tag.end.html", "r": { "dark_plus": "punctuation.definition.tag: #808080", "light_plus": "punctuation.definition.tag: #800000", @@ -78,7 +78,7 @@ }, { "c": "<", - "t": "text.html.php meta.tag.inline.any.html punctuation.definition.tag.begin.html", + "t": "text.html.php meta.tag.metadata.title.start.html punctuation.definition.tag.begin.html", "r": { "dark_plus": "punctuation.definition.tag: #808080", "light_plus": "punctuation.definition.tag: #800000", @@ -89,7 +89,7 @@ }, { "c": "title", - "t": "text.html.php meta.tag.inline.any.html entity.name.tag.inline.any.html", + "t": "text.html.php meta.tag.metadata.title.start.html entity.name.tag.html", "r": { "dark_plus": "entity.name.tag: #569CD6", "light_plus": "entity.name.tag: #800000", @@ -100,7 +100,7 @@ }, { "c": ">", - "t": "text.html.php meta.tag.inline.any.html punctuation.definition.tag.end.html", + "t": "text.html.php meta.tag.metadata.title.start.html punctuation.definition.tag.end.html", "r": { "dark_plus": "punctuation.definition.tag: #808080", "light_plus": "punctuation.definition.tag: #800000", @@ -122,7 +122,7 @@ }, { "c": "", - "t": "text.html.php meta.tag.inline.any.html punctuation.definition.tag.end.html", + "t": "text.html.php meta.tag.metadata.title.end.html punctuation.definition.tag.end.html", "r": { "dark_plus": "punctuation.definition.tag: #808080", "light_plus": "punctuation.definition.tag: #800000", @@ -155,7 +155,7 @@ }, { "c": "", - "t": "text.html.php meta.tag.structure.any.html punctuation.definition.tag.html", + "t": "text.html.php meta.tag.structure.head.end.html punctuation.definition.tag.end.html", "r": { "dark_plus": "punctuation.definition.tag: #808080", "light_plus": "punctuation.definition.tag: #800000", @@ -188,7 +188,7 @@ }, { "c": "<", - "t": "text.html.php meta.tag.structure.any.html punctuation.definition.tag.html", + "t": "text.html.php meta.tag.structure.body.start.html punctuation.definition.tag.begin.html", "r": { "dark_plus": "punctuation.definition.tag: #808080", "light_plus": "punctuation.definition.tag: #800000", @@ -199,7 +199,7 @@ }, { "c": "body", - "t": "text.html.php meta.tag.structure.any.html entity.name.tag.structure.any.html", + "t": "text.html.php meta.tag.structure.body.start.html entity.name.tag.html", "r": { "dark_plus": "entity.name.tag: #569CD6", "light_plus": "entity.name.tag: #800000", @@ -210,7 +210,7 @@ }, { "c": ">", - "t": "text.html.php meta.tag.structure.any.html punctuation.definition.tag.html", + "t": "text.html.php meta.tag.structure.body.start.html punctuation.definition.tag.end.html", "r": { "dark_plus": "punctuation.definition.tag: #808080", "light_plus": "punctuation.definition.tag: #800000", @@ -322,9 +322,9 @@ "c": "//", "t": "text.html.php meta.embedded.block.php source.php comment.line.double-slash.php punctuation.definition.comment.php", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -333,9 +333,9 @@ "c": " Code to be executed", "t": "text.html.php meta.embedded.block.php source.php comment.line.double-slash.php", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -377,9 +377,9 @@ "c": "/*", "t": "text.html.php meta.embedded.block.php source.php comment.block.php punctuation.definition.comment.php", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -388,9 +388,9 @@ "c": " Example PHP file", "t": "text.html.php meta.embedded.block.php source.php comment.block.php", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -399,9 +399,9 @@ "c": "\tmultiline comment", "t": "text.html.php meta.embedded.block.php source.php comment.block.php", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -410,9 +410,9 @@ "c": "\t", "t": "text.html.php meta.embedded.block.php source.php comment.block.php", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -421,9 +421,9 @@ "c": "*/", "t": "text.html.php meta.embedded.block.php source.php comment.block.php punctuation.definition.comment.php", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -2654,9 +2654,9 @@ "c": "//", "t": "text.html.php meta.embedded.block.php source.php comment.line.double-slash.php punctuation.definition.comment.php", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -2665,9 +2665,9 @@ "c": " display shuffled cards (EXAMPLE ONLY)", "t": "text.html.php meta.embedded.block.php source.php comment.line.double-slash.php", "r": { - "dark_plus": "comment: #608B4E", + "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", - "dark_vs": "comment: #608B4E", + "dark_vs": "comment: #6A9955", "light_vs": "comment: #008000", "hc_black": "comment: #7CA668" } @@ -3565,7 +3565,7 @@ }, { "c": "", - "t": "text.html.php meta.tag.structure.any.html punctuation.definition.tag.html", + "t": "text.html.php meta.tag.structure.body.end.html punctuation.definition.tag.end.html", "r": { "dark_plus": "punctuation.definition.tag: #808080", "light_plus": "punctuation.definition.tag: #800000", @@ -3598,7 +3598,7 @@ }, { "c": "", - "t": "text.html.php meta.tag.structure.any.html punctuation.definition.tag.html", + "t": "text.html.php meta.tag.structure.html.end.html punctuation.definition.tag.end.html", "r": { "dark_plus": "punctuation.definition.tag: #808080", "light_plus": "punctuation.definition.tag: #800000", From 86f3a8077a3cee3630ae30415c3a68c500151230 Mon Sep 17 00:00:00 2001 From: Martin Aeschlimann Date: Fri, 27 Jul 2018 11:01:50 +0200 Subject: [PATCH 0221/1276] [powershell] update grammar --- extensions/powershell/syntaxes/powershell.tmLanguage.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/extensions/powershell/syntaxes/powershell.tmLanguage.json b/extensions/powershell/syntaxes/powershell.tmLanguage.json index ca3fd4d5a4d..0e3c0dbe84a 100644 --- a/extensions/powershell/syntaxes/powershell.tmLanguage.json +++ b/extensions/powershell/syntaxes/powershell.tmLanguage.json @@ -4,7 +4,7 @@ "If you want to provide a fix or improvement, please create a pull request against the original repository.", "Once accepted there, we are happy to receive an update request." ], - "version": "https://github.com/PowerShell/EditorSyntax/commit/146e421358945dbfbd24a9dcf56d759bdb0693db", + "version": "https://github.com/PowerShell/EditorSyntax/commit/472c9447da4e3160bef211d5e1a0c2dee3cce497", "name": "PowerShell", "scopeName": "source.powershell", "patterns": [ @@ -262,7 +262,7 @@ "name": "punctuation.definition.comment.powershell" } }, - "end": "$", + "end": "$\\n?", "name": "comment.line.powershell", "patterns": [ { From cc660093df7dd81145f2bcb08791e2e583b47a87 Mon Sep 17 00:00:00 2001 From: Johannes Rieken Date: Fri, 27 Jul 2018 09:40:08 +0200 Subject: [PATCH 0222/1276] bc - fix missing highlights in file picker --- .../workbench/browser/parts/editor/breadcrumbsPicker.ts | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/vs/workbench/browser/parts/editor/breadcrumbsPicker.ts b/src/vs/workbench/browser/parts/editor/breadcrumbsPicker.ts index 72b004f7abc..dc1f396ebcd 100644 --- a/src/vs/workbench/browser/parts/editor/breadcrumbsPicker.ts +++ b/src/vs/workbench/browser/parts/editor/breadcrumbsPicker.ts @@ -197,7 +197,7 @@ export class FileDataSource implements IDataSource { export class FileRenderer implements IRenderer, IHighlightingRenderer { - private readonly _scores = new Map(); + private readonly _scores = new Map(); constructor( @IInstantiationService private readonly _instantiationService: IInstantiationService, @@ -223,14 +223,14 @@ export class FileRenderer implements IRenderer, IHighlightingRenderer { hidePath: true, fileKind: FileKind.ROOT_FOLDER, fileDecorations: fileDecorations, - matches: createMatches((this._scores.get(element) || [, []])[1]) + matches: createMatches((this._scores.get(element.uri.toString()) || [, []])[1]) }); } else { templateData.setFile(element.resource, { hidePath: true, fileKind: element.isDirectory ? FileKind.FOLDER : FileKind.FILE, fileDecorations: fileDecorations, - matches: createMatches((this._scores.get(element) || [, []])[1]) + matches: createMatches((this._scores.get(element.resource.toString()) || [, []])[1]) }); } } @@ -246,7 +246,7 @@ export class FileRenderer implements IRenderer, IHighlightingRenderer { while (nav.next()) { let element = nav.current() as IFileStat | IWorkspaceFolder; let score = fuzzyScore(pattern, element.name, undefined, true); - this._scores.set(element, score); + this._scores.set(IWorkspaceFolder.isIWorkspaceFolder(element) ? element.uri.toString() : element.resource.toString(), score); if (!topScore || score && topScore[0] < score[0]) { topScore = score; topElement = element; From bcb2c46a450dd1c8c090a453a2d7dc5036f6d7b6 Mon Sep 17 00:00:00 2001 From: Johannes Rieken Date: Fri, 27 Jul 2018 09:42:30 +0200 Subject: [PATCH 0223/1276] :lipstick: --- .../browser/parts/editor/breadcrumbsPicker.ts | 24 +++++++++---------- 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/src/vs/workbench/browser/parts/editor/breadcrumbsPicker.ts b/src/vs/workbench/browser/parts/editor/breadcrumbsPicker.ts index dc1f396ebcd..3ee60065b1c 100644 --- a/src/vs/workbench/browser/parts/editor/breadcrumbsPicker.ts +++ b/src/vs/workbench/browser/parts/editor/breadcrumbsPicker.ts @@ -218,21 +218,21 @@ export class FileRenderer implements IRenderer, IHighlightingRenderer { renderElement(tree: ITree, element: IFileStat | IWorkspaceFolder, templateId: string, templateData: FileLabel): void { let fileDecorations = this._configService.getValue<{ colors: boolean, badges: boolean }>('explorer.decorations'); + let resource: URI; + let fileKind: FileKind; if (IWorkspaceFolder.isIWorkspaceFolder(element)) { - templateData.setFile(element.uri, { - hidePath: true, - fileKind: FileKind.ROOT_FOLDER, - fileDecorations: fileDecorations, - matches: createMatches((this._scores.get(element.uri.toString()) || [, []])[1]) - }); + resource = element.uri; + fileKind = FileKind.ROOT_FOLDER; } else { - templateData.setFile(element.resource, { - hidePath: true, - fileKind: element.isDirectory ? FileKind.FOLDER : FileKind.FILE, - fileDecorations: fileDecorations, - matches: createMatches((this._scores.get(element.resource.toString()) || [, []])[1]) - }); + resource = element.resource; + fileKind = element.isDirectory ? FileKind.FOLDER : FileKind.FILE; } + templateData.setFile(resource, { + fileKind, + hidePath: true, + fileDecorations: fileDecorations, + matches: createMatches((this._scores.get(resource.toString()) || [, []])[1]) + }); } disposeTemplate(tree: ITree, templateId: string, templateData: FileLabel): void { From 4d29b56db04fbb540d9fcb00bda0f7fbdae052fa Mon Sep 17 00:00:00 2001 From: Johannes Rieken Date: Fri, 27 Jul 2018 11:15:48 +0200 Subject: [PATCH 0224/1276] bc - remove useQuckPick option for now --- src/vs/workbench/browser/parts/editor/breadcrumbs.ts | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/vs/workbench/browser/parts/editor/breadcrumbs.ts b/src/vs/workbench/browser/parts/editor/breadcrumbs.ts index 83f309f828b..c076583eb44 100644 --- a/src/vs/workbench/browser/parts/editor/breadcrumbs.ts +++ b/src/vs/workbench/browser/parts/editor/breadcrumbs.ts @@ -114,11 +114,11 @@ Registry.as(Extensions.Configuration).registerConfigurat type: 'boolean', default: false }, - 'breadcrumbs.useQuickPick': { - description: localize('useQuickPick', "Use quick pick instead of breadcrumb-pickers."), - type: 'boolean', - default: false - }, + // 'breadcrumbs.useQuickPick': { + // description: localize('useQuickPick', "Use quick pick instead of breadcrumb-pickers."), + // type: 'boolean', + // default: false + // }, 'breadcrumbs.filePath': { description: localize('filepath', "Controls if and how file paths are shown in the breadcrumbs view."), type: 'string', From 59b585a7caa786dd5b826516025634863413e612 Mon Sep 17 00:00:00 2001 From: Johannes Rieken Date: Fri, 27 Jul 2018 11:43:32 +0200 Subject: [PATCH 0225/1276] perf - ensure stable sort when marks happened at the same time --- src/vs/base/common/performance.js | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/src/vs/base/common/performance.js b/src/vs/base/common/performance.js index baf730387ac..c89ace71f2c 100644 --- a/src/vs/base/common/performance.js +++ b/src/vs/base/common/performance.js @@ -42,31 +42,33 @@ define([], function () { function getEntries(type, name) { const result = []; const entries = global._performanceEntries; - for (let i = 0; i < entries.length; i += 4) { + for (let i = 0; i < entries.length; i += 5) { if (entries[i] === type && (name === void 0 || entries[i + 1] === name)) { result.push({ type: entries[i], name: entries[i + 1], startTime: entries[i + 2], duration: entries[i + 3], + seq: entries[i + 4], }); } } return result.sort((a, b) => { - return a.startTime - b.startTime; + return a.startTime - b.startTime || a.seq - b.seq; }); } function getEntry(type, name) { const entries = global._performanceEntries; - for (let i = 0; i < entries.length; i += 4) { + for (let i = 0; i < entries.length; i += 5) { if (entries[i] === type && entries[i + 1] === name) { return { type: entries[i], name: entries[i + 1], startTime: entries[i + 2], duration: entries[i + 3], + seq: entries[i + 4], }; } } @@ -76,7 +78,7 @@ define([], function () { const entries = global._performanceEntries; let name = from; let startTime = 0; - for (let i = 0; i < entries.length; i += 4) { + for (let i = 0; i < entries.length; i += 5) { if (entries[i + 1] === name) { if (name === from) { // found `from` (start of interval) @@ -91,8 +93,10 @@ define([], function () { return 0; } + let seq = 0; + function mark(name) { - global._performanceEntries.push('mark', name, _now(), 0); + global._performanceEntries.push('mark', name, _now(), 0, seq++); if (typeof console.timeStamp === 'function') { console.timeStamp(name); } @@ -121,9 +125,9 @@ define([], function () { function _getLastStartTime(name) { const entries = global._performanceEntries; - for (let i = entries.length - 1; i >= 0; i -= 4) { - if (entries[i - 2] === name) { - return entries[i - 1]; + for (let i = entries.length - 1; i >= 0; i -= 5) { + if (entries[i - 3] === name) { + return entries[i - 2]; } } From d3cdc5f8eafce7d9dac776179e6c6277d9ff01ee Mon Sep 17 00:00:00 2001 From: Johannes Rieken Date: Fri, 27 Jul 2018 11:46:44 +0200 Subject: [PATCH 0226/1276] debt - use const enums when possible --- src/vs/editor/contrib/documentSymbols/outlineTree.ts | 2 +- src/vs/editor/contrib/snippet/snippetParser.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/vs/editor/contrib/documentSymbols/outlineTree.ts b/src/vs/editor/contrib/documentSymbols/outlineTree.ts index 72f66dd91e2..6737e50335b 100644 --- a/src/vs/editor/contrib/documentSymbols/outlineTree.ts +++ b/src/vs/editor/contrib/documentSymbols/outlineTree.ts @@ -23,7 +23,7 @@ import { MarkerSeverity } from 'vs/platform/markers/common/markers'; import { listErrorForeground, listWarningForeground } from 'vs/platform/theme/common/colorRegistry'; import { IThemeService } from 'vs/platform/theme/common/themeService'; -export enum OutlineItemCompareType { +export const enum OutlineItemCompareType { ByPosition, ByName, ByKind diff --git a/src/vs/editor/contrib/snippet/snippetParser.ts b/src/vs/editor/contrib/snippet/snippetParser.ts index bf034b00bb3..c839cffd343 100644 --- a/src/vs/editor/contrib/snippet/snippetParser.ts +++ b/src/vs/editor/contrib/snippet/snippetParser.ts @@ -7,7 +7,7 @@ import { CharCode } from 'vs/base/common/charCode'; -export enum TokenType { +export const enum TokenType { Dollar, Colon, Comma, From 454c47f42bba51b1df4f380a37e22b76380ac98c Mon Sep 17 00:00:00 2001 From: Christof Marti Date: Fri, 27 Jul 2018 11:52:19 +0200 Subject: [PATCH 0227/1276] Show a terminal hint (fixes #50775) --- .../parts/welcome/overlay/browser/welcomeOverlay.css | 6 ++++++ .../parts/welcome/overlay/browser/welcomeOverlay.ts | 11 ++++++++--- 2 files changed, 14 insertions(+), 3 deletions(-) diff --git a/src/vs/workbench/parts/welcome/overlay/browser/welcomeOverlay.css b/src/vs/workbench/parts/welcome/overlay/browser/welcomeOverlay.css index bc843e58ab3..e76b3e08093 100644 --- a/src/vs/workbench/parts/welcome/overlay/browser/welcomeOverlay.css +++ b/src/vs/workbench/parts/welcome/overlay/browser/welcomeOverlay.css @@ -97,6 +97,12 @@ left: 45px; } +.monaco-workbench > .welcomeOverlay > .key.terminal { + position: absolute; + bottom: 25px; + left: 50%; +} + .monaco-workbench > .welcomeOverlay > .key.notifications { position: absolute; bottom: 25px; diff --git a/src/vs/workbench/parts/welcome/overlay/browser/welcomeOverlay.ts b/src/vs/workbench/parts/welcome/overlay/browser/welcomeOverlay.ts index 8bff80b2110..9fbcb9ac51f 100644 --- a/src/vs/workbench/parts/welcome/overlay/browser/welcomeOverlay.ts +++ b/src/vs/workbench/parts/welcome/overlay/browser/welcomeOverlay.ts @@ -28,7 +28,7 @@ import { Color } from 'vs/base/common/color'; interface Key { id: string; - arrow: string; + arrow?: string; label: string; command?: string; arrowLast?: boolean; @@ -78,6 +78,11 @@ const keys: Key[] = [ label: localize('welcomeOverlay.problems', "View errors and warnings"), command: 'workbench.actions.view.problems' }, + { + id: 'terminal', + label: localize('welcomeOverlay.terminal', "Toggle integrated terminal"), + command: 'workbench.action.terminal.toggleTerminal' + }, // { // id: 'openfile', // arrow: '⤸', @@ -182,7 +187,7 @@ class WelcomeOverlay { keys.filter(key => !('withEditor' in key) || key.withEditor === editorOpen) .forEach(({ id, arrow, label, command, arrowLast }) => { const div = $(this._overlay).div({ 'class': ['key', id] }); - if (!arrowLast) { + if (arrow && !arrowLast) { $(div).span({ 'class': 'arrow' }).innerHtml(arrow); } $(div).span({ 'class': 'label' }).text(label); @@ -192,7 +197,7 @@ class WelcomeOverlay { $(div).span({ 'class': 'shortcut' }).text(shortcut.getLabel()); } } - if (arrowLast) { + if (arrow && arrowLast) { $(div).span({ 'class': 'arrow' }).innerHtml(arrow); } }); From cb29f8f9532d4abe07840957c2e65b1669a957ca Mon Sep 17 00:00:00 2001 From: isidor Date: Fri, 27 Jul 2018 12:20:46 +0200 Subject: [PATCH 0228/1276] uriDisplayService: also create it on the main side and share registration between rendere and main --- src/vs/code/electron-main/app.ts | 8 +++++- src/vs/code/electron-main/main.ts | 3 +++ .../platform/uriDisplay/common/uriDisplay.ts | 13 ++++++++-- .../uriDisplay.contribution.ts | 25 +++++++++++++++++++ src/vs/workbench/workbench.main.ts | 1 + 5 files changed, 47 insertions(+), 3 deletions(-) create mode 100644 src/vs/platform/uriDisplay/electron-browser/uriDisplay.contribution.ts diff --git a/src/vs/code/electron-main/app.ts b/src/vs/code/electron-main/app.ts index e4a0ad09017..1b10a58da57 100644 --- a/src/vs/code/electron-main/app.ts +++ b/src/vs/code/electron-main/app.ts @@ -63,6 +63,7 @@ import { serve as serveDriver } from 'vs/platform/driver/electron-main/driver'; import { IMenubarService } from 'vs/platform/menubar/common/menubar'; import { MenubarService } from 'vs/platform/menubar/electron-main/menubarService'; import { MenubarChannel } from 'vs/platform/menubar/common/menubarIpc'; +import { IUriDisplayService } from 'vs/platform/uriDisplay/common/uriDisplay'; export class CodeApplication { @@ -85,7 +86,8 @@ export class CodeApplication { @ILifecycleService private lifecycleService: ILifecycleService, @IConfigurationService private configurationService: ConfigurationService, @IStateService private stateService: IStateService, - @IHistoryMainService private historyMainService: IHistoryMainService + @IHistoryMainService private historyMainService: IHistoryMainService, + @IUriDisplayService private uriDisplayService: IUriDisplayService ) { this.toDispose = [mainIpcServer, configurationService]; @@ -220,6 +222,10 @@ export class CodeApplication { } }); + ipc.on('vscode:uriDisplayRegisterFormater', (event: any, { scheme, formater }) => { + this.uriDisplayService.registerFormater(scheme, formater); + }); + // Keyboard layout changes KeyboardLayoutMonitor.INSTANCE.onDidChangeKeyboardLayout(() => { if (this.windowsMainService) { diff --git a/src/vs/code/electron-main/main.ts b/src/vs/code/electron-main/main.ts index 134f4379fb3..060c2459c5f 100644 --- a/src/vs/code/electron-main/main.ts +++ b/src/vs/code/electron-main/main.ts @@ -50,6 +50,7 @@ import { uploadLogs } from 'vs/code/electron-main/logUploader'; import { setUnexpectedErrorHandler } from 'vs/base/common/errors'; import { IDialogService } from 'vs/platform/dialogs/common/dialogs'; import { CommandLineDialogService } from 'vs/platform/dialogs/node/dialogService'; +import { IUriDisplayService, UriDisplayService } from 'vs/platform/uriDisplay/common/uriDisplay'; function createServices(args: ParsedArgs, bufferLogService: BufferLogService): IInstantiationService { const services = new ServiceCollection(); @@ -57,6 +58,7 @@ function createServices(args: ParsedArgs, bufferLogService: BufferLogService): I const environmentService = new EnvironmentService(args, process.execPath); const consoleLogService = new ConsoleLogMainService(getLogLevel(environmentService)); const logService = new MultiplexLogService([consoleLogService, bufferLogService]); + const uriDisplayService = new UriDisplayService(environmentService, undefined); process.once('exit', () => logService.dispose()); @@ -64,6 +66,7 @@ function createServices(args: ParsedArgs, bufferLogService: BufferLogService): I setTimeout(() => cleanupOlderLogs(environmentService).then(null, err => console.error(err)), 10000); services.set(IEnvironmentService, environmentService); + services.set(IUriDisplayService, uriDisplayService); services.set(ILogService, logService); services.set(IWorkspacesMainService, new SyncDescriptor(WorkspacesMainService)); services.set(IHistoryMainService, new SyncDescriptor(HistoryMainService)); diff --git a/src/vs/platform/uriDisplay/common/uriDisplay.ts b/src/vs/platform/uriDisplay/common/uriDisplay.ts index e78934fb6de..0a3b55dd4bd 100644 --- a/src/vs/platform/uriDisplay/common/uriDisplay.ts +++ b/src/vs/platform/uriDisplay/common/uriDisplay.ts @@ -5,6 +5,7 @@ import URI from 'vs/base/common/uri'; import { IDisposable } from 'vs/base/common/lifecycle'; +import { Event, Emitter } from 'vs/base/common/event'; import { IEnvironmentService } from 'vs/platform/environment/common/environment'; import { IWorkspaceContextService } from 'vs/platform/workspace/common/workspace'; import { createDecorator } from 'vs/platform/instantiation/common/instantiation'; @@ -17,6 +18,7 @@ export interface IUriDisplayService { _serviceBrand: any; getLabel(resource: URI, relative?: boolean): string; registerFormater(schema: string, formater: UriDisplayRules): IDisposable; + onDidRegisterFormater: Event<{ scheme: string, formater: UriDisplayRules }>; } export interface UriDisplayRules { @@ -37,13 +39,19 @@ function hasDriveLetter(path: string): boolean { export class UriDisplayService implements IUriDisplayService { _serviceBrand: any; - private formaters = new Map(); + private readonly formaters = new Map(); + private readonly _onDidRegisterFormater = new Emitter<{ scheme: string, formater: UriDisplayRules }>(); constructor( @IEnvironmentService private environmentService: IEnvironmentService, @IWorkspaceContextService private contextService: IWorkspaceContextService ) { } + + get onDidRegisterFormater(): Event<{ scheme: string, formater: UriDisplayRules }> { + return this._onDidRegisterFormater.event; + } + getLabel(resource: URI, relative: boolean): string { if (!resource) { return undefined; @@ -54,7 +62,7 @@ export class UriDisplayService implements IUriDisplayService { } if (relative) { - const baseResource = this.contextService.getWorkspaceFolder(resource); + const baseResource = this.contextService && this.contextService.getWorkspaceFolder(resource); if (baseResource) { let relativeLabel: string; if (isEqual(baseResource.uri, resource, !isLinux)) { @@ -79,6 +87,7 @@ export class UriDisplayService implements IUriDisplayService { registerFormater(scheme: string, formater: UriDisplayRules): IDisposable { this.formaters.set(scheme, formater); + this._onDidRegisterFormater.fire({ scheme, formater }); return { dispose: () => this.formaters.delete(scheme) diff --git a/src/vs/platform/uriDisplay/electron-browser/uriDisplay.contribution.ts b/src/vs/platform/uriDisplay/electron-browser/uriDisplay.contribution.ts new file mode 100644 index 00000000000..9637712a2ec --- /dev/null +++ b/src/vs/platform/uriDisplay/electron-browser/uriDisplay.contribution.ts @@ -0,0 +1,25 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import { IWorkbenchContribution, IWorkbenchContributionsRegistry, Extensions as WorkbenchExtensions } from 'vs/workbench/common/contributions'; +import { IUriDisplayService } from 'vs/platform/uriDisplay/common/uriDisplay'; +import { ipcRenderer as ipc } from 'electron'; +import { Registry } from 'vs/platform/registry/common/platform'; +import { LifecyclePhase } from 'vs/platform/lifecycle/common/lifecycle'; + +/** + * Uri display registration needs to be shared from renderer to main. + * Since there will be another instance of the uri display service running on main. + */ +class UriDisplayRegistrationContribution implements IWorkbenchContribution { + + constructor(@IUriDisplayService uriDisplayService: IUriDisplayService) { + uriDisplayService.onDidRegisterFormater(data => { + ipc.send('vscode:uriDisplayRegisterFormater', data); + }); + } +} + +Registry.as(WorkbenchExtensions.Workbench).registerWorkbenchContribution(UriDisplayRegistrationContribution, LifecyclePhase.Starting); diff --git a/src/vs/workbench/workbench.main.ts b/src/vs/workbench/workbench.main.ts index a83b89a74e7..bab2fdcc700 100644 --- a/src/vs/workbench/workbench.main.ts +++ b/src/vs/workbench/workbench.main.ts @@ -17,6 +17,7 @@ import 'vs/editor/editor.all'; // Platform import 'vs/platform/widget/browser/contextScopedHistoryWidget'; +import 'vs/platform/uriDisplay/electron-browser/uriDisplay.contribution'; // Menus/Actions import 'vs/workbench/services/actions/electron-browser/menusExtensionPoint'; From 3f8f272633574308725bbc4b428be63575073038 Mon Sep 17 00:00:00 2001 From: isidor Date: Fri, 27 Jul 2018 12:20:55 +0200 Subject: [PATCH 0229/1276] menubar: adopt uri display service --- src/vs/code/electron-main/menubar.ts | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/vs/code/electron-main/menubar.ts b/src/vs/code/electron-main/menubar.ts index 1cbe2539b44..759c1e7f140 100644 --- a/src/vs/code/electron-main/menubar.ts +++ b/src/vs/code/electron-main/menubar.ts @@ -16,12 +16,13 @@ import { IUpdateService, StateType } from 'vs/platform/update/common/update'; import product from 'vs/platform/node/product'; import { RunOnceScheduler } from 'vs/base/common/async'; import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; -import { mnemonicMenuLabel as baseMnemonicLabel, unmnemonicLabel, getPathLabel } from 'vs/base/common/labels'; +import { mnemonicMenuLabel as baseMnemonicLabel, unmnemonicLabel } from 'vs/base/common/labels'; import { IWindowsMainService, IWindowsCountChangedEvent } from 'vs/platform/windows/electron-main/windows'; import { IHistoryMainService } from 'vs/platform/history/common/history'; import { IWorkspaceIdentifier, getWorkspaceLabel, ISingleFolderWorkspaceIdentifier, isSingleFolderWorkspaceIdentifier, isWorkspaceIdentifier } from 'vs/platform/workspaces/common/workspaces'; import { IMenubarData, IMenubarKeybinding, MenubarMenuItem, isMenubarMenuItemSeparator, isMenubarMenuItemSubmenu, isMenubarMenuItemAction } from 'vs/platform/menubar/common/menubar'; import URI from 'vs/base/common/uri'; +import { IUriDisplayService } from 'vs/platform/uriDisplay/common/uriDisplay'; const telemetryFrom = 'menu'; @@ -46,7 +47,8 @@ export class Menubar { @IWindowsMainService private windowsMainService: IWindowsMainService, @IEnvironmentService private environmentService: IEnvironmentService, @ITelemetryService private telemetryService: ITelemetryService, - @IHistoryMainService private historyMainService: IHistoryMainService + @IHistoryMainService private historyMainService: IHistoryMainService, + @IUriDisplayService private uriDisplayService: IUriDisplayService ) { this.menuUpdater = new RunOnceScheduler(() => this.doUpdateMenu(), 0); @@ -528,8 +530,8 @@ export class Menubar { label = getWorkspaceLabel(workspace, this.environmentService, { verbose: true }); uri = URI.file(workspace.configPath); } else { - label = unmnemonicLabel(getPathLabel(workspace, this.environmentService, null)); uri = URI.file(workspace); + label = unmnemonicLabel(this.uriDisplayService.getLabel(uri)); } return new MenuItem(this.likeAction(commandId, { From 2ba14ee19a00f796d97e674494c6291f15b3500f Mon Sep 17 00:00:00 2001 From: isidor Date: Fri, 27 Jul 2018 12:27:02 +0200 Subject: [PATCH 0230/1276] preferences: use UriDisplayService --- .../services/preferences/browser/preferencesService.ts | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/vs/workbench/services/preferences/browser/preferencesService.ts b/src/vs/workbench/services/preferences/browser/preferencesService.ts index f0c69877821..1c87721d27a 100644 --- a/src/vs/workbench/services/preferences/browser/preferencesService.ts +++ b/src/vs/workbench/services/preferences/browser/preferencesService.ts @@ -7,7 +7,6 @@ import * as network from 'vs/base/common/network'; import { TPromise } from 'vs/base/common/winjs.base'; import * as nls from 'vs/nls'; import URI from 'vs/base/common/uri'; -import * as labels from 'vs/base/common/labels'; import * as strings from 'vs/base/common/strings'; import { Disposable } from 'vs/base/common/lifecycle'; import { Emitter } from 'vs/base/common/event'; @@ -37,6 +36,7 @@ import { INotificationService } from 'vs/platform/notification/common/notificati import { assign } from 'vs/base/common/objects'; import { IEditorService } from 'vs/workbench/services/editor/common/editorService'; import { IEditorGroup, IEditorGroupsService, GroupDirection } from 'vs/workbench/services/group/common/editorGroupsService'; +import { IUriDisplayService } from 'vs/platform/uriDisplay/common/uriDisplay'; const emptyEditableSettingsContent = '{\n}'; @@ -69,7 +69,8 @@ export class PreferencesService extends Disposable implements IPreferencesServic @IKeybindingService keybindingService: IKeybindingService, @IModelService private modelService: IModelService, @IJSONEditingService private jsonEditingService: IJSONEditingService, - @IModeService private modeService: IModeService + @IModeService private modeService: IModeService, + @IUriDisplayService private uriDisplayService: IUriDisplayService ) { super(); // The default keybindings.json updates based on keyboard layouts, so here we make sure @@ -444,7 +445,7 @@ export class PreferencesService extends Disposable implements IPreferencesServic return this.fileService.resolveContent(resource, { acceptTextOnly: true }).then(null, error => { if ((error).fileOperationResult === FileOperationResult.FILE_NOT_FOUND) { return this.fileService.updateContent(resource, contents).then(null, error => { - return TPromise.wrapError(new Error(nls.localize('fail.createSettings', "Unable to create '{0}' ({1}).", labels.getPathLabel(resource, this.environmentService, this.contextService), error))); + return TPromise.wrapError(new Error(nls.localize('fail.createSettings', "Unable to create '{0}' ({1}).", this.uriDisplayService.getLabel(resource, true), error))); }); } From d33df6957ca3b3c1772c957c8e6edda15718d595 Mon Sep 17 00:00:00 2001 From: Johannes Rieken Date: Fri, 27 Jul 2018 12:41:14 +0200 Subject: [PATCH 0231/1276] debt - adopt UriDisplayService for reference search --- .../referenceSearch/referencesController.ts | 12 ++---------- .../contrib/referenceSearch/referencesModel.ts | 18 +----------------- .../referenceSearch/referencesWidget.ts | 15 ++++++++------- .../standaloneReferenceSearch.ts | 14 +------------- .../workbenchReferenceSearch.ts | 18 +++--------------- 5 files changed, 15 insertions(+), 62 deletions(-) diff --git a/src/vs/editor/contrib/referenceSearch/referencesController.ts b/src/vs/editor/contrib/referenceSearch/referencesController.ts index 92dcaddafe9..32b8746b768 100644 --- a/src/vs/editor/contrib/referenceSearch/referencesController.ts +++ b/src/vs/editor/contrib/referenceSearch/referencesController.ts @@ -9,20 +9,16 @@ import { onUnexpectedError } from 'vs/base/common/errors'; import { IDisposable, dispose } from 'vs/base/common/lifecycle'; import { TPromise } from 'vs/base/common/winjs.base'; import { ICodeEditorService } from 'vs/editor/browser/services/codeEditorService'; -import { IInstantiationService, optional } from 'vs/platform/instantiation/common/instantiation'; +import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; import { IContextKey, IContextKeyService, RawContextKey } from 'vs/platform/contextkey/common/contextkey'; import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; -import { IWorkspaceContextService } from 'vs/platform/workspace/common/workspace'; import { IStorageService } from 'vs/platform/storage/common/storage'; import * as editorCommon from 'vs/editor/common/editorCommon'; import { ICodeEditor } from 'vs/editor/browser/editorBrowser'; import { ReferencesModel } from './referencesModel'; import { ReferenceWidget, LayoutData } from './referencesWidget'; import { Range } from 'vs/editor/common/core/range'; -import { ITextModelService } from 'vs/editor/common/services/resolverService'; -import { IThemeService } from 'vs/platform/theme/common/themeService'; import { Position } from 'vs/editor/common/core/position'; -import { IEnvironmentService } from 'vs/platform/environment/common/environment'; import { Location } from 'vs/editor/common/modes'; import { INotificationService } from 'vs/platform/notification/common/notification'; import { CancelablePromise } from 'vs/base/common/async'; @@ -56,14 +52,10 @@ export abstract class ReferencesController implements editorCommon.IEditorContri editor: ICodeEditor, @IContextKeyService contextKeyService: IContextKeyService, @ICodeEditorService private readonly _editorService: ICodeEditorService, - @ITextModelService private readonly _textModelResolverService: ITextModelService, @INotificationService private readonly _notificationService: INotificationService, @IInstantiationService private readonly _instantiationService: IInstantiationService, - @IWorkspaceContextService private readonly _contextService: IWorkspaceContextService, @IStorageService private readonly _storageService: IStorageService, - @IThemeService private readonly _themeService: IThemeService, @IConfigurationService private readonly _configurationService: IConfigurationService, - @optional(IEnvironmentService) private _environmentService: IEnvironmentService ) { this._editor = editor; this._referenceSearchVisible = ctxReferenceSearchVisible.bindTo(contextKeyService); @@ -106,7 +98,7 @@ export abstract class ReferencesController implements editorCommon.IEditorContri })); const storageKey = 'peekViewLayout'; const data = JSON.parse(this._storageService.get(storageKey, undefined, '{}')); - this._widget = new ReferenceWidget(this._editor, this._defaultTreeKeyboardSupport, data, this._textModelResolverService, this._contextService, this._themeService, this._instantiationService, this._environmentService); + this._widget = this._instantiationService.createInstance(ReferenceWidget, this._editor, this._defaultTreeKeyboardSupport, data); this._widget.setTitle(nls.localize('labelLoading', "Loading...")); this._widget.show(range); this._disposables.push(this._widget.onDidClose(() => { diff --git a/src/vs/editor/contrib/referenceSearch/referencesModel.ts b/src/vs/editor/contrib/referenceSearch/referencesModel.ts index 81865714ad8..d27198f8a52 100644 --- a/src/vs/editor/contrib/referenceSearch/referencesModel.ts +++ b/src/vs/editor/contrib/referenceSearch/referencesModel.ts @@ -6,7 +6,7 @@ import { localize } from 'vs/nls'; import { Event, Emitter } from 'vs/base/common/event'; -import { basename, dirname } from 'vs/base/common/paths'; +import { basename } from 'vs/base/common/paths'; import { IDisposable, dispose, IReference } from 'vs/base/common/lifecycle'; import * as strings from 'vs/base/common/strings'; import URI from 'vs/base/common/uri'; @@ -46,14 +46,6 @@ export class OneReference { return this._parent.uri; } - public get name(): string { - return this._parent.name; - } - - public get directory(): string { - return this._parent.directory; - } - public get range(): IRange { return this._range; } @@ -135,14 +127,6 @@ export class FileReferences implements IDisposable { return this._uri; } - public get name(): string { - return basename(this.uri.fsPath); - } - - public get directory(): string { - return dirname(this.uri.fsPath); - } - public get preview(): FilePreview { return this._preview; } diff --git a/src/vs/editor/contrib/referenceSearch/referencesWidget.ts b/src/vs/editor/contrib/referenceSearch/referencesWidget.ts index e4f12351690..efc09da762f 100644 --- a/src/vs/editor/contrib/referenceSearch/referencesWidget.ts +++ b/src/vs/editor/contrib/referenceSearch/referencesWidget.ts @@ -7,7 +7,6 @@ import 'vs/css!./media/referencesWidget'; import * as nls from 'vs/nls'; import { onUnexpectedError } from 'vs/base/common/errors'; -import { getPathLabel } from 'vs/base/common/labels'; import { Event, Emitter } from 'vs/base/common/event'; import { IDisposable, dispose, IReference } from 'vs/base/common/lifecycle'; import { Schemas } from 'vs/base/common/network'; @@ -44,6 +43,9 @@ import { WorkbenchTree, WorkbenchTreeController } from 'vs/platform/list/browser import { RawContextKey } from 'vs/platform/contextkey/common/contextkey'; import { Location } from 'vs/editor/common/modes'; import { ClickBehavior } from 'vs/base/parts/tree/browser/treeDefaults'; +import { IUriDisplayService } from 'vs/platform/uriDisplay/common/uriDisplay'; +import { dirname, basenameOrAuthority } from 'vs/base/common/resources'; + class DecorationsManager implements IDisposable { @@ -530,11 +532,10 @@ export class ReferenceWidget extends PeekViewWidget { editor: ICodeEditor, private _defaultTreeKeyboardSupport: boolean, public layoutData: LayoutData, - private _textModelResolverService: ITextModelService, - private _contextService: IWorkspaceContextService, - themeService: IThemeService, - private _instantiationService: IInstantiationService, - private _environmentService: IEnvironmentService + @IThemeService themeService: IThemeService, + @ITextModelService private _textModelResolverService: ITextModelService, + @IInstantiationService private _instantiationService: IInstantiationService, + @IUriDisplayService private _uriDisplay: IUriDisplayService ) { super(editor, { showFrame: false, showArrow: true, isResizeable: true, isAccessible: true }); @@ -780,7 +781,7 @@ export class ReferenceWidget extends PeekViewWidget { // Update widget header if (reference.uri.scheme !== Schemas.inMemory) { - this.setTitle(reference.name, getPathLabel(reference.directory, this._environmentService, this._contextService)); + this.setTitle(basenameOrAuthority(reference.uri), this._uriDisplay.getLabel(dirname(reference.uri), false)); } else { this.setTitle(nls.localize('peekView.alternateTitle', "References")); } diff --git a/src/vs/editor/standalone/browser/referenceSearch/standaloneReferenceSearch.ts b/src/vs/editor/standalone/browser/referenceSearch/standaloneReferenceSearch.ts index e0b2289a0ef..3259edf4f88 100644 --- a/src/vs/editor/standalone/browser/referenceSearch/standaloneReferenceSearch.ts +++ b/src/vs/editor/standalone/browser/referenceSearch/standaloneReferenceSearch.ts @@ -5,16 +5,12 @@ 'use strict'; import { ICodeEditorService } from 'vs/editor/browser/services/codeEditorService'; -import { IInstantiationService, optional } from 'vs/platform/instantiation/common/instantiation'; +import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; import { IContextKeyService } from 'vs/platform/contextkey/common/contextkey'; import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; -import { IWorkspaceContextService } from 'vs/platform/workspace/common/workspace'; import { IStorageService } from 'vs/platform/storage/common/storage'; import { ICodeEditor } from 'vs/editor/browser/editorBrowser'; import { registerEditorContribution } from 'vs/editor/browser/editorExtensions'; -import { ITextModelService } from 'vs/editor/common/services/resolverService'; -import { IThemeService } from 'vs/platform/theme/common/themeService'; -import { IEnvironmentService } from 'vs/platform/environment/common/environment'; import { INotificationService } from 'vs/platform/notification/common/notification'; import { ReferencesController } from 'vs/editor/contrib/referenceSearch/referencesController'; @@ -24,28 +20,20 @@ export class StandaloneReferencesController extends ReferencesController { editor: ICodeEditor, @IContextKeyService contextKeyService: IContextKeyService, @ICodeEditorService editorService: ICodeEditorService, - @ITextModelService textModelResolverService: ITextModelService, @INotificationService notificationService: INotificationService, @IInstantiationService instantiationService: IInstantiationService, - @IWorkspaceContextService contextService: IWorkspaceContextService, @IStorageService storageService: IStorageService, - @IThemeService themeService: IThemeService, @IConfigurationService configurationService: IConfigurationService, - @optional(IEnvironmentService) environmentService: IEnvironmentService ) { super( true, editor, contextKeyService, editorService, - textModelResolverService, notificationService, instantiationService, - contextService, storageService, - themeService, configurationService, - environmentService ); } } diff --git a/src/vs/workbench/parts/codeEditor/electron-browser/workbenchReferenceSearch.ts b/src/vs/workbench/parts/codeEditor/electron-browser/workbenchReferenceSearch.ts index 3b0d4b2c532..260c669fa73 100644 --- a/src/vs/workbench/parts/codeEditor/electron-browser/workbenchReferenceSearch.ts +++ b/src/vs/workbench/parts/codeEditor/electron-browser/workbenchReferenceSearch.ts @@ -4,16 +4,12 @@ *--------------------------------------------------------------------------------------------*/ 'use strict'; -import { IInstantiationService, optional } from 'vs/platform/instantiation/common/instantiation'; +import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; import { IContextKeyService } from 'vs/platform/contextkey/common/contextkey'; import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; -import { IWorkspaceContextService } from 'vs/platform/workspace/common/workspace'; import { IStorageService } from 'vs/platform/storage/common/storage'; import { ICodeEditor } from 'vs/editor/browser/editorBrowser'; import { registerEditorContribution } from 'vs/editor/browser/editorExtensions'; -import { ITextModelService } from 'vs/editor/common/services/resolverService'; -import { IThemeService } from 'vs/platform/theme/common/themeService'; -import { IEnvironmentService } from 'vs/platform/environment/common/environment'; import { INotificationService } from 'vs/platform/notification/common/notification'; import { ReferencesController } from 'vs/editor/contrib/referenceSearch/referencesController'; import { ICodeEditorService } from 'vs/editor/browser/services/codeEditorService'; @@ -23,29 +19,21 @@ export class WorkbenchReferencesController extends ReferencesController { public constructor( editor: ICodeEditor, @IContextKeyService contextKeyService: IContextKeyService, - @ICodeEditorService codeEditorService: ICodeEditorService, - @ITextModelService textModelResolverService: ITextModelService, + @ICodeEditorService editorService: ICodeEditorService, @INotificationService notificationService: INotificationService, @IInstantiationService instantiationService: IInstantiationService, - @IWorkspaceContextService contextService: IWorkspaceContextService, @IStorageService storageService: IStorageService, - @IThemeService themeService: IThemeService, @IConfigurationService configurationService: IConfigurationService, - @optional(IEnvironmentService) environmentService: IEnvironmentService ) { super( false, editor, contextKeyService, - codeEditorService, - textModelResolverService, + editorService, notificationService, instantiationService, - contextService, storageService, - themeService, configurationService, - environmentService ); } } From c2a1178d6d0c025dbcf212c1206b2bef4ebbfe1c Mon Sep 17 00:00:00 2001 From: isidor Date: Fri, 27 Jul 2018 14:52:28 +0200 Subject: [PATCH 0232/1276] workbench: more adoption of uriDisplayService --- src/vs/base/common/labels.ts | 4 +-- src/vs/code/electron-main/menubar.ts | 4 +-- .../electron-main/historyMainService.ts | 13 ++++---- .../platform/workspaces/common/workspaces.ts | 11 ++++--- .../browser/parts/menubar/menubarPart.ts | 10 +++--- src/vs/workbench/electron-browser/actions.ts | 31 +++++++++++-------- .../workbench/electron-browser/workbench.ts | 4 ++- .../parts/search/browser/openFileHandler.ts | 10 +++--- .../page/electron-browser/welcomePage.ts | 10 +++--- .../node/configurationService.ts | 12 +++++-- 10 files changed, 64 insertions(+), 45 deletions(-) diff --git a/src/vs/base/common/labels.ts b/src/vs/base/common/labels.ts index 15d9a56d269..44d9373ab80 100644 --- a/src/vs/base/common/labels.ts +++ b/src/vs/base/common/labels.ts @@ -23,9 +23,7 @@ export interface IUserHomeProvider { } /** - * @param resource for which to compute the path label - * @param userHomeProvider if a resource has a file schema userHomeProvider is used for tildifiying the label - * @param rootProvider only passed in if the label should be relative to the workspace root + * @deprecated use UriLabelService instead */ export function getPathLabel(resource: URI | string, userHomeProvider: IUserHomeProvider, rootProvider?: IWorkspaceFolderProvider): string { if (!resource) { diff --git a/src/vs/code/electron-main/menubar.ts b/src/vs/code/electron-main/menubar.ts index 759c1e7f140..cb32507e007 100644 --- a/src/vs/code/electron-main/menubar.ts +++ b/src/vs/code/electron-main/menubar.ts @@ -524,10 +524,10 @@ export class Menubar { let label: string; let uri: URI; if (isSingleFolderWorkspaceIdentifier(workspace)) { - label = unmnemonicLabel(getWorkspaceLabel(workspace, this.environmentService, { verbose: true })); + label = unmnemonicLabel(getWorkspaceLabel(workspace, this.environmentService, this.uriDisplayService, { verbose: true })); uri = workspace; } else if (isWorkspaceIdentifier(workspace)) { - label = getWorkspaceLabel(workspace, this.environmentService, { verbose: true }); + label = getWorkspaceLabel(workspace, this.environmentService, this.uriDisplayService, { verbose: true }); uri = URI.file(workspace.configPath); } else { uri = URI.file(workspace); diff --git a/src/vs/platform/history/electron-main/historyMainService.ts b/src/vs/platform/history/electron-main/historyMainService.ts index 92ef9abe5dc..d24cfee31d1 100644 --- a/src/vs/platform/history/electron-main/historyMainService.ts +++ b/src/vs/platform/history/electron-main/historyMainService.ts @@ -5,14 +5,13 @@ 'use strict'; -import * as path from 'path'; import * as nls from 'vs/nls'; import * as arrays from 'vs/base/common/arrays'; import { trim } from 'vs/base/common/strings'; import { IStateService } from 'vs/platform/state/common/state'; import { app } from 'electron'; import { ILogService } from 'vs/platform/log/common/log'; -import { getPathLabel, getBaseLabel } from 'vs/base/common/labels'; +import { getBaseLabel } from 'vs/base/common/labels'; import { IPath } from 'vs/platform/windows/common/windows'; import { Event as CommonEvent, Emitter } from 'vs/base/common/event'; import { isWindows, isMacintosh, isLinux } from 'vs/base/common/platform'; @@ -21,9 +20,10 @@ import { IHistoryMainService, IRecentlyOpened } from 'vs/platform/history/common import { IEnvironmentService } from 'vs/platform/environment/common/environment'; import { isEqual } from 'vs/base/common/paths'; import { RunOnceScheduler } from 'vs/base/common/async'; -import { getComparisonKey, isEqual as areResourcesEqual, hasToIgnoreCase } from 'vs/base/common/resources'; +import { getComparisonKey, isEqual as areResourcesEqual, hasToIgnoreCase, dirname } from 'vs/base/common/resources'; import URI, { UriComponents } from 'vs/base/common/uri'; import { Schemas } from 'vs/base/common/network'; +import { IUriDisplayService } from 'vs/platform/uriDisplay/common/uriDisplay'; interface ISerializedRecentlyOpened { workspaces: (IWorkspaceIdentifier | string | UriComponents)[]; @@ -48,7 +48,8 @@ export class HistoryMainService implements IHistoryMainService { @IStateService private stateService: IStateService, @ILogService private logService: ILogService, @IWorkspacesMainService private workspacesMainService: IWorkspacesMainService, - @IEnvironmentService private environmentService: IEnvironmentService + @IEnvironmentService private environmentService: IEnvironmentService, + @IUriDisplayService private uriDisplayService: IUriDisplayService ) { this.macOSRecentDocumentsUpdater = new RunOnceScheduler(() => this.updateMacOSRecentDocuments(), 800); @@ -308,8 +309,8 @@ export class HistoryMainService implements IHistoryMainService { type: 'custom', name: nls.localize('recentFolders', "Recent Workspaces"), items: this.getRecentlyOpened().workspaces.slice(0, 7 /* limit number of entries here */).map(workspace => { - const title = getWorkspaceLabel(workspace, this.environmentService); - const description = isSingleFolderWorkspaceIdentifier(workspace) ? nls.localize('folderDesc', "{0} {1}", getBaseLabel(workspace), getPathLabel(path.dirname(workspace.path), this.environmentService)) : nls.localize('codeWorkspace', "Code Workspace"); + const title = getWorkspaceLabel(workspace, this.environmentService, this.uriDisplayService); + const description = isSingleFolderWorkspaceIdentifier(workspace) ? nls.localize('folderDesc', "{0} {1}", getBaseLabel(workspace), this.uriDisplayService.getLabel(dirname(workspace))) : nls.localize('codeWorkspace', "Code Workspace"); let args; // use quotes to support paths with whitespaces if (isSingleFolderWorkspaceIdentifier(workspace)) { diff --git a/src/vs/platform/workspaces/common/workspaces.ts b/src/vs/platform/workspaces/common/workspaces.ts index 7bfa4235a63..3c3f6fe8c40 100644 --- a/src/vs/platform/workspaces/common/workspaces.ts +++ b/src/vs/platform/workspaces/common/workspaces.ts @@ -13,10 +13,11 @@ import { basename, dirname, join } from 'vs/base/common/paths'; import { isLinux } from 'vs/base/common/platform'; import { IEnvironmentService } from 'vs/platform/environment/common/environment'; import { Event } from 'vs/base/common/event'; -import { getPathLabel, getBaseLabel } from 'vs/base/common/labels'; +import { getBaseLabel } from 'vs/base/common/labels'; import { IWorkspaceFolder } from 'vs/platform/workspace/common/workspace'; import URI from 'vs/base/common/uri'; import { Schemas } from 'vs/base/common/network'; +import { IUriDisplayService } from 'vs/platform/uriDisplay/common/uriDisplay'; export const IWorkspacesMainService = createDecorator('workspacesMainService'); export const IWorkspacesService = createDecorator('workspacesService'); @@ -112,17 +113,17 @@ export interface IWorkspacesService { createWorkspace(folders?: IWorkspaceFolderCreationData[]): TPromise; } -export function getWorkspaceLabel(workspace: (IWorkspaceIdentifier | ISingleFolderWorkspaceIdentifier), environmentService: IEnvironmentService, options?: { verbose: boolean }): string { +export function getWorkspaceLabel(workspace: (IWorkspaceIdentifier | ISingleFolderWorkspaceIdentifier), environmentService: IEnvironmentService, uriDisplayService: IUriDisplayService, options?: { verbose: boolean }): string { // Workspace: Single Folder if (isSingleFolderWorkspaceIdentifier(workspace)) { // Folder on disk if (workspace.scheme === Schemas.file) { - return options && options.verbose ? getPathLabel(workspace, environmentService) : getBaseLabel(workspace); + return options && options.verbose ? uriDisplayService.getLabel(workspace) : getBaseLabel(workspace); } // Remote folder - return options && options.verbose ? getPathLabel(workspace, environmentService) : `${getBaseLabel(workspace)} (${workspace.scheme})`; + return options && options.verbose ? uriDisplayService.getLabel(workspace) : `${getBaseLabel(workspace)} (${workspace.scheme})`; } // Workspace: Untitled @@ -134,7 +135,7 @@ export function getWorkspaceLabel(workspace: (IWorkspaceIdentifier | ISingleFold const filename = basename(workspace.configPath); const workspaceName = filename.substr(0, filename.length - WORKSPACE_EXTENSION.length - 1); if (options && options.verbose) { - return localize('workspaceNameVerbose', "{0} (Workspace)", getPathLabel(join(dirname(workspace.configPath), workspaceName), environmentService)); + return localize('workspaceNameVerbose', "{0} (Workspace)", uriDisplayService.getLabel(URI.file(join(dirname(workspace.configPath), workspaceName)))); } return localize('workspaceName', "{0} (Workspace)", workspaceName); diff --git a/src/vs/workbench/browser/parts/menubar/menubarPart.ts b/src/vs/workbench/browser/parts/menubar/menubarPart.ts index 10b320cd478..6445a23248b 100644 --- a/src/vs/workbench/browser/parts/menubar/menubarPart.ts +++ b/src/vs/workbench/browser/parts/menubar/menubarPart.ts @@ -35,6 +35,7 @@ import { IEnvironmentService } from 'vs/platform/environment/common/environment' import { RunOnceScheduler } from 'vs/base/common/async'; import { MENUBAR_SELECTION_FOREGROUND, MENUBAR_SELECTION_BACKGROUND, MENUBAR_SELECTION_BORDER, TITLE_BAR_ACTIVE_FOREGROUND, TITLE_BAR_INACTIVE_FOREGROUND, MENU_BACKGROUND, MENU_FOREGROUND, MENU_SELECTION_BACKGROUND, MENU_SELECTION_FOREGROUND, MENU_SELECTION_BORDER } from 'vs/workbench/common/theme'; import URI from 'vs/base/common/uri'; +import { IUriDisplayService } from 'vs/platform/uriDisplay/common/uriDisplay'; interface CustomMenu { title: string; @@ -128,7 +129,8 @@ export class MenubarPart extends Part { @IContextKeyService private contextKeyService: IContextKeyService, @IKeybindingService private keybindingService: IKeybindingService, @IConfigurationService private configurationService: IConfigurationService, - @IEnvironmentService private environmentService: IEnvironmentService + @IEnvironmentService private environmentService: IEnvironmentService, + @IUriDisplayService private uriDisplayService: IUriDisplayService ) { super(id, { hasTitle: false }, themeService); @@ -496,10 +498,10 @@ export class MenubarPart extends Part { let uri: URI; if (isSingleFolderWorkspaceIdentifier(workspace)) { - label = getWorkspaceLabel(workspace, this.environmentService, { verbose: true }); + label = getWorkspaceLabel(workspace, this.environmentService, this.uriDisplayService, { verbose: true }); uri = workspace; } else if (isWorkspaceIdentifier(workspace)) { - label = getWorkspaceLabel(workspace, this.environmentService, { verbose: true }); + label = getWorkspaceLabel(workspace, this.environmentService, this.uriDisplayService, { verbose: true }); uri = URI.file(workspace.configPath); } else { label = getPathLabel(workspace, this.environmentService); @@ -1211,4 +1213,4 @@ class ModifierKeyEmitter extends Emitter { super.dispose(); this._subscriptions = dispose(this._subscriptions); } -} \ No newline at end of file +} diff --git a/src/vs/workbench/electron-browser/actions.ts b/src/vs/workbench/electron-browser/actions.ts index 8bc31bd7219..ee16bc0f5a5 100644 --- a/src/vs/workbench/electron-browser/actions.ts +++ b/src/vs/workbench/electron-browser/actions.ts @@ -33,7 +33,7 @@ import { IViewletService } from 'vs/workbench/services/viewlet/browser/viewlet'; import { IKeybindingService } from 'vs/platform/keybinding/common/keybinding'; import * as os from 'os'; import { webFrame, shell } from 'electron'; -import { getPathLabel, getBaseLabel } from 'vs/base/common/labels'; +import { getBaseLabel } from 'vs/base/common/labels'; import { IViewlet } from 'vs/workbench/common/viewlet'; import { IPanel } from 'vs/workbench/common/panel'; import { IWorkspaceIdentifier, getWorkspaceLabel, ISingleFolderWorkspaceIdentifier, isSingleFolderWorkspaceIdentifier, isWorkspaceIdentifier } from 'vs/platform/workspaces/common/workspaces'; @@ -50,6 +50,8 @@ import { IContextKeyService } from 'vs/platform/contextkey/common/contextkey'; import { Context } from 'vs/platform/contextkey/browser/contextKeyService'; import { IWorkbenchIssueService } from 'vs/workbench/services/issue/common/issue'; import { INotificationService } from 'vs/platform/notification/common/notification'; +import { IUriDisplayService } from 'vs/platform/uriDisplay/common/uriDisplay'; +import { dirname } from 'vs/base/common/resources'; // --- actions @@ -705,6 +707,7 @@ export abstract class BaseOpenRecentAction extends Action { private quickOpenService: IQuickOpenService, private contextService: IWorkspaceContextService, private environmentService: IEnvironmentService, + private uriDisplayService: IUriDisplayService, private keybindingService: IKeybindingService, private instantiationService: IInstantiationService ) { @@ -720,22 +723,22 @@ export abstract class BaseOpenRecentAction extends Action { private openRecent(recentWorkspaces: (IWorkspaceIdentifier | ISingleFolderWorkspaceIdentifier)[], recentFiles: string[]): void { - function toPick(workspace: IWorkspaceIdentifier | ISingleFolderWorkspaceIdentifier | string, separator: ISeparator, fileKind: FileKind, environmentService: IEnvironmentService, action: IAction): IFilePickOpenEntry { + function toPick(workspace: IWorkspaceIdentifier | ISingleFolderWorkspaceIdentifier | string, separator: ISeparator, fileKind: FileKind, environmentService: IEnvironmentService, uriDisplayService: IUriDisplayService, action: IAction): IFilePickOpenEntry { let resource: URI; let label: string; let description: string; if (isSingleFolderWorkspaceIdentifier(workspace)) { resource = workspace; - label = getWorkspaceLabel(workspace, environmentService); - description = getPathLabel(resource.with({ path: paths.dirname(resource.path) }), environmentService); + label = getWorkspaceLabel(workspace, environmentService, uriDisplayService); + description = uriDisplayService.getLabel(resource.with({ path: paths.dirname(resource.path) })); } else if (isWorkspaceIdentifier(workspace)) { resource = URI.file(workspace.configPath); - label = getWorkspaceLabel(workspace, environmentService); - description = getPathLabel(paths.dirname(workspace.configPath), environmentService); + label = getWorkspaceLabel(workspace, environmentService, uriDisplayService); + description = uriDisplayService.getLabel(dirname(resource)); } else { resource = URI.file(workspace); label = getBaseLabel(workspace); - description = getPathLabel(paths.dirname(workspace), environmentService); + description = uriDisplayService.getLabel(dirname(resource)); } return { @@ -760,8 +763,8 @@ export abstract class BaseOpenRecentAction extends Action { this.windowService.openWindow([resource], { forceNewWindow, forceOpenWorkspaceAsFile: isFile }); }; - const workspacePicks: IFilePickOpenEntry[] = recentWorkspaces.map((workspace, index) => toPick(workspace, index === 0 ? { label: nls.localize('workspaces', "workspaces") } : void 0, isSingleFolderWorkspaceIdentifier(workspace) ? FileKind.FOLDER : FileKind.ROOT_FOLDER, this.environmentService, !this.isQuickNavigate() ? this.instantiationService.createInstance(RemoveFromRecentlyOpened, workspace) : void 0)); - const filePicks: IFilePickOpenEntry[] = recentFiles.map((p, index) => toPick(p, index === 0 ? { label: nls.localize('files', "files"), border: true } : void 0, FileKind.FILE, this.environmentService, !this.isQuickNavigate() ? this.instantiationService.createInstance(RemoveFromRecentlyOpened, p) : void 0)); + const workspacePicks: IFilePickOpenEntry[] = recentWorkspaces.map((workspace, index) => toPick(workspace, index === 0 ? { label: nls.localize('workspaces', "workspaces") } : void 0, isSingleFolderWorkspaceIdentifier(workspace) ? FileKind.FOLDER : FileKind.ROOT_FOLDER, this.environmentService, this.uriDisplayService, !this.isQuickNavigate() ? this.instantiationService.createInstance(RemoveFromRecentlyOpened, workspace) : void 0)); + const filePicks: IFilePickOpenEntry[] = recentFiles.map((p, index) => toPick(p, index === 0 ? { label: nls.localize('files', "files"), border: true } : void 0, FileKind.FILE, this.environmentService, this.uriDisplayService, !this.isQuickNavigate() ? this.instantiationService.createInstance(RemoveFromRecentlyOpened, p) : void 0)); // focus second entry if the first recent workspace is the current workspace let autoFocusSecondEntry: boolean = recentWorkspaces[0] && this.contextService.isCurrentWorkspace(recentWorkspaces[0]); @@ -812,9 +815,10 @@ export class OpenRecentAction extends BaseOpenRecentAction { @IWorkspaceContextService contextService: IWorkspaceContextService, @IEnvironmentService environmentService: IEnvironmentService, @IKeybindingService keybindingService: IKeybindingService, - @IInstantiationService instantiationService: IInstantiationService + @IInstantiationService instantiationService: IInstantiationService, + @IUriDisplayService uriDisplayService: IUriDisplayService ) { - super(id, label, windowService, quickOpenService, contextService, environmentService, keybindingService, instantiationService); + super(id, label, windowService, quickOpenService, contextService, environmentService, uriDisplayService, keybindingService, instantiationService); } protected isQuickNavigate(): boolean { @@ -835,9 +839,10 @@ export class QuickOpenRecentAction extends BaseOpenRecentAction { @IWorkspaceContextService contextService: IWorkspaceContextService, @IEnvironmentService environmentService: IEnvironmentService, @IKeybindingService keybindingService: IKeybindingService, - @IInstantiationService instantiationService: IInstantiationService + @IInstantiationService instantiationService: IInstantiationService, + @IUriDisplayService uriDisplayService: IUriDisplayService ) { - super(id, label, windowService, quickOpenService, contextService, environmentService, keybindingService, instantiationService); + super(id, label, windowService, quickOpenService, contextService, environmentService, uriDisplayService, keybindingService, instantiationService); } protected isQuickNavigate(): boolean { diff --git a/src/vs/workbench/electron-browser/workbench.ts b/src/vs/workbench/electron-browser/workbench.ts index 365d20568b8..8aa8bdc1bad 100644 --- a/src/vs/workbench/electron-browser/workbench.ts +++ b/src/vs/workbench/electron-browser/workbench.ts @@ -336,7 +336,9 @@ export class Workbench extends Disposable implements IPartService { serviceCollection.set(IClipboardService, new ClipboardService()); // Uri Display - serviceCollection.set(IUriDisplayService, new UriDisplayService(this.environmentService, this.contextService)); + const uriDisplayService = new UriDisplayService(this.environmentService, this.contextService); + serviceCollection.set(IUriDisplayService, uriDisplayService); + this.configurationService.acquireUriDisplayService(uriDisplayService); // Status bar this.statusbarPart = this.instantiationService.createInstance(StatusbarPart, Identifiers.STATUSBAR_PART); diff --git a/src/vs/workbench/parts/search/browser/openFileHandler.ts b/src/vs/workbench/parts/search/browser/openFileHandler.ts index 179ea2e6ec3..baf0b860cc8 100644 --- a/src/vs/workbench/parts/search/browser/openFileHandler.ts +++ b/src/vs/workbench/parts/search/browser/openFileHandler.ts @@ -8,7 +8,6 @@ import { TPromise } from 'vs/base/common/winjs.base'; import * as errors from 'vs/base/common/errors'; import * as nls from 'vs/nls'; import * as paths from 'vs/base/common/paths'; -import * as labels from 'vs/base/common/labels'; import * as objects from 'vs/base/common/objects'; import { defaultGenerator } from 'vs/base/common/idGenerator'; import URI from 'vs/base/common/uri'; @@ -34,6 +33,8 @@ import { getOutOfWorkspaceEditorResources } from 'vs/workbench/parts/search/comm import { IEditorService } from 'vs/workbench/services/editor/common/editorService'; import { prepareQuery, IPreparedQuery } from 'vs/base/parts/quickopen/common/quickOpenScorer'; import { IFileService } from 'vs/platform/files/common/files'; +import { IUriDisplayService } from 'vs/platform/uriDisplay/common/uriDisplay'; +import { untildify } from 'vs/base/common/labels'; export class FileQuickOpenModel extends QuickOpenModel { @@ -125,7 +126,8 @@ export class OpenFileHandler extends QuickOpenHandler { @IWorkspaceContextService private contextService: IWorkspaceContextService, @ISearchService private searchService: ISearchService, @IEnvironmentService private environmentService: IEnvironmentService, - @IFileService private fileService: IFileService + @IFileService private fileService: IFileService, + @IUriDisplayService private uriDisplayService: IUriDisplayService ) { super(); @@ -145,7 +147,7 @@ export class OpenFileHandler extends QuickOpenHandler { } // Untildify file pattern - query.value = labels.untildify(query.value, this.environmentService.userHome); + query.value = untildify(query.value, this.environmentService.userHome); // Do find results return this.doFindResults(query, this.cacheState.cacheKey, maxSortedResults); @@ -171,7 +173,7 @@ export class OpenFileHandler extends QuickOpenHandler { const fileMatch = complete.results[i]; const label = paths.basename(fileMatch.resource.fsPath); - const description = labels.getPathLabel(resources.dirname(fileMatch.resource), this.environmentService, this.contextService); + const description = this.uriDisplayService.getLabel(resources.dirname(fileMatch.resource), true); results.push(this.instantiationService.createInstance(FileEntry, fileMatch.resource, label, description, iconClass)); } diff --git a/src/vs/workbench/parts/welcome/page/electron-browser/welcomePage.ts b/src/vs/workbench/parts/welcome/page/electron-browser/welcomePage.ts index dff4b7f549b..ad2032a68ca 100644 --- a/src/vs/workbench/parts/welcome/page/electron-browser/welcomePage.ts +++ b/src/vs/workbench/parts/welcome/page/electron-browser/welcomePage.ts @@ -28,7 +28,7 @@ import { IExtensionEnablementService, IExtensionManagementService, IExtensionGal import { used } from 'vs/workbench/parts/welcome/page/electron-browser/vs_code_welcome_page'; import { ILifecycleService, StartupKind } from 'vs/platform/lifecycle/common/lifecycle'; import { IDisposable, dispose } from 'vs/base/common/lifecycle'; -import { tildify, getBaseLabel, getPathLabel } from 'vs/base/common/labels'; +import { tildify, getBaseLabel } from 'vs/base/common/labels'; import { registerThemingParticipant } from 'vs/platform/theme/common/themeService'; import { registerColor, focusBorder, textLinkForeground, textLinkActiveForeground, foreground, descriptionForeground, contrastBorder, activeContrastBorder } from 'vs/platform/theme/common/colorRegistry'; import { getExtraColor } from 'vs/workbench/parts/welcome/walkThrough/node/walkThroughUtils'; @@ -40,6 +40,7 @@ import { getIdAndVersionFromLocalExtensionId } from 'vs/platform/extensionManage import { INotificationService, Severity } from 'vs/platform/notification/common/notification'; import { TimeoutTimer } from 'vs/base/common/async'; import { areSameExtensions } from 'vs/platform/extensionManagement/common/extensionManagementUtil'; +import { IUriDisplayService } from 'vs/platform/uriDisplay/common/uriDisplay'; used(); @@ -225,6 +226,7 @@ class WelcomePage { @IWorkspaceContextService private contextService: IWorkspaceContextService, @IConfigurationService private configurationService: IConfigurationService, @IEnvironmentService private environmentService: IEnvironmentService, + @IUriDisplayService private uriDisplayService: IUriDisplayService, @INotificationService private notificationService: INotificationService, @IExtensionEnablementService private extensionEnablementService: IExtensionEnablementService, @IExtensionGalleryService private extensionGalleryService: IExtensionGalleryService, @@ -281,9 +283,9 @@ class WelcomePage { let resource: URI; if (isSingleFolderWorkspaceIdentifier(workspace)) { resource = workspace; - label = getWorkspaceLabel(workspace, this.environmentService); + label = getWorkspaceLabel(workspace, this.environmentService, this.uriDisplayService); } else if (isWorkspaceIdentifier(workspace)) { - label = getWorkspaceLabel(workspace, this.environmentService); + label = getWorkspaceLabel(workspace, this.environmentService, this.uriDisplayService); resource = URI.file(workspace.configPath); } else { label = getBaseLabel(workspace); @@ -305,7 +307,7 @@ class WelcomePage { } parentFolderPath = tildify(parentFolder, this.environmentService.userHome); } else { - parentFolderPath = getPathLabel(resource, this.environmentService); + parentFolderPath = this.uriDisplayService.getLabel(resource); } diff --git a/src/vs/workbench/services/configuration/node/configurationService.ts b/src/vs/workbench/services/configuration/node/configurationService.ts index b21ed903322..02320795944 100644 --- a/src/vs/workbench/services/configuration/node/configurationService.ts +++ b/src/vs/workbench/services/configuration/node/configurationService.ts @@ -41,6 +41,7 @@ import { UserConfiguration } from 'vs/platform/configuration/node/configuration' import { IJSONSchema, IJSONSchemaMap } from 'vs/base/common/jsonSchema'; import { localize } from 'vs/nls'; import { isEqual, hasToIgnoreCase } from 'vs/base/common/resources'; +import { IUriDisplayService } from 'vs/platform/uriDisplay/common/uriDisplay'; export class WorkspaceService extends Disposable implements IWorkspaceConfigurationService, IWorkspaceContextService { @@ -68,6 +69,7 @@ export class WorkspaceService extends Disposable implements IWorkspaceConfigurat public readonly onDidChangeWorkbenchState: Event = this._onDidChangeWorkbenchState.event; private fileService: IFileService; + private uriDisplayService: IUriDisplayService; private configurationEditingService: ConfigurationEditingService; private jsonEditingService: JSONEditingService; @@ -317,6 +319,10 @@ export class WorkspaceService extends Disposable implements IWorkspaceConfigurat }); } + acquireUriDisplayService(uriDisplayService: IUriDisplayService): void { + this.uriDisplayService = uriDisplayService; + } + acquireInstantiationService(instantiationService: IInstantiationService): void { this.configurationEditingService = instantiationService.createInstance(ConfigurationEditingService); this.jsonEditingService = instantiationService.createInstance(JSONEditingService); @@ -340,7 +346,7 @@ export class WorkspaceService extends Disposable implements IWorkspaceConfigurat .then(() => { const workspaceFolders = toWorkspaceFolders(this.workspaceConfiguration.getFolders(), URI.file(dirname(workspaceConfigPath.fsPath))); const workspaceId = workspaceIdentifier.id; - const workspaceName = getWorkspaceLabel({ id: workspaceId, configPath: workspaceConfigPath.fsPath }, this.environmentService); + const workspaceName = getWorkspaceLabel({ id: workspaceId, configPath: workspaceConfigPath.fsPath }, this.environmentService, this.uriDisplayService); return new Workspace(workspaceId, workspaceName, workspaceFolders, workspaceConfigPath); }); } @@ -363,11 +369,11 @@ export class WorkspaceService extends Disposable implements IWorkspaceConfigurat } const id = createHash('md5').update(folder.fsPath).update(ctime ? String(ctime) : '').digest('hex'); - return new Workspace(id, getWorkspaceLabel(folder, this.environmentService), toWorkspaceFolders([{ path: folder.fsPath }]), null, ctime); + return new Workspace(id, getWorkspaceLabel(folder, this.environmentService, this.uriDisplayService), toWorkspaceFolders([{ path: folder.fsPath }]), null, ctime); }); } else { const id = createHash('md5').update(folder.toString()).digest('hex'); - return TPromise.as(new Workspace(id, getWorkspaceLabel(folder, this.environmentService), toWorkspaceFolders([{ uri: folder.toString() }]), null)); + return TPromise.as(new Workspace(id, getWorkspaceLabel(folder, this.environmentService, this.uriDisplayService), toWorkspaceFolders([{ uri: folder.toString() }]), null)); } } From 15411fdcb2dcc625a364e28d15f0f193d10897b5 Mon Sep 17 00:00:00 2001 From: Johannes Rieken Date: Fri, 27 Jul 2018 14:55:36 +0200 Subject: [PATCH 0233/1276] fix #54769 --- .../parts/markers/electron-browser/markersFileDecorations.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vs/workbench/parts/markers/electron-browser/markersFileDecorations.ts b/src/vs/workbench/parts/markers/electron-browser/markersFileDecorations.ts index 5f5b3ba56df..5338f344e90 100644 --- a/src/vs/workbench/parts/markers/electron-browser/markersFileDecorations.ts +++ b/src/vs/workbench/parts/markers/electron-browser/markersFileDecorations.ts @@ -49,7 +49,7 @@ class MarkersDecorationsProvider implements IDecorationsProvider { weight: 100 * first.severity, bubble: true, tooltip: markers.length === 1 ? localize('tooltip.1', "1 problem in this file") : localize('tooltip.N', "{0} problems in this file", markers.length), - letter: markers.length < 10 ? markers.length.toString() : '+9', + letter: markers.length < 10 ? markers.length.toString() : '9+', color: first.severity === MarkerSeverity.Error ? listErrorForeground : listWarningForeground, }; } From de45a1a65919d97e63ae8e720924b311677bb82c Mon Sep 17 00:00:00 2001 From: isidor Date: Fri, 27 Jul 2018 15:02:15 +0200 Subject: [PATCH 0234/1276] workbench: uri display service adoption --- .../browser/parts/menubar/menubarPart.ts | 3 +-- .../browser/parts/titlebar/titlebarPart.ts | 16 +++++++++------- .../electron-browser/localizationsActions.ts | 9 ++++----- .../electron-browser/markersTreeViewer.ts | 16 ++++++---------- .../parts/search/browser/openSymbolHandler.ts | 9 +++------ 5 files changed, 23 insertions(+), 30 deletions(-) diff --git a/src/vs/workbench/browser/parts/menubar/menubarPart.ts b/src/vs/workbench/browser/parts/menubar/menubarPart.ts index 6445a23248b..1e27cf6f9f3 100644 --- a/src/vs/workbench/browser/parts/menubar/menubarPart.ts +++ b/src/vs/workbench/browser/parts/menubar/menubarPart.ts @@ -30,7 +30,6 @@ import { IDisposable, dispose } from 'vs/base/common/lifecycle'; import { domEvent } from 'vs/base/browser/event'; import { IRecentlyOpened } from 'vs/platform/history/common/history'; import { IWorkspaceIdentifier, getWorkspaceLabel, ISingleFolderWorkspaceIdentifier, isSingleFolderWorkspaceIdentifier, isWorkspaceIdentifier } from 'vs/platform/workspaces/common/workspaces'; -import { getPathLabel } from 'vs/base/common/labels'; import { IEnvironmentService } from 'vs/platform/environment/common/environment'; import { RunOnceScheduler } from 'vs/base/common/async'; import { MENUBAR_SELECTION_FOREGROUND, MENUBAR_SELECTION_BACKGROUND, MENUBAR_SELECTION_BORDER, TITLE_BAR_ACTIVE_FOREGROUND, TITLE_BAR_INACTIVE_FOREGROUND, MENU_BACKGROUND, MENU_FOREGROUND, MENU_SELECTION_BACKGROUND, MENU_SELECTION_FOREGROUND, MENU_SELECTION_BORDER } from 'vs/workbench/common/theme'; @@ -504,8 +503,8 @@ export class MenubarPart extends Part { label = getWorkspaceLabel(workspace, this.environmentService, this.uriDisplayService, { verbose: true }); uri = URI.file(workspace.configPath); } else { - label = getPathLabel(workspace, this.environmentService); uri = URI.file(workspace); + label = this.uriDisplayService.getLabel(uri); } return new Action(commandId, label, undefined, undefined, (event) => { diff --git a/src/vs/workbench/browser/parts/titlebar/titlebarPart.ts b/src/vs/workbench/browser/parts/titlebar/titlebarPart.ts index 6188f621f55..132fe7f1091 100644 --- a/src/vs/workbench/browser/parts/titlebar/titlebarPart.ts +++ b/src/vs/workbench/browser/parts/titlebar/titlebarPart.ts @@ -21,7 +21,6 @@ import { IConfigurationService, IConfigurationChangeEvent } from 'vs/platform/co import { IEditorService } from 'vs/workbench/services/editor/common/editorService'; import { IDisposable, dispose } from 'vs/base/common/lifecycle'; import * as nls from 'vs/nls'; -import * as labels from 'vs/base/common/labels'; import { EditorInput, toResource, Verbosity } from 'vs/workbench/common/editor'; import { IEnvironmentService } from 'vs/platform/environment/common/environment'; import { IWorkspaceContextService, WorkbenchState } from 'vs/platform/workspace/common/workspace'; @@ -33,6 +32,8 @@ import { Color } from 'vs/base/common/color'; import { trim } from 'vs/base/common/strings'; import { addDisposableListener, EventType, EventHelper, Dimension } from 'vs/base/browser/dom'; import { IPartService } from 'vs/workbench/services/part/common/partService'; +import { template, getBaseLabel } from 'vs/base/common/labels'; +import { IUriDisplayService } from 'vs/platform/uriDisplay/common/uriDisplay'; export class TitlebarPart extends Part implements ITitleService { @@ -78,7 +79,8 @@ export class TitlebarPart extends Part implements ITitleService { @IEnvironmentService private environmentService: IEnvironmentService, @IWorkspaceContextService private contextService: IWorkspaceContextService, @IPartService private partService: IPartService, - @IThemeService themeService: IThemeService + @IThemeService themeService: IThemeService, + @IUriDisplayService private uriDisplayService: IUriDisplayService ) { super(id, { hasTitle: false }, themeService); @@ -226,15 +228,15 @@ export class TitlebarPart extends Part implements ITitleService { const activeEditorMedium = editor ? editor.getTitle(Verbosity.MEDIUM) : activeEditorShort; const activeEditorLong = editor ? editor.getTitle(Verbosity.LONG) : activeEditorMedium; const rootName = workspace.name; - const rootPath = root ? labels.getPathLabel(root, this.environmentService) : ''; + const rootPath = root ? this.uriDisplayService.getLabel(root) : ''; const folderName = folder ? folder.name : ''; - const folderPath = folder ? labels.getPathLabel(folder.uri, this.environmentService) : ''; + const folderPath = folder ? this.uriDisplayService.getLabel(folder.uri) : ''; const dirty = editor && editor.isDirty() ? TitlebarPart.TITLE_DIRTY : ''; const appName = this.environmentService.appNameLong; const separator = TitlebarPart.TITLE_SEPARATOR; const titleTemplate = this.configurationService.getValue('window.title'); - return labels.template(titleTemplate, { + return template(titleTemplate, { activeEditorShort, activeEditorLong, activeEditorMedium, @@ -411,9 +413,9 @@ export class TitlebarPart extends Part implements ITitleService { let label: string; if (!isFile) { - label = labels.getBaseLabel(paths.dirname(path)); + label = getBaseLabel(paths.dirname(path)); } else { - label = labels.getBaseLabel(path); + label = getBaseLabel(path); } actions.push(new ShowItemInFolderAction(path, label || paths.sep, this.windowsService)); diff --git a/src/vs/workbench/parts/localizations/electron-browser/localizationsActions.ts b/src/vs/workbench/parts/localizations/electron-browser/localizationsActions.ts index 7d22c8fc3a6..2290be2e5d0 100644 --- a/src/vs/workbench/parts/localizations/electron-browser/localizationsActions.ts +++ b/src/vs/workbench/parts/localizations/electron-browser/localizationsActions.ts @@ -6,15 +6,14 @@ import { localize } from 'vs/nls'; import { Action } from 'vs/base/common/actions'; import { IFileService } from 'vs/platform/files/common/files'; -import { IWorkspaceContextService } from 'vs/platform/workspace/common/workspace'; import { IEnvironmentService } from 'vs/platform/environment/common/environment'; import { TPromise } from 'vs/base/common/winjs.base'; import { IEditor } from 'vs/workbench/common/editor'; import { join } from 'vs/base/common/paths'; import URI from 'vs/base/common/uri'; import { IEditorService } from 'vs/workbench/services/editor/common/editorService'; -import { getPathLabel } from 'vs/base/common/labels'; import { language } from 'vs/base/common/platform'; +import { IUriDisplayService } from 'vs/platform/uriDisplay/common/uriDisplay'; export class ConfigureLocaleAction extends Action { public static readonly ID = 'workbench.action.configureLocale'; @@ -31,9 +30,9 @@ export class ConfigureLocaleAction extends Action { constructor(id: string, label: string, @IFileService private fileService: IFileService, - @IWorkspaceContextService private contextService: IWorkspaceContextService, @IEnvironmentService private environmentService: IEnvironmentService, - @IEditorService private editorService: IEditorService + @IEditorService private editorService: IEditorService, + @IUriDisplayService private uriDisplayService: IUriDisplayService ) { super(id, label); } @@ -50,7 +49,7 @@ export class ConfigureLocaleAction extends Action { resource: stat.resource }); }, (error) => { - throw new Error(localize('fail.createSettings', "Unable to create '{0}' ({1}).", getPathLabel(file, this.environmentService, this.contextService), error)); + throw new Error(localize('fail.createSettings', "Unable to create '{0}' ({1}).", this.uriDisplayService.getLabel(file, true), error)); }); } } diff --git a/src/vs/workbench/parts/markers/electron-browser/markersTreeViewer.ts b/src/vs/workbench/parts/markers/electron-browser/markersTreeViewer.ts index fa7cc47b431..133884c00dd 100644 --- a/src/vs/workbench/parts/markers/electron-browser/markersTreeViewer.ts +++ b/src/vs/workbench/parts/markers/electron-browser/markersTreeViewer.ts @@ -19,11 +19,9 @@ import { IInstantiationService } from 'vs/platform/instantiation/common/instanti import { attachBadgeStyler } from 'vs/platform/theme/common/styler'; import { IThemeService } from 'vs/platform/theme/common/themeService'; import { IDisposable } from 'vs/base/common/lifecycle'; -import { getPathLabel } from 'vs/base/common/labels'; -import { IEnvironmentService } from 'vs/platform/environment/common/environment'; -import { IWorkspaceContextService } from 'vs/platform/workspace/common/workspace'; import { ActionBar, IActionItemProvider } from 'vs/base/browser/ui/actionbar/actionbar'; import { QuickFixAction } from 'vs/workbench/parts/markers/electron-browser/markersPanelActions'; +import { IUriDisplayService } from 'vs/platform/uriDisplay/common/uriDisplay'; interface IResourceMarkersTemplateData { resourceLabel: ResourceLabel; @@ -101,8 +99,7 @@ export class Renderer implements IRenderer { private actionItemProvider: IActionItemProvider, @IInstantiationService private instantiationService: IInstantiationService, @IThemeService private themeService: IThemeService, - @IEnvironmentService private environmentService: IEnvironmentService, - @IWorkspaceContextService private contextService: IWorkspaceContextService + @IUriDisplayService private uriDisplayService: IUriDisplayService ) { } @@ -211,7 +208,7 @@ export class Renderer implements IRenderer { if (templateData.resourceLabel instanceof FileLabel) { templateData.resourceLabel.setFile(element.uri, { matches: element.uriMatches }); } else { - templateData.resourceLabel.setLabel({ name: element.name, description: getPathLabel(element.uri, this.environmentService, this.contextService), resource: element.uri }, { matches: element.uriMatches }); + templateData.resourceLabel.setLabel({ name: element.name, description: this.uriDisplayService.getLabel(element.uri, true), resource: element.uri }, { matches: element.uriMatches }); } (templateData).count.setCount(element.filteredCount); } @@ -238,7 +235,7 @@ export class Renderer implements IRenderer { private renderRelatedInfoElement(tree: ITree, element: RelatedInformation, templateData: IRelatedInformationTemplateData) { templateData.resourceLabel.set(paths.basename(element.raw.resource.fsPath), element.uriMatches); - templateData.resourceLabel.element.title = getPathLabel(element.raw.resource, this.environmentService, this.contextService); + templateData.resourceLabel.element.title = this.uriDisplayService.getLabel(element.raw.resource, true); templateData.lnCol.textContent = Messages.MARKERS_PANEL_AT_LINE_COL_NUMBER(element.raw.startLineNumber, element.raw.startColumn); templateData.description.set(element.raw.message, element.messageMatches); templateData.description.element.title = element.raw.message; @@ -275,14 +272,13 @@ export class Renderer implements IRenderer { export class MarkersTreeAccessibilityProvider implements IAccessibilityProvider { constructor( - @IWorkspaceContextService private contextService: IWorkspaceContextService, - @IEnvironmentService private environmentService: IEnvironmentService + @IUriDisplayService private uriDisplayServie: IUriDisplayService ) { } public getAriaLabel(tree: ITree, element: any): string { if (element instanceof ResourceMarkers) { - const path = getPathLabel(element.uri, this.environmentService, this.contextService) || element.uri.fsPath; + const path = this.uriDisplayServie.getLabel(element.uri, true) || element.uri.fsPath; return Messages.MARKERS_TREE_ARIA_LABEL_RESOURCE(element.filteredCount, element.name, paths.dirname(path)); } if (element instanceof Marker) { diff --git a/src/vs/workbench/parts/search/browser/openSymbolHandler.ts b/src/vs/workbench/parts/search/browser/openSymbolHandler.ts index 8882abb8fc5..17472a73e75 100644 --- a/src/vs/workbench/parts/search/browser/openSymbolHandler.ts +++ b/src/vs/workbench/parts/search/browser/openSymbolHandler.ts @@ -16,16 +16,14 @@ import * as filters from 'vs/base/common/filters'; import * as strings from 'vs/base/common/strings'; import { Range } from 'vs/editor/common/core/range'; import { EditorInput, IWorkbenchEditorConfiguration } from 'vs/workbench/common/editor'; -import * as labels from 'vs/base/common/labels'; import { symbolKindToCssClass } from 'vs/editor/common/modes'; import { IResourceInput } from 'vs/platform/editor/common/editor'; import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; -import { IWorkspaceContextService } from 'vs/platform/workspace/common/workspace'; import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; import { IWorkspaceSymbolProvider, getWorkspaceSymbols, IWorkspaceSymbol } from 'vs/workbench/parts/search/common/search'; -import { IEnvironmentService } from 'vs/platform/environment/common/environment'; import { basename } from 'vs/base/common/paths'; import { IEditorService } from 'vs/workbench/services/editor/common/editorService'; +import { IUriDisplayService } from 'vs/platform/uriDisplay/common/uriDisplay'; class SymbolEntry extends EditorQuickOpenEntry { @@ -35,9 +33,8 @@ class SymbolEntry extends EditorQuickOpenEntry { private _bearing: IWorkspaceSymbol, private _provider: IWorkspaceSymbolProvider, @IConfigurationService private readonly _configurationService: IConfigurationService, - @IWorkspaceContextService private readonly _contextService: IWorkspaceContextService, @IEditorService editorService: IEditorService, - @IEnvironmentService private readonly _environmentService: IEnvironmentService + @IUriDisplayService private _uriDisplayService: IUriDisplayService ) { super(editorService); } @@ -56,7 +53,7 @@ class SymbolEntry extends EditorQuickOpenEntry { if (containerName) { return `${containerName} — ${basename(this._bearing.location.uri.fsPath)}`; } else { - return labels.getPathLabel(this._bearing.location.uri, this._environmentService, this._contextService); + return this._uriDisplayService.getLabel(this._bearing.location.uri, true); } } return containerName; From b07b57d9119030ca50ff55f816674e3addc448b7 Mon Sep 17 00:00:00 2001 From: isidor Date: Fri, 27 Jul 2018 15:23:21 +0200 Subject: [PATCH 0235/1276] workbench: uriDisplayService adoption --- .../parts/search/browser/searchResultsView.ts | 8 +++----- .../bulkEdit/electron-browser/bulkEditService.ts | 14 +++++--------- .../electron-browser/api/mainThreadEditors.test.ts | 3 ++- 3 files changed, 10 insertions(+), 15 deletions(-) diff --git a/src/vs/workbench/parts/search/browser/searchResultsView.ts b/src/vs/workbench/parts/search/browser/searchResultsView.ts index a401c67d8ac..7424cdc338d 100644 --- a/src/vs/workbench/parts/search/browser/searchResultsView.ts +++ b/src/vs/workbench/parts/search/browser/searchResultsView.ts @@ -21,14 +21,13 @@ import { RemoveAction, ReplaceAllAction, ReplaceAction, ReplaceAllInFolderAction import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; import { attachBadgeStyler } from 'vs/platform/theme/common/styler'; import { IThemeService } from 'vs/platform/theme/common/themeService'; -import { getPathLabel } from 'vs/base/common/labels'; import { FileKind } from 'vs/platform/files/common/files'; import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; import { IContextMenuService } from 'vs/platform/contextview/browser/contextView'; import { IMenuService, MenuId, IMenu } from 'vs/platform/actions/common/actions'; import { WorkbenchTreeController, WorkbenchTree } from 'vs/platform/list/browser/listService'; import { fillInContextMenuActions } from 'vs/platform/actions/browser/menuItemActionItem'; -import { IEnvironmentService } from 'vs/platform/environment/common/environment'; +import { IUriDisplayService } from 'vs/platform/uriDisplay/common/uriDisplay'; export class SearchDataSource implements IDataSource { @@ -321,8 +320,7 @@ export class SearchRenderer extends Disposable implements IRenderer { export class SearchAccessibilityProvider implements IAccessibilityProvider { constructor( - @IWorkspaceContextService private contextService: IWorkspaceContextService, - @IEnvironmentService private environmentService: IEnvironmentService + @IUriDisplayService private uriDisplayService: IUriDisplayService ) { } @@ -332,7 +330,7 @@ export class SearchAccessibilityProvider implements IAccessibilityProvider { } if (element instanceof FileMatch) { - const path = getPathLabel(element.resource(), this.environmentService, this.contextService) || element.resource().fsPath; + const path = this.uriDisplayService.getLabel(element.resource(), true) || element.resource().fsPath; return nls.localize('fileMatchAriaLabel', "{0} matches in file {1} of folder {2}, Search result", element.count(), element.name(), paths.dirname(path)); } diff --git a/src/vs/workbench/services/bulkEdit/electron-browser/bulkEditService.ts b/src/vs/workbench/services/bulkEdit/electron-browser/bulkEditService.ts index dd3d391644c..7fb340f111a 100644 --- a/src/vs/workbench/services/bulkEdit/electron-browser/bulkEditService.ts +++ b/src/vs/workbench/services/bulkEdit/electron-browser/bulkEditService.ts @@ -6,7 +6,6 @@ import { mergeSort } from 'vs/base/common/arrays'; -import { getPathLabel } from 'vs/base/common/labels'; import { dispose, IDisposable, IReference } from 'vs/base/common/lifecycle'; import URI from 'vs/base/common/uri'; import { TPromise } from 'vs/base/common/winjs.base'; @@ -19,14 +18,13 @@ import { isResourceFileEdit, isResourceTextEdit, ResourceFileEdit, ResourceTextE import { IModelService } from 'vs/editor/common/services/modelService'; import { ITextEditorModel, ITextModelService } from 'vs/editor/common/services/resolverService'; import { localize } from 'vs/nls'; -import { IEnvironmentService } from 'vs/platform/environment/common/environment'; import { IFileService } from 'vs/platform/files/common/files'; import { registerSingleton } from 'vs/platform/instantiation/common/extensions'; import { ILogService } from 'vs/platform/log/common/log'; import { emptyProgressRunner, IProgress, IProgressRunner } from 'vs/platform/progress/common/progress'; -import { IWorkspaceContextService } from 'vs/platform/workspace/common/workspace'; import { IEditorService } from 'vs/workbench/services/editor/common/editorService'; import { ITextFileService } from 'vs/workbench/services/textfile/common/textfiles'; +import { IUriDisplayService } from 'vs/platform/uriDisplay/common/uriDisplay'; abstract class Recording { @@ -235,8 +233,7 @@ export class BulkEdit { @ITextModelService private readonly _textModelService: ITextModelService, @IFileService private readonly _fileService: IFileService, @ITextFileService private readonly _textFileService: ITextFileService, - @IEnvironmentService private readonly _environmentService: IEnvironmentService, - @IWorkspaceContextService private readonly _contextService: IWorkspaceContextService + @IUriDisplayService private readonly _uriDisplayServie: IUriDisplayService ) { this._editor = editor; this._progress = progress || emptyProgressRunner; @@ -342,7 +339,7 @@ export class BulkEdit { const conflicts = edits .filter(edit => recording.hasChanged(edit.resource)) - .map(edit => getPathLabel(edit.resource, this._environmentService, this._contextService)); + .map(edit => this._uriDisplayServie.getLabel(edit.resource, true)); recording.stop(); @@ -372,8 +369,7 @@ export class BulkEditService implements IBulkEditService { @ITextModelService private readonly _textModelService: ITextModelService, @IFileService private readonly _fileService: IFileService, @ITextFileService private readonly _textFileService: ITextFileService, - @IEnvironmentService private readonly _environmentService: IEnvironmentService, - @IWorkspaceContextService private readonly _contextService: IWorkspaceContextService + @IUriDisplayService private readonly _uriDisplayService: IUriDisplayService ) { } @@ -404,7 +400,7 @@ export class BulkEditService implements IBulkEditService { } } - const bulkEdit = new BulkEdit(options.editor, options.progress, this._logService, this._textModelService, this._fileService, this._textFileService, this._environmentService, this._contextService); + const bulkEdit = new BulkEdit(options.editor, options.progress, this._logService, this._textModelService, this._fileService, this._textFileService, this._uriDisplayService); bulkEdit.add(edits); return TPromise.wrap(bulkEdit.perform().then(() => { diff --git a/src/vs/workbench/test/electron-browser/api/mainThreadEditors.test.ts b/src/vs/workbench/test/electron-browser/api/mainThreadEditors.test.ts index fdb4b5575c3..b9728fac684 100644 --- a/src/vs/workbench/test/electron-browser/api/mainThreadEditors.test.ts +++ b/src/vs/workbench/test/electron-browser/api/mainThreadEditors.test.ts @@ -28,6 +28,7 @@ import { BulkEditService } from 'vs/workbench/services/bulkEdit/electron-browser import { NullLogService } from 'vs/platform/log/common/log'; import { ITextModelService, ITextEditorModel } from 'vs/editor/common/services/resolverService'; import { IReference, ImmortalReference } from 'vs/base/common/lifecycle'; +import { UriDisplayService } from 'vs/platform/uriDisplay/common/uriDisplay'; suite('MainThreadEditors', () => { @@ -82,7 +83,7 @@ suite('MainThreadEditors', () => { } }; - const bulkEditService = new BulkEditService(new NullLogService(), modelService, new TestEditorService(), textModelService, new TestFileService(), textFileService, TestEnvironmentService, new TestContextService()); + const bulkEditService = new BulkEditService(new NullLogService(), modelService, new TestEditorService(), textModelService, new TestFileService(), textFileService, new UriDisplayService(TestEnvironmentService, new TestContextService())); const rpcProtocol = new TestRPCProtocol(); rpcProtocol.set(ExtHostContext.ExtHostDocuments, new class extends mock() { From b6d1fd2d735d7d81e23d8bfa70f44850b2bb8e2f Mon Sep 17 00:00:00 2001 From: isidor Date: Fri, 27 Jul 2018 15:46:50 +0200 Subject: [PATCH 0236/1276] workbench: adopt uriDisplayService --- .../browser/actions/workspaceCommands.ts | 9 +++--- src/vs/workbench/browser/labels.ts | 30 +++++-------------- .../parts/search/browser/searchResultsView.ts | 4 +-- .../workbench/test/workbenchTestServices.ts | 5 +++- 4 files changed, 18 insertions(+), 30 deletions(-) diff --git a/src/vs/workbench/browser/actions/workspaceCommands.ts b/src/vs/workbench/browser/actions/workspaceCommands.ts index a473438cb5a..9ead6f9f1fb 100644 --- a/src/vs/workbench/browser/actions/workspaceCommands.ts +++ b/src/vs/workbench/browser/actions/workspaceCommands.ts @@ -16,13 +16,14 @@ import { IViewletService } from 'vs/workbench/services/viewlet/browser/viewlet'; import { dirname } from 'vs/base/common/paths'; import { IQuickOpenService, IFilePickOpenEntry, IPickOptions } from 'vs/platform/quickOpen/common/quickOpen'; import { CancellationToken } from 'vs/base/common/cancellation'; -import { mnemonicButtonLabel, getPathLabel } from 'vs/base/common/labels'; +import { mnemonicButtonLabel } from 'vs/base/common/labels'; import { CommandsRegistry } from 'vs/platform/commands/common/commands'; import { IHistoryService } from 'vs/workbench/services/history/common/history'; import { FileKind, isParent } from 'vs/platform/files/common/files'; import { IEnvironmentService } from 'vs/platform/environment/common/environment'; import { ServicesAccessor } from 'vs/platform/instantiation/common/instantiation'; import { isLinux } from 'vs/base/common/platform'; +import { IUriDisplayService } from 'vs/platform/uriDisplay/common/uriDisplay'; export const ADD_ROOT_FOLDER_COMMAND_ID = 'addRootFolder'; export const ADD_ROOT_FOLDER_LABEL = nls.localize('addFolderToWorkspace', "Add Folder to Workspace..."); @@ -158,9 +159,9 @@ CommandsRegistry.registerCommand({ }); CommandsRegistry.registerCommand(PICK_WORKSPACE_FOLDER_COMMAND_ID, function (accessor, args?: [IPickOptions, CancellationToken]) { - const contextService = accessor.get(IWorkspaceContextService); const quickOpenService = accessor.get(IQuickOpenService); - const environmentService = accessor.get(IEnvironmentService); + const uriDisplayService = accessor.get(IUriDisplayService); + const contextService = accessor.get(IWorkspaceContextService); const folders = contextService.getWorkspace().folders; if (!folders.length) { @@ -170,7 +171,7 @@ CommandsRegistry.registerCommand(PICK_WORKSPACE_FOLDER_COMMAND_ID, function (acc const folderPicks = folders.map(folder => { return { label: folder.name, - description: getPathLabel(resources.dirname(folder.uri), environmentService, contextService), + description: uriDisplayService.getLabel(resources.dirname(folder.uri), true), folder, resource: folder.uri, fileKind: FileKind.ROOT_FOLDER diff --git a/src/vs/workbench/browser/labels.ts b/src/vs/workbench/browser/labels.ts index 2de5aa211ec..7357d3a8b6b 100644 --- a/src/vs/workbench/browser/labels.ts +++ b/src/vs/workbench/browser/labels.ts @@ -11,12 +11,10 @@ import { IconLabel, IIconLabelValueOptions, IIconLabelCreationOptions } from 'vs import { IExtensionService } from 'vs/workbench/services/extensions/common/extensions'; import { IModeService } from 'vs/editor/common/services/modeService'; import { toResource, IEditorInput } from 'vs/workbench/common/editor'; -import { getPathLabel, IWorkspaceFolderProvider } from 'vs/base/common/labels'; import { PLAINTEXT_MODE_ID } from 'vs/editor/common/modes/modesRegistry'; import { IWorkspaceContextService } from 'vs/platform/workspace/common/workspace'; import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; import { IModelService } from 'vs/editor/common/services/modelService'; -import { IEnvironmentService } from 'vs/platform/environment/common/environment'; import { IUntitledEditorService } from 'vs/workbench/services/untitled/common/untitledEditorService'; import { IDecorationsService, IResourceDecorationChangeEvent, IDecorationData } from 'vs/workbench/services/decorations/browser/decorations'; import { Schemas } from 'vs/base/common/network'; @@ -25,6 +23,7 @@ import { ITextModel } from 'vs/editor/common/model'; import { IThemeService } from 'vs/platform/theme/common/themeService'; import { Event, Emitter } from 'vs/base/common/event'; import { DataUri } from 'vs/workbench/common/resources'; +import { IUriDisplayService } from 'vs/platform/uriDisplay/common/uriDisplay'; export interface IResourceLabel { name: string; @@ -52,13 +51,12 @@ export class ResourceLabel extends IconLabel { container: HTMLElement, options: IIconLabelCreationOptions, @IExtensionService private extensionService: IExtensionService, - @IWorkspaceContextService protected contextService: IWorkspaceContextService, @IConfigurationService private configurationService: IConfigurationService, @IModeService private modeService: IModeService, @IModelService private modelService: IModelService, - @IEnvironmentService protected environmentService: IEnvironmentService, @IDecorationsService protected decorationsService: IDecorationsService, - @IThemeService private themeService: IThemeService + @IThemeService private themeService: IThemeService, + @IUriDisplayService protected uriDisplayService: IUriDisplayService ) { super(container, options); @@ -193,8 +191,7 @@ export class ResourceLabel extends IconLabel { iconLabelOptions.title = this.options.title; } else if (resource && resource.scheme !== Schemas.data /* do not accidentally inline Data URIs */) { if (!this.computedPathLabel) { - const rootProvider = resource.scheme !== Schemas.file ? this.contextService : undefined; - this.computedPathLabel = getPathLabel(resource, this.environmentService, rootProvider); + this.computedPathLabel = this.uriDisplayService.getLabel(resource, true); } iconLabelOptions.title = this.computedPathLabel; @@ -262,7 +259,6 @@ export class EditorLabel extends ResourceLabel { export interface IFileLabelOptions extends IResourceLabelOptions { hideLabel?: boolean; hidePath?: boolean; - root?: uri; } export class FileLabel extends ResourceLabel { @@ -271,16 +267,16 @@ export class FileLabel extends ResourceLabel { container: HTMLElement, options: IIconLabelCreationOptions, @IExtensionService extensionService: IExtensionService, - @IWorkspaceContextService contextService: IWorkspaceContextService, + @IWorkspaceContextService private contextService: IWorkspaceContextService, @IConfigurationService configurationService: IConfigurationService, @IModeService modeService: IModeService, @IModelService modelService: IModelService, - @IEnvironmentService environmentService: IEnvironmentService, @IDecorationsService decorationsService: IDecorationsService, @IThemeService themeService: IThemeService, @IUntitledEditorService private untitledEditorService: IUntitledEditorService, + @IUriDisplayService uriDisplayService: IUriDisplayService ) { - super(container, options, extensionService, contextService, configurationService, modeService, modelService, environmentService, decorationsService, themeService); + super(container, options, extensionService, configurationService, modeService, modelService, decorationsService, themeService, uriDisplayService); } setFile(resource: uri, options?: IFileLabelOptions): void { @@ -302,17 +298,7 @@ export class FileLabel extends ResourceLabel { let description: string; const hidePath = (options && options.hidePath) || (resource.scheme === Schemas.untitled && !this.untitledEditorService.hasAssociatedFilePath(resource)); if (!hidePath) { - let rootProvider: IWorkspaceFolderProvider; - if (options && options.root) { - rootProvider = { - getWorkspaceFolder(): { uri } { return { uri: options.root }; }, - getWorkspace(): { folders: { uri: uri }[]; } { return { folders: [{ uri: options.root }] }; }, - }; - } else { - rootProvider = this.contextService; - } - - description = getPathLabel(resources.dirname(resource), this.environmentService, rootProvider); + description = this.uriDisplayService.getLabel(resources.dirname(resource), true); } this.setLabel({ resource, name, description }, options); diff --git a/src/vs/workbench/parts/search/browser/searchResultsView.ts b/src/vs/workbench/parts/search/browser/searchResultsView.ts index 7424cdc338d..8f3f69372cd 100644 --- a/src/vs/workbench/parts/search/browser/searchResultsView.ts +++ b/src/vs/workbench/parts/search/browser/searchResultsView.ts @@ -262,10 +262,8 @@ export class SearchRenderer extends Disposable implements IRenderer { } private renderFileMatch(tree: ITree, fileMatch: FileMatch, templateData: IFileMatchTemplate): void { - const folderMatch = fileMatch.parent(); - const root = folderMatch.hasRoot() ? folderMatch.resource() : undefined; templateData.el.setAttribute('data-resource', fileMatch.resource().toString()); - templateData.label.setFile(fileMatch.resource(), { root }); + templateData.label.setFile(fileMatch.resource()); let count = fileMatch.count(); templateData.badge.setCount(count); templateData.badge.setTitleFormat(count > 1 ? nls.localize('searchMatches', "{0} matches found", count) : nls.localize('searchMatch', "{0} match found", count)); diff --git a/src/vs/workbench/test/workbenchTestServices.ts b/src/vs/workbench/test/workbenchTestServices.ts index 14d5a319045..55ac4b47cc6 100644 --- a/src/vs/workbench/test/workbenchTestServices.ts +++ b/src/vs/workbench/test/workbenchTestServices.ts @@ -75,6 +75,7 @@ import { IDecorationRenderOptions } from 'vs/editor/common/editorCommon'; import { EditorGroup } from 'vs/workbench/common/editor/editorGroup'; import { Dimension } from 'vs/base/browser/dom'; import { ILogService, LogLevel } from 'vs/platform/log/common/log'; +import { IUriDisplayService, UriDisplayService } from 'vs/platform/uriDisplay/common/uriDisplay'; export function createFileInput(instantiationService: IInstantiationService, resource: URI): FileEditorInput { return instantiationService.createInstance(FileEditorInput, resource, void 0); @@ -241,7 +242,8 @@ export class TestTextFileService extends TextFileService { export function workbenchInstantiationService(): IInstantiationService { let instantiationService = new TestInstantiationService(new ServiceCollection([ILifecycleService, new TestLifecycleService()])); instantiationService.stub(IContextKeyService, instantiationService.createInstance(MockContextKeyService)); - instantiationService.stub(IWorkspaceContextService, new TestContextService(TestWorkspace)); + const workspaceContextService = new TestContextService(TestWorkspace); + instantiationService.stub(IWorkspaceContextService, workspaceContextService); const configService = new TestConfigurationService(); instantiationService.stub(IConfigurationService, configService); instantiationService.stub(ITextResourceConfigurationService, new TestTextResourceConfigurationService(configService)); @@ -269,6 +271,7 @@ export function workbenchInstantiationService(): IInstantiationService { instantiationService.stub(IHashService, new TestHashService()); instantiationService.stub(ILogService, new TestLogService()); instantiationService.stub(IEditorGroupsService, new TestEditorGroupsService([new TestEditorGroup(0)])); + instantiationService.stub(IUriDisplayService, new UriDisplayService(TestEnvironmentService, workspaceContextService)); const editorService = new TestEditorService(); instantiationService.stub(IEditorService, editorService); instantiationService.stub(ICodeEditorService, new TestCodeEditorService()); From ef40ff9bfd43c88014d11d1f9a4e28874b694ec7 Mon Sep 17 00:00:00 2001 From: isidor Date: Fri, 27 Jul 2018 15:58:37 +0200 Subject: [PATCH 0237/1276] uri display: if no formater regeistered just return path --- src/vs/platform/uriDisplay/common/uriDisplay.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vs/platform/uriDisplay/common/uriDisplay.ts b/src/vs/platform/uriDisplay/common/uriDisplay.ts index 0a3b55dd4bd..486aeb0d77e 100644 --- a/src/vs/platform/uriDisplay/common/uriDisplay.ts +++ b/src/vs/platform/uriDisplay/common/uriDisplay.ts @@ -58,7 +58,7 @@ export class UriDisplayService implements IUriDisplayService { } const formater = this.formaters.get(resource.scheme); if (!formater) { - return resource.with({ query: null, fragment: null }).toString(true); + return resource.path; } if (relative) { From 27cb073c1c050a3be392bab23367a53f5770f866 Mon Sep 17 00:00:00 2001 From: isidor Date: Fri, 27 Jul 2018 15:59:52 +0200 Subject: [PATCH 0238/1276] workbench: adopt uriDisplayService --- .../common/editor/untitledEditorInput.ts | 19 +++++++--------- .../files/common/editors/fileEditorInput.ts | 22 +++++++------------ 2 files changed, 16 insertions(+), 25 deletions(-) diff --git a/src/vs/workbench/common/editor/untitledEditorInput.ts b/src/vs/workbench/common/editor/untitledEditorInput.ts index ee49dbe7211..27d9f0d2cdd 100644 --- a/src/vs/workbench/common/editor/untitledEditorInput.ts +++ b/src/vs/workbench/common/editor/untitledEditorInput.ts @@ -8,19 +8,17 @@ import { TPromise } from 'vs/base/common/winjs.base'; import URI from 'vs/base/common/uri'; import { suggestFilename } from 'vs/base/common/mime'; import { memoize } from 'vs/base/common/decorators'; -import * as labels from 'vs/base/common/labels'; import { PLAINTEXT_MODE_ID } from 'vs/editor/common/modes/modesRegistry'; import * as paths from 'vs/base/common/paths'; import * as resources from 'vs/base/common/resources'; import { EditorInput, IEncodingSupport, EncodingMode, ConfirmResult, Verbosity } from 'vs/workbench/common/editor'; import { UntitledEditorModel } from 'vs/workbench/common/editor/untitledEditorModel'; import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; -import { IWorkspaceContextService } from 'vs/platform/workspace/common/workspace'; import { Event, Emitter } from 'vs/base/common/event'; import { ITextFileService } from 'vs/workbench/services/textfile/common/textfiles'; import { telemetryURIDescriptor } from 'vs/platform/telemetry/common/telemetryUtils'; -import { IEnvironmentService } from 'vs/platform/environment/common/environment'; import { IHashService } from 'vs/workbench/services/hash/common/hashService'; +import { IUriDisplayService } from 'vs/platform/uriDisplay/common/uriDisplay'; /** * An editor input to be used for untitled text buffers. @@ -46,10 +44,9 @@ export class UntitledEditorInput extends EditorInput implements IEncodingSupport private initialValue: string, private preferredEncoding: string, @IInstantiationService private instantiationService: IInstantiationService, - @IWorkspaceContextService private contextService: IWorkspaceContextService, @ITextFileService private textFileService: ITextFileService, - @IEnvironmentService private environmentService: IEnvironmentService, - @IHashService private hashService: IHashService + @IHashService private hashService: IHashService, + @IUriDisplayService private uriDisplayService: IUriDisplayService ) { super(); @@ -82,17 +79,17 @@ export class UntitledEditorInput extends EditorInput implements IEncodingSupport @memoize private get shortDescription(): string { - return paths.basename(labels.getPathLabel(resources.dirname(this.resource), this.environmentService)); + return paths.basename(this.uriDisplayService.getLabel(resources.dirname(this.resource))); } @memoize private get mediumDescription(): string { - return labels.getPathLabel(resources.dirname(this.resource), this.environmentService, this.contextService); + return this.uriDisplayService.getLabel(resources.dirname(this.resource), true); } @memoize private get longDescription(): string { - return labels.getPathLabel(resources.dirname(this.resource), this.environmentService); + return this.uriDisplayService.getLabel(resources.dirname(this.resource)); } getDescription(verbosity: Verbosity = Verbosity.MEDIUM): string { @@ -124,12 +121,12 @@ export class UntitledEditorInput extends EditorInput implements IEncodingSupport @memoize private get mediumTitle(): string { - return labels.getPathLabel(this.resource, this.environmentService, this.contextService); + return this.uriDisplayService.getLabel(this.resource, true); } @memoize private get longTitle(): string { - return labels.getPathLabel(this.resource, this.environmentService); + return this.uriDisplayService.getLabel(this.resource); } getTitle(verbosity: Verbosity): string { diff --git a/src/vs/workbench/parts/files/common/editors/fileEditorInput.ts b/src/vs/workbench/parts/files/common/editors/fileEditorInput.ts index 8ec1880198a..1d0e661bdb6 100644 --- a/src/vs/workbench/parts/files/common/editors/fileEditorInput.ts +++ b/src/vs/workbench/parts/files/common/editors/fileEditorInput.ts @@ -9,22 +9,19 @@ import { TPromise } from 'vs/base/common/winjs.base'; import { memoize } from 'vs/base/common/decorators'; import * as paths from 'vs/base/common/paths'; import * as resources from 'vs/base/common/resources'; -import * as labels from 'vs/base/common/labels'; import URI from 'vs/base/common/uri'; import { EncodingMode, ConfirmResult, EditorInput, IFileEditorInput, ITextEditorModel, Verbosity, IRevertOptions } from 'vs/workbench/common/editor'; import { TextFileEditorModel } from 'vs/workbench/services/textfile/common/textFileEditorModel'; import { BinaryEditorModel } from 'vs/workbench/common/editor/binaryEditorModel'; import { FileOperationError, FileOperationResult } from 'vs/platform/files/common/files'; import { ITextFileService, AutoSaveMode, ModelState, TextFileModelChangeEvent, LoadReason } from 'vs/workbench/services/textfile/common/textfiles'; -import { IWorkspaceContextService } from 'vs/platform/workspace/common/workspace'; import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; import { IReference } from 'vs/base/common/lifecycle'; import { telemetryURIDescriptor } from 'vs/platform/telemetry/common/telemetryUtils'; -import { IEnvironmentService } from 'vs/platform/environment/common/environment'; import { ITextModelService } from 'vs/editor/common/services/resolverService'; import { IHashService } from 'vs/workbench/services/hash/common/hashService'; import { FILE_EDITOR_INPUT_ID, TEXT_FILE_EDITOR_ID, BINARY_FILE_EDITOR_ID } from 'vs/workbench/parts/files/common/files'; -import { Schemas } from 'vs/base/common/network'; +import { IUriDisplayService } from 'vs/platform/uriDisplay/common/uriDisplay'; /** * A file editor input is the input type for the file editor of file system resources. @@ -43,11 +40,10 @@ export class FileEditorInput extends EditorInput implements IFileEditorInput { private resource: URI, preferredEncoding: string, @IInstantiationService private instantiationService: IInstantiationService, - @IWorkspaceContextService private contextService: IWorkspaceContextService, @ITextFileService private textFileService: ITextFileService, - @IEnvironmentService private environmentService: IEnvironmentService, @ITextModelService private textModelResolverService: ITextModelService, - @IHashService private hashService: IHashService + @IHashService private hashService: IHashService, + @IUriDisplayService private uriDisplayService: IUriDisplayService ) { super(); @@ -136,18 +132,17 @@ export class FileEditorInput extends EditorInput implements IFileEditorInput { @memoize private get shortDescription(): string { - return paths.basename(labels.getPathLabel(resources.dirname(this.resource), this.environmentService)); + return paths.basename(this.uriDisplayService.getLabel(resources.dirname(this.resource))); } @memoize private get mediumDescription(): string { - return labels.getPathLabel(resources.dirname(this.resource), this.environmentService, this.contextService); + return this.uriDisplayService.getLabel(resources.dirname(this.resource), true); } @memoize private get longDescription(): string { - const rootProvider = this.resource.scheme !== Schemas.file ? this.contextService : undefined; - return labels.getPathLabel(resources.dirname(this.resource), this.environmentService, rootProvider); + return this.uriDisplayService.getLabel(resources.dirname(this.resource), true); } getDescription(verbosity: Verbosity = Verbosity.MEDIUM): string { @@ -175,13 +170,12 @@ export class FileEditorInput extends EditorInput implements IFileEditorInput { @memoize private get mediumTitle(): string { - return labels.getPathLabel(this.resource, this.environmentService, this.contextService); + return this.uriDisplayService.getLabel(this.resource, true); } @memoize private get longTitle(): string { - const rootProvider = this.resource.scheme !== Schemas.file ? this.contextService : undefined; - return labels.getPathLabel(this.resource, this.environmentService, rootProvider); + return this.uriDisplayService.getLabel(this.resource, true); } getTitle(verbosity: Verbosity): string { From 336bf572a85ac6865bf36e358f064480f8b54ccc Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Fri, 27 Jul 2018 07:41:09 -0700 Subject: [PATCH 0239/1276] vscode-xterm@3.6.0-beta6 Readme change Double click word works across wrapped lines Fixes #55189 --- package.json | 2 +- yarn.lock | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/package.json b/package.json index 8d1b75d32d0..d134b388a6e 100644 --- a/package.json +++ b/package.json @@ -50,7 +50,7 @@ "vscode-nsfw": "1.0.17", "vscode-ripgrep": "^1.0.1", "vscode-textmate": "^4.0.1", - "vscode-xterm": "3.6.0-beta5", + "vscode-xterm": "3.6.0-beta6", "yauzl": "^2.9.1" }, "devDependencies": { diff --git a/yarn.lock b/yarn.lock index 9e322ec55d9..bc4c82cffff 100644 --- a/yarn.lock +++ b/yarn.lock @@ -6256,9 +6256,9 @@ vscode-textmate@^4.0.1: dependencies: oniguruma "^7.0.0" -vscode-xterm@3.6.0-beta5: - version "3.6.0-beta5" - resolved "https://registry.yarnpkg.com/vscode-xterm/-/vscode-xterm-3.6.0-beta5.tgz#b44fd70451944624f148bd9f0be4925b52b7a7e0" +vscode-xterm@3.6.0-beta6: + version "3.6.0-beta6" + resolved "https://registry.yarnpkg.com/vscode-xterm/-/vscode-xterm-3.6.0-beta6.tgz#22feaf1d1a92f88ac977c9b387b8cb69a2347da5" vso-node-api@^6.1.2-preview: version "6.1.2-preview" From 45a0828db04686c5b47afc072f6f188cff31c0eb Mon Sep 17 00:00:00 2001 From: isidor Date: Fri, 27 Jul 2018 17:42:46 +0200 Subject: [PATCH 0240/1276] dnd use uri display service --- src/vs/workbench/browser/dnd.ts | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/vs/workbench/browser/dnd.ts b/src/vs/workbench/browser/dnd.ts index 8db6cf1d71e..dd879f9d831 100644 --- a/src/vs/workbench/browser/dnd.ts +++ b/src/vs/workbench/browser/dnd.ts @@ -35,6 +35,7 @@ import { IEditorService, IResourceEditor } from 'vs/workbench/services/editor/co import { Disposable } from 'vs/base/common/lifecycle'; import { addDisposableListener, EventType } from 'vs/base/browser/dom'; import { IEditorGroup } from 'vs/workbench/services/group/common/editorGroupsService'; +import { IUriDisplayService } from 'vs/platform/uriDisplay/common/uriDisplay'; export interface IDraggedResource { resource: URI; @@ -165,7 +166,8 @@ export class ResourcesDropHandler { @IBackupFileService private backupFileService: IBackupFileService, @IUntitledEditorService private untitledEditorService: IUntitledEditorService, @IEditorService private editorService: IEditorService, - @IConfigurationService private configurationService: IConfigurationService + @IConfigurationService private configurationService: IConfigurationService, + @IUriDisplayService private uriDisplayService: IUriDisplayService ) { } @@ -187,7 +189,7 @@ export class ResourcesDropHandler { // Add external ones to recently open list unless dropped resource is a workspace const filesToAddToHistory = untitledOrFileResources.filter(d => d.isExternal && d.resource.scheme === Schemas.file).map(d => d.resource); if (filesToAddToHistory.length) { - this.windowsService.addRecentlyOpened(filesToAddToHistory.map(resource => resource.fsPath)); + this.windowsService.addRecentlyOpened(filesToAddToHistory.map(resource => this.uriDisplayService.getLabel(resource))); } const editors: IResourceEditor[] = untitledOrFileResources.map(untitledOrFileResource => ({ From dd636d46dd20268202c2eb25e7c9fe3e7d510c3f Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Fri, 27 Jul 2018 09:29:46 -0700 Subject: [PATCH 0241/1276] vscode-xterm@3.6.0-beta7 Pulls in fix to not scroll to bottom when term status is requested --- package.json | 2 +- yarn.lock | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/package.json b/package.json index d134b388a6e..c2df6f4f32e 100644 --- a/package.json +++ b/package.json @@ -50,7 +50,7 @@ "vscode-nsfw": "1.0.17", "vscode-ripgrep": "^1.0.1", "vscode-textmate": "^4.0.1", - "vscode-xterm": "3.6.0-beta6", + "vscode-xterm": "3.6.0-beta7", "yauzl": "^2.9.1" }, "devDependencies": { diff --git a/yarn.lock b/yarn.lock index bc4c82cffff..08bc6f8be19 100644 --- a/yarn.lock +++ b/yarn.lock @@ -6256,9 +6256,9 @@ vscode-textmate@^4.0.1: dependencies: oniguruma "^7.0.0" -vscode-xterm@3.6.0-beta6: - version "3.6.0-beta6" - resolved "https://registry.yarnpkg.com/vscode-xterm/-/vscode-xterm-3.6.0-beta6.tgz#22feaf1d1a92f88ac977c9b387b8cb69a2347da5" +vscode-xterm@3.6.0-beta7: + version "3.6.0-beta7" + resolved "https://registry.yarnpkg.com/vscode-xterm/-/vscode-xterm-3.6.0-beta7.tgz#c079061ec43cddc2f952c8075a388c25fb4ca2b0" vso-node-api@^6.1.2-preview: version "6.1.2-preview" From 6085483537abe06fe5981ff7a898470e16ac594b Mon Sep 17 00:00:00 2001 From: SteVen Batten <6561887+sbatten@users.noreply.github.com> Date: Fri, 27 Jul 2018 10:10:26 -0700 Subject: [PATCH 0242/1276] merging menu/titlebar (#55100) * merging menu/titlebar * install empty native menu to override electron --- src/vs/code/electron-main/menubar.ts | 5 + src/vs/workbench/browser/layout.ts | 56 ++---- .../parts/menubar/media/menubarpart.css | 17 +- .../browser/parts/menubar/menubarPart.ts | 112 ++++-------- .../parts/titlebar/media/titlebarpart.css | 36 ++-- .../browser/parts/titlebar/titlebarPart.ts | 162 ++++++++++-------- .../workbench/electron-browser/workbench.ts | 38 +--- .../services/part/common/partService.ts | 11 +- .../workbench/test/workbenchTestServices.ts | 6 +- 9 files changed, 196 insertions(+), 247 deletions(-) diff --git a/src/vs/code/electron-main/menubar.ts b/src/vs/code/electron-main/menubar.ts index cb32507e007..ac259f0aa3c 100644 --- a/src/vs/code/electron-main/menubar.ts +++ b/src/vs/code/electron-main/menubar.ts @@ -362,6 +362,11 @@ export class Menubar { } private shouldDrawMenu(menuId: string): boolean { + // We need to draw an empty menu to override the electron default + if (!isMacintosh && this.configurationService.getValue('window.titleBarStyle') === 'custom') { + return false; + } + switch (menuId) { case 'File': case 'Help': diff --git a/src/vs/workbench/browser/layout.ts b/src/vs/workbench/browser/layout.ts index 01fe21c6a4c..5089f6ff8af 100644 --- a/src/vs/workbench/browser/layout.ts +++ b/src/vs/workbench/browser/layout.ts @@ -14,7 +14,6 @@ import { IViewletService } from 'vs/workbench/services/viewlet/browser/viewlet'; import { IStorageService, StorageScope } from 'vs/platform/storage/common/storage'; import { IContextViewService } from 'vs/platform/contextview/browser/contextView'; import { Disposable } from 'vs/base/common/lifecycle'; -import { getZoomFactor } from 'vs/base/browser/browser'; import { IThemeService } from 'vs/platform/theme/common/themeService'; import { isMacintosh } from 'vs/base/common/platform'; import { memoize } from 'vs/base/common/decorators'; @@ -28,7 +27,7 @@ import { ActivitybarPart } from 'vs/workbench/browser/parts/activitybar/activity import { SidebarPart } from 'vs/workbench/browser/parts/sidebar/sidebarPart'; import { PanelPart } from 'vs/workbench/browser/parts/panel/panelPart'; import { StatusbarPart } from 'vs/workbench/browser/parts/statusbar/statusbarPart'; -import { MenubarPart } from 'vs/workbench/browser/parts/menubar/menubarPart'; +import { getZoomFactor } from 'vs/base/browser/browser'; const TITLE_BAR_HEIGHT = isMacintosh ? 22 : 30; const STATUS_BAR_HEIGHT = 22; @@ -65,8 +64,6 @@ export class WorkbenchLayout extends Disposable implements IVerticalSashLayoutPr private _sidebarWidth: number; private sidebarHeight: number; private titlebarHeight: number; - private menubarHeight: number; - private headingHeight: number; private statusbarHeight: number; private panelSizeBeforeMaximized: number; private panelMaximized: boolean; @@ -79,7 +76,6 @@ export class WorkbenchLayout extends Disposable implements IVerticalSashLayoutPr private workbenchContainer: HTMLElement, private parts: { titlebar: TitlebarPart, - menubar: MenubarPart, activitybar: ActivitybarPart, editor: EditorPart, sidebar: SidebarPart, @@ -224,9 +220,6 @@ export class WorkbenchLayout extends Disposable implements IVerticalSashLayoutPr titlebar: { height: TITLE_BAR_HEIGHT }, - menubar: { - height: TITLE_BAR_HEIGHT - }, activitybar: { width: ACTIVITY_BAR_WIDTH }, @@ -319,7 +312,7 @@ export class WorkbenchLayout extends Disposable implements IVerticalSashLayoutPr if (newSashHeight + HIDE_PANEL_HEIGHT_THRESHOLD < this.partLayoutInfo.panel.minHeight) { let dragCompensation = this.partLayoutInfo.panel.minHeight - HIDE_PANEL_HEIGHT_THRESHOLD; promise = this.partService.setPanelHidden(true); - startY = Math.min(this.sidebarHeight - this.statusbarHeight - this.headingHeight, e.currentY + dragCompensation); + startY = Math.min(this.sidebarHeight - this.statusbarHeight - this.titlebarHeight, e.currentY + dragCompensation); this.panelHeight = startPanelHeight; // when restoring panel, restore to the panel height we started from } @@ -420,12 +413,12 @@ export class WorkbenchLayout extends Disposable implements IVerticalSashLayoutPr const isActivityBarHidden = !this.partService.isVisible(Parts.ACTIVITYBAR_PART); const isTitlebarHidden = !this.partService.isVisible(Parts.TITLEBAR_PART); - const isMenubarHidden = !this.partService.isVisible(Parts.MENUBAR_PART); const isPanelHidden = !this.partService.isVisible(Parts.PANEL_PART); const isStatusbarHidden = !this.partService.isVisible(Parts.STATUSBAR_PART); const isSidebarHidden = !this.partService.isVisible(Parts.SIDEBAR_PART); const sidebarPosition = this.partService.getSideBarPosition(); const panelPosition = this.partService.getPanelPosition(); + const menubarVisibility = this.partService.getMenubarVisibility(); // Sidebar if (this.sidebarWidth === -1) { @@ -433,11 +426,9 @@ export class WorkbenchLayout extends Disposable implements IVerticalSashLayoutPr } this.statusbarHeight = isStatusbarHidden ? 0 : this.partLayoutInfo.statusbar.height; - this.titlebarHeight = isTitlebarHidden ? 0 : this.partLayoutInfo.titlebar.height / getZoomFactor(); // adjust for zoom prevention - this.menubarHeight = isMenubarHidden ? 0 : this.partLayoutInfo.menubar.height / getZoomFactor(); // adjust for zoom prevention - this.headingHeight = Math.max(this.menubarHeight, this.titlebarHeight); + this.titlebarHeight = isTitlebarHidden ? 0 : this.partLayoutInfo.titlebar.height / (!menubarVisibility || menubarVisibility === 'hidden' ? getZoomFactor() : 1); // adjust for zoom prevention - this.sidebarHeight = this.workbenchSize.height - this.statusbarHeight - this.headingHeight; + this.sidebarHeight = this.workbenchSize.height - this.statusbarHeight - this.titlebarHeight; let sidebarSize = new Dimension(this.sidebarWidth, this.sidebarHeight); // Activity Bar @@ -574,14 +565,6 @@ export class WorkbenchLayout extends Disposable implements IVerticalSashLayoutPr show(titleContainer); } - // Menubar - const menubarContainer = this.parts.menubar.getContainer(); - if (isMenubarHidden) { - hide(menubarContainer); - } else { - show(menubarContainer); - } - // Editor Part and Panel part const editorContainer = this.parts.editor.getContainer(); const panelContainer = this.parts.panel.getContainer(); @@ -590,19 +573,19 @@ export class WorkbenchLayout extends Disposable implements IVerticalSashLayoutPr if (panelPosition === Position.BOTTOM) { if (sidebarPosition === Position.LEFT) { - position(editorContainer, this.headingHeight, 0, this.statusbarHeight + panelDimension.height, sidebarSize.width + activityBarSize.width); - position(panelContainer, editorSize.height + this.headingHeight, 0, this.statusbarHeight, sidebarSize.width + activityBarSize.width); + position(editorContainer, this.titlebarHeight, 0, this.statusbarHeight + panelDimension.height, sidebarSize.width + activityBarSize.width); + position(panelContainer, editorSize.height + this.titlebarHeight, 0, this.statusbarHeight, sidebarSize.width + activityBarSize.width); } else { - position(editorContainer, this.headingHeight, sidebarSize.width, this.statusbarHeight + panelDimension.height, 0); - position(panelContainer, editorSize.height + this.headingHeight, sidebarSize.width, this.statusbarHeight, 0); + position(editorContainer, this.titlebarHeight, sidebarSize.width, this.statusbarHeight + panelDimension.height, 0); + position(panelContainer, editorSize.height + this.titlebarHeight, sidebarSize.width, this.statusbarHeight, 0); } } else { if (sidebarPosition === Position.LEFT) { - position(editorContainer, this.headingHeight, panelDimension.width, this.statusbarHeight, sidebarSize.width + activityBarSize.width); - position(panelContainer, this.headingHeight, 0, this.statusbarHeight, sidebarSize.width + activityBarSize.width + editorSize.width); + position(editorContainer, this.titlebarHeight, panelDimension.width, this.statusbarHeight, sidebarSize.width + activityBarSize.width); + position(panelContainer, this.titlebarHeight, 0, this.statusbarHeight, sidebarSize.width + activityBarSize.width + editorSize.width); } else { - position(editorContainer, this.headingHeight, sidebarSize.width + activityBarSize.width + panelWidth, this.statusbarHeight, 0); - position(panelContainer, this.headingHeight, sidebarSize.width + activityBarSize.width, this.statusbarHeight, editorSize.width); + position(editorContainer, this.titlebarHeight, sidebarSize.width + activityBarSize.width + panelWidth, this.statusbarHeight, 0); + position(panelContainer, this.titlebarHeight, sidebarSize.width + activityBarSize.width, this.statusbarHeight, editorSize.width); } } @@ -611,10 +594,10 @@ export class WorkbenchLayout extends Disposable implements IVerticalSashLayoutPr size(activitybarContainer, null, activityBarSize.height); if (sidebarPosition === Position.LEFT) { this.parts.activitybar.getContainer().style.right = ''; - position(activitybarContainer, this.headingHeight, null, 0, 0); + position(activitybarContainer, this.titlebarHeight, null, 0, 0); } else { this.parts.activitybar.getContainer().style.left = ''; - position(activitybarContainer, this.headingHeight, 0, 0, null); + position(activitybarContainer, this.titlebarHeight, 0, 0, null); } if (isActivityBarHidden) { hide(activitybarContainer); @@ -627,9 +610,9 @@ export class WorkbenchLayout extends Disposable implements IVerticalSashLayoutPr size(sidebarContainer, sidebarSize.width, sidebarSize.height); const editorAndPanelWidth = editorSize.width + (panelPosition === Position.RIGHT ? panelWidth : 0); if (sidebarPosition === Position.LEFT) { - position(sidebarContainer, this.headingHeight, editorAndPanelWidth, this.statusbarHeight, activityBarSize.width); + position(sidebarContainer, this.titlebarHeight, editorAndPanelWidth, this.statusbarHeight, activityBarSize.width); } else { - position(sidebarContainer, this.headingHeight, activityBarSize.width, this.statusbarHeight, editorAndPanelWidth); + position(sidebarContainer, this.titlebarHeight, activityBarSize.width, this.statusbarHeight, editorAndPanelWidth); } // Statusbar Part @@ -665,7 +648,6 @@ export class WorkbenchLayout extends Disposable implements IVerticalSashLayoutPr // Propagate to Part Layouts this.parts.titlebar.layout(new Dimension(this.workbenchSize.width, this.titlebarHeight)); - this.parts.menubar.layout(new Dimension(this.workbenchSize.width, this.menubarHeight)); this.parts.editor.layout(new Dimension(editorSize.width, editorSize.height)); this.parts.sidebar.layout(sidebarSize); this.parts.panel.layout(panelDimension); @@ -676,7 +658,7 @@ export class WorkbenchLayout extends Disposable implements IVerticalSashLayoutPr } getVerticalSashTop(sash: Sash): number { - return this.headingHeight; + return this.titlebarHeight; } getVerticalSashLeft(sash: Sash): number { @@ -703,7 +685,7 @@ export class WorkbenchLayout extends Disposable implements IVerticalSashLayoutPr getHorizontalSashTop(sash: Sash): number { const offset = 2; // Horizontal sash should be a bit lower than the editor area, thus add 2px #5524 - return offset + (this.partService.isVisible(Parts.PANEL_PART) ? this.sidebarHeight - this.panelHeight + this.headingHeight : this.sidebarHeight + this.headingHeight); + return offset + (this.partService.isVisible(Parts.PANEL_PART) ? this.sidebarHeight - this.panelHeight + this.titlebarHeight : this.sidebarHeight + this.titlebarHeight); } getHorizontalSashLeft(sash: Sash): number { diff --git a/src/vs/workbench/browser/parts/menubar/media/menubarpart.css b/src/vs/workbench/browser/parts/menubar/media/menubarpart.css index 9b4ab103998..f18a71b0435 100644 --- a/src/vs/workbench/browser/parts/menubar/media/menubarpart.css +++ b/src/vs/workbench/browser/parts/menubar/media/menubarpart.css @@ -3,29 +3,24 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -.monaco-workbench > .part.menubar { +.monaco-workbench .part.menubar { display: flex; - position: absolute; + flex-shrink: 1; box-sizing: border-box; - padding-left: 35px; - padding-right: 138px; height: 30px; + -webkit-app-region: no-drag; + overflow-x: hidden; } -.monaco-workbench.fullscreen > .part.menubar { - position: absolute; - width: 100%; +.monaco-workbench.fullscreen .part.menubar { margin: 0px; padding: 0px 5px; } -.monaco-workbench > .part.menubar > .menubar-menu-button { - display: flex; - flex-shrink: 0; +.monaco-workbench .part.menubar > .menubar-menu-button { align-items: center; box-sizing: border-box; padding: 0px 8px; - position: relative; cursor: default; -webkit-app-region: no-drag; zoom: 1; diff --git a/src/vs/workbench/browser/parts/menubar/menubarPart.ts b/src/vs/workbench/browser/parts/menubar/menubarPart.ts index 1e27cf6f9f3..c0ef6872610 100644 --- a/src/vs/workbench/browser/parts/menubar/menubarPart.ts +++ b/src/vs/workbench/browser/parts/menubar/menubarPart.ts @@ -20,7 +20,7 @@ import { Builder, $ } from 'vs/base/browser/builder'; import { Separator } from 'vs/base/browser/ui/actionbar/actionbar'; import { EventType, Dimension } from 'vs/base/browser/dom'; import { IKeybindingService } from 'vs/platform/keybinding/common/keybinding'; -import { isWindows, isMacintosh } from 'vs/base/common/platform'; +import { isMacintosh } from 'vs/base/common/platform'; import { Menu, IMenuOptions, SubmenuAction } from 'vs/base/browser/ui/menu/menu'; import { KeyCode } from 'vs/base/common/keyCodes'; import { StandardKeyboardEvent } from 'vs/base/browser/keyboardEvent'; @@ -106,15 +106,7 @@ export class MenubarPart extends Part { private _modifierKeyStatus: IModifierKeyStatus; private _focusState: MenubarState; - private _onVisibilityChange: Emitter; - - private initialSizing: { - menuButtonPaddingLeftRight?: number; - menubarHeight?: number; - menubarPaddingLeft?: number; - menubarPaddingRight?: number; - menubarFontSize?: number; - } = {}; + private _onVisibilityChange: Emitter; private static MAX_MENU_RECENT_ENTRIES = 5; @@ -157,7 +149,7 @@ export class MenubarPart extends Part { this.setUnfocusedState(); })); - this._onVisibilityChange = this._register(new Emitter()); + this._onVisibilityChange = this._register(new Emitter()); if (isMacintosh || this.currentTitlebarStyleSetting !== 'custom') { for (let topLevelMenuName of Object.keys(this.topLevelMenus)) { @@ -338,20 +330,24 @@ export class MenubarPart extends Part { if (this.keys.some(key => event.affectsConfiguration(key))) { this.setupMenubar(); } + + if (event.affectsConfiguration('window.menuBarVisibility')) { + this.setUnfocusedState(); + } } private setUnfocusedState(): void { - this.focusState = this.currentMenubarVisibility === 'toggle' ? MenubarState.HIDDEN : MenubarState.VISIBLE; + this.focusState = this.currentMenubarVisibility === 'toggle' || this.currentMenubarVisibility === 'hidden' ? MenubarState.HIDDEN : MenubarState.VISIBLE; } private hideMenubar(): void { - this._onVisibilityChange.fire(new Dimension(0, 0)); - this.container.style('visibility', 'hidden'); + this.container.style('display', 'none'); + this._onVisibilityChange.fire(false); } private showMenubar(): void { - this._onVisibilityChange.fire(this.getMenubarItemsDimensions()); - this.container.style('visibility', null); + this.container.style('display', 'flex'); + this._onVisibilityChange.fire(true); } private onModifierKeyToggled(modifierKeyStatus: IModifierKeyStatus): void { @@ -359,6 +355,10 @@ export class MenubarPart extends Part { const altKeyAlone = modifierKeyStatus.lastKeyPressed === 'alt' && !modifierKeyStatus.ctrlKey && !modifierKeyStatus.shiftKey; const allModifiersReleased = !modifierKeyStatus.altKey && !modifierKeyStatus.ctrlKey && !modifierKeyStatus.shiftKey; + if (this.currentMenubarVisibility === 'hidden') { + return; + } + if (this.currentMenubarVisibility === 'toggle') { if (altKeyAlone) { if (!this.isVisible) { @@ -889,8 +889,8 @@ export class MenubarPart extends Part { $(menuHolder.getHTMLElement().parentElement).addClass('open'); menuHolder.style({ - 'zoom': `${1 / browser.getZoomFactor()}`, - 'top': `${this.container.getClientArea().height * browser.getZoomFactor()}px` + 'top': `${this.container.getClientArea().height}px`, + 'left': `${customMenu.buttonElement.getHTMLElement().getBoundingClientRect().left}px` }); let menuOptions: IMenuOptions = { @@ -921,48 +921,12 @@ export class MenubarPart extends Part { }; } - public get onVisibilityChange(): Event { + public get onVisibilityChange(): Event { return this._onVisibilityChange.event; } public layout(dimension: Dimension): Dimension[] { - // To prevent zooming we need to adjust the font size with the zoom factor - if (this.customMenus) { - if (typeof this.initialSizing.menubarFontSize !== 'number') { - this.initialSizing.menubarFontSize = parseInt(this.container.getComputedStyle().fontSize, 10); - } - - if (typeof this.initialSizing.menubarHeight !== 'number') { - this.initialSizing.menubarHeight = parseInt(this.container.getComputedStyle().height, 10); - } - - if (typeof this.initialSizing.menubarPaddingLeft !== 'number') { - this.initialSizing.menubarPaddingLeft = parseInt(this.container.getComputedStyle().paddingLeft, 10); - } - - if (typeof this.initialSizing.menubarPaddingRight !== 'number') { - this.initialSizing.menubarPaddingRight = parseInt(this.container.getComputedStyle().paddingRight, 10); - } - - if (typeof this.initialSizing.menuButtonPaddingLeftRight !== 'number') { - this.initialSizing.menuButtonPaddingLeftRight = parseInt(this.customMenus[0].buttonElement.getComputedStyle().paddingLeft, 10); - } - - this.container.style({ - height: `${this.initialSizing.menubarHeight / browser.getZoomFactor()}px`, - 'padding-left': `${this.initialSizing.menubarPaddingLeft / browser.getZoomFactor()}px`, - 'padding-right': `${this.initialSizing.menubarPaddingRight / browser.getZoomFactor()}px`, - 'font-size': `${this.initialSizing.menubarFontSize / browser.getZoomFactor()}px`, - }); - - this.customMenus.forEach(customMenu => { - customMenu.buttonElement.style({ - 'padding': `0 ${this.initialSizing.menuButtonPaddingLeftRight / browser.getZoomFactor()}px` - }); - }); - } - - if (this.currentMenubarVisibility === 'toggle') { + if (!this.isVisible) { this.hideMenubar(); } else { this.showMenubar(); @@ -984,13 +948,13 @@ export class MenubarPart extends Part { public createContentArea(parent: HTMLElement): HTMLElement { this.container = $(parent); - if (!isWindows) { - return this.container.getHTMLElement(); - } - // Build the menubar if (this.container) { this.doSetupMenubar(); + + if (!isMacintosh && this.currentTitlebarStyleSetting === 'custom') { + this.setUnfocusedState(); + } } return this.container.getHTMLElement(); @@ -1001,7 +965,7 @@ registerThemingParticipant((theme: ITheme, collector: ICssStyleCollector) => { const menubarActiveWindowFgColor = theme.getColor(TITLE_BAR_ACTIVE_FOREGROUND); if (menubarActiveWindowFgColor) { collector.addRule(` - .monaco-workbench > .part.menubar > .menubar-menu-button { + .monaco-workbench .part.menubar > .menubar-menu-button { color: ${menubarActiveWindowFgColor}; } `); @@ -1010,7 +974,7 @@ registerThemingParticipant((theme: ITheme, collector: ICssStyleCollector) => { const menubarInactiveWindowFgColor = theme.getColor(TITLE_BAR_INACTIVE_FOREGROUND); if (menubarInactiveWindowFgColor) { collector.addRule(` - .monaco-workbench > .part.menubar.inactive > .menubar-menu-button { + .monaco-workbench .part.menubar.inactive > .menubar-menu-button { color: ${menubarInactiveWindowFgColor}; } `); @@ -1020,9 +984,9 @@ registerThemingParticipant((theme: ITheme, collector: ICssStyleCollector) => { const menubarSelectedFgColor = theme.getColor(MENUBAR_SELECTION_FOREGROUND); if (menubarSelectedFgColor) { collector.addRule(` - .monaco-workbench > .part.menubar > .menubar-menu-button.open, - .monaco-workbench > .part.menubar > .menubar-menu-button:focus, - .monaco-workbench > .part.menubar > .menubar-menu-button:hover { + .monaco-workbench .part.menubar > .menubar-menu-button.open, + .monaco-workbench .part.menubar > .menubar-menu-button:focus, + .monaco-workbench .part.menubar > .menubar-menu-button:hover { color: ${menubarSelectedFgColor}; } `); @@ -1031,9 +995,9 @@ registerThemingParticipant((theme: ITheme, collector: ICssStyleCollector) => { const menubarSelectedBgColor = theme.getColor(MENUBAR_SELECTION_BACKGROUND); if (menubarSelectedBgColor) { collector.addRule(` - .monaco-workbench > .part.menubar > .menubar-menu-button.open, - .monaco-workbench > .part.menubar > .menubar-menu-button:focus, - .monaco-workbench > .part.menubar > .menubar-menu-button:hover { + .monaco-workbench .part.menubar > .menubar-menu-button.open, + .monaco-workbench .part.menubar > .menubar-menu-button:focus, + .monaco-workbench .part.menubar > .menubar-menu-button:hover { background-color: ${menubarSelectedBgColor}; } `); @@ -1042,18 +1006,18 @@ registerThemingParticipant((theme: ITheme, collector: ICssStyleCollector) => { const menubarSelectedBorderColor = theme.getColor(MENUBAR_SELECTION_BORDER); if (menubarSelectedBorderColor) { collector.addRule(` - .monaco-workbench > .part.menubar > .menubar-menu-button:hover { + .monaco-workbench .part.menubar > .menubar-menu-button:hover { outline: dashed 1px; } - .monaco-workbench > .part.menubar > .menubar-menu-button.open, - .monaco-workbench > .part.menubar > .menubar-menu-button:focus { + .monaco-workbench .part.menubar > .menubar-menu-button.open, + .monaco-workbench .part.menubar > .menubar-menu-button:focus { outline: solid 1px; } - .monaco-workbench > .part.menubar > .menubar-menu-button.open, - .monaco-workbench > .part.menubar > .menubar-menu-button:focus, - .monaco-workbench > .part.menubar > .menubar-menu-button:hover { + .monaco-workbench .part.menubar > .menubar-menu-button.open, + .monaco-workbench .part.menubar > .menubar-menu-button:focus, + .monaco-workbench .part.menubar > .menubar-menu-button:hover { outline-offset: -1px; outline-color: ${menubarSelectedBorderColor}; } diff --git a/src/vs/workbench/browser/parts/titlebar/media/titlebarpart.css b/src/vs/workbench/browser/parts/titlebar/media/titlebarpart.css index 28af45e5b91..54a27a0b1a3 100644 --- a/src/vs/workbench/browser/parts/titlebar/media/titlebarpart.css +++ b/src/vs/workbench/browser/parts/titlebar/media/titlebarpart.css @@ -6,7 +6,6 @@ .monaco-workbench > .part.titlebar { box-sizing: border-box; width: 100%; - font-size: 12px; padding: 0 70px; overflow: hidden; flex-shrink: 0; @@ -26,14 +25,18 @@ position: absolute; width: 100%; height: 100%; + z-index: -1; -webkit-app-region: drag; } .monaco-workbench > .part.titlebar > .window-title { flex: 0 1 auto; + font-size: 12px; overflow: hidden; white-space: nowrap; text-overflow: ellipsis; + margin-left: auto; + margin-right: auto; zoom: 1; /* prevent zooming */ } @@ -44,7 +47,8 @@ padding: 0; height: 30px; line-height: 30px; - justify-content: space-between; + justify-content: left; + overflow: visible; } .monaco-workbench.windows > .part.titlebar > .resizer, @@ -56,22 +60,27 @@ height: 20%; } -.monaco-workbench.windows > .part.titlebar > .window-title, -.monaco-workbench.linux > .part.titlebar > .window-title { - order: 2; +.monaco-workbench.windows.fullscreen > .part.titlebar > .resizer, +.monaco-workbench.linux.fullscreen > .part.titlebar > .resizer { + display: none; } + .monaco-workbench > .part.titlebar > .window-appicon { width: 35px; - margin-right: 113px; + height: 100%; -webkit-app-region: no-drag; position: relative; z-index: 99; - order: 1; background-image: url('code-icon.svg'); background-repeat: no-repeat; background-position: center center; background-size: 16px; + flex-shrink: 0; +} + +.monaco-workbench.fullscreen > .part.titlebar > .window-appicon { + display: none; } .monaco-workbench > .part.titlebar > .window-controls-container { @@ -84,7 +93,10 @@ -webkit-app-region: no-drag; height: 100%; width: 138px; - order: 3; +} + +.monaco-workbench.fullscreen > .part.titlebar > .window-controls-container { + display: none; } .monaco-workbench > .part.titlebar > .window-controls-container > .window-icon { @@ -106,42 +118,34 @@ .monaco-workbench > .part.titlebar.titlebar > .window-controls-container > .window-close { background-image: url('chrome-close-dark.svg'); - order: 3; } .monaco-workbench > .part.titlebar.titlebar.light > .window-controls-container > .window-close { background-image: url('chrome-close.svg'); - order: 3; } .monaco-workbench > .part.titlebar.titlebar > .window-controls-container > .window-unmaximize { background-image: url('chrome-restore-dark.svg'); - order: 2; } .monaco-workbench > .part.titlebar.titlebar.light > .window-controls-container > .window-unmaximize { background-image: url('chrome-restore.svg'); - order: 2; } .monaco-workbench > .part.titlebar > .window-controls-container > .window-maximize { background-image: url('chrome-maximize-dark.svg'); - order: 2; } .monaco-workbench > .part.titlebar.light > .window-controls-container > .window-maximize { background-image: url('chrome-maximize.svg'); - order: 2; } .monaco-workbench > .part.titlebar > .window-controls-container > .window-minimize { background-image: url('chrome-minimize-dark.svg'); - order: 1; } .monaco-workbench > .part.titlebar.light > .window-controls-container > .window-minimize { background-image: url('chrome-minimize.svg'); - order: 1; } .monaco-workbench > .part.titlebar > .window-controls-container > .window-icon:hover { diff --git a/src/vs/workbench/browser/parts/titlebar/titlebarPart.ts b/src/vs/workbench/browser/parts/titlebar/titlebarPart.ts index 132fe7f1091..02513af6ff6 100644 --- a/src/vs/workbench/browser/parts/titlebar/titlebarPart.ts +++ b/src/vs/workbench/browser/parts/titlebar/titlebarPart.ts @@ -31,7 +31,8 @@ import URI from 'vs/base/common/uri'; import { Color } from 'vs/base/common/color'; import { trim } from 'vs/base/common/strings'; import { addDisposableListener, EventType, EventHelper, Dimension } from 'vs/base/browser/dom'; -import { IPartService } from 'vs/workbench/services/part/common/partService'; +import { MenubarPart } from 'vs/workbench/browser/parts/menubar/menubarPart'; +import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; import { template, getBaseLabel } from 'vs/base/common/labels'; import { IUriDisplayService } from 'vs/platform/uriDisplay/common/uriDisplay'; @@ -51,10 +52,11 @@ export class TitlebarPart extends Part implements ITitleService { private windowControls: Builder; private maxRestoreControl: Builder; private appIcon: Builder; + private menubarPart: MenubarPart; + private menubar: Builder; private pendingTitle: string; private representedFileName: string; - private menubarWidth: number; private initialSizing: { titleFontSize?: number; @@ -78,7 +80,7 @@ export class TitlebarPart extends Part implements ITitleService { @IEditorService private editorService: IEditorService, @IEnvironmentService private environmentService: IEnvironmentService, @IWorkspaceContextService private contextService: IWorkspaceContextService, - @IPartService private partService: IPartService, + @IInstantiationService private instantiationService: IInstantiationService, @IThemeService themeService: IThemeService, @IUriDisplayService private uriDisplayService: IUriDisplayService ) { @@ -98,7 +100,6 @@ export class TitlebarPart extends Part implements ITitleService { this._register(this.contextService.onDidChangeWorkspaceFolders(() => this.setTitle(this.getWindowTitle()))); this._register(this.contextService.onDidChangeWorkbenchState(() => this.setTitle(this.getWindowTitle()))); this._register(this.contextService.onDidChangeWorkspaceName(() => this.setTitle(this.getWindowTitle()))); - this._register(this.partService.onMenubarVisibilityChange(this.onMenubarVisibilityChanged, this)); } private onBlur(): void { @@ -117,10 +118,19 @@ export class TitlebarPart extends Part implements ITitleService { } } - private onMenubarVisibilityChanged(dimension: Dimension): void { - this.menubarWidth = dimension.width; + private onMenubarVisibilityChanged(visible: boolean) { + if (isWindows || isLinux) { + // Hide title when toggling menu bar + if (this.configurationService.getValue('window.menuBarVisibility') === 'toggle' && visible) { + this.title.style('visibility', 'hidden'); - this.updateLayout(); + // Hack to fix issue #52522 with layered webkit-app-region elements appearing under cursor + this.dragRegion.hide(); + this.dragRegion.showDelayed(50); + } else { + this.title.style('visibility', null); + } + } } private onActiveEditorChange(): void { @@ -269,6 +279,20 @@ export class TitlebarPart extends Part implements ITitleService { } } + // Menubar: the menubar part which is responsible for populating both the custom and native menubars + this.menubarPart = this.instantiationService.createInstance(MenubarPart, 'workbench.parts.menubar'); + this.menubar = $(this.titleContainer).div({ + 'class': ['part', 'menubar'], + id: 'workbench.parts.menubar', + role: 'menubar' + }); + + this.menubarPart.create(this.menubar.getHTMLElement()); + + if (!isMacintosh) { + this._register(this.menubarPart.onVisibilityChange(e => this.onMenubarVisibilityChanged(e))); + } + // Title this.title = $(this.titleContainer).div({ class: 'window-title' }); if (this.pendingTitle) { @@ -278,7 +302,7 @@ export class TitlebarPart extends Part implements ITitleService { } // Maximize/Restore on doubleclick - this.titleContainer.on(EventType.DBLCLICK, (e) => { + this.title.on(EventType.DBLCLICK, (e) => { EventHelper.stop(e); this.onTitleDoubleclick(); @@ -438,88 +462,84 @@ export class TitlebarPart extends Part implements ITitleService { } } - private updateLayout() { - - // To prevent zooming we need to adjust the font size with the zoom factor + private updateLayout(dimension: Dimension) { + // Store initital title sizing if we need to prevent zooming if (typeof this.initialSizing.titleFontSize !== 'number') { - this.initialSizing.titleFontSize = parseInt(this.titleContainer.getComputedStyle().fontSize, 10); + this.initialSizing.titleFontSize = parseInt(this.title.getComputedStyle().fontSize, 10); } if (typeof this.initialSizing.titlebarHeight !== 'number') { - this.initialSizing.titlebarHeight = parseInt(this.titleContainer.getComputedStyle().height, 10); + this.initialSizing.titlebarHeight = parseInt(this.title.getComputedStyle().height, 10); } - // Set font size and line height - const newHeight = this.initialSizing.titlebarHeight / getZoomFactor(); - this.titleContainer.style({ - fontSize: `${this.initialSizing.titleFontSize / getZoomFactor()}px`, - 'line-height': `${newHeight}px` - }); + // Only prevent zooming behavior on macOS or when the menubar is not visible + if (isMacintosh || this.configurationService.getValue('window.menuBarVisibility') === 'hidden') { + // To prevent zooming we need to adjust the font size with the zoom factor + const newHeight = this.initialSizing.titlebarHeight / getZoomFactor(); + this.title.style({ + fontSize: `${this.initialSizing.titleFontSize / getZoomFactor()}px`, + 'line-height': `${newHeight}px` + }); - // Windows/Linux specific layout - if (isWindows || isLinux) { - if (typeof this.initialSizing.controlsWidth !== 'number') { - this.initialSizing.controlsWidth = parseInt(this.windowControls.getComputedStyle().width, 10); + // Windows/Linux specific layout + if (isWindows || isLinux) { + if (typeof this.initialSizing.controlsWidth !== 'number') { + this.initialSizing.controlsWidth = parseInt(this.windowControls.getComputedStyle().width, 10); + } + + if (typeof this.initialSizing.appIconWidth !== 'number') { + this.initialSizing.appIconWidth = parseInt(this.appIcon.getComputedStyle().width, 10); + } + + if (typeof this.initialSizing.appIconSize !== 'number') { + this.initialSizing.appIconSize = parseInt(this.appIcon.getComputedStyle().backgroundSize, 10); + } + + const currentAppIconHeight = parseInt(this.appIcon.getComputedStyle().height, 10); + const newControlsWidth = this.initialSizing.controlsWidth / getZoomFactor(); + const newAppIconWidth = this.initialSizing.appIconWidth / getZoomFactor(); + const newAppIconSize = this.initialSizing.appIconSize / getZoomFactor(); + + // Adjust app icon mimic menubar + this.appIcon.style({ + 'width': `${newAppIconWidth}px`, + 'background-size': `${newAppIconSize}px`, + 'padding-top': `${(newHeight - currentAppIconHeight) / 2.0}px`, + 'padding-bottom': `${(newHeight - currentAppIconHeight) / 2.0}px` + }); + + // Adjust windows controls + this.windowControls.style({ + 'width': `${newControlsWidth}px` + }); } + } else { + // We need to undo zoom prevention + this.title.style({ + fontSize: null, + 'line-height': null + }); - if (typeof this.initialSizing.appIconWidth !== 'number') { - this.initialSizing.appIconWidth = parseInt(this.appIcon.getComputedStyle().width, 10); - } - - if (typeof this.initialSizing.appIconSize !== 'number') { - this.initialSizing.appIconSize = parseInt(this.appIcon.getComputedStyle().backgroundSize, 10); - } - - const currentAppIconHeight = parseInt(this.appIcon.getComputedStyle().height, 10); - const newControlsWidth = this.initialSizing.controlsWidth / getZoomFactor(); - const newAppIconWidth = this.initialSizing.appIconWidth / getZoomFactor(); - const newAppIconSize = this.initialSizing.appIconSize / getZoomFactor(); - - if (!this.menubarWidth) { - this.menubarWidth = 0; - } - - // If we can center the title in the titlebar, we should - const fullWidth = parseInt(this.titleContainer.getComputedStyle().width, 10); - const titleWidth = parseInt(this.title.getComputedStyle().width, 10); - const freeSpace = fullWidth - newAppIconWidth - newControlsWidth - titleWidth; - const leftSideTitle = newAppIconWidth + (freeSpace / 2); - - let bufferWidth = this.menubarWidth; - if (newAppIconWidth + this.menubarWidth < leftSideTitle) { - bufferWidth = 0; - } - - // Adjust app icon mimic menubar this.appIcon.style({ - 'width': `${newAppIconWidth}px`, - 'background-size': `${newAppIconSize}px`, - 'margin-right': `${newControlsWidth - newAppIconWidth + bufferWidth}px`, - 'padding-top': `${(newHeight - currentAppIconHeight) / 2.0}px`, - 'padding-bottom': `${(newHeight - currentAppIconHeight) / 2.0}px` + 'width': null, + 'background-size': null, + 'padding-top': null, + 'padding-bottom': null }); - // Adjust windows controls this.windowControls.style({ - 'width': `${newControlsWidth}px` + 'width': null }); + } - // Hide title when toggling menu bar - let menubarToggled = this.configurationService.getValue('window.menuBarVisibility') === 'toggle'; - if (menubarToggled && this.menubarWidth) { - this.title.style('visibility', 'hidden'); - - // Hack to fix issue #52522 with layered webkit-app-region elements appearing under cursor - this.dragRegion.hide(); - this.dragRegion.showDelayed(50); - } else { - this.title.style('visibility', null); - } + if (this.menubarPart) { + const menubarDimension = new Dimension(undefined, dimension.height); + this.menubarPart.layout(menubarDimension); } } layout(dimension: Dimension): Dimension[] { - this.updateLayout(); + this.updateLayout(dimension); return super.layout(dimension); } diff --git a/src/vs/workbench/electron-browser/workbench.ts b/src/vs/workbench/electron-browser/workbench.ts index 8aa8bdc1bad..7b1a3b7212b 100644 --- a/src/vs/workbench/electron-browser/workbench.ts +++ b/src/vs/workbench/electron-browser/workbench.ts @@ -30,7 +30,6 @@ import { SidebarPart } from 'vs/workbench/browser/parts/sidebar/sidebarPart'; import { PanelPart } from 'vs/workbench/browser/parts/panel/panelPart'; import { StatusbarPart } from 'vs/workbench/browser/parts/statusbar/statusbarPart'; import { TitlebarPart } from 'vs/workbench/browser/parts/titlebar/titlebarPart'; -import { MenubarPart } from 'vs/workbench/browser/parts/menubar/menubarPart'; import { EditorPart } from 'vs/workbench/browser/parts/editor/editorPart'; import { WorkbenchLayout } from 'vs/workbench/browser/layout'; import { IActionBarRegistry, Extensions as ActionBarExtensions } from 'vs/workbench/browser/actions'; @@ -152,8 +151,7 @@ const Identifiers = { SIDEBAR_PART: 'workbench.parts.sidebar', PANEL_PART: 'workbench.parts.panel', EDITOR_PART: 'workbench.parts.editor', - STATUSBAR_PART: 'workbench.parts.statusbar', - MENUBAR_PART: 'workbench.parts.menubar' + STATUSBAR_PART: 'workbench.parts.statusbar' }; function getWorkbenchStateString(state: WorkbenchState): string { @@ -210,7 +208,6 @@ export class Workbench extends Disposable implements IPartService { private workbenchLayout: WorkbenchLayout; private titlebarPart: TitlebarPart; - private menubarPart: MenubarPart; private activitybarPart: ActivitybarPart; private sidebarPart: SidebarPart; private panelPart: PanelPart; @@ -418,9 +415,6 @@ export class Workbench extends Disposable implements IPartService { // History serviceCollection.set(IHistoryService, new SyncDescriptor(HistoryService)); - // Menubar - this.menubarPart = this.instantiationService.createInstance(MenubarPart, Identifiers.MENUBAR_PART); - // Backup File Service if (this.workbenchParams.configuration.backupPath) { this.backupFileService = this.instantiationService.createInstance(BackupFileService, this.workbenchParams.configuration.backupPath); @@ -952,7 +946,6 @@ export class Workbench extends Disposable implements IPartService { this.workbench.getHTMLElement(), { titlebar: this.titlebarPart, - menubar: this.menubarPart, activitybar: this.activitybarPart, editor: this.editorPart, sidebar: this.sidebarPart, @@ -989,7 +982,6 @@ export class Workbench extends Disposable implements IPartService { // Create Parts this.createTitlebarPart(); - this.createMenubarPart(); this.createActivityBarPart(); this.createSidebarPart(); this.createEditorPart(); @@ -1013,20 +1005,6 @@ export class Workbench extends Disposable implements IPartService { this.titlebarPart.create(titlebarContainer.getHTMLElement()); } - private createMenubarPart(): void { - const menubarContainer = $(this.workbench).div({ - 'class': ['part', 'menubar'], - id: Identifiers.MENUBAR_PART, - role: 'menubar' - }); - - this.menubarPart.create(menubarContainer.getHTMLElement()); - - this._register(this.menubarPart.onVisibilityChange((dimension => { - this._onMenubarVisibilityChange.fire(dimension); - }))); - } - private createActivityBarPart(): void { const activitybarPartContainer = $(this.workbench) .div({ @@ -1141,9 +1119,6 @@ export class Workbench extends Disposable implements IPartService { private _onTitleBarVisibilityChange: Emitter = this._register(new Emitter()); get onTitleBarVisibilityChange(): Event { return this._onTitleBarVisibilityChange.event; } - private _onMenubarVisibilityChange: Emitter = this._register(new Emitter()); - get onMenubarVisibilityChange(): Event { return this._onMenubarVisibilityChange.event; } - get onEditorLayout(): Event { return this.editorPart.onDidLayout; } isCreated(): boolean { @@ -1166,9 +1141,6 @@ export class Workbench extends Disposable implements IPartService { case Parts.TITLEBAR_PART: container = this.titlebarPart.getContainer(); break; - case Parts.MENUBAR_PART: - container = this.menubarPart.getContainer(); - break; case Parts.ACTIVITYBAR_PART: container = this.activitybarPart.getContainer(); break; @@ -1192,9 +1164,7 @@ export class Workbench extends Disposable implements IPartService { isVisible(part: Parts): boolean { switch (part) { case Parts.TITLEBAR_PART: - return this.getCustomTitleBarStyle() === 'custom' && !browser.isFullscreen(); - case Parts.MENUBAR_PART: - return !isMacintosh && this.isVisible(Parts.TITLEBAR_PART) && !(this.menubarVisibility === 'hidden' || (this.menubarVisibility === 'default' && browser.isFullscreen())); + return this.getCustomTitleBarStyle() === 'custom' && (!browser.isFullscreen() || this.menubarVisibility === 'visible' || this.menubarVisibility === 'toggle'); case Parts.SIDEBAR_PART: return !this.sideBarHidden; case Parts.PANEL_PART: @@ -1473,6 +1443,10 @@ export class Workbench extends Disposable implements IPartService { } } + getMenubarVisibility(): MenuBarVisibility { + return this.menubarVisibility; + } + getPanelPosition(): Position { return this.panelPosition; } diff --git a/src/vs/workbench/services/part/common/partService.ts b/src/vs/workbench/services/part/common/partService.ts index e157b37687f..887597600b8 100644 --- a/src/vs/workbench/services/part/common/partService.ts +++ b/src/vs/workbench/services/part/common/partService.ts @@ -7,6 +7,7 @@ import { TPromise } from 'vs/base/common/winjs.base'; import { createDecorator, ServiceIdentifier } from 'vs/platform/instantiation/common/instantiation'; import { Event } from 'vs/base/common/event'; +import { MenuBarVisibility } from 'vs/platform/windows/common/windows'; export enum Parts { ACTIVITYBAR_PART, @@ -44,11 +45,6 @@ export interface IPartService { */ onTitleBarVisibilityChange: Event; - /** - * Emits when the visibility of the menubar changes. - */ - onMenubarVisibilityChange: Event; - /** * Emits when the editor part's layout changes. */ @@ -115,6 +111,11 @@ export interface IPartService { */ getSideBarPosition(): Position; + /** + * Gets the current menubar visibility. + */ + getMenubarVisibility(): MenuBarVisibility; + /** * Gets the current panel position. Note that the panel can be hidden too. */ diff --git a/src/vs/workbench/test/workbenchTestServices.ts b/src/vs/workbench/test/workbenchTestServices.ts index 55ac4b47cc6..8cf78a8f658 100644 --- a/src/vs/workbench/test/workbenchTestServices.ts +++ b/src/vs/workbench/test/workbenchTestServices.ts @@ -42,7 +42,7 @@ import { IModeService } from 'vs/editor/common/services/modeService'; import { IHistoryService } from 'vs/workbench/services/history/common/history'; import { IInstantiationService, ServicesAccessor, ServiceIdentifier } from 'vs/platform/instantiation/common/instantiation'; import { TestConfigurationService } from 'vs/platform/configuration/test/common/testConfigurationService'; -import { IWindowsService, IWindowService, INativeOpenDialogOptions, IEnterWorkspaceResult, IMessageBoxResult, IWindowConfiguration } from 'vs/platform/windows/common/windows'; +import { IWindowsService, IWindowService, INativeOpenDialogOptions, IEnterWorkspaceResult, IMessageBoxResult, IWindowConfiguration, MenuBarVisibility } from 'vs/platform/windows/common/windows'; import { TestWorkspace } from 'vs/platform/workspace/test/common/testWorkspace'; import { createTextBufferFactory } from 'vs/editor/common/model/textModel'; import { IEnvironmentService } from 'vs/platform/environment/common/environment'; @@ -453,6 +453,10 @@ export class TestPartService implements IPartService { return false; } + public getMenubarVisibility(): MenuBarVisibility { + return null; + } + public getSideBarPosition() { return 0; } From 41c9a6ac8e0f714c092c64a2f6f4b930820b47d4 Mon Sep 17 00:00:00 2001 From: Rob Lourens Date: Fri, 27 Jul 2018 09:16:29 -0700 Subject: [PATCH 0243/1276] Search provider interface methods required --- src/vs/vscode.proposed.d.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/vs/vscode.proposed.d.ts b/src/vs/vscode.proposed.d.ts index 70e0640de35..efd2ed56157 100644 --- a/src/vs/vscode.proposed.d.ts +++ b/src/vs/vscode.proposed.d.ts @@ -165,7 +165,7 @@ declare module 'vscode' { * @param progress A progress callback that must be invoked for all results. * @param token A cancellation token. */ - provideTextSearchResults?(query: TextSearchQuery, options: TextSearchOptions, progress: Progress, token: CancellationToken): Thenable; + provideTextSearchResults(query: TextSearchQuery, options: TextSearchOptions, progress: Progress, token: CancellationToken): Thenable; } /** @@ -179,7 +179,7 @@ declare module 'vscode' { * @param progress A progress callback that must be invoked for all results. * @param token A cancellation token. */ - provideFileSearchResults?(query: FileSearchQuery, options: FileSearchOptions, progress: Progress, token: CancellationToken): Thenable; + provideFileSearchResults(query: FileSearchQuery, options: FileSearchOptions, progress: Progress, token: CancellationToken): Thenable; } /** From f1756b427f64e226dca85a93dc5ef2087edbfbe3 Mon Sep 17 00:00:00 2001 From: Rob Lourens Date: Fri, 27 Jul 2018 09:18:42 -0700 Subject: [PATCH 0244/1276] Settings editor filterByTag - focus search input and add a space after tag --- src/vs/workbench/parts/preferences/browser/settingsEditor2.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/vs/workbench/parts/preferences/browser/settingsEditor2.ts b/src/vs/workbench/parts/preferences/browser/settingsEditor2.ts index 5d6ed7375b6..8ec337a949c 100644 --- a/src/vs/workbench/parts/preferences/browser/settingsEditor2.ts +++ b/src/vs/workbench/parts/preferences/browser/settingsEditor2.ts @@ -182,7 +182,8 @@ export class SettingsEditor2 extends BaseEditor { filterByTag(tag: string): void { if (this.searchWidget) { - this.searchWidget.setValue(`@tag:${tag}`); + this.searchWidget.focus(); + this.searchWidget.setValue(`@tag:${tag} `); } } From cde60042116f192d06b9e37e2a82593a95502a89 Mon Sep 17 00:00:00 2001 From: Rob Lourens Date: Fri, 27 Jul 2018 09:26:06 -0700 Subject: [PATCH 0245/1276] "Edit in settings.json" searches for the selected setting --- .../parts/preferences/browser/settingsEditor2.ts | 9 ++++++++- .../workbench/parts/preferences/browser/settingsTree.ts | 9 ++++----- 2 files changed, 12 insertions(+), 6 deletions(-) diff --git a/src/vs/workbench/parts/preferences/browser/settingsEditor2.ts b/src/vs/workbench/parts/preferences/browser/settingsEditor2.ts index 8ec337a949c..e8df1004e74 100644 --- a/src/vs/workbench/parts/preferences/browser/settingsEditor2.ts +++ b/src/vs/workbench/parts/preferences/browser/settingsEditor2.ts @@ -41,6 +41,7 @@ import { DefaultSettingsEditorModel } from 'vs/workbench/services/preferences/co import { editorBackground, foreground } from 'vs/platform/theme/common/colorRegistry'; import { settingsHeaderForeground } from 'vs/workbench/parts/preferences/browser/settingsWidgets'; import { Separator } from 'vs/base/browser/ui/actionbar/actionbar'; +import { PreferencesEditor } from 'vs/workbench/parts/preferences/browser/preferencesEditor'; const $ = DOM.$; @@ -351,7 +352,13 @@ export class SettingsEditor2 extends BaseEditor { const renderer = this.instantiationService.createInstance(SettingsRenderer, this.settingsTreeContainer); this._register(renderer.onDidChangeSetting(e => this.onDidChangeSetting(e.key, e.value))); - this._register(renderer.onDidOpenSettings(() => this.openSettingsFile())); + this._register(renderer.onDidOpenSettings(settingKey => { + this.openSettingsFile().then(editor => { + if (editor instanceof PreferencesEditor && settingKey) { + editor.focusSearch(settingKey); + } + }); + })); this._register(renderer.onDidClickSettingLink(settingName => this.revealSetting(settingName))); this.settingsTree = this.instantiationService.createInstance(SettingsTree, diff --git a/src/vs/workbench/parts/preferences/browser/settingsTree.ts b/src/vs/workbench/parts/preferences/browser/settingsTree.ts index 85fca4d80cc..e1dfd2f0e4f 100644 --- a/src/vs/workbench/parts/preferences/browser/settingsTree.ts +++ b/src/vs/workbench/parts/preferences/browser/settingsTree.ts @@ -537,8 +537,8 @@ export class SettingsRenderer implements ITreeRenderer { private readonly _onDidChangeSetting: Emitter = new Emitter(); public readonly onDidChangeSetting: Event = this._onDidChangeSetting.event; - private readonly _onDidOpenSettings: Emitter = new Emitter(); - public readonly onDidOpenSettings: Event = this._onDidOpenSettings.event; + private readonly _onDidOpenSettings: Emitter = new Emitter(); + public readonly onDidOpenSettings: Event = this._onDidOpenSettings.event; private readonly _onDidClickSettingLink: Emitter = new Emitter(); public readonly onDidClickSettingLink: Event = this._onDidClickSettingLink.event; @@ -917,7 +917,7 @@ export class SettingsRenderer implements ITreeRenderer { const openSettingsButton = new Button(common.controlElement, { title: true, buttonBackground: null, buttonHoverBackground: null }); common.toDispose.push(openSettingsButton); - common.toDispose.push(openSettingsButton.onDidClick(() => this._onDidOpenSettings.fire())); + common.toDispose.push(openSettingsButton.onDidClick(() => template.onChange(null))); openSettingsButton.label = localize('editInSettingsJson', "Edit in settings.json"); openSettingsButton.element.classList.add('edit-in-settings-button'); @@ -1126,8 +1126,7 @@ export class SettingsRenderer implements ITreeRenderer { private renderComplexSetting(dataElement: SettingsTreeSettingElement, isSelected: boolean, template: ISettingComplexItemTemplate): void { template.button.element.tabIndex = isSelected ? 0 : -1; - - template.onChange = () => this._onDidOpenSettings.fire(); + template.onChange = () => this._onDidOpenSettings.fire(dataElement.setting.key); } disposeTemplate(tree: ITree, templateId: string, template: IDisposableTemplate): void { From 351f3f127f5e20a84973b4fb3a59ad8f609e859a Mon Sep 17 00:00:00 2001 From: Rob Lourens Date: Fri, 27 Jul 2018 10:21:38 -0700 Subject: [PATCH 0246/1276] Don't run remote search in old settings editor when local search found an exact match --- .../preferences/browser/preferencesEditor.ts | 26 ++++++++++++++----- .../electron-browser/preferencesSearch.ts | 26 ++++++++++++++----- .../preferences/common/preferences.ts | 2 ++ 3 files changed, 41 insertions(+), 13 deletions(-) diff --git a/src/vs/workbench/parts/preferences/browser/preferencesEditor.ts b/src/vs/workbench/parts/preferences/browser/preferencesEditor.ts index 1875e5070fc..3f1ba5f6ebd 100644 --- a/src/vs/workbench/parts/preferences/browser/preferencesEditor.ts +++ b/src/vs/workbench/parts/preferences/browser/preferencesEditor.ts @@ -242,7 +242,7 @@ export class PreferencesEditor extends BaseEditor { private triggerSearch(query: string): TPromise { if (query) { return TPromise.join([ - this.localSearchDelayer.trigger(() => this.preferencesRenderers.localFilterPreferences(query)), + this.localSearchDelayer.trigger(() => this.preferencesRenderers.localFilterPreferences(query).then(() => { })), this.remoteSearchThrottle.trigger(() => TPromise.wrap(this.progressService.showWhile(this.preferencesRenderers.remoteSearchPreferences(query), 500))) ]) as TPromise; } else { @@ -436,8 +436,10 @@ class PreferencesRenderersController extends Disposable { } private async _onEditableContentDidChange(): Promise { - await this.localFilterPreferences(this._lastQuery, true); - await this.remoteSearchPreferences(this._lastQuery, true); + const foundExactMatch = await this.localFilterPreferences(this._lastQuery, true); + if (!foundExactMatch) { + await this.remoteSearchPreferences(this._lastQuery, true); + } } onHidden(): void { @@ -446,6 +448,11 @@ class PreferencesRenderersController extends Disposable { } remoteSearchPreferences(query: string, updateCurrentResults?: boolean): TPromise { + if (this.lastFilterResult && this.lastFilterResult.exactMatch) { + // Skip and clear remote search + query = ''; + } + if (this._remoteFilterInProgress && this._remoteFilterInProgress.cancel) { // Resolved/rejected promises have no .cancel() this._remoteFilterInProgress.cancel(); @@ -466,7 +473,7 @@ class PreferencesRenderersController extends Disposable { }); } - localFilterPreferences(query: string, updateCurrentResults?: boolean): TPromise { + localFilterPreferences(query: string, updateCurrentResults?: boolean): TPromise { if (this._settingsNavigator) { this._settingsNavigator.reset(); } @@ -475,14 +482,15 @@ class PreferencesRenderersController extends Disposable { return this.filterOrSearchPreferences(query, this._currentLocalSearchProvider, 'filterResult', nls.localize('filterResult', "Filtered Results"), 0, updateCurrentResults); } - private filterOrSearchPreferences(query: string, searchProvider: ISearchProvider, groupId: string, groupLabel: string, groupOrder: number, editableContentOnly?: boolean): TPromise { + private filterOrSearchPreferences(query: string, searchProvider: ISearchProvider, groupId: string, groupLabel: string, groupOrder: number, editableContentOnly?: boolean): TPromise { this._lastQuery = query; - const filterPs: TPromise[] = [this._filterOrSearchPreferences(query, this.editablePreferencesRenderer, searchProvider, groupId, groupLabel, groupOrder)]; + const filterPs: TPromise[] = [this._filterOrSearchPreferences(query, this.editablePreferencesRenderer, searchProvider, groupId, groupLabel, groupOrder)]; if (!editableContentOnly) { filterPs.push( this._filterOrSearchPreferences(query, this.defaultPreferencesRenderer, searchProvider, groupId, groupLabel, groupOrder)); - filterPs.push(this.searchAllSettingsTargets(query, searchProvider, groupId, groupLabel, groupOrder)); + filterPs.push( + this.searchAllSettingsTargets(query, searchProvider, groupId, groupLabel, groupOrder).then(() => null)); } return TPromise.join(filterPs).then(results => { @@ -494,6 +502,8 @@ class PreferencesRenderersController extends Disposable { this.consolidateAndUpdate(defaultFilterResult, editableFilterResult); this._lastFilterResult = defaultFilterResult; + + return defaultFilterResult && defaultFilterResult.exactMatch; }); } @@ -624,8 +634,10 @@ class PreferencesRenderersController extends Disposable { if (filterResult) { filterResult.query = filter; + filterResult.exactMatch = searchResult && searchResult.exactMatch; } + return filterResult; }); } diff --git a/src/vs/workbench/parts/preferences/electron-browser/preferencesSearch.ts b/src/vs/workbench/parts/preferences/electron-browser/preferencesSearch.ts index f0037613a93..ac1fc3c1c1b 100644 --- a/src/vs/workbench/parts/preferences/electron-browser/preferencesSearch.ts +++ b/src/vs/workbench/parts/preferences/electron-browser/preferencesSearch.ts @@ -90,6 +90,9 @@ export class PreferencesSearchService extends Disposable implements IPreferences } export class LocalSearchProvider implements ISearchProvider { + static readonly EXACT_MATCH_SCORE = 10000; + static readonly START_SCORE = 1000; + constructor(private _filter: string) { // Remove " and : which are likely to be copypasted as part of a setting name. // Leave other special characters which the user might want to search for. @@ -104,25 +107,36 @@ export class LocalSearchProvider implements ISearchProvider { return TPromise.wrap(null); } - let score = 1000; // Sort is not stable + let orderedScore = LocalSearchProvider.START_SCORE; // Sort is not stable const settingMatcher = (setting: ISetting) => { const matches = new SettingMatches(this._filter, setting, true, true, (filter, setting) => preferencesModel.findValueMatches(filter, setting)).matches; + const score = this._filter === setting.key ? + LocalSearchProvider.EXACT_MATCH_SCORE : + orderedScore--; + return matches && matches.length ? { matches, - score: score-- + score } : null; }; const filterMatches = preferencesModel.filterSettings(this._filter, this.getGroupFilter(this._filter), settingMatcher); - return TPromise.wrap({ - filterMatches - }); + if (filterMatches[0] && filterMatches[0].score === LocalSearchProvider.EXACT_MATCH_SCORE) { + return TPromise.wrap({ + filterMatches: filterMatches.slice(0, 1), + exactMatch: true + }); + } else { + return TPromise.wrap({ + filterMatches + }); + } } private getGroupFilter(filter: string): IGroupFilter { - const regex = strings.createRegExp(this._filter, false, { global: true }); + const regex = strings.createRegExp(filter, false, { global: true }); return (group: ISettingsGroup) => { return regex.test(group.title); }; diff --git a/src/vs/workbench/services/preferences/common/preferences.ts b/src/vs/workbench/services/preferences/common/preferences.ts index ddfe928f57b..45f0caf3b35 100644 --- a/src/vs/workbench/services/preferences/common/preferences.ts +++ b/src/vs/workbench/services/preferences/common/preferences.ts @@ -59,6 +59,7 @@ export interface IExtensionSetting extends ISetting { export interface ISearchResult { filterMatches: ISettingMatch[]; + exactMatch?: boolean; metadata?: IFilterMetadata; } @@ -75,6 +76,7 @@ export interface IFilterResult { allGroups: ISettingsGroup[]; matches: IRange[]; metadata?: IStringDictionary; + exactMatch?: boolean; } export interface ISettingMatch { From 577ac23d6fc4d71dc3b73853a959c7b638ed8a3c Mon Sep 17 00:00:00 2001 From: SteVen Batten <6561887+sbatten@users.noreply.github.com> Date: Fri, 27 Jul 2018 10:31:47 -0700 Subject: [PATCH 0247/1276] fixes #55221 --- src/vs/base/browser/ui/actionbar/actionbar.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/vs/base/browser/ui/actionbar/actionbar.ts b/src/vs/base/browser/ui/actionbar/actionbar.ts index 9a121effc1e..8f3ba0aca67 100644 --- a/src/vs/base/browser/ui/actionbar/actionbar.ts +++ b/src/vs/base/browser/ui/actionbar/actionbar.ts @@ -408,8 +408,6 @@ export class ActionBar implements IActionRunner { this.domNode = document.createElement('div'); this.domNode.className = 'monaco-action-bar'; - this.domNode.tabIndex = 0; - if (options.animated !== false) { DOM.addClass(this.domNode, 'animated'); } @@ -499,6 +497,8 @@ export class ActionBar implements IActionRunner { } if (this.options.isMenu) { + this.domNode.tabIndex = 0; + $(this.actionsList).on(DOM.EventType.MOUSE_OVER, (e) => { let target = e.target as HTMLElement; if (!target || !DOM.isAncestor(target, this.actionsList) || target === this.actionsList) { From 24ea61972078f510d06a769c136b455d7d93a11c Mon Sep 17 00:00:00 2001 From: SteVen Batten <6561887+sbatten@users.noreply.github.com> Date: Fri, 27 Jul 2018 10:43:20 -0700 Subject: [PATCH 0248/1276] fix hover and outline behavior (#55200) --- src/vs/base/browser/ui/actionbar/actionbar.ts | 20 +++++++++--- src/vs/base/browser/ui/menu/menu.ts | 31 ++++++------------- .../parts/menubar/media/menubarpart.css | 10 ++++-- 3 files changed, 32 insertions(+), 29 deletions(-) diff --git a/src/vs/base/browser/ui/actionbar/actionbar.ts b/src/vs/base/browser/ui/actionbar/actionbar.ts index 8f3ba0aca67..dd85d1c0645 100644 --- a/src/vs/base/browser/ui/actionbar/actionbar.ts +++ b/src/vs/base/browser/ui/actionbar/actionbar.ts @@ -499,6 +499,15 @@ export class ActionBar implements IActionRunner { if (this.options.isMenu) { this.domNode.tabIndex = 0; + $(this.domNode).on(DOM.EventType.MOUSE_OUT, (e) => { + let relatedTarget = (e as MouseEvent).relatedTarget as HTMLElement; + if (!DOM.isAncestor(relatedTarget, this.domNode)) { + this.focusedItem = undefined; + this.updateFocus(); + e.stopPropagation(); + } + }); + $(this.actionsList).on(DOM.EventType.MOUSE_OVER, (e) => { let target = e.target as HTMLElement; if (!target || !DOM.isAncestor(target, this.actionsList) || target === this.actionsList) { @@ -509,7 +518,7 @@ export class ActionBar implements IActionRunner { target = target.parentElement; } - if (DOM.hasClass(target, 'action-item') && !DOM.hasClass(target, 'disabled')) { + if (DOM.hasClass(target, 'action-item')) { const lastFocusedItem = this.focusedItem; this.setFocusedItem(target); @@ -730,7 +739,6 @@ export class ActionBar implements IActionRunner { private updateFocus(fromRight?: boolean): void { if (typeof this.focusedItem === 'undefined') { this.domNode.focus(); - return; } for (let i = 0; i < this.items.length; i++) { @@ -739,8 +747,12 @@ export class ActionBar implements IActionRunner { let actionItem = item; if (i === this.focusedItem) { - if (types.isFunction(actionItem.focus)) { - actionItem.focus(fromRight); + if (types.isFunction(actionItem.isEnabled)) { + if (actionItem.isEnabled() && types.isFunction(actionItem.focus)) { + actionItem.focus(fromRight); + } else { + this.domNode.focus(); + } } } else { if (types.isFunction(actionItem.blur)) { diff --git a/src/vs/base/browser/ui/menu/menu.ts b/src/vs/base/browser/ui/menu/menu.ts index f6698809a31..ef82b63ddad 100644 --- a/src/vs/base/browser/ui/menu/menu.ts +++ b/src/vs/base/browser/ui/menu/menu.ts @@ -12,7 +12,7 @@ import { IActionRunner, IAction, Action } from 'vs/base/common/actions'; import { ActionBar, IActionItemProvider, ActionsOrientation, Separator, ActionItem, IActionItemOptions, BaseActionItem } from 'vs/base/browser/ui/actionbar/actionbar'; import { ResolvedKeybinding, KeyCode } from 'vs/base/common/keyCodes'; import { Event } from 'vs/base/common/event'; -import { addClass, EventType, EventHelper, EventLike, removeTabIndexAndUpdateFocus } from 'vs/base/browser/dom'; +import { addClass, EventType, EventHelper, EventLike, removeTabIndexAndUpdateFocus, isAncestor } from 'vs/base/browser/dom'; import { StandardKeyboardEvent } from 'vs/base/browser/keyboardEvent'; import { $, Builder } from 'vs/base/browser/builder'; import { RunOnceScheduler } from 'vs/base/common/async'; @@ -241,8 +241,6 @@ class MenuActionItem extends BaseActionItem { class SubmenuActionItem extends MenuActionItem { private mysubmenu: Menu; private submenuContainer: Builder; - private mouseOver: boolean; - private showScheduler: RunOnceScheduler; private hideScheduler: RunOnceScheduler; constructor( @@ -253,16 +251,9 @@ class SubmenuActionItem extends MenuActionItem { ) { super(action, action, { label: true, isMenu: true }); - this.showScheduler = new RunOnceScheduler(() => { - if (this.mouseOver) { - this.cleanupExistingSubmenu(false); - this.createSubmenu(false); - } - }, 250); - this.hideScheduler = new RunOnceScheduler(() => { - if (!this.mouseOver && this.parentData.submenu === this.mysubmenu) { - this.parentData.parent.focus(); + if ((!isAncestor(document.activeElement, this.builder.getHTMLElement()) && this.parentData.submenu === this.mysubmenu)) { + this.parentData.parent.focus(false); this.cleanupExistingSubmenu(true); } }, 750); @@ -292,17 +283,14 @@ class SubmenuActionItem extends MenuActionItem { }); $(this.builder).on(EventType.MOUSE_OVER, (e) => { - if (!this.mouseOver) { - this.mouseOver = true; - - this.showScheduler.schedule(); - } + this.cleanupExistingSubmenu(false); + this.createSubmenu(false); }); - $(this.builder).on(EventType.MOUSE_LEAVE, (e) => { - this.mouseOver = false; - - this.hideScheduler.schedule(); + $(this.builder).on(EventType.FOCUS_OUT, (e) => { + if (!isAncestor(document.activeElement, this.builder.getHTMLElement())) { + this.hideScheduler.schedule(); + } }); } @@ -368,7 +356,6 @@ class SubmenuActionItem extends MenuActionItem { super.dispose(); this.hideScheduler.dispose(); - this.showScheduler.dispose(); if (this.mysubmenu) { this.mysubmenu.dispose(); diff --git a/src/vs/workbench/browser/parts/menubar/media/menubarpart.css b/src/vs/workbench/browser/parts/menubar/media/menubarpart.css index f18a71b0435..39912f3dd35 100644 --- a/src/vs/workbench/browser/parts/menubar/media/menubarpart.css +++ b/src/vs/workbench/browser/parts/menubar/media/menubarpart.css @@ -26,19 +26,23 @@ zoom: 1; } -.menubar-menu-items-holder { +.monaco-workbench .part.menubar .menubar-menu-items-holder { position: absolute; left: 0px; opacity: 1; z-index: 2000; } -.menubar-menu-items-holder.monaco-menu-container { +.monaco-workbench .part.menubar .menubar-menu-items-holder.monaco-menu-container { font-family: "Segoe WPC", "Segoe UI", ".SFNSDisplay-Light", "SFUIText-Light", "HelveticaNeue-Light", sans-serif, "Droid Sans Fallback"; outline: 0; border: none; } -.menubar-menu-items-holder.monaco-menu-container :focus { +.monaco-workbench .part.menubar .menubar-menu-items-holder.monaco-menu-container :focus { outline: 0; +} + +.hc-black .monaco-workbench .part.menubar .menubar-menu-items-holder.monaco-menu-container { + border: 2px solid #6FC3DF; } \ No newline at end of file From ca35204e112820c0ee40795b75d82cca103ca8af Mon Sep 17 00:00:00 2001 From: Rob Lourens Date: Fri, 27 Jul 2018 11:15:00 -0700 Subject: [PATCH 0249/1276] Fix #55164 - opening setting.json from new editor on windows --- .../preferences/browser/settingsEditor2.ts | 21 ++++++++++++------- 1 file changed, 13 insertions(+), 8 deletions(-) diff --git a/src/vs/workbench/parts/preferences/browser/settingsEditor2.ts b/src/vs/workbench/parts/preferences/browser/settingsEditor2.ts index e8df1004e74..01edb6072c1 100644 --- a/src/vs/workbench/parts/preferences/browser/settingsEditor2.ts +++ b/src/vs/workbench/parts/preferences/browser/settingsEditor2.ts @@ -214,7 +214,7 @@ export class SettingsEditor2 extends BaseEditor { this.settingsTargetsWidget.settingsTarget = ConfigurationTarget.USER; this.settingsTargetsWidget.onDidTargetChange(() => { this.viewState.settingsTarget = this.settingsTargetsWidget.settingsTarget; - this.toolbar.context = this.settingsTargetsWidget.settingsTarget; + this.toolbar.context = { target: this.settingsTargetsWidget.settingsTarget }; this.settingsTreeModel.update(); this.refreshTreeAndMaintainFocus(); @@ -245,7 +245,7 @@ export class SettingsEditor2 extends BaseEditor { this.instantiationService.createInstance(OpenSettingsAction) ]; this.toolbar.setActions([], actions)(); - this.toolbar.context = this.settingsTargetsWidget.settingsTarget; + this.toolbar.context = { target: this.settingsTargetsWidget.settingsTarget }; } private revealSetting(settingName: string): void { @@ -810,6 +810,10 @@ export class SettingsEditor2 extends BaseEditor { } } +interface ISettingsToolbarContext { + target: SettingsTarget; +} + class OpenSettingsAction extends Action { static readonly ID = 'settings.openSettingsJson'; static readonly LABEL = localize('openSettingsJsonLabel', "Open settings.json"); @@ -821,18 +825,19 @@ class OpenSettingsAction extends Action { } - run(context?: SettingsTarget): TPromise { + run(context?: ISettingsToolbarContext): TPromise { return this._run(context) .then(() => { }); } - private _run(context?: SettingsTarget): TPromise { - if (context === ConfigurationTarget.USER) { + private _run(context?: ISettingsToolbarContext): TPromise { + const target = context && context.target; + if (target === ConfigurationTarget.USER) { return this.preferencesService.openGlobalSettings(); - } else if (context === ConfigurationTarget.WORKSPACE) { + } else if (target === ConfigurationTarget.WORKSPACE) { return this.preferencesService.openWorkspaceSettings(); - } else if (URI.isUri(context)) { - return this.preferencesService.openFolderSettings(context); + } else if (URI.isUri(target)) { + return this.preferencesService.openFolderSettings(target); } return TPromise.wrap(null); From 866bc0aa4c80a7966fe8eb1351e9920527e3988f Mon Sep 17 00:00:00 2001 From: Rob Lourens Date: Fri, 27 Jul 2018 11:25:00 -0700 Subject: [PATCH 0250/1276] Fix #55224 - use different cacheKeys per folder in FileIndexProvider --- .../api/node/extHostSearch.fileIndex.ts | 36 +++++++++++++++---- src/vs/workbench/api/node/extHostSearch.ts | 3 +- 2 files changed, 32 insertions(+), 7 deletions(-) diff --git a/src/vs/workbench/api/node/extHostSearch.fileIndex.ts b/src/vs/workbench/api/node/extHostSearch.fileIndex.ts index 81241f49dde..89422c20368 100644 --- a/src/vs/workbench/api/node/extHostSearch.fileIndex.ts +++ b/src/vs/workbench/api/node/extHostSearch.fileIndex.ts @@ -395,6 +395,8 @@ export class FileIndexSearchManager { private caches: { [cacheKey: string]: Cache; } = Object.create(null); + private readonly folderCacheKeys = new Map>(); + public fileSearch(config: ISearchQuery, provider: vscode.FileIndexProvider, onBatch: (matches: IFileMatch[]) => void): TPromise { if (config.sortByScore) { let sortedSearch = this.trySortedSearchFromCache(config); @@ -430,13 +432,25 @@ export class FileIndexSearchManager { }); } + private getFolderCacheKey(config: ISearchQuery): string { + const uri = config.folderQueries[0].folder.toString(); + const folderCacheKey = config.cacheKey && `${uri}_${config.cacheKey}`; + if (!this.folderCacheKeys.get(config.cacheKey)) { + this.folderCacheKeys.set(config.cacheKey, new Set()); + } + + this.folderCacheKeys.get(config.cacheKey).add(folderCacheKey); + + return folderCacheKey; + } + private rawMatchToSearchItem(match: IInternalFileMatch): IFileMatch { return { resource: match.original || resources.joinPath(match.base, match.relativePath) }; } - private doSortedSearch(engine: FileIndexSearchEngine, config: IRawSearchQuery): TPromise { + private doSortedSearch(engine: FileIndexSearchEngine, config: ISearchQuery): TPromise { let searchPromise: TPromise; let allResultsPromise = new TPromise((c, e) => { searchPromise = this.doSearch(engine).then(c, e); @@ -444,9 +458,10 @@ export class FileIndexSearchManager { searchPromise.cancel(); }); + const folderCacheKey = this.getFolderCacheKey(config); let cache: Cache; - if (config.cacheKey) { - cache = this.getOrCreateCache(config.cacheKey); + if (folderCacheKey) { + cache = this.getOrCreateCache(folderCacheKey); cache.resultsToSearchCache[config.filePattern] = allResultsPromise; allResultsPromise.then(null, err => { delete cache.resultsToSearchCache[config.filePattern]; @@ -480,8 +495,9 @@ export class FileIndexSearchManager { return this.caches[cacheKey] = new Cache(); } - private trySortedSearchFromCache(config: IRawSearchQuery): TPromise { - const cache = config.cacheKey && this.caches[config.cacheKey]; + private trySortedSearchFromCache(config: ISearchQuery): TPromise { + const folderCacheKey = this.getFolderCacheKey(config); + const cache = folderCacheKey && this.caches[folderCacheKey]; if (!cache) { return undefined; } @@ -596,7 +612,15 @@ export class FileIndexSearchManager { } public clearCache(cacheKey: string): TPromise { - delete this.caches[cacheKey]; + if (!this.folderCacheKeys.has(cacheKey)) { + return TPromise.wrap(undefined); + } + + const expandedKeys = this.folderCacheKeys.get(cacheKey); + expandedKeys.forEach(key => delete this.caches[key]); + + this.folderCacheKeys.delete(cacheKey); + return TPromise.as(undefined); } diff --git a/src/vs/workbench/api/node/extHostSearch.ts b/src/vs/workbench/api/node/extHostSearch.ts index 8aaf7982ddc..a4be83baa25 100644 --- a/src/vs/workbench/api/node/extHostSearch.ts +++ b/src/vs/workbench/api/node/extHostSearch.ts @@ -96,7 +96,8 @@ export class ExtHostSearch implements ExtHostSearchShape { } $clearCache(cacheKey: string): TPromise { - // Only relevant to file index search + // Actually called once per provider. + // Only relevant to file index search. return this._fileIndexSearchManager.clearCache(cacheKey); } From 5c646ecb1b73c7857da8489eab89521fc901367b Mon Sep 17 00:00:00 2001 From: SteVen Batten Date: Fri, 27 Jul 2018 11:28:59 -0700 Subject: [PATCH 0251/1276] fix #55147 --- src/vs/code/electron-main/menubar.ts | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/src/vs/code/electron-main/menubar.ts b/src/vs/code/electron-main/menubar.ts index ac259f0aa3c..5d25416f1f9 100644 --- a/src/vs/code/electron-main/menubar.ts +++ b/src/vs/code/electron-main/menubar.ts @@ -678,6 +678,17 @@ export class Menubar { commandId = arg2[0]; } + // Add role for special case menu items + if (isMacintosh) { + if (commandId === 'editor.action.clipboardCutAction') { + options['role'] = 'cut'; + } else if (commandId === 'editor.action.clipboardCopyAction') { + options['role'] = 'copy'; + } else if (commandId === 'editor.action.clipboardPasteAction') { + options['role'] = 'paste'; + } + } + return new MenuItem(this.withKeybinding(commandId, options)); } From 0edee5d2280b899aad5794f95eeaa1a669db51e6 Mon Sep 17 00:00:00 2001 From: Matt Bierner Date: Fri, 27 Jul 2018 11:52:37 -0700 Subject: [PATCH 0252/1276] Support clickable folder projects refences A project reference may point either to a tsconfig or to a folder containing a `tsconfig.json` file --- .../src/features/tsconfig.ts | 32 +++++++++++++------ 1 file changed, 23 insertions(+), 9 deletions(-) diff --git a/extensions/typescript-language-features/src/features/tsconfig.ts b/extensions/typescript-language-features/src/features/tsconfig.ts index 414c0f01148..048ac79ab2c 100644 --- a/extensions/typescript-language-features/src/features/tsconfig.ts +++ b/extensions/typescript-language-features/src/features/tsconfig.ts @@ -4,11 +4,11 @@ *--------------------------------------------------------------------------------------------*/ import * as jsonc from 'jsonc-parser'; -import { dirname, join } from 'path'; +import { dirname, join, basename } from 'path'; import * as vscode from 'vscode'; import { flatten } from '../utils/arrays'; -function mapNode(node: jsonc.Node | undefined, f: (x: jsonc.Node) => R): R[] { +function mapChildren(node: jsonc.Node | undefined, f: (x: jsonc.Node) => R): R[] { return node && node.type === 'array' && node.children ? node.children.map(f) : []; @@ -37,15 +37,25 @@ class TsconfigLinkProvider implements vscode.DocumentLinkProvider { } private getFilesLinks(document: vscode.TextDocument, root: jsonc.Node) { - return mapNode( + return mapChildren( jsonc.findNodeAtLocation(root, ['files']), - node => this.pathNodeToLink(document, node)); + child => this.pathNodeToLink(document, child)); } private getReferencesLinks(document: vscode.TextDocument, root: jsonc.Node) { - return mapNode( + return mapChildren( jsonc.findNodeAtLocation(root, ['references']), - child => this.pathNodeToLink(document, jsonc.findNodeAtLocation(child, ['path']))); + child => { + const pathNode = jsonc.findNodeAtLocation(child, ['path']); + if (!this.isPathValue(pathNode)) { + return undefined; + } + + return new vscode.DocumentLink(this.getRange(document, pathNode), + basename(pathNode.value).match('.json$') + ? this.getFileTarget(document, pathNode) + : this.getFolderTarget(document, pathNode)); + }); } private pathNodeToLink( @@ -53,7 +63,7 @@ class TsconfigLinkProvider implements vscode.DocumentLinkProvider { node: jsonc.Node | undefined ): vscode.DocumentLink | undefined { return this.isPathValue(node) - ? new vscode.DocumentLink(this.getRange(document, node), this.getTarget(document, node)) + ? new vscode.DocumentLink(this.getRange(document, node), this.getFileTarget(document, node)) : undefined; } @@ -61,13 +71,17 @@ class TsconfigLinkProvider implements vscode.DocumentLinkProvider { return extendsNode && extendsNode.type === 'string' && extendsNode.value - && !(extendsNode.value as string).includes('*'); + && !(extendsNode.value as string).includes('*'); // don't treat globs as links. } - private getTarget(document: vscode.TextDocument, node: jsonc.Node): vscode.Uri { + private getFileTarget(document: vscode.TextDocument, node: jsonc.Node): vscode.Uri { return vscode.Uri.file(join(dirname(document.uri.fsPath), node!.value)); } + private getFolderTarget(document: vscode.TextDocument, node: jsonc.Node): vscode.Uri { + return vscode.Uri.file(join(dirname(document.uri.fsPath), node!.value, 'tsconfig.json')); + } + private getRange(document: vscode.TextDocument, node: jsonc.Node) { const offset = node!.offset; const start = document.positionAt(offset + 1); From 8e35b4272b88fae97b03478f4bc20b22c183bba3 Mon Sep 17 00:00:00 2001 From: Matt Bierner Date: Fri, 27 Jul 2018 13:22:27 -0700 Subject: [PATCH 0253/1276] Disable interuptGetErr until next release. Needs more testing --- .../src/features/bufferSyncSupport.ts | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/extensions/typescript-language-features/src/features/bufferSyncSupport.ts b/extensions/typescript-language-features/src/features/bufferSyncSupport.ts index b44ec9fa0a0..d63c8c3a81c 100644 --- a/extensions/typescript-language-features/src/features/bufferSyncSupport.ts +++ b/extensions/typescript-language-features/src/features/bufferSyncSupport.ts @@ -266,16 +266,17 @@ export default class BufferSyncSupport extends Disposable { } public interuptGetErr(f: () => R): R { - console.log('try inter'); - if (!this.pendingGetErr) { - return f(); - } + // TODO: re-enable for 1.27 insiders + return f(); + // if (!this.pendingGetErr) { + // return f(); + // } - this.pendingGetErr.cancel(); - this.pendingGetErr = undefined; - const result = f(); - this.triggerDiagnostics(); - return result; + // this.pendingGetErr.cancel(); + // this.pendingGetErr = undefined; + // const result = f(); + // this.triggerDiagnostics(); + // return result; } private onDidCloseTextDocument(document: vscode.TextDocument): void { From 5039c23a66d30b4f2de8a4e166726c8903ff6e40 Mon Sep 17 00:00:00 2001 From: Ramya Rao Date: Fri, 27 Jul 2018 13:31:54 -0700 Subject: [PATCH 0254/1276] Allow users to turn off automatic checking of extension updates (#55087) * Add setting to turn off automatic checking of extension updates * update tag name * Fix tests --- .../parts/extensions/common/extensions.ts | 2 ++ .../electron-browser/extensions.contribution.ts | 7 +++++++ .../extensions/node/extensionsWorkbenchService.ts | 14 ++++++++++++-- .../extensionsWorkbenchService.test.ts | 11 +++++++++-- 4 files changed, 30 insertions(+), 4 deletions(-) diff --git a/src/vs/workbench/parts/extensions/common/extensions.ts b/src/vs/workbench/parts/extensions/common/extensions.ts index bf50d9d44ae..4a08d9122f7 100644 --- a/src/vs/workbench/parts/extensions/common/extensions.ts +++ b/src/vs/workbench/parts/extensions/common/extensions.ts @@ -96,11 +96,13 @@ export interface IExtensionsWorkbenchService { export const ConfigurationKey = 'extensions'; export const AutoUpdateConfigurationKey = 'extensions.autoUpdate'; +export const AutoCheckUpdatesConfigurationKey = 'extensions.autoCheckUpdates'; export const ShowRecommendationsOnlyOnDemandKey = 'extensions.showRecommendationsOnlyOnDemand'; export const CloseExtensionDetailsOnViewChangeKey = 'extensions.closeExtensionDetailsOnViewChange'; export interface IExtensionsConfiguration { autoUpdate: boolean; + autoCheckUpdates: boolean; ignoreRecommendations: boolean; showRecommendationsOnlyOnDemand: boolean; closeExtensionDetailsOnViewChange: boolean; diff --git a/src/vs/workbench/parts/extensions/electron-browser/extensions.contribution.ts b/src/vs/workbench/parts/extensions/electron-browser/extensions.contribution.ts index cccfee273b8..25ced8dabe0 100644 --- a/src/vs/workbench/parts/extensions/electron-browser/extensions.contribution.ts +++ b/src/vs/workbench/parts/extensions/electron-browser/extensions.contribution.ts @@ -209,6 +209,13 @@ Registry.as(ConfigurationExtensions.Configuration) scope: ConfigurationScope.APPLICATION, tags: ['usesOnlineServices'] }, + 'extensions.autoCheckUpdates': { + type: 'boolean', + description: localize('extensionsCheckUpdates', "Automatically checks for extension updates. If an extension update is available and the extension auto update feature is disabled, then the extension will appear as outdated in the Extensions view."), + default: true, + scope: ConfigurationScope.APPLICATION, + tags: ['usesOnlineServices'] + }, 'extensions.ignoreRecommendations': { type: 'boolean', description: localize('extensionsIgnoreRecommendations', "When enabled, the notifications for extension recommendations will not be shown."), diff --git a/src/vs/workbench/parts/extensions/node/extensionsWorkbenchService.ts b/src/vs/workbench/parts/extensions/node/extensionsWorkbenchService.ts index 8804517eaa1..5930310b95e 100644 --- a/src/vs/workbench/parts/extensions/node/extensionsWorkbenchService.ts +++ b/src/vs/workbench/parts/extensions/node/extensionsWorkbenchService.ts @@ -26,7 +26,7 @@ import { IConfigurationService } from 'vs/platform/configuration/common/configur import { IWindowService } from 'vs/platform/windows/common/windows'; import Severity from 'vs/base/common/severity'; import URI from 'vs/base/common/uri'; -import { IExtension, IExtensionDependencies, ExtensionState, IExtensionsWorkbenchService, AutoUpdateConfigurationKey } from 'vs/workbench/parts/extensions/common/extensions'; +import { IExtension, IExtensionDependencies, ExtensionState, IExtensionsWorkbenchService, AutoUpdateConfigurationKey, AutoCheckUpdatesConfigurationKey } from 'vs/workbench/parts/extensions/common/extensions'; import { IEditorService, SIDE_GROUP, ACTIVE_GROUP } from 'vs/workbench/services/editor/common/editorService'; import { IURLService, IURLHandler } from 'vs/platform/url/common/url'; import { ExtensionsInput } from 'vs/workbench/parts/extensions/common/extensionsInput'; @@ -415,6 +415,11 @@ export class ExtensionsWorkbenchService implements IExtensionsWorkbenchService, this.checkForUpdates(); } } + if (e.affectsConfiguration(AutoCheckUpdatesConfigurationKey)) { + if (this.isAutoCheckUpdatesEnabled()) { + this.checkForUpdates(); + } + } }, this, this.disposables); this.queryLocal().done(() => this.eventuallySyncWithGallery(true)); @@ -610,8 +615,13 @@ export class ExtensionsWorkbenchService implements IExtensionsWorkbenchService, return this.configurationService.getValue(AutoUpdateConfigurationKey); } + private isAutoCheckUpdatesEnabled(): boolean { + return this.configurationService.getValue(AutoCheckUpdatesConfigurationKey); + } + private eventuallySyncWithGallery(immediate = false): void { - const loop = () => this.syncWithGallery().then(() => this.eventuallySyncWithGallery()); + const shouldSync = this.isAutoUpdateEnabled() || this.isAutoCheckUpdatesEnabled(); + const loop = () => (shouldSync ? this.syncWithGallery() : TPromise.as(null)).then(() => this.eventuallySyncWithGallery()); const delay = immediate ? 0 : ExtensionsWorkbenchService.SyncPeriod; this.syncDelayer.trigger(loop, delay) diff --git a/src/vs/workbench/parts/extensions/test/electron-browser/extensionsWorkbenchService.test.ts b/src/vs/workbench/parts/extensions/test/electron-browser/extensionsWorkbenchService.test.ts index eca3169eca8..411ed8b209f 100644 --- a/src/vs/workbench/parts/extensions/test/electron-browser/extensionsWorkbenchService.test.ts +++ b/src/vs/workbench/parts/extensions/test/electron-browser/extensionsWorkbenchService.test.ts @@ -11,7 +11,7 @@ import * as fs from 'fs'; import { assign } from 'vs/base/common/objects'; import { TPromise } from 'vs/base/common/winjs.base'; import { generateUuid } from 'vs/base/common/uuid'; -import { IExtensionsWorkbenchService, ExtensionState } from 'vs/workbench/parts/extensions/common/extensions'; +import { IExtensionsWorkbenchService, ExtensionState, AutoCheckUpdatesConfigurationKey, AutoUpdateConfigurationKey } from 'vs/workbench/parts/extensions/common/extensions'; import { ExtensionsWorkbenchService } from 'vs/workbench/parts/extensions/node/extensionsWorkbenchService'; import { IExtensionManagementService, IExtensionGalleryService, IExtensionEnablementService, IExtensionTipsService, ILocalExtension, LocalExtensionType, IGalleryExtension, @@ -66,7 +66,14 @@ suite('ExtensionsWorkbenchServiceTest', () => { instantiationService.stub(IURLService, URLService); instantiationService.stub(IWorkspaceContextService, new TestContextService()); - instantiationService.stub(IConfigurationService, { onDidUpdateConfiguration: () => { }, onDidChangeConfiguration: () => { }, getConfiguration: () => ({}) }); + instantiationService.stub(IConfigurationService, { + onDidUpdateConfiguration: () => { }, + onDidChangeConfiguration: () => { }, + getConfiguration: () => ({}), + getValue: (key) => { + return (key === AutoCheckUpdatesConfigurationKey || key === AutoUpdateConfigurationKey) ? true : undefined; + } + }); instantiationService.stub(IExtensionManagementService, ExtensionManagementService); instantiationService.stub(IExtensionManagementService, 'onInstallExtension', installEvent.event); From 1098de4c11814d2a77af773d1bcfccabf5677621 Mon Sep 17 00:00:00 2001 From: Ramya Achutha Rao Date: Fri, 27 Jul 2018 13:38:29 -0700 Subject: [PATCH 0255/1276] Absence of ai key stops only core from sending telemetry not extensions --- product.json | 1 - 1 file changed, 1 deletion(-) diff --git a/product.json b/product.json index d16dca66ecd..ed3ced1c1be 100644 --- a/product.json +++ b/product.json @@ -4,7 +4,6 @@ "applicationName": "code-oss", "dataFolderName": ".vscode-oss", "win32MutexName": "vscodeoss", - "enableTelemetry": true, "licenseName": "MIT", "licenseUrl": "https://github.com/Microsoft/vscode/blob/master/LICENSE.txt", "win32DirName": "Microsoft Code OSS", From 4ba03608c04b7f8c717d45f423182ed7f2739f85 Mon Sep 17 00:00:00 2001 From: Rachel Macfarlane Date: Fri, 27 Jul 2018 13:58:03 -0700 Subject: [PATCH 0256/1276] Remove new comment glyph on mouse leave instead of blur to allow adding comments --- .../electron-browser/commentsEditorContribution.ts | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/src/vs/workbench/parts/comments/electron-browser/commentsEditorContribution.ts b/src/vs/workbench/parts/comments/electron-browser/commentsEditorContribution.ts index 619170cb23a..2b088806cbf 100644 --- a/src/vs/workbench/parts/comments/electron-browser/commentsEditorContribution.ts +++ b/src/vs/workbench/parts/comments/electron-browser/commentsEditorContribution.ts @@ -243,7 +243,7 @@ export class ReviewController implements IEditorContribution { this._commentWidgets = []; this.localToDispose.push(this.editor.onMouseMove(e => this.onEditorMouseMove(e))); - this.localToDispose.push(this.editor.onDidBlurEditorText(() => this.onDidBlurEditorText())); + this.localToDispose.push(this.editor.onMouseLeave(() => this.onMouseLeave())); this.localToDispose.push(this.editor.onDidChangeModelContent(() => { if (this._newCommentGlyph) { this.editor.removeContentWidget(this._newCommentGlyph); @@ -318,10 +318,6 @@ export class ReviewController implements IEditorContribution { return; } - if (!this.editor.hasTextFocus()) { - return; - } - const hasCommentingRanges = this._commentInfos.length && this._commentInfos.some(info => !!info.commentingRanges.length); if (hasCommentingRanges && e.target.position && e.target.position.lineNumber !== undefined) { if (this._newCommentGlyph && e.target.element.className !== 'comment-hint') { @@ -343,7 +339,7 @@ export class ReviewController implements IEditorContribution { } } - private onDidBlurEditorText(): void { + private onMouseLeave(): void { if (this._newCommentGlyph) { this.editor.removeContentWidget(this._newCommentGlyph); } From 6ffbde1f4ad2dbaea75ff4ceb7e493e4fa960759 Mon Sep 17 00:00:00 2001 From: Matt Bierner Date: Fri, 27 Jul 2018 13:35:49 -0700 Subject: [PATCH 0257/1276] Don't lowercase all file paths on case insensitive file-sysystems for geterr Instead, we should always use the casing of the first file we see with a given path --- .../src/features/bufferSyncSupport.ts | 40 +++++++++++-------- .../src/utils/resourceMap.ts | 36 ++++++++++++----- 2 files changed, 48 insertions(+), 28 deletions(-) diff --git a/extensions/typescript-language-features/src/features/bufferSyncSupport.ts b/extensions/typescript-language-features/src/features/bufferSyncSupport.ts index d63c8c3a81c..564325f563c 100644 --- a/extensions/typescript-language-features/src/features/bufferSyncSupport.ts +++ b/extensions/typescript-language-features/src/features/bufferSyncSupport.ts @@ -117,10 +117,16 @@ class SyncedBufferMap extends ResourceMap { } class PendingDiagnostics extends ResourceMap { - public getFileList(): Set { - return new Set(Array.from(this.entries) - .sort((a, b) => a[1] - b[1]) - .map(entry => entry[0])); + public getOrderedFileSet(): ResourceMap { + const orderedResources = Array.from(this.entries) + .sort((a, b) => a.value - b.value) + .map(entry => entry.resource); + + const map = new ResourceMap(); + for (const resource of orderedResources) { + map.set(resource, void 0); + } + return map; } } @@ -128,7 +134,7 @@ class GetErrRequest { public static executeGetErrRequest( client: ITypeScriptServiceClient, - files: string[], + files: ResourceMap, onDone: () => void ) { const token = new vscode.CancellationTokenSource(); @@ -139,13 +145,15 @@ class GetErrRequest { private constructor( client: ITypeScriptServiceClient, - public readonly files: string[], + public readonly files: ResourceMap, private readonly _token: vscode.CancellationTokenSource, onDone: () => void ) { const args: Proto.GeterrRequestArgs = { delay: 0, - files + files: Array.from(files.entries) + .map(entry => client.normalizedPath(entry.resource)) + .filter(x => !!x) as string[] }; client.executeAsync('geterr', args, _token.token) @@ -345,27 +353,25 @@ export default class BufferSyncSupport extends Disposable { } private sendPendingDiagnostics(): void { - const fileList = this.pendingDiagnostics.getFileList(); + const orderedFileSet = this.pendingDiagnostics.getOrderedFileSet(); // Add all open TS buffers to the geterr request. They might be visible for (const buffer of this.syncedBuffers.values) { if (!this.pendingDiagnostics.has(buffer.resource)) { - fileList.add(buffer.filepath); + orderedFileSet.set(buffer.resource, void 0); } } - if (this.pendingGetErr) { - for (const file of this.pendingGetErr.files) { - fileList.add(file); - } - } - - if (fileList.size) { + if (orderedFileSet.size) { if (this.pendingGetErr) { this.pendingGetErr.cancel(); + + for (const file of this.pendingGetErr.files.entries) { + orderedFileSet.set(file.resource, void 0); + } } - const getErr = this.pendingGetErr = GetErrRequest.executeGetErrRequest(this.client, Array.from(fileList), () => { + const getErr = this.pendingGetErr = GetErrRequest.executeGetErrRequest(this.client, orderedFileSet, () => { if (this.pendingGetErr === getErr) { this.pendingGetErr = undefined; } diff --git a/extensions/typescript-language-features/src/utils/resourceMap.ts b/extensions/typescript-language-features/src/utils/resourceMap.ts index 73364c03207..33d6f00b4be 100644 --- a/extensions/typescript-language-features/src/utils/resourceMap.ts +++ b/extensions/typescript-language-features/src/utils/resourceMap.ts @@ -15,12 +15,16 @@ import { getTempFile } from './temp'; * file systems. */ export class ResourceMap { - private readonly _map = new Map(); + private readonly _map = new Map(); constructor( - private readonly _normalizePath?: (resource: vscode.Uri) => string | null + private readonly _normalizePath: (resource: vscode.Uri) => string | null = (resource) => resource.fsPath ) { } + public get size() { + return this._map.size; + } + public has(resource: vscode.Uri): boolean { const file = this.toKey(resource); return !!file && this._map.has(file); @@ -28,13 +32,23 @@ export class ResourceMap { public get(resource: vscode.Uri): T | undefined { const file = this.toKey(resource); - return file ? this._map.get(file) : undefined; + if (!file) { + return undefined; + } + const entry = this._map.get(file); + return entry ? entry.value : undefined; } public set(resource: vscode.Uri, value: T) { const file = this.toKey(resource); - if (file) { - this._map.set(file, value); + if (!file) { + return; + } + const entry = this._map.get(file); + if (entry) { + entry.value = value; + } else { + this._map.set(file, { resource, value }); } } @@ -45,20 +59,20 @@ export class ResourceMap { } } - public clear() { + public clear(): void { this._map.clear(); } public get values(): Iterable { + return Array.from(this._map.values()).map(x => x.value); + } + + public get entries(): Iterable<{ resource: vscode.Uri, value: T }> { return this._map.values(); } - public get entries() { - return this._map.entries(); - } - private toKey(resource: vscode.Uri): string | null { - const key = this._normalizePath ? this._normalizePath(resource) : resource.fsPath; + const key = this._normalizePath(resource); if (!key) { return key; } From eb0688ed63e54ad96ce2b115e6bbff96b0edeb6d Mon Sep 17 00:00:00 2001 From: Matt Bierner Date: Fri, 27 Jul 2018 14:21:18 -0700 Subject: [PATCH 0258/1276] Remove extra check This is already handled by using a resource map --- .../src/features/bufferSyncSupport.ts | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/extensions/typescript-language-features/src/features/bufferSyncSupport.ts b/extensions/typescript-language-features/src/features/bufferSyncSupport.ts index 564325f563c..d18304c63ee 100644 --- a/extensions/typescript-language-features/src/features/bufferSyncSupport.ts +++ b/extensions/typescript-language-features/src/features/bufferSyncSupport.ts @@ -357,9 +357,7 @@ export default class BufferSyncSupport extends Disposable { // Add all open TS buffers to the geterr request. They might be visible for (const buffer of this.syncedBuffers.values) { - if (!this.pendingDiagnostics.has(buffer.resource)) { - orderedFileSet.set(buffer.resource, void 0); - } + orderedFileSet.set(buffer.resource, void 0); } if (orderedFileSet.size) { From 01fb34dc00c36566afc7ac55e09be4c17f2f1bb4 Mon Sep 17 00:00:00 2001 From: SteVen Batten <6561887+sbatten@users.noreply.github.com> Date: Fri, 27 Jul 2018 14:47:06 -0700 Subject: [PATCH 0259/1276] increase specificity so that we can beat out shell.css definitively --- src/vs/base/browser/ui/menu/menu.css | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/vs/base/browser/ui/menu/menu.css b/src/vs/base/browser/ui/menu/menu.css index 76f2599c526..221640196a1 100644 --- a/src/vs/base/browser/ui/menu/menu.css +++ b/src/vs/base/browser/ui/menu/menu.css @@ -117,7 +117,9 @@ animation: fadeIn 0.083s linear; } -.context-view.monaco-menu-container :focus { +.context-view.monaco-menu-container :focus, +.context-view.monaco-menu-container .monaco-action-bar.vertical:focus, +.context-view.monaco-menu-container .monaco-action-bar.vertical :focus { outline: 0; } From 523826abfec2030fc8dc255df5daee6d96e6ed1f Mon Sep 17 00:00:00 2001 From: Jackson Kearl Date: Fri, 27 Jul 2018 15:06:04 -0700 Subject: [PATCH 0260/1276] Allow users to see installed extensions while offline --- .../electron-browser/extensionTipsService.ts | 37 +++++++++---------- .../electron-browser/extensionsViews.ts | 5 ++- 2 files changed, 21 insertions(+), 21 deletions(-) diff --git a/src/vs/workbench/parts/extensions/electron-browser/extensionTipsService.ts b/src/vs/workbench/parts/extensions/electron-browser/extensionTipsService.ts index ab53ea18d8b..5550d05036c 100644 --- a/src/vs/workbench/parts/extensions/electron-browser/extensionTipsService.ts +++ b/src/vs/workbench/parts/extensions/electron-browser/extensionTipsService.ts @@ -311,7 +311,7 @@ export class ExtensionTipsService extends Disposable implements IExtensionTipsSe .then(content => json.parse(content.value), err => null); } - private validateExtensions(contents: IExtensionsConfigContent[]): TPromise<{ invalidExtensions: string[], message: string }> { + private async validateExtensions(contents: IExtensionsConfigContent[]): TPromise<{ invalidExtensions: string[], message: string }> { const extensionsContent: IExtensionsConfigContent = { recommendations: distinct(flatten(contents.map(content => content.recommendations || []))), unwantedRecommendations: distinct(flatten(contents.map(content => content.unwantedRecommendations || []))) @@ -339,27 +339,24 @@ export class ExtensionTipsService extends Disposable implements IExtensionTipsSe const filteredWanted = regexFilter(extensionsContent.recommendations || []).map(x => x.toLowerCase()); - if (!filteredWanted.length) { - return TPromise.as({ invalidExtensions, message }); - } + if (filteredWanted.length) { + try { + let validRecommendations = (await this._galleryService.query({ names: filteredWanted })).firstPage + .map(extension => extension.identifier.id.toLowerCase()); - return this._galleryService.query({ names: filteredWanted }).then(pager => { - let page = pager.firstPage; - let validRecommendations = page.map(extension => { - return extension.identifier.id.toLowerCase(); - }); - - if (validRecommendations.length !== filteredWanted.length) { - filteredWanted.forEach(element => { - if (validRecommendations.indexOf(element.toLowerCase()) === -1) { - invalidExtensions.push(element.toLowerCase()); - message += `${element} (not found in marketplace)\n`; - } - }); + if (validRecommendations.length !== filteredWanted.length) { + filteredWanted.forEach(element => { + if (validRecommendations.indexOf(element.toLowerCase()) === -1) { + invalidExtensions.push(element.toLowerCase()); + message += `${element} (not found in marketplace)\n`; + } + }); + } + } catch (e) { + console.warn('Error querying extensions gallery', e); } - - return TPromise.as({ invalidExtensions, message }); - }); + } + return { invalidExtensions, message }; } private isExtensionAllowedToBeRecommended(id: string): boolean { diff --git a/src/vs/workbench/parts/extensions/electron-browser/extensionsViews.ts b/src/vs/workbench/parts/extensions/electron-browser/extensionsViews.ts index e057216762f..8fc5ed3bca1 100644 --- a/src/vs/workbench/parts/extensions/electron-browser/extensionsViews.ts +++ b/src/vs/workbench/parts/extensions/electron-browser/extensionsViews.ts @@ -111,7 +111,10 @@ export class ExtensionsListView extends ViewletPanel { } async show(query: string): Promise> { - const model = await this.query(query); + const model = await this.query(query).catch(e => { + console.warn('Error querying extensions gallery', e); + return new PagedModel([]); + }); this.setModel(model); return model; } From 9435bde3d4c8259af6a907548c065401088a82ce Mon Sep 17 00:00:00 2001 From: Jackson Kearl Date: Fri, 27 Jul 2018 15:26:09 -0700 Subject: [PATCH 0261/1276] Prevent pasting multiple lines into the editor (#55202) --- .../parts/extensions/electron-browser/extensionsViewlet.ts | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/vs/workbench/parts/extensions/electron-browser/extensionsViewlet.ts b/src/vs/workbench/parts/extensions/electron-browser/extensionsViewlet.ts index 1154cc6cb8e..f7989de7bce 100644 --- a/src/vs/workbench/parts/extensions/electron-browser/extensionsViewlet.ts +++ b/src/vs/workbench/parts/extensions/electron-browser/extensionsViewlet.ts @@ -350,6 +350,10 @@ export class ExtensionsViewlet extends ViewContainerViewlet implements IExtensio this.searchBox.setModel(this.modelService.createModel('', null, uri.parse('extensions:searchinput'), true)); + this.disposables.push(this.searchBox.onDidPaste(() => { + this.searchBox.setValue(this.searchBox.getValue().replace(/\s+/g, ' ')); + this.searchBox.setScrollTop(0); + })); this.disposables.push(this.searchBox.onDidFocusEditorText(() => addClass(this.monacoStyleContainer, 'synthetic-focus'))); this.disposables.push(this.searchBox.onDidBlurEditorText(() => removeClass(this.monacoStyleContainer, 'synthetic-focus'))); From 5c7b2f32fa401f16924e523814064d92834578b5 Mon Sep 17 00:00:00 2001 From: Jackson Kearl Date: Fri, 27 Jul 2018 15:36:13 -0700 Subject: [PATCH 0262/1276] Should autosuggest dropdown on empty input (or at start of word) (#55197) --- .../workbench/parts/extensions/common/extensionQuery.ts | 6 +++++- .../extensions/electron-browser/extensionsViewlet.ts | 9 +++++---- 2 files changed, 10 insertions(+), 5 deletions(-) diff --git a/src/vs/workbench/parts/extensions/common/extensionQuery.ts b/src/vs/workbench/parts/extensions/common/extensionQuery.ts index 4a3cc885ec5..aa271d1498f 100644 --- a/src/vs/workbench/parts/extensions/common/extensionQuery.ts +++ b/src/vs/workbench/parts/extensions/common/extensionQuery.ts @@ -21,7 +21,11 @@ export class Query { 'ext': [''] }; - return flatten(commands.map(command => subcommands[command] ? subcommands[command].map(subcommand => `${command}:${subcommand}`) : [command])); + return flatten( + commands.map(command => + subcommands[command] + ? subcommands[command].map(subcommand => `@${command}:${subcommand}${subcommand === '' ? '' : ' '}`) + : [`@${command} `])); } static parse(value: string): Query { diff --git a/src/vs/workbench/parts/extensions/electron-browser/extensionsViewlet.ts b/src/vs/workbench/parts/extensions/electron-browser/extensionsViewlet.ts index f7989de7bce..5a17cd2c003 100644 --- a/src/vs/workbench/parts/extensions/electron-browser/extensionsViewlet.ts +++ b/src/vs/workbench/parts/extensions/electron-browser/extensionsViewlet.ts @@ -359,7 +359,7 @@ export class ExtensionsViewlet extends ViewContainerViewlet implements IExtensio const onKeyDownMonaco = chain(this.searchBox.onKeyDown); onKeyDownMonaco.filter(e => e.keyCode === KeyCode.Enter).on(e => e.preventDefault(), this, this.disposables); - onKeyDownMonaco.filter(e => e.keyCode === KeyCode.DownArrow).on(() => this.focusListView(), this, this.disposables); + onKeyDownMonaco.filter(e => e.keyCode === KeyCode.DownArrow && e.ctrlKey).on(() => this.focusListView(), this, this.disposables); const searchChangeEvent = new Emitter(); this.onSearchChange = searchChangeEvent.event; @@ -521,11 +521,12 @@ export class ExtensionsViewlet extends ViewContainerViewlet implements IExtensio } private autoComplete(query: string, position: number): { fullText: string, overwrite: number }[] { - if (query.lastIndexOf('@', position - 1) !== query.lastIndexOf(' ', position - 1) + 1) { return []; } - - let wordStart = query.lastIndexOf('@', position - 1) + 1; + let wordStart = query.lastIndexOf(' ', position - 1) + 1; let alreadyTypedCount = position - wordStart - 1; + // dont show autosuggestions if the user has typed something, but hasn't used the trigger character + if (alreadyTypedCount > 0 && query[wordStart] !== '@') { return []; } + return Query.autocompletions().map(replacement => ({ fullText: replacement, overwrite: alreadyTypedCount })); } From 8ca017eaba5b851d608d09a73b7e48e16fedab2f Mon Sep 17 00:00:00 2001 From: Ramya Rao Date: Fri, 27 Jul 2018 15:38:31 -0700 Subject: [PATCH 0263/1276] Polish tag search as per feedback (#55269) * Polish tag search as per feedback * Updated regex --- .../preferences/browser/settingsEditor2.ts | 24 ++++++++++++------- .../parts/preferences/browser/settingsTree.ts | 8 +++---- 2 files changed, 18 insertions(+), 14 deletions(-) diff --git a/src/vs/workbench/parts/preferences/browser/settingsEditor2.ts b/src/vs/workbench/parts/preferences/browser/settingsEditor2.ts index 01edb6072c1..3793973a9fd 100644 --- a/src/vs/workbench/parts/preferences/browser/settingsEditor2.ts +++ b/src/vs/workbench/parts/preferences/browser/settingsEditor2.ts @@ -84,6 +84,8 @@ export class SettingsEditor2 extends BaseEditor { private inSettingsEditorContextKey: IContextKey; private searchFocusContextKey: IContextKey; + private tagRegex = /(^|\s)@tag:("([^"]*)"|[^"]\S*)/g; + /** Don't spam warnings */ private hasWarnedMissingSettings: boolean; @@ -181,10 +183,10 @@ export class SettingsEditor2 extends BaseEditor { this.searchWidget.clear(); } - filterByTag(tag: string): void { + search(text: string): void { if (this.searchWidget) { this.searchWidget.focus(); - this.searchWidget.setValue(`@tag:${tag} `); + this.searchWidget.setValue(text); } } @@ -233,7 +235,7 @@ export class SettingsEditor2 extends BaseEditor { const actions = [ this.instantiationService.createInstance(FilterByTagAction, - localize('filterModifiedLabel', "Show modified settings only"), + localize('filterModifiedLabel', "Show modified settings"), MODIFIED_SETTING_TAG, this), this.instantiationService.createInstance( @@ -664,12 +666,16 @@ export class SettingsEditor2 extends BaseEditor { private triggerSearch(query: string): TPromise { this.viewState.tagFilters = new Set(); if (query) { - const tagMatches = query.match(/\s*@tag:(\S+)(.*)/); // For now, we support single tag at a time. - if (tagMatches) { - this.viewState.tagFilters.add(tagMatches[1]); - query = tagMatches[2]; - } + query = query.replace(this.tagRegex, (_, __, quotedTag, tag) => { + this.viewState.tagFilters.add(tag || quotedTag); + return ''; + }); + query = query.replace(`@${MODIFIED_SETTING_TAG}`, () => { + this.viewState.tagFilters.add(MODIFIED_SETTING_TAG); + return ''; + }); } + query = query.trim(); if (query) { return this.searchInProgress = TPromise.join([ this.localSearchDelayer.trigger(() => this.localFilterPreferences(query)), @@ -856,7 +862,7 @@ class FilterByTagAction extends Action { } run(): TPromise { - this.settingsEditor.filterByTag(this.tag); + this.settingsEditor.search(this.tag === MODIFIED_SETTING_TAG ? `@${this.tag} ` : `@tag:${this.tag} `); return TPromise.as(null); } } diff --git a/src/vs/workbench/parts/preferences/browser/settingsTree.ts b/src/vs/workbench/parts/preferences/browser/settingsTree.ts index e1dfd2f0e4f..7f0205c640e 100644 --- a/src/vs/workbench/parts/preferences/browser/settingsTree.ts +++ b/src/vs/workbench/parts/preferences/browser/settingsTree.ts @@ -1181,11 +1181,9 @@ export class SettingsTreeFilter implements IFilter { if (element instanceof SettingsTreeSettingElement && this.viewState.tagFilters && this.viewState.tagFilters.size) { if (element.tags) { - let hasFilteredTag = false; - element.tags.forEach(tag => { - if (this.viewState.tagFilters.has(tag)) { - hasFilteredTag = true; - } + let hasFilteredTag = true; + this.viewState.tagFilters.forEach(tag => { + hasFilteredTag = hasFilteredTag && element.tags.has(tag); }); return hasFilteredTag; } else { From f51c30d8f42d025dc28b4ce41a7e352a009f9b50 Mon Sep 17 00:00:00 2001 From: Ramya Rao Date: Fri, 27 Jul 2018 15:42:17 -0700 Subject: [PATCH 0264/1276] Allow users to opt-out of features that send online requests in the background (#55097) --- extensions/npm/README.md | 6 +++++- extensions/npm/package.json | 7 +++++++ extensions/npm/package.nls.json | 1 + .../npm/src/features/bowerJSONContribution.ts | 18 +++++++++++++++--- .../npm/src/features/jsonContributions.ts | 2 ++ .../src/features/packageJSONContribution.ts | 16 +++++++++++++--- 6 files changed, 43 insertions(+), 7 deletions(-) diff --git a/extensions/npm/README.md b/extensions/npm/README.md index 6c8fa19625d..f4b85999742 100644 --- a/extensions/npm/README.md +++ b/extensions/npm/README.md @@ -15,12 +15,16 @@ For more information about auto detection of Tasks, see the [documentation](http ### Script Explorer -The Npm Script Explorer shows the npm scripts found in your workspace. The explorer view is enabled by the setting `npm.enableScriptExplorer`. A script can be opened, run, or debug from the explorer. +The Npm Script Explorer shows the npm scripts found in your workspace. The explorer view is enabled by the setting `npm.enableScriptExplorer`. A script can be opened, run, or debug from the explorer. ### Run Scripts from the Editor The extension provides code lense actions to run or debug a script from the editor. +### Others + +The extension fetches data from https://registry.npmjs/org and https://registry.bower.io to provide auto-completion and information on hover features on npm dependencies. + ## Settings - `npm.autoDetect` - Enable detecting scripts as tasks, the default is `on`. diff --git a/extensions/npm/package.json b/extensions/npm/package.json index df9c903fcb4..d5647618a81 100644 --- a/extensions/npm/package.json +++ b/extensions/npm/package.json @@ -214,6 +214,13 @@ "description": "%config.npm.scriptExplorerAction%", "scope": "window", "default": "open" + }, + "npm.fetchOnlinePackageInfo": { + "type": "boolean", + "description": "%config.npm.fetchOnlinePackageInfo%", + "default": true, + "scope": "window", + "tags": ["usesOnlineServices"] } } }, diff --git a/extensions/npm/package.nls.json b/extensions/npm/package.nls.json index 92665d5f65a..3a59c27cad1 100644 --- a/extensions/npm/package.nls.json +++ b/extensions/npm/package.nls.json @@ -7,6 +7,7 @@ "config.npm.exclude": "Configure glob patterns for folders that should be excluded from automatic script detection.", "config.npm.enableScriptExplorer": "Enable an explorer view for npm scripts.", "config.npm.scriptExplorerAction": "The default click action used in the scripts explorer: 'open' or 'run', the default is 'open'.", + "config.npm.fetchOnlinePackageInfo": "Fetch data from https://registry.npmjs/org and https://registry.bower.io to provide auto-completion and information on hover features on npm dependencies.", "npm.parseError": "Npm task detection: failed to parse the file {0}", "taskdef.script": "The npm script to customize.", "taskdef.path": "The path to the folder of the package.json file that provides the script. Can be omitted.", diff --git a/extensions/npm/src/features/bowerJSONContribution.ts b/extensions/npm/src/features/bowerJSONContribution.ts index a00f347078c..038057bf2b2 100644 --- a/extensions/npm/src/features/bowerJSONContribution.ts +++ b/extensions/npm/src/features/bowerJSONContribution.ts @@ -4,8 +4,8 @@ *--------------------------------------------------------------------------------------------*/ 'use strict'; -import { MarkedString, CompletionItemKind, CompletionItem, DocumentSelector, SnippetString } from 'vscode'; -import { IJSONContribution, ISuggestionsCollector } from './jsonContributions'; +import { MarkedString, CompletionItemKind, CompletionItem, DocumentSelector, SnippetString, workspace } from 'vscode'; +import { IJSONContribution, ISuggestionsCollector, xhrDisabled } from './jsonContributions'; import { XHRRequest } from 'request-light'; import { Location } from 'jsonc-parser'; import { textToMarkedString } from './markedTextUtil'; @@ -25,7 +25,19 @@ export class BowerJSONContribution implements IJSONContribution { 'hui', 'bootstrap-languages', 'async', 'gulp', 'jquery-pjax', 'coffeescript', 'hammer.js', 'ace', 'leaflet', 'jquery-mobile', 'sweetalert', 'typeahead.js', 'soup', 'typehead.js', 'sails', 'codeigniter2']; - public constructor(private xhr: XHRRequest) { + private xhr: XHRRequest; + + public constructor(httprequestxhr: XHRRequest) { + + const getxhr = () => { + return workspace.getConfiguration('npm').get('fetchOnlinePackageInfo') === false ? xhrDisabled : httprequestxhr; + }; + this.xhr = getxhr(); + workspace.onDidChangeConfiguration((e) => { + if (e.affectsConfiguration('npm.fetchOnlinePackageInfo')) { + this.xhr = getxhr(); + } + }); } public getDocumentSelector(): DocumentSelector { diff --git a/extensions/npm/src/features/jsonContributions.ts b/extensions/npm/src/features/jsonContributions.ts index 81f8a66f2c2..a18bccf28ff 100644 --- a/extensions/npm/src/features/jsonContributions.ts +++ b/extensions/npm/src/features/jsonContributions.ts @@ -164,3 +164,5 @@ export class JSONCompletionItemProvider implements CompletionItemProvider { return nextToken === SyntaxKind.CloseBraceToken || nextToken === SyntaxKind.EOF; } } + +export const xhrDisabled = () => Promise.reject({ responseText: 'Use of online resources is disabled.' }); \ No newline at end of file diff --git a/extensions/npm/src/features/packageJSONContribution.ts b/extensions/npm/src/features/packageJSONContribution.ts index b060290eb51..1576ded6a4d 100644 --- a/extensions/npm/src/features/packageJSONContribution.ts +++ b/extensions/npm/src/features/packageJSONContribution.ts @@ -4,8 +4,8 @@ *--------------------------------------------------------------------------------------------*/ 'use strict'; -import { MarkedString, CompletionItemKind, CompletionItem, DocumentSelector, SnippetString } from 'vscode'; -import { IJSONContribution, ISuggestionsCollector } from './jsonContributions'; +import { MarkedString, CompletionItemKind, CompletionItem, DocumentSelector, SnippetString, workspace } from 'vscode'; +import { IJSONContribution, ISuggestionsCollector, xhrDisabled } from './jsonContributions'; import { XHRRequest } from 'request-light'; import { Location } from 'jsonc-parser'; import { textToMarkedString } from './markedTextUtil'; @@ -28,12 +28,22 @@ export class PackageJSONContribution implements IJSONContribution { 'jsdom', 'stylus', 'when', 'readable-stream', 'aws-sdk', 'concat-stream', 'chai', 'Thenable', 'wrench']; private knownScopes = ['@types', '@angular']; + private xhr: XHRRequest; public getDocumentSelector(): DocumentSelector { return [{ language: 'json', scheme: '*', pattern: '**/package.json' }]; } - public constructor(private xhr: XHRRequest) { + public constructor(httprequestxhr: XHRRequest) { + const getxhr = () => { + return workspace.getConfiguration('npm').get('fetchOnlinePackageInfo') === false ? xhrDisabled : httprequestxhr; + }; + this.xhr = getxhr(); + workspace.onDidChangeConfiguration((e) => { + if (e.affectsConfiguration('npm.fetchOnlinePackageInfo')) { + this.xhr = getxhr(); + } + }); } public collectDefaultSuggestions(_fileName: string, result: ISuggestionsCollector): Thenable { From 5424fb492627af206f683513ed999dba4130011f Mon Sep 17 00:00:00 2001 From: SteVen Batten <6561887+sbatten@users.noreply.github.com> Date: Fri, 27 Jul 2018 16:25:52 -0700 Subject: [PATCH 0265/1276] settings sweep #54690 --- .../common/config/commonEditorConfig.ts | 40 +++++++++++-------- 1 file changed, 23 insertions(+), 17 deletions(-) diff --git a/src/vs/editor/common/config/commonEditorConfig.ts b/src/vs/editor/common/config/commonEditorConfig.ts index 3524620da5a..5c2a991431a 100644 --- a/src/vs/editor/common/config/commonEditorConfig.ts +++ b/src/vs/editor/common/config/commonEditorConfig.ts @@ -246,7 +246,7 @@ const editorConfiguration: IConfigurationNode = { 'editor.lineHeight': { 'type': 'number', 'default': EDITOR_FONT_DEFAULTS.lineHeight, - 'description': nls.localize('lineHeight', "Controls the line height. Use 0 to compute the lineHeight from the fontSize.") + 'description': nls.localize('lineHeight', "Controls the line height. Use 0 to compute the line height from the font size.") }, 'editor.letterSpacing': { 'type': 'number', @@ -271,7 +271,7 @@ const editorConfiguration: IConfigurationNode = { 'type': 'number' }, 'default': EDITOR_DEFAULTS.viewInfo.rulers, - 'description': nls.localize('rulers', "Render vertical rulers after a certain number of monospace characters. Use multiple values for multiple rulers. No rulers are drawn if array is empty") + 'description': nls.localize('rulers', "Render vertical rulers after a certain number of monospace characters. Use multiple values for multiple rulers. No rulers are drawn if array is empty.") }, 'editor.wordSeparators': { 'type': 'string', @@ -299,17 +299,17 @@ const editorConfiguration: IConfigurationNode = { 'editor.roundedSelection': { 'type': 'boolean', 'default': EDITOR_DEFAULTS.viewInfo.roundedSelection, - 'description': nls.localize('roundedSelection', "Controls if selections have rounded corners") + 'description': nls.localize('roundedSelection', "Controls whether selections have rounded corners.") }, 'editor.scrollBeyondLastLine': { 'type': 'boolean', 'default': EDITOR_DEFAULTS.viewInfo.scrollBeyondLastLine, - 'description': nls.localize('scrollBeyondLastLine', "Controls if the editor will scroll beyond the last line") + 'description': nls.localize('scrollBeyondLastLine', "Controls whether the editor will scroll beyond the last line.") }, 'editor.scrollBeyondLastColumn': { 'type': 'number', 'default': EDITOR_DEFAULTS.viewInfo.scrollBeyondLastColumn, - 'description': nls.localize('scrollBeyondLastColumn', "Controls the number of extra characters beyond which the editor will scroll horizontally") + 'description': nls.localize('scrollBeyondLastColumn', "Controls the number of extra characters beyond which the editor will scroll horizontally.") }, 'editor.smoothScrolling': { 'type': 'boolean', @@ -319,7 +319,7 @@ const editorConfiguration: IConfigurationNode = { 'editor.minimap.enabled': { 'type': 'boolean', 'default': EDITOR_DEFAULTS.viewInfo.minimap.enabled, - 'description': nls.localize('minimap.enabled', "Controls if the minimap is shown") + 'description': nls.localize('minimap.enabled', "Controls whether the minimap is shown.") }, 'editor.minimap.side': { 'type': 'string', @@ -336,12 +336,12 @@ const editorConfiguration: IConfigurationNode = { 'editor.minimap.renderCharacters': { 'type': 'boolean', 'default': EDITOR_DEFAULTS.viewInfo.minimap.renderCharacters, - 'description': nls.localize('minimap.renderCharacters', "Render the actual characters on a line (as opposed to color blocks)") + 'description': nls.localize('minimap.renderCharacters', "Render the actual characters on a line as opposed to color blocks.") }, 'editor.minimap.maxColumn': { 'type': 'number', 'default': EDITOR_DEFAULTS.viewInfo.minimap.maxColumn, - 'description': nls.localize('minimap.maxColumn', "Limit the width of the minimap to render at most a certain number of columns") + 'description': nls.localize('minimap.maxColumn', "Limit the width of the minimap to render at most a certain number of columns.") }, 'editor.hover.enabled': { 'type': 'boolean', @@ -480,18 +480,18 @@ const editorConfiguration: IConfigurationNode = { } ], 'default': EDITOR_DEFAULTS.contribInfo.quickSuggestions, - 'description': nls.localize('quickSuggestions', "Controls if suggestions should automatically show up while typing") + 'description': nls.localize('quickSuggestions', "Controls whether suggestions should automatically show up while typing.") }, 'editor.quickSuggestionsDelay': { 'type': 'integer', 'default': EDITOR_DEFAULTS.contribInfo.quickSuggestionsDelay, 'minimum': 0, - 'description': nls.localize('quickSuggestionsDelay', "Controls the delay in ms after which quick suggestions will show up") + 'description': nls.localize('quickSuggestionsDelay', "Controls the delay in milliseconds after which quick suggestions will show up.") }, 'editor.parameterHints': { 'type': 'boolean', 'default': EDITOR_DEFAULTS.contribInfo.parameterHints, - 'description': nls.localize('parameterHints', "Enables pop-up that shows parameter documentation and type information as you type") + 'description': nls.localize('parameterHints', "Enables a pop-up that shows parameter documentation and type information as you type.") }, 'editor.autoClosingBrackets': { 'type': 'boolean', @@ -607,7 +607,7 @@ const editorConfiguration: IConfigurationNode = { 'editor.overviewRulerBorder': { 'type': 'boolean', 'default': EDITOR_DEFAULTS.viewInfo.overviewRulerBorder, - 'description': nls.localize('overviewRulerBorder', "Controls if a border should be drawn around the overview ruler.") + 'description': nls.localize('overviewRulerBorder', "Controls whether a border should be drawn around the overview ruler.") }, 'editor.cursorBlinking': { 'type': 'string', @@ -618,7 +618,7 @@ const editorConfiguration: IConfigurationNode = { 'editor.mouseWheelZoom': { 'type': 'boolean', 'default': EDITOR_DEFAULTS.viewInfo.mouseWheelZoom, - 'description': nls.localize('mouseWheelZoom', "Zoom the font of the editor when using mouse wheel and holding Ctrl.") + 'description': nls.localize('mouseWheelZoom', "Zoom the font of the editor when using mouse wheel and holding `Ctrl`.") }, 'editor.cursorStyle': { 'type': 'string', @@ -670,8 +670,14 @@ const editorConfiguration: IConfigurationNode = { 'editor.renderLineHighlight': { 'type': 'string', 'enum': ['none', 'gutter', 'line', 'all'], + 'enumDescriptions': [ + '', + '', + '', + nls.localize('renderLineHighlight.all', "Highlights both the gutter and the current line."), + ], default: EDITOR_DEFAULTS.viewInfo.renderLineHighlight, - description: nls.localize('renderLineHighlight', "Controls how the editor should render the current line highlight, possibilities are 'none', 'gutter', 'line', and 'all'.") + description: nls.localize('renderLineHighlight', "Controls how the editor should render the current line highlight.") }, 'editor.codeLens': { 'type': 'boolean', @@ -748,7 +754,7 @@ const editorConfiguration: IConfigurationNode = { 'editor.links': { 'type': 'boolean', 'default': EDITOR_DEFAULTS.contribInfo.links, - 'description': nls.localize('links', "Controls whether the editor should detect links and make them clickable") + 'description': nls.localize('links', "Controls whether the editor should detect links and make them clickable.") }, 'editor.colorDecorators': { 'type': 'boolean', @@ -758,7 +764,7 @@ const editorConfiguration: IConfigurationNode = { 'editor.lightbulb.enabled': { 'type': 'boolean', 'default': EDITOR_DEFAULTS.contribInfo.lightbulbEnabled, - 'description': nls.localize('codeActions', "Enables the code action lightbulb") + 'description': nls.localize('codeActions', "Enables the code action lightbulb in the editor.") }, 'editor.codeActionsOnSave': { 'type': 'object', @@ -782,7 +788,7 @@ const editorConfiguration: IConfigurationNode = { 'editor.selectionClipboard': { 'type': 'boolean', 'default': EDITOR_DEFAULTS.contribInfo.selectionClipboard, - 'description': nls.localize('selectionClipboard', "Controls if the Linux primary clipboard should be supported."), + 'description': nls.localize('selectionClipboard', "Controls whether the Linux primary clipboard should be supported."), 'included': platform.isLinux }, 'diffEditor.renderSideBySide': { From 2cfa05d5986359b773c40a6ca7115d338907af34 Mon Sep 17 00:00:00 2001 From: Jackson Kearl Date: Fri, 27 Jul 2018 16:27:32 -0700 Subject: [PATCH 0266/1276] Minor css tweaks to enable eoverflow elipsis in more places (#55277) --- src/vs/workbench/browser/media/part.css | 3 +++ .../extensions/electron-browser/media/extensionsViewlet.css | 6 +----- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/src/vs/workbench/browser/media/part.css b/src/vs/workbench/browser/media/part.css index f9f85749d90..fc87a52eaf3 100644 --- a/src/vs/workbench/browser/media/part.css +++ b/src/vs/workbench/browser/media/part.css @@ -36,6 +36,9 @@ font-weight: normal; -webkit-margin-before: 0; -webkit-margin-after: 0; + overflow: hidden; + white-space: nowrap; + text-overflow: ellipsis; } .monaco-workbench > .part > .title > .title-label a { diff --git a/src/vs/workbench/parts/extensions/electron-browser/media/extensionsViewlet.css b/src/vs/workbench/parts/extensions/electron-browser/media/extensionsViewlet.css index 068b300a098..98e419e22e2 100644 --- a/src/vs/workbench/parts/extensions/electron-browser/media/extensionsViewlet.css +++ b/src/vs/workbench/parts/extensions/electron-browser/media/extensionsViewlet.css @@ -27,10 +27,6 @@ height: calc(100% - 38px); } -.extensions-viewlet > .extensions .list-actionbar-container { - margin-right: 10px; -} - .extensions-viewlet > .extensions .list-actionbar-container .monaco-action-bar .action-item > .octicon { font-size: 12px; line-height: 1; @@ -48,7 +44,7 @@ } .extensions-viewlet > .extensions .panel-header { - padding-right: 12px; + padding-right: 28px; } .extensions-viewlet > .extensions .panel-header > .title { From 74ec3dc59c1adf8991d80e618a68c00759df7e29 Mon Sep 17 00:00:00 2001 From: SteVen Batten <6561887+sbatten@users.noreply.github.com> Date: Fri, 27 Jul 2018 16:49:15 -0700 Subject: [PATCH 0267/1276] fix an issue with titlebarheight when not scaling with zoom --- src/vs/workbench/electron-browser/workbench.ts | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/vs/workbench/electron-browser/workbench.ts b/src/vs/workbench/electron-browser/workbench.ts index 7b1a3b7212b..2ae71ce73f3 100644 --- a/src/vs/workbench/electron-browser/workbench.ts +++ b/src/vs/workbench/electron-browser/workbench.ts @@ -1182,6 +1182,9 @@ export class Workbench extends Disposable implements IPartService { let offset = 0; if (this.isVisible(Parts.TITLEBAR_PART)) { offset = this.workbenchLayout.partLayoutInfo.titlebar.height; + if (isMacintosh || this.menubarVisibility === 'hidden') { + offset /= browser.getZoomFactor(); + } } return offset; From f3ef439d3c13cf09aaafbd443ff80cf07a05469e Mon Sep 17 00:00:00 2001 From: Ramya Achutha Rao Date: Fri, 27 Jul 2018 16:52:10 -0700 Subject: [PATCH 0268/1276] Settings descriptions update #54690 --- .../common/config/commonEditorConfig.ts | 48 +++++++++---------- .../electron-browser/files.contribution.ts | 2 +- 2 files changed, 23 insertions(+), 27 deletions(-) diff --git a/src/vs/editor/common/config/commonEditorConfig.ts b/src/vs/editor/common/config/commonEditorConfig.ts index 5c2a991431a..33a9a433690 100644 --- a/src/vs/editor/common/config/commonEditorConfig.ts +++ b/src/vs/editor/common/config/commonEditorConfig.ts @@ -294,12 +294,12 @@ const editorConfiguration: IConfigurationNode = { 'editor.detectIndentation': { 'type': 'boolean', 'default': EDITOR_MODEL_DEFAULTS.detectIndentation, - 'description': nls.localize('detectIndentation', "When opening a file, `#editor.tabSize#` and `#editor.insertSpaces#` will be detected based on the file contents.") + 'description': nls.localize('detectIndentation', "Controls whether `#editor.tabSize#` and `#editor.insertSpaces#` will be automatically detected when a file is opened based on the file contents.") }, 'editor.roundedSelection': { 'type': 'boolean', 'default': EDITOR_DEFAULTS.viewInfo.roundedSelection, - 'description': nls.localize('roundedSelection', "Controls whether selections have rounded corners.") + 'description': nls.localize('roundedSelection', "Controls whether selections should have rounded corners.") }, 'editor.scrollBeyondLastLine': { 'type': 'boolean', @@ -346,17 +346,17 @@ const editorConfiguration: IConfigurationNode = { 'editor.hover.enabled': { 'type': 'boolean', 'default': EDITOR_DEFAULTS.contribInfo.hover.enabled, - 'description': nls.localize('hover.enabled', "Controls if the hover is shown") + 'description': nls.localize('hover.enabled', "Controls whether the hover is shown.") }, 'editor.hover.delay': { 'type': 'number', 'default': EDITOR_DEFAULTS.contribInfo.hover.delay, - 'description': nls.localize('hover.delay', "Controls the delay after which to show the hover") + 'description': nls.localize('hover.delay', "Time delay in milliseconds after which to the hover is shown.") }, 'editor.hover.sticky': { 'type': 'boolean', 'default': EDITOR_DEFAULTS.contribInfo.hover.sticky, - 'description': nls.localize('hover.sticky', "Controls if the hover should remain visible when mouse is moved over it") + 'description': nls.localize('hover.sticky', "Controls whether the hover should remain visible when mouse is moved over it.") }, 'editor.find.seedSearchStringFromSelection': { 'type': 'boolean', @@ -366,7 +366,7 @@ const editorConfiguration: IConfigurationNode = { 'editor.find.autoFindInSelection': { 'type': 'boolean', 'default': EDITOR_DEFAULTS.contribInfo.find.autoFindInSelection, - 'description': nls.localize('find.autoFindInSelection', "Controls whether the Find in Selection flag is turned on when multiple characters or lines of text are selected in the editor.") + 'description': nls.localize('find.autoFindInSelection', "Controls whether the find operation is carried on selected text or the entire file in the editor.") }, 'editor.find.globalFindClipboard': { 'type': 'boolean', @@ -430,7 +430,7 @@ const editorConfiguration: IConfigurationNode = { 'editor.mouseWheelScrollSensitivity': { 'type': 'number', 'default': EDITOR_DEFAULTS.viewInfo.scrollbar.mouseWheelScrollSensitivity, - 'description': nls.localize('mouseWheelScrollSensitivity', "A multiplier to be used on the `deltaX` and `deltaY` of mouse wheel scroll events") + 'description': nls.localize('mouseWheelScrollSensitivity', "A multiplier to be used on the `deltaX` and `deltaY` of mouse wheel scroll events.") }, 'editor.multiCursorModifier': { 'type': 'string', @@ -496,27 +496,27 @@ const editorConfiguration: IConfigurationNode = { 'editor.autoClosingBrackets': { 'type': 'boolean', 'default': EDITOR_DEFAULTS.autoClosingBrackets, - 'description': nls.localize('autoClosingBrackets', "Controls if the editor should automatically close brackets after opening them") + 'description': nls.localize('autoClosingBrackets', "Controls whether the editor should automatically close brackets after the user adds an opening bracket.") }, 'editor.formatOnType': { 'type': 'boolean', 'default': EDITOR_DEFAULTS.contribInfo.formatOnType, - 'description': nls.localize('formatOnType', "Controls if the editor should automatically format the line after typing.") + 'description': nls.localize('formatOnType', "Controls whether the editor should automatically format the line after typing.") }, 'editor.formatOnPaste': { 'type': 'boolean', 'default': EDITOR_DEFAULTS.contribInfo.formatOnPaste, - 'description': nls.localize('formatOnPaste', "Controls if the editor should automatically format the pasted content. A formatter must be available and the formatter should be able to format a range in a document.") + 'description': nls.localize('formatOnPaste', "Controls whether the editor should automatically format the pasted content. A formatter must be available and the formatter should be able to format a range in a document.") }, 'editor.autoIndent': { 'type': 'boolean', 'default': EDITOR_DEFAULTS.autoIndent, - 'description': nls.localize('autoIndent', "Controls if the editor should automatically adjust the indentation when users type, paste or move lines. Indentation rules of the language must be available.") + 'description': nls.localize('autoIndent', "Controls whether the editor should automatically adjust the indentation when users type, paste or move lines. Extensions with indentation rules of the language must be available.") }, 'editor.suggestOnTriggerCharacters': { 'type': 'boolean', 'default': EDITOR_DEFAULTS.contribInfo.suggestOnTriggerCharacters, - 'description': nls.localize('suggestOnTriggerCharacters', "Controls if suggestions should automatically show up when typing trigger characters.") + 'description': nls.localize('suggestOnTriggerCharacters', "Controls whether suggestions should automatically show up when typing trigger characters.") }, 'editor.acceptSuggestionOnEnter': { 'type': 'string', @@ -634,12 +634,12 @@ const editorConfiguration: IConfigurationNode = { 'editor.fontLigatures': { 'type': 'boolean', 'default': EDITOR_DEFAULTS.viewInfo.fontLigatures, - 'description': nls.localize('fontLigatures', "Enables font ligatures.") + 'description': nls.localize('fontLigatures', "Enables/Disables font ligatures.") }, 'editor.hideCursorInOverviewRuler': { 'type': 'boolean', 'default': EDITOR_DEFAULTS.viewInfo.hideCursorInOverviewRuler, - 'description': nls.localize('hideCursorInOverviewRuler', "Controls if the cursor should be hidden in the overview ruler.") + 'description': nls.localize('hideCursorInOverviewRuler', "Controls whether the cursor should be hidden in the overview ruler.") }, 'editor.renderWhitespace': { 'type': 'string', @@ -665,7 +665,7 @@ const editorConfiguration: IConfigurationNode = { 'editor.highlightActiveIndentGuide': { 'type': 'boolean', default: EDITOR_DEFAULTS.viewInfo.highlightActiveIndentGuide, - description: nls.localize('highlightActiveIndentGuide', "Controls whether the editor should highlight the active indent guide") + description: nls.localize('highlightActiveIndentGuide', "Controls whether the editor should highlight the active indent guide.") }, 'editor.renderLineHighlight': { 'type': 'string', @@ -682,7 +682,7 @@ const editorConfiguration: IConfigurationNode = { 'editor.codeLens': { 'type': 'boolean', 'default': EDITOR_DEFAULTS.contribInfo.codeLens, - 'description': nls.localize('codeLens', "Controls if the editor shows CodeLens") + 'description': nls.localize('codeLens', "Controls whether the editor shows CodeLens") }, 'editor.folding': { 'type': 'boolean', @@ -692,12 +692,8 @@ const editorConfiguration: IConfigurationNode = { 'editor.foldingStrategy': { 'type': 'string', 'enum': ['auto', 'indentation'], - 'enumDescriptions': [ - nls.localize('foldingStrategyAuto', 'If available, use a language specific folding strategy, otherwise falls back to the indentation based strategy.'), - nls.localize('foldingStrategyIndentation', 'Always use the indentation based folding strategy') - ], 'default': EDITOR_DEFAULTS.contribInfo.foldingStrategy, - 'description': nls.localize('foldingStrategy', "Controls the way folding ranges are computed. 'auto' picks uses a language specific folding strategy, if available. 'indentation' forces that the indentation based folding strategy is used.") + 'description': nls.localize('foldingStrategy', "Controls the strategy for computing folding ranges. `auto` uses a language specific folding strategy, if available. `indentation` uses the indentation based folding strategy.") }, 'editor.showFoldingControls': { 'type': 'string', @@ -733,7 +729,7 @@ const editorConfiguration: IConfigurationNode = { 'editor.dragAndDrop': { 'type': 'boolean', 'default': EDITOR_DEFAULTS.dragAndDrop, - 'description': nls.localize('dragAndDrop', "Controls if the editor should allow to move selections via drag and drop.") + 'description': nls.localize('dragAndDrop', "Controls whether the editor should allow moving selections via drag and drop.") }, 'editor.accessibilitySupport': { 'type': 'string', @@ -771,7 +767,7 @@ const editorConfiguration: IConfigurationNode = { 'properties': { 'source.organizeImports': { 'type': 'boolean', - 'description': nls.localize('codeActionsOnSave.organizeImports', "Run organize imports on save?") + 'description': nls.localize('codeActionsOnSave.organizeImports', "Controls whether organize imports action should be run on file save.") } }, 'additionalProperties': { @@ -783,7 +779,7 @@ const editorConfiguration: IConfigurationNode = { 'editor.codeActionsOnSaveTimeout': { 'type': 'number', 'default': EDITOR_DEFAULTS.contribInfo.codeActionsOnSaveTimeout, - 'description': nls.localize('codeActionsOnSaveTimeout', "Timeout for code actions run on save.") + 'description': nls.localize('codeActionsOnSaveTimeout', "Timeout in milliseconds after which the code actions that are run on save are cancelled.") }, 'editor.selectionClipboard': { 'type': 'boolean', @@ -799,7 +795,7 @@ const editorConfiguration: IConfigurationNode = { 'diffEditor.ignoreTrimWhitespace': { 'type': 'boolean', 'default': true, - 'description': nls.localize('ignoreTrimWhitespace', "Controls if the diff editor shows changes in leading or trailing whitespace as diffs") + 'description': nls.localize('ignoreTrimWhitespace', "Controls whether the diff editor shows changes in leading or trailing whitespace as diffs.") }, 'editor.largeFileOptimizations': { 'type': 'boolean', @@ -809,7 +805,7 @@ const editorConfiguration: IConfigurationNode = { 'diffEditor.renderIndicators': { 'type': 'boolean', 'default': true, - 'description': nls.localize('renderIndicators', "Controls if the diff editor shows +/- indicators for added/removed changes") + 'description': nls.localize('renderIndicators', "Controls whether the diff editor shows +/- indicators for added/removed changes.") } } }; diff --git a/src/vs/workbench/parts/files/electron-browser/files.contribution.ts b/src/vs/workbench/parts/files/electron-browser/files.contribution.ts index 4c937a50456..a1ff10697c8 100644 --- a/src/vs/workbench/parts/files/electron-browser/files.contribution.ts +++ b/src/vs/workbench/parts/files/electron-browser/files.contribution.ts @@ -331,7 +331,7 @@ configurationRegistry.registerConfiguration({ 'editor.formatOnSaveTimeout': { 'type': 'number', 'default': 750, - 'description': nls.localize('formatOnSaveTimeout', "Format on save timeout. Specifies a time limit in milliseconds for `formatOnSave`-commands. Commands taking longer than the specified timeout will be cancelled."), + 'description': nls.localize('formatOnSaveTimeout', "Timeout in milliseconds after which the formatting that is run on file save is cancelled."), 'overridable': true, 'scope': ConfigurationScope.RESOURCE } From 56e21e287358ce7e6a99194e623f56df7e27745a Mon Sep 17 00:00:00 2001 From: SteVen Batten Date: Fri, 27 Jul 2018 17:01:26 -0700 Subject: [PATCH 0269/1276] fixes #55209 --- src/vs/code/electron-main/menubar.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/vs/code/electron-main/menubar.ts b/src/vs/code/electron-main/menubar.ts index 5d25416f1f9..556dfe6d3c4 100644 --- a/src/vs/code/electron-main/menubar.ts +++ b/src/vs/code/electron-main/menubar.ts @@ -489,6 +489,8 @@ export class Menubar { // Store the keybinding if (item.keybinding) { this.keybindings[item.id] = item.keybinding; + } else if (this.keybindings[item.id]) { + this.keybindings[item.id] = undefined; } const menuItem = this.createMenuItem(item.label, item.id, item.enabled, item.checked); From 2ffccf8f2e44247dd75c624e215c854b3aeb1f1c Mon Sep 17 00:00:00 2001 From: Rob Lourens Date: Fri, 27 Jul 2018 15:45:21 -0700 Subject: [PATCH 0270/1276] Settings editor - many padding fixes --- .../browser/media/settingsEditor2.css | 33 +++++++++++-------- .../preferences/browser/settingsEditor2.ts | 10 +++--- .../parts/preferences/browser/settingsTree.ts | 2 +- 3 files changed, 26 insertions(+), 19 deletions(-) diff --git a/src/vs/workbench/parts/preferences/browser/media/settingsEditor2.css b/src/vs/workbench/parts/preferences/browser/media/settingsEditor2.css index 27752e36211..725e3b30bb3 100644 --- a/src/vs/workbench/parts/preferences/browser/media/settingsEditor2.css +++ b/src/vs/workbench/parts/preferences/browser/media/settingsEditor2.css @@ -56,9 +56,10 @@ } .settings-editor > .settings-header > .settings-header-controls { - height: 29px; + height: 32px; display: flex; border-bottom: solid 1px; + margin-top: 10px; } .settings-editor > .settings-header > .settings-header-controls .settings-tabs-widget .action-label { @@ -122,7 +123,7 @@ text-transform: none; font-size: 13px; - padding-bottom: 4px; + padding-bottom: 7px; padding-top: 7px; padding-left: 8px; padding-right: 8px; @@ -148,7 +149,7 @@ .settings-editor > .settings-body .settings-toc-container { width: 160px; - margin-top: 5px; + margin-top: 16px; padding-left: 5px; } @@ -200,15 +201,15 @@ flex: 1; max-width: 792px; margin-right: 1px; /* So the item doesn't blend into the edge of the view container */ - margin-top: 8px; + margin-top: 14px; border-spacing: 0; border-collapse: separate; position: relative; } .settings-editor > .settings-body > .settings-tree-container .setting-item { - padding-top: 11px; - padding-bottom: 15px; + padding-top: 8px; + padding-bottom: 14px; box-sizing: border-box; cursor: default; white-space: normal; @@ -276,15 +277,15 @@ } .settings-editor > .settings-body > .settings-tree-container .setting-item-bool .setting-value-checkbox { - height: 16px; - width: 16px; + height: 18px; + width: 18px; border: 1px solid transparent; border-radius: 3px; - margin-right: 4px; + margin-right: 9px; margin-left: 0px; - margin-top: 2px; + margin-top: 4px; padding: 0px; - background-size: 14px !important; + background-size: 16px !important; } .vs .settings-editor > .settings-body > .settings-tree-container .setting-item-bool .setting-value-checkbox.checked { @@ -296,7 +297,7 @@ } .settings-editor > .settings-body > .settings-tree-container .setting-item .setting-item-value { - margin-top: 7px; + margin-top: 9px; display: flex; } @@ -304,6 +305,10 @@ min-width: 200px; } +.settings-editor > .settings-body > .settings-tree-container .setting-item.setting-item-text { + width: 500px; +} + .settings-editor > .settings-body > .settings-tree-container .setting-item.setting-item-enum .setting-item-value > .setting-item-control, .settings-editor > .settings-body > .settings-tree-container .setting-item.setting-item-text .setting-item-value > .setting-item-control { flex: 1; @@ -311,7 +316,7 @@ } .settings-editor > .settings-body > .settings-tree-container .setting-item.setting-item-enum .setting-item-value > .setting-item-control > select { - width: 100%; + width: 320px; } .settings-editor > .settings-body > .settings-tree-container .setting-item .setting-item-value .edit-in-settings-button, @@ -350,7 +355,7 @@ .settings-editor > .settings-body > .settings-tree-container .settings-group-title-label { margin: 0px; - font-weight: bold; + font-weight: 500; } .settings-editor > .settings-body > .settings-tree-container .settings-group-level-1 { diff --git a/src/vs/workbench/parts/preferences/browser/settingsEditor2.ts b/src/vs/workbench/parts/preferences/browser/settingsEditor2.ts index 3793973a9fd..ca1aec458a6 100644 --- a/src/vs/workbench/parts/preferences/browser/settingsEditor2.ts +++ b/src/vs/workbench/parts/preferences/browser/settingsEditor2.ts @@ -803,16 +803,18 @@ export class SettingsEditor2 extends BaseEditor { private layoutTrees(dimension: DOM.Dimension): void { const listHeight = dimension.height - (DOM.getDomNodePagePosition(this.headerContainer).height + 11 /*padding*/); - this.settingsTreeContainer.style.height = `${listHeight}px`; - this.settingsTree.layout(listHeight - 8, 800); + const settingsTreeHeight = listHeight - 14; + this.settingsTreeContainer.style.height = `${settingsTreeHeight}px`; + this.settingsTree.layout(settingsTreeHeight, 800); const selectedSetting = this.settingsTree.getSelection()[0]; if (selectedSetting) { this.settingsTree.refresh(selectedSetting); } - this.tocTreeContainer.style.height = `${listHeight}px`; - this.tocTree.layout(listHeight - 5, 175); + const tocTreeHeight = listHeight - 16; + this.tocTreeContainer.style.height = `${tocTreeHeight}px`; + this.tocTree.layout(tocTreeHeight, 175); } } diff --git a/src/vs/workbench/parts/preferences/browser/settingsTree.ts b/src/vs/workbench/parts/preferences/browser/settingsTree.ts index 7f0205c640e..77fabc6ac17 100644 --- a/src/vs/workbench/parts/preferences/browser/settingsTree.ts +++ b/src/vs/workbench/parts/preferences/browser/settingsTree.ts @@ -530,7 +530,7 @@ export interface ISettingChangeEvent { export class SettingsRenderer implements ITreeRenderer { - private static readonly SETTING_ROW_HEIGHT = 98; + private static readonly SETTING_ROW_HEIGHT = 96; private static readonly SETTING_BOOL_ROW_HEIGHT = 65; public static readonly MAX_ENUM_DESCRIPTIONS = 10; From d6d9cd20c275357adaa1807e94a61d9a401c5247 Mon Sep 17 00:00:00 2001 From: Rob Lourens Date: Fri, 27 Jul 2018 16:10:54 -0700 Subject: [PATCH 0271/1276] More space above level 2 label --- .../parts/preferences/browser/media/settingsEditor2.css | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vs/workbench/parts/preferences/browser/media/settingsEditor2.css b/src/vs/workbench/parts/preferences/browser/media/settingsEditor2.css index 725e3b30bb3..010ed8a37d2 100644 --- a/src/vs/workbench/parts/preferences/browser/media/settingsEditor2.css +++ b/src/vs/workbench/parts/preferences/browser/media/settingsEditor2.css @@ -364,7 +364,7 @@ } .settings-editor > .settings-body > .settings-tree-container .settings-group-level-2 { - padding-top: 27px; + padding-top: 32px; font-size: 20px; } From 812d082e9032647dcbbd9e44bda4e576e96d27d6 Mon Sep 17 00:00:00 2001 From: Erich Gamma Date: Sat, 28 Jul 2018 18:40:21 +0200 Subject: [PATCH 0272/1276] Fixing Cannot debug npm script using Yarn #55103 --- extensions/npm/src/tasks.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/extensions/npm/src/tasks.ts b/extensions/npm/src/tasks.ts index 008d5ba7e70..3060cce1ed6 100644 --- a/extensions/npm/src/tasks.ts +++ b/extensions/npm/src/tasks.ts @@ -289,8 +289,8 @@ async function readFile(file: string): Promise { } export function extractDebugArgFromScript(scriptValue: string): [string, number] | undefined { - // matches --debug, --debug=1234, --debug-brk, debug-brk=1234, --inspect, - // --inspect=1234, --inspect-brk, --inspect-brk=1234, + // matches --debug, --debug=1234, --debug-brk, debug-brk=1234, --inspect, + // --inspect=1234, --inspect-brk, --inspect-brk=1234, // --inspect=localhost:1245, --inspect=127.0.0.1:1234, --inspect=[aa:1:0:0:0]:1234, --inspect=:1234 let match = scriptValue.match(/--(inspect|debug)(-brk)?(=((\[[0-9a-fA-F:]*\]|[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+|[a-zA-Z0-9\.]*):)?(\d+))?/); @@ -321,7 +321,7 @@ export function startDebugging(scriptName: string, protocol: string, port: numbe name: `Debug ${scriptName}`, runtimeExecutable: packageManager, runtimeArgs: [ - 'run-script', + 'run', scriptName, ], port: port, From d773878e72b2aa1c439ef09c4967cd8f8292b980 Mon Sep 17 00:00:00 2001 From: Rob Lourens Date: Fri, 27 Jul 2018 20:55:15 -0700 Subject: [PATCH 0273/1276] Settings editor - show ellipsis when description overflows --- .../browser/media/settingsEditor2.css | 24 ++- .../parts/preferences/browser/settingsTree.ts | 145 +++++++++++++++--- 2 files changed, 147 insertions(+), 22 deletions(-) diff --git a/src/vs/workbench/parts/preferences/browser/media/settingsEditor2.css b/src/vs/workbench/parts/preferences/browser/media/settingsEditor2.css index 010ed8a37d2..2ef284f2d0e 100644 --- a/src/vs/workbench/parts/preferences/browser/media/settingsEditor2.css +++ b/src/vs/workbench/parts/preferences/browser/media/settingsEditor2.css @@ -216,6 +216,18 @@ height: 100%; } +.settings-editor > .settings-body > .settings-tree-container .setting-item .setting-expand-indicator { + display: none; +} + +.settings-editor > .settings-body > .settings-tree-container .setting-item.is-expandable:not(.is-expanded) .setting-expand-indicator { + display: block; + position: absolute; + left: 7px; + top: 2px; + opacity: .9; +} + .settings-editor > .settings-body > .settings-tree-container .setting-item .setting-item-title { white-space: nowrap; overflow: hidden; @@ -246,10 +258,13 @@ opacity: 0.9; } -.settings-editor > .settings-body > .settings-tree-container .setting-item .setting-item-description { +.settings-editor > .settings-body > .settings-tree-container .setting-item .setting-item-description-container { margin-top: 3px; + position: relative; +} + +.settings-editor > .settings-body > .settings-tree-container .setting-item .setting-item-description { overflow: hidden; - text-overflow: ellipsis; height: 18px; } @@ -272,6 +287,11 @@ height: initial; } +.settings-editor > .settings-body > .settings-tree-container .setting-description-measure-container .setting-item .setting-item-description, +.settings-editor > .settings-body > .settings-tree-container .setting-description-measure-container .setting-item .setting-item-description * { + display: inline; +} + .settings-editor > .settings-body > .settings-tree-container .setting-item-bool .setting-item-value-description { display: flex; } diff --git a/src/vs/workbench/parts/preferences/browser/settingsTree.ts b/src/vs/workbench/parts/preferences/browser/settingsTree.ts index 77fabc6ac17..260ce71ac97 100644 --- a/src/vs/workbench/parts/preferences/browser/settingsTree.ts +++ b/src/vs/workbench/parts/preferences/browser/settingsTree.ts @@ -471,6 +471,7 @@ interface ISettingItemTemplate extends IDisposableTemplate { categoryElement: HTMLElement; labelElement: HTMLElement; descriptionElement: HTMLElement; + expandIndicatorElement: HTMLElement; controlElement: HTMLElement; isConfiguredElement: HTMLElement; otherOverridesElement: HTMLElement; @@ -544,6 +545,8 @@ export class SettingsRenderer implements ITreeRenderer { public readonly onDidClickSettingLink: Event = this._onDidClickSettingLink.event; private measureContainer: HTMLElement; + private measureDescriptionContainer: HTMLElement; + private measureDescriptionTemplates = new Map(); constructor( _measureContainer: HTMLElement, @@ -554,6 +557,7 @@ export class SettingsRenderer implements ITreeRenderer { @ICommandService private readonly commandService: ICommandService, ) { this.measureContainer = DOM.append(_measureContainer, $('.setting-measure-container.monaco-tree-row')); + this.measureDescriptionContainer = DOM.append(_measureContainer, $('.setting-measure-container.setting-description-measure-container.monaco-tree-row')); } getHeight(tree: ITree, element: SettingsTreeElement): number { @@ -608,6 +612,40 @@ export class SettingsRenderer implements ITreeRenderer { return Math.max(height, this._getUnexpandedSettingHeight(element)); } + private measureSettingDescriptionHeight(tree: ITree, element: SettingsTreeSettingElement): number { + const measureHelper = DOM.append(this.measureContainer, $('.setting-measure-helper')); + + const templateId = this.getTemplateId(tree, element); + const template = this.renderTemplate(tree, templateId, measureHelper); + this.renderDescription(element.description, template, true); + + const height = (template).descriptionElement.offsetHeight; + this.measureContainer.removeChild(this.measureContainer.firstChild); + return height; + } + + private measureSettingDescription(tree: ITree, element: SettingsTreeSettingElement, text: string): { height: number, width: number } { + const templateId = this.getTemplateId(tree, element); + if (!this.measureDescriptionTemplates.has(templateId)) { + const measureHelper = $('.setting-measure-helper'); + this.measureDescriptionTemplates.set(templateId, this.renderTemplate(tree, templateId, measureHelper)); + } + + const template = this.measureDescriptionTemplates.get(templateId); + this.measureDescriptionContainer.appendChild(template.containerElement); + this.renderDescription(text, template, true); + + const descriptionElement = (template).descriptionElement; + const width = descriptionElement.offsetWidth; + const height = descriptionElement.offsetHeight; + + if (this.measureDescriptionContainer.firstChild) { + this.measureDescriptionContainer.removeChild(this.measureDescriptionContainer.firstChild); + } + + return { height, width }; + } + getTemplateId(tree: ITree, element: SettingsTreeElement): string { if (element instanceof SettingsTreeGroupElement) { @@ -702,11 +740,15 @@ export class SettingsRenderer implements ITreeRenderer { const labelElement = DOM.append(titleElement, $('span.setting-item-label')); const isConfiguredElement = DOM.append(titleElement, $('span.setting-item-is-configured-label')); const otherOverridesElement = DOM.append(titleElement, $('span.setting-item-overrides')); - const descriptionElement = DOM.append(container, $('.setting-item-description')); + const descriptionContainerElement = DOM.append(container, $('.setting-item-description-container')); + const descriptionElement = DOM.append(descriptionContainerElement, $('.setting-item-description')); const valueElement = DOM.append(container, $('.setting-item-value')); const controlElement = DOM.append(valueElement, $('div.setting-item-control')); + const expandIndicatorElement = DOM.append(descriptionContainerElement, $('.setting-expand-indicator')); + expandIndicatorElement.textContent = '…'; + const toDispose = []; const template: ISettingItemTemplate = { toDispose, @@ -717,6 +759,7 @@ export class SettingsRenderer implements ITreeRenderer { descriptionElement, controlElement, isConfiguredElement, + expandIndicatorElement, otherOverridesElement }; @@ -797,7 +840,10 @@ export class SettingsRenderer implements ITreeRenderer { const descriptionAndValueElement = DOM.append(container, $('.setting-item-value-description')); const controlElement = DOM.append(descriptionAndValueElement, $('.setting-item-bool-control')); - const descriptionElement = DOM.append(descriptionAndValueElement, $('.setting-item-description')); + const descriptionContainerElement = DOM.append(descriptionAndValueElement, $('.setting-item-description-container')); + const descriptionElement = DOM.append(descriptionContainerElement, $('.setting-item-description')); + const expandIndicatorElement = DOM.append(descriptionContainerElement, $('.setting-expand-indicator')); + expandIndicatorElement.textContent = '…'; const toDispose = []; const checkbox = new Checkbox({ actionClassName: 'setting-value-checkbox', isChecked: true, title: '', inputActiveOptionBorder: null }); @@ -818,6 +864,7 @@ export class SettingsRenderer implements ITreeRenderer { controlElement, checkbox, descriptionElement, + expandIndicatorElement, isConfiguredElement, otherOverridesElement }; @@ -992,12 +1039,56 @@ export class SettingsRenderer implements ITreeRenderer { template.context = element; } + private isSettingExpandable(tree: ITree, element: SettingsTreeSettingElement): boolean { + // Shortcuts before measuring + if (element.valueType === 'enum' && element.setting.enumDescriptions && element.setting.enum && element.setting.enum.length < SettingsRenderer.MAX_ENUM_DESCRIPTIONS) { + return true; + } + + if (element.setting.description.indexOf('\n') >= 0) { + return true; + } + + const height = this.measureSettingDescriptionHeight(tree, element); + return height > 18; + } + + private settingDescriptionFirstLine(tree: ITree, element: SettingsTreeSettingElement): number { + const fullDescription = element.description; + + // Add characters one at a time, measure the width. Start from some safe number. + let size: { height: number, width: number }; + for (let i = 0; i < fullDescription.length;) { + let description = fullDescription.substr(0, i); + size = this.measureSettingDescription(tree, element, description); + if (size.height > 20) { + // It wrapped + return size.width; + } + + const nextBreakMatch = fullDescription.slice(i + 1).match(/[\s.,$]/); + if (nextBreakMatch) { + if (nextBreakMatch[0] === '\n') { + return size.width; + } else { + i = nextBreakMatch.index + i + 1; + } + } else { + return size.width; + } + } + + return size ? size.width : 0; + } + private renderSettingElement(tree: ITree, element: SettingsTreeSettingElement, templateId: string, template: ISettingItemTemplate | ISettingBoolItemTemplate): void { const isSelected = !!this.elementIsSelected(tree, element); const setting = element.setting; - DOM.toggleClass(template.containerElement, 'is-configured', element.isConfigured); + const isExpandable = this.isSettingExpandable(tree, element); + DOM.toggleClass(template.containerElement, 'is-expandable', isExpandable); DOM.toggleClass(template.containerElement, 'is-expanded', isSelected); + DOM.toggleClass(template.containerElement, 'is-configured', element.isConfigured); template.containerElement.id = element.id.replace(/\./g, '_'); const titleTooltip = setting.key; @@ -1007,9 +1098,33 @@ export class SettingsRenderer implements ITreeRenderer { template.labelElement.textContent = element.displayLabel; template.labelElement.title = titleTooltip; + if (isExpandable) { + const widthInFirstLine = this.settingDescriptionFirstLine(tree, element); + template.expandIndicatorElement.style.left = (widthInFirstLine + 8) + 'px'; + } + + const descriptionText = element.description + this.getEnumDescriptionText(element); + this.renderDescription(descriptionText, template, isSelected); + this.renderValue(element, isSelected, templateId, template); + + template.isConfiguredElement.textContent = element.isConfigured ? localize('configured', "Modified") : ''; + + if (element.overriddenScopeList.length) { + const otherOverridesLabel = element.isConfigured ? + localize('alsoConfiguredIn', "Also modified in") : + localize('configuredIn', "Modified in"); + + template.otherOverridesElement.textContent = `(${otherOverridesLabel}: ${element.overriddenScopeList.join(', ')})`; + } else { + template.otherOverridesElement.textContent = ''; + } + } + + private getEnumDescriptionText(element: SettingsTreeSettingElement): string { + const setting = element.setting; let enumDescriptionText = ''; - if (element.valueType === 'enum' && element.setting.enumDescriptions && element.setting.enum && element.setting.enum.length < SettingsRenderer.MAX_ENUM_DESCRIPTIONS) { - enumDescriptionText = '\n' + element.setting.enumDescriptions + if (element.valueType === 'enum' && setting.enumDescriptions && setting.enum && setting.enum.length < SettingsRenderer.MAX_ENUM_DESCRIPTIONS) { + enumDescriptionText = '\n' + setting.enumDescriptions .map((desc, i) => { const displayEnum = escapeInvisibleChars(setting.enum[i]); return desc ? @@ -1020,8 +1135,12 @@ export class SettingsRenderer implements ITreeRenderer { .join('\n'); } + return enumDescriptionText; + } + + private renderDescription(text: string, template: ISettingItemTemplate | ISettingBoolItemTemplate, isSelected: boolean): void { // Rewrite `#editor.fontSize#` to link format - const descriptionText = (element.description + enumDescriptionText) + const descriptionText = text .replace(/`#(.*)#`/g, (match, settingName) => `[\`${settingName}\`](#${settingName})`); const renderedDescription = renderMarkdown({ value: descriptionText }, { @@ -1043,20 +1162,6 @@ export class SettingsRenderer implements ITreeRenderer { (renderedDescription.querySelectorAll('a')).forEach(aElement => { aElement.tabIndex = isSelected ? 0 : -1; }); - - this.renderValue(element, isSelected, templateId, template); - - template.isConfiguredElement.textContent = element.isConfigured ? localize('configured', "Modified") : ''; - - if (element.overriddenScopeList.length) { - let otherOverridesLabel = element.isConfigured ? - localize('alsoConfiguredIn', "Also modified in") : - localize('configuredIn', "Modified in"); - - template.otherOverridesElement.textContent = `(${otherOverridesLabel}: ${element.overriddenScopeList.join(', ')})`; - } else { - template.otherOverridesElement.textContent = ''; - } } private renderValue(element: SettingsTreeSettingElement, isSelected: boolean, templateId: string, template: ISettingItemTemplate | ISettingBoolItemTemplate): void { From c186d378b884f166eaa2d8b884e96f8059338727 Mon Sep 17 00:00:00 2001 From: Rob Lourens Date: Fri, 27 Jul 2018 21:17:35 -0700 Subject: [PATCH 0274/1276] Settings editor - ... fix measuring around links, relayout --- .../browser/media/settingsEditor2.css | 2 +- .../preferences/browser/settingsEditor2.ts | 5 ++ .../parts/preferences/browser/settingsTree.ts | 55 +++++++++++-------- 3 files changed, 37 insertions(+), 25 deletions(-) diff --git a/src/vs/workbench/parts/preferences/browser/media/settingsEditor2.css b/src/vs/workbench/parts/preferences/browser/media/settingsEditor2.css index 2ef284f2d0e..7e28d6f6021 100644 --- a/src/vs/workbench/parts/preferences/browser/media/settingsEditor2.css +++ b/src/vs/workbench/parts/preferences/browser/media/settingsEditor2.css @@ -224,7 +224,7 @@ display: block; position: absolute; left: 7px; - top: 2px; + top: 0px; opacity: .9; } diff --git a/src/vs/workbench/parts/preferences/browser/settingsEditor2.ts b/src/vs/workbench/parts/preferences/browser/settingsEditor2.ts index ca1aec458a6..7671789a22c 100644 --- a/src/vs/workbench/parts/preferences/browser/settingsEditor2.ts +++ b/src/vs/workbench/parts/preferences/browser/settingsEditor2.ts @@ -86,6 +86,8 @@ export class SettingsEditor2 extends BaseEditor { private tagRegex = /(^|\s)@tag:("([^"]*)"|[^"]\S*)/g; + private layoutDelayer: Delayer; + /** Don't spam warnings */ private hasWarnedMissingSettings: boolean; @@ -106,6 +108,7 @@ export class SettingsEditor2 extends BaseEditor { this.localSearchDelayer = new Delayer(100); this.remoteSearchThrottle = new ThrottledDelayer(200); this.viewState = { settingsTarget: ConfigurationTarget.USER }; + this.layoutDelayer = new Delayer(100); this.settingUpdateDelayer = new Delayer(500); @@ -150,6 +153,8 @@ export class SettingsEditor2 extends BaseEditor { this.layoutTrees(dimension); DOM.toggleClass(this.rootElement, 'narrow', dimension.width < 600); + + this.layoutDelayer.trigger(() => this.refreshTreeAndMaintainFocus()); } focus(): void { diff --git a/src/vs/workbench/parts/preferences/browser/settingsTree.ts b/src/vs/workbench/parts/preferences/browser/settingsTree.ts index 260ce71ac97..437f3f1ba8f 100644 --- a/src/vs/workbench/parts/preferences/browser/settingsTree.ts +++ b/src/vs/workbench/parts/preferences/browser/settingsTree.ts @@ -1053,12 +1053,15 @@ export class SettingsRenderer implements ITreeRenderer { return height > 18; } - private settingDescriptionFirstLine(tree: ITree, element: SettingsTreeSettingElement): number { - const fullDescription = element.description; + private settingDescriptionFirstLineLength(tree: ITree, element: SettingsTreeSettingElement): number { + const fullDescription = element.description + .replace(/\[(.*)\]\(.*\)/, '$1') + .split('\n')[0]; // Add characters one at a time, measure the width. Start from some safe number. + // const startPos = Math.min(50, fullDescription.length - 1); let size: { height: number, width: number }; - for (let i = 0; i < fullDescription.length;) { + for (let i = 10; i <= fullDescription.length;) { let description = fullDescription.substr(0, i); size = this.measureSettingDescription(tree, element, description); if (size.height > 20) { @@ -1068,11 +1071,7 @@ export class SettingsRenderer implements ITreeRenderer { const nextBreakMatch = fullDescription.slice(i + 1).match(/[\s.,$]/); if (nextBreakMatch) { - if (nextBreakMatch[0] === '\n') { - return size.width; - } else { - i = nextBreakMatch.index + i + 1; - } + i = nextBreakMatch.index + i + 1; } else { return size.width; } @@ -1099,7 +1098,7 @@ export class SettingsRenderer implements ITreeRenderer { template.labelElement.title = titleTooltip; if (isExpandable) { - const widthInFirstLine = this.settingDescriptionFirstLine(tree, element); + const widthInFirstLine = this.settingDescriptionFirstLineLength(tree, element); template.expandIndicatorElement.style.left = (widthInFirstLine + 8) + 'px'; } @@ -1138,30 +1137,38 @@ export class SettingsRenderer implements ITreeRenderer { return enumDescriptionText; } - private renderDescription(text: string, template: ISettingItemTemplate | ISettingBoolItemTemplate, isSelected: boolean): void { + private renderDescription(text: string, template: ISettingItemTemplate | ISettingBoolItemTemplate, isSelected: boolean, measuring = false): void { // Rewrite `#editor.fontSize#` to link format const descriptionText = text .replace(/`#(.*)#`/g, (match, settingName) => `[\`${settingName}\`](#${settingName})`); const renderedDescription = renderMarkdown({ value: descriptionText }, { - actionHandler: { - callback: (content: string) => { - if (startsWith(content, '#')) { - this._onDidClickSettingLink.fire(content.substr(1)); - } else { - this.openerService.open(URI.parse(content)).then(void 0, onUnexpectedError); - } - }, - disposeables: template.toDispose - } + actionHandler: measuring ? + undefined : + { + callback: (content: string) => { + if (startsWith(content, '#')) { + this._onDidClickSettingLink.fire(content.substr(1)); + } else { + this.openerService.open(URI.parse(content)).then(void 0, onUnexpectedError); + } + }, + disposeables: template.toDispose + } }); - cleanRenderedMarkdown(renderedDescription); + if (!measuring) { + cleanRenderedMarkdown(renderedDescription); + } + renderedDescription.classList.add('setting-item-description-markdown'); template.descriptionElement.innerHTML = ''; template.descriptionElement.appendChild(renderedDescription); - (renderedDescription.querySelectorAll('a')).forEach(aElement => { - aElement.tabIndex = isSelected ? 0 : -1; - }); + + if (!measuring) { + (renderedDescription.querySelectorAll('a')).forEach(aElement => { + aElement.tabIndex = isSelected ? 0 : -1; + }); + } } private renderValue(element: SettingsTreeSettingElement, isSelected: boolean, templateId: string, template: ISettingItemTemplate | ISettingBoolItemTemplate): void { From a2767ab649572d98fc53ab8856ab581b1e35bfdb Mon Sep 17 00:00:00 2001 From: Rob Lourens Date: Sat, 28 Jul 2018 09:29:28 -0700 Subject: [PATCH 0275/1276] Setting descriptions --- extensions/typescript-language-features/package.json | 5 +++++ .../typescript-language-features/package.nls.json | 5 ++++- src/vs/workbench/electron-browser/main.contribution.ts | 10 +++++----- 3 files changed, 14 insertions(+), 6 deletions(-) diff --git a/extensions/typescript-language-features/package.json b/extensions/typescript-language-features/package.json index 6ba67c823ab..cd5dc87bf4c 100644 --- a/extensions/typescript-language-features/package.json +++ b/extensions/typescript-language-features/package.json @@ -496,6 +496,11 @@ "always", "never" ], + "enumDescriptions": [ + "%typescript.updateImportsOnFileMove.enabled.prompt%", + "%typescript.updateImportsOnFileMove.enabled.always%", + "%typescript.updateImportsOnFileMove.enabled.never%" + ], "default": "prompt", "description": "%typescript.updateImportsOnFileMove.enabled%", "scope": "resource" diff --git a/extensions/typescript-language-features/package.nls.json b/extensions/typescript-language-features/package.nls.json index 26b3c6e0bdf..918366a21ca 100644 --- a/extensions/typescript-language-features/package.nls.json +++ b/extensions/typescript-language-features/package.nls.json @@ -61,6 +61,9 @@ "typescript.preferences.importModuleSpecifier.auto": "Infer the shortest path type.", "typescript.preferences.importModuleSpecifier.relative": "Relative to the file location.", "typescript.preferences.importModuleSpecifier.nonRelative": "Based on the `baseUrl` configured in your `jsconfig.json` / `tsconfig.json`.", - "typescript.updateImportsOnFileMove.enabled": "Enable/disable automatic updating of import paths when you rename or move a file in VS Code. Possible values are: 'prompt' on each rename, 'always' update paths automatically, and 'never' rename paths and don't prompt me. Requires using TypeScript 2.9 or newer in the workspace.", + "typescript.updateImportsOnFileMove.enabled": "Enable/disable automatic updating of import paths when you rename or move a file in VS Code. Requires using TypeScript 2.9 or newer in the workspace.", + "typescript.updateImportsOnFileMove.enabled.prompt": "Prompt on each rename.", + "typescript.updateImportsOnFileMove.enabled.always": "Always update paths automatically.", + "typescript.updateImportsOnFileMove.enabled.never": "Never rename paths and don't prompt.", "typescript.autoClosingTags": "Enable/disable automatic closing of JSX tags. Requires using TypeScript 3.0 or newer in the workspace." } \ No newline at end of file diff --git a/src/vs/workbench/electron-browser/main.contribution.ts b/src/vs/workbench/electron-browser/main.contribution.ts index 3753a536e3c..e2bf1cb5113 100644 --- a/src/vs/workbench/electron-browser/main.contribution.ts +++ b/src/vs/workbench/electron-browser/main.contribution.ts @@ -566,13 +566,13 @@ configurationRegistry.registerConfiguration({ ], 'default': 'one', 'scope': ConfigurationScope.APPLICATION, - 'description': nls.localize('restoreWindows', "Controls how windows are being reopened after a restart. Select 'none' to always start with an empty workspace, 'one' to reopen the last window you worked on, 'folders' to reopen all windows that had folders opened or 'all' to reopen all windows of your last session.") + 'description': nls.localize('restoreWindows', "Controls how windows are being reopened after a restart.") }, 'window.restoreFullscreen': { 'type': 'boolean', 'default': false, 'scope': ConfigurationScope.APPLICATION, - 'description': nls.localize('restoreFullscreen', "Controls if a window should restore to full screen mode if it was exited in full screen mode.") + 'description': nls.localize('restoreFullscreen', "Controls whether a window should restore to full screen mode if it was exited in full screen mode.") }, 'window.zoomLevel': { 'type': 'number', @@ -583,7 +583,7 @@ configurationRegistry.registerConfiguration({ 'type': 'string', 'default': isMacintosh ? '${activeEditorShort}${separator}${rootName}' : '${dirty}${activeEditorShort}${separator}${rootName}${separator}${appName}', 'description': nls.localize({ comment: ['This is the description for a setting. Values surrounded by parenthesis are not to be translated.'], key: 'title' }, - "Controls the window title based on the active editor. Variables are substituted based on the context:\n\${activeEditorShort}: the file name (e.g. myFile.txt)\n\${activeEditorMedium}: the path of the file relative to the workspace folder (e.g. myFolder/myFile.txt)\n\${activeEditorLong}: the full path of the file (e.g. /Users/Development/myProject/myFolder/myFile.txt)\n\${folderName}: name of the workspace folder the file is contained in (e.g. myFolder)\n\${folderPath}: file path of the workspace folder the file is contained in (e.g. /Users/Development/myFolder)\n\${rootName}: name of the workspace (e.g. myFolder or myWorkspace)\n\${rootPath}: file path of the workspace (e.g. /Users/Development/myWorkspace)\n\${appName}: e.g. VS Code\n\${dirty}: a dirty indicator if the active editor is dirty\n\${separator}: a conditional separator (\" - \") that only shows when surrounded by variables with values or static text") + "Controls the window title based on the active editor. Variables are substituted based on the context:\n- `\${activeEditorShort}`: the file name (e.g. myFile.txt).\n- `\${activeEditorMedium}`: the path of the file relative to the workspace folder (e.g. myFolder/myFile.txt).\n- `\${activeEditorLong}`: the full path of the file (e.g. /Users/Development/myProject/myFolder/myFile.txt).\n- `\${folderName}`: name of the workspace folder the file is contained in (e.g. myFolder).\n- `\${folderPath}`: file path of the workspace folder the file is contained in (e.g. /Users/Development/myFolder).\n- `\${rootName}`: name of the workspace (e.g. myFolder or myWorkspace).\n- `\${rootPath}`: file path of the workspace (e.g. /Users/Development/myWorkspace).\n- `\${appName}`: e.g. VS Code.\n- `\${dirty}`: a dirty indicator if the active editor is dirty.\n- `\${separator}`: a conditional separator (\" - \") that only shows when surrounded by variables with values or static text.") }, 'window.newWindowDimensions': { 'type': 'string', @@ -596,7 +596,7 @@ configurationRegistry.registerConfiguration({ ], 'default': 'default', 'scope': ConfigurationScope.APPLICATION, - 'description': nls.localize('newWindowDimensions', "Controls the dimensions of opening a new window when at least one window is already opened. By default, a new window will open in the center of the screen with small dimensions. When set to 'inherit', the window will get the same dimensions as the last window that was active. When set to 'maximized', the window will open maximized and fullscreen if configured to 'fullscreen'. Note that this setting does not have an impact on the first window that is opened. The first window will always restore the size and location as you left it before closing.") + 'description': nls.localize('newWindowDimensions', "Controls the dimensions of opening a new window when at least one window is already opened. Note that this setting does not have an impact on the first window that is opened. The first window will always restore the size and location as you left it before closing.") }, 'window.closeWhenEmpty': { 'type': 'boolean', @@ -648,7 +648,7 @@ configurationRegistry.registerConfiguration({ 'type': 'boolean', 'default': false, 'scope': ConfigurationScope.APPLICATION, - 'description': nls.localize('window.smoothScrollingWorkaround', "Enable this workaround if scrolling is no longer smooth after restoring a minimized VS Code window. This is a workaround for an issue (https://github.com/Microsoft/vscode/issues/13612) where scrolling starts to lag on devices with precision trackpads like the Surface devices from Microsoft. Enabling this workaround can result in a little bit of layout flickering after restoring the window from minimized state but is otherwise harmless. Note: in order for this workaround to function, make sure to also set 'window.titleBarStyle: native'."), + 'description': nls.localize('window.smoothScrollingWorkaround', "Enable this workaround if scrolling is no longer smooth after restoring a minimized VS Code window. This is a workaround for an issue (https://github.com/Microsoft/vscode/issues/13612) where scrolling starts to lag on devices with precision trackpads like the Surface devices from Microsoft. Enabling this workaround can result in a little bit of layout flickering after restoring the window from minimized state but is otherwise harmless. Note: in order for this workaround to function, make sure to also set `#window.titleBarStyle#` to `native`."), 'included': isWindows }, 'window.clickThroughInactive': { From eb8a1b5781855fa4d871ec5859482f82f6f8c2d4 Mon Sep 17 00:00:00 2001 From: Rob Lourens Date: Sat, 28 Jul 2018 09:30:33 -0700 Subject: [PATCH 0276/1276] Settings editor - fix ... for some short lines, fix select container width --- .../parts/preferences/browser/media/settingsEditor2.css | 3 ++- src/vs/workbench/parts/preferences/browser/settingsTree.ts | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/src/vs/workbench/parts/preferences/browser/media/settingsEditor2.css b/src/vs/workbench/parts/preferences/browser/media/settingsEditor2.css index 7e28d6f6021..29a2e7f0adf 100644 --- a/src/vs/workbench/parts/preferences/browser/media/settingsEditor2.css +++ b/src/vs/workbench/parts/preferences/browser/media/settingsEditor2.css @@ -325,7 +325,7 @@ min-width: 200px; } -.settings-editor > .settings-body > .settings-tree-container .setting-item.setting-item-text { +.settings-editor > .settings-body > .settings-tree-container .setting-item.setting-item-text .setting-item-value { width: 500px; } @@ -335,6 +335,7 @@ min-width: initial; } +.settings-editor > .settings-body > .settings-tree-container .setting-item.setting-item-enum .setting-item-value, .settings-editor > .settings-body > .settings-tree-container .setting-item.setting-item-enum .setting-item-value > .setting-item-control > select { width: 320px; } diff --git a/src/vs/workbench/parts/preferences/browser/settingsTree.ts b/src/vs/workbench/parts/preferences/browser/settingsTree.ts index 437f3f1ba8f..dfac0160a39 100644 --- a/src/vs/workbench/parts/preferences/browser/settingsTree.ts +++ b/src/vs/workbench/parts/preferences/browser/settingsTree.ts @@ -1069,7 +1069,7 @@ export class SettingsRenderer implements ITreeRenderer { return size.width; } - const nextBreakMatch = fullDescription.slice(i + 1).match(/[\s.,$]/); + const nextBreakMatch = fullDescription.slice(i + 1).match(/([\s.,]|$)/); if (nextBreakMatch) { i = nextBreakMatch.index + i + 1; } else { From 2a100df2ebfb52cd7ad213fe1808a731bcafee97 Mon Sep 17 00:00:00 2001 From: Rob Lourens Date: Sat, 28 Jul 2018 09:54:36 -0700 Subject: [PATCH 0277/1276] Settings editor - overlay trees so scrollable shadow is full width --- .../browser/media/settingsEditor2.css | 17 ++++++++++------- .../preferences/browser/settingsEditor2.ts | 2 +- 2 files changed, 11 insertions(+), 8 deletions(-) diff --git a/src/vs/workbench/parts/preferences/browser/media/settingsEditor2.css b/src/vs/workbench/parts/preferences/browser/media/settingsEditor2.css index 29a2e7f0adf..a862bb6f49c 100644 --- a/src/vs/workbench/parts/preferences/browser/media/settingsEditor2.css +++ b/src/vs/workbench/parts/preferences/browser/media/settingsEditor2.css @@ -140,14 +140,22 @@ outline: none !important; } +.settings-editor.search-mode > .settings-body .settings-tree-container .monaco-tree-wrapper, +.settings-editor.search-mode > .settings-body > .settings-tree-container .setting-measure-container { + width: calc(100% - 11px); + margin-left: 0px; +} + .settings-editor > .settings-body .settings-tree-container .monaco-tree-wrapper, .settings-editor > .settings-body > .settings-tree-container .setting-measure-container { - /** Match header padding, leave room for scrollbar on the outside */ - width: calc(100% - 11px); + /** 11px for scrollbar + 208px for TOC margin */ + width: calc(100% - 219px); + margin-left: 208px; } .settings-editor > .settings-body .settings-toc-container { + position: absolute; width: 160px; margin-top: 16px; padding-left: 5px; @@ -161,10 +169,6 @@ display: none; } -.settings-editor.search-mode > .settings-body .settings-tree-container { - max-width: 1100px; -} - .settings-editor.narrow > .settings-body .settings-toc-container { display: none; } @@ -199,7 +203,6 @@ .settings-editor > .settings-body .settings-tree-container { flex: 1; - max-width: 792px; margin-right: 1px; /* So the item doesn't blend into the edge of the view container */ margin-top: 14px; border-spacing: 0; diff --git a/src/vs/workbench/parts/preferences/browser/settingsEditor2.ts b/src/vs/workbench/parts/preferences/browser/settingsEditor2.ts index 7671789a22c..7512bb4955a 100644 --- a/src/vs/workbench/parts/preferences/browser/settingsEditor2.ts +++ b/src/vs/workbench/parts/preferences/browser/settingsEditor2.ts @@ -280,8 +280,8 @@ export class SettingsEditor2 extends BaseEditor { private createBody(parent: HTMLElement): void { const bodyContainer = DOM.append(parent, $('.settings-body')); - this.createTOC(bodyContainer); this.createSettingsTree(bodyContainer); + this.createTOC(bodyContainer); if (this.environmentService.appQuality !== 'stable') { this.createFeedbackButton(bodyContainer); From 8583f60ae5e8c204555604d313f9e5c47702c26e Mon Sep 17 00:00:00 2001 From: Rob Lourens Date: Sat, 28 Jul 2018 10:05:24 -0700 Subject: [PATCH 0278/1276] Fix #54133 - missing extension settings after reload --- src/vs/workbench/parts/preferences/browser/settingsEditor2.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/src/vs/workbench/parts/preferences/browser/settingsEditor2.ts b/src/vs/workbench/parts/preferences/browser/settingsEditor2.ts index 7512bb4955a..5803a5f97fc 100644 --- a/src/vs/workbench/parts/preferences/browser/settingsEditor2.ts +++ b/src/vs/workbench/parts/preferences/browser/settingsEditor2.ts @@ -571,6 +571,7 @@ export class SettingsEditor2 extends BaseEditor { return void 0; } + this._register(model.onDidChangeGroups(() => this.onConfigUpdate())); this.defaultSettingsEditorModel = model; this.onConfigUpdate(); }); From decfb6d665df80748a13f7691a7e095f704d93ad Mon Sep 17 00:00:00 2001 From: Rob Lourens Date: Sat, 28 Jul 2018 12:09:24 -0700 Subject: [PATCH 0279/1276] Settings color token description tweak --- src/vs/workbench/parts/preferences/browser/settingsWidgets.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/vs/workbench/parts/preferences/browser/settingsWidgets.ts b/src/vs/workbench/parts/preferences/browser/settingsWidgets.ts index 35c02ec6750..706e5bdd9f6 100644 --- a/src/vs/workbench/parts/preferences/browser/settingsWidgets.ts +++ b/src/vs/workbench/parts/preferences/browser/settingsWidgets.ts @@ -20,8 +20,8 @@ import { attachButtonStyler, attachInputBoxStyler } from 'vs/platform/theme/comm import { ICssStyleCollector, ITheme, IThemeService, registerThemingParticipant } from 'vs/platform/theme/common/themeService'; const $ = DOM.$; -export const settingsHeaderForeground = registerColor('settings.headerForeground', { light: '#444444', dark: '#e7e7e7', hc: '#ffffff' }, localize('headerForeground', "(For settings editor preview) The foreground color for a section header or active title in the editor.")); -export const modifiedItemForeground = registerColor('settings.modifiedItemForeground', { light: '#018101', dark: '#73C991', hc: '#73C991' }, localize('modifiedItemForeground', "(For settings editor preview) The foreground color for a modified setting.")); +export const settingsHeaderForeground = registerColor('settings.headerForeground', { light: '#444444', dark: '#e7e7e7', hc: '#ffffff' }, localize('headerForeground', "(For settings editor preview) The foreground color for a section header or active title.")); +export const modifiedItemForeground = registerColor('settings.modifiedItemForeground', { light: '#018101', dark: '#73C991', hc: '#73C991' }, localize('modifiedItemForeground', "(For settings editor preview) The foreground color for a the modified setting indicator.")); export const settingItemInactiveSelectionBorder = registerColor('settings.inactiveSelectedItemBorder', { dark: '#3F3F46', light: '#CCCEDB', hc: null }, localize('settingItemInactiveSelectionBorder', "(For settings editor preview) The color of the selected setting row border, when the settings list does not have focus.")); // Enum control colors From 0218d1d3f1bea1bb20d52b51a884ee551d4c5ec3 Mon Sep 17 00:00:00 2001 From: Rob Lourens Date: Sat, 28 Jul 2018 12:13:29 -0700 Subject: [PATCH 0280/1276] Settings editor - disable overflow indicator temporarily, needs to be faster --- .../parts/preferences/browser/settingsTree.ts | 138 +++++++++--------- 1 file changed, 69 insertions(+), 69 deletions(-) diff --git a/src/vs/workbench/parts/preferences/browser/settingsTree.ts b/src/vs/workbench/parts/preferences/browser/settingsTree.ts index dfac0160a39..449fcacdad0 100644 --- a/src/vs/workbench/parts/preferences/browser/settingsTree.ts +++ b/src/vs/workbench/parts/preferences/browser/settingsTree.ts @@ -545,8 +545,8 @@ export class SettingsRenderer implements ITreeRenderer { public readonly onDidClickSettingLink: Event = this._onDidClickSettingLink.event; private measureContainer: HTMLElement; - private measureDescriptionContainer: HTMLElement; - private measureDescriptionTemplates = new Map(); + // private measureDescriptionContainer: HTMLElement; + // private measureDescriptionTemplates = new Map(); constructor( _measureContainer: HTMLElement, @@ -557,7 +557,7 @@ export class SettingsRenderer implements ITreeRenderer { @ICommandService private readonly commandService: ICommandService, ) { this.measureContainer = DOM.append(_measureContainer, $('.setting-measure-container.monaco-tree-row')); - this.measureDescriptionContainer = DOM.append(_measureContainer, $('.setting-measure-container.setting-description-measure-container.monaco-tree-row')); + // this.measureDescriptionContainer = DOM.append(_measureContainer, $('.setting-measure-container.setting-description-measure-container.monaco-tree-row')); } getHeight(tree: ITree, element: SettingsTreeElement): number { @@ -612,39 +612,39 @@ export class SettingsRenderer implements ITreeRenderer { return Math.max(height, this._getUnexpandedSettingHeight(element)); } - private measureSettingDescriptionHeight(tree: ITree, element: SettingsTreeSettingElement): number { - const measureHelper = DOM.append(this.measureContainer, $('.setting-measure-helper')); + // private measureSettingDescriptionHeight(tree: ITree, element: SettingsTreeSettingElement): number { + // const measureHelper = DOM.append(this.measureContainer, $('.setting-measure-helper')); - const templateId = this.getTemplateId(tree, element); - const template = this.renderTemplate(tree, templateId, measureHelper); - this.renderDescription(element.description, template, true); + // const templateId = this.getTemplateId(tree, element); + // const template = this.renderTemplate(tree, templateId, measureHelper); + // this.renderDescription(element.description, template, true); - const height = (template).descriptionElement.offsetHeight; - this.measureContainer.removeChild(this.measureContainer.firstChild); - return height; - } + // const height = (template).descriptionElement.offsetHeight; + // this.measureContainer.removeChild(this.measureContainer.firstChild); + // return height; + // } - private measureSettingDescription(tree: ITree, element: SettingsTreeSettingElement, text: string): { height: number, width: number } { - const templateId = this.getTemplateId(tree, element); - if (!this.measureDescriptionTemplates.has(templateId)) { - const measureHelper = $('.setting-measure-helper'); - this.measureDescriptionTemplates.set(templateId, this.renderTemplate(tree, templateId, measureHelper)); - } + // private measureSettingDescription(tree: ITree, element: SettingsTreeSettingElement, text: string): { height: number, width: number } { + // const templateId = this.getTemplateId(tree, element); + // if (!this.measureDescriptionTemplates.has(templateId)) { + // const measureHelper = $('.setting-measure-helper'); + // this.measureDescriptionTemplates.set(templateId, this.renderTemplate(tree, templateId, measureHelper)); + // } - const template = this.measureDescriptionTemplates.get(templateId); - this.measureDescriptionContainer.appendChild(template.containerElement); - this.renderDescription(text, template, true); + // const template = this.measureDescriptionTemplates.get(templateId); + // this.measureDescriptionContainer.appendChild(template.containerElement); + // this.renderDescription(text, template, true); - const descriptionElement = (template).descriptionElement; - const width = descriptionElement.offsetWidth; - const height = descriptionElement.offsetHeight; + // const descriptionElement = (template).descriptionElement; + // const width = descriptionElement.offsetWidth; + // const height = descriptionElement.offsetHeight; - if (this.measureDescriptionContainer.firstChild) { - this.measureDescriptionContainer.removeChild(this.measureDescriptionContainer.firstChild); - } + // if (this.measureDescriptionContainer.firstChild) { + // this.measureDescriptionContainer.removeChild(this.measureDescriptionContainer.firstChild); + // } - return { height, width }; - } + // return { height, width }; + // } getTemplateId(tree: ITree, element: SettingsTreeElement): string { @@ -1039,53 +1039,53 @@ export class SettingsRenderer implements ITreeRenderer { template.context = element; } - private isSettingExpandable(tree: ITree, element: SettingsTreeSettingElement): boolean { - // Shortcuts before measuring - if (element.valueType === 'enum' && element.setting.enumDescriptions && element.setting.enum && element.setting.enum.length < SettingsRenderer.MAX_ENUM_DESCRIPTIONS) { - return true; - } + // private isSettingExpandable(tree: ITree, element: SettingsTreeSettingElement): boolean { + // // Shortcuts before measuring + // if (element.valueType === 'enum' && element.setting.enumDescriptions && element.setting.enum && element.setting.enum.length < SettingsRenderer.MAX_ENUM_DESCRIPTIONS) { + // return true; + // } - if (element.setting.description.indexOf('\n') >= 0) { - return true; - } + // if (element.setting.description.indexOf('\n') >= 0) { + // return true; + // } - const height = this.measureSettingDescriptionHeight(tree, element); - return height > 18; - } + // const height = this.measureSettingDescriptionHeight(tree, element); + // return height > 18; + // } - private settingDescriptionFirstLineLength(tree: ITree, element: SettingsTreeSettingElement): number { - const fullDescription = element.description - .replace(/\[(.*)\]\(.*\)/, '$1') - .split('\n')[0]; + // private settingDescriptionFirstLineLength(tree: ITree, element: SettingsTreeSettingElement): number { + // const fullDescription = element.description + // .replace(/\[(.*)\]\(.*\)/, '$1') + // .split('\n')[0]; - // Add characters one at a time, measure the width. Start from some safe number. - // const startPos = Math.min(50, fullDescription.length - 1); - let size: { height: number, width: number }; - for (let i = 10; i <= fullDescription.length;) { - let description = fullDescription.substr(0, i); - size = this.measureSettingDescription(tree, element, description); - if (size.height > 20) { - // It wrapped - return size.width; - } + // // Add characters one at a time, measure the width. Start from some safe number. + // // const startPos = Math.min(50, fullDescription.length - 1); + // let size: { height: number, width: number }; + // for (let i = 10; i <= fullDescription.length;) { + // let description = fullDescription.substr(0, i); + // size = this.measureSettingDescription(tree, element, description); + // if (size.height > 20) { + // // It wrapped + // return size.width; + // } - const nextBreakMatch = fullDescription.slice(i + 1).match(/([\s.,]|$)/); - if (nextBreakMatch) { - i = nextBreakMatch.index + i + 1; - } else { - return size.width; - } - } + // const nextBreakMatch = fullDescription.slice(i + 1).match(/([\s.,]|$)/); + // if (nextBreakMatch) { + // i = nextBreakMatch.index + i + 1; + // } else { + // return size.width; + // } + // } - return size ? size.width : 0; - } + // return size ? size.width : 0; + // } private renderSettingElement(tree: ITree, element: SettingsTreeSettingElement, templateId: string, template: ISettingItemTemplate | ISettingBoolItemTemplate): void { const isSelected = !!this.elementIsSelected(tree, element); const setting = element.setting; - const isExpandable = this.isSettingExpandable(tree, element); - DOM.toggleClass(template.containerElement, 'is-expandable', isExpandable); + // const isExpandable = this.isSettingExpandable(tree, element); + // DOM.toggleClass(template.containerElement, 'is-expandable', isExpandable); DOM.toggleClass(template.containerElement, 'is-expanded', isSelected); DOM.toggleClass(template.containerElement, 'is-configured', element.isConfigured); template.containerElement.id = element.id.replace(/\./g, '_'); @@ -1097,10 +1097,10 @@ export class SettingsRenderer implements ITreeRenderer { template.labelElement.textContent = element.displayLabel; template.labelElement.title = titleTooltip; - if (isExpandable) { - const widthInFirstLine = this.settingDescriptionFirstLineLength(tree, element); - template.expandIndicatorElement.style.left = (widthInFirstLine + 8) + 'px'; - } + // if (isExpandable) { + // const widthInFirstLine = this.settingDescriptionFirstLineLength(tree, element); + // template.expandIndicatorElement.style.left = (widthInFirstLine + 8) + 'px'; + // } const descriptionText = element.description + this.getEnumDescriptionText(element); this.renderDescription(descriptionText, template, isSelected); From 82423033d9b1d8ab26d68d38f980ac8061e67e63 Mon Sep 17 00:00:00 2001 From: Erich Gamma Date: Sat, 28 Jul 2018 22:09:40 +0200 Subject: [PATCH 0281/1276] Added command to Run the selected npm script --- extensions/npm/README.md | 3 ++- extensions/npm/package.json | 4 +++ extensions/npm/package.nls.json | 3 ++- extensions/npm/src/commands.ts | 32 ++++++++++++++++++++++ extensions/npm/src/main.ts | 3 ++- extensions/npm/src/tasks.ts | 47 ++++++++++++++++++++++++++++++++- 6 files changed, 88 insertions(+), 4 deletions(-) create mode 100644 extensions/npm/src/commands.ts diff --git a/extensions/npm/README.md b/extensions/npm/README.md index f4b85999742..a24a7d69d6e 100644 --- a/extensions/npm/README.md +++ b/extensions/npm/README.md @@ -19,7 +19,8 @@ The Npm Script Explorer shows the npm scripts found in your workspace. The explo ### Run Scripts from the Editor -The extension provides code lense actions to run or debug a script from the editor. +The extension supports to run the selected script as a task when editing the `package.json`file. You can either run a script from +the hover shown on a script or using the command `Run Selected Npm Script`. ### Others diff --git a/extensions/npm/package.json b/extensions/npm/package.json index d5647618a81..2052b7a8228 100644 --- a/extensions/npm/package.json +++ b/extensions/npm/package.json @@ -82,6 +82,10 @@ "light": "resources/light/refresh.svg", "dark": "resources/dark/refresh.svg" } + }, + { + "command": "npm.runSelectedScript", + "title": "%command.runSelectedScript%" } ], "menus": { diff --git a/extensions/npm/package.nls.json b/extensions/npm/package.nls.json index 3a59c27cad1..b3800cd96e4 100644 --- a/extensions/npm/package.nls.json +++ b/extensions/npm/package.nls.json @@ -16,5 +16,6 @@ "command.run": "Run", "command.debug": "Debug", "command.openScript": "Open", - "command.runInstall": "Run Install" + "command.runInstall": "Run Install", + "command.runSelectedScript": "Run Selected Npm Script" } diff --git a/extensions/npm/src/commands.ts b/extensions/npm/src/commands.ts new file mode 100644 index 00000000000..509d536db92 --- /dev/null +++ b/extensions/npm/src/commands.ts @@ -0,0 +1,32 @@ +/*--------------------------------------------------------------------------------------------- + * 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 * as vscode from 'vscode'; +import { + runScript, findScriptAtPosition +} from './tasks'; +import * as nls from 'vscode-nls'; + +const localize = nls.loadMessageBundle(); + +export function runSelectedScript() { + let editor = vscode.window.activeTextEditor; + if (!editor) { + return; + } + let document = editor.document; + let contents = document.getText(); + let selection = editor.selection; + let offset = document.offsetAt(selection.anchor); + + let script = findScriptAtPosition(contents, offset); + if (script) { + runScript(script, document); + } else { + let message = localize('noScriptFound', 'Could not find an npm script at the selection.'); + vscode.window.showErrorMessage(message); + } +} \ No newline at end of file diff --git a/extensions/npm/src/main.ts b/extensions/npm/src/main.ts index 116852100dc..02e22490fd7 100644 --- a/extensions/npm/src/main.ts +++ b/extensions/npm/src/main.ts @@ -10,6 +10,7 @@ import { addJSONProviders } from './features/jsonContributions'; import { NpmScriptsTreeDataProvider } from './npmView'; import { invalidateTasksCache, NpmTaskProvider } from './tasks'; import { invalidateHoverScriptsCache, NpmScriptHoverProvider } from './scriptHover'; +import { runSelectedScript } from './commands'; export async function activate(context: vscode.ExtensionContext): Promise { const taskProvider = registerTaskProvider(context); @@ -37,7 +38,7 @@ export async function activate(context: vscode.ExtensionContext): Promise invalidateHoverScriptsCache(e.document); }); context.subscriptions.push(d); - + context.subscriptions.push(vscode.commands.registerCommand('npm.runSelectedScript', runSelectedScript)); context.subscriptions.push(addJSONProviders(httpRequest.xhr)); } diff --git a/extensions/npm/src/tasks.ts b/extensions/npm/src/tasks.ts index 3060cce1ed6..189fd98baec 100644 --- a/extensions/npm/src/tasks.ts +++ b/extensions/npm/src/tasks.ts @@ -6,7 +6,7 @@ import { TaskDefinition, Task, TaskGroup, WorkspaceFolder, RelativePattern, ShellExecution, Uri, workspace, - DebugConfiguration, debug, TaskProvider, ExtensionContext + DebugConfiguration, debug, TaskProvider, ExtensionContext, TextDocument, tasks } from 'vscode'; import * as path from 'path'; import * as fs from 'fs'; @@ -288,6 +288,15 @@ async function readFile(file: string): Promise { }); } +export function runScript(script: string, document: TextDocument) { + let uri = document.uri; + let folder = workspace.getWorkspaceFolder(uri); + if (folder) { + let task = createTask(script, `run ${script}`, folder, uri); + tasks.executeTask(task); + } +} + export function extractDebugArgFromScript(scriptValue: string): [string, number] | undefined { // matches --debug, --debug=1234, --debug-brk, debug-brk=1234, --inspect, // --inspect=1234, --inspect-brk, --inspect-brk=1234, @@ -405,6 +414,42 @@ export function findAllScriptRanges(buffer: string): Map= scriptStart && offset < nodeOffset + nodeLength) { + // found the script + inScripts = false; + } else { + script = undefined; + } + } + }, + onObjectProperty(property: string, nodeOffset: number, nodeLength: number) { + if (property === 'scripts') { + inScripts = true; + } + else if (inScripts) { + scriptStart = nodeOffset; + script = property; + } + } + }; + visit(buffer, visitor); + return script; +} export async function getScripts(packageJsonUri: Uri): Promise { From 1ff1c125bf3794a92dbd065baf470418f22ae69d Mon Sep 17 00:00:00 2001 From: SteVen Batten <6561887+sbatten@users.noreply.github.com> Date: Sat, 28 Jul 2018 22:37:14 -0700 Subject: [PATCH 0282/1276] fixes #54452 --- .../parts/titlebar/media/titlebarpart.css | 55 +++++++------------ .../browser/parts/titlebar/titlebarPart.ts | 34 ++++++++++-- 2 files changed, 51 insertions(+), 38 deletions(-) diff --git a/src/vs/workbench/browser/parts/titlebar/media/titlebarpart.css b/src/vs/workbench/browser/parts/titlebar/media/titlebarpart.css index 54a27a0b1a3..06774758a71 100644 --- a/src/vs/workbench/browser/parts/titlebar/media/titlebarpart.css +++ b/src/vs/workbench/browser/parts/titlebar/media/titlebarpart.css @@ -99,65 +99,52 @@ display: none; } -.monaco-workbench > .part.titlebar > .window-controls-container > .window-icon { +.monaco-workbench > .part.titlebar > .window-controls-container > .window-icon-bg { display: inline-block; -webkit-app-region: no-drag; - -webkit-transition: background-color .1s; - transition: background-color .1s; height: 100%; width: 33.34%; - background-size: 21.74%; - background-position: center center; - background-repeat: no-repeat; } -.monaco-workbench > .part.titlebar > .window-controls-container > .window-icon svg { +.monaco-workbench > .part.titlebar > .window-controls-container .window-icon svg { shape-rendering: crispEdges; text-align: center; } -.monaco-workbench > .part.titlebar.titlebar > .window-controls-container > .window-close { - background-image: url('chrome-close-dark.svg'); +.monaco-workbench > .part.titlebar.titlebar > .window-controls-container .window-close { + -webkit-mask: url('chrome-close.svg') no-repeat 50% 50%; } -.monaco-workbench > .part.titlebar.titlebar.light > .window-controls-container > .window-close { - background-image: url('chrome-close.svg'); +.monaco-workbench > .part.titlebar.titlebar > .window-controls-container .window-unmaximize { + -webkit-mask: url('chrome-restore.svg') no-repeat 50% 50%; } -.monaco-workbench > .part.titlebar.titlebar > .window-controls-container > .window-unmaximize { - background-image: url('chrome-restore-dark.svg'); +.monaco-workbench > .part.titlebar > .window-controls-container .window-maximize { + -webkit-mask: url('chrome-maximize.svg') no-repeat 50% 50%; } -.monaco-workbench > .part.titlebar.titlebar.light > .window-controls-container > .window-unmaximize { - background-image: url('chrome-restore.svg'); +.monaco-workbench > .part.titlebar > .window-controls-container .window-minimize { + -webkit-mask: url('chrome-minimize.svg') no-repeat 50% 50%; } -.monaco-workbench > .part.titlebar > .window-controls-container > .window-maximize { - background-image: url('chrome-maximize-dark.svg'); +.monaco-workbench > .part.titlebar > .window-controls-container > .window-icon-bg > .window-icon { + height: 100%; + width: 100%; + -webkit-mask-size: 23.1%; } -.monaco-workbench > .part.titlebar.light > .window-controls-container > .window-maximize { - background-image: url('chrome-maximize.svg'); -} - -.monaco-workbench > .part.titlebar > .window-controls-container > .window-minimize { - background-image: url('chrome-minimize-dark.svg'); -} - -.monaco-workbench > .part.titlebar.light > .window-controls-container > .window-minimize { - background-image: url('chrome-minimize.svg'); -} - -.monaco-workbench > .part.titlebar > .window-controls-container > .window-icon:hover { +.monaco-workbench > .part.titlebar > .window-controls-container > .window-icon-bg:hover { background-color: rgba(255, 255, 255, 0.1); } -.monaco-workbench > .part.titlebar.light > .window-controls-container > .window-icon:hover { +.monaco-workbench > .part.titlebar.light > .window-controls-container > .window-icon-bg:hover { background-color: rgba(0, 0, 0, 0.1); } -.monaco-workbench > .part.titlebar > .window-controls-container > .window-close:hover, - .monaco-workbench > .part.titlebar.light > .window-controls-container > .window-close:hover { +.monaco-workbench > .part.titlebar > .window-controls-container > .window-icon-bg.window-close-bg:hover { background-color: rgba(232, 17, 35, 0.9); - background-image: url('chrome-close-dark.svg'); +} + +.monaco-workbench > .part.titlebar > .window-controls-container .window-icon.window-close:hover { + background-color: white; } \ No newline at end of file diff --git a/src/vs/workbench/browser/parts/titlebar/titlebarPart.ts b/src/vs/workbench/browser/parts/titlebar/titlebarPart.ts index 02513af6ff6..e725ed368a1 100644 --- a/src/vs/workbench/browser/parts/titlebar/titlebarPart.ts +++ b/src/vs/workbench/browser/parts/titlebar/titlebarPart.ts @@ -24,7 +24,7 @@ import * as nls from 'vs/nls'; import { EditorInput, toResource, Verbosity } from 'vs/workbench/common/editor'; import { IEnvironmentService } from 'vs/platform/environment/common/environment'; import { IWorkspaceContextService, WorkbenchState } from 'vs/platform/workspace/common/workspace'; -import { IThemeService } from 'vs/platform/theme/common/themeService'; +import { IThemeService, registerThemingParticipant, ITheme, ICssStyleCollector } from 'vs/platform/theme/common/themeService'; import { TITLE_BAR_ACTIVE_BACKGROUND, TITLE_BAR_ACTIVE_FOREGROUND, TITLE_BAR_INACTIVE_FOREGROUND, TITLE_BAR_INACTIVE_BACKGROUND, TITLE_BAR_BORDER } from 'vs/workbench/common/theme'; import { isMacintosh, isWindows, isLinux } from 'vs/base/common/platform'; import URI from 'vs/base/common/uri'; @@ -322,12 +322,12 @@ export class TitlebarPart extends Part implements ITitleService { this.windowControls = $(this.titleContainer).div({ class: 'window-controls-container' }); // Minimize - $(this.windowControls).div({ class: 'window-icon window-minimize' }).on(EventType.CLICK, () => { + $($(this.windowControls).div({ class: 'window-icon-bg' })).div({ class: 'window-icon window-minimize' }).on(EventType.CLICK, () => { this.windowService.minimizeWindow().then(null, errors.onUnexpectedError); }); // Restore - this.maxRestoreControl = $(this.windowControls).div({ class: 'window-icon window-max-restore' }).on(EventType.CLICK, () => { + this.maxRestoreControl = $($(this.windowControls).div({ class: 'window-icon-bg' })).div({ class: 'window-icon window-max-restore' }).on(EventType.CLICK, () => { this.windowService.isMaximized().then((maximized) => { if (maximized) { return this.windowService.unmaximizeWindow(); @@ -338,7 +338,7 @@ export class TitlebarPart extends Part implements ITitleService { }); // Close - $(this.windowControls).div({ class: 'window-icon window-close' }).on(EventType.CLICK, () => { + $($(this.windowControls).div({ class: 'window-icon-bg window-close-bg' })).div({ class: 'window-icon window-close' }).on(EventType.CLICK, () => { this.windowService.closeWindow().then(null, errors.onUnexpectedError); }); @@ -383,6 +383,12 @@ export class TitlebarPart extends Part implements ITitleService { // Part container if (this.titleContainer) { + if (this.isInactive) { + this.titleContainer.addClass('inactive'); + } else { + this.titleContainer.removeClass('inactive'); + } + const titleBackground = this.getColor(this.isInactive ? TITLE_BAR_INACTIVE_BACKGROUND : TITLE_BAR_ACTIVE_BACKGROUND); this.titleContainer.style('background-color', titleBackground); if (Color.fromHex(titleBackground).isLighter()) { @@ -555,3 +561,23 @@ class ShowItemInFolderAction extends Action { return this.windowsService.showItemInFolder(this.path); } } + +registerThemingParticipant((theme: ITheme, collector: ICssStyleCollector) => { + const titlebarActiveFg = theme.getColor(TITLE_BAR_ACTIVE_FOREGROUND); + if (titlebarActiveFg) { + collector.addRule(` + .monaco-workbench > .part.titlebar > .window-controls-container .window-icon { + background-color: ${titlebarActiveFg}; + } + `); + } + + const titlebarInactiveFg = theme.getColor(TITLE_BAR_INACTIVE_FOREGROUND); + if (titlebarInactiveFg) { + collector.addRule(` + .monaco-workbench > .part.titlebar.inactive > .window-controls-container .window-icon { + background-color: ${titlebarInactiveFg}; + } + `); + } +}); From 93925573191bc808204a2954c8e7ac6564f024b1 Mon Sep 17 00:00:00 2001 From: SteVen Batten <6561887+sbatten@users.noreply.github.com> Date: Sat, 28 Jul 2018 22:55:54 -0700 Subject: [PATCH 0283/1276] fixes #54929 --- .../browser/parts/titlebar/media/titlebarpart.css | 1 - src/vs/workbench/browser/parts/titlebar/titlebarPart.ts | 8 -------- 2 files changed, 9 deletions(-) diff --git a/src/vs/workbench/browser/parts/titlebar/media/titlebarpart.css b/src/vs/workbench/browser/parts/titlebar/media/titlebarpart.css index 06774758a71..29bb9ba3abf 100644 --- a/src/vs/workbench/browser/parts/titlebar/media/titlebarpart.css +++ b/src/vs/workbench/browser/parts/titlebar/media/titlebarpart.css @@ -69,7 +69,6 @@ .monaco-workbench > .part.titlebar > .window-appicon { width: 35px; height: 100%; - -webkit-app-region: no-drag; position: relative; z-index: 99; background-image: url('code-icon.svg'); diff --git a/src/vs/workbench/browser/parts/titlebar/titlebarPart.ts b/src/vs/workbench/browser/parts/titlebar/titlebarPart.ts index e725ed368a1..3eedcb97500 100644 --- a/src/vs/workbench/browser/parts/titlebar/titlebarPart.ts +++ b/src/vs/workbench/browser/parts/titlebar/titlebarPart.ts @@ -269,14 +269,6 @@ export class TitlebarPart extends Part implements ITitleService { // App Icon (Windows/Linux) if (!isMacintosh) { this.appIcon = $(this.titleContainer).div({ class: 'window-appicon' }); - - if (isWindows) { - this.appIcon.on(EventType.DBLCLICK, e => { - EventHelper.stop(e, true); - - this.windowService.closeWindow().then(null, errors.onUnexpectedError); - }); - } } // Menubar: the menubar part which is responsible for populating both the custom and native menubars From 323f97519646f77b41b94d29228294f1e61187cf Mon Sep 17 00:00:00 2001 From: SteVen Batten Date: Sat, 28 Jul 2018 23:20:38 -0700 Subject: [PATCH 0284/1276] fixes #55248 --- src/vs/code/electron-main/menubar.ts | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/vs/code/electron-main/menubar.ts b/src/vs/code/electron-main/menubar.ts index 556dfe6d3c4..480717e7860 100644 --- a/src/vs/code/electron-main/menubar.ts +++ b/src/vs/code/electron-main/menubar.ts @@ -67,7 +67,7 @@ export class Menubar { }); // // Listen to some events from window service to update menu - // this.historyMainService.onRecentlyOpenedChange(() => this.updateMenu()); + this.historyMainService.onRecentlyOpenedChange(() => this.scheduleUpdateMenu()); this.windowsMainService.onWindowsCountChanged(e => this.onWindowsCountChanged(e)); // this.windowsMainService.onActiveWindowChanged(() => this.updateWorkspaceMenuItems()); // this.windowsMainService.onWindowReady(() => this.updateWorkspaceMenuItems()); @@ -391,11 +391,16 @@ export class Menubar { const openWorkspace = new MenuItem(this.likeAction('workbench.action.openWorkspace', { label: this.mnemonicLabel(nls.localize({ key: 'miOpenWorkspace', comment: ['&& denotes a mnemonic'] }, "Open Wor&&kspace...")), click: (menuItem, win, event) => this.windowsMainService.pickWorkspaceAndOpen({ forceNewWindow: this.isOptionClick(event), telemetryExtraData: { from: telemetryFrom } }) })); + const openRecentMenu = new Menu(); + this.setFallbackMenuById(openRecentMenu, 'Recent'); + const openRecent = new MenuItem({ label: this.mnemonicLabel(nls.localize({ key: 'miOpenRecent', comment: ['&& denotes a mnemonic'] }, "Open &&Recent")), submenu: openRecentMenu }); + menu.append(newFile); menu.append(newWindow); menu.append(__separator__()); menu.append(open); menu.append(openWorkspace); + menu.append(openRecent); break; From 345440f62fa3de29a48ee007206f0e7cf4349513 Mon Sep 17 00:00:00 2001 From: Erich Gamma Date: Sun, 29 Jul 2018 11:10:56 +0200 Subject: [PATCH 0285/1276] prefix command with extension name --- extensions/npm/package.nls.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/extensions/npm/package.nls.json b/extensions/npm/package.nls.json index b3800cd96e4..99f4836fc17 100644 --- a/extensions/npm/package.nls.json +++ b/extensions/npm/package.nls.json @@ -17,5 +17,5 @@ "command.debug": "Debug", "command.openScript": "Open", "command.runInstall": "Run Install", - "command.runSelectedScript": "Run Selected Npm Script" + "command.runSelectedScript": "Npm: Run Selected Script" } From 83a42a58afea450e6ef0f9b1498752d950f89552 Mon Sep 17 00:00:00 2001 From: Erich Gamma Date: Sun, 29 Jul 2018 11:38:22 +0200 Subject: [PATCH 0286/1276] Contribute run selected to the context menu --- extensions/npm/package.json | 11 +++++++++++ extensions/npm/package.nls.json | 2 +- 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/extensions/npm/package.json b/extensions/npm/package.json index 2052b7a8228..b0017b08b49 100644 --- a/extensions/npm/package.json +++ b/extensions/npm/package.json @@ -109,6 +109,17 @@ { "command": "npm.runInstall", "when": "false" + }, + { + "command": "npm.runSelectedScript", + "when": "false" + } + ], + "editor/context": [ + { + "command": "npm.runSelectedScript", + "when": "resourceFilename == 'package.json'", + "group": "navigation@+1" } ], "view/title": [ diff --git a/extensions/npm/package.nls.json b/extensions/npm/package.nls.json index 99f4836fc17..8c27e0ca5bd 100644 --- a/extensions/npm/package.nls.json +++ b/extensions/npm/package.nls.json @@ -17,5 +17,5 @@ "command.debug": "Debug", "command.openScript": "Open", "command.runInstall": "Run Install", - "command.runSelectedScript": "Npm: Run Selected Script" + "command.runSelectedScript": "Run Script" } From 5af98479331684decb62dcff9705e3507bc70e47 Mon Sep 17 00:00:00 2001 From: Andre Weinand Date: Sun, 29 Jul 2018 16:51:31 +0200 Subject: [PATCH 0287/1276] node-debug@1.26.6 --- build/builtInExtensions.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build/builtInExtensions.json b/build/builtInExtensions.json index 5c0deaea8b3..bd38e83dcac 100644 --- a/build/builtInExtensions.json +++ b/build/builtInExtensions.json @@ -1,7 +1,7 @@ [ { "name": "ms-vscode.node-debug", - "version": "1.26.5", + "version": "1.26.6", "repo": "https://github.com/Microsoft/vscode-node-debug" }, { From 7f5beafe6e7bedec2fa309b6429c293523dee6b2 Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Sun, 29 Jul 2018 14:32:00 -0700 Subject: [PATCH 0288/1276] Allow terminal rendererType to be swapped out at runtime Part of #53274 Fixes #55344 --- package.json | 2 +- .../terminal/electron-browser/terminal.contribution.ts | 2 +- .../parts/terminal/electron-browser/terminalInstance.ts | 3 ++- yarn.lock | 6 +++--- 4 files changed, 7 insertions(+), 6 deletions(-) diff --git a/package.json b/package.json index c2df6f4f32e..84dcc5c59b2 100644 --- a/package.json +++ b/package.json @@ -50,7 +50,7 @@ "vscode-nsfw": "1.0.17", "vscode-ripgrep": "^1.0.1", "vscode-textmate": "^4.0.1", - "vscode-xterm": "3.6.0-beta7", + "vscode-xterm": "3.6.0-beta11", "yauzl": "^2.9.1" }, "devDependencies": { diff --git a/src/vs/workbench/parts/terminal/electron-browser/terminal.contribution.ts b/src/vs/workbench/parts/terminal/electron-browser/terminal.contribution.ts index 835be4cc86f..4e288255067 100644 --- a/src/vs/workbench/parts/terminal/electron-browser/terminal.contribution.ts +++ b/src/vs/workbench/parts/terminal/electron-browser/terminal.contribution.ts @@ -202,7 +202,7 @@ configurationRegistry.registerConfiguration({ nls.localize('terminal.integrated.rendererType.dom', "Use the fallback DOM-based renderer.") ], default: 'auto', - description: nls.localize('terminal.integrated.rendererType', "Controls how the terminal is rendered. This setting needs VS Code to reload in order to take effect.") + description: nls.localize('terminal.integrated.rendererType', "Controls how the terminal is rendered.") }, 'terminal.integrated.rightClickBehavior': { type: 'string', diff --git a/src/vs/workbench/parts/terminal/electron-browser/terminalInstance.ts b/src/vs/workbench/parts/terminal/electron-browser/terminalInstance.ts index df30323b6a6..42174a7c0ac 100644 --- a/src/vs/workbench/parts/terminal/electron-browser/terminalInstance.ts +++ b/src/vs/workbench/parts/terminal/electron-browser/terminalInstance.ts @@ -481,7 +481,7 @@ export class TerminalInstance implements ITerminalInstance { label: nls.localize('yes', "Yes"), run: () => { this._configurationService.updateValue('terminal.integrated.rendererType', 'dom', ConfigurationTarget.USER).then(() => { - this._notificationService.info(nls.localize('terminal.rendererInAllNewTerminals', "All newly created terminals will use the non-GPU renderer.")); + this._notificationService.info(nls.localize('terminal.rendererInAllNewTerminals', "The termnial is now using the fallback renderer.")); }); } } as IPromptChoice, @@ -884,6 +884,7 @@ export class TerminalInstance implements ITerminalInstance { this._safeSetOption('macOptionIsMeta', config.macOptionIsMeta); this._safeSetOption('macOptionClickForcesSelection', config.macOptionClickForcesSelection); this._safeSetOption('rightClickSelectsWord', config.rightClickBehavior === 'selectWord'); + this._safeSetOption('rendererType', config.rendererType === 'auto' ? 'canvas' : config.rendererType); } public updateAccessibilitySupport(): void { diff --git a/yarn.lock b/yarn.lock index 08bc6f8be19..556d40b5a1f 100644 --- a/yarn.lock +++ b/yarn.lock @@ -6256,9 +6256,9 @@ vscode-textmate@^4.0.1: dependencies: oniguruma "^7.0.0" -vscode-xterm@3.6.0-beta7: - version "3.6.0-beta7" - resolved "https://registry.yarnpkg.com/vscode-xterm/-/vscode-xterm-3.6.0-beta7.tgz#c079061ec43cddc2f952c8075a388c25fb4ca2b0" +vscode-xterm@3.6.0-beta11: + version "3.6.0-beta11" + resolved "https://registry.yarnpkg.com/vscode-xterm/-/vscode-xterm-3.6.0-beta11.tgz#d492ae1baf5cf9884f7b49a4fadc0c354248c830" vso-node-api@^6.1.2-preview: version "6.1.2-preview" From 643a15e56f46322f8ab0814b862bfa85017d960f Mon Sep 17 00:00:00 2001 From: Rob Lourens Date: Sat, 28 Jul 2018 21:37:49 -0700 Subject: [PATCH 0289/1276] Settings editor - fix not focusing search when restoring editor setInput must be actually async. Will be fixed naturally when we aren't using winJS promises... --- .../workbench/parts/preferences/browser/settingsEditor2.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/vs/workbench/parts/preferences/browser/settingsEditor2.ts b/src/vs/workbench/parts/preferences/browser/settingsEditor2.ts index 5803a5f97fc..6affe34a687 100644 --- a/src/vs/workbench/parts/preferences/browser/settingsEditor2.ts +++ b/src/vs/workbench/parts/preferences/browser/settingsEditor2.ts @@ -139,8 +139,8 @@ export class SettingsEditor2 extends BaseEditor { this.inSettingsEditorContextKey.set(true); return super.setInput(input, options, token) .then(() => { - this.render(token); - }); + return this.render(token); + }).then(() => new Promise(process.nextTick)); // Force setInput to be async } clearInput(): void { @@ -573,7 +573,7 @@ export class SettingsEditor2 extends BaseEditor { this._register(model.onDidChangeGroups(() => this.onConfigUpdate())); this.defaultSettingsEditorModel = model; - this.onConfigUpdate(); + return this.onConfigUpdate(); }); } return TPromise.as(null); From 3ce8963a2bd11bf3d510162f5c3742780a19286a Mon Sep 17 00:00:00 2001 From: Rob Lourens Date: Sun, 29 Jul 2018 11:55:22 -0700 Subject: [PATCH 0290/1276] Settings editor - TOC should only expand the section with a selected item --- src/vs/base/parts/tree/browser/treeUtils.ts | 23 ++++++++++++++++++ .../preferences/browser/settingsEditor2.ts | 24 ++++++++++++------- .../parts/preferences/browser/tocTree.ts | 4 ---- 3 files changed, 38 insertions(+), 13 deletions(-) create mode 100644 src/vs/base/parts/tree/browser/treeUtils.ts diff --git a/src/vs/base/parts/tree/browser/treeUtils.ts b/src/vs/base/parts/tree/browser/treeUtils.ts new file mode 100644 index 00000000000..07e95954552 --- /dev/null +++ b/src/vs/base/parts/tree/browser/treeUtils.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. + *--------------------------------------------------------------------------------------------*/ +'use strict'; + +import * as _ from 'vs/base/parts/tree/browser/tree'; + +export function collapseAll(tree: _.ITree): void { + const nav = tree.getNavigator(); + let cur; + while (cur = nav.next()) { + tree.collapse(cur); + } +} + +export function expandAll(tree: _.ITree): void { + const nav = tree.getNavigator(); + let cur; + while (cur = nav.next()) { + tree.expand(cur); + } +} diff --git a/src/vs/workbench/parts/preferences/browser/settingsEditor2.ts b/src/vs/workbench/parts/preferences/browser/settingsEditor2.ts index 6affe34a687..6da01b54581 100644 --- a/src/vs/workbench/parts/preferences/browser/settingsEditor2.ts +++ b/src/vs/workbench/parts/preferences/browser/settingsEditor2.ts @@ -4,6 +4,7 @@ *--------------------------------------------------------------------------------------------*/ import * as DOM from 'vs/base/browser/dom'; +import { Separator } from 'vs/base/browser/ui/actionbar/actionbar'; import { Button } from 'vs/base/browser/ui/button/button'; import { ToolBar } from 'vs/base/browser/ui/toolbar/toolbar'; import { Action } from 'vs/base/common/actions'; @@ -15,7 +16,8 @@ import { getErrorMessage, isPromiseCanceledError } from 'vs/base/common/errors'; import URI from 'vs/base/common/uri'; import { TPromise } from 'vs/base/common/winjs.base'; import { ITreeConfiguration } from 'vs/base/parts/tree/browser/tree'; -import { OpenMode, DefaultTreestyler } from 'vs/base/parts/tree/browser/treeDefaults'; +import { DefaultTreestyler, OpenMode } from 'vs/base/parts/tree/browser/treeDefaults'; +import { collapseAll, expandAll } from 'vs/base/parts/tree/browser/treeUtils'; import 'vs/css!./media/settingsEditor2'; import { localize } from 'vs/nls'; import { ConfigurationTarget, IConfigurationOverrides, IConfigurationService } from 'vs/platform/configuration/common/configuration'; @@ -26,22 +28,21 @@ import { IInstantiationService } from 'vs/platform/instantiation/common/instanti import { WorkbenchTree, WorkbenchTreeController } from 'vs/platform/list/browser/listService'; import { ILogService } from 'vs/platform/log/common/log'; import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry'; +import { editorBackground, foreground } from 'vs/platform/theme/common/colorRegistry'; import { attachButtonStyler, attachStyler } from 'vs/platform/theme/common/styler'; import { IThemeService } from 'vs/platform/theme/common/themeService'; import { BaseEditor } from 'vs/workbench/browser/parts/editor/baseEditor'; import { EditorOptions, IEditor } from 'vs/workbench/common/editor'; +import { PreferencesEditor } from 'vs/workbench/parts/preferences/browser/preferencesEditor'; import { SearchWidget, SettingsTarget, SettingsTargetsWidget } from 'vs/workbench/parts/preferences/browser/preferencesWidgets'; import { commonlyUsedData, tocData } from 'vs/workbench/parts/preferences/browser/settingsLayout'; -import { ISettingsEditorViewState, resolveExtensionsSettings, resolveSettingsTree, SearchResultIdx, SearchResultModel, SettingsRenderer, SettingsTree, SettingsTreeElement, SettingsTreeFilter, SettingsTreeGroupElement, SettingsTreeModel, SettingsTreeSettingElement, MODIFIED_SETTING_TAG, ONLINE_SERVICES_SETTING_TAG } from 'vs/workbench/parts/preferences/browser/settingsTree'; +import { ISettingsEditorViewState, MODIFIED_SETTING_TAG, ONLINE_SERVICES_SETTING_TAG, resolveExtensionsSettings, resolveSettingsTree, SearchResultIdx, SearchResultModel, SettingsRenderer, SettingsTree, SettingsTreeElement, SettingsTreeFilter, SettingsTreeGroupElement, SettingsTreeModel, SettingsTreeSettingElement } from 'vs/workbench/parts/preferences/browser/settingsTree'; +import { settingsHeaderForeground } from 'vs/workbench/parts/preferences/browser/settingsWidgets'; import { TOCDataSource, TOCRenderer, TOCTreeModel } from 'vs/workbench/parts/preferences/browser/tocTree'; import { CONTEXT_SETTINGS_EDITOR, CONTEXT_SETTINGS_FIRST_ROW_FOCUS, CONTEXT_SETTINGS_ROW_FOCUS, CONTEXT_SETTINGS_SEARCH_FOCUS, CONTEXT_TOC_ROW_FOCUS, IPreferencesSearchService, ISearchProvider } from 'vs/workbench/parts/preferences/common/preferences'; import { IPreferencesService, ISearchResult, ISettingsEditorModel } from 'vs/workbench/services/preferences/common/preferences'; import { SettingsEditor2Input } from 'vs/workbench/services/preferences/common/preferencesEditorInput'; import { DefaultSettingsEditorModel } from 'vs/workbench/services/preferences/common/preferencesModels'; -import { editorBackground, foreground } from 'vs/platform/theme/common/colorRegistry'; -import { settingsHeaderForeground } from 'vs/workbench/parts/preferences/browser/settingsWidgets'; -import { Separator } from 'vs/base/browser/ui/actionbar/actionbar'; -import { PreferencesEditor } from 'vs/workbench/parts/preferences/browser/preferencesEditor'; const $ = DOM.$; @@ -462,11 +463,15 @@ export class SettingsEditor2 extends BaseEditor { null; if (element && this.tocTree.getSelection()[0] !== element) { + this.tocTree.reveal(element); const elementTop = this.tocTree.getRelativeTop(element); + collapseAll(this.tocTree); if (elementTop < 0) { this.tocTree.reveal(element, 0); } else if (elementTop > 1) { this.tocTree.reveal(element, 1); + } else { + this.tocTree.reveal(element, elementTop); } this.tocTree.setSelection([element]); @@ -701,9 +706,8 @@ export class SettingsEditor2 extends BaseEditor { this.viewState.filterToCategory = null; this.tocTree.refresh(); this.toggleSearchMode(); - this.settingsTree.setInput(this.settingsTreeModel.root); - - return TPromise.wrap(null); + collapseAll(this.tocTree); + return this.settingsTree.setInput(this.settingsTreeModel.root); } } @@ -776,6 +780,8 @@ export class SettingsEditor2 extends BaseEditor { } this.tocTreeModel.update(); + expandAll(this.tocTree); + resolve(this.refreshTreeAndMaintainFocus()); }); }, () => { diff --git a/src/vs/workbench/parts/preferences/browser/tocTree.ts b/src/vs/workbench/parts/preferences/browser/tocTree.ts index 4863ba7c612..0d9bf95590c 100644 --- a/src/vs/workbench/parts/preferences/browser/tocTree.ts +++ b/src/vs/workbench/parts/preferences/browser/tocTree.ts @@ -102,10 +102,6 @@ export class TOCDataSource implements IDataSource { getParent(tree: ITree, element: TOCTreeElement): TPromise { return TPromise.wrap(element instanceof SettingsTreeGroupElement && element.parent); } - - shouldAutoexpand() { - return true; - } } const TOC_ENTRY_TEMPLATE_ID = 'settings.toc.entry'; From f8aa1fc20882ae7861dbf36f5b10d5686f2ae4c5 Mon Sep 17 00:00:00 2001 From: Rob Lourens Date: Sun, 29 Jul 2018 11:55:31 -0700 Subject: [PATCH 0291/1276] Bump node-debug2 --- build/builtInExtensions.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build/builtInExtensions.json b/build/builtInExtensions.json index bd38e83dcac..a017fbcce91 100644 --- a/build/builtInExtensions.json +++ b/build/builtInExtensions.json @@ -6,7 +6,7 @@ }, { "name": "ms-vscode.node-debug2", - "version": "1.26.6", + "version": "1.26.7", "repo": "https://github.com/Microsoft/vscode-node-debug2" } ] From 39edf26c83b3a84a4fb4f96aae1f5abad6124008 Mon Sep 17 00:00:00 2001 From: Rob Lourens Date: Sun, 29 Jul 2018 13:33:20 -0700 Subject: [PATCH 0292/1276] Settings editor - Tree focus outlines --- .../browser/media/settingsEditor2.css | 4 - .../preferences/browser/settingsEditor2.ts | 44 ++--------- .../parts/preferences/browser/settingsTree.ts | 3 + .../parts/preferences/browser/tocTree.ts | 77 ++++++++++++++++++- 4 files changed, 85 insertions(+), 43 deletions(-) diff --git a/src/vs/workbench/parts/preferences/browser/media/settingsEditor2.css b/src/vs/workbench/parts/preferences/browser/media/settingsEditor2.css index a862bb6f49c..76ab4e7c44b 100644 --- a/src/vs/workbench/parts/preferences/browser/media/settingsEditor2.css +++ b/src/vs/workbench/parts/preferences/browser/media/settingsEditor2.css @@ -136,10 +136,6 @@ justify-content: space-between; } -.settings-editor > .settings-body .settings-tree-container .monaco-tree::before { - outline: none !important; -} - .settings-editor.search-mode > .settings-body .settings-tree-container .monaco-tree-wrapper, .settings-editor.search-mode > .settings-body > .settings-tree-container .setting-measure-container { width: calc(100% - 11px); diff --git a/src/vs/workbench/parts/preferences/browser/settingsEditor2.ts b/src/vs/workbench/parts/preferences/browser/settingsEditor2.ts index 6da01b54581..dd029ff93f8 100644 --- a/src/vs/workbench/parts/preferences/browser/settingsEditor2.ts +++ b/src/vs/workbench/parts/preferences/browser/settingsEditor2.ts @@ -15,8 +15,6 @@ import * as collections from 'vs/base/common/collections'; import { getErrorMessage, isPromiseCanceledError } from 'vs/base/common/errors'; import URI from 'vs/base/common/uri'; import { TPromise } from 'vs/base/common/winjs.base'; -import { ITreeConfiguration } from 'vs/base/parts/tree/browser/tree'; -import { DefaultTreestyler, OpenMode } from 'vs/base/parts/tree/browser/treeDefaults'; import { collapseAll, expandAll } from 'vs/base/parts/tree/browser/treeUtils'; import 'vs/css!./media/settingsEditor2'; import { localize } from 'vs/nls'; @@ -25,20 +23,18 @@ import { IContextKey, IContextKeyService } from 'vs/platform/contextkey/common/c import { IContextMenuService } from 'vs/platform/contextview/browser/contextView'; import { IEnvironmentService } from 'vs/platform/environment/common/environment'; import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; -import { WorkbenchTree, WorkbenchTreeController } from 'vs/platform/list/browser/listService'; +import { WorkbenchTree } from 'vs/platform/list/browser/listService'; import { ILogService } from 'vs/platform/log/common/log'; import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry'; -import { editorBackground, foreground } from 'vs/platform/theme/common/colorRegistry'; -import { attachButtonStyler, attachStyler } from 'vs/platform/theme/common/styler'; +import { attachButtonStyler } from 'vs/platform/theme/common/styler'; import { IThemeService } from 'vs/platform/theme/common/themeService'; import { BaseEditor } from 'vs/workbench/browser/parts/editor/baseEditor'; import { EditorOptions, IEditor } from 'vs/workbench/common/editor'; import { PreferencesEditor } from 'vs/workbench/parts/preferences/browser/preferencesEditor'; import { SearchWidget, SettingsTarget, SettingsTargetsWidget } from 'vs/workbench/parts/preferences/browser/preferencesWidgets'; import { commonlyUsedData, tocData } from 'vs/workbench/parts/preferences/browser/settingsLayout'; -import { ISettingsEditorViewState, MODIFIED_SETTING_TAG, ONLINE_SERVICES_SETTING_TAG, resolveExtensionsSettings, resolveSettingsTree, SearchResultIdx, SearchResultModel, SettingsRenderer, SettingsTree, SettingsTreeElement, SettingsTreeFilter, SettingsTreeGroupElement, SettingsTreeModel, SettingsTreeSettingElement } from 'vs/workbench/parts/preferences/browser/settingsTree'; -import { settingsHeaderForeground } from 'vs/workbench/parts/preferences/browser/settingsWidgets'; -import { TOCDataSource, TOCRenderer, TOCTreeModel } from 'vs/workbench/parts/preferences/browser/tocTree'; +import { ISettingsEditorViewState, MODIFIED_SETTING_TAG, ONLINE_SERVICES_SETTING_TAG, resolveExtensionsSettings, resolveSettingsTree, SearchResultIdx, SearchResultModel, SettingsRenderer, SettingsTree, SettingsTreeElement, SettingsTreeGroupElement, SettingsTreeModel, SettingsTreeSettingElement } from 'vs/workbench/parts/preferences/browser/settingsTree'; +import { TOCRenderer, TOCTree, TOCTreeModel } from 'vs/workbench/parts/preferences/browser/tocTree'; import { CONTEXT_SETTINGS_EDITOR, CONTEXT_SETTINGS_FIRST_ROW_FOCUS, CONTEXT_SETTINGS_ROW_FOCUS, CONTEXT_SETTINGS_SEARCH_FOCUS, CONTEXT_TOC_ROW_FOCUS, IPreferencesSearchService, ISearchProvider } from 'vs/workbench/parts/preferences/common/preferences'; import { IPreferencesService, ISearchResult, ISettingsEditorModel } from 'vs/workbench/services/preferences/common/preferences'; import { SettingsEditor2Input } from 'vs/workbench/services/preferences/common/preferencesEditorInput'; @@ -290,40 +286,16 @@ export class SettingsEditor2 extends BaseEditor { } private createTOC(parent: HTMLElement): void { + this.tocTreeModel = new TOCTreeModel(); this.tocTreeContainer = DOM.append(parent, $('.settings-toc-container')); - const tocDataSource = this.instantiationService.createInstance(TOCDataSource); const tocRenderer = this.instantiationService.createInstance(TOCRenderer); - this.tocTreeModel = new TOCTreeModel(); - this.tocTree = this.instantiationService.createInstance(WorkbenchTree, this.tocTreeContainer, - { - dataSource: tocDataSource, - renderer: tocRenderer, - controller: this.instantiationService.createInstance(WorkbenchTreeController, { openMode: OpenMode.DOUBLE_CLICK }), - filter: this.instantiationService.createInstance(SettingsTreeFilter, this.viewState), - styler: new DefaultTreestyler(DOM.createStyleSheet(), 'settings-toc-tree'), - }, + this.tocTree = this.instantiationService.createInstance(TOCTree, this.tocTreeContainer, + this.viewState, { - showLoading: false, - twistiePixels: 15 + renderer: tocRenderer }); - this.tocTree.getHTMLElement().classList.add('settings-toc-tree'); - - this._register(attachStyler(this.themeService, { - listActiveSelectionBackground: editorBackground, - listActiveSelectionForeground: settingsHeaderForeground, - listFocusAndSelectionBackground: editorBackground, - listFocusAndSelectionForeground: settingsHeaderForeground, - listFocusBackground: editorBackground, - listFocusForeground: settingsHeaderForeground, - listHoverForeground: foreground, - listHoverBackground: editorBackground, - listInactiveSelectionBackground: editorBackground, - listInactiveSelectionForeground: settingsHeaderForeground, - }, colors => { - this.tocTree.style(colors); - })); this._register(this.tocTree.onDidChangeFocus(e => { const element = e.focus; diff --git a/src/vs/workbench/parts/preferences/browser/settingsTree.ts b/src/vs/workbench/parts/preferences/browser/settingsTree.ts index 449fcacdad0..913ed12fab2 100644 --- a/src/vs/workbench/parts/preferences/browser/settingsTree.ts +++ b/src/vs/workbench/parts/preferences/browser/settingsTree.ts @@ -1512,6 +1512,9 @@ export class SettingsTree extends NonExpandableTree { const activeBorderColor = theme.getColor(focusBorder); if (activeBorderColor) { collector.addRule(`.settings-editor > .settings-body > .settings-tree-container .monaco-tree:focus .monaco-tree-row.focused {outline: solid 1px ${activeBorderColor}; outline-offset: -1px; }`); + + // TODO@rob - why isn't this applied when added to the stylesheet from tocTree.ts? Seems like a chromium glitch. + collector.addRule(`.settings-editor > .settings-body > .settings-toc-container .monaco-tree:focus .monaco-tree-row.focused {outline: solid 1px ${activeBorderColor}; outline-offset: -1px; }`); } const inactiveBorderColor = theme.getColor(settingItemInactiveSelectionBorder); diff --git a/src/vs/workbench/parts/preferences/browser/tocTree.ts b/src/vs/workbench/parts/preferences/browser/tocTree.ts index 0d9bf95590c..d81dc3bcac6 100644 --- a/src/vs/workbench/parts/preferences/browser/tocTree.ts +++ b/src/vs/workbench/parts/preferences/browser/tocTree.ts @@ -5,10 +5,18 @@ import * as DOM from 'vs/base/browser/dom'; import { TPromise } from 'vs/base/common/winjs.base'; -import { IDataSource, IRenderer, ITree } from 'vs/base/parts/tree/browser/tree'; -import { SearchResultModel, SettingsTreeElement, SettingsTreeGroupElement, SettingsTreeSettingElement } from 'vs/workbench/parts/preferences/browser/settingsTree'; -import { ISetting } from 'vs/workbench/services/preferences/common/preferences'; +import { IDataSource, IRenderer, ITree, ITreeConfiguration } from 'vs/base/parts/tree/browser/tree'; +import { DefaultTreestyler, OpenMode } from 'vs/base/parts/tree/browser/treeDefaults'; import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; +import { IContextKeyService } from 'vs/platform/contextkey/common/contextkey'; +import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; +import { IListService, WorkbenchTree, WorkbenchTreeController } from 'vs/platform/list/browser/listService'; +import { editorBackground, focusBorder, foreground } from 'vs/platform/theme/common/colorRegistry'; +import { attachStyler } from 'vs/platform/theme/common/styler'; +import { ICssStyleCollector, ITheme, IThemeService, registerThemingParticipant } from 'vs/platform/theme/common/themeService'; +import { ISettingsEditorViewState, SearchResultModel, SettingsAccessibilityProvider, SettingsTreeElement, SettingsTreeFilter, SettingsTreeGroupElement, SettingsTreeSettingElement } from 'vs/workbench/parts/preferences/browser/settingsTree'; +import { settingsHeaderForeground } from 'vs/workbench/parts/preferences/browser/settingsWidgets'; +import { ISetting } from 'vs/workbench/services/preferences/common/preferences'; const $ = DOM.$; @@ -137,3 +145,66 @@ export class TOCRenderer implements IRenderer { disposeTemplate(tree: ITree, templateId: string, templateData: any): void { } } + +export class TOCTree extends WorkbenchTree { + constructor( + container: HTMLElement, + viewState: ISettingsEditorViewState, + configuration: Partial, + @IContextKeyService contextKeyService: IContextKeyService, + @IListService listService: IListService, + @IThemeService themeService: IThemeService, + @IInstantiationService instantiationService: IInstantiationService, + @IConfigurationService configurationService: IConfigurationService + ) { + const treeClass = 'settings-toc-tree'; + + const fullConfiguration = { + controller: instantiationService.createInstance(WorkbenchTreeController, { openMode: OpenMode.DOUBLE_CLICK }), + filter: instantiationService.createInstance(SettingsTreeFilter, viewState), + styler: new DefaultTreestyler(DOM.createStyleSheet(), treeClass), + dataSource: instantiationService.createInstance(TOCDataSource), + accessibilityProvider: instantiationService.createInstance(SettingsAccessibilityProvider), + + ...configuration + }; + + const options = { + showLoading: false, + twistiePixels: 15 + }; + + super(container, + fullConfiguration, + options, + contextKeyService, + listService, + themeService, + instantiationService, + configurationService); + + this.disposables.push(registerThemingParticipant((theme: ITheme, collector: ICssStyleCollector) => { + const activeBorderColor = theme.getColor(focusBorder); + if (activeBorderColor) { + collector.addRule(`.settings-editor > .settings-body > .settings-toc-container .monaco-tree:focus .monaco-tree-row.focused { outline-color: ${activeBorderColor}; }`); + } + })); + + this.getHTMLElement().classList.add(treeClass); + + this.disposables.push(attachStyler(themeService, { + listActiveSelectionBackground: editorBackground, + listActiveSelectionForeground: settingsHeaderForeground, + listFocusAndSelectionBackground: editorBackground, + listFocusAndSelectionForeground: settingsHeaderForeground, + listFocusBackground: editorBackground, + listFocusForeground: settingsHeaderForeground, + listHoverForeground: foreground, + listHoverBackground: editorBackground, + listInactiveSelectionBackground: editorBackground, + listInactiveSelectionForeground: settingsHeaderForeground, + }, colors => { + this.style(colors); + })); + } +} From bd262c9ab55332be988bef6ccc8019ed7f3d7f3d Mon Sep 17 00:00:00 2001 From: Rob Lourens Date: Sun, 29 Jul 2018 14:26:25 -0700 Subject: [PATCH 0293/1276] Settings editor - don't blink the scrollbar when toc selection changes And hide TOC correctly when the editor is narrow --- src/vs/base/parts/tree/browser/treeUtils.ts | 18 ++++++++++++++++-- .../browser/media/settingsEditor2.css | 8 ++++++-- .../preferences/browser/settingsEditor2.ts | 8 +++----- 3 files changed, 25 insertions(+), 9 deletions(-) diff --git a/src/vs/base/parts/tree/browser/treeUtils.ts b/src/vs/base/parts/tree/browser/treeUtils.ts index 07e95954552..7187ca1bd2a 100644 --- a/src/vs/base/parts/tree/browser/treeUtils.ts +++ b/src/vs/base/parts/tree/browser/treeUtils.ts @@ -6,14 +6,28 @@ import * as _ from 'vs/base/parts/tree/browser/tree'; -export function collapseAll(tree: _.ITree): void { +export function collapseAll(tree: _.ITree, except?: any): void { const nav = tree.getNavigator(); let cur; while (cur = nav.next()) { - tree.collapse(cur); + if (!except || !isEqualOrParent(tree, except, cur)) { + tree.collapse(cur); + } } } +export function isEqualOrParent(tree: _.ITree, element: any, candidateParent: any): boolean { + const nav = tree.getNavigator(element); + + do { + if (element === candidateParent) { + return true; + } + } while (element = nav.parent()); + + return false; +} + export function expandAll(tree: _.ITree): void { const nav = tree.getNavigator(); let cur; diff --git a/src/vs/workbench/parts/preferences/browser/media/settingsEditor2.css b/src/vs/workbench/parts/preferences/browser/media/settingsEditor2.css index 76ab4e7c44b..3be8f0ad66d 100644 --- a/src/vs/workbench/parts/preferences/browser/media/settingsEditor2.css +++ b/src/vs/workbench/parts/preferences/browser/media/settingsEditor2.css @@ -133,7 +133,6 @@ display: flex; margin: auto; max-width: 1000px; - justify-content: space-between; } .settings-editor.search-mode > .settings-body .settings-tree-container .monaco-tree-wrapper, @@ -142,6 +141,12 @@ margin-left: 0px; } +.settings-editor.narrow > .settings-body .settings-tree-container .monaco-tree-wrapper, +.settings-editor.narrow > .settings-body > .settings-tree-container .setting-measure-container { + width: calc(100% - 11px); + margin-left: 0px; +} + .settings-editor > .settings-body .settings-tree-container .monaco-tree-wrapper, .settings-editor > .settings-body > .settings-tree-container .setting-measure-container { /** 11px for scrollbar + 208px for TOC margin */ @@ -149,7 +154,6 @@ margin-left: 208px; } - .settings-editor > .settings-body .settings-toc-container { position: absolute; width: 160px; diff --git a/src/vs/workbench/parts/preferences/browser/settingsEditor2.ts b/src/vs/workbench/parts/preferences/browser/settingsEditor2.ts index dd029ff93f8..79fef29f2a4 100644 --- a/src/vs/workbench/parts/preferences/browser/settingsEditor2.ts +++ b/src/vs/workbench/parts/preferences/browser/settingsEditor2.ts @@ -437,11 +437,9 @@ export class SettingsEditor2 extends BaseEditor { if (element && this.tocTree.getSelection()[0] !== element) { this.tocTree.reveal(element); const elementTop = this.tocTree.getRelativeTop(element); - collapseAll(this.tocTree); - if (elementTop < 0) { - this.tocTree.reveal(element, 0); - } else if (elementTop > 1) { - this.tocTree.reveal(element, 1); + collapseAll(this.tocTree, element); + if (elementTop < 0 || elementTop > 1) { + this.tocTree.reveal(element); } else { this.tocTree.reveal(element, elementTop); } From 8922069381e2a26c7fa280d62634f9142d1d6889 Mon Sep 17 00:00:00 2001 From: Rob Lourens Date: Sun, 29 Jul 2018 15:01:18 -0700 Subject: [PATCH 0294/1276] Settings editor - header rows should not be selectable --- .../parts/preferences/browser/settingsTree.ts | 41 +++++++++++++++++++ 1 file changed, 41 insertions(+) diff --git a/src/vs/workbench/parts/preferences/browser/settingsTree.ts b/src/vs/workbench/parts/preferences/browser/settingsTree.ts index 913ed12fab2..a11bf419339 100644 --- a/src/vs/workbench/parts/preferences/browser/settingsTree.ts +++ b/src/vs/workbench/parts/preferences/browser/settingsTree.ts @@ -1553,4 +1553,45 @@ export class SettingsTree extends NonExpandableTree { this.style(colors); })); } + + public setFocus(element?: any, eventPayload?: any): void { + if (element instanceof SettingsTreeGroupElement) { + const nav = this.getNavigator(element, false); + do { + element = nav.next(); + } while (element instanceof SettingsTreeGroupElement); + } + + super.setFocus(element, eventPayload); + } + + public focusNext(count?: number, eventPayload?: any): void { + const focus = this.getFocus(); + if (!focus) { + return super.focusFirst(); + } + + const nav = this.getNavigator(focus, false); + let current; + do { + current = nav.next(); + } while (current instanceof SettingsTreeGroupElement); + + this.setFocus(current, eventPayload); + } + + public focusPrevious(count?: number, eventPayload?: any): void { + const focus = this.getFocus(); + if (!focus) { + return super.focusFirst(); + } + + const nav = this.getNavigator(focus, false); + let current; + do { + current = nav.previous(); + } while (current instanceof SettingsTreeGroupElement); + + this.setFocus(current, eventPayload); + } } From 64c433bf2bd43c85d1bfe5753bb6fb90ff4be14a Mon Sep 17 00:00:00 2001 From: SteVen Batten <6561887+sbatten@users.noreply.github.com> Date: Sun, 29 Jul 2018 21:05:17 -0700 Subject: [PATCH 0295/1276] fixes #54877 --- .../browser/parts/titlebar/titlebarPart.ts | 29 ++++++++++++------- 1 file changed, 18 insertions(+), 11 deletions(-) diff --git a/src/vs/workbench/browser/parts/titlebar/titlebarPart.ts b/src/vs/workbench/browser/parts/titlebar/titlebarPart.ts index 3eedcb97500..4fae75a06ea 100644 --- a/src/vs/workbench/browser/parts/titlebar/titlebarPart.ts +++ b/src/vs/workbench/browser/parts/titlebar/titlebarPart.ts @@ -54,6 +54,7 @@ export class TitlebarPart extends Part implements ITitleService { private appIcon: Builder; private menubarPart: MenubarPart; private menubar: Builder; + private resizer: Builder; private pendingTitle: string; private representedFileName: string; @@ -334,12 +335,12 @@ export class TitlebarPart extends Part implements ITitleService { this.windowService.closeWindow().then(null, errors.onUnexpectedError); }); + // Resizer + this.resizer = $(this.titleContainer).div({ class: 'resizer' }); + const isMaximized = this.windowService.getConfiguration().maximized ? true : false; this.onDidChangeMaximized(isMaximized); this.windowService.onDidChangeMaximize(this.onDidChangeMaximized, this); - - // Resizer - $(this.titleContainer).div({ class: 'resizer' }); } // Since the title area is used to drag the window, we do not want to steal focus from the @@ -357,16 +358,22 @@ export class TitlebarPart extends Part implements ITitleService { } private onDidChangeMaximized(maximized: boolean) { - if (!this.maxRestoreControl) { - return; + if (this.maxRestoreControl) { + if (maximized) { + this.maxRestoreControl.removeClass('window-maximize'); + this.maxRestoreControl.addClass('window-unmaximize'); + } else { + this.maxRestoreControl.removeClass('window-unmaximize'); + this.maxRestoreControl.addClass('window-maximize'); + } } - if (maximized) { - this.maxRestoreControl.removeClass('window-maximize'); - this.maxRestoreControl.addClass('window-unmaximize'); - } else { - this.maxRestoreControl.removeClass('window-unmaximize'); - this.maxRestoreControl.addClass('window-maximize'); + if (this.resizer) { + if (maximized) { + this.resizer.hide(); + } else { + this.resizer.show(); + } } } From 7e26d22eee2662b643de9996b5cb4b731c0dacf5 Mon Sep 17 00:00:00 2001 From: Andre Weinand Date: Mon, 30 Jul 2018 07:42:15 +0200 Subject: [PATCH 0296/1276] change debug assignee to isi --- .github/classifier.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/classifier.yml b/.github/classifier.yml index c1c067e5c53..a7bcb40c96f 100644 --- a/.github/classifier.yml +++ b/.github/classifier.yml @@ -15,7 +15,7 @@ css-less-scss: [ aeschli ], debug-console: [], debug: { - assignees: [ weinand ], + assignees: [ isidorn ], assignLabel: false }, diff-editor: [], From a67c81516f6fd676737fa2bf4affa55d41413398 Mon Sep 17 00:00:00 2001 From: ozyx Date: Mon, 30 Jul 2018 01:10:44 -0700 Subject: [PATCH 0297/1276] Add option to enable cycling of parameter hints --- .../common/config/commonEditorConfig.ts | 5 +++++ src/vs/editor/common/config/editorOptions.ts | 10 +++++++++ .../parameterHints/parameterHintsWidget.ts | 21 +++++++++++++++---- src/vs/monaco.d.ts | 6 ++++++ .../telemetry/common/telemetryUtils.ts | 1 + 5 files changed, 39 insertions(+), 4 deletions(-) diff --git a/src/vs/editor/common/config/commonEditorConfig.ts b/src/vs/editor/common/config/commonEditorConfig.ts index 33a9a433690..8b39ee0f249 100644 --- a/src/vs/editor/common/config/commonEditorConfig.ts +++ b/src/vs/editor/common/config/commonEditorConfig.ts @@ -684,6 +684,11 @@ const editorConfiguration: IConfigurationNode = { 'default': EDITOR_DEFAULTS.contribInfo.codeLens, 'description': nls.localize('codeLens', "Controls whether the editor shows CodeLens") }, + 'editor.cycleParameterHints': { + 'type': 'boolean', + 'default': EDITOR_DEFAULTS.contribInfo.cycleParameterHints, + 'description': nls.localize('cycleParameterHints', "Controls whether the parameter hints menu cycles or closes when reaching the end of the list.") + }, 'editor.folding': { 'type': 'boolean', 'default': EDITOR_DEFAULTS.contribInfo.folding, diff --git a/src/vs/editor/common/config/editorOptions.ts b/src/vs/editor/common/config/editorOptions.ts index 14365ee9925..902d02abf79 100644 --- a/src/vs/editor/common/config/editorOptions.ts +++ b/src/vs/editor/common/config/editorOptions.ts @@ -416,6 +416,11 @@ export interface IEditorOptions { * Defaults to true. */ contextmenu?: boolean; + /** + * Enable cycling through parameter hints. + * Defaults to false. + */ + cycleParameterHints?: boolean; /** * A multiplier to be used on the `deltaX` and `deltaY` of mouse wheel scroll events. * Defaults to 1. @@ -909,6 +914,7 @@ export interface EditorContribOptions { readonly hover: InternalEditorHoverOptions; readonly links: boolean; readonly contextmenu: boolean; + readonly cycleParameterHints: boolean; readonly quickSuggestions: boolean | { other: boolean, comments: boolean, strings: boolean }; readonly quickSuggestionsDelay: number; readonly parameterHints: boolean; @@ -1289,6 +1295,7 @@ export class InternalEditorOptions { && this._equalsHoverOptions(a.hover, b.hover) && a.links === b.links && a.contextmenu === b.contextmenu + && a.cycleParameterHints === b.cycleParameterHints && InternalEditorOptions._equalsQuickSuggestions(a.quickSuggestions, b.quickSuggestions) && a.quickSuggestionsDelay === b.quickSuggestionsDelay && a.parameterHints === b.parameterHints @@ -1884,6 +1891,7 @@ export class EditorOptionsValidator { hover: this._santizeHoverOpts(opts.hover, defaults.hover), links: _boolean(opts.links, defaults.links), contextmenu: _boolean(opts.contextmenu, defaults.contextmenu), + cycleParameterHints: _boolean(opts.cycleParameterHints, defaults.cycleParameterHints), quickSuggestions: quickSuggestions, quickSuggestionsDelay: _clampedInt(opts.quickSuggestionsDelay, defaults.quickSuggestionsDelay, Constants.MIN_SAFE_SMALL_INTEGER, Constants.MAX_SAFE_SMALL_INTEGER), parameterHints: _boolean(opts.parameterHints, defaults.parameterHints), @@ -1992,6 +2000,7 @@ export class InternalEditorOptionsFactory { hover: opts.contribInfo.hover, links: (accessibilityIsOn ? false : opts.contribInfo.links), // DISABLED WHEN SCREEN READER IS ATTACHED contextmenu: opts.contribInfo.contextmenu, + cycleParameterHints: opts.contribInfo.cycleParameterHints, quickSuggestions: opts.contribInfo.quickSuggestions, quickSuggestionsDelay: opts.contribInfo.quickSuggestionsDelay, parameterHints: opts.contribInfo.parameterHints, @@ -2463,6 +2472,7 @@ export const EDITOR_DEFAULTS: IValidatedEditorOptions = { }, links: true, contextmenu: true, + cycleParameterHints: false, quickSuggestions: { other: true, comments: false, strings: false }, quickSuggestionsDelay: 10, parameterHints: true, diff --git a/src/vs/editor/contrib/parameterHints/parameterHintsWidget.ts b/src/vs/editor/contrib/parameterHints/parameterHintsWidget.ts index 9a5cfbdb383..0120cb2d5a1 100644 --- a/src/vs/editor/contrib/parameterHints/parameterHintsWidget.ts +++ b/src/vs/editor/contrib/parameterHints/parameterHintsWidget.ts @@ -476,14 +476,20 @@ export class ParameterHintsWidget implements IContentWidget, IDisposable { next(): boolean { const length = this.hints.signatures.length; const last = (this.currentSignature % length) === (length - 1); + const cycleParameterHints = this.editor.getConfiguration().contribInfo.cycleParameterHints; // If there is only one signature, or we're on last signature of list - if (length < 2 || last) { + if ((length < 2 || last) && !cycleParameterHints) { this.cancel(); return false; } - this.currentSignature++; + if (last && cycleParameterHints) { + this.currentSignature = 0; + } else { + this.currentSignature++; + } + this.render(); return true; } @@ -491,13 +497,20 @@ export class ParameterHintsWidget implements IContentWidget, IDisposable { previous(): boolean { const length = this.hints.signatures.length; const first = this.currentSignature === 0; + const cycleParameterHints = this.editor.getConfiguration().contribInfo.cycleParameterHints; - if (length < 2 || first) { + // If there is only one signature, or we're on first signature of list + if ((length < 2 || first) && !cycleParameterHints) { this.cancel(); return false; } - this.currentSignature--; + if (first && cycleParameterHints) { + this.currentSignature = length - 1; + } else { + this.currentSignature--; + } + this.render(); return true; } diff --git a/src/vs/monaco.d.ts b/src/vs/monaco.d.ts index 438105b4d89..fd79f366e38 100644 --- a/src/vs/monaco.d.ts +++ b/src/vs/monaco.d.ts @@ -2754,6 +2754,11 @@ declare namespace monaco.editor { * Defaults to true. */ contextmenu?: boolean; + /** + * Enable cycling through parameter hints. + * Defaults to false. + */ + cycleParameterHints?: boolean; /** * A multiplier to be used on the `deltaX` and `deltaY` of mouse wheel scroll events. * Defaults to 1. @@ -3188,6 +3193,7 @@ declare namespace monaco.editor { readonly hover: InternalEditorHoverOptions; readonly links: boolean; readonly contextmenu: boolean; + readonly cycleParameterHints: boolean; readonly quickSuggestions: boolean | { other: boolean; comments: boolean; diff --git a/src/vs/platform/telemetry/common/telemetryUtils.ts b/src/vs/platform/telemetry/common/telemetryUtils.ts index a68ff28367b..9e655dfb6d6 100644 --- a/src/vs/platform/telemetry/common/telemetryUtils.ts +++ b/src/vs/platform/telemetry/common/telemetryUtils.ts @@ -113,6 +113,7 @@ const configurationValueWhitelist = [ 'editor.multiCursorModifier', 'editor.quickSuggestions', 'editor.quickSuggestionsDelay', + 'editor.cycleParameterHints', 'editor.parameterHints', 'editor.autoClosingBrackets', 'editor.autoIndent', From 47212be6f39630c31bfb60ad22a277b88fe51175 Mon Sep 17 00:00:00 2001 From: Alex Dima Date: Mon, 30 Jul 2018 12:35:43 +0200 Subject: [PATCH 0298/1276] Settings sweep (#54690) --- extensions/css-language-features/package.nls.json | 12 ++++++------ extensions/merge-conflict/package.nls.json | 4 ++-- extensions/npm/package.nls.json | 2 +- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/extensions/css-language-features/package.nls.json b/extensions/css-language-features/package.nls.json index ca6e4df4c2c..6686d0e4f21 100644 --- a/extensions/css-language-features/package.nls.json +++ b/extensions/css-language-features/package.nls.json @@ -11,16 +11,16 @@ "css.lint.fontFaceProperties.desc": "`@font-face` rule must define `src` and `font-family` properties", "css.lint.hexColorLength.desc": "Hex colors must consist of three or six hex numbers", "css.lint.idSelector.desc": "Selectors should not contain IDs because these rules are too tightly coupled with the HTML.", - "css.lint.ieHack.desc": "IE hacks are only necessary when supporting IE7 and older", + "css.lint.ieHack.desc": "IE hacks are only necessary when supporting IE7 and older.", "css.lint.important.desc": "Avoid using !important. It is an indication that the specificity of the entire CSS has gotten out of control and needs to be refactored.", - "css.lint.importStatement.desc": "Import statements do not load in parallel", - "css.lint.propertyIgnoredDueToDisplay.desc": "Property is ignored due to the display. E.g. with 'display: inline', the width, height, margin-top, margin-bottom, and float properties have no effect", - "css.lint.universalSelector.desc": "The universal selector (*) is known to be slow", + "css.lint.importStatement.desc": "Import statements do not load in parallel.", + "css.lint.propertyIgnoredDueToDisplay.desc": "Property is ignored due to the display. E.g. with 'display: inline', the width, height, margin-top, margin-bottom, and float properties have no effect.", + "css.lint.universalSelector.desc": "The universal selector (*) is known to be slow.", "css.lint.unknownAtRules.desc": "Unknown at-rule.", "css.lint.unknownProperties.desc": "Unknown property.", "css.lint.unknownVendorSpecificProperties.desc": "Unknown vendor specific property.", - "css.lint.vendorPrefix.desc": "When using a vendor-specific prefix also include the standard property", - "css.lint.zeroUnits.desc": "No unit for zero needed", + "css.lint.vendorPrefix.desc": "When using a vendor-specific prefix also include the standard property.", + "css.lint.zeroUnits.desc": "No unit for zero needed.", "css.trace.server.desc": "Traces the communication between VS Code and the CSS language server.", "css.validate.title": "Controls CSS validation and problem severities.", "css.validate.desc": "Enables or disables all validations", diff --git a/extensions/merge-conflict/package.nls.json b/extensions/merge-conflict/package.nls.json index 66076bd7a87..ed7430674cb 100644 --- a/extensions/merge-conflict/package.nls.json +++ b/extensions/merge-conflict/package.nls.json @@ -13,6 +13,6 @@ "command.previous": "Previous Conflict", "command.compare": "Compare Current Conflict", "config.title": "Merge Conflict", - "config.codeLensEnabled": "Enable/disable merge conflict block CodeLens within editor", - "config.decoratorsEnabled": "Enable/disable merge conflict decorators within editor" + "config.codeLensEnabled": "Create a Code Lens for merge conflict blocks within editor.", + "config.decoratorsEnabled": "Create decorators for merge conflict blocks within editor." } \ No newline at end of file diff --git a/extensions/npm/package.nls.json b/extensions/npm/package.nls.json index 8c27e0ca5bd..7bdfed8e973 100644 --- a/extensions/npm/package.nls.json +++ b/extensions/npm/package.nls.json @@ -1,7 +1,7 @@ { "description": "Extension to add task support for npm scripts.", "displayName": "Npm support for VS Code", - "config.npm.autoDetect": "Controls whether auto detection of npm scripts is on or off. Default is on.", + "config.npm.autoDetect": "Controls whether npm scripts should be automatically detected.", "config.npm.runSilent": "Run npm commands with the `--silent` option.", "config.npm.packageManager": "The package manager used to run scripts.", "config.npm.exclude": "Configure glob patterns for folders that should be excluded from automatic script detection.", From 50dba3707cebd1f9a0088c8522db2817d1265b65 Mon Sep 17 00:00:00 2001 From: Martin Aeschlimann Date: Mon, 30 Jul 2018 15:07:08 +0200 Subject: [PATCH 0299/1276] Support file-uris as arguments --- src/vs/code/electron-main/app.ts | 11 ++- src/vs/code/electron-main/launch.ts | 3 +- src/vs/code/electron-main/menubar.ts | 20 ++-- src/vs/code/electron-main/windows.ts | 93 ++++++++++------- src/vs/code/node/args.ts | 20 ++++ src/vs/code/node/windowsFinder.ts | 19 ++-- src/vs/code/test/node/windowsFinder.test.ts | 30 +++--- .../environment/common/environment.ts | 1 + src/vs/platform/environment/node/argv.ts | 6 +- src/vs/platform/history/common/history.ts | 7 +- .../electron-main/historyMainService.ts | 99 ++++++++++++------- src/vs/platform/windows/common/windows.ts | 6 +- src/vs/platform/windows/common/windowsIpc.ts | 12 +-- .../windows/electron-main/windowsService.ts | 4 +- src/vs/workbench/browser/dnd.ts | 6 +- .../browser/parts/menubar/menubarPart.ts | 6 +- src/vs/workbench/electron-browser/actions.ts | 10 +- src/vs/workbench/electron-browser/commands.ts | 5 +- src/vs/workbench/electron-browser/window.ts | 4 +- .../workbench/electron-browser/workbench.ts | 4 +- .../parts/stats/node/workspaceStats.ts | 6 +- .../page/electron-browser/welcomePage.ts | 2 +- .../history/electron-browser/history.ts | 2 +- .../workbench/test/workbenchTestServices.ts | 4 +- 24 files changed, 228 insertions(+), 152 deletions(-) create mode 100644 src/vs/code/node/args.ts diff --git a/src/vs/code/electron-main/app.ts b/src/vs/code/electron-main/app.ts index 1b10a58da57..54b6be346e7 100644 --- a/src/vs/code/electron-main/app.ts +++ b/src/vs/code/electron-main/app.ts @@ -64,6 +64,7 @@ import { IMenubarService } from 'vs/platform/menubar/common/menubar'; import { MenubarService } from 'vs/platform/menubar/electron-main/menubarService'; import { MenubarChannel } from 'vs/platform/menubar/common/menubarIpc'; import { IUriDisplayService } from 'vs/platform/uriDisplay/common/uriDisplay'; +import { asArray } from 'vs/code/node/args'; export class CodeApplication { @@ -466,12 +467,16 @@ export class CodeApplication { // Open our first window const macOpenFiles = (global).macOpenFiles as string[]; const context = !!process.env['VSCODE_CLI'] ? OpenContext.CLI : OpenContext.DESKTOP; - if (args['new-window'] && args._.length === 0 && (args['folder-uri'] || []).length === 0) { + const cliArgs = args._ || []; + const folderURIs = asArray(args['folder-uri']); + const fileURIs = asArray(args['file-uri']); + + if (args['new-window'] && !cliArgs.length && !folderURIs.length && !fileURIs.length) { this.windowsMainService.open({ context, cli: args, forceNewWindow: true, forceEmpty: true, initialStartup: true }); // new window if "-n" was used without paths - } else if (macOpenFiles && macOpenFiles.length && (!args._ || !args._.length || !args['folder-uri'] || !args['folder-uri'].length)) { + } else if (macOpenFiles && macOpenFiles.length && !cliArgs.length && !folderURIs.length && !fileURIs.length) { this.windowsMainService.open({ context: OpenContext.DOCK, cli: args, urisToOpen: macOpenFiles.map(file => URI.file(file)), initialStartup: true }); // mac: open-file event received on startup } else { - this.windowsMainService.open({ context, cli: args, forceNewWindow: args['new-window'] || (!args._.length && args['unity-launch']), diffMode: args.diff, initialStartup: true }); // default: read paths from cli + this.windowsMainService.open({ context, cli: args, forceNewWindow: args['new-window'] || (!cliArgs.length && args['unity-launch']), diffMode: args.diff, initialStartup: true }); // default: read paths from cli } } diff --git a/src/vs/code/electron-main/launch.ts b/src/vs/code/electron-main/launch.ts index 2cad34a8d84..bf3c3d45c2a 100644 --- a/src/vs/code/electron-main/launch.ts +++ b/src/vs/code/electron-main/launch.ts @@ -20,6 +20,7 @@ import { IConfigurationService } from 'vs/platform/configuration/common/configur import URI, { UriComponents } from 'vs/base/common/uri'; import { BrowserWindow } from 'electron'; import { Event } from 'vs/base/common/event'; +import { asArray } from 'vs/code/node/args'; export const ID = 'launchService'; export const ILaunchService = createDecorator(ID); @@ -178,7 +179,7 @@ export class LaunchService implements ILaunchService { } // Start without file/folder arguments - else if (args._.length === 0 && (args['folder-uri'] || []).length === 0) { + else if (args._.length === 0 && !asArray(args['folder-uri'].length && !asArray(args['file-uri'].length))) { let openNewWindow = false; // Force new window diff --git a/src/vs/code/electron-main/menubar.ts b/src/vs/code/electron-main/menubar.ts index 556dfe6d3c4..e61db37a668 100644 --- a/src/vs/code/electron-main/menubar.ts +++ b/src/vs/code/electron-main/menubar.ts @@ -527,18 +527,18 @@ export class Menubar { } } - private createOpenRecentMenuItem(workspace: IWorkspaceIdentifier | ISingleFolderWorkspaceIdentifier | string, commandId: string, isFile: boolean): Electron.MenuItem { + private createOpenRecentMenuItem(workspaceOrFile: IWorkspaceIdentifier | ISingleFolderWorkspaceIdentifier | URI, commandId: string, isFile: boolean): Electron.MenuItem { let label: string; let uri: URI; - if (isSingleFolderWorkspaceIdentifier(workspace)) { - label = unmnemonicLabel(getWorkspaceLabel(workspace, this.environmentService, this.uriDisplayService, { verbose: true })); - uri = workspace; - } else if (isWorkspaceIdentifier(workspace)) { - label = getWorkspaceLabel(workspace, this.environmentService, this.uriDisplayService, { verbose: true }); - uri = URI.file(workspace.configPath); + if (isSingleFolderWorkspaceIdentifier(workspaceOrFile) && !isFile) { + label = unmnemonicLabel(getWorkspaceLabel(workspaceOrFile, this.environmentService, this.uriDisplayService, { verbose: true })); + uri = workspaceOrFile; + } else if (isWorkspaceIdentifier(workspaceOrFile)) { + label = getWorkspaceLabel(workspaceOrFile, this.environmentService, this.uriDisplayService, { verbose: true }); + uri = URI.file(workspaceOrFile.configPath); } else { - uri = URI.file(workspace); - label = unmnemonicLabel(this.uriDisplayService.getLabel(uri)); + label = unmnemonicLabel(this.uriDisplayService.getLabel(workspaceOrFile)); + uri = workspaceOrFile; } return new MenuItem(this.likeAction(commandId, { @@ -554,7 +554,7 @@ export class Menubar { }).length > 0; if (!success) { - this.historyMainService.removeFromRecentlyOpened([workspace]); + this.historyMainService.removeFromRecentlyOpened([workspaceOrFile]); } } }, false)); diff --git a/src/vs/code/electron-main/windows.ts b/src/vs/code/electron-main/windows.ts index 482676324a4..dc463908bc9 100644 --- a/src/vs/code/electron-main/windows.ts +++ b/src/vs/code/electron-main/windows.ts @@ -14,6 +14,7 @@ import { IBackupMainService } from 'vs/platform/backup/common/backup'; import { IEnvironmentService, ParsedArgs } from 'vs/platform/environment/common/environment'; import { IStateService } from 'vs/platform/state/common/state'; import { CodeWindow, defaultWindowState } from 'vs/code/electron-main/window'; +import { asArray } from 'vs/code/node/args'; import { ipcMain as ipc, screen, BrowserWindow, dialog, systemPreferences, app } from 'electron'; import { IPathWithLineAndColumn, parseLineAndColumnAware } from 'vs/code/node/paths'; import { ILifecycleService, UnloadReason, IWindowUnloadEvent } from 'vs/platform/lifecycle/electron-main/lifecycleMain'; @@ -365,8 +366,8 @@ export class WindowsManager implements IWindowsMainService { pathsToOpen = pathsToOpen.filter(path => !path.folderUri); } - let filesToOpen = pathsToOpen.filter(path => !!path.filePath && !path.createFilePath); - let filesToCreate = pathsToOpen.filter(path => !!path.filePath && path.createFilePath); + let filesToOpen = pathsToOpen.filter(path => !!path.fileUri && !path.createFilePath); + let filesToCreate = pathsToOpen.filter(path => !!path.fileUri && path.createFilePath); // When run with --diff, take the files to open as files to diff // if there are exactly two files provided. @@ -391,7 +392,7 @@ export class WindowsManager implements IWindowsMainService { // // These are windows to open to show either folders or files (including diffing files or creating them) // - const foldersToOpen = arrays.distinct(pathsToOpen.filter(win => win.folderUri && !win.filePath).map(win => win.folderUri), folder => getComparisonKey(folder)); // prevent duplicates + const foldersToOpen = arrays.distinct(pathsToOpen.filter(win => win.folderUri && !win.fileUri).map(win => win.folderUri), folder => getComparisonKey(folder)); // prevent duplicates // // These are windows to restore because of hot-exit or from previous session (only performed once on startup!) @@ -413,7 +414,7 @@ export class WindowsManager implements IWindowsMainService { // // These are empty windows to open // - const emptyToOpen = pathsToOpen.filter(win => !win.workspace && !win.folderUri && !win.filePath && !win.backupPath).length; + const emptyToOpen = pathsToOpen.filter(win => !win.workspace && !win.folderUri && !win.fileUri && !win.backupPath).length; // Open based on config const usedWindows = this.doOpen(openConfig, workspacesToOpen, workspacesToRestore, foldersToOpen, foldersToRestore, emptyToRestore, emptyToOpen, filesToOpen, filesToCreate, filesToDiff, filesToWait, foldersToAdd); @@ -421,7 +422,7 @@ export class WindowsManager implements IWindowsMainService { // Make sure to pass focus to the most relevant of the windows if we open multiple if (usedWindows.length > 1) { - let focusLastActive = this.windowsState.lastActiveWindow && !openConfig.forceEmpty && !openConfig.cli._.length && !(openConfig.cli['folder-uri'] || []).length && !(openConfig.urisToOpen || []).length; + let focusLastActive = this.windowsState.lastActiveWindow && !openConfig.forceEmpty && !openConfig.cli._.length && !asArray(openConfig.cli['file-uri']).length && !asArray(openConfig.cli['folder-uri']).length && !asArray(openConfig.urisToOpen).length; let focusLastOpened = true; let focusLastWindow = true; @@ -463,13 +464,13 @@ export class WindowsManager implements IWindowsMainService { // Also do not add paths when files are opened for diffing, only if opened individually if (!usedWindows.some(w => w.isExtensionDevelopmentHost) && !openConfig.cli.diff) { const recentlyOpenedWorkspaces: (IWorkspaceIdentifier | ISingleFolderWorkspaceIdentifier)[] = []; - const recentlyOpenedFiles: string[] = []; + const recentlyOpenedFiles: URI[] = []; pathsToOpen.forEach(win => { if (win.workspace || win.folderUri) { recentlyOpenedWorkspaces.push(win.workspace || win.folderUri); - } else if (win.filePath) { - recentlyOpenedFiles.push(win.filePath); + } else if (win.fileUri) { + recentlyOpenedFiles.push(win.fileUri); } }); @@ -539,7 +540,7 @@ export class WindowsManager implements IWindowsMainService { newWindow: openFilesInNewWindow, reuseWindow: openConfig.forceReuseWindow, context: openConfig.context, - filePath: fileToCheck && fileToCheck.filePath, + fileUri: fileToCheck && fileToCheck.fileUri, workspaceResolver: workspace => this.workspacesMainService.resolveWorkspaceSync(workspace.configPath) }); @@ -789,7 +790,7 @@ export class WindowsManager implements IWindowsMainService { } // Extract paths: from CLI - else if (openConfig.cli._.length > 0 || (openConfig.cli['folder-uri'] || []).length > 0) { + else if (openConfig.cli._.length > 0 || asArray(openConfig.cli['folder-uri']).length > 0 || asArray(openConfig.cli['file-uri']).length > 0) { windowsToOpen = this.doExtractPathsFromCLI(openConfig.cli); isCommandLineOrAPICall = true; } @@ -819,7 +820,7 @@ export class WindowsManager implements IWindowsMainService { private doExtractPathsFromAPI(openConfig: IOpenConfiguration): IPath[] { let pathsToOpen = openConfig.urisToOpen.map(pathToOpen => { - const path = this.parseUri(pathToOpen, { gotoLineMode: openConfig.cli && openConfig.cli.goto, forceOpenWorkspaceAsFile: openConfig.forceOpenWorkspaceAsFile }); + const path = this.parseUri(pathToOpen, openConfig.forceOpenWorkspaceAsFile, { gotoLineMode: openConfig.cli && openConfig.cli.goto, forceOpenWorkspaceAsFile: openConfig.forceOpenWorkspaceAsFile }); // Warn if the requested path to open does not exist if (!path) { @@ -848,10 +849,15 @@ export class WindowsManager implements IWindowsMainService { const pathsToOpen = []; // folder uris - if (cli['folder-uri'] && cli['folder-uri'].length) { - const arg = cli['folder-uri']; - const folderUris: string[] = typeof arg === 'string' ? [arg] : arg; - pathsToOpen.push(...arrays.coalesce(folderUris.map(candidate => this.parseUri(this.parseFolderUriArg(candidate), { ignoreFileNotFound: true, gotoLineMode: cli.goto })))); + const folderUris = asArray(cli['folder-uri']); + if (folderUris.length) { + pathsToOpen.push(...arrays.coalesce(folderUris.map(candidate => this.parseUri(this.parseUriArg(candidate), false, { ignoreFileNotFound: true, gotoLineMode: cli.goto })))); + } + + // file uris + const fileUris = asArray(cli['file-uri']); + if (fileUris.length) { + pathsToOpen.push(...arrays.coalesce(fileUris.map(candidate => this.parseUri(this.parseUriArg(candidate), true, { ignoreFileNotFound: true, gotoLineMode: cli.goto })))); } // folder or file paths @@ -892,7 +898,7 @@ export class WindowsManager implements IWindowsMainService { // folder (if path is valid) else if (lastActiveWindow.folderUri) { - const validatedFolder = this.parseUri(lastActiveWindow.folderUri); + const validatedFolder = this.parseUri(lastActiveWindow.folderUri, false); if (validatedFolder && validatedFolder.folderUri) { return [validatedFolder]; } @@ -923,7 +929,7 @@ export class WindowsManager implements IWindowsMainService { if (lastActiveWindow && lastActiveWindow.folderUri) { folderCandidates.push(lastActiveWindow.folderUri); } - windowsToOpen.push(...folderCandidates.map(candidate => this.parseUri(candidate)).filter(window => window && window.folderUri)); + windowsToOpen.push(...folderCandidates.map(candidate => this.parseUri(candidate, false)).filter(window => window && window.folderUri)); // Windows that were Empty if (restoreWindows === 'all') { @@ -963,7 +969,7 @@ export class WindowsManager implements IWindowsMainService { return restoreWindows; } - private parseFolderUriArg(arg: string): URI { + private parseUriArg(arg: string): URI { // Do not support if user has passed folder path on Windows if (isWindows && /^([a-z])\:(.*)$/i.test(arg)) { return null; @@ -971,7 +977,7 @@ export class WindowsManager implements IWindowsMainService { return URI.parse(arg); } - private parseUri(anyUri: URI, options?: { ignoreFileNotFound?: boolean, gotoLineMode?: boolean, forceOpenWorkspaceAsFile?: boolean; }): IPathToOpen { + private parseUri(anyUri: URI, isFile: boolean, options?: { ignoreFileNotFound?: boolean, gotoLineMode?: boolean, forceOpenWorkspaceAsFile?: boolean; }): IPathToOpen { if (!anyUri || !anyUri.scheme) { return null; } @@ -979,7 +985,11 @@ export class WindowsManager implements IWindowsMainService { if (anyUri.scheme === Schemas.file) { return this.parsePath(anyUri.fsPath, options); } - + if (isFile) { + return { + fileUri: anyUri + }; + } return { folderUri: anyUri }; @@ -1014,7 +1024,7 @@ export class WindowsManager implements IWindowsMainService { // File return { - filePath: candidate, + fileUri: URI.file(candidate), lineNumber: gotoLineMode ? parsedPath.line : void 0, columnNumber: gotoLineMode ? parsedPath.column : void 0 }; @@ -1030,10 +1040,11 @@ export class WindowsManager implements IWindowsMainService { } } } catch (error) { - this.historyMainService.removeFromRecentlyOpened([candidate]); // since file does not seem to exist anymore, remove from recent + const fileUri = URI.file(candidate); + this.historyMainService.removeFromRecentlyOpened([fileUri]); // since file does not seem to exist anymore, remove from recent if (options && options.ignoreFileNotFound) { - return { filePath: candidate, createFilePath: true }; // assume this is a file that does not yet exist + return { fileUri, createFilePath: true }; // assume this is a file that does not yet exist } } @@ -1093,38 +1104,46 @@ export class WindowsManager implements IWindowsMainService { return; } + let folderUris = asArray(openConfig.cli['folder-uri']); + let fileUris = asArray(openConfig.cli['file-uri']); + let cliArgs = openConfig.cli._; // Fill in previously opened workspace unless an explicit path is provided and we are not unit testing - if (openConfig.cli._.length === 0 && (openConfig.cli['folder-uri'] || []).length === 0 && !openConfig.cli.extensionTestsPath) { + if (!cliArgs.length && !folderUris.length && !fileUris.length && !openConfig.cli.extensionTestsPath) { const extensionDevelopmentWindowState = this.windowsState.lastPluginDevelopmentHostWindow; const workspaceToOpen = extensionDevelopmentWindowState && (extensionDevelopmentWindowState.workspace || extensionDevelopmentWindowState.folderUri); if (workspaceToOpen) { if (isSingleFolderWorkspaceIdentifier(workspaceToOpen)) { if (workspaceToOpen.scheme === Schemas.file) { - openConfig.cli._ = [workspaceToOpen.fsPath]; + cliArgs = [workspaceToOpen.fsPath]; } else { - openConfig.cli['folder-uri'] = [workspaceToOpen.toString()]; + folderUris = [workspaceToOpen.toString()]; } } else { - openConfig.cli._ = [workspaceToOpen.configPath]; + cliArgs = [workspaceToOpen.configPath]; } } } // Make sure we are not asked to open a workspace or folder that is already opened - if (openConfig.cli._.some(path => !!findWindowOnWorkspaceOrFolderUri(WindowsManager.WINDOWS, URI.file(path)))) { - openConfig.cli._ = []; - } - if (openConfig.cli['folder-uri']) { - const arg = openConfig.cli['folder-uri']; - const folderUris: string[] = typeof arg === 'string' ? [arg] : arg; - if (folderUris.some(uri => !!findWindowOnWorkspaceOrFolderUri(WindowsManager.WINDOWS, this.parseFolderUriArg(uri)))) { - openConfig.cli['folder-uri'] = []; - } + if (cliArgs.length && cliArgs.some(path => !!findWindowOnWorkspaceOrFolderUri(WindowsManager.WINDOWS, URI.file(path)))) { + cliArgs = []; } + if (folderUris.length && folderUris.some(uri => !!findWindowOnWorkspaceOrFolderUri(WindowsManager.WINDOWS, this.parseUriArg(uri)))) { + folderUris = []; + } + + if (fileUris.length && fileUris.some(uri => !!findWindowOnWorkspaceOrFolderUri(WindowsManager.WINDOWS, this.parseUriArg(uri)))) { + fileUris = []; + } + + openConfig.cli._ = cliArgs; + openConfig.cli['folder-uri'] = folderUris; + openConfig.cli['file-uri'] = fileUris; + // Open it - this.open({ context: openConfig.context, cli: openConfig.cli, forceNewWindow: true, forceEmpty: openConfig.cli._.length === 0 && (openConfig.cli['folder-uri'] || []).length === 0, userEnv: openConfig.userEnv }); + this.open({ context: openConfig.context, cli: openConfig.cli, forceNewWindow: true, forceEmpty: !cliArgs.length && !folderUris.length && !fileUris.length, userEnv: openConfig.userEnv }); } private openInBrowserWindow(options: IOpenBrowserWindowOptions): ICodeWindow { diff --git a/src/vs/code/node/args.ts b/src/vs/code/node/args.ts new file mode 100644 index 00000000000..8f1a5a9fc9c --- /dev/null +++ b/src/vs/code/node/args.ts @@ -0,0 +1,20 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +'use strict'; + +/** + * Converts an arument into to an array + * @param arg a argument value. Can be undefined, en entry or an array + */ +export function asArray(arg: T | T[] | undefined): T[] { + if (arg) { + if (Array.isArray(arg)) { + return arg; + } + return [arg]; + } + return []; +} \ No newline at end of file diff --git a/src/vs/code/node/windowsFinder.ts b/src/vs/code/node/windowsFinder.ts index cd9bca97297..c4cc2e87c44 100644 --- a/src/vs/code/node/windowsFinder.ts +++ b/src/vs/code/node/windowsFinder.ts @@ -9,14 +9,13 @@ import * as platform from 'vs/base/common/platform'; import * as paths from 'vs/base/common/paths'; import { OpenContext } from 'vs/platform/windows/common/windows'; import { IWorkspaceIdentifier, IResolvedWorkspace, ISingleFolderWorkspaceIdentifier, isSingleFolderWorkspaceIdentifier } from 'vs/platform/workspaces/common/workspaces'; -import { Schemas } from 'vs/base/common/network'; import URI from 'vs/base/common/uri'; -import { hasToIgnoreCase, isEqual } from 'vs/base/common/resources'; +import { hasToIgnoreCase, isEqual, isEqualOrParent } from 'vs/base/common/resources'; export interface ISimpleWindow { openedWorkspace?: IWorkspaceIdentifier; openedFolderUri?: URI; - openedFilePath?: string; + openedFileUri?: URI; extensionDevelopmentPath?: string; lastFocusTime: number; } @@ -26,15 +25,15 @@ export interface IBestWindowOrFolderOptions { newWindow: boolean; reuseWindow: boolean; context: OpenContext; - filePath?: string; + fileUri?: URI; userHome?: string; codeSettingsFolder?: string; workspaceResolver: (workspace: IWorkspaceIdentifier) => IResolvedWorkspace; } -export function findBestWindowOrFolderForFile({ windows, newWindow, reuseWindow, context, filePath, workspaceResolver }: IBestWindowOrFolderOptions): W { - if (!newWindow && filePath && (context === OpenContext.DESKTOP || context === OpenContext.CLI || context === OpenContext.DOCK)) { - const windowOnFilePath = findWindowOnFilePath(windows, filePath, workspaceResolver); +export function findBestWindowOrFolderForFile({ windows, newWindow, reuseWindow, context, fileUri, workspaceResolver }: IBestWindowOrFolderOptions): W { + if (!newWindow && fileUri && (context === OpenContext.DESKTOP || context === OpenContext.CLI || context === OpenContext.DOCK)) { + const windowOnFilePath = findWindowOnFilePath(windows, fileUri, workspaceResolver); if (windowOnFilePath) { return windowOnFilePath; } @@ -43,20 +42,20 @@ export function findBestWindowOrFolderForFile({ windows return !newWindow ? getLastActiveWindow(windows) : null; } -function findWindowOnFilePath(windows: W[], filePath: string, workspaceResolver: (workspace: IWorkspaceIdentifier) => IResolvedWorkspace): W { +function findWindowOnFilePath(windows: W[], fileUri: URI, workspaceResolver: (workspace: IWorkspaceIdentifier) => IResolvedWorkspace): W { // First check for windows with workspaces that have a parent folder of the provided path opened const workspaceWindows = windows.filter(window => !!window.openedWorkspace); for (let i = 0; i < workspaceWindows.length; i++) { const window = workspaceWindows[i]; const resolvedWorkspace = workspaceResolver(window.openedWorkspace); - if (resolvedWorkspace && resolvedWorkspace.folders.some(folder => folder.uri.scheme === Schemas.file && paths.isEqualOrParent(filePath, folder.uri.fsPath, !platform.isLinux /* ignorecase */))) { + if (resolvedWorkspace && resolvedWorkspace.folders.some(folder => isEqualOrParent(fileUri, folder.uri, hasToIgnoreCase(fileUri)))) { return window; } } // Then go with single folder windows that are parent of the provided file path - const singleFolderWindowsOnFilePath = windows.filter(window => window.openedFolderUri && window.openedFolderUri.scheme === Schemas.file && paths.isEqualOrParent(filePath, window.openedFolderUri.fsPath, !platform.isLinux /* ignorecase */)); + const singleFolderWindowsOnFilePath = windows.filter(window => window.openedFolderUri && isEqualOrParent(fileUri, window.openedFolderUri, hasToIgnoreCase(fileUri))); if (singleFolderWindowsOnFilePath.length) { return singleFolderWindowsOnFilePath.sort((a, b) => -(a.openedFolderUri.path.length - b.openedFolderUri.path.length))[0]; } diff --git a/src/vs/code/test/node/windowsFinder.test.ts b/src/vs/code/test/node/windowsFinder.test.ts index b9b70a3503d..8b774f68b7b 100644 --- a/src/vs/code/test/node/windowsFinder.test.ts +++ b/src/vs/code/test/node/windowsFinder.test.ts @@ -45,32 +45,32 @@ suite('WindowsFinder', () => { test('New window without folder when no windows exist', () => { assert.equal(findBestWindowOrFolderForFile(options()), null); assert.equal(findBestWindowOrFolderForFile(options({ - filePath: path.join(fixturesFolder, 'no_vscode_folder', 'file.txt') + fileUri: URI.file(path.join(fixturesFolder, 'no_vscode_folder', 'file.txt')) })), null); assert.equal(findBestWindowOrFolderForFile(options({ - filePath: path.join(fixturesFolder, 'vscode_folder', 'file.txt'), + fileUri: URI.file(path.join(fixturesFolder, 'vscode_folder', 'file.txt')), newWindow: true })), null); assert.equal(findBestWindowOrFolderForFile(options({ - filePath: path.join(fixturesFolder, 'vscode_folder', 'file.txt'), + fileUri: URI.file(path.join(fixturesFolder, 'vscode_folder', 'file.txt')), reuseWindow: true })), null); assert.equal(findBestWindowOrFolderForFile(options({ - filePath: path.join(fixturesFolder, 'vscode_folder', 'file.txt'), + fileUri: URI.file(path.join(fixturesFolder, 'vscode_folder', 'file.txt')), context: OpenContext.API })), null); assert.equal(findBestWindowOrFolderForFile(options({ - filePath: path.join(fixturesFolder, 'vscode_folder', 'file.txt') + fileUri: URI.file(path.join(fixturesFolder, 'vscode_folder', 'file.txt')) })), null); assert.equal(findBestWindowOrFolderForFile(options({ - filePath: path.join(fixturesFolder, 'vscode_folder', 'new_folder', 'new_file.txt') + fileUri: URI.file(path.join(fixturesFolder, 'vscode_folder', 'new_folder', 'new_file.txt')) })), null); }); test('New window without folder when windows exist', () => { assert.equal(findBestWindowOrFolderForFile(options({ windows, - filePath: path.join(fixturesFolder, 'no_vscode_folder', 'file.txt'), + fileUri: URI.file(path.join(fixturesFolder, 'no_vscode_folder', 'file.txt')), newWindow: true })), null); }); @@ -81,16 +81,16 @@ suite('WindowsFinder', () => { })), lastActiveWindow); assert.equal(findBestWindowOrFolderForFile(options({ windows, - filePath: path.join(fixturesFolder, 'no_vscode_folder2', 'file.txt') + fileUri: URI.file(path.join(fixturesFolder, 'no_vscode_folder2', 'file.txt')) })), lastActiveWindow); assert.equal(findBestWindowOrFolderForFile(options({ windows: [lastActiveWindow, noVscodeFolderWindow], - filePath: path.join(fixturesFolder, 'vscode_folder', 'file.txt'), + fileUri: URI.file(path.join(fixturesFolder, 'vscode_folder', 'file.txt')), reuseWindow: true })), lastActiveWindow); assert.equal(findBestWindowOrFolderForFile(options({ windows, - filePath: path.join(fixturesFolder, 'no_vscode_folder', 'file.txt'), + fileUri: URI.file(path.join(fixturesFolder, 'no_vscode_folder', 'file.txt')), context: OpenContext.API })), lastActiveWindow); }); @@ -98,16 +98,16 @@ suite('WindowsFinder', () => { test('Existing window with folder', () => { assert.equal(findBestWindowOrFolderForFile(options({ windows, - filePath: path.join(fixturesFolder, 'no_vscode_folder', 'file.txt') + fileUri: URI.file(path.join(fixturesFolder, 'no_vscode_folder', 'file.txt')) })), noVscodeFolderWindow); assert.equal(findBestWindowOrFolderForFile(options({ windows, - filePath: path.join(fixturesFolder, 'vscode_folder', 'file.txt') + fileUri: URI.file(path.join(fixturesFolder, 'vscode_folder', 'file.txt')) })), vscodeFolderWindow); const window: ISimpleWindow = { lastFocusTime: 1, openedFolderUri: URI.file(path.join(fixturesFolder, 'vscode_folder', 'nested_folder')) }; assert.equal(findBestWindowOrFolderForFile(options({ windows: [window], - filePath: path.join(fixturesFolder, 'vscode_folder', 'nested_folder', 'subfolder', 'file.txt') + fileUri: URI.file(path.join(fixturesFolder, 'vscode_folder', 'nested_folder', 'subfolder', 'file.txt')) })), window); }); @@ -116,7 +116,7 @@ suite('WindowsFinder', () => { const nestedFolderWindow: ISimpleWindow = { lastFocusTime: 1, openedFolderUri: URI.file(path.join(fixturesFolder, 'no_vscode_folder', 'nested_folder')) }; assert.equal(findBestWindowOrFolderForFile(options({ windows: [window, nestedFolderWindow], - filePath: path.join(fixturesFolder, 'no_vscode_folder', 'nested_folder', 'subfolder', 'file.txt') + fileUri: URI.file(path.join(fixturesFolder, 'no_vscode_folder', 'nested_folder', 'subfolder', 'file.txt')) })), nestedFolderWindow); }); @@ -124,7 +124,7 @@ suite('WindowsFinder', () => { const window: ISimpleWindow = { lastFocusTime: 1, openedWorkspace: testWorkspace }; assert.equal(findBestWindowOrFolderForFile(options({ windows: [window], - filePath: path.join(fixturesFolder, 'vscode_workspace_2_folder', 'nested_vscode_folder', 'subfolder', 'file.txt') + fileUri: URI.file(path.join(fixturesFolder, 'vscode_workspace_2_folder', 'nested_vscode_folder', 'subfolder', 'file.txt')) })), window); }); }); diff --git a/src/vs/platform/environment/common/environment.ts b/src/vs/platform/environment/common/environment.ts index c291dff9fec..ec4a4d2e12c 100644 --- a/src/vs/platform/environment/common/environment.ts +++ b/src/vs/platform/environment/common/environment.ts @@ -9,6 +9,7 @@ export interface ParsedArgs { [arg: string]: any; _: string[]; 'folder-uri'?: string | string[]; + 'file-uri'?: string | string[]; _urls?: string[]; help?: boolean; version?: boolean; diff --git a/src/vs/platform/environment/node/argv.ts b/src/vs/platform/environment/node/argv.ts index 30cfd3ddd91..386b12f597c 100644 --- a/src/vs/platform/environment/node/argv.ts +++ b/src/vs/platform/environment/node/argv.ts @@ -19,6 +19,7 @@ const options: minimist.Opts = { 'user-data-dir', 'extensions-dir', 'folder-uri', + 'file-uri', 'extensionDevelopmentPath', 'extensionTestsPath', 'install-extension', @@ -145,7 +146,6 @@ export function parseArgs(args: string[]): ParsedArgs { const optionsHelp: { [name: string]: string; } = { '-d, --diff ': localize('diff', "Compare two files with each other."), - '--folder-uri ': localize('folder uri', "Opens a window with given folder uri(s)"), '-a, --add ': localize('add', "Add folder(s) to the last active window."), '-g, --goto ': localize('goto', "Open a file at the path on the specified line and character position."), '-n, --new-window': localize('newWindow', "Force to open a new window."), @@ -154,7 +154,9 @@ const optionsHelp: { [name: string]: string; } = { '--locale ': localize('locale', "The locale to use (e.g. en-US or zh-TW)."), '--user-data-dir ': localize('userDataDir', "Specifies the directory that user data is kept in. Can be used to open multiple distinct instances of Code."), '-v, --version': localize('version', "Print version."), - '-h, --help': localize('help', "Print usage.") + '-h, --help': localize('help', "Print usage."), + '--folder-uri ': localize('folder uri', "Opens a window with given folder uri(s)"), + '--file-uri ': localize('file uri', "Opens a window with given file uri(s)") }; const extensionsHelp: { [name: string]: string; } = { diff --git a/src/vs/platform/history/common/history.ts b/src/vs/platform/history/common/history.ts index f09d7fd44ba..0434680bcea 100644 --- a/src/vs/platform/history/common/history.ts +++ b/src/vs/platform/history/common/history.ts @@ -9,12 +9,13 @@ import { IPath } from 'vs/platform/windows/common/windows'; import { Event as CommonEvent } from 'vs/base/common/event'; import { createDecorator } from 'vs/platform/instantiation/common/instantiation'; import { IWorkspaceIdentifier, ISingleFolderWorkspaceIdentifier } from 'vs/platform/workspaces/common/workspaces'; +import URI from 'vs/base/common/uri'; export const IHistoryMainService = createDecorator('historyMainService'); export interface IRecentlyOpened { workspaces: (IWorkspaceIdentifier | ISingleFolderWorkspaceIdentifier)[]; - files: string[]; + files: URI[]; } export interface IHistoryMainService { @@ -22,9 +23,9 @@ export interface IHistoryMainService { onRecentlyOpenedChange: CommonEvent; - addRecentlyOpened(workspaces: (IWorkspaceIdentifier | ISingleFolderWorkspaceIdentifier)[], files: string[]): void; + addRecentlyOpened(workspaces: (IWorkspaceIdentifier | ISingleFolderWorkspaceIdentifier)[], files: URI[]): void; getRecentlyOpened(currentWorkspace?: IWorkspaceIdentifier | ISingleFolderWorkspaceIdentifier, currentFiles?: IPath[]): IRecentlyOpened; - removeFromRecentlyOpened(paths: (IWorkspaceIdentifier | ISingleFolderWorkspaceIdentifier | string)[]): void; + removeFromRecentlyOpened(paths: (IWorkspaceIdentifier | ISingleFolderWorkspaceIdentifier | URI | string)[]): void; clearRecentlyOpened(): void; updateWindowsJumpList(): void; diff --git a/src/vs/platform/history/electron-main/historyMainService.ts b/src/vs/platform/history/electron-main/historyMainService.ts index d24cfee31d1..f2e7a4cc229 100644 --- a/src/vs/platform/history/electron-main/historyMainService.ts +++ b/src/vs/platform/history/electron-main/historyMainService.ts @@ -7,7 +7,7 @@ import * as nls from 'vs/nls'; import * as arrays from 'vs/base/common/arrays'; -import { trim } from 'vs/base/common/strings'; +import { trim, startsWith } from 'vs/base/common/strings'; import { IStateService } from 'vs/platform/state/common/state'; import { app } from 'electron'; import { ILogService } from 'vs/platform/log/common/log'; @@ -27,7 +27,7 @@ import { IUriDisplayService } from 'vs/platform/uriDisplay/common/uriDisplay'; interface ISerializedRecentlyOpened { workspaces: (IWorkspaceIdentifier | string | UriComponents)[]; - files: string[]; + files: (string | UriComponents)[]; } export class HistoryMainService implements IHistoryMainService { @@ -66,7 +66,7 @@ export class HistoryMainService implements IHistoryMainService { this.addRecentlyOpened([e.workspace], []); } - addRecentlyOpened(workspaces: (IWorkspaceIdentifier | ISingleFolderWorkspaceIdentifier)[], files: string[]): void { + addRecentlyOpened(workspaces: (IWorkspaceIdentifier | ISingleFolderWorkspaceIdentifier)[], files: URI[]): void { if ((workspaces && workspaces.length > 0) || (files && files.length > 0)) { const mru = this.getRecentlyOpened(); @@ -88,13 +88,13 @@ export class HistoryMainService implements IHistoryMainService { // Files if (Array.isArray(files)) { - files.forEach((path) => { - mru.files.unshift(path); + files.forEach((fileUri) => { + mru.files.unshift(fileUri); mru.files = arrays.distinct(mru.files, file => this.distinctFn(file)); // Add to recent documents (Windows only, macOS later) - if (isWindows) { - app.addRecentDocument(path); + if (isWindows && fileUri.scheme === Schemas.file) { + app.addRecentDocument(fileUri.fsPath); } }); } @@ -113,7 +113,7 @@ export class HistoryMainService implements IHistoryMainService { } } - removeFromRecentlyOpened(pathsToRemove: (IWorkspaceIdentifier | ISingleFolderWorkspaceIdentifier | string)[]): void { + removeFromRecentlyOpened(pathsToRemove: (IWorkspaceIdentifier | ISingleFolderWorkspaceIdentifier | URI | string)[]): void { const mru = this.getRecentlyOpened(); let update = false; @@ -143,7 +143,10 @@ export class HistoryMainService implements IHistoryMainService { } // Remove file - index = arrays.firstIndex(mru.files, file => typeof pathToRemove === 'string' && isEqual(file, pathToRemove, !isLinux /* ignorecase */)); + const pathToRemoveURI = pathToRemove instanceof URI ? pathToRemove : typeof pathToRemove === 'string' ? URI.file(pathToRemove) : null; + if (pathToRemoveURI) { + index = arrays.firstIndex(mru.files, file => areResourcesEqual(file, pathToRemoveURI, hasToIgnoreCase(pathToRemoveURI))); + } if (index >= 0) { mru.files.splice(index, 1); update = true; @@ -178,17 +181,27 @@ export class HistoryMainService implements IHistoryMainService { let maxEntries = HistoryMainService.MAX_MACOS_DOCK_RECENT_ENTRIES; // Take up to maxEntries/2 workspaces - const workspaces = mru.workspaces.filter(w => !(isSingleFolderWorkspaceIdentifier(w) && w.scheme !== Schemas.file)); - for (let i = 0; i < workspaces.length && i < HistoryMainService.MAX_MACOS_DOCK_RECENT_ENTRIES / 2; i++) { - const workspace = workspaces[i]; - app.addRecentDocument(isSingleFolderWorkspaceIdentifier(workspace) ? workspace.scheme === Schemas.file ? workspace.fsPath : workspace.toString() : workspace.configPath); - maxEntries--; + let nEntries = 0; + for (let i = 0; i < mru.workspaces.length && nEntries < HistoryMainService.MAX_MACOS_DOCK_RECENT_ENTRIES / 2; i++) { + const workspace = mru.workspaces[i]; + if (isSingleFolderWorkspaceIdentifier(workspace)) { + if (workspace.scheme === Schemas.file) { + app.addRecentDocument(workspace.fsPath); + nEntries++; + } + } else { + app.addRecentDocument(workspace.configPath); + nEntries++; + } } // Take up to maxEntries files - for (let i = 0; i < mru.files.length && i < maxEntries; i++) { + for (let i = 0; i < mru.files.length && nEntries < maxEntries; i++) { const file = mru.files[i]; - app.addRecentDocument(file); + if (file.scheme === Schemas.file) { + app.addRecentDocument(file.fsPath); + nEntries++; + } } } @@ -202,7 +215,7 @@ export class HistoryMainService implements IHistoryMainService { getRecentlyOpened(currentWorkspace?: IWorkspaceIdentifier | ISingleFolderWorkspaceIdentifier, currentFiles?: IPath[]): IRecentlyOpened { let workspaces: (IWorkspaceIdentifier | ISingleFolderWorkspaceIdentifier)[]; - let files: string[]; + let files: URI[]; // Get from storage const storedRecents = this.getRecentlyOpenedFromStorage(); @@ -221,7 +234,7 @@ export class HistoryMainService implements IHistoryMainService { // Add currently files to open to the beginning if any if (currentFiles) { - files.unshift(...currentFiles.map(f => f.filePath)); + files.unshift(...currentFiles.map(f => f.fileUri)); } // Clear those dupes @@ -234,22 +247,19 @@ export class HistoryMainService implements IHistoryMainService { return { workspaces, files }; } - private distinctFn(workspaceOrFile: IWorkspaceIdentifier | ISingleFolderWorkspaceIdentifier | string): string { - if (isSingleFolderWorkspaceIdentifier(workspaceOrFile)) { + private distinctFn(workspaceOrFile: IWorkspaceIdentifier | ISingleFolderWorkspaceIdentifier | URI): string { + if (workspaceOrFile instanceof URI) { return getComparisonKey(workspaceOrFile); } - if (typeof workspaceOrFile === 'string') { - return isLinux ? workspaceOrFile : workspaceOrFile.toLowerCase(); - } - return workspaceOrFile.id; } private getRecentlyOpenedFromStorage(): IRecentlyOpened { const storedRecents: ISerializedRecentlyOpened = this.stateService.getItem(HistoryMainService.recentlyOpenedStorageKey) || { workspaces: [], files: [] }; - const result: IRecentlyOpened = { workspaces: [], files: storedRecents.files }; + const result: IRecentlyOpened = { workspaces: [], files: [] }; for (const workspace of storedRecents.workspaces) { if (typeof workspace === 'string') { + // folder paths were strings <= 1.25 result.workspaces.push(URI.file(workspace)); } else if (isWorkspaceIdentifier(workspace)) { result.workspaces.push(workspace); @@ -257,11 +267,19 @@ export class HistoryMainService implements IHistoryMainService { result.workspaces.push(URI.revive(workspace)); } } + for (const file of storedRecents.files) { + if (typeof file === 'string') { + // file paths were strings <= 1.25 + result.workspaces.push(URI.file(file)); + } else { + result.workspaces.push(URI.revive(file)); + } + } return result; } private saveRecentlyOpened(recent: IRecentlyOpened): void { - const serialized: ISerializedRecentlyOpened = { workspaces: [], files: recent.files }; + const serialized: ISerializedRecentlyOpened = { workspaces: [], files: [] }; for (const workspace of recent.workspaces) { if (isSingleFolderWorkspaceIdentifier(workspace)) { serialized.workspaces.push(workspace.toJSON()); @@ -269,6 +287,9 @@ export class HistoryMainService implements IHistoryMainService { serialized.workspaces.push(workspace); } } + for (const file of recent.files) { + serialized.workspaces.push(file.toJSON()); + } this.stateService.setItem(HistoryMainService.recentlyOpenedStorageKey, recent); } @@ -302,7 +323,19 @@ export class HistoryMainService implements IHistoryMainService { // so we need to update our list of recent paths with the choice of the user to not add them again // Also: Windows will not show our custom category at all if there is any entry which was removed // by the user! See https://github.com/Microsoft/vscode/issues/15052 - this.removeFromRecentlyOpened(app.getJumpListSettings().removedItems.filter(r => !!r.args).map(r => trim(r.args, '"'))); + let toRemove: (ISingleFolderWorkspaceIdentifier | IWorkspaceIdentifier)[] = []; + for (let item of app.getJumpListSettings().removedItems) { + const args = item.args; + if (args) { + if (startsWith(args, '--folderUri')) { + toRemove.push(URI.parse(args.substring(13, args.length - 1))); + } else { + let configPath = trim(args, '"'); + toRemove.push({ id: this.workspacesMainService.getWorkspaceId(configPath), configPath }); + } + } + } + this.removeFromRecentlyOpened(toRemove); // Add entries jumpList.push({ @@ -310,19 +343,15 @@ export class HistoryMainService implements IHistoryMainService { name: nls.localize('recentFolders', "Recent Workspaces"), items: this.getRecentlyOpened().workspaces.slice(0, 7 /* limit number of entries here */).map(workspace => { const title = getWorkspaceLabel(workspace, this.environmentService, this.uriDisplayService); - const description = isSingleFolderWorkspaceIdentifier(workspace) ? nls.localize('folderDesc', "{0} {1}", getBaseLabel(workspace), this.uriDisplayService.getLabel(dirname(workspace))) : nls.localize('codeWorkspace', "Code Workspace"); + let description; let args; - // use quotes to support paths with whitespaces if (isSingleFolderWorkspaceIdentifier(workspace)) { - if (workspace.scheme === Schemas.file) { - args = `"${workspace.fsPath}"`; - } else { - args = `--folderUri "${workspace.path}"`; - } + description = nls.localize('folderDesc', "{0} {1}", getBaseLabel(workspace), this.uriDisplayService.getLabel(dirname(workspace))); + args = `--folderUri "${workspace.toString()}"`; } else { + description = nls.localize('codeWorkspace', "Code Workspace"); args = `"${workspace.configPath}"`; } - return { type: 'task', title, diff --git a/src/vs/platform/windows/common/windows.ts b/src/vs/platform/windows/common/windows.ts index 269f0bf03d0..5f69dac4613 100644 --- a/src/vs/platform/windows/common/windows.ts +++ b/src/vs/platform/windows/common/windows.ts @@ -126,8 +126,8 @@ export interface IWindowsService { saveAndEnterWorkspace(windowId: number, path: string): TPromise; toggleFullScreen(windowId: number): TPromise; setRepresentedFilename(windowId: number, fileName: string): TPromise; - addRecentlyOpened(files: string[]): TPromise; - removeFromRecentlyOpened(paths: (IWorkspaceIdentifier | ISingleFolderWorkspaceIdentifier | string)[]): TPromise; + addRecentlyOpened(files: URI[]): TPromise; + removeFromRecentlyOpened(paths: (IWorkspaceIdentifier | ISingleFolderWorkspaceIdentifier | URI | string)[]): TPromise; clearRecentlyOpened(): TPromise; getRecentlyOpened(windowId: number): TPromise; focusWindow(windowId: number): TPromise; @@ -295,7 +295,7 @@ export enum ReadyState { export interface IPath { // the file path to open within a Code instance - filePath?: string; + fileUri?: URI; // the line number in the file path to open lineNumber?: number; diff --git a/src/vs/platform/windows/common/windowsIpc.ts b/src/vs/platform/windows/common/windowsIpc.ts index 572713c7498..05912a7c133 100644 --- a/src/vs/platform/windows/common/windowsIpc.ts +++ b/src/vs/platform/windows/common/windowsIpc.ts @@ -40,8 +40,8 @@ export interface IWindowsChannel extends IChannel { call(command: 'saveAndEnterWorkspace', arg: [number, string]): TPromise; call(command: 'toggleFullScreen', arg: number): TPromise; call(command: 'setRepresentedFilename', arg: [number, string]): TPromise; - call(command: 'addRecentlyOpened', arg: string[]): TPromise; - call(command: 'removeFromRecentlyOpened', arg: (IWorkspaceIdentifier | ISingleFolderWorkspaceIdentifier | string)[]): TPromise; + call(command: 'addRecentlyOpened', arg: URI[]): TPromise; + call(command: 'removeFromRecentlyOpened', arg: (IWorkspaceIdentifier | ISingleFolderWorkspaceIdentifier | URI)[]): TPromise; call(command: 'clearRecentlyOpened'): TPromise; call(command: 'getRecentlyOpened', arg: number): TPromise; call(command: 'showPreviousWindowTab'): TPromise; @@ -141,9 +141,9 @@ export class WindowsChannel implements IWindowsChannel { case 'setRepresentedFilename': return this.service.setRepresentedFilename(arg[0], arg[1]); case 'addRecentlyOpened': return this.service.addRecentlyOpened(arg); case 'removeFromRecentlyOpened': { - let paths: (IWorkspaceIdentifier | ISingleFolderWorkspaceIdentifier | string)[] = arg; + let paths: (IWorkspaceIdentifier | ISingleFolderWorkspaceIdentifier | URI)[] = arg; if (Array.isArray(paths)) { - paths = paths.map(path => isWorkspaceIdentifier(path) || typeof path === 'string' ? path : URI.revive(path)); + paths = paths.map(path => isWorkspaceIdentifier(path) ? path : URI.revive(path)); } return this.service.removeFromRecentlyOpened(paths); } @@ -262,11 +262,11 @@ export class WindowsChannelClient implements IWindowsService { return this.channel.call('setRepresentedFilename', [windowId, fileName]); } - addRecentlyOpened(files: string[]): TPromise { + addRecentlyOpened(files: URI[]): TPromise { return this.channel.call('addRecentlyOpened', files); } - removeFromRecentlyOpened(paths: (IWorkspaceIdentifier | ISingleFolderWorkspaceIdentifier | string)[]): TPromise { + removeFromRecentlyOpened(paths: (IWorkspaceIdentifier | ISingleFolderWorkspaceIdentifier | URI)[]): TPromise { return this.channel.call('removeFromRecentlyOpened', paths); } diff --git a/src/vs/platform/windows/electron-main/windowsService.ts b/src/vs/platform/windows/electron-main/windowsService.ts index 0e2ace3e04f..58674c4a4c9 100644 --- a/src/vs/platform/windows/electron-main/windowsService.ts +++ b/src/vs/platform/windows/electron-main/windowsService.ts @@ -226,14 +226,14 @@ export class WindowsService implements IWindowsService, IURLHandler, IDisposable return TPromise.as(null); } - addRecentlyOpened(files: string[]): TPromise { + addRecentlyOpened(files: URI[]): TPromise { this.logService.trace('windowsService#addRecentlyOpened'); this.historyService.addRecentlyOpened(void 0, files); return TPromise.as(null); } - removeFromRecentlyOpened(paths: (IWorkspaceIdentifier | ISingleFolderWorkspaceIdentifier | string)[]): TPromise { + removeFromRecentlyOpened(paths: (IWorkspaceIdentifier | ISingleFolderWorkspaceIdentifier | URI | string)[]): TPromise { this.logService.trace('windowsService#removeFromRecentlyOpened'); this.historyService.removeFromRecentlyOpened(paths); diff --git a/src/vs/workbench/browser/dnd.ts b/src/vs/workbench/browser/dnd.ts index dd879f9d831..ec1f0660606 100644 --- a/src/vs/workbench/browser/dnd.ts +++ b/src/vs/workbench/browser/dnd.ts @@ -35,7 +35,6 @@ import { IEditorService, IResourceEditor } from 'vs/workbench/services/editor/co import { Disposable } from 'vs/base/common/lifecycle'; import { addDisposableListener, EventType } from 'vs/base/browser/dom'; import { IEditorGroup } from 'vs/workbench/services/group/common/editorGroupsService'; -import { IUriDisplayService } from 'vs/platform/uriDisplay/common/uriDisplay'; export interface IDraggedResource { resource: URI; @@ -166,8 +165,7 @@ export class ResourcesDropHandler { @IBackupFileService private backupFileService: IBackupFileService, @IUntitledEditorService private untitledEditorService: IUntitledEditorService, @IEditorService private editorService: IEditorService, - @IConfigurationService private configurationService: IConfigurationService, - @IUriDisplayService private uriDisplayService: IUriDisplayService + @IConfigurationService private configurationService: IConfigurationService ) { } @@ -189,7 +187,7 @@ export class ResourcesDropHandler { // Add external ones to recently open list unless dropped resource is a workspace const filesToAddToHistory = untitledOrFileResources.filter(d => d.isExternal && d.resource.scheme === Schemas.file).map(d => d.resource); if (filesToAddToHistory.length) { - this.windowsService.addRecentlyOpened(filesToAddToHistory.map(resource => this.uriDisplayService.getLabel(resource))); + this.windowsService.addRecentlyOpened(filesToAddToHistory); } const editors: IResourceEditor[] = untitledOrFileResources.map(untitledOrFileResource => ({ diff --git a/src/vs/workbench/browser/parts/menubar/menubarPart.ts b/src/vs/workbench/browser/parts/menubar/menubarPart.ts index c0ef6872610..09f72b0bc8e 100644 --- a/src/vs/workbench/browser/parts/menubar/menubarPart.ts +++ b/src/vs/workbench/browser/parts/menubar/menubarPart.ts @@ -491,19 +491,19 @@ export class MenubarPart extends Part { return this.currentEnableMenuBarMnemonics ? label : label.replace(/&&(.)/g, '$1'); } - private createOpenRecentMenuAction(workspace: IWorkspaceIdentifier | ISingleFolderWorkspaceIdentifier | string, commandId: string, isFile: boolean): IAction { + private createOpenRecentMenuAction(workspace: IWorkspaceIdentifier | ISingleFolderWorkspaceIdentifier | URI, commandId: string, isFile: boolean): IAction { let label: string; let uri: URI; - if (isSingleFolderWorkspaceIdentifier(workspace)) { + if (isSingleFolderWorkspaceIdentifier(workspace) && !isFile) { label = getWorkspaceLabel(workspace, this.environmentService, this.uriDisplayService, { verbose: true }); uri = workspace; } else if (isWorkspaceIdentifier(workspace)) { label = getWorkspaceLabel(workspace, this.environmentService, this.uriDisplayService, { verbose: true }); uri = URI.file(workspace.configPath); } else { - uri = URI.file(workspace); + uri = workspace; label = this.uriDisplayService.getLabel(uri); } diff --git a/src/vs/workbench/electron-browser/actions.ts b/src/vs/workbench/electron-browser/actions.ts index ee16bc0f5a5..63426fa881a 100644 --- a/src/vs/workbench/electron-browser/actions.ts +++ b/src/vs/workbench/electron-browser/actions.ts @@ -721,13 +721,13 @@ export abstract class BaseOpenRecentAction extends Action { .then(({ workspaces, files }) => this.openRecent(workspaces, files)); } - private openRecent(recentWorkspaces: (IWorkspaceIdentifier | ISingleFolderWorkspaceIdentifier)[], recentFiles: string[]): void { + private openRecent(recentWorkspaces: (IWorkspaceIdentifier | ISingleFolderWorkspaceIdentifier)[], recentFiles: URI[]): void { - function toPick(workspace: IWorkspaceIdentifier | ISingleFolderWorkspaceIdentifier | string, separator: ISeparator, fileKind: FileKind, environmentService: IEnvironmentService, uriDisplayService: IUriDisplayService, action: IAction): IFilePickOpenEntry { + function toPick(workspace: IWorkspaceIdentifier | ISingleFolderWorkspaceIdentifier | URI, separator: ISeparator, fileKind: FileKind, environmentService: IEnvironmentService, uriDisplayService: IUriDisplayService, action: IAction): IFilePickOpenEntry { let resource: URI; let label: string; let description: string; - if (isSingleFolderWorkspaceIdentifier(workspace)) { + if (isSingleFolderWorkspaceIdentifier(workspace) && fileKind !== FileKind.FILE) { resource = workspace; label = getWorkspaceLabel(workspace, environmentService, uriDisplayService); description = uriDisplayService.getLabel(resource.with({ path: paths.dirname(resource.path) })); @@ -736,7 +736,7 @@ export abstract class BaseOpenRecentAction extends Action { label = getWorkspaceLabel(workspace, environmentService, uriDisplayService); description = uriDisplayService.getLabel(dirname(resource)); } else { - resource = URI.file(workspace); + resource = workspace; label = getBaseLabel(workspace); description = uriDisplayService.getLabel(dirname(resource)); } @@ -785,7 +785,7 @@ class RemoveFromRecentlyOpened extends Action implements IPickOpenAction { static readonly LABEL = nls.localize('remove', "Remove from Recently Opened"); constructor( - private path: (IWorkspaceIdentifier | ISingleFolderWorkspaceIdentifier | string), + private path: (IWorkspaceIdentifier | ISingleFolderWorkspaceIdentifier | URI), @IWindowsService private windowsService: IWindowsService ) { super(RemoveFromRecentlyOpened.ID, RemoveFromRecentlyOpened.LABEL); diff --git a/src/vs/workbench/electron-browser/commands.ts b/src/vs/workbench/electron-browser/commands.ts index 3853ebdfab4..e7f8c93d838 100644 --- a/src/vs/workbench/electron-browser/commands.ts +++ b/src/vs/workbench/electron-browser/commands.ts @@ -19,7 +19,8 @@ import { range } from 'vs/base/common/arrays'; import { ContextKeyExpr } from 'vs/platform/contextkey/common/contextkey'; import { ITree } from 'vs/base/parts/tree/browser/tree'; import { InEditorZenModeContext, NoEditorsVisibleContext, SingleEditorGroupsContext } from 'vs/workbench/common/editor'; -import { ISingleFolderWorkspaceIdentifier } from 'vs/platform/workspaces/common/workspaces'; +import { IWorkspaceIdentifier, ISingleFolderWorkspaceIdentifier } from 'vs/platform/workspaces/common/workspaces'; +import URI from 'vs/base/common/uri'; // --- List Commands @@ -550,7 +551,7 @@ export function registerCommands(): void { win: { primary: void 0 } }); - CommandsRegistry.registerCommand('_workbench.removeFromRecentlyOpened', function (accessor: ServicesAccessor, path: string | ISingleFolderWorkspaceIdentifier) { + CommandsRegistry.registerCommand('_workbench.removeFromRecentlyOpened', function (accessor: ServicesAccessor, path: IWorkspaceIdentifier | ISingleFolderWorkspaceIdentifier | URI | string) { const windowsService = accessor.get(IWindowsService); return windowsService.removeFromRecentlyOpened([path]).then(() => void 0); diff --git a/src/vs/workbench/electron-browser/window.ts b/src/vs/workbench/electron-browser/window.ts index b6b6953d245..b6dc2cbc7d1 100644 --- a/src/vs/workbench/electron-browser/window.ts +++ b/src/vs/workbench/electron-browser/window.ts @@ -401,7 +401,7 @@ export class ElectronWindow extends Themable { // In wait mode, listen to changes to the editors and wait until the files // are closed that the user wants to wait for. When this happens we delete // the wait marker file to signal to the outside that editing is done. - const resourcesToWaitFor = request.filesToWait.paths.map(p => URI.file(p.filePath)); + const resourcesToWaitFor = request.filesToWait.paths.map(p => p.fileUri); const waitMarkerFile = URI.file(request.filesToWait.waitMarkerFilePath); const unbind = this.editorService.onDidCloseEditor(() => { if (resourcesToWaitFor.every(resource => !this.editorService.isOpen({ resource }))) { @@ -432,7 +432,7 @@ export class ElectronWindow extends Themable { private toInputs(paths: IPath[], isNew: boolean): IResourceEditor[] { return paths.map(p => { - const resource = URI.file(p.filePath); + const resource = p.fileUri; let input: IResourceInput | IUntitledResourceInput; if (isNew) { input = { filePath: resource.fsPath, options: { pinned: true } } as IUntitledResourceInput; diff --git a/src/vs/workbench/electron-browser/workbench.ts b/src/vs/workbench/electron-browser/workbench.ts index 2ae71ce73f3..c3ead3cacd8 100644 --- a/src/vs/workbench/electron-browser/workbench.ts +++ b/src/vs/workbench/electron-browser/workbench.ts @@ -490,7 +490,7 @@ export class Workbench extends Disposable implements IPartService { // Listen to editor closing (if we run with --wait) const filesToWait = this.workbenchParams.configuration.filesToWait; if (filesToWait) { - const resourcesToWaitFor = filesToWait.paths.map(p => URI.file(p.filePath)); + const resourcesToWaitFor = filesToWait.paths.map(p => p.fileUri); const waitMarkerFile = URI.file(filesToWait.waitMarkerFilePath); const listenerDispose = this.editorService.onDidCloseEditor(() => this.onEditorClosed(listenerDispose, resourcesToWaitFor, waitMarkerFile)); @@ -805,7 +805,7 @@ export class Workbench extends Disposable implements IPartService { } return paths.map(p => { - const resource = URI.file(p.filePath); + const resource = p.fileUri; let input: IResourceInput | IUntitledResourceInput; if (isNew) { input = { filePath: resource.fsPath, options: { pinned: true } } as IUntitledResourceInput; diff --git a/src/vs/workbench/parts/stats/node/workspaceStats.ts b/src/vs/workbench/parts/stats/node/workspaceStats.ts index 19bc5120d59..cc62a408918 100644 --- a/src/vs/workbench/parts/stats/node/workspaceStats.ts +++ b/src/vs/workbench/parts/stats/node/workspaceStats.ts @@ -356,11 +356,11 @@ export class WorkspaceStats implements IWorkbenchContribution { private findFolder({ filesToOpen, filesToCreate, filesToDiff }: IWindowConfiguration): URI { if (filesToOpen && filesToOpen.length) { - return this.parentURI(URI.file(filesToOpen[0].filePath)); + return this.parentURI(filesToOpen[0].fileUri); } else if (filesToCreate && filesToCreate.length) { - return this.parentURI(URI.file(filesToCreate[0].filePath)); + return this.parentURI(filesToCreate[0].fileUri); } else if (filesToDiff && filesToDiff.length) { - return this.parentURI(URI.file(filesToDiff[0].filePath)); + return this.parentURI(filesToDiff[0].fileUri); } return undefined; } diff --git a/src/vs/workbench/parts/welcome/page/electron-browser/welcomePage.ts b/src/vs/workbench/parts/welcome/page/electron-browser/welcomePage.ts index ad2032a68ca..c27b1e12bc6 100644 --- a/src/vs/workbench/parts/welcome/page/electron-browser/welcomePage.ts +++ b/src/vs/workbench/parts/welcome/page/electron-browser/welcomePage.ts @@ -258,7 +258,7 @@ class WelcomePage { return this.editorService.openEditor(this.editorInput, { pinned: false }); } - private onReady(container: HTMLElement, recentlyOpened: TPromise<{ files: string[]; workspaces: (IWorkspaceIdentifier | ISingleFolderWorkspaceIdentifier)[]; }>, installedExtensions: TPromise): void { + private onReady(container: HTMLElement, recentlyOpened: TPromise<{ files: URI[]; workspaces: (IWorkspaceIdentifier | ISingleFolderWorkspaceIdentifier)[]; }>, installedExtensions: TPromise): void { const enabled = isWelcomePageEnabled(this.configurationService); const showOnStartup = container.querySelector('#showOnStartup'); if (enabled) { diff --git a/src/vs/workbench/services/history/electron-browser/history.ts b/src/vs/workbench/services/history/electron-browser/history.ts index 0cb907bc631..ac8666d41f2 100644 --- a/src/vs/workbench/services/history/electron-browser/history.ts +++ b/src/vs/workbench/services/history/electron-browser/history.ts @@ -606,7 +606,7 @@ export class HistoryService extends Disposable implements IHistoryService { const input = arg1 as IResourceInput; - this.windowService.removeFromRecentlyOpened([input.resource.fsPath]); + this.windowService.removeFromRecentlyOpened([input.resource]); } private isFileOpened(resource: URI, group: IEditorGroup): boolean { diff --git a/src/vs/workbench/test/workbenchTestServices.ts b/src/vs/workbench/test/workbenchTestServices.ts index 8cf78a8f658..0b15100e5bb 100644 --- a/src/vs/workbench/test/workbenchTestServices.ts +++ b/src/vs/workbench/test/workbenchTestServices.ts @@ -1199,11 +1199,11 @@ export class TestWindowsService implements IWindowsService { return TPromise.as(void 0); } - addRecentlyOpened(files: string[]): TPromise { + addRecentlyOpened(files: URI[]): TPromise { return TPromise.as(void 0); } - removeFromRecentlyOpened(paths: string[]): TPromise { + removeFromRecentlyOpened(paths: URI[]): TPromise { return TPromise.as(void 0); } From 5505935fa7af22be303f5b292ebc5c904768db0c Mon Sep 17 00:00:00 2001 From: Erich Gamma Date: Sat, 28 Jul 2018 22:09:40 +0200 Subject: [PATCH 0300/1276] Added command to Run the selected npm script --- extensions/npm/README.md | 3 ++- extensions/npm/package.json | 4 +++ extensions/npm/package.nls.json | 3 ++- extensions/npm/src/commands.ts | 32 ++++++++++++++++++++++ extensions/npm/src/main.ts | 3 ++- extensions/npm/src/tasks.ts | 47 ++++++++++++++++++++++++++++++++- 6 files changed, 88 insertions(+), 4 deletions(-) create mode 100644 extensions/npm/src/commands.ts diff --git a/extensions/npm/README.md b/extensions/npm/README.md index f4b85999742..a24a7d69d6e 100644 --- a/extensions/npm/README.md +++ b/extensions/npm/README.md @@ -19,7 +19,8 @@ The Npm Script Explorer shows the npm scripts found in your workspace. The explo ### Run Scripts from the Editor -The extension provides code lense actions to run or debug a script from the editor. +The extension supports to run the selected script as a task when editing the `package.json`file. You can either run a script from +the hover shown on a script or using the command `Run Selected Npm Script`. ### Others diff --git a/extensions/npm/package.json b/extensions/npm/package.json index d5647618a81..2052b7a8228 100644 --- a/extensions/npm/package.json +++ b/extensions/npm/package.json @@ -82,6 +82,10 @@ "light": "resources/light/refresh.svg", "dark": "resources/dark/refresh.svg" } + }, + { + "command": "npm.runSelectedScript", + "title": "%command.runSelectedScript%" } ], "menus": { diff --git a/extensions/npm/package.nls.json b/extensions/npm/package.nls.json index 3a59c27cad1..b3800cd96e4 100644 --- a/extensions/npm/package.nls.json +++ b/extensions/npm/package.nls.json @@ -16,5 +16,6 @@ "command.run": "Run", "command.debug": "Debug", "command.openScript": "Open", - "command.runInstall": "Run Install" + "command.runInstall": "Run Install", + "command.runSelectedScript": "Run Selected Npm Script" } diff --git a/extensions/npm/src/commands.ts b/extensions/npm/src/commands.ts new file mode 100644 index 00000000000..509d536db92 --- /dev/null +++ b/extensions/npm/src/commands.ts @@ -0,0 +1,32 @@ +/*--------------------------------------------------------------------------------------------- + * 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 * as vscode from 'vscode'; +import { + runScript, findScriptAtPosition +} from './tasks'; +import * as nls from 'vscode-nls'; + +const localize = nls.loadMessageBundle(); + +export function runSelectedScript() { + let editor = vscode.window.activeTextEditor; + if (!editor) { + return; + } + let document = editor.document; + let contents = document.getText(); + let selection = editor.selection; + let offset = document.offsetAt(selection.anchor); + + let script = findScriptAtPosition(contents, offset); + if (script) { + runScript(script, document); + } else { + let message = localize('noScriptFound', 'Could not find an npm script at the selection.'); + vscode.window.showErrorMessage(message); + } +} \ No newline at end of file diff --git a/extensions/npm/src/main.ts b/extensions/npm/src/main.ts index 116852100dc..02e22490fd7 100644 --- a/extensions/npm/src/main.ts +++ b/extensions/npm/src/main.ts @@ -10,6 +10,7 @@ import { addJSONProviders } from './features/jsonContributions'; import { NpmScriptsTreeDataProvider } from './npmView'; import { invalidateTasksCache, NpmTaskProvider } from './tasks'; import { invalidateHoverScriptsCache, NpmScriptHoverProvider } from './scriptHover'; +import { runSelectedScript } from './commands'; export async function activate(context: vscode.ExtensionContext): Promise { const taskProvider = registerTaskProvider(context); @@ -37,7 +38,7 @@ export async function activate(context: vscode.ExtensionContext): Promise invalidateHoverScriptsCache(e.document); }); context.subscriptions.push(d); - + context.subscriptions.push(vscode.commands.registerCommand('npm.runSelectedScript', runSelectedScript)); context.subscriptions.push(addJSONProviders(httpRequest.xhr)); } diff --git a/extensions/npm/src/tasks.ts b/extensions/npm/src/tasks.ts index 3060cce1ed6..189fd98baec 100644 --- a/extensions/npm/src/tasks.ts +++ b/extensions/npm/src/tasks.ts @@ -6,7 +6,7 @@ import { TaskDefinition, Task, TaskGroup, WorkspaceFolder, RelativePattern, ShellExecution, Uri, workspace, - DebugConfiguration, debug, TaskProvider, ExtensionContext + DebugConfiguration, debug, TaskProvider, ExtensionContext, TextDocument, tasks } from 'vscode'; import * as path from 'path'; import * as fs from 'fs'; @@ -288,6 +288,15 @@ async function readFile(file: string): Promise { }); } +export function runScript(script: string, document: TextDocument) { + let uri = document.uri; + let folder = workspace.getWorkspaceFolder(uri); + if (folder) { + let task = createTask(script, `run ${script}`, folder, uri); + tasks.executeTask(task); + } +} + export function extractDebugArgFromScript(scriptValue: string): [string, number] | undefined { // matches --debug, --debug=1234, --debug-brk, debug-brk=1234, --inspect, // --inspect=1234, --inspect-brk, --inspect-brk=1234, @@ -405,6 +414,42 @@ export function findAllScriptRanges(buffer: string): Map= scriptStart && offset < nodeOffset + nodeLength) { + // found the script + inScripts = false; + } else { + script = undefined; + } + } + }, + onObjectProperty(property: string, nodeOffset: number, nodeLength: number) { + if (property === 'scripts') { + inScripts = true; + } + else if (inScripts) { + scriptStart = nodeOffset; + script = property; + } + } + }; + visit(buffer, visitor); + return script; +} export async function getScripts(packageJsonUri: Uri): Promise { From 67abeb217bc4bb1048da0965225bf83eecb191ae Mon Sep 17 00:00:00 2001 From: SteVen Batten <6561887+sbatten@users.noreply.github.com> Date: Sat, 28 Jul 2018 22:37:14 -0700 Subject: [PATCH 0301/1276] fixes #54452 --- .../parts/titlebar/media/titlebarpart.css | 55 +++++++------------ .../browser/parts/titlebar/titlebarPart.ts | 34 ++++++++++-- 2 files changed, 51 insertions(+), 38 deletions(-) diff --git a/src/vs/workbench/browser/parts/titlebar/media/titlebarpart.css b/src/vs/workbench/browser/parts/titlebar/media/titlebarpart.css index 54a27a0b1a3..06774758a71 100644 --- a/src/vs/workbench/browser/parts/titlebar/media/titlebarpart.css +++ b/src/vs/workbench/browser/parts/titlebar/media/titlebarpart.css @@ -99,65 +99,52 @@ display: none; } -.monaco-workbench > .part.titlebar > .window-controls-container > .window-icon { +.monaco-workbench > .part.titlebar > .window-controls-container > .window-icon-bg { display: inline-block; -webkit-app-region: no-drag; - -webkit-transition: background-color .1s; - transition: background-color .1s; height: 100%; width: 33.34%; - background-size: 21.74%; - background-position: center center; - background-repeat: no-repeat; } -.monaco-workbench > .part.titlebar > .window-controls-container > .window-icon svg { +.monaco-workbench > .part.titlebar > .window-controls-container .window-icon svg { shape-rendering: crispEdges; text-align: center; } -.monaco-workbench > .part.titlebar.titlebar > .window-controls-container > .window-close { - background-image: url('chrome-close-dark.svg'); +.monaco-workbench > .part.titlebar.titlebar > .window-controls-container .window-close { + -webkit-mask: url('chrome-close.svg') no-repeat 50% 50%; } -.monaco-workbench > .part.titlebar.titlebar.light > .window-controls-container > .window-close { - background-image: url('chrome-close.svg'); +.monaco-workbench > .part.titlebar.titlebar > .window-controls-container .window-unmaximize { + -webkit-mask: url('chrome-restore.svg') no-repeat 50% 50%; } -.monaco-workbench > .part.titlebar.titlebar > .window-controls-container > .window-unmaximize { - background-image: url('chrome-restore-dark.svg'); +.monaco-workbench > .part.titlebar > .window-controls-container .window-maximize { + -webkit-mask: url('chrome-maximize.svg') no-repeat 50% 50%; } -.monaco-workbench > .part.titlebar.titlebar.light > .window-controls-container > .window-unmaximize { - background-image: url('chrome-restore.svg'); +.monaco-workbench > .part.titlebar > .window-controls-container .window-minimize { + -webkit-mask: url('chrome-minimize.svg') no-repeat 50% 50%; } -.monaco-workbench > .part.titlebar > .window-controls-container > .window-maximize { - background-image: url('chrome-maximize-dark.svg'); +.monaco-workbench > .part.titlebar > .window-controls-container > .window-icon-bg > .window-icon { + height: 100%; + width: 100%; + -webkit-mask-size: 23.1%; } -.monaco-workbench > .part.titlebar.light > .window-controls-container > .window-maximize { - background-image: url('chrome-maximize.svg'); -} - -.monaco-workbench > .part.titlebar > .window-controls-container > .window-minimize { - background-image: url('chrome-minimize-dark.svg'); -} - -.monaco-workbench > .part.titlebar.light > .window-controls-container > .window-minimize { - background-image: url('chrome-minimize.svg'); -} - -.monaco-workbench > .part.titlebar > .window-controls-container > .window-icon:hover { +.monaco-workbench > .part.titlebar > .window-controls-container > .window-icon-bg:hover { background-color: rgba(255, 255, 255, 0.1); } -.monaco-workbench > .part.titlebar.light > .window-controls-container > .window-icon:hover { +.monaco-workbench > .part.titlebar.light > .window-controls-container > .window-icon-bg:hover { background-color: rgba(0, 0, 0, 0.1); } -.monaco-workbench > .part.titlebar > .window-controls-container > .window-close:hover, - .monaco-workbench > .part.titlebar.light > .window-controls-container > .window-close:hover { +.monaco-workbench > .part.titlebar > .window-controls-container > .window-icon-bg.window-close-bg:hover { background-color: rgba(232, 17, 35, 0.9); - background-image: url('chrome-close-dark.svg'); +} + +.monaco-workbench > .part.titlebar > .window-controls-container .window-icon.window-close:hover { + background-color: white; } \ No newline at end of file diff --git a/src/vs/workbench/browser/parts/titlebar/titlebarPart.ts b/src/vs/workbench/browser/parts/titlebar/titlebarPart.ts index 02513af6ff6..e725ed368a1 100644 --- a/src/vs/workbench/browser/parts/titlebar/titlebarPart.ts +++ b/src/vs/workbench/browser/parts/titlebar/titlebarPart.ts @@ -24,7 +24,7 @@ import * as nls from 'vs/nls'; import { EditorInput, toResource, Verbosity } from 'vs/workbench/common/editor'; import { IEnvironmentService } from 'vs/platform/environment/common/environment'; import { IWorkspaceContextService, WorkbenchState } from 'vs/platform/workspace/common/workspace'; -import { IThemeService } from 'vs/platform/theme/common/themeService'; +import { IThemeService, registerThemingParticipant, ITheme, ICssStyleCollector } from 'vs/platform/theme/common/themeService'; import { TITLE_BAR_ACTIVE_BACKGROUND, TITLE_BAR_ACTIVE_FOREGROUND, TITLE_BAR_INACTIVE_FOREGROUND, TITLE_BAR_INACTIVE_BACKGROUND, TITLE_BAR_BORDER } from 'vs/workbench/common/theme'; import { isMacintosh, isWindows, isLinux } from 'vs/base/common/platform'; import URI from 'vs/base/common/uri'; @@ -322,12 +322,12 @@ export class TitlebarPart extends Part implements ITitleService { this.windowControls = $(this.titleContainer).div({ class: 'window-controls-container' }); // Minimize - $(this.windowControls).div({ class: 'window-icon window-minimize' }).on(EventType.CLICK, () => { + $($(this.windowControls).div({ class: 'window-icon-bg' })).div({ class: 'window-icon window-minimize' }).on(EventType.CLICK, () => { this.windowService.minimizeWindow().then(null, errors.onUnexpectedError); }); // Restore - this.maxRestoreControl = $(this.windowControls).div({ class: 'window-icon window-max-restore' }).on(EventType.CLICK, () => { + this.maxRestoreControl = $($(this.windowControls).div({ class: 'window-icon-bg' })).div({ class: 'window-icon window-max-restore' }).on(EventType.CLICK, () => { this.windowService.isMaximized().then((maximized) => { if (maximized) { return this.windowService.unmaximizeWindow(); @@ -338,7 +338,7 @@ export class TitlebarPart extends Part implements ITitleService { }); // Close - $(this.windowControls).div({ class: 'window-icon window-close' }).on(EventType.CLICK, () => { + $($(this.windowControls).div({ class: 'window-icon-bg window-close-bg' })).div({ class: 'window-icon window-close' }).on(EventType.CLICK, () => { this.windowService.closeWindow().then(null, errors.onUnexpectedError); }); @@ -383,6 +383,12 @@ export class TitlebarPart extends Part implements ITitleService { // Part container if (this.titleContainer) { + if (this.isInactive) { + this.titleContainer.addClass('inactive'); + } else { + this.titleContainer.removeClass('inactive'); + } + const titleBackground = this.getColor(this.isInactive ? TITLE_BAR_INACTIVE_BACKGROUND : TITLE_BAR_ACTIVE_BACKGROUND); this.titleContainer.style('background-color', titleBackground); if (Color.fromHex(titleBackground).isLighter()) { @@ -555,3 +561,23 @@ class ShowItemInFolderAction extends Action { return this.windowsService.showItemInFolder(this.path); } } + +registerThemingParticipant((theme: ITheme, collector: ICssStyleCollector) => { + const titlebarActiveFg = theme.getColor(TITLE_BAR_ACTIVE_FOREGROUND); + if (titlebarActiveFg) { + collector.addRule(` + .monaco-workbench > .part.titlebar > .window-controls-container .window-icon { + background-color: ${titlebarActiveFg}; + } + `); + } + + const titlebarInactiveFg = theme.getColor(TITLE_BAR_INACTIVE_FOREGROUND); + if (titlebarInactiveFg) { + collector.addRule(` + .monaco-workbench > .part.titlebar.inactive > .window-controls-container .window-icon { + background-color: ${titlebarInactiveFg}; + } + `); + } +}); From 13f6721bfde4c3857861ba7b910f9edb526e3203 Mon Sep 17 00:00:00 2001 From: SteVen Batten <6561887+sbatten@users.noreply.github.com> Date: Sat, 28 Jul 2018 22:55:54 -0700 Subject: [PATCH 0302/1276] fixes #54929 --- .../browser/parts/titlebar/media/titlebarpart.css | 1 - src/vs/workbench/browser/parts/titlebar/titlebarPart.ts | 8 -------- 2 files changed, 9 deletions(-) diff --git a/src/vs/workbench/browser/parts/titlebar/media/titlebarpart.css b/src/vs/workbench/browser/parts/titlebar/media/titlebarpart.css index 06774758a71..29bb9ba3abf 100644 --- a/src/vs/workbench/browser/parts/titlebar/media/titlebarpart.css +++ b/src/vs/workbench/browser/parts/titlebar/media/titlebarpart.css @@ -69,7 +69,6 @@ .monaco-workbench > .part.titlebar > .window-appicon { width: 35px; height: 100%; - -webkit-app-region: no-drag; position: relative; z-index: 99; background-image: url('code-icon.svg'); diff --git a/src/vs/workbench/browser/parts/titlebar/titlebarPart.ts b/src/vs/workbench/browser/parts/titlebar/titlebarPart.ts index e725ed368a1..3eedcb97500 100644 --- a/src/vs/workbench/browser/parts/titlebar/titlebarPart.ts +++ b/src/vs/workbench/browser/parts/titlebar/titlebarPart.ts @@ -269,14 +269,6 @@ export class TitlebarPart extends Part implements ITitleService { // App Icon (Windows/Linux) if (!isMacintosh) { this.appIcon = $(this.titleContainer).div({ class: 'window-appicon' }); - - if (isWindows) { - this.appIcon.on(EventType.DBLCLICK, e => { - EventHelper.stop(e, true); - - this.windowService.closeWindow().then(null, errors.onUnexpectedError); - }); - } } // Menubar: the menubar part which is responsible for populating both the custom and native menubars From 53aa2d6a54e5e446b694d21cda63aeac1f16bc39 Mon Sep 17 00:00:00 2001 From: SteVen Batten Date: Sat, 28 Jul 2018 23:20:38 -0700 Subject: [PATCH 0303/1276] fixes #55248 --- src/vs/code/electron-main/menubar.ts | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/vs/code/electron-main/menubar.ts b/src/vs/code/electron-main/menubar.ts index e61db37a668..fcb357c0f9e 100644 --- a/src/vs/code/electron-main/menubar.ts +++ b/src/vs/code/electron-main/menubar.ts @@ -67,7 +67,7 @@ export class Menubar { }); // // Listen to some events from window service to update menu - // this.historyMainService.onRecentlyOpenedChange(() => this.updateMenu()); + this.historyMainService.onRecentlyOpenedChange(() => this.scheduleUpdateMenu()); this.windowsMainService.onWindowsCountChanged(e => this.onWindowsCountChanged(e)); // this.windowsMainService.onActiveWindowChanged(() => this.updateWorkspaceMenuItems()); // this.windowsMainService.onWindowReady(() => this.updateWorkspaceMenuItems()); @@ -391,11 +391,16 @@ export class Menubar { const openWorkspace = new MenuItem(this.likeAction('workbench.action.openWorkspace', { label: this.mnemonicLabel(nls.localize({ key: 'miOpenWorkspace', comment: ['&& denotes a mnemonic'] }, "Open Wor&&kspace...")), click: (menuItem, win, event) => this.windowsMainService.pickWorkspaceAndOpen({ forceNewWindow: this.isOptionClick(event), telemetryExtraData: { from: telemetryFrom } }) })); + const openRecentMenu = new Menu(); + this.setFallbackMenuById(openRecentMenu, 'Recent'); + const openRecent = new MenuItem({ label: this.mnemonicLabel(nls.localize({ key: 'miOpenRecent', comment: ['&& denotes a mnemonic'] }, "Open &&Recent")), submenu: openRecentMenu }); + menu.append(newFile); menu.append(newWindow); menu.append(__separator__()); menu.append(open); menu.append(openWorkspace); + menu.append(openRecent); break; From 8c4b14c8d9f259ab0da68658fb926992b9220dd8 Mon Sep 17 00:00:00 2001 From: Erich Gamma Date: Sun, 29 Jul 2018 11:10:56 +0200 Subject: [PATCH 0304/1276] prefix command with extension name --- extensions/npm/package.nls.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/extensions/npm/package.nls.json b/extensions/npm/package.nls.json index b3800cd96e4..99f4836fc17 100644 --- a/extensions/npm/package.nls.json +++ b/extensions/npm/package.nls.json @@ -17,5 +17,5 @@ "command.debug": "Debug", "command.openScript": "Open", "command.runInstall": "Run Install", - "command.runSelectedScript": "Run Selected Npm Script" + "command.runSelectedScript": "Npm: Run Selected Script" } From be4c7065cc74851c9d7676a940178df93e3add10 Mon Sep 17 00:00:00 2001 From: Erich Gamma Date: Sun, 29 Jul 2018 11:38:22 +0200 Subject: [PATCH 0305/1276] Contribute run selected to the context menu --- extensions/npm/package.json | 11 +++++++++++ extensions/npm/package.nls.json | 2 +- 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/extensions/npm/package.json b/extensions/npm/package.json index 2052b7a8228..b0017b08b49 100644 --- a/extensions/npm/package.json +++ b/extensions/npm/package.json @@ -109,6 +109,17 @@ { "command": "npm.runInstall", "when": "false" + }, + { + "command": "npm.runSelectedScript", + "when": "false" + } + ], + "editor/context": [ + { + "command": "npm.runSelectedScript", + "when": "resourceFilename == 'package.json'", + "group": "navigation@+1" } ], "view/title": [ diff --git a/extensions/npm/package.nls.json b/extensions/npm/package.nls.json index 99f4836fc17..8c27e0ca5bd 100644 --- a/extensions/npm/package.nls.json +++ b/extensions/npm/package.nls.json @@ -17,5 +17,5 @@ "command.debug": "Debug", "command.openScript": "Open", "command.runInstall": "Run Install", - "command.runSelectedScript": "Npm: Run Selected Script" + "command.runSelectedScript": "Run Script" } From e5e0e841ec175c87938ada103950a98a9f241ca1 Mon Sep 17 00:00:00 2001 From: Andre Weinand Date: Sun, 29 Jul 2018 16:51:31 +0200 Subject: [PATCH 0306/1276] node-debug@1.26.6 --- build/builtInExtensions.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build/builtInExtensions.json b/build/builtInExtensions.json index 5c0deaea8b3..bd38e83dcac 100644 --- a/build/builtInExtensions.json +++ b/build/builtInExtensions.json @@ -1,7 +1,7 @@ [ { "name": "ms-vscode.node-debug", - "version": "1.26.5", + "version": "1.26.6", "repo": "https://github.com/Microsoft/vscode-node-debug" }, { From de1e8d7725becdaea09f381aae18f7b6216790a0 Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Sun, 29 Jul 2018 14:32:00 -0700 Subject: [PATCH 0307/1276] Allow terminal rendererType to be swapped out at runtime Part of #53274 Fixes #55344 --- package.json | 2 +- .../terminal/electron-browser/terminal.contribution.ts | 2 +- .../parts/terminal/electron-browser/terminalInstance.ts | 3 ++- yarn.lock | 6 +++--- 4 files changed, 7 insertions(+), 6 deletions(-) diff --git a/package.json b/package.json index c2df6f4f32e..84dcc5c59b2 100644 --- a/package.json +++ b/package.json @@ -50,7 +50,7 @@ "vscode-nsfw": "1.0.17", "vscode-ripgrep": "^1.0.1", "vscode-textmate": "^4.0.1", - "vscode-xterm": "3.6.0-beta7", + "vscode-xterm": "3.6.0-beta11", "yauzl": "^2.9.1" }, "devDependencies": { diff --git a/src/vs/workbench/parts/terminal/electron-browser/terminal.contribution.ts b/src/vs/workbench/parts/terminal/electron-browser/terminal.contribution.ts index 835be4cc86f..4e288255067 100644 --- a/src/vs/workbench/parts/terminal/electron-browser/terminal.contribution.ts +++ b/src/vs/workbench/parts/terminal/electron-browser/terminal.contribution.ts @@ -202,7 +202,7 @@ configurationRegistry.registerConfiguration({ nls.localize('terminal.integrated.rendererType.dom', "Use the fallback DOM-based renderer.") ], default: 'auto', - description: nls.localize('terminal.integrated.rendererType', "Controls how the terminal is rendered. This setting needs VS Code to reload in order to take effect.") + description: nls.localize('terminal.integrated.rendererType', "Controls how the terminal is rendered.") }, 'terminal.integrated.rightClickBehavior': { type: 'string', diff --git a/src/vs/workbench/parts/terminal/electron-browser/terminalInstance.ts b/src/vs/workbench/parts/terminal/electron-browser/terminalInstance.ts index df30323b6a6..42174a7c0ac 100644 --- a/src/vs/workbench/parts/terminal/electron-browser/terminalInstance.ts +++ b/src/vs/workbench/parts/terminal/electron-browser/terminalInstance.ts @@ -481,7 +481,7 @@ export class TerminalInstance implements ITerminalInstance { label: nls.localize('yes', "Yes"), run: () => { this._configurationService.updateValue('terminal.integrated.rendererType', 'dom', ConfigurationTarget.USER).then(() => { - this._notificationService.info(nls.localize('terminal.rendererInAllNewTerminals', "All newly created terminals will use the non-GPU renderer.")); + this._notificationService.info(nls.localize('terminal.rendererInAllNewTerminals', "The termnial is now using the fallback renderer.")); }); } } as IPromptChoice, @@ -884,6 +884,7 @@ export class TerminalInstance implements ITerminalInstance { this._safeSetOption('macOptionIsMeta', config.macOptionIsMeta); this._safeSetOption('macOptionClickForcesSelection', config.macOptionClickForcesSelection); this._safeSetOption('rightClickSelectsWord', config.rightClickBehavior === 'selectWord'); + this._safeSetOption('rendererType', config.rendererType === 'auto' ? 'canvas' : config.rendererType); } public updateAccessibilitySupport(): void { diff --git a/yarn.lock b/yarn.lock index 08bc6f8be19..556d40b5a1f 100644 --- a/yarn.lock +++ b/yarn.lock @@ -6256,9 +6256,9 @@ vscode-textmate@^4.0.1: dependencies: oniguruma "^7.0.0" -vscode-xterm@3.6.0-beta7: - version "3.6.0-beta7" - resolved "https://registry.yarnpkg.com/vscode-xterm/-/vscode-xterm-3.6.0-beta7.tgz#c079061ec43cddc2f952c8075a388c25fb4ca2b0" +vscode-xterm@3.6.0-beta11: + version "3.6.0-beta11" + resolved "https://registry.yarnpkg.com/vscode-xterm/-/vscode-xterm-3.6.0-beta11.tgz#d492ae1baf5cf9884f7b49a4fadc0c354248c830" vso-node-api@^6.1.2-preview: version "6.1.2-preview" From 111a93c1067a56b88e237a8caabda646f9fe8c38 Mon Sep 17 00:00:00 2001 From: Rob Lourens Date: Sat, 28 Jul 2018 21:37:49 -0700 Subject: [PATCH 0308/1276] Settings editor - fix not focusing search when restoring editor setInput must be actually async. Will be fixed naturally when we aren't using winJS promises... --- .../workbench/parts/preferences/browser/settingsEditor2.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/vs/workbench/parts/preferences/browser/settingsEditor2.ts b/src/vs/workbench/parts/preferences/browser/settingsEditor2.ts index 5803a5f97fc..6affe34a687 100644 --- a/src/vs/workbench/parts/preferences/browser/settingsEditor2.ts +++ b/src/vs/workbench/parts/preferences/browser/settingsEditor2.ts @@ -139,8 +139,8 @@ export class SettingsEditor2 extends BaseEditor { this.inSettingsEditorContextKey.set(true); return super.setInput(input, options, token) .then(() => { - this.render(token); - }); + return this.render(token); + }).then(() => new Promise(process.nextTick)); // Force setInput to be async } clearInput(): void { @@ -573,7 +573,7 @@ export class SettingsEditor2 extends BaseEditor { this._register(model.onDidChangeGroups(() => this.onConfigUpdate())); this.defaultSettingsEditorModel = model; - this.onConfigUpdate(); + return this.onConfigUpdate(); }); } return TPromise.as(null); From d41a5ed944ec3c6d810d217f0f58ba15dbb1060b Mon Sep 17 00:00:00 2001 From: Rob Lourens Date: Sun, 29 Jul 2018 11:55:22 -0700 Subject: [PATCH 0309/1276] Settings editor - TOC should only expand the section with a selected item --- src/vs/base/parts/tree/browser/treeUtils.ts | 23 ++++++++++++++++++ .../preferences/browser/settingsEditor2.ts | 24 ++++++++++++------- .../parts/preferences/browser/tocTree.ts | 4 ---- 3 files changed, 38 insertions(+), 13 deletions(-) create mode 100644 src/vs/base/parts/tree/browser/treeUtils.ts diff --git a/src/vs/base/parts/tree/browser/treeUtils.ts b/src/vs/base/parts/tree/browser/treeUtils.ts new file mode 100644 index 00000000000..07e95954552 --- /dev/null +++ b/src/vs/base/parts/tree/browser/treeUtils.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. + *--------------------------------------------------------------------------------------------*/ +'use strict'; + +import * as _ from 'vs/base/parts/tree/browser/tree'; + +export function collapseAll(tree: _.ITree): void { + const nav = tree.getNavigator(); + let cur; + while (cur = nav.next()) { + tree.collapse(cur); + } +} + +export function expandAll(tree: _.ITree): void { + const nav = tree.getNavigator(); + let cur; + while (cur = nav.next()) { + tree.expand(cur); + } +} diff --git a/src/vs/workbench/parts/preferences/browser/settingsEditor2.ts b/src/vs/workbench/parts/preferences/browser/settingsEditor2.ts index 6affe34a687..6da01b54581 100644 --- a/src/vs/workbench/parts/preferences/browser/settingsEditor2.ts +++ b/src/vs/workbench/parts/preferences/browser/settingsEditor2.ts @@ -4,6 +4,7 @@ *--------------------------------------------------------------------------------------------*/ import * as DOM from 'vs/base/browser/dom'; +import { Separator } from 'vs/base/browser/ui/actionbar/actionbar'; import { Button } from 'vs/base/browser/ui/button/button'; import { ToolBar } from 'vs/base/browser/ui/toolbar/toolbar'; import { Action } from 'vs/base/common/actions'; @@ -15,7 +16,8 @@ import { getErrorMessage, isPromiseCanceledError } from 'vs/base/common/errors'; import URI from 'vs/base/common/uri'; import { TPromise } from 'vs/base/common/winjs.base'; import { ITreeConfiguration } from 'vs/base/parts/tree/browser/tree'; -import { OpenMode, DefaultTreestyler } from 'vs/base/parts/tree/browser/treeDefaults'; +import { DefaultTreestyler, OpenMode } from 'vs/base/parts/tree/browser/treeDefaults'; +import { collapseAll, expandAll } from 'vs/base/parts/tree/browser/treeUtils'; import 'vs/css!./media/settingsEditor2'; import { localize } from 'vs/nls'; import { ConfigurationTarget, IConfigurationOverrides, IConfigurationService } from 'vs/platform/configuration/common/configuration'; @@ -26,22 +28,21 @@ import { IInstantiationService } from 'vs/platform/instantiation/common/instanti import { WorkbenchTree, WorkbenchTreeController } from 'vs/platform/list/browser/listService'; import { ILogService } from 'vs/platform/log/common/log'; import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry'; +import { editorBackground, foreground } from 'vs/platform/theme/common/colorRegistry'; import { attachButtonStyler, attachStyler } from 'vs/platform/theme/common/styler'; import { IThemeService } from 'vs/platform/theme/common/themeService'; import { BaseEditor } from 'vs/workbench/browser/parts/editor/baseEditor'; import { EditorOptions, IEditor } from 'vs/workbench/common/editor'; +import { PreferencesEditor } from 'vs/workbench/parts/preferences/browser/preferencesEditor'; import { SearchWidget, SettingsTarget, SettingsTargetsWidget } from 'vs/workbench/parts/preferences/browser/preferencesWidgets'; import { commonlyUsedData, tocData } from 'vs/workbench/parts/preferences/browser/settingsLayout'; -import { ISettingsEditorViewState, resolveExtensionsSettings, resolveSettingsTree, SearchResultIdx, SearchResultModel, SettingsRenderer, SettingsTree, SettingsTreeElement, SettingsTreeFilter, SettingsTreeGroupElement, SettingsTreeModel, SettingsTreeSettingElement, MODIFIED_SETTING_TAG, ONLINE_SERVICES_SETTING_TAG } from 'vs/workbench/parts/preferences/browser/settingsTree'; +import { ISettingsEditorViewState, MODIFIED_SETTING_TAG, ONLINE_SERVICES_SETTING_TAG, resolveExtensionsSettings, resolveSettingsTree, SearchResultIdx, SearchResultModel, SettingsRenderer, SettingsTree, SettingsTreeElement, SettingsTreeFilter, SettingsTreeGroupElement, SettingsTreeModel, SettingsTreeSettingElement } from 'vs/workbench/parts/preferences/browser/settingsTree'; +import { settingsHeaderForeground } from 'vs/workbench/parts/preferences/browser/settingsWidgets'; import { TOCDataSource, TOCRenderer, TOCTreeModel } from 'vs/workbench/parts/preferences/browser/tocTree'; import { CONTEXT_SETTINGS_EDITOR, CONTEXT_SETTINGS_FIRST_ROW_FOCUS, CONTEXT_SETTINGS_ROW_FOCUS, CONTEXT_SETTINGS_SEARCH_FOCUS, CONTEXT_TOC_ROW_FOCUS, IPreferencesSearchService, ISearchProvider } from 'vs/workbench/parts/preferences/common/preferences'; import { IPreferencesService, ISearchResult, ISettingsEditorModel } from 'vs/workbench/services/preferences/common/preferences'; import { SettingsEditor2Input } from 'vs/workbench/services/preferences/common/preferencesEditorInput'; import { DefaultSettingsEditorModel } from 'vs/workbench/services/preferences/common/preferencesModels'; -import { editorBackground, foreground } from 'vs/platform/theme/common/colorRegistry'; -import { settingsHeaderForeground } from 'vs/workbench/parts/preferences/browser/settingsWidgets'; -import { Separator } from 'vs/base/browser/ui/actionbar/actionbar'; -import { PreferencesEditor } from 'vs/workbench/parts/preferences/browser/preferencesEditor'; const $ = DOM.$; @@ -462,11 +463,15 @@ export class SettingsEditor2 extends BaseEditor { null; if (element && this.tocTree.getSelection()[0] !== element) { + this.tocTree.reveal(element); const elementTop = this.tocTree.getRelativeTop(element); + collapseAll(this.tocTree); if (elementTop < 0) { this.tocTree.reveal(element, 0); } else if (elementTop > 1) { this.tocTree.reveal(element, 1); + } else { + this.tocTree.reveal(element, elementTop); } this.tocTree.setSelection([element]); @@ -701,9 +706,8 @@ export class SettingsEditor2 extends BaseEditor { this.viewState.filterToCategory = null; this.tocTree.refresh(); this.toggleSearchMode(); - this.settingsTree.setInput(this.settingsTreeModel.root); - - return TPromise.wrap(null); + collapseAll(this.tocTree); + return this.settingsTree.setInput(this.settingsTreeModel.root); } } @@ -776,6 +780,8 @@ export class SettingsEditor2 extends BaseEditor { } this.tocTreeModel.update(); + expandAll(this.tocTree); + resolve(this.refreshTreeAndMaintainFocus()); }); }, () => { diff --git a/src/vs/workbench/parts/preferences/browser/tocTree.ts b/src/vs/workbench/parts/preferences/browser/tocTree.ts index 4863ba7c612..0d9bf95590c 100644 --- a/src/vs/workbench/parts/preferences/browser/tocTree.ts +++ b/src/vs/workbench/parts/preferences/browser/tocTree.ts @@ -102,10 +102,6 @@ export class TOCDataSource implements IDataSource { getParent(tree: ITree, element: TOCTreeElement): TPromise { return TPromise.wrap(element instanceof SettingsTreeGroupElement && element.parent); } - - shouldAutoexpand() { - return true; - } } const TOC_ENTRY_TEMPLATE_ID = 'settings.toc.entry'; From 0d5ed1e4e776e455829436600435a6df83734f73 Mon Sep 17 00:00:00 2001 From: Rob Lourens Date: Sun, 29 Jul 2018 11:55:31 -0700 Subject: [PATCH 0310/1276] Bump node-debug2 --- build/builtInExtensions.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build/builtInExtensions.json b/build/builtInExtensions.json index bd38e83dcac..a017fbcce91 100644 --- a/build/builtInExtensions.json +++ b/build/builtInExtensions.json @@ -6,7 +6,7 @@ }, { "name": "ms-vscode.node-debug2", - "version": "1.26.6", + "version": "1.26.7", "repo": "https://github.com/Microsoft/vscode-node-debug2" } ] From 09d9e686e8d39f06d3ff9ff4ddd6138f86da44ad Mon Sep 17 00:00:00 2001 From: Rob Lourens Date: Sun, 29 Jul 2018 13:33:20 -0700 Subject: [PATCH 0311/1276] Settings editor - Tree focus outlines --- .../browser/media/settingsEditor2.css | 4 - .../preferences/browser/settingsEditor2.ts | 44 ++--------- .../parts/preferences/browser/settingsTree.ts | 3 + .../parts/preferences/browser/tocTree.ts | 77 ++++++++++++++++++- 4 files changed, 85 insertions(+), 43 deletions(-) diff --git a/src/vs/workbench/parts/preferences/browser/media/settingsEditor2.css b/src/vs/workbench/parts/preferences/browser/media/settingsEditor2.css index a862bb6f49c..76ab4e7c44b 100644 --- a/src/vs/workbench/parts/preferences/browser/media/settingsEditor2.css +++ b/src/vs/workbench/parts/preferences/browser/media/settingsEditor2.css @@ -136,10 +136,6 @@ justify-content: space-between; } -.settings-editor > .settings-body .settings-tree-container .monaco-tree::before { - outline: none !important; -} - .settings-editor.search-mode > .settings-body .settings-tree-container .monaco-tree-wrapper, .settings-editor.search-mode > .settings-body > .settings-tree-container .setting-measure-container { width: calc(100% - 11px); diff --git a/src/vs/workbench/parts/preferences/browser/settingsEditor2.ts b/src/vs/workbench/parts/preferences/browser/settingsEditor2.ts index 6da01b54581..dd029ff93f8 100644 --- a/src/vs/workbench/parts/preferences/browser/settingsEditor2.ts +++ b/src/vs/workbench/parts/preferences/browser/settingsEditor2.ts @@ -15,8 +15,6 @@ import * as collections from 'vs/base/common/collections'; import { getErrorMessage, isPromiseCanceledError } from 'vs/base/common/errors'; import URI from 'vs/base/common/uri'; import { TPromise } from 'vs/base/common/winjs.base'; -import { ITreeConfiguration } from 'vs/base/parts/tree/browser/tree'; -import { DefaultTreestyler, OpenMode } from 'vs/base/parts/tree/browser/treeDefaults'; import { collapseAll, expandAll } from 'vs/base/parts/tree/browser/treeUtils'; import 'vs/css!./media/settingsEditor2'; import { localize } from 'vs/nls'; @@ -25,20 +23,18 @@ import { IContextKey, IContextKeyService } from 'vs/platform/contextkey/common/c import { IContextMenuService } from 'vs/platform/contextview/browser/contextView'; import { IEnvironmentService } from 'vs/platform/environment/common/environment'; import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; -import { WorkbenchTree, WorkbenchTreeController } from 'vs/platform/list/browser/listService'; +import { WorkbenchTree } from 'vs/platform/list/browser/listService'; import { ILogService } from 'vs/platform/log/common/log'; import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry'; -import { editorBackground, foreground } from 'vs/platform/theme/common/colorRegistry'; -import { attachButtonStyler, attachStyler } from 'vs/platform/theme/common/styler'; +import { attachButtonStyler } from 'vs/platform/theme/common/styler'; import { IThemeService } from 'vs/platform/theme/common/themeService'; import { BaseEditor } from 'vs/workbench/browser/parts/editor/baseEditor'; import { EditorOptions, IEditor } from 'vs/workbench/common/editor'; import { PreferencesEditor } from 'vs/workbench/parts/preferences/browser/preferencesEditor'; import { SearchWidget, SettingsTarget, SettingsTargetsWidget } from 'vs/workbench/parts/preferences/browser/preferencesWidgets'; import { commonlyUsedData, tocData } from 'vs/workbench/parts/preferences/browser/settingsLayout'; -import { ISettingsEditorViewState, MODIFIED_SETTING_TAG, ONLINE_SERVICES_SETTING_TAG, resolveExtensionsSettings, resolveSettingsTree, SearchResultIdx, SearchResultModel, SettingsRenderer, SettingsTree, SettingsTreeElement, SettingsTreeFilter, SettingsTreeGroupElement, SettingsTreeModel, SettingsTreeSettingElement } from 'vs/workbench/parts/preferences/browser/settingsTree'; -import { settingsHeaderForeground } from 'vs/workbench/parts/preferences/browser/settingsWidgets'; -import { TOCDataSource, TOCRenderer, TOCTreeModel } from 'vs/workbench/parts/preferences/browser/tocTree'; +import { ISettingsEditorViewState, MODIFIED_SETTING_TAG, ONLINE_SERVICES_SETTING_TAG, resolveExtensionsSettings, resolveSettingsTree, SearchResultIdx, SearchResultModel, SettingsRenderer, SettingsTree, SettingsTreeElement, SettingsTreeGroupElement, SettingsTreeModel, SettingsTreeSettingElement } from 'vs/workbench/parts/preferences/browser/settingsTree'; +import { TOCRenderer, TOCTree, TOCTreeModel } from 'vs/workbench/parts/preferences/browser/tocTree'; import { CONTEXT_SETTINGS_EDITOR, CONTEXT_SETTINGS_FIRST_ROW_FOCUS, CONTEXT_SETTINGS_ROW_FOCUS, CONTEXT_SETTINGS_SEARCH_FOCUS, CONTEXT_TOC_ROW_FOCUS, IPreferencesSearchService, ISearchProvider } from 'vs/workbench/parts/preferences/common/preferences'; import { IPreferencesService, ISearchResult, ISettingsEditorModel } from 'vs/workbench/services/preferences/common/preferences'; import { SettingsEditor2Input } from 'vs/workbench/services/preferences/common/preferencesEditorInput'; @@ -290,40 +286,16 @@ export class SettingsEditor2 extends BaseEditor { } private createTOC(parent: HTMLElement): void { + this.tocTreeModel = new TOCTreeModel(); this.tocTreeContainer = DOM.append(parent, $('.settings-toc-container')); - const tocDataSource = this.instantiationService.createInstance(TOCDataSource); const tocRenderer = this.instantiationService.createInstance(TOCRenderer); - this.tocTreeModel = new TOCTreeModel(); - this.tocTree = this.instantiationService.createInstance(WorkbenchTree, this.tocTreeContainer, - { - dataSource: tocDataSource, - renderer: tocRenderer, - controller: this.instantiationService.createInstance(WorkbenchTreeController, { openMode: OpenMode.DOUBLE_CLICK }), - filter: this.instantiationService.createInstance(SettingsTreeFilter, this.viewState), - styler: new DefaultTreestyler(DOM.createStyleSheet(), 'settings-toc-tree'), - }, + this.tocTree = this.instantiationService.createInstance(TOCTree, this.tocTreeContainer, + this.viewState, { - showLoading: false, - twistiePixels: 15 + renderer: tocRenderer }); - this.tocTree.getHTMLElement().classList.add('settings-toc-tree'); - - this._register(attachStyler(this.themeService, { - listActiveSelectionBackground: editorBackground, - listActiveSelectionForeground: settingsHeaderForeground, - listFocusAndSelectionBackground: editorBackground, - listFocusAndSelectionForeground: settingsHeaderForeground, - listFocusBackground: editorBackground, - listFocusForeground: settingsHeaderForeground, - listHoverForeground: foreground, - listHoverBackground: editorBackground, - listInactiveSelectionBackground: editorBackground, - listInactiveSelectionForeground: settingsHeaderForeground, - }, colors => { - this.tocTree.style(colors); - })); this._register(this.tocTree.onDidChangeFocus(e => { const element = e.focus; diff --git a/src/vs/workbench/parts/preferences/browser/settingsTree.ts b/src/vs/workbench/parts/preferences/browser/settingsTree.ts index 449fcacdad0..913ed12fab2 100644 --- a/src/vs/workbench/parts/preferences/browser/settingsTree.ts +++ b/src/vs/workbench/parts/preferences/browser/settingsTree.ts @@ -1512,6 +1512,9 @@ export class SettingsTree extends NonExpandableTree { const activeBorderColor = theme.getColor(focusBorder); if (activeBorderColor) { collector.addRule(`.settings-editor > .settings-body > .settings-tree-container .monaco-tree:focus .monaco-tree-row.focused {outline: solid 1px ${activeBorderColor}; outline-offset: -1px; }`); + + // TODO@rob - why isn't this applied when added to the stylesheet from tocTree.ts? Seems like a chromium glitch. + collector.addRule(`.settings-editor > .settings-body > .settings-toc-container .monaco-tree:focus .monaco-tree-row.focused {outline: solid 1px ${activeBorderColor}; outline-offset: -1px; }`); } const inactiveBorderColor = theme.getColor(settingItemInactiveSelectionBorder); diff --git a/src/vs/workbench/parts/preferences/browser/tocTree.ts b/src/vs/workbench/parts/preferences/browser/tocTree.ts index 0d9bf95590c..d81dc3bcac6 100644 --- a/src/vs/workbench/parts/preferences/browser/tocTree.ts +++ b/src/vs/workbench/parts/preferences/browser/tocTree.ts @@ -5,10 +5,18 @@ import * as DOM from 'vs/base/browser/dom'; import { TPromise } from 'vs/base/common/winjs.base'; -import { IDataSource, IRenderer, ITree } from 'vs/base/parts/tree/browser/tree'; -import { SearchResultModel, SettingsTreeElement, SettingsTreeGroupElement, SettingsTreeSettingElement } from 'vs/workbench/parts/preferences/browser/settingsTree'; -import { ISetting } from 'vs/workbench/services/preferences/common/preferences'; +import { IDataSource, IRenderer, ITree, ITreeConfiguration } from 'vs/base/parts/tree/browser/tree'; +import { DefaultTreestyler, OpenMode } from 'vs/base/parts/tree/browser/treeDefaults'; import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; +import { IContextKeyService } from 'vs/platform/contextkey/common/contextkey'; +import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; +import { IListService, WorkbenchTree, WorkbenchTreeController } from 'vs/platform/list/browser/listService'; +import { editorBackground, focusBorder, foreground } from 'vs/platform/theme/common/colorRegistry'; +import { attachStyler } from 'vs/platform/theme/common/styler'; +import { ICssStyleCollector, ITheme, IThemeService, registerThemingParticipant } from 'vs/platform/theme/common/themeService'; +import { ISettingsEditorViewState, SearchResultModel, SettingsAccessibilityProvider, SettingsTreeElement, SettingsTreeFilter, SettingsTreeGroupElement, SettingsTreeSettingElement } from 'vs/workbench/parts/preferences/browser/settingsTree'; +import { settingsHeaderForeground } from 'vs/workbench/parts/preferences/browser/settingsWidgets'; +import { ISetting } from 'vs/workbench/services/preferences/common/preferences'; const $ = DOM.$; @@ -137,3 +145,66 @@ export class TOCRenderer implements IRenderer { disposeTemplate(tree: ITree, templateId: string, templateData: any): void { } } + +export class TOCTree extends WorkbenchTree { + constructor( + container: HTMLElement, + viewState: ISettingsEditorViewState, + configuration: Partial, + @IContextKeyService contextKeyService: IContextKeyService, + @IListService listService: IListService, + @IThemeService themeService: IThemeService, + @IInstantiationService instantiationService: IInstantiationService, + @IConfigurationService configurationService: IConfigurationService + ) { + const treeClass = 'settings-toc-tree'; + + const fullConfiguration = { + controller: instantiationService.createInstance(WorkbenchTreeController, { openMode: OpenMode.DOUBLE_CLICK }), + filter: instantiationService.createInstance(SettingsTreeFilter, viewState), + styler: new DefaultTreestyler(DOM.createStyleSheet(), treeClass), + dataSource: instantiationService.createInstance(TOCDataSource), + accessibilityProvider: instantiationService.createInstance(SettingsAccessibilityProvider), + + ...configuration + }; + + const options = { + showLoading: false, + twistiePixels: 15 + }; + + super(container, + fullConfiguration, + options, + contextKeyService, + listService, + themeService, + instantiationService, + configurationService); + + this.disposables.push(registerThemingParticipant((theme: ITheme, collector: ICssStyleCollector) => { + const activeBorderColor = theme.getColor(focusBorder); + if (activeBorderColor) { + collector.addRule(`.settings-editor > .settings-body > .settings-toc-container .monaco-tree:focus .monaco-tree-row.focused { outline-color: ${activeBorderColor}; }`); + } + })); + + this.getHTMLElement().classList.add(treeClass); + + this.disposables.push(attachStyler(themeService, { + listActiveSelectionBackground: editorBackground, + listActiveSelectionForeground: settingsHeaderForeground, + listFocusAndSelectionBackground: editorBackground, + listFocusAndSelectionForeground: settingsHeaderForeground, + listFocusBackground: editorBackground, + listFocusForeground: settingsHeaderForeground, + listHoverForeground: foreground, + listHoverBackground: editorBackground, + listInactiveSelectionBackground: editorBackground, + listInactiveSelectionForeground: settingsHeaderForeground, + }, colors => { + this.style(colors); + })); + } +} From 24168f82ff63a4c506ad9dd307e8d65710c1734f Mon Sep 17 00:00:00 2001 From: Rob Lourens Date: Sun, 29 Jul 2018 14:26:25 -0700 Subject: [PATCH 0312/1276] Settings editor - don't blink the scrollbar when toc selection changes And hide TOC correctly when the editor is narrow --- src/vs/base/parts/tree/browser/treeUtils.ts | 18 ++++++++++++++++-- .../browser/media/settingsEditor2.css | 8 ++++++-- .../preferences/browser/settingsEditor2.ts | 8 +++----- 3 files changed, 25 insertions(+), 9 deletions(-) diff --git a/src/vs/base/parts/tree/browser/treeUtils.ts b/src/vs/base/parts/tree/browser/treeUtils.ts index 07e95954552..7187ca1bd2a 100644 --- a/src/vs/base/parts/tree/browser/treeUtils.ts +++ b/src/vs/base/parts/tree/browser/treeUtils.ts @@ -6,14 +6,28 @@ import * as _ from 'vs/base/parts/tree/browser/tree'; -export function collapseAll(tree: _.ITree): void { +export function collapseAll(tree: _.ITree, except?: any): void { const nav = tree.getNavigator(); let cur; while (cur = nav.next()) { - tree.collapse(cur); + if (!except || !isEqualOrParent(tree, except, cur)) { + tree.collapse(cur); + } } } +export function isEqualOrParent(tree: _.ITree, element: any, candidateParent: any): boolean { + const nav = tree.getNavigator(element); + + do { + if (element === candidateParent) { + return true; + } + } while (element = nav.parent()); + + return false; +} + export function expandAll(tree: _.ITree): void { const nav = tree.getNavigator(); let cur; diff --git a/src/vs/workbench/parts/preferences/browser/media/settingsEditor2.css b/src/vs/workbench/parts/preferences/browser/media/settingsEditor2.css index 76ab4e7c44b..3be8f0ad66d 100644 --- a/src/vs/workbench/parts/preferences/browser/media/settingsEditor2.css +++ b/src/vs/workbench/parts/preferences/browser/media/settingsEditor2.css @@ -133,7 +133,6 @@ display: flex; margin: auto; max-width: 1000px; - justify-content: space-between; } .settings-editor.search-mode > .settings-body .settings-tree-container .monaco-tree-wrapper, @@ -142,6 +141,12 @@ margin-left: 0px; } +.settings-editor.narrow > .settings-body .settings-tree-container .monaco-tree-wrapper, +.settings-editor.narrow > .settings-body > .settings-tree-container .setting-measure-container { + width: calc(100% - 11px); + margin-left: 0px; +} + .settings-editor > .settings-body .settings-tree-container .monaco-tree-wrapper, .settings-editor > .settings-body > .settings-tree-container .setting-measure-container { /** 11px for scrollbar + 208px for TOC margin */ @@ -149,7 +154,6 @@ margin-left: 208px; } - .settings-editor > .settings-body .settings-toc-container { position: absolute; width: 160px; diff --git a/src/vs/workbench/parts/preferences/browser/settingsEditor2.ts b/src/vs/workbench/parts/preferences/browser/settingsEditor2.ts index dd029ff93f8..79fef29f2a4 100644 --- a/src/vs/workbench/parts/preferences/browser/settingsEditor2.ts +++ b/src/vs/workbench/parts/preferences/browser/settingsEditor2.ts @@ -437,11 +437,9 @@ export class SettingsEditor2 extends BaseEditor { if (element && this.tocTree.getSelection()[0] !== element) { this.tocTree.reveal(element); const elementTop = this.tocTree.getRelativeTop(element); - collapseAll(this.tocTree); - if (elementTop < 0) { - this.tocTree.reveal(element, 0); - } else if (elementTop > 1) { - this.tocTree.reveal(element, 1); + collapseAll(this.tocTree, element); + if (elementTop < 0 || elementTop > 1) { + this.tocTree.reveal(element); } else { this.tocTree.reveal(element, elementTop); } From 1f42ef2a98de8f4c27759f0c5203828bb1439c68 Mon Sep 17 00:00:00 2001 From: Rob Lourens Date: Sun, 29 Jul 2018 15:01:18 -0700 Subject: [PATCH 0313/1276] Settings editor - header rows should not be selectable --- .../parts/preferences/browser/settingsTree.ts | 41 +++++++++++++++++++ 1 file changed, 41 insertions(+) diff --git a/src/vs/workbench/parts/preferences/browser/settingsTree.ts b/src/vs/workbench/parts/preferences/browser/settingsTree.ts index 913ed12fab2..a11bf419339 100644 --- a/src/vs/workbench/parts/preferences/browser/settingsTree.ts +++ b/src/vs/workbench/parts/preferences/browser/settingsTree.ts @@ -1553,4 +1553,45 @@ export class SettingsTree extends NonExpandableTree { this.style(colors); })); } + + public setFocus(element?: any, eventPayload?: any): void { + if (element instanceof SettingsTreeGroupElement) { + const nav = this.getNavigator(element, false); + do { + element = nav.next(); + } while (element instanceof SettingsTreeGroupElement); + } + + super.setFocus(element, eventPayload); + } + + public focusNext(count?: number, eventPayload?: any): void { + const focus = this.getFocus(); + if (!focus) { + return super.focusFirst(); + } + + const nav = this.getNavigator(focus, false); + let current; + do { + current = nav.next(); + } while (current instanceof SettingsTreeGroupElement); + + this.setFocus(current, eventPayload); + } + + public focusPrevious(count?: number, eventPayload?: any): void { + const focus = this.getFocus(); + if (!focus) { + return super.focusFirst(); + } + + const nav = this.getNavigator(focus, false); + let current; + do { + current = nav.previous(); + } while (current instanceof SettingsTreeGroupElement); + + this.setFocus(current, eventPayload); + } } From becfc5aa60f0c8bea8557a70a30972467618c8d8 Mon Sep 17 00:00:00 2001 From: SteVen Batten <6561887+sbatten@users.noreply.github.com> Date: Sun, 29 Jul 2018 21:05:17 -0700 Subject: [PATCH 0314/1276] fixes #54877 --- .../browser/parts/titlebar/titlebarPart.ts | 29 ++++++++++++------- 1 file changed, 18 insertions(+), 11 deletions(-) diff --git a/src/vs/workbench/browser/parts/titlebar/titlebarPart.ts b/src/vs/workbench/browser/parts/titlebar/titlebarPart.ts index 3eedcb97500..4fae75a06ea 100644 --- a/src/vs/workbench/browser/parts/titlebar/titlebarPart.ts +++ b/src/vs/workbench/browser/parts/titlebar/titlebarPart.ts @@ -54,6 +54,7 @@ export class TitlebarPart extends Part implements ITitleService { private appIcon: Builder; private menubarPart: MenubarPart; private menubar: Builder; + private resizer: Builder; private pendingTitle: string; private representedFileName: string; @@ -334,12 +335,12 @@ export class TitlebarPart extends Part implements ITitleService { this.windowService.closeWindow().then(null, errors.onUnexpectedError); }); + // Resizer + this.resizer = $(this.titleContainer).div({ class: 'resizer' }); + const isMaximized = this.windowService.getConfiguration().maximized ? true : false; this.onDidChangeMaximized(isMaximized); this.windowService.onDidChangeMaximize(this.onDidChangeMaximized, this); - - // Resizer - $(this.titleContainer).div({ class: 'resizer' }); } // Since the title area is used to drag the window, we do not want to steal focus from the @@ -357,16 +358,22 @@ export class TitlebarPart extends Part implements ITitleService { } private onDidChangeMaximized(maximized: boolean) { - if (!this.maxRestoreControl) { - return; + if (this.maxRestoreControl) { + if (maximized) { + this.maxRestoreControl.removeClass('window-maximize'); + this.maxRestoreControl.addClass('window-unmaximize'); + } else { + this.maxRestoreControl.removeClass('window-unmaximize'); + this.maxRestoreControl.addClass('window-maximize'); + } } - if (maximized) { - this.maxRestoreControl.removeClass('window-maximize'); - this.maxRestoreControl.addClass('window-unmaximize'); - } else { - this.maxRestoreControl.removeClass('window-unmaximize'); - this.maxRestoreControl.addClass('window-maximize'); + if (this.resizer) { + if (maximized) { + this.resizer.hide(); + } else { + this.resizer.show(); + } } } From 8bb091868b7577539356e8290f82d120e316a8e9 Mon Sep 17 00:00:00 2001 From: Andre Weinand Date: Mon, 30 Jul 2018 07:42:15 +0200 Subject: [PATCH 0315/1276] change debug assignee to isi --- .github/classifier.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/classifier.yml b/.github/classifier.yml index c1c067e5c53..a7bcb40c96f 100644 --- a/.github/classifier.yml +++ b/.github/classifier.yml @@ -15,7 +15,7 @@ css-less-scss: [ aeschli ], debug-console: [], debug: { - assignees: [ weinand ], + assignees: [ isidorn ], assignLabel: false }, diff-editor: [], From 5b461e35e4153f615b3a28790d2ffffa8f713be9 Mon Sep 17 00:00:00 2001 From: Alex Dima Date: Mon, 30 Jul 2018 12:35:43 +0200 Subject: [PATCH 0316/1276] Settings sweep (#54690) --- extensions/css-language-features/package.nls.json | 12 ++++++------ extensions/merge-conflict/package.nls.json | 4 ++-- extensions/npm/package.nls.json | 2 +- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/extensions/css-language-features/package.nls.json b/extensions/css-language-features/package.nls.json index ca6e4df4c2c..6686d0e4f21 100644 --- a/extensions/css-language-features/package.nls.json +++ b/extensions/css-language-features/package.nls.json @@ -11,16 +11,16 @@ "css.lint.fontFaceProperties.desc": "`@font-face` rule must define `src` and `font-family` properties", "css.lint.hexColorLength.desc": "Hex colors must consist of three or six hex numbers", "css.lint.idSelector.desc": "Selectors should not contain IDs because these rules are too tightly coupled with the HTML.", - "css.lint.ieHack.desc": "IE hacks are only necessary when supporting IE7 and older", + "css.lint.ieHack.desc": "IE hacks are only necessary when supporting IE7 and older.", "css.lint.important.desc": "Avoid using !important. It is an indication that the specificity of the entire CSS has gotten out of control and needs to be refactored.", - "css.lint.importStatement.desc": "Import statements do not load in parallel", - "css.lint.propertyIgnoredDueToDisplay.desc": "Property is ignored due to the display. E.g. with 'display: inline', the width, height, margin-top, margin-bottom, and float properties have no effect", - "css.lint.universalSelector.desc": "The universal selector (*) is known to be slow", + "css.lint.importStatement.desc": "Import statements do not load in parallel.", + "css.lint.propertyIgnoredDueToDisplay.desc": "Property is ignored due to the display. E.g. with 'display: inline', the width, height, margin-top, margin-bottom, and float properties have no effect.", + "css.lint.universalSelector.desc": "The universal selector (*) is known to be slow.", "css.lint.unknownAtRules.desc": "Unknown at-rule.", "css.lint.unknownProperties.desc": "Unknown property.", "css.lint.unknownVendorSpecificProperties.desc": "Unknown vendor specific property.", - "css.lint.vendorPrefix.desc": "When using a vendor-specific prefix also include the standard property", - "css.lint.zeroUnits.desc": "No unit for zero needed", + "css.lint.vendorPrefix.desc": "When using a vendor-specific prefix also include the standard property.", + "css.lint.zeroUnits.desc": "No unit for zero needed.", "css.trace.server.desc": "Traces the communication between VS Code and the CSS language server.", "css.validate.title": "Controls CSS validation and problem severities.", "css.validate.desc": "Enables or disables all validations", diff --git a/extensions/merge-conflict/package.nls.json b/extensions/merge-conflict/package.nls.json index 66076bd7a87..ed7430674cb 100644 --- a/extensions/merge-conflict/package.nls.json +++ b/extensions/merge-conflict/package.nls.json @@ -13,6 +13,6 @@ "command.previous": "Previous Conflict", "command.compare": "Compare Current Conflict", "config.title": "Merge Conflict", - "config.codeLensEnabled": "Enable/disable merge conflict block CodeLens within editor", - "config.decoratorsEnabled": "Enable/disable merge conflict decorators within editor" + "config.codeLensEnabled": "Create a Code Lens for merge conflict blocks within editor.", + "config.decoratorsEnabled": "Create decorators for merge conflict blocks within editor." } \ No newline at end of file diff --git a/extensions/npm/package.nls.json b/extensions/npm/package.nls.json index 8c27e0ca5bd..7bdfed8e973 100644 --- a/extensions/npm/package.nls.json +++ b/extensions/npm/package.nls.json @@ -1,7 +1,7 @@ { "description": "Extension to add task support for npm scripts.", "displayName": "Npm support for VS Code", - "config.npm.autoDetect": "Controls whether auto detection of npm scripts is on or off. Default is on.", + "config.npm.autoDetect": "Controls whether npm scripts should be automatically detected.", "config.npm.runSilent": "Run npm commands with the `--silent` option.", "config.npm.packageManager": "The package manager used to run scripts.", "config.npm.exclude": "Configure glob patterns for folders that should be excluded from automatic script detection.", From c517d23109c1a931393fd54e0c7243ba868ff221 Mon Sep 17 00:00:00 2001 From: Martin Aeschlimann Date: Mon, 30 Jul 2018 15:28:29 +0200 Subject: [PATCH 0317/1276] workaround for #55051 --- .../services/textfile/common/textFileEditorModel.ts | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/vs/workbench/services/textfile/common/textFileEditorModel.ts b/src/vs/workbench/services/textfile/common/textFileEditorModel.ts index dbf27ba83f8..41e23fc9981 100644 --- a/src/vs/workbench/services/textfile/common/textFileEditorModel.ts +++ b/src/vs/workbench/services/textfile/common/textFileEditorModel.ts @@ -754,6 +754,12 @@ export class TextFileEditorModel extends BaseTextEditorModel implements ITextFil // Emit File Saved Event this._onDidStateChange.fire(StateChange.SAVED); }, error => { + if (!FileOperationError.isFileOperationError(error)) { + // TODO@ben, workaround issue #55051 + this.logService.error(`doSave(${versionId}) - Unexpected error type ${error}`, this.resource); + return; + } + this.logService.error(`doSave(${versionId}) - exit - resulted in a save error: ${error.toString()}`, this.resource); // Flag as error state in the model From 0e391952795c79bf6281911e174cb1f5883f68e4 Mon Sep 17 00:00:00 2001 From: Christof Marti Date: Mon, 30 Jul 2018 15:31:03 +0200 Subject: [PATCH 0318/1276] Settings sweep (#54690) --- .../css-language-features/package.nls.json | 90 +++++++++---------- src/vs/workbench/parts/debug/common/debug.ts | 2 +- .../electron-browser/debug.contribution.ts | 12 +-- 3 files changed, 52 insertions(+), 52 deletions(-) diff --git a/extensions/css-language-features/package.nls.json b/extensions/css-language-features/package.nls.json index 6686d0e4f21..9cb867c43aa 100644 --- a/extensions/css-language-features/package.nls.json +++ b/extensions/css-language-features/package.nls.json @@ -2,20 +2,20 @@ "displayName": "CSS Language Features", "description": "Provides rich language support for CSS, LESS and SCSS files.", "css.title": "CSS", - "css.lint.argumentsInColorFunction.desc": "Invalid number of parameters", - "css.lint.boxModel.desc": "Do not use width or height when using padding or border", - "css.lint.compatibleVendorPrefixes.desc": "When using a vendor-specific prefix make sure to also include all other vendor-specific properties", - "css.lint.duplicateProperties.desc": "Do not use duplicate style definitions", - "css.lint.emptyRules.desc": "Do not use empty rulesets", - "css.lint.float.desc": "Avoid using 'float'. Floats lead to fragile CSS that is easy to break if one aspect of the layout changes.", - "css.lint.fontFaceProperties.desc": "`@font-face` rule must define `src` and `font-family` properties", - "css.lint.hexColorLength.desc": "Hex colors must consist of three or six hex numbers", + "css.lint.argumentsInColorFunction.desc": "Invalid number of parameters.", + "css.lint.boxModel.desc": "Do not use `width` or `height` when using `padding` or `border`.", + "css.lint.compatibleVendorPrefixes.desc": "When using a vendor-specific prefix make sure to also include all other vendor-specific properties.", + "css.lint.duplicateProperties.desc": "Do not use duplicate style definitions.", + "css.lint.emptyRules.desc": "Do not use empty rulesets.", + "css.lint.float.desc": "Avoid using `float`. Floats lead to fragile CSS that is easy to break if one aspect of the layout changes.", + "css.lint.fontFaceProperties.desc": "`@font-face` rule must define `src` and `font-family` properties.", + "css.lint.hexColorLength.desc": "Hex colors must consist of three or six hex numbers.", "css.lint.idSelector.desc": "Selectors should not contain IDs because these rules are too tightly coupled with the HTML.", "css.lint.ieHack.desc": "IE hacks are only necessary when supporting IE7 and older.", - "css.lint.important.desc": "Avoid using !important. It is an indication that the specificity of the entire CSS has gotten out of control and needs to be refactored.", + "css.lint.important.desc": "Avoid using `!important`. It is an indication that the specificity of the entire CSS has gotten out of control and needs to be refactored.", "css.lint.importStatement.desc": "Import statements do not load in parallel.", - "css.lint.propertyIgnoredDueToDisplay.desc": "Property is ignored due to the display. E.g. with 'display: inline', the width, height, margin-top, margin-bottom, and float properties have no effect.", - "css.lint.universalSelector.desc": "The universal selector (*) is known to be slow.", + "css.lint.propertyIgnoredDueToDisplay.desc": "Property is ignored due to the display. E.g. with `display: inline`, the `width`, `height`, `margin-top`, `margin-bottom`, and `float` properties have no effect.", + "css.lint.universalSelector.desc": "The universal selector (`*`) is known to be slow.", "css.lint.unknownAtRules.desc": "Unknown at-rule.", "css.lint.unknownProperties.desc": "Unknown property.", "css.lint.unknownVendorSpecificProperties.desc": "Unknown vendor specific property.", @@ -23,52 +23,52 @@ "css.lint.zeroUnits.desc": "No unit for zero needed.", "css.trace.server.desc": "Traces the communication between VS Code and the CSS language server.", "css.validate.title": "Controls CSS validation and problem severities.", - "css.validate.desc": "Enables or disables all validations", + "css.validate.desc": "Enables or disables all validations.", "less.title": "LESS", - "less.lint.argumentsInColorFunction.desc": "Invalid number of parameters", - "less.lint.boxModel.desc": "Do not use width or height when using padding or border", - "less.lint.compatibleVendorPrefixes.desc": "When using a vendor-specific prefix make sure to also include all other vendor-specific properties", - "less.lint.duplicateProperties.desc": "Do not use duplicate style definitions", - "less.lint.emptyRules.desc": "Do not use empty rulesets", - "less.lint.float.desc": "Avoid using 'float'. Floats lead to fragile CSS that is easy to break if one aspect of the layout changes.", - "less.lint.fontFaceProperties.desc": "`@font-face` rule must define `src` and `font-family` properties", - "less.lint.hexColorLength.desc": "Hex colors must consist of three or six hex numbers", + "less.lint.argumentsInColorFunction.desc": "Invalid number of parameters.", + "less.lint.boxModel.desc": "Do not use `width` or `height` when using `padding` or `border`.", + "less.lint.compatibleVendorPrefixes.desc": "When using a vendor-specific prefix make sure to also include all other vendor-specific properties.", + "less.lint.duplicateProperties.desc": "Do not use duplicate style definitions.", + "less.lint.emptyRules.desc": "Do not use empty rulesets.", + "less.lint.float.desc": "Avoid using `float`. Floats lead to fragile CSS that is easy to break if one aspect of the layout changes.", + "less.lint.fontFaceProperties.desc": "`@font-face` rule must define `src` and `font-family` properties.", + "less.lint.hexColorLength.desc": "Hex colors must consist of three or six hex numbers.", "less.lint.idSelector.desc": "Selectors should not contain IDs because these rules are too tightly coupled with the HTML.", - "less.lint.ieHack.desc": "IE hacks are only necessary when supporting IE7 and older", + "less.lint.ieHack.desc": "IE hacks are only necessary when supporting IE7 and older.", "less.lint.important.desc": "Avoid using !important. It is an indication that the specificity of the entire CSS has gotten out of control and needs to be refactored.", - "less.lint.importStatement.desc": "Import statements do not load in parallel", - "less.lint.propertyIgnoredDueToDisplay.desc": "Property is ignored due to the display. E.g. with 'display: inline', the width, height, margin-top, margin-bottom, and float properties have no effect", - "less.lint.universalSelector.desc": "The universal selector (*) is known to be slow", + "less.lint.importStatement.desc": "Import statements do not load in parallel.", + "less.lint.propertyIgnoredDueToDisplay.desc": "Property is ignored due to the display. E.g. with `display: inline`, the `width`, `height`, `margin-top`, `margin-bottom`, and `float` properties have no effect.", + "less.lint.universalSelector.desc": "The universal selector (`*`) is known to be slow.", "less.lint.unknownProperties.desc": "Unknown property.", "less.lint.unknownVendorSpecificProperties.desc": "Unknown vendor specific property.", - "less.lint.vendorPrefix.desc": "When using a vendor-specific prefix also include the standard property", - "less.lint.zeroUnits.desc": "No unit for zero needed", + "less.lint.vendorPrefix.desc": "When using a vendor-specific prefix also include the standard property.", + "less.lint.zeroUnits.desc": "No unit for zero needed.", "less.validate.title": "Controls LESS validation and problem severities.", - "less.validate.desc": "Enables or disables all validations", + "less.validate.desc": "Enables or disables all validations.", "scss.title": "SCSS (Sass)", - "scss.lint.argumentsInColorFunction.desc": "Invalid number of parameters", - "scss.lint.boxModel.desc": "Do not use width or height when using padding or border", - "scss.lint.compatibleVendorPrefixes.desc": "When using a vendor-specific prefix make sure to also include all other vendor-specific properties", - "scss.lint.duplicateProperties.desc": "Do not use duplicate style definitions", - "scss.lint.emptyRules.desc": "Do not use empty rulesets", - "scss.lint.float.desc": "Avoid using 'float'. Floats lead to fragile CSS that is easy to break if one aspect of the layout changes.", - "scss.lint.fontFaceProperties.desc": "`@font-face` rule must define `src` and `font-family` properties", - "scss.lint.hexColorLength.desc": "Hex colors must consist of three or six hex numbers", + "scss.lint.argumentsInColorFunction.desc": "Invalid number of parameters.", + "scss.lint.boxModel.desc": "Do not use `width` or `height` when using `padding` or `border`.", + "scss.lint.compatibleVendorPrefixes.desc": "When using a vendor-specific prefix make sure to also include all other vendor-specific properties.", + "scss.lint.duplicateProperties.desc": "Do not use duplicate style definitions.", + "scss.lint.emptyRules.desc": "Do not use empty rulesets.", + "scss.lint.float.desc": "Avoid using `float`. Floats lead to fragile CSS that is easy to break if one aspect of the layout changes.", + "scss.lint.fontFaceProperties.desc": "`@font-face` rule must define `src` and `font-family` properties.", + "scss.lint.hexColorLength.desc": "Hex colors must consist of three or six hex numbers.", "scss.lint.idSelector.desc": "Selectors should not contain IDs because these rules are too tightly coupled with the HTML.", - "scss.lint.ieHack.desc": "IE hacks are only necessary when supporting IE7 and older", + "scss.lint.ieHack.desc": "IE hacks are only necessary when supporting IE7 and older.", "scss.lint.important.desc": "Avoid using !important. It is an indication that the specificity of the entire CSS has gotten out of control and needs to be refactored.", - "scss.lint.importStatement.desc": "Import statements do not load in parallel", - "scss.lint.propertyIgnoredDueToDisplay.desc": "Property is ignored due to the display. E.g. with 'display: inline', the width, height, margin-top, margin-bottom, and float properties have no effect", - "scss.lint.universalSelector.desc": "The universal selector (*) is known to be slow", + "scss.lint.importStatement.desc": "Import statements do not load in parallel.", + "scss.lint.propertyIgnoredDueToDisplay.desc": "Property is ignored due to the display. E.g. with `display: inline`, the `width`, `height`, `margin-top`, `margin-bottom`, and `float` properties have no effect.", + "scss.lint.universalSelector.desc": "The universal selector (`*`) is known to be slow.", "scss.lint.unknownProperties.desc": "Unknown property.", "scss.lint.unknownVendorSpecificProperties.desc": "Unknown vendor specific property.", - "scss.lint.vendorPrefix.desc": "When using a vendor-specific prefix also include the standard property", - "scss.lint.zeroUnits.desc": "No unit for zero needed", + "scss.lint.vendorPrefix.desc": "When using a vendor-specific prefix also include the standard property.", + "scss.lint.zeroUnits.desc": "No unit for zero needed.", "scss.validate.title": "Controls SCSS validation and problem severities.", - "scss.validate.desc": "Enables or disables all validations", - "less.colorDecorators.enable.desc": "Enables or disables color decorators", - "scss.colorDecorators.enable.desc": "Enables or disables color decorators", - "css.colorDecorators.enable.desc": "Enables or disables color decorators", + "scss.validate.desc": "Enables or disables all validations.", + "less.colorDecorators.enable.desc": "Enables or disables color decorators.", + "scss.colorDecorators.enable.desc": "Enables or disables color decorators.", + "css.colorDecorators.enable.desc": "Enables or disables color decorators.", "css.colorDecorators.enable.deprecationMessage": "The setting `css.colorDecorators.enable` has been deprecated in favor of `editor.colorDecorators`.", "scss.colorDecorators.enable.deprecationMessage": "The setting `scss.colorDecorators.enable` has been deprecated in favor of `editor.colorDecorators`.", "less.colorDecorators.enable.deprecationMessage": "The setting `less.colorDecorators.enable` has been deprecated in favor of `editor.colorDecorators`." diff --git a/src/vs/workbench/parts/debug/common/debug.ts b/src/vs/workbench/parts/debug/common/debug.ts index 8db643264cd..3ddd5867504 100644 --- a/src/vs/workbench/parts/debug/common/debug.ts +++ b/src/vs/workbench/parts/debug/common/debug.ts @@ -55,7 +55,7 @@ export const DEBUG_SCHEME = 'debug'; export const INTERNAL_CONSOLE_OPTIONS_SCHEMA = { enum: ['neverOpen', 'openOnSessionStart', 'openOnFirstSessionStart'], default: 'openOnFirstSessionStart', - description: nls.localize('internalConsoleOptions', "Controls behavior of the internal debug console.") + description: nls.localize('internalConsoleOptions', "Controls when the internal debug console should open.") }; // raw diff --git a/src/vs/workbench/parts/debug/electron-browser/debug.contribution.ts b/src/vs/workbench/parts/debug/electron-browser/debug.contribution.ts index 398a15c9a86..6ac7e091834 100644 --- a/src/vs/workbench/parts/debug/electron-browser/debug.contribution.ts +++ b/src/vs/workbench/parts/debug/electron-browser/debug.contribution.ts @@ -178,17 +178,17 @@ configurationRegistry.registerConfiguration({ properties: { 'debug.allowBreakpointsEverywhere': { type: 'boolean', - description: nls.localize({ comment: ['This is the description for a setting'], key: 'allowBreakpointsEverywhere' }, "Allows setting breakpoint in any file"), + description: nls.localize({ comment: ['This is the description for a setting'], key: 'allowBreakpointsEverywhere' }, "Allow setting breakpoints in any file."), default: false }, 'debug.openExplorerOnEnd': { type: 'boolean', - description: nls.localize({ comment: ['This is the description for a setting'], key: 'openExplorerOnEnd' }, "Automatically open explorer view on the end of a debug session"), + description: nls.localize({ comment: ['This is the description for a setting'], key: 'openExplorerOnEnd' }, "Automatically open the explorer view at the end of a debug session"), default: false }, 'debug.inlineValues': { type: 'boolean', - description: nls.localize({ comment: ['This is the description for a setting'], key: 'inlineValues' }, "Show variable values inline in editor while debugging"), + description: nls.localize({ comment: ['This is the description for a setting'], key: 'inlineValues' }, "Show variable values inline in editor while debugging."), default: false }, 'debug.toolBarLocation': { @@ -199,18 +199,18 @@ configurationRegistry.registerConfiguration({ 'debug.showInStatusBar': { enum: ['never', 'always', 'onFirstSessionStart'], enumDescriptions: [nls.localize('never', "Never show debug in status bar"), nls.localize('always', "Always show debug in status bar"), nls.localize('onFirstSessionStart', "Show debug in status bar only after debug was started for the first time")], - description: nls.localize({ comment: ['This is the description for a setting'], key: 'showInStatusBar' }, "Controls when the debug status bar should be visible"), + description: nls.localize({ comment: ['This is the description for a setting'], key: 'showInStatusBar' }, "Controls when the debug status bar should be visible."), default: 'onFirstSessionStart' }, 'debug.internalConsoleOptions': INTERNAL_CONSOLE_OPTIONS_SCHEMA, 'debug.openDebug': { enum: ['neverOpen', 'openOnSessionStart', 'openOnFirstSessionStart', 'openOnDebugBreak'], default: 'openOnFirstSessionStart', - description: nls.localize('openDebug', "Controls whether debug view should be open on debugging session start.") + description: nls.localize('openDebug', "Controls when the debug view should open.") }, 'debug.enableAllHovers': { type: 'boolean', - description: nls.localize({ comment: ['This is the description for a setting'], key: 'enableAllHovers' }, "Controls if the non debug hovers should be enabled while debugging. If true the hover providers will be called to provide a hover. Regular hovers will not be shown even if this setting is true."), + description: nls.localize({ comment: ['This is the description for a setting'], key: 'enableAllHovers' }, "Controls whether the non-debug hovers should be enabled while debugging. When enabled the hover providers will be called to provide a hover. Regular hovers will not be shown even if this setting is enabled."), default: false }, 'launch': { From 890d482de05208211c83d910b0757de389c916bc Mon Sep 17 00:00:00 2001 From: Martin Aeschlimann Date: Mon, 30 Jul 2018 16:52:55 +0200 Subject: [PATCH 0319/1276] revive path urls --- src/vs/platform/windows/common/windows.ts | 33 ++++++++++++++++--- src/vs/platform/windows/common/windowsIpc.ts | 1 + src/vs/workbench/electron-browser/main.ts | 34 ++++++++++++++++++-- src/vs/workbench/electron-browser/window.ts | 8 ++--- 4 files changed, 64 insertions(+), 12 deletions(-) diff --git a/src/vs/platform/windows/common/windows.ts b/src/vs/platform/windows/common/windows.ts index 5f69dac4613..5a5dd0c6fdf 100644 --- a/src/vs/platform/windows/common/windows.ts +++ b/src/vs/platform/windows/common/windows.ts @@ -309,11 +309,28 @@ export interface IPathsToWaitFor { waitMarkerFilePath: string; } +export interface IPathData { + + // the file path to open within a Code instance + fileUri?: UriComponents; + + // the line number in the file path to open + lineNumber?: number; + + // the column number in the file path to open + columnNumber?: number; +} + +export interface IPathsToWaitForData { + paths: IPathData[]; + waitMarkerFilePath: string; +} + export interface IOpenFileRequest { - filesToOpen?: IPath[]; - filesToCreate?: IPath[]; - filesToDiff?: IPath[]; - filesToWait?: IPathsToWaitFor; + filesToOpen?: IPathData[]; + filesToCreate?: IPathData[]; + filesToDiff?: IPathData[]; + filesToWait?: IPathsToWaitForData; termProgram?: string; } @@ -321,7 +338,7 @@ export interface IAddFoldersRequest { foldersToAdd: UriComponents[]; } -export interface IWindowConfiguration extends ParsedArgs, IOpenFileRequest { +export interface IWindowConfiguration extends ParsedArgs { machineId: string; windowId: number; logLevel: LogLevel; @@ -351,6 +368,12 @@ export interface IWindowConfiguration extends ParsedArgs, IOpenFileRequest { perfStartTime?: number; perfAppReady?: number; perfWindowLoadTime?: number; + + filesToOpen?: IPath[]; + filesToCreate?: IPath[]; + filesToDiff?: IPath[]; + filesToWait?: IPathsToWaitFor; + termProgram?: string; } export interface IRunActionInWindowRequest { diff --git a/src/vs/platform/windows/common/windowsIpc.ts b/src/vs/platform/windows/common/windowsIpc.ts index 05912a7c133..30f4085be7d 100644 --- a/src/vs/platform/windows/common/windowsIpc.ts +++ b/src/vs/platform/windows/common/windowsIpc.ts @@ -278,6 +278,7 @@ export class WindowsChannelClient implements IWindowsService { return this.channel.call('getRecentlyOpened', windowId) .then(recentlyOpened => { recentlyOpened.workspaces = recentlyOpened.workspaces.map(workspace => isWorkspaceIdentifier(workspace) ? workspace : URI.revive(workspace)); + recentlyOpened.files = recentlyOpened.files.map(URI.revive); return recentlyOpened; }); } diff --git a/src/vs/workbench/electron-browser/main.ts b/src/vs/workbench/electron-browser/main.ts index 05c7a8a054e..fb2f9584086 100644 --- a/src/vs/workbench/electron-browser/main.ts +++ b/src/vs/workbench/electron-browser/main.ts @@ -15,7 +15,7 @@ import * as errors from 'vs/base/common/errors'; import * as comparer from 'vs/base/common/comparers'; import * as platform from 'vs/base/common/platform'; import * as paths from 'vs/base/common/paths'; -import uri from 'vs/base/common/uri'; +import uri, { UriComponents } from 'vs/base/common/uri'; import * as strings from 'vs/base/common/strings'; import { IWorkspaceContextService, Workspace, WorkbenchState } from 'vs/platform/workspace/common/workspace'; import { WorkspaceService } from 'vs/workbench/services/configuration/node/configurationService'; @@ -55,6 +55,8 @@ gracefulFs.gracefulify(fs); // enable gracefulFs export function startup(configuration: IWindowConfiguration): TPromise { + revive(configuration); + // Ensure others can listen to zoom level changes browser.setZoomFactor(webFrame.getZoomFactor()); @@ -75,6 +77,33 @@ export function startup(configuration: IWindowConfiguration): TPromise { return openWorkbench(configuration); } +function revive(workbench: IWindowConfiguration) { + if (workbench.folderUri) { + workbench.folderUri = uri.revive(workbench.folderUri); + } + function reviveFileUri(path: { fileUri?: UriComponents }) { + if (path.fileUri) { + path.fileUri = uri.revive(path.fileUri); + } + } + const filesToOpen = workbench.filesToOpen; + if (Array.isArray(filesToOpen)) { + filesToOpen.forEach(reviveFileUri); + } + const filesToCreate = workbench.filesToCreate; + if (Array.isArray(filesToCreate)) { + filesToCreate.forEach(reviveFileUri); + } + const filesToDiff = workbench.filesToDiff; + if (Array.isArray(filesToDiff)) { + filesToDiff.forEach(reviveFileUri); + } + const filesToWait = workbench.filesToWait; + if (filesToWait && Array.isArray(filesToWait.paths)) { + filesToWait.paths.forEach(reviveFileUri); + } +} + function openWorkbench(configuration: IWindowConfiguration): TPromise { const mainProcessClient = new ElectronIPCClient(`window:${configuration.windowId}`); const mainServices = createMainProcessServices(mainProcessClient, configuration); @@ -116,8 +145,7 @@ function openWorkbench(configuration: IWindowConfiguration): TPromise { } function createAndInitializeWorkspaceService(configuration: IWindowConfiguration, environmentService: EnvironmentService): TPromise { - const folderUri = configuration.folderUri ? uri.revive(configuration.folderUri) : null; - return validateFolderUri(folderUri, configuration.verbose).then(validatedFolderUri => { + return validateFolderUri(configuration.folderUri, configuration.verbose).then(validatedFolderUri => { const workspaceService = new WorkspaceService(environmentService); diff --git a/src/vs/workbench/electron-browser/window.ts b/src/vs/workbench/electron-browser/window.ts index b6dc2cbc7d1..6cfbb1235b9 100644 --- a/src/vs/workbench/electron-browser/window.ts +++ b/src/vs/workbench/electron-browser/window.ts @@ -18,7 +18,7 @@ import { toResource, IUntitledResourceInput } from 'vs/workbench/common/editor'; import { IEditorService, IResourceEditor } from 'vs/workbench/services/editor/common/editorService'; import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry'; import { IWorkspaceConfigurationService } from 'vs/workbench/services/configuration/common/configuration'; -import { IWindowsService, IWindowService, IWindowSettings, IPath, IOpenFileRequest, IWindowsConfiguration, IAddFoldersRequest, IRunActionInWindowRequest } from 'vs/platform/windows/common/windows'; +import { IWindowsService, IWindowService, IWindowSettings, IOpenFileRequest, IWindowsConfiguration, IAddFoldersRequest, IRunActionInWindowRequest, IPathData } from 'vs/platform/windows/common/windows'; import { IContextMenuService } from 'vs/platform/contextview/browser/contextView'; import { ITitleService } from 'vs/workbench/services/title/common/titleService'; import { IWorkbenchThemeService, VS_HC_THEME, VS_DARK_THEME } from 'vs/workbench/services/themes/common/workbenchThemeService'; @@ -401,7 +401,7 @@ export class ElectronWindow extends Themable { // In wait mode, listen to changes to the editors and wait until the files // are closed that the user wants to wait for. When this happens we delete // the wait marker file to signal to the outside that editing is done. - const resourcesToWaitFor = request.filesToWait.paths.map(p => p.fileUri); + const resourcesToWaitFor = request.filesToWait.paths.map(p => URI.revive(p.fileUri)); const waitMarkerFile = URI.file(request.filesToWait.waitMarkerFilePath); const unbind = this.editorService.onDidCloseEditor(() => { if (resourcesToWaitFor.every(resource => !this.editorService.isOpen({ resource }))) { @@ -430,9 +430,9 @@ export class ElectronWindow extends Themable { }); } - private toInputs(paths: IPath[], isNew: boolean): IResourceEditor[] { + private toInputs(paths: IPathData[], isNew: boolean): IResourceEditor[] { return paths.map(p => { - const resource = p.fileUri; + const resource = URI.revive(p.fileUri); let input: IResourceInput | IUntitledResourceInput; if (isNew) { input = { filePath: resource.fsPath, options: { pinned: true } } as IUntitledResourceInput; From 55dfcd730eb94e702140496be5d546811de9fd61 Mon Sep 17 00:00:00 2001 From: isidor Date: Mon, 30 Jul 2018 16:53:05 +0200 Subject: [PATCH 0320/1276] settings sweep #54690 --- .../package.nls.json | 16 ++++++------ .../electron-browser/main.contribution.ts | 26 +++++++++---------- .../electron-browser/search.contribution.ts | 6 ++--- 3 files changed, 24 insertions(+), 24 deletions(-) diff --git a/extensions/typescript-language-features/package.nls.json b/extensions/typescript-language-features/package.nls.json index 918366a21ca..4015ea739b0 100644 --- a/extensions/typescript-language-features/package.nls.json +++ b/extensions/typescript-language-features/package.nls.json @@ -33,11 +33,11 @@ "javascript.referencesCodeLens.enabled": "Enable/disable references CodeLens in JavaScript files.", "typescript.referencesCodeLens.enabled": "Enable/disable references CodeLens in TypeScript files.", "typescript.implementationsCodeLens.enabled": "Enable/disable implementations CodeLens.", - "typescript.openTsServerLog.title": "Open TS Server log", - "typescript.restartTsServer": "Restart TS server", - "typescript.selectTypeScriptVersion.title": "Select TypeScript Version", - "typescript.reportStyleChecksAsWarnings": "Report style checks as warnings", - "jsDocCompletion.enabled": "Enable/disable auto JSDoc comments", + "typescript.openTsServerLog.title": "Open TS Server log.", + "typescript.restartTsServer": "Restart TS server.", + "typescript.selectTypeScriptVersion.title": "Select TypeScript Version.", + "typescript.reportStyleChecksAsWarnings": "Report style checks as warnings.", + "jsDocCompletion.enabled": "Enable/disable auto JSDoc comments.", "javascript.implicitProjectConfig.checkJs": "Enable/disable semantic checking of JavaScript files. Existing jsconfig.json or tsconfig.json files override this setting. Requires using TypeScript 2.3.1 or newer in the workspace.", "typescript.npm": "Specifies the path to the NPM executable used for Automatic Type Acquisition. Requires using TypeScript 2.3.4 or newer in the workspace.", "typescript.check.npmIsInstalled": "Check if NPM is installed for Automatic Type Acquisition.", @@ -50,13 +50,13 @@ "typescript.problemMatchers.tsc.label": "TypeScript problems", "typescript.problemMatchers.tscWatch.label": "TypeScript problems (watch mode)", "typescript.quickSuggestionsForPaths": "Enable/disable quick suggestions when typing out an import path.", - "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.", + "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.", "typescript.autoImportSuggestions.enabled": "Enable/disable auto import suggestions. Requires using TypeScript 2.6.1 or newer in the workspace.", "taskDefinition.tsconfig.description": "The tsconfig file that defines the TS build.", "javascript.suggestionActions.enabled": "Enable/disable suggestion diagnostics for JavaScript files in the editor. Requires using TypeScript 2.8 or newer in the workspace.", "typescript.suggestionActions.enabled": "Enable/disable suggestion diagnostics for TypeScript files in the editor. Requires using TypeScript 2.8 or newer in the workspace.", - "typescript.preferences.quoteStyle": "Preferred quote style to use for quick fixes: 'single' quotes, 'double' quotes, or 'auto' infer quote type from existing imports. Requires using TypeScript 2.9 or newer in the workspace.", + "typescript.preferences.quoteStyle": "Preferred quote style to use for quick fixes: `single` quotes, `double` quotes, or `auto` infer quote type from existing imports. Requires using TypeScript 2.9 or newer in the workspace.", "typescript.preferences.importModuleSpecifier": "Preferred path style for auto imports.", "typescript.preferences.importModuleSpecifier.auto": "Infer the shortest path type.", "typescript.preferences.importModuleSpecifier.relative": "Relative to the file location.", @@ -66,4 +66,4 @@ "typescript.updateImportsOnFileMove.enabled.always": "Always update paths automatically.", "typescript.updateImportsOnFileMove.enabled.never": "Never rename paths and don't prompt.", "typescript.autoClosingTags": "Enable/disable automatic closing of JSX tags. Requires using TypeScript 3.0 or newer in the workspace." -} \ No newline at end of file +} diff --git a/src/vs/workbench/electron-browser/main.contribution.ts b/src/vs/workbench/electron-browser/main.contribution.ts index e2bf1cb5113..7c71735efb9 100644 --- a/src/vs/workbench/electron-browser/main.contribution.ts +++ b/src/vs/workbench/electron-browser/main.contribution.ts @@ -519,41 +519,41 @@ configurationRegistry.registerConfiguration({ 'type': 'string', 'enum': ['on', 'off', 'default'], 'enumDescriptions': [ - nls.localize('window.openFilesInNewWindow.on', "Files will open in a new window"), - nls.localize('window.openFilesInNewWindow.off', "Files will open in the window with the files' folder open or the last active window"), + nls.localize('window.openFilesInNewWindow.on', "Files will open in a new window."), + nls.localize('window.openFilesInNewWindow.off', "Files will open in the window with the files' folder open or the last active window."), isMacintosh ? - nls.localize('window.openFilesInNewWindow.defaultMac', "Files will open in the window with the files' folder open or the last active window unless opened via the Dock or from Finder") : - nls.localize('window.openFilesInNewWindow.default', "Files will open in a new window unless picked from within the application (e.g. via the File menu)") + nls.localize('window.openFilesInNewWindow.defaultMac', "Files will open in the window with the files' folder open or the last active window unless opened via the Dock or from Finder.") : + nls.localize('window.openFilesInNewWindow.default', "Files will open in a new window unless picked from within the application (e.g. via the File menu).") ], 'default': 'off', 'scope': ConfigurationScope.APPLICATION, 'description': isMacintosh ? - nls.localize('openFilesInNewWindowMac', "Controls if files should open in a new window.\n- default: files will open in the window with the files' folder open or the last active window unless opened via the Dock or from Finder\n- on: files will open in a new window\n- off: files will open in the window with the files' folder open or 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).") : - nls.localize('openFilesInNewWindow', "Controls if files should open in a new window.\n- default: files will open in a new window unless picked from within the application (e.g. via the File menu)\n- on: files will open in a new window\n- off: files will open in the window with the files' folder open or 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).") + 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)") + 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, - 'description': nls.localize('openFoldersInNewWindow', "Controls if folders should open in a new window or replace the last active window.\n- default: folders will open in a new window unless a folder is picked from within the application (e.g. via the File menu)\n- on: folders will open in a new window\n- off: folders will 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).") + 'description': 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'], 'enumDescriptions': [ - nls.localize('window.openWithoutArgumentsInNewWindow.on', "Open a new empty window"), - nls.localize('window.openWithoutArgumentsInNewWindow.off', "Focus the last active running instance") + nls.localize('window.openWithoutArgumentsInNewWindow.on', "Open a new empty window."), + nls.localize('window.openWithoutArgumentsInNewWindow.off', "Focus the last active running instance.") ], 'default': isMacintosh ? 'off' : 'on', 'scope': ConfigurationScope.APPLICATION, - 'description': nls.localize('openWithoutArgumentsInNewWindow', "Controls if a new empty window should open when starting a second instance without arguments or if the last running instance should get focus.\n- on: open a new empty window\n- off: the last active running instance will get focus\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).") + 'description': nls.localize('openWithoutArgumentsInNewWindow', "Controls whether a new empty window should open when starting a second instance without arguments or if the last running instance should get focus.\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.restoreWindows': { 'type': 'string', diff --git a/src/vs/workbench/parts/search/electron-browser/search.contribution.ts b/src/vs/workbench/parts/search/electron-browser/search.contribution.ts index 03f9e4057c9..f3dfe629672 100644 --- a/src/vs/workbench/parts/search/electron-browser/search.contribution.ts +++ b/src/vs/workbench/parts/search/electron-browser/search.contribution.ts @@ -585,12 +585,12 @@ configurationRegistry.registerConfiguration({ }, 'search.useRipgrep': { type: 'boolean', - description: nls.localize('useRipgrep', "Controls whether to use ripgrep in text and file search"), + description: nls.localize('useRipgrep', "Controls whether to use ripgrep in text and file search."), default: true }, 'search.useIgnoreFiles': { type: 'boolean', - description: nls.localize('useIgnoreFiles', "Controls whether to use .gitignore and .ignore files when searching for files."), + description: nls.localize('useIgnoreFiles', "Controls whether to use `.gitignore` and `.ignore` files when searching for files."), default: true, scope: ConfigurationScope.RESOURCE }, @@ -612,7 +612,7 @@ configurationRegistry.registerConfiguration({ 'search.globalFindClipboard': { type: 'boolean', default: false, - description: nls.localize('search.globalFindClipboard', "Controls if the search view should read or modify the shared find clipboard on macOS"), + description: nls.localize('search.globalFindClipboard', "Controls whether the search view should read or modify the shared find clipboard on macOS."), included: platform.isMacintosh }, 'search.location': { From 3086c88d21f6c7c2492ddd2a1f52628df0a5a046 Mon Sep 17 00:00:00 2001 From: Matt Bierner Date: Fri, 27 Jul 2018 14:41:04 -0700 Subject: [PATCH 0321/1276] Don't try closing tags when you type > after another > --- .../typescript-language-features/src/features/tagClosing.ts | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/extensions/typescript-language-features/src/features/tagClosing.ts b/extensions/typescript-language-features/src/features/tagClosing.ts index 838779848da..ab9843ae7f2 100644 --- a/extensions/typescript-language-features/src/features/tagClosing.ts +++ b/extensions/typescript-language-features/src/features/tagClosing.ts @@ -73,8 +73,10 @@ class TagClosing extends Disposable { return; } - const secondToLastCharacter = lastChange.text[lastChange.text.length - 2]; - if (secondToLastCharacter === '>') { + const priorCharacter = lastChange.range.start.character > 0 + ? document.getText(new vscode.Range(lastChange.range.start.translate({ characterDelta: -1 }), lastChange.range.start)) + : ''; + if (priorCharacter === '>') { return; } From 5198030c0977fef20f1bee131fb5e11d9a150cc9 Mon Sep 17 00:00:00 2001 From: Matt Bierner Date: Mon, 30 Jul 2018 15:59:17 +0100 Subject: [PATCH 0322/1276] Describe what implementation code lens does Fixes #55370 --- extensions/typescript-language-features/package.nls.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/extensions/typescript-language-features/package.nls.json b/extensions/typescript-language-features/package.nls.json index 4015ea739b0..15b80915353 100644 --- a/extensions/typescript-language-features/package.nls.json +++ b/extensions/typescript-language-features/package.nls.json @@ -32,7 +32,7 @@ "goToProjectConfig.title": "Go to Project Configuration", "javascript.referencesCodeLens.enabled": "Enable/disable references CodeLens in JavaScript files.", "typescript.referencesCodeLens.enabled": "Enable/disable references CodeLens in TypeScript files.", - "typescript.implementationsCodeLens.enabled": "Enable/disable implementations CodeLens.", + "typescript.implementationsCodeLens.enabled": "Enable/disable implementations CodeLens. This CodeLens shows the implementers of an interface.", "typescript.openTsServerLog.title": "Open TS Server log.", "typescript.restartTsServer": "Restart TS server.", "typescript.selectTypeScriptVersion.title": "Select TypeScript Version.", From 2eb31c71704b3505d4b17aaa7e707d5d8651e901 Mon Sep 17 00:00:00 2001 From: Martin Aeschlimann Date: Mon, 30 Jul 2018 17:03:04 +0200 Subject: [PATCH 0323/1276] fix javadoc formatter setting description --- extensions/json-language-features/package.nls.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/extensions/json-language-features/package.nls.json b/extensions/json-language-features/package.nls.json index f9d52e8ebcf..943de414e15 100644 --- a/extensions/json-language-features/package.nls.json +++ b/extensions/json-language-features/package.nls.json @@ -6,7 +6,7 @@ "json.schemas.fileMatch.desc": "An array of file patterns to match against when resolving JSON files to schemas.", "json.schemas.fileMatch.item.desc": "A file pattern that can contain '*' to match against when resolving JSON files to schemas.", "json.schemas.schema.desc": "The schema definition for the given URL. The schema only needs to be provided to avoid accesses to the schema URL.", - "json.format.enable.desc": "Enable/disable default JSON formatter (requires restart)", + "json.format.enable.desc": "Enable/disable default JSON formatter", "json.tracing.desc": "Traces the communication between VS Code and the JSON language server.", "json.colorDecorators.enable.desc": "Enables or disables color decorators", "json.colorDecorators.enable.deprecationMessage": "The setting `json.colorDecorators.enable` has been deprecated in favor of `editor.colorDecorators`." From 78f41b4921af1cda133bf09c7d9b5697281d5789 Mon Sep 17 00:00:00 2001 From: isidor Date: Mon, 30 Jul 2018 18:04:43 +0200 Subject: [PATCH 0324/1276] fixes #55325 --- src/vs/workbench/parts/debug/common/debug.ts | 4 ++-- src/vs/workbench/parts/debug/electron-browser/debugService.ts | 3 +++ 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/src/vs/workbench/parts/debug/common/debug.ts b/src/vs/workbench/parts/debug/common/debug.ts index 3ddd5867504..fe295f8a723 100644 --- a/src/vs/workbench/parts/debug/common/debug.ts +++ b/src/vs/workbench/parts/debug/common/debug.ts @@ -37,8 +37,8 @@ export const REPL_ID = 'workbench.panel.repl'; export const DEBUG_SERVICE_ID = 'debugService'; export const CONTEXT_DEBUG_TYPE = new RawContextKey('debugType', undefined); export const CONTEXT_DEBUG_STATE = new RawContextKey('debugState', 'inactive'); -export const CONTEXT_NOT_IN_DEBUG_MODE = CONTEXT_DEBUG_STATE.isEqualTo('inactive'); -export const CONTEXT_IN_DEBUG_MODE = CONTEXT_DEBUG_STATE.notEqualsTo('inactive'); +export const CONTEXT_IN_DEBUG_MODE = new RawContextKey('inDebugMode', false); +export const CONTEXT_NOT_IN_DEBUG_MODE = CONTEXT_IN_DEBUG_MODE.toNegated(); export const CONTEXT_IN_DEBUG_REPL = new RawContextKey('inDebugRepl', false); export const CONTEXT_BREAKPOINT_WIDGET_VISIBLE = new RawContextKey('breakpointWidgetVisible', false); export const CONTEXT_IN_BREAKPOINT_WIDGET = new RawContextKey('inBreakpointWidget', false); diff --git a/src/vs/workbench/parts/debug/electron-browser/debugService.ts b/src/vs/workbench/parts/debug/electron-browser/debugService.ts index 3ec47d67994..0a16c3ba620 100644 --- a/src/vs/workbench/parts/debug/electron-browser/debugService.ts +++ b/src/vs/workbench/parts/debug/electron-browser/debugService.ts @@ -78,6 +78,7 @@ export class DebugService implements debug.IDebugService { private toDisposeOnSessionEnd: Map; private debugType: IContextKey; private debugState: IContextKey; + private inDebugMode: IContextKey; private breakpointsToSendOnResourceSaved: Set; private firstSessionStart: boolean; private skipRunningTask: boolean; @@ -121,6 +122,7 @@ export class DebugService implements debug.IDebugService { this.toDispose.push(this.configurationManager); this.debugType = debug.CONTEXT_DEBUG_TYPE.bindTo(contextKeyService); this.debugState = debug.CONTEXT_DEBUG_STATE.bindTo(contextKeyService); + this.inDebugMode = debug.CONTEXT_IN_DEBUG_MODE.bindTo(contextKeyService); this.model = new Model(this.loadBreakpoints(), this.storageService.getBoolean(DEBUG_BREAKPOINTS_ACTIVATED_KEY, StorageScope.WORKSPACE, true), this.loadFunctionBreakpoints(), this.loadExceptionBreakpoints(), this.loadWatchExpressions()); @@ -558,6 +560,7 @@ export class DebugService implements debug.IDebugService { const stateLabel = debug.State[state]; if (stateLabel) { this.debugState.set(stateLabel.toLowerCase()); + this.inDebugMode.set(state !== debug.State.Inactive); } this.previousState = state; this._onDidChangeState.fire(state); From 5534d7868f790fc1987ae9753ea1ad9fce891a39 Mon Sep 17 00:00:00 2001 From: kieferrm Date: Mon, 30 Jul 2018 10:55:29 -0700 Subject: [PATCH 0325/1276] update to officical TS version --- extensions/package.json | 2 +- extensions/yarn.lock | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/extensions/package.json b/extensions/package.json index 7483338ab01..8e143a8485e 100644 --- a/extensions/package.json +++ b/extensions/package.json @@ -3,7 +3,7 @@ "version": "0.0.1", "description": "Dependencies shared by all extensions", "dependencies": { - "typescript": "3.0.1-insiders.20180726" + "typescript": "3.0.1" }, "scripts": { "postinstall": "node ./postinstall" diff --git a/extensions/yarn.lock b/extensions/yarn.lock index a9d7e2b8a70..67d803d4e5e 100644 --- a/extensions/yarn.lock +++ b/extensions/yarn.lock @@ -2,6 +2,6 @@ # yarn lockfile v1 -typescript@3.0.1-insiders.20180726: - version "3.0.1-insiders.20180726" - resolved "https://registry.yarnpkg.com/typescript/-/typescript-3.0.1-insiders.20180726.tgz#3f921f23c8768b6fb665ee8a6895b5fca14b0c5f" +typescript@3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/typescript/-/typescript-3.0.1.tgz#43738f29585d3a87575520a4b93ab6026ef11fdb" From 67559ca851d4a23a8810f05fff334951cc29fd76 Mon Sep 17 00:00:00 2001 From: Rob Lourens Date: Mon, 30 Jul 2018 10:42:07 -0700 Subject: [PATCH 0326/1276] Settings editor - Even more padding, use semibold instead of bold --- .../parts/preferences/browser/media/settingsEditor2.css | 8 ++++---- .../workbench/parts/preferences/browser/settingsTree.ts | 4 ++-- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/vs/workbench/parts/preferences/browser/media/settingsEditor2.css b/src/vs/workbench/parts/preferences/browser/media/settingsEditor2.css index 3be8f0ad66d..e04004d4969 100644 --- a/src/vs/workbench/parts/preferences/browser/media/settingsEditor2.css +++ b/src/vs/workbench/parts/preferences/browser/media/settingsEditor2.css @@ -211,8 +211,8 @@ } .settings-editor > .settings-body > .settings-tree-container .setting-item { - padding-top: 8px; - padding-bottom: 14px; + padding-top: 12px; + padding-bottom: 18px; box-sizing: border-box; cursor: default; white-space: normal; @@ -254,7 +254,7 @@ .settings-editor > .settings-body > .settings-tree-container .setting-item .setting-item-label, .settings-editor > .settings-body > .settings-tree-container .setting-item .setting-item-category { - font-weight: bold; + font-weight: 600; } .settings-editor > .settings-body > .settings-tree-container .setting-item .setting-item-category { @@ -379,7 +379,7 @@ .settings-editor > .settings-body > .settings-tree-container .settings-group-title-label { margin: 0px; - font-weight: 500; + font-weight: 600; } .settings-editor > .settings-body > .settings-tree-container .settings-group-level-1 { diff --git a/src/vs/workbench/parts/preferences/browser/settingsTree.ts b/src/vs/workbench/parts/preferences/browser/settingsTree.ts index a11bf419339..2101fdd3897 100644 --- a/src/vs/workbench/parts/preferences/browser/settingsTree.ts +++ b/src/vs/workbench/parts/preferences/browser/settingsTree.ts @@ -531,8 +531,8 @@ export interface ISettingChangeEvent { export class SettingsRenderer implements ITreeRenderer { - private static readonly SETTING_ROW_HEIGHT = 96; - private static readonly SETTING_BOOL_ROW_HEIGHT = 65; + private static readonly SETTING_ROW_HEIGHT = 104; + private static readonly SETTING_BOOL_ROW_HEIGHT = 73; public static readonly MAX_ENUM_DESCRIPTIONS = 10; private readonly _onDidChangeSetting: Emitter = new Emitter(); From b9b78028d58e8c89b94843ff2a17f6c3b6f46f8e Mon Sep 17 00:00:00 2001 From: Rob Lourens Date: Mon, 30 Jul 2018 10:59:00 -0700 Subject: [PATCH 0327/1276] Fix #55357 - fix TOC twistie --- .../preferences/browser/settingsEditor2.ts | 31 ++++++++++++------- 1 file changed, 19 insertions(+), 12 deletions(-) diff --git a/src/vs/workbench/parts/preferences/browser/settingsEditor2.ts b/src/vs/workbench/parts/preferences/browser/settingsEditor2.ts index 79fef29f2a4..1253fb2145f 100644 --- a/src/vs/workbench/parts/preferences/browser/settingsEditor2.ts +++ b/src/vs/workbench/parts/preferences/browser/settingsEditor2.ts @@ -298,17 +298,22 @@ export class SettingsEditor2 extends BaseEditor { }); this._register(this.tocTree.onDidChangeFocus(e => { - const element = e.focus; - if (this.searchResultModel) { - this.viewState.filterToCategory = element; - this.refreshTreeAndMaintainFocus(); - } else if (this.settingsTreeModel) { - if (element && !e.payload.fromScroll) { - this.settingsTree.reveal(element, 0); - this.settingsTree.setSelection([element]); - this.settingsTree.setFocus(element); + // Let the caller finish before trying to sync with settings tree. + // e.g. clicking this twistie, which will toggle the row's expansion state _after_ this event is fired. + process.nextTick(() => { + const element = e.focus; + if (this.searchResultModel) { + this.viewState.filterToCategory = element; + this.refreshTreeAndMaintainFocus(); + } else if (this.settingsTreeModel) { + if (element && !e.payload.fromScroll) { + const payload = { fromTOC: true }; + this.settingsTree.reveal(element, 0); + this.settingsTree.setSelection([element], payload); + this.settingsTree.setFocus(element, payload); + } } - } + }); })); this._register(this.tocTree.onDidFocus(() => { @@ -349,7 +354,7 @@ export class SettingsEditor2 extends BaseEditor { }); this._register(this.settingsTree.onDidChangeFocus(e => { - this.settingsTree.setSelection([e.focus]); + this.settingsTree.setSelection([e.focus], e.payload); if (this.selectedElement) { this.settingsTree.refresh(this.selectedElement); } @@ -367,7 +372,9 @@ export class SettingsEditor2 extends BaseEditor { })); this._register(this.settingsTree.onDidChangeSelection(e => { - this.updateTreeScrollSync(); + if (!e.payload || !e.payload.fromTOC) { + this.updateTreeScrollSync(); + } let firstRowFocused = false; let rowFocused = false; From 1f7b140f2382eef5241278bb9ac9ec6f3ecec0d4 Mon Sep 17 00:00:00 2001 From: kieferrm Date: Mon, 30 Jul 2018 11:55:24 -0700 Subject: [PATCH 0328/1276] fixes #55288 --- .../workbench/parts/snippets/electron-browser/snippetsFile.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vs/workbench/parts/snippets/electron-browser/snippetsFile.ts b/src/vs/workbench/parts/snippets/electron-browser/snippetsFile.ts index e624664bbe6..d0776ceed99 100644 --- a/src/vs/workbench/parts/snippets/electron-browser/snippetsFile.ts +++ b/src/vs/workbench/parts/snippets/electron-browser/snippetsFile.ts @@ -33,7 +33,7 @@ export class Snippet { readonly isFromExtension?: boolean, ) { // - this.prefixLow = prefix.toLowerCase(); + this.prefixLow = prefix ? prefix.toLowerCase() : prefix; } get codeSnippet(): string { From deed7f1344c438b2270bf11281b9e3acac2abcfa Mon Sep 17 00:00:00 2001 From: isidor Date: Mon, 30 Jul 2018 22:02:10 +0200 Subject: [PATCH 0329/1276] explorer: refresh on di change file system provider registration fixes #53256 --- .../workbench/parts/files/electron-browser/views/explorerView.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/src/vs/workbench/parts/files/electron-browser/views/explorerView.ts b/src/vs/workbench/parts/files/electron-browser/views/explorerView.ts index cadc88c5131..40850fe8f72 100644 --- a/src/vs/workbench/parts/files/electron-browser/views/explorerView.ts +++ b/src/vs/workbench/parts/files/electron-browser/views/explorerView.ts @@ -196,6 +196,7 @@ export class ExplorerView extends TreeViewsViewletPanel implements IExplorerView this.disposables.push(this.contextService.onDidChangeWorkspaceFolders(e => this.refreshFromEvent(e.added))); this.disposables.push(this.contextService.onDidChangeWorkbenchState(e => this.refreshFromEvent())); + this.disposables.push(this.fileService.onDidChangeFileSystemProviderRegistrations(() => this.refreshFromEvent())); } layoutBody(size: number): void { From 94a3c18781a2e14b2d96734f9b75c4fb1d4b71d5 Mon Sep 17 00:00:00 2001 From: Christof Marti Date: Mon, 30 Jul 2018 22:44:00 +0200 Subject: [PATCH 0330/1276] Disable push to Linux repo to test standalone publisher --- build/tfs/linux/product-build-linux.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/build/tfs/linux/product-build-linux.yml b/build/tfs/linux/product-build-linux.yml index f6e067ebfe3..79675e4627c 100644 --- a/build/tfs/linux/product-build-linux.yml +++ b/build/tfs/linux/product-build-linux.yml @@ -104,8 +104,8 @@ steps: pushd build/tfs/linux # Submit to apt repo if [ "$DEB_ARCH" = "amd64" ]; then - echo "{ \"server\": \"azure-apt-cat.cloudapp.net\", \"protocol\": \"https\", \"port\": \"443\", \"repositoryId\": \"58a4adf642421134a1a48d1a\", \"username\": \"vscode\", \"password\": \"$(LINUX_REPO_PASSWORD)\" }" > apt-config.json - ./repoapi_client.sh -config apt-config.json -addfile $DEB_PATH + # echo "{ \"server\": \"azure-apt-cat.cloudapp.net\", \"protocol\": \"https\", \"port\": \"443\", \"repositoryId\": \"58a4adf642421134a1a48d1a\", \"username\": \"vscode\", \"password\": \"$(LINUX_REPO_PASSWORD)\" }" > apt-config.json + # ./repoapi_client.sh -config apt-config.json -addfile $DEB_PATH fi # Submit to yum repo (disabled as it's manual until signing is automated) # eval echo '{ \"server\": \"azure-apt-cat.cloudapp.net\", \"protocol\": \"https\", \"port\": \"443\", \"repositoryId\": \"58a4ae3542421134a1a48d1b\", \"username\": \"vscode\", \"password\": \"$(LINUX_REPO_PASSWORD)\" }' > yum-config.json From 9645f0219a5960a1b0df1cdf9dc20e1a7f646dd6 Mon Sep 17 00:00:00 2001 From: Ramya Achutha Rao Date: Mon, 30 Jul 2018 14:03:17 -0700 Subject: [PATCH 0331/1276] New env var to notify log level to extensions #54001 --- src/vs/platform/environment/common/environment.ts | 1 + src/vs/platform/environment/node/environmentService.ts | 1 + .../services/extensions/electron-browser/extensionHost.ts | 3 ++- 3 files changed, 4 insertions(+), 1 deletion(-) diff --git a/src/vs/platform/environment/common/environment.ts b/src/vs/platform/environment/common/environment.ts index c291dff9fec..4fc2805267b 100644 --- a/src/vs/platform/environment/common/environment.ts +++ b/src/vs/platform/environment/common/environment.ts @@ -119,6 +119,7 @@ export interface IEnvironmentService { performance: boolean; // logging + log: string; logsPath: string; verbose: boolean; diff --git a/src/vs/platform/environment/node/environmentService.ts b/src/vs/platform/environment/node/environmentService.ts index 9ef3481c43d..5625ae2ca2d 100644 --- a/src/vs/platform/environment/node/environmentService.ts +++ b/src/vs/platform/environment/node/environmentService.ts @@ -183,6 +183,7 @@ export class EnvironmentService implements IEnvironmentService { get isBuilt(): boolean { return !process.env['VSCODE_DEV']; } get verbose(): boolean { return this._args.verbose; } + get log(): string { return this._args.log; } get wait(): boolean { return this._args.wait; } get logExtensionHostCommunication(): boolean { return this._args.logExtensionHostCommunication; } diff --git a/src/vs/workbench/services/extensions/electron-browser/extensionHost.ts b/src/vs/workbench/services/extensions/electron-browser/extensionHost.ts index ab3dda8c90e..84a39c92a4b 100644 --- a/src/vs/workbench/services/extensions/electron-browser/extensionHost.ts +++ b/src/vs/workbench/services/extensions/electron-browser/extensionHost.ts @@ -141,7 +141,8 @@ export class ExtensionHostProcessWorker { VERBOSE_LOGGING: true, VSCODE_IPC_HOOK_EXTHOST: pipeName, VSCODE_HANDLES_UNCAUGHT_ERRORS: true, - VSCODE_LOG_STACK: !this._isExtensionDevTestFromCli && (this._isExtensionDevHost || !this._environmentService.isBuilt || product.quality !== 'stable' || this._environmentService.verbose) + VSCODE_LOG_STACK: !this._isExtensionDevTestFromCli && (this._isExtensionDevHost || !this._environmentService.isBuilt || product.quality !== 'stable' || this._environmentService.verbose), + VSCODE_LOG_LEVEL: this._environmentService.verbose ? 'trace' : this._environmentService.log }), // We only detach the extension host on windows. Linux and Mac orphan by default // and detach under Linux and Mac create another process group. From 28bfd5b73c9f5e59c0a9a6cbaef3900097ad0b8e Mon Sep 17 00:00:00 2001 From: Jackson Kearl Date: Mon, 30 Jul 2018 14:28:31 -0700 Subject: [PATCH 0332/1276] Disable snippets in extension search (when not in suggest dropdown) (#55281) * Disable snippits in extension search (when not in suggest dropdown) * Add monaco input contributions * Fix bug preventing snippetSuggestions from taking effect in sub-editors --- src/vs/editor/common/config/editorOptions.ts | 8 +++----- .../electron-browser/extensionsViewlet.ts | 16 ++++++++++++++-- 2 files changed, 17 insertions(+), 7 deletions(-) diff --git a/src/vs/editor/common/config/editorOptions.ts b/src/vs/editor/common/config/editorOptions.ts index 14365ee9925..75fd5559db8 100644 --- a/src/vs/editor/common/config/editorOptions.ts +++ b/src/vs/editor/common/config/editorOptions.ts @@ -1752,13 +1752,11 @@ export class EditorOptionsValidator { } private static _sanitizeSuggestOpts(opts: IEditorOptions, defaults: InternalSuggestOptions): InternalSuggestOptions { - if (!opts.suggest) { - return defaults; - } + const suggestOpts = opts.suggest || {}; return { - filterGraceful: _boolean(opts.suggest.filterGraceful, defaults.filterGraceful), + filterGraceful: _boolean(suggestOpts.filterGraceful, defaults.filterGraceful), snippets: _stringSet<'top' | 'bottom' | 'inline' | 'none'>(opts.snippetSuggestions, defaults.snippets, ['top', 'bottom', 'inline', 'none']), - snippetsPreventQuickSuggestions: _boolean(opts.suggest.snippetsPreventQuickSuggestions, defaults.filterGraceful), + snippetsPreventQuickSuggestions: _boolean(suggestOpts.snippetsPreventQuickSuggestions, defaults.filterGraceful), }; } diff --git a/src/vs/workbench/parts/extensions/electron-browser/extensionsViewlet.ts b/src/vs/workbench/parts/extensions/electron-browser/extensionsViewlet.ts index 5a17cd2c003..67115759ef2 100644 --- a/src/vs/workbench/parts/extensions/electron-browser/extensionsViewlet.ts +++ b/src/vs/workbench/parts/extensions/electron-browser/extensionsViewlet.ts @@ -65,7 +65,11 @@ import { Range } from 'vs/editor/common/core/range'; import { Position } from 'vs/editor/common/core/position'; import { ITextModel } from 'vs/editor/common/model'; import { IEditorOptions } from 'vs/editor/common/config/editorOptions'; -import { getSimpleEditorOptions, getSimpleCodeEditorWidgetOptions } from 'vs/workbench/parts/codeEditor/electron-browser/simpleEditorOptions'; +import { getSimpleEditorOptions } from 'vs/workbench/parts/codeEditor/electron-browser/simpleEditorOptions'; +import { SuggestController } from 'vs/editor/contrib/suggest/suggestController'; +import { ContextMenuController } from 'vs/editor/contrib/contextmenu/contextmenu'; +import { MenuPreventer } from 'vs/workbench/parts/codeEditor/electron-browser/menuPreventer'; +import { SnippetController2 } from 'vs/editor/contrib/snippet/snippetController2'; interface SearchInputEvent extends Event { target: HTMLInputElement; @@ -342,7 +346,14 @@ export class ExtensionsViewlet extends ViewContainerViewlet implements IExtensio this.monacoStyleContainer = append(header, $('.monaco-container')); this.searchBox = this.instantiationService.createInstance(CodeEditorWidget, this.monacoStyleContainer, mixinHTMLInputStyleOptions(getSimpleEditorOptions(), localize('searchExtensions', "Search Extensions in Marketplace")), - getSimpleCodeEditorWidgetOptions()); + { + isSimpleWidget: true, contributions: [ + SuggestController, + SnippetController2, + ContextMenuController, + MenuPreventer + ] + }); this.placeholderText = append(this.monacoStyleContainer, $('.search-placeholder', null, localize('searchExtensions', "Search Extensions in Marketplace"))); @@ -680,6 +691,7 @@ function mixinHTMLInputStyleOptions(config: IEditorOptions, ariaLabel?: string): config.scrollbar.vertical = 'hidden'; config.ariaLabel = ariaLabel || ''; config.cursorWidth = 1; + config.snippetSuggestions = 'none'; config.fontFamily = ' -apple-system, BlinkMacSystemFont, "Segoe WPC", "Segoe UI", "HelveticaNeue-Light", "Ubuntu", "Droid Sans", sans-serif'; return config; } From 4afd9f534394b22d17bc4899940f6b5ac062ce3d Mon Sep 17 00:00:00 2001 From: Ramya Achutha Rao Date: Mon, 30 Jul 2018 15:33:56 -0700 Subject: [PATCH 0333/1276] Latest emmet helper to fix #52366 --- extensions/emmet/package.json | 2 +- extensions/emmet/yarn.lock | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/extensions/emmet/package.json b/extensions/emmet/package.json index 406b25c97d2..ccf17588f3b 100644 --- a/extensions/emmet/package.json +++ b/extensions/emmet/package.json @@ -447,7 +447,7 @@ "@emmetio/html-matcher": "^0.3.3", "@emmetio/math-expression": "^0.1.1", "image-size": "^0.5.2", - "vscode-emmet-helper": "^1.2.10", + "vscode-emmet-helper": "^1.2.11", "vscode-languageserver-types": "^3.5.0", "vscode-nls": "3.2.4" } diff --git a/extensions/emmet/yarn.lock b/extensions/emmet/yarn.lock index 040417ab779..00ba81087eb 100644 --- a/extensions/emmet/yarn.lock +++ b/extensions/emmet/yarn.lock @@ -2115,9 +2115,9 @@ vinyl@~2.0.1: remove-trailing-separator "^1.0.1" replace-ext "^1.0.0" -vscode-emmet-helper@^1.2.10: - version "1.2.10" - resolved "https://registry.yarnpkg.com/vscode-emmet-helper/-/vscode-emmet-helper-1.2.10.tgz#c4e08c721fa379f57e53c6bdf2843d4b3c830d16" +vscode-emmet-helper@^1.2.11: + version "1.2.11" + resolved "https://registry.yarnpkg.com/vscode-emmet-helper/-/vscode-emmet-helper-1.2.11.tgz#4de78223666bf917eb6dc4b225b6c40f6901950c" dependencies: "@emmetio/extract-abbreviation" "0.1.6" jsonc-parser "^1.0.0" From 00392f1802c143ecc54c5a35df327a5458b007c0 Mon Sep 17 00:00:00 2001 From: Rachel Macfarlane Date: Mon, 30 Jul 2018 16:13:33 -0700 Subject: [PATCH 0334/1276] Fix comment updates for threads within same file --- .../parts/comments/common/commentModel.ts | 18 ++++++++++++++++-- .../comments/electron-browser/commentsPanel.ts | 6 ++++-- 2 files changed, 20 insertions(+), 4 deletions(-) diff --git a/src/vs/workbench/parts/comments/common/commentModel.ts b/src/vs/workbench/parts/comments/common/commentModel.ts index 4fb5b74843c..305acad3ce4 100644 --- a/src/vs/workbench/parts/comments/common/commentModel.ts +++ b/src/vs/workbench/parts/comments/common/commentModel.ts @@ -67,8 +67,12 @@ export class CommentsModel { this.resourceCommentThreads = flatten(values(this.commentThreadsMap)); } - public updateCommentThreads(event: CommentThreadChangedEvent): void { + public updateCommentThreads(event: CommentThreadChangedEvent): boolean { const { owner, removed, changed, added } = event; + if (!this.commentThreadsMap.has(owner)) { + return false; + } + let threadsForOwner = this.commentThreadsMap.get(owner); removed.forEach(thread => { @@ -96,10 +100,20 @@ export class CommentsModel { matchingResourceData.commentThreads[index] = ResourceWithCommentThreads.createCommentNode(URI.parse(matchingResourceData.id), thread); }); - threadsForOwner = threadsForOwner.concat(this.groupByResource(added)); + added.forEach(thread => { + const existingResource = threadsForOwner.filter(resourceWithThreads => resourceWithThreads.resource.toString() === thread.resource); + if (existingResource.length) { + const resource = existingResource[0]; + resource.commentThreads.push(ResourceWithCommentThreads.createCommentNode(resource.resource, thread)); + } else { + threadsForOwner.push(new ResourceWithCommentThreads(URI.parse(thread.resource), [thread])); + } + }); this.commentThreadsMap.set(owner, threadsForOwner); this.resourceCommentThreads = flatten(values(this.commentThreadsMap)); + + return removed.length > 0 || changed.length > 0 || added.length > 0; } public hasCommentThreads(): boolean { diff --git a/src/vs/workbench/parts/comments/electron-browser/commentsPanel.ts b/src/vs/workbench/parts/comments/electron-browser/commentsPanel.ts index c916bec1da8..4701e552987 100644 --- a/src/vs/workbench/parts/comments/electron-browser/commentsPanel.ts +++ b/src/vs/workbench/parts/comments/electron-browser/commentsPanel.ts @@ -262,7 +262,9 @@ export class CommentsPanel extends Panel { } private onCommentsUpdated(e: CommentThreadChangedEvent): void { - this.commentsModel.updateCommentThreads(e); - this.refresh(); + const didUpdate = this.commentsModel.updateCommentThreads(e); + if (didUpdate) { + this.refresh(); + } } } From 1912c5d7550de0941397d246304cfb041fe616bc Mon Sep 17 00:00:00 2001 From: Ramya Achutha Rao Date: Mon, 30 Jul 2018 16:14:14 -0700 Subject: [PATCH 0335/1276] Allow extensions to log telemetry to log files #54001 --- extensions/git/package.json | 2 +- extensions/git/yarn.lock | 6 +++--- extensions/html-language-features/package.json | 2 +- extensions/html-language-features/yarn.lock | 6 +++--- extensions/json-language-features/package.json | 2 +- extensions/json-language-features/yarn.lock | 6 +++--- extensions/markdown-language-features/package.json | 2 +- extensions/markdown-language-features/yarn.lock | 6 +++--- extensions/search-rg/package.json | 2 +- extensions/search-rg/yarn.lock | 6 +++--- extensions/typescript-language-features/package.json | 2 +- extensions/typescript-language-features/yarn.lock | 6 +++--- 12 files changed, 24 insertions(+), 24 deletions(-) diff --git a/extensions/git/package.json b/extensions/git/package.json index 96b81482585..5a329452b34 100644 --- a/extensions/git/package.json +++ b/extensions/git/package.json @@ -1189,7 +1189,7 @@ "file-type": "^7.2.0", "iconv-lite": "0.4.19", "jschardet": "^1.6.0", - "vscode-extension-telemetry": "0.0.17", + "vscode-extension-telemetry": "0.0.18", "vscode-nls": "^3.2.4", "which": "^1.3.0" }, diff --git a/extensions/git/yarn.lock b/extensions/git/yarn.lock index d8a4d64e743..497e26b21d6 100644 --- a/extensions/git/yarn.lock +++ b/extensions/git/yarn.lock @@ -257,9 +257,9 @@ supports-color@3.1.2: dependencies: has-flag "^1.0.0" -vscode-extension-telemetry@0.0.17: - version "0.0.17" - resolved "https://registry.yarnpkg.com/vscode-extension-telemetry/-/vscode-extension-telemetry-0.0.17.tgz#15123e7edb34e7b9724b6056f54a869bbb922cb7" +vscode-extension-telemetry@0.0.18: + version "0.0.18" + resolved "https://registry.yarnpkg.com/vscode-extension-telemetry/-/vscode-extension-telemetry-0.0.18.tgz#602ba20d8c71453aa34533a291e7638f6e5c0327" dependencies: applicationinsights "1.0.1" diff --git a/extensions/html-language-features/package.json b/extensions/html-language-features/package.json index fbe7c1f157b..cbbc1fb81de 100644 --- a/extensions/html-language-features/package.json +++ b/extensions/html-language-features/package.json @@ -173,7 +173,7 @@ } }, "dependencies": { - "vscode-extension-telemetry": "0.0.17", + "vscode-extension-telemetry": "0.0.18", "vscode-languageclient": "^4.4.0", "vscode-nls": "^3.2.4" }, diff --git a/extensions/html-language-features/yarn.lock b/extensions/html-language-features/yarn.lock index 2ff934b3440..a33a4a08108 100644 --- a/extensions/html-language-features/yarn.lock +++ b/extensions/html-language-features/yarn.lock @@ -28,9 +28,9 @@ semver@^5.3.0: version "5.5.0" resolved "https://registry.yarnpkg.com/semver/-/semver-5.5.0.tgz#dc4bbc7a6ca9d916dee5d43516f0092b58f7b8ab" -vscode-extension-telemetry@0.0.17: - version "0.0.17" - resolved "https://registry.yarnpkg.com/vscode-extension-telemetry/-/vscode-extension-telemetry-0.0.17.tgz#15123e7edb34e7b9724b6056f54a869bbb922cb7" +vscode-extension-telemetry@0.0.18: + version "0.0.18" + resolved "https://registry.yarnpkg.com/vscode-extension-telemetry/-/vscode-extension-telemetry-0.0.18.tgz#602ba20d8c71453aa34533a291e7638f6e5c0327" dependencies: applicationinsights "1.0.1" diff --git a/extensions/json-language-features/package.json b/extensions/json-language-features/package.json index 610fa55776c..f814f5e747d 100644 --- a/extensions/json-language-features/package.json +++ b/extensions/json-language-features/package.json @@ -100,7 +100,7 @@ } }, "dependencies": { - "vscode-extension-telemetry": "0.0.17", + "vscode-extension-telemetry": "0.0.18", "vscode-languageclient": "^4.4.0", "vscode-nls": "^3.2.4" }, diff --git a/extensions/json-language-features/yarn.lock b/extensions/json-language-features/yarn.lock index 2ff934b3440..a33a4a08108 100644 --- a/extensions/json-language-features/yarn.lock +++ b/extensions/json-language-features/yarn.lock @@ -28,9 +28,9 @@ semver@^5.3.0: version "5.5.0" resolved "https://registry.yarnpkg.com/semver/-/semver-5.5.0.tgz#dc4bbc7a6ca9d916dee5d43516f0092b58f7b8ab" -vscode-extension-telemetry@0.0.17: - version "0.0.17" - resolved "https://registry.yarnpkg.com/vscode-extension-telemetry/-/vscode-extension-telemetry-0.0.17.tgz#15123e7edb34e7b9724b6056f54a869bbb922cb7" +vscode-extension-telemetry@0.0.18: + version "0.0.18" + resolved "https://registry.yarnpkg.com/vscode-extension-telemetry/-/vscode-extension-telemetry-0.0.18.tgz#602ba20d8c71453aa34533a291e7638f6e5c0327" dependencies: applicationinsights "1.0.1" diff --git a/extensions/markdown-language-features/package.json b/extensions/markdown-language-features/package.json index 984967f637f..b49638d9707 100644 --- a/extensions/markdown-language-features/package.json +++ b/extensions/markdown-language-features/package.json @@ -295,7 +295,7 @@ "highlight.js": "9.12.0", "markdown-it": "^8.4.1", "markdown-it-named-headers": "0.0.4", - "vscode-extension-telemetry": "0.0.17", + "vscode-extension-telemetry": "0.0.18", "vscode-nls": "^3.2.4" }, "devDependencies": { diff --git a/extensions/markdown-language-features/yarn.lock b/extensions/markdown-language-features/yarn.lock index c44b9715579..a2e69ddb6b8 100644 --- a/extensions/markdown-language-features/yarn.lock +++ b/extensions/markdown-language-features/yarn.lock @@ -5456,9 +5456,9 @@ vm-browserify@0.0.4: dependencies: indexof "0.0.1" -vscode-extension-telemetry@0.0.17: - version "0.0.17" - resolved "https://registry.yarnpkg.com/vscode-extension-telemetry/-/vscode-extension-telemetry-0.0.17.tgz#15123e7edb34e7b9724b6056f54a869bbb922cb7" +vscode-extension-telemetry@0.0.18: + version "0.0.18" + resolved "https://registry.yarnpkg.com/vscode-extension-telemetry/-/vscode-extension-telemetry-0.0.18.tgz#602ba20d8c71453aa34533a291e7638f6e5c0327" dependencies: applicationinsights "1.0.1" diff --git a/extensions/search-rg/package.json b/extensions/search-rg/package.json index d798d7b2842..c4621670df8 100644 --- a/extensions/search-rg/package.json +++ b/extensions/search-rg/package.json @@ -13,7 +13,7 @@ }, "categories": [], "dependencies": { - "vscode-extension-telemetry": "0.0.15", + "vscode-extension-telemetry": "0.0.18", "vscode-nls": "^3.2.4", "vscode-ripgrep": "^1.0.1" }, diff --git a/extensions/search-rg/yarn.lock b/extensions/search-rg/yarn.lock index 99b491f01ff..1be6ca92db5 100644 --- a/extensions/search-rg/yarn.lock +++ b/extensions/search-rg/yarn.lock @@ -1539,9 +1539,9 @@ vinyl@^2.0.1, vinyl@^2.0.2: remove-trailing-separator "^1.0.1" replace-ext "^1.0.0" -vscode-extension-telemetry@0.0.15: - version "0.0.15" - resolved "https://registry.yarnpkg.com/vscode-extension-telemetry/-/vscode-extension-telemetry-0.0.15.tgz#685c32f3b67e8fb85ba689c1d7f88ff90ff87856" +vscode-extension-telemetry@0.0.18: + version "0.0.18" + resolved "https://registry.yarnpkg.com/vscode-extension-telemetry/-/vscode-extension-telemetry-0.0.18.tgz#602ba20d8c71453aa34533a291e7638f6e5c0327" dependencies: applicationinsights "1.0.1" diff --git a/extensions/typescript-language-features/package.json b/extensions/typescript-language-features/package.json index cd5dc87bf4c..f06f35fccc1 100644 --- a/extensions/typescript-language-features/package.json +++ b/extensions/typescript-language-features/package.json @@ -18,7 +18,7 @@ "dependencies": { "jsonc-parser": "^2.0.1", "semver": "4.3.6", - "vscode-extension-telemetry": "0.0.17", + "vscode-extension-telemetry": "0.0.18", "vscode-nls": "^3.2.4" }, "devDependencies": { diff --git a/extensions/typescript-language-features/yarn.lock b/extensions/typescript-language-features/yarn.lock index 3f1d2b4ed86..b0a99345853 100644 --- a/extensions/typescript-language-features/yarn.lock +++ b/extensions/typescript-language-features/yarn.lock @@ -1546,9 +1546,9 @@ vinyl@^2.0.1, vinyl@^2.0.2: remove-trailing-separator "^1.0.1" replace-ext "^1.0.0" -vscode-extension-telemetry@0.0.17: - version "0.0.17" - resolved "https://registry.yarnpkg.com/vscode-extension-telemetry/-/vscode-extension-telemetry-0.0.17.tgz#15123e7edb34e7b9724b6056f54a869bbb922cb7" +vscode-extension-telemetry@0.0.18: + version "0.0.18" + resolved "https://registry.yarnpkg.com/vscode-extension-telemetry/-/vscode-extension-telemetry-0.0.18.tgz#602ba20d8c71453aa34533a291e7638f6e5c0327" dependencies: applicationinsights "1.0.1" From 53b5645dc2d7433dc4ebf98e102dd9e84f590514 Mon Sep 17 00:00:00 2001 From: Pine Wu Date: Mon, 30 Jul 2018 16:28:14 -0700 Subject: [PATCH 0336/1276] Pull latest css grammar --- extensions/css/syntaxes/css.tmLanguage.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/extensions/css/syntaxes/css.tmLanguage.json b/extensions/css/syntaxes/css.tmLanguage.json index f426e662f58..07977e3835a 100644 --- a/extensions/css/syntaxes/css.tmLanguage.json +++ b/extensions/css/syntaxes/css.tmLanguage.json @@ -4,7 +4,7 @@ "If you want to provide a fix or improvement, please create a pull request against the original repository.", "Once accepted there, we are happy to receive an update request." ], - "version": "https://github.com/octref/language-css/commit/f8a70d3f2540a7bf12a7cbc13c1d7bb76cc8cdd0", + "version": "https://github.com/octref/language-css/commit/aadd130de82cf2351b459041109b49f586142f11", "name": "CSS", "scopeName": "source.css", "patterns": [ @@ -508,7 +508,7 @@ ] }, { - "begin": "(?i)((@)viewport)(?=[\\s'\"{;]|/\\*|$)", + "begin": "(?i)((@)(-ms-|-o-)?viewport)(?=[\\s'\"{;]|/\\*|$)", "beginCaptures": { "1": { "name": "keyword.control.at-rule.viewport.css" From e58c103e6e809630d82d1b2bb7d74a98d7c80655 Mon Sep 17 00:00:00 2001 From: Rob Lourens Date: Mon, 30 Jul 2018 15:03:07 -0700 Subject: [PATCH 0337/1276] files.exclude control - use same style for "add" vs "edit" --- .../browser/media/settingsWidgets.css | 16 ++--- .../preferences/browser/settingsWidgets.ts | 70 ++++++++----------- 2 files changed, 39 insertions(+), 47 deletions(-) diff --git a/src/vs/workbench/parts/preferences/browser/media/settingsWidgets.css b/src/vs/workbench/parts/preferences/browser/media/settingsWidgets.css index f6b08e12198..a95f6fe028c 100644 --- a/src/vs/workbench/parts/preferences/browser/media/settingsWidgets.css +++ b/src/vs/workbench/parts/preferences/browser/media/settingsWidgets.css @@ -71,20 +71,20 @@ .settings-editor > .settings-body > .settings-tree-container .setting-item.setting-item-exclude .monaco-text-button { width: initial; - padding: 4px 10px; + padding: 2px 9px; +} + +.settings-editor > .settings-body > .settings-tree-container .setting-item.setting-item-exclude .setting-item-control.setting-exclude-new-mode .setting-exclude-new-row { + display: none; } .settings-editor > .settings-body > .settings-tree-container .setting-item.setting-item-exclude .monaco-text-button.setting-exclude-addButton { margin-right: 10px; } -.settings-editor > .settings-body > .settings-tree-container .setting-item.setting-item-exclude .setting-exclude-edit-row.setting-exclude-newExcludeItem { - display: flex; -} - .settings-editor > .settings-body > .settings-tree-container .setting-item.setting-item-exclude .setting-exclude-patternInput, -.settings-editor > .settings-body > .settings-tree-container .setting-item.setting-item-exclude .setting-exclude-siblingInput, -.settings-editor > .settings-body > .settings-tree-container .setting-item.setting-item-exclude .setting-exclude-newPatternInput { +.settings-editor > .settings-body > .settings-tree-container .setting-item.setting-item-exclude .setting-exclude-siblingInput { + height: 22px; max-width: 300px; display: inline-block; margin-right: 10px; @@ -95,5 +95,5 @@ } .settings-editor > .settings-body > .settings-tree-container .setting-item.setting-item-exclude .setting-exclude-widget { - margin-bottom: 10px; + margin-bottom: 1px; } diff --git a/src/vs/workbench/parts/preferences/browser/settingsWidgets.ts b/src/vs/workbench/parts/preferences/browser/settingsWidgets.ts index 706e5bdd9f6..88137b7e2fe 100644 --- a/src/vs/workbench/parts/preferences/browser/settingsWidgets.ts +++ b/src/vs/workbench/parts/preferences/browser/settingsWidgets.ts @@ -87,12 +87,22 @@ export class ExcludeSettingListModel { private _editKey: string; get items(): IExcludeViewItem[] { - return this._dataItems.map(item => { + const items = this._dataItems.map(item => { return { ...item, editing: item.pattern === this._editKey }; }); + + if (this._editKey === '') { + items.push({ + editing: true, + pattern: '', + sibling: '' + }); + } + + return items; } setEditKey(key: string): void { @@ -113,7 +123,6 @@ interface IExcludeChangeEvent { export class ExcludeSettingWidget extends Disposable { private listElement: HTMLElement; private listDisposables: IDisposable[] = []; - private patternInput: InputBox; private model = new ExcludeSettingListModel(); @@ -121,27 +130,29 @@ export class ExcludeSettingWidget extends Disposable { public readonly onDidChangeExclude: Event = this._onDidChangeExclude.event; constructor( - container: HTMLElement, + private container: HTMLElement, @IThemeService private themeService: IThemeService, @IContextViewService private contextViewService: IContextViewService ) { super(); this.listElement = DOM.append(container, $('.setting-exclude-widget')); - DOM.append(container, this.renderAddItem()); - this.update(); + DOM.append(container, this.renderAddButton()); + this.renderList(); } setValue(excludeData: IExcludeDataItem[]): void { this.model.setValue(excludeData); - this.patternInput.value = ''; - this.update(); + this.renderList(); } - private update(): void { + private renderList(): void { DOM.clearNode(this.listElement); this.listDisposables = dispose(this.listDisposables); + const newMode = this.model.items.some(item => item.editing && !item.pattern); + DOM.toggleClass(this.container, 'setting-exclude-new-mode', newMode); + this.model.items .map(item => this.renderItem(item)) .forEach(itemElement => this.listElement.appendChild(itemElement)); @@ -168,7 +179,7 @@ export class ExcludeSettingWidget extends Disposable { tooltip: localize('editExcludeItem', "Edit Exclude Item"), run: () => { this.model.setEditKey(key); - this.update(); + this.renderList(); } }; } @@ -201,37 +212,18 @@ export class ExcludeSettingWidget extends Disposable { return rowElement; } - private renderAddItem(): HTMLElement { + private renderAddButton(): HTMLElement { const rowElement = $('.setting-exclude-new-row'); - this.patternInput = new InputBox(rowElement, this.contextViewService, { - placeholder: localize('excludePatternInputPlaceholder', "Exclude Pattern...") - }); - this.patternInput.element.classList.add('setting-exclude-newPatternInput'); - this._register(attachInputBoxStyler(this.patternInput, this.themeService, { - inputBackground: settingsTextInputBackground, - inputForeground: settingsTextInputForeground, - inputBorder: settingsTextInputBorder + + const startAddButton = this._register(new Button(rowElement)); + startAddButton.label = localize('addPattern', "Add Pattern"); + startAddButton.element.classList.add('setting-exclude-addButton'); + this._register(attachButtonStyler(startAddButton, this.themeService)); + + this._register(startAddButton.onDidClick(() => { + this.model.setEditKey(''); + this.renderList(); })); - this._register(this.patternInput); - - const addPatternButton = this._register(new Button(rowElement)); - addPatternButton.label = localize('addPattern', "Add Pattern"); - addPatternButton.element.classList.add('setting-exclude-addButton'); - this._register(attachButtonStyler(addPatternButton, this.themeService)); - - const addItem = () => this._onDidChangeExclude.fire({ - originalPattern: undefined, - pattern: this.patternInput.value - }); - - this._register(addPatternButton.onDidClick(addItem)); - - const onKeydown = (e: StandardKeyboardEvent) => { - if (e.equals(KeyCode.Enter)) { - addItem(); - } - }; - this._register(DOM.addStandardDisposableListener(this.patternInput.inputElement, DOM.EventType.KEY_DOWN, onKeydown)); return rowElement; } @@ -248,7 +240,7 @@ export class ExcludeSettingWidget extends Disposable { sibling: siblingInput && siblingInput.value }); } else { - this.update(); + this.renderList(); } }; From 423da148d31361c923cfda443a87d84a00034711 Mon Sep 17 00:00:00 2001 From: Rob Lourens Date: Mon, 30 Jul 2018 16:33:42 -0700 Subject: [PATCH 0338/1276] files.exclude control - focus/keyboard behavior --- .../browser/media/settingsWidgets.css | 6 +- .../preferences/browser/settingsWidgets.ts | 100 ++++++++++++++++-- 2 files changed, 97 insertions(+), 9 deletions(-) diff --git a/src/vs/workbench/parts/preferences/browser/media/settingsWidgets.css b/src/vs/workbench/parts/preferences/browser/media/settingsWidgets.css index a95f6fe028c..e2e1bfa7f4f 100644 --- a/src/vs/workbench/parts/preferences/browser/media/settingsWidgets.css +++ b/src/vs/workbench/parts/preferences/browser/media/settingsWidgets.css @@ -37,8 +37,12 @@ position: relative; } +.settings-editor > .settings-body > .settings-tree-container .setting-item.setting-item-exclude .setting-exclude-row:focus { + outline: none; +} + .settings-editor > .settings-body > .settings-tree-container .setting-item.setting-item-exclude .setting-exclude-row:hover .monaco-action-bar, -.settings-editor > .settings-body > .settings-tree-container .setting-item.setting-item-exclude .setting-exclude-row.focused .monaco-action-bar { +.settings-editor > .settings-body > .settings-tree-container .setting-item.setting-item-exclude .setting-exclude-row.selected .monaco-action-bar { display: block; } diff --git a/src/vs/workbench/parts/preferences/browser/settingsWidgets.ts b/src/vs/workbench/parts/preferences/browser/settingsWidgets.ts index 88137b7e2fe..1c123e6f943 100644 --- a/src/vs/workbench/parts/preferences/browser/settingsWidgets.ts +++ b/src/vs/workbench/parts/preferences/browser/settingsWidgets.ts @@ -15,7 +15,7 @@ import { Disposable, dispose, IDisposable } from 'vs/base/common/lifecycle'; import 'vs/css!./media/settingsWidgets'; import { localize } from 'vs/nls'; import { IContextViewService } from 'vs/platform/contextview/browser/contextView'; -import { foreground, inputBackground, inputBorder, inputForeground, listHoverBackground, registerColor, selectBackground, selectBorder, selectForeground, textLinkForeground } from 'vs/platform/theme/common/colorRegistry'; +import { foreground, inputBackground, inputBorder, inputForeground, listHoverBackground, registerColor, selectBackground, selectBorder, selectForeground, textLinkForeground, listHoverForeground, listActiveSelectionBackground, listActiveSelectionForeground } from 'vs/platform/theme/common/colorRegistry'; import { attachButtonStyler, attachInputBoxStyler } from 'vs/platform/theme/common/styler'; import { ICssStyleCollector, ITheme, IThemeService, registerThemingParticipant } from 'vs/platform/theme/common/themeService'; @@ -76,27 +76,47 @@ registerThemingParticipant((theme: ITheme, collector: ICssStyleCollector) => { collector.addRule(`.settings-editor > .settings-header > .settings-header-controls .settings-tabs-widget .action-label { color: ${foregroundColor}; }`); } + // Exclude control const listHoverBackgroundColor = theme.getColor(listHoverBackground); if (listHoverBackgroundColor) { collector.addRule(`.settings-editor > .settings-body > .settings-tree-container .setting-item.setting-item-exclude .setting-exclude-row:hover { background-color: ${listHoverBackgroundColor}; }`); } + + const listHoverForegroundColor = theme.getColor(listHoverForeground); + if (listHoverForegroundColor) { + collector.addRule(`.settings-editor > .settings-body > .settings-tree-container .setting-item.setting-item-exclude .setting-exclude-row:hover { color: ${listHoverForegroundColor}; }`); + } + + const listSelectBackgroundColor = theme.getColor(listActiveSelectionBackground); + if (listSelectBackgroundColor) { + collector.addRule(`.settings-editor > .settings-body > .settings-tree-container .setting-item.setting-item-exclude .setting-exclude-row.selected { background-color: ${listSelectBackgroundColor}; }`); + } + + const listSelectForegroundColor = theme.getColor(listActiveSelectionForeground); + if (listSelectForegroundColor) { + collector.addRule(`.settings-editor > .settings-body > .settings-tree-container .setting-item.setting-item-exclude .setting-exclude-row.selected { color: ${listSelectForegroundColor}; }`); + } }); export class ExcludeSettingListModel { private _dataItems: IExcludeDataItem[] = []; - private _editKey: string; + private _editKey: string | null; + private _selectedIdx: number | null; get items(): IExcludeViewItem[] { - const items = this._dataItems.map(item => { + const items = this._dataItems.map((item, i) => { + const editing = item.pattern === this._editKey; return { ...item, - editing: item.pattern === this._editKey + editing, + selected: i === this._selectedIdx || editing }; }); if (this._editKey === '') { items.push({ editing: true, + selected: true, pattern: '', sibling: '' }); @@ -112,6 +132,26 @@ export class ExcludeSettingListModel { setValue(excludeData: IExcludeDataItem[]): void { this._dataItems = excludeData; } + + select(idx: number): void { + this._selectedIdx = idx; + } + + selectNext(): void { + if (typeof this._selectedIdx === 'number') { + this._selectedIdx = Math.min(this._selectedIdx + 1, this._dataItems.length - 1); + } else { + this._selectedIdx = 0; + } + } + + selectPrevious(): void { + if (typeof this._selectedIdx === 'number') { + this._selectedIdx = Math.max(this._selectedIdx - 1, 0); + } else { + this._selectedIdx = 0; + } + } } interface IExcludeChangeEvent { @@ -137,8 +177,41 @@ export class ExcludeSettingWidget extends Disposable { super(); this.listElement = DOM.append(container, $('.setting-exclude-widget')); + this.listElement.setAttribute('tabindex', '0'); DOM.append(container, this.renderAddButton()); this.renderList(); + + this._register(DOM.addDisposableListener(this.listElement, 'click', (e: MouseEvent) => { + if (!e.target) { + return; + } + + const element = DOM.findParentWithClass((e.target), 'setting-exclude-row'); + if (!element) { + return; + } + + const targetIdx = element.getAttribute('data-index'); + if (!targetIdx) { + return; + } + + this.model.select(parseInt(targetIdx)); + this.renderList(); + e.preventDefault(); + e.stopPropagation(); + })); + + + this._register(DOM.addStandardDisposableListener(this.listElement, 'keydown', (e: KeyboardEvent) => { + if (e.keyCode === KeyCode.UpArrow) { + this.model.selectPrevious(); + this.renderList(); + } else if (e.keyCode === KeyCode.DownArrow) { + this.model.selectNext(); + this.renderList(); + } + })); } setValue(excludeData: IExcludeDataItem[]): void { @@ -154,7 +227,7 @@ export class ExcludeSettingWidget extends Disposable { DOM.toggleClass(this.container, 'setting-exclude-new-mode', newMode); this.model.items - .map(item => this.renderItem(item)) + .map((item, i) => this.renderItem(item, i)) .forEach(itemElement => this.listElement.appendChild(itemElement)); const listHeight = 22 * this.model.items.length; @@ -184,14 +257,18 @@ export class ExcludeSettingWidget extends Disposable { }; } - private renderItem(item: IExcludeViewItem): HTMLElement { + private renderItem(item: IExcludeViewItem, idx: number): HTMLElement { return item.editing ? this.renderEditItem(item) : - this.renderDataItem(item); + this.renderDataItem(item, idx); } - private renderDataItem(item: IExcludeDataItem): HTMLElement { + private renderDataItem(item: IExcludeViewItem, idx: number): HTMLElement { const rowElement = $('.setting-exclude-row'); + rowElement.setAttribute('data-index', idx + ''); + rowElement.setAttribute('tabindex', item.selected ? '0' : '-1'); + DOM.toggleClass(rowElement, 'selected', item.selected); + const actionBar = new ActionBar(rowElement); this.listDisposables.push(actionBar); @@ -209,6 +286,12 @@ export class ExcludeSettingWidget extends Disposable { localize('excludeSiblingHintLabel', "Exclude files matching `{0}`, only when a file matching `{1}` is present", item.pattern, item.sibling) : localize('excludePatternHintLabel', "Exclude files matching `{0}`", item.pattern); + if (item.selected) { + setTimeout(() => { + rowElement.focus(); + }, 10); + } + return rowElement; } @@ -312,4 +395,5 @@ export interface IExcludeDataItem { interface IExcludeViewItem extends IExcludeDataItem { editing?: boolean; + selected?: boolean; } From 6d7c257f38793e77d3e32b76d77c8c9a4255b724 Mon Sep 17 00:00:00 2001 From: SteVen Batten Date: Mon, 30 Jul 2018 16:54:38 -0700 Subject: [PATCH 0339/1276] don't show menubar too early --- src/vs/code/electron-main/menubar.ts | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/src/vs/code/electron-main/menubar.ts b/src/vs/code/electron-main/menubar.ts index 480717e7860..76450d9930a 100644 --- a/src/vs/code/electron-main/menubar.ts +++ b/src/vs/code/electron-main/menubar.ts @@ -310,7 +310,11 @@ export class Menubar { menubar.append(helpMenuItem); } - Menu.setApplicationMenu(menubar); + if (menubar.items && menubar.items.length > 0) { + Menu.setApplicationMenu(menubar); + } else { + Menu.setApplicationMenu(null); + } } private setMacApplicationMenu(macApplicationMenu: Electron.Menu): void { @@ -370,14 +374,14 @@ export class Menubar { switch (menuId) { case 'File': case 'Help': - return true; + return isMacintosh || !!this.menubarMenus[menuId]; default: return this.windowsMainService.getWindowCount() > 0 && !!this.menubarMenus[menuId]; } } private shouldFallback(menuId: string): boolean { - return this.shouldDrawMenu(menuId) && (this.windowsMainService.getWindowCount() === 0); + return this.shouldDrawMenu(menuId) && (this.windowsMainService.getWindowCount() === 0 && isMacintosh); } private setFallbackMenuById(menu: Electron.Menu, menuId: string): void { From 9c445352cd2b357ac5147952f14b4c360170f80f Mon Sep 17 00:00:00 2001 From: Rob Lourens Date: Mon, 30 Jul 2018 16:46:07 -0700 Subject: [PATCH 0340/1276] files.exclude - better styling --- .../preferences/browser/settingsWidgets.ts | 36 ++++++++++++++----- 1 file changed, 27 insertions(+), 9 deletions(-) diff --git a/src/vs/workbench/parts/preferences/browser/settingsWidgets.ts b/src/vs/workbench/parts/preferences/browser/settingsWidgets.ts index 1c123e6f943..de45cdbae93 100644 --- a/src/vs/workbench/parts/preferences/browser/settingsWidgets.ts +++ b/src/vs/workbench/parts/preferences/browser/settingsWidgets.ts @@ -15,7 +15,7 @@ import { Disposable, dispose, IDisposable } from 'vs/base/common/lifecycle'; import 'vs/css!./media/settingsWidgets'; import { localize } from 'vs/nls'; import { IContextViewService } from 'vs/platform/contextview/browser/contextView'; -import { foreground, inputBackground, inputBorder, inputForeground, listHoverBackground, registerColor, selectBackground, selectBorder, selectForeground, textLinkForeground, listHoverForeground, listActiveSelectionBackground, listActiveSelectionForeground } from 'vs/platform/theme/common/colorRegistry'; +import { foreground, inputBackground, inputBorder, inputForeground, listHoverBackground, registerColor, selectBackground, selectBorder, selectForeground, textLinkForeground, listHoverForeground, listActiveSelectionBackground, listActiveSelectionForeground, listInactiveSelectionBackground, listInactiveSelectionForeground } from 'vs/platform/theme/common/colorRegistry'; import { attachButtonStyler, attachInputBoxStyler } from 'vs/platform/theme/common/styler'; import { ICssStyleCollector, ITheme, IThemeService, registerThemingParticipant } from 'vs/platform/theme/common/themeService'; @@ -89,7 +89,17 @@ registerThemingParticipant((theme: ITheme, collector: ICssStyleCollector) => { const listSelectBackgroundColor = theme.getColor(listActiveSelectionBackground); if (listSelectBackgroundColor) { - collector.addRule(`.settings-editor > .settings-body > .settings-tree-container .setting-item.setting-item-exclude .setting-exclude-row.selected { background-color: ${listSelectBackgroundColor}; }`); + collector.addRule(`.settings-editor > .settings-body > .settings-tree-container .setting-item.setting-item-exclude .setting-exclude-row:focus { background-color: ${listSelectBackgroundColor}; }`); + } + + const listInactiveSelectionBackgroundColor = theme.getColor(listInactiveSelectionBackground); + if (listInactiveSelectionBackgroundColor) { + collector.addRule(`.settings-editor > .settings-body > .settings-tree-container .setting-item.setting-item-exclude .setting-exclude-row.selected:not(:focus) { background-color: ${listInactiveSelectionBackgroundColor}; }`); + } + + const listInactiveSelectionForegroundColor = theme.getColor(listInactiveSelectionForeground); + if (listInactiveSelectionForegroundColor) { + collector.addRule(`.settings-editor > .settings-body > .settings-tree-container .setting-item.setting-item-exclude .setting-exclude-row.selected:not(:focus) { color: ${listInactiveSelectionForegroundColor}; }`); } const listSelectForegroundColor = theme.getColor(listActiveSelectionForeground); @@ -207,9 +217,13 @@ export class ExcludeSettingWidget extends Disposable { if (e.keyCode === KeyCode.UpArrow) { this.model.selectPrevious(); this.renderList(); + e.preventDefault(); + e.stopPropagation(); } else if (e.keyCode === KeyCode.DownArrow) { this.model.selectNext(); this.renderList(); + e.preventDefault(); + e.stopPropagation(); } })); } @@ -220,6 +234,8 @@ export class ExcludeSettingWidget extends Disposable { } private renderList(): void { + const focused = DOM.isAncestor(document.activeElement, this.listElement); + DOM.clearNode(this.listElement); this.listDisposables = dispose(this.listDisposables); @@ -227,7 +243,7 @@ export class ExcludeSettingWidget extends Disposable { DOM.toggleClass(this.container, 'setting-exclude-new-mode', newMode); this.model.items - .map((item, i) => this.renderItem(item, i)) + .map((item, i) => this.renderItem(item, i, focused)) .forEach(itemElement => this.listElement.appendChild(itemElement)); const listHeight = 22 * this.model.items.length; @@ -257,13 +273,13 @@ export class ExcludeSettingWidget extends Disposable { }; } - private renderItem(item: IExcludeViewItem, idx: number): HTMLElement { + private renderItem(item: IExcludeViewItem, idx: number, listFocused: boolean): HTMLElement { return item.editing ? this.renderEditItem(item) : - this.renderDataItem(item, idx); + this.renderDataItem(item, idx, listFocused); } - private renderDataItem(item: IExcludeViewItem, idx: number): HTMLElement { + private renderDataItem(item: IExcludeViewItem, idx: number, listFocused: boolean): HTMLElement { const rowElement = $('.setting-exclude-row'); rowElement.setAttribute('data-index', idx + ''); rowElement.setAttribute('tabindex', item.selected ? '0' : '-1'); @@ -287,9 +303,11 @@ export class ExcludeSettingWidget extends Disposable { localize('excludePatternHintLabel', "Exclude files matching `{0}`", item.pattern); if (item.selected) { - setTimeout(() => { - rowElement.focus(); - }, 10); + if (listFocused) { + setTimeout(() => { + rowElement.focus(); + }, 10); + } } return rowElement; From 488465194e1ad876f453d67a2effd04b113b7435 Mon Sep 17 00:00:00 2001 From: Jackson Kearl Date: Mon, 30 Jul 2018 17:03:36 -0700 Subject: [PATCH 0341/1276] Place cursor at end of extensions search box on autofill (#55254) * Place cursor at end of extensions search box on autofill * Use position instead of selection --- .../parts/extensions/electron-browser/extensionsViewlet.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/src/vs/workbench/parts/extensions/electron-browser/extensionsViewlet.ts b/src/vs/workbench/parts/extensions/electron-browser/extensionsViewlet.ts index 67115759ef2..22399279075 100644 --- a/src/vs/workbench/parts/extensions/electron-browser/extensionsViewlet.ts +++ b/src/vs/workbench/parts/extensions/electron-browser/extensionsViewlet.ts @@ -486,6 +486,7 @@ export class ExtensionsViewlet extends ViewContainerViewlet implements IExtensio event.immediate = true; this.searchBox.setValue(value); + this.searchBox.setPosition(new Position(1, value.length + 1)); } private triggerSearch(immediate = false): void { From e466293f2bc69af88decd47232ca2f54c03faabb Mon Sep 17 00:00:00 2001 From: SteVen Batten Date: Mon, 30 Jul 2018 20:37:20 -0700 Subject: [PATCH 0342/1276] fix linux build issue (empty if block) --- build/tfs/linux/product-build-linux.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/build/tfs/linux/product-build-linux.yml b/build/tfs/linux/product-build-linux.yml index 79675e4627c..9505d71ff34 100644 --- a/build/tfs/linux/product-build-linux.yml +++ b/build/tfs/linux/product-build-linux.yml @@ -103,10 +103,10 @@ steps: # Write config files needed by API, use eval to force environment variable expansion pushd build/tfs/linux # Submit to apt repo - if [ "$DEB_ARCH" = "amd64" ]; then + # if [ "$DEB_ARCH" = "amd64" ]; then # echo "{ \"server\": \"azure-apt-cat.cloudapp.net\", \"protocol\": \"https\", \"port\": \"443\", \"repositoryId\": \"58a4adf642421134a1a48d1a\", \"username\": \"vscode\", \"password\": \"$(LINUX_REPO_PASSWORD)\" }" > apt-config.json # ./repoapi_client.sh -config apt-config.json -addfile $DEB_PATH - fi + # fi # Submit to yum repo (disabled as it's manual until signing is automated) # eval echo '{ \"server\": \"azure-apt-cat.cloudapp.net\", \"protocol\": \"https\", \"port\": \"443\", \"repositoryId\": \"58a4ae3542421134a1a48d1b\", \"username\": \"vscode\", \"password\": \"$(LINUX_REPO_PASSWORD)\" }' > yum-config.json From 000146931d332c218cdf0963ec6759d789daf96c Mon Sep 17 00:00:00 2001 From: Rob Lourens Date: Mon, 30 Jul 2018 21:14:54 -0700 Subject: [PATCH 0343/1276] Settings editor - fix extension category prefixes --- .../parts/preferences/browser/settingsTree.ts | 11 ++++++----- .../preferences/test/browser/settingsTree.test.ts | 11 +++++++++-- .../common/configurationExtensionPoint.ts | 2 +- 3 files changed, 16 insertions(+), 8 deletions(-) diff --git a/src/vs/workbench/parts/preferences/browser/settingsTree.ts b/src/vs/workbench/parts/preferences/browser/settingsTree.ts index 2101fdd3897..da45292f34d 100644 --- a/src/vs/workbench/parts/preferences/browser/settingsTree.ts +++ b/src/vs/workbench/parts/preferences/browser/settingsTree.ts @@ -402,17 +402,18 @@ export class SettingsDataSource implements IDataSource { } export function settingKeyToDisplayFormat(key: string, groupId = ''): { category: string, label: string } { - let label = wordifyKey(key); - const lastDotIdx = label.lastIndexOf('.'); + const lastDotIdx = key.lastIndexOf('.'); let category = ''; if (lastDotIdx >= 0) { - category = label.substr(0, lastDotIdx); - label = label.substr(lastDotIdx + 1); + category = key.substr(0, lastDotIdx); + key = key.substr(lastDotIdx + 1); } - groupId = wordifyKey(groupId.replace(/\//g, '.')); + groupId = groupId.replace(/\//g, '.'); category = trimCategoryForGroup(category, groupId); + category = wordifyKey(category); + const label = wordifyKey(key); return { category, label }; } diff --git a/src/vs/workbench/parts/preferences/test/browser/settingsTree.test.ts b/src/vs/workbench/parts/preferences/test/browser/settingsTree.test.ts index a1d32f71ac6..06517a42795 100644 --- a/src/vs/workbench/parts/preferences/test/browser/settingsTree.test.ts +++ b/src/vs/workbench/parts/preferences/test/browser/settingsTree.test.ts @@ -47,6 +47,13 @@ suite('SettingsTree', () => { label: 'Bar' }); + assert.deepEqual( + settingKeyToDisplayFormat('disableligatures.ligatures', 'disableligatures'), + { + category: '', + label: 'Ligatures' + }); + assert.deepEqual( settingKeyToDisplayFormat('foo.bar.etc', 'foo'), { @@ -62,14 +69,14 @@ suite('SettingsTree', () => { }); assert.deepEqual( - settingKeyToDisplayFormat('foo.bar.etc', 'foo.bar'), + settingKeyToDisplayFormat('foo.bar.etc', 'foo/bar'), { category: '', label: 'Etc' }); assert.deepEqual( - settingKeyToDisplayFormat('foo.bar.etc', 'something.foo'), + settingKeyToDisplayFormat('foo.bar.etc', 'something/foo'), { category: 'Bar', label: 'Etc' diff --git a/src/vs/workbench/services/configuration/common/configurationExtensionPoint.ts b/src/vs/workbench/services/configuration/common/configurationExtensionPoint.ts index 6b55d1b1930..6197ea71e29 100644 --- a/src/vs/workbench/services/configuration/common/configurationExtensionPoint.ts +++ b/src/vs/workbench/services/configuration/common/configurationExtensionPoint.ts @@ -113,7 +113,7 @@ configurationExtPoint.setHandler(extensions => { validateProperties(configuration, extension); - configuration.id = node.id || extension.description.uuid || extension.description.id; + configuration.id = node.id || extension.description.id || extension.description.uuid; configuration.contributedByExtension = true; configuration.title = configuration.title || extension.description.displayName || extension.description.id; configurations.push(configuration); From 0707dd4940b3fdbea8339595de478f354f6dda83 Mon Sep 17 00:00:00 2001 From: Rob Lourens Date: Mon, 30 Jul 2018 21:29:56 -0700 Subject: [PATCH 0344/1276] Settings editor - add simple ellipsis for first line that overflows, doesn't cover case when first line does not overflow but there is more text, TODO --- .../parts/preferences/browser/media/settingsEditor2.css | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/vs/workbench/parts/preferences/browser/media/settingsEditor2.css b/src/vs/workbench/parts/preferences/browser/media/settingsEditor2.css index e04004d4969..6d25aa01849 100644 --- a/src/vs/workbench/parts/preferences/browser/media/settingsEditor2.css +++ b/src/vs/workbench/parts/preferences/browser/media/settingsEditor2.css @@ -269,6 +269,9 @@ .settings-editor > .settings-body > .settings-tree-container .setting-item .setting-item-description { overflow: hidden; height: 18px; + display: -webkit-box; + -webkit-line-clamp: 1; + -webkit-box-orient: vertical; } .settings-editor > .settings-body > .settings-tree-container .setting-item .setting-item-description * { @@ -288,6 +291,7 @@ .settings-editor > .settings-body > .settings-tree-container .setting-item.is-expanded .setting-item-description, .settings-editor > .settings-body > .settings-tree-container .setting-item.setting-measure-helper .setting-item-description { height: initial; + -webkit-line-clamp: initial; } .settings-editor > .settings-body > .settings-tree-container .setting-description-measure-container .setting-item .setting-item-description, From f35b6ce8d8a24f2dcf756d8bd6e2069dd4f25cc9 Mon Sep 17 00:00:00 2001 From: Rob Lourens Date: Mon, 30 Jul 2018 22:06:42 -0700 Subject: [PATCH 0345/1276] File/Text search provider docs --- src/vs/vscode.proposed.d.ts | 74 +++++++++++++++++++++++++------------ 1 file changed, 50 insertions(+), 24 deletions(-) diff --git a/src/vs/vscode.proposed.d.ts b/src/vs/vscode.proposed.d.ts index efd2ed56157..8d6261752bb 100644 --- a/src/vs/vscode.proposed.d.ts +++ b/src/vs/vscode.proposed.d.ts @@ -153,23 +153,36 @@ declare module 'vscode' { preview: TextSearchResultPreview; } + /** + * A FileIndexProvider provides a list of files in the given folder. VS Code will filter that list for searching with quickopen or from other extensions. + * + * A FileIndexProvider is the simpler of two ways to implement file search in VS Code. Use a FileIndexProvider if you are able to provide a listing of all files + * in a folder, and want VS Code to filter them according to the user's search query. + * + * The FileIndexProvider will be invoked once when quickopen is opened, and VS Code will filter the returned list. It will also be invoked when + * `workspace.findFiles` is called. + * + * If a [`FileSearchProvider`](#FileSearchProvider) is registered for the scheme, that provider will be used instead. + */ export interface FileIndexProvider { + /** + * Provide the set of files in the folder. + * @param options A set of options to consider while searching. + * @param token A cancellation token. + */ provideFileIndex(options: FileSearchOptions, token: CancellationToken): Thenable; } - export interface TextSearchProvider { - /** - * Provide results that match the given text pattern. - * @param query The parameters for this query. - * @param options A set of options to consider while searching. - * @param progress A progress callback that must be invoked for all results. - * @param token A cancellation token. - */ - provideTextSearchResults(query: TextSearchQuery, options: TextSearchOptions, progress: Progress, token: CancellationToken): Thenable; - } - /** - * A FileSearchProvider provides search results for files or text in files. It can be invoked by quickopen and other extensions. + * A FileSearchProvider provides search results for files in the given folder that match a query string. It can be invoked by quickopen or other extensions. + * + * A FileSearchProvider is the more powerful of two ways to implement file search in VS Code. Use a FileSearchProvider if you wish to search within a folder for + * all files that match the user's query. + * + * The FileSearchProvider will be invoked on every keypress in quickopen. When `workspace.findFiles` is called, it will be invoked with an empty query string, + * and in that case, every file in the folder should be returned. + * + * @see [FileIndexProvider](#FileIndexProvider) */ export interface FileSearchProvider { /** @@ -182,6 +195,20 @@ declare module 'vscode' { provideFileSearchResults(query: FileSearchQuery, options: FileSearchOptions, progress: Progress, token: CancellationToken): Thenable; } + /** + * A TextSearchProvider provides search results for text results inside files in the workspace. + */ + export interface TextSearchProvider { + /** + * Provide results that match the given text pattern. + * @param query The parameters for this query. + * @param options A set of options to consider while searching. + * @param progress A progress callback that must be invoked for all results. + * @param token A cancellation token. + */ + provideTextSearchResults(query: TextSearchQuery, options: TextSearchOptions, progress: Progress, token: CancellationToken): Thenable; + } + /** * Options that can be set on a findTextInFiles search. */ @@ -230,6 +257,17 @@ declare module 'vscode' { */ export function registerSearchProvider(): Disposable; + /** + * Register a file index provider. + * + * Only one provider can be registered per scheme. + * + * @param scheme The provider will be invoked for workspace folders that have this file scheme. + * @param provider The provider. + * @return A [disposable](#Disposable) that unregisters this provider when being disposed. + */ + export function registerFileIndexProvider(scheme: string, provider: FileIndexProvider): Disposable; + /** * Register a search provider. * @@ -252,18 +290,6 @@ declare module 'vscode' { */ export function registerTextSearchProvider(scheme: string, provider: TextSearchProvider): Disposable; - /** - * Register a file index provider. - * - * Only one provider can be registered per scheme. - * - * @param scheme The provider will be invoked for workspace folders that have this file scheme. - * @param provider The provider. - * @return A [disposable](#Disposable) that unregisters this provider when being disposed. - */ - export function registerFileIndexProvider(scheme: string, provider: FileIndexProvider): Disposable; - - /** * Search text in files across all [workspace folders](#workspace.workspaceFolders) in the workspace. * @param query The query parameters for the search - the search string, whether it's case-sensitive, or a regex, or matches whole words. From c7a9eb8cd228bff532a98599f1a7640158df45fb Mon Sep 17 00:00:00 2001 From: Peng Lyu Date: Wed, 25 Jul 2018 17:02:35 +0800 Subject: [PATCH 0346/1276] comment affordance in line decorations area. --- .../commentsEditorContribution.ts | 189 ++++++++++++++++-- .../electron-browser/media/review.css | 25 ++- 2 files changed, 191 insertions(+), 23 deletions(-) diff --git a/src/vs/workbench/parts/comments/electron-browser/commentsEditorContribution.ts b/src/vs/workbench/parts/comments/electron-browser/commentsEditorContribution.ts index 2b088806cbf..6da71013116 100644 --- a/src/vs/workbench/parts/comments/electron-browser/commentsEditorContribution.ts +++ b/src/vs/workbench/parts/comments/electron-browser/commentsEditorContribution.ts @@ -10,18 +10,19 @@ import { $ } from 'vs/base/browser/builder'; import { findFirstInSorted } from 'vs/base/common/arrays'; import { KeyCode, KeyMod } from 'vs/base/common/keyCodes'; import { IDisposable, dispose } from 'vs/base/common/lifecycle'; -import { ICodeEditor, IEditorMouseEvent, IViewZone } from 'vs/editor/browser/editorBrowser'; +import { ICodeEditor, IEditorMouseEvent, IViewZone, MouseTargetType } from 'vs/editor/browser/editorBrowser'; import { registerEditorContribution, EditorAction, registerEditorAction } from 'vs/editor/browser/editorExtensions'; import { ICodeEditorService } from 'vs/editor/browser/services/codeEditorService'; import { EmbeddedCodeEditorWidget } from 'vs/editor/browser/widget/embeddedCodeEditorWidget'; import { IEditorContribution } from 'vs/editor/common/editorCommon'; +import { Range } from 'vs/editor/common/core/range'; import * as modes from 'vs/editor/common/modes'; import { peekViewEditorBackground, peekViewResultsBackground, peekViewResultsSelectionBackground } from 'vs/editor/contrib/referenceSearch/referencesWidget'; import { IContextKey, IContextKeyService, RawContextKey } from 'vs/platform/contextkey/common/contextkey'; import { ServicesAccessor, IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; import { KeybindingsRegistry, KeybindingWeight } from 'vs/platform/keybinding/common/keybindingsRegistry'; import { INotificationService } from 'vs/platform/notification/common/notification'; -import { editorForeground } from 'vs/platform/theme/common/colorRegistry'; +import { editorForeground, registerColor } from 'vs/platform/theme/common/colorRegistry'; import { IThemeService, registerThemingParticipant } from 'vs/platform/theme/common/themeService'; import { CommentThreadCollapsibleState } from 'vs/workbench/api/node/extHostTypes'; import { ReviewModel } from 'vs/workbench/parts/comments/common/reviewModel'; @@ -31,6 +32,10 @@ import { ICommentService } from 'vs/workbench/parts/comments/electron-browser/co import { IModelService } from 'vs/editor/common/services/modelService'; import { IModeService } from 'vs/editor/common/services/modeService'; import { IOpenerService } from 'vs/platform/opener/common/opener'; +import { ModelDecorationOptions } from 'vs/editor/common/model/textModel'; +import { IModelDecorationOptions } from 'vs/editor/common/model'; +import { Color, RGBA } from 'vs/base/common/color'; +import { IMarginData } from 'vs/editor/browser/controller/mouseTarget'; export const ctxReviewPanelVisible = new RawContextKey('reviewPanelVisible', false); @@ -53,6 +58,59 @@ export class ReviewViewZone implements IViewZone { } } +const overviewRulerDefault = new Color(new RGBA(255, 69, 0, 1)); + +export const overviewRulerCommentingRangeForeground = registerColor('editorOverviewRuler.addedForeground', { dark: overviewRulerDefault, light: overviewRulerDefault, hc: overviewRulerDefault }, nls.localize('overviewRulerAddedForeground', 'Overview ruler marker color for added content.')); + +class CommentingRangeDecorator { + + static createDecoration(className: string, foregroundColor: string, options: { gutter: boolean, overview: boolean }): ModelDecorationOptions { + const decorationOptions: IModelDecorationOptions = { + isWholeLine: true, + }; + + decorationOptions.linesDecorationsClassName = `comment-dirty-diff-glyph ${className}`; + return ModelDecorationOptions.createDynamic(decorationOptions); + } + + private commentingOptions: ModelDecorationOptions; + private decorations: string[] = []; + private disposables: IDisposable[] = []; + + constructor( + ) { + const options = { gutter: true, overview: false }; + this.commentingOptions = CommentingRangeDecorator.createDecoration('comment-diff-added', overviewRulerCommentingRangeForeground, options); + } + + update(editor: ICodeEditor, ranges: Range[]) { + let model = editor.getModel(); + if (!model) { + return; + } + + let decorations = ranges.map((change) => { + const startLineNumber = change.startLineNumber; + const endLineNumber = change.endLineNumber; + + return { + range: { + startLineNumber: startLineNumber, startColumn: 1, + endLineNumber: endLineNumber, endColumn: 1 + }, + options: this.commentingOptions + }; + }); + + this.decorations = model.deltaDecorations(this.decorations, decorations); + } + + dispose(): void { + this.disposables = dispose(this.disposables); + this.decorations = []; + } +} + export class ReviewController implements IEditorContribution { private globalToDispose: IDisposable[]; private localToDispose: IDisposable[]; @@ -63,7 +121,10 @@ export class ReviewController implements IEditorContribution { private _commentInfos: modes.CommentInfo[]; private _reviewModel: ReviewModel; private _newCommentGlyph: CommentGlyphWidget; - private _hasSetComments: boolean; + // private _hasSetComments: boolean; + private _commentingRangeDecorator: CommentingRangeDecorator; + private mouseDownInfo: { lineNumber: number } | null = null; + constructor( editor: ICodeEditor, @@ -84,10 +145,11 @@ export class ReviewController implements IEditorContribution { this._commentWidgets = []; this._newCommentWidget = null; this._newCommentGlyph = null; - this._hasSetComments = false; + // this._hasSetComments = false; this._reviewPanelVisible = ctxReviewPanelVisible.bindTo(contextKeyService); this._reviewModel = new ReviewModel(); + this._commentingRangeDecorator = new CommentingRangeDecorator(); this._reviewModel.onDidChangeStyle(style => { if (this._newCommentWidget) { @@ -242,7 +304,8 @@ export class ReviewController implements IEditorContribution { }); this._commentWidgets = []; - this.localToDispose.push(this.editor.onMouseMove(e => this.onEditorMouseMove(e))); + this.localToDispose.push(this.editor.onMouseDown(e => this.onEditorMouseDown(e))); + this.localToDispose.push(this.editor.onMouseUp(e => this.onEditorMouseUp(e))); this.localToDispose.push(this.editor.onMouseLeave(() => this.onMouseLeave())); this.localToDispose.push(this.editor.onDidChangeModelContent(() => { if (this._newCommentGlyph) { @@ -313,28 +376,94 @@ export class ReviewController implements IEditorContribution { this._newCommentWidget.display(lineNumber); } - private onEditorMouseMove(e: IEditorMouseEvent): void { - if (!this._hasSetComments) { + /* private onEditorMouseMove(e: IEditorMouseEvent): void { + if (!this._hasSetComments) { + return; + } + + if (!this.editor.hasTextFocus()) { + return; + } + + const hasCommentingRanges = this._commentInfos.length && this._commentInfos.some(info => !!info.commentingRanges.length); + if (hasCommentingRanges && e.target.position && e.target.position.lineNumber !== undefined) { + if (this._newCommentGlyph && e.target.element.className !== 'comment-hint') { + this.editor.removeContentWidget(this._newCommentGlyph); + } + + const lineNumber = e.target.position.lineNumber; + if (!this.isExistingCommentThreadAtLine(lineNumber)) { + this._newCommentGlyph = this.isLineInCommentingRange(lineNumber) + ? this._newCommentGlyph = new CommentGlyphWidget('comment-hint', this.editor, lineNumber, false, () => { + this.addComment(lineNumber); + }) + : this._newCommentGlyph = new CommentGlyphWidget('comment-hint', this.editor, lineNumber, true, () => { + this.notificationService.warn('Commenting is not supported outside of diff hunk areas.'); + }); + + this.editor.layoutContentWidget(this._newCommentGlyph); + } + } + } */ + + private onEditorMouseDown(e: IEditorMouseEvent): void { + this.mouseDownInfo = null; + + const range = e.target.range; + + if (!range) { return; } - const hasCommentingRanges = this._commentInfos.length && this._commentInfos.some(info => !!info.commentingRanges.length); - if (hasCommentingRanges && e.target.position && e.target.position.lineNumber !== undefined) { - if (this._newCommentGlyph && e.target.element.className !== 'comment-hint') { - this.editor.removeContentWidget(this._newCommentGlyph); - } + if (!e.event.leftButton) { + return; + } + if (e.target.type !== MouseTargetType.GUTTER_LINE_DECORATIONS) { + return; + } + + const data = e.target.detail as IMarginData; + const gutterOffsetX = data.offsetX - data.glyphMarginWidth - data.lineNumbersWidth - data.glyphMarginLeft; + + // TODO@joao TODO@alex TODO@martin this is such that we don't collide with folding + if (gutterOffsetX > 10) { + return; + } + + this.mouseDownInfo = { lineNumber: range.startLineNumber }; + } + + private onEditorMouseUp(e: IEditorMouseEvent): void { + if (!this.mouseDownInfo) { + return; + } + + const { lineNumber } = this.mouseDownInfo; + this.mouseDownInfo = null; + + const range = e.target.range; + + if (!range || range.startLineNumber !== lineNumber) { + return; + } + + if (e.target.type !== MouseTargetType.GUTTER_LINE_DECORATIONS) { + return; + } + + if (!e.target.element) { + return; + } + + if (e.target.element.className.indexOf('comment-dirty-diff-glyph') >= 0) { const lineNumber = e.target.position.lineNumber; if (!this.isExistingCommentThreadAtLine(lineNumber)) { - this._newCommentGlyph = this.isLineInCommentingRange(lineNumber) - ? this._newCommentGlyph = new CommentGlyphWidget('comment-hint', this.editor, lineNumber, false, () => { - this.addComment(lineNumber); - }) - : this._newCommentGlyph = new CommentGlyphWidget('comment-hint', this.editor, lineNumber, true, () => { - this.notificationService.warn('Commenting is not supported outside of diff hunk areas.'); - }); - - this.editor.layoutContentWidget(this._newCommentGlyph); + if (this.isLineInCommentingRange(lineNumber)) { + this.addComment(lineNumber); + } else { + this.notificationService.warn('Commenting is not supported outside of diff hunk areas.'); + } } } } @@ -385,7 +514,7 @@ export class ReviewController implements IEditorContribution { setComments(commentInfos: modes.CommentInfo[]): void { this._commentInfos = commentInfos; - this._hasSetComments = true; + // this._hasSetComments = true; // create viewzones this._commentWidgets.forEach(zone => { @@ -399,6 +528,10 @@ export class ReviewController implements IEditorContribution { this._commentWidgets.push(zoneWidget); }); }); + + const commentingRanges = []; + this._commentInfos.forEach(info => commentingRanges.push(...info.commentingRanges)); + this._commentingRangeDecorator.update(this.editor, commentingRanges); } @@ -518,4 +651,16 @@ registerThemingParticipant((theme, collector) => { `}` ); } + + const commentingRangeForeground = theme.getColor(overviewRulerCommentingRangeForeground); + if (commentingRangeForeground) { + collector.addRule(` + .monaco-editor .comment-diff-added { + border-left: 3px solid ${commentingRangeForeground}; + } + .monaco-editor .comment-diff-added:before { + background: ${commentingRangeForeground}; + } + `); + } }); diff --git a/src/vs/workbench/parts/comments/electron-browser/media/review.css b/src/vs/workbench/parts/comments/electron-browser/media/review.css index dd28fb338ef..a01ef1ed9ed 100644 --- a/src/vs/workbench/parts/comments/electron-browser/media/review.css +++ b/src/vs/workbench/parts/comments/electron-browser/media/review.css @@ -10,7 +10,7 @@ background-position: center center; } -.monaco-editor .comment-hint{ +.monaco-editor .comment-hint { height: 20px; width: 20px; padding-left: 2px; @@ -239,4 +239,27 @@ .monaco-editor .review-widget>.body { border-top: 1px solid; position: relative; +} + +.monaco-editor .comment-dirty-diff-glyph { + margin-left: 1px; + cursor: pointer; +} + +.monaco-editor .comment-dirty-diff-glyph:before { + position: absolute; + content: ''; + height: 100%; + width: 0; + left: -2px; + transition: width 80ms linear, left 80ms linear; +} + +.monaco-editor .margin-view-overlays>div:hover>.comment-dirty-diff-glyph:before { + position: absolute; + content: '+'; + height: 100%; + width: 8px; + left: -4px; + z-index: 10; } \ No newline at end of file From 9a5f305193fcc20c87862058b7de43defaa5801c Mon Sep 17 00:00:00 2001 From: Peng Lyu Date: Fri, 27 Jul 2018 10:40:26 +0800 Subject: [PATCH 0347/1276] Grey color. --- .../comments/electron-browser/commentsEditorContribution.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vs/workbench/parts/comments/electron-browser/commentsEditorContribution.ts b/src/vs/workbench/parts/comments/electron-browser/commentsEditorContribution.ts index 6da71013116..7f0dea1edf0 100644 --- a/src/vs/workbench/parts/comments/electron-browser/commentsEditorContribution.ts +++ b/src/vs/workbench/parts/comments/electron-browser/commentsEditorContribution.ts @@ -58,7 +58,7 @@ export class ReviewViewZone implements IViewZone { } } -const overviewRulerDefault = new Color(new RGBA(255, 69, 0, 1)); +const overviewRulerDefault = new Color(new RGBA(197, 197, 197, 1)); export const overviewRulerCommentingRangeForeground = registerColor('editorOverviewRuler.addedForeground', { dark: overviewRulerDefault, light: overviewRulerDefault, hc: overviewRulerDefault }, nls.localize('overviewRulerAddedForeground', 'Overview ruler marker color for added content.')); From 6cdbbdc2d602253b33d0f93c38b85ccf627a6885 Mon Sep 17 00:00:00 2001 From: Peng Lyu Date: Mon, 30 Jul 2018 14:39:02 +0800 Subject: [PATCH 0348/1276] put commenting ranges affordance into line decorations area. --- src/vs/editor/common/config/editorOptions.ts | 2 +- .../electron-browser/commentGlyphWidget.ts | 41 +++-- .../electron-browser/commentThreadWidget.ts | 74 +++++---- .../commentsEditorContribution.ts | 146 +++++++++--------- .../electron-browser/media/review.css | 23 ++- 5 files changed, 159 insertions(+), 127 deletions(-) diff --git a/src/vs/editor/common/config/editorOptions.ts b/src/vs/editor/common/config/editorOptions.ts index 75fd5559db8..35c16ff732d 100644 --- a/src/vs/editor/common/config/editorOptions.ts +++ b/src/vs/editor/common/config/editorOptions.ts @@ -1543,7 +1543,7 @@ function _stringSet(value: T, defaultValue: T, allowedValues: T[]): T { return value; } -function _clampedInt(value: any, defaultValue: number, minimum: number, maximum: number): number { +export function _clampedInt(value: any, defaultValue: number, minimum: number, maximum: number): number { let r: number; if (typeof value === 'undefined') { r = defaultValue; diff --git a/src/vs/workbench/parts/comments/electron-browser/commentGlyphWidget.ts b/src/vs/workbench/parts/comments/electron-browser/commentGlyphWidget.ts index 44d7a10810e..b05c049300e 100644 --- a/src/vs/workbench/parts/comments/electron-browser/commentGlyphWidget.ts +++ b/src/vs/workbench/parts/comments/electron-browser/commentGlyphWidget.ts @@ -4,37 +4,38 @@ *--------------------------------------------------------------------------------------------*/ 'use strict'; -import { ICodeEditor, IContentWidget, IContentWidgetPosition, ContentWidgetPositionPreference } from 'vs/editor/browser/editorBrowser'; +import { ICodeEditor, IContentWidgetPosition, ContentWidgetPositionPreference } from 'vs/editor/browser/editorBrowser'; +import { ModelDecorationOptions } from 'vs/editor/common/model/textModel'; -export class CommentGlyphWidget implements IContentWidget { - private _id: string; +export class CommentGlyphWidget { private _lineNumber: number; - private _domNode: HTMLDivElement; private _editor: ICodeEditor; + private commentsDecorations: string[] = []; + private _commentsOptions: ModelDecorationOptions; - constructor(id: string, editor: ICodeEditor, lineNumber: number, disabled: boolean, onClick: () => void) { - this._id = id; - this._domNode = document.createElement('div'); - this._domNode.className = disabled ? 'comment-hint commenting-disabled' : 'comment-hint'; - this._domNode.addEventListener('click', onClick); + constructor(editor: ICodeEditor, lineNumber: number, commentsOptions: ModelDecorationOptions, onClick: () => void) { + this._commentsOptions = commentsOptions; this._lineNumber = lineNumber; - this._editor = editor; - this._editor.addContentWidget(this); - + this.update(); } - getDomNode(): HTMLElement { - return this._domNode; - } + update() { + let commentsDecorations = [{ + range: { + startLineNumber: this._lineNumber, startColumn: 1, + endLineNumber: this._lineNumber, endColumn: 1 + }, + options: this._commentsOptions + }]; - getId(): string { - return this._id; + this.commentsDecorations = this._editor.getModel().deltaDecorations(this.commentsDecorations, commentsDecorations); } setLineNumber(lineNumber: number): void { this._lineNumber = lineNumber; + this.update(); } getPosition(): IContentWidgetPosition { @@ -46,4 +47,10 @@ export class CommentGlyphWidget implements IContentWidget { preference: [ContentWidgetPositionPreference.EXACT] }; } + + dispose() { + if (this.commentsDecorations) { + this._editor.deltaDecorations(this.commentsDecorations, []); + } + } } \ No newline at end of file diff --git a/src/vs/workbench/parts/comments/electron-browser/commentThreadWidget.ts b/src/vs/workbench/parts/comments/electron-browser/commentThreadWidget.ts index 41fd94bf268..763a07cd439 100644 --- a/src/vs/workbench/parts/comments/electron-browser/commentThreadWidget.ts +++ b/src/vs/workbench/parts/comments/electron-browser/commentThreadWidget.ts @@ -34,6 +34,8 @@ import { Range, IRange } from 'vs/editor/common/core/range'; import { IPosition } from 'vs/editor/common/core/position'; import { IOpenerService } from 'vs/platform/opener/common/opener'; import { MarkdownRenderer } from 'vs/editor/contrib/markdown/markdownRenderer'; +import { IMarginData } from 'vs/editor/browser/controller/mouseTarget'; +import { ModelDecorationOptions } from 'vs/editor/common/model/textModel'; export const COMMENTEDITOR_DECORATION_KEY = 'commenteditordecoration'; const EXPAND_ACTION_CLASS = 'expand-review-action octicon octicon-chevron-down'; @@ -287,11 +289,10 @@ export class ReviewZoneWidget extends ZoneWidget { this._commentEditor.layout({ height: (this._commentEditor.hasWidgetFocus() ? 5 : 1) * 18, width: widthInPixel - 40 /* margin */ }); } - display(lineNumber: number) { - this._commentGlyph = new CommentGlyphWidget(`review_${lineNumber}`, this.editor, lineNumber, false, () => { + display(lineNumber: number, commentsOptions: ModelDecorationOptions) { + this._commentGlyph = new CommentGlyphWidget(this.editor, lineNumber, commentsOptions, () => { this.toggleExpand(); }); - this.editor.layoutContentWidget(this._commentGlyph); this._localToDispose.push(this.editor.onMouseDown(e => this.onEditorMouseDown(e))); this._localToDispose.push(this.editor.onMouseUp(e => this.onEditorMouseUp(e))); @@ -300,7 +301,6 @@ export class ReviewZoneWidget extends ZoneWidget { if (this.position) { if (this.position.lineNumber !== this._commentGlyph.getPosition().position.lineNumber) { this._commentGlyph.setLineNumber(this.position.lineNumber); - this.editor.layoutContentWidget(this._commentGlyph); } } else { // Otherwise manually calculate position change :( @@ -312,7 +312,6 @@ export class ReviewZoneWidget extends ZoneWidget { } }).reduce((prev, curr) => prev + curr, 0); this._commentGlyph.setLineNumber(this._commentGlyph.getPosition().position.lineNumber + positionChange); - this.editor.layoutContentWidget(this._commentGlyph); } })); var headHeight = Math.ceil(this.editor.getConfiguration().lineHeight * 1.2); @@ -501,42 +500,58 @@ export class ReviewZoneWidget extends ZoneWidget { } } - private mouseDownInfo: { lineNumber: number, iconClicked: boolean }; + private mouseDownInfo: { lineNumber: number }; private onEditorMouseDown(e: IEditorMouseEvent): void { - if (!e.event.leftButton) { - return; - } + this.mouseDownInfo = null; + + const range = e.target.range; - let range = e.target.range; if (!range) { return; } - let iconClicked = false; - switch (e.target.type) { - case MouseTargetType.GUTTER_GLYPH_MARGIN: - iconClicked = true; - break; - default: - return; + if (!e.event.leftButton) { + return; } - this.mouseDownInfo = { lineNumber: range.startLineNumber, iconClicked }; + if (e.target.type !== MouseTargetType.GUTTER_LINE_DECORATIONS) { + return; + } + + const data = e.target.detail as IMarginData; + const gutterOffsetX = data.offsetX - data.glyphMarginWidth - data.lineNumbersWidth - data.glyphMarginLeft; + + // don't collide with folding and git decorations + if (gutterOffsetX < 10 && gutterOffsetX > 19) { + return; + } + + this.mouseDownInfo = { lineNumber: range.startLineNumber }; } private onEditorMouseUp(e: IEditorMouseEvent): void { if (!this.mouseDownInfo) { return; } - let lineNumber = this.mouseDownInfo.lineNumber; - let iconClicked = this.mouseDownInfo.iconClicked; - let range = e.target.range; + const { lineNumber } = this.mouseDownInfo; + this.mouseDownInfo = null; + + const range = e.target.range; + if (!range || range.startLineNumber !== lineNumber) { return; } + if (e.target.type !== MouseTargetType.GUTTER_LINE_DECORATIONS) { + return; + } + + if (!e.target.element) { + return; + } + if (this.position && this.position.lineNumber !== lineNumber) { return; } @@ -545,17 +560,14 @@ export class ReviewZoneWidget extends ZoneWidget { return; } - if (iconClicked) { - if (e.target.type !== MouseTargetType.GUTTER_GLYPH_MARGIN) { - return; + if (e.target.element.className.indexOf('comment-thread') >= 0) { + if (this._isCollapsed) { + this.show({ lineNumber: lineNumber, column: 1 }, 2); + } else { + this.hide(); + this._onDidClose.fire(); } } - - if (this._isCollapsed) { - this.show({ lineNumber: lineNumber, column: 1 }, 2); - } else { - this.hide(); - } } private _applyTheme(theme: ITheme) { @@ -623,7 +635,7 @@ export class ReviewZoneWidget extends ZoneWidget { } if (this._commentGlyph) { - this.editor.removeContentWidget(this._commentGlyph); + this._commentGlyph.dispose(); this._commentGlyph = null; } diff --git a/src/vs/workbench/parts/comments/electron-browser/commentsEditorContribution.ts b/src/vs/workbench/parts/comments/electron-browser/commentsEditorContribution.ts index 7f0dea1edf0..8c6b8b55cf5 100644 --- a/src/vs/workbench/parts/comments/electron-browser/commentsEditorContribution.ts +++ b/src/vs/workbench/parts/comments/electron-browser/commentsEditorContribution.ts @@ -26,7 +26,6 @@ import { editorForeground, registerColor } from 'vs/platform/theme/common/colorR import { IThemeService, registerThemingParticipant } from 'vs/platform/theme/common/themeService'; import { CommentThreadCollapsibleState } from 'vs/workbench/api/node/extHostTypes'; import { ReviewModel } from 'vs/workbench/parts/comments/common/reviewModel'; -import { CommentGlyphWidget } from 'vs/workbench/parts/comments/electron-browser/commentGlyphWidget'; import { ReviewZoneWidget, COMMENTEDITOR_DECORATION_KEY } from 'vs/workbench/parts/comments/electron-browser/commentThreadWidget'; import { ICommentService } from 'vs/workbench/parts/comments/electron-browser/commentService'; import { IModelService } from 'vs/editor/common/services/modelService'; @@ -74,22 +73,24 @@ class CommentingRangeDecorator { } private commentingOptions: ModelDecorationOptions; - private decorations: string[] = []; + public commentsOptions: ModelDecorationOptions; + private commentingRangeDecorations: string[] = []; private disposables: IDisposable[] = []; constructor( ) { const options = { gutter: true, overview: false }; this.commentingOptions = CommentingRangeDecorator.createDecoration('comment-diff-added', overviewRulerCommentingRangeForeground, options); + this.commentsOptions = CommentingRangeDecorator.createDecoration('comment-thread', overviewRulerCommentingRangeForeground, options); } - update(editor: ICodeEditor, ranges: Range[]) { + update(editor: ICodeEditor, commentsRanges: Range[], commentingRanges: Range[]) { let model = editor.getModel(); if (!model) { return; } - let decorations = ranges.map((change) => { + let commentingRangesDecorations = commentingRanges.map((change) => { const startLineNumber = change.startLineNumber; const endLineNumber = change.endLineNumber; @@ -102,12 +103,27 @@ class CommentingRangeDecorator { }; }); - this.decorations = model.deltaDecorations(this.decorations, decorations); + this.commentingRangeDecorations = model.deltaDecorations(this.commentingRangeDecorations, commentingRangesDecorations); + } + + + getActiveRanges(editor: ICodeEditor): Range[] { + let model = editor.getModel(); + if (!model) { + return []; + } + + let ranges = []; + for (let i = 0; i < this.commentingRangeDecorations.length; i++) { + ranges.push(model.getDecorationRange(this.commentingRangeDecorations[i])); + } + + return ranges; } dispose(): void { this.disposables = dispose(this.disposables); - this.decorations = []; + this.commentingRangeDecorations = []; } } @@ -120,10 +136,10 @@ export class ReviewController implements IEditorContribution { private _reviewPanelVisible: IContextKey; private _commentInfos: modes.CommentInfo[]; private _reviewModel: ReviewModel; - private _newCommentGlyph: CommentGlyphWidget; // private _hasSetComments: boolean; private _commentingRangeDecorator: CommentingRangeDecorator; private mouseDownInfo: { lineNumber: number } | null = null; + private _commentingRangeSpaceReserved = false; constructor( @@ -144,7 +160,6 @@ export class ReviewController implements IEditorContribution { this._commentInfos = []; this._commentWidgets = []; this._newCommentWidget = null; - this._newCommentGlyph = null; // this._hasSetComments = false; this._reviewPanelVisible = ctxReviewPanelVisible.bindTo(contextKeyService); @@ -164,7 +179,7 @@ export class ReviewController implements IEditorContribution { this._commentInfos.forEach(info => { info.threads.forEach(thread => { let zoneWidget = new ReviewZoneWidget(this.instantiationService, this.modeService, this.modelService, this.themeService, this.commentService, this.openerService, this.editor, info.owner, thread, {}); - zoneWidget.display(thread.range.startLineNumber); + zoneWidget.display(thread.range.startLineNumber, this._commentingRangeDecorator.commentsOptions); this._commentWidgets.push(zoneWidget); }); }); @@ -177,11 +192,6 @@ export class ReviewController implements IEditorContribution { this._newCommentWidget = null; } - if (this._newCommentGlyph) { - this.editor.removeContentWidget(this._newCommentGlyph); - this._newCommentGlyph = null; - } - this.getComments(); })); @@ -294,11 +304,6 @@ export class ReviewController implements IEditorContribution { this._newCommentWidget = null; } - if (this._newCommentGlyph) { - this.editor.removeContentWidget(this._newCommentGlyph); - this._newCommentGlyph = null; - } - this._commentWidgets.forEach(zone => { zone.dispose(); }); @@ -306,12 +311,7 @@ export class ReviewController implements IEditorContribution { this.localToDispose.push(this.editor.onMouseDown(e => this.onEditorMouseDown(e))); this.localToDispose.push(this.editor.onMouseUp(e => this.onEditorMouseUp(e))); - this.localToDispose.push(this.editor.onMouseLeave(() => this.onMouseLeave())); this.localToDispose.push(this.editor.onDidChangeModelContent(() => { - if (this._newCommentGlyph) { - this.editor.removeContentWidget(this._newCommentGlyph); - this._newCommentGlyph = null; - } })); this.localToDispose.push(this.commentService.onDidUpdateCommentThreads(e => { const editorURI = this.editor && this.editor.getModel() && this.editor.getModel().uri; @@ -340,7 +340,7 @@ export class ReviewController implements IEditorContribution { }); added.forEach(thread => { let zoneWidget = new ReviewZoneWidget(this.instantiationService, this.modeService, this.modelService, this.themeService, this.commentService, this.openerService, this.editor, e.owner, thread, {}); - zoneWidget.display(thread.range.startLineNumber); + zoneWidget.display(thread.range.startLineNumber, this._commentingRangeDecorator.commentsOptions); this._commentWidgets.push(zoneWidget); this._commentInfos.filter(info => info.owner === e.owner)[0].threads.push(thread); }); @@ -371,41 +371,12 @@ export class ReviewController implements IEditorContribution { }, {}); this._newCommentWidget.onDidClose(e => { + this._newCommentWidget.dispose(); this._newCommentWidget = null; }); - this._newCommentWidget.display(lineNumber); + this._newCommentWidget.display(lineNumber, this._commentingRangeDecorator.commentsOptions); } - /* private onEditorMouseMove(e: IEditorMouseEvent): void { - if (!this._hasSetComments) { - return; - } - - if (!this.editor.hasTextFocus()) { - return; - } - - const hasCommentingRanges = this._commentInfos.length && this._commentInfos.some(info => !!info.commentingRanges.length); - if (hasCommentingRanges && e.target.position && e.target.position.lineNumber !== undefined) { - if (this._newCommentGlyph && e.target.element.className !== 'comment-hint') { - this.editor.removeContentWidget(this._newCommentGlyph); - } - - const lineNumber = e.target.position.lineNumber; - if (!this.isExistingCommentThreadAtLine(lineNumber)) { - this._newCommentGlyph = this.isLineInCommentingRange(lineNumber) - ? this._newCommentGlyph = new CommentGlyphWidget('comment-hint', this.editor, lineNumber, false, () => { - this.addComment(lineNumber); - }) - : this._newCommentGlyph = new CommentGlyphWidget('comment-hint', this.editor, lineNumber, true, () => { - this.notificationService.warn('Commenting is not supported outside of diff hunk areas.'); - }); - - this.editor.layoutContentWidget(this._newCommentGlyph); - } - } - } */ - private onEditorMouseDown(e: IEditorMouseEvent): void { this.mouseDownInfo = null; @@ -426,8 +397,8 @@ export class ReviewController implements IEditorContribution { const data = e.target.detail as IMarginData; const gutterOffsetX = data.offsetX - data.glyphMarginWidth - data.lineNumbersWidth - data.glyphMarginLeft; - // TODO@joao TODO@alex TODO@martin this is such that we don't collide with folding - if (gutterOffsetX > 10) { + // don't collide with folding and git decorations + if (gutterOffsetX < 10 && gutterOffsetX > 19) { return; } @@ -456,7 +427,7 @@ export class ReviewController implements IEditorContribution { return; } - if (e.target.element.className.indexOf('comment-dirty-diff-glyph') >= 0) { + if (e.target.element.className.indexOf('comment-diff-added') >= 0) { const lineNumber = e.target.position.lineNumber; if (!this.isExistingCommentThreadAtLine(lineNumber)) { if (this.isLineInCommentingRange(lineNumber)) { @@ -468,12 +439,6 @@ export class ReviewController implements IEditorContribution { } } - private onMouseLeave(): void { - if (this._newCommentGlyph) { - this.editor.removeContentWidget(this._newCommentGlyph); - } - } - private getNewCommentAction(line: number): { replyCommand: modes.Command, ownerId: number } { for (let i = 0; i < this._commentInfos.length; i++) { const commentInfo = this._commentInfos[i]; @@ -493,11 +458,10 @@ export class ReviewController implements IEditorContribution { } private isLineInCommentingRange(line: number): boolean { - return this._commentInfos.some(commentInfo => { - return commentInfo.commentingRanges.some(range => - range.startLineNumber <= line && line <= range.endLineNumber - ); - }); + let ranges = this._commentingRangeDecorator.getActiveRanges(this.editor); + return ranges.some(range => + range.startLineNumber <= line && line <= range.endLineNumber + ); } private isExistingCommentThreadAtLine(line: number): boolean { @@ -514,6 +478,29 @@ export class ReviewController implements IEditorContribution { setComments(commentInfos: modes.CommentInfo[]): void { this._commentInfos = commentInfos; + let lineDecorationsWidth: number = this.editor.getConfiguration().layoutInfo.decorationsWidth; + + if (this._commentInfos.some(info => Boolean(info.commentingRanges && info.commentingRanges.length))) { + if (!this._commentingRangeSpaceReserved) { + this._commentingRangeSpaceReserved = true; + let extraEditorClassName = []; + if (this.editor.getRawConfiguration().extraEditorClassName) { + extraEditorClassName = this.editor.getRawConfiguration().extraEditorClassName.split(' '); + } + + if (this.editor.getConfiguration().contribInfo.folding) { + lineDecorationsWidth -= 16; + } + lineDecorationsWidth += 9; + extraEditorClassName.push('inline-comment'); + this.editor.updateOptions({ + extraEditorClassName: extraEditorClassName.join(' '), + lineDecorationsWidth: lineDecorationsWidth + }); + this.editor.layout(); + } + } + // this._hasSetComments = true; // create viewzones @@ -524,17 +511,22 @@ export class ReviewController implements IEditorContribution { this._commentInfos.forEach(info => { info.threads.forEach(thread => { let zoneWidget = new ReviewZoneWidget(this.instantiationService, this.modeService, this.modelService, this.themeService, this.commentService, this.openerService, this.editor, info.owner, thread, {}); - zoneWidget.display(thread.range.startLineNumber); + zoneWidget.display(thread.range.startLineNumber, this._commentingRangeDecorator.commentsOptions); this._commentWidgets.push(zoneWidget); }); }); const commentingRanges = []; - this._commentInfos.forEach(info => commentingRanges.push(...info.commentingRanges)); - this._commentingRangeDecorator.update(this.editor, commentingRanges); + const commentsRanges = []; + this._commentInfos.forEach(info => { + commentingRanges.push(...info.commentingRanges); + info.threads.forEach(thread => { + commentsRanges.push(thread.range); + }); + }); + this._commentingRangeDecorator.update(this.editor, commentsRanges, commentingRanges); } - public closeWidget(): void { this._reviewPanelVisible.reset(); @@ -661,6 +653,12 @@ registerThemingParticipant((theme, collector) => { .monaco-editor .comment-diff-added:before { background: ${commentingRangeForeground}; } + .monaco-editor .comment-thread { + border-left: 3px solid ${commentingRangeForeground}; + } + .monaco-editor .comment-thread:before { + background: ${commentingRangeForeground}; + } `); } }); diff --git a/src/vs/workbench/parts/comments/electron-browser/media/review.css b/src/vs/workbench/parts/comments/electron-browser/media/review.css index a01ef1ed9ed..78b1615a052 100644 --- a/src/vs/workbench/parts/comments/electron-browser/media/review.css +++ b/src/vs/workbench/parts/comments/electron-browser/media/review.css @@ -242,7 +242,7 @@ } .monaco-editor .comment-dirty-diff-glyph { - margin-left: 1px; + margin-left: 14px; cursor: pointer; } @@ -255,11 +255,26 @@ transition: width 80ms linear, left 80ms linear; } -.monaco-editor .margin-view-overlays>div:hover>.comment-dirty-diff-glyph:before { +.monaco-editor .margin-view-overlays>div:hover>.comment-dirty-diff-glyph.comment-diff-added:before { position: absolute; content: '+'; height: 100%; - width: 8px; - left: -4px; + width: 9px; + left: -6px; z-index: 10; + color: black; +} + +.monaco-editor .comment-dirty-diff-glyph.comment-thread:before { + position: absolute; + content: '·'; + height: 100%; + width: 9px; + left: -6px; + z-index: 20; + color: black; +} + +.monaco-editor.inline-comment .margin-view-overlays .folding { + margin-left: 14px; } \ No newline at end of file From 897bdf7bed578aef1d0a81e4615f64491c216c34 Mon Sep 17 00:00:00 2001 From: Peng Lyu Date: Mon, 30 Jul 2018 16:09:07 +0800 Subject: [PATCH 0349/1276] commenting range to be marker based. --- .../electron-browser/commentThreadWidget.ts | 4 - .../commentsEditorContribution.ts | 134 ++++++++---------- 2 files changed, 56 insertions(+), 82 deletions(-) diff --git a/src/vs/workbench/parts/comments/electron-browser/commentThreadWidget.ts b/src/vs/workbench/parts/comments/electron-browser/commentThreadWidget.ts index 763a07cd439..cf03d184c67 100644 --- a/src/vs/workbench/parts/comments/electron-browser/commentThreadWidget.ts +++ b/src/vs/workbench/parts/comments/electron-browser/commentThreadWidget.ts @@ -556,10 +556,6 @@ export class ReviewZoneWidget extends ZoneWidget { return; } - if (!this.position && lineNumber !== this._commentThread.range.startLineNumber) { - return; - } - if (e.target.element.className.indexOf('comment-thread') >= 0) { if (this._isCollapsed) { this.show({ lineNumber: lineNumber, column: 1 }, 2); diff --git a/src/vs/workbench/parts/comments/electron-browser/commentsEditorContribution.ts b/src/vs/workbench/parts/comments/electron-browser/commentsEditorContribution.ts index 8c6b8b55cf5..62b9f49d6e5 100644 --- a/src/vs/workbench/parts/comments/electron-browser/commentsEditorContribution.ts +++ b/src/vs/workbench/parts/comments/electron-browser/commentsEditorContribution.ts @@ -15,13 +15,12 @@ import { registerEditorContribution, EditorAction, registerEditorAction } from ' import { ICodeEditorService } from 'vs/editor/browser/services/codeEditorService'; import { EmbeddedCodeEditorWidget } from 'vs/editor/browser/widget/embeddedCodeEditorWidget'; import { IEditorContribution } from 'vs/editor/common/editorCommon'; -import { Range } from 'vs/editor/common/core/range'; +import { IRange } from 'vs/editor/common/core/range'; import * as modes from 'vs/editor/common/modes'; import { peekViewEditorBackground, peekViewResultsBackground, peekViewResultsSelectionBackground } from 'vs/editor/contrib/referenceSearch/referencesWidget'; import { IContextKey, IContextKeyService, RawContextKey } from 'vs/platform/contextkey/common/contextkey'; import { ServicesAccessor, IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; import { KeybindingsRegistry, KeybindingWeight } from 'vs/platform/keybinding/common/keybindingsRegistry'; -import { INotificationService } from 'vs/platform/notification/common/notification'; import { editorForeground, registerColor } from 'vs/platform/theme/common/colorRegistry'; import { IThemeService, registerThemingParticipant } from 'vs/platform/theme/common/themeService'; import { CommentThreadCollapsibleState } from 'vs/workbench/api/node/extHostTypes'; @@ -61,6 +60,41 @@ const overviewRulerDefault = new Color(new RGBA(197, 197, 197, 1)); export const overviewRulerCommentingRangeForeground = registerColor('editorOverviewRuler.addedForeground', { dark: overviewRulerDefault, light: overviewRulerDefault, hc: overviewRulerDefault }, nls.localize('overviewRulerAddedForeground', 'Overview ruler marker color for added content.')); +class CommentingRangeDecoration { + private _decorationId: string; + + constructor(private _editor: ICodeEditor, private _ownerId: number, private _range: IRange, private _reply: modes.Command, commentingOptions: ModelDecorationOptions) { + const startLineNumber = _range.startLineNumber; + const endLineNumber = _range.endLineNumber; + let commentingRangeDecorations = [{ + range: { + startLineNumber: startLineNumber, startColumn: 1, + endLineNumber: endLineNumber, endColumn: 1 + }, + options: commentingOptions + }]; + + let model = this._editor.getModel(); + if (model) { + this._decorationId = model.deltaDecorations([this._decorationId], commentingRangeDecorations)[0]; + } + } + + getCommentAction(): { replyCommand: modes.Command, ownerId: number } { + return { + replyCommand: this._reply, + ownerId: this._ownerId + }; + } + + getOriginalRange() { + return this._range; + } + + getActiveRange() { + return this._editor.getModel().getDecorationRange(this._decorationId); + } +} class CommentingRangeDecorator { static createDecoration(className: string, foregroundColor: string, options: { gutter: boolean, overview: boolean }): ModelDecorationOptions { @@ -74,7 +108,7 @@ class CommentingRangeDecorator { private commentingOptions: ModelDecorationOptions; public commentsOptions: ModelDecorationOptions; - private commentingRangeDecorations: string[] = []; + private commentingRangeDecorations: CommentingRangeDecoration[] = []; private disposables: IDisposable[] = []; constructor( @@ -84,41 +118,33 @@ class CommentingRangeDecorator { this.commentsOptions = CommentingRangeDecorator.createDecoration('comment-thread', overviewRulerCommentingRangeForeground, options); } - update(editor: ICodeEditor, commentsRanges: Range[], commentingRanges: Range[]) { + update(editor: ICodeEditor, commentInfos: modes.CommentInfo[]) { let model = editor.getModel(); if (!model) { return; } - let commentingRangesDecorations = commentingRanges.map((change) => { - const startLineNumber = change.startLineNumber; - const endLineNumber = change.endLineNumber; + let commentingRangeDecorations = []; + for (let i = 0; i < commentInfos.length; i++) { + let info = commentInfos[i]; + info.commentingRanges.forEach(range => { + commentingRangeDecorations.push(new CommentingRangeDecoration(editor, info.owner, range, info.reply, this.commentingOptions)); + }); + } - return { - range: { - startLineNumber: startLineNumber, startColumn: 1, - endLineNumber: endLineNumber, endColumn: 1 - }, - options: this.commentingOptions - }; - }); - - this.commentingRangeDecorations = model.deltaDecorations(this.commentingRangeDecorations, commentingRangesDecorations); + this.commentingRangeDecorations = commentingRangeDecorations; } - - getActiveRanges(editor: ICodeEditor): Range[] { - let model = editor.getModel(); - if (!model) { - return []; - } - - let ranges = []; + getMatchedCommentAction(line: number) { for (let i = 0; i < this.commentingRangeDecorations.length; i++) { - ranges.push(model.getDecorationRange(this.commentingRangeDecorations[i])); + let range = this.commentingRangeDecorations[i].getActiveRange(); + + if (range.startLineNumber <= line && line <= range.endLineNumber) { + return this.commentingRangeDecorations[i].getCommentAction(); + } } - return ranges; + return null; } dispose(): void { @@ -147,7 +173,6 @@ export class ReviewController implements IEditorContribution { @IContextKeyService contextKeyService: IContextKeyService, @IThemeService private themeService: IThemeService, @ICommentService private commentService: ICommentService, - @INotificationService private notificationService: INotificationService, @IInstantiationService private instantiationService: IInstantiationService, @IModeService private modeService: IModeService, @IModelService private modelService: IModelService, @@ -348,7 +373,7 @@ export class ReviewController implements IEditorContribution { } private addComment(lineNumber: number) { - let newCommentInfo = this.getNewCommentAction(lineNumber); + let newCommentInfo = this._commentingRangeDecorator.getMatchedCommentAction(lineNumber); if (!newCommentInfo) { return; } @@ -429,53 +454,10 @@ export class ReviewController implements IEditorContribution { if (e.target.element.className.indexOf('comment-diff-added') >= 0) { const lineNumber = e.target.position.lineNumber; - if (!this.isExistingCommentThreadAtLine(lineNumber)) { - if (this.isLineInCommentingRange(lineNumber)) { - this.addComment(lineNumber); - } else { - this.notificationService.warn('Commenting is not supported outside of diff hunk areas.'); - } - } + this.addComment(lineNumber); } } - private getNewCommentAction(line: number): { replyCommand: modes.Command, ownerId: number } { - for (let i = 0; i < this._commentInfos.length; i++) { - const commentInfo = this._commentInfos[i]; - const lineWithinRange = commentInfo.commentingRanges.some(range => - range.startLineNumber <= line && line <= range.endLineNumber - ); - - if (lineWithinRange) { - return { - replyCommand: commentInfo.reply, - ownerId: commentInfo.owner - }; - } - } - - return null; - } - - private isLineInCommentingRange(line: number): boolean { - let ranges = this._commentingRangeDecorator.getActiveRanges(this.editor); - return ranges.some(range => - range.startLineNumber <= line && line <= range.endLineNumber - ); - } - - private isExistingCommentThreadAtLine(line: number): boolean { - const existingThread = this._commentInfos.some(commentInfo => { - return commentInfo.threads.some(thread => - thread.range.startLineNumber === line - ); - }); - - const existingNewComment = this._newCommentWidget && this._newCommentWidget.position && this._newCommentWidget.position.lineNumber === line; - - return existingThread || existingNewComment; - } - setComments(commentInfos: modes.CommentInfo[]): void { this._commentInfos = commentInfos; let lineDecorationsWidth: number = this.editor.getConfiguration().layoutInfo.decorationsWidth; @@ -517,14 +499,10 @@ export class ReviewController implements IEditorContribution { }); const commentingRanges = []; - const commentsRanges = []; this._commentInfos.forEach(info => { commentingRanges.push(...info.commentingRanges); - info.threads.forEach(thread => { - commentsRanges.push(thread.range); - }); }); - this._commentingRangeDecorator.update(this.editor, commentsRanges, commentingRanges); + this._commentingRangeDecorator.update(this.editor, this._commentInfos); } public closeWidget(): void { From 64005b74fe310932b43c636f7b7f6802d524a2ab Mon Sep 17 00:00:00 2001 From: Peng Lyu Date: Tue, 31 Jul 2018 21:06:43 +0800 Subject: [PATCH 0350/1276] resolve conflicts for folding, git and comment in glyph --- src/vs/editor/contrib/folding/folding.ts | 7 ++++-- .../electron-browser/commentThreadWidget.ts | 2 +- .../commentsEditorContribution.ts | 4 ++-- .../electron-browser/media/review.css | 22 ++++++++++++++----- .../electron-browser/dirtydiffDecorator.ts | 9 ++++++-- .../media/dirtydiffDecorator.css | 1 + 6 files changed, 32 insertions(+), 13 deletions(-) diff --git a/src/vs/editor/contrib/folding/folding.ts b/src/vs/editor/contrib/folding/folding.ts index a2a57574264..c972f6885a2 100644 --- a/src/vs/editor/contrib/folding/folding.ts +++ b/src/vs/editor/contrib/folding/folding.ts @@ -332,10 +332,13 @@ export class FoldingController implements IEditorContribution { switch (e.target.type) { case MouseTargetType.GUTTER_LINE_DECORATIONS: const data = e.target.detail as IMarginData; - const gutterOffsetX = data.offsetX - data.glyphMarginWidth - data.lineNumbersWidth - data.glyphMarginLeft; + const offsetLeftInGutter = (e.target.element as HTMLElement).offsetLeft; + const gutterOffsetX = data.offsetX - offsetLeftInGutter; + + // const gutterOffsetX = data.offsetX - data.glyphMarginWidth - data.lineNumbersWidth - data.glyphMarginLeft; // TODO@joao TODO@alex TODO@martin this is such that we don't collide with dirty diff - if (gutterOffsetX <= 10) { + if (gutterOffsetX < 10) { return; } diff --git a/src/vs/workbench/parts/comments/electron-browser/commentThreadWidget.ts b/src/vs/workbench/parts/comments/electron-browser/commentThreadWidget.ts index cf03d184c67..96041ed6b3d 100644 --- a/src/vs/workbench/parts/comments/electron-browser/commentThreadWidget.ts +++ b/src/vs/workbench/parts/comments/electron-browser/commentThreadWidget.ts @@ -523,7 +523,7 @@ export class ReviewZoneWidget extends ZoneWidget { const gutterOffsetX = data.offsetX - data.glyphMarginWidth - data.lineNumbersWidth - data.glyphMarginLeft; // don't collide with folding and git decorations - if (gutterOffsetX < 10 && gutterOffsetX > 19) { + if (gutterOffsetX > 14) { return; } diff --git a/src/vs/workbench/parts/comments/electron-browser/commentsEditorContribution.ts b/src/vs/workbench/parts/comments/electron-browser/commentsEditorContribution.ts index 62b9f49d6e5..094367fe97b 100644 --- a/src/vs/workbench/parts/comments/electron-browser/commentsEditorContribution.ts +++ b/src/vs/workbench/parts/comments/electron-browser/commentsEditorContribution.ts @@ -102,7 +102,7 @@ class CommentingRangeDecorator { isWholeLine: true, }; - decorationOptions.linesDecorationsClassName = `comment-dirty-diff-glyph ${className}`; + decorationOptions.linesDecorationsClassName = `comment-range-glyph ${className}`; return ModelDecorationOptions.createDynamic(decorationOptions); } @@ -423,7 +423,7 @@ export class ReviewController implements IEditorContribution { const gutterOffsetX = data.offsetX - data.glyphMarginWidth - data.lineNumbersWidth - data.glyphMarginLeft; // don't collide with folding and git decorations - if (gutterOffsetX < 10 && gutterOffsetX > 19) { + if (gutterOffsetX > 14) { return; } diff --git a/src/vs/workbench/parts/comments/electron-browser/media/review.css b/src/vs/workbench/parts/comments/electron-browser/media/review.css index 78b1615a052..c2658cc248c 100644 --- a/src/vs/workbench/parts/comments/electron-browser/media/review.css +++ b/src/vs/workbench/parts/comments/electron-browser/media/review.css @@ -241,12 +241,14 @@ position: relative; } -.monaco-editor .comment-dirty-diff-glyph { - margin-left: 14px; +.monaco-editor .comment-range-glyph { + margin-left: 5px; + width: 4px !important; cursor: pointer; + z-index: 10; } -.monaco-editor .comment-dirty-diff-glyph:before { +.monaco-editor .comment-range-glyph:before { position: absolute; content: ''; height: 100%; @@ -255,7 +257,7 @@ transition: width 80ms linear, left 80ms linear; } -.monaco-editor .margin-view-overlays>div:hover>.comment-dirty-diff-glyph.comment-diff-added:before { +.monaco-editor .margin-view-overlays>div:hover>.comment-range-glyph.comment-diff-added:before { position: absolute; content: '+'; height: 100%; @@ -265,7 +267,11 @@ color: black; } -.monaco-editor .comment-dirty-diff-glyph.comment-thread:before { +.monaco-editor .comment-range-glyph.comment-thread { + z-index: 20; +} + +.monaco-editor .comment-range-glyph.comment-thread:before { position: absolute; content: '·'; height: 100%; @@ -277,4 +283,8 @@ .monaco-editor.inline-comment .margin-view-overlays .folding { margin-left: 14px; -} \ No newline at end of file +} + +.monaco-editor.inline-comment .margin-view-overlays .dirty-diff-glyph { + margin-left: 14px; +} diff --git a/src/vs/workbench/parts/scm/electron-browser/dirtydiffDecorator.ts b/src/vs/workbench/parts/scm/electron-browser/dirtydiffDecorator.ts index 505f3c8a672..def130b2dd7 100644 --- a/src/vs/workbench/parts/scm/electron-browser/dirtydiffDecorator.ts +++ b/src/vs/workbench/parts/scm/electron-browser/dirtydiffDecorator.ts @@ -703,11 +703,16 @@ export class DirtyDiffController implements IEditorContribution { return; } + if (e.target.element.className.indexOf('dirty-diff-glyph') < 0) { + return; + } + const data = e.target.detail as IMarginData; - const gutterOffsetX = data.offsetX - data.glyphMarginWidth - data.lineNumbersWidth - data.glyphMarginLeft; + const offsetLeftInGutter = (e.target.element as HTMLElement).offsetLeft; + const gutterOffsetX = data.offsetX - offsetLeftInGutter; // TODO@joao TODO@alex TODO@martin this is such that we don't collide with folding - if (gutterOffsetX > 10) { + if (gutterOffsetX < 0 || gutterOffsetX > 10) { return; } diff --git a/src/vs/workbench/parts/scm/electron-browser/media/dirtydiffDecorator.css b/src/vs/workbench/parts/scm/electron-browser/media/dirtydiffDecorator.css index de4d95ed717..8a884647c66 100644 --- a/src/vs/workbench/parts/scm/electron-browser/media/dirtydiffDecorator.css +++ b/src/vs/workbench/parts/scm/electron-browser/media/dirtydiffDecorator.css @@ -6,6 +6,7 @@ .monaco-editor .dirty-diff-glyph { margin-left: 5px; cursor: pointer; + z-index: 5; } .monaco-editor .dirty-diff-deleted:after { From 6bbc7e78e366ca24fe45b6b4dbd130adaf985446 Mon Sep 17 00:00:00 2001 From: Alex Dima Date: Tue, 31 Jul 2018 15:26:11 +0200 Subject: [PATCH 0351/1276] Fixes #52655 --- src/vs/editor/contrib/hover/modesContentHover.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/vs/editor/contrib/hover/modesContentHover.ts b/src/vs/editor/contrib/hover/modesContentHover.ts index 26db8c908f0..071469c7a18 100644 --- a/src/vs/editor/contrib/hover/modesContentHover.ts +++ b/src/vs/editor/contrib/hover/modesContentHover.ts @@ -361,11 +361,11 @@ export class ModesContentHoverWidget extends ContentHoverWidget { newRange = range.setEndPosition(range.endLineNumber, range.startColumn + model.presentation.label.length); } - editorModel.pushEditOperations([], textEdits, () => []); + this._editor.executeEdits('colorpicker', textEdits); if (model.presentation.additionalTextEdits) { textEdits = [...model.presentation.additionalTextEdits]; - editorModel.pushEditOperations([], textEdits, () => []); + this._editor.executeEdits('colorpicker', textEdits); this.hide(); } this._editor.pushUndoStop(); From 025d7e6eeb35424da8f2faecbff276c393b0806a Mon Sep 17 00:00:00 2001 From: Christof Marti Date: Tue, 31 Jul 2018 15:27:24 +0200 Subject: [PATCH 0352/1276] Include epoch (#55008) --- resources/linux/debian/control.template | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/resources/linux/debian/control.template b/resources/linux/debian/control.template index d84aba31105..92dbac93f45 100644 --- a/resources/linux/debian/control.template +++ b/resources/linux/debian/control.template @@ -1,7 +1,7 @@ Package: @@NAME@@ Version: @@VERSION@@ Section: devel -Depends: libnotify4, libnss3 (>= 3.26), gnupg, apt, libxkbfile1, libgconf-2-4, libsecret-1-0, libgtk-3-0 (>= 3.10.0) +Depends: libnotify4, libnss3 (>= 2:3.26), gnupg, apt, libxkbfile1, libgconf-2-4, libsecret-1-0, libgtk-3-0 (>= 3.10.0) Priority: optional Architecture: @@ARCHITECTURE@@ Maintainer: Microsoft Corporation From aa50962cf29313b9448f76cb487ee22871d9a480 Mon Sep 17 00:00:00 2001 From: Alex Dima Date: Tue, 31 Jul 2018 15:30:40 +0200 Subject: [PATCH 0353/1276] Fixes #53385 --- src/vs/editor/contrib/bracketMatching/bracketMatching.ts | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/vs/editor/contrib/bracketMatching/bracketMatching.ts b/src/vs/editor/contrib/bracketMatching/bracketMatching.ts index 5ed915fe01a..ed17ffb44dc 100644 --- a/src/vs/editor/contrib/bracketMatching/bracketMatching.ts +++ b/src/vs/editor/contrib/bracketMatching/bracketMatching.ts @@ -118,7 +118,13 @@ export class BracketMatchingController extends Disposable implements editorCommo this._updateBracketsSoon.schedule(); })); - this._register(editor.onDidChangeModel((e) => { this._decorations = []; this._updateBracketsSoon.schedule(); })); + this._register(editor.onDidChangeModelContent((e) => { + this._updateBracketsSoon.schedule(); + })); + this._register(editor.onDidChangeModel((e) => { + this._decorations = []; + this._updateBracketsSoon.schedule(); + })); this._register(editor.onDidChangeModelLanguageConfiguration((e) => { this._lastBracketsData = []; this._updateBracketsSoon.schedule(); From ad3c4b06b21634bf917abde2eb941f6ec87d0be9 Mon Sep 17 00:00:00 2001 From: Peng Lyu Date: Tue, 31 Jul 2018 21:36:08 +0800 Subject: [PATCH 0354/1276] remove unnecessary change. --- src/vs/editor/common/config/editorOptions.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vs/editor/common/config/editorOptions.ts b/src/vs/editor/common/config/editorOptions.ts index 35c16ff732d..75fd5559db8 100644 --- a/src/vs/editor/common/config/editorOptions.ts +++ b/src/vs/editor/common/config/editorOptions.ts @@ -1543,7 +1543,7 @@ function _stringSet(value: T, defaultValue: T, allowedValues: T[]): T { return value; } -export function _clampedInt(value: any, defaultValue: number, minimum: number, maximum: number): number { +function _clampedInt(value: any, defaultValue: number, minimum: number, maximum: number): number { let r: number; if (typeof value === 'undefined') { r = defaultValue; From ad28f0fec3bac28fd41aeed905a91aaa48bcbbdd Mon Sep 17 00:00:00 2001 From: Alex Dima Date: Tue, 31 Jul 2018 16:48:48 +0200 Subject: [PATCH 0355/1276] Fixes #49480 --- src/vs/editor/browser/controller/textAreaState.ts | 2 +- .../test/browser/controller/textAreaState.test.ts | 14 ++++++++++++++ 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/src/vs/editor/browser/controller/textAreaState.ts b/src/vs/editor/browser/controller/textAreaState.ts index 09f54a8a013..fb3249c7903 100644 --- a/src/vs/editor/browser/controller/textAreaState.ts +++ b/src/vs/editor/browser/controller/textAreaState.ts @@ -121,7 +121,7 @@ export class TextAreaState { // See https://github.com/Microsoft/vscode/issues/42251 // where typing always happens at offset 0 in the textarea // when using a custom title area in OSX and moving the window - if (strings.endsWith(currentValue, previousValue)) { + if (!strings.startsWith(currentValue, previousValue) && strings.endsWith(currentValue, previousValue)) { // Looks like something was typed at offset 0 // ==> pretend we placed the cursor at offset 0 to begin with... previousSelectionStart = 0; diff --git a/src/vs/editor/test/browser/controller/textAreaState.test.ts b/src/vs/editor/test/browser/controller/textAreaState.test.ts index 492ad210207..a954c51f42e 100644 --- a/src/vs/editor/test/browser/controller/textAreaState.test.ts +++ b/src/vs/editor/test/browser/controller/textAreaState.test.ts @@ -518,6 +518,20 @@ suite('TextAreaState', () => { ); }); + test('issue #49480: Double curly braces inserted', () => { + // Characters get doubled + testDeduceInput( + new TextAreaState( + 'aa', + 2, 2, + null, null + ), + 'aaa', + 3, 3, true, true, + 'a', 0 + ); + }); + suite('PagedScreenReaderStrategy', () => { function testPagedScreenReaderStrategy(lines: string[], selection: Selection, expected: TextAreaState): void { From 77d90a9de6e5b81c74e5174f3260b62dbc9d5d99 Mon Sep 17 00:00:00 2001 From: Martin Aeschlimann Date: Tue, 31 Jul 2018 16:54:55 +0200 Subject: [PATCH 0356/1276] VS Code Insiders (Users) not opening Fixes #55353 --- .../electron-main/historyMainService.ts | 23 +++++++++++-------- 1 file changed, 14 insertions(+), 9 deletions(-) diff --git a/src/vs/platform/history/electron-main/historyMainService.ts b/src/vs/platform/history/electron-main/historyMainService.ts index d24cfee31d1..796cfaffb92 100644 --- a/src/vs/platform/history/electron-main/historyMainService.ts +++ b/src/vs/platform/history/electron-main/historyMainService.ts @@ -246,17 +246,22 @@ export class HistoryMainService implements IHistoryMainService { } private getRecentlyOpenedFromStorage(): IRecentlyOpened { - const storedRecents: ISerializedRecentlyOpened = this.stateService.getItem(HistoryMainService.recentlyOpenedStorageKey) || { workspaces: [], files: [] }; - const result: IRecentlyOpened = { workspaces: [], files: storedRecents.files }; - for (const workspace of storedRecents.workspaces) { - if (typeof workspace === 'string') { - result.workspaces.push(URI.file(workspace)); - } else if (isWorkspaceIdentifier(workspace)) { - result.workspaces.push(workspace); - } else { - result.workspaces.push(URI.revive(workspace)); + const storedRecents: ISerializedRecentlyOpened = this.stateService.getItem(HistoryMainService.recentlyOpenedStorageKey); + const result: IRecentlyOpened = { workspaces: [], files: [] }; + if (storedRecents && Array.isArray(storedRecents.workspaces)) { + for (const workspace of storedRecents.workspaces) { + if (typeof workspace === 'string') { + result.workspaces.push(URI.file(workspace)); + } else if (isWorkspaceIdentifier(workspace)) { + result.workspaces.push(workspace); + } else { + result.workspaces.push(URI.revive(workspace)); + } } } + if (storedRecents && Array.isArray(storedRecents.files)) { + result.files.push(...storedRecents.files); + } return result; } From ec0e33f9304b12dd7f947b7210d4cd5c4d348ae0 Mon Sep 17 00:00:00 2001 From: Alex Dima Date: Tue, 31 Jul 2018 17:14:34 +0200 Subject: [PATCH 0357/1276] Better handling of the case when the extension host fails to start --- .../extensions/electron-browser/extensionService.ts | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/vs/workbench/services/extensions/electron-browser/extensionService.ts b/src/vs/workbench/services/extensions/electron-browser/extensionService.ts index 45c442c325b..35e8c870c9b 100644 --- a/src/vs/workbench/services/extensions/electron-browser/extensionService.ts +++ b/src/vs/workbench/services/extensions/electron-browser/extensionService.ts @@ -122,7 +122,7 @@ export class ExtensionHostProcessManager extends Disposable { /** * winjs believes a proxy is a promise because it has a `then` method, so wrap the result in an object. */ - private readonly _extensionHostProcessProxy: TPromise<{ value: ExtHostExtensionServiceShape; }>; + private _extensionHostProcessProxy: TPromise<{ value: ExtHostExtensionServiceShape; }>; constructor( extensionHostProcessWorker: ExtensionHostProcessWorker, @@ -134,7 +134,6 @@ export class ExtensionHostProcessManager extends Disposable { this._extensionHostProcessFinishedActivateEvents = Object.create(null); this._extensionHostProcessRPCProtocol = null; this._extensionHostProcessCustomers = []; - this._extensionHostProcessProxy = null; this._extensionHostProcessWorker = extensionHostProcessWorker; this.onDidCrash = this._extensionHostProcessWorker.onCrashed; @@ -168,6 +167,7 @@ export class ExtensionHostProcessManager extends Disposable { errors.onUnexpectedError(err); } } + this._extensionHostProcessProxy = null; super.dispose(); } @@ -218,6 +218,11 @@ export class ExtensionHostProcessManager extends Disposable { return NO_OP_VOID_PROMISE; } return this._extensionHostProcessProxy.then((proxy) => { + if (!proxy) { + // this case is already covered above and logged. + // i.e. the extension host could not be started + return NO_OP_VOID_PROMISE; + } return proxy.value.$activateByEvent(activationEvent); }).then(() => { this._extensionHostProcessFinishedActivateEvents[activationEvent] = true; From 7d59d2dcf4e5bc16b64caf509299ca31e35c2ede Mon Sep 17 00:00:00 2001 From: Alex Dima Date: Tue, 31 Jul 2018 17:41:19 +0200 Subject: [PATCH 0358/1276] Fixes #53966 --- .../languageConfigurationExtensionPoint.ts | 2 +- .../workbench/parts/snippets/electron-browser/snippetsFile.ts | 2 +- .../workbench/services/textMate/electron-browser/TMSyntax.ts | 2 +- .../services/themes/electron-browser/colorThemeData.ts | 4 ++-- .../services/themes/electron-browser/fileIconThemeData.ts | 2 +- 5 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/vs/workbench/parts/codeEditor/electron-browser/languageConfiguration/languageConfigurationExtensionPoint.ts b/src/vs/workbench/parts/codeEditor/electron-browser/languageConfiguration/languageConfigurationExtensionPoint.ts index 15a56872cdc..4b1038f2039 100644 --- a/src/vs/workbench/parts/codeEditor/electron-browser/languageConfiguration/languageConfigurationExtensionPoint.ts +++ b/src/vs/workbench/parts/codeEditor/electron-browser/languageConfiguration/languageConfigurationExtensionPoint.ts @@ -89,7 +89,7 @@ export class LanguageConfigurationFileHandler { } private _handleConfigFile(languageIdentifier: LanguageIdentifier, configFileLocation: URI): void { - this._fileService.resolveContent(configFileLocation).then((contents) => { + this._fileService.resolveContent(configFileLocation, { encoding: 'utf8' }).then((contents) => { const errors: ParseError[] = []; const configuration = parse(contents.value.toString(), errors); if (errors.length) { diff --git a/src/vs/workbench/parts/snippets/electron-browser/snippetsFile.ts b/src/vs/workbench/parts/snippets/electron-browser/snippetsFile.ts index d0776ceed99..699d144f02b 100644 --- a/src/vs/workbench/parts/snippets/electron-browser/snippetsFile.ts +++ b/src/vs/workbench/parts/snippets/electron-browser/snippetsFile.ts @@ -195,7 +195,7 @@ export class SnippetFile { load(): Promise { if (!this._loadPromise) { - this._loadPromise = Promise.resolve(this._fileService.resolveContent(this.location)).then(content => { + this._loadPromise = Promise.resolve(this._fileService.resolveContent(this.location, { encoding: 'utf8' })).then(content => { const data = jsonParse(content.value.toString()); if (typeof data === 'object') { forEach(data, entry => { diff --git a/src/vs/workbench/services/textMate/electron-browser/TMSyntax.ts b/src/vs/workbench/services/textMate/electron-browser/TMSyntax.ts index d4fca9d949e..ab2e62d53f6 100644 --- a/src/vs/workbench/services/textMate/electron-browser/TMSyntax.ts +++ b/src/vs/workbench/services/textMate/electron-browser/TMSyntax.ts @@ -219,7 +219,7 @@ export class TextMateService implements ITextMateService { this._logService.info(`No grammar found for scope ${scopeName}`); return null; } - return this._fileService.resolveContent(location).then(content => { + return this._fileService.resolveContent(location, { encoding: 'utf8' }).then(content => { return parseRawGrammar(content.value, location.path); }, e => { this._logService.error(`Unable to load and parse grammar for scope ${scopeName} from ${location}`, e); diff --git a/src/vs/workbench/services/themes/electron-browser/colorThemeData.ts b/src/vs/workbench/services/themes/electron-browser/colorThemeData.ts index 7a52cc4ef45..d9b1331feda 100644 --- a/src/vs/workbench/services/themes/electron-browser/colorThemeData.ts +++ b/src/vs/workbench/services/themes/electron-browser/colorThemeData.ts @@ -272,7 +272,7 @@ function toCSSSelector(str: string) { function _loadColorTheme(fileService: IFileService, themeLocation: URI, resultRules: ITokenColorizationRule[], resultColors: IColorMap): TPromise { if (Paths.extname(themeLocation.path) === '.json') { - return fileService.resolveContent(themeLocation).then(content => { + return fileService.resolveContent(themeLocation, { encoding: 'utf8' }).then(content => { let errors: Json.ParseError[] = []; let contentValue = Json.parse(content.value.toString(), errors); if (errors.length > 0) { @@ -325,7 +325,7 @@ function getPListParser() { } function _loadSyntaxTokens(fileService: IFileService, themeLocation: URI, resultRules: ITokenColorizationRule[], resultColors: IColorMap): TPromise { - return fileService.resolveContent(themeLocation).then(content => { + return fileService.resolveContent(themeLocation, { encoding: 'utf8' }).then(content => { return getPListParser().then(parser => { try { let contentValue = parser.parse(content.value.toString()); diff --git a/src/vs/workbench/services/themes/electron-browser/fileIconThemeData.ts b/src/vs/workbench/services/themes/electron-browser/fileIconThemeData.ts index 9fe9957a0ec..1fda23ca011 100644 --- a/src/vs/workbench/services/themes/electron-browser/fileIconThemeData.ts +++ b/src/vs/workbench/services/themes/electron-browser/fileIconThemeData.ts @@ -159,7 +159,7 @@ interface IconThemeDocument extends IconsAssociation { } function _loadIconThemeDocument(fileService: IFileService, location: URI): TPromise { - return fileService.resolveContent(location).then((content) => { + return fileService.resolveContent(location, { encoding: 'utf8' }).then((content) => { let errors: Json.ParseError[] = []; let contentValue = Json.parse(content.value.toString(), errors); if (errors.length > 0 || !contentValue) { From 53ce6d66e7195c26234f484e2e3db0f2fd19f3f4 Mon Sep 17 00:00:00 2001 From: Guillaume Marcoux Date: Tue, 31 Jul 2018 13:52:11 -0400 Subject: [PATCH 0359/1276] Remove confusing Start from wordPartLeft commands ID --- .../editor/contrib/wordPartOperations/wordPartOperations.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/vs/editor/contrib/wordPartOperations/wordPartOperations.ts b/src/vs/editor/contrib/wordPartOperations/wordPartOperations.ts index 229dbedfc18..50e8f13733c 100644 --- a/src/vs/editor/contrib/wordPartOperations/wordPartOperations.ts +++ b/src/vs/editor/contrib/wordPartOperations/wordPartOperations.ts @@ -79,7 +79,7 @@ export class CursorWordPartLeft extends WordPartLeftCommand { super({ inSelectionMode: false, wordNavigationType: WordNavigationType.WordStart, - id: 'cursorWordPartStartLeft', + id: 'cursorWordPartLeft', precondition: null, kbOpts: { kbExpr: EditorContextKeys.textInputFocus, @@ -95,7 +95,7 @@ export class CursorWordPartLeftSelect extends WordPartLeftCommand { super({ inSelectionMode: true, wordNavigationType: WordNavigationType.WordStart, - id: 'cursorWordPartStartLeftSelect', + id: 'cursorWordPartLeftSelect', precondition: null, kbOpts: { kbExpr: EditorContextKeys.textInputFocus, From 65991760af72225e42a69007db226be4a9d44f28 Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Tue, 31 Jul 2018 11:03:13 -0700 Subject: [PATCH 0360/1276] vscode-xterm@3.6.0-beta12 Fixes #55488 --- package.json | 2 +- yarn.lock | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/package.json b/package.json index 84dcc5c59b2..95efbf04ae2 100644 --- a/package.json +++ b/package.json @@ -50,7 +50,7 @@ "vscode-nsfw": "1.0.17", "vscode-ripgrep": "^1.0.1", "vscode-textmate": "^4.0.1", - "vscode-xterm": "3.6.0-beta11", + "vscode-xterm": "3.6.0-beta12", "yauzl": "^2.9.1" }, "devDependencies": { diff --git a/yarn.lock b/yarn.lock index 556d40b5a1f..05e9801e2ba 100644 --- a/yarn.lock +++ b/yarn.lock @@ -6256,9 +6256,9 @@ vscode-textmate@^4.0.1: dependencies: oniguruma "^7.0.0" -vscode-xterm@3.6.0-beta11: - version "3.6.0-beta11" - resolved "https://registry.yarnpkg.com/vscode-xterm/-/vscode-xterm-3.6.0-beta11.tgz#d492ae1baf5cf9884f7b49a4fadc0c354248c830" +vscode-xterm@3.6.0-beta12: + version "3.6.0-beta12" + resolved "https://registry.yarnpkg.com/vscode-xterm/-/vscode-xterm-3.6.0-beta12.tgz#ae99dedecf7f354777ab5a4e37a86cfd975adf1f" vso-node-api@^6.1.2-preview: version "6.1.2-preview" From a4b96a02a0db6f52222599d9f602353ec7d46149 Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Tue, 31 Jul 2018 11:17:23 -0700 Subject: [PATCH 0361/1276] Use editor.next/prevChange keybinding for diff navigation Fixes #53062 --- src/vs/workbench/browser/parts/editor/editorCommands.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/vs/workbench/browser/parts/editor/editorCommands.ts b/src/vs/workbench/browser/parts/editor/editorCommands.ts index 600ece0164f..0b81b022ae7 100644 --- a/src/vs/workbench/browser/parts/editor/editorCommands.ts +++ b/src/vs/workbench/browser/parts/editor/editorCommands.ts @@ -224,7 +224,7 @@ function registerDiffEditorCommands(): void { id: 'workbench.action.compareEditor.nextChange', weight: KeybindingWeight.WorkbenchContrib, when: TextCompareEditorVisibleContext, - primary: null, + primary: KeyMod.Alt | KeyCode.F5, handler: accessor => navigateInDiffEditor(accessor, true) }); @@ -232,7 +232,7 @@ function registerDiffEditorCommands(): void { id: 'workbench.action.compareEditor.previousChange', weight: KeybindingWeight.WorkbenchContrib, when: TextCompareEditorVisibleContext, - primary: null, + primary: KeyMod.Alt | KeyMod.Shift | KeyCode.F5, handler: accessor => navigateInDiffEditor(accessor, false) }); From 500a35cfdbebc811fd224e4dcb6f1a25c0c142ed Mon Sep 17 00:00:00 2001 From: Ramya Achutha Rao Date: Tue, 31 Jul 2018 11:56:53 -0700 Subject: [PATCH 0362/1276] Initial size is set to infinity!! Fixes #55461 --- src/vs/workbench/browser/parts/views/viewsViewlet.ts | 3 +-- .../parts/extensions/electron-browser/extensionsViewlet.ts | 4 ++-- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/src/vs/workbench/browser/parts/views/viewsViewlet.ts b/src/vs/workbench/browser/parts/views/viewsViewlet.ts index 183b36edfb6..36268d9a636 100644 --- a/src/vs/workbench/browser/parts/views/viewsViewlet.ts +++ b/src/vs/workbench/browser/parts/views/viewsViewlet.ts @@ -377,9 +377,8 @@ export abstract class ViewContainerViewlet extends PanelViewlet implements IView private computeInitialSizes(): { [id: string]: number } { let sizes = {}; if (this.dimension) { - let totalWeight = 0; for (const viewDescriptor of this.viewsModel.visibleViewDescriptors) { - sizes[viewDescriptor.id] = this.dimension.height * (viewDescriptor.weight || 20) / totalWeight; + sizes[viewDescriptor.id] = this.dimension.height * (viewDescriptor.weight || 20) / 100; } } return sizes; diff --git a/src/vs/workbench/parts/extensions/electron-browser/extensionsViewlet.ts b/src/vs/workbench/parts/extensions/electron-browser/extensionsViewlet.ts index 22399279075..1cc7982203d 100644 --- a/src/vs/workbench/parts/extensions/electron-browser/extensionsViewlet.ts +++ b/src/vs/workbench/parts/extensions/electron-browser/extensionsViewlet.ts @@ -132,7 +132,7 @@ export class ExtensionsViewletViewsContribution implements IWorkbenchContributio container: VIEW_CONTAINER, ctor: EnabledExtensionsView, when: ContextKeyExpr.not('searchExtensions'), - weight: 30, + weight: 40, canToggleVisibility: true, order: 1 }; @@ -181,7 +181,7 @@ export class ExtensionsViewletViewsContribution implements IWorkbenchContributio container: VIEW_CONTAINER, ctor: DefaultRecommendedExtensionsView, when: ContextKeyExpr.and(ContextKeyExpr.not('searchExtensions'), ContextKeyExpr.has('defaultRecommendedExtensions')), - weight: 70, + weight: 60, order: 2, canToggleVisibility: true }; From d757b21c45ac249a7a3220e71326ac841411261a Mon Sep 17 00:00:00 2001 From: Christof Marti Date: Fri, 27 Jul 2018 14:43:32 +0200 Subject: [PATCH 0363/1276] Polish embeddedEditorBackground --- .../theme-quietlight/themes/quietlight-color-theme.json | 3 ++- .../themes/solarized-light-color-theme.json | 5 ++++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/extensions/theme-quietlight/themes/quietlight-color-theme.json b/extensions/theme-quietlight/themes/quietlight-color-theme.json index e8915e04b78..81a8591a875 100644 --- a/extensions/theme-quietlight/themes/quietlight-color-theme.json +++ b/extensions/theme-quietlight/themes/quietlight-color-theme.json @@ -529,6 +529,7 @@ "inputValidation.errorBorder": "#f1897f", "errorForeground": "#f1897f", "badge.background": "#705697AA", - "progressBar.background": "#705697" + "progressBar.background": "#705697", + "walkThrough.embeddedEditorBackground": "#00000014" } } diff --git a/extensions/theme-solarized-light/themes/solarized-light-color-theme.json b/extensions/theme-solarized-light/themes/solarized-light-color-theme.json index 37f3e385d7b..1f0cd3202e7 100644 --- a/extensions/theme-solarized-light/themes/solarized-light-color-theme.json +++ b/extensions/theme-solarized-light/themes/solarized-light-color-theme.json @@ -481,6 +481,9 @@ "terminal.ansiBrightBlue": "#839496", "terminal.ansiBrightMagenta": "#6c71c4", "terminal.ansiBrightCyan": "#93a1a1", - "terminal.ansiBrightWhite": "#eee8d5" + "terminal.ansiBrightWhite": "#eee8d5", + + // Interactive Playground + "walkThrough.embeddedEditorBackground": "#00000014" } } \ No newline at end of file From 261fd546f9d316c04f2b094838b526744757f58a Mon Sep 17 00:00:00 2001 From: Martin Aeschlimann Date: Tue, 31 Jul 2018 23:02:46 +0200 Subject: [PATCH 0364/1276] configuration service misses event --- src/vs/base/common/paths.ts | 10 ++-- src/vs/base/common/resources.ts | 2 +- src/vs/base/test/common/resources.test.ts | 49 ++++++++++++++++++- .../configuration/node/configuration.ts | 3 +- 4 files changed, 56 insertions(+), 8 deletions(-) diff --git a/src/vs/base/common/paths.ts b/src/vs/base/common/paths.ts index a837ce51685..0cabea33b62 100644 --- a/src/vs/base/common/paths.ts +++ b/src/vs/base/common/paths.ts @@ -328,7 +328,7 @@ export function isEqual(pathA: string, pathB: string, ignoreCase?: boolean): boo return equalsIgnoreCase(pathA, pathB); } -export function isEqualOrParent(path: string, candidate: string, ignoreCase?: boolean): boolean { +export function isEqualOrParent(path: string, candidate: string, ignoreCase?: boolean, separator = nativeSep): boolean { if (path === candidate) { return true; } @@ -352,15 +352,15 @@ export function isEqualOrParent(path: string, candidate: string, ignoreCase?: bo } let sepOffset = candidate.length; - if (candidate.charAt(candidate.length - 1) === nativeSep) { + if (candidate.charAt(candidate.length - 1) === separator) { sepOffset--; // adjust the expected sep offset in case our candidate already ends in separator character } - return path.charAt(sepOffset) === nativeSep; + return path.charAt(sepOffset) === separator; } - if (candidate.charAt(candidate.length - 1) !== nativeSep) { - candidate += nativeSep; + if (candidate.charAt(candidate.length - 1) !== separator) { + candidate += separator; } return path.indexOf(candidate) === 0; diff --git a/src/vs/base/common/resources.ts b/src/vs/base/common/resources.ts index 141b17598b2..c09f6334b7f 100644 --- a/src/vs/base/common/resources.ts +++ b/src/vs/base/common/resources.ts @@ -30,7 +30,7 @@ export function isEqualOrParent(resource: uri, candidate: uri, ignoreCase?: bool return paths.isEqualOrParent(resource.fsPath, candidate.fsPath, ignoreCase); } - return paths.isEqualOrParent(resource.path, candidate.path, ignoreCase); + return paths.isEqualOrParent(resource.path, candidate.path, ignoreCase, '/'); } return false; diff --git a/src/vs/base/test/common/resources.test.ts b/src/vs/base/test/common/resources.test.ts index 6a613730db3..2c5509a740a 100644 --- a/src/vs/base/test/common/resources.test.ts +++ b/src/vs/base/test/common/resources.test.ts @@ -6,8 +6,9 @@ import * as assert from 'assert'; import { normalize } from 'vs/base/common/paths'; -import { dirname, distinctParents, joinPath } from 'vs/base/common/resources'; +import { dirname, distinctParents, joinPath, isEqual, isEqualOrParent, hasToIgnoreCase } from 'vs/base/common/resources'; import URI from 'vs/base/common/uri'; +import { isWindows } from 'vs/base/common/platform'; suite('Resources', () => { @@ -68,4 +69,50 @@ suite('Resources', () => { joinPath(URI.from({ scheme: 'myScheme', authority: 'authority', path: '/path', query: 'query', fragment: 'fragment' }), '/file.js').toString(), 'myScheme://authority/path/file.js?query#fragment'); }); + + test('isEqual', () => { + let fileURI = URI.file('/foo/bar'); + let fileURI2 = URI.file('/foo/Bar'); + assert.equal(isEqual(fileURI, fileURI, true), true); + assert.equal(isEqual(fileURI, fileURI, false), true); + assert.equal(isEqual(fileURI, fileURI, hasToIgnoreCase(fileURI)), true); + assert.equal(isEqual(fileURI, fileURI2, true), true); + assert.equal(isEqual(fileURI, fileURI2, false), false); + + let fileURI3 = URI.parse('foo://server:453/foo/bar'); + let fileURI4 = URI.parse('foo://server:453/foo/Bar'); + assert.equal(isEqual(fileURI3, fileURI3, true), true); + assert.equal(isEqual(fileURI3, fileURI3, false), true); + assert.equal(isEqual(fileURI3, fileURI3, hasToIgnoreCase(fileURI3)), true); + assert.equal(isEqual(fileURI3, fileURI4, true), true); + assert.equal(isEqual(fileURI3, fileURI4, false), false); + + + assert.equal(isEqual(fileURI, fileURI3, true), false); + }); + + test('isEqualOrParent', () => { + let fileURI = isWindows ? URI.file('c:\\foo\\bar') : URI.file('/foo/bar'); + let fileURI2 = isWindows ? URI.file('c:\\foo') : URI.file('/foo'); + let fileURI2b = isWindows ? URI.file('C:\\Foo\\') : URI.file('/Foo/'); + assert.equal(isEqualOrParent(fileURI, fileURI, true), true, '1'); + assert.equal(isEqualOrParent(fileURI, fileURI, false), true, '2'); + assert.equal(isEqualOrParent(fileURI, fileURI2, true), true, '3'); + assert.equal(isEqualOrParent(fileURI, fileURI2, false), true, '4'); + assert.equal(isEqualOrParent(fileURI, fileURI2b, true), true, '5'); + assert.equal(isEqualOrParent(fileURI, fileURI2b, false), false, '6'); + + assert.equal(isEqualOrParent(fileURI2, fileURI, false), false, '7'); + assert.equal(isEqualOrParent(fileURI2b, fileURI2, true), true, '8'); + + let fileURI3 = URI.parse('foo://server:453/foo/bar/goo'); + let fileURI4 = URI.parse('foo://server:453/foo/'); + let fileURI5 = URI.parse('foo://server:453/foo'); + assert.equal(isEqualOrParent(fileURI3, fileURI3, true), true, '11'); + assert.equal(isEqualOrParent(fileURI3, fileURI3, false), true, '12'); + assert.equal(isEqualOrParent(fileURI3, fileURI4, true), true, '13'); + assert.equal(isEqualOrParent(fileURI3, fileURI4, false), true, '14'); + assert.equal(isEqualOrParent(fileURI3, fileURI, true), false, '15'); + assert.equal(isEqualOrParent(fileURI5, fileURI5, true), true, '16'); + }); }); \ No newline at end of file diff --git a/src/vs/workbench/services/configuration/node/configuration.ts b/src/vs/workbench/services/configuration/node/configuration.ts index e09d62ad085..947dd50a25a 100644 --- a/src/vs/workbench/services/configuration/node/configuration.ts +++ b/src/vs/workbench/services/configuration/node/configuration.ts @@ -6,6 +6,7 @@ import URI from 'vs/base/common/uri'; import { createHash } from 'crypto'; import * as paths from 'vs/base/common/paths'; +import * as resources from 'vs/base/common/resources'; import { TPromise } from 'vs/base/common/winjs.base'; import { Event, Emitter } from 'vs/base/common/event'; import * as pfs from 'vs/base/node/pfs'; @@ -337,7 +338,7 @@ export class FileServiceBasedFolderConfiguration extends AbstractFolderConfigura return paths.normalize(relative(this.folderConfigurationPath.fsPath, resource.fsPath)); } } else { - if (paths.isEqualOrParent(resource.path, this.folderConfigurationPath.path, true /* ignorecase */)) { + if (resources.isEqualOrParent(resource, this.folderConfigurationPath, resources.hasToIgnoreCase(resource))) { return paths.normalize(relative(this.folderConfigurationPath.path, resource.path)); } } From 51c70dc5de385718b9e89cb1d1a0638dab6dca60 Mon Sep 17 00:00:00 2001 From: Rob Lourens Date: Tue, 31 Jul 2018 15:39:52 -0700 Subject: [PATCH 0365/1276] Fix #55224 - fix duplicate results in multiroot workspace from splitting the diskseach query --- .../services/search/node/searchService.ts | 66 ++++++++++++------- 1 file changed, 42 insertions(+), 24 deletions(-) diff --git a/src/vs/workbench/services/search/node/searchService.ts b/src/vs/workbench/services/search/node/searchService.ts index e1ae90bb784..f89264988a1 100644 --- a/src/vs/workbench/services/search/node/searchService.ts +++ b/src/vs/workbench/services/search/node/searchService.ts @@ -125,29 +125,9 @@ export class SearchService extends Disposable implements ISearchService { const schemesInQuery = query.folderQueries.map(fq => fq.folder.scheme); const providerActivations = schemesInQuery.map(scheme => this.extensionService.activateByEvent(`onSearch:${scheme}`)); - const providerPromise = TPromise.join(providerActivations).then(() => { - return TPromise.join(query.folderQueries.map(fq => { - const oneFolderQuery = { - ...query, - ...{ - folderQueries: [fq] - } - }; - - let provider = query.type === QueryType.File ? - this.fileSearchProviders.get(fq.folder.scheme) || this.fileIndexProviders.get(fq.folder.scheme) : - this.textSearchProviders.get(fq.folder.scheme); - - if (!provider && fq.folder.scheme === 'file') { - provider = this.diskSearch; - } - - if (!provider) { - return TPromise.wrapError(new Error('No search provider registered for scheme: ' + fq.folder.scheme)); - } - - return provider.search(oneFolderQuery, onProviderProgress); - })).then(completes => { + const providerPromise = TPromise.join(providerActivations) + .then(() => this.searchWithProviders(query, onProviderProgress)) + .then(completes => { completes = completes.filter(c => !!c); if (!completes.length) { return null; @@ -166,7 +146,6 @@ export class SearchService extends Disposable implements ISearchService { errs = errs.filter(e => !!e); return TPromise.wrapError(errs[0]); }); - }); combinedPromise = providerPromise.then(value => { this.logService.debug(`SearchService#search: ${Date.now() - startTime}ms`); @@ -202,6 +181,45 @@ export class SearchService extends Disposable implements ISearchService { }, () => combinedPromise && combinedPromise.cancel()); } + private searchWithProviders(query: ISearchQuery, onProviderProgress: (progress: ISearchProgressItem) => void) { + const diskSearchQueries: IFolderQuery[] = []; + const searchPs = []; + + query.folderQueries.forEach(fq => { + let provider = query.type === QueryType.File ? + this.fileSearchProviders.get(fq.folder.scheme) || this.fileIndexProviders.get(fq.folder.scheme) : + this.textSearchProviders.get(fq.folder.scheme); + + if (!provider && fq.folder.scheme === 'file') { + diskSearchQueries.push(fq); + } else if (!provider) { + throw new Error('No search provider registered for scheme: ' + fq.folder.scheme); + } else { + const oneFolderQuery = { + ...query, + ...{ + folderQueries: [fq] + } + }; + + searchPs.push(provider.search(oneFolderQuery, onProviderProgress)); + } + }); + + if (diskSearchQueries.length) { + const diskSearchQuery = { + ...query, + ...{ + folderQueries: diskSearchQueries + } + }; + + searchPs.push(this.diskSearch.search(diskSearchQuery, onProviderProgress)); + } + + return TPromise.join(searchPs); + } + private getLocalResults(query: ISearchQuery): ResourceMap { const localResults = new ResourceMap(); From 3463370a25d64769e1503af8a6dad9d4492afb47 Mon Sep 17 00:00:00 2001 From: Rachel Macfarlane Date: Tue, 31 Jul 2018 16:12:31 -0700 Subject: [PATCH 0366/1276] Select all not working in issue reporter on mac, fixes #55424 --- .../code/electron-browser/issue/issueReporterMain.ts | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/vs/code/electron-browser/issue/issueReporterMain.ts b/src/vs/code/electron-browser/issue/issueReporterMain.ts index a642157cdca..2e25cb33248 100644 --- a/src/vs/code/electron-browser/issue/issueReporterMain.ts +++ b/src/vs/code/electron-browser/issue/issueReporterMain.ts @@ -413,6 +413,16 @@ export class IssueReporter extends Disposable { if (cmdOrCtrlKey && e.keyCode === 189) { this.applyZoom(webFrame.getZoomLevel() - 1); } + + // With latest electron upgrade, cmd+a is no longer propagating correctly for inputs in this window on mac + // Manually perform the selection + if (platform.isMacintosh) { + if (cmdOrCtrlKey && e.keyCode === 65 && e.target) { + if (e.target instanceof HTMLInputElement || e.target instanceof HTMLTextAreaElement) { + (e.target).select(); + } + } + } }; } From bb41a90dbcbe4b22c8dff6316a1a55d951a83891 Mon Sep 17 00:00:00 2001 From: Jackson Kearl Date: Tue, 31 Jul 2018 17:03:36 -0700 Subject: [PATCH 0367/1276] Disable fuzzy matching for extensions autosuggest (#55498) --- .../parts/extensions/electron-browser/extensionsViewlet.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/src/vs/workbench/parts/extensions/electron-browser/extensionsViewlet.ts b/src/vs/workbench/parts/extensions/electron-browser/extensionsViewlet.ts index 1cc7982203d..f4ff324caae 100644 --- a/src/vs/workbench/parts/extensions/electron-browser/extensionsViewlet.ts +++ b/src/vs/workbench/parts/extensions/electron-browser/extensionsViewlet.ts @@ -693,6 +693,7 @@ function mixinHTMLInputStyleOptions(config: IEditorOptions, ariaLabel?: string): config.ariaLabel = ariaLabel || ''; config.cursorWidth = 1; config.snippetSuggestions = 'none'; + config.suggest = { filterGraceful: false }; config.fontFamily = ' -apple-system, BlinkMacSystemFont, "Segoe WPC", "Segoe UI", "HelveticaNeue-Light", "Ubuntu", "Droid Sans", sans-serif'; return config; } From 627c34b60af7a670d5c340b6f48db643f2c836cd Mon Sep 17 00:00:00 2001 From: Jackson Kearl Date: Tue, 31 Jul 2018 17:08:49 -0700 Subject: [PATCH 0368/1276] Fix clipping of extensions search border in some third party themes (#55504) --- .../parts/extensions/electron-browser/extensionsViewlet.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vs/workbench/parts/extensions/electron-browser/extensionsViewlet.ts b/src/vs/workbench/parts/extensions/electron-browser/extensionsViewlet.ts index f4ff324caae..ece3592e355 100644 --- a/src/vs/workbench/parts/extensions/electron-browser/extensionsViewlet.ts +++ b/src/vs/workbench/parts/extensions/electron-browser/extensionsViewlet.ts @@ -428,7 +428,7 @@ export class ExtensionsViewlet extends ViewContainerViewlet implements IExtensio layout(dimension: Dimension): void { toggleClass(this.root, 'narrow', dimension.width <= 300); - this.searchBox.layout({ height: 20, width: dimension.width - 30 }); + this.searchBox.layout({ height: 20, width: dimension.width - 34 }); this.placeholderText.style.width = '' + (dimension.width - 30) + 'px'; super.layout(new Dimension(dimension.width, dimension.height - 38)); From b17af810fd4615905a5cb8bad6253f83c10c5731 Mon Sep 17 00:00:00 2001 From: kieferrm Date: Tue, 31 Jul 2018 17:14:35 -0700 Subject: [PATCH 0369/1276] fixes #55538 --- src/vs/workbench/electron-browser/actions.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/vs/workbench/electron-browser/actions.ts b/src/vs/workbench/electron-browser/actions.ts index ee16bc0f5a5..8855a21628c 100644 --- a/src/vs/workbench/electron-browser/actions.ts +++ b/src/vs/workbench/electron-browser/actions.ts @@ -493,7 +493,9 @@ export class ShowStartupPerformance extends Action { } i += 1; - ticks[stat.type].push(new Tick(stat, nextStat)); + if (ticks[stat.type]) { + ticks[stat.type].push(new Tick(stat, nextStat)); + } } ticks[LoaderEventType.BeginInvokeFactory].sort(Tick.compareUsingStartTimestamp); From 703b916afca5c53cd1a5351d75af19aa51c5b95a Mon Sep 17 00:00:00 2001 From: Jackson Kearl Date: Tue, 31 Jul 2018 18:02:48 -0700 Subject: [PATCH 0370/1276] Fix bug causing an aria alert to not be shown the third time (and odd numbers thereafter) --- src/vs/base/browser/ui/aria/aria.ts | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/src/vs/base/browser/ui/aria/aria.ts b/src/vs/base/browser/ui/aria/aria.ts index 9d59cecfdce..c54d89b0aba 100644 --- a/src/vs/base/browser/ui/aria/aria.ts +++ b/src/vs/base/browser/ui/aria/aria.ts @@ -50,13 +50,22 @@ export function status(msg: string): void { } } +let repeatedTimes = 0; +let prevText: string | undefined = undefined; function insertMessage(target: HTMLElement, msg: string): void { + if (!ariaContainer) { // console.warn('ARIA support needs a container. Call setARIAContainer() first.'); return; } - if (target.textContent === msg) { - msg = nls.localize('repeated', "{0} (occurred again)", msg); + + if (prevText === msg) { repeatedTimes++; } + prevText = msg; + + switch (repeatedTimes) { + case 0: break; + case 1: msg = nls.localize('repeated', "{0} (occurred again)", msg); break; + default: msg = nls.localize('repeatedNtimes', "{0} (occurred {1} times)", msg, repeatedTimes); break; } dom.clearNode(target); From fa47281c46059e1e7c002e91df25eb2ddfb144ff Mon Sep 17 00:00:00 2001 From: Rob Lourens Date: Tue, 31 Jul 2018 15:57:00 -0700 Subject: [PATCH 0371/1276] Settings editor - work around rendering glitch with webkit-line-clamp --- .../parts/preferences/browser/media/settingsEditor2.css | 1 + 1 file changed, 1 insertion(+) diff --git a/src/vs/workbench/parts/preferences/browser/media/settingsEditor2.css b/src/vs/workbench/parts/preferences/browser/media/settingsEditor2.css index 6d25aa01849..13e744ec8af 100644 --- a/src/vs/workbench/parts/preferences/browser/media/settingsEditor2.css +++ b/src/vs/workbench/parts/preferences/browser/media/settingsEditor2.css @@ -272,6 +272,7 @@ display: -webkit-box; -webkit-line-clamp: 1; -webkit-box-orient: vertical; + transform: translate3d(0px, 0px, 0px); } .settings-editor > .settings-body > .settings-tree-container .setting-item .setting-item-description * { From c319007abd36b283c1186345d53a844bb14f85b7 Mon Sep 17 00:00:00 2001 From: Rob Lourens Date: Tue, 31 Jul 2018 16:00:46 -0700 Subject: [PATCH 0372/1276] Settings editor - revert earlier '...' changes --- .../browser/media/settingsEditor2.css | 27 +-- .../preferences/browser/settingsEditor2.ts | 5 - .../parts/preferences/browser/settingsTree.ts | 176 ++++-------------- 3 files changed, 35 insertions(+), 173 deletions(-) diff --git a/src/vs/workbench/parts/preferences/browser/media/settingsEditor2.css b/src/vs/workbench/parts/preferences/browser/media/settingsEditor2.css index 13e744ec8af..1019b0087b5 100644 --- a/src/vs/workbench/parts/preferences/browser/media/settingsEditor2.css +++ b/src/vs/workbench/parts/preferences/browser/media/settingsEditor2.css @@ -219,18 +219,6 @@ height: 100%; } -.settings-editor > .settings-body > .settings-tree-container .setting-item .setting-expand-indicator { - display: none; -} - -.settings-editor > .settings-body > .settings-tree-container .setting-item.is-expandable:not(.is-expanded) .setting-expand-indicator { - display: block; - position: absolute; - left: 7px; - top: 0px; - opacity: .9; -} - .settings-editor > .settings-body > .settings-tree-container .setting-item .setting-item-title { white-space: nowrap; overflow: hidden; @@ -261,13 +249,10 @@ opacity: 0.9; } -.settings-editor > .settings-body > .settings-tree-container .setting-item .setting-item-description-container { - margin-top: 3px; - position: relative; -} - .settings-editor > .settings-body > .settings-tree-container .setting-item .setting-item-description { + margin-top: 3px; overflow: hidden; + text-overflow: ellipsis; height: 18px; display: -webkit-box; -webkit-line-clamp: 1; @@ -295,11 +280,6 @@ -webkit-line-clamp: initial; } -.settings-editor > .settings-body > .settings-tree-container .setting-description-measure-container .setting-item .setting-item-description, -.settings-editor > .settings-body > .settings-tree-container .setting-description-measure-container .setting-item .setting-item-description * { - display: inline; -} - .settings-editor > .settings-body > .settings-tree-container .setting-item-bool .setting-item-value-description { display: flex; } @@ -333,7 +313,7 @@ min-width: 200px; } -.settings-editor > .settings-body > .settings-tree-container .setting-item.setting-item-text .setting-item-value { +.settings-editor > .settings-body > .settings-tree-container .setting-item.setting-item-text { width: 500px; } @@ -343,7 +323,6 @@ min-width: initial; } -.settings-editor > .settings-body > .settings-tree-container .setting-item.setting-item-enum .setting-item-value, .settings-editor > .settings-body > .settings-tree-container .setting-item.setting-item-enum .setting-item-value > .setting-item-control > select { width: 320px; } diff --git a/src/vs/workbench/parts/preferences/browser/settingsEditor2.ts b/src/vs/workbench/parts/preferences/browser/settingsEditor2.ts index 1253fb2145f..3346f396a0b 100644 --- a/src/vs/workbench/parts/preferences/browser/settingsEditor2.ts +++ b/src/vs/workbench/parts/preferences/browser/settingsEditor2.ts @@ -83,8 +83,6 @@ export class SettingsEditor2 extends BaseEditor { private tagRegex = /(^|\s)@tag:("([^"]*)"|[^"]\S*)/g; - private layoutDelayer: Delayer; - /** Don't spam warnings */ private hasWarnedMissingSettings: boolean; @@ -105,7 +103,6 @@ export class SettingsEditor2 extends BaseEditor { this.localSearchDelayer = new Delayer(100); this.remoteSearchThrottle = new ThrottledDelayer(200); this.viewState = { settingsTarget: ConfigurationTarget.USER }; - this.layoutDelayer = new Delayer(100); this.settingUpdateDelayer = new Delayer(500); @@ -150,8 +147,6 @@ export class SettingsEditor2 extends BaseEditor { this.layoutTrees(dimension); DOM.toggleClass(this.rootElement, 'narrow', dimension.width < 600); - - this.layoutDelayer.trigger(() => this.refreshTreeAndMaintainFocus()); } focus(): void { diff --git a/src/vs/workbench/parts/preferences/browser/settingsTree.ts b/src/vs/workbench/parts/preferences/browser/settingsTree.ts index da45292f34d..f0b9c730b98 100644 --- a/src/vs/workbench/parts/preferences/browser/settingsTree.ts +++ b/src/vs/workbench/parts/preferences/browser/settingsTree.ts @@ -472,7 +472,6 @@ interface ISettingItemTemplate extends IDisposableTemplate { categoryElement: HTMLElement; labelElement: HTMLElement; descriptionElement: HTMLElement; - expandIndicatorElement: HTMLElement; controlElement: HTMLElement; isConfiguredElement: HTMLElement; otherOverridesElement: HTMLElement; @@ -546,8 +545,6 @@ export class SettingsRenderer implements ITreeRenderer { public readonly onDidClickSettingLink: Event = this._onDidClickSettingLink.event; private measureContainer: HTMLElement; - // private measureDescriptionContainer: HTMLElement; - // private measureDescriptionTemplates = new Map(); constructor( _measureContainer: HTMLElement, @@ -558,7 +555,6 @@ export class SettingsRenderer implements ITreeRenderer { @ICommandService private readonly commandService: ICommandService, ) { this.measureContainer = DOM.append(_measureContainer, $('.setting-measure-container.monaco-tree-row')); - // this.measureDescriptionContainer = DOM.append(_measureContainer, $('.setting-measure-container.setting-description-measure-container.monaco-tree-row')); } getHeight(tree: ITree, element: SettingsTreeElement): number { @@ -613,40 +609,6 @@ export class SettingsRenderer implements ITreeRenderer { return Math.max(height, this._getUnexpandedSettingHeight(element)); } - // private measureSettingDescriptionHeight(tree: ITree, element: SettingsTreeSettingElement): number { - // const measureHelper = DOM.append(this.measureContainer, $('.setting-measure-helper')); - - // const templateId = this.getTemplateId(tree, element); - // const template = this.renderTemplate(tree, templateId, measureHelper); - // this.renderDescription(element.description, template, true); - - // const height = (template).descriptionElement.offsetHeight; - // this.measureContainer.removeChild(this.measureContainer.firstChild); - // return height; - // } - - // private measureSettingDescription(tree: ITree, element: SettingsTreeSettingElement, text: string): { height: number, width: number } { - // const templateId = this.getTemplateId(tree, element); - // if (!this.measureDescriptionTemplates.has(templateId)) { - // const measureHelper = $('.setting-measure-helper'); - // this.measureDescriptionTemplates.set(templateId, this.renderTemplate(tree, templateId, measureHelper)); - // } - - // const template = this.measureDescriptionTemplates.get(templateId); - // this.measureDescriptionContainer.appendChild(template.containerElement); - // this.renderDescription(text, template, true); - - // const descriptionElement = (template).descriptionElement; - // const width = descriptionElement.offsetWidth; - // const height = descriptionElement.offsetHeight; - - // if (this.measureDescriptionContainer.firstChild) { - // this.measureDescriptionContainer.removeChild(this.measureDescriptionContainer.firstChild); - // } - - // return { height, width }; - // } - getTemplateId(tree: ITree, element: SettingsTreeElement): string { if (element instanceof SettingsTreeGroupElement) { @@ -741,15 +703,11 @@ export class SettingsRenderer implements ITreeRenderer { const labelElement = DOM.append(titleElement, $('span.setting-item-label')); const isConfiguredElement = DOM.append(titleElement, $('span.setting-item-is-configured-label')); const otherOverridesElement = DOM.append(titleElement, $('span.setting-item-overrides')); - const descriptionContainerElement = DOM.append(container, $('.setting-item-description-container')); - const descriptionElement = DOM.append(descriptionContainerElement, $('.setting-item-description')); + const descriptionElement = DOM.append(container, $('.setting-item-description')); const valueElement = DOM.append(container, $('.setting-item-value')); const controlElement = DOM.append(valueElement, $('div.setting-item-control')); - const expandIndicatorElement = DOM.append(descriptionContainerElement, $('.setting-expand-indicator')); - expandIndicatorElement.textContent = '…'; - const toDispose = []; const template: ISettingItemTemplate = { toDispose, @@ -760,7 +718,6 @@ export class SettingsRenderer implements ITreeRenderer { descriptionElement, controlElement, isConfiguredElement, - expandIndicatorElement, otherOverridesElement }; @@ -841,10 +798,7 @@ export class SettingsRenderer implements ITreeRenderer { const descriptionAndValueElement = DOM.append(container, $('.setting-item-value-description')); const controlElement = DOM.append(descriptionAndValueElement, $('.setting-item-bool-control')); - const descriptionContainerElement = DOM.append(descriptionAndValueElement, $('.setting-item-description-container')); - const descriptionElement = DOM.append(descriptionContainerElement, $('.setting-item-description')); - const expandIndicatorElement = DOM.append(descriptionContainerElement, $('.setting-expand-indicator')); - expandIndicatorElement.textContent = '…'; + const descriptionElement = DOM.append(descriptionAndValueElement, $('.setting-item-description')); const toDispose = []; const checkbox = new Checkbox({ actionClassName: 'setting-value-checkbox', isChecked: true, title: '', inputActiveOptionBorder: null }); @@ -865,7 +819,6 @@ export class SettingsRenderer implements ITreeRenderer { controlElement, checkbox, descriptionElement, - expandIndicatorElement, isConfiguredElement, otherOverridesElement }; @@ -1040,55 +993,12 @@ export class SettingsRenderer implements ITreeRenderer { template.context = element; } - // private isSettingExpandable(tree: ITree, element: SettingsTreeSettingElement): boolean { - // // Shortcuts before measuring - // if (element.valueType === 'enum' && element.setting.enumDescriptions && element.setting.enum && element.setting.enum.length < SettingsRenderer.MAX_ENUM_DESCRIPTIONS) { - // return true; - // } - - // if (element.setting.description.indexOf('\n') >= 0) { - // return true; - // } - - // const height = this.measureSettingDescriptionHeight(tree, element); - // return height > 18; - // } - - // private settingDescriptionFirstLineLength(tree: ITree, element: SettingsTreeSettingElement): number { - // const fullDescription = element.description - // .replace(/\[(.*)\]\(.*\)/, '$1') - // .split('\n')[0]; - - // // Add characters one at a time, measure the width. Start from some safe number. - // // const startPos = Math.min(50, fullDescription.length - 1); - // let size: { height: number, width: number }; - // for (let i = 10; i <= fullDescription.length;) { - // let description = fullDescription.substr(0, i); - // size = this.measureSettingDescription(tree, element, description); - // if (size.height > 20) { - // // It wrapped - // return size.width; - // } - - // const nextBreakMatch = fullDescription.slice(i + 1).match(/([\s.,]|$)/); - // if (nextBreakMatch) { - // i = nextBreakMatch.index + i + 1; - // } else { - // return size.width; - // } - // } - - // return size ? size.width : 0; - // } - private renderSettingElement(tree: ITree, element: SettingsTreeSettingElement, templateId: string, template: ISettingItemTemplate | ISettingBoolItemTemplate): void { const isSelected = !!this.elementIsSelected(tree, element); const setting = element.setting; - // const isExpandable = this.isSettingExpandable(tree, element); - // DOM.toggleClass(template.containerElement, 'is-expandable', isExpandable); - DOM.toggleClass(template.containerElement, 'is-expanded', isSelected); DOM.toggleClass(template.containerElement, 'is-configured', element.isConfigured); + DOM.toggleClass(template.containerElement, 'is-expanded', isSelected); template.containerElement.id = element.id.replace(/\./g, '_'); const titleTooltip = setting.key; @@ -1098,33 +1008,9 @@ export class SettingsRenderer implements ITreeRenderer { template.labelElement.textContent = element.displayLabel; template.labelElement.title = titleTooltip; - // if (isExpandable) { - // const widthInFirstLine = this.settingDescriptionFirstLineLength(tree, element); - // template.expandIndicatorElement.style.left = (widthInFirstLine + 8) + 'px'; - // } - - const descriptionText = element.description + this.getEnumDescriptionText(element); - this.renderDescription(descriptionText, template, isSelected); - this.renderValue(element, isSelected, templateId, template); - - template.isConfiguredElement.textContent = element.isConfigured ? localize('configured', "Modified") : ''; - - if (element.overriddenScopeList.length) { - const otherOverridesLabel = element.isConfigured ? - localize('alsoConfiguredIn', "Also modified in") : - localize('configuredIn', "Modified in"); - - template.otherOverridesElement.textContent = `(${otherOverridesLabel}: ${element.overriddenScopeList.join(', ')})`; - } else { - template.otherOverridesElement.textContent = ''; - } - } - - private getEnumDescriptionText(element: SettingsTreeSettingElement): string { - const setting = element.setting; let enumDescriptionText = ''; - if (element.valueType === 'enum' && setting.enumDescriptions && setting.enum && setting.enum.length < SettingsRenderer.MAX_ENUM_DESCRIPTIONS) { - enumDescriptionText = '\n' + setting.enumDescriptions + if (element.valueType === 'enum' && element.setting.enumDescriptions && element.setting.enum && element.setting.enum.length < SettingsRenderer.MAX_ENUM_DESCRIPTIONS) { + enumDescriptionText = '\n' + element.setting.enumDescriptions .map((desc, i) => { const displayEnum = escapeInvisibleChars(setting.enum[i]); return desc ? @@ -1135,40 +1021,42 @@ export class SettingsRenderer implements ITreeRenderer { .join('\n'); } - return enumDescriptionText; - } - - private renderDescription(text: string, template: ISettingItemTemplate | ISettingBoolItemTemplate, isSelected: boolean, measuring = false): void { // Rewrite `#editor.fontSize#` to link format - const descriptionText = text + const descriptionText = (element.description + enumDescriptionText) .replace(/`#(.*)#`/g, (match, settingName) => `[\`${settingName}\`](#${settingName})`); const renderedDescription = renderMarkdown({ value: descriptionText }, { - actionHandler: measuring ? - undefined : - { - callback: (content: string) => { - if (startsWith(content, '#')) { - this._onDidClickSettingLink.fire(content.substr(1)); - } else { - this.openerService.open(URI.parse(content)).then(void 0, onUnexpectedError); - } - }, - disposeables: template.toDispose - } + actionHandler: { + callback: (content: string) => { + if (startsWith(content, '#')) { + this._onDidClickSettingLink.fire(content.substr(1)); + } else { + this.openerService.open(URI.parse(content)).then(void 0, onUnexpectedError); + } + }, + disposeables: template.toDispose + } }); - if (!measuring) { - cleanRenderedMarkdown(renderedDescription); - } - + cleanRenderedMarkdown(renderedDescription); renderedDescription.classList.add('setting-item-description-markdown'); template.descriptionElement.innerHTML = ''; template.descriptionElement.appendChild(renderedDescription); + (renderedDescription.querySelectorAll('a')).forEach(aElement => { + aElement.tabIndex = isSelected ? 0 : -1; + }); - if (!measuring) { - (renderedDescription.querySelectorAll('a')).forEach(aElement => { - aElement.tabIndex = isSelected ? 0 : -1; - }); + this.renderValue(element, isSelected, templateId, template); + + template.isConfiguredElement.textContent = element.isConfigured ? localize('configured', "Modified") : ''; + + if (element.overriddenScopeList.length) { + let otherOverridesLabel = element.isConfigured ? + localize('alsoConfiguredIn', "Also modified in") : + localize('configuredIn', "Modified in"); + + template.otherOverridesElement.textContent = `(${otherOverridesLabel}: ${element.overriddenScopeList.join(', ')})`; + } else { + template.otherOverridesElement.textContent = ''; } } From 6c8fe7c45f2bf45efeff4a91f373f5e0ddf562e0 Mon Sep 17 00:00:00 2001 From: Rob Lourens Date: Tue, 31 Jul 2018 16:22:04 -0700 Subject: [PATCH 0373/1276] Settings editor - move enumDescription to its own div, because it disturbs -webkit-line-clamp for some reason --- .../browser/media/settingsEditor2.css | 13 +++- .../parts/preferences/browser/settingsTree.ts | 76 +++++++++++-------- .../preferences/browser/settingsWidgets.ts | 4 +- 3 files changed, 59 insertions(+), 34 deletions(-) diff --git a/src/vs/workbench/parts/preferences/browser/media/settingsEditor2.css b/src/vs/workbench/parts/preferences/browser/media/settingsEditor2.css index 1019b0087b5..8984d36fdc4 100644 --- a/src/vs/workbench/parts/preferences/browser/media/settingsEditor2.css +++ b/src/vs/workbench/parts/preferences/browser/media/settingsEditor2.css @@ -260,11 +260,11 @@ transform: translate3d(0px, 0px, 0px); } -.settings-editor > .settings-body > .settings-tree-container .setting-item .setting-item-description * { +.settings-editor > .settings-body > .settings-tree-container .setting-item .setting-item-description-markdown * { margin: 0px; } -.settings-editor > .settings-body > .settings-tree-container .setting-item .setting-item-description code { +.settings-editor > .settings-body > .settings-tree-container .setting-item .setting-item-description-markdown code { line-height: 15px; /** For some reason, this is needed, otherwise will take up 20px height */ font-family: Menlo, Monaco, Consolas, "Droid Sans Mono", "Courier New", monospace, "Droid Sans Fallback"; } @@ -280,6 +280,15 @@ -webkit-line-clamp: initial; } +.settings-editor > .settings-body > .settings-tree-container .setting-item .setting-item-enumDescription { + display: none; +} + +.settings-editor > .settings-body > .settings-tree-container .setting-item.is-expanded .setting-item-enumDescription, +.settings-editor > .settings-body > .settings-tree-container .setting-item.setting-measure-helper .setting-item-enumDescription { + display: block; +} + .settings-editor > .settings-body > .settings-tree-container .setting-item-bool .setting-item-value-description { display: flex; } diff --git a/src/vs/workbench/parts/preferences/browser/settingsTree.ts b/src/vs/workbench/parts/preferences/browser/settingsTree.ts index f0b9c730b98..e703f3e08ce 100644 --- a/src/vs/workbench/parts/preferences/browser/settingsTree.ts +++ b/src/vs/workbench/parts/preferences/browser/settingsTree.ts @@ -489,6 +489,7 @@ type ISettingNumberItemTemplate = ISettingTextItemTemplate; interface ISettingEnumItemTemplate extends ISettingItemTemplate { selectBox: SelectBox; + enumDescriptionElement: HTMLElement; } interface ISettingComplexItemTemplate extends ISettingItemTemplate { @@ -855,9 +856,12 @@ export class SettingsRenderer implements ITreeRenderer { } })); + const enumDescriptionElement = common.containerElement.insertBefore($('.setting-item-enumDescription'), common.descriptionElement.nextSibling); + const template: ISettingEnumItemTemplate = { ...common, - selectBox + selectBox, + enumDescriptionElement }; return template; @@ -1008,37 +1012,10 @@ export class SettingsRenderer implements ITreeRenderer { template.labelElement.textContent = element.displayLabel; template.labelElement.title = titleTooltip; - let enumDescriptionText = ''; - if (element.valueType === 'enum' && element.setting.enumDescriptions && element.setting.enum && element.setting.enum.length < SettingsRenderer.MAX_ENUM_DESCRIPTIONS) { - enumDescriptionText = '\n' + element.setting.enumDescriptions - .map((desc, i) => { - const displayEnum = escapeInvisibleChars(setting.enum[i]); - return desc ? - ` - \`${displayEnum}\`: ${desc}` : - ` - \`${setting.enum[i]}\``; - }) - .filter(desc => !!desc) - .join('\n'); - } - // Rewrite `#editor.fontSize#` to link format - const descriptionText = (element.description + enumDescriptionText) - .replace(/`#(.*)#`/g, (match, settingName) => `[\`${settingName}\`](#${settingName})`); + const descriptionText = fixSettingLinks(element.description); + const renderedDescription = this.renderDescriptionMarkdown(descriptionText, template.toDispose); - const renderedDescription = renderMarkdown({ value: descriptionText }, { - actionHandler: { - callback: (content: string) => { - if (startsWith(content, '#')) { - this._onDidClickSettingLink.fire(content.substr(1)); - } else { - this.openerService.open(URI.parse(content)).then(void 0, onUnexpectedError); - } - }, - disposeables: template.toDispose - } - }); - cleanRenderedMarkdown(renderedDescription); - renderedDescription.classList.add('setting-item-description-markdown'); template.descriptionElement.innerHTML = ''; template.descriptionElement.appendChild(renderedDescription); (renderedDescription.querySelectorAll('a')).forEach(aElement => { @@ -1060,6 +1037,25 @@ export class SettingsRenderer implements ITreeRenderer { } } + private renderDescriptionMarkdown(text: string, disposeables: IDisposable[]): HTMLElement { + const renderedMarkdown = renderMarkdown({ value: text }, { + actionHandler: { + callback: (content: string) => { + if (startsWith(content, '#')) { + this._onDidClickSettingLink.fire(content.substr(1)); + } else { + this.openerService.open(URI.parse(content)).then(void 0, onUnexpectedError); + } + }, + disposeables + } + }); + + renderedMarkdown.classList.add('setting-item-description-markdown'); + cleanRenderedMarkdown(renderedMarkdown); + return renderedMarkdown; + } + private renderValue(element: SettingsTreeSettingElement, isSelected: boolean, templateId: string, template: ISettingItemTemplate | ISettingBoolItemTemplate): void { const onChange = value => this._onDidChangeSetting.fire({ key: element.setting.key, value }); @@ -1101,6 +1097,22 @@ export class SettingsRenderer implements ITreeRenderer { if (template.controlElement.firstElementChild) { template.controlElement.firstElementChild.setAttribute('tabindex', isSelected ? '0' : '-1'); } + + template.enumDescriptionElement.innerHTML = ''; + if (dataElement.setting.enumDescriptions && dataElement.setting.enum && dataElement.setting.enum.length < SettingsRenderer.MAX_ENUM_DESCRIPTIONS) { + let enumDescriptionText = '\n' + dataElement.setting.enumDescriptions + .map((desc, i) => { + const displayEnum = escapeInvisibleChars(dataElement.setting.enum[i]); + return desc ? + ` - \`${displayEnum}\`: ${desc}` : + ` - \`${dataElement.setting.enum[i]}\``; + }) + .filter(desc => !!desc) + .join('\n'); + + const renderedMarkdown = this.renderDescriptionMarkdown(fixSettingLinks(enumDescriptionText), template.toDispose); + template.enumDescriptionElement.appendChild(renderedMarkdown); + } } private renderText(dataElement: SettingsTreeSettingElement, isSelected: boolean, template: ISettingTextItemTemplate, onChange: (value: string) => void): void { @@ -1148,6 +1160,10 @@ function cleanRenderedMarkdown(element: Node): void { } } +function fixSettingLinks(text: string): string { + return text.replace(/`#(.*)#`/g, (match, settingName) => `[\`${settingName}\`](#${settingName})`); +} + function getDisplayEnumOptions(setting: ISetting): string[] { if (setting.enum.length > SettingsRenderer.MAX_ENUM_DESCRIPTIONS && setting.enumDescriptions) { return setting.enum diff --git a/src/vs/workbench/parts/preferences/browser/settingsWidgets.ts b/src/vs/workbench/parts/preferences/browser/settingsWidgets.ts index de45cdbae93..94bf81c8108 100644 --- a/src/vs/workbench/parts/preferences/browser/settingsWidgets.ts +++ b/src/vs/workbench/parts/preferences/browser/settingsWidgets.ts @@ -62,8 +62,8 @@ registerThemingParticipant((theme: ITheme, collector: ICssStyleCollector) => { const link = theme.getColor(textLinkForeground); if (link) { - collector.addRule(`.settings-editor > .settings-body > .settings-tree-container .setting-item .setting-item-description a { color: ${link}; }`); - collector.addRule(`.settings-editor > .settings-body > .settings-tree-container .setting-item .setting-item-description a > code { color: ${link}; }`); + collector.addRule(`.settings-editor > .settings-body > .settings-tree-container .setting-item .setting-item-description-markdown a { color: ${link}; }`); + collector.addRule(`.settings-editor > .settings-body > .settings-tree-container .setting-item .setting-item-description-markdown a > code { color: ${link}; }`); } const headerForegroundColor = theme.getColor(settingsHeaderForeground); From 2cc4ba01bfbf5aa78bd1f744bf34ed43bd62e473 Mon Sep 17 00:00:00 2001 From: Rob Lourens Date: Tue, 31 Jul 2018 18:25:08 -0700 Subject: [PATCH 0374/1276] Settings editor - better overflow indicator --- .../browser/media/settingsEditor2.css | 19 ++++++- .../parts/preferences/browser/settingsTree.ts | 55 ++++++++++++------- 2 files changed, 54 insertions(+), 20 deletions(-) diff --git a/src/vs/workbench/parts/preferences/browser/media/settingsEditor2.css b/src/vs/workbench/parts/preferences/browser/media/settingsEditor2.css index 8984d36fdc4..dffcd2fe540 100644 --- a/src/vs/workbench/parts/preferences/browser/media/settingsEditor2.css +++ b/src/vs/workbench/parts/preferences/browser/media/settingsEditor2.css @@ -260,6 +260,24 @@ transform: translate3d(0px, 0px, 0px); } +.settings-editor > .settings-body > .settings-tree-container .setting-item .setting-item-description.setting-item-description-artificial-overflow { + display: block; +} + +.settings-editor > .settings-body > .settings-tree-container .setting-item .setting-item-description-artificial-overflow .setting-item-description-markdown { + display: inline-block; + margin-right: 3px; +} + +.settings-editor > .settings-body > .settings-tree-container .setting-item .setting-item-description-artificial-overflow::after { + display: inline-block; + content: '…'; + width: 16px; + height: 16px; + position: absolute; + transform: translate3d(0px, 0px, 0px); +} + .settings-editor > .settings-body > .settings-tree-container .setting-item .setting-item-description-markdown * { margin: 0px; } @@ -328,7 +346,6 @@ .settings-editor > .settings-body > .settings-tree-container .setting-item.setting-item-enum .setting-item-value > .setting-item-control, .settings-editor > .settings-body > .settings-tree-container .setting-item.setting-item-text .setting-item-value > .setting-item-control { - flex: 1; min-width: initial; } diff --git a/src/vs/workbench/parts/preferences/browser/settingsTree.ts b/src/vs/workbench/parts/preferences/browser/settingsTree.ts index e703f3e08ce..0500c36655a 100644 --- a/src/vs/workbench/parts/preferences/browser/settingsTree.ts +++ b/src/vs/workbench/parts/preferences/browser/settingsTree.ts @@ -516,6 +516,10 @@ interface IGroupTitleTemplate extends IDisposableTemplate { parent: HTMLElement; } +interface IValueRenderResult { + overflows?: boolean; +} + const SETTINGS_TEXT_TEMPLATE_ID = 'settings.text.template'; const SETTINGS_NUMBER_TEMPLATE_ID = 'settings.number.template'; const SETTINGS_ENUM_TEMPLATE_ID = 'settings.enum.template'; @@ -1012,17 +1016,19 @@ export class SettingsRenderer implements ITreeRenderer { template.labelElement.textContent = element.displayLabel; template.labelElement.title = titleTooltip; - // Rewrite `#editor.fontSize#` to link format - const descriptionText = fixSettingLinks(element.description); - const renderedDescription = this.renderDescriptionMarkdown(descriptionText, template.toDispose); - + const renderedDescription = this.renderDescriptionMarkdown(element.description, template.toDispose); template.descriptionElement.innerHTML = ''; template.descriptionElement.appendChild(renderedDescription); (renderedDescription.querySelectorAll('a')).forEach(aElement => { aElement.tabIndex = isSelected ? 0 : -1; }); - this.renderValue(element, isSelected, templateId, template); + const result = this.renderValue(element, isSelected, templateId, template); + + const firstLineOverflows = renderedDescription.firstElementChild.clientHeight > 18; + const hasExtraLines = renderedDescription.childElementCount > 1; + const needsManualOverflowIndicator = (hasExtraLines || result.overflows) && !firstLineOverflows && !isSelected; + DOM.toggleClass(template.descriptionElement, 'setting-item-description-artificial-overflow', needsManualOverflowIndicator); template.isConfiguredElement.textContent = element.isConfigured ? localize('configured', "Modified") : ''; @@ -1038,6 +1044,9 @@ export class SettingsRenderer implements ITreeRenderer { } private renderDescriptionMarkdown(text: string, disposeables: IDisposable[]): HTMLElement { + // Rewrite `#editor.fontSize#` to link format + text = fixSettingLinks(text); + const renderedMarkdown = renderMarkdown({ value: text }, { actionHandler: { callback: (content: string) => { @@ -1056,11 +1065,11 @@ export class SettingsRenderer implements ITreeRenderer { return renderedMarkdown; } - private renderValue(element: SettingsTreeSettingElement, isSelected: boolean, templateId: string, template: ISettingItemTemplate | ISettingBoolItemTemplate): void { + private renderValue(element: SettingsTreeSettingElement, isSelected: boolean, templateId: string, template: ISettingItemTemplate | ISettingBoolItemTemplate): IValueRenderResult { const onChange = value => this._onDidChangeSetting.fire({ key: element.setting.key, value }); if (templateId === SETTINGS_ENUM_TEMPLATE_ID) { - this.renderEnum(element, isSelected, template, onChange); + return this.renderEnum(element, isSelected, template, onChange); } else if (templateId === SETTINGS_TEXT_TEMPLATE_ID) { this.renderText(element, isSelected, template, onChange); } else if (templateId === SETTINGS_NUMBER_TEMPLATE_ID) { @@ -1072,6 +1081,8 @@ export class SettingsRenderer implements ITreeRenderer { } else if (templateId === SETTINGS_COMPLEX_TEMPLATE_ID) { this.renderComplexSetting(element, isSelected, template); } + + return { overflows: false }; } private renderBool(dataElement: SettingsTreeSettingElement, isSelected: boolean, template: ISettingBoolItemTemplate, onChange: (value: boolean) => void): void { @@ -1082,7 +1093,7 @@ export class SettingsRenderer implements ITreeRenderer { template.checkbox.domNode.tabIndex = isSelected ? 0 : -1; } - private renderEnum(dataElement: SettingsTreeSettingElement, isSelected: boolean, template: ISettingEnumItemTemplate, onChange: (value: string) => void): void { + private renderEnum(dataElement: SettingsTreeSettingElement, isSelected: boolean, template: ISettingEnumItemTemplate, onChange: (value: string) => void): IValueRenderResult { const displayOptions = getDisplayEnumOptions(dataElement.setting); template.selectBox.setOptions(displayOptions); @@ -1100,19 +1111,25 @@ export class SettingsRenderer implements ITreeRenderer { template.enumDescriptionElement.innerHTML = ''; if (dataElement.setting.enumDescriptions && dataElement.setting.enum && dataElement.setting.enum.length < SettingsRenderer.MAX_ENUM_DESCRIPTIONS) { - let enumDescriptionText = '\n' + dataElement.setting.enumDescriptions - .map((desc, i) => { - const displayEnum = escapeInvisibleChars(dataElement.setting.enum[i]); - return desc ? - ` - \`${displayEnum}\`: ${desc}` : - ` - \`${dataElement.setting.enum[i]}\``; - }) - .filter(desc => !!desc) - .join('\n'); + if (isSelected) { + let enumDescriptionText = '\n' + dataElement.setting.enumDescriptions + .map((desc, i) => { + const displayEnum = escapeInvisibleChars(dataElement.setting.enum[i]); + return desc ? + ` - \`${displayEnum}\`: ${desc}` : + ` - \`${dataElement.setting.enum[i]}\``; + }) + .filter(desc => !!desc) + .join('\n'); - const renderedMarkdown = this.renderDescriptionMarkdown(fixSettingLinks(enumDescriptionText), template.toDispose); - template.enumDescriptionElement.appendChild(renderedMarkdown); + const renderedMarkdown = this.renderDescriptionMarkdown(fixSettingLinks(enumDescriptionText), template.toDispose); + template.enumDescriptionElement.appendChild(renderedMarkdown); + } + + return { overflows: true }; } + + return { overflows: false }; } private renderText(dataElement: SettingsTreeSettingElement, isSelected: boolean, template: ISettingTextItemTemplate, onChange: (value: string) => void): void { From f54367869d089335c2213340b8d2732404015295 Mon Sep 17 00:00:00 2001 From: Jackson Kearl Date: Tue, 31 Jul 2018 18:39:24 -0700 Subject: [PATCH 0375/1276] Don't show existing filters in autocomplete (#55495) * Dont show existing filters in autocomplete * Simplify --- .../parts/extensions/common/extensionQuery.ts | 22 ++++++++++++++----- .../electron-browser/extensionsViewlet.ts | 2 +- .../test/common/extensionQuery.test.ts | 8 +++++++ 3 files changed, 26 insertions(+), 6 deletions(-) diff --git a/src/vs/workbench/parts/extensions/common/extensionQuery.ts b/src/vs/workbench/parts/extensions/common/extensionQuery.ts index aa271d1498f..b966d438028 100644 --- a/src/vs/workbench/parts/extensions/common/extensionQuery.ts +++ b/src/vs/workbench/parts/extensions/common/extensionQuery.ts @@ -12,7 +12,7 @@ export class Query { this.value = value.trim(); } - static autocompletions(): string[] { + static autocompletions(query: string): string[] { const commands = ['installed', 'outdated', 'enabled', 'disabled', 'builtin', 'recommended', 'sort', 'category', 'tag', 'ext']; const subcommands = { 'sort': ['installs', 'rating', 'name'], @@ -21,11 +21,23 @@ export class Query { 'ext': [''] }; + let queryContains = (substr: string) => query.indexOf(substr) > -1; + let hasSort = subcommands.sort.some(subcommand => queryContains(`@sort:${subcommand}`)); + let hasCategory = subcommands.category.some(subcommand => queryContains(`@category:${subcommand}`)); + return flatten( - commands.map(command => - subcommands[command] - ? subcommands[command].map(subcommand => `@${command}:${subcommand}${subcommand === '' ? '' : ' '}`) - : [`@${command} `])); + commands.map(command => { + if (hasSort && command === 'sort' || hasCategory && command === 'category') { + return []; + } + if (subcommands[command]) { + return subcommands[command].map(subcommand => `@${command}:${subcommand}${subcommand === '' ? '' : ' '}`); + } + else { + return [`@${command} `]; + } + })); + } static parse(value: string): Query { diff --git a/src/vs/workbench/parts/extensions/electron-browser/extensionsViewlet.ts b/src/vs/workbench/parts/extensions/electron-browser/extensionsViewlet.ts index ece3592e355..f9a6fdd2949 100644 --- a/src/vs/workbench/parts/extensions/electron-browser/extensionsViewlet.ts +++ b/src/vs/workbench/parts/extensions/electron-browser/extensionsViewlet.ts @@ -539,7 +539,7 @@ export class ExtensionsViewlet extends ViewContainerViewlet implements IExtensio // dont show autosuggestions if the user has typed something, but hasn't used the trigger character if (alreadyTypedCount > 0 && query[wordStart] !== '@') { return []; } - return Query.autocompletions().map(replacement => ({ fullText: replacement, overwrite: alreadyTypedCount })); + return Query.autocompletions(query).map(replacement => ({ fullText: replacement, overwrite: alreadyTypedCount })); } private count(): number { diff --git a/src/vs/workbench/parts/extensions/test/common/extensionQuery.test.ts b/src/vs/workbench/parts/extensions/test/common/extensionQuery.test.ts index 1d1031053eb..a3ba946041f 100644 --- a/src/vs/workbench/parts/extensions/test/common/extensionQuery.test.ts +++ b/src/vs/workbench/parts/extensions/test/common/extensionQuery.test.ts @@ -140,4 +140,12 @@ suite('Extension query', () => { query2 = new Query('hello', 'installs', ''); assert(!query1.equals(query2)); }); + + test('autocomplete', () => { + Query.autocompletions('@sort:in').some(x => x === '@sort:installs '); + Query.autocompletions('@sort:installs').every(x => x !== '@sort:rating '); + + Query.autocompletions('@category:blah').some(x => x === '@category:"extension packs" '); + Query.autocompletions('@category:"extension packs"').every(x => x !== '@category:formatters '); + }); }); \ No newline at end of file From 2ba4c71110375d01c49011df1ddc7848fb987d53 Mon Sep 17 00:00:00 2001 From: Christopher Leidigh Date: Tue, 31 Jul 2018 22:00:25 -0400 Subject: [PATCH 0376/1276] Settings Editor: Add aria labels for input elements Fixes: #54836 (#55543) --- .../browser/ui/selectBox/selectBoxCustom.ts | 3 + .../parts/preferences/browser/settingsTree.ts | 60 ++++++++++++++++++- 2 files changed, 62 insertions(+), 1 deletion(-) diff --git a/src/vs/base/browser/ui/selectBox/selectBoxCustom.ts b/src/vs/base/browser/ui/selectBox/selectBoxCustom.ts index 2efed5c5dcf..d78f3f89e15 100644 --- a/src/vs/base/browser/ui/selectBox/selectBoxCustom.ts +++ b/src/vs/base/browser/ui/selectBox/selectBoxCustom.ts @@ -58,6 +58,9 @@ class SelectListRenderer implements IRendererdata.root), 'option-disabled'); diff --git a/src/vs/workbench/parts/preferences/browser/settingsTree.ts b/src/vs/workbench/parts/preferences/browser/settingsTree.ts index 0500c36655a..f89696551ba 100644 --- a/src/vs/workbench/parts/preferences/browser/settingsTree.ts +++ b/src/vs/workbench/parts/preferences/browser/settingsTree.ts @@ -1091,13 +1091,32 @@ export class SettingsRenderer implements ITreeRenderer { template.onChange = onChange; template.checkbox.domNode.tabIndex = isSelected ? 0 : -1; + + // Setup and add ARIA attributes + // Create id and label for control/input element - parent is wrapper div + const id = (dataElement.displayCategory + '_' + dataElement.displayLabel).replace(/ /g, '_'); + const label = ' ' + dataElement.displayCategory + ' ' + dataElement.displayLabel + ' checkbox ' + (dataElement.value ? 'checked ' : 'unchecked ') + template.isConfiguredElement.textContent; + + // We use the parent control div for the aria-labelledby target + // Does not appear you can use the direct label on the element itself within a tree + template.checkbox.domNode.parentElement.setAttribute('id', id); + template.checkbox.domNode.parentElement.setAttribute('aria-label', label); + + // Labels will not be read on descendent input elements of the parent treeitem + // unless defined as role=treeitem and indirect aria-labelledby approach + // TODO: Determine method to normally label input items with value read last + template.checkbox.domNode.setAttribute('id', id + 'item'); + template.checkbox.domNode.setAttribute('role', 'treeitem'); + template.checkbox.domNode.setAttribute('aria-labelledby', id + 'item ' + id); + } private renderEnum(dataElement: SettingsTreeSettingElement, isSelected: boolean, template: ISettingEnumItemTemplate, onChange: (value: string) => void): IValueRenderResult { const displayOptions = getDisplayEnumOptions(dataElement.setting); template.selectBox.setOptions(displayOptions); - const label = dataElement.displayCategory + ' ' + dataElement.displayLabel; + const label = ' ' + dataElement.displayCategory + ' ' + dataElement.displayLabel + ' combobox ' + template.isConfiguredElement.textContent; + template.selectBox.setAriaLabel(label); const idx = dataElement.setting.enum.indexOf(dataElement.value); @@ -1107,6 +1126,8 @@ export class SettingsRenderer implements ITreeRenderer { if (template.controlElement.firstElementChild) { template.controlElement.firstElementChild.setAttribute('tabindex', isSelected ? '0' : '-1'); + // SelectBox needs to be treeitem to read correctly within tree + template.controlElement.firstElementChild.setAttribute('role', 'treeitem'); } template.enumDescriptionElement.innerHTML = ''; @@ -1137,8 +1158,27 @@ export class SettingsRenderer implements ITreeRenderer { template.inputBox.value = dataElement.value; template.onChange = value => onChange(value); template.inputBox.inputElement.tabIndex = isSelected ? 0 : -1; + + // Setup and add ARIA attributes + // Create id and label for control/input element - parent is wrapper div + const id = (dataElement.displayCategory + '_' + dataElement.displayLabel).replace(/ /g, '_'); + const label = ' ' + dataElement.displayCategory + ' ' + dataElement.displayLabel + ' ' + template.isConfiguredElement.textContent; + + // We use the parent control div for the aria-labelledby target + // Does not appear you can use the direct label on the element itself within a tree + template.inputBox.inputElement.parentElement.setAttribute('id', id); + template.inputBox.inputElement.parentElement.setAttribute('aria-label', label); + + // Labels will not be read on descendent input elements of the parent treeitem + // unless defined as role=treeitem and indirect aria-labelledby approach + // TODO: Determine method to normally label input items with value read last + template.inputBox.inputElement.setAttribute('id', id + 'item'); + template.inputBox.inputElement.setAttribute('role', 'treeitem'); + template.inputBox.inputElement.setAttribute('aria-labelledby', id + 'item ' + id); + } + private renderNumber(dataElement: SettingsTreeSettingElement, isSelected: boolean, template: ISettingTextItemTemplate, onChange: (value: number) => void): void { template.onChange = null; template.inputBox.value = dataElement.value; @@ -1146,6 +1186,24 @@ export class SettingsRenderer implements ITreeRenderer { template.inputBox.inputElement.tabIndex = isSelected ? 0 : -1; const parseFn = dataElement.valueType === 'integer' ? parseInt : parseFloat; + + // Setup and add ARIA attributes + // Create id and label for control/input element - parent is wrapper div + const id = (dataElement.displayCategory + '_' + dataElement.displayLabel).replace(/ /g, '_'); + const label = ' ' + dataElement.displayCategory + ' ' + dataElement.displayLabel + ' number ' + template.isConfiguredElement.textContent; + + // We use the parent control div for the aria-labelledby target + // Does not appear you can use the direct label on the element itself within a tree + template.inputBox.inputElement.parentElement.setAttribute('id', id); + template.inputBox.inputElement.parentElement.setAttribute('aria-label', label); + + // Labels will not be read on descendent input elements of the parent treeitem + // unless defined as role=treeitem and indirect aria-labelledby approach + // TODO: Determine method to normally label input items with value read last + template.inputBox.inputElement.setAttribute('id', id + 'item'); + template.inputBox.inputElement.setAttribute('role', 'treeitem'); + template.inputBox.inputElement.setAttribute('aria-labelledby', id + 'item ' + id); + } private renderExcludeSetting(dataElement: SettingsTreeSettingElement, isSelected: boolean, template: ISettingExcludeItemTemplate): void { From d869b6440de521db120e4551600d935cd73a62ff Mon Sep 17 00:00:00 2001 From: SteVen Batten Date: Tue, 31 Jul 2018 19:08:25 -0700 Subject: [PATCH 0377/1276] fixes #55223 --- src/vs/workbench/electron-browser/media/shell.css | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/vs/workbench/electron-browser/media/shell.css b/src/vs/workbench/electron-browser/media/shell.css index 4911010c77c..fcadf9c40ac 100644 --- a/src/vs/workbench/electron-browser/media/shell.css +++ b/src/vs/workbench/electron-browser/media/shell.css @@ -65,6 +65,10 @@ cursor: pointer; } +.monaco-shell .monaco-menu-container .monaco-menu { + font-family: -apple-system, BlinkMacSystemFont, "Segoe WPC", "Segoe UI", "HelveticaNeue-Light", "Ubuntu", "Droid Sans", sans-serif; +} + .monaco-shell .monaco-menu .monaco-action-bar.vertical { padding: .5em 0; } From ba83f60dc38f740a3ae0d9a89f33e8149062686f Mon Sep 17 00:00:00 2001 From: Pine Wu Date: Tue, 31 Jul 2018 19:26:52 -0700 Subject: [PATCH 0378/1276] Update vscode-css-languageservice to 3.0.10-next.1 --- extensions/css-language-features/server/package.json | 2 +- extensions/css-language-features/server/yarn.lock | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/extensions/css-language-features/server/package.json b/extensions/css-language-features/server/package.json index 756396ae8fa..2a42529da61 100644 --- a/extensions/css-language-features/server/package.json +++ b/extensions/css-language-features/server/package.json @@ -8,7 +8,7 @@ "node": "*" }, "dependencies": { - "vscode-css-languageservice": "^3.0.9", + "vscode-css-languageservice": "^3.0.10-next.1", "vscode-languageserver": "^4.4.0" }, "devDependencies": { diff --git a/extensions/css-language-features/server/yarn.lock b/extensions/css-language-features/server/yarn.lock index c2025f27675..b8f4a686759 100644 --- a/extensions/css-language-features/server/yarn.lock +++ b/extensions/css-language-features/server/yarn.lock @@ -194,9 +194,9 @@ supports-color@5.4.0: dependencies: has-flag "^3.0.0" -vscode-css-languageservice@^3.0.9: - version "3.0.9" - resolved "https://registry.yarnpkg.com/vscode-css-languageservice/-/vscode-css-languageservice-3.0.9.tgz#770471350120c5bcf6918632a125638fc0ece3be" +vscode-css-languageservice@^3.0.10-next.1: + version "3.0.10-next.1" + resolved "https://registry.yarnpkg.com/vscode-css-languageservice/-/vscode-css-languageservice-3.0.10-next.1.tgz#1df5c9f306ad22f5c4f45ea8a2f96664ecc19de8" dependencies: vscode-languageserver-types "^3.10.0" vscode-nls "^3.2.4" From c1c820296373978c12d1e1c28e9ac6267ae58439 Mon Sep 17 00:00:00 2001 From: Rob Lourens Date: Tue, 31 Jul 2018 20:57:57 -0700 Subject: [PATCH 0379/1276] Fix #55509 - settings navigation --- src/vs/workbench/parts/preferences/browser/settingsTree.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/vs/workbench/parts/preferences/browser/settingsTree.ts b/src/vs/workbench/parts/preferences/browser/settingsTree.ts index f89696551ba..888d13f4b36 100644 --- a/src/vs/workbench/parts/preferences/browser/settingsTree.ts +++ b/src/vs/workbench/parts/preferences/browser/settingsTree.ts @@ -1572,6 +1572,8 @@ export class SettingsTree extends NonExpandableTree { current = nav.previous(); } while (current instanceof SettingsTreeGroupElement); - this.setFocus(current, eventPayload); + if (current) { + this.setFocus(current, eventPayload); + } } } From 9f6b201b7f92b4719d8904d336acd4d41832fb20 Mon Sep 17 00:00:00 2001 From: Rob Lourens Date: Tue, 31 Jul 2018 21:12:12 -0700 Subject: [PATCH 0380/1276] Fix #55519 --- .../workbench/parts/preferences/browser/settingsWidgets.ts | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/vs/workbench/parts/preferences/browser/settingsWidgets.ts b/src/vs/workbench/parts/preferences/browser/settingsWidgets.ts index 94bf81c8108..f0db59af916 100644 --- a/src/vs/workbench/parts/preferences/browser/settingsWidgets.ts +++ b/src/vs/workbench/parts/preferences/browser/settingsWidgets.ts @@ -334,11 +334,12 @@ export class ExcludeSettingWidget extends Disposable { const onSubmit = edited => { this.model.setEditKey(null); - if (edited) { + const pattern = patternInput.value.trim(); + if (edited && pattern) { this._onDidChangeExclude.fire({ originalPattern: item.pattern, - pattern: patternInput.value, - sibling: siblingInput && siblingInput.value + pattern, + sibling: siblingInput && siblingInput.value.trim() }); } else { this.renderList(); From 656e740ad9998748b672551a5f315f6dfaa87041 Mon Sep 17 00:00:00 2001 From: Rob Lourens Date: Tue, 31 Jul 2018 21:13:35 -0700 Subject: [PATCH 0381/1276] Fix #55520 --- src/vs/workbench/parts/preferences/browser/settingsWidgets.ts | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/vs/workbench/parts/preferences/browser/settingsWidgets.ts b/src/vs/workbench/parts/preferences/browser/settingsWidgets.ts index f0db59af916..595f1a90e36 100644 --- a/src/vs/workbench/parts/preferences/browser/settingsWidgets.ts +++ b/src/vs/workbench/parts/preferences/browser/settingsWidgets.ts @@ -349,6 +349,9 @@ export class ExcludeSettingWidget extends Disposable { const onKeydown = (e: StandardKeyboardEvent) => { if (e.equals(KeyCode.Enter)) { onSubmit(true); + } else if (e.equals(KeyCode.Escape)) { + onSubmit(false); + e.preventDefault(); } }; From 573d53815e74f8e4a52c2b6665f5ba9a92dbd341 Mon Sep 17 00:00:00 2001 From: Rob Lourens Date: Tue, 31 Jul 2018 21:24:14 -0700 Subject: [PATCH 0382/1276] FIx #55524 --- .../parts/preferences/browser/media/settingsWidgets.css | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vs/workbench/parts/preferences/browser/media/settingsWidgets.css b/src/vs/workbench/parts/preferences/browser/media/settingsWidgets.css index e2e1bfa7f4f..b34fee0b67b 100644 --- a/src/vs/workbench/parts/preferences/browser/media/settingsWidgets.css +++ b/src/vs/workbench/parts/preferences/browser/media/settingsWidgets.css @@ -75,7 +75,7 @@ .settings-editor > .settings-body > .settings-tree-container .setting-item.setting-item-exclude .monaco-text-button { width: initial; - padding: 2px 9px; + padding: 2px 14px; } .settings-editor > .settings-body > .settings-tree-container .setting-item.setting-item-exclude .setting-item-control.setting-exclude-new-mode .setting-exclude-new-row { From 377939ac043400e2a18344d9c865b6b13121ea50 Mon Sep 17 00:00:00 2001 From: Rob Lourens Date: Tue, 31 Jul 2018 22:12:42 -0700 Subject: [PATCH 0383/1276] Fix #55556 - include wordSeparators in all search queries, so findTextInFiles can respect isWordMatch correctly --- src/vs/workbench/parts/search/browser/searchView.ts | 1 - src/vs/workbench/parts/search/common/queryBuilder.ts | 4 +++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/src/vs/workbench/parts/search/browser/searchView.ts b/src/vs/workbench/parts/search/browser/searchView.ts index 85bd5d5d603..fe81d90a0f5 100644 --- a/src/vs/workbench/parts/search/browser/searchView.ts +++ b/src/vs/workbench/parts/search/browser/searchView.ts @@ -1069,7 +1069,6 @@ export class SearchView extends Viewlet implements IViewlet, IPanel { isRegExp: isRegex, isCaseSensitive: isCaseSensitive, isWordMatch: isWholeWords, - wordSeparators: this.configurationService.getValue().editor.wordSeparators, isSmartCase: this.configurationService.getValue().search.smartCase }; diff --git a/src/vs/workbench/parts/search/common/queryBuilder.ts b/src/vs/workbench/parts/search/common/queryBuilder.ts index 525753bcae8..8d13bef82a3 100644 --- a/src/vs/workbench/parts/search/common/queryBuilder.ts +++ b/src/vs/workbench/parts/search/common/queryBuilder.ts @@ -73,6 +73,8 @@ export class QueryBuilder { if (contentPattern) { this.resolveSmartCaseToCaseSensitive(contentPattern); + + contentPattern.wordSeparators = this.configurationService.getValue().editor.wordSeparators; } const query: ISearchQuery = { @@ -88,7 +90,7 @@ export class QueryBuilder { maxResults: options.maxResults, sortByScore: options.sortByScore, cacheKey: options.cacheKey, - contentPattern: contentPattern, + contentPattern, useRipgrep, disregardIgnoreFiles: options.disregardIgnoreFiles || !useIgnoreFiles, disregardExcludeSettings: options.disregardExcludeSettings, From 44f5e55785a2227e7098b05d02ced16a03c94d55 Mon Sep 17 00:00:00 2001 From: SteVen Batten Date: Tue, 31 Jul 2018 22:40:01 -0700 Subject: [PATCH 0384/1276] oss updates for endgame --- ThirdPartyNotices.txt | 378 ++++++++++++++++-- .../OSSREADME.json | 76 +--- package.json | 2 +- 3 files changed, 344 insertions(+), 112 deletions(-) diff --git a/ThirdPartyNotices.txt b/ThirdPartyNotices.txt index b2fe9e4c585..80e9fd6e808 100644 --- a/ThirdPartyNotices.txt +++ b/ThirdPartyNotices.txt @@ -21,48 +21,51 @@ This project incorporates components from the projects listed below. The origina 14. davidrios/pug-tmbundle (https://github.com/davidrios/pug-tmbundle) 15. definitelytyped (https://github.com/DefinitelyTyped/DefinitelyTyped) 16. demyte/language-cshtml (https://github.com/demyte/language-cshtml) -17. dotnet/csharp-tmLanguage version 0.1.0 (https://github.com/dotnet/csharp-tmLanguage) -18. expand-abbreviation version 0.5.8 (https://github.com/emmetio/expand-abbreviation) -19. fadeevab/make.tmbundle (https://github.com/fadeevab/make.tmbundle) -20. freebroccolo/atom-language-swift (https://github.com/freebroccolo/atom-language-swift) -21. HTML 5.1 W3C Working Draft version 08 October 2015 (http://www.w3.org/TR/2015/WD-html51-20151008/) -22. Ikuyadeu/vscode-R (https://github.com/Ikuyadeu/vscode-R) -23. Ionic documentation version 1.2.4 (https://github.com/ionic-team/ionic-site) -24. ionide/ionide-fsgrammar (https://github.com/ionide/ionide-fsgrammar) -25. js-beautify version 1.6.8 (https://github.com/beautify-web/js-beautify) -26. Jxck/assert version 1.0.0 (https://github.com/Jxck/assert) -27. language-docker (https://github.com/moby/moby) -28. language-go version 0.39.0 (https://github.com/atom/language-go) -29. language-less (https://github.com/atom/language-less) -30. language-php (https://github.com/atom/language-php) -31. language-rust version 0.4.9 (https://github.com/zargony/atom-language-rust) -32. MagicStack/MagicPython (https://github.com/MagicStack/MagicPython) -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 (https://github.com/Microsoft/vscode-mssql) -37. mmims/language-batchfile (https://github.com/mmims/language-batchfile) -38. octicons-code version 3.1.0 (https://octicons.github.com) -39. octicons-font version 3.1.0 (https://octicons.github.com) -40. PowerShell/EditorSyntax (https://github.com/powershell/editorsyntax) -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. vscode-logfile-highlighter version 1.2.0 (https://github.com/emilast/vscode-logfile-highlighter) -58. vscode-swift version 0.0.1 (https://github.com/owensd/vscode-swift) +17. Document Object Model () +18. dotnet/csharp-tmLanguage version 0.1.0 (https://github.com/dotnet/csharp-tmLanguage) +19. expand-abbreviation version 0.5.8 (https://github.com/emmetio/expand-abbreviation) +20. fadeevab/make.tmbundle (https://github.com/fadeevab/make.tmbundle) +21. freebroccolo/atom-language-swift (https://github.com/freebroccolo/atom-language-swift) +22. HTML 5.1 W3C Working Draft version 08 October 2015 (http://www.w3.org/TR/2015/WD-html51-20151008/) +23. Ikuyadeu/vscode-R (https://github.com/Ikuyadeu/vscode-R) +24. Ionic documentation version 1.2.4 (https://github.com/ionic-team/ionic-site) +25. ionide/ionide-fsgrammar (https://github.com/ionide/ionide-fsgrammar) +26. js-beautify version 1.6.8 (https://github.com/beautify-web/js-beautify) +27. Jxck/assert version 1.0.0 (https://github.com/Jxck/assert) +28. language-docker (https://github.com/moby/moby) +29. language-go version 0.39.0 (https://github.com/atom/language-go) +30. language-less (https://github.com/atom/language-less) +31. language-php (https://github.com/atom/language-php) +32. language-rust version 0.4.9 (https://github.com/zargony/atom-language-rust) +33. MagicStack/MagicPython (https://github.com/MagicStack/MagicPython) +34. mdn-data version 1.1.12 (https://github.com/mdn/data) +35. Microsoft/TypeScript-TmLanguage version 0.0.1 (https://github.com/Microsoft/TypeScript-TmLanguage) +36. Microsoft/vscode-JSON.tmLanguage (https://github.com/Microsoft/vscode-JSON.tmLanguage) +37. Microsoft/vscode-mssql (https://github.com/Microsoft/vscode-mssql) +38. mmims/language-batchfile (https://github.com/mmims/language-batchfile) +39. octicons-code version 3.1.0 (https://octicons.github.com) +40. octicons-font version 3.1.0 (https://octicons.github.com) +41. PowerShell/EditorSyntax (https://github.com/powershell/editorsyntax) +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. Unicode () +59. vscode-logfile-highlighter version 1.2.0 (https://github.com/emilast/vscode-logfile-highlighter) +60. vscode-swift version 0.0.1 (https://github.com/owensd/vscode-swift) +61. Web Background Synchronization (https://github.com/WICG/BackgroundSync) %% atom/language-c NOTICES AND INFORMATION BEGIN HERE @@ -600,6 +603,27 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ========================================= END OF demyte/language-cshtml NOTICES AND INFORMATION +%% Document Object Model NOTICES AND INFORMATION BEGIN HERE +========================================= +W3C License +This work is being provided by the copyright holders under the following license. +By obtaining and/or copying this work, you (the licensee) agree that you have read, understood, and will comply with the following terms and conditions. +Permission to copy, modify, and distribute this work, with or without modification, for any purpose and without fee or royalty is hereby granted, provided that you include the following +on ALL copies of the work or portions thereof, including modifications: +* The full text of this NOTICE in a location viewable to users of the redistributed or derivative work. +* Any pre-existing intellectual property disclaimers, notices, or terms and conditions. If none exist, the W3C Software and Document Short Notice should be included. +* Notice of any changes or modifications, through a copyright statement on the new code or document such as "This software or document includes material copied from or derived +from Document Object Model. Copyright © 2015 W3C® (MIT, ERCIM, Keio, Beihang)." +Disclaimers +THIS WORK IS PROVIDED "AS IS + AND COPYRIGHT HOLDERS MAKE NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO, WARRANTIES OF MERCHANTABILITY OR +FITNESS FOR ANY PARTICULAR PURPOSE OR THAT THE USE OF THE SOFTWARE OR DOCUMENT WILL NOT INFRINGE ANY THIRD PARTY PATENTS, COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS. +COPYRIGHT HOLDERS WILL NOT BE LIABLE FOR ANY DIRECT, INDIRECT, SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF ANY USE OF THE SOFTWARE OR DOCUMENT. +The name and trademarks of copyright holders may NOT be used in advertising or publicity pertaining to the work without specific, written prior permission. +Title to copyright in this work will at all times remain with copyright holders. +========================================= +END OF Document Object Model NOTICES AND INFORMATION + %% dotnet/csharp-tmLanguage NOTICES AND INFORMATION BEGIN HERE ========================================= MIT License @@ -831,7 +855,7 @@ END OF ionide/ionide-fsgrammar NOTICES AND INFORMATION ========================================= The MIT License (MIT) -Copyright (c) 2007-2017 Einar Lielmanis, Liam Newman, and contributors. +Copyright (c) 2007-2018 Einar Lielmanis, Liam Newman, and contributors. 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: @@ -2225,6 +2249,66 @@ THE SOFTWARE. ========================================= END OF TypeScript-TmLanguage NOTICES AND INFORMATION +%% Unicode NOTICES AND INFORMATION BEGIN HERE +========================================= +Unicode Data Files include all data files under the directories +http://www.unicode.org/Public/, http://www.unicode.org/reports/, +http://www.unicode.org/cldr/data/, http://source.icu-project.org/repos/icu/, and +http://www.unicode.org/utility/trac/browser/. + +Unicode Data Files do not include PDF online code charts under the +directory http://www.unicode.org/Public/. + +Software includes any source code published in the Unicode Standard +or under the directories +http://www.unicode.org/Public/, http://www.unicode.org/reports/, +http://www.unicode.org/cldr/data/, http://source.icu-project.org/repos/icu/, and +http://www.unicode.org/utility/trac/browser/. + +NOTICE TO USER: Carefully read the following legal agreement. +BY DOWNLOADING, INSTALLING, COPYING OR OTHERWISE USING UNICODE INC.'S +DATA FILES ("DATA FILES"), AND/OR SOFTWARE ("SOFTWARE"), +YOU UNEQUIVOCALLY ACCEPT, AND AGREE TO BE BOUND BY, ALL OF THE +TERMS AND CONDITIONS OF THIS AGREEMENT. +IF YOU DO NOT AGREE, DO NOT DOWNLOAD, INSTALL, COPY, DISTRIBUTE OR USE +THE DATA FILES OR SOFTWARE. + +COPYRIGHT AND PERMISSION NOTICE + +Copyright (c) 1991-2017 Unicode, Inc. All rights reserved. +Distributed under the Terms of Use in http://www.unicode.org/copyright.html. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of the Unicode data files and any associated documentation +(the "Data Files") or Unicode software and any associated documentation +(the "Software") to deal in the Data Files or Software +without restriction, including without limitation the rights to use, +copy, modify, merge, publish, distribute, and/or sell copies of +the Data Files or Software, and to permit persons to whom the Data Files +or Software are furnished to do so, provided that either +(a) this copyright and permission notice appear with all copies +of the Data Files or Software, or +(b) this copyright and permission notice appear in associated +Documentation. + +THE DATA FILES AND SOFTWARE ARE 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 OF THIRD PARTY RIGHTS. +IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS INCLUDED IN THIS +NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL +DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, +DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER +TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR +PERFORMANCE OF THE DATA FILES OR SOFTWARE. + +Except as contained in this notice, the name of a copyright holder +shall not be used in advertising or otherwise to promote the sale, +use or other dealings in these Data Files or Software without prior +written authorization of the copyright holder. +========================================= +END OF Unicode NOTICES AND INFORMATION + %% vscode-logfile-highlighter NOTICES AND INFORMATION BEGIN HERE ========================================= The MIT License (MIT) @@ -2274,4 +2358,210 @@ 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. ========================================= -END OF vscode-swift NOTICES AND INFORMATION \ No newline at end of file +END OF vscode-swift NOTICES AND INFORMATION + +%% Web Background Synchronization NOTICES AND INFORMATION BEGIN HERE +========================================= +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: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) 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 + + (d) 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 + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "{}" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright {yyyy} {name of copyright owner} + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +========================================= +END OF Web Background Synchronization NOTICES AND INFORMATION \ No newline at end of file diff --git a/extensions/typescript-language-features/OSSREADME.json b/extensions/typescript-language-features/OSSREADME.json index d36b840718e..692c0592a16 100644 --- a/extensions/typescript-language-features/OSSREADME.json +++ b/extensions/typescript-language-features/OSSREADME.json @@ -7,19 +7,10 @@ "description": "The files syntaxes/TypeScript.tmLanguage.json and syntaxes/TypeScriptReact.tmLanguage.json were derived from TypeScript.tmLanguage and TypeScriptReact.tmLanguage in https://github.com/Microsoft/TypeScript-TmLanguage." }, { - "name": "DefinitelyTyped", - "version": "0.0.2", + "name": "definitelytyped", "license": "MIT", "repositoryURL": "https://github.com/DefinitelyTyped/DefinitelyTyped", - "description": "Typings files that are downloaded by TypeScript. These typings power IntelliSense for JavaScript and TypeScript.", - "licenseDetail": [ - "MIT License", - "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.", - ] + "description": "Typings files that are downloaded by TypeScript. These typings power IntelliSense for JavaScript and TypeScript." }, { "name": "Unicode", @@ -80,7 +71,7 @@ "Except as contained in this notice, the name of a copyright holder", "shall not be used in advertising or otherwise to promote the sale,", "use or other dealings in these Data Files or Software without prior", - "written authorization of the copyright holder.", + "written authorization of the copyright holder." ] }, { @@ -91,74 +82,25 @@ "W3C License", "This work is being provided by the copyright holders under the following license.", "By obtaining and/or copying this work, you (the licensee) agree that you have read, understood, and will comply with the following terms and conditions.", - "Permission to copy, modify, and distribute this work, with or without modification,�for any purpose and without fee or royalty is hereby granted, provided that you include the following ", + "Permission to copy, modify, and distribute this work, with or without modification, for any purpose and without fee or royalty is hereby granted, provided that you include the following ", "on ALL copies of the work or portions thereof, including modifications:", "* The full text of this NOTICE in a location viewable to users of the redistributed or derivative work.", "* Any pre-existing intellectual property disclaimers, notices, or terms and conditions. If none exist, the W3C Software and Document Short Notice should be included.", "* Notice of any changes or modifications, through a copyright statement on the new code or document such as \"This software or document includes material copied from or derived ", - "from [title and URI of the W3C document]. Copyright � [YEAR] W3C� (MIT, ERCIM, Keio, Beihang).\" ", + "from Document Object Model. Copyright © 2015 W3C® (MIT, ERCIM, Keio, Beihang).\" ", "Disclaimers", "THIS WORK IS PROVIDED \"AS IS", " AND COPYRIGHT HOLDERS MAKE NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO, WARRANTIES OF MERCHANTABILITY OR ", "FITNESS FOR ANY PARTICULAR PURPOSE OR THAT THE USE OF THE SOFTWARE OR DOCUMENT WILL NOT INFRINGE ANY THIRD PARTY PATENTS, COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS.", "COPYRIGHT HOLDERS WILL NOT BE LIABLE FOR ANY DIRECT, INDIRECT, SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF ANY USE OF THE SOFTWARE OR DOCUMENT.", "The name and trademarks of copyright holders may NOT be used in advertising or publicity pertaining to the work without specific, written prior permission. ", - "Title to copyright in this work will at all times remain with copyright holders.", + "Title to copyright in this work will at all times remain with copyright holders." ] }, { "name": "Web Background Synchronization", - "license": "W3C Community Final Specification Agreement", - "description": "TypeScript includes files related to this specification", - "licenseDetail": [ - "W3C Community Final Specification Agreement ", - "To secure commitments from participants for the full text of a Community or Business Group Report, the group may call for voluntary commitments to the following terms; a \"summary\" is ", - "available. See also the related \"W3C Community Contributor License Agreement\".", - "1. The Purpose of this Agreement.", - "This Agreement sets forth the terms under which I make certain copyright and patent rights available to you for your implementation of the Specification. ", - "Any other capitalized terms not specifically defined herein have the same meaning as those terms have in the \"W3C Patent Policy\", and if not defined there, in the \"W3C Process Document\".", - "2. Copyrights. ", - "2.1. Copyright Grant. I grant to you a perpetual (for the duration of the applicable copyright), worldwide, non-exclusive, no-charge, royalty-free, copyright license, without any obligation for accounting to me, to reproduce, prepare derivative works of, publicly display, publicly perform, sublicense, distribute, and implement the Specification to the full extent of my copyright interest in the Specification. ", - "2.2. Attribution. As a condition of the copyright grant, you must include an attribution to the Specification in any derivative work you make based on the Specification. That attribution must include, at minimum, the Specification name and version number.", - "3. Patents. ", - "3.1. Patent Licensing Commitment. I agree to license my Essential Claims under the W3C Community RF Licensing Requirements. This requirement includes Essential Claims that I own and any that I have the right to license without obligation of payment or other consideration to an unrelated third party. W3C Community RF Licensing Requirements obligations made concerning the Specification and described in this policy are binding on me for the life of the patents in question and encumber the patents containing Essential Claims, regardless of changes in participation status or W3C Membership. I also agree to license my Essential Claims under the W3C Community RF Licensing Requirements in derivative works of the Specification so long as all normative portions of the Specification are maintained and that this licensing commitment does not extend to any portion of the derivative work that was not included in the Specification.", - "3.2. Optional, Additional Patent Grant. In addition to the provisions of Section 3.1, I may also, at my option, make certain intellectual property rights infringed by implementations of the Specification, including Essential Claims, available by providing those terms via the W3C Web site.", - "4. No Other Rights. Except as specifically set forth in this Agreement, no other express or implied patent, trademark, copyright, or other property rights are granted under this Agreement, including by implication, waiver, or estoppel.", - "5. Antitrust Compliance. I acknowledge that I may compete with other participants, that I am under no obligation to implement the Specification, that each participant is free to develop competing technologies and standards, and that each party is free to license its patent rights to third parties, including for the purpose of enabling competing technologies and standards.", - "6. Non-Circumvention. I agree that I will not intentionally take or willfully assist any third party to take any action for the purpose of circumventing my obligations under this Agreement.", - "7. Transition to W3C Recommendation Track. The Specification developed by the Project may transition to the W3C Recommendation Track. The W3C Team is responsible for notifying me that a Corresponding Working Group has been chartered. I have no obligation to join the Corresponding Working Group. If the Specification developed by the Project transitions to the W3C Recommendation Track, the following terms apply: ", - "7.1. If I join the Corresponding Working Group. If I join the Corresponding Working Group, I will be subject to all W3C rules, obligations, licensing commitments, and policies that govern that Corresponding Working Group.", - "7.2. If I Do Not Join the Corresponding Working Group. ", - "7.2.1. Licensing Obligations to Resulting Specification. If I do not join the Corresponding Working Group, I agree to offer patent licenses according to the W3C Royalty-Free licensing requirements described in Section 5 of the W3C Patent Policy for the portions of the Specification included in the resulting Recommendation. This licensing commitment does not extend to any portion of an implementation of the Recommendation that was not included in the Specification. This licensing commitment may not be revoked but may be modified through the exclusion process defined in Section 4 of the W3C Patent Policy. I am not required to join the Corresponding Working Group to exclude patents from the W3C Royalty-Free licensing commitment, but must otherwise follow the normal exclusion procedures defined by the W3C Patent Policy. The W3C Team will notify me of any Call for Exclusion in the Corresponding Working Group as set forth in Section 4.5 of the W3C Patent Policy.", - "7.2.2. No Disclosure Obligation. If I do not join the Corresponding Working Group, I have no patent disclosure obligations outside of those set forth in Section 6 of the W3C Patent Policy.", - "8. Conflict of Interest. I will disclose significant relationships when those relationships might reasonably be perceived as creating a conflict of interest with my role. I will notify W3C of any change in my affiliation using W3C-provided mechanisms.", - "9. Representations, Warranties and Disclaimers. I represent and warrant that I am legally entitled to grant the rights and promises set forth in this Agreement. IN ALL OTHER RESPECTS THE SPECIFICATION IS PROVIDED �AS IS.� The entire risk as to implementing or otherwise using the Specification is assumed by the implementer and user. Except as stated herein, I expressly disclaim any warranties (express, implied, or otherwise), including implied warranties of merchantability, non-infringement, fitness for a particular purpose, or title, related to the Specification. IN NO EVENT WILL ANY PARTY BE LIABLE TO ANY OTHER PARTY FOR LOST PROFITS OR ANY FORM OF INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES OF ANY CHARACTER FROM ANY CAUSES OF ACTION OF ANY KIND WITH RESPECT TO THIS AGREEMENT, WHETHER BASED ON BREACH OF CONTRACT, TORT (INCLUDING NEGLIGENCE), OR OTHERWISE, AND WHETHER OR NOT THE OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. All of my obligations under Section 3 regarding the transfer, successors in interest, or assignment of Granted Claims will be satisfied if I notify the transferee or assignee of any patent that I know contains Granted Claims of the obligations under Section 3. Nothing in this Agreement requires me to undertake a patent search.", - "10. Definitions. ", - "10.1. Agreement. �Agreement� means this W3C Community Final Specification Agreement.", - "10.2. Corresponding Working Group. �Corresponding Working Group� is a W3C Working Group that is chartered to develop a Recommendation, as defined in the W3C Process Document, that takes the Specification as an input.", - "10.3. Essential Claims. �Essential Claims� shall mean all claims in any patent or patent application in any jurisdiction in the world that would necessarily be infringed by implementation of the Specification. A claim is necessarily infringed hereunder only when it is not possible to avoid infringing it because there is no non-infringing alternative for implementing the normative portions of the Specification. Existence of a non-infringing alternative shall be judged based on the state of the art at the time of the publication of the Specification. The following are expressly excluded from and shall not be deemed to constitute Essential Claims: ", - "10.3.1. any claims other than as set forth above even if contained in the same patent as Essential Claims; and", - "10.3.2. claims which would be infringed only by: ", - "portions of an implementation that are not specified in the normative portions of the Specification, or", - "enabling technologies that may be necessary to make or use any product or portion thereof that complies with the Specification and are not themselves expressly set forth in the Specification (e.g., semiconductor manufacturing technology, compiler technology, object-oriented technology, basic operating system technology, and the like); or", - "the implementation of technology developed elsewhere and merely incorporated by reference in the body of the Specification.", - "10.3.3. design patents and design registrations.", - "For purposes of this definition, the normative portions of the Specification shall be deemed to include only architectural and interoperability requirements. Optional features in the RFC 2119 sense are considered normative unless they are specifically identified as informative. Implementation examples or any other material that merely illustrate the requirements of the Specification are informative, rather than normative.", - "10.4. I, Me, or My. �I,� �me,� or �my� refers to the signatory.", - "10.5 Project. �Project� means the W3C Community Group or Business Group for which I executed this Agreement.", - "10.6. Specification. �Specification� means the Specification identified by the Project as the target of this agreement in a call for Final Specification Commitments. W3C shall provide the authoritative mechanisms for the identification of this Specification.", - "10.7. W3C Community RF Licensing Requirements. �W3C Community RF Licensing Requirements� license shall mean a non-assignable, non-sublicensable license to make, have made, use, sell, have sold, offer to sell, import, and distribute and dispose of implementations of the Specification that: ", - "10.7.1. shall be available to all, worldwide, whether or not they are W3C Members;", - "10.7.2. shall extend to all Essential Claims owned or controlled by me;", - "10.7.3. may be limited to implementations of the Specification, and to what is required by the Specification;", - "10.7.4. may be conditioned on a grant of a reciprocal RF license (as defined in this policy) to all Essential Claims owned or controlled by the licensee. A reciprocal license may be required to be available to all, and a reciprocal license may itself be conditioned on a further reciprocal license from all.", - "10.7.5. may not be conditioned on payment of royalties, fees or other consideration;", - "10.7.6. may be suspended with respect to any licensee when licensor issued by licensee for infringement of claims essential to implement the Specification or any W3C Recommendation;", - "10.7.7. may not impose any further conditions or restrictions on the use of any technology, intellectual property rights, or other restrictions on behavior of the licensee, but may include reasonable, customary terms relating to operation or maintenance of the license relationship such as the following: choice of law and dispute resolution;", - "10.7.8. shall not be considered accepted by an implementer who manifests an intent not to accept the terms of the W3C Community RF Licensing Requirements license as offered by the licensor.", - "10.7.9. The RF license conforming to the requirements in this policy shall be made available by the licensor as long as the Specification is in effect. The term of such license shall be for the life of the patents in question.", - "I am encouraged to provide a contact from which licensing information can be obtained and other relevant licensing information. Any such information will be made publicly available. ", - "10.8. You or Your. �You,� �you,� or �your� means any person or entity who exercises copyright or patent rights granted under this Agreement, and any person that person or entity controls.", - ] + "license": "Apache2", + "repositoryURL": "https://github.com/WICG/BackgroundSync", + "description": "TypeScript includes files related to this specification" } ] \ No newline at end of file diff --git a/package.json b/package.json index 95efbf04ae2..0d6b1e29e79 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "code-oss-dev", "version": "1.26.0", - "distro": "4b5c6aa6ea6f222d62d08ca5653049b200be93a5", + "distro": "26814526269ba3caa2e8c501de9626ad266eadd3", "author": { "name": "Microsoft Corporation" }, From 8ed12eacea3f893d53685822541ce36cdd7d681a Mon Sep 17 00:00:00 2001 From: Rob Lourens Date: Wed, 1 Aug 2018 07:58:36 -0700 Subject: [PATCH 0385/1276] Fix unit tests --- src/vs/workbench/parts/search/test/common/queryBuilder.test.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/vs/workbench/parts/search/test/common/queryBuilder.test.ts b/src/vs/workbench/parts/search/test/common/queryBuilder.test.ts index c3e961993fc..4ac216e7e23 100644 --- a/src/vs/workbench/parts/search/test/common/queryBuilder.test.ts +++ b/src/vs/workbench/parts/search/test/common/queryBuilder.test.ts @@ -17,6 +17,7 @@ import { IWorkspaceContextService, toWorkspaceFolders, Workspace } from 'vs/plat import { ISearchPathsResult, QueryBuilder } from 'vs/workbench/parts/search/common/queryBuilder'; import { TestContextService, TestEnvironmentService } from 'vs/workbench/test/workbenchTestServices'; +const DEFAULT_EDITOR_CONFIG = {}; const DEFAULT_USER_CONFIG = { useRipgrep: true, useIgnoreFiles: true }; const DEFAULT_QUERY_PROPS = { useRipgrep: true, disregardIgnoreFiles: false }; @@ -36,6 +37,7 @@ suite('QueryBuilder', () => { mockConfigService = new TestConfigurationService(); mockConfigService.setUserConfiguration('search', DEFAULT_USER_CONFIG); + mockConfigService.setUserConfiguration('editor', DEFAULT_EDITOR_CONFIG); instantiationService.stub(IConfigurationService, mockConfigService); mockContextService = new TestContextService(); From 7d74927479ad96a291d56db4518459e2ece08850 Mon Sep 17 00:00:00 2001 From: SteVen Batten Date: Wed, 1 Aug 2018 10:36:00 -0700 Subject: [PATCH 0386/1276] fixes #55522 --- src/vs/workbench/browser/parts/menubar/menubarPart.ts | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/vs/workbench/browser/parts/menubar/menubarPart.ts b/src/vs/workbench/browser/parts/menubar/menubarPart.ts index c0ef6872610..2163c692dc0 100644 --- a/src/vs/workbench/browser/parts/menubar/menubarPart.ts +++ b/src/vs/workbench/browser/parts/menubar/menubarPart.ts @@ -35,6 +35,7 @@ import { RunOnceScheduler } from 'vs/base/common/async'; import { MENUBAR_SELECTION_FOREGROUND, MENUBAR_SELECTION_BACKGROUND, MENUBAR_SELECTION_BORDER, TITLE_BAR_ACTIVE_FOREGROUND, TITLE_BAR_INACTIVE_FOREGROUND, MENU_BACKGROUND, MENU_FOREGROUND, MENU_SELECTION_BACKGROUND, MENU_SELECTION_FOREGROUND, MENU_SELECTION_BORDER } from 'vs/workbench/common/theme'; import URI from 'vs/base/common/uri'; import { IUriDisplayService } from 'vs/platform/uriDisplay/common/uriDisplay'; +import { foreground } from 'vs/platform/theme/common/colorRegistry'; interface CustomMenu { title: string; @@ -1043,7 +1044,11 @@ registerThemingParticipant((theme: ITheme, collector: ICssStyleCollector) => { `); } - const menuFgColor = theme.getColor(MENU_FOREGROUND); + let menuFgColor = theme.getColor(MENU_FOREGROUND); + if (!menuFgColor) { + menuFgColor = theme.getColor(foreground); + } + if (menuFgColor) { collector.addRule(` .monaco-shell .monaco-menu .monaco-action-bar.vertical, From 9e98050354ae55d4a25b77098a0a6e0ac03dfe43 Mon Sep 17 00:00:00 2001 From: Ramya Achutha Rao Date: Wed, 1 Aug 2018 10:49:41 -0700 Subject: [PATCH 0387/1276] Avoid missing manifest error from bubbling up #54757 --- .../parts/extensions/electron-browser/extensionsList.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vs/workbench/parts/extensions/electron-browser/extensionsList.ts b/src/vs/workbench/parts/extensions/electron-browser/extensionsList.ts index 1153fd57fb8..846d0185cd5 100644 --- a/src/vs/workbench/parts/extensions/electron-browser/extensionsList.ts +++ b/src/vs/workbench/parts/extensions/electron-browser/extensionsList.ts @@ -191,7 +191,7 @@ export class Renderer implements IPagedRenderer { extension.getManifest().then(manifest => { const name = manifest && manifest.contributes && manifest.contributes.localizations && manifest.contributes.localizations.length > 0 && manifest.contributes.localizations[0].localizedLanguageName; if (name) { data.description.textContent = name[0].toLocaleUpperCase() + name.slice(1); } - }); + }, () => { }); } disposeElement(): void { From c94aad7f1dc31c86692818a77b3d83116ff712ea Mon Sep 17 00:00:00 2001 From: Jackson Kearl Date: Wed, 1 Aug 2018 11:37:32 -0700 Subject: [PATCH 0388/1276] Settings format crawl --- extensions/php-language-features/package.nls.json | 2 +- src/vs/workbench/parts/markers/electron-browser/messages.ts | 2 +- src/vs/workbench/parts/scm/electron-browser/scm.contribution.ts | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/extensions/php-language-features/package.nls.json b/extensions/php-language-features/package.nls.json index c991103e41d..3920760d1d2 100644 --- a/extensions/php-language-features/package.nls.json +++ b/extensions/php-language-features/package.nls.json @@ -1,5 +1,5 @@ { - "configuration.suggest.basic": "Configures if the built-in PHP language suggestions are enabled. The support suggests PHP globals and variables.", + "configuration.suggest.basic": "Controls whether the built-in PHP language suggestions are enabled. The support suggests PHP globals and variables.", "configuration.validate.enable": "Enable/disable built-in PHP validation.", "configuration.validate.executablePath": "Points to the PHP executable.", "configuration.validate.run": "Whether the linter is run on save or on type.", diff --git a/src/vs/workbench/parts/markers/electron-browser/messages.ts b/src/vs/workbench/parts/markers/electron-browser/messages.ts index c5285fae726..09e3eddbb5d 100644 --- a/src/vs/workbench/parts/markers/electron-browser/messages.ts +++ b/src/vs/workbench/parts/markers/electron-browser/messages.ts @@ -16,7 +16,7 @@ export default class Messages { public static MARKERS_PANEL_SHOW_LABEL: string = nls.localize('problems.view.focus.label', "Focus Problems (Errors, Warnings, Infos)"); public static PROBLEMS_PANEL_CONFIGURATION_TITLE: string = nls.localize('problems.panel.configuration.title', "Problems View"); - public static PROBLEMS_PANEL_CONFIGURATION_AUTO_REVEAL: string = nls.localize('problems.panel.configuration.autoreveal', "Controls if Problems view should automatically reveal files when opening them"); + public static PROBLEMS_PANEL_CONFIGURATION_AUTO_REVEAL: string = nls.localize('problems.panel.configuration.autoreveal', "Controls whether Problems view should automatically reveal files when opening them."); public static MARKERS_PANEL_TITLE_PROBLEMS: string = nls.localize('markers.panel.title.problems', "Problems"); public static MARKERS_PANEL_ARIA_LABEL_PROBLEMS_TREE: string = nls.localize('markers.panel.aria.label.problems.tree', "Problems grouped by files"); diff --git a/src/vs/workbench/parts/scm/electron-browser/scm.contribution.ts b/src/vs/workbench/parts/scm/electron-browser/scm.contribution.ts index 6a37c940969..453a5aa6da3 100644 --- a/src/vs/workbench/parts/scm/electron-browser/scm.contribution.ts +++ b/src/vs/workbench/parts/scm/electron-browser/scm.contribution.ts @@ -71,7 +71,7 @@ Registry.as(ConfigurationExtensions.Configuration).regis properties: { 'scm.alwaysShowProviders': { type: 'boolean', - description: localize('alwaysShowProviders', "Whether to always show the Source Control Provider section."), + description: localize('alwaysShowProviders', "Controls whether to always show the Source Control Provider section."), default: false }, 'scm.diffDecorations': { From e69e4d3a477de5acd64802ac355ad6563a248ed6 Mon Sep 17 00:00:00 2001 From: Rob Lourens Date: Wed, 1 Aug 2018 10:04:20 -0700 Subject: [PATCH 0389/1276] Search provider - Fix FileSearchProvider to return array, not progress --- src/vs/vscode.proposed.d.ts | 2 +- src/vs/workbench/api/node/extHostSearch.ts | 39 +++++++++++----------- 2 files changed, 20 insertions(+), 21 deletions(-) diff --git a/src/vs/vscode.proposed.d.ts b/src/vs/vscode.proposed.d.ts index 8d6261752bb..93e24c066bf 100644 --- a/src/vs/vscode.proposed.d.ts +++ b/src/vs/vscode.proposed.d.ts @@ -192,7 +192,7 @@ declare module 'vscode' { * @param progress A progress callback that must be invoked for all results. * @param token A cancellation token. */ - provideFileSearchResults(query: FileSearchQuery, options: FileSearchOptions, progress: Progress, token: CancellationToken): Thenable; + provideFileSearchResults(query: FileSearchQuery, options: FileSearchOptions, token: CancellationToken): Thenable; } /** diff --git a/src/vs/workbench/api/node/extHostSearch.ts b/src/vs/workbench/api/node/extHostSearch.ts index a4be83baa25..234132adf2b 100644 --- a/src/vs/workbench/api/node/extHostSearch.ts +++ b/src/vs/workbench/api/node/extHostSearch.ts @@ -488,24 +488,6 @@ class FileSearchEngine { const queryTester = new QueryGlobTester(this.config, fq); const noSiblingsClauses = !queryTester.hasSiblingExcludeClauses(); - const onProviderResult = (result: URI) => { - if (this.isCanceled) { - return; - } - - const relativePath = path.relative(fq.folder.fsPath, result.fsPath); - - if (noSiblingsClauses) { - const basename = path.basename(result.fsPath); - this.matchFile(onResult, { base: fq.folder, relativePath, basename }); - - return; - } - - // TODO: Optimize siblings clauses with ripgrep here. - this.addDirectoryEntries(tree, fq.folder, relativePath, onResult); - }; - new TPromise(_resolve => process.nextTick(_resolve)) .then(() => { this.activeCancellationTokens.add(cancellation); @@ -515,10 +497,27 @@ class FileSearchEngine { pattern: this.config.filePattern || '' }, options, - { report: onProviderResult }, cancellation.token); }) - .then(() => { + .then(results => { + if (this.isCanceled) { + return; + } + + results.forEach(result => { + const relativePath = path.relative(fq.folder.fsPath, result.fsPath); + + if (noSiblingsClauses) { + const basename = path.basename(result.fsPath); + this.matchFile(onResult, { base: fq.folder, relativePath, basename }); + + return; + } + + // TODO: Optimize siblings clauses with ripgrep here. + this.addDirectoryEntries(tree, fq.folder, relativePath, onResult); + }); + this.activeCancellationTokens.delete(cancellation); if (this.isCanceled) { return null; From adf837e76954ccb716932267db21da4b4cfa7b55 Mon Sep 17 00:00:00 2001 From: Rob Lourens Date: Wed, 1 Aug 2018 11:44:37 -0700 Subject: [PATCH 0390/1276] Fix #55598 --- src/vs/vscode.proposed.d.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/vs/vscode.proposed.d.ts b/src/vs/vscode.proposed.d.ts index 93e24c066bf..8ff2ee9dd69 100644 --- a/src/vs/vscode.proposed.d.ts +++ b/src/vs/vscode.proposed.d.ts @@ -70,18 +70,18 @@ declare module 'vscode' { * Whether external files that exclude files, like .gitignore, should be respected. * See the vscode setting `"search.useIgnoreFiles"`. */ - useIgnoreFiles?: boolean; + useIgnoreFiles: boolean; /** * Whether symlinks should be followed while searching. * See the vscode setting `"search.followSymlinks"`. */ - followSymlinks?: boolean; + followSymlinks: boolean; /** * The maximum number of results to be returned. */ - maxResults?: number; + maxResults: number; } /** From c259ee91ec21acc9e6550d11a94a935bee9c7830 Mon Sep 17 00:00:00 2001 From: Rob Lourens Date: Wed, 1 Aug 2018 11:55:30 -0700 Subject: [PATCH 0391/1276] Settings editor - fix NPE rendering settings with no description --- src/vs/workbench/parts/preferences/browser/settingsTree.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vs/workbench/parts/preferences/browser/settingsTree.ts b/src/vs/workbench/parts/preferences/browser/settingsTree.ts index 888d13f4b36..15fbab7e679 100644 --- a/src/vs/workbench/parts/preferences/browser/settingsTree.ts +++ b/src/vs/workbench/parts/preferences/browser/settingsTree.ts @@ -1025,7 +1025,7 @@ export class SettingsRenderer implements ITreeRenderer { const result = this.renderValue(element, isSelected, templateId, template); - const firstLineOverflows = renderedDescription.firstElementChild.clientHeight > 18; + const firstLineOverflows = renderedDescription.firstElementChild && renderedDescription.firstElementChild.clientHeight > 18; const hasExtraLines = renderedDescription.childElementCount > 1; const needsManualOverflowIndicator = (hasExtraLines || result.overflows) && !firstLineOverflows && !isSelected; DOM.toggleClass(template.descriptionElement, 'setting-item-description-artificial-overflow', needsManualOverflowIndicator); From c8f0ee9763ee25c42c9b8db1fe55cb2a4607131f Mon Sep 17 00:00:00 2001 From: Jackson Kearl Date: Wed, 1 Aug 2018 12:05:04 -0700 Subject: [PATCH 0392/1276] dont render inden guides in search box (#55600) --- .../parts/extensions/electron-browser/extensionsViewlet.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/src/vs/workbench/parts/extensions/electron-browser/extensionsViewlet.ts b/src/vs/workbench/parts/extensions/electron-browser/extensionsViewlet.ts index f9a6fdd2949..f9328505929 100644 --- a/src/vs/workbench/parts/extensions/electron-browser/extensionsViewlet.ts +++ b/src/vs/workbench/parts/extensions/electron-browser/extensionsViewlet.ts @@ -691,6 +691,7 @@ function mixinHTMLInputStyleOptions(config: IEditorOptions, ariaLabel?: string): config.wordWrap = 'off'; config.scrollbar.vertical = 'hidden'; config.ariaLabel = ariaLabel || ''; + config.renderIndentGuides = false; config.cursorWidth = 1; config.snippetSuggestions = 'none'; config.suggest = { filterGraceful: false }; From 9129656f3d384634c513d5b1c9a555d76c936a40 Mon Sep 17 00:00:00 2001 From: SteVen Batten Date: Wed, 1 Aug 2018 13:03:00 -0700 Subject: [PATCH 0393/1276] fixes #55454 --- src/vs/code/electron-main/menubar.ts | 8 +++++++- src/vs/platform/menubar/common/menubar.ts | 2 +- src/vs/platform/menubar/common/menubarIpc.ts | 8 ++++---- .../platform/menubar/electron-main/menubarService.ts | 6 +++--- .../workbench/browser/parts/menubar/menubarPart.ts | 12 ++++++++++-- 5 files changed, 25 insertions(+), 11 deletions(-) diff --git a/src/vs/code/electron-main/menubar.ts b/src/vs/code/electron-main/menubar.ts index 76450d9930a..099946d4298 100644 --- a/src/vs/code/electron-main/menubar.ts +++ b/src/vs/code/electron-main/menubar.ts @@ -112,8 +112,14 @@ export class Menubar { return enableNativeTabs; } - updateMenu(menus: IMenubarData, windowId: number) { + updateMenu(menus: IMenubarData, windowId: number, additionalKeybindings?: Array) { this.menubarMenus = menus; + if (additionalKeybindings) { + additionalKeybindings.forEach(keybinding => { + this.keybindings[keybinding.id] = keybinding; + }); + } + this.scheduleUpdateMenu(); } diff --git a/src/vs/platform/menubar/common/menubar.ts b/src/vs/platform/menubar/common/menubar.ts index 817b099cc32..3e58c3e4c9b 100644 --- a/src/vs/platform/menubar/common/menubar.ts +++ b/src/vs/platform/menubar/common/menubar.ts @@ -13,7 +13,7 @@ export const IMenubarService = createDecorator('menubarService' export interface IMenubarService { _serviceBrand: any; - updateMenubar(windowId: number, menus: IMenubarData): TPromise; + updateMenubar(windowId: number, menus: IMenubarData, additionalKeybindings?: Array): TPromise; } export interface IMenubarData { diff --git a/src/vs/platform/menubar/common/menubarIpc.ts b/src/vs/platform/menubar/common/menubarIpc.ts index 13699176ef5..25a28a13845 100644 --- a/src/vs/platform/menubar/common/menubarIpc.ts +++ b/src/vs/platform/menubar/common/menubarIpc.ts @@ -6,7 +6,7 @@ 'use strict'; import { IChannel } from 'vs/base/parts/ipc/common/ipc'; import { TPromise } from 'vs/base/common/winjs.base'; -import { IMenubarService, IMenubarData } from 'vs/platform/menubar/common/menubar'; +import { IMenubarService, IMenubarData, IMenubarKeybinding } from 'vs/platform/menubar/common/menubar'; import { Event } from 'vs/base/common/event'; export interface IMenubarChannel extends IChannel { @@ -24,7 +24,7 @@ export class MenubarChannel implements IMenubarChannel { call(command: string, arg?: any): TPromise { switch (command) { - case 'updateMenubar': return this.service.updateMenubar(arg[0], arg[1]); + case 'updateMenubar': return this.service.updateMenubar(arg[0], arg[1], arg[2]); } return undefined; } @@ -36,7 +36,7 @@ export class MenubarChannelClient implements IMenubarService { constructor(private channel: IMenubarChannel) { } - updateMenubar(windowId: number, menus: IMenubarData): TPromise { - return this.channel.call('updateMenubar', [windowId, menus]); + updateMenubar(windowId: number, menus: IMenubarData, additionalKeybindings?: Array): TPromise { + return this.channel.call('updateMenubar', [windowId, menus, additionalKeybindings]); } } \ No newline at end of file diff --git a/src/vs/platform/menubar/electron-main/menubarService.ts b/src/vs/platform/menubar/electron-main/menubarService.ts index a24dd49126b..41bffbb3c69 100644 --- a/src/vs/platform/menubar/electron-main/menubarService.ts +++ b/src/vs/platform/menubar/electron-main/menubarService.ts @@ -5,7 +5,7 @@ 'use strict'; -import { IMenubarService, IMenubarData } from 'vs/platform/menubar/common/menubar'; +import { IMenubarService, IMenubarData, IMenubarKeybinding } from 'vs/platform/menubar/common/menubar'; import { Menubar } from 'vs/code/electron-main/menubar'; import { ILogService } from 'vs/platform/log/common/log'; import { TPromise } from 'vs/base/common/winjs.base'; @@ -24,11 +24,11 @@ export class MenubarService implements IMenubarService { this._menubar = this.instantiationService.createInstance(Menubar); } - updateMenubar(windowId: number, menus: IMenubarData): TPromise { + updateMenubar(windowId: number, menus: IMenubarData, additionalKeybindings?: Array): TPromise { this.logService.trace('menubarService#updateMenubar', windowId); if (this._menubar) { - this._menubar.updateMenu(menus, windowId); + this._menubar.updateMenu(menus, windowId, additionalKeybindings); } return TPromise.as(null); diff --git a/src/vs/workbench/browser/parts/menubar/menubarPart.ts b/src/vs/workbench/browser/parts/menubar/menubarPart.ts index 2163c692dc0..63d53eb8e02 100644 --- a/src/vs/workbench/browser/parts/menubar/menubarPart.ts +++ b/src/vs/workbench/browser/parts/menubar/menubarPart.ts @@ -430,8 +430,7 @@ export class MenubarPart extends Part { this.setupCustomMenubar(); } else { // Send menus to main process to be rendered by Electron - this.menubarService.updateMenubar(this.windowService.getCurrentWindowId(), this.getMenubarMenus()); - + this.menubarService.updateMenubar(this.windowService.getCurrentWindowId(), this.getMenubarMenus(), this.getAdditionalKeybindings()); } } @@ -846,6 +845,15 @@ export class MenubarPart extends Part { } } + private getAdditionalKeybindings(): Array { + const keybindings = []; + if (isMacintosh) { + keybindings.push(this.getMenubarKeybinding('workbench.action.quit')); + } + + return keybindings; + } + private getMenubarMenus(): IMenubarData { let ret: IMenubarData = {}; From 15044e8b2d8872ca83f5b5d75498a3e9746ede08 Mon Sep 17 00:00:00 2001 From: Jackson Kearl Date: Wed, 1 Aug 2018 13:27:26 -0700 Subject: [PATCH 0394/1276] More settings crawl --- src/vs/platform/list/browser/listService.ts | 8 ++--- .../electron-browser/main.contribution.ts | 36 ++++++++++--------- .../welcomePage.contribution.ts | 4 +-- 3 files changed, 24 insertions(+), 24 deletions(-) diff --git a/src/vs/platform/list/browser/listService.ts b/src/vs/platform/list/browser/listService.ts index 19f6c28b08a..d40542626af 100644 --- a/src/vs/platform/list/browser/listService.ts +++ b/src/vs/platform/list/browser/listService.ts @@ -748,20 +748,16 @@ configurationRegistry.registerConfiguration({ '- `ctrlCmd` refers to a value the setting can take and should not be localized.', '- `Control` and `Command` refer to the modifier keys Ctrl or Cmd on the keyboard and can be localized.' ] - }, "The modifier to be used to add an item in trees and lists to a multi-selection with the mouse (for example in the explorer, open editors and scm view). `ctrlCmd` maps to `Control` on Windows and Linux and to `Command` on macOS. The 'Open to Side' mouse gestures - if supported - will adapt such that they do not conflict with the multiselect modifier.") + }, "The modifier to be used to add an item in trees and lists to a multi-selection with the mouse (for example in the explorer, open editors and scm view). The 'Open to Side' mouse gestures - if supported - will adapt such that they do not conflict with the multiselect modifier.") }, [openModeSettingKey]: { 'type': 'string', 'enum': ['singleClick', 'doubleClick'], - 'enumDescriptions': [ - localize('openMode.singleClick', "Opens items on mouse single click."), - localize('openMode.doubleClick', "Open items on mouse double click.") - ], 'default': 'singleClick', 'description': localize({ key: 'openModeModifier', comment: ['`singleClick` and `doubleClick` refers to a value the setting can take and should not be localized.'] - }, "Controls how to open items in trees and lists using the mouse (if supported). Set to `singleClick` to open items with a single mouse click and `doubleClick` to only open via mouse double click. For parents with children in trees, this setting will control if a single click expands the parent or a double click. Note that some trees and lists might choose to ignore this setting if it is not applicable. ") + }, "Controls how to open items in trees and lists using the mouse (if supported). For parents with children in trees, this setting will control if a single click expands the parent or a double click. Note that some trees and lists might choose to ignore this setting if it is not applicable. ") }, [horizontalScrollingKey]: { 'type': 'boolean', diff --git a/src/vs/workbench/electron-browser/main.contribution.ts b/src/vs/workbench/electron-browser/main.contribution.ts index 7c71735efb9..689b07557a8 100644 --- a/src/vs/workbench/electron-browser/main.contribution.ts +++ b/src/vs/workbench/electron-browser/main.contribution.ts @@ -342,7 +342,7 @@ configurationRegistry.registerConfiguration({ 'properties': { 'workbench.editor.showTabs': { 'type': 'boolean', - 'description': nls.localize('showEditorTabs', "Controls if opened editors should show in tabs or not."), + 'description': nls.localize('showEditorTabs', "Controls whether opened editors should show in tabs or not."), 'default': true }, 'workbench.editor.labelFormat': { @@ -362,27 +362,31 @@ configurationRegistry.registerConfiguration({ 'type': 'string', 'enum': ['left', 'right', 'off'], 'default': 'right', - 'description': nls.localize({ comment: ['This is the description for a setting. Values surrounded by single quotes are not to be translated.'], key: 'editorTabCloseButton' }, "Controls the position of the editor's tabs close buttons or disables them when set to 'off'.") + 'description': nls.localize({ comment: ['This is the description for a setting. Values surrounded by single quotes are not to be translated.'], key: 'editorTabCloseButton' }, "Controls the position of the editor's tabs close buttons, or disables them when set to 'off'.") }, 'workbench.editor.tabSizing': { 'type': 'string', 'enum': ['fit', 'shrink'], 'default': 'fit', - 'description': nls.localize({ comment: ['This is the description for a setting. Values surrounded by single quotes are not to be translated.'], key: 'tabSizing' }, "Controls the sizing of editor tabs. Set to 'fit' to keep tabs always large enough to show the full editor label. Set to 'shrink' to allow tabs to get smaller when the available space is not enough to show all tabs at once.") + 'enumDescriptions': [ + nls.localize('workbench.editor.tabSizing.fit', "Always keep tabs large enough to show the full editor label."), + nls.localize('workbench.editor.tabSizing.shrink', "Allow tabs to get smaller when the available space is not enough to show all tabs at once.") + ], + 'description': nls.localize({ comment: ['This is the description for a setting. Values surrounded by single quotes are not to be translated.'], key: 'tabSizing' }, "Controls the sizing of editor tabs.") }, 'workbench.editor.showIcons': { 'type': 'boolean', - 'description': nls.localize('showIcons', "Controls if opened editors should show with an icon or not. This requires an icon theme to be enabled as well."), + 'description': nls.localize('showIcons', "Controls whether opened editors should show with an icon or not. This requires an icon theme to be enabled as well."), 'default': true }, 'workbench.editor.enablePreview': { 'type': 'boolean', - 'description': nls.localize('enablePreview', "Controls if opened editors show as preview. Preview editors are reused until they are kept (e.g. via double click or editing) and show up with an italic font style."), + 'description': nls.localize('enablePreview', "Controls whether opened editors show as preview. Preview editors are reused until they are kept (e.g. via double click or editing) and show up with an italic font style."), 'default': true }, 'workbench.editor.enablePreviewFromQuickOpen': { 'type': 'boolean', - 'description': nls.localize('enablePreviewFromQuickOpen', "Controls if opened editors from Quick Open show as preview. Preview editors are reused until they are kept (e.g. via double click or editing)."), + 'description': nls.localize('enablePreviewFromQuickOpen', "Controls whether opened editors from Quick Open show as preview. Preview editors are reused until they are kept (e.g. via double click or editing)."), 'default': true }, 'workbench.editor.closeOnFileDelete': { @@ -409,7 +413,7 @@ configurationRegistry.registerConfiguration({ }, 'workbench.editor.revealIfOpen': { 'type': 'boolean', - 'description': nls.localize('revealIfOpen', "Controls if an editor is revealed in any of the visible groups if opened. If disabled, an editor will prefer to open in the currently active editor group. If enabled, an already opened editor will be revealed instead of opened again in the currently active editor group. Note that there are some cases where this setting is ignored, e.g. when forcing an editor to open in a specific group or to the side of the currently active group."), + 'description': nls.localize('revealIfOpen', "Controls whether an editor is revealed in any of the visible groups if opened. If disabled, an editor will prefer to open in the currently active editor group. If enabled, an already opened editor will be revealed instead of opened again in the currently active editor group. Note that there are some cases where this setting is ignored, e.g. when forcing an editor to open in a specific group or to the side of the currently active group."), 'default': false }, 'workbench.editor.swipeToNavigate': { @@ -425,22 +429,22 @@ configurationRegistry.registerConfiguration({ }, 'workbench.commandPalette.preserveInput': { 'type': 'boolean', - 'description': nls.localize('preserveInput', "Controls if the last typed input to the command palette should be restored when opening it the next time."), + 'description': nls.localize('preserveInput', "Controls whether the last typed input to the command palette should be restored when opening it the next time."), 'default': false }, 'workbench.quickOpen.closeOnFocusLost': { 'type': 'boolean', - 'description': nls.localize('closeOnFocusLost', "Controls if Quick Open should close automatically once it loses focus."), + 'description': nls.localize('closeOnFocusLost', "Controls whether Quick Open should close automatically once it loses focus."), 'default': true }, 'workbench.settings.openDefaultSettings': { 'type': 'boolean', - 'description': nls.localize('openDefaultSettings', "Controls if opening settings also opens an editor showing all default settings."), + 'description': nls.localize('openDefaultSettings', "Controls whether opening settings also opens an editor showing all default settings."), 'default': true }, 'workbench.settings.openDefaultKeybindings': { 'type': 'boolean', - 'description': nls.localize('openDefaultKeybindings', "Controls if opening keybinding settings also opens an editor showing all default keybindings."), + 'description': nls.localize('openDefaultKeybindings', "Controls whether opening keybinding settings also opens an editor showing all default keybindings."), 'default': true }, 'workbench.sideBar.location': { @@ -475,7 +479,7 @@ configurationRegistry.registerConfiguration({ 'enum': ['default', 'antialiased', 'none', 'auto'], 'default': 'default', 'description': - nls.localize('fontAliasing', "Controls font aliasing method in the workbench.\n- default: Sub-pixel font smoothing. On most non-retina displays this will give the sharpest text\n- antialiased: Smooth the font on the level of the pixel, as opposed to the subpixel. Can make the font appear lighter overall\n- none: Disables font smoothing. Text will show with jagged sharp edges\n- auto: Applies `default` or `antialiased` automatically based on the DPI of displays."), + nls.localize('fontAliasing', "Controls font aliasing method in the workbench."), 'enumDescriptions': [ nls.localize('workbench.fontAliasing.default', "Sub-pixel font smoothing. On most non-retina displays this will give the sharpest text."), nls.localize('workbench.fontAliasing.antialiased', "Smooth the font on the level of the pixel, as opposed to the subpixel. Can make the font appear lighter overall."), @@ -601,7 +605,7 @@ configurationRegistry.registerConfiguration({ 'window.closeWhenEmpty': { 'type': 'boolean', 'default': false, - 'description': nls.localize('closeWhenEmpty', "Controls if closing the last editor should also close the window. This setting only applies for windows that do not show folders.") + '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', @@ -671,12 +675,12 @@ configurationRegistry.registerConfiguration({ 'zenMode.fullScreen': { 'type': 'boolean', 'default': true, - 'description': nls.localize('zenMode.fullScreen', "Controls if turning on Zen Mode also puts the workbench into full screen mode.") + 'description': nls.localize('zenMode.fullScreen', "Controls whether turning on Zen Mode also puts the workbench into full screen mode.") }, 'zenMode.centerLayout': { 'type': 'boolean', 'default': true, - 'description': nls.localize('zenMode.centerLayout', "Controls if turning on Zen Mode also centers the layout.") + 'description': nls.localize('zenMode.centerLayout', "Controls whether turning on Zen Mode also centers the layout.") }, 'zenMode.hideTabs': { 'type': 'boolean', @@ -691,7 +695,7 @@ configurationRegistry.registerConfiguration({ 'zenMode.hideActivityBar': { 'type': 'boolean', 'default': true, - 'description': nls.localize('zenMode.hideActivityBar', "Controls if turning on Zen Mode also hides the activity bar at the left of the workbench.") + 'description': nls.localize('zenMode.hideActivityBar', "Controls whether turning on Zen Mode also hides the activity bar at the left of the workbench.") }, 'zenMode.restore': { 'type': 'boolean', diff --git a/src/vs/workbench/parts/welcome/page/electron-browser/welcomePage.contribution.ts b/src/vs/workbench/parts/welcome/page/electron-browser/welcomePage.contribution.ts index 2e5f8844e43..38cf82f6c69 100644 --- a/src/vs/workbench/parts/welcome/page/electron-browser/welcomePage.contribution.ts +++ b/src/vs/workbench/parts/welcome/page/electron-browser/welcomePage.contribution.ts @@ -26,10 +26,10 @@ Registry.as(ConfigurationExtensions.Configuration) 'enumDescriptions': [ localize({ comment: ['This is the description for a setting. Values surrounded by single quotes are not to be translated.'], key: 'workbench.startupEditor.none' }, "Start without an editor."), localize({ comment: ['This is the description for a setting. Values surrounded by single quotes are not to be translated.'], key: 'workbench.startupEditor.welcomePage' }, "Open the Welcome page (default)."), - localize({ comment: ['This is the description for a setting. Values surrounded by single quotes are not to be translated.'], key: 'workbench.startupEditor.newUntitledFile' }, "Open a new untitled file."), + localize({ comment: ['This is the description for a setting. Values surrounded by single quotes are not to be translated.'], key: 'workbench.startupEditor.newUntitledFile' }, "Open a new untitled file (only applies when opening an empty workspace)."), ], 'default': 'welcomePage', - 'description': localize('workbench.startupEditor', "Controls which editor is shown at startup, if none is restored from the previous session. Select 'none' to start without an editor, 'welcomePage' to open the Welcome page (default), 'newUntitledFile' to open a new untitled file (only opening an empty workspace).") + 'description': localize('workbench.startupEditor', "Controls which editor is shown at startup, if none are restored from the previous session.") }, } }); From 453de34b0fd71e60830ed55e6cf55c3432e67fda Mon Sep 17 00:00:00 2001 From: Rob Lourens Date: Wed, 1 Aug 2018 12:58:15 -0700 Subject: [PATCH 0395/1276] Another change for #55598 - maxResults applies to FileSearch and TextSearch but not FileIndex --- src/vs/vscode.proposed.d.ts | 22 ++++++++++++++++------ 1 file changed, 16 insertions(+), 6 deletions(-) diff --git a/src/vs/vscode.proposed.d.ts b/src/vs/vscode.proposed.d.ts index 8ff2ee9dd69..05ae2459c2b 100644 --- a/src/vs/vscode.proposed.d.ts +++ b/src/vs/vscode.proposed.d.ts @@ -77,17 +77,17 @@ declare module 'vscode' { * See the vscode setting `"search.followSymlinks"`. */ followSymlinks: boolean; - - /** - * The maximum number of results to be returned. - */ - maxResults: number; } /** * Options that apply to text search. */ export interface TextSearchOptions extends SearchOptions { + /** + * The maximum number of results to be returned. + */ + maxResults: number; + /** * TODO@roblou - total length? # of context lines? leading and trailing # of chars? */ @@ -118,7 +118,17 @@ declare module 'vscode' { /** * Options that apply to file search. */ - export interface FileSearchOptions extends SearchOptions { } + export interface FileSearchOptions extends SearchOptions { + /** + * The maximum number of results to be returned. + */ + maxResults: number; + } + + /** + * Options that apply to requesting the file index. + */ + export interface FileIndexOptions extends SearchOptions { } export interface TextSearchResultPreview { /** From 49bbb88160e8b0943f1d17d47ba26f23a0f72463 Mon Sep 17 00:00:00 2001 From: Rob Lourens Date: Wed, 1 Aug 2018 13:39:13 -0700 Subject: [PATCH 0396/1276] Fix FileSearchProvider unit tests for progress change --- src/vs/vscode.proposed.d.ts | 2 +- .../api/node/extHostSearch.fileIndex.ts | 2 +- src/vs/workbench/api/node/extHostSearch.ts | 22 +++-- .../api/extHostSearch.test.ts | 92 ++++++------------- 4 files changed, 42 insertions(+), 76 deletions(-) diff --git a/src/vs/vscode.proposed.d.ts b/src/vs/vscode.proposed.d.ts index 05ae2459c2b..b3ed4943e3e 100644 --- a/src/vs/vscode.proposed.d.ts +++ b/src/vs/vscode.proposed.d.ts @@ -180,7 +180,7 @@ declare module 'vscode' { * @param options A set of options to consider while searching. * @param token A cancellation token. */ - provideFileIndex(options: FileSearchOptions, token: CancellationToken): Thenable; + provideFileIndex(options: FileIndexOptions, token: CancellationToken): Thenable; } /** diff --git a/src/vs/workbench/api/node/extHostSearch.fileIndex.ts b/src/vs/workbench/api/node/extHostSearch.fileIndex.ts index 89422c20368..4e2079d1df5 100644 --- a/src/vs/workbench/api/node/extHostSearch.fileIndex.ts +++ b/src/vs/workbench/api/node/extHostSearch.fileIndex.ts @@ -276,7 +276,7 @@ export class FileIndexSearchEngine { }); } - private getSearchOptionsForFolder(fq: IFolderQuery): vscode.FileSearchOptions { + private getSearchOptionsForFolder(fq: IFolderQuery): vscode.FileIndexOptions { const includes = resolvePatternsForProvider(this.config.includePattern, fq.includePattern); const excludes = resolvePatternsForProvider(this.config.excludePattern, fq.excludePattern); diff --git a/src/vs/workbench/api/node/extHostSearch.ts b/src/vs/workbench/api/node/extHostSearch.ts index 234132adf2b..33647f92927 100644 --- a/src/vs/workbench/api/node/extHostSearch.ts +++ b/src/vs/workbench/api/node/extHostSearch.ts @@ -504,19 +504,21 @@ class FileSearchEngine { return; } - results.forEach(result => { - const relativePath = path.relative(fq.folder.fsPath, result.fsPath); + if (results) { + results.forEach(result => { + const relativePath = path.relative(fq.folder.fsPath, result.fsPath); - if (noSiblingsClauses) { - const basename = path.basename(result.fsPath); - this.matchFile(onResult, { base: fq.folder, relativePath, basename }); + if (noSiblingsClauses) { + const basename = path.basename(result.fsPath); + this.matchFile(onResult, { base: fq.folder, relativePath, basename }); - return; - } + return; + } - // TODO: Optimize siblings clauses with ripgrep here. - this.addDirectoryEntries(tree, fq.folder, relativePath, onResult); - }); + // TODO: Optimize siblings clauses with ripgrep here. + this.addDirectoryEntries(tree, fq.folder, relativePath, onResult); + }); + } this.activeCancellationTokens.delete(cancellation); if (this.isCanceled) { diff --git a/src/vs/workbench/test/electron-browser/api/extHostSearch.test.ts b/src/vs/workbench/test/electron-browser/api/extHostSearch.test.ts index bd3d303ad19..d1a70c00f48 100644 --- a/src/vs/workbench/test/electron-browser/api/extHostSearch.test.ts +++ b/src/vs/workbench/test/electron-browser/api/extHostSearch.test.ts @@ -167,7 +167,7 @@ suite('ExtHostSearch', () => { test('no results', async () => { await registerTestFileSearchProvider({ - provideFileSearchResults(query: vscode.FileSearchQuery, options: vscode.FileSearchOptions, progress: vscode.Progress, token: vscode.CancellationToken): Thenable { + provideFileSearchResults(query: vscode.FileSearchQuery, options: vscode.FileSearchOptions, token: vscode.CancellationToken): Thenable { return TPromise.wrap(null); } }); @@ -185,9 +185,8 @@ suite('ExtHostSearch', () => { ]; await registerTestFileSearchProvider({ - provideFileSearchResults(query: vscode.FileSearchQuery, options: vscode.FileSearchOptions, progress: vscode.Progress, token: vscode.CancellationToken): Thenable { - reportedResults.forEach(r => progress.report(r)); - return TPromise.wrap(null); + provideFileSearchResults(query: vscode.FileSearchQuery, options: vscode.FileSearchOptions, token: vscode.CancellationToken): Thenable { + return TPromise.wrap(reportedResults); } }); @@ -200,13 +199,12 @@ suite('ExtHostSearch', () => { test('Search canceled', async () => { let cancelRequested = false; await registerTestFileSearchProvider({ - provideFileSearchResults(query: vscode.FileSearchQuery, options: vscode.FileSearchOptions, progress: vscode.Progress, token: vscode.CancellationToken): Thenable { + provideFileSearchResults(query: vscode.FileSearchQuery, options: vscode.FileSearchOptions, token: vscode.CancellationToken): Thenable { return new TPromise((resolve, reject) => { token.onCancellationRequested(() => { cancelRequested = true; - progress.report(joinPath(options.folder, 'file1.ts')); - resolve(null); // or reject or nothing? + resolve([joinPath(options.folder, 'file1.ts')]); // or reject or nothing? }); }); } @@ -217,34 +215,9 @@ suite('ExtHostSearch', () => { assert(!results.length); }); - test('provider fail', async () => { - const reportedResults = [ - 'file1.ts', - 'file2.ts', - 'file3.ts', - ]; - - await registerTestFileSearchProvider({ - provideFileSearchResults(query: vscode.FileSearchQuery, options: vscode.FileSearchOptions, progress: vscode.Progress, token: vscode.CancellationToken): Thenable { - reportedResults - .map(relativePath => joinPath(options.folder, relativePath)) - .forEach(r => progress.report(r)); - - throw new Error('I broke'); - } - }); - - try { - await runFileSearch(getSimpleQuery()); - assert(false, 'Expected to fail'); - } catch { - // Expected to throw - } - }); - test('provider returns null', async () => { await registerTestFileSearchProvider({ - provideFileSearchResults(query: vscode.FileSearchQuery, options: vscode.FileSearchOptions, progress: vscode.Progress, token: vscode.CancellationToken): Thenable { + provideFileSearchResults(query: vscode.FileSearchQuery, options: vscode.FileSearchOptions, token: vscode.CancellationToken): Thenable { return null; } }); @@ -259,7 +232,7 @@ suite('ExtHostSearch', () => { test('all provider calls get global include/excludes', async () => { await registerTestFileSearchProvider({ - provideFileSearchResults(query: vscode.FileSearchQuery, options: vscode.FileSearchOptions, progress: vscode.Progress, token: vscode.CancellationToken): Thenable { + provideFileSearchResults(query: vscode.FileSearchQuery, options: vscode.FileSearchOptions, token: vscode.CancellationToken): Thenable { assert(options.excludes.length === 2 && options.includes.length === 2, 'Missing global include/excludes'); return TPromise.wrap(null); } @@ -288,7 +261,7 @@ suite('ExtHostSearch', () => { test('global/local include/excludes combined', async () => { await registerTestFileSearchProvider({ - provideFileSearchResults(query: vscode.FileSearchQuery, options: vscode.FileSearchOptions, progress: vscode.Progress, token: vscode.CancellationToken): Thenable { + provideFileSearchResults(query: vscode.FileSearchQuery, options: vscode.FileSearchOptions, token: vscode.CancellationToken): Thenable { if (options.folder.toString() === rootFolderA.toString()) { assert.deepEqual(options.includes.sort(), ['*.ts', 'foo']); assert.deepEqual(options.excludes.sort(), ['*.js', 'bar']); @@ -330,7 +303,7 @@ suite('ExtHostSearch', () => { test('include/excludes resolved correctly', async () => { await registerTestFileSearchProvider({ - provideFileSearchResults(query: vscode.FileSearchQuery, options: vscode.FileSearchOptions, progress: vscode.Progress, token: vscode.CancellationToken): Thenable { + provideFileSearchResults(query: vscode.FileSearchQuery, options: vscode.FileSearchOptions, token: vscode.CancellationToken): Thenable { assert.deepEqual(options.includes.sort(), ['*.jsx', '*.ts']); assert.deepEqual(options.excludes.sort(), []); @@ -373,11 +346,9 @@ suite('ExtHostSearch', () => { ]; await registerTestFileSearchProvider({ - provideFileSearchResults(query: vscode.FileSearchQuery, options: vscode.FileSearchOptions, progress: vscode.Progress, token: vscode.CancellationToken): Thenable { - reportedResults - .map(relativePath => joinPath(options.folder, relativePath)) - .forEach(r => progress.report(r)); - return TPromise.wrap(null); + provideFileSearchResults(query: vscode.FileSearchQuery, options: vscode.FileSearchOptions, token: vscode.CancellationToken): Thenable { + return TPromise.wrap(reportedResults + .map(relativePath => joinPath(options.folder, relativePath))); } }); @@ -406,7 +377,7 @@ suite('ExtHostSearch', () => { test('multiroot sibling exclude clause', async () => { await registerTestFileSearchProvider({ - provideFileSearchResults(query: vscode.FileSearchQuery, options: vscode.FileSearchOptions, progress: vscode.Progress, token: vscode.CancellationToken): Thenable { + provideFileSearchResults(query: vscode.FileSearchQuery, options: vscode.FileSearchOptions, token: vscode.CancellationToken): Thenable { let reportedResults: URI[]; if (options.folder.fsPath === rootFolderA.fsPath) { reportedResults = [ @@ -422,8 +393,7 @@ suite('ExtHostSearch', () => { ].map(relativePath => joinPath(rootFolderB, relativePath)); } - reportedResults.forEach(r => progress.report(r)); - return TPromise.wrap(null); + return TPromise.wrap(reportedResults); } }); @@ -468,7 +438,7 @@ suite('ExtHostSearch', () => { ]); }); - test('max results = 1', async () => { + test.skip('max results = 1', async () => { const reportedResults = [ joinPath(rootFolderA, 'file1.ts'), joinPath(rootFolderA, 'file2.ts'), @@ -477,12 +447,10 @@ suite('ExtHostSearch', () => { let wasCanceled = false; await registerTestFileSearchProvider({ - provideFileSearchResults(query: vscode.FileSearchQuery, options: vscode.FileSearchOptions, progress: vscode.Progress, token: vscode.CancellationToken): Thenable { - reportedResults - .forEach(r => progress.report(r)); + provideFileSearchResults(query: vscode.FileSearchQuery, options: vscode.FileSearchOptions, token: vscode.CancellationToken): Thenable { token.onCancellationRequested(() => wasCanceled = true); - return TPromise.wrap(null); + return TPromise.wrap(reportedResults); } }); @@ -506,7 +474,7 @@ suite('ExtHostSearch', () => { assert(wasCanceled, 'Expected to be canceled when hitting limit'); }); - test('max results = 2', async () => { + test.skip('max results = 2', async () => { const reportedResults = [ joinPath(rootFolderA, 'file1.ts'), joinPath(rootFolderA, 'file2.ts'), @@ -515,11 +483,10 @@ suite('ExtHostSearch', () => { let wasCanceled = false; await registerTestFileSearchProvider({ - provideFileSearchResults(query: vscode.FileSearchQuery, options: vscode.FileSearchOptions, progress: vscode.Progress, token: vscode.CancellationToken): Thenable { - reportedResults.forEach(r => progress.report(r)); + provideFileSearchResults(query: vscode.FileSearchQuery, options: vscode.FileSearchOptions, token: vscode.CancellationToken): Thenable { token.onCancellationRequested(() => wasCanceled = true); - return TPromise.wrap(null); + return TPromise.wrap(reportedResults); } }); @@ -543,7 +510,7 @@ suite('ExtHostSearch', () => { assert(wasCanceled, 'Expected to be canceled when hitting limit'); }); - test('provider returns maxResults exactly', async () => { + test.skip('provider returns maxResults exactly', async () => { const reportedResults = [ joinPath(rootFolderA, 'file1.ts'), joinPath(rootFolderA, 'file2.ts'), @@ -551,11 +518,10 @@ suite('ExtHostSearch', () => { let wasCanceled = false; await registerTestFileSearchProvider({ - provideFileSearchResults(query: vscode.FileSearchQuery, options: vscode.FileSearchOptions, progress: vscode.Progress, token: vscode.CancellationToken): Thenable { - reportedResults.forEach(r => progress.report(r)); + provideFileSearchResults(query: vscode.FileSearchQuery, options: vscode.FileSearchOptions, token: vscode.CancellationToken): Thenable { token.onCancellationRequested(() => wasCanceled = true); - return TPromise.wrap(null); + return TPromise.wrap(reportedResults); } }); @@ -582,18 +548,17 @@ suite('ExtHostSearch', () => { test('multiroot max results', async () => { let cancels = 0; await registerTestFileSearchProvider({ - provideFileSearchResults(query: vscode.FileSearchQuery, options: vscode.FileSearchOptions, progress: vscode.Progress, token: vscode.CancellationToken): Thenable { + provideFileSearchResults(query: vscode.FileSearchQuery, options: vscode.FileSearchOptions, token: vscode.CancellationToken): Thenable { token.onCancellationRequested(() => cancels++); // Provice results async so it has a chance to invoke every provider return new TPromise(r => process.nextTick(r)) .then(() => { - [ + return [ 'file1.ts', 'file2.ts', 'file3.ts', - ].map(relativePath => joinPath(options.folder, relativePath)) - .forEach(r => progress.report(r)); + ].map(relativePath => joinPath(options.folder, relativePath)); }); } }); @@ -628,9 +593,8 @@ suite('ExtHostSearch', () => { ]; await registerTestFileSearchProvider({ - provideFileSearchResults(query: vscode.FileSearchQuery, options: vscode.FileSearchOptions, progress: vscode.Progress, token: vscode.CancellationToken): Thenable { - reportedResults.forEach(r => progress.report(r)); - return TPromise.wrap(null); + provideFileSearchResults(query: vscode.FileSearchQuery, options: vscode.FileSearchOptions, token: vscode.CancellationToken): Thenable { + return TPromise.wrap(reportedResults); } }, fancyScheme); From 9fc7de948614b9f41e31086b0e2dbb3d6dc8189c Mon Sep 17 00:00:00 2001 From: SteVen Batten Date: Wed, 1 Aug 2018 14:00:45 -0700 Subject: [PATCH 0397/1276] fixes #55561 --- src/vs/workbench/browser/parts/menubar/media/menubarpart.css | 1 + 1 file changed, 1 insertion(+) diff --git a/src/vs/workbench/browser/parts/menubar/media/menubarpart.css b/src/vs/workbench/browser/parts/menubar/media/menubarpart.css index 39912f3dd35..e40e091aae3 100644 --- a/src/vs/workbench/browser/parts/menubar/media/menubarpart.css +++ b/src/vs/workbench/browser/parts/menubar/media/menubarpart.css @@ -24,6 +24,7 @@ cursor: default; -webkit-app-region: no-drag; zoom: 1; + white-space: nowrap; } .monaco-workbench .part.menubar .menubar-menu-items-holder { From c9764c85d7cfc6f8046a67489f063601e38ca5b3 Mon Sep 17 00:00:00 2001 From: Pine Wu Date: Wed, 1 Aug 2018 14:46:33 -0700 Subject: [PATCH 0398/1276] Settings description update for #54690 --- extensions/css-language-features/package.nls.json | 8 ++++---- extensions/git/package.nls.json | 14 +++++++------- extensions/npm/package.nls.json | 2 +- src/vs/editor/common/config/commonEditorConfig.ts | 2 +- .../electron-browser/main.contribution.ts | 10 ++++++---- .../debug/electron-browser/debug.contribution.ts | 2 +- 6 files changed, 20 insertions(+), 18 deletions(-) diff --git a/extensions/css-language-features/package.nls.json b/extensions/css-language-features/package.nls.json index 9cb867c43aa..9bf6d29766e 100644 --- a/extensions/css-language-features/package.nls.json +++ b/extensions/css-language-features/package.nls.json @@ -19,7 +19,7 @@ "css.lint.unknownAtRules.desc": "Unknown at-rule.", "css.lint.unknownProperties.desc": "Unknown property.", "css.lint.unknownVendorSpecificProperties.desc": "Unknown vendor specific property.", - "css.lint.vendorPrefix.desc": "When using a vendor-specific prefix also include the standard property.", + "css.lint.vendorPrefix.desc": "When using a vendor-specific prefix and also including the standard property.", "css.lint.zeroUnits.desc": "No unit for zero needed.", "css.trace.server.desc": "Traces the communication between VS Code and the CSS language server.", "css.validate.title": "Controls CSS validation and problem severities.", @@ -30,7 +30,7 @@ "less.lint.compatibleVendorPrefixes.desc": "When using a vendor-specific prefix make sure to also include all other vendor-specific properties.", "less.lint.duplicateProperties.desc": "Do not use duplicate style definitions.", "less.lint.emptyRules.desc": "Do not use empty rulesets.", - "less.lint.float.desc": "Avoid using `float`. Floats lead to fragile CSS that is easy to break if one aspect of the layout changes.", + "less.lint.float.desc": "Avoids using `float`. Floats lead to fragile CSS that is easy to break if one aspect of the layout changes.", "less.lint.fontFaceProperties.desc": "`@font-face` rule must define `src` and `font-family` properties.", "less.lint.hexColorLength.desc": "Hex colors must consist of three or six hex numbers.", "less.lint.idSelector.desc": "Selectors should not contain IDs because these rules are too tightly coupled with the HTML.", @@ -41,7 +41,7 @@ "less.lint.universalSelector.desc": "The universal selector (`*`) is known to be slow.", "less.lint.unknownProperties.desc": "Unknown property.", "less.lint.unknownVendorSpecificProperties.desc": "Unknown vendor specific property.", - "less.lint.vendorPrefix.desc": "When using a vendor-specific prefix also include the standard property.", + "less.lint.vendorPrefix.desc": "When using a vendor-specific prefix and also including the standard property.", "less.lint.zeroUnits.desc": "No unit for zero needed.", "less.validate.title": "Controls LESS validation and problem severities.", "less.validate.desc": "Enables or disables all validations.", @@ -62,7 +62,7 @@ "scss.lint.universalSelector.desc": "The universal selector (`*`) is known to be slow.", "scss.lint.unknownProperties.desc": "Unknown property.", "scss.lint.unknownVendorSpecificProperties.desc": "Unknown vendor specific property.", - "scss.lint.vendorPrefix.desc": "When using a vendor-specific prefix also include the standard property.", + "scss.lint.vendorPrefix.desc": "When using a vendor-specific prefix and also including the standard property.", "scss.lint.zeroUnits.desc": "No unit for zero needed.", "scss.validate.title": "Controls SCSS validation and problem severities.", "scss.validate.desc": "Enables or disables all validations.", diff --git a/extensions/git/package.nls.json b/extensions/git/package.nls.json index 38050ced547..dc335771b90 100644 --- a/extensions/git/package.nls.json +++ b/extensions/git/package.nls.json @@ -53,9 +53,9 @@ "config.enabled": "Whether git is enabled.", "config.path": "Path to the git executable.", "config.autoRepositoryDetection": "Configures when repositories should be automatically detected.", - "config.autorefresh": "Whether auto refreshing is enabled", - "config.autofetch": "Whether auto fetching is enabled", - "config.enableLongCommitWarning": "Whether long commit messages should be warned about", + "config.autorefresh": "Whether auto refreshing is enabled.", + "config.autofetch": "Whether auto fetching is enabled.", + "config.enableLongCommitWarning": "Whether long commit messages should be warned about.", "config.confirmSync": "Confirm before synchronizing git repositories.", "config.countBadge": "Controls the git badge counter.", "config.countBadge.all": "Count all changes.", @@ -67,8 +67,8 @@ "config.checkoutType.tags": "Show only tags.", "config.checkoutType.remote": "Show only remote branches.", "config.ignoreLegacyWarning": "Ignores the legacy Git warning.", - "config.ignoreMissingGitWarning": "Ignores the warning when Git is missing", - "config.ignoreLimitWarning": "Ignores the warning when there are too many changes in a repository", + "config.ignoreMissingGitWarning": "Ignores the warning when Git is missing.", + "config.ignoreLimitWarning": "Ignores the warning when there are too many changes in a repository.", "config.defaultCloneDirectory": "The default location to clone a git repository.", "config.enableSmartCommit": "Commit all changes when there are no staged changes.", "config.enableCommitSigning": "Enables commit signing with GPG.", @@ -81,8 +81,8 @@ "config.detectSubmodules": "Controls whether to automatically detect git submodules.", "colors.added": "Color for added resources.", "config.detectSubmodulesLimit": "Controls the limit of git submodules detected.", - "config.alwaysSignOff": "Controls the signoff flag for all commits", - "config.ignoredRepositories": "List of git repositories to ignore", + "config.alwaysSignOff": "Controls the signoff flag for all commits.", + "config.ignoredRepositories": "List of git repositories to ignore.", "colors.modified": "Color for modified resources.", "colors.deleted": "Color for deleted resources.", "colors.untracked": "Color for untracked resources.", diff --git a/extensions/npm/package.nls.json b/extensions/npm/package.nls.json index 7bdfed8e973..4a33bcc0bc3 100644 --- a/extensions/npm/package.nls.json +++ b/extensions/npm/package.nls.json @@ -6,7 +6,7 @@ "config.npm.packageManager": "The package manager used to run scripts.", "config.npm.exclude": "Configure glob patterns for folders that should be excluded from automatic script detection.", "config.npm.enableScriptExplorer": "Enable an explorer view for npm scripts.", - "config.npm.scriptExplorerAction": "The default click action used in the scripts explorer: 'open' or 'run', the default is 'open'.", + "config.npm.scriptExplorerAction": "The default click action used in the scripts explorer: `open` or `run`, the default is `open`.", "config.npm.fetchOnlinePackageInfo": "Fetch data from https://registry.npmjs/org and https://registry.bower.io to provide auto-completion and information on hover features on npm dependencies.", "npm.parseError": "Npm task detection: failed to parse the file {0}", "taskdef.script": "The npm script to customize.", diff --git a/src/vs/editor/common/config/commonEditorConfig.ts b/src/vs/editor/common/config/commonEditorConfig.ts index 33a9a433690..f0668375eef 100644 --- a/src/vs/editor/common/config/commonEditorConfig.ts +++ b/src/vs/editor/common/config/commonEditorConfig.ts @@ -592,7 +592,7 @@ const editorConfiguration: IConfigurationNode = { 'editor.selectionHighlight': { 'type': 'boolean', 'default': EDITOR_DEFAULTS.contribInfo.selectionHighlight, - 'description': nls.localize('selectionHighlight', "Controls whether the editor should highlight similar matches to the selection") + 'description': nls.localize('selectionHighlight', "Controls whether the editor should highlight matches similar to the selection") }, 'editor.occurrencesHighlight': { 'type': 'boolean', diff --git a/src/vs/workbench/electron-browser/main.contribution.ts b/src/vs/workbench/electron-browser/main.contribution.ts index 689b07557a8..766c0110f3b 100644 --- a/src/vs/workbench/electron-browser/main.contribution.ts +++ b/src/vs/workbench/electron-browser/main.contribution.ts @@ -355,8 +355,10 @@ configurationRegistry.registerConfiguration({ nls.localize('workbench.editor.labelFormat.long', "Show the name of the file followed by it's absolute path.") ], 'default': 'default', - 'description': nls.localize({ comment: ['This is the description for a setting. Values surrounded by parenthesis are not to be translated.'], key: 'tabDescription' }, - "Controls the format of the label for an editor. Changing this setting can for example make it easier to understand the location of a file:\n- short: 'parent'\n- medium: 'workspace/src/parent'\n- long: '/home/user/workspace/src/parent'\n- default: '.../parent', when another tab shares the same title, or the relative workspace path if tabs are disabled"), + 'description': nls.localize({ + comment: ['This is the description for a setting. Values surrounded by parenthesis are not to be translated.'], + key: 'tabDescription' + }, "Controls the format of editor's label."), }, 'workbench.editor.tabCloseButton': { 'type': 'string', @@ -398,13 +400,13 @@ configurationRegistry.registerConfiguration({ 'type': 'string', 'enum': ['left', 'right', 'first', 'last'], 'default': 'right', - 'description': nls.localize({ comment: ['This is the description for a setting. Values surrounded by single quotes are not to be translated.'], key: 'editorOpenPositioning' }, "Controls where editors open. Select 'left' or 'right' to open editors to the left or right of the currently active one. Select 'first' or 'last' to open editors independently from the currently active one.") + 'description': nls.localize({ comment: ['This is the description for a setting. Values surrounded by single quotes are not to be translated.'], key: 'editorOpenPositioning' }, "Controls where editors open. Select `left` or `right` to open editors to the left or right of the currently active one. Select `first` or `last` to open editors independently from the currently active one.") }, 'workbench.editor.openSideBySideDirection': { 'type': 'string', 'enum': ['right', 'down'], 'default': 'right', - 'description': nls.localize('sideBySideDirection', "Controls the default direction of editors that are opened side by side (e.g. from the explorer). By default, editors will open on the right hand side of the currently active one. If changed to open down, the editors will open below the currently active one.") + 'description': nls.localize('sideBySideDirection', "Controls the default direction of editors that are opened side by side (e.g. from the explorer). By default, editors will open on the right hand side of the currently active one. If changed to `down`, the editors will open below the currently active one.") }, 'workbench.editor.closeEmptyGroups': { 'type': 'boolean', diff --git a/src/vs/workbench/parts/debug/electron-browser/debug.contribution.ts b/src/vs/workbench/parts/debug/electron-browser/debug.contribution.ts index 6ac7e091834..35bad718d0b 100644 --- a/src/vs/workbench/parts/debug/electron-browser/debug.contribution.ts +++ b/src/vs/workbench/parts/debug/electron-browser/debug.contribution.ts @@ -193,7 +193,7 @@ configurationRegistry.registerConfiguration({ }, 'debug.toolBarLocation': { enum: ['floating', 'docked', 'hidden'], - description: nls.localize({ comment: ['This is the description for a setting'], key: 'toolBarLocation' }, "Controls the location of the debug toolbar. Either \"floating\" in all views, \"docked\" in the debug view, or \"hidden\""), + description: nls.localize({ comment: ['This is the description for a setting'], key: 'toolBarLocation' }, "Controls the location of the debug toolbar. Either `floating` in all views, `docked` in the debug view, or `hidden`"), default: 'floating' }, 'debug.showInStatusBar': { From 3b82258154ab7a6c60065a3e8a8ac36a3ccbe091 Mon Sep 17 00:00:00 2001 From: Ramya Achutha Rao Date: Wed, 1 Aug 2018 14:58:21 -0700 Subject: [PATCH 0399/1276] Update setting descriptions for online services --- src/vs/platform/telemetry/common/telemetryService.ts | 2 +- src/vs/platform/update/node/update.config.contribution.ts | 6 +++--- src/vs/workbench/electron-browser/main.contribution.ts | 2 +- .../extensions/electron-browser/extensions.contribution.ts | 6 +++--- .../crashReporter/electron-browser/crashReporterService.ts | 2 +- 5 files changed, 9 insertions(+), 9 deletions(-) diff --git a/src/vs/platform/telemetry/common/telemetryService.ts b/src/vs/platform/telemetry/common/telemetryService.ts index f30292529f7..72b7d856930 100644 --- a/src/vs/platform/telemetry/common/telemetryService.ts +++ b/src/vs/platform/telemetry/common/telemetryService.ts @@ -166,7 +166,7 @@ Registry.as(Extensions.Configuration).registerConfigurat 'properties': { 'telemetry.enableTelemetry': { 'type': 'boolean', - 'description': localize('telemetry.enableTelemetry', "Enable usage data and errors to be sent to Microsoft."), + 'description': localize('telemetry.enableTelemetry', "Enable usage data and errors to be sent to a Microsoft online service."), 'default': true, 'tags': ['usesOnlineServices'] } diff --git a/src/vs/platform/update/node/update.config.contribution.ts b/src/vs/platform/update/node/update.config.contribution.ts index 7c4cc968e67..7ad60bdfc4f 100644 --- a/src/vs/platform/update/node/update.config.contribution.ts +++ b/src/vs/platform/update/node/update.config.contribution.ts @@ -21,20 +21,20 @@ configurationRegistry.registerConfiguration({ 'enum': ['none', 'default'], 'default': 'default', 'scope': ConfigurationScope.APPLICATION, - 'description': nls.localize('updateChannel', "Configure whether you receive automatic updates from an update channel. Requires a restart after change."), + 'description': nls.localize('updateChannel', "Configure whether you receive automatic updates from an update channel. Requires a restart after change. The updates are fetched from an online service."), 'tags': ['usesOnlineServices'] }, 'update.enableWindowsBackgroundUpdates': { 'type': 'boolean', 'default': true, 'scope': ConfigurationScope.APPLICATION, - 'description': nls.localize('enableWindowsBackgroundUpdates', "Enables Windows background updates."), + 'description': nls.localize('enableWindowsBackgroundUpdates', "Enables Windows background updates. The updates are fetched from an online service."), 'tags': ['usesOnlineServices'] }, 'update.showReleaseNotes': { 'type': 'boolean', 'default': true, - 'description': nls.localize('showReleaseNotes', "Show Release Notes after an update."), + 'description': nls.localize('showReleaseNotes', "Show Release Notes after an update. The Release Notes are fetched from an online service."), 'tags': ['usesOnlineServices'] } } diff --git a/src/vs/workbench/electron-browser/main.contribution.ts b/src/vs/workbench/electron-browser/main.contribution.ts index 689b07557a8..dfb0d06a5ab 100644 --- a/src/vs/workbench/electron-browser/main.contribution.ts +++ b/src/vs/workbench/electron-browser/main.contribution.ts @@ -490,7 +490,7 @@ configurationRegistry.registerConfiguration({ }, 'workbench.settings.enableNaturalLanguageSearch': { 'type': 'boolean', - 'description': nls.localize('enableNaturalLanguageSettingsSearch', "Controls whether to enable the natural language search mode for settings."), + 'description': nls.localize('enableNaturalLanguageSettingsSearch', "Controls whether to enable the natural language search mode for settings. The natural language search is provided by an online service."), 'default': true, 'scope': ConfigurationScope.WINDOW, 'tags': ['usesOnlineServices'] diff --git a/src/vs/workbench/parts/extensions/electron-browser/extensions.contribution.ts b/src/vs/workbench/parts/extensions/electron-browser/extensions.contribution.ts index 25ced8dabe0..d14b8666b9d 100644 --- a/src/vs/workbench/parts/extensions/electron-browser/extensions.contribution.ts +++ b/src/vs/workbench/parts/extensions/electron-browser/extensions.contribution.ts @@ -204,14 +204,14 @@ Registry.as(ConfigurationExtensions.Configuration) properties: { 'extensions.autoUpdate': { type: 'boolean', - description: localize('extensionsAutoUpdate', "Automatically update extensions."), + description: localize('extensionsAutoUpdate', "When enabled, automatically installs updates for extensions. The updates are fetched from an online service."), default: true, scope: ConfigurationScope.APPLICATION, tags: ['usesOnlineServices'] }, 'extensions.autoCheckUpdates': { type: 'boolean', - description: localize('extensionsCheckUpdates', "Automatically checks for extension updates. If an extension update is available and the extension auto update feature is disabled, then the extension will appear as outdated in the Extensions view."), + description: localize('extensionsCheckUpdates', "When enabled, automatically checks extensions for updates. If an extension has an update, it is marked as outdated in the Extensions view. The updates are fetched from an online service."), default: true, scope: ConfigurationScope.APPLICATION, tags: ['usesOnlineServices'] @@ -223,7 +223,7 @@ Registry.as(ConfigurationExtensions.Configuration) }, 'extensions.showRecommendationsOnlyOnDemand': { type: 'boolean', - description: localize('extensionsShowRecommendationsOnlyOnDemand', "When enabled, recommendations will not be fetched or shown unless specifically requested by the user."), + description: localize('extensionsShowRecommendationsOnlyOnDemand', "When enabled, recommendations will not be fetched or shown unless specifically requested by the user. Some recommendations are fetched from an online service."), default: false, tags: ['usesOnlineServices'] }, diff --git a/src/vs/workbench/services/crashReporter/electron-browser/crashReporterService.ts b/src/vs/workbench/services/crashReporter/electron-browser/crashReporterService.ts index 6df2345bd64..677f02de1b7 100644 --- a/src/vs/workbench/services/crashReporter/electron-browser/crashReporterService.ts +++ b/src/vs/workbench/services/crashReporter/electron-browser/crashReporterService.ts @@ -36,7 +36,7 @@ configurationRegistry.registerConfiguration({ 'properties': { 'telemetry.enableCrashReporter': { 'type': 'boolean', - 'description': nls.localize('telemetry.enableCrashReporting', "Enable crash reports to be sent to Microsoft.\nThis option requires restart to take effect."), + 'description': nls.localize('telemetry.enableCrashReporting', "Enable crash reports to be sent to a Microsoft online service..\nThis option requires restart to take effect."), 'default': true, 'tags': ['usesOnlineServices'] } From c48eda2c8306365477086690535d015c0d712623 Mon Sep 17 00:00:00 2001 From: Rob Lourens Date: Wed, 1 Aug 2018 15:16:51 -0700 Subject: [PATCH 0400/1276] Minor edits --- extensions/css-language-features/package.nls.json | 8 ++++---- src/vs/workbench/electron-browser/main.contribution.ts | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/extensions/css-language-features/package.nls.json b/extensions/css-language-features/package.nls.json index 9bf6d29766e..f62c6fb669c 100644 --- a/extensions/css-language-features/package.nls.json +++ b/extensions/css-language-features/package.nls.json @@ -19,7 +19,7 @@ "css.lint.unknownAtRules.desc": "Unknown at-rule.", "css.lint.unknownProperties.desc": "Unknown property.", "css.lint.unknownVendorSpecificProperties.desc": "Unknown vendor specific property.", - "css.lint.vendorPrefix.desc": "When using a vendor-specific prefix and also including the standard property.", + "css.lint.vendorPrefix.desc": "When using a vendor-specific prefix, also include the standard property.", "css.lint.zeroUnits.desc": "No unit for zero needed.", "css.trace.server.desc": "Traces the communication between VS Code and the CSS language server.", "css.validate.title": "Controls CSS validation and problem severities.", @@ -30,7 +30,7 @@ "less.lint.compatibleVendorPrefixes.desc": "When using a vendor-specific prefix make sure to also include all other vendor-specific properties.", "less.lint.duplicateProperties.desc": "Do not use duplicate style definitions.", "less.lint.emptyRules.desc": "Do not use empty rulesets.", - "less.lint.float.desc": "Avoids using `float`. Floats lead to fragile CSS that is easy to break if one aspect of the layout changes.", + "less.lint.float.desc": "Avoid using `float`. Floats lead to fragile CSS that is easy to break if one aspect of the layout changes.", "less.lint.fontFaceProperties.desc": "`@font-face` rule must define `src` and `font-family` properties.", "less.lint.hexColorLength.desc": "Hex colors must consist of three or six hex numbers.", "less.lint.idSelector.desc": "Selectors should not contain IDs because these rules are too tightly coupled with the HTML.", @@ -41,7 +41,7 @@ "less.lint.universalSelector.desc": "The universal selector (`*`) is known to be slow.", "less.lint.unknownProperties.desc": "Unknown property.", "less.lint.unknownVendorSpecificProperties.desc": "Unknown vendor specific property.", - "less.lint.vendorPrefix.desc": "When using a vendor-specific prefix and also including the standard property.", + "less.lint.vendorPrefix.desc": "When using a vendor-specific prefix, also include the standard property.", "less.lint.zeroUnits.desc": "No unit for zero needed.", "less.validate.title": "Controls LESS validation and problem severities.", "less.validate.desc": "Enables or disables all validations.", @@ -62,7 +62,7 @@ "scss.lint.universalSelector.desc": "The universal selector (`*`) is known to be slow.", "scss.lint.unknownProperties.desc": "Unknown property.", "scss.lint.unknownVendorSpecificProperties.desc": "Unknown vendor specific property.", - "scss.lint.vendorPrefix.desc": "When using a vendor-specific prefix and also including the standard property.", + "scss.lint.vendorPrefix.desc": "When using a vendor-specific prefix, also include the standard property.", "scss.lint.zeroUnits.desc": "No unit for zero needed.", "scss.validate.title": "Controls SCSS validation and problem severities.", "scss.validate.desc": "Enables or disables all validations.", diff --git a/src/vs/workbench/electron-browser/main.contribution.ts b/src/vs/workbench/electron-browser/main.contribution.ts index 766c0110f3b..2602a0c87f8 100644 --- a/src/vs/workbench/electron-browser/main.contribution.ts +++ b/src/vs/workbench/electron-browser/main.contribution.ts @@ -358,7 +358,7 @@ configurationRegistry.registerConfiguration({ 'description': nls.localize({ comment: ['This is the description for a setting. Values surrounded by parenthesis are not to be translated.'], key: 'tabDescription' - }, "Controls the format of editor's label."), + }, "Controls the format of the label for an editor."), }, 'workbench.editor.tabCloseButton': { 'type': 'string', From cd5081e67ff7bd043441b13db02fd5d268bfa4c0 Mon Sep 17 00:00:00 2001 From: SteVen Batten Date: Wed, 1 Aug 2018 15:20:49 -0700 Subject: [PATCH 0401/1276] fixes #55513 --- src/vs/workbench/browser/parts/menubar/menubarPart.ts | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/vs/workbench/browser/parts/menubar/menubarPart.ts b/src/vs/workbench/browser/parts/menubar/menubarPart.ts index 63d53eb8e02..4c1ef5c3267 100644 --- a/src/vs/workbench/browser/parts/menubar/menubarPart.ts +++ b/src/vs/workbench/browser/parts/menubar/menubarPart.ts @@ -656,6 +656,11 @@ export class MenubarPart extends Part { }); this.customMenus[menuIndex].buttonElement.on(EventType.CLICK, (e) => { + // This should only happen for mnemonics and we shouldn't trigger them + if (!this.isVisible) { + return; + } + if (this._modifierKeyStatus && (this._modifierKeyStatus.shiftKey || this._modifierKeyStatus.ctrlKey)) { return; // supress keyboard shortcuts that shouldn't conflict } From 560724f6191259c4773568a2f4fb35a17daba63a Mon Sep 17 00:00:00 2001 From: SteVen Batten Date: Wed, 1 Aug 2018 15:34:30 -0700 Subject: [PATCH 0402/1276] fixes #55451 --- .../parts/menubar/menubar.contribution.ts | 9 --------- src/vs/workbench/electron-browser/actions.ts | 19 ------------------- .../electron-browser/main.contribution.ts | 3 +-- 3 files changed, 1 insertion(+), 30 deletions(-) diff --git a/src/vs/workbench/browser/parts/menubar/menubar.contribution.ts b/src/vs/workbench/browser/parts/menubar/menubar.contribution.ts index 57e3026f0eb..39c87100cce 100644 --- a/src/vs/workbench/browser/parts/menubar/menubar.contribution.ts +++ b/src/vs/workbench/browser/parts/menubar/menubar.contribution.ts @@ -389,15 +389,6 @@ function helpMenuRegistration() { }); if (!isMacintosh) { - MenuRegistry.appendMenuItem(MenuId.MenubarHelpMenu, { - group: '5_tools', - command: { - id: 'workbench.action.showAccessibilityOptions', - title: nls.localize({ key: 'miAccessibilityOptions', comment: ['&& denotes a mnemonic'] }, "Accessibility &&Options") - }, - order: 3 - }); - // About MenuRegistry.appendMenuItem(MenuId.MenubarHelpMenu, { group: 'z_about', diff --git a/src/vs/workbench/electron-browser/actions.ts b/src/vs/workbench/electron-browser/actions.ts index 8855a21628c..79b40283093 100644 --- a/src/vs/workbench/electron-browser/actions.ts +++ b/src/vs/workbench/electron-browser/actions.ts @@ -1643,25 +1643,6 @@ export class OpenPrivacyStatementUrlAction extends Action { } } -export class ShowAccessibilityOptionsAction extends Action { - - static readonly ID = 'workbench.action.showAccessibilityOptions'; - static LABEL = nls.localize('accessibilityOptions', "Accessibility Options"); - - constructor( - id: string, - label: string, - @IWindowsService private windowsService: IWindowsService - ) { - super(id, label); - } - - run(): TPromise { - return this.windowsService.openAccessibilityOptions(); - } -} - - export class ShowAboutDialogAction extends Action { static readonly ID = 'workbench.action.showAboutDialog'; diff --git a/src/vs/workbench/electron-browser/main.contribution.ts b/src/vs/workbench/electron-browser/main.contribution.ts index 91cffa0c85d..5e8a9c2f035 100644 --- a/src/vs/workbench/electron-browser/main.contribution.ts +++ b/src/vs/workbench/electron-browser/main.contribution.ts @@ -14,7 +14,7 @@ import { IConfigurationRegistry, Extensions as ConfigurationExtensions, Configur import { IWorkbenchActionRegistry, Extensions } from 'vs/workbench/common/actions'; import { KeyMod, KeyChord, KeyCode } from 'vs/base/common/keyCodes'; import { isWindows, isLinux, isMacintosh } from 'vs/base/common/platform'; -import { KeybindingsReferenceAction, OpenDocumentationUrlAction, OpenIntroductoryVideosUrlAction, OpenTipsAndTricksUrlAction, OpenIssueReporterAction, ReportPerformanceIssueUsingReporterAction, ZoomResetAction, ZoomOutAction, ZoomInAction, ToggleFullScreenAction, ToggleMenuBarAction, CloseWorkspaceAction, CloseCurrentWindowAction, SwitchWindow, NewWindowAction, NavigateUpAction, NavigateDownAction, NavigateLeftAction, NavigateRightAction, IncreaseViewSizeAction, DecreaseViewSizeAction, ShowStartupPerformance, ToggleSharedProcessAction, QuickSwitchWindow, QuickOpenRecentAction, inRecentFilesPickerContextKey, ShowAboutDialogAction, InspectContextKeysAction, OpenProcessExplorer, OpenTwitterUrlAction, OpenRequestFeatureUrlAction, OpenPrivacyStatementUrlAction, OpenLicenseUrlAction, ShowAccessibilityOptionsAction, OpenRecentAction } from 'vs/workbench/electron-browser/actions'; +import { KeybindingsReferenceAction, OpenDocumentationUrlAction, OpenIntroductoryVideosUrlAction, OpenTipsAndTricksUrlAction, OpenIssueReporterAction, ReportPerformanceIssueUsingReporterAction, ZoomResetAction, ZoomOutAction, ZoomInAction, ToggleFullScreenAction, ToggleMenuBarAction, CloseWorkspaceAction, CloseCurrentWindowAction, SwitchWindow, NewWindowAction, NavigateUpAction, NavigateDownAction, NavigateLeftAction, NavigateRightAction, IncreaseViewSizeAction, DecreaseViewSizeAction, ShowStartupPerformance, ToggleSharedProcessAction, QuickSwitchWindow, QuickOpenRecentAction, inRecentFilesPickerContextKey, ShowAboutDialogAction, InspectContextKeysAction, OpenProcessExplorer, OpenTwitterUrlAction, OpenRequestFeatureUrlAction, OpenPrivacyStatementUrlAction, OpenLicenseUrlAction, OpenRecentAction } from 'vs/workbench/electron-browser/actions'; import { registerCommands, QUIT_ID } from 'vs/workbench/electron-browser/commands'; import { AddRootFolderAction, GlobalRemoveRootFolderAction, OpenWorkspaceAction, SaveWorkspaceAsAction, OpenWorkspaceConfigFileAction, DuplicateWorkspaceInNewWindowAction, OpenFileFolderAction, OpenFileAction, OpenFolderAction } from 'vs/workbench/browser/actions/workspaceActions'; import { ContextKeyExpr, RawContextKey } from 'vs/platform/contextkey/common/contextkey'; @@ -70,7 +70,6 @@ workbenchActionsRegistry.registerWorkbenchAction(new SyncActionDescriptor(OpenTw workbenchActionsRegistry.registerWorkbenchAction(new SyncActionDescriptor(OpenRequestFeatureUrlAction, OpenRequestFeatureUrlAction.ID, OpenRequestFeatureUrlAction.LABEL), 'Help: Search Feature Requests', helpCategory); workbenchActionsRegistry.registerWorkbenchAction(new SyncActionDescriptor(OpenLicenseUrlAction, OpenLicenseUrlAction.ID, OpenLicenseUrlAction.LABEL), 'Help: View License', helpCategory); workbenchActionsRegistry.registerWorkbenchAction(new SyncActionDescriptor(OpenPrivacyStatementUrlAction, OpenPrivacyStatementUrlAction.ID, OpenPrivacyStatementUrlAction.LABEL), 'Help: Privacy Statement', helpCategory); -workbenchActionsRegistry.registerWorkbenchAction(new SyncActionDescriptor(ShowAccessibilityOptionsAction, ShowAccessibilityOptionsAction.ID, ShowAccessibilityOptionsAction.LABEL), 'Help: Accessibility Options', helpCategory); workbenchActionsRegistry.registerWorkbenchAction(new SyncActionDescriptor(ShowAboutDialogAction, ShowAboutDialogAction.ID, ShowAboutDialogAction.LABEL), 'Help: About', helpCategory); workbenchActionsRegistry.registerWorkbenchAction( From 55ae86a53db9042fe8fa4b3adafda7cbfa22ae16 Mon Sep 17 00:00:00 2001 From: Rob Lourens Date: Wed, 1 Aug 2018 15:48:12 -0700 Subject: [PATCH 0403/1276] Fix #55612 - fix findTextInFiles cancellation --- .../src/singlefolder-tests/workspace.test.ts | 10 +++++ .../electron-browser/mainThreadWorkspace.ts | 38 +++++++++---------- src/vs/workbench/api/node/extHostWorkspace.ts | 11 +++++- 3 files changed, 39 insertions(+), 20 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 a350f5334e2..41305d076b2 100644 --- a/extensions/vscode-api-tests/src/singlefolder-tests/workspace.test.ts +++ b/extensions/vscode-api-tests/src/singlefolder-tests/workspace.test.ts @@ -520,6 +520,16 @@ suite('workspace-namespace', () => { assert.equal(vscode.workspace.asRelativePath(results[0].uri), '10linefile.ts'); }); + test('findTextInFiles, cancellation', async () => { + const results: vscode.TextSearchResult[] = []; + const cancellation = new vscode.CancellationTokenSource(); + cancellation.cancel(); + + await vscode.workspace.findTextInFiles({ pattern: 'foo' }, result => { + results.push(result); + }, cancellation.token); + }); + test('applyEdit', () => { return vscode.workspace.openTextDocument(vscode.Uri.parse('untitled:' + join(vscode.workspace.rootPath || '', './new2.txt'))).then(doc => { diff --git a/src/vs/workbench/api/electron-browser/mainThreadWorkspace.ts b/src/vs/workbench/api/electron-browser/mainThreadWorkspace.ts index 8db9fa2331f..c43f1982a74 100644 --- a/src/vs/workbench/api/electron-browser/mainThreadWorkspace.ts +++ b/src/vs/workbench/api/electron-browser/mainThreadWorkspace.ts @@ -172,29 +172,29 @@ export class MainThreadWorkspace implements MainThreadWorkspaceShape { const queryBuilder = this._instantiationService.createInstance(QueryBuilder); const query = queryBuilder.text(pattern, folders, options); - return new TPromise((resolve, reject) => { - const onProgress = (p: ISearchProgressItem) => { - if (p.lineMatches) { - this._proxy.$handleTextSearchResult(p, requestId); + const onProgress = (p: ISearchProgressItem) => { + if (p.lineMatches) { + this._proxy.$handleTextSearchResult(p, requestId); + } + }; + + const search = this._searchService.search(query, onProgress).then( + () => { + delete this._activeSearches[requestId]; + return null; + }, + err => { + delete this._activeSearches[requestId]; + if (!isPromiseCanceledError(err)) { + return TPromise.wrapError(err); } - }; - const search = this._searchService.search(query, onProgress).then( - () => { - delete this._activeSearches[requestId]; - resolve(null); - }, - err => { - delete this._activeSearches[requestId]; - if (!isPromiseCanceledError(err)) { - reject(TPromise.wrapError(err)); - } + return undefined; + }); - return undefined; - }); + this._activeSearches[requestId] = search; - this._activeSearches[requestId] = search; - }); + return search; } $cancelSearch(requestId: number): Thenable { diff --git a/src/vs/workbench/api/node/extHostWorkspace.ts b/src/vs/workbench/api/node/extHostWorkspace.ts index ae1f6739927..13de47ac058 100644 --- a/src/vs/workbench/api/node/extHostWorkspace.ts +++ b/src/vs/workbench/api/node/extHostWorkspace.ts @@ -395,7 +395,13 @@ export class ExtHostWorkspace implements ExtHostWorkspaceShape { excludePattern: options.exclude && globPatternToString(options.exclude) }; + let isCanceled = false; + this._activeSearchCallbacks[requestId] = p => { + if (isCanceled) { + return; + } + p.lineMatches.forEach(lineMatch => { lineMatch.offsetAndLengths.forEach(offsetAndLength => { const range = new Range(lineMatch.lineNumber, offsetAndLength[0], lineMatch.lineNumber, offsetAndLength[0] + offsetAndLength[1]); @@ -409,7 +415,10 @@ export class ExtHostWorkspace implements ExtHostWorkspaceShape { }; if (token) { - token.onCancellationRequested(() => this._proxy.$cancelSearch(requestId)); + token.onCancellationRequested(() => { + isCanceled = true; + this._proxy.$cancelSearch(requestId); + }); } return this._proxy.$startTextSearch(query, queryOptions, requestId).then( From 3da7b066b2e2e6954577eb4d622c1280ac668d86 Mon Sep 17 00:00:00 2001 From: SteVen Batten Date: Wed, 1 Aug 2018 15:52:47 -0700 Subject: [PATCH 0404/1276] fixes #55539 --- src/vs/workbench/browser/parts/menubar/menubarPart.ts | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/vs/workbench/browser/parts/menubar/menubarPart.ts b/src/vs/workbench/browser/parts/menubar/menubarPart.ts index 4c1ef5c3267..17da790a322 100644 --- a/src/vs/workbench/browser/parts/menubar/menubarPart.ts +++ b/src/vs/workbench/browser/parts/menubar/menubarPart.ts @@ -106,6 +106,7 @@ export class MenubarPart extends Part { private updatePending: boolean; private _modifierKeyStatus: IModifierKeyStatus; private _focusState: MenubarState; + private openedViaKeyboard: boolean; private _onVisibilityChange: Emitter; @@ -292,7 +293,7 @@ export class MenubarPart extends Part { } if (this.focusedMenu) { - this.showCustomMenu(this.focusedMenu.index, !!this._modifierKeyStatus && this._modifierKeyStatus.altKey); + this.showCustomMenu(this.focusedMenu.index, this.openedViaKeyboard); } break; } @@ -644,6 +645,7 @@ export class MenubarPart extends Part { if ((event.equals(KeyCode.DownArrow) || event.equals(KeyCode.Enter)) && !this.isOpen) { this.focusedMenu = { index: menuIndex }; + this.openedViaKeyboard = true; this.focusState = MenubarState.OPEN; } else { eventHandled = false; @@ -670,10 +672,11 @@ export class MenubarPart extends Part { this.setUnfocusedState(); } else { this.cleanupCustomMenu(); - this.showCustomMenu(menuIndex, !!this._modifierKeyStatus && this._modifierKeyStatus.altKey); + this.showCustomMenu(menuIndex, this.openedViaKeyboard); } } else { this.focusedMenu = { index: menuIndex }; + this.openedViaKeyboard = (e as MouseEvent).detail === 0; // Indicates mouse was not clicked this.focusState = MenubarState.OPEN; } From 7dc16e946ff1d4ecb775b317657469678ceb8ae8 Mon Sep 17 00:00:00 2001 From: Rob Lourens Date: Wed, 1 Aug 2018 16:14:55 -0700 Subject: [PATCH 0405/1276] More setting description tweaks --- .../workbench/browser/parts/editor/breadcrumbs.ts | 4 ++-- .../files/electron-browser/files.contribution.ts | 14 +++++++------- .../electron-browser/crashReporterService.ts | 2 +- 3 files changed, 10 insertions(+), 10 deletions(-) diff --git a/src/vs/workbench/browser/parts/editor/breadcrumbs.ts b/src/vs/workbench/browser/parts/editor/breadcrumbs.ts index c076583eb44..e0e5dfa0fc8 100644 --- a/src/vs/workbench/browser/parts/editor/breadcrumbs.ts +++ b/src/vs/workbench/browser/parts/editor/breadcrumbs.ts @@ -120,7 +120,7 @@ Registry.as(Extensions.Configuration).registerConfigurat // default: false // }, 'breadcrumbs.filePath': { - description: localize('filepath', "Controls if and how file paths are shown in the breadcrumbs view."), + description: localize('filepath', "Controls whether and how file paths are shown in the breadcrumbs view."), type: 'string', default: 'on', enum: ['on', 'off', 'last'], @@ -131,7 +131,7 @@ Registry.as(Extensions.Configuration).registerConfigurat ] }, 'breadcrumbs.symbolPath': { - description: localize('symbolpath', "Controls if and how symbols are shown in the breadcrumbs view."), + description: localize('symbolpath', "Controls whether and how symbols are shown in the breadcrumbs view."), type: 'string', default: 'on', enum: ['on', 'off', 'last'], diff --git a/src/vs/workbench/parts/files/electron-browser/files.contribution.ts b/src/vs/workbench/parts/files/electron-browser/files.contribution.ts index a1ff10697c8..7656b2f3b24 100644 --- a/src/vs/workbench/parts/files/electron-browser/files.contribution.ts +++ b/src/vs/workbench/parts/files/electron-browser/files.contribution.ts @@ -186,7 +186,7 @@ configurationRegistry.registerConfiguration({ 'properties': { 'files.exclude': { 'type': 'object', - 'description': nls.localize('exclude', "Configure glob patterns for excluding files and folders. For example, the files explorer decides which files and folders to show or hide based on this setting."), + 'description': nls.localize('exclude', "Configure glob patterns for excluding files and folders. For example, the files explorer decides which files and folders to show or hide based on this setting. Read more about glob patterns [here](https://code.visualstudio.com/docs/editor/codebasics#_advanced-search-options)."), 'default': { '**/.git': true, '**/.svn': true, '**/.hg': true, '**/CVS': true, '**/.DS_Store': true }, 'scope': ConfigurationScope.RESOURCE, 'additionalProperties': { @@ -351,22 +351,22 @@ configurationRegistry.registerConfiguration({ }, 'explorer.autoReveal': { 'type': 'boolean', - 'description': nls.localize('autoReveal', "Controls if the explorer should automatically reveal and select files when opening them."), + 'description': nls.localize('autoReveal', "Controls whether the explorer should automatically reveal and select files when opening them."), 'default': true }, 'explorer.enableDragAndDrop': { 'type': 'boolean', - 'description': nls.localize('enableDragAndDrop', "Controls if the explorer should allow to move files and folders via drag and drop."), + 'description': nls.localize('enableDragAndDrop', "Controls whether the explorer should allow to move files and folders via drag and drop."), 'default': true }, 'explorer.confirmDragAndDrop': { 'type': 'boolean', - 'description': nls.localize('confirmDragAndDrop', "Controls if the explorer should ask for confirmation to move files and folders via drag and drop."), + 'description': nls.localize('confirmDragAndDrop', "Controls whether the explorer should ask for confirmation to move files and folders via drag and drop."), 'default': true }, 'explorer.confirmDelete': { 'type': 'boolean', - 'description': nls.localize('confirmDelete', "Controls if the explorer should ask for confirmation when deleting a file via the trash."), + 'description': nls.localize('confirmDelete', "Controls whether the explorer should ask for confirmation when deleting a file via the trash."), 'default': true }, 'explorer.sortOrder': { @@ -384,12 +384,12 @@ configurationRegistry.registerConfiguration({ }, 'explorer.decorations.colors': { type: 'boolean', - description: nls.localize('explorer.decorations.colors', "Controls if file decorations should use colors."), + description: nls.localize('explorer.decorations.colors', "Controls whether file decorations should use colors."), default: true }, 'explorer.decorations.badges': { type: 'boolean', - description: nls.localize('explorer.decorations.badges', "Controls if file decorations should use badges."), + description: nls.localize('explorer.decorations.badges', "Controls whether file decorations should use badges."), default: true }, } diff --git a/src/vs/workbench/services/crashReporter/electron-browser/crashReporterService.ts b/src/vs/workbench/services/crashReporter/electron-browser/crashReporterService.ts index 677f02de1b7..13049eb3358 100644 --- a/src/vs/workbench/services/crashReporter/electron-browser/crashReporterService.ts +++ b/src/vs/workbench/services/crashReporter/electron-browser/crashReporterService.ts @@ -36,7 +36,7 @@ configurationRegistry.registerConfiguration({ 'properties': { 'telemetry.enableCrashReporter': { 'type': 'boolean', - 'description': nls.localize('telemetry.enableCrashReporting', "Enable crash reports to be sent to a Microsoft online service..\nThis option requires restart to take effect."), + 'description': nls.localize('telemetry.enableCrashReporting', "Enable crash reports to be sent to a Microsoft online service. \nThis option requires restart to take effect."), 'default': true, 'tags': ['usesOnlineServices'] } From 3cd7cc3f484168f3bff3a2afbea077f214543487 Mon Sep 17 00:00:00 2001 From: Ramya Achutha Rao Date: Wed, 1 Aug 2018 16:41:08 -0700 Subject: [PATCH 0406/1276] Setting to disable online experiments #54354 --- .../workbench/electron-browser/main.contribution.ts | 6 ++++++ .../parts/experiments/node/experimentService.ts | 12 +++++------- 2 files changed, 11 insertions(+), 7 deletions(-) diff --git a/src/vs/workbench/electron-browser/main.contribution.ts b/src/vs/workbench/electron-browser/main.contribution.ts index 5e8a9c2f035..e3442e9f9a0 100644 --- a/src/vs/workbench/electron-browser/main.contribution.ts +++ b/src/vs/workbench/electron-browser/main.contribution.ts @@ -508,6 +508,12 @@ configurationRegistry.registerConfiguration({ 'description': nls.localize('settingsTocVisible', "Controls whether the settings editor Table of Contents is visible."), 'default': true, 'scope': ConfigurationScope.WINDOW + }, + 'workbench.enableExperiments': { + 'type': 'boolean', + 'description': nls.localize('workbench.enableExperiments', "Fetches experiments to run from a Microsoft online service."), + 'default': true, + 'tags': ['usesOnlineServices'] } } }); diff --git a/src/vs/workbench/parts/experiments/node/experimentService.ts b/src/vs/workbench/parts/experiments/node/experimentService.ts index ea5ff884fe7..96777a2416c 100644 --- a/src/vs/workbench/parts/experiments/node/experimentService.ts +++ b/src/vs/workbench/parts/experiments/node/experimentService.ts @@ -10,20 +10,17 @@ import { IStorageService, StorageScope } from 'vs/platform/storage/common/storag import { IEnvironmentService } from 'vs/platform/environment/common/environment'; import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry'; import { ILifecycleService, LifecyclePhase } from 'vs/platform/lifecycle/common/lifecycle'; - +import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; import { IExtensionManagementService, LocalExtensionType } from 'vs/platform/extensionManagement/common/extensionManagement'; import { IRequestService } from 'vs/platform/request/node/request'; - import { TPromise } from 'vs/base/common/winjs.base'; import { language } from 'vs/base/common/platform'; import { Disposable, IDisposable, dispose } from 'vs/base/common/lifecycle'; 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/parts/stats/node/workspaceStats'; -import { Emitter, Event } from 'vs/base/common/event'; - interface IExperimentStorageState { enabled: boolean; @@ -123,7 +120,8 @@ export class ExperimentService extends Disposable implements IExperimentService @IEnvironmentService private environmentService: IEnvironmentService, @ITelemetryService private telemetryService: ITelemetryService, @ILifecycleService private lifecycleService: ILifecycleService, - @IRequestService private requestService: IRequestService + @IRequestService private requestService: IRequestService, + @IConfigurationService private configurationService: IConfigurationService ) { super(); @@ -167,7 +165,7 @@ export class ExperimentService extends Disposable implements IExperimentService } protected getExperiments(): TPromise { - if (!product.experimentsUrl) { + if (!product.experimentsUrl || this.configurationService.getValue('workbench.enableExperiments') === false) { return TPromise.as([]); } return this.requestService.request({ type: 'GET', url: product.experimentsUrl }).then(context => { From 62b021cb68ce638412adb0a89921cf95e0016cab Mon Sep 17 00:00:00 2001 From: SteVen Batten Date: Wed, 1 Aug 2018 16:57:12 -0700 Subject: [PATCH 0407/1276] fixes #55507 --- src/vs/workbench/browser/parts/menubar/menubarPart.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vs/workbench/browser/parts/menubar/menubarPart.ts b/src/vs/workbench/browser/parts/menubar/menubarPart.ts index 17da790a322..6a0811f61e1 100644 --- a/src/vs/workbench/browser/parts/menubar/menubarPart.ts +++ b/src/vs/workbench/browser/parts/menubar/menubarPart.ts @@ -144,7 +144,7 @@ export class MenubarPart extends Part { this.topLevelMenus['Window'] = this._register(this.menuService.createMenu(MenuId.MenubarWindowMenu, this.contextKeyService)); } - this.menuUpdater = this._register(new RunOnceScheduler(() => this.doSetupMenubar(), 0)); + this.menuUpdater = this._register(new RunOnceScheduler(() => this.doSetupMenubar(), 100)); this.actionRunner = this._register(new ActionRunner()); this._register(this.actionRunner.onDidBeforeRun(() => { From 77dcb8b833178fad6cc19bb4941f83d1513eee4a Mon Sep 17 00:00:00 2001 From: SteVen Batten Date: Wed, 1 Aug 2018 17:22:38 -0700 Subject: [PATCH 0408/1276] fixes #55515 --- src/vs/code/electron-main/menubar.ts | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/vs/code/electron-main/menubar.ts b/src/vs/code/electron-main/menubar.ts index 099946d4298..26f371881fe 100644 --- a/src/vs/code/electron-main/menubar.ts +++ b/src/vs/code/electron-main/menubar.ts @@ -278,7 +278,7 @@ export class Menubar { // Mac: Window let macWindowMenuItem: Electron.MenuItem; - if (isMacintosh) { + if (this.shouldDrawMenu('Window')) { const windowMenu = new Menu(); macWindowMenuItem = new MenuItem({ label: this.mnemonicLabel(nls.localize('mWindow', "Window")), submenu: windowMenu, role: 'window' }); this.setMacWindowMenu(windowMenu); @@ -379,8 +379,9 @@ export class Menubar { switch (menuId) { case 'File': + case 'Window': case 'Help': - return isMacintosh || !!this.menubarMenus[menuId]; + return isMacintosh && (this.windowsMainService.getWindowCount() === 0 || !!this.menubarMenus[menuId]); default: return this.windowsMainService.getWindowCount() > 0 && !!this.menubarMenus[menuId]; } From 582cd9547d435735e583be540d0ba0c8262880c8 Mon Sep 17 00:00:00 2001 From: Ramya Achutha Rao Date: Wed, 1 Aug 2018 18:05:50 -0700 Subject: [PATCH 0409/1276] Show online services action only in Insiders for now --- .../preferences/browser/settingsEditor2.ts | 22 +++++++++++-------- 1 file changed, 13 insertions(+), 9 deletions(-) diff --git a/src/vs/workbench/parts/preferences/browser/settingsEditor2.ts b/src/vs/workbench/parts/preferences/browser/settingsEditor2.ts index 3346f396a0b..f9738e7c3f6 100644 --- a/src/vs/workbench/parts/preferences/browser/settingsEditor2.ts +++ b/src/vs/workbench/parts/preferences/browser/settingsEditor2.ts @@ -230,19 +230,23 @@ export class SettingsEditor2 extends BaseEditor { actionRunner: this.actionRunner }); - const actions = [ + const actions: Action[] = [ this.instantiationService.createInstance(FilterByTagAction, localize('filterModifiedLabel', "Show modified settings"), MODIFIED_SETTING_TAG, - this), - this.instantiationService.createInstance( - FilterByTagAction, - localize('filterOnlineServicesLabel', "Show settings for online services"), - ONLINE_SERVICES_SETTING_TAG, - this), - new Separator(), - this.instantiationService.createInstance(OpenSettingsAction) + this) ]; + if (this.environmentService.appQuality !== 'stable') { + actions.push( + this.instantiationService.createInstance( + FilterByTagAction, + localize('filterOnlineServicesLabel', "Show settings for online services"), + ONLINE_SERVICES_SETTING_TAG, + this)); + actions.push(new Separator()); + } + actions.push(this.instantiationService.createInstance(OpenSettingsAction)); + this.toolbar.setActions([], actions)(); this.toolbar.context = { target: this.settingsTargetsWidget.settingsTarget }; } From 65523944da6b7198be7f1f835cf395d87833b568 Mon Sep 17 00:00:00 2001 From: Rob Lourens Date: Wed, 1 Aug 2018 17:50:13 -0700 Subject: [PATCH 0410/1276] Settings editor - change toc behavior default to 'filter' --- src/vs/workbench/electron-browser/main.contribution.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vs/workbench/electron-browser/main.contribution.ts b/src/vs/workbench/electron-browser/main.contribution.ts index e3442e9f9a0..9b09e526c44 100644 --- a/src/vs/workbench/electron-browser/main.contribution.ts +++ b/src/vs/workbench/electron-browser/main.contribution.ts @@ -500,7 +500,7 @@ configurationRegistry.registerConfiguration({ 'type': 'string', 'enum': ['hide', 'filter', 'show'], 'description': nls.localize('settingsSearchTocBehavior', "Controls the behavior of the settings editor Table of Contents while searching."), - 'default': 'hide', + 'default': 'filter', 'scope': ConfigurationScope.WINDOW }, 'workbench.settings.tocVisible': { From 0abfd43ec0f3bccab659982dd479571e4cf0b9f7 Mon Sep 17 00:00:00 2001 From: Rob Lourens Date: Wed, 1 Aug 2018 18:18:57 -0700 Subject: [PATCH 0411/1276] Settings editor - nicer filter count style during search --- .../preferences/browser/media/settingsEditor2.css | 4 ++++ .../workbench/parts/preferences/browser/tocTree.ts | 13 +++++++++---- 2 files changed, 13 insertions(+), 4 deletions(-) diff --git a/src/vs/workbench/parts/preferences/browser/media/settingsEditor2.css b/src/vs/workbench/parts/preferences/browser/media/settingsEditor2.css index dffcd2fe540..075651c9821 100644 --- a/src/vs/workbench/parts/preferences/browser/media/settingsEditor2.css +++ b/src/vs/workbench/parts/preferences/browser/media/settingsEditor2.css @@ -184,6 +184,10 @@ opacity: 0.9; } +.settings-editor > .settings-body .settings-toc-container .monaco-tree-row .settings-toc-entry .settings-toc-count { + opacity: 0.7; +} + .settings-editor > .settings-body .settings-toc-container .monaco-tree-row.has-children > .content:before { opacity: 0.9; } diff --git a/src/vs/workbench/parts/preferences/browser/tocTree.ts b/src/vs/workbench/parts/preferences/browser/tocTree.ts index d81dc3bcac6..4f42cfc4a89 100644 --- a/src/vs/workbench/parts/preferences/browser/tocTree.ts +++ b/src/vs/workbench/parts/preferences/browser/tocTree.ts @@ -134,12 +134,17 @@ export class TOCRenderer implements IRenderer { } renderElement(tree: ITree, element: SettingsTreeGroupElement, templateId: string, template: ITOCEntryTemplate): void { - const label = (element).count ? - `${element.label} (${(element).count})` : - element.label; + const count = (element).count; + const label = element.label; - DOM.toggleClass(template.element, 'no-results', (element).count === 0); + DOM.toggleClass(template.element, 'no-results', count === 0); template.element.textContent = label; + + if (count) { + const countElement = $('span.settings-toc-count'); + countElement.textContent = ` (${count})`; + template.element.appendChild(countElement); + } } disposeTemplate(tree: ITree, templateId: string, templateData: any): void { From 86f76374e4e5a14c5503c842d2e93b6151371050 Mon Sep 17 00:00:00 2001 From: Rob Lourens Date: Wed, 1 Aug 2018 19:00:43 -0700 Subject: [PATCH 0412/1276] Fix #55617 - search viewlet icons --- src/vs/workbench/parts/search/browser/searchResultsView.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vs/workbench/parts/search/browser/searchResultsView.ts b/src/vs/workbench/parts/search/browser/searchResultsView.ts index 8f3f69372cd..4a27ccf12d5 100644 --- a/src/vs/workbench/parts/search/browser/searchResultsView.ts +++ b/src/vs/workbench/parts/search/browser/searchResultsView.ts @@ -263,7 +263,7 @@ export class SearchRenderer extends Disposable implements IRenderer { private renderFileMatch(tree: ITree, fileMatch: FileMatch, templateData: IFileMatchTemplate): void { templateData.el.setAttribute('data-resource', fileMatch.resource().toString()); - templateData.label.setFile(fileMatch.resource()); + templateData.label.setFile(fileMatch.resource(), { hideIcon: false }); let count = fileMatch.count(); templateData.badge.setCount(count); templateData.badge.setTitleFormat(count > 1 ? nls.localize('searchMatches', "{0} matches found", count) : nls.localize('searchMatch', "{0} match found", count)); From ec78bd91fa037a76f298e84d3876e88aeab319f6 Mon Sep 17 00:00:00 2001 From: Rob Lourens Date: Wed, 1 Aug 2018 20:46:41 -0700 Subject: [PATCH 0413/1276] Settings editor - better styling for element count indicator --- .../browser/media/settingsEditor2.css | 9 ++++++++- .../parts/preferences/browser/tocTree.ts | 16 +++++++++------- 2 files changed, 17 insertions(+), 8 deletions(-) diff --git a/src/vs/workbench/parts/preferences/browser/media/settingsEditor2.css b/src/vs/workbench/parts/preferences/browser/media/settingsEditor2.css index 075651c9821..67353f45bc3 100644 --- a/src/vs/workbench/parts/preferences/browser/media/settingsEditor2.css +++ b/src/vs/workbench/parts/preferences/browser/media/settingsEditor2.css @@ -177,15 +177,22 @@ display: none; } +.settings-editor > .settings-body .settings-toc-container .monaco-tree-row .content { + display: flex; +} + .settings-editor > .settings-body .settings-toc-container .monaco-tree-row .settings-toc-entry { overflow: hidden; text-overflow: ellipsis; line-height: 22px; opacity: 0.9; + flex-shrink: 1; } -.settings-editor > .settings-body .settings-toc-container .monaco-tree-row .settings-toc-entry .settings-toc-count { +.settings-editor > .settings-body .settings-toc-container .monaco-tree-row .settings-toc-count { + line-height: 22px; opacity: 0.7; + margin-left: 3px; } .settings-editor > .settings-body .settings-toc-container .monaco-tree-row.has-children > .content:before { diff --git a/src/vs/workbench/parts/preferences/browser/tocTree.ts b/src/vs/workbench/parts/preferences/browser/tocTree.ts index 4f42cfc4a89..87c7a723981 100644 --- a/src/vs/workbench/parts/preferences/browser/tocTree.ts +++ b/src/vs/workbench/parts/preferences/browser/tocTree.ts @@ -115,7 +115,8 @@ export class TOCDataSource implements IDataSource { const TOC_ENTRY_TEMPLATE_ID = 'settings.toc.entry'; interface ITOCEntryTemplate { - element: HTMLElement; + labelElement: HTMLElement; + countElement: HTMLElement; } export class TOCRenderer implements IRenderer { @@ -129,7 +130,8 @@ export class TOCRenderer implements IRenderer { renderTemplate(tree: ITree, templateId: string, container: HTMLElement): ITOCEntryTemplate { return { - element: DOM.append(container, $('.settings-toc-entry')) + labelElement: DOM.append(container, $('.settings-toc-entry')), + countElement: DOM.append(container, $('.settings-toc-count')) }; } @@ -137,13 +139,13 @@ export class TOCRenderer implements IRenderer { const count = (element).count; const label = element.label; - DOM.toggleClass(template.element, 'no-results', count === 0); - template.element.textContent = label; + DOM.toggleClass(template.labelElement, 'no-results', count === 0); + template.labelElement.textContent = label; if (count) { - const countElement = $('span.settings-toc-count'); - countElement.textContent = ` (${count})`; - template.element.appendChild(countElement); + template.countElement.textContent = ` (${count})`; + } else { + template.countElement.textContent = ''; } } From c86cab2211d6dce686e5c89934d915b1e020ba9e Mon Sep 17 00:00:00 2001 From: Rob Lourens Date: Wed, 1 Aug 2018 21:27:18 -0700 Subject: [PATCH 0414/1276] SearchProvider - fix NPE when searching extraFileResources --- src/vs/workbench/api/node/extHostSearch.ts | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/src/vs/workbench/api/node/extHostSearch.ts b/src/vs/workbench/api/node/extHostSearch.ts index 33647f92927..47b7f055eee 100644 --- a/src/vs/workbench/api/node/extHostSearch.ts +++ b/src/vs/workbench/api/node/extHostSearch.ts @@ -669,9 +669,16 @@ class FileSearchManager { } private rawMatchToSearchItem(match: IInternalFileMatch): IFileMatch { - return { - resource: resources.joinPath(match.base, match.relativePath) - }; + if (match.relativePath) { + return { + resource: resources.joinPath(match.base, match.relativePath) + }; + } else { + // extraFileResources + return { + resource: match.base + }; + } } private doSearch(engine: FileSearchEngine, batchSize: number, onResultBatch: (matches: IInternalFileMatch[]) => void): TPromise { From 7c6c7ac5fe2bdad395d1a03b284cf560dfe4e820 Mon Sep 17 00:00:00 2001 From: Matt Bierner Date: Thu, 2 Aug 2018 10:35:54 +0200 Subject: [PATCH 0415/1276] Allow extends to work without json suffix Fixes #16905 --- .../src/features/tsconfig.ts | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/extensions/typescript-language-features/src/features/tsconfig.ts b/extensions/typescript-language-features/src/features/tsconfig.ts index 048ac79ab2c..a7e89ea1332 100644 --- a/extensions/typescript-language-features/src/features/tsconfig.ts +++ b/extensions/typescript-language-features/src/features/tsconfig.ts @@ -33,7 +33,16 @@ class TsconfigLinkProvider implements vscode.DocumentLinkProvider { } private getExendsLink(document: vscode.TextDocument, root: jsonc.Node): vscode.DocumentLink | undefined { - return this.pathNodeToLink(document, jsonc.findNodeAtLocation(root, ['extends'])); + const extendsNode = jsonc.findNodeAtLocation(root, ['extends']); + if (!this.isPathValue(extendsNode)) { + return undefined; + } + + return new vscode.DocumentLink( + this.getRange(document, extendsNode), + basename(extendsNode.value).match('.json$') + ? this.getFileTarget(document, extendsNode) + : vscode.Uri.file(join(dirname(document.uri.fsPath), extendsNode!.value + '.json'))); } private getFilesLinks(document: vscode.TextDocument, root: jsonc.Node) { From 0325e2527e35c0db7de4c2076e7ba6887e595b2d Mon Sep 17 00:00:00 2001 From: Matt Bierner Date: Thu, 2 Aug 2018 11:06:04 +0200 Subject: [PATCH 0416/1276] Remove accessability options logic entirely Follow up on #55451 --- src/vs/platform/windows/common/windows.ts | 1 - src/vs/platform/windows/common/windowsIpc.ts | 6 ----- .../windows/electron-main/windowsService.ts | 25 +------------------ .../workbench/test/workbenchTestServices.ts | 4 --- 4 files changed, 1 insertion(+), 35 deletions(-) diff --git a/src/vs/platform/windows/common/windows.ts b/src/vs/platform/windows/common/windows.ts index 269f0bf03d0..d5ce1f512ac 100644 --- a/src/vs/platform/windows/common/windows.ts +++ b/src/vs/platform/windows/common/windows.ts @@ -173,7 +173,6 @@ export interface IWindowsService { // TODO: this is a bit backwards startCrashReporter(config: CrashReporterStartOptions): TPromise; - openAccessibilityOptions(): TPromise; openAboutDialog(): TPromise; } diff --git a/src/vs/platform/windows/common/windowsIpc.ts b/src/vs/platform/windows/common/windowsIpc.ts index 572713c7498..30c4b7527fd 100644 --- a/src/vs/platform/windows/common/windowsIpc.ts +++ b/src/vs/platform/windows/common/windowsIpc.ts @@ -73,7 +73,6 @@ export interface IWindowsChannel extends IChannel { call(command: 'getActiveWindowId'): TPromise; call(command: 'openExternal', arg: string): TPromise; call(command: 'startCrashReporter', arg: CrashReporterStartOptions): TPromise; - call(command: 'openAccessibilityOptions'): TPromise; call(command: 'openAboutDialog'): TPromise; } @@ -178,7 +177,6 @@ export class WindowsChannel implements IWindowsChannel { case 'getActiveWindowId': return this.service.getActiveWindowId(); case 'openExternal': return this.service.openExternal(arg); case 'startCrashReporter': return this.service.startCrashReporter(arg); - case 'openAccessibilityOptions': return this.service.openAccessibilityOptions(); case 'openAboutDialog': return this.service.openAboutDialog(); } return undefined; @@ -398,10 +396,6 @@ export class WindowsChannelClient implements IWindowsService { return this.channel.call('updateTouchBar', [windowId, items]); } - openAccessibilityOptions(): TPromise { - return this.channel.call('openAccessibilityOptions'); - } - openAboutDialog(): TPromise { return this.channel.call('openAboutDialog'); } diff --git a/src/vs/platform/windows/electron-main/windowsService.ts b/src/vs/platform/windows/electron-main/windowsService.ts index 0e2ace3e04f..1cf5341aac2 100644 --- a/src/vs/platform/windows/electron-main/windowsService.ts +++ b/src/vs/platform/windows/electron-main/windowsService.ts @@ -13,7 +13,7 @@ import URI from 'vs/base/common/uri'; import product from 'vs/platform/node/product'; import { IWindowsService, OpenContext, INativeOpenDialogOptions, IEnterWorkspaceResult, IMessageBoxResult, IDevToolsOptions } from 'vs/platform/windows/common/windows'; import { IEnvironmentService, ParsedArgs } from 'vs/platform/environment/common/environment'; -import { shell, crashReporter, app, Menu, clipboard, BrowserWindow } from 'electron'; +import { shell, crashReporter, app, Menu, clipboard } from 'electron'; import { Event, fromNodeEventEmitter, mapEvent, filterEvent, anyEvent, latch } from 'vs/base/common/event'; import { IURLService, IURLHandler } from 'vs/platform/url/common/url'; import { ILifecycleService } from 'vs/platform/lifecycle/electron-main/lifecycleMain'; @@ -491,29 +491,6 @@ export class WindowsService implements IWindowsService, IURLHandler, IDisposable return TPromise.as(null); } - openAccessibilityOptions(): TPromise { - this.logService.trace('windowsService#openAccessibilityOptions'); - - const win = new BrowserWindow({ - alwaysOnTop: true, - skipTaskbar: true, - resizable: false, - width: 450, - height: 300, - show: true, - title: nls.localize('accessibilityOptionsWindowTitle', "Accessibility Options"), - webPreferences: { - disableBlinkFeatures: 'Auxclick' - } - }); - - win.setMenuBarVisibility(false); - - win.loadURL('chrome://accessibility'); - - return TPromise.as(null); - } - openAboutDialog(): TPromise { this.logService.trace('windowsService#openAboutDialog'); const lastActiveWindow = this.windowsMainService.getFocusedWindow() || this.windowsMainService.getLastActiveWindow(); diff --git a/src/vs/workbench/test/workbenchTestServices.ts b/src/vs/workbench/test/workbenchTestServices.ts index 8cf78a8f658..62bbd8234db 100644 --- a/src/vs/workbench/test/workbenchTestServices.ts +++ b/src/vs/workbench/test/workbenchTestServices.ts @@ -1343,10 +1343,6 @@ export class TestWindowsService implements IWindowsService { return TPromise.as(void 0); } - openAccessibilityOptions(): TPromise { - return TPromise.as(void 0); - } - openAboutDialog(): TPromise { return TPromise.as(void 0); } From 1b110553950e3474ace35007ec28b6ab80c8efba Mon Sep 17 00:00:00 2001 From: Andre Weinand Date: Thu, 2 Aug 2018 12:02:36 +0200 Subject: [PATCH 0417/1276] use latest version of DAP --- package.json | 2 +- yarn.lock | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/package.json b/package.json index 0d6b1e29e79..8f7d28e7755 100644 --- a/package.json +++ b/package.json @@ -46,7 +46,7 @@ "sudo-prompt": "8.2.0", "v8-inspect-profiler": "^0.0.8", "vscode-chokidar": "1.6.2", - "vscode-debugprotocol": "1.30.0", + "vscode-debugprotocol": "1.31.0", "vscode-nsfw": "1.0.17", "vscode-ripgrep": "^1.0.1", "vscode-textmate": "^4.0.1", diff --git a/yarn.lock b/yarn.lock index 05e9801e2ba..fe0f0ef16a6 100644 --- a/yarn.lock +++ b/yarn.lock @@ -6210,9 +6210,9 @@ vscode-chokidar@1.6.2: optionalDependencies: vscode-fsevents "0.3.8" -vscode-debugprotocol@1.30.0: - version "1.30.0" - resolved "https://registry.yarnpkg.com/vscode-debugprotocol/-/vscode-debugprotocol-1.30.0.tgz#ece6d8559733e87bc7a2147b385899777a92af69" +vscode-debugprotocol@1.31.0: + version "1.31.0" + resolved "https://registry.yarnpkg.com/vscode-debugprotocol/-/vscode-debugprotocol-1.31.0.tgz#8467eeabeea65f52da5ac03b03c18e10e8b95eb4" vscode-fsevents@0.3.8: version "0.3.8" From 488b194a98cd1af942a58d1e7f19d09d17bbb267 Mon Sep 17 00:00:00 2001 From: isidor Date: Thu, 2 Aug 2018 12:36:02 +0200 Subject: [PATCH 0418/1276] fixes #55490 --- src/vs/workbench/browser/labels.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/vs/workbench/browser/labels.ts b/src/vs/workbench/browser/labels.ts index 7357d3a8b6b..2745cfdedbe 100644 --- a/src/vs/workbench/browser/labels.ts +++ b/src/vs/workbench/browser/labels.ts @@ -191,7 +191,7 @@ export class ResourceLabel extends IconLabel { iconLabelOptions.title = this.options.title; } else if (resource && resource.scheme !== Schemas.data /* do not accidentally inline Data URIs */) { if (!this.computedPathLabel) { - this.computedPathLabel = this.uriDisplayService.getLabel(resource, true); + this.computedPathLabel = this.uriDisplayService.getLabel(resource); } iconLabelOptions.title = this.computedPathLabel; @@ -298,7 +298,7 @@ export class FileLabel extends ResourceLabel { let description: string; const hidePath = (options && options.hidePath) || (resource.scheme === Schemas.untitled && !this.untitledEditorService.hasAssociatedFilePath(resource)); if (!hidePath) { - description = this.uriDisplayService.getLabel(resources.dirname(resource), true); + description = this.uriDisplayService.getLabel(resources.dirname(resource)); } this.setLabel({ resource, name, description }, options); From 9682614323e36de248a780131fa374ea23a17cd2 Mon Sep 17 00:00:00 2001 From: Joao Moreno Date: Thu, 2 Aug 2018 14:26:32 +0200 Subject: [PATCH 0419/1276] fixes #55122 --- extensions/git/src/commands.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/extensions/git/src/commands.ts b/extensions/git/src/commands.ts index 19c3cbdbe59..2e1c115c14f 100644 --- a/extensions/git/src/commands.ts +++ b/extensions/git/src/commands.ts @@ -1021,8 +1021,8 @@ export class CommandCenter { if (unsavedTextDocuments.length > 0) { const message = unsavedTextDocuments.length === 1 - ? localize('unsaved files single', "The following file is unsaved: {0}.\n\nWould you like to save it before comitting?", path.basename(unsavedTextDocuments[0].uri.fsPath)) - : localize('unsaved files', "There are {0} unsaved files.\n\nWould you like to save them before comitting?", unsavedTextDocuments.length); + ? localize('unsaved files single', "The following file is unsaved: {0}.\n\nWould you like to save it before committing?", path.basename(unsavedTextDocuments[0].uri.fsPath)) + : localize('unsaved files', "There are {0} unsaved files.\n\nWould you like to save them before committing?", unsavedTextDocuments.length); const saveAndCommit = localize('save and commit', "Save All & Commit"); const commit = localize('commit', "Commit Anyway"); const pick = await window.showWarningMessage(message, { modal: true }, saveAndCommit, commit); From e7594477812fac735d48f00bbaa82dd83cadf933 Mon Sep 17 00:00:00 2001 From: isidor Date: Thu, 2 Aug 2018 14:45:46 +0200 Subject: [PATCH 0420/1276] fixes #52332 --- src/vs/workbench/parts/debug/browser/debugActionItems.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/src/vs/workbench/parts/debug/browser/debugActionItems.ts b/src/vs/workbench/parts/debug/browser/debugActionItems.ts index 42d3ff235fd..8590c1bc66b 100644 --- a/src/vs/workbench/parts/debug/browser/debugActionItems.ts +++ b/src/vs/workbench/parts/debug/browser/debugActionItems.ts @@ -72,6 +72,7 @@ export class StartDebugActionItem implements IActionItem { dom.addClass(container, 'start-debug-action-item'); this.start = dom.append(container, $('.icon')); this.start.title = this.action.label; + this.start.setAttribute('role', 'button'); this.start.tabIndex = 0; this.toDispose.push(dom.addDisposableListener(this.start, dom.EventType.CLICK, () => { From c09911add3efda281261aa710b2b53fad32f1144 Mon Sep 17 00:00:00 2001 From: Christof Marti Date: Thu, 2 Aug 2018 15:09:51 +0200 Subject: [PATCH 0421/1276] Avoid assumptions about git: URIs (fixes #36236) --- extensions/extension-editing/src/extensionLinter.ts | 3 +++ 1 file changed, 3 insertions(+) diff --git a/extensions/extension-editing/src/extensionLinter.ts b/extensions/extension-editing/src/extensionLinter.ts index 04b0521c591..2724038bdf7 100644 --- a/extensions/extension-editing/src/extensionLinter.ts +++ b/extensions/extension-editing/src/extensionLinter.ts @@ -263,6 +263,9 @@ export class ExtensionLinter { } private async loadPackageJson(folder: Uri) { + if (folder.scheme === 'git') { // #36236 + return undefined; + } const file = folder.with({ path: path.posix.join(folder.path, 'package.json') }); try { const document = await workspace.openTextDocument(file); From 52cf58a8947c8996c7e6327d1f75b7a17438f4bc Mon Sep 17 00:00:00 2001 From: isidor Date: Thu, 2 Aug 2018 15:46:39 +0200 Subject: [PATCH 0422/1276] relative path for descriptions --- src/vs/workbench/browser/labels.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vs/workbench/browser/labels.ts b/src/vs/workbench/browser/labels.ts index 2745cfdedbe..bf04e217fa7 100644 --- a/src/vs/workbench/browser/labels.ts +++ b/src/vs/workbench/browser/labels.ts @@ -298,7 +298,7 @@ export class FileLabel extends ResourceLabel { let description: string; const hidePath = (options && options.hidePath) || (resource.scheme === Schemas.untitled && !this.untitledEditorService.hasAssociatedFilePath(resource)); if (!hidePath) { - description = this.uriDisplayService.getLabel(resources.dirname(resource)); + description = this.uriDisplayService.getLabel(resources.dirname(resource), true); } this.setLabel({ resource, name, description }, options); From f365098657c23f11aa3c8abbc878b0235a82f04a Mon Sep 17 00:00:00 2001 From: isidor Date: Thu, 2 Aug 2018 15:55:37 +0200 Subject: [PATCH 0423/1276] resourece: get rid of isFile context key fixes #48275 --- src/vs/workbench/common/resources.ts | 9 +------- .../fileActions.contribution.ts | 22 +++++++++---------- 2 files changed, 12 insertions(+), 19 deletions(-) diff --git a/src/vs/workbench/common/resources.ts b/src/vs/workbench/common/resources.ts index 1801c5ad38c..f58e4867ebe 100644 --- a/src/vs/workbench/common/resources.ts +++ b/src/vs/workbench/common/resources.ts @@ -9,7 +9,6 @@ import URI from 'vs/base/common/uri'; import * as paths from 'vs/base/common/paths'; import { RawContextKey, IContextKeyService, IContextKey } from 'vs/platform/contextkey/common/contextkey'; import { IModeService } from 'vs/editor/common/services/modeService'; -import { IFileService } from 'vs/platform/files/common/files'; export class ResourceContextKey implements IContextKey { @@ -19,7 +18,6 @@ export class ResourceContextKey implements IContextKey { static Resource = new RawContextKey('resource', undefined); static Extension = new RawContextKey('resourceExtname', undefined); static HasResource = new RawContextKey('resourceSet', false); - static IsFile = new RawContextKey('resourceIsFile', false); private _resourceKey: IContextKey; private _schemeKey: IContextKey; @@ -27,12 +25,10 @@ export class ResourceContextKey implements IContextKey { private _langIdKey: IContextKey; private _extensionKey: IContextKey; private _hasResource: IContextKey; - private _isFile: IContextKey; constructor( @IContextKeyService contextKeyService: IContextKeyService, - @IModeService private readonly _modeService: IModeService, - @IFileService private readonly _fileService: IFileService + @IModeService private readonly _modeService: IModeService ) { this._schemeKey = ResourceContextKey.Scheme.bindTo(contextKeyService); this._filenameKey = ResourceContextKey.Filename.bindTo(contextKeyService); @@ -40,7 +36,6 @@ export class ResourceContextKey implements IContextKey { this._resourceKey = ResourceContextKey.Resource.bindTo(contextKeyService); this._extensionKey = ResourceContextKey.Extension.bindTo(contextKeyService); this._hasResource = ResourceContextKey.HasResource.bindTo(contextKeyService); - this._isFile = ResourceContextKey.IsFile.bindTo(contextKeyService); } set(value: URI) { @@ -50,7 +45,6 @@ export class ResourceContextKey implements IContextKey { this._langIdKey.set(value && this._modeService.getModeIdByFilenameOrFirstLine(value.fsPath)); this._extensionKey.set(value && paths.extname(value.fsPath)); this._hasResource.set(!!value); - this._isFile.set(value && this._fileService.canHandleResource(value)); } reset(): void { @@ -60,7 +54,6 @@ export class ResourceContextKey implements IContextKey { this._langIdKey.reset(); this._extensionKey.reset(); this._hasResource.reset(); - this._isFile.reset(); } get(): URI { diff --git a/src/vs/workbench/parts/files/electron-browser/fileActions.contribution.ts b/src/vs/workbench/parts/files/electron-browser/fileActions.contribution.ts index dbca8fb34ef..8b9e89c8e5f 100644 --- a/src/vs/workbench/parts/files/electron-browser/fileActions.contribution.ts +++ b/src/vs/workbench/parts/files/electron-browser/fileActions.contribution.ts @@ -114,8 +114,8 @@ const copyRelativePathCommand = { // Editor Title Context Menu appendEditorTitleContextMenuItem(REVEAL_IN_OS_COMMAND_ID, REVEAL_IN_OS_LABEL, ResourceContextKey.Scheme.isEqualTo(Schemas.file)); -appendEditorTitleContextMenuItem(COPY_PATH_COMMAND_ID, copyPathCommand.title, ResourceContextKey.IsFile, copyRelativePathCommand); -appendEditorTitleContextMenuItem(REVEAL_IN_EXPLORER_COMMAND_ID, nls.localize('revealInSideBar', "Reveal in Side Bar"), ResourceContextKey.IsFile); +appendEditorTitleContextMenuItem(COPY_PATH_COMMAND_ID, copyPathCommand.title, ResourceContextKey.HasResource, copyRelativePathCommand); +appendEditorTitleContextMenuItem(REVEAL_IN_EXPLORER_COMMAND_ID, nls.localize('revealInSideBar', "Reveal in Side Bar"), ResourceContextKey.HasResource); function appendEditorTitleContextMenuItem(id: string, title: string, when: ContextKeyExpr, alt?: { id: string, title: string }): void { @@ -186,7 +186,7 @@ MenuRegistry.appendMenuItem(MenuId.OpenEditorsContext, { group: 'navigation', order: 10, command: openToSideCommand, - when: ResourceContextKey.IsFile + when: ResourceContextKey.HasResource }); const revealInOsCommand = { @@ -205,7 +205,7 @@ MenuRegistry.appendMenuItem(MenuId.OpenEditorsContext, { order: 40, command: copyPathCommand, alt: copyRelativePathCommand, - when: ResourceContextKey.IsFile + when: ResourceContextKey.HasResource }); MenuRegistry.appendMenuItem(MenuId.OpenEditorsContext, { @@ -216,7 +216,7 @@ MenuRegistry.appendMenuItem(MenuId.OpenEditorsContext, { title: SAVE_FILE_LABEL, precondition: DirtyEditorContext }, - when: ContextKeyExpr.and(ResourceContextKey.IsFile, AutoSaveContext.notEqualsTo('afterDelay') && AutoSaveContext.notEqualsTo('')) + when: ContextKeyExpr.and(ResourceContextKey.Scheme.isEqualTo(Schemas.file), AutoSaveContext.notEqualsTo('afterDelay') && AutoSaveContext.notEqualsTo('')) }); MenuRegistry.appendMenuItem(MenuId.OpenEditorsContext, { @@ -227,7 +227,7 @@ MenuRegistry.appendMenuItem(MenuId.OpenEditorsContext, { title: nls.localize('revert', "Revert File"), precondition: DirtyEditorContext }, - when: ContextKeyExpr.and(ResourceContextKey.IsFile, AutoSaveContext.notEqualsTo('afterDelay') && AutoSaveContext.notEqualsTo('')) + when: ContextKeyExpr.and(ResourceContextKey.Scheme.isEqualTo(Schemas.file), AutoSaveContext.notEqualsTo('afterDelay') && AutoSaveContext.notEqualsTo('')) }); MenuRegistry.appendMenuItem(MenuId.OpenEditorsContext, { @@ -256,7 +256,7 @@ MenuRegistry.appendMenuItem(MenuId.OpenEditorsContext, { title: nls.localize('compareWithSaved', "Compare with Saved"), precondition: DirtyEditorContext }, - when: ContextKeyExpr.and(ResourceContextKey.IsFile, AutoSaveContext.notEqualsTo('afterDelay') && AutoSaveContext.notEqualsTo(''), WorkbenchListDoubleSelection.toNegated()) + when: ContextKeyExpr.and(ResourceContextKey.Scheme.isEqualTo(Schemas.file), AutoSaveContext.notEqualsTo('afterDelay') && AutoSaveContext.notEqualsTo(''), WorkbenchListDoubleSelection.toNegated()) }); const compareResourceCommand = { @@ -372,21 +372,21 @@ MenuRegistry.appendMenuItem(MenuId.ExplorerContext, { group: '3_compare', order: 20, command: compareResourceCommand, - when: ContextKeyExpr.and(ExplorerFolderContext.toNegated(), ResourceContextKey.IsFile, ResourceSelectedForCompareContext, WorkbenchListDoubleSelection.toNegated()) + when: ContextKeyExpr.and(ExplorerFolderContext.toNegated(), ResourceContextKey.HasResource, ResourceSelectedForCompareContext, WorkbenchListDoubleSelection.toNegated()) }); MenuRegistry.appendMenuItem(MenuId.ExplorerContext, { group: '3_compare', order: 30, command: selectForCompareCommand, - when: ContextKeyExpr.and(ExplorerFolderContext.toNegated(), ResourceContextKey.IsFile, WorkbenchListDoubleSelection.toNegated()) + when: ContextKeyExpr.and(ExplorerFolderContext.toNegated(), ResourceContextKey.HasResource, WorkbenchListDoubleSelection.toNegated()) }); MenuRegistry.appendMenuItem(MenuId.ExplorerContext, { group: '3_compare', order: 30, command: compareSelectedCommand, - when: ContextKeyExpr.and(ExplorerFolderContext.toNegated(), ResourceContextKey.IsFile, WorkbenchListDoubleSelection) + when: ContextKeyExpr.and(ExplorerFolderContext.toNegated(), ResourceContextKey.HasResource, WorkbenchListDoubleSelection) }); MenuRegistry.appendMenuItem(MenuId.ExplorerContext, { @@ -415,7 +415,7 @@ MenuRegistry.appendMenuItem(MenuId.ExplorerContext, { order: 30, command: copyPathCommand, alt: copyRelativePathCommand, - when: ResourceContextKey.IsFile + when: ResourceContextKey.HasResource }); MenuRegistry.appendMenuItem(MenuId.ExplorerContext, { From 435955d6ccb77c81f5f6e12b9e86d1850c8a613f Mon Sep 17 00:00:00 2001 From: Alex Dima Date: Thu, 2 Aug 2018 16:18:56 +0200 Subject: [PATCH 0424/1276] Register previous ids for compatibility (#53497) --- .../contrib/wordPartOperations/wordPartOperations.ts | 6 ++++++ src/vs/platform/commands/common/commands.ts | 7 +++++++ 2 files changed, 13 insertions(+) diff --git a/src/vs/editor/contrib/wordPartOperations/wordPartOperations.ts b/src/vs/editor/contrib/wordPartOperations/wordPartOperations.ts index 50e8f13733c..5c7dc9166f6 100644 --- a/src/vs/editor/contrib/wordPartOperations/wordPartOperations.ts +++ b/src/vs/editor/contrib/wordPartOperations/wordPartOperations.ts @@ -16,6 +16,7 @@ import { WordCharacterClassifier } from 'vs/editor/common/controller/wordCharact import { DeleteWordCommand, MoveWordCommand } from '../wordOperations/wordOperations'; import { Position } from 'vs/editor/common/core/position'; import { KeybindingWeight } from 'vs/platform/keybinding/common/keybindingsRegistry'; +import { CommandsRegistry } from 'vs/platform/commands/common/commands'; export class DeleteWordPartLeft extends DeleteWordCommand { constructor() { @@ -90,6 +91,9 @@ export class CursorWordPartLeft extends WordPartLeftCommand { }); } } +// Register previous id for compatibility purposes +CommandsRegistry.registerCommandAlias('cursorWordPartStartLeft', 'cursorWordPartLeft'); + export class CursorWordPartLeftSelect extends WordPartLeftCommand { constructor() { super({ @@ -106,6 +110,8 @@ export class CursorWordPartLeftSelect extends WordPartLeftCommand { }); } } +// Register previous id for compatibility purposes +CommandsRegistry.registerCommandAlias('cursorWordPartStartLeftSelect', 'cursorWordPartLeftSelect'); export class WordPartRightCommand extends MoveWordCommand { protected _move(wordSeparators: WordCharacterClassifier, model: ITextModel, position: Position, wordNavigationType: WordNavigationType): Position { diff --git a/src/vs/platform/commands/common/commands.ts b/src/vs/platform/commands/common/commands.ts index b5f23e0b9f3..b912a022dfc 100644 --- a/src/vs/platform/commands/common/commands.ts +++ b/src/vs/platform/commands/common/commands.ts @@ -46,6 +46,7 @@ export interface ICommandHandlerDescription { export interface ICommandRegistry { registerCommand(id: string, command: ICommandHandler): IDisposable; registerCommand(command: ICommand): IDisposable; + registerCommandAlias(oldId: string, newId: string): IDisposable; getCommand(id: string): ICommand; getCommands(): ICommandsMap; } @@ -99,6 +100,12 @@ export const CommandsRegistry: ICommandRegistry = new class implements ICommandR }); } + registerCommandAlias(oldId: string, newId: string): IDisposable { + return CommandsRegistry.registerCommand(oldId, (accessor, ...args) => { + accessor.get(ICommandService).executeCommand(newId, ...args); + }); + } + getCommand(id: string): ICommand { const list = this._commands.get(id); if (!list || list.isEmpty()) { From 7a9c8de86eed788206442aa6ac68b36ad4ea4780 Mon Sep 17 00:00:00 2001 From: isidor Date: Thu, 2 Aug 2018 16:20:21 +0200 Subject: [PATCH 0425/1276] more tuning for #48275 --- .../files/electron-browser/fileActions.contribution.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/vs/workbench/parts/files/electron-browser/fileActions.contribution.ts b/src/vs/workbench/parts/files/electron-browser/fileActions.contribution.ts index 8b9e89c8e5f..aea7d036304 100644 --- a/src/vs/workbench/parts/files/electron-browser/fileActions.contribution.ts +++ b/src/vs/workbench/parts/files/electron-browser/fileActions.contribution.ts @@ -216,7 +216,7 @@ MenuRegistry.appendMenuItem(MenuId.OpenEditorsContext, { title: SAVE_FILE_LABEL, precondition: DirtyEditorContext }, - when: ContextKeyExpr.and(ResourceContextKey.Scheme.isEqualTo(Schemas.file), AutoSaveContext.notEqualsTo('afterDelay') && AutoSaveContext.notEqualsTo('')) + when: ContextKeyExpr.and(ResourceContextKey.HasResource, AutoSaveContext.notEqualsTo('afterDelay') && AutoSaveContext.notEqualsTo('')) }); MenuRegistry.appendMenuItem(MenuId.OpenEditorsContext, { @@ -227,7 +227,7 @@ MenuRegistry.appendMenuItem(MenuId.OpenEditorsContext, { title: nls.localize('revert', "Revert File"), precondition: DirtyEditorContext }, - when: ContextKeyExpr.and(ResourceContextKey.Scheme.isEqualTo(Schemas.file), AutoSaveContext.notEqualsTo('afterDelay') && AutoSaveContext.notEqualsTo('')) + when: ContextKeyExpr.and(ResourceContextKey.HasResource, AutoSaveContext.notEqualsTo('afterDelay') && AutoSaveContext.notEqualsTo('')) }); MenuRegistry.appendMenuItem(MenuId.OpenEditorsContext, { @@ -256,7 +256,7 @@ MenuRegistry.appendMenuItem(MenuId.OpenEditorsContext, { title: nls.localize('compareWithSaved', "Compare with Saved"), precondition: DirtyEditorContext }, - when: ContextKeyExpr.and(ResourceContextKey.Scheme.isEqualTo(Schemas.file), AutoSaveContext.notEqualsTo('afterDelay') && AutoSaveContext.notEqualsTo(''), WorkbenchListDoubleSelection.toNegated()) + when: ContextKeyExpr.and(ResourceContextKey.HasResource, AutoSaveContext.notEqualsTo('afterDelay') && AutoSaveContext.notEqualsTo(''), WorkbenchListDoubleSelection.toNegated()) }); const compareResourceCommand = { From 2219d239b5dd5c46ba26245f937fb4bb2af595df Mon Sep 17 00:00:00 2001 From: isidor Date: Thu, 2 Aug 2018 17:08:55 +0200 Subject: [PATCH 0426/1276] no need to always re-read "files explorer" fixes #52003 --- .../parts/files/electron-browser/views/explorerViewer.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vs/workbench/parts/files/electron-browser/views/explorerViewer.ts b/src/vs/workbench/parts/files/electron-browser/views/explorerViewer.ts index a59212c44df..ffaeaf38297 100644 --- a/src/vs/workbench/parts/files/electron-browser/views/explorerViewer.ts +++ b/src/vs/workbench/parts/files/electron-browser/views/explorerViewer.ts @@ -390,7 +390,7 @@ export class FileRenderer implements IRenderer { export class FileAccessibilityProvider implements IAccessibilityProvider { public getAriaLabel(tree: ITree, stat: ExplorerItem): string { - return nls.localize('filesExplorerViewerAriaLabel', "{0}, Files Explorer", stat.name); + return stat.name; } } From 45d29b779d1e85795833ff3457f07bcf3bfcbf29 Mon Sep 17 00:00:00 2001 From: isidor Date: Thu, 2 Aug 2018 17:23:34 +0200 Subject: [PATCH 0427/1276] read out active composites properly fixes #51967 --- .../workbench/browser/parts/compositebar/compositeBarActions.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/vs/workbench/browser/parts/compositebar/compositeBarActions.ts b/src/vs/workbench/browser/parts/compositebar/compositeBarActions.ts index 6d6647e8c5a..eed75df278b 100644 --- a/src/vs/workbench/browser/parts/compositebar/compositeBarActions.ts +++ b/src/vs/workbench/browser/parts/compositebar/compositeBarActions.ts @@ -604,8 +604,10 @@ export class CompositeActionItem extends ActivityActionItem { protected _updateChecked(): void { if (this.getAction().checked) { this.$container.addClass('checked'); + this.$container.attr('aria-label', nls.localize('compositeActive', "{0} active", this.$container.getHTMLElement().title)); } else { this.$container.removeClass('checked'); + this.$container.attr('aria-label', this.$container.getHTMLElement().title); } } From 8578ed1e6a8dee4713fb53ace44058fa5dfa2333 Mon Sep 17 00:00:00 2001 From: Miguel Solorio Date: Thu, 2 Aug 2018 08:32:22 -0700 Subject: [PATCH 0428/1276] Update link colors for hc theme to meet color contrast ratio, fixes #55651 Also updated link color for `textLinkActiveForeground` to be the same as `textLinkForeground` as it wasn't properly updated --- src/vs/platform/theme/common/colorRegistry.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/vs/platform/theme/common/colorRegistry.ts b/src/vs/platform/theme/common/colorRegistry.ts index d2f8fd97639..f4404ffd508 100644 --- a/src/vs/platform/theme/common/colorRegistry.ts +++ b/src/vs/platform/theme/common/colorRegistry.ts @@ -163,8 +163,8 @@ export const selectionBackground = registerColor('selection.background', { light // ------ text colors export const textSeparatorForeground = registerColor('textSeparator.foreground', { light: '#0000002e', dark: '#ffffff2e', hc: Color.black }, nls.localize('textSeparatorForeground', "Color for text separators.")); -export const textLinkForeground = registerColor('textLink.foreground', { light: '#006AB1', dark: '#3794FF', hc: '#006AB1' }, nls.localize('textLinkForeground', "Foreground color for links in text.")); -export const textLinkActiveForeground = registerColor('textLink.activeForeground', { light: '#007acc', dark: '#3794FF', hc: '#007acc' }, nls.localize('textLinkActiveForeground', "Foreground color for links in text when clicked on and on mouse hover.")); +export const textLinkForeground = registerColor('textLink.foreground', { light: '#006AB1', dark: '#3794FF', hc: '#3794FF' }, nls.localize('textLinkForeground', "Foreground color for links in text.")); +export const textLinkActiveForeground = registerColor('textLink.activeForeground', { light: '#006AB1', dark: '#3794FF', hc: '#3794FF' }, nls.localize('textLinkActiveForeground', "Foreground color for links in text when clicked on and on mouse hover.")); export const textPreformatForeground = registerColor('textPreformat.foreground', { light: '#A31515', dark: '#D7BA7D', hc: '#D7BA7D' }, nls.localize('textPreformatForeground', "Foreground color for preformatted text segments.")); export const textBlockQuoteBackground = registerColor('textBlockQuote.background', { light: '#7f7f7f1a', dark: '#7f7f7f1a', hc: null }, nls.localize('textBlockQuoteBackground', "Background color for block quotes in text.")); export const textBlockQuoteBorder = registerColor('textBlockQuote.border', { light: '#007acc80', dark: '#007acc80', hc: Color.white }, nls.localize('textBlockQuoteBorder', "Border color for block quotes in text.")); From 47cf06001c7dcc9a8265220d84c86abdd9a24441 Mon Sep 17 00:00:00 2001 From: Andre Weinand Date: Thu, 2 Aug 2018 17:26:09 +0200 Subject: [PATCH 0429/1276] detect 'winpty-agent.exe'; fixes #55672 --- extensions/debug-auto-launch/src/nodeProcessTree.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/extensions/debug-auto-launch/src/nodeProcessTree.ts b/extensions/debug-auto-launch/src/nodeProcessTree.ts index 16bc55476e1..d803ddd1bcd 100644 --- a/extensions/debug-auto-launch/src/nodeProcessTree.ts +++ b/extensions/debug-auto-launch/src/nodeProcessTree.ts @@ -97,7 +97,7 @@ function findChildProcesses(rootPid: number, inTerminal: boolean, cb: (pid: numb function walker(node: ProcessTreeNode, terminal: boolean, renderer: number) { - if (node.args.indexOf('--type=terminal') >= 0 && (renderer === 0 || node.ppid === renderer)) { + if ((node.args.indexOf('--type=terminal') >= 0 || node.command.indexOf('\\winpty-agent.exe') >= 0) && (renderer === 0 || node.ppid === renderer)) { terminal = true; } From a3837f57a209d2e81808ee836b50235140fe2b39 Mon Sep 17 00:00:00 2001 From: Andre Weinand Date: Thu, 2 Aug 2018 17:50:16 +0200 Subject: [PATCH 0430/1276] node-debug@1.26.7 --- build/builtInExtensions.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build/builtInExtensions.json b/build/builtInExtensions.json index a017fbcce91..663f81987cc 100644 --- a/build/builtInExtensions.json +++ b/build/builtInExtensions.json @@ -1,7 +1,7 @@ [ { "name": "ms-vscode.node-debug", - "version": "1.26.6", + "version": "1.26.7", "repo": "https://github.com/Microsoft/vscode-node-debug" }, { From c9cfac693d78e61afdda91e13b9dcf9c8053cfd2 Mon Sep 17 00:00:00 2001 From: Jackson Kearl Date: Thu, 2 Aug 2018 10:11:33 -0700 Subject: [PATCH 0431/1276] reset counter on new label --- src/vs/base/browser/ui/aria/aria.ts | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/src/vs/base/browser/ui/aria/aria.ts b/src/vs/base/browser/ui/aria/aria.ts index c54d89b0aba..61c7dfd348d 100644 --- a/src/vs/base/browser/ui/aria/aria.ts +++ b/src/vs/base/browser/ui/aria/aria.ts @@ -53,14 +53,19 @@ export function status(msg: string): void { let repeatedTimes = 0; let prevText: string | undefined = undefined; function insertMessage(target: HTMLElement, msg: string): void { - if (!ariaContainer) { // console.warn('ARIA support needs a container. Call setARIAContainer() first.'); return; } - if (prevText === msg) { repeatedTimes++; } - prevText = msg; + if (prevText === msg) { + repeatedTimes++; + } + else { + prevText = msg; + repeatedTimes = 0; + } + switch (repeatedTimes) { case 0: break; From a740a21fae9670d41596b133686d915dfb2d28e7 Mon Sep 17 00:00:00 2001 From: Rob Lourens Date: Thu, 2 Aug 2018 09:14:53 -0700 Subject: [PATCH 0432/1276] Settings editor - fix multiple setting links in one description --- src/vs/workbench/parts/preferences/browser/settingsTree.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vs/workbench/parts/preferences/browser/settingsTree.ts b/src/vs/workbench/parts/preferences/browser/settingsTree.ts index 15fbab7e679..ff7422b15b4 100644 --- a/src/vs/workbench/parts/preferences/browser/settingsTree.ts +++ b/src/vs/workbench/parts/preferences/browser/settingsTree.ts @@ -1236,7 +1236,7 @@ function cleanRenderedMarkdown(element: Node): void { } function fixSettingLinks(text: string): string { - return text.replace(/`#(.*)#`/g, (match, settingName) => `[\`${settingName}\`](#${settingName})`); + return text.replace(/`#([^#]*)#`/g, (match, settingName) => `[\`${settingName}\`](#${settingName})`); } function getDisplayEnumOptions(setting: ISetting): string[] { From f5bc577d5fa5c0188c8deed10dca4e57d07af239 Mon Sep 17 00:00:00 2001 From: Rob Lourens Date: Thu, 2 Aug 2018 09:15:30 -0700 Subject: [PATCH 0433/1276] Settings editor - color code blocks in setting descriptions, fix #55532 --- .../workbench/parts/preferences/browser/settingsWidgets.ts | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/vs/workbench/parts/preferences/browser/settingsWidgets.ts b/src/vs/workbench/parts/preferences/browser/settingsWidgets.ts index 595f1a90e36..ee1a2e61104 100644 --- a/src/vs/workbench/parts/preferences/browser/settingsWidgets.ts +++ b/src/vs/workbench/parts/preferences/browser/settingsWidgets.ts @@ -15,7 +15,7 @@ import { Disposable, dispose, IDisposable } from 'vs/base/common/lifecycle'; import 'vs/css!./media/settingsWidgets'; import { localize } from 'vs/nls'; import { IContextViewService } from 'vs/platform/contextview/browser/contextView'; -import { foreground, inputBackground, inputBorder, inputForeground, listHoverBackground, registerColor, selectBackground, selectBorder, selectForeground, textLinkForeground, listHoverForeground, listActiveSelectionBackground, listActiveSelectionForeground, listInactiveSelectionBackground, listInactiveSelectionForeground } from 'vs/platform/theme/common/colorRegistry'; +import { foreground, inputBackground, inputBorder, inputForeground, listActiveSelectionBackground, listActiveSelectionForeground, listHoverBackground, listHoverForeground, listInactiveSelectionBackground, listInactiveSelectionForeground, registerColor, selectBackground, selectBorder, selectForeground, textLinkForeground, textPreformatForeground } from 'vs/platform/theme/common/colorRegistry'; import { attachButtonStyler, attachInputBoxStyler } from 'vs/platform/theme/common/styler'; import { ICssStyleCollector, ITheme, IThemeService, registerThemingParticipant } from 'vs/platform/theme/common/themeService'; @@ -106,6 +106,11 @@ registerThemingParticipant((theme: ITheme, collector: ICssStyleCollector) => { if (listSelectForegroundColor) { collector.addRule(`.settings-editor > .settings-body > .settings-tree-container .setting-item.setting-item-exclude .setting-exclude-row.selected { color: ${listSelectForegroundColor}; }`); } + + const codeTextForegroundColor = theme.getColor(textPreformatForeground); + if (codeTextForegroundColor) { + collector.addRule(`.settings-editor > .settings-body > .settings-tree-container .setting-item .setting-item-description-markdown code { color: ${codeTextForegroundColor} }`); + } }); export class ExcludeSettingListModel { From be6acd94b2c20e9eb9bf0ca098001b0a596a5032 Mon Sep 17 00:00:00 2001 From: Rob Lourens Date: Thu, 2 Aug 2018 10:06:59 -0700 Subject: [PATCH 0434/1276] Settings editor - hover color in TOC --- src/vs/workbench/parts/preferences/browser/tocTree.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/vs/workbench/parts/preferences/browser/tocTree.ts b/src/vs/workbench/parts/preferences/browser/tocTree.ts index 87c7a723981..f6d79fd69eb 100644 --- a/src/vs/workbench/parts/preferences/browser/tocTree.ts +++ b/src/vs/workbench/parts/preferences/browser/tocTree.ts @@ -11,7 +11,7 @@ import { IConfigurationService } from 'vs/platform/configuration/common/configur import { IContextKeyService } from 'vs/platform/contextkey/common/contextkey'; import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; import { IListService, WorkbenchTree, WorkbenchTreeController } from 'vs/platform/list/browser/listService'; -import { editorBackground, focusBorder, foreground } from 'vs/platform/theme/common/colorRegistry'; +import { editorBackground, focusBorder } from 'vs/platform/theme/common/colorRegistry'; import { attachStyler } from 'vs/platform/theme/common/styler'; import { ICssStyleCollector, ITheme, IThemeService, registerThemingParticipant } from 'vs/platform/theme/common/themeService'; import { ISettingsEditorViewState, SearchResultModel, SettingsAccessibilityProvider, SettingsTreeElement, SettingsTreeFilter, SettingsTreeGroupElement, SettingsTreeSettingElement } from 'vs/workbench/parts/preferences/browser/settingsTree'; @@ -206,7 +206,7 @@ export class TOCTree extends WorkbenchTree { listFocusAndSelectionForeground: settingsHeaderForeground, listFocusBackground: editorBackground, listFocusForeground: settingsHeaderForeground, - listHoverForeground: foreground, + listHoverForeground: settingsHeaderForeground, listHoverBackground: editorBackground, listInactiveSelectionBackground: editorBackground, listInactiveSelectionForeground: settingsHeaderForeground, From c793515fbfbe4e7564f1b20fef7648c2704afb94 Mon Sep 17 00:00:00 2001 From: Rob Lourens Date: Thu, 2 Aug 2018 10:07:12 -0700 Subject: [PATCH 0435/1276] Settings editor - fix navigation NPE --- src/vs/workbench/parts/preferences/browser/settingsTree.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/vs/workbench/parts/preferences/browser/settingsTree.ts b/src/vs/workbench/parts/preferences/browser/settingsTree.ts index ff7422b15b4..010da15571b 100644 --- a/src/vs/workbench/parts/preferences/browser/settingsTree.ts +++ b/src/vs/workbench/parts/preferences/browser/settingsTree.ts @@ -1557,7 +1557,9 @@ export class SettingsTree extends NonExpandableTree { current = nav.next(); } while (current instanceof SettingsTreeGroupElement); - this.setFocus(current, eventPayload); + if (current) { + this.setFocus(current, eventPayload); + } } public focusPrevious(count?: number, eventPayload?: any): void { From 2e02d7c01969031fd8e4aa01acfd95d00eba496f Mon Sep 17 00:00:00 2001 From: Rob Lourens Date: Thu, 2 Aug 2018 10:11:55 -0700 Subject: [PATCH 0436/1276] Settings editor - fix text control width --- .../parts/preferences/browser/media/settingsEditor2.css | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vs/workbench/parts/preferences/browser/media/settingsEditor2.css b/src/vs/workbench/parts/preferences/browser/media/settingsEditor2.css index 67353f45bc3..75649af6ef1 100644 --- a/src/vs/workbench/parts/preferences/browser/media/settingsEditor2.css +++ b/src/vs/workbench/parts/preferences/browser/media/settingsEditor2.css @@ -351,7 +351,7 @@ min-width: 200px; } -.settings-editor > .settings-body > .settings-tree-container .setting-item.setting-item-text { +.settings-editor > .settings-body > .settings-tree-container .setting-item.setting-item-text .setting-item-control { width: 500px; } From 4d68abcedddb784f726ad57238c8f49d9ee82ded Mon Sep 17 00:00:00 2001 From: Rob Lourens Date: Thu, 2 Aug 2018 10:15:54 -0700 Subject: [PATCH 0437/1276] Settings editor - maybe fix #55684 --- src/vs/workbench/parts/preferences/browser/settingsTree.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vs/workbench/parts/preferences/browser/settingsTree.ts b/src/vs/workbench/parts/preferences/browser/settingsTree.ts index 010da15571b..2037df5ebef 100644 --- a/src/vs/workbench/parts/preferences/browser/settingsTree.ts +++ b/src/vs/workbench/parts/preferences/browser/settingsTree.ts @@ -393,7 +393,7 @@ export class SettingsDataSource implements IDataSource { } getParent(tree: ITree, element: SettingsTreeElement): TPromise { - return TPromise.wrap(element.parent); + return TPromise.wrap(element && element.parent); } shouldAutoexpand(): boolean { From dfe88124bf0d79cf1b442d4fa01bdb0534ebfa9d Mon Sep 17 00:00:00 2001 From: Jackson Kearl Date: Thu, 2 Aug 2018 10:22:27 -0700 Subject: [PATCH 0438/1276] Fix bug causing cursor to not move on paste --- .../parts/extensions/electron-browser/extensionsViewlet.ts | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/vs/workbench/parts/extensions/electron-browser/extensionsViewlet.ts b/src/vs/workbench/parts/extensions/electron-browser/extensionsViewlet.ts index f9a6fdd2949..2f8cf927022 100644 --- a/src/vs/workbench/parts/extensions/electron-browser/extensionsViewlet.ts +++ b/src/vs/workbench/parts/extensions/electron-browser/extensionsViewlet.ts @@ -362,9 +362,12 @@ export class ExtensionsViewlet extends ViewContainerViewlet implements IExtensio this.searchBox.setModel(this.modelService.createModel('', null, uri.parse('extensions:searchinput'), true)); this.disposables.push(this.searchBox.onDidPaste(() => { - this.searchBox.setValue(this.searchBox.getValue().replace(/\s+/g, ' ')); + let trimmed = this.searchBox.getValue().replace(/\s+/g, ' '); + this.searchBox.setValue(trimmed); this.searchBox.setScrollTop(0); + this.searchBox.setPosition(new Position(1, trimmed.length + 1)); })); + this.disposables.push(this.searchBox.onDidFocusEditorText(() => addClass(this.monacoStyleContainer, 'synthetic-focus'))); this.disposables.push(this.searchBox.onDidBlurEditorText(() => removeClass(this.monacoStyleContainer, 'synthetic-focus'))); From 3a98b554b6ff6246ea65f86aded2105ea86fe6bf Mon Sep 17 00:00:00 2001 From: SteVen Batten Date: Thu, 2 Aug 2018 10:28:34 -0700 Subject: [PATCH 0439/1276] fixes #53582 --- .../electron-browser/main.contribution.ts | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/src/vs/workbench/electron-browser/main.contribution.ts b/src/vs/workbench/electron-browser/main.contribution.ts index 9b09e526c44..d6eb49d077a 100644 --- a/src/vs/workbench/electron-browser/main.contribution.ts +++ b/src/vs/workbench/electron-browser/main.contribution.ts @@ -249,9 +249,21 @@ MenuRegistry.appendMenuItem(MenuId.MenubarFileMenu, { group: '6_close', command: { id: CloseWorkspaceAction.ID, - title: nls.localize({ key: 'miCloseFolder', comment: ['&& denotes a mnemonic'] }, "Close &&Folder") + title: nls.localize({ key: 'miCloseFolder', comment: ['&& denotes a mnemonic'] }, "Close &&Folder"), + precondition: new RawContextKey('workspaceFolderCount', 0).notEqualsTo('0') }, - order: 3 + order: 3, + when: new RawContextKey('workbenchState', '').notEqualsTo('workspace') +}); + +MenuRegistry.appendMenuItem(MenuId.MenubarFileMenu, { + group: '6_close', + command: { + id: CloseWorkspaceAction.ID, + title: nls.localize({ key: 'miCloseWorkspace', comment: ['&& denotes a mnemonic'] }, "Close &&Workspace") + }, + order: 3, + when: new RawContextKey('workbenchState', '').isEqualTo('workspace') }); MenuRegistry.appendMenuItem(MenuId.MenubarFileMenu, { From 67b2ccbd4af62594daa7850d10165dbde9fd24d1 Mon Sep 17 00:00:00 2001 From: Jackson Kearl Date: Thu, 2 Aug 2018 10:45:14 -0700 Subject: [PATCH 0440/1276] Use ctrlCmd instead of ctrl for go down from search box --- .../parts/extensions/electron-browser/extensionsViewlet.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/vs/workbench/parts/extensions/electron-browser/extensionsViewlet.ts b/src/vs/workbench/parts/extensions/electron-browser/extensionsViewlet.ts index f9a6fdd2949..35a3931a1e1 100644 --- a/src/vs/workbench/parts/extensions/electron-browser/extensionsViewlet.ts +++ b/src/vs/workbench/parts/extensions/electron-browser/extensionsViewlet.ts @@ -70,6 +70,7 @@ import { SuggestController } from 'vs/editor/contrib/suggest/suggestController'; import { ContextMenuController } from 'vs/editor/contrib/contextmenu/contextmenu'; import { MenuPreventer } from 'vs/workbench/parts/codeEditor/electron-browser/menuPreventer'; import { SnippetController2 } from 'vs/editor/contrib/snippet/snippetController2'; +import { isMacintosh } from 'vs/base/common/platform'; interface SearchInputEvent extends Event { target: HTMLInputElement; @@ -370,7 +371,7 @@ export class ExtensionsViewlet extends ViewContainerViewlet implements IExtensio const onKeyDownMonaco = chain(this.searchBox.onKeyDown); onKeyDownMonaco.filter(e => e.keyCode === KeyCode.Enter).on(e => e.preventDefault(), this, this.disposables); - onKeyDownMonaco.filter(e => e.keyCode === KeyCode.DownArrow && e.ctrlKey).on(() => this.focusListView(), this, this.disposables); + onKeyDownMonaco.filter(e => e.keyCode === KeyCode.DownArrow && (isMacintosh ? e.metaKey : e.ctrlKey)).on(() => this.focusListView(), this, this.disposables); const searchChangeEvent = new Emitter(); this.onSearchChange = searchChangeEvent.event; From 02822bf5c356612dc41ddbb3daf9e32ac7440f31 Mon Sep 17 00:00:00 2001 From: SteVen Batten Date: Thu, 2 Aug 2018 11:03:25 -0700 Subject: [PATCH 0441/1276] fixes #55264 --- src/vs/code/electron-main/menubar.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/vs/code/electron-main/menubar.ts b/src/vs/code/electron-main/menubar.ts index 26f371881fe..9ba8d96ee24 100644 --- a/src/vs/code/electron-main/menubar.ts +++ b/src/vs/code/electron-main/menubar.ts @@ -381,7 +381,9 @@ export class Menubar { case 'File': case 'Window': case 'Help': - return isMacintosh && (this.windowsMainService.getWindowCount() === 0 || !!this.menubarMenus[menuId]); + if (isMacintosh) { + return this.windowsMainService.getWindowCount() === 0 || !!this.menubarMenus[menuId]; + } default: return this.windowsMainService.getWindowCount() > 0 && !!this.menubarMenus[menuId]; } From eb720dced98a709fc163ed3cdaa98be252dbda8f Mon Sep 17 00:00:00 2001 From: SteVen Batten Date: Thu, 2 Aug 2018 11:20:59 -0700 Subject: [PATCH 0442/1276] fixes #55456 --- src/vs/workbench/electron-browser/workbench.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/vs/workbench/electron-browser/workbench.ts b/src/vs/workbench/electron-browser/workbench.ts index 2ae71ce73f3..defea5dd0cc 100644 --- a/src/vs/workbench/electron-browser/workbench.ts +++ b/src/vs/workbench/electron-browser/workbench.ts @@ -300,6 +300,8 @@ export class Workbench extends Disposable implements IPartService { 'class': `monaco-workbench ${isWindows ? 'windows' : isLinux ? 'linux' : 'mac'}`, id: Identifiers.WORKBENCH_CONTAINER }); + + this.workbench.on(DOM.EventType.SCROLL, e => { this.workbench.getHTMLElement().scrollTop = 0; }); // Prevent workbench from scrolling #55456 } private createGlobalActions(): void { From b88f16c1775f894e8c21b20e48738466accc0981 Mon Sep 17 00:00:00 2001 From: Jackson Kearl Date: Thu, 2 Aug 2018 11:22:57 -0700 Subject: [PATCH 0443/1276] filter for spcaes before triggering search (#55611) --- .../parts/extensions/electron-browser/extensionsViewlet.ts | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/vs/workbench/parts/extensions/electron-browser/extensionsViewlet.ts b/src/vs/workbench/parts/extensions/electron-browser/extensionsViewlet.ts index 8aa387f23f7..334c02d10d7 100644 --- a/src/vs/workbench/parts/extensions/electron-browser/extensionsViewlet.ts +++ b/src/vs/workbench/parts/extensions/electron-browser/extensionsViewlet.ts @@ -379,11 +379,14 @@ export class ExtensionsViewlet extends ViewContainerViewlet implements IExtensio const searchChangeEvent = new Emitter(); this.onSearchChange = searchChangeEvent.event; + let existingContent = this.searchBox.getValue().trim(); this.disposables.push(this.searchBox.getModel().onDidChangeContent(() => { + this.placeholderText.style.visibility = this.searchBox.getValue() ? 'hidden' : 'visible'; + let content = this.searchBox.getValue().trim(); + if (existingContent === content) { return; } this.triggerSearch(); - const content = this.searchBox.getValue(); searchChangeEvent.fire(content); - this.placeholderText.style.visibility = content ? 'hidden' : 'visible'; + existingContent = content; })); return super.create(this.extensionsBox) From 3a5b1263a5161bc4fec8606ac743c30d051c69bf Mon Sep 17 00:00:00 2001 From: Rob Lourens Date: Thu, 2 Aug 2018 11:41:30 -0700 Subject: [PATCH 0444/1276] Fix #55698 - don't lose filtered TOC counts when refreshing TOC --- src/vs/workbench/parts/preferences/browser/settingsEditor2.ts | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/vs/workbench/parts/preferences/browser/settingsEditor2.ts b/src/vs/workbench/parts/preferences/browser/settingsEditor2.ts index f9738e7c3f6..bba9169303c 100644 --- a/src/vs/workbench/parts/preferences/browser/settingsEditor2.ts +++ b/src/vs/workbench/parts/preferences/browser/settingsEditor2.ts @@ -625,6 +625,9 @@ export class SettingsEditor2 extends BaseEditor { } }) .then(() => { + // TODO@roblou - hack + this.tocTreeModel.update(); + return this.tocTree.refresh(); }); } From 1ce69ed492b69a03b3e84cae6d39ffcf7680830b Mon Sep 17 00:00:00 2001 From: SteVen Batten Date: Thu, 2 Aug 2018 11:48:02 -0700 Subject: [PATCH 0445/1276] fixes #55421 --- .../workbench/browser/parts/titlebar/titlebarPart.ts | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/vs/workbench/browser/parts/titlebar/titlebarPart.ts b/src/vs/workbench/browser/parts/titlebar/titlebarPart.ts index 4fae75a06ea..6b2d003499b 100644 --- a/src/vs/workbench/browser/parts/titlebar/titlebarPart.ts +++ b/src/vs/workbench/browser/parts/titlebar/titlebarPart.ts @@ -295,11 +295,13 @@ export class TitlebarPart extends Part implements ITitleService { } // Maximize/Restore on doubleclick - this.title.on(EventType.DBLCLICK, (e) => { - EventHelper.stop(e); + if (isMacintosh) { + this.titleContainer.on(EventType.DBLCLICK, (e) => { + EventHelper.stop(e); - this.onTitleDoubleclick(); - }); + this.onTitleDoubleclick(); + }); + } // Context menu on title this.title.on([EventType.CONTEXT_MENU, EventType.MOUSE_DOWN], (e: MouseEvent) => { From 1dc0385e5d0e2fc5213871fefd617560d56fb34e Mon Sep 17 00:00:00 2001 From: isidor Date: Thu, 2 Aug 2018 21:26:22 +0200 Subject: [PATCH 0446/1276] fixes #28979 --- src/vs/workbench/parts/debug/electron-browser/debugService.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/vs/workbench/parts/debug/electron-browser/debugService.ts b/src/vs/workbench/parts/debug/electron-browser/debugService.ts index 0a16c3ba620..b8d45826a44 100644 --- a/src/vs/workbench/parts/debug/electron-browser/debugService.ts +++ b/src/vs/workbench/parts/debug/electron-browser/debugService.ts @@ -1105,7 +1105,8 @@ export class DebugService implements debug.IDebugService { const unresolvedConfiguration = (session).unresolvedConfiguration; if (session.raw.capabilities.supportsRestartRequest) { return this.runTask(session.getId(), session.raw.root, session.configuration.postDebugTask, session.configuration, unresolvedConfiguration, - () => session.raw.custom('restart', null)); + () => this.runTask(session.getId(), session.raw.root, session.configuration.preLaunchTask, session.configuration, unresolvedConfiguration, + () => session.raw.custom('restart', null))); } const focusedSession = this.viewModel.focusedSession; From b9885b9960169e746336e735bb302bb8db3a861b Mon Sep 17 00:00:00 2001 From: SteVen Batten Date: Thu, 2 Aug 2018 12:38:14 -0700 Subject: [PATCH 0447/1276] fixes #55576 --- src/vs/code/electron-main/menubar.ts | 10 ++++ .../browser/parts/menubar/menubarPart.ts | 50 ++++++++++++++++++- 2 files changed, 58 insertions(+), 2 deletions(-) diff --git a/src/vs/code/electron-main/menubar.ts b/src/vs/code/electron-main/menubar.ts index 9ba8d96ee24..469b2ab76ee 100644 --- a/src/vs/code/electron-main/menubar.ts +++ b/src/vs/code/electron-main/menubar.ts @@ -502,6 +502,8 @@ export class Menubar { } else if (isMenubarMenuItemAction(item)) { if (item.id === 'workbench.action.openRecent') { this.insertRecentMenuItems(menu); + } else if (item.id === 'workbench.action.showAboutDialog') { + this.insertCheckForUpdatesItems(menu); } // Store the keybinding @@ -523,6 +525,14 @@ export class Menubar { } } + private insertCheckForUpdatesItems(menu: Electron.Menu) { + const updateItems = this.getUpdateMenuItems(); + if (updateItems.length) { + updateItems.forEach(i => menu.append(i)); + menu.append(__separator__()); + } + } + private insertRecentMenuItems(menu: Electron.Menu) { const { workspaces, files } = this.historyMainService.getRecentlyOpened(); diff --git a/src/vs/workbench/browser/parts/menubar/menubarPart.ts b/src/vs/workbench/browser/parts/menubar/menubarPart.ts index 6a0811f61e1..8aa518dd81f 100644 --- a/src/vs/workbench/browser/parts/menubar/menubarPart.ts +++ b/src/vs/workbench/browser/parts/menubar/menubarPart.ts @@ -36,6 +36,7 @@ import { MENUBAR_SELECTION_FOREGROUND, MENUBAR_SELECTION_BACKGROUND, MENUBAR_SEL import URI from 'vs/base/common/uri'; import { IUriDisplayService } from 'vs/platform/uriDisplay/common/uriDisplay'; import { foreground } from 'vs/platform/theme/common/colorRegistry'; +import { IUpdateService, StateType } from 'vs/platform/update/common/update'; interface CustomMenu { title: string; @@ -123,7 +124,8 @@ export class MenubarPart extends Part { @IKeybindingService private keybindingService: IKeybindingService, @IConfigurationService private configurationService: IConfigurationService, @IEnvironmentService private environmentService: IEnvironmentService, - @IUriDisplayService private uriDisplayService: IUriDisplayService + @IUriDisplayService private uriDisplayService: IUriDisplayService, + @IUpdateService private updateService: IUpdateService ) { super(id, { hasTitle: false }, themeService); @@ -402,7 +404,7 @@ export class MenubarPart extends Part { this._register(this.configurationService.onDidChangeConfiguration(e => this.onConfigurationUpdated(e))); // Listen to update service - // this.updateService.onStateChange(() => this.setupMenubar()); + this.updateService.onStateChange(() => this.setupMenubar()); // Listen for context changes this._register(this.contextKeyService.onDidChangeContext(() => this.setupMenubar())); @@ -546,12 +548,56 @@ export class MenubarPart extends Part { return result; } + private getUpdateAction(): IAction | null { + const state = this.updateService.state; + + switch (state.type) { + case StateType.Uninitialized: + return null; + + case StateType.Idle: + const windowId = this.windowService.getCurrentWindowId(); + return new Action('update.check', nls.localize('checkForUpdates', "Check for Updates..."), undefined, true, () => + this.updateService.checkForUpdates({ windowId })); + + case StateType.CheckingForUpdates: + return new Action('update.checking', nls.localize('checkingForUpdates', "Checking For Updates..."), undefined, false); + + case StateType.AvailableForDownload: + return new Action('update.downloadNow', nls.localize('download now', "Download Now"), null, true, () => + this.updateService.downloadUpdate()); + + case StateType.Downloading: + return new Action('update.downloading', nls.localize('DownloadingUpdate', "Downloading Update..."), undefined, false); + + case StateType.Downloaded: + return new Action('update.install', nls.localize('installUpdate...', "Install Update..."), undefined, true, () => + this.updateService.applyUpdate()); + + case StateType.Updating: + return new Action('update.updating', nls.localize('installingUpdate', "Installing Update..."), undefined, false); + + case StateType.Ready: + return new Action('update.restart', nls.localize('restartToUpdate', "Restart to Update..."), undefined, true, () => + this.updateService.quitAndInstall()); + } + } + private insertActionsBefore(nextAction: IAction, target: IAction[]): void { switch (nextAction.id) { case 'workbench.action.openRecent': target.push(...this.getOpenRecentActions()); break; + case 'workbench.action.showAboutDialog': + const updateAction = this.getUpdateAction(); + if (updateAction) { + target.push(updateAction); + target.push(new Separator()); + } + + break; + default: break; } From 8ea66339e9f32110906ca495bd3de9370035e620 Mon Sep 17 00:00:00 2001 From: SteVen Batten Date: Thu, 2 Aug 2018 12:39:33 -0700 Subject: [PATCH 0448/1276] only add check for updates to windows/linux help --- src/vs/workbench/browser/parts/menubar/menubarPart.ts | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/vs/workbench/browser/parts/menubar/menubarPart.ts b/src/vs/workbench/browser/parts/menubar/menubarPart.ts index 8aa518dd81f..8655741599a 100644 --- a/src/vs/workbench/browser/parts/menubar/menubarPart.ts +++ b/src/vs/workbench/browser/parts/menubar/menubarPart.ts @@ -590,10 +590,12 @@ export class MenubarPart extends Part { break; case 'workbench.action.showAboutDialog': - const updateAction = this.getUpdateAction(); - if (updateAction) { - target.push(updateAction); - target.push(new Separator()); + if (!isMacintosh) { + const updateAction = this.getUpdateAction(); + if (updateAction) { + target.push(updateAction); + target.push(new Separator()); + } } break; From bbd1d81645deeb7085405910f8360932dd0c8b98 Mon Sep 17 00:00:00 2001 From: isidor Date: Thu, 2 Aug 2018 21:40:06 +0200 Subject: [PATCH 0449/1276] readonly files: append decoration to label fixes #53022 --- .../parts/files/common/editors/fileEditorInput.ts | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/vs/workbench/parts/files/common/editors/fileEditorInput.ts b/src/vs/workbench/parts/files/common/editors/fileEditorInput.ts index 1d0e661bdb6..7be9e9f8a2c 100644 --- a/src/vs/workbench/parts/files/common/editors/fileEditorInput.ts +++ b/src/vs/workbench/parts/files/common/editors/fileEditorInput.ts @@ -127,7 +127,7 @@ export class FileEditorInput extends EditorInput implements IFileEditorInput { this.name = resources.basenameOrAuthority(this.resource); } - return this.decorateOrphanedFiles(this.name); + return this.decorateLabel(this.name); } @memoize @@ -192,14 +192,17 @@ export class FileEditorInput extends EditorInput implements IFileEditorInput { break; } - return this.decorateOrphanedFiles(title); + return this.decorateLabel(title); } - private decorateOrphanedFiles(label: string): string { + private decorateLabel(label: string): string { const model = this.textFileService.models.get(this.resource); if (model && model.hasState(ModelState.ORPHAN)) { return localize('orphanedFile', "{0} (deleted from disk)", label); } + if (model && model.isReadonly) { + return localize('readonlyFile', "{0} (read-only)", label); + } return label; } From 8db5914823ab57b34d78f05491f978caecb5fac0 Mon Sep 17 00:00:00 2001 From: isidor Date: Thu, 2 Aug 2018 21:50:47 +0200 Subject: [PATCH 0450/1276] debug: do not show toolbar while initialising fixes #55026 --- src/vs/workbench/parts/debug/browser/debugActionsWidget.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vs/workbench/parts/debug/browser/debugActionsWidget.ts b/src/vs/workbench/parts/debug/browser/debugActionsWidget.ts index 545751a774d..19f6fb170af 100644 --- a/src/vs/workbench/parts/debug/browser/debugActionsWidget.ts +++ b/src/vs/workbench/parts/debug/browser/debugActionsWidget.ts @@ -94,7 +94,7 @@ export class DebugActionsWidget extends Themable implements IWorkbenchContributi this.updateScheduler = this._register(new RunOnceScheduler(() => { const state = this.debugService.state; const toolBarLocation = this.configurationService.getValue('debug').toolBarLocation; - if (state === State.Inactive || toolBarLocation === 'docked' || toolBarLocation === 'hidden') { + if (state === State.Inactive || state === State.Initializing || toolBarLocation === 'docked' || toolBarLocation === 'hidden') { return this.hide(); } From e4b7417e7118df59f715c40d55bf026c1f257a31 Mon Sep 17 00:00:00 2001 From: isidor Date: Thu, 2 Aug 2018 21:57:05 +0200 Subject: [PATCH 0451/1276] Opening launch.json should not activate debug extensions fixes #55029 --- .../debugConfigurationManager.ts | 58 +++++++++---------- 1 file changed, 28 insertions(+), 30 deletions(-) diff --git a/src/vs/workbench/parts/debug/electron-browser/debugConfigurationManager.ts b/src/vs/workbench/parts/debug/electron-browser/debugConfigurationManager.ts index 3daf1bd37ca..f40406a23ba 100644 --- a/src/vs/workbench/parts/debug/electron-browser/debugConfigurationManager.ts +++ b/src/vs/workbench/parts/debug/electron-browser/debugConfigurationManager.ts @@ -442,14 +442,12 @@ class Launch implements ILaunch { } public openConfigFile(sideBySide: boolean, type?: string): TPromise<{ editor: IEditor, created: boolean }> { - return this.configurationManager.activateDebuggers().then(() => { - const resource = this.uri; - let created = false; - - return this.fileService.resolveContent(resource).then(content => content.value, err => { - - // launch.json not found: create one by collecting launch configs from debugConfigProviders + const resource = this.uri; + let created = false; + return this.fileService.resolveContent(resource).then(content => content.value, err => { + // launch.json not found: create one by collecting launch configs from debugConfigProviders + return this.configurationManager.activateDebuggers().then(() => { return this.configurationManager.guessDebugger(type).then(adapter => { if (adapter) { return this.configurationManager.provideDebugConfigurations(this.workspace.uri, adapter.type).then(initialConfigs => { @@ -470,30 +468,30 @@ class Launch implements ILaunch { return content; }); }); - }).then(content => { - if (!content) { - return { editor: undefined, created: false }; - } - const index = content.indexOf(`"${this.configurationManager.selectedConfiguration.name}"`); - let startLineNumber = 1; - for (let i = 0; i < index; i++) { - if (content.charAt(i) === '\n') { - startLineNumber++; - } - } - const selection = startLineNumber > 1 ? { startLineNumber, startColumn: 4 } : undefined; - - return this.editorService.openEditor({ - resource: resource, - options: { - selection, - pinned: created, - revealIfVisible: true - }, - }, sideBySide ? SIDE_GROUP : ACTIVE_GROUP).then(editor => ({ editor, created })); - }, (error) => { - throw new Error(nls.localize('DebugConfig.failed', "Unable to create 'launch.json' file inside the '.vscode' folder ({0}).", error)); }); + }).then(content => { + if (!content) { + return { editor: undefined, created: false }; + } + const index = content.indexOf(`"${this.configurationManager.selectedConfiguration.name}"`); + let startLineNumber = 1; + for (let i = 0; i < index; i++) { + if (content.charAt(i) === '\n') { + startLineNumber++; + } + } + const selection = startLineNumber > 1 ? { startLineNumber, startColumn: 4 } : undefined; + + return this.editorService.openEditor({ + resource, + options: { + selection, + pinned: created, + revealIfVisible: true + }, + }, sideBySide ? SIDE_GROUP : ACTIVE_GROUP).then(editor => ({ editor, created })); + }, (error) => { + throw new Error(nls.localize('DebugConfig.failed', "Unable to create 'launch.json' file inside the '.vscode' folder ({0}).", error)); }); } } From a7792b88a336a3ba1e244988a8493295d75c4b71 Mon Sep 17 00:00:00 2001 From: SteVen Batten Date: Thu, 2 Aug 2018 13:32:39 -0700 Subject: [PATCH 0452/1276] fixes #55435 --- .../workbench/browser/parts/titlebar/media/titlebarpart.css | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/vs/workbench/browser/parts/titlebar/media/titlebarpart.css b/src/vs/workbench/browser/parts/titlebar/media/titlebarpart.css index 29bb9ba3abf..d46c6e868cc 100644 --- a/src/vs/workbench/browser/parts/titlebar/media/titlebarpart.css +++ b/src/vs/workbench/browser/parts/titlebar/media/titlebarpart.css @@ -51,6 +51,10 @@ overflow: visible; } +.monaco-workbench.linux > .part.titlebar > .window-title { + font-size: inherit; +} + .monaco-workbench.windows > .part.titlebar > .resizer, .monaco-workbench.linux > .part.titlebar > .resizer { -webkit-app-region: no-drag; From d91fdfd8d18fa443c8a25b3f70ef63d30c064584 Mon Sep 17 00:00:00 2001 From: SteVen Batten Date: Thu, 2 Aug 2018 13:50:12 -0700 Subject: [PATCH 0453/1276] fixes #55434 --- src/vs/workbench/browser/parts/menubar/media/menubarpart.css | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/vs/workbench/browser/parts/menubar/media/menubarpart.css b/src/vs/workbench/browser/parts/menubar/media/menubarpart.css index e40e091aae3..d117e3f9fc1 100644 --- a/src/vs/workbench/browser/parts/menubar/media/menubarpart.css +++ b/src/vs/workbench/browser/parts/menubar/media/menubarpart.css @@ -9,7 +9,8 @@ box-sizing: border-box; height: 30px; -webkit-app-region: no-drag; - overflow-x: hidden; + overflow: hidden; + flex-wrap: wrap; } .monaco-workbench.fullscreen .part.menubar { From 49bce6d9dc0ee54af91de28262a6f19bf958c8bb Mon Sep 17 00:00:00 2001 From: SteVen Batten Date: Thu, 2 Aug 2018 14:07:06 -0700 Subject: [PATCH 0454/1276] fixes #55439 --- src/vs/base/browser/ui/menu/menu.ts | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/src/vs/base/browser/ui/menu/menu.ts b/src/vs/base/browser/ui/menu/menu.ts index ef82b63ddad..3a79019d4f1 100644 --- a/src/vs/base/browser/ui/menu/menu.ts +++ b/src/vs/base/browser/ui/menu/menu.ts @@ -241,6 +241,8 @@ class MenuActionItem extends BaseActionItem { class SubmenuActionItem extends MenuActionItem { private mysubmenu: Menu; private submenuContainer: Builder; + private mouseOver: boolean; + private showScheduler: RunOnceScheduler; private hideScheduler: RunOnceScheduler; constructor( @@ -251,6 +253,13 @@ class SubmenuActionItem extends MenuActionItem { ) { super(action, action, { label: true, isMenu: true }); + this.showScheduler = new RunOnceScheduler(() => { + if (this.mouseOver) { + this.cleanupExistingSubmenu(false); + this.createSubmenu(false); + } + }, 250); + this.hideScheduler = new RunOnceScheduler(() => { if ((!isAncestor(document.activeElement, this.builder.getHTMLElement()) && this.parentData.submenu === this.mysubmenu)) { this.parentData.parent.focus(false); @@ -283,8 +292,15 @@ class SubmenuActionItem extends MenuActionItem { }); $(this.builder).on(EventType.MOUSE_OVER, (e) => { - this.cleanupExistingSubmenu(false); - this.createSubmenu(false); + if (!this.mouseOver) { + this.mouseOver = true; + + this.showScheduler.schedule(); + } + }); + + $(this.builder).on(EventType.MOUSE_LEAVE, (e) => { + this.mouseOver = false; }); $(this.builder).on(EventType.FOCUS_OUT, (e) => { From 69ccf52492491a8ee8c80b9695a68214e8075c7a Mon Sep 17 00:00:00 2001 From: SteVen Batten Date: Thu, 2 Aug 2018 14:29:48 -0700 Subject: [PATCH 0455/1276] trigger menu only on altkey up --- .../workbench/browser/parts/menubar/menubarPart.ts | 13 ++----------- 1 file changed, 2 insertions(+), 11 deletions(-) diff --git a/src/vs/workbench/browser/parts/menubar/menubarPart.ts b/src/vs/workbench/browser/parts/menubar/menubarPart.ts index 8655741599a..46774c5684f 100644 --- a/src/vs/workbench/browser/parts/menubar/menubarPart.ts +++ b/src/vs/workbench/browser/parts/menubar/menubarPart.ts @@ -316,6 +316,7 @@ export class MenubarPart extends Part { } private onDidChangeFullscreen(): void { + this.setUnfocusedState(); this.updateStyles(); } @@ -356,22 +357,12 @@ export class MenubarPart extends Part { private onModifierKeyToggled(modifierKeyStatus: IModifierKeyStatus): void { this._modifierKeyStatus = modifierKeyStatus; - const altKeyAlone = modifierKeyStatus.lastKeyPressed === 'alt' && !modifierKeyStatus.ctrlKey && !modifierKeyStatus.shiftKey; const allModifiersReleased = !modifierKeyStatus.altKey && !modifierKeyStatus.ctrlKey && !modifierKeyStatus.shiftKey; if (this.currentMenubarVisibility === 'hidden') { return; } - if (this.currentMenubarVisibility === 'toggle') { - if (altKeyAlone) { - if (!this.isVisible) { - this.focusState = MenubarState.VISIBLE; - } - } else if (!allModifiersReleased && !this.isFocused) { - this.focusState = MenubarState.HIDDEN; - } - } if (allModifiersReleased && modifierKeyStatus.lastKeyPressed === 'alt' && modifierKeyStatus.lastKeyReleased === 'alt') { if (!this.isFocused) { @@ -707,7 +698,7 @@ export class MenubarPart extends Part { this.customMenus[menuIndex].buttonElement.on(EventType.CLICK, (e) => { // This should only happen for mnemonics and we shouldn't trigger them - if (!this.isVisible) { + if (this.currentMenubarVisibility === 'hidden') { return; } From c8e14b5ae57972553c2e21816a0be3910438fd57 Mon Sep 17 00:00:00 2001 From: Rob Lourens Date: Thu, 2 Aug 2018 17:02:37 -0700 Subject: [PATCH 0456/1276] Fix #50555 - fix settings editor memory leak --- .../browser/parts/editor/editorGroupView.ts | 1 + .../parts/preferences/browser/settingsEditor2.ts | 12 ++++++------ .../parts/preferences/browser/settingsTree.ts | 5 ++++- 3 files changed, 11 insertions(+), 7 deletions(-) diff --git a/src/vs/workbench/browser/parts/editor/editorGroupView.ts b/src/vs/workbench/browser/parts/editor/editorGroupView.ts index c55b73e43ca..f699ad2c76a 100644 --- a/src/vs/workbench/browser/parts/editor/editorGroupView.ts +++ b/src/vs/workbench/browser/parts/editor/editorGroupView.ts @@ -1373,6 +1373,7 @@ export class EditorGroupView extends Themable implements IEditorGroupView { this._onWillDispose.fire(); this.titleAreaControl.dispose(); + // this.editorControl = null; super.dispose(); } diff --git a/src/vs/workbench/parts/preferences/browser/settingsEditor2.ts b/src/vs/workbench/parts/preferences/browser/settingsEditor2.ts index bba9169303c..d82754f0c2a 100644 --- a/src/vs/workbench/parts/preferences/browser/settingsEditor2.ts +++ b/src/vs/workbench/parts/preferences/browser/settingsEditor2.ts @@ -225,10 +225,10 @@ export class SettingsEditor2 extends BaseEditor { private createHeaderControls(parent: HTMLElement): void { const headerControlsContainerRight = DOM.append(parent, $('.settings-header-controls-right')); - this.toolbar = new ToolBar(headerControlsContainerRight, this.contextMenuService, { + this.toolbar = this._register(new ToolBar(headerControlsContainerRight, this.contextMenuService, { ariaLabel: localize('settingsToolbarLabel', "Settings Editor Actions"), actionRunner: this.actionRunner - }); + })); const actions: Action[] = [ this.instantiationService.createInstance(FilterByTagAction, @@ -290,11 +290,11 @@ export class SettingsEditor2 extends BaseEditor { const tocRenderer = this.instantiationService.createInstance(TOCRenderer); - this.tocTree = this.instantiationService.createInstance(TOCTree, this.tocTreeContainer, + this.tocTree = this._register(this.instantiationService.createInstance(TOCTree, this.tocTreeContainer, this.viewState, { renderer: tocRenderer - }); + })); this._register(this.tocTree.onDidChangeFocus(e => { // Let the caller finish before trying to sync with settings tree. @@ -345,12 +345,12 @@ export class SettingsEditor2 extends BaseEditor { })); this._register(renderer.onDidClickSettingLink(settingName => this.revealSetting(settingName))); - this.settingsTree = this.instantiationService.createInstance(SettingsTree, + this.settingsTree = this._register(this.instantiationService.createInstance(SettingsTree, this.settingsTreeContainer, this.viewState, { renderer - }); + })); this._register(this.settingsTree.onDidChangeFocus(e => { this.settingsTree.setSelection([e.focus], e.payload); diff --git a/src/vs/workbench/parts/preferences/browser/settingsTree.ts b/src/vs/workbench/parts/preferences/browser/settingsTree.ts index 2037df5ebef..15520d791e1 100644 --- a/src/vs/workbench/parts/preferences/browser/settingsTree.ts +++ b/src/vs/workbench/parts/preferences/browser/settingsTree.ts @@ -1462,9 +1462,10 @@ export class SettingsTree extends NonExpandableTree { ) { const treeClass = 'settings-editor-tree'; + const controller = instantiationService.createInstance(SettingsTreeController); const fullConfiguration = { dataSource: instantiationService.createInstance(SettingsDataSource, viewState), - controller: instantiationService.createInstance(SettingsTreeController), + controller, accessibilityProvider: instantiationService.createInstance(SettingsAccessibilityProvider), filter: instantiationService.createInstance(SettingsTreeFilter, viewState), styler: new DefaultTreestyler(DOM.createStyleSheet(), treeClass), @@ -1488,6 +1489,8 @@ export class SettingsTree extends NonExpandableTree { instantiationService, configurationService); + this.disposables.push(controller); + this.disposables.push(registerThemingParticipant((theme: ITheme, collector: ICssStyleCollector) => { const activeBorderColor = theme.getColor(focusBorder); if (activeBorderColor) { From 0c2d71e2bb9a020995729ab7d5d5f8e4e897e657 Mon Sep 17 00:00:00 2001 From: Rob Lourens Date: Thu, 2 Aug 2018 17:07:19 -0700 Subject: [PATCH 0457/1276] Fix #55712 - no need to focus 'a' anymore when restoring control focus after tree render --- src/vs/workbench/parts/preferences/browser/settingsEditor2.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vs/workbench/parts/preferences/browser/settingsEditor2.ts b/src/vs/workbench/parts/preferences/browser/settingsEditor2.ts index d82754f0c2a..27c14ebd24a 100644 --- a/src/vs/workbench/parts/preferences/browser/settingsEditor2.ts +++ b/src/vs/workbench/parts/preferences/browser/settingsEditor2.ts @@ -634,7 +634,7 @@ export class SettingsEditor2 extends BaseEditor { private focusEditControlForRow(id: string, selection?: number): void { const rowSelector = `.setting-item#${id}`; - const inputElementToFocus: HTMLElement = this.settingsTreeContainer.querySelector(`${rowSelector} input, ${rowSelector} select, ${rowSelector} a, ${rowSelector} .monaco-custom-checkbox`); + const inputElementToFocus: HTMLElement = this.settingsTreeContainer.querySelector(`${rowSelector} input, ${rowSelector} select, ${rowSelector} .monaco-custom-checkbox`); if (inputElementToFocus) { inputElementToFocus.focus(); if (typeof selection === 'number') { From 37a8896dcec8838595b02938a7144eaeecc498c0 Mon Sep 17 00:00:00 2001 From: Rachel Macfarlane Date: Thu, 2 Aug 2018 18:16:39 -0700 Subject: [PATCH 0458/1276] Fix multiple comment zones being toggled on single click --- .../parts/comments/electron-browser/commentThreadWidget.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vs/workbench/parts/comments/electron-browser/commentThreadWidget.ts b/src/vs/workbench/parts/comments/electron-browser/commentThreadWidget.ts index 96041ed6b3d..281e1fb30dc 100644 --- a/src/vs/workbench/parts/comments/electron-browser/commentThreadWidget.ts +++ b/src/vs/workbench/parts/comments/electron-browser/commentThreadWidget.ts @@ -552,7 +552,7 @@ export class ReviewZoneWidget extends ZoneWidget { return; } - if (this.position && this.position.lineNumber !== lineNumber) { + if (this._commentGlyph && this._commentGlyph.getPosition().position.lineNumber !== lineNumber) { return; } From 9dbbe69390322982b7e61581b7c724871e2323e7 Mon Sep 17 00:00:00 2001 From: Joao Moreno Date: Fri, 3 Aug 2018 09:26:51 +0200 Subject: [PATCH 0459/1276] fixes #55335 --- src/vs/base/parts/ipc/common/ipc.ts | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/vs/base/parts/ipc/common/ipc.ts b/src/vs/base/parts/ipc/common/ipc.ts index 67376daaf3d..5110f4ddc0a 100644 --- a/src/vs/base/parts/ipc/common/ipc.ts +++ b/src/vs/base/parts/ipc/common/ipc.ts @@ -24,7 +24,12 @@ enum MessageType { } function isResponse(messageType: MessageType): boolean { - return messageType >= MessageType.ResponseInitialize; + return messageType === MessageType.ResponseInitialize + || messageType === MessageType.ResponsePromiseSuccess + || messageType === MessageType.ResponsePromiseProgress + || messageType === MessageType.ResponsePromiseError + || messageType === MessageType.ResponsePromiseErrorObj + || messageType === MessageType.ResponseEventFire; } interface IRawMessage { From ce44d8be502a8db80536331e032eabbd342e42b0 Mon Sep 17 00:00:00 2001 From: isidor Date: Fri, 3 Aug 2018 10:00:51 +0200 Subject: [PATCH 0460/1276] proper fix for readonly model fixes #53022 --- src/vs/workbench/parts/files/common/editors/fileEditorInput.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vs/workbench/parts/files/common/editors/fileEditorInput.ts b/src/vs/workbench/parts/files/common/editors/fileEditorInput.ts index 7be9e9f8a2c..5eea47892d2 100644 --- a/src/vs/workbench/parts/files/common/editors/fileEditorInput.ts +++ b/src/vs/workbench/parts/files/common/editors/fileEditorInput.ts @@ -200,7 +200,7 @@ export class FileEditorInput extends EditorInput implements IFileEditorInput { if (model && model.hasState(ModelState.ORPHAN)) { return localize('orphanedFile', "{0} (deleted from disk)", label); } - if (model && model.isReadonly) { + if (model && model.isReadonly()) { return localize('readonlyFile', "{0} (read-only)", label); } From dea3960817a9b20d854f6c003f49abe16de065c5 Mon Sep 17 00:00:00 2001 From: Martin Aeschlimann Date: Fri, 3 Aug 2018 10:42:03 +0200 Subject: [PATCH 0461/1276] improve FoldingRangeKind spec (for #55686) --- src/vs/vscode.d.ts | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/vs/vscode.d.ts b/src/vs/vscode.d.ts index 85c30a83a6b..1efbbc3b096 100644 --- a/src/vs/vscode.d.ts +++ b/src/vs/vscode.d.ts @@ -3552,6 +3552,7 @@ declare module 'vscode' { * [Region](#FoldingRangeKind.Region). The kind is used to categorize folding ranges and used by commands * like 'Fold all comments'. See * [FoldingRangeKind](#FoldingRangeKind) for an enumeration of all kinds. + * If not set, the range is originated from a syntax element. */ kind?: FoldingRangeKind; @@ -3566,7 +3567,10 @@ declare module 'vscode' { } /** - * An enumeration of all folding range kinds. The kind is used to categorize folding ranges. + * An enumeration of specific folding range kinds. The kind is an optional field of a [FoldingRange](#FoldingRange) + * and is used to distinguish specific folding ranges such as ranges originated from comments. The kind is used by commands like + * `Fold all comments` or `Fold all regions`. + * If the kind is not set on the range, the range originated from a syntax element other than comments, imports or region markers. */ export enum FoldingRangeKind { /** @@ -3578,7 +3582,7 @@ declare module 'vscode' { */ Imports = 2, /** - * Kind for folding range representing regions (for example a folding range marked by `#region` and `#endregion`). + * Kind for folding range representing regions originating from folding markers like `#region` and `#endregion`. */ Region = 3 } From 1b675ac9ab9ac6221506a99f48a8cc2077be015e Mon Sep 17 00:00:00 2001 From: Christof Marti Date: Fri, 3 Aug 2018 10:53:43 +0200 Subject: [PATCH 0462/1276] Use class with static fields (fixes #55494) --- src/vs/vscode.d.ts | 9 +++++++-- src/vs/workbench/api/node/extHost.api.impl.ts | 7 +------ src/vs/workbench/api/node/extHostQuickOpen.ts | 10 +++------- src/vs/workbench/api/node/extHostTypes.ts | 7 +++++++ 4 files changed, 18 insertions(+), 15 deletions(-) diff --git a/src/vs/vscode.d.ts b/src/vs/vscode.d.ts index 1efbbc3b096..71081b8f94a 100644 --- a/src/vs/vscode.d.ts +++ b/src/vs/vscode.d.ts @@ -6892,7 +6892,7 @@ declare module 'vscode' { /** * Predefined buttons for [QuickPick](#QuickPick) and [InputBox](#InputBox). */ - export namespace QuickInputButtons { + export class QuickInputButtons { /** * A back button for [QuickPick](#QuickPick) and [InputBox](#InputBox). @@ -6900,7 +6900,12 @@ declare module 'vscode' { * When a navigation 'back' button is needed this one should be used for consistency. * It comes with a predefined icon, tooltip and location. */ - export const Back: QuickInputButton; + static readonly Back: QuickInputButton; + + /** + * @hidden + */ + private constructor(); } /** diff --git a/src/vs/workbench/api/node/extHost.api.impl.ts b/src/vs/workbench/api/node/extHost.api.impl.ts index c6daee8c6ca..bc631fe2d4d 100644 --- a/src/vs/workbench/api/node/extHost.api.impl.ts +++ b/src/vs/workbench/api/node/extHost.api.impl.ts @@ -463,11 +463,6 @@ export function createApiFactory( }, }; - // namespace: QuickInputButtons - const QuickInputButtons: typeof vscode.QuickInputButtons = { - Back: extHostQuickOpen.backButton, - }; - // namespace: workspace const workspace: typeof vscode.workspace = { get rootPath() { @@ -732,7 +727,7 @@ export function createApiFactory( OverviewRulerLane: OverviewRulerLane, ParameterInformation: extHostTypes.ParameterInformation, Position: extHostTypes.Position, - QuickInputButtons, + QuickInputButtons: extHostTypes.QuickInputButtons, Range: extHostTypes.Range, Selection: extHostTypes.Selection, SignatureHelp: extHostTypes.SignatureHelp, diff --git a/src/vs/workbench/api/node/extHostQuickOpen.ts b/src/vs/workbench/api/node/extHostQuickOpen.ts index 43c5f784178..29928df44f9 100644 --- a/src/vs/workbench/api/node/extHostQuickOpen.ts +++ b/src/vs/workbench/api/node/extHostQuickOpen.ts @@ -14,9 +14,7 @@ import { ExtHostWorkspace } from 'vs/workbench/api/node/extHostWorkspace'; import { InputBox, InputBoxOptions, QuickInput, QuickInputButton, QuickPick, QuickPickItem, QuickPickOptions, WorkspaceFolder, WorkspaceFolderPickOptions } from 'vscode'; import { ExtHostQuickOpenShape, IMainContext, MainContext, MainThreadQuickOpenShape, TransferQuickPickItems, TransferQuickInput, TransferQuickInputButton } from './extHost.protocol'; import URI from 'vs/base/common/uri'; -import { ThemeIcon } from 'vs/workbench/api/node/extHostTypes'; - -const backButton: QuickInputButton = { iconPath: 'back.svg' }; +import { ThemeIcon, QuickInputButtons } from 'vs/workbench/api/node/extHostTypes'; export type Item = string | QuickPickItem; @@ -153,8 +151,6 @@ export class ExtHostQuickOpen implements ExtHostQuickOpenShape { // ---- QuickInput - backButton = backButton; - createQuickPick(extensionId: string): QuickPick { const session = new ExtHostQuickPick(this._proxy, extensionId, () => this._sessions.delete(session._id)); this._sessions.set(session._id, session); @@ -328,14 +324,14 @@ class ExtHostQuickInput implements QuickInput { this._buttons = buttons.slice(); this._handlesToButtons.clear(); buttons.forEach((button, i) => { - const handle = button === backButton ? -1 : i; + const handle = button === QuickInputButtons.Back ? -1 : i; this._handlesToButtons.set(handle, button); }); this.update({ buttons: buttons.map((button, i) => ({ iconPath: getIconUris(button.iconPath), tooltip: button.tooltip, - handle: button === backButton ? -1 : i, + handle: button === QuickInputButtons.Back ? -1 : i, })) }); } diff --git a/src/vs/workbench/api/node/extHostTypes.ts b/src/vs/workbench/api/node/extHostTypes.ts index 4bf2cd070ba..7e7572fe66c 100644 --- a/src/vs/workbench/api/node/extHostTypes.ts +++ b/src/vs/workbench/api/node/extHostTypes.ts @@ -1956,3 +1956,10 @@ export enum CommentThreadCollapsibleState { */ Expanded = 1 } + +export class QuickInputButtons { + + static readonly Back: vscode.QuickInputButton = { iconPath: 'back.svg' }; + + private constructor() { } +} From 1bcb1015ad86b967a9421ba14094581bfb9452c6 Mon Sep 17 00:00:00 2001 From: Alex Dima Date: Fri, 3 Aug 2018 11:34:00 +0200 Subject: [PATCH 0463/1276] Fixes #53671 --- .../contrib/wordPartOperations/wordPartOperations.ts | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/vs/editor/contrib/wordPartOperations/wordPartOperations.ts b/src/vs/editor/contrib/wordPartOperations/wordPartOperations.ts index 5c7dc9166f6..fec93549d35 100644 --- a/src/vs/editor/contrib/wordPartOperations/wordPartOperations.ts +++ b/src/vs/editor/contrib/wordPartOperations/wordPartOperations.ts @@ -27,7 +27,7 @@ export class DeleteWordPartLeft extends DeleteWordCommand { precondition: EditorContextKeys.writable, kbOpts: { kbExpr: EditorContextKeys.textInputFocus, - primary: KeyMod.CtrlCmd | KeyMod.Alt | KeyCode.Backspace, + primary: 0, mac: { primary: KeyMod.WinCtrl | KeyMod.Alt | KeyCode.Backspace }, weight: KeybindingWeight.EditorContrib } @@ -52,7 +52,7 @@ export class DeleteWordPartRight extends DeleteWordCommand { precondition: EditorContextKeys.writable, kbOpts: { kbExpr: EditorContextKeys.textInputFocus, - primary: KeyMod.CtrlCmd | KeyMod.Alt | KeyCode.Delete, + primary: 0, mac: { primary: KeyMod.WinCtrl | KeyMod.Alt | KeyCode.Delete }, weight: KeybindingWeight.EditorContrib } @@ -84,7 +84,7 @@ export class CursorWordPartLeft extends WordPartLeftCommand { precondition: null, kbOpts: { kbExpr: EditorContextKeys.textInputFocus, - primary: KeyMod.CtrlCmd | KeyMod.Alt | KeyCode.LeftArrow, + primary: 0, mac: { primary: KeyMod.WinCtrl | KeyMod.Alt | KeyCode.LeftArrow }, weight: KeybindingWeight.EditorContrib } @@ -103,7 +103,7 @@ export class CursorWordPartLeftSelect extends WordPartLeftCommand { precondition: null, kbOpts: { kbExpr: EditorContextKeys.textInputFocus, - primary: KeyMod.CtrlCmd | KeyMod.Alt | KeyMod.Shift | KeyCode.LeftArrow, + primary: 0, mac: { primary: KeyMod.WinCtrl | KeyMod.Alt | KeyMod.Shift | KeyCode.LeftArrow }, weight: KeybindingWeight.EditorContrib } @@ -127,7 +127,7 @@ export class CursorWordPartRight extends WordPartRightCommand { precondition: null, kbOpts: { kbExpr: EditorContextKeys.textInputFocus, - primary: KeyMod.CtrlCmd | KeyMod.Alt | KeyCode.RightArrow, + primary: 0, mac: { primary: KeyMod.WinCtrl | KeyMod.Alt | KeyCode.RightArrow }, weight: KeybindingWeight.EditorContrib } @@ -143,7 +143,7 @@ export class CursorWordPartRightSelect extends WordPartRightCommand { precondition: null, kbOpts: { kbExpr: EditorContextKeys.textInputFocus, - primary: KeyMod.CtrlCmd | KeyMod.Alt | KeyMod.Shift | KeyCode.RightArrow, + primary: 0, mac: { primary: KeyMod.WinCtrl | KeyMod.Alt | KeyMod.Shift | KeyCode.RightArrow }, weight: KeybindingWeight.EditorContrib } From ee1fb7b629c24271dc9ea0b0ecf4b1e591d847a2 Mon Sep 17 00:00:00 2001 From: Joao Moreno Date: Fri, 3 Aug 2018 12:01:19 +0200 Subject: [PATCH 0464/1276] fixes #54630 --- .../browser/ui/contextview/contextview.ts | 101 ++++++++---------- .../ui/contextview/contextview.test.ts | 28 +++++ 2 files changed, 75 insertions(+), 54 deletions(-) create mode 100644 src/vs/base/test/browser/ui/contextview/contextview.test.ts diff --git a/src/vs/base/browser/ui/contextview/contextview.ts b/src/vs/base/browser/ui/contextview/contextview.ts index 8a14b87c36c..8da408322a4 100644 --- a/src/vs/base/browser/ui/contextview/contextview.ts +++ b/src/vs/base/browser/ui/contextview/contextview.ts @@ -54,51 +54,46 @@ export interface ISize { export interface IView extends IPosition, ISize { } -function layout(view: ISize, around: IView, viewport: IView, anchorPosition: AnchorPosition, anchorAlignment: AnchorAlignment): IPosition { +export enum LayoutAnchorPosition { + Before, + After +} - let chooseBiased = (a: number, aIsGood: boolean, b: number, bIsGood: boolean) => { - if (aIsGood) { - return a; +export interface ILayoutAnchor { + offset: number; + size: number; + position: LayoutAnchorPosition; +} + +/** + * Lays out a one dimensional view next to an anchor in a viewport. + * + * @returns The view offset within the viewport. + */ +export function layout(viewportSize: number, viewSize: number, anchor: ILayoutAnchor): number { + const anchorEnd = anchor.offset + anchor.size; + + if (anchor.position === LayoutAnchorPosition.Before) { + if (viewSize <= viewportSize - anchorEnd) { + return anchorEnd; // happy case, lay it out after the anchor } - if (bIsGood) { - return b; + + if (viewSize <= anchor.offset) { + return anchor.offset - viewSize; // ok case, lay it out before the anchor } - return a; - }; - let chooseOne = (a: number, aIsGood: boolean, b: number, bIsGood: boolean, aIsPreferred: boolean) => { - if (aIsPreferred) { - return chooseBiased(a, aIsGood, b, bIsGood); - } else { - return chooseBiased(b, bIsGood, a, aIsGood); + return Math.max(viewportSize - viewSize, 0); // sad case, lay it over the anchor + } else { + if (viewSize <= anchor.offset) { + return anchor.offset - viewSize; // happy case, lay it out before the anchor } - }; - let top = (() => { - // Compute both options (putting the segment above and below) - let posAbove = around.top - view.height; - let posBelow = around.top + around.height; + if (viewSize <= viewportSize - anchorEnd) { + return anchorEnd; // ok case, lay it out after the anchor + } - // Check for both options if they are good - let aboveIsGood = (posAbove >= viewport.top && posAbove + view.height <= viewport.top + viewport.height); - let belowIsGood = (posBelow >= viewport.top && posBelow + view.height <= viewport.top + viewport.height); - - return chooseOne(posAbove, aboveIsGood, posBelow, belowIsGood, anchorPosition === AnchorPosition.ABOVE); - })(); - - let left = (() => { - // Compute both options (aligning left and right) - let posLeft = around.left; - let posRight = around.left + around.width - view.width; - - // Check for both options if they are good - let leftIsGood = (posLeft >= viewport.left && posLeft + view.width <= viewport.left + viewport.width); - let rightIsGood = (posRight >= viewport.left && posRight + view.width <= viewport.left + viewport.width); - - return chooseOne(posLeft, leftIsGood, posRight, rightIsGood, anchorAlignment === AnchorAlignment.LEFT); - })(); - - return { top: top, left: left }; + return 0; // sad case, lay it over the anchor + } } export class ContextView { @@ -205,30 +200,28 @@ export class ContextView { }; } - let viewport = { - top: DOM.StandardWindow.scrollY, - left: DOM.StandardWindow.scrollX, - height: window.innerHeight, - width: window.innerWidth - }; + const viewSize = this.$view.getTotalSize(); + const anchorPosition = this.delegate.anchorPosition || AnchorPosition.BELOW; + const anchorAlignment = this.delegate.anchorAlignment || AnchorAlignment.LEFT; - // Get the view's size - let viewSize = this.$view.getTotalSize(); - let view = { width: viewSize.width, height: viewSize.height }; + const verticalAnchor: ILayoutAnchor = { offset: around.top, size: around.height, position: anchorPosition === AnchorPosition.BELOW ? LayoutAnchorPosition.Before : LayoutAnchorPosition.After }; - let anchorPosition = this.delegate.anchorPosition || AnchorPosition.BELOW; - let anchorAlignment = this.delegate.anchorAlignment || AnchorAlignment.LEFT; + let horizontalAnchor: ILayoutAnchor; - let result = layout(view, around, viewport, anchorPosition, anchorAlignment); + if (anchorAlignment === AnchorAlignment.LEFT) { + horizontalAnchor = { offset: around.left, size: 0, position: LayoutAnchorPosition.Before }; + } else { + horizontalAnchor = { offset: around.left + around.width, size: 0, position: LayoutAnchorPosition.After }; + } - let containerPosition = DOM.getDomNodePagePosition(this.$container.getHTMLElement()); - result.top -= containerPosition.top; - result.left -= containerPosition.left; + const containerPosition = DOM.getDomNodePagePosition(this.$container.getHTMLElement()); + const top = layout(window.innerHeight, viewSize.height, verticalAnchor) - containerPosition.top; + const left = layout(window.innerWidth, viewSize.width, horizontalAnchor) - containerPosition.left; this.$view.removeClass('top', 'bottom', 'left', 'right'); this.$view.addClass(anchorPosition === AnchorPosition.BELOW ? 'bottom' : 'top'); this.$view.addClass(anchorAlignment === AnchorAlignment.LEFT ? 'left' : 'right'); - this.$view.style({ top: result.top + 'px', left: result.left + 'px', width: 'initial' }); + this.$view.style({ top: `${top}px`, left: `${left}px`, width: 'initial' }); } public hide(data?: any): void { diff --git a/src/vs/base/test/browser/ui/contextview/contextview.test.ts b/src/vs/base/test/browser/ui/contextview/contextview.test.ts new file mode 100644 index 00000000000..09214cfc06d --- /dev/null +++ b/src/vs/base/test/browser/ui/contextview/contextview.test.ts @@ -0,0 +1,28 @@ +/*--------------------------------------------------------------------------------------------- + * 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 { layout, LayoutAnchorPosition } from 'vs/base/browser/ui/contextview/contextview'; + +suite('Contextview', function () { + + test('layout', function () { + assert.equal(layout(200, 20, { offset: 0, size: 0, position: LayoutAnchorPosition.Before }), 0); + assert.equal(layout(200, 20, { offset: 50, size: 0, position: LayoutAnchorPosition.Before }), 50); + assert.equal(layout(200, 20, { offset: 200, size: 0, position: LayoutAnchorPosition.Before }), 180); + + assert.equal(layout(200, 20, { offset: 0, size: 0, position: LayoutAnchorPosition.After }), 0); + assert.equal(layout(200, 20, { offset: 50, size: 0, position: LayoutAnchorPosition.After }), 30); + assert.equal(layout(200, 20, { offset: 200, size: 0, position: LayoutAnchorPosition.After }), 180); + + assert.equal(layout(200, 20, { offset: 0, size: 50, position: LayoutAnchorPosition.Before }), 50); + assert.equal(layout(200, 20, { offset: 50, size: 50, position: LayoutAnchorPosition.Before }), 100); + assert.equal(layout(200, 20, { offset: 150, size: 50, position: LayoutAnchorPosition.Before }), 130); + + assert.equal(layout(200, 20, { offset: 0, size: 50, position: LayoutAnchorPosition.After }), 50); + assert.equal(layout(200, 20, { offset: 50, size: 50, position: LayoutAnchorPosition.After }), 30); + assert.equal(layout(200, 20, { offset: 150, size: 50, position: LayoutAnchorPosition.After }), 130); + }); +}); From 4fa62b246c4305b4ca00507551f77c58135ce928 Mon Sep 17 00:00:00 2001 From: Martin Aeschlimann Date: Fri, 3 Aug 2018 11:38:01 +0200 Subject: [PATCH 0465/1276] [html] should disable ionic suggestions by default. Currently forces deprecated Ionic v1 suggestions in .html files while typing. Fixes #53324 --- extensions/html-language-features/package.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/extensions/html-language-features/package.json b/extensions/html-language-features/package.json index cbbc1fb81de..586b1684cda 100644 --- a/extensions/html-language-features/package.json +++ b/extensions/html-language-features/package.json @@ -125,13 +125,13 @@ "html.suggest.angular1": { "type": "boolean", "scope": "resource", - "default": true, + "default": false, "description": "%html.suggest.angular1.desc%" }, "html.suggest.ionic": { "type": "boolean", "scope": "resource", - "default": true, + "default": false, "description": "%html.suggest.ionic.desc%" }, "html.suggest.html5": { From 4dc8a7c33ad19846f4f80d4933044241b21c95f2 Mon Sep 17 00:00:00 2001 From: Joao Moreno Date: Fri, 3 Aug 2018 16:15:15 +0200 Subject: [PATCH 0466/1276] cleanup deps --- package.json | 3 +- yarn.lock | 141 ++------------------------------------------------- 2 files changed, 6 insertions(+), 138 deletions(-) diff --git a/package.json b/package.json index 8f7d28e7755..09ccdd7cc59 100644 --- a/package.json +++ b/package.json @@ -60,7 +60,6 @@ "@types/mocha": "2.2.39", "@types/sinon": "1.16.34", "asar": "^0.14.0", - "azure-storage": "^0.3.1", "chromium-pickle-js": "^0.2.0", "clean-css": "3.4.6", "coveralls": "^2.11.11", @@ -102,7 +101,7 @@ "istanbul": "^0.3.17", "jsdom-no-contextify": "^3.1.0", "lazy.js": "^0.4.2", - "mime": "1.2.11", + "mime": "^1.4.1", "minimatch": "^2.0.10", "mkdirp": "^0.5.0", "mocha": "^2.2.5", diff --git a/yarn.lock b/yarn.lock index fe0f0ef16a6..a9e1b428b8a 100644 --- a/yarn.lock +++ b/yarn.lock @@ -294,10 +294,6 @@ asar@^0.14.0: mksnapshot "^0.3.0" tmp "0.0.28" -asn1@0.1.11: - version "0.1.11" - resolved "https://registry.yarnpkg.com/asn1/-/asn1-0.1.11.tgz#559be18376d08a4ec4dbe80877d27818639b2df7" - asn1@~0.2.3: version "0.2.3" resolved "https://registry.yarnpkg.com/asn1/-/asn1-0.2.3.tgz#dac8787713c9966849fc8180777ebe9c1ddf3b86" @@ -306,10 +302,6 @@ assert-plus@1.0.0, assert-plus@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/assert-plus/-/assert-plus-1.0.0.tgz#f12e0f3c5d77b0b1cdd9146942e4e96c1e4dd525" -assert-plus@^0.1.5: - version "0.1.5" - resolved "https://registry.yarnpkg.com/assert-plus/-/assert-plus-0.1.5.tgz#ee74009413002d84cec7219c6ac811812e723160" - assert-plus@^0.2.0: version "0.2.0" resolved "https://registry.yarnpkg.com/assert-plus/-/assert-plus-0.2.0.tgz#d74e1b87e7affc0db8aadb7021f3fe48101ab234" @@ -336,10 +328,6 @@ async@~0.2.8: version "0.2.10" resolved "https://registry.yarnpkg.com/async/-/async-0.2.10.tgz#b6bbe0b0674b9d719708ca38de8c237cb526c3d1" -async@~0.9.0: - version "0.9.2" - resolved "https://registry.yarnpkg.com/async/-/async-0.9.2.tgz#aea74d5e61c1f899613bf64bda66d4c78f2fd17d" - asynckit@^0.4.0: version "0.4.0" resolved "https://registry.yarnpkg.com/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79" @@ -367,27 +355,10 @@ aws-sign2@~0.7.0: version "0.7.0" resolved "https://registry.yarnpkg.com/aws-sign2/-/aws-sign2-0.7.0.tgz#b46e890934a9591f2d2f6f86d7e6a9f1b3fe76a8" -aws-sign@~0.3.0: - version "0.3.0" - resolved "https://registry.yarnpkg.com/aws-sign/-/aws-sign-0.3.0.tgz#3d81ca69b474b1e16518728b51c24ff0bbedc6e9" - aws4@^1.2.1, aws4@^1.6.0: version "1.6.0" resolved "https://registry.yarnpkg.com/aws4/-/aws4-1.6.0.tgz#83ef5ca860b2b32e4a0deedee8c771b9db57471e" -azure-storage@^0.3.1: - version "0.3.3" - resolved "https://registry.yarnpkg.com/azure-storage/-/azure-storage-0.3.3.tgz#5e1920ba75c678cb3f5e52a89136ef36210b58a1" - dependencies: - extend "~1.2.1" - mime "~1.2.4" - node-uuid "~1.4.0" - request "~2.27.0" - underscore "~1.4.4" - validator "~3.1.0" - xml2js "0.2.7" - xmlbuilder "0.4.3" - azure-storage@^1.3.1: version "1.4.0" resolved "https://registry.yarnpkg.com/azure-storage/-/azure-storage-1.4.0.tgz#fb52fa68b3efa6980c33fd7c5cd489b7adc46ed1" @@ -492,12 +463,6 @@ boolbase@~1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/boolbase/-/boolbase-1.0.0.tgz#68dff5fbe60c51eb37725ea9e3ed310dcc1e776e" -boom@0.4.x: - version "0.4.2" - resolved "https://registry.yarnpkg.com/boom/-/boom-0.4.2.tgz#7a636e9ded4efcefb19cef4947a3c67dfaee911b" - dependencies: - hoek "0.9.x" - boom@2.x.x: version "2.10.1" resolved "https://registry.yarnpkg.com/boom/-/boom-2.10.1.tgz#39c8918ceff5799f83f9492a848f625add0c766f" @@ -851,12 +816,6 @@ combined-stream@^1.0.5, combined-stream@~1.0.5: dependencies: delayed-stream "~1.0.0" -combined-stream@~0.0.4: - version "0.0.7" - resolved "https://registry.yarnpkg.com/combined-stream/-/combined-stream-0.0.7.tgz#0137e657baa5a7541c57ac37ac5fc07d73b4dc1f" - dependencies: - delayed-stream "0.0.5" - commander@*, commander@^2.11.0: version "2.15.0" resolved "https://registry.yarnpkg.com/commander/-/commander-2.15.0.tgz#ad2a23a1c3b036e392469b8012cec6b33b4c1322" @@ -928,10 +887,6 @@ convert-source-map@1.X, convert-source-map@^1.1.1: version "1.5.0" resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-1.5.0.tgz#9acd70851c6d5dfdd93d9282e5edf94a03ff46b5" -cookie-jar@~0.3.0: - version "0.3.0" - resolved "https://registry.yarnpkg.com/cookie-jar/-/cookie-jar-0.3.0.tgz#bc9a27d4e2b97e186cd57c9e2063cb99fa68cccc" - cookie-signature@1.0.6: version "1.0.6" resolved "https://registry.yarnpkg.com/cookie-signature/-/cookie-signature-1.0.6.tgz#e303a882b342cc3ee8ca513a79999734dab3ae2c" @@ -973,12 +928,6 @@ crypt@~0.0.1: version "0.0.2" resolved "https://registry.yarnpkg.com/crypt/-/crypt-0.0.2.tgz#88d7ff7ec0dfb86f713dc87bbb42d044d3e6c41b" -cryptiles@0.2.x: - version "0.2.2" - resolved "https://registry.yarnpkg.com/cryptiles/-/cryptiles-0.2.2.tgz#ed91ff1f17ad13d3748288594f8a48a0d26f325c" - dependencies: - boom "0.4.x" - cryptiles@2.x.x: version "2.0.5" resolved "https://registry.yarnpkg.com/cryptiles/-/cryptiles-2.0.5.tgz#3bdfecdc608147c1c67202fa291e7dca59eaa3b8" @@ -1077,10 +1026,6 @@ cssom@0.3.x, "cssom@>= 0.3.0 < 0.4.0": dependencies: cssom "0.3.x" -ctype@0.5.3: - version "0.5.3" - resolved "https://registry.yarnpkg.com/ctype/-/ctype-0.5.3.tgz#82c18c2461f74114ef16c135224ad0b9144ca12f" - cuint@^0.2.1: version "0.2.2" resolved "https://registry.yarnpkg.com/cuint/-/cuint-0.2.2.tgz#408086d409550c2631155619e9fa7bcadc3b991b" @@ -1204,10 +1149,6 @@ del@^2.0.2: pinkie-promise "^2.0.0" rimraf "^2.2.8" -delayed-stream@0.0.5: - version "0.0.5" - resolved "https://registry.yarnpkg.com/delayed-stream/-/delayed-stream-0.0.5.tgz#d4b1f43a93e8296dfe02694f4680bc37a313c73f" - delayed-stream@0.0.6: version "0.0.6" resolved "https://registry.yarnpkg.com/delayed-stream/-/delayed-stream-0.0.6.tgz#a2646cb7ec3d5d7774614670a7a65de0c173edbc" @@ -1936,22 +1877,10 @@ for-own@^1.0.0: dependencies: for-in "^1.0.1" -forever-agent@~0.5.0: - version "0.5.2" - resolved "https://registry.yarnpkg.com/forever-agent/-/forever-agent-0.5.2.tgz#6d0e09c4921f94a27f63d3b49c5feff1ea4c5130" - forever-agent@~0.6.1: version "0.6.1" resolved "https://registry.yarnpkg.com/forever-agent/-/forever-agent-0.6.1.tgz#fbc71f0c41adeb37f96c577ad1ed42d8fdacca91" -form-data@~0.1.0: - version "0.1.4" - resolved "https://registry.yarnpkg.com/form-data/-/form-data-0.1.4.tgz#91abd788aba9702b1aabfa8bc01031a2ac9e3b12" - dependencies: - async "~0.9.0" - combined-stream "~0.0.4" - mime "~1.2.11" - form-data@~1.0.0-rc4: version "1.0.1" resolved "https://registry.yarnpkg.com/form-data/-/form-data-1.0.1.tgz#ae315db9a4907fa065502304a66d7733475ee37c" @@ -2699,15 +2628,6 @@ has@^1.0.1: dependencies: function-bind "^1.0.2" -hawk@~1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/hawk/-/hawk-1.0.0.tgz#b90bb169807285411da7ffcb8dd2598502d3b52d" - dependencies: - boom "0.4.x" - cryptiles "0.2.x" - hoek "0.9.x" - sntp "0.2.x" - hawk@~3.1.3: version "3.1.3" resolved "https://registry.yarnpkg.com/hawk/-/hawk-3.1.3.tgz#078444bd7c1640b0fe540d2c9b73d59678e8e1c4" @@ -2726,10 +2646,6 @@ hawk@~6.0.2: hoek "4.x.x" sntp "2.x.x" -hoek@0.9.x: - version "0.9.1" - resolved "https://registry.yarnpkg.com/hoek/-/hoek-0.9.1.tgz#3d322462badf07716ea7eb85baf88079cddce505" - hoek@2.x.x: version "2.16.3" resolved "https://registry.yarnpkg.com/hoek/-/hoek-2.16.3.tgz#20bb7403d3cea398e91dc4710a8ff1b8274a25ed" @@ -2779,14 +2695,6 @@ http-proxy-agent@^2.1.0: agent-base "4" debug "3.1.0" -http-signature@~0.10.0: - version "0.10.1" - resolved "https://registry.yarnpkg.com/http-signature/-/http-signature-0.10.1.tgz#4fbdac132559aa8323121e540779c0a012b27e66" - dependencies: - asn1 "0.1.11" - assert-plus "^0.1.5" - ctype "0.5.3" - http-signature@~1.1.0: version "1.1.1" resolved "https://registry.yarnpkg.com/http-signature/-/http-signature-1.1.1.tgz#df72e267066cd0ac67fb76adf8e134a8fbcf91bf" @@ -3261,7 +3169,7 @@ json-stable-stringify@^1.0.0, json-stable-stringify@^1.0.1: dependencies: jsonify "~0.0.0" -json-stringify-safe@~5.0.0, json-stringify-safe@~5.0.1: +json-stringify-safe@~5.0.1: version "5.0.1" resolved "https://registry.yarnpkg.com/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz#1296a2d58fd45f19a0f6ce01d65701e2c735b6eb" @@ -3778,14 +3686,14 @@ mime-types@^2.1.11, mime-types@^2.1.12, mime-types@~2.1.15, mime-types@~2.1.16, dependencies: mime-db "~1.30.0" -mime@1.2.11, mime@~1.2.11, mime@~1.2.4, mime@~1.2.9: - version "1.2.11" - resolved "https://registry.yarnpkg.com/mime/-/mime-1.2.11.tgz#58203eed86e3a5ef17aed2b7d9ebd47f0a60dd10" - mime@1.4.1, mime@^1.3.4: version "1.4.1" resolved "https://registry.yarnpkg.com/mime/-/mime-1.4.1.tgz#121f9ebc49e3766f311a76e1fa1c8003c4b03aa6" +mime@^1.4.1: + version "1.6.0" + resolved "https://registry.yarnpkg.com/mime/-/mime-1.6.0.tgz#32cd9e5c64553bd58d19a568af452acff04981b1" + mimic-fn@^1.0.0: version "1.1.0" resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-1.1.0.tgz#e667783d92e89dbd342818b5230b9d62a672ad18" @@ -4093,10 +4001,6 @@ number-is-nan@^1.0.0: version "1.4.3" resolved "https://registry.yarnpkg.com/nwmatcher/-/nwmatcher-1.4.3.tgz#64348e3b3d80f035b40ac11563d278f8b72db89c" -oauth-sign@~0.3.0: - version "0.3.0" - resolved "https://registry.yarnpkg.com/oauth-sign/-/oauth-sign-0.3.0.tgz#cb540f93bb2b22a7d5941691a288d60e8ea9386e" - oauth-sign@~0.8.1, oauth-sign@~0.8.2: version "0.8.2" resolved "https://registry.yarnpkg.com/oauth-sign/-/oauth-sign-0.8.2.tgz#46a6ab7f0aead8deae9ec0565780b7d4efeb9d43" @@ -4772,10 +4676,6 @@ qs@6.5.1, qs@~6.5.1: version "6.5.1" resolved "https://registry.yarnpkg.com/qs/-/qs-6.5.1.tgz#349cdf6eef89ec45c12d7d5eb3fc0c870343a6d8" -qs@~0.6.0: - version "0.6.6" - resolved "https://registry.yarnpkg.com/qs/-/qs-0.6.6.tgz#6e015098ff51968b8a3c819001d5f2c89bc4b107" - qs@~6.2.0: version "6.2.3" resolved "https://registry.yarnpkg.com/qs/-/qs-6.2.3.tgz#1cfcb25c10a9b2b483053ff39f5dfc9233908cfe" @@ -5103,23 +5003,6 @@ request@2.81.0: tunnel-agent "^0.6.0" uuid "^3.1.0" -request@~2.27.0: - version "2.27.0" - resolved "https://registry.yarnpkg.com/request/-/request-2.27.0.tgz#dfb1a224dd3a5a9bade4337012503d710e538668" - dependencies: - aws-sign "~0.3.0" - cookie-jar "~0.3.0" - forever-agent "~0.5.0" - form-data "~0.1.0" - hawk "~1.0.0" - http-signature "~0.10.0" - json-stringify-safe "~5.0.0" - mime "~1.2.9" - node-uuid "~1.4.0" - oauth-sign "~0.3.0" - qs "~0.6.0" - tunnel-agent "~0.3.0" - request@~2.74.0: version "2.74.0" resolved "https://registry.yarnpkg.com/request/-/request-2.74.0.tgz#7693ca768bbb0ea5c8ce08c084a45efa05b892ab" @@ -5369,12 +5252,6 @@ slice-ansi@0.0.4: version "0.0.4" resolved "https://registry.yarnpkg.com/slice-ansi/-/slice-ansi-0.0.4.tgz#edbf8903f66f7ce2f8eafd6ceed65e264c831b35" -sntp@0.2.x: - version "0.2.4" - resolved "https://registry.yarnpkg.com/sntp/-/sntp-0.2.4.tgz#fb885f18b0f3aad189f824862536bceeec750900" - dependencies: - hoek "0.9.x" - sntp@1.x.x: version "1.0.9" resolved "https://registry.yarnpkg.com/sntp/-/sntp-1.0.9.tgz#6541184cc90aeea6c6e7b35e2659082443c66198" @@ -5860,10 +5737,6 @@ tunnel-agent@^0.6.0: dependencies: safe-buffer "^5.0.1" -tunnel-agent@~0.3.0: - version "0.3.0" - resolved "https://registry.yarnpkg.com/tunnel-agent/-/tunnel-agent-0.3.0.tgz#ad681b68f5321ad2827c4cfb1b7d5df2cfe942ee" - tunnel-agent@~0.4.1: version "0.4.3" resolved "https://registry.yarnpkg.com/tunnel-agent/-/tunnel-agent-0.4.3.tgz#6373db76909fe570e08d73583365ed828a74eeeb" @@ -6056,10 +5929,6 @@ validate-npm-package-license@^3.0.1: spdx-correct "~1.0.0" spdx-expression-parse "~1.0.0" -validator@~3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/validator/-/validator-3.1.0.tgz#2ea1ff7e92254d69367f385f015299e5ead8755b" - validator@~3.22.2: version "3.22.2" resolved "https://registry.yarnpkg.com/validator/-/validator-3.22.2.tgz#6f297ae67f7f82acc76d0afdb49f18d9a09c18c0" From 09b7a988c1818a56f773d62af7917c39f87e421e Mon Sep 17 00:00:00 2001 From: isidor Date: Fri, 3 Aug 2018 16:28:20 +0200 Subject: [PATCH 0467/1276] debug issues back to andre --- .github/classifier.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/classifier.yml b/.github/classifier.yml index a7bcb40c96f..c1c067e5c53 100644 --- a/.github/classifier.yml +++ b/.github/classifier.yml @@ -15,7 +15,7 @@ css-less-scss: [ aeschli ], debug-console: [], debug: { - assignees: [ isidorn ], + assignees: [ weinand ], assignLabel: false }, diff-editor: [], From b839bdec72d688b7587a6424597db3ea4a5acd4f Mon Sep 17 00:00:00 2001 From: Joao Moreno Date: Fri, 3 Aug 2018 16:35:55 +0200 Subject: [PATCH 0468/1276] update electron for smoketest --- test/smoke/package.json | 2 +- test/smoke/yarn.lock | 14 +++++++------- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/test/smoke/package.json b/test/smoke/package.json index 0ce01ada8b8..c3d79b62111 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": "1.7.7", + "electron": "^2.0.6", "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 c628b2089e2..55ab35aceea 100644 --- a/test/smoke/yarn.lock +++ b/test/smoke/yarn.lock @@ -41,9 +41,9 @@ version "8.0.33" resolved "https://registry.yarnpkg.com/@types/node/-/node-8.0.33.tgz#1126e94374014e54478092830704f6ea89df04cd" -"@types/node@^7.0.18": - version "7.0.46" - resolved "https://registry.yarnpkg.com/@types/node/-/node-7.0.46.tgz#c3dedd25558c676b3d6303e51799abb9c3f8f314" +"@types/node@^8.0.24": + version "8.10.23" + resolved "https://registry.yarnpkg.com/@types/node/-/node-8.10.23.tgz#e5ccfdafff42af5397c29669b6d7d65f7d629a00" "@types/rimraf@2.0.2": version "2.0.2" @@ -493,11 +493,11 @@ electron-download@^3.0.1: semver "^5.3.0" sumchecker "^1.2.0" -electron@1.7.7: - version "1.7.7" - resolved "https://registry.yarnpkg.com/electron/-/electron-1.7.7.tgz#cfd89ca9eba79d763ac0b0c6dcc583792097b9b6" +electron@^2.0.6: + version "2.0.6" + resolved "https://registry.yarnpkg.com/electron/-/electron-2.0.6.tgz#8e5c1bd2ebc08fa7a6ee906de3753c1ece9d7300" dependencies: - "@types/node" "^7.0.18" + "@types/node" "^8.0.24" electron-download "^3.0.1" extract-zip "^1.0.3" From 9465c29dba0f5a7de718835e385cd1bb4c712d3c Mon Sep 17 00:00:00 2001 From: Rob Lourens Date: Fri, 3 Aug 2018 08:31:55 -0700 Subject: [PATCH 0469/1276] Fix #55757 - prevent settings tabs from overflowing --- .../parts/preferences/browser/media/settingsEditor2.css | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/vs/workbench/parts/preferences/browser/media/settingsEditor2.css b/src/vs/workbench/parts/preferences/browser/media/settingsEditor2.css index 75649af6ef1..19651c22713 100644 --- a/src/vs/workbench/parts/preferences/browser/media/settingsEditor2.css +++ b/src/vs/workbench/parts/preferences/browser/media/settingsEditor2.css @@ -17,6 +17,7 @@ .settings-editor > .settings-header { box-sizing: border-box; margin: auto; + overflow: hidden; } .settings-editor > .settings-header > .settings-preview-header { @@ -25,6 +26,7 @@ .settings-editor > .settings-header > .settings-preview-header .settings-preview-label { opacity: .7; + white-space: nowrap; } .settings-editor > .settings-header > .settings-preview-header > .settings-preview-warning { From be6914d0cb236488671ed6d4d2435656e0f05d73 Mon Sep 17 00:00:00 2001 From: Rob Lourens Date: Fri, 3 Aug 2018 08:36:59 -0700 Subject: [PATCH 0470/1276] Fix #53897 - revert setting menu defaults to old editor --- .../electron-browser/preferences.contribution.ts | 6 +++--- src/vs/workbench/parts/update/electron-browser/update.ts | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/vs/workbench/parts/preferences/electron-browser/preferences.contribution.ts b/src/vs/workbench/parts/preferences/electron-browser/preferences.contribution.ts index c8ab50f2ba7..00ee94dd845 100644 --- a/src/vs/workbench/parts/preferences/electron-browser/preferences.contribution.ts +++ b/src/vs/workbench/parts/preferences/electron-browser/preferences.contribution.ts @@ -191,8 +191,8 @@ Registry.as(EditorInputExtensions.EditorInputFactor const category = nls.localize('preferences', "Preferences"); const registry = Registry.as(Extensions.WorkbenchActions); registry.registerWorkbenchAction(new SyncActionDescriptor(OpenRawDefaultSettingsAction, OpenRawDefaultSettingsAction.ID, OpenRawDefaultSettingsAction.LABEL), 'Preferences: Open Raw Default Settings', category); -registry.registerWorkbenchAction(new SyncActionDescriptor(OpenSettingsAction, OpenSettingsAction.ID, OpenSettingsAction.LABEL), 'Preferences: Open Settings', category); -registry.registerWorkbenchAction(new SyncActionDescriptor(OpenSettings2Action, OpenSettings2Action.ID, OpenSettings2Action.LABEL, { primary: KeyMod.CtrlCmd | KeyCode.US_COMMA }), 'Preferences: Open Settings (Preview)', category); +registry.registerWorkbenchAction(new SyncActionDescriptor(OpenSettingsAction, OpenSettingsAction.ID, OpenSettingsAction.LABEL, { primary: KeyMod.CtrlCmd | KeyCode.US_COMMA }), 'Preferences: Open Settings', category); +registry.registerWorkbenchAction(new SyncActionDescriptor(OpenSettings2Action, OpenSettings2Action.ID, OpenSettings2Action.LABEL), 'Preferences: Open Settings (Preview)', category); registry.registerWorkbenchAction(new SyncActionDescriptor(OpenGlobalSettingsAction, OpenGlobalSettingsAction.ID, OpenGlobalSettingsAction.LABEL), 'Preferences: Open User Settings', category); registry.registerWorkbenchAction(new SyncActionDescriptor(OpenGlobalKeybindingsAction, OpenGlobalKeybindingsAction.ID, OpenGlobalKeybindingsAction.LABEL, { primary: KeyChord(KeyMod.CtrlCmd | KeyCode.KEY_K, KeyMod.CtrlCmd | KeyCode.KEY_S) }), 'Preferences: Open Keyboard Shortcuts', category); registry.registerWorkbenchAction(new SyncActionDescriptor(OpenDefaultKeybindingsFileAction, OpenDefaultKeybindingsFileAction.ID, OpenDefaultKeybindingsFileAction.LABEL), 'Preferences: Open Default Keyboard Shortcuts File', category); @@ -500,7 +500,7 @@ focusSettingsListCommand.register(); MenuRegistry.appendMenuItem(MenuId.MenubarPreferencesMenu, { group: '1_settings', command: { - id: OpenSettings2Action.ID, + id: OpenSettingsAction.ID, title: nls.localize({ key: 'miOpenSettings', comment: ['&& denotes a mnemonic'] }, "&&Settings") }, order: 1 diff --git a/src/vs/workbench/parts/update/electron-browser/update.ts b/src/vs/workbench/parts/update/electron-browser/update.ts index 941351830b6..2ce9bd83b96 100644 --- a/src/vs/workbench/parts/update/electron-browser/update.ts +++ b/src/vs/workbench/parts/update/electron-browser/update.ts @@ -297,7 +297,7 @@ class CommandAction extends Action { export class UpdateContribution implements IGlobalActivity { private static readonly showCommandsId = 'workbench.action.showCommands'; - private static readonly openSettingsId = 'workbench.action.openSettings2'; + private static readonly openSettingsId = 'workbench.action.openSettings'; private static readonly openKeybindingsId = 'workbench.action.openGlobalKeybindings'; private static readonly openUserSnippets = 'workbench.action.openSnippets'; private static readonly selectColorThemeId = 'workbench.action.selectTheme'; From 6bcabdeefe04924f5194b8240739e1a3685d4eae Mon Sep 17 00:00:00 2001 From: Matt Bierner Date: Fri, 3 Aug 2018 18:06:26 +0200 Subject: [PATCH 0471/1276] Add enum descriptions to `typescript.preferences.importModuleSpecifier` --- extensions/typescript-language-features/package.json | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/extensions/typescript-language-features/package.json b/extensions/typescript-language-features/package.json index f06f35fccc1..41c826ea71b 100644 --- a/extensions/typescript-language-features/package.json +++ b/extensions/typescript-language-features/package.json @@ -485,6 +485,11 @@ "relative", "non-relative" ], + "enumDescriptions": [ + "%typescript.preferences.importModuleSpecifier.auto%", + "%typescript.preferences.importModuleSpecifier.relative%", + "%typescript.preferences.importModuleSpecifier.nonRelative%" + ], "default": "auto", "description": "%typescript.preferences.importModuleSpecifier%", "scope": "resource" From b54c8efedd8f1423f98646e0bf3a835e9f981480 Mon Sep 17 00:00:00 2001 From: Rob Lourens Date: Fri, 3 Aug 2018 09:48:12 -0700 Subject: [PATCH 0472/1276] Fix #55767 - leaking style elements from settings editor --- src/vs/workbench/parts/preferences/browser/settingsTree.ts | 2 +- src/vs/workbench/parts/preferences/browser/tocTree.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/vs/workbench/parts/preferences/browser/settingsTree.ts b/src/vs/workbench/parts/preferences/browser/settingsTree.ts index 15520d791e1..8db86095977 100644 --- a/src/vs/workbench/parts/preferences/browser/settingsTree.ts +++ b/src/vs/workbench/parts/preferences/browser/settingsTree.ts @@ -1468,7 +1468,7 @@ export class SettingsTree extends NonExpandableTree { controller, accessibilityProvider: instantiationService.createInstance(SettingsAccessibilityProvider), filter: instantiationService.createInstance(SettingsTreeFilter, viewState), - styler: new DefaultTreestyler(DOM.createStyleSheet(), treeClass), + styler: new DefaultTreestyler(DOM.createStyleSheet(container), treeClass), ...configuration }; diff --git a/src/vs/workbench/parts/preferences/browser/tocTree.ts b/src/vs/workbench/parts/preferences/browser/tocTree.ts index f6d79fd69eb..3f1d29fdde6 100644 --- a/src/vs/workbench/parts/preferences/browser/tocTree.ts +++ b/src/vs/workbench/parts/preferences/browser/tocTree.ts @@ -169,7 +169,7 @@ export class TOCTree extends WorkbenchTree { const fullConfiguration = { controller: instantiationService.createInstance(WorkbenchTreeController, { openMode: OpenMode.DOUBLE_CLICK }), filter: instantiationService.createInstance(SettingsTreeFilter, viewState), - styler: new DefaultTreestyler(DOM.createStyleSheet(), treeClass), + styler: new DefaultTreestyler(DOM.createStyleSheet(container), treeClass), dataSource: instantiationService.createInstance(TOCDataSource), accessibilityProvider: instantiationService.createInstance(SettingsAccessibilityProvider), From 841456f04898fe94e9bc5529e9c8476da4b1ea3c Mon Sep 17 00:00:00 2001 From: Rob Lourens Date: Fri, 3 Aug 2018 10:16:55 -0700 Subject: [PATCH 0473/1276] Fix #55521 - prevent flashing when clicking in exclude control --- .../preferences/browser/settingsWidgets.ts | 20 ++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) diff --git a/src/vs/workbench/parts/preferences/browser/settingsWidgets.ts b/src/vs/workbench/parts/preferences/browser/settingsWidgets.ts index ee1a2e61104..16c7dc7ad40 100644 --- a/src/vs/workbench/parts/preferences/browser/settingsWidgets.ts +++ b/src/vs/workbench/parts/preferences/browser/settingsWidgets.ts @@ -89,7 +89,7 @@ registerThemingParticipant((theme: ITheme, collector: ICssStyleCollector) => { const listSelectBackgroundColor = theme.getColor(listActiveSelectionBackground); if (listSelectBackgroundColor) { - collector.addRule(`.settings-editor > .settings-body > .settings-tree-container .setting-item.setting-item-exclude .setting-exclude-row:focus { background-color: ${listSelectBackgroundColor}; }`); + collector.addRule(`.settings-editor > .settings-body > .settings-tree-container .setting-item.setting-item-exclude .setting-exclude-row.selected:focus { background-color: ${listSelectBackgroundColor}; }`); } const listInactiveSelectionBackgroundColor = theme.getColor(listInactiveSelectionBackground); @@ -104,7 +104,7 @@ registerThemingParticipant((theme: ITheme, collector: ICssStyleCollector) => { const listSelectForegroundColor = theme.getColor(listActiveSelectionForeground); if (listSelectForegroundColor) { - collector.addRule(`.settings-editor > .settings-body > .settings-tree-container .setting-item.setting-item-exclude .setting-exclude-row.selected { color: ${listSelectForegroundColor}; }`); + collector.addRule(`.settings-editor > .settings-body > .settings-tree-container .setting-item.setting-item-exclude .setting-exclude-row.selected:focus { color: ${listSelectForegroundColor}; }`); } const codeTextForegroundColor = theme.getColor(textPreformatForeground); @@ -152,6 +152,10 @@ export class ExcludeSettingListModel { this._selectedIdx = idx; } + getSelected(): number { + return this._selectedIdx; + } + selectNext(): void { if (typeof this._selectedIdx === 'number') { this._selectedIdx = Math.min(this._selectedIdx + 1, this._dataItems.length - 1); @@ -206,12 +210,18 @@ export class ExcludeSettingWidget extends Disposable { return; } - const targetIdx = element.getAttribute('data-index'); - if (!targetIdx) { + const targetIdxStr = element.getAttribute('data-index'); + if (!targetIdxStr) { return; } - this.model.select(parseInt(targetIdx)); + const targetIdx = parseInt(targetIdxStr); + + if (this.model.getSelected() === targetIdx) { + return; + } + + this.model.select(targetIdx); this.renderList(); e.preventDefault(); e.stopPropagation(); From e275a424483dfb4ed33b428c97d5e2c441d6b917 Mon Sep 17 00:00:00 2001 From: Miguel Solorio Date: Fri, 3 Aug 2018 10:37:35 -0700 Subject: [PATCH 0474/1276] Update Git modified color for contrast ratio, fixes #53140 --- extensions/git/package.json | 2 +- src/vs/platform/theme/common/colorRegistry.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/extensions/git/package.json b/extensions/git/package.json index 5a329452b34..371637af774 100644 --- a/extensions/git/package.json +++ b/extensions/git/package.json @@ -1054,7 +1054,7 @@ "id": "gitDecoration.modifiedResourceForeground", "description": "%colors.modified%", "defaults": { - "light": "#a76e12", + "light": "#895503", "dark": "#E2C08D", "highContrast": "#E2C08D" } diff --git a/src/vs/platform/theme/common/colorRegistry.ts b/src/vs/platform/theme/common/colorRegistry.ts index f4404ffd508..b1543ed3d2f 100644 --- a/src/vs/platform/theme/common/colorRegistry.ts +++ b/src/vs/platform/theme/common/colorRegistry.ts @@ -195,7 +195,7 @@ export const listFocusBackground = registerColor('list.focusBackground', { dark: export const listFocusForeground = registerColor('list.focusForeground', { dark: null, light: null, hc: null }, nls.localize('listFocusForeground', "List/Tree foreground color for the focused item when the list/tree is active. An active list/tree has keyboard focus, an inactive does not.")); export const listActiveSelectionBackground = registerColor('list.activeSelectionBackground', { dark: '#094771', light: '#2477CE', hc: null }, nls.localize('listActiveSelectionBackground', "List/Tree background color for the selected item when the list/tree is active. An active list/tree has keyboard focus, an inactive does not.")); export const listActiveSelectionForeground = registerColor('list.activeSelectionForeground', { dark: Color.white, light: Color.white, hc: null }, nls.localize('listActiveSelectionForeground', "List/Tree foreground color for the selected item when the list/tree is active. An active list/tree has keyboard focus, an inactive does not.")); -export const listInactiveSelectionBackground = registerColor('list.inactiveSelectionBackground', { dark: '#37373D', light: '#CCCEDB', hc: null }, nls.localize('listInactiveSelectionBackground', "List/Tree background color for the selected item when the list/tree is inactive. An active list/tree has keyboard focus, an inactive does not.")); +export const listInactiveSelectionBackground = registerColor('list.inactiveSelectionBackground', { dark: '#37373D', light: '#dddfea', hc: null }, nls.localize('listInactiveSelectionBackground', "List/Tree background color for the selected item when the list/tree is inactive. An active list/tree has keyboard focus, an inactive does not.")); export const listInactiveSelectionForeground = registerColor('list.inactiveSelectionForeground', { dark: null, light: null, hc: null }, nls.localize('listInactiveSelectionForeground', "List/Tree foreground color for the selected item when the list/tree is inactive. An active list/tree has keyboard focus, an inactive does not.")); export const listInactiveFocusBackground = registerColor('list.inactiveFocusBackground', { dark: '#313135', light: '#d8dae6', hc: null }, nls.localize('listInactiveFocusBackground', "List/Tree background color for the focused item when the list/tree is inactive. An active list/tree has keyboard focus, an inactive does not.")); export const listHoverBackground = registerColor('list.hoverBackground', { dark: '#2A2D2E', light: '#F0F0F0', hc: null }, nls.localize('listHoverBackground', "List/Tree background when hovering over items using the mouse.")); From 53949d963f39e40757557c6526332354a31d9154 Mon Sep 17 00:00:00 2001 From: Miguel Solorio Date: Fri, 3 Aug 2018 10:38:35 -0700 Subject: [PATCH 0475/1276] Revert "Merge branch 'master' of github.com:Microsoft/vscode" This reverts commit bf46b6bfbae0cab99c2863e1244a916181fa9fbc, reversing changes made to e275a424483dfb4ed33b428c97d5e2c441d6b917. --- .../parts/preferences/browser/settingsTree.ts | 2 +- .../preferences/browser/settingsWidgets.ts | 20 +++++-------------- .../parts/preferences/browser/tocTree.ts | 2 +- 3 files changed, 7 insertions(+), 17 deletions(-) diff --git a/src/vs/workbench/parts/preferences/browser/settingsTree.ts b/src/vs/workbench/parts/preferences/browser/settingsTree.ts index 8db86095977..15520d791e1 100644 --- a/src/vs/workbench/parts/preferences/browser/settingsTree.ts +++ b/src/vs/workbench/parts/preferences/browser/settingsTree.ts @@ -1468,7 +1468,7 @@ export class SettingsTree extends NonExpandableTree { controller, accessibilityProvider: instantiationService.createInstance(SettingsAccessibilityProvider), filter: instantiationService.createInstance(SettingsTreeFilter, viewState), - styler: new DefaultTreestyler(DOM.createStyleSheet(container), treeClass), + styler: new DefaultTreestyler(DOM.createStyleSheet(), treeClass), ...configuration }; diff --git a/src/vs/workbench/parts/preferences/browser/settingsWidgets.ts b/src/vs/workbench/parts/preferences/browser/settingsWidgets.ts index 16c7dc7ad40..ee1a2e61104 100644 --- a/src/vs/workbench/parts/preferences/browser/settingsWidgets.ts +++ b/src/vs/workbench/parts/preferences/browser/settingsWidgets.ts @@ -89,7 +89,7 @@ registerThemingParticipant((theme: ITheme, collector: ICssStyleCollector) => { const listSelectBackgroundColor = theme.getColor(listActiveSelectionBackground); if (listSelectBackgroundColor) { - collector.addRule(`.settings-editor > .settings-body > .settings-tree-container .setting-item.setting-item-exclude .setting-exclude-row.selected:focus { background-color: ${listSelectBackgroundColor}; }`); + collector.addRule(`.settings-editor > .settings-body > .settings-tree-container .setting-item.setting-item-exclude .setting-exclude-row:focus { background-color: ${listSelectBackgroundColor}; }`); } const listInactiveSelectionBackgroundColor = theme.getColor(listInactiveSelectionBackground); @@ -104,7 +104,7 @@ registerThemingParticipant((theme: ITheme, collector: ICssStyleCollector) => { const listSelectForegroundColor = theme.getColor(listActiveSelectionForeground); if (listSelectForegroundColor) { - collector.addRule(`.settings-editor > .settings-body > .settings-tree-container .setting-item.setting-item-exclude .setting-exclude-row.selected:focus { color: ${listSelectForegroundColor}; }`); + collector.addRule(`.settings-editor > .settings-body > .settings-tree-container .setting-item.setting-item-exclude .setting-exclude-row.selected { color: ${listSelectForegroundColor}; }`); } const codeTextForegroundColor = theme.getColor(textPreformatForeground); @@ -152,10 +152,6 @@ export class ExcludeSettingListModel { this._selectedIdx = idx; } - getSelected(): number { - return this._selectedIdx; - } - selectNext(): void { if (typeof this._selectedIdx === 'number') { this._selectedIdx = Math.min(this._selectedIdx + 1, this._dataItems.length - 1); @@ -210,18 +206,12 @@ export class ExcludeSettingWidget extends Disposable { return; } - const targetIdxStr = element.getAttribute('data-index'); - if (!targetIdxStr) { + const targetIdx = element.getAttribute('data-index'); + if (!targetIdx) { return; } - const targetIdx = parseInt(targetIdxStr); - - if (this.model.getSelected() === targetIdx) { - return; - } - - this.model.select(targetIdx); + this.model.select(parseInt(targetIdx)); this.renderList(); e.preventDefault(); e.stopPropagation(); diff --git a/src/vs/workbench/parts/preferences/browser/tocTree.ts b/src/vs/workbench/parts/preferences/browser/tocTree.ts index 3f1d29fdde6..f6d79fd69eb 100644 --- a/src/vs/workbench/parts/preferences/browser/tocTree.ts +++ b/src/vs/workbench/parts/preferences/browser/tocTree.ts @@ -169,7 +169,7 @@ export class TOCTree extends WorkbenchTree { const fullConfiguration = { controller: instantiationService.createInstance(WorkbenchTreeController, { openMode: OpenMode.DOUBLE_CLICK }), filter: instantiationService.createInstance(SettingsTreeFilter, viewState), - styler: new DefaultTreestyler(DOM.createStyleSheet(container), treeClass), + styler: new DefaultTreestyler(DOM.createStyleSheet(), treeClass), dataSource: instantiationService.createInstance(TOCDataSource), accessibilityProvider: instantiationService.createInstance(SettingsAccessibilityProvider), From dbd9ef149b045c2beac00b97297f37b96e6f9adb Mon Sep 17 00:00:00 2001 From: Miguel Solorio Date: Fri, 3 Aug 2018 10:46:50 -0700 Subject: [PATCH 0476/1276] Revert "Revert "Merge branch 'master' of github.com:Microsoft/vscode"" This reverts commit 53949d963f39e40757557c6526332354a31d9154. --- .../parts/preferences/browser/settingsTree.ts | 2 +- .../preferences/browser/settingsWidgets.ts | 20 ++++++++++++++----- .../parts/preferences/browser/tocTree.ts | 2 +- 3 files changed, 17 insertions(+), 7 deletions(-) diff --git a/src/vs/workbench/parts/preferences/browser/settingsTree.ts b/src/vs/workbench/parts/preferences/browser/settingsTree.ts index 15520d791e1..8db86095977 100644 --- a/src/vs/workbench/parts/preferences/browser/settingsTree.ts +++ b/src/vs/workbench/parts/preferences/browser/settingsTree.ts @@ -1468,7 +1468,7 @@ export class SettingsTree extends NonExpandableTree { controller, accessibilityProvider: instantiationService.createInstance(SettingsAccessibilityProvider), filter: instantiationService.createInstance(SettingsTreeFilter, viewState), - styler: new DefaultTreestyler(DOM.createStyleSheet(), treeClass), + styler: new DefaultTreestyler(DOM.createStyleSheet(container), treeClass), ...configuration }; diff --git a/src/vs/workbench/parts/preferences/browser/settingsWidgets.ts b/src/vs/workbench/parts/preferences/browser/settingsWidgets.ts index ee1a2e61104..16c7dc7ad40 100644 --- a/src/vs/workbench/parts/preferences/browser/settingsWidgets.ts +++ b/src/vs/workbench/parts/preferences/browser/settingsWidgets.ts @@ -89,7 +89,7 @@ registerThemingParticipant((theme: ITheme, collector: ICssStyleCollector) => { const listSelectBackgroundColor = theme.getColor(listActiveSelectionBackground); if (listSelectBackgroundColor) { - collector.addRule(`.settings-editor > .settings-body > .settings-tree-container .setting-item.setting-item-exclude .setting-exclude-row:focus { background-color: ${listSelectBackgroundColor}; }`); + collector.addRule(`.settings-editor > .settings-body > .settings-tree-container .setting-item.setting-item-exclude .setting-exclude-row.selected:focus { background-color: ${listSelectBackgroundColor}; }`); } const listInactiveSelectionBackgroundColor = theme.getColor(listInactiveSelectionBackground); @@ -104,7 +104,7 @@ registerThemingParticipant((theme: ITheme, collector: ICssStyleCollector) => { const listSelectForegroundColor = theme.getColor(listActiveSelectionForeground); if (listSelectForegroundColor) { - collector.addRule(`.settings-editor > .settings-body > .settings-tree-container .setting-item.setting-item-exclude .setting-exclude-row.selected { color: ${listSelectForegroundColor}; }`); + collector.addRule(`.settings-editor > .settings-body > .settings-tree-container .setting-item.setting-item-exclude .setting-exclude-row.selected:focus { color: ${listSelectForegroundColor}; }`); } const codeTextForegroundColor = theme.getColor(textPreformatForeground); @@ -152,6 +152,10 @@ export class ExcludeSettingListModel { this._selectedIdx = idx; } + getSelected(): number { + return this._selectedIdx; + } + selectNext(): void { if (typeof this._selectedIdx === 'number') { this._selectedIdx = Math.min(this._selectedIdx + 1, this._dataItems.length - 1); @@ -206,12 +210,18 @@ export class ExcludeSettingWidget extends Disposable { return; } - const targetIdx = element.getAttribute('data-index'); - if (!targetIdx) { + const targetIdxStr = element.getAttribute('data-index'); + if (!targetIdxStr) { return; } - this.model.select(parseInt(targetIdx)); + const targetIdx = parseInt(targetIdxStr); + + if (this.model.getSelected() === targetIdx) { + return; + } + + this.model.select(targetIdx); this.renderList(); e.preventDefault(); e.stopPropagation(); diff --git a/src/vs/workbench/parts/preferences/browser/tocTree.ts b/src/vs/workbench/parts/preferences/browser/tocTree.ts index f6d79fd69eb..3f1d29fdde6 100644 --- a/src/vs/workbench/parts/preferences/browser/tocTree.ts +++ b/src/vs/workbench/parts/preferences/browser/tocTree.ts @@ -169,7 +169,7 @@ export class TOCTree extends WorkbenchTree { const fullConfiguration = { controller: instantiationService.createInstance(WorkbenchTreeController, { openMode: OpenMode.DOUBLE_CLICK }), filter: instantiationService.createInstance(SettingsTreeFilter, viewState), - styler: new DefaultTreestyler(DOM.createStyleSheet(), treeClass), + styler: new DefaultTreestyler(DOM.createStyleSheet(container), treeClass), dataSource: instantiationService.createInstance(TOCDataSource), accessibilityProvider: instantiationService.createInstance(SettingsAccessibilityProvider), From e30a864fe80e6e032e87417afa4cf6ecf14ad4ef Mon Sep 17 00:00:00 2001 From: SteVen Batten Date: Fri, 3 Aug 2018 10:51:51 -0700 Subject: [PATCH 0477/1276] don't ask to install an incomplete menu --- .../browser/parts/menubar/menubarPart.ts | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/src/vs/workbench/browser/parts/menubar/menubarPart.ts b/src/vs/workbench/browser/parts/menubar/menubarPart.ts index 46774c5684f..7bae0b21225 100644 --- a/src/vs/workbench/browser/parts/menubar/menubarPart.ts +++ b/src/vs/workbench/browser/parts/menubar/menubarPart.ts @@ -424,7 +424,10 @@ export class MenubarPart extends Part { this.setupCustomMenubar(); } else { // Send menus to main process to be rendered by Electron - this.menubarService.updateMenubar(this.windowService.getCurrentWindowId(), this.getMenubarMenus(), this.getAdditionalKeybindings()); + const menubarData = {}; + if (this.getMenubarMenus(menubarData)) { + this.menubarService.updateMenubar(this.windowService.getCurrentWindowId(), menubarData, this.getAdditionalKeybindings()); + } } } @@ -901,17 +904,23 @@ export class MenubarPart extends Part { return keybindings; } - private getMenubarMenus(): IMenubarData { - let ret: IMenubarData = {}; + private getMenubarMenus(menubarData: IMenubarData): boolean { + if (!menubarData) { + return false; + } for (let topLevelMenuName of Object.keys(this.topLevelMenus)) { const menu = this.topLevelMenus[topLevelMenuName]; let menubarMenu: IMenubarMenu = { items: [] }; this.populateMenuItems(menu, menubarMenu); - ret[topLevelMenuName] = menubarMenu; + if (menubarMenu.items.length === 0) { + // Menus are incomplete + return false; + } + menubarData[topLevelMenuName] = menubarMenu; } - return ret; + return true; } private isCurrentMenu(menuIndex: number): boolean { From 1e45ce6add2ac86c2a6e214aa84c85281df1814b Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Fri, 3 Aug 2018 11:19:03 -0700 Subject: [PATCH 0478/1276] Fix NPE in terminal AccessibilityManager Fixes #55744 --- package.json | 2 +- yarn.lock | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/package.json b/package.json index 09ccdd7cc59..4a4588e38b3 100644 --- a/package.json +++ b/package.json @@ -50,7 +50,7 @@ "vscode-nsfw": "1.0.17", "vscode-ripgrep": "^1.0.1", "vscode-textmate": "^4.0.1", - "vscode-xterm": "3.6.0-beta12", + "vscode-xterm": "3.6.0-beta13", "yauzl": "^2.9.1" }, "devDependencies": { diff --git a/yarn.lock b/yarn.lock index a9e1b428b8a..b0b61b7a439 100644 --- a/yarn.lock +++ b/yarn.lock @@ -6125,9 +6125,9 @@ vscode-textmate@^4.0.1: dependencies: oniguruma "^7.0.0" -vscode-xterm@3.6.0-beta12: - version "3.6.0-beta12" - resolved "https://registry.yarnpkg.com/vscode-xterm/-/vscode-xterm-3.6.0-beta12.tgz#ae99dedecf7f354777ab5a4e37a86cfd975adf1f" +vscode-xterm@3.6.0-beta13: + version "3.6.0-beta13" + resolved "https://registry.yarnpkg.com/vscode-xterm/-/vscode-xterm-3.6.0-beta13.tgz#88c511041beb9f84fa63ed52fec074c5ccaff296" vso-node-api@^6.1.2-preview: version "6.1.2-preview" From 1a1b92fbd020353051b51d2efa2dd88a63416a26 Mon Sep 17 00:00:00 2001 From: SteVen Batten Date: Fri, 3 Aug 2018 11:37:57 -0700 Subject: [PATCH 0479/1276] don't display fallback menu unless we've closed the last window --- src/vs/code/electron-main/menubar.ts | 21 ++++++++++++------- src/vs/platform/actions/common/actions.ts | 1 - .../browser/parts/menubar/menubarPart.ts | 3 +-- 3 files changed, 15 insertions(+), 10 deletions(-) diff --git a/src/vs/code/electron-main/menubar.ts b/src/vs/code/electron-main/menubar.ts index 469b2ab76ee..bd9aceb6879 100644 --- a/src/vs/code/electron-main/menubar.ts +++ b/src/vs/code/electron-main/menubar.ts @@ -31,12 +31,13 @@ export class Menubar { private static readonly MAX_MENU_RECENT_ENTRIES = 10; private isQuitting: boolean; private appMenuInstalled: boolean; + private closedLastWindow: boolean; private menuUpdater: RunOnceScheduler; private nativeTabMenuItems: Electron.MenuItem[]; - private menubarMenus: IMenubarData = {}; + private menubarMenus: IMenubarData; private keybindings: { [commandId: string]: IMenubarKeybinding }; @@ -54,6 +55,8 @@ export class Menubar { this.keybindings = Object.create(null); + this.closedLastWindow = false; + this.install(); this.registerListeners(); @@ -149,9 +152,9 @@ export class Menubar { return; } - // Update menu if window count goes from N > 0 or 0 > N to update menu item enablement if ((e.oldCount === 0 && e.newCount > 0) || (e.oldCount > 0 && e.newCount === 0)) { + this.closedLastWindow = e.newCount === 0; this.scheduleUpdateMenu(); } @@ -379,18 +382,22 @@ export class Menubar { switch (menuId) { case 'File': - case 'Window': case 'Help': if (isMacintosh) { - return this.windowsMainService.getWindowCount() === 0 || !!this.menubarMenus[menuId]; + return (this.windowsMainService.getWindowCount() === 0 && this.closedLastWindow) || (!!this.menubarMenus && !!this.menubarMenus[menuId]); + } + break; + case 'Window': + if (isMacintosh) { + return (this.windowsMainService.getWindowCount() === 0 && this.closedLastWindow) || !!this.menubarMenus; } default: - return this.windowsMainService.getWindowCount() > 0 && !!this.menubarMenus[menuId]; + return this.windowsMainService.getWindowCount() > 0 && (!!this.menubarMenus && !!this.menubarMenus[menuId]); } } private shouldFallback(menuId: string): boolean { - return this.shouldDrawMenu(menuId) && (this.windowsMainService.getWindowCount() === 0 && isMacintosh); + return this.shouldDrawMenu(menuId) && (this.windowsMainService.getWindowCount() === 0 && this.closedLastWindow && isMacintosh); } private setFallbackMenuById(menu: Electron.Menu, menuId: string): void { @@ -520,7 +527,7 @@ export class Menubar { } private setMenuById(menu: Electron.Menu, menuId: string): void { - if (this.menubarMenus[menuId]) { + if (this.menubarMenus && this.menubarMenus[menuId]) { this.setMenu(menu, this.menubarMenus[menuId].items); } } diff --git a/src/vs/platform/actions/common/actions.ts b/src/vs/platform/actions/common/actions.ts index 21c79a07b8c..f0ba370d22d 100644 --- a/src/vs/platform/actions/common/actions.ts +++ b/src/vs/platform/actions/common/actions.ts @@ -98,7 +98,6 @@ export class MenuId { static readonly MenubarDebugMenu = new MenuId(); static readonly MenubarNewBreakpointMenu = new MenuId(); static readonly MenubarTasksMenu = new MenuId(); - static readonly MenubarWindowMenu = new MenuId(); static readonly MenubarPreferencesMenu = new MenuId(); static readonly MenubarHelpMenu = new MenuId(); static readonly MenubarTerminalMenu = new MenuId(); diff --git a/src/vs/workbench/browser/parts/menubar/menubarPart.ts b/src/vs/workbench/browser/parts/menubar/menubarPart.ts index 7bae0b21225..b0cbfbf570f 100644 --- a/src/vs/workbench/browser/parts/menubar/menubarPart.ts +++ b/src/vs/workbench/browser/parts/menubar/menubarPart.ts @@ -62,7 +62,7 @@ export class MenubarPart extends Part { 'workbench.statusBar.visible', 'workbench.activityBar.visible', 'window.enableMenuBarMnemonics', - // 'window.nativeTabs' + 'window.nativeTabs' ]; private topLevelMenus: { @@ -143,7 +143,6 @@ export class MenubarPart extends Part { if (isMacintosh) { this.topLevelMenus['Preferences'] = this._register(this.menuService.createMenu(MenuId.MenubarPreferencesMenu, this.contextKeyService)); - this.topLevelMenus['Window'] = this._register(this.menuService.createMenu(MenuId.MenubarWindowMenu, this.contextKeyService)); } this.menuUpdater = this._register(new RunOnceScheduler(() => this.doSetupMenubar(), 100)); From 38eca13f92d3118c714c0b37641219e21a7943a8 Mon Sep 17 00:00:00 2001 From: SteVen Batten Date: Fri, 3 Aug 2018 13:29:11 -0700 Subject: [PATCH 0480/1276] fixes #55547 --- src/vs/code/electron-main/menubar.ts | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/src/vs/code/electron-main/menubar.ts b/src/vs/code/electron-main/menubar.ts index bd9aceb6879..b4bd6f0412b 100644 --- a/src/vs/code/electron-main/menubar.ts +++ b/src/vs/code/electron-main/menubar.ts @@ -386,11 +386,12 @@ export class Menubar { if (isMacintosh) { return (this.windowsMainService.getWindowCount() === 0 && this.closedLastWindow) || (!!this.menubarMenus && !!this.menubarMenus[menuId]); } - break; + case 'Window': if (isMacintosh) { return (this.windowsMainService.getWindowCount() === 0 && this.closedLastWindow) || !!this.menubarMenus; } + default: return this.windowsMainService.getWindowCount() > 0 && (!!this.menubarMenus && !!this.menubarMenus[menuId]); } @@ -482,16 +483,12 @@ export class Menubar { }); } - const openProcessExplorer = new MenuItem({ label: this.mnemonicLabel(nls.localize({ key: 'miOpenProcessExplorerer', comment: ['&& denotes a mnemonic'] }, "Open &&Process Explorer")), click: () => this.runActionInRenderer('workbench.action.openProcessExplorer') }); - if (twitterItem) { menu.append(twitterItem); } if (featureRequestsItem) { menu.append(featureRequestsItem); } if (reportIssuesItem) { menu.append(reportIssuesItem); } - if (twitterItem || featureRequestsItem || reportIssuesItem) { menu.append(__separator__()); } + if ((twitterItem || featureRequestsItem || reportIssuesItem) && (licenseItem || privacyStatementItem)) { menu.append(__separator__()); } if (licenseItem) { menu.append(licenseItem); } if (privacyStatementItem) { menu.append(privacyStatementItem); } - if (licenseItem || privacyStatementItem) { menu.append(__separator__()); } - menu.append(openProcessExplorer); break; } From ea8d5a4b221d22ad2d826a314403f83c3a9b0e28 Mon Sep 17 00:00:00 2001 From: Ramya Achutha Rao Date: Fri, 3 Aug 2018 15:51:58 -0700 Subject: [PATCH 0481/1276] Fix smoke tests for extension search box --- test/smoke/src/areas/extensions/extensions.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/smoke/src/areas/extensions/extensions.ts b/test/smoke/src/areas/extensions/extensions.ts index c904df46862..be72895ae26 100644 --- a/test/smoke/src/areas/extensions/extensions.ts +++ b/test/smoke/src/areas/extensions/extensions.ts @@ -6,7 +6,7 @@ import { Viewlet } from '../workbench/viewlet'; import { Code } from '../../vscode/code'; -const SEARCH_BOX = 'div.extensions-viewlet[id="workbench.view.extensions"] input.search-box'; +const SEARCH_BOX = 'div.extensions-viewlet[id="workbench.view.extensions"] .monaco-editor textarea'; export class Extensions extends Viewlet { @@ -27,7 +27,7 @@ export class Extensions extends Viewlet { async searchForExtension(name: string): Promise { await this.code.waitAndClick(SEARCH_BOX); await this.code.waitForActiveElement(SEARCH_BOX); - await this.code.waitForSetValue(SEARCH_BOX, `name:"${name}"`); + await this.code.waitForTypeInEditor(SEARCH_BOX, `name:"${name}"`); } async installExtension(name: string): Promise { From 11567e39f5bd9a56685bd72703043b511bc546f4 Mon Sep 17 00:00:00 2001 From: SteVen Batten Date: Fri, 3 Aug 2018 17:10:32 -0700 Subject: [PATCH 0482/1276] update version to 1.27.0 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 4a4588e38b3..4259bb0eeac 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "code-oss-dev", - "version": "1.26.0", + "version": "1.27.0", "distro": "26814526269ba3caa2e8c501de9626ad266eadd3", "author": { "name": "Microsoft Corporation" From 374c626c06abc8c3bf4005b1b461d31398a085a5 Mon Sep 17 00:00:00 2001 From: Alexandr Fadeev Date: Sun, 5 Aug 2018 00:06:16 +0300 Subject: [PATCH 0483/1276] Tests about to check the improvements: ${}, $$, and $(shell ()). Current issue: https://github.com/Microsoft/vscode/issues/55256, "[makefile] highlighting issues with variable definitions and shell commands". --- .../make/test/colorize-fixtures/makefile | 17 +- .../make/test/colorize-results/makefile.json | 594 ++++++++++++++++++ 2 files changed, 610 insertions(+), 1 deletion(-) diff --git a/extensions/make/test/colorize-fixtures/makefile b/extensions/make/test/colorize-fixtures/makefile index 5d01e6a16e3..74f93dd5d1c 100644 --- a/extensions/make/test/colorize-fixtures/makefile +++ b/extensions/make/test/colorize-fixtures/makefile @@ -25,6 +25,10 @@ hello.o: hello.cpp \ clean: rm *o hello +all: + # "$$" in a shell means to escape makefile's variable substitution. + some_shell_var=$$(sed -nre 's/some regex with (group)/\1/p') + define defined $(info Checking existance of $(1) $(flavor $(1))) $(if $(filter undefined,$(flavor $(1))),0,1) @@ -38,4 +42,15 @@ endif ifeq ($(strip $(call defined,CODIT_DIR)),0) $(info CODIT_DIR must be set in $(TOP_DIR)3rdparty.mk) -endif \ No newline at end of file +endif + +CXXVER_GE480 := $(shell expr `$(CXX) -dumpversion | sed -e 's/\.\([0-9][0-9]\)/\1/g' -e 's/\.\([0-9]\)/0\1/g' -e 's/^[0-9]\{3,4\}$$/&00/'` \>= 40800) + +ok := ok +$(info Braces {} in parentheses ({}): ${ok}) +${info Parentheses () in braces {()}: $(ok)} + +ifeq ("${ok}", "skip") + $(ok))} + ${ok}}) +endif diff --git a/extensions/make/test/colorize-results/makefile.json b/extensions/make/test/colorize-results/makefile.json index 6fbce98489a..523f2b6a050 100644 --- a/extensions/make/test/colorize-results/makefile.json +++ b/extensions/make/test/colorize-results/makefile.json @@ -692,6 +692,127 @@ "hc_black": "default: #FFFFFF" } }, + { + "c": "all", + "t": "source.makefile meta.scope.target.makefile entity.name.function.target.makefile", + "r": { + "dark_plus": "entity.name.function: #DCDCAA", + "light_plus": "entity.name.function: #795E26", + "dark_vs": "default: #D4D4D4", + "light_vs": "default: #000000", + "hc_black": "entity.name.function: #DCDCAA" + } + }, + { + "c": ":", + "t": "source.makefile meta.scope.target.makefile punctuation.separator.key-value.makefile", + "r": { + "dark_plus": "default: #D4D4D4", + "light_plus": "default: #000000", + "dark_vs": "default: #D4D4D4", + "light_vs": "default: #000000", + "hc_black": "default: #FFFFFF" + } + }, + { + "c": "\t", + "t": "source.makefile punctuation.whitespace.comment.leading.makefile", + "r": { + "dark_plus": "default: #D4D4D4", + "light_plus": "default: #000000", + "dark_vs": "default: #D4D4D4", + "light_vs": "default: #000000", + "hc_black": "default: #FFFFFF" + } + }, + { + "c": "#", + "t": "source.makefile comment.line.number-sign.makefile punctuation.definition.comment.makefile", + "r": { + "dark_plus": "comment: #6A9955", + "light_plus": "comment: #008000", + "dark_vs": "comment: #6A9955", + "light_vs": "comment: #008000", + "hc_black": "comment: #7CA668" + } + }, + { + "c": " \"$$\" in a shell means to escape makefile's variable substitution.", + "t": "source.makefile comment.line.number-sign.makefile", + "r": { + "dark_plus": "comment: #6A9955", + "light_plus": "comment: #008000", + "dark_vs": "comment: #6A9955", + "light_vs": "comment: #008000", + "hc_black": "comment: #7CA668" + } + }, + { + "c": "\tsome_shell_var=", + "t": "source.makefile", + "r": { + "dark_plus": "default: #D4D4D4", + "light_plus": "default: #000000", + "dark_vs": "default: #D4D4D4", + "light_vs": "default: #000000", + "hc_black": "default: #FFFFFF" + } + }, + { + "c": "$$", + "t": "source.makefile variable.language.makefile", + "r": { + "dark_plus": "variable.language: #569CD6", + "light_plus": "variable.language: #0000FF", + "dark_vs": "variable.language: #569CD6", + "light_vs": "variable.language: #0000FF", + "hc_black": "variable: #9CDCFE" + } + }, + { + "c": "(", + "t": "source.makefile string.interpolated.makefile punctuation.definition.variable.makefile", + "r": { + "dark_plus": "string: #CE9178", + "light_plus": "string: #A31515", + "dark_vs": "string: #CE9178", + "light_vs": "string: #A31515", + "hc_black": "string: #CE9178" + } + }, + { + "c": "sed -nre 's/some regex with (group", + "t": "source.makefile string.interpolated.makefile variable.other.makefile", + "r": { + "dark_plus": "variable: #9CDCFE", + "light_plus": "variable: #001080", + "dark_vs": "string: #CE9178", + "light_vs": "string: #A31515", + "hc_black": "variable: #9CDCFE" + } + }, + { + "c": ")", + "t": "source.makefile string.interpolated.makefile punctuation.definition.variable.makefile", + "r": { + "dark_plus": "string: #CE9178", + "light_plus": "string: #A31515", + "dark_vs": "string: #CE9178", + "light_vs": "string: #A31515", + "hc_black": "string: #CE9178" + } + }, + { + "c": "/\\1/p')", + "t": "source.makefile", + "r": { + "dark_plus": "default: #D4D4D4", + "light_plus": "default: #000000", + "dark_vs": "default: #D4D4D4", + "light_vs": "default: #000000", + "hc_black": "default: #FFFFFF" + } + }, { "c": "define", "t": "source.makefile meta.scope.conditional.makefile keyword.control.define.makefile", @@ -1572,6 +1693,479 @@ "hc_black": "string: #CE9178" } }, + { + "c": "endif", + "t": "source.makefile meta.scope.conditional.makefile keyword.control.endif.makefile", + "r": { + "dark_plus": "keyword.control: #C586C0", + "light_plus": "keyword.control: #AF00DB", + "dark_vs": "keyword.control: #569CD6", + "light_vs": "keyword.control: #0000FF", + "hc_black": "keyword.control: #C586C0" + } + }, + { + "c": "CXXVER_GE480", + "t": "source.makefile variable.other.makefile", + "r": { + "dark_plus": "variable: #9CDCFE", + "light_plus": "variable: #001080", + "dark_vs": "default: #D4D4D4", + "light_vs": "default: #000000", + "hc_black": "variable: #9CDCFE" + } + }, + { + "c": " ", + "t": "source.makefile", + "r": { + "dark_plus": "default: #D4D4D4", + "light_plus": "default: #000000", + "dark_vs": "default: #D4D4D4", + "light_vs": "default: #000000", + "hc_black": "default: #FFFFFF" + } + }, + { + "c": ":=", + "t": "source.makefile punctuation.separator.key-value.makefile", + "r": { + "dark_plus": "default: #D4D4D4", + "light_plus": "default: #000000", + "dark_vs": "default: #D4D4D4", + "light_vs": "default: #000000", + "hc_black": "default: #FFFFFF" + } + }, + { + "c": " ", + "t": "source.makefile", + "r": { + "dark_plus": "default: #D4D4D4", + "light_plus": "default: #000000", + "dark_vs": "default: #D4D4D4", + "light_vs": "default: #000000", + "hc_black": "default: #FFFFFF" + } + }, + { + "c": "$(", + "t": "source.makefile string.interpolated.makefile punctuation.definition.variable.makefile", + "r": { + "dark_plus": "string: #CE9178", + "light_plus": "string: #A31515", + "dark_vs": "string: #CE9178", + "light_vs": "string: #A31515", + "hc_black": "string: #CE9178" + } + }, + { + "c": "shell", + "t": "source.makefile string.interpolated.makefile meta.scope.function-call.makefile support.function.shell.makefile", + "r": { + "dark_plus": "support.function: #DCDCAA", + "light_plus": "support.function: #795E26", + "dark_vs": "string: #CE9178", + "light_vs": "string: #A31515", + "hc_black": "support.function: #DCDCAA" + } + }, + { + "c": " expr `", + "t": "source.makefile string.interpolated.makefile meta.scope.function-call.makefile", + "r": { + "dark_plus": "string: #CE9178", + "light_plus": "string: #A31515", + "dark_vs": "string: #CE9178", + "light_vs": "string: #A31515", + "hc_black": "string: #CE9178" + } + }, + { + "c": "$(", + "t": "source.makefile string.interpolated.makefile meta.scope.function-call.makefile string.interpolated.makefile punctuation.definition.variable.makefile", + "r": { + "dark_plus": "string: #CE9178", + "light_plus": "string: #A31515", + "dark_vs": "string: #CE9178", + "light_vs": "string: #A31515", + "hc_black": "string: #CE9178" + } + }, + { + "c": "CXX", + "t": "source.makefile string.interpolated.makefile meta.scope.function-call.makefile string.interpolated.makefile variable.other.makefile", + "r": { + "dark_plus": "variable: #9CDCFE", + "light_plus": "variable: #001080", + "dark_vs": "string: #CE9178", + "light_vs": "string: #A31515", + "hc_black": "variable: #9CDCFE" + } + }, + { + "c": ")", + "t": "source.makefile string.interpolated.makefile meta.scope.function-call.makefile string.interpolated.makefile punctuation.definition.variable.makefile", + "r": { + "dark_plus": "string: #CE9178", + "light_plus": "string: #A31515", + "dark_vs": "string: #CE9178", + "light_vs": "string: #A31515", + "hc_black": "string: #CE9178" + } + }, + { + "c": " -dumpversion | sed -e 's/\\.\\([0-9][0-9]\\)/\\1/g' -e 's/\\.\\([0-9]\\)/0\\1/g' -e 's/^[0-9]\\{3,4\\}", + "t": "source.makefile string.interpolated.makefile meta.scope.function-call.makefile", + "r": { + "dark_plus": "string: #CE9178", + "light_plus": "string: #A31515", + "dark_vs": "string: #CE9178", + "light_vs": "string: #A31515", + "hc_black": "string: #CE9178" + } + }, + { + "c": "$$", + "t": "source.makefile string.interpolated.makefile meta.scope.function-call.makefile variable.language.makefile", + "r": { + "dark_plus": "variable.language: #569CD6", + "light_plus": "variable.language: #0000FF", + "dark_vs": "variable.language: #569CD6", + "light_vs": "variable.language: #0000FF", + "hc_black": "variable: #9CDCFE" + } + }, + { + "c": "/&00/'` \\>= 40800", + "t": "source.makefile string.interpolated.makefile meta.scope.function-call.makefile", + "r": { + "dark_plus": "string: #CE9178", + "light_plus": "string: #A31515", + "dark_vs": "string: #CE9178", + "light_vs": "string: #A31515", + "hc_black": "string: #CE9178" + } + }, + { + "c": ")", + "t": "source.makefile string.interpolated.makefile punctuation.definition.variable.makefile", + "r": { + "dark_plus": "string: #CE9178", + "light_plus": "string: #A31515", + "dark_vs": "string: #CE9178", + "light_vs": "string: #A31515", + "hc_black": "string: #CE9178" + } + }, + { + "c": "ok", + "t": "source.makefile variable.other.makefile", + "r": { + "dark_plus": "variable: #9CDCFE", + "light_plus": "variable: #001080", + "dark_vs": "default: #D4D4D4", + "light_vs": "default: #000000", + "hc_black": "variable: #9CDCFE" + } + }, + { + "c": " ", + "t": "source.makefile", + "r": { + "dark_plus": "default: #D4D4D4", + "light_plus": "default: #000000", + "dark_vs": "default: #D4D4D4", + "light_vs": "default: #000000", + "hc_black": "default: #FFFFFF" + } + }, + { + "c": ":=", + "t": "source.makefile punctuation.separator.key-value.makefile", + "r": { + "dark_plus": "default: #D4D4D4", + "light_plus": "default: #000000", + "dark_vs": "default: #D4D4D4", + "light_vs": "default: #000000", + "hc_black": "default: #FFFFFF" + } + }, + { + "c": " ok", + "t": "source.makefile", + "r": { + "dark_plus": "default: #D4D4D4", + "light_plus": "default: #000000", + "dark_vs": "default: #D4D4D4", + "light_vs": "default: #000000", + "hc_black": "default: #FFFFFF" + } + }, + { + "c": "$(", + "t": "source.makefile string.interpolated.makefile punctuation.definition.variable.makefile", + "r": { + "dark_plus": "string: #CE9178", + "light_plus": "string: #A31515", + "dark_vs": "string: #CE9178", + "light_vs": "string: #A31515", + "hc_black": "string: #CE9178" + } + }, + { + "c": "info", + "t": "source.makefile string.interpolated.makefile meta.scope.function-call.makefile support.function.info.makefile", + "r": { + "dark_plus": "support.function: #DCDCAA", + "light_plus": "support.function: #795E26", + "dark_vs": "string: #CE9178", + "light_vs": "string: #A31515", + "hc_black": "support.function: #DCDCAA" + } + }, + { + "c": " Braces {} in parentheses ({}): ", + "t": "source.makefile string.interpolated.makefile meta.scope.function-call.makefile", + "r": { + "dark_plus": "string: #CE9178", + "light_plus": "string: #A31515", + "dark_vs": "string: #CE9178", + "light_vs": "string: #A31515", + "hc_black": "string: #CE9178" + } + }, + { + "c": "${", + "t": "source.makefile string.interpolated.makefile meta.scope.function-call.makefile variable.language.makefile", + "r": { + "dark_plus": "variable.language: #569CD6", + "light_plus": "variable.language: #0000FF", + "dark_vs": "variable.language: #569CD6", + "light_vs": "variable.language: #0000FF", + "hc_black": "variable: #9CDCFE" + } + }, + { + "c": "ok}", + "t": "source.makefile string.interpolated.makefile meta.scope.function-call.makefile", + "r": { + "dark_plus": "string: #CE9178", + "light_plus": "string: #A31515", + "dark_vs": "string: #CE9178", + "light_vs": "string: #A31515", + "hc_black": "string: #CE9178" + } + }, + { + "c": ")", + "t": "source.makefile string.interpolated.makefile punctuation.definition.variable.makefile", + "r": { + "dark_plus": "string: #CE9178", + "light_plus": "string: #A31515", + "dark_vs": "string: #CE9178", + "light_vs": "string: #A31515", + "hc_black": "string: #CE9178" + } + }, + { + "c": "${", + "t": "source.makefile variable.language.makefile", + "r": { + "dark_plus": "variable.language: #569CD6", + "light_plus": "variable.language: #0000FF", + "dark_vs": "variable.language: #569CD6", + "light_vs": "variable.language: #0000FF", + "hc_black": "variable: #9CDCFE" + } + }, + { + "c": "info Parentheses () in braces {()}: ", + "t": "source.makefile", + "r": { + "dark_plus": "default: #D4D4D4", + "light_plus": "default: #000000", + "dark_vs": "default: #D4D4D4", + "light_vs": "default: #000000", + "hc_black": "default: #FFFFFF" + } + }, + { + "c": "$(", + "t": "source.makefile string.interpolated.makefile punctuation.definition.variable.makefile", + "r": { + "dark_plus": "string: #CE9178", + "light_plus": "string: #A31515", + "dark_vs": "string: #CE9178", + "light_vs": "string: #A31515", + "hc_black": "string: #CE9178" + } + }, + { + "c": "ok", + "t": "source.makefile string.interpolated.makefile variable.other.makefile", + "r": { + "dark_plus": "variable: #9CDCFE", + "light_plus": "variable: #001080", + "dark_vs": "string: #CE9178", + "light_vs": "string: #A31515", + "hc_black": "variable: #9CDCFE" + } + }, + { + "c": ")", + "t": "source.makefile string.interpolated.makefile punctuation.definition.variable.makefile", + "r": { + "dark_plus": "string: #CE9178", + "light_plus": "string: #A31515", + "dark_vs": "string: #CE9178", + "light_vs": "string: #A31515", + "hc_black": "string: #CE9178" + } + }, + { + "c": "}", + "t": "source.makefile", + "r": { + "dark_plus": "default: #D4D4D4", + "light_plus": "default: #000000", + "dark_vs": "default: #D4D4D4", + "light_vs": "default: #000000", + "hc_black": "default: #FFFFFF" + } + }, + { + "c": "ifeq", + "t": "source.makefile meta.scope.conditional.makefile keyword.control.ifeq.makefile", + "r": { + "dark_plus": "keyword.control: #C586C0", + "light_plus": "keyword.control: #AF00DB", + "dark_vs": "keyword.control: #569CD6", + "light_vs": "keyword.control: #0000FF", + "hc_black": "keyword.control: #C586C0" + } + }, + { + "c": " (\"", + "t": "source.makefile meta.scope.conditional.makefile meta.scope.condition.makefile", + "r": { + "dark_plus": "default: #D4D4D4", + "light_plus": "default: #000000", + "dark_vs": "default: #D4D4D4", + "light_vs": "default: #000000", + "hc_black": "default: #FFFFFF" + } + }, + { + "c": "${", + "t": "source.makefile meta.scope.conditional.makefile meta.scope.condition.makefile variable.language.makefile", + "r": { + "dark_plus": "variable.language: #569CD6", + "light_plus": "variable.language: #0000FF", + "dark_vs": "variable.language: #569CD6", + "light_vs": "variable.language: #0000FF", + "hc_black": "variable: #9CDCFE" + } + }, + { + "c": "ok}\", \"skip\")", + "t": "source.makefile meta.scope.conditional.makefile meta.scope.condition.makefile", + "r": { + "dark_plus": "default: #D4D4D4", + "light_plus": "default: #000000", + "dark_vs": "default: #D4D4D4", + "light_vs": "default: #000000", + "hc_black": "default: #FFFFFF" + } + }, + { + "c": " ", + "t": "source.makefile meta.scope.conditional.makefile", + "r": { + "dark_plus": "default: #D4D4D4", + "light_plus": "default: #000000", + "dark_vs": "default: #D4D4D4", + "light_vs": "default: #000000", + "hc_black": "default: #FFFFFF" + } + }, + { + "c": "$(", + "t": "source.makefile meta.scope.conditional.makefile string.interpolated.makefile punctuation.definition.variable.makefile", + "r": { + "dark_plus": "string: #CE9178", + "light_plus": "string: #A31515", + "dark_vs": "string: #CE9178", + "light_vs": "string: #A31515", + "hc_black": "string: #CE9178" + } + }, + { + "c": "ok", + "t": "source.makefile meta.scope.conditional.makefile string.interpolated.makefile variable.other.makefile", + "r": { + "dark_plus": "variable: #9CDCFE", + "light_plus": "variable: #001080", + "dark_vs": "string: #CE9178", + "light_vs": "string: #A31515", + "hc_black": "variable: #9CDCFE" + } + }, + { + "c": ")", + "t": "source.makefile meta.scope.conditional.makefile string.interpolated.makefile punctuation.definition.variable.makefile", + "r": { + "dark_plus": "string: #CE9178", + "light_plus": "string: #A31515", + "dark_vs": "string: #CE9178", + "light_vs": "string: #A31515", + "hc_black": "string: #CE9178" + } + }, + { + "c": ")}", + "t": "source.makefile meta.scope.conditional.makefile", + "r": { + "dark_plus": "default: #D4D4D4", + "light_plus": "default: #000000", + "dark_vs": "default: #D4D4D4", + "light_vs": "default: #000000", + "hc_black": "default: #FFFFFF" + } + }, + { + "c": " ", + "t": "source.makefile meta.scope.conditional.makefile", + "r": { + "dark_plus": "default: #D4D4D4", + "light_plus": "default: #000000", + "dark_vs": "default: #D4D4D4", + "light_vs": "default: #000000", + "hc_black": "default: #FFFFFF" + } + }, + { + "c": "${", + "t": "source.makefile meta.scope.conditional.makefile variable.language.makefile", + "r": { + "dark_plus": "variable.language: #569CD6", + "light_plus": "variable.language: #0000FF", + "dark_vs": "variable.language: #569CD6", + "light_vs": "variable.language: #0000FF", + "hc_black": "variable: #9CDCFE" + } + }, + { + "c": "ok}})", + "t": "source.makefile meta.scope.conditional.makefile", + "r": { + "dark_plus": "default: #D4D4D4", + "light_plus": "default: #000000", + "dark_vs": "default: #D4D4D4", + "light_vs": "default: #000000", + "hc_black": "default: #FFFFFF" + } + }, { "c": "endif", "t": "source.makefile meta.scope.conditional.makefile keyword.control.endif.makefile", From e5c3c0f37e993de6a0f8fe6d2ce6596d4e5745ae Mon Sep 17 00:00:00 2001 From: Andre Weinand Date: Tue, 24 Jul 2018 23:15:36 +0200 Subject: [PATCH 0484/1276] builtin loaded scripts view; fixes #37767 --- .../parts/debug/browser/loadedScriptsView.ts | 419 +++++++++++++++++- src/vs/workbench/parts/debug/common/debug.ts | 15 + .../parts/debug/common/debugModel.ts | 8 + .../parts/debug/common/debugViewModel.ts | 2 - .../debug/electron-browser/debugService.ts | 14 + .../debug/electron-browser/rawDebugSession.ts | 15 +- .../parts/debug/test/common/mockDebug.ts | 10 +- 7 files changed, 463 insertions(+), 20 deletions(-) diff --git a/src/vs/workbench/parts/debug/browser/loadedScriptsView.ts b/src/vs/workbench/parts/debug/browser/loadedScriptsView.ts index da803391a97..d5f424be629 100644 --- a/src/vs/workbench/parts/debug/browser/loadedScriptsView.ts +++ b/src/vs/workbench/parts/debug/browser/loadedScriptsView.ts @@ -7,18 +7,293 @@ import * as nls from 'vs/nls'; import { TreeViewsViewletPanel, IViewletViewOptions } from 'vs/workbench/browser/parts/views/viewsViewlet'; import { TPromise } from 'vs/base/common/winjs.base'; import * as dom from 'vs/base/browser/dom'; +import * as errors from 'vs/base/common/errors'; +import { normalize, isAbsolute, sep } from 'vs/base/common/paths'; import { IViewletPanelOptions } from 'vs/workbench/browser/parts/views/panelViewlet'; import { IContextMenuService } from 'vs/platform/contextview/browser/contextView'; import { IKeybindingService } from 'vs/platform/keybinding/common/keybinding'; import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; -import { WorkbenchTree } from 'vs/platform/list/browser/listService'; +import { WorkbenchTree, TreeResourceNavigator } from 'vs/platform/list/browser/listService'; import { renderViewTree, twistiePixels } from 'vs/workbench/parts/debug/browser/baseDebugView'; import { IAccessibilityProvider, ITree, IRenderer, IDataSource } from 'vs/base/parts/tree/browser/tree'; +import { ISession, IDebugService, IModel, CONTEXT_LOADED_SCRIPTS_ITEM_TYPE } from 'vs/workbench/parts/debug/common/debug'; +import { Source } from 'vs/workbench/parts/debug/common/debugSource'; +import { IWorkspaceContextService, IWorkspaceFolder } from 'vs/platform/workspace/common/workspace'; +import { IEditorService } from 'vs/workbench/services/editor/common/editorService'; +import { IContextKey, IContextKeyService } from 'vs/platform/contextkey/common/contextkey'; +import { IEnvironmentService } from 'vs/platform/environment/common/environment'; +import { tildify } from 'vs/base/common/labels'; +import { isWindows } from 'vs/base/common/platform'; +import URI from 'vs/base/common/uri'; +import { ltrim } from 'vs/base/common/strings'; + +const SMART = true; + +const $ = dom.$; + +const SESSION_TEMPLATE_ID = 'session'; +const SOURCE_TEMPLATE_ID = 'source'; +const ROOT_FOLDER_TEMPLATE_ID = 'node'; + +class BaseTreeItem { + + private _id: string; + private _children: { [key: string]: BaseTreeItem; }; + private _source: Source; + + constructor(private _parent: BaseTreeItem, private _label: string) { + this._id = this._parent ? `${this._parent._id}/${this._label}` : this._label; + this._children = {}; + } + + getLabel() { + const child = this.oneChild(); + if (child) { + const sep = this instanceof RootFolderTreeItem ? ' • ' : '/'; + return `${this._label}${sep}${child.getLabel()}`; + } + return this._label; + } + + getId(): string { + return this._id; + } + + getTemplateId(): string { + return SOURCE_TEMPLATE_ID; + } + + getChildren(): TPromise { + const child = this.oneChild(); + if (child) { + return child.getChildren(); + } + const array = Object.keys(this._children).map(key => this._children[key]); + return TPromise.as(array.sort((a, b) => this.compare(a, b))); + } + + hasChildren(): boolean { + const child = this.oneChild(); + if (child) { + return child.hasChildren(); + } + return Object.keys(this._children).length > 0; + } + + getSource() { + const child = this.oneChild(); + if (child) { + return child.getSource(); + } + return this._source; + } + + setSource(session: ISession, source: Source): void { + this._source = source; + } + + createIfNeeded(key: string, factory: (parent: BaseTreeItem, label: string) => T): T { + let child = this._children[key]; + if (!child) { + child = factory(this, key); + this._children[key] = child; + } + return child; + } + + remove(key: string): void { + delete this._children[key]; + } + + protected compare(a: BaseTreeItem, b: BaseTreeItem): number { + if (a._label && b._label) { + return a._label.localeCompare(b._label); + } + return 0; + } + + private oneChild(): BaseTreeItem { + if (SMART && !(this instanceof RootTreeItem)) { + const keys = Object.keys(this._children); + if (keys.length === 1) { + return this._children[keys[0]]; + } + } + return undefined; + } +} + +class RootFolderTreeItem extends BaseTreeItem { + + constructor(parent: BaseTreeItem, public folder: IWorkspaceFolder) { + super(parent, folder.name); + } + + getTemplateId(): string { + return ROOT_FOLDER_TEMPLATE_ID; + } +} + +class RootTreeItem extends BaseTreeItem { + + private _showedMoreThanOne: boolean; + + constructor(private _debugModel: IModel, private _environmentService: IEnvironmentService, private _contextService: IWorkspaceContextService) { + super(undefined, 'Root'); + this._showedMoreThanOne = false; + this._debugModel.getSessions().forEach(session => { + this.add(session); + }); + } + + hasChildren(): boolean { + return true; + } + + getChildren(): TPromise { + return super.getChildren().then(children => { + const size = children.length; + if (!this._showedMoreThanOne && size === 1) { + // skip session if there is only one + return children[0].getChildren(); + } + this._showedMoreThanOne = size > 1; + return children; + }); + } + + add(session: ISession): SessionTreeItem { + return this.createIfNeeded(session.getId(), () => new SessionTreeItem(this, session, this._environmentService, this._contextService)); + } +} + +class SessionTreeItem extends BaseTreeItem { + + private static URL_REGEXP = /^(https?:\/\/[^/]+)(\/.*)$/; + + private _session: ISession; + private _initialized: boolean; + + constructor(parent: BaseTreeItem, session: ISession, private _environmentService: IEnvironmentService, private rootProvider: IWorkspaceContextService) { + super(parent, session.getName(true)); + this._initialized = false; + this._session = session; + } + + getTemplateId(): string { + return SESSION_TEMPLATE_ID; + } + + hasChildren(): boolean { + return true; + } + + getChildren(): TPromise { + + if (!this._initialized) { + this._initialized = true; + return this._session.getLoadedSources().then(paths => { + paths.forEach(path => this.addPath(path)); + return super.getChildren(); + }); + } + + return super.getChildren(); + } + + protected compare(a: BaseTreeItem, b: BaseTreeItem): number { + const acat = this.category(a); + const bcat = this.category(b); + if (acat !== bcat) { + return acat - bcat; + } + return super.compare(a, b); + } + + /** + * Return an ordinal number for folders + */ + private category(item: BaseTreeItem): number { + + // workspace scripts come at the beginning in "folder" order + if (item instanceof RootFolderTreeItem) { + return item.folder.index; + } + + // <...> come at the very end + const l = item.getLabel(); + if (l && /^<.+>$/.test(l)) { + return 1000; + } + + // everything else in between + return 999; + } + + addPath(source: Source): void { + + let folder: IWorkspaceFolder; + let url: string; + + let path = source.raw.path; + + const match = SessionTreeItem.URL_REGEXP.exec(path); + if (match && match.length === 3) { + url = match[1]; + path = decodeURI(match[2]); + } else { + if (isAbsolute(path)) { + const resource = URI.file(path); + + // return early if we can resolve a relative path label from the root folder + folder = this.rootProvider ? this.rootProvider.getWorkspaceFolder(resource) : null; + if (folder) { + // strip off the root folder path + path = normalize(ltrim(resource.path.substr(folder.uri.path.length), sep), true); + const hasMultipleRoots = this.rootProvider.getWorkspace().folders.length > 1; + if (hasMultipleRoots) { + path = '/' + path; + } else { + // don't show root folder + folder = undefined; + } + } else { + // on unix try to tildify absolute paths + path = normalize(path, true); + if (!isWindows) { + path = tildify(path, this._environmentService.userHome); + } + } + } + } + + let x: BaseTreeItem = this; + path.split(/[\/\\]/).forEach((segment, i) => { + if (segment.length === 0) { // macOS or unix path + segment = '/'; + } + if (i === 0 && folder) { + x = x.createIfNeeded(folder.name, parent => new RootFolderTreeItem(parent, folder)); + } else if (i === 0 && url) { + x = x.createIfNeeded(url, parent => new BaseTreeItem(parent, url)); + } else { + x = x.createIfNeeded(segment, parent => new BaseTreeItem(parent, segment)); + } + }); + + x.setSource(this._session, source); + } +} export class LoadedScriptsView extends TreeViewsViewletPanel { + private static readonly MEMENTO = 'loadedscriptsview.memento'; + private treeContainer: HTMLElement; + private loadedScriptsItemType: IContextKey; + private settings: any; + constructor( options: IViewletViewOptions, @@ -26,22 +301,77 @@ export class LoadedScriptsView extends TreeViewsViewletPanel { @IKeybindingService keybindingService: IKeybindingService, @IInstantiationService private instantiationService: IInstantiationService, @IConfigurationService configurationService: IConfigurationService, + @IEditorService private editorService: IEditorService, + @IContextKeyService contextKeyService: IContextKeyService, + @IWorkspaceContextService private contextService: IWorkspaceContextService, + @IEnvironmentService private environmentService: IEnvironmentService, + @IDebugService private debugService: IDebugService ) { super({ ...(options as IViewletPanelOptions), ariaHeaderLabel: nls.localize('loadedScriptsSection', "Loaded Scripts Section") }, keybindingService, contextMenuService, configurationService); + this.settings = options.viewletSettings; + this.loadedScriptsItemType = CONTEXT_LOADED_SCRIPTS_ITEM_TYPE.bindTo(contextKeyService); } protected renderBody(container: HTMLElement): void { dom.addClass(container, 'debug-loaded-scripts'); + this.treeContainer = renderViewTree(container); - this.tree = this.instantiationService.createInstance(WorkbenchTree, this.treeContainer, { - dataSource: new LoadedScriptsDataSource(), - renderer: this.instantiationService.createInstance(LoadedScriptsRenderer), - accessibilityProvider: new LoadedSciptsAccessibilityProvider(), - }, { + this.tree = this.instantiationService.createInstance(WorkbenchTree, this.treeContainer, + { + dataSource: new LoadedScriptsDataSource(), + renderer: this.instantiationService.createInstance(LoadedScriptsRenderer), + accessibilityProvider: new LoadedSciptsAccessibilityProvider(), + }, + { ariaLabel: nls.localize({ comment: ['Debug is a noun in this context, not a verb.'], key: 'loadedScriptsAriaLabel' }, "Debug Loaded Scripts"), twistiePixels - }); + } + ); + + const callstackNavigator = new TreeResourceNavigator(this.tree); + this.disposables.push(callstackNavigator); + this.disposables.push(callstackNavigator.openResource(e => { + + const element = e.element; + + if (element instanceof BaseTreeItem) { + const source = element.getSource(); + if (source && source.available) { + const nullRange = { startLineNumber: 0, startColumn: 0, endLineNumber: 0, endColumn: 0 }; + source.openInEditor(this.editorService, nullRange, e.editorOptions.preserveFocus, e.sideBySide, e.editorOptions.pinned).done(undefined, errors.onUnexpectedError); + } + } + })); + + this.disposables.push(this.tree.onDidChangeFocus(() => { + const focus = this.tree.getFocus(); + if (focus instanceof SessionTreeItem) { + this.loadedScriptsItemType.set('session'); + } else { + this.loadedScriptsItemType.reset(); + } + })); + + const root = new RootTreeItem(this.debugService.getModel(), this.environmentService, this.contextService); + this.tree.setInput(root); + + let timeout: number; + + this.disposables.push(this.debugService.onDidLoadedSource(event => { + const sessionRoot = root.add(event.session); + sessionRoot.addPath(event.source); + + clearTimeout(timeout); + timeout = setTimeout(() => { + this.tree.refresh(root, true); + }, 300); + })); + + this.disposables.push(this.debugService.onDidEndSession(session => { + root.remove(session.getId()); + this.tree.refresh(root, false); + })); } layoutBody(size: number): void { @@ -50,6 +380,11 @@ export class LoadedScriptsView extends TreeViewsViewletPanel { } super.layoutBody(size); } + + public shutdown(): void { + this.settings[LoadedScriptsView.MEMENTO] = !this.isExpanded(); + super.shutdown(); + } } // A good example of data source, renderers, action providers and accessibilty providers can be found in the callStackView.ts @@ -57,42 +392,94 @@ export class LoadedScriptsView extends TreeViewsViewletPanel { class LoadedScriptsDataSource implements IDataSource { getId(tree: ITree, element: any): string { - throw new Error('Method not implemented.'); + return element.getId(); } hasChildren(tree: ITree, element: any): boolean { - throw new Error('Method not implemented.'); + return element.hasChildren(); } getChildren(tree: ITree, element: any): TPromise { - throw new Error('Method not implemented.'); + return element.getChildren(); } getParent(tree: ITree, element: any): TPromise { - throw new Error('Method not implemented.'); + return TPromise.as(null); } + + shouldAutoexpand?(tree: ITree, element: any): boolean { + return element instanceof RootTreeItem || element instanceof SessionTreeItem; + } +} + +interface ISessionTemplateData { + session: HTMLElement; +} + +interface ISourceTemplateData { + source: HTMLElement; +} + +interface INodeTemplateData { + node: HTMLElement; } class LoadedScriptsRenderer implements IRenderer { getHeight(tree: ITree, element: any): number { - throw new Error('Method not implemented.'); + return 22; } getTemplateId(tree: ITree, element: any): string { - throw new Error('Method not implemented.'); + return element.getTemplateId(); } renderTemplate(tree: ITree, templateId: string, container: HTMLElement) { - throw new Error('Method not implemented.'); + + if (templateId === SESSION_TEMPLATE_ID) { + let data: ISessionTemplateData = Object.create(null); + data.session = dom.append(container, $('.session')); + return data; + } + + if (templateId === SOURCE_TEMPLATE_ID) { + let data: ISourceTemplateData = Object.create(null); + data.source = dom.append(container, $('.source')); + return data; + } + + let data: INodeTemplateData = Object.create(null); + data.node = dom.append(container, $('.node')); + return data; } renderElement(tree: ITree, element: any, templateId: string, templateData: any): void { - throw new Error('Method not implemented.'); + if (templateId === SESSION_TEMPLATE_ID) { + this.renderSession(element, templateData); + } else if (templateId === SOURCE_TEMPLATE_ID) { + this.renderSource(element, templateData); + } else if (templateId === ROOT_FOLDER_TEMPLATE_ID) { + this.renderNode(element, templateData); + } } disposeTemplate(tree: ITree, templateId: string, templateData: any): void { - throw new Error('Method not implemented.'); + // noop + } + + private renderSession(session: SessionTreeItem, data: ISessionTemplateData): void { + data.session.title = 'session'; + data.session.textContent = session.getLabel(); + } + + private renderSource(source: BaseTreeItem, data: ISourceTemplateData): void { + data.source.title = 'source'; + data.source.textContent = source.getLabel(); + } + + private renderNode(node: BaseTreeItem, data: INodeTemplateData): void { + data.node.title = 'node'; + data.node.textContent = node.getLabel(); } } diff --git a/src/vs/workbench/parts/debug/common/debug.ts b/src/vs/workbench/parts/debug/common/debug.ts index fe295f8a723..6af33b36e60 100644 --- a/src/vs/workbench/parts/debug/common/debug.ts +++ b/src/vs/workbench/parts/debug/common/debug.ts @@ -49,6 +49,7 @@ export const CONTEXT_EXPRESSION_SELECTED = new RawContextKey('expressio export const CONTEXT_BREAKPOINT_SELECTED = new RawContextKey('breakpointSelected', false); export const CONTEXT_CALLSTACK_ITEM_TYPE = new RawContextKey('callStackItemType', undefined); export const CONTEXT_LOADED_SCRIPTS_SUPPORTED = new RawContextKey('loadedScriptsSupported', false); +export const CONTEXT_LOADED_SCRIPTS_ITEM_TYPE = new RawContextKey('loadedScriptsItemType', undefined); export const EDITOR_CONTRIBUTION_ID = 'editor.contrib.debug'; export const DEBUG_SCHEME = 'debug'; @@ -135,6 +136,8 @@ export interface IRawSession { completions(args: DebugProtocol.CompletionsArguments): TPromise; setVariable(args: DebugProtocol.SetVariableArguments): TPromise; source(args: DebugProtocol.SourceArguments): TPromise; + loadedSources(args: DebugProtocol.LoadedSourcesArguments): TPromise; + } export enum SessionState { @@ -151,6 +154,7 @@ export interface ISession extends ITreeElement { getThread(threadId: number): IThread; getAllThreads(): ReadonlyArray; getSource(raw: DebugProtocol.Source): Source; + getLoadedSources(): TPromise; completions(frameId: number, text: string, position: Position, overwriteBefore: number): TPromise; } @@ -572,6 +576,12 @@ export interface DebugEvent extends DebugProtocol.Event { sessionId?: string; } +export interface LoadedSourceEvent { + session: ISession; + reason: string; + source: Source; +} + export interface IDebugService { _serviceBrand: any; @@ -595,6 +605,11 @@ export interface IDebugService { */ onDidEndSession: Event; + /** + * Allows to register on loaded source events. + */ + onDidLoadedSource: Event; + /** * Allows to register on custom DAP events. */ diff --git a/src/vs/workbench/parts/debug/common/debugModel.ts b/src/vs/workbench/parts/debug/common/debugModel.ts index 6e8edd9f7cf..3a58268ec72 100644 --- a/src/vs/workbench/parts/debug/common/debugModel.ts +++ b/src/vs/workbench/parts/debug/common/debugModel.ts @@ -616,6 +616,14 @@ export class Session implements ISession { return result; } + public getLoadedSources(): TPromise { + return this.raw.loadedSources({}).then(response => { + return response.body.sources.map(src => this.getSource(src)); + }, error => { + return []; + }); + } + public getId(): string { return this.session.getId(); } diff --git a/src/vs/workbench/parts/debug/common/debugViewModel.ts b/src/vs/workbench/parts/debug/common/debugViewModel.ts index d1d7cc88b50..c5816ddb628 100644 --- a/src/vs/workbench/parts/debug/common/debugViewModel.ts +++ b/src/vs/workbench/parts/debug/common/debugViewModel.ts @@ -69,8 +69,6 @@ export class ViewModel implements IViewModel { this._focusedStackFrame = stackFrame; this.loadedScriptsSupportedContextKey.set(session && session.raw.capabilities.supportsLoadedSourcesRequest); - // @weinand remove the next line which always disables the context for the view to be shown - this.loadedScriptsSupportedContextKey.set(false); if (shouldEmit) { this._onDidFocusStackFrame.fire({ stackFrame, explicit }); diff --git a/src/vs/workbench/parts/debug/electron-browser/debugService.ts b/src/vs/workbench/parts/debug/electron-browser/debugService.ts index b8d45826a44..a5e2dcee7a0 100644 --- a/src/vs/workbench/parts/debug/electron-browser/debugService.ts +++ b/src/vs/workbench/parts/debug/electron-browser/debugService.ts @@ -69,6 +69,7 @@ export class DebugService implements debug.IDebugService { private readonly _onDidChangeState: Emitter; private readonly _onDidNewSession: Emitter; private readonly _onDidEndSession: Emitter; + private readonly _onDidLoadedSource: Emitter; private readonly _onDidCustomEvent: Emitter; private model: Model; private viewModel: ViewModel; @@ -113,6 +114,7 @@ export class DebugService implements debug.IDebugService { this._onDidChangeState = new Emitter(); this._onDidNewSession = new Emitter(); this._onDidEndSession = new Emitter(); + this._onDidLoadedSource = new Emitter(); this._onDidCustomEvent = new Emitter(); this.sessionStates = new Map(); this.allSessions = new Map(); @@ -450,6 +452,14 @@ export class DebugService implements debug.IDebugService { } })); + this.toDisposeOnSessionEnd.get(session.getId()).push(raw.onDidLoadedSource(event => { + this._onDidLoadedSource.fire({ + session: session, + reason: event.body.reason, + source: session.getSource(event.body.source) + }); + })); + this.toDisposeOnSessionEnd.get(session.getId()).push(raw.onDidCustomEvent(event => { this._onDidCustomEvent.fire(event); })); @@ -542,6 +552,10 @@ export class DebugService implements debug.IDebugService { return this._onDidEndSession.event; } + public get onDidLoadedSource(): Event { + return this._onDidLoadedSource.event; + } + public get onDidCustomEvent(): Event { return this._onDidCustomEvent.event; } diff --git a/src/vs/workbench/parts/debug/electron-browser/rawDebugSession.ts b/src/vs/workbench/parts/debug/electron-browser/rawDebugSession.ts index 1e7a2fd9db2..5e9785e36c8 100644 --- a/src/vs/workbench/parts/debug/electron-browser/rawDebugSession.ts +++ b/src/vs/workbench/parts/debug/electron-browser/rawDebugSession.ts @@ -58,6 +58,7 @@ export class RawDebugSession implements IRawSession { private readonly _onDidThread: Emitter; private readonly _onDidOutput: Emitter; private readonly _onDidBreakpoint: Emitter; + private readonly _onDidLoadedSource: Emitter; private readonly _onDidCustomEvent: Emitter; private readonly _onDidEvent: Emitter; @@ -85,6 +86,7 @@ export class RawDebugSession implements IRawSession { this._onDidThread = new Emitter(); this._onDidOutput = new Emitter(); this._onDidBreakpoint = new Emitter(); + this._onDidLoadedSource = new Emitter(); this._onDidCustomEvent = new Emitter(); this._onDidEvent = new Emitter(); } @@ -129,6 +131,10 @@ export class RawDebugSession implements IRawSession { return this._onDidBreakpoint.event; } + public get onDidLoadedSource(): Event { + return this._onDidLoadedSource.event; + } + public get onDidCustomEvent(): Event { return this._onDidCustomEvent.event; } @@ -234,7 +240,9 @@ export class RawDebugSession implements IRawSession { private onDapEvent(event: DebugEvent): void { event.sessionId = this.id; - if (event.event === 'initialized') { + if (event.event === 'loadedSource') { // most frequent comes first + this._onDidLoadedSource.fire(event); + } else if (event.event === 'initialized') { this.readyForBreakpoints = true; this._onDidInitialize.fire(event); } else if (event.event === 'capabilities' && event.body) { @@ -387,6 +395,11 @@ export class RawDebugSession implements IRawSession { return this.send('source', args); } + public loadedSources(args: DebugProtocol.LoadedSourcesArguments): TPromise { + return this.send('loadedSources', args); + } + + public threads(): TPromise { return this.send('threads', null); } diff --git a/src/vs/workbench/parts/debug/test/common/mockDebug.ts b/src/vs/workbench/parts/debug/test/common/mockDebug.ts index ceb4cc25a49..b186fce4eb8 100644 --- a/src/vs/workbench/parts/debug/test/common/mockDebug.ts +++ b/src/vs/workbench/parts/debug/test/common/mockDebug.ts @@ -7,7 +7,7 @@ import uri from 'vs/base/common/uri'; import { Event, Emitter } from 'vs/base/common/event'; import { TPromise } from 'vs/base/common/winjs.base'; import { IWorkspaceFolder } from 'vs/platform/workspace/common/workspace'; -import { ILaunch, IDebugService, State, DebugEvent, ISession, IConfigurationManager, IStackFrame, IBreakpointData, IBreakpointUpdateData, IConfig, IModel, IViewModel, IRawSession, IBreakpoint } from 'vs/workbench/parts/debug/common/debug'; +import { ILaunch, IDebugService, State, DebugEvent, ISession, IConfigurationManager, IStackFrame, IBreakpointData, IBreakpointUpdateData, IConfig, IModel, IViewModel, IRawSession, IBreakpoint, LoadedSourceEvent } from 'vs/workbench/parts/debug/common/debug'; export class MockDebugService implements IDebugService { public _serviceBrand: any; @@ -32,6 +32,10 @@ export class MockDebugService implements IDebugService { return null; } + public get onDidLoadedSource(): Event { + return null; + } + public getConfigurationManager(): IConfigurationManager { return null; } @@ -242,6 +246,10 @@ export class MockSession implements IRawSession { return TPromise.as(null); } + public loadedSources(args: DebugProtocol.LoadedSourcesArguments): TPromise { + return TPromise.as(null); + } + public setBreakpoints(args: DebugProtocol.SetBreakpointsArguments): TPromise { return TPromise.as(null); } From e0b36a98c21f56d5332685b2b03adabef6341c5d Mon Sep 17 00:00:00 2001 From: Andre Weinand Date: Mon, 6 Aug 2018 00:00:42 +0200 Subject: [PATCH 0485/1276] node-debug@1.27.1 --- build/builtInExtensions.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build/builtInExtensions.json b/build/builtInExtensions.json index 663f81987cc..f717be5d28d 100644 --- a/build/builtInExtensions.json +++ b/build/builtInExtensions.json @@ -1,7 +1,7 @@ [ { "name": "ms-vscode.node-debug", - "version": "1.26.7", + "version": "1.27.1", "repo": "https://github.com/Microsoft/vscode-node-debug" }, { From f8420b48df76821d6ab65e03ad77befb3be58dcc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mathieu=20D=C3=A9ziel?= Date: Sun, 5 Aug 2018 18:36:31 -0400 Subject: [PATCH 0486/1276] Fixed emmet validation when open angle bracket is followed by space (#55762) * Fixed emmet validation when open angle bracket is followed by space * Fixed space check to support every kind of whitespace * Added test --- extensions/emmet/src/abbreviationActions.ts | 6 ++++++ extensions/emmet/src/test/abbreviationAction.test.ts | 10 ++++++++++ 2 files changed, 16 insertions(+) diff --git a/extensions/emmet/src/abbreviationActions.ts b/extensions/emmet/src/abbreviationActions.ts index 5ec3f401a70..26444af31e5 100644 --- a/extensions/emmet/src/abbreviationActions.ts +++ b/extensions/emmet/src/abbreviationActions.ts @@ -498,6 +498,12 @@ export function isValidLocationForEmmetAbbreviation(document: vscode.TextDocumen i--; continue; } + // Fix for https://github.com/Microsoft/vscode/issues/55411 + // A space is not a valid character right after < in a tag name. + if (/\s/.test(char) && textToBackTrack[i] === startAngle) { + i--; + continue; + } if (char !== startAngle && char !== endAngle) { continue; } diff --git a/extensions/emmet/src/test/abbreviationAction.test.ts b/extensions/emmet/src/test/abbreviationAction.test.ts index 14286654d05..b5fb87d8b07 100644 --- a/extensions/emmet/src/test/abbreviationAction.test.ts +++ b/extensions/emmet/src/test/abbreviationAction.test.ts @@ -466,6 +466,16 @@ suite('Tests for jsx, xml and xsl', () => { }); }); + test('Expand abbreviation with condition containing less than sign for jsx', () => { + return withRandomFileEditor('if (foo < 10) { span.bar', 'javascriptreact', (editor, doc) => { + editor.selection = new Selection(0, 27, 0, 27); + return expandEmmetAbbreviation({ language: 'javascriptreact' }).then(() => { + assert.equal(editor.document.getText(), 'if (foo < 10) { '); + return Promise.resolve(); + }); + }); + }); + test('No expanding text inside open tag in completion list (jsx)', () => { return testNoCompletion('jsx', htmlContents, new Selection(2, 4, 2, 4)); }); From 36bf7e26ea2e8ff8abb72367418d11371a28c427 Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Mon, 6 Aug 2018 00:22:35 -0700 Subject: [PATCH 0487/1276] Update OSSREADME.json for Electron 2.0.5 --- OSSREADME.json | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/OSSREADME.json b/OSSREADME.json index 8f167afc904..ddfe2a1fa05 100644 --- a/OSSREADME.json +++ b/OSSREADME.json @@ -2,7 +2,7 @@ [ { "name": "chromium", - "version": "58.0.3029.110", + "version": "61.0.3163.100", "repositoryURL": "http://www.chromium.org/Home", "licenseDetail": [ "BSD License", @@ -38,20 +38,20 @@ }, { "name": "libchromiumcontent", - "version": "58.0.3029.110", + "version": "61.0.3163.100", "license": "MIT", "repositoryURL": "https://github.com/electron/libchromiumcontent", "isProd": true }, { "name": "nodejs", - "version": "7.9.0", + "version": "8.9.3", "repositoryURL": "https://github.com/nodejs/node", "isProd": true }, { "name": "electron", - "version": "1.7.3", + "version": "2.0.5", "license": "MIT", "repositoryURL": "https://github.com/electron/electron", "isProd": true From 19af281d433070eabfe151483533b57a1d1253f6 Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Mon, 6 Aug 2018 00:28:38 -0700 Subject: [PATCH 0488/1276] Update distro Includes Chromium license changes --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 4259bb0eeac..6a66667a271 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "code-oss-dev", "version": "1.27.0", - "distro": "26814526269ba3caa2e8c501de9626ad266eadd3", + "distro": "3962f36fb9f758cc0c608d0c585d50a1f204de3a", "author": { "name": "Microsoft Corporation" }, From badc0d5299dcb09ae2b459f8e76339c1b921bcc8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Moreno?= Date: Mon, 6 Aug 2018 10:36:54 +0200 Subject: [PATCH 0489/1276] remove coveralls badge --- README.md | 1 - 1 file changed, 1 deletion(-) diff --git a/README.md b/README.md index 4c4f434141d..b2ba4ca1dcb 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,6 @@ # Visual Studio Code - Open Source [![Build Status](https://vscode.visualstudio.com/_apis/public/build/definitions/a4cdce18-a05c-4bb8-9476-5d07e63bfd76/1/badge?branch=master)](https://aka.ms/vscode-builds) -[![Coverage Status](https://img.shields.io/coveralls/Microsoft/vscode/master.svg)](https://coveralls.io/github/Microsoft/vscode?branch=master) [![Gitter](https://img.shields.io/badge/chat-on%20gitter-blue.svg)](https://gitter.im/Microsoft/vscode) [VS Code](https://code.visualstudio.com) is a new type of tool that combines the simplicity of From c51d1fc49cd707d0aa899313dee5e43f8a5f547b Mon Sep 17 00:00:00 2001 From: Johannes Rieken Date: Mon, 6 Aug 2018 10:36:34 +0200 Subject: [PATCH 0490/1276] fix #55455 --- .../partsSplash.contribution.ts | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/src/vs/workbench/parts/splash/electron-browser/partsSplash.contribution.ts b/src/vs/workbench/parts/splash/electron-browser/partsSplash.contribution.ts index 849d454f33d..4632aaf6efb 100644 --- a/src/vs/workbench/parts/splash/electron-browser/partsSplash.contribution.ts +++ b/src/vs/workbench/parts/splash/electron-browser/partsSplash.contribution.ts @@ -16,6 +16,7 @@ import { IPartService, Parts, Position } from 'vs/workbench/services/part/common import { IDisposable, dispose } from 'vs/base/common/lifecycle'; import { debounceEvent } from 'vs/base/common/event'; import { DEFAULT_EDITOR_MIN_DIMENSIONS } from 'vs/workbench/browser/parts/editor/editor'; +import { ColorIdentifier } from 'vs/platform/theme/common/colorRegistry'; class PartsSplash { @@ -38,13 +39,12 @@ class PartsSplash { } private _savePartsSplash() { - const theme = this._themeService.getTheme(); const colorInfo = { - titleBarBackground: theme.getColor(themes.TITLE_BAR_ACTIVE_BACKGROUND).toString(), - activityBarBackground: theme.getColor(themes.ACTIVITY_BAR_BACKGROUND).toString(), - sideBarBackground: theme.getColor(themes.SIDE_BAR_BACKGROUND).toString(), - statusBarBackground: theme.getColor(themes.STATUS_BAR_BACKGROUND).toString(), - statusBarNoFolderBackground: theme.getColor(themes.STATUS_BAR_NO_FOLDER_BACKGROUND).toString(), + titleBarBackground: this._getThemeColor(themes.TITLE_BAR_ACTIVE_BACKGROUND), + activityBarBackground: this._getThemeColor(themes.ACTIVITY_BAR_BACKGROUND), + sideBarBackground: this._getThemeColor(themes.SIDE_BAR_BACKGROUND), + statusBarBackground: this._getThemeColor(themes.STATUS_BAR_BACKGROUND), + statusBarNoFolderBackground: this._getThemeColor(themes.STATUS_BAR_NO_FOLDER_BACKGROUND), }; const layoutInfo = { sideBarSide: this._partService.getSideBarPosition() === Position.RIGHT ? 'right' : 'left', @@ -57,6 +57,12 @@ class PartsSplash { this._storageService.store('parts-splash-data', JSON.stringify({ id: PartsSplash._splashElementId, colorInfo, layoutInfo }), StorageScope.GLOBAL); } + private _getThemeColor(id: ColorIdentifier): string { + const theme = this._themeService.getTheme(); + const color = theme.getColor(id); + return color ? color.toString() : undefined; + } + private _removePartsSplash(): void { let element = document.getElementById(PartsSplash._splashElementId); if (element) { From e482fad1f028c3268ac889052c8e11208ddc941a Mon Sep 17 00:00:00 2001 From: Martin Aeschlimann Date: Mon, 6 Aug 2018 11:06:05 +0200 Subject: [PATCH 0491/1276] [make] update grammar (fixes #55256) --- extensions/make/syntaxes/make.tmLanguage.json | 312 ++++++++++++++---- .../make/test/colorize-results/makefile.json | 183 +++++----- 2 files changed, 351 insertions(+), 144 deletions(-) diff --git a/extensions/make/syntaxes/make.tmLanguage.json b/extensions/make/syntaxes/make.tmLanguage.json index 505336ac862..acfd8adea23 100644 --- a/extensions/make/syntaxes/make.tmLanguage.json +++ b/extensions/make/syntaxes/make.tmLanguage.json @@ -4,7 +4,7 @@ "If you want to provide a fix or improvement, please create a pull request against the original repository.", "Once accepted there, we are happy to receive an update request." ], - "version": "https://github.com/fadeevab/make.tmbundle/commit/43e1a67476dea3ddefbb4f0ee7901834b31b8bee", + "version": "https://github.com/fadeevab/make.tmbundle/commit/d94d403d6d31623763a4ff86b656886fa699ef60", "name": "Makefile", "scopeName": "source.makefile", "patterns": [ @@ -257,7 +257,7 @@ } ] }, - "interpolation": { + "shell-interpolation": { "begin": "(?=`)", "end": "(?!\\G)", "name": "meta.embedded.line.shell", @@ -288,18 +288,6 @@ } ] }, - "braces-interpolation": { - "begin": "\\(", - "end": "\\)", - "patterns": [ - { - "include": "#variables" - }, - { - "include": "#braces-interpolation" - } - ] - }, "recipe": { "begin": "^(?!\\t)([^:]*)(:)(?!\\=)", "beginCaptures": { @@ -404,6 +392,40 @@ { "include": "#comment" }, + { + "include": "#variables" + }, + { + "include": "#shell-interpolation" + } + ] + }, + "interpolation": { + "patterns": [ + { + "include": "#parentheses-interpolation" + }, + { + "include": "#braces-interpolation" + } + ] + }, + "parentheses-interpolation": { + "begin": "\\(", + "end": "\\)", + "patterns": [ + { + "include": "#variables" + }, + { + "include": "#interpolation" + } + ] + }, + "braces-interpolation": { + "begin": "{", + "end": "}", + "patterns": [ { "include": "#variables" }, @@ -415,11 +437,28 @@ "variables": { "patterns": [ { - "match": "\\$[^\\(\\)]", - "name": "variable.language.makefile" + "include": "#simple-variable" }, { - "begin": "(\\$|(?<=\\$))\\(", + "include": "#variable-parentheses" + }, + { + "include": "#variable-braces" + } + ] + }, + "simple-variable": { + "patterns": [ + { + "match": "\\$[^(){}]", + "name": "variable.language.makefile" + } + ] + }, + "variable-parentheses": { + "patterns": [ + { + "begin": "\\$\\(", "captures": { "0": { "name": "punctuation.definition.variable.makefile" @@ -432,64 +471,199 @@ "include": "#variables" }, { - "match": "(?<=\\()(MAKEFILES|VPATH|SHELL|MAKESHELL|MAKE|MAKELEVEL|MAKEFLAGS|MAKECMDGOALS|CURDIR|SUFFIXES|\\.LIBPATTERNS)(?=\\s*\\))", - "name": "variable.language.makefile" + "include": "#builtin-variable-parentheses" }, { - "begin": "(?<=\\()(subst|patsubst|strip|findstring|filter(-out)?|sort|word(list)?|firstword|lastword|dir|notdir|suffix|basename|addsuffix|addprefix|join|wildcard|realpath|abspath|info|error|warning|shell|foreach|if|or|and|call|eval|value|file|guile)\\s", - "beginCaptures": { - "1": { - "name": "support.function.$1.makefile" - } - }, - "end": "(?=\\)|((? Date: Mon, 6 Aug 2018 11:08:05 +0200 Subject: [PATCH 0492/1276] fix #55482 --- src/vs/base/browser/ui/iconLabel/iconLabel.ts | 17 -------------- .../referenceSearch/referencesWidget.ts | 23 ++++++++----------- 2 files changed, 10 insertions(+), 30 deletions(-) diff --git a/src/vs/base/browser/ui/iconLabel/iconLabel.ts b/src/vs/base/browser/ui/iconLabel/iconLabel.ts index cb972251f77..74be56db003 100644 --- a/src/vs/base/browser/ui/iconLabel/iconLabel.ts +++ b/src/vs/base/browser/ui/iconLabel/iconLabel.ts @@ -9,9 +9,6 @@ import 'vs/css!./iconlabel'; import * as dom from 'vs/base/browser/dom'; import { HighlightedLabel } from 'vs/base/browser/ui/highlightedlabel/highlightedLabel'; import { IMatch } from 'vs/base/common/filters'; -import uri from 'vs/base/common/uri'; -import * as paths from 'vs/base/common/paths'; -import { IWorkspaceFolderProvider, getPathLabel, IUserHomeProvider, getBaseLabel } from 'vs/base/common/labels'; import { IDisposable, combinedDisposable, Disposable } from 'vs/base/common/lifecycle'; export interface IIconLabelCreationOptions { @@ -167,17 +164,3 @@ export class IconLabel extends Disposable { } } -export class FileLabel extends IconLabel { - - constructor(container: HTMLElement, file: uri, provider: IWorkspaceFolderProvider, userHome?: IUserHomeProvider) { - super(container); - - this.setFile(file, provider, userHome); - } - - setFile(file: uri, provider: IWorkspaceFolderProvider, userHome: IUserHomeProvider): void { - const parent = paths.dirname(file.fsPath); - - this.setValue(getBaseLabel(file), parent && parent !== '.' ? getPathLabel(parent, userHome, provider) : '', { title: file.fsPath }); - } -} diff --git a/src/vs/editor/contrib/referenceSearch/referencesWidget.ts b/src/vs/editor/contrib/referenceSearch/referencesWidget.ts index efc09da762f..45fd356d9d9 100644 --- a/src/vs/editor/contrib/referenceSearch/referencesWidget.ts +++ b/src/vs/editor/contrib/referenceSearch/referencesWidget.ts @@ -20,10 +20,9 @@ import { IKeyboardEvent } from 'vs/base/browser/keyboardEvent'; import { IMouseEvent } from 'vs/base/browser/mouseEvent'; import { GestureEvent } from 'vs/base/browser/touch'; import { CountBadge } from 'vs/base/browser/ui/countBadge/countBadge'; -import { FileLabel } from 'vs/base/browser/ui/iconLabel/iconLabel'; +import { IconLabel } from 'vs/base/browser/ui/iconLabel/iconLabel'; import * as tree from 'vs/base/parts/tree/browser/tree'; -import { IInstantiationService, optional } from 'vs/platform/instantiation/common/instantiation'; -import { IWorkspaceContextService } from 'vs/platform/workspace/common/workspace'; +import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; import { Range, IRange } from 'vs/editor/common/core/range'; import * as editorCommon from 'vs/editor/common/editorCommon'; import { TextModel, ModelDecorationOptions } from 'vs/editor/common/model/textModel'; @@ -36,8 +35,6 @@ import { registerColor, activeContrastBorder, contrastBorder } from 'vs/platform import { registerThemingParticipant, ITheme, IThemeService } from 'vs/platform/theme/common/themeService'; import { attachBadgeStyler } from 'vs/platform/theme/common/styler'; import { IEditorOptions } from 'vs/editor/common/config/editorOptions'; -import { IEnvironmentService } from 'vs/platform/environment/common/environment'; -import URI from 'vs/base/common/uri'; import { TrackedRangeStickiness, IModelDeltaDecoration } from 'vs/editor/common/model'; import { WorkbenchTree, WorkbenchTreeController } from 'vs/platform/list/browser/listService'; import { RawContextKey } from 'vs/platform/contextkey/common/contextkey'; @@ -45,6 +42,7 @@ import { Location } from 'vs/editor/common/modes'; import { ClickBehavior } from 'vs/base/parts/tree/browser/treeDefaults'; import { IUriDisplayService } from 'vs/platform/uriDisplay/common/uriDisplay'; import { dirname, basenameOrAuthority } from 'vs/base/common/resources'; +import { getBaseLabel } from 'vs/base/common/labels'; class DecorationsManager implements IDisposable { @@ -296,20 +294,19 @@ class Controller extends WorkbenchTreeController { class FileReferencesTemplate { - readonly file: FileLabel; + readonly file: IconLabel; readonly badge: CountBadge; readonly dispose: () => void; constructor( container: HTMLElement, - @IWorkspaceContextService private readonly _contextService: IWorkspaceContextService, - @optional(IEnvironmentService) private _environmentService: IEnvironmentService, + @IUriDisplayService private readonly _uriDisplay: IUriDisplayService, @IThemeService themeService: IThemeService, ) { const parent = document.createElement('div'); dom.addClass(parent, 'reference-file'); container.appendChild(parent); - this.file = new FileLabel(parent, URI.parse('no:file'), this._contextService, this._environmentService); + this.file = new IconLabel(parent); this.badge = new CountBadge($('.count').appendTo(parent).getHTMLElement()); const styler = attachBadgeStyler(this.badge, themeService); @@ -321,7 +318,8 @@ class FileReferencesTemplate { } set(element: FileReferences) { - this.file.setFile(element.uri, this._contextService, this._environmentService); + let parent = dirname(element.uri); + this.file.setValue(getBaseLabel(element.uri), parent ? this._uriDisplay.getLabel(parent, true) : undefined, { title: this._uriDisplay.getLabel(element.uri) }); const len = element.children.length; this.badge.setCount(len); if (element.failure) { @@ -369,9 +367,8 @@ class Renderer implements tree.IRenderer { }; constructor( - @IWorkspaceContextService private readonly _contextService: IWorkspaceContextService, @IThemeService private readonly _themeService: IThemeService, - @optional(IEnvironmentService) private _environmentService: IEnvironmentService, + @IUriDisplayService private readonly _uriDisplay: IUriDisplayService, ) { // } @@ -391,7 +388,7 @@ class Renderer implements tree.IRenderer { renderTemplate(tree: tree.ITree, templateId: string, container: HTMLElement) { if (templateId === Renderer._ids.FileReferences) { - return new FileReferencesTemplate(container, this._contextService, this._environmentService, this._themeService); + return new FileReferencesTemplate(container, this._uriDisplay, this._themeService); } else if (templateId === Renderer._ids.OneReference) { return new OneReferenceTemplate(container); } From 2d23241975c8b1dc29b35cf93a0aa1d118cd1de0 Mon Sep 17 00:00:00 2001 From: Johannes Rieken Date: Mon, 6 Aug 2018 11:17:06 +0200 Subject: [PATCH 0493/1276] fix #55388 --- .../parts/editor/breadcrumbsControl.ts | 46 +++++++++++-------- 1 file changed, 26 insertions(+), 20 deletions(-) diff --git a/src/vs/workbench/browser/parts/editor/breadcrumbsControl.ts b/src/vs/workbench/browser/parts/editor/breadcrumbsControl.ts index 555823a6d83..16a103c59d0 100644 --- a/src/vs/workbench/browser/parts/editor/breadcrumbsControl.ts +++ b/src/vs/workbench/browser/parts/editor/breadcrumbsControl.ts @@ -362,12 +362,6 @@ export class BreadcrumbsControl { //#region commands -MenuRegistry.appendMenuItem(MenuId.CommandPalette, { - command: { - id: 'breadcrumbs.focusAndSelect', - title: localize('cmd.focus', "Focus Breadcrumbs") - } -}); MenuRegistry.appendMenuItem(MenuId.CommandPalette, { command: { id: 'breadcrumbs.toggle', @@ -388,17 +382,11 @@ CommandsRegistry.registerCommand('breadcrumbs.toggle', accessor => { BreadcrumbsConfig.IsEnabled.bindTo(config).value = !value; }); -KeybindingsRegistry.registerCommandAndKeybindingRule({ - id: 'breadcrumbs.focus', - weight: KeybindingWeight.WorkbenchContrib, - primary: KeyMod.CtrlCmd | KeyMod.Shift | KeyCode.US_SEMICOLON, - when: BreadcrumbsControl.CK_BreadcrumbsVisible, - handler(accessor) { - const groups = accessor.get(IEditorGroupsService); - const breadcrumbs = accessor.get(IBreadcrumbsService); - const widget = breadcrumbs.getWidget(groups.activeGroup.id); - const item = tail(widget.getItems()); - widget.setFocused(item); +MenuRegistry.appendMenuItem(MenuId.CommandPalette, { + command: { + id: 'breadcrumbs.focusAndSelect', + title: localize('cmd.focus', "Focus Breadcrumbs"), + precondition: BreadcrumbsControl.CK_BreadcrumbsVisible } }); KeybindingsRegistry.registerCommandAndKeybindingRule({ @@ -410,11 +398,29 @@ KeybindingsRegistry.registerCommandAndKeybindingRule({ const groups = accessor.get(IEditorGroupsService); const breadcrumbs = accessor.get(IBreadcrumbsService); const widget = breadcrumbs.getWidget(groups.activeGroup.id); - const item = tail(widget.getItems()); - widget.setFocused(item); - widget.setSelection(item, BreadcrumbsControl.Payload_Pick); + if (widget) { + const item = tail(widget.getItems()); + widget.setFocused(item); + widget.setSelection(item, BreadcrumbsControl.Payload_Pick); + } } }); +KeybindingsRegistry.registerCommandAndKeybindingRule({ + id: 'breadcrumbs.focus', + weight: KeybindingWeight.WorkbenchContrib, + primary: KeyMod.CtrlCmd | KeyMod.Shift | KeyCode.US_SEMICOLON, + when: BreadcrumbsControl.CK_BreadcrumbsVisible, + handler(accessor) { + const groups = accessor.get(IEditorGroupsService); + const breadcrumbs = accessor.get(IBreadcrumbsService); + const widget = breadcrumbs.getWidget(groups.activeGroup.id); + if (widget) { + const item = tail(widget.getItems()); + widget.setFocused(item); + } + } +}); + KeybindingsRegistry.registerCommandAndKeybindingRule({ id: 'breadcrumbs.focusNext', weight: KeybindingWeight.WorkbenchContrib, From d01fcd3168fd9bdabdad37cd065189f6088d6dcb Mon Sep 17 00:00:00 2001 From: Johannes Rieken Date: Mon, 6 Aug 2018 11:38:43 +0200 Subject: [PATCH 0494/1276] move "keyevent to printbale key"-logic into service, removes duplicated code and fixes #55387 --- .../common/abstractKeybindingService.ts | 16 +++++++++++++- .../platform/keybinding/common/keybinding.ts | 6 ++++++ .../test/common/mockKeybindingService.ts | 4 ++++ src/vs/platform/list/browser/listService.ts | 15 ++++--------- .../outline/electron-browser/outlinePanel.ts | 21 +++---------------- .../electron-browser/keybindingService.ts | 21 +++++++++++++++++++ 6 files changed, 53 insertions(+), 30 deletions(-) diff --git a/src/vs/platform/keybinding/common/abstractKeybindingService.ts b/src/vs/platform/keybinding/common/abstractKeybindingService.ts index 075cb92fe87..4c6c989f169 100644 --- a/src/vs/platform/keybinding/common/abstractKeybindingService.ts +++ b/src/vs/platform/keybinding/common/abstractKeybindingService.ts @@ -5,7 +5,7 @@ 'use strict'; import * as nls from 'vs/nls'; -import { ResolvedKeybinding, Keybinding } from 'vs/base/common/keyCodes'; +import { ResolvedKeybinding, Keybinding, KeyCode } from 'vs/base/common/keyCodes'; import { IDisposable, Disposable } from 'vs/base/common/lifecycle'; import { ICommandService } from 'vs/platform/commands/common/commands'; import { KeybindingResolver, IResolveResult } from 'vs/platform/keybinding/common/keybindingResolver'; @@ -204,4 +204,18 @@ export abstract class AbstractKeybindingService extends Disposable implements IK return shouldPreventDefault; } + + mightProducePrintableCharacter(event: IKeyboardEvent): boolean { + if (event.ctrlKey || event.metaKey) { + // ignore ctrl/cmd-combination but not shift/alt-combinatios + return false; + } + // weak check for certain ranges. this is properly implemented in a subclass + // with access to the KeyboardMapperFactory. + if ((event.keyCode >= KeyCode.KEY_A && event.keyCode <= KeyCode.KEY_Z) + || (event.keyCode >= KeyCode.KEY_0 && event.keyCode <= KeyCode.KEY_9)) { + return true; + } + return false; + } } diff --git a/src/vs/platform/keybinding/common/keybinding.ts b/src/vs/platform/keybinding/common/keybinding.ts index c491ec7a8d0..7110738c198 100644 --- a/src/vs/platform/keybinding/common/keybinding.ts +++ b/src/vs/platform/keybinding/common/keybinding.ts @@ -77,5 +77,11 @@ export interface IKeybindingService { getKeybindings(): ResolvedKeybindingItem[]; customKeybindingsCount(): number; + + /** + * Will the given key event produce a character that's rendered on screen, e.g. in a + * text box. *Note* that the results of this function can be incorrect. + */ + mightProducePrintableCharacter(event: IKeyboardEvent): boolean; } diff --git a/src/vs/platform/keybinding/test/common/mockKeybindingService.ts b/src/vs/platform/keybinding/test/common/mockKeybindingService.ts index 8a44c7bd8db..a8b00dfb030 100644 --- a/src/vs/platform/keybinding/test/common/mockKeybindingService.ts +++ b/src/vs/platform/keybinding/test/common/mockKeybindingService.ts @@ -124,4 +124,8 @@ export class MockKeybindingService implements IKeybindingService { dispatchEvent(e: IKeyboardEvent, target: IContextKeyServiceTarget): boolean { return false; } + + mightProducePrintableCharacter(e: IKeyboardEvent): boolean { + return false; + } } diff --git a/src/vs/platform/list/browser/listService.ts b/src/vs/platform/list/browser/listService.ts index d40542626af..8df85fe9180 100644 --- a/src/vs/platform/list/browser/listService.ts +++ b/src/vs/platform/list/browser/listService.ts @@ -31,6 +31,7 @@ import { TPromise } from 'vs/base/common/winjs.base'; import { onUnexpectedError, canceled } from 'vs/base/common/errors'; import { KeyCode } from 'vs/base/common/keyCodes'; import { IKeyboardEvent } from 'vs/base/browser/keyboardEvent'; +import { IKeybindingService } from 'vs/platform/keybinding/common/keybinding'; export type ListWidget = List | PagedList | ITree; @@ -578,7 +579,8 @@ export class HighlightingTreeController extends WorkbenchTreeController { constructor( options: IControllerOptions, private readonly onType: () => any, - @IConfigurationService configurationService: IConfigurationService + @IConfigurationService configurationService: IConfigurationService, + @IKeybindingService private readonly _keybindingService: IKeybindingService, ) { super(options, configurationService); } @@ -591,16 +593,7 @@ export class HighlightingTreeController extends WorkbenchTreeController { if (this.upKeyBindingDispatcher.has(event.keyCode)) { return false; } - if (event.ctrlKey || event.metaKey) { - // ignore ctrl/cmd-combination but not shift/alt-combinatios - return false; - } - // crazy -> during keydown focus moves to the input box - // and because of that the keyup event is handled by the - // input field - if (event.keyCode >= KeyCode.KEY_A && event.keyCode <= KeyCode.KEY_Z) { - // todo@joh this is much weaker than using the KeyboardMapperFactory - // but due to layering-challanges that's not available here... + if (this._keybindingService.mightProducePrintableCharacter(event)) { this.onType(); return true; } diff --git a/src/vs/workbench/parts/outline/electron-browser/outlinePanel.ts b/src/vs/workbench/parts/outline/electron-browser/outlinePanel.ts index c61097b03d3..4123498f29d 100644 --- a/src/vs/workbench/parts/outline/electron-browser/outlinePanel.ts +++ b/src/vs/workbench/parts/outline/electron-browser/outlinePanel.ts @@ -50,7 +50,6 @@ import { IViewletViewOptions } from 'vs/workbench/browser/parts/views/viewsViewl import { CollapseAction } from 'vs/workbench/browser/viewlet'; import { IViewsService } from 'vs/workbench/common/views'; import { ACTIVE_GROUP, IEditorService, SIDE_GROUP } from 'vs/workbench/services/editor/common/editorService'; -import { KeyboardMapperFactory } from 'vs/workbench/services/keybinding/electron-browser/keybindingService'; import { OutlineConfigKeys, OutlineViewFiltered, OutlineViewFocused, OutlineViewId } from './outline'; import { OutlineController, OutlineDataSource, OutlineItemComparator, OutlineItemCompareType, OutlineItemFilter, OutlineRenderer, OutlineTreeState } from '../../../../editor/contrib/documentSymbols/outlineTree'; import { IResourceInput } from 'vs/platform/editor/common/editor'; @@ -256,12 +255,12 @@ export class OutlinePanel extends ViewletPanel { @IEditorService private readonly _editorService: IEditorService, @IMarkerService private readonly _markerService: IMarkerService, @IConfigurationService private readonly _configurationService: IConfigurationService, + @IKeybindingService private readonly _keybindingService: IKeybindingService, @IConfigurationService configurationService: IConfigurationService, - @IKeybindingService keybindingService: IKeybindingService, @IContextKeyService contextKeyService: IContextKeyService, @IContextMenuService contextMenuService: IContextMenuService, ) { - super(options, keybindingService, contextMenuService, configurationService); + super(options, _keybindingService, contextMenuService, configurationService); this._outlineViewState.restore(this._storageService); this._contextKeyFocused = OutlineViewFocused.bindTo(contextKeyService); this._contextKeyFiltered = OutlineViewFiltered.bindTo(contextKeyService); @@ -326,8 +325,6 @@ export class OutlinePanel extends ViewletPanel { const $this = this; const controller = new class extends OutlineController { - private readonly _mapper = KeyboardMapperFactory.INSTANCE; - constructor() { super({}, $this.configurationService); } @@ -340,22 +337,10 @@ export class OutlinePanel extends ViewletPanel { if (this.upKeyBindingDispatcher.has(event.keyCode)) { return false; } - if (event.ctrlKey || event.metaKey) { - // ignore ctrl/cmd-combination but not shift/alt-combinatios - return false; - } // crazy -> during keydown focus moves to the input box // and because of that the keyup event is handled by the // input field - const mapping = this._mapper.getRawKeyboardMapping(); - if (!mapping) { - return false; - } - const keyInfo = mapping[event.code]; - if (!keyInfo) { - return false; - } - if (keyInfo.value) { + if ($this._keybindingService.mightProducePrintableCharacter(event)) { $this._input.focus(); return true; } diff --git a/src/vs/workbench/services/keybinding/electron-browser/keybindingService.ts b/src/vs/workbench/services/keybinding/electron-browser/keybindingService.ts index c0521529d6e..775b74e6e76 100644 --- a/src/vs/workbench/services/keybinding/electron-browser/keybindingService.ts +++ b/src/vs/workbench/services/keybinding/electron-browser/keybindingService.ts @@ -540,6 +540,27 @@ export class WorkbenchKeybindingService extends AbstractKeybindingService { let pretty = unboundCommands.sort().join('\n// - '); return '// ' + nls.localize('unboundCommands', "Here are other available commands: ") + '\n// - ' + pretty; } + + mightProducePrintableCharacter(event: IKeyboardEvent): boolean { + if (event.ctrlKey || event.metaKey) { + // ignore ctrl/cmd-combination but not shift/alt-combinatios + return false; + } + // consult the KeyboardMapperFactory to check the given event for + // a printable value. + const mapping = KeyboardMapperFactory.INSTANCE.getRawKeyboardMapping(); + if (!mapping) { + return false; + } + const keyInfo = mapping[event.code]; + if (!keyInfo) { + return false; + } + if (keyInfo.value) { + return true; + } + return false; + } } let schemaId = 'vscode://schemas/keybindings'; From bca795fc81ccec46679c0937223b197ab154369d Mon Sep 17 00:00:00 2001 From: Johannes Rieken Date: Mon, 6 Aug 2018 11:54:25 +0200 Subject: [PATCH 0495/1276] fix #55865 --- src/vs/platform/theme/common/colorRegistry.ts | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/vs/platform/theme/common/colorRegistry.ts b/src/vs/platform/theme/common/colorRegistry.ts index b1543ed3d2f..8d984bd6f21 100644 --- a/src/vs/platform/theme/common/colorRegistry.ts +++ b/src/vs/platform/theme/common/colorRegistry.ts @@ -223,10 +223,10 @@ export const scrollbarSliderActiveBackground = registerColor('scrollbarSlider.ac export const progressBarBackground = registerColor('progressBar.background', { dark: Color.fromHex('#0E70C0'), light: Color.fromHex('#0E70C0'), hc: contrastBorder }, nls.localize('progressBarBackground', "Background color of the progress bar that can show for long running operations.")); -export const breadcrumbsForeground = registerColor('breadcrumb.breadcrumbsForeground', { light: Color.fromHex('#6C6C6C').transparent(.7), dark: Color.fromHex('#CCCCCC').transparent(.7), hc: Color.white.transparent(.7) }, nls.localize('breadcrumbsFocusForeground', "Color of focused breadcrumb items.")); -export const breadcrumbsFocusForeground = registerColor('breadcrumb.breadcrumbsFocusForeground', { light: '#6C6C6C', dark: '#CCCCCC', hc: Color.white }, nls.localize('breadcrumbsFocusForeground', "Color of focused breadcrumb items.")); -export const breadcrumbsActiveSelectionForeground = registerColor('breadcrumb.breadcrumbsActiveSelectionForeground', { light: '#6C6C6C', dark: '#CCCCCC', hc: Color.white }, nls.localize('breadcrumbsSelectedForegound', "Color of selected breadcrumb items.")); -export const breadcrumbsPickerBackground = registerColor('breadcrumb.breadcrumbsPickerBackground', { light: '#ECECEC', dark: '#252526', hc: Color.black }, nls.localize('breadcrumbsSelectedBackground', "Background color of breadcrumb item picker.")); +export const breadcrumbsForeground = registerColor('breadcrumb.foreground', { light: Color.fromHex('#6C6C6C').transparent(.7), dark: Color.fromHex('#CCCCCC').transparent(.7), hc: Color.white.transparent(.7) }, nls.localize('breadcrumbsFocusForeground', "Color of focused breadcrumb items.")); +export const breadcrumbsFocusForeground = registerColor('breadcrumb.focusForeground', { light: '#6C6C6C', dark: '#CCCCCC', hc: Color.white }, nls.localize('breadcrumbsFocusForeground', "Color of focused breadcrumb items.")); +export const breadcrumbsActiveSelectionForeground = registerColor('breadcrumb.activeSelectionForeground', { light: '#6C6C6C', dark: '#CCCCCC', hc: Color.white }, nls.localize('breadcrumbsSelectedForegound', "Color of selected breadcrumb items.")); +export const breadcrumbsPickerBackground = registerColor('breadcrumbPicker.background', { light: '#ECECEC', dark: '#252526', hc: Color.black }, nls.localize('breadcrumbsSelectedBackground', "Background color of breadcrumb item picker.")); /** * Editor background color. From ea7232e79119c3537945932006653ae252e9ee2b Mon Sep 17 00:00:00 2001 From: Johannes Rieken Date: Mon, 6 Aug 2018 12:18:19 +0200 Subject: [PATCH 0496/1276] debt - use Promise and CancellationToken instead of TPromise --- src/vs/editor/contrib/format/format.ts | 23 +++++++++--------- src/vs/editor/contrib/format/formatActions.ts | 24 ++++++++++--------- .../mainThreadSaveParticipant.ts | 6 +++-- .../api/extHostLanguageFeatures.test.ts | 12 +++++----- 4 files changed, 35 insertions(+), 30 deletions(-) diff --git a/src/vs/editor/contrib/format/format.ts b/src/vs/editor/contrib/format/format.ts index 60b2b6e72c5..c98fefbab91 100644 --- a/src/vs/editor/contrib/format/format.ts +++ b/src/vs/editor/contrib/format/format.ts @@ -12,8 +12,9 @@ import { ITextModel } from 'vs/editor/common/model'; import { registerDefaultLanguageCommand, registerLanguageCommand } from 'vs/editor/browser/editorExtensions'; import { DocumentFormattingEditProviderRegistry, DocumentRangeFormattingEditProviderRegistry, OnTypeFormattingEditProviderRegistry, FormattingOptions, TextEdit } from 'vs/editor/common/modes'; import { IModelService } from 'vs/editor/common/services/modelService'; -import { asWinJsPromise, first } from 'vs/base/common/async'; +import { asWinJsPromise, first2 } from 'vs/base/common/async'; import { Position } from 'vs/editor/common/core/position'; +import { CancellationToken } from 'vs/base/common/cancellation'; export class NoProviderError extends Error { @@ -26,30 +27,30 @@ export class NoProviderError extends Error { } } -export function getDocumentRangeFormattingEdits(model: ITextModel, range: Range, options: FormattingOptions): TPromise { +export function getDocumentRangeFormattingEdits(model: ITextModel, range: Range, options: FormattingOptions, token: CancellationToken): Promise { const providers = DocumentRangeFormattingEditProviderRegistry.ordered(model); if (providers.length === 0) { - return TPromise.wrapError(new NoProviderError()); + return Promise.reject(new NoProviderError()); } - return first(providers.map(provider => () => { - return asWinJsPromise(token => provider.provideDocumentRangeFormattingEdits(model, range, options, token)) + return first2(providers.map(provider => () => { + return Promise.resolve(provider.provideDocumentRangeFormattingEdits(model, range, options, token)) .then(undefined, onUnexpectedExternalError); }), result => !isFalsyOrEmpty(result)); } -export function getDocumentFormattingEdits(model: ITextModel, options: FormattingOptions): TPromise { +export function getDocumentFormattingEdits(model: ITextModel, options: FormattingOptions, token: CancellationToken): Promise { const providers = DocumentFormattingEditProviderRegistry.ordered(model); // try range formatters when no document formatter is registered if (providers.length === 0) { - return getDocumentRangeFormattingEdits(model, model.getFullModelRange(), options); + return getDocumentRangeFormattingEdits(model, model.getFullModelRange(), options, token); } - return first(providers.map(provider => () => { - return asWinJsPromise(token => provider.provideDocumentFormattingEdits(model, options, token)) + return first2(providers.map(provider => () => { + return Promise.resolve(provider.provideDocumentFormattingEdits(model, options, token)) .then(undefined, onUnexpectedExternalError); }), result => !isFalsyOrEmpty(result)); } @@ -77,7 +78,7 @@ registerLanguageCommand('_executeFormatRangeProvider', function (accessor, args) if (!model) { throw illegalArgument('resource'); } - return getDocumentRangeFormattingEdits(model, Range.lift(range), options); + return getDocumentRangeFormattingEdits(model, Range.lift(range), options, CancellationToken.None); }); registerLanguageCommand('_executeFormatDocumentProvider', function (accessor, args) { @@ -90,7 +91,7 @@ registerLanguageCommand('_executeFormatDocumentProvider', function (accessor, ar throw illegalArgument('resource'); } - return getDocumentFormattingEdits(model, options); + return getDocumentFormattingEdits(model, options, CancellationToken.None); }); registerDefaultLanguageCommand('_executeFormatOnTypeProvider', function (model, position, args) { diff --git a/src/vs/editor/contrib/format/formatActions.ts b/src/vs/editor/contrib/format/formatActions.ts index 25dee8a028a..02a454eab11 100644 --- a/src/vs/editor/contrib/format/formatActions.ts +++ b/src/vs/editor/contrib/format/formatActions.ts @@ -27,6 +27,7 @@ import { ICodeEditor } from 'vs/editor/browser/editorBrowser'; import { ISingleEditOperation } from 'vs/editor/common/model'; import { INotificationService } from 'vs/platform/notification/common/notification'; import { KeybindingWeight } from 'vs/platform/keybinding/common/keybindingsRegistry'; +import { CancellationToken } from 'vs/base/common/cancellation'; function alertFormattingEdits(edits: ISingleEditOperation[]): void { @@ -239,7 +240,7 @@ class FormatOnPaste implements editorCommon.IEditorContribution { const { tabSize, insertSpaces } = model.getOptions(); const state = new EditorState(this.editor, CodeEditorStateFlag.Value | CodeEditorStateFlag.Position); - getDocumentRangeFormattingEdits(model, range, { tabSize, insertSpaces }).then(edits => { + getDocumentRangeFormattingEdits(model, range, { tabSize, insertSpaces }, CancellationToken.None).then(edits => { return this.workerService.computeMoreMinimalEdits(model.uri, edits); }).then(edits => { if (!state.validate(this.editor) || isFalsyOrEmpty(edits)) { @@ -267,7 +268,7 @@ export abstract class AbstractFormatAction extends EditorAction { const workerService = accessor.get(IEditorWorkerService); const notificationService = accessor.get(INotificationService); - const formattingPromise = this._getFormattingEdits(editor); + const formattingPromise = this._getFormattingEdits(editor, CancellationToken.None); if (!formattingPromise) { return TPromise.as(void 0); } @@ -276,7 +277,7 @@ export abstract class AbstractFormatAction extends EditorAction { const state = new EditorState(editor, CodeEditorStateFlag.Value | CodeEditorStateFlag.Position); // Receive formatted value from worker - return formattingPromise.then(edits => workerService.computeMoreMinimalEdits(editor.getModel().uri, edits)).then(edits => { + return TPromise.wrap(formattingPromise).then(edits => workerService.computeMoreMinimalEdits(editor.getModel().uri, edits)).then(edits => { if (!state.validate(editor) || isFalsyOrEmpty(edits)) { return; } @@ -293,7 +294,8 @@ export abstract class AbstractFormatAction extends EditorAction { }); } - protected abstract _getFormattingEdits(editor: ICodeEditor): TPromise; + protected abstract _getFormattingEdits(editor: ICodeEditor, token: CancellationToken): Promise; + protected _notifyNoProviderError(notificationService: INotificationService, language: string): void { notificationService.info(nls.localize('no.provider', "There is no formatter for '{0}'-files installed.", language)); } @@ -322,10 +324,10 @@ export class FormatDocumentAction extends AbstractFormatAction { }); } - protected _getFormattingEdits(editor: ICodeEditor): TPromise { + protected _getFormattingEdits(editor: ICodeEditor, token: CancellationToken): Promise { const model = editor.getModel(); const { tabSize, insertSpaces } = model.getOptions(); - return getDocumentFormattingEdits(model, { tabSize, insertSpaces }); + return getDocumentFormattingEdits(model, { tabSize, insertSpaces }, token); } protected _notifyNoProviderError(notificationService: INotificationService, language: string): void { @@ -354,10 +356,10 @@ export class FormatSelectionAction extends AbstractFormatAction { }); } - protected _getFormattingEdits(editor: ICodeEditor): TPromise { + protected _getFormattingEdits(editor: ICodeEditor, token: CancellationToken): Promise { const model = editor.getModel(); const { tabSize, insertSpaces } = model.getOptions(); - return getDocumentRangeFormattingEdits(model, editor.getSelection(), { tabSize, insertSpaces }); + return getDocumentRangeFormattingEdits(model, editor.getSelection(), { tabSize, insertSpaces }, token); } protected _notifyNoProviderError(notificationService: INotificationService, language: string): void { @@ -379,14 +381,14 @@ CommandsRegistry.registerCommand('editor.action.format', accessor => { constructor() { super({} as IActionOptions); } - _getFormattingEdits(editor: ICodeEditor): TPromise { + _getFormattingEdits(editor: ICodeEditor, token: CancellationToken): Promise { const model = editor.getModel(); const editorSelection = editor.getSelection(); const { tabSize, insertSpaces } = model.getOptions(); return editorSelection.isEmpty() - ? getDocumentFormattingEdits(model, { tabSize, insertSpaces }) - : getDocumentRangeFormattingEdits(model, editorSelection, { tabSize, insertSpaces }); + ? getDocumentFormattingEdits(model, { tabSize, insertSpaces }, token) + : getDocumentRangeFormattingEdits(model, editorSelection, { tabSize, insertSpaces }, token); } }().run(accessor, editor); } diff --git a/src/vs/workbench/api/electron-browser/mainThreadSaveParticipant.ts b/src/vs/workbench/api/electron-browser/mainThreadSaveParticipant.ts index 59f93eb7f2f..aa936863ad3 100644 --- a/src/vs/workbench/api/electron-browser/mainThreadSaveParticipant.ts +++ b/src/vs/workbench/api/electron-browser/mainThreadSaveParticipant.ts @@ -37,6 +37,7 @@ import { applyCodeAction } from 'vs/editor/contrib/codeAction/codeActionCommands import { getCodeActions } from 'vs/editor/contrib/codeAction/codeAction'; import { ICodeActionsOnSaveOptions } from 'vs/editor/common/config/editorOptions'; import { IBulkEditService } from 'vs/editor/browser/services/bulkEditService'; +import { CancellationTokenSource } from 'vs/base/common/cancellation'; export interface ISaveParticipantParticipant extends ISaveParticipant { // progressMessage: string; @@ -215,11 +216,12 @@ class FormatOnSaveParticipant implements ISaveParticipantParticipant { const timeout = this._configurationService.getValue('editor.formatOnSaveTimeout', { overrideIdentifier: model.getLanguageIdentifier().language, resource: editorModel.getResource() }); return new Promise((resolve, reject) => { - let request = getDocumentFormattingEdits(model, { tabSize, insertSpaces }); + let source = new CancellationTokenSource(); + let request = getDocumentFormattingEdits(model, { tabSize, insertSpaces }, source.token); setTimeout(() => { reject(localize('timeout.formatOnSave', "Aborted format on save after {0}ms", timeout)); - request.cancel(); + source.cancel(); }, timeout); request.then(edits => this._editorWorkerService.computeMoreMinimalEdits(model.uri, edits)).then(resolve, err => { diff --git a/src/vs/workbench/test/electron-browser/api/extHostLanguageFeatures.test.ts b/src/vs/workbench/test/electron-browser/api/extHostLanguageFeatures.test.ts index 74c35400db8..a88b3af5604 100644 --- a/src/vs/workbench/test/electron-browser/api/extHostLanguageFeatures.test.ts +++ b/src/vs/workbench/test/electron-browser/api/extHostLanguageFeatures.test.ts @@ -1011,7 +1011,7 @@ suite('ExtHostLanguageFeatures', function () { })); return rpcProtocol.sync().then(() => { - return getDocumentFormattingEdits(model, { insertSpaces: true, tabSize: 4 }).then(value => { + return getDocumentFormattingEdits(model, { insertSpaces: true, tabSize: 4 }, CancellationToken.None).then(value => { assert.equal(value.length, 2); let [first, second] = value; assert.equal(first.text, 'testing'); @@ -1032,7 +1032,7 @@ suite('ExtHostLanguageFeatures', function () { })); return rpcProtocol.sync().then(() => { - return getDocumentFormattingEdits(model, { insertSpaces: true, tabSize: 4 }); + return getDocumentFormattingEdits(model, { insertSpaces: true, tabSize: 4 }, CancellationToken.None); }); }); @@ -1057,7 +1057,7 @@ suite('ExtHostLanguageFeatures', function () { })); return rpcProtocol.sync().then(() => { - return getDocumentFormattingEdits(model, { insertSpaces: true, tabSize: 4 }).then(value => { + return getDocumentFormattingEdits(model, { insertSpaces: true, tabSize: 4 }, CancellationToken.None).then(value => { assert.equal(value.length, 1); let [first] = value; assert.equal(first.text, 'testing'); @@ -1074,7 +1074,7 @@ suite('ExtHostLanguageFeatures', function () { })); return rpcProtocol.sync().then(() => { - return getDocumentRangeFormattingEdits(model, new EditorRange(1, 1, 1, 1), { insertSpaces: true, tabSize: 4 }).then(value => { + return getDocumentRangeFormattingEdits(model, new EditorRange(1, 1, 1, 1), { insertSpaces: true, tabSize: 4 }, CancellationToken.None).then(value => { assert.equal(value.length, 1); let [first] = value; assert.equal(first.text, 'testing'); @@ -1100,7 +1100,7 @@ suite('ExtHostLanguageFeatures', function () { } })); return rpcProtocol.sync().then(() => { - return getDocumentRangeFormattingEdits(model, new EditorRange(1, 1, 1, 1), { insertSpaces: true, tabSize: 4 }).then(value => { + return getDocumentRangeFormattingEdits(model, new EditorRange(1, 1, 1, 1), { insertSpaces: true, tabSize: 4 }, CancellationToken.None).then(value => { assert.equal(value.length, 1); let [first] = value; assert.equal(first.text, 'range2'); @@ -1120,7 +1120,7 @@ suite('ExtHostLanguageFeatures', function () { })); return rpcProtocol.sync().then(() => { - return getDocumentRangeFormattingEdits(model, new EditorRange(1, 1, 1, 1), { insertSpaces: true, tabSize: 4 }); + return getDocumentRangeFormattingEdits(model, new EditorRange(1, 1, 1, 1), { insertSpaces: true, tabSize: 4 }, CancellationToken.None); }); }); From 7db62946186d368307d7ece6a694e624a12b5b2b Mon Sep 17 00:00:00 2001 From: Johannes Rieken Date: Mon, 6 Aug 2018 12:55:29 +0200 Subject: [PATCH 0497/1276] make sure dots have enough space, fixes #53094 --- src/vs/editor/common/services/modelServiceImpl.ts | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/vs/editor/common/services/modelServiceImpl.ts b/src/vs/editor/common/services/modelServiceImpl.ts index 56a282da585..560ed428507 100644 --- a/src/vs/editor/common/services/modelServiceImpl.ts +++ b/src/vs/editor/common/services/modelServiceImpl.ts @@ -85,9 +85,12 @@ class ModelMarkerHandler { let ret = Range.lift(rawMarker); - if (rawMarker.severity === MarkerSeverity.Hint && Range.spansMultipleLines(ret)) { - // never render hints on multiple lines - ret = ret.setEndPosition(ret.startLineNumber, ret.startColumn); + if (rawMarker.severity === MarkerSeverity.Hint) { + // * never render hints on multiple lines + // * make enough space for three dots + if (Range.spansMultipleLines(ret) || ret.endColumn - ret.startColumn < 2) { + ret = ret.setEndPosition(ret.startLineNumber, ret.startColumn + 2); + } } ret = model.validateRange(ret); From dcd40db38428beca156d55304bcce52d92fe2cb1 Mon Sep 17 00:00:00 2001 From: Johannes Rieken Date: Mon, 6 Aug 2018 14:27:31 +0200 Subject: [PATCH 0498/1276] fix #55866 --- src/vs/workbench/browser/parts/editor/noTabsTitleControl.ts | 4 ++++ src/vs/workbench/browser/parts/editor/tabsTitleControl.ts | 5 +++++ src/vs/workbench/browser/parts/editor/titleControl.ts | 6 ++++-- 3 files changed, 13 insertions(+), 2 deletions(-) diff --git a/src/vs/workbench/browser/parts/editor/noTabsTitleControl.ts b/src/vs/workbench/browser/parts/editor/noTabsTitleControl.ts index e4cd8fb91df..a5a99f0c2bd 100644 --- a/src/vs/workbench/browser/parts/editor/noTabsTitleControl.ts +++ b/src/vs/workbench/browser/parts/editor/noTabsTitleControl.ts @@ -147,6 +147,10 @@ export class NoTabsTitleControl extends TitleControl { this.redraw(); } + protected handleBreadcrumbsEnablementChange(): void { + this.redraw(); + } + private ifActiveEditorChanged(fn: () => void): void { if ( !this.lastRenderedActiveEditor && this.group.activeEditor || // active editor changed from null => editor diff --git a/src/vs/workbench/browser/parts/editor/tabsTitleControl.ts b/src/vs/workbench/browser/parts/editor/tabsTitleControl.ts index 605ac959776..2cf73b3bf5a 100644 --- a/src/vs/workbench/browser/parts/editor/tabsTitleControl.ts +++ b/src/vs/workbench/browser/parts/editor/tabsTitleControl.ts @@ -145,6 +145,11 @@ export class TabsTitleControl extends TitleControl { } } + protected handleBreadcrumbsEnablementChange(): void { + // relayout when breadcrumbs are enable/disabled + this.group.relayout(); + } + private registerContainerListeners(): void { // Group dragging diff --git a/src/vs/workbench/browser/parts/editor/titleControl.ts b/src/vs/workbench/browser/parts/editor/titleControl.ts index 3a123c9c218..91d2e0b3e83 100644 --- a/src/vs/workbench/browser/parts/editor/titleControl.ts +++ b/src/vs/workbench/browser/parts/editor/titleControl.ts @@ -101,11 +101,11 @@ export abstract class TitleControl extends Themable { if (!value && this.breadcrumbsControl) { this.breadcrumbsControl.dispose(); this.breadcrumbsControl = undefined; - this.group.relayout(); + this.handleBreadcrumbsEnablementChange(); } else if (value && !this.breadcrumbsControl) { this.breadcrumbsControl = this.instantiationService.createInstance(BreadcrumbsControl, container, options, this.group); this.breadcrumbsControl.update(); - this.group.relayout(); + this.handleBreadcrumbsEnablementChange(); } }); if (config.value) { @@ -113,6 +113,8 @@ export abstract class TitleControl extends Themable { } } + protected abstract handleBreadcrumbsEnablementChange(): void; + protected createEditorActionsToolBar(container: HTMLElement): void { const context = { groupId: this.group.id } as IEditorCommandsContext; From 5cdfa0ccc0ffc7dc27dff07d1f244afb9591cf69 Mon Sep 17 00:00:00 2001 From: Joao Moreno Date: Mon, 6 Aug 2018 14:34:14 +0200 Subject: [PATCH 0499/1276] remove more PPromise usages --- src/vs/base/parts/ipc/common/ipc.ts | 1 - src/vs/workbench/api/electron-browser/mainThreadWorkspace.ts | 4 ++-- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/src/vs/base/parts/ipc/common/ipc.ts b/src/vs/base/parts/ipc/common/ipc.ts index d6cc96d6170..8543a0ba8bf 100644 --- a/src/vs/base/parts/ipc/common/ipc.ts +++ b/src/vs/base/parts/ipc/common/ipc.ts @@ -25,7 +25,6 @@ enum MessageType { function isResponse(messageType: MessageType): boolean { return messageType === MessageType.ResponseInitialize || messageType === MessageType.ResponsePromiseSuccess - || messageType === MessageType.ResponsePromiseProgress || messageType === MessageType.ResponsePromiseError || messageType === MessageType.ResponsePromiseErrorObj || messageType === MessageType.ResponseEventFire; diff --git a/src/vs/workbench/api/electron-browser/mainThreadWorkspace.ts b/src/vs/workbench/api/electron-browser/mainThreadWorkspace.ts index c43f1982a74..e797ba2ba0b 100644 --- a/src/vs/workbench/api/electron-browser/mainThreadWorkspace.ts +++ b/src/vs/workbench/api/electron-browser/mainThreadWorkspace.ts @@ -11,7 +11,7 @@ import { TPromise } from 'vs/base/common/winjs.base'; import { localize } from 'vs/nls'; import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; import { IInstantiationService, ServicesAccessor } from 'vs/platform/instantiation/common/instantiation'; -import { IFileMatch, IFolderQuery, IPatternInfo, IQueryOptions, ISearchConfiguration, ISearchQuery, ISearchService, QueryType, ISearchProgressItem } from 'vs/platform/search/common/search'; +import { IFolderQuery, IPatternInfo, IQueryOptions, ISearchConfiguration, ISearchQuery, ISearchService, QueryType, ISearchProgressItem } from 'vs/platform/search/common/search'; import { IStatusbarService } from 'vs/platform/statusbar/common/statusbar'; import { IWorkspaceContextService, WorkbenchState } from 'vs/platform/workspace/common/workspace'; import { extHostNamedCustomer } from 'vs/workbench/api/electron-browser/extHostCustomers'; @@ -165,7 +165,7 @@ export class MainThreadWorkspace implements MainThreadWorkspaceShape { return search; } - $startTextSearch(pattern: IPatternInfo, options: IQueryOptions, requestId: number): TPromise { + $startTextSearch(pattern: IPatternInfo, options: IQueryOptions, requestId: number): TPromise { const workspace = this._contextService.getWorkspace(); const folders = workspace.folders.map(folder => folder.uri); From 2c070ce82c267769f6fa6ec664fe76ed27fd699a Mon Sep 17 00:00:00 2001 From: Christof Marti Date: Mon, 6 Aug 2018 14:44:58 +0200 Subject: [PATCH 0500/1276] Use QuickInput (#29096) --- .../editor/contrib/indentation/indentation.ts | 6 ++--- .../platform/quickinput/common/quickInput.ts | 7 +++++- .../browser/parts/quickinput/quickInput.ts | 22 +++++++++++-------- 3 files changed, 22 insertions(+), 13 deletions(-) diff --git a/src/vs/editor/contrib/indentation/indentation.ts b/src/vs/editor/contrib/indentation/indentation.ts index ab6c491ed74..7437bf9a56c 100644 --- a/src/vs/editor/contrib/indentation/indentation.ts +++ b/src/vs/editor/contrib/indentation/indentation.ts @@ -11,7 +11,6 @@ import { IEditorContribution, ICommand, ICursorStateComputerData, IEditOperation import { IIdentifiedSingleEditOperation, ITextModel } from 'vs/editor/common/model'; import { EditorContextKeys } from 'vs/editor/common/editorContextKeys'; import { registerEditorAction, ServicesAccessor, IActionOptions, EditorAction, registerEditorContribution } from 'vs/editor/browser/editorExtensions'; -import { IQuickOpenService } from 'vs/platform/quickOpen/common/quickOpen'; import { IModelService } from 'vs/editor/common/services/modelService'; import { Range } from 'vs/editor/common/core/range'; import { Selection } from 'vs/editor/common/core/selection'; @@ -23,6 +22,7 @@ import { TextEdit, StandardTokenType } from 'vs/editor/common/modes'; import * as IndentUtil from './indentUtils'; import { ICodeEditor } from 'vs/editor/browser/editorBrowser'; import { IndentConsts } from 'vs/editor/common/modes/supports/indentRules'; +import { IQuickInputService } from 'vs/platform/quickinput/common/quickInput'; export function shiftIndent(tabSize: number, indentation: string, count?: number): string { count = count || 1; @@ -217,7 +217,7 @@ export class ChangeIndentationSizeAction extends EditorAction { } public run(accessor: ServicesAccessor, editor: ICodeEditor): TPromise { - const quickOpenService = accessor.get(IQuickOpenService); + const quickInputService = accessor.get(IQuickInputService); const modelService = accessor.get(IModelService); let model = editor.getModel(); @@ -237,7 +237,7 @@ export class ChangeIndentationSizeAction extends EditorAction { const autoFocusIndex = Math.min(model.getOptions().tabSize - 1, 7); return TPromise.timeout(50 /* quick open is sensitive to being opened so soon after another */).then(() => - quickOpenService.pick(picks, { placeHolder: nls.localize({ key: 'selectTabWidth', comment: ['Tab corresponds to the tab key'] }, "Select Tab Size for Current File"), autoFocus: { autoFocusIndex } }).then(pick => { + quickInputService.pick(picks, { placeHolder: nls.localize({ key: 'selectTabWidth', comment: ['Tab corresponds to the tab key'] }, "Select Tab Size for Current File"), activeItem: picks[autoFocusIndex] }).then(pick => { if (pick) { model.updateOptions({ tabSize: parseInt(pick.label, 10), diff --git a/src/vs/platform/quickinput/common/quickInput.ts b/src/vs/platform/quickinput/common/quickInput.ts index 0ec12af97a1..311b5b65853 100644 --- a/src/vs/platform/quickinput/common/quickInput.ts +++ b/src/vs/platform/quickinput/common/quickInput.ts @@ -50,6 +50,11 @@ export interface IPickOptions { */ canPickMany?: boolean; + /** + * an optional property for the item to focus initially. + */ + activeItem?: TPromise | T; + onDidFocus?: (entry: T) => void; } @@ -179,7 +184,7 @@ export interface IQuickInputService { /** * Opens the quick input box for selecting items and returns a promise with the user selected item(s) if any. */ - pick>(picks: TPromise, options?: O, token?: CancellationToken): TPromise; + pick>(picks: TPromise | T[], options?: O, token?: CancellationToken): TPromise; /** * Opens the quick input box for text input and returns a promise with the user typed value if any. diff --git a/src/vs/workbench/browser/parts/quickinput/quickInput.ts b/src/vs/workbench/browser/parts/quickinput/quickInput.ts index 83145223bde..7e6021ce4a4 100644 --- a/src/vs/workbench/browser/parts/quickinput/quickInput.ts +++ b/src/vs/workbench/browser/parts/quickinput/quickInput.ts @@ -927,7 +927,7 @@ export class QuickInputService extends Component implements IQuickInputService { this.updateStyles(); } - pick>(picks: TPromise, options: O = {}, token: CancellationToken = CancellationToken.None): TPromise { + pick>(picks: TPromise | T[], options: O = {}, token: CancellationToken = CancellationToken.None): TPromise { return new TPromise((resolve, reject) => { if (token.isCancellationRequested) { resolve(undefined); @@ -977,15 +977,19 @@ export class QuickInputService extends Component implements IQuickInputService { input.matchOnDescription = options.matchOnDescription; input.matchOnDetail = options.matchOnDetail; input.busy = true; - picks.then(items => { - input.busy = false; - input.items = items; - if (input.canSelectMany) { - input.selectedItems = items.filter(item => item.picked); - } - }); + TPromise.join([picks, options.activeItem]) + .then(([items, activeItem]) => { + input.busy = false; + input.items = items; + if (input.canSelectMany) { + input.selectedItems = items.filter(item => item.picked); + } + if (activeItem) { + input.activeItems = [activeItem]; + } + }); input.show(); - picks.then(null, err => { + TPromise.wrap(picks).then(null, err => { reject(err); input.hide(); }); From c0917d8e6f0f1b5ea06ef231b24ff2ffa1416589 Mon Sep 17 00:00:00 2001 From: Johannes Rieken Date: Mon, 6 Aug 2018 14:51:35 +0200 Subject: [PATCH 0501/1276] fix #54545 --- src/vs/editor/contrib/suggest/suggestModel.ts | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/vs/editor/contrib/suggest/suggestModel.ts b/src/vs/editor/contrib/suggest/suggestModel.ts index 4a427b85dfe..d3b11c702fb 100644 --- a/src/vs/editor/contrib/suggest/suggestModel.ts +++ b/src/vs/editor/contrib/suggest/suggestModel.ts @@ -123,6 +123,9 @@ export class SuggestModel implements IDisposable { this._updateTriggerCharacters(); this.cancel(); })); + this._toDispose.push(this._editor.onDidBlurEditorText(() => { + this.cancel(); + })); this._toDispose.push(this._editor.onDidChangeConfiguration(() => { this._updateTriggerCharacters(); this._updateQuickSuggest(); From e92270e6f98213b49b754147d7744588830bc5be Mon Sep 17 00:00:00 2001 From: Johannes Rieken Date: Mon, 6 Aug 2018 15:05:39 +0200 Subject: [PATCH 0502/1276] prep work for #54938 --- src/vs/vscode.proposed.d.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/vs/vscode.proposed.d.ts b/src/vs/vscode.proposed.d.ts index b3ed4943e3e..64859f24589 100644 --- a/src/vs/vscode.proposed.d.ts +++ b/src/vs/vscode.proposed.d.ts @@ -362,9 +362,9 @@ declare module 'vscode' { priority?: number; title?: string; bubble?: boolean; - abbreviation?: string; + abbreviation?: string; // letter, not optional color?: ThemeColor; - source?: string; + source?: string; // hacky... we should remove it and use equality under the hood } export interface SourceControlResourceDecorations { From 7289c303db9c6437489b08e558a83a11ff063438 Mon Sep 17 00:00:00 2001 From: Johannes Rieken Date: Mon, 6 Aug 2018 15:09:27 +0200 Subject: [PATCH 0503/1276] :lipstick: --- src/vs/base/common/resources.ts | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/src/vs/base/common/resources.ts b/src/vs/base/common/resources.ts index c09f6334b7f..4afd24287ba 100644 --- a/src/vs/base/common/resources.ts +++ b/src/vs/base/common/resources.ts @@ -5,26 +5,26 @@ 'use strict'; import * as paths from 'vs/base/common/paths'; -import uri from 'vs/base/common/uri'; +import URI from 'vs/base/common/uri'; import { equalsIgnoreCase } from 'vs/base/common/strings'; import { Schemas } from 'vs/base/common/network'; import { isLinux } from 'vs/base/common/platform'; -export function getComparisonKey(resource: uri): string { +export function getComparisonKey(resource: URI): string { return hasToIgnoreCase(resource) ? resource.toString().toLowerCase() : resource.toString(); } -export function hasToIgnoreCase(resource: uri): boolean { +export function hasToIgnoreCase(resource: URI): boolean { // A file scheme resource is in the same platform as code, so ignore case for non linux platforms // Resource can be from another platform. Lowering the case as an hack. Should come from File system provider return resource.scheme === Schemas.file ? !isLinux : true; } -export function basenameOrAuthority(resource: uri): string { +export function basenameOrAuthority(resource: URI): string { return paths.basename(resource.path) || resource.authority; } -export function isEqualOrParent(resource: uri, candidate: uri, ignoreCase?: boolean): boolean { +export function isEqualOrParent(resource: URI, candidate: URI, ignoreCase?: boolean): boolean { if (resource.scheme === candidate.scheme && resource.authority === candidate.authority) { if (resource.scheme === 'file') { return paths.isEqualOrParent(resource.fsPath, candidate.fsPath, ignoreCase); @@ -36,7 +36,7 @@ export function isEqualOrParent(resource: uri, candidate: uri, ignoreCase?: bool return false; } -export function isEqual(first: uri, second: uri, ignoreCase?: boolean): boolean { +export function isEqual(first: URI, second: URI, ignoreCase?: boolean): boolean { const identityEquals = (first === second); if (identityEquals) { return true; @@ -53,7 +53,7 @@ export function isEqual(first: uri, second: uri, ignoreCase?: boolean): boolean return first.toString() === second.toString(); } -export function dirname(resource: uri): uri { +export function dirname(resource: URI): URI { const dirname = paths.dirname(resource.path); if (resource.authority && dirname && !paths.isAbsolute(dirname)) { return null; // If a URI contains an authority component, then the path component must either be empty or begin with a slash ("/") character @@ -64,14 +64,14 @@ export function dirname(resource: uri): uri { }); } -export function joinPath(resource: uri, pathFragment: string): uri { +export function joinPath(resource: URI, pathFragment: string): URI { const joinedPath = paths.join(resource.path || '/', pathFragment); return resource.with({ path: joinedPath }); } -export function distinctParents(items: T[], resourceAccessor: (item: T) => uri): T[] { +export function distinctParents(items: T[], resourceAccessor: (item: T) => URI): T[] { const distinctParents: T[] = []; for (let i = 0; i < items.length; i++) { const candidateResource = resourceAccessor(items[i]); From eec79d70207c5cf052b2ead3c055c14e788d8642 Mon Sep 17 00:00:00 2001 From: Joao Moreno Date: Mon, 6 Aug 2018 15:23:54 +0200 Subject: [PATCH 0504/1276] fixes #54399 --- .../parts/update/electron-browser/releaseNotesEditor.ts | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/vs/workbench/parts/update/electron-browser/releaseNotesEditor.ts b/src/vs/workbench/parts/update/electron-browser/releaseNotesEditor.ts index c81582ead3b..c3c0cf180a6 100644 --- a/src/vs/workbench/parts/update/electron-browser/releaseNotesEditor.ts +++ b/src/vs/workbench/parts/update/electron-browser/releaseNotesEditor.ts @@ -158,6 +158,13 @@ export class ReleaseNotesManager { if (!this._releaseNotesCache[version]) { this._releaseNotesCache[version] = this._requestService.request({ url }) .then(asText) + .then(text => { + if (!/^#\s/.test(text)) { // release notes always starts with `#` followed by whitespace + return TPromise.wrapError(new Error('Invalid release notes')); + } + + return TPromise.wrap(text); + }) .then(text => patchKeybindings(text)); } From 52d71bba275f7297b8d578b9d697b952b3f6c90c Mon Sep 17 00:00:00 2001 From: Joao Moreno Date: Mon, 6 Aug 2018 16:05:10 +0200 Subject: [PATCH 0505/1276] fixes #55563 --- extensions/git/package.nls.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/extensions/git/package.nls.json b/extensions/git/package.nls.json index dc335771b90..68a61cfd0de 100644 --- a/extensions/git/package.nls.json +++ b/extensions/git/package.nls.json @@ -51,7 +51,7 @@ "command.stashPop": "Pop Stash...", "command.stashPopLatest": "Pop Latest Stash", "config.enabled": "Whether git is enabled.", - "config.path": "Path to the git executable.", + "config.path": "Path to the git executable. Eg: `C:\\Program Files\\Git\\bin\\git.exe` (Windows).", "config.autoRepositoryDetection": "Configures when repositories should be automatically detected.", "config.autorefresh": "Whether auto refreshing is enabled.", "config.autofetch": "Whether auto fetching is enabled.", From 45e9530554a3f27c036ba03e0e22eb5e26f5810a Mon Sep 17 00:00:00 2001 From: Joao Moreno Date: Mon, 6 Aug 2018 16:07:17 +0200 Subject: [PATCH 0506/1276] fixes #55696 --- extensions/git/package.nls.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/extensions/git/package.nls.json b/extensions/git/package.nls.json index 68a61cfd0de..1ab36d8a859 100644 --- a/extensions/git/package.nls.json +++ b/extensions/git/package.nls.json @@ -52,7 +52,7 @@ "command.stashPopLatest": "Pop Latest Stash", "config.enabled": "Whether git is enabled.", "config.path": "Path to the git executable. Eg: `C:\\Program Files\\Git\\bin\\git.exe` (Windows).", - "config.autoRepositoryDetection": "Configures when repositories should be automatically detected.", + "config.autoRepositoryDetection": "Configures when repositories should be automatically detected. `subFolders` will scan for subfolders of the currently opened folder. `openEditors` will scan for parent folders of open files. `true` will scan in all cases. `false` will disable scanning.", "config.autorefresh": "Whether auto refreshing is enabled.", "config.autofetch": "Whether auto fetching is enabled.", "config.enableLongCommitWarning": "Whether long commit messages should be warned about.", From 10bf4c62abf29eff09d50e4ff455b66618eb6486 Mon Sep 17 00:00:00 2001 From: Christof Marti Date: Mon, 6 Aug 2018 15:09:02 +0200 Subject: [PATCH 0507/1276] Try improve typing --- src/vs/platform/quickinput/common/quickInput.ts | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/vs/platform/quickinput/common/quickInput.ts b/src/vs/platform/quickinput/common/quickInput.ts index 311b5b65853..40985866711 100644 --- a/src/vs/platform/quickinput/common/quickInput.ts +++ b/src/vs/platform/quickinput/common/quickInput.ts @@ -177,6 +177,8 @@ export interface IQuickInputButton { export const IQuickInputService = createDecorator('quickInputService'); +export type Omit = Pick>; + export interface IQuickInputService { _serviceBrand: any; @@ -184,7 +186,9 @@ export interface IQuickInputService { /** * Opens the quick input box for selecting items and returns a promise with the user selected item(s) if any. */ - pick>(picks: TPromise | T[], options?: O, token?: CancellationToken): TPromise; + pick(picks: TPromise | T[], options?: IPickOptions & { canPickMany: true }, token?: CancellationToken): TPromise; + pick(picks: TPromise | T[], options?: IPickOptions & { canPickMany: false }, token?: CancellationToken): TPromise; + pick(picks: TPromise | T[], options?: Omit, 'canPickMany'>, token?: CancellationToken): TPromise; /** * Opens the quick input box for text input and returns a promise with the user typed value if any. From 35f7ed7b7bdac5ea92d419ed3a32d8f031d20dad Mon Sep 17 00:00:00 2001 From: Christof Marti Date: Mon, 6 Aug 2018 16:30:30 +0200 Subject: [PATCH 0508/1276] Use QuickInput (#29096) --- .../platform/quickinput/common/quickInput.ts | 6 +++ .../browser/actions/workspaceCommands.ts | 16 ++++---- .../browser/parts/editor/editorStatus.ts | 40 ++++++++++--------- 3 files changed, 36 insertions(+), 26 deletions(-) diff --git a/src/vs/platform/quickinput/common/quickInput.ts b/src/vs/platform/quickinput/common/quickInput.ts index 40985866711..24d730db9b4 100644 --- a/src/vs/platform/quickinput/common/quickInput.ts +++ b/src/vs/platform/quickinput/common/quickInput.ts @@ -10,6 +10,7 @@ import { CancellationToken } from 'vs/base/common/cancellation'; import { ResolvedKeybinding } from 'vs/base/common/keyCodes'; import URI from 'vs/base/common/uri'; import { Event } from 'vs/base/common/event'; +import { FileKind } from 'vs/platform/files/common/files'; export interface IQuickPickItem { id?: string; @@ -19,6 +20,11 @@ export interface IQuickPickItem { picked?: boolean; } +export interface IFilePickItem extends IQuickPickItem { + resource: URI; + fileKind?: FileKind; +} + export interface IQuickNavigateConfiguration { keybindings: ResolvedKeybinding[]; } diff --git a/src/vs/workbench/browser/actions/workspaceCommands.ts b/src/vs/workbench/browser/actions/workspaceCommands.ts index 9ead6f9f1fb..268890850d4 100644 --- a/src/vs/workbench/browser/actions/workspaceCommands.ts +++ b/src/vs/workbench/browser/actions/workspaceCommands.ts @@ -14,7 +14,6 @@ import URI from 'vs/base/common/uri'; import * as resources from 'vs/base/common/resources'; import { IViewletService } from 'vs/workbench/services/viewlet/browser/viewlet'; import { dirname } from 'vs/base/common/paths'; -import { IQuickOpenService, IFilePickOpenEntry, IPickOptions } from 'vs/platform/quickOpen/common/quickOpen'; import { CancellationToken } from 'vs/base/common/cancellation'; import { mnemonicButtonLabel } from 'vs/base/common/labels'; import { CommandsRegistry } from 'vs/platform/commands/common/commands'; @@ -24,6 +23,7 @@ import { IEnvironmentService } from 'vs/platform/environment/common/environment' import { ServicesAccessor } from 'vs/platform/instantiation/common/instantiation'; import { isLinux } from 'vs/base/common/platform'; import { IUriDisplayService } from 'vs/platform/uriDisplay/common/uriDisplay'; +import { IQuickInputService, IPickOptions, IFilePickItem } from 'vs/platform/quickinput/common/quickInput'; export const ADD_ROOT_FOLDER_COMMAND_ID = 'addRootFolder'; export const ADD_ROOT_FOLDER_LABEL = nls.localize('addFolderToWorkspace', "Add Folder to Workspace..."); @@ -158,8 +158,8 @@ CommandsRegistry.registerCommand({ } }); -CommandsRegistry.registerCommand(PICK_WORKSPACE_FOLDER_COMMAND_ID, function (accessor, args?: [IPickOptions, CancellationToken]) { - const quickOpenService = accessor.get(IQuickOpenService); +CommandsRegistry.registerCommand(PICK_WORKSPACE_FOLDER_COMMAND_ID, function (accessor, args?: [IPickOptions, CancellationToken]) { + const quickInputService = accessor.get(IQuickInputService); const uriDisplayService = accessor.get(IUriDisplayService); const contextService = accessor.get(IWorkspaceContextService); @@ -175,10 +175,10 @@ CommandsRegistry.registerCommand(PICK_WORKSPACE_FOLDER_COMMAND_ID, function (acc folder, resource: folder.uri, fileKind: FileKind.ROOT_FOLDER - } as IFilePickOpenEntry; + } as IFilePickItem; }); - let options: IPickOptions; + let options: IPickOptions; if (args) { options = args[0]; } @@ -187,8 +187,8 @@ CommandsRegistry.registerCommand(PICK_WORKSPACE_FOLDER_COMMAND_ID, function (acc options = Object.create(null); } - if (!options.autoFocus) { - options.autoFocus = { autoFocusFirstEntry: true }; + if (!options.activeItem) { + options.activeItem = folderPicks[0]; } if (!options.placeHolder) { @@ -208,7 +208,7 @@ CommandsRegistry.registerCommand(PICK_WORKSPACE_FOLDER_COMMAND_ID, function (acc token = CancellationToken.None; } - return quickOpenService.pick(folderPicks, options, token).then(pick => { + return quickInputService.pick(folderPicks, options, token).then(pick => { if (!pick) { return void 0; } diff --git a/src/vs/workbench/browser/parts/editor/editorStatus.ts b/src/vs/workbench/browser/parts/editor/editorStatus.ts index 7b24eca3f73..20a1bc2d68d 100644 --- a/src/vs/workbench/browser/parts/editor/editorStatus.ts +++ b/src/vs/workbench/browser/parts/editor/editorStatus.ts @@ -58,6 +58,7 @@ import { Schemas } from 'vs/base/common/network'; import { IAnchor } from 'vs/base/browser/ui/contextview/contextview'; import { Themable } from 'vs/workbench/common/theme'; import { IPreferencesService } from 'vs/workbench/services/preferences/common/preferences'; +import { IQuickInputService, IQuickPickItem } from 'vs/platform/quickinput/common/quickInput'; class SideBySideEditorEncodingSupport implements IEncodingSupport { constructor(private master: IEncodingSupport, private details: IEncodingSupport) { } @@ -834,6 +835,7 @@ export class ChangeModeAction extends Action { @IEditorService private editorService: IEditorService, @IWorkspaceConfigurationService private configurationService: IWorkspaceConfigurationService, @IQuickOpenService private quickOpenService: IQuickOpenService, + @IQuickInputService private quickInputService: IQuickInputService, @IPreferencesService private preferencesService: IPreferencesService, @IInstantiationService private instantiationService: IInstantiationService, @IUntitledEditorService private untitledEditorService: IUntitledEditorService @@ -844,7 +846,7 @@ export class ChangeModeAction extends Action { run(): TPromise { const activeTextEditorWidget = getCodeEditor(this.editorService.activeTextEditorWidget); if (!activeTextEditorWidget) { - return this.quickOpenService.pick([{ label: nls.localize('noEditor', "No text editor active at this time") }]); + return this.quickInputService.pick([{ label: nls.localize('noEditor', "No text editor active at this time") }]); } const textModel = activeTextEditorWidget.getModel(); @@ -987,10 +989,10 @@ export class ChangeModeAction extends Action { const currentAssociation = this.modeService.getModeIdByFilenameOrFirstLine(basename); const languages = this.modeService.getRegisteredLanguageNames(); - const picks: IPickOpenEntry[] = languages.sort().map((lang, index) => { + const picks: IQuickPickItem[] = languages.sort().map((lang, index) => { const id = this.modeService.getModeIdForLanguageName(lang.toLowerCase()); - return { + return { id, label: lang, description: (id === currentAssociation) ? nls.localize('currentAssociation', "Current Association") : void 0 @@ -998,7 +1000,7 @@ export class ChangeModeAction extends Action { }); TPromise.timeout(50 /* quick open is sensitive to being opened so soon after another */).done(() => { - this.quickOpenService.pick(picks, { placeHolder: nls.localize('pickLanguageToConfigure', "Select Language Mode to Associate with '{0}'", extension || basename) }).done(language => { + this.quickInputService.pick(picks, { placeHolder: nls.localize('pickLanguageToConfigure', "Select Language Mode to Associate with '{0}'", extension || basename) }).done(language => { if (language) { const fileAssociationsConfig = this.configurationService.inspect(FILES_ASSOCIATIONS_CONFIG); @@ -1030,7 +1032,7 @@ export class ChangeModeAction extends Action { } } -export interface IChangeEOLEntry extends IPickOpenEntry { +export interface IChangeEOLEntry extends IQuickPickItem { eol: EndOfLineSequence; } @@ -1043,7 +1045,8 @@ class ChangeIndentationAction extends Action { actionId: string, actionLabel: string, @IEditorService private editorService: IEditorService, - @IQuickOpenService private quickOpenService: IQuickOpenService + @IQuickOpenService private quickOpenService: IQuickOpenService, + @IQuickInputService private quickInputService: IQuickInputService ) { super(actionId, actionLabel); } @@ -1051,11 +1054,11 @@ class ChangeIndentationAction extends Action { run(): TPromise { const activeTextEditorWidget = getCodeEditor(this.editorService.activeTextEditorWidget); if (!activeTextEditorWidget) { - return this.quickOpenService.pick([{ label: nls.localize('noEditor', "No text editor active at this time") }]); + return this.quickInputService.pick([{ label: nls.localize('noEditor', "No text editor active at this time") }]); } if (!isWritableCodeEditor(activeTextEditorWidget)) { - return this.quickOpenService.pick([{ label: nls.localize('noWritableCodeEditor', "The active code editor is read-only.") }]); + return this.quickInputService.pick([{ label: nls.localize('noWritableCodeEditor', "The active code editor is read-only.") }]); } const picks = [ @@ -1093,7 +1096,7 @@ export class ChangeEOLAction extends Action { actionId: string, actionLabel: string, @IEditorService private editorService: IEditorService, - @IQuickOpenService private quickOpenService: IQuickOpenService + @IQuickInputService private quickInputService: IQuickInputService ) { super(actionId, actionLabel); } @@ -1101,11 +1104,11 @@ export class ChangeEOLAction extends Action { run(): TPromise { const activeTextEditorWidget = getCodeEditor(this.editorService.activeTextEditorWidget); if (!activeTextEditorWidget) { - return this.quickOpenService.pick([{ label: nls.localize('noEditor', "No text editor active at this time") }]); + return this.quickInputService.pick([{ label: nls.localize('noEditor', "No text editor active at this time") }]); } if (!isWritableCodeEditor(activeTextEditorWidget)) { - return this.quickOpenService.pick([{ label: nls.localize('noWritableCodeEditor', "The active code editor is read-only.") }]); + return this.quickInputService.pick([{ label: nls.localize('noWritableCodeEditor', "The active code editor is read-only.") }]); } const textModel = activeTextEditorWidget.getModel(); @@ -1117,7 +1120,7 @@ export class ChangeEOLAction extends Action { const selectedIndex = (textModel && textModel.getEOL() === '\n') ? 0 : 1; - return this.quickOpenService.pick(EOLOptions, { placeHolder: nls.localize('pickEndOfLine', "Select End of Line Sequence"), autoFocus: { autoFocusIndex: selectedIndex } }).then(eol => { + return this.quickInputService.pick(EOLOptions, { placeHolder: nls.localize('pickEndOfLine', "Select End of Line Sequence"), activeItem: EOLOptions[selectedIndex] }).then(eol => { if (eol) { const activeCodeEditor = getCodeEditor(this.editorService.activeTextEditorWidget); if (activeCodeEditor && isWritableCodeEditor(activeCodeEditor)) { @@ -1139,6 +1142,7 @@ export class ChangeEncodingAction extends Action { actionLabel: string, @IEditorService private editorService: IEditorService, @IQuickOpenService private quickOpenService: IQuickOpenService, + @IQuickInputService private quickInputService: IQuickInputService, @ITextResourceConfigurationService private textResourceConfigurationService: ITextResourceConfigurationService, @IFileService private fileService: IFileService ) { @@ -1147,19 +1151,19 @@ export class ChangeEncodingAction extends Action { run(): TPromise { if (!getCodeEditor(this.editorService.activeTextEditorWidget)) { - return this.quickOpenService.pick([{ label: nls.localize('noEditor', "No text editor active at this time") }]); + return this.quickInputService.pick([{ label: nls.localize('noEditor', "No text editor active at this time") }]); } let activeControl = this.editorService.activeControl; let encodingSupport: IEncodingSupport = toEditorWithEncodingSupport(activeControl.input); if (!encodingSupport) { - return this.quickOpenService.pick([{ label: nls.localize('noFileEditor', "No file active at this time") }]); + return this.quickInputService.pick([{ label: nls.localize('noFileEditor', "No file active at this time") }]); } - let pickActionPromise: TPromise; + let pickActionPromise: TPromise; - let saveWithEncodingPick: IPickOpenEntry; - let reopenWithEncodingPick: IPickOpenEntry; + let saveWithEncodingPick: IQuickPickItem; + let reopenWithEncodingPick: IQuickPickItem; if (language === LANGUAGE_DEFAULT) { saveWithEncodingPick = { label: nls.localize('saveWithEncoding', "Save with Encoding") }; reopenWithEncodingPick = { label: nls.localize('reopenWithEncoding', "Reopen with Encoding") }; @@ -1173,7 +1177,7 @@ export class ChangeEncodingAction extends Action { } else if (!isWritableBaseEditor(activeControl)) { pickActionPromise = TPromise.as(reopenWithEncodingPick); } else { - pickActionPromise = this.quickOpenService.pick([reopenWithEncodingPick, saveWithEncodingPick], { placeHolder: nls.localize('pickAction', "Select Action"), matchOnDetail: true }); + pickActionPromise = this.quickInputService.pick([reopenWithEncodingPick, saveWithEncodingPick], { placeHolder: nls.localize('pickAction', "Select Action"), matchOnDetail: true }); } return pickActionPromise.then(action => { From 3ffdfae516ec9df525e1f7de642e50a91882771e Mon Sep 17 00:00:00 2001 From: Jackson Kearl Date: Mon, 6 Aug 2018 09:42:42 -0700 Subject: [PATCH 0509/1276] Fix bug causing workspace recommendations to go away upon ignoring a recommendation (#55805) * Fix bug causing workspace recommendations to go away upon ignoring a recommendation * ONly show on @recommended or @recommended:workspace * Make more consistant --- .../parts/extensions/electron-browser/extensionsViews.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/vs/workbench/parts/extensions/electron-browser/extensionsViews.ts b/src/vs/workbench/parts/extensions/electron-browser/extensionsViews.ts index 8fc5ed3bca1..70edc1d5fab 100644 --- a/src/vs/workbench/parts/extensions/electron-browser/extensionsViews.ts +++ b/src/vs/workbench/parts/extensions/electron-browser/extensionsViews.ts @@ -801,7 +801,8 @@ export class WorkspaceRecommendedExtensionsView extends ExtensionsListView { } async show(query: string): Promise> { - let model = await ((query && query.trim() !== '@recommended') ? this.showEmptyModel() : super.show(this.recommendedExtensionsQuery)); + let shouldShowEmptyView = query && query.trim() !== '@recommended' && query.trim() !== '@recommended:workspace'; + let model = await (shouldShowEmptyView ? this.showEmptyModel() : super.show(this.recommendedExtensionsQuery)); this.setExpanded(model.length > 0); return model; } From 24465045a1307c6f26a8eb105dec9a5ae49e8d50 Mon Sep 17 00:00:00 2001 From: rebornix Date: Mon, 6 Aug 2018 11:26:36 -0700 Subject: [PATCH 0510/1276] Fix microsoft/vscode-pull-request-github#127. Close new comment widget when escape if it's empty --- .../comments/electron-browser/commentThreadWidget.ts | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/src/vs/workbench/parts/comments/electron-browser/commentThreadWidget.ts b/src/vs/workbench/parts/comments/electron-browser/commentThreadWidget.ts index 41fd94bf268..93f9c3209fe 100644 --- a/src/vs/workbench/parts/comments/electron-browser/commentThreadWidget.ts +++ b/src/vs/workbench/parts/comments/electron-browser/commentThreadWidget.ts @@ -354,9 +354,14 @@ export class ReviewZoneWidget extends ZoneWidget { this._localToDispose.push(this._commentEditor.onKeyDown((ev: IKeyboardEvent) => { const hasExistingComments = this._commentThread.comments.length > 0; - if (this._commentEditor.getModel().getValueLength() === 0 && ev.keyCode === KeyCode.Escape && hasExistingComments) { - if (dom.hasClass(this._commentForm, 'expand')) { - dom.removeClass(this._commentForm, 'expand'); + + if (this._commentEditor.getModel().getValueLength() === 0 && ev.keyCode === KeyCode.Escape) { + if (hasExistingComments) { + if (dom.hasClass(this._commentForm, 'expand')) { + dom.removeClass(this._commentForm, 'expand'); + } + } else { + this.dispose(); } } })); From 141877e7e4ff442b4db07d111e5248602c14cdad Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Mon, 6 Aug 2018 11:40:41 -0700 Subject: [PATCH 0511/1276] Update xterm Removed Terminal.send (private API). --- package.json | 2 +- src/typings/vscode-xterm.d.ts | 2 +- src/vs/platform/driver/electron-browser/driver.ts | 2 +- yarn.lock | 6 +++--- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/package.json b/package.json index 6a66667a271..39865234fc7 100644 --- a/package.json +++ b/package.json @@ -50,7 +50,7 @@ "vscode-nsfw": "1.0.17", "vscode-ripgrep": "^1.0.1", "vscode-textmate": "^4.0.1", - "vscode-xterm": "3.6.0-beta13", + "vscode-xterm": "3.7.0-beta1", "yauzl": "^2.9.1" }, "devDependencies": { diff --git a/src/typings/vscode-xterm.d.ts b/src/typings/vscode-xterm.d.ts index b3a6c367c60..5f1e27de082 100644 --- a/src/typings/vscode-xterm.d.ts +++ b/src/typings/vscode-xterm.d.ts @@ -692,7 +692,7 @@ declare module 'vscode-xterm' { translateBufferLineToString(lineIndex: number, trimRight: boolean): string; }; - send(text: string): void; + handler(text: string): void; /** * Emit an event on the terminal. diff --git a/src/vs/platform/driver/electron-browser/driver.ts b/src/vs/platform/driver/electron-browser/driver.ts index 4dbaaff6c95..6b4d876f49d 100644 --- a/src/vs/platform/driver/electron-browser/driver.ts +++ b/src/vs/platform/driver/electron-browser/driver.ts @@ -207,7 +207,7 @@ class WindowDriver implements IWindowDriver { return TPromise.wrapError(new Error('Xterm not found')); } - xterm._core.send(text); + xterm._core.handler(text); return TPromise.as(null); } diff --git a/yarn.lock b/yarn.lock index b0b61b7a439..e6fcc699ad7 100644 --- a/yarn.lock +++ b/yarn.lock @@ -6125,9 +6125,9 @@ vscode-textmate@^4.0.1: dependencies: oniguruma "^7.0.0" -vscode-xterm@3.6.0-beta13: - version "3.6.0-beta13" - resolved "https://registry.yarnpkg.com/vscode-xterm/-/vscode-xterm-3.6.0-beta13.tgz#88c511041beb9f84fa63ed52fec074c5ccaff296" +vscode-xterm@3.7.0-beta1: + version "3.7.0-beta1" + resolved "https://registry.yarnpkg.com/vscode-xterm/-/vscode-xterm-3.7.0-beta1.tgz#c1af64a25ff2f157daecce2326277c1e51acb80d" vso-node-api@^6.1.2-preview: version "6.1.2-preview" From 898474a40774f00ee3be136ee4bcdb5e67656a40 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?D=C3=A1niel=20Tar?= Date: Wed, 1 Aug 2018 17:21:01 +0200 Subject: [PATCH 0512/1276] Fix hot exit settings' descriptions --- .../parts/files/electron-browser/files.contribution.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/vs/workbench/parts/files/electron-browser/files.contribution.ts b/src/vs/workbench/parts/files/electron-browser/files.contribution.ts index 7656b2f3b24..f6b90bd8536 100644 --- a/src/vs/workbench/parts/files/electron-browser/files.contribution.ts +++ b/src/vs/workbench/parts/files/electron-browser/files.contribution.ts @@ -293,8 +293,8 @@ configurationRegistry.registerConfiguration({ 'default': HotExitConfiguration.ON_EXIT, 'enumDescriptions': [ 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.'), - nls.localize('hotExit.onExitAndWindowClose', '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), and also for any window with a folder opened regardless of whether it\'s the last window. All windows without folders opened will be restored upon next launch. To restore folder windows as they were before shutdown set `#window.restoreWindows#` to `all`.') + 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.'), + nls.localize('hotExit.onExitAndWindowClose', '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), and also for any window with a folder opened regardless of whether it\'s the last window. All windows without folders opened will be restored upon next launch. To restore folder windows as they were before shutdown set `#window.restoreWindows#` to `all`.') ], 'description': nls.localize('hotExit', "Controls whether unsaved files are remembered between sessions, allowing the save prompt when exiting the editor to be skipped.", HotExitConfiguration.ON_EXIT, HotExitConfiguration.ON_EXIT_AND_WINDOW_CLOSE) }, From 5ef09f9f62a36ce4a509f222ffa64588a3be3c0b Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Mon, 6 Aug 2018 11:58:05 -0700 Subject: [PATCH 0513/1276] Remove texture atlas terminal setting The default and only option is now dynamic Fixes #54907 --- src/vs/workbench/parts/terminal/common/terminal.ts | 1 - .../terminal/electron-browser/terminal.contribution.ts | 9 +-------- .../parts/terminal/electron-browser/terminalInstance.ts | 3 ++- 3 files changed, 3 insertions(+), 10 deletions(-) diff --git a/src/vs/workbench/parts/terminal/common/terminal.ts b/src/vs/workbench/parts/terminal/common/terminal.ts index 245a8ac3a6e..56f40227d1c 100644 --- a/src/vs/workbench/parts/terminal/common/terminal.ts +++ b/src/vs/workbench/parts/terminal/common/terminal.ts @@ -98,7 +98,6 @@ export interface ITerminalConfiguration { }; showExitAlert: boolean; experimentalRestore: boolean; - experimentalTextureCachingStrategy: 'static' | 'dynamic'; } export interface ITerminalConfigHelper { diff --git a/src/vs/workbench/parts/terminal/electron-browser/terminal.contribution.ts b/src/vs/workbench/parts/terminal/electron-browser/terminal.contribution.ts index 4e288255067..209de8feb66 100644 --- a/src/vs/workbench/parts/terminal/electron-browser/terminal.contribution.ts +++ b/src/vs/workbench/parts/terminal/electron-browser/terminal.contribution.ts @@ -361,14 +361,7 @@ configurationRegistry.registerConfiguration({ description: nls.localize('terminal.integrated.experimentalRestore', "Controls whether to restore terminal sessions for the workspace automatically when launching VS Code. This is an experimental setting; it may be buggy and could change or be removed in the future."), type: 'boolean', default: false - }, - // TODO: Default to dynamic and remove setting in 1.27 - 'terminal.integrated.experimentalTextureCachingStrategy': { - description: nls.localize('terminal.integrated.experimentalTextureCachingStrategy', "Controls how the terminal stores glyph textures. `static` is the default and uses a fixed texture to draw the characters from. `dynamic` will draw the characters to the texture as they are needed, this should boost overall performance at the cost of slightly increased draw time the first time a character is drawn. `dynamic` will eventually become the default and this setting will be removed. Changes to this setting will only apply to new terminals."), - type: 'string', - enum: ['static', 'dynamic'], - default: 'dynamic' - }, + } } }); diff --git a/src/vs/workbench/parts/terminal/electron-browser/terminalInstance.ts b/src/vs/workbench/parts/terminal/electron-browser/terminalInstance.ts index 42174a7c0ac..0b7ed17b6dc 100644 --- a/src/vs/workbench/parts/terminal/electron-browser/terminalInstance.ts +++ b/src/vs/workbench/parts/terminal/electron-browser/terminalInstance.ts @@ -293,7 +293,8 @@ export class TerminalInstance implements ITerminalInstance { rightClickSelectsWord: config.rightClickBehavior === 'selectWord', // TODO: Guess whether to use canvas or dom better rendererType: config.rendererType === 'auto' ? 'canvas' : config.rendererType, - experimentalCharAtlas: config.experimentalTextureCachingStrategy + // TODO: Remove this once the setting is removed upstream + experimentalCharAtlas: 'dynamic' }); if (this._shellLaunchConfig.initialText) { this._xterm.writeln(this._shellLaunchConfig.initialText); From e39b1f076afff06d06d2284914aac6a4f89c29e1 Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Mon, 6 Aug 2018 12:02:55 -0700 Subject: [PATCH 0514/1276] Remove terminal experimental restore setting Part of #44302 --- .../parts/terminal/common/terminal.ts | 1 - .../parts/terminal/common/terminalService.ts | 41 +------------------ .../electron-browser/terminal.contribution.ts | 5 --- 3 files changed, 2 insertions(+), 45 deletions(-) diff --git a/src/vs/workbench/parts/terminal/common/terminal.ts b/src/vs/workbench/parts/terminal/common/terminal.ts index 56f40227d1c..b7a2c8e5915 100644 --- a/src/vs/workbench/parts/terminal/common/terminal.ts +++ b/src/vs/workbench/parts/terminal/common/terminal.ts @@ -97,7 +97,6 @@ export interface ITerminalConfiguration { windows: { [key: string]: string }; }; showExitAlert: boolean; - experimentalRestore: boolean; } export interface ITerminalConfigHelper { diff --git a/src/vs/workbench/parts/terminal/common/terminalService.ts b/src/vs/workbench/parts/terminal/common/terminalService.ts index 2c28f173a59..c1650928b9d 100644 --- a/src/vs/workbench/parts/terminal/common/terminalService.ts +++ b/src/vs/workbench/parts/terminal/common/terminalService.ts @@ -6,14 +6,12 @@ import * as errors from 'vs/base/common/errors'; import { Event, Emitter } from 'vs/base/common/event'; import { IContextKeyService, IContextKey } from 'vs/platform/contextkey/common/contextkey'; -import { ILifecycleService, LifecyclePhase } from 'vs/platform/lifecycle/common/lifecycle'; +import { ILifecycleService } from 'vs/platform/lifecycle/common/lifecycle'; import { IPanelService } from 'vs/workbench/services/panel/common/panelService'; import { IPartService } from 'vs/workbench/services/part/common/partService'; 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 } from 'vs/workbench/parts/terminal/common/terminal'; import { TPromise } from 'vs/base/common/winjs.base'; -import { IStorageService, StorageScope } from 'vs/platform/storage/common/storage'; - -const TERMINAL_STATE_STORAGE_KEY = 'terminal.state'; +import { IStorageService } from 'vs/platform/storage/common/storage'; export abstract class TerminalService implements ITerminalService { public _serviceBrand: any; @@ -70,8 +68,6 @@ export abstract class TerminalService implements ITerminalService { this._findWidgetVisible = KEYBINDING_CONTEXT_TERMINAL_FIND_WIDGET_VISIBLE.bindTo(this._contextKeyService); this.onTabDisposed(tab => this._removeTab(tab)); - lifecycleService.when(LifecyclePhase.Restoring).then(() => this._restoreTabs()); - this._handleContextKeys(); } @@ -94,29 +90,6 @@ export abstract class TerminalService implements ITerminalService { public abstract setContainers(panelContainer: HTMLElement, terminalContainer: HTMLElement): void; public abstract requestExtHostProcess(proxy: ITerminalProcessExtHostProxy, shellLaunchConfig: IShellLaunchConfig, cols: number, rows: number): void; - private _restoreTabs(): void { - if (!this.configHelper.config.experimentalRestore) { - return; - } - - const tabConfigsJson = this._storageService.get(TERMINAL_STATE_STORAGE_KEY, StorageScope.WORKSPACE); - if (!tabConfigsJson) { - return; - } - - const tabConfigs = <{ instances: IShellLaunchConfig[] }[]>JSON.parse(tabConfigsJson); - if (!Array.isArray(tabConfigs)) { - return; - } - - tabConfigs.forEach(tabConfig => { - const instance = this.createTerminal(tabConfig.instances[0]); - for (let i = 1; i < tabConfig.instances.length; i++) { - this.splitInstance(instance, tabConfig.instances[i]); - } - }); - } - private _onWillShutdown(): boolean | TPromise { if (this.terminalInstances.length === 0) { // No terminal instances, don't veto @@ -139,16 +112,6 @@ export abstract class TerminalService implements ITerminalService { } private _onShutdown(): void { - // Store terminal tab layout - if (this.configHelper.config.experimentalRestore) { - const configs = this.terminalTabs.map(tab => { - return { - instances: tab.terminalInstances.map(instance => instance.shellLaunchConfig) - }; - }); - this._storageService.store(TERMINAL_STATE_STORAGE_KEY, JSON.stringify(configs), StorageScope.WORKSPACE); - } - // Dispose of all instances this.terminalInstances.forEach(instance => instance.dispose()); } diff --git a/src/vs/workbench/parts/terminal/electron-browser/terminal.contribution.ts b/src/vs/workbench/parts/terminal/electron-browser/terminal.contribution.ts index 209de8feb66..fa2894cbcae 100644 --- a/src/vs/workbench/parts/terminal/electron-browser/terminal.contribution.ts +++ b/src/vs/workbench/parts/terminal/electron-browser/terminal.contribution.ts @@ -356,11 +356,6 @@ configurationRegistry.registerConfiguration({ description: nls.localize('terminal.integrated.showExitAlert', "Controls whether to show the alert \"The terminal process terminated with exit code\" when exit code is non-zero."), type: 'boolean', default: true - }, - 'terminal.integrated.experimentalRestore': { - description: nls.localize('terminal.integrated.experimentalRestore', "Controls whether to restore terminal sessions for the workspace automatically when launching VS Code. This is an experimental setting; it may be buggy and could change or be removed in the future."), - type: 'boolean', - default: false } } }); From 505f4b376bf2335a87eda3407a25598ac3cb6640 Mon Sep 17 00:00:00 2001 From: Rachel Macfarlane Date: Mon, 6 Aug 2018 12:32:19 -0700 Subject: [PATCH 0515/1276] Disable add comment button when textbox is empty, fixes https://github.com/Microsoft/vscode-pull-request-github/issues/128 --- .../electron-browser/commentThreadWidget.ts | 24 +++++++------------ 1 file changed, 9 insertions(+), 15 deletions(-) diff --git a/src/vs/workbench/parts/comments/electron-browser/commentThreadWidget.ts b/src/vs/workbench/parts/comments/electron-browser/commentThreadWidget.ts index 93f9c3209fe..de324d7d2f0 100644 --- a/src/vs/workbench/parts/comments/electron-browser/commentThreadWidget.ts +++ b/src/vs/workbench/parts/comments/electron-browser/commentThreadWidget.ts @@ -25,7 +25,7 @@ import { IInstantiationService } from 'vs/platform/instantiation/common/instanti import { IModelService } from 'vs/editor/common/services/modelService'; import { SimpleCommentEditor } from './simpleCommentEditor'; import URI from 'vs/base/common/uri'; -import { transparent, editorForeground, inputValidationErrorBorder, textLinkActiveForeground, textLinkForeground, focusBorder, textBlockQuoteBackground, textBlockQuoteBorder, contrastBorder } from 'vs/platform/theme/common/colorRegistry'; +import { transparent, editorForeground, textLinkActiveForeground, textLinkForeground, focusBorder, textBlockQuoteBackground, textBlockQuoteBorder, contrastBorder } from 'vs/platform/theme/common/colorRegistry'; import { IModeService } from 'vs/editor/common/services/modeService'; import { IKeyboardEvent } from 'vs/base/browser/keyboardEvent'; import { KeyCode } from 'vs/base/common/keyCodes'; @@ -371,23 +371,17 @@ export class ReviewZoneWidget extends ZoneWidget { const button = new Button(formActions); attachButtonStyler(button, this.themeService); button.label = 'Add comment'; - button.onDidClick(async () => { - if (!this._commentEditor.getValue()) { - this._commentEditor.focus(); - this._commentEditor.getDomNode().style.outline = `1px solid ${this.themeService.getTheme().getColor(inputValidationErrorBorder)}`; - - this._disposables.push(this._commentEditor.onDidChangeModelContent(_ => { - if (!this._commentEditor.getValue()) { - this._commentEditor.getDomNode().style.outline = `1px solid ${this.themeService.getTheme().getColor(inputValidationErrorBorder)}`; - } else { - this._commentEditor.getDomNode().style.outline = ''; - } - })); - - return; + button.enabled = false; + this._localToDispose.push(this._commentEditor.onDidChangeModelContent(_ => { + if (this._commentEditor.getValue()) { + button.enabled = true; + } else { + button.enabled = false; } + })); + button.onDidClick(async () => { let newCommentThread; if (this._commentThread.threadId) { // reply From b7e888bc680c5bdffcd2641a1ba0b3b683c82d10 Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Mon, 6 Aug 2018 12:46:59 -0700 Subject: [PATCH 0516/1276] Fix additional column select bug and flickering of last cell Fixes #55904 Fixes #55903 --- package.json | 2 +- yarn.lock | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/package.json b/package.json index 39865234fc7..efdb015672e 100644 --- a/package.json +++ b/package.json @@ -50,7 +50,7 @@ "vscode-nsfw": "1.0.17", "vscode-ripgrep": "^1.0.1", "vscode-textmate": "^4.0.1", - "vscode-xterm": "3.7.0-beta1", + "vscode-xterm": "3.7.0-beta2", "yauzl": "^2.9.1" }, "devDependencies": { diff --git a/yarn.lock b/yarn.lock index e6fcc699ad7..6dcbc60e044 100644 --- a/yarn.lock +++ b/yarn.lock @@ -6125,9 +6125,9 @@ vscode-textmate@^4.0.1: dependencies: oniguruma "^7.0.0" -vscode-xterm@3.7.0-beta1: - version "3.7.0-beta1" - resolved "https://registry.yarnpkg.com/vscode-xterm/-/vscode-xterm-3.7.0-beta1.tgz#c1af64a25ff2f157daecce2326277c1e51acb80d" +vscode-xterm@3.7.0-beta2: + version "3.7.0-beta2" + resolved "https://registry.yarnpkg.com/vscode-xterm/-/vscode-xterm-3.7.0-beta2.tgz#b46417f740ee6a90875ab956b4583f20a09cc2db" vso-node-api@^6.1.2-preview: version "6.1.2-preview" From 67d84d4096b5f7ea1487136e04c4797f71b4156d Mon Sep 17 00:00:00 2001 From: rebornix Date: Mon, 6 Aug 2018 12:52:21 -0700 Subject: [PATCH 0517/1276] Fix microsoft/vscode-pull-request-github#129. Diff indicators should not scale with lineDecoration width. --- src/vs/editor/browser/widget/media/diffEditor.css | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/vs/editor/browser/widget/media/diffEditor.css b/src/vs/editor/browser/widget/media/diffEditor.css index 08829aa00e7..5e71f38a9bd 100644 --- a/src/vs/editor/browser/widget/media/diffEditor.css +++ b/src/vs/editor/browser/widget/media/diffEditor.css @@ -41,6 +41,8 @@ opacity: 0.7; background-repeat: no-repeat; background-position: 50% 50%; + background-position: center; + background-size: 11px 11px; } .monaco-editor.hc-black .insert-sign, .monaco-diff-editor.hc-black .insert-sign, From d27ebd2ad81bde7bb7ac02570b5e66cdd0e13336 Mon Sep 17 00:00:00 2001 From: SteVen Batten Date: Mon, 6 Aug 2018 14:37:10 -0700 Subject: [PATCH 0518/1276] fixes #55893 --- src/vs/workbench/browser/parts/menubar/menubarPart.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vs/workbench/browser/parts/menubar/menubarPart.ts b/src/vs/workbench/browser/parts/menubar/menubarPart.ts index b0cbfbf570f..00f43d61a10 100644 --- a/src/vs/workbench/browser/parts/menubar/menubarPart.ts +++ b/src/vs/workbench/browser/parts/menubar/menubarPart.ts @@ -111,7 +111,7 @@ export class MenubarPart extends Part { private _onVisibilityChange: Emitter; - private static MAX_MENU_RECENT_ENTRIES = 5; + private static MAX_MENU_RECENT_ENTRIES = 10; constructor( id: string, From bb623e7733e37266080fc06fc8408afeb39c00cd Mon Sep 17 00:00:00 2001 From: Rob Lourens Date: Mon, 6 Aug 2018 16:41:32 -0700 Subject: [PATCH 0519/1276] Fix #55895 --- src/vs/workbench/parts/preferences/browser/settingsTree.ts | 4 +++- .../services/preferences/common/preferencesModels.ts | 2 +- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/src/vs/workbench/parts/preferences/browser/settingsTree.ts b/src/vs/workbench/parts/preferences/browser/settingsTree.ts index 8db86095977..8ad53e770cf 100644 --- a/src/vs/workbench/parts/preferences/browser/settingsTree.ts +++ b/src/vs/workbench/parts/preferences/browser/settingsTree.ts @@ -1250,7 +1250,9 @@ function getDisplayEnumOptions(setting: ISetting): string[] { }); } - return setting.enum.map(escapeInvisibleChars); + return setting.enum + .map(String) + .map(escapeInvisibleChars); } function escapeInvisibleChars(enumValue: string): string { diff --git a/src/vs/workbench/services/preferences/common/preferencesModels.ts b/src/vs/workbench/services/preferences/common/preferencesModels.ts index 2bb3302a828..1898d088670 100644 --- a/src/vs/workbench/services/preferences/common/preferencesModels.ts +++ b/src/vs/workbench/services/preferences/common/preferencesModels.ts @@ -899,7 +899,7 @@ class SettingsContentBuilder { if (setting.enumDescriptions && setting.enumDescriptions.some(desc => !!desc)) { setting.enumDescriptions.forEach((desc, i) => { - const displayEnum = escapeInvisibleChars(setting.enum[i]); + const displayEnum = escapeInvisibleChars(String(setting.enum[i])); const line = desc ? `${displayEnum}: ${fixSettingLink(desc)}` : displayEnum; From 2d996fe4fc9f902a68cd55adc7576a12f1e77d2a Mon Sep 17 00:00:00 2001 From: Rob Lourens Date: Mon, 6 Aug 2018 16:42:26 -0700 Subject: [PATCH 0520/1276] Fix #55911 --- build/builtInExtensions.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build/builtInExtensions.json b/build/builtInExtensions.json index f717be5d28d..e927280e32f 100644 --- a/build/builtInExtensions.json +++ b/build/builtInExtensions.json @@ -6,7 +6,7 @@ }, { "name": "ms-vscode.node-debug2", - "version": "1.26.7", + "version": "1.26.8", "repo": "https://github.com/Microsoft/vscode-node-debug2" } ] From 23f5f3e8d621f15be9c949038862bb88ad8be9e9 Mon Sep 17 00:00:00 2001 From: Rob Lourens Date: Mon, 6 Aug 2018 16:51:45 -0700 Subject: [PATCH 0521/1276] Remove unneeded PPromise progress callback... #53487 --- src/vs/workbench/api/node/extHostSearch.fileIndex.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vs/workbench/api/node/extHostSearch.fileIndex.ts b/src/vs/workbench/api/node/extHostSearch.fileIndex.ts index 4e2079d1df5..90b8a578f1c 100644 --- a/src/vs/workbench/api/node/extHostSearch.fileIndex.ts +++ b/src/vs/workbench/api/node/extHostSearch.fileIndex.ts @@ -416,7 +416,7 @@ export class FileIndexSearchManager { sortedSearch.then(complete => { this.sendAsBatches(complete.results, onBatch, FileIndexSearchManager.BATCH_SIZE); c(complete); - }, e, onBatch); + }, e); }, () => { sortedSearch.cancel(); }); From cb5f2ce5c8752687a63bfad6465c913c31cc18bd Mon Sep 17 00:00:00 2001 From: Ramya Achutha Rao Date: Mon, 6 Aug 2018 17:39:40 -0700 Subject: [PATCH 0522/1276] Understand json file activity --- .../textfile/common/textFileEditorModel.ts | 74 ++++++++++++++----- 1 file changed, 56 insertions(+), 18 deletions(-) diff --git a/src/vs/workbench/services/textfile/common/textFileEditorModel.ts b/src/vs/workbench/services/textfile/common/textFileEditorModel.ts index 41e23fc9981..d678b4a0e0a 100644 --- a/src/vs/workbench/services/textfile/common/textFileEditorModel.ts +++ b/src/vs/workbench/services/textfile/common/textFileEditorModel.ts @@ -360,18 +360,12 @@ export class TextFileEditorModel extends BaseTextEditorModel implements ITextFil } else { /* __GDPR__ "fileGet" : { - "mimeType" : { "classification": "SystemMetaData", "purpose": "FeatureInsight" }, - "ext": { "classification": "SystemMetaData", "purpose": "FeatureInsight" }, - "path": { "classification": "SystemMetaData", "purpose": "FeatureInsight" }, - "reason": { "classification": "SystemMetaData", "purpose": "FeatureInsight", "isMeasurement": true } + "${include}": [ + "${FileTelemetryData}" + ] } */ - this.telemetryService.publicLog('fileGet', { - mimeType: guessMimeTypes(this.resource.fsPath).join(', '), - ext: path.extname(this.resource.fsPath), - path: this.hashService.createSHA1(this.resource.fsPath), - reason: options && options.reason ? options.reason : LoadReason.OTHER - }); + this.telemetryService.publicLog('fileGet', this.getTelemetryData(options && options.reason ? options.reason : LoadReason.OTHER)); } return model; @@ -725,16 +719,12 @@ export class TextFileEditorModel extends BaseTextEditorModel implements ITextFil } else { /* __GDPR__ "filePUT" : { - "mimeType" : { "classification": "SystemMetaData", "purpose": "FeatureInsight" }, - "ext": { "classification": "SystemMetaData", "purpose": "FeatureInsight" }, - "reason": { "classification": "SystemMetaData", "purpose": "FeatureInsight", "isMeasurement": true } + "${include}": [ + "${FileTelemetryData}" + ] } */ - this.telemetryService.publicLog('filePUT', { - mimeType: guessMimeTypes(this.resource.fsPath).join(', '), - ext: path.extname(this.resource.fsPath), - reason: options.reason - }); + this.telemetryService.publicLog('filePUT', this.getTelemetryData(options.reason)); } // Update dirty state unless model has changed meanwhile @@ -795,6 +785,54 @@ export class TextFileEditorModel extends BaseTextEditorModel implements ITextFil }); } + private getTelemetryData(reason: number): Object { + const telemetryData = { + mimeType: guessMimeTypes(this.resource.fsPath).join(', '), + ext: path.extname(this.resource.fsPath), + path: this.hashService.createSHA1(this.resource.fsPath), + reason + }; + + if (path.extname(this.resource.fsPath) === '.json') { + switch (path.basename(this.resource.fsPath)) { + case 'package.json': + telemetryData['whitelistedjson'] = 'package.json'; + break; + case 'package-lock.json': + telemetryData['whitelistedjson'] = 'package-lock.json'; + break; + case 'tsconfig.json': + telemetryData['whitelistedjson'] = 'tsconfig.json'; + break; + case 'bower.json': + telemetryData['whitelistedjson'] = 'bower.json'; + break; + case 'tslint.json': + telemetryData['whitelistedjson'] = 'tslint.json'; + break; + case 'jsconfig.json': + telemetryData['whitelistedjson'] = 'jsconfig.json'; + break; + case '.eslintrc.json': + telemetryData['whitelistedjson'] = 'eslintrc.json'; + break; + default: + break; + } + } + + /* __GDPR__FRAGMENT__ + "FileTelemetryData" : { + "mimeType" : { "classification": "SystemMetaData", "purpose": "FeatureInsight" }, + "ext": { "classification": "SystemMetaData", "purpose": "FeatureInsight" }, + "path": { "classification": "SystemMetaData", "purpose": "FeatureInsight" }, + "reason": { "classification": "SystemMetaData", "purpose": "FeatureInsight", "isMeasurement": true }, + "whitelistedjson": { "classification": "SystemMetaData", "purpose": "FeatureInsight" } + } + */ + return telemetryData; + } + private doTouch(versionId: number): TPromise { return this.saveSequentializer.setPending(versionId, this.fileService.updateContent(this.lastResolvedDiskStat.resource, this.createSnapshot(), { mtime: this.lastResolvedDiskStat.mtime, From 03dc586a2aa2217e04c232febad391e20491f3c3 Mon Sep 17 00:00:00 2001 From: Ramya Achutha Rao Date: Mon, 6 Aug 2018 17:53:11 -0700 Subject: [PATCH 0523/1276] Refactoring --- .../textfile/common/textFileEditorModel.ts | 33 ++++--------------- 1 file changed, 6 insertions(+), 27 deletions(-) diff --git a/src/vs/workbench/services/textfile/common/textFileEditorModel.ts b/src/vs/workbench/services/textfile/common/textFileEditorModel.ts index d678b4a0e0a..1514022a8ca 100644 --- a/src/vs/workbench/services/textfile/common/textFileEditorModel.ts +++ b/src/vs/workbench/services/textfile/common/textFileEditorModel.ts @@ -42,6 +42,7 @@ export class TextFileEditorModel extends BaseTextEditorModel implements ITextFil static DEFAULT_CONTENT_CHANGE_BUFFER_DELAY = CONTENT_CHANGE_EVENT_BUFFER_DELAY; static DEFAULT_ORPHANED_CHANGE_BUFFER_DELAY = 100; + static WHITELIST_JSON = ['package.json', 'package-lock.json', 'tsconfig.json', 'jsconfig.json', 'bower.json', '.eslintrc.json', 'tslint.json']; private static saveErrorHandler: ISaveErrorHandler; static setSaveErrorHandler(handler: ISaveErrorHandler): void { TextFileEditorModel.saveErrorHandler = handler; } @@ -786,39 +787,17 @@ export class TextFileEditorModel extends BaseTextEditorModel implements ITextFil } private getTelemetryData(reason: number): Object { + const ext = path.extname(this.resource.fsPath); + const fileName = path.basename(this.resource.fsPath); const telemetryData = { mimeType: guessMimeTypes(this.resource.fsPath).join(', '), - ext: path.extname(this.resource.fsPath), + ext, path: this.hashService.createSHA1(this.resource.fsPath), reason }; - if (path.extname(this.resource.fsPath) === '.json') { - switch (path.basename(this.resource.fsPath)) { - case 'package.json': - telemetryData['whitelistedjson'] = 'package.json'; - break; - case 'package-lock.json': - telemetryData['whitelistedjson'] = 'package-lock.json'; - break; - case 'tsconfig.json': - telemetryData['whitelistedjson'] = 'tsconfig.json'; - break; - case 'bower.json': - telemetryData['whitelistedjson'] = 'bower.json'; - break; - case 'tslint.json': - telemetryData['whitelistedjson'] = 'tslint.json'; - break; - case 'jsconfig.json': - telemetryData['whitelistedjson'] = 'jsconfig.json'; - break; - case '.eslintrc.json': - telemetryData['whitelistedjson'] = 'eslintrc.json'; - break; - default: - break; - } + if (ext === '.json' && TextFileEditorModel.WHITELIST_JSON.indexOf(fileName) > -1) { + telemetryData['whitelistedjson'] = fileName; } /* __GDPR__FRAGMENT__ From 18bde2e29b5955e829095dbba0d3415d694924e6 Mon Sep 17 00:00:00 2001 From: ozyx Date: Mon, 6 Aug 2018 18:22:58 -0700 Subject: [PATCH 0524/1276] Refactor parameterHints settings as per code review comments --- .../common/config/commonEditorConfig.ts | 17 ++--- src/vs/editor/common/config/editorOptions.ts | 67 ++++++++++++++----- .../parameterHints/parameterHintsWidget.ts | 14 ++-- src/vs/monaco.d.ts | 33 ++++++--- .../telemetry/common/telemetryUtils.ts | 4 +- 5 files changed, 93 insertions(+), 42 deletions(-) diff --git a/src/vs/editor/common/config/commonEditorConfig.ts b/src/vs/editor/common/config/commonEditorConfig.ts index 8b39ee0f249..dae1337be0b 100644 --- a/src/vs/editor/common/config/commonEditorConfig.ts +++ b/src/vs/editor/common/config/commonEditorConfig.ts @@ -83,6 +83,7 @@ export abstract class CommonEditorConfiguration extends Disposable implements ed this._rawOptions.minimap = objects.mixin({}, this._rawOptions.minimap || {}); this._rawOptions.find = objects.mixin({}, this._rawOptions.find || {}); this._rawOptions.hover = objects.mixin({}, this._rawOptions.hover || {}); + this._rawOptions.parameterHints = objects.mixin({}, this._rawOptions.parameterHints || {}); this._validatedOptions = editorOptions.EditorOptionsValidator.validate(this._rawOptions, EDITOR_DEFAULTS); this.editor = null; @@ -488,10 +489,15 @@ const editorConfiguration: IConfigurationNode = { 'minimum': 0, 'description': nls.localize('quickSuggestionsDelay', "Controls the delay in milliseconds after which quick suggestions will show up.") }, - 'editor.parameterHints': { + 'editor.parameterHints.enabled': { 'type': 'boolean', - 'default': EDITOR_DEFAULTS.contribInfo.parameterHints, - 'description': nls.localize('parameterHints', "Enables a pop-up that shows parameter documentation and type information as you type.") + 'default': EDITOR_DEFAULTS.contribInfo.parameterHints.enabled, + 'description': nls.localize('parameterHints.enabled', "Enables a pop-up that shows parameter documentation and type information as you type.") + }, + 'editor.parameterHints.cycle': { + 'type': 'boolean', + 'default': EDITOR_DEFAULTS.contribInfo.parameterHints.cycle, + 'description': nls.localize('parameterHints.cycle', "Controls whether the parameter hints menu cycles or closes when reaching the end of the list.") }, 'editor.autoClosingBrackets': { 'type': 'boolean', @@ -684,11 +690,6 @@ const editorConfiguration: IConfigurationNode = { 'default': EDITOR_DEFAULTS.contribInfo.codeLens, 'description': nls.localize('codeLens', "Controls whether the editor shows CodeLens") }, - 'editor.cycleParameterHints': { - 'type': 'boolean', - 'default': EDITOR_DEFAULTS.contribInfo.cycleParameterHints, - 'description': nls.localize('cycleParameterHints', "Controls whether the parameter hints menu cycles or closes when reaching the end of the list.") - }, 'editor.folding': { 'type': 'boolean', 'default': EDITOR_DEFAULTS.contribInfo.folding, diff --git a/src/vs/editor/common/config/editorOptions.ts b/src/vs/editor/common/config/editorOptions.ts index 902d02abf79..1b99eacb988 100644 --- a/src/vs/editor/common/config/editorOptions.ts +++ b/src/vs/editor/common/config/editorOptions.ts @@ -158,6 +158,22 @@ export interface IEditorHoverOptions { sticky?: boolean; } +/** + * Configuration options for parameter hints + */ +export interface IEditorParameterHintOptions { + /** + * Enable parameter hints. + * Defaults to true. + */ + enabled?: boolean; + /** + * Enable cycling of parameter hints. + * Defaults to false. + */ + cycle?: boolean; +} + export interface ISuggestOptions { /** * Enable graceful matching. Defaults to true. @@ -416,11 +432,6 @@ export interface IEditorOptions { * Defaults to true. */ contextmenu?: boolean; - /** - * Enable cycling through parameter hints. - * Defaults to false. - */ - cycleParameterHints?: boolean; /** * A multiplier to be used on the `deltaX` and `deltaY` of mouse wheel scroll events. * Defaults to 1. @@ -456,9 +467,9 @@ export interface IEditorOptions { */ quickSuggestionsDelay?: number; /** - * Enables parameter hints + * Parameter hint options. */ - parameterHints?: boolean; + parameterHints?: IEditorParameterHintOptions; /** * Render icons in suggestions box. * Defaults to true. @@ -856,6 +867,11 @@ export interface InternalSuggestOptions { readonly snippetsPreventQuickSuggestions: boolean; } +export interface InternalParameterHintOptions { + readonly enabled: boolean; + readonly cycle: boolean; +} + export interface EditorWrappingInfo { readonly inDiffEditor: boolean; readonly isDominatedByLongLines: boolean; @@ -914,10 +930,9 @@ export interface EditorContribOptions { readonly hover: InternalEditorHoverOptions; readonly links: boolean; readonly contextmenu: boolean; - readonly cycleParameterHints: boolean; readonly quickSuggestions: boolean | { other: boolean, comments: boolean, strings: boolean }; readonly quickSuggestionsDelay: number; - readonly parameterHints: boolean; + readonly parameterHints: InternalParameterHintOptions; readonly iconsInSuggestions: boolean; readonly formatOnType: boolean; readonly formatOnPaste: boolean; @@ -1243,6 +1258,16 @@ export class InternalEditorOptions { ); } + /** + * @internal + */ + private static _equalsParameterHintOptions(a: InternalParameterHintOptions, b: InternalParameterHintOptions): boolean { + return ( + a.enabled === b.enabled + && a.cycle === b.cycle + ); + } + /** * @internal */ @@ -1295,10 +1320,9 @@ export class InternalEditorOptions { && this._equalsHoverOptions(a.hover, b.hover) && a.links === b.links && a.contextmenu === b.contextmenu - && a.cycleParameterHints === b.cycleParameterHints && InternalEditorOptions._equalsQuickSuggestions(a.quickSuggestions, b.quickSuggestions) && a.quickSuggestionsDelay === b.quickSuggestionsDelay - && a.parameterHints === b.parameterHints + && this._equalsParameterHintOptions(a.parameterHints, b.parameterHints) && a.iconsInSuggestions === b.iconsInSuggestions && a.formatOnType === b.formatOnType && a.formatOnPaste === b.formatOnPaste @@ -1739,6 +1763,17 @@ export class EditorOptionsValidator { }; } + private static _sanitizeParameterHintOpts(opts: IEditorParameterHintOptions, defaults: InternalParameterHintOptions): InternalParameterHintOptions { + if (typeof opts !== 'object') { + return defaults; + } + + return { + enabled: _boolean(opts.enabled, defaults.enabled), + cycle: _boolean(opts.cycle, defaults.cycle) + }; + } + private static _santizeHoverOpts(_opts: boolean | IEditorHoverOptions, defaults: InternalEditorHoverOptions): InternalEditorHoverOptions { let opts: IEditorHoverOptions; if (typeof _opts === 'boolean') { @@ -1891,10 +1926,9 @@ export class EditorOptionsValidator { hover: this._santizeHoverOpts(opts.hover, defaults.hover), links: _boolean(opts.links, defaults.links), contextmenu: _boolean(opts.contextmenu, defaults.contextmenu), - cycleParameterHints: _boolean(opts.cycleParameterHints, defaults.cycleParameterHints), quickSuggestions: quickSuggestions, quickSuggestionsDelay: _clampedInt(opts.quickSuggestionsDelay, defaults.quickSuggestionsDelay, Constants.MIN_SAFE_SMALL_INTEGER, Constants.MAX_SAFE_SMALL_INTEGER), - parameterHints: _boolean(opts.parameterHints, defaults.parameterHints), + parameterHints: this._sanitizeParameterHintOpts(opts.parameterHints, defaults.parameterHints), iconsInSuggestions: _boolean(opts.iconsInSuggestions, defaults.iconsInSuggestions), formatOnType: _boolean(opts.formatOnType, defaults.formatOnType), formatOnPaste: _boolean(opts.formatOnPaste, defaults.formatOnPaste), @@ -2000,7 +2034,6 @@ export class InternalEditorOptionsFactory { hover: opts.contribInfo.hover, links: (accessibilityIsOn ? false : opts.contribInfo.links), // DISABLED WHEN SCREEN READER IS ATTACHED contextmenu: opts.contribInfo.contextmenu, - cycleParameterHints: opts.contribInfo.cycleParameterHints, quickSuggestions: opts.contribInfo.quickSuggestions, quickSuggestionsDelay: opts.contribInfo.quickSuggestionsDelay, parameterHints: opts.contribInfo.parameterHints, @@ -2472,10 +2505,12 @@ export const EDITOR_DEFAULTS: IValidatedEditorOptions = { }, links: true, contextmenu: true, - cycleParameterHints: false, quickSuggestions: { other: true, comments: false, strings: false }, quickSuggestionsDelay: 10, - parameterHints: true, + parameterHints: { + enabled: true, + cycle: false + }, iconsInSuggestions: true, formatOnType: false, formatOnPaste: false, diff --git a/src/vs/editor/contrib/parameterHints/parameterHintsWidget.ts b/src/vs/editor/contrib/parameterHints/parameterHintsWidget.ts index 0120cb2d5a1..80c27ea30e5 100644 --- a/src/vs/editor/contrib/parameterHints/parameterHintsWidget.ts +++ b/src/vs/editor/contrib/parameterHints/parameterHintsWidget.ts @@ -169,7 +169,7 @@ export class ParameterHintsModel extends Disposable { } private onEditorConfigurationChange(): void { - this.enabled = this.editor.getConfiguration().contribInfo.parameterHints; + this.enabled = this.editor.getConfiguration().contribInfo.parameterHints.enabled; if (!this.enabled) { this.cancel(); @@ -476,15 +476,15 @@ export class ParameterHintsWidget implements IContentWidget, IDisposable { next(): boolean { const length = this.hints.signatures.length; const last = (this.currentSignature % length) === (length - 1); - const cycleParameterHints = this.editor.getConfiguration().contribInfo.cycleParameterHints; + const cycle = this.editor.getConfiguration().contribInfo.parameterHints.cycle; // If there is only one signature, or we're on last signature of list - if ((length < 2 || last) && !cycleParameterHints) { + if ((length < 2 || last) && !cycle) { this.cancel(); return false; } - if (last && cycleParameterHints) { + if (last && cycle) { this.currentSignature = 0; } else { this.currentSignature++; @@ -497,15 +497,15 @@ export class ParameterHintsWidget implements IContentWidget, IDisposable { previous(): boolean { const length = this.hints.signatures.length; const first = this.currentSignature === 0; - const cycleParameterHints = this.editor.getConfiguration().contribInfo.cycleParameterHints; + const cycle = this.editor.getConfiguration().contribInfo.parameterHints.cycle; // If there is only one signature, or we're on first signature of list - if ((length < 2 || first) && !cycleParameterHints) { + if ((length < 2 || first) && !cycle) { this.cancel(); return false; } - if (first && cycleParameterHints) { + if (first && cycle) { this.currentSignature = length - 1; } else { this.currentSignature--; diff --git a/src/vs/monaco.d.ts b/src/vs/monaco.d.ts index fd79f366e38..884de0bfcff 100644 --- a/src/vs/monaco.d.ts +++ b/src/vs/monaco.d.ts @@ -2508,6 +2508,22 @@ declare namespace monaco.editor { sticky?: boolean; } + /** + * Configuration options for parameter hints + */ + export interface IEditorParameterHintOptions { + /** + * Enable parameter hints. + * Defaults to true. + */ + enabled?: boolean; + /** + * Enable cycling of parameter hints. + * Defaults to false. + */ + cycle?: boolean; + } + export interface ISuggestOptions { /** * Enable graceful matching. Defaults to true. @@ -2754,11 +2770,6 @@ declare namespace monaco.editor { * Defaults to true. */ contextmenu?: boolean; - /** - * Enable cycling through parameter hints. - * Defaults to false. - */ - cycleParameterHints?: boolean; /** * A multiplier to be used on the `deltaX` and `deltaY` of mouse wheel scroll events. * Defaults to 1. @@ -2798,9 +2809,9 @@ declare namespace monaco.editor { */ quickSuggestionsDelay?: number; /** - * Enables parameter hints + * Parameter hint options. */ - parameterHints?: boolean; + parameterHints?: IEditorParameterHintOptions; /** * Render icons in suggestions box. * Defaults to true. @@ -3135,6 +3146,11 @@ declare namespace monaco.editor { readonly snippetsPreventQuickSuggestions: boolean; } + export interface InternalParameterHintOptions { + readonly enabled: boolean; + readonly cycle: boolean; + } + export interface EditorWrappingInfo { readonly inDiffEditor: boolean; readonly isDominatedByLongLines: boolean; @@ -3193,14 +3209,13 @@ declare namespace monaco.editor { readonly hover: InternalEditorHoverOptions; readonly links: boolean; readonly contextmenu: boolean; - readonly cycleParameterHints: boolean; readonly quickSuggestions: boolean | { other: boolean; comments: boolean; strings: boolean; }; readonly quickSuggestionsDelay: number; - readonly parameterHints: boolean; + readonly parameterHints: InternalParameterHintOptions; readonly iconsInSuggestions: boolean; readonly formatOnType: boolean; readonly formatOnPaste: boolean; diff --git a/src/vs/platform/telemetry/common/telemetryUtils.ts b/src/vs/platform/telemetry/common/telemetryUtils.ts index 9e655dfb6d6..83a4326ca5e 100644 --- a/src/vs/platform/telemetry/common/telemetryUtils.ts +++ b/src/vs/platform/telemetry/common/telemetryUtils.ts @@ -113,8 +113,8 @@ const configurationValueWhitelist = [ 'editor.multiCursorModifier', 'editor.quickSuggestions', 'editor.quickSuggestionsDelay', - 'editor.cycleParameterHints', - 'editor.parameterHints', + 'editor.parameterHints.enabled', + 'editor.parameterHints.cycle', 'editor.autoClosingBrackets', 'editor.autoIndent', 'editor.formatOnType', From bcb0e57b7f1d375505d36b27b42e7c519d2187d2 Mon Sep 17 00:00:00 2001 From: kieferrm Date: Mon, 6 Aug 2018 18:27:47 -0700 Subject: [PATCH 0525/1276] adding composer.json --- .../workbench/services/textfile/common/textFileEditorModel.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vs/workbench/services/textfile/common/textFileEditorModel.ts b/src/vs/workbench/services/textfile/common/textFileEditorModel.ts index 1514022a8ca..aea7e08e8f0 100644 --- a/src/vs/workbench/services/textfile/common/textFileEditorModel.ts +++ b/src/vs/workbench/services/textfile/common/textFileEditorModel.ts @@ -42,7 +42,7 @@ export class TextFileEditorModel extends BaseTextEditorModel implements ITextFil static DEFAULT_CONTENT_CHANGE_BUFFER_DELAY = CONTENT_CHANGE_EVENT_BUFFER_DELAY; static DEFAULT_ORPHANED_CHANGE_BUFFER_DELAY = 100; - static WHITELIST_JSON = ['package.json', 'package-lock.json', 'tsconfig.json', 'jsconfig.json', 'bower.json', '.eslintrc.json', 'tslint.json']; + static WHITELIST_JSON = ['package.json', 'package-lock.json', 'tsconfig.json', 'jsconfig.json', 'bower.json', '.eslintrc.json', 'tslint.json', 'composer.json']; private static saveErrorHandler: ISaveErrorHandler; static setSaveErrorHandler(handler: ISaveErrorHandler): void { TextFileEditorModel.saveErrorHandler = handler; } From 8a4c2ce110b21bd2d32a7342ee172a814d6535e4 Mon Sep 17 00:00:00 2001 From: Ramya Achutha Rao Date: Mon, 6 Aug 2018 19:15:00 -0700 Subject: [PATCH 0526/1276] Log telemetry for opt out experiment --- .../electron-browser/telemetryOptOut.ts | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/src/vs/workbench/parts/welcome/gettingStarted/electron-browser/telemetryOptOut.ts b/src/vs/workbench/parts/welcome/gettingStarted/electron-browser/telemetryOptOut.ts index 257d791463e..e220bb1054e 100644 --- a/src/vs/workbench/parts/welcome/gettingStarted/electron-browser/telemetryOptOut.ts +++ b/src/vs/workbench/parts/welcome/gettingStarted/electron-browser/telemetryOptOut.ts @@ -49,17 +49,28 @@ export class TelemetryOptOut implements IWorkbenchContribution { const privacyUrl = product.privacyStatementUrl || product.telemetryOptOutUrl; if (experimentState && experimentState.state === ExperimentState.Run && telemetryService.isOptedIn) { + const logTelemetry = (optout: boolean) => { + /* __GDPR__ + "experiments:optout" : { + "optOut": { "classification": "SystemMetaData", "purpose": "PerformanceAndHealth", "isMeasurement": true }optOut + } + */ + telemetryService.publicLog('experiments:optout', { optout }); + }; notificationService.prompt( Severity.Info, localize('telemetryOptOut.optOutOption', "Please help Microsoft improve Visual Studio Code by allowing the collection of usage data. Read our [privacy statement]({0}) for more details.", privacyUrl), [ { label: localize('telemetryOptOut.OptIn', "Yes, glad to help"), - run: () => { } + run: () => { + logTelemetry(false); + } }, { label: localize('telemetryOptOut.OptOut', "No, thanks"), run: () => { + logTelemetry(true); configurationService.updateValue('telemetry.enableTelemetry', false); configurationService.updateValue('telemetry.enableCrashReporter', false); } From 2ec120e8eec0e318743fc58094041e5e3e82d835 Mon Sep 17 00:00:00 2001 From: Ramya Achutha Rao Date: Mon, 6 Aug 2018 19:21:20 -0700 Subject: [PATCH 0527/1276] Update GDPR annotations --- .../welcome/gettingStarted/electron-browser/telemetryOptOut.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vs/workbench/parts/welcome/gettingStarted/electron-browser/telemetryOptOut.ts b/src/vs/workbench/parts/welcome/gettingStarted/electron-browser/telemetryOptOut.ts index e220bb1054e..3c76c9bedb4 100644 --- a/src/vs/workbench/parts/welcome/gettingStarted/electron-browser/telemetryOptOut.ts +++ b/src/vs/workbench/parts/welcome/gettingStarted/electron-browser/telemetryOptOut.ts @@ -52,7 +52,7 @@ export class TelemetryOptOut implements IWorkbenchContribution { const logTelemetry = (optout: boolean) => { /* __GDPR__ "experiments:optout" : { - "optOut": { "classification": "SystemMetaData", "purpose": "PerformanceAndHealth", "isMeasurement": true }optOut + "optOut": { "classification": "SystemMetaData", "purpose": "FeatureInsight", "isMeasurement": true } } */ telemetryService.publicLog('experiments:optout', { optout }); From e3c782821d1fa1cc5f1dd1a7f06e667322c058f5 Mon Sep 17 00:00:00 2001 From: Ramya Achutha Rao Date: Mon, 6 Aug 2018 21:48:05 -0700 Subject: [PATCH 0528/1276] Distro update for experiments --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index efdb015672e..8042314a7e6 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "code-oss-dev", "version": "1.27.0", - "distro": "3962f36fb9f758cc0c608d0c585d50a1f204de3a", + "distro": "73cb7173636931afba8d741be343ceafb11a177e", "author": { "name": "Microsoft Corporation" }, From b9caa370eef871e3e0cbb0d7641af7a7c7c8fbc9 Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Mon, 6 Aug 2018 22:24:07 -0700 Subject: [PATCH 0529/1276] Add context keys for platforms (#54894) Fixes #8962 --- src/vs/workbench/electron-browser/workbench.ts | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/vs/workbench/electron-browser/workbench.ts b/src/vs/workbench/electron-browser/workbench.ts index defea5dd0cc..28e1853fed9 100644 --- a/src/vs/workbench/electron-browser/workbench.ts +++ b/src/vs/workbench/electron-browser/workbench.ts @@ -597,6 +597,10 @@ export class Workbench extends Disposable implements IPartService { private handleContextKeys(): void { this.inZenMode = InEditorZenModeContext.bindTo(this.contextKeyService); + (new RawContextKey('isMac', isMacintosh)).bindTo(this.contextKeyService); + (new RawContextKey('isLinux', isLinux)).bindTo(this.contextKeyService); + (new RawContextKey('isWindows', isWindows)).bindTo(this.contextKeyService); + const sidebarVisibleContextRaw = new RawContextKey('sidebarVisible', false); this.sideBarVisibleContext = sidebarVisibleContextRaw.bindTo(this.contextKeyService); From 014737f9a07e66deb9e8efdc00d6915c34ed4a44 Mon Sep 17 00:00:00 2001 From: Johannes Rieken Date: Tue, 7 Aug 2018 10:29:27 +0200 Subject: [PATCH 0530/1276] tweak tree height (workaround for #55887) --- .../browser/parts/editor/breadcrumbsPicker.ts | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/src/vs/workbench/browser/parts/editor/breadcrumbsPicker.ts b/src/vs/workbench/browser/parts/editor/breadcrumbsPicker.ts index 3ee60065b1c..301be5ddb44 100644 --- a/src/vs/workbench/browser/parts/editor/breadcrumbsPicker.ts +++ b/src/vs/workbench/browser/parts/editor/breadcrumbsPicker.ts @@ -123,12 +123,20 @@ export abstract class BreadcrumbsPicker { } layout(height: number, width: number, arrowSize: number, arrowOffset: number) { - this._domNode.style.height = `${height}px`; + + let treeHeight = height - 2 * arrowSize; + let elementHeight = 22; + let elementCount = treeHeight / elementHeight; + if (elementCount % 2 !== 1) { + treeHeight = elementHeight * (elementCount + 1); + } + let totalHeight = treeHeight + 2 + arrowSize; + + this._domNode.style.height = `${totalHeight}px`; this._domNode.style.width = `${width}px`; this._arrow.style.borderWidth = `${arrowSize}px`; this._arrow.style.marginLeft = `${arrowOffset}px`; - - this._treeContainer.style.height = `${height - 2 * arrowSize}px`; + this._treeContainer.style.height = `${treeHeight}px`; this._treeContainer.style.width = `${width}px`; this._tree.layout(); } From 37ebbbec4045f8580f9aa44fcd2dd73ed6e93024 Mon Sep 17 00:00:00 2001 From: Joao Moreno Date: Tue, 7 Aug 2018 10:34:14 +0200 Subject: [PATCH 0531/1276] docs --- extensions/git/package.nls.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/extensions/git/package.nls.json b/extensions/git/package.nls.json index 1ab36d8a859..9635e3ede22 100644 --- a/extensions/git/package.nls.json +++ b/extensions/git/package.nls.json @@ -51,7 +51,7 @@ "command.stashPop": "Pop Stash...", "command.stashPopLatest": "Pop Latest Stash", "config.enabled": "Whether git is enabled.", - "config.path": "Path to the git executable. Eg: `C:\\Program Files\\Git\\bin\\git.exe` (Windows).", + "config.path": "Path and filename of the git executable. Eg: `C:\\Program Files\\Git\\bin\\git.exe` (Windows).", "config.autoRepositoryDetection": "Configures when repositories should be automatically detected. `subFolders` will scan for subfolders of the currently opened folder. `openEditors` will scan for parent folders of open files. `true` will scan in all cases. `false` will disable scanning.", "config.autorefresh": "Whether auto refreshing is enabled.", "config.autofetch": "Whether auto fetching is enabled.", From 0615dbe00ac65728bd34142c90a7125b9dbb236e Mon Sep 17 00:00:00 2001 From: Joao Moreno Date: Tue, 7 Aug 2018 10:35:05 +0200 Subject: [PATCH 0532/1276] docs --- extensions/git/package.nls.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/extensions/git/package.nls.json b/extensions/git/package.nls.json index 9635e3ede22..2224d3a718c 100644 --- a/extensions/git/package.nls.json +++ b/extensions/git/package.nls.json @@ -51,7 +51,7 @@ "command.stashPop": "Pop Stash...", "command.stashPopLatest": "Pop Latest Stash", "config.enabled": "Whether git is enabled.", - "config.path": "Path and filename of the git executable. Eg: `C:\\Program Files\\Git\\bin\\git.exe` (Windows).", + "config.path": "Path and filename of the git executable, e.g. `C:\\Program Files\\Git\\bin\\git.exe` (Windows).", "config.autoRepositoryDetection": "Configures when repositories should be automatically detected. `subFolders` will scan for subfolders of the currently opened folder. `openEditors` will scan for parent folders of open files. `true` will scan in all cases. `false` will disable scanning.", "config.autorefresh": "Whether auto refreshing is enabled.", "config.autofetch": "Whether auto fetching is enabled.", From 3a4edc806aec7e4b09956e27928c0cd340baf609 Mon Sep 17 00:00:00 2001 From: Benjamin Pasero Date: Tue, 7 Aug 2018 10:39:47 +0200 Subject: [PATCH 0533/1276] Add toggle.diff.editorMode to the command palette (fixes #54974) --- src/vs/workbench/browser/parts/editor/editorCommands.ts | 9 +++++++++ src/vs/workbench/common/editor.ts | 1 + src/vs/workbench/electron-browser/workbench.ts | 5 ++++- 3 files changed, 14 insertions(+), 1 deletion(-) diff --git a/src/vs/workbench/browser/parts/editor/editorCommands.ts b/src/vs/workbench/browser/parts/editor/editorCommands.ts index 600ece0164f..b6545f0bdc6 100644 --- a/src/vs/workbench/browser/parts/editor/editorCommands.ts +++ b/src/vs/workbench/browser/parts/editor/editorCommands.ts @@ -23,6 +23,7 @@ import { IEditorGroupsService, IEditorGroup, GroupDirection, GroupLocation, Grou import { ContextKeyExpr } from 'vs/platform/contextkey/common/contextkey'; import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; import { CommandsRegistry } from 'vs/platform/commands/common/commands'; +import { MenuRegistry, MenuId } from 'vs/platform/actions/common/actions'; export const CLOSE_SAVED_EDITORS_COMMAND_ID = 'workbench.action.closeUnmodifiedEditors'; export const CLOSE_EDITORS_IN_GROUP_COMMAND_ID = 'workbench.action.closeEditorsInGroup'; @@ -263,6 +264,14 @@ function registerDiffEditorCommands(): void { } } }); + + MenuRegistry.appendMenuItem(MenuId.CommandPalette, { + command: { + id: TOGGLE_DIFF_INLINE_MODE, + title: nls.localize('toggleInlineView', "Compare: Toggle Inline View") + }, + when: ContextKeyExpr.has('textCompareEditorActive') + }); } function registerOpenEditorAtIndexCommands(): void { diff --git a/src/vs/workbench/common/editor.ts b/src/vs/workbench/common/editor.ts index e49e2d26fc5..8162f48a02e 100644 --- a/src/vs/workbench/common/editor.ts +++ b/src/vs/workbench/common/editor.ts @@ -25,6 +25,7 @@ export const EditorsVisibleContext = new RawContextKey('editorIsOpen', export const EditorGroupActiveEditorDirtyContext = new RawContextKey('groupActiveEditorDirty', false); export const NoEditorsVisibleContext: ContextKeyExpr = EditorsVisibleContext.toNegated(); export const TextCompareEditorVisibleContext = new RawContextKey('textCompareEditorVisible', false); +export const TextCompareEditorActiveContext = new RawContextKey('textCompareEditorActive', false); export const ActiveEditorGroupEmptyContext = new RawContextKey('activeEditorGroupEmpty', false); export const MultipleEditorGroupsContext = new RawContextKey('multipleEditorGroups', false); export const SingleEditorGroupsContext = MultipleEditorGroupsContext.toNegated(); diff --git a/src/vs/workbench/electron-browser/workbench.ts b/src/vs/workbench/electron-browser/workbench.ts index 28e1853fed9..ed8d5ba2f2b 100644 --- a/src/vs/workbench/electron-browser/workbench.ts +++ b/src/vs/workbench/electron-browser/workbench.ts @@ -23,7 +23,7 @@ import { Registry } from 'vs/platform/registry/common/platform'; import { isWindows, isLinux, isMacintosh } from 'vs/base/common/platform'; import { IResourceInput } from 'vs/platform/editor/common/editor'; import { IWorkbenchContributionsRegistry, Extensions as WorkbenchExtensions } from 'vs/workbench/common/contributions'; -import { IEditorInputFactoryRegistry, Extensions as EditorExtensions, TextCompareEditorVisibleContext, TEXT_DIFF_EDITOR_ID, EditorsVisibleContext, InEditorZenModeContext, ActiveEditorGroupEmptyContext, MultipleEditorGroupsContext, IUntitledResourceInput, IResourceDiffInput, SplitEditorsVertically } from 'vs/workbench/common/editor'; +import { IEditorInputFactoryRegistry, Extensions as EditorExtensions, TextCompareEditorVisibleContext, TEXT_DIFF_EDITOR_ID, EditorsVisibleContext, InEditorZenModeContext, ActiveEditorGroupEmptyContext, MultipleEditorGroupsContext, IUntitledResourceInput, IResourceDiffInput, SplitEditorsVertically, TextCompareEditorActiveContext } from 'vs/workbench/common/editor'; import { HistoryService } from 'vs/workbench/services/history/electron-browser/history'; import { ActivitybarPart } from 'vs/workbench/browser/parts/activitybar/activitybarPart'; import { SidebarPart } from 'vs/workbench/browser/parts/sidebar/sidebarPart'; @@ -606,12 +606,15 @@ export class Workbench extends Disposable implements IPartService { const editorsVisibleContext = EditorsVisibleContext.bindTo(this.contextKeyService); const textCompareEditorVisible = TextCompareEditorVisibleContext.bindTo(this.contextKeyService); + const textCompareEditorActive = TextCompareEditorActiveContext.bindTo(this.contextKeyService); const activeEditorGroupEmpty = ActiveEditorGroupEmptyContext.bindTo(this.contextKeyService); const multipleEditorGroups = MultipleEditorGroupsContext.bindTo(this.contextKeyService); const updateEditorContextKeys = () => { + const activeControl = this.editorService.activeControl; const visibleEditors = this.editorService.visibleControls; + textCompareEditorActive.set(activeControl && activeControl.getId() === TEXT_DIFF_EDITOR_ID); textCompareEditorVisible.set(visibleEditors.some(control => control.getId() === TEXT_DIFF_EDITOR_ID)); if (visibleEditors.length > 0) { From 9c19fe9406f2487b60b8b280b7e447b54a475b6e Mon Sep 17 00:00:00 2001 From: Zach Bloomquist Date: Tue, 7 Aug 2018 04:42:23 -0400 Subject: [PATCH 0534/1276] Default 'Quick Switch Window' selection to be next window, closes #55166 (#55535) --- src/vs/workbench/electron-browser/actions.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/vs/workbench/electron-browser/actions.ts b/src/vs/workbench/electron-browser/actions.ts index 79b40283093..161acfd709d 100644 --- a/src/vs/workbench/electron-browser/actions.ts +++ b/src/vs/workbench/electron-browser/actions.ts @@ -616,9 +616,11 @@ export abstract class BaseSwitchWindow extends Action { action: (!this.isQuickNavigate() && currentWindowId !== win.id) ? this.closeWindowAction : void 0 } as IFilePickOpenEntry)); + const autoFocusIndex = (picks.indexOf(picks.filter(pick => pick.payload === currentWindowId)[0]) + 1) % picks.length; + this.quickOpenService.pick(picks, { contextKey: 'inWindowsPicker', - autoFocus: { autoFocusFirstEntry: true }, + autoFocus: { autoFocusIndex }, placeHolder, quickNavigateConfiguration: this.isQuickNavigate() ? { keybindings: this.keybindingService.lookupKeybindings(this.id) } : void 0 }); From 9b7c16e0a6f35f3fc55169be40edbc11bef8a3e9 Mon Sep 17 00:00:00 2001 From: Johannes Rieken Date: Tue, 7 Aug 2018 11:08:06 +0200 Subject: [PATCH 0535/1276] debt - make test renderer use a correct baseUrl (and adopt tests using require.toUrl) --- src/vs/base/common/amd.ts | 12 +++++++ src/vs/base/parts/ipc/test/node/ipc.test.ts | 6 ++-- .../base/test/node/encoding/encoding.test.ts | 35 ++++++++++--------- src/vs/base/test/node/extfs/extfs.test.ts | 7 ++-- src/vs/base/test/node/stream/stream.test.ts | 11 +++--- src/vs/base/test/node/zip/zip.test.ts | 2 +- src/vs/code/test/node/windowsFinder.test.ts | 3 +- .../colorRegistry.releaseTest.ts | 5 +-- .../extensionsWorkbenchService.test.ts | 6 ++-- .../test/electron-browser/fileService.test.ts | 9 ++--- .../test/electron-browser/resolver.test.ts | 5 +-- .../test/keyboardMapperTestUtils.ts | 5 +-- .../services/search/test/node/search.test.ts | 25 ++++++------- .../search/test/node/searchService.test.ts | 5 +-- .../test/node/textSearch.integrationTest.ts | 3 +- test/electron/renderer.js | 2 +- 16 files changed, 82 insertions(+), 59 deletions(-) create mode 100644 src/vs/base/common/amd.ts diff --git a/src/vs/base/common/amd.ts b/src/vs/base/common/amd.ts new file mode 100644 index 00000000000..45e45a7bbe2 --- /dev/null +++ b/src/vs/base/common/amd.ts @@ -0,0 +1,12 @@ +/*--------------------------------------------------------------------------------------------- + * 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 URI from 'vs/base/common/uri'; + +export function getPathFromAmdModule(requirefn: typeof require, relativePath: string): string { + return URI.parse(requirefn.toUrl(relativePath)).fsPath; +} diff --git a/src/vs/base/parts/ipc/test/node/ipc.test.ts b/src/vs/base/parts/ipc/test/node/ipc.test.ts index 3091fce1d7f..01deb13302b 100644 --- a/src/vs/base/parts/ipc/test/node/ipc.test.ts +++ b/src/vs/base/parts/ipc/test/node/ipc.test.ts @@ -8,13 +8,13 @@ import * as assert from 'assert'; import { TPromise } from 'vs/base/common/winjs.base'; import { Client } from 'vs/base/parts/ipc/node/ipc.cp'; -import uri from 'vs/base/common/uri'; import { always } from 'vs/base/common/async'; import { isPromiseCanceledError } from 'vs/base/common/errors'; import { ITestChannel, TestServiceClient } from './testService'; +import { getPathFromAmdModule } from 'vs/base/common/amd'; function createClient(): Client { - return new Client(uri.parse(require.toUrl('bootstrap')).fsPath, { + return new Client(getPathFromAmdModule(require, 'bootstrap'), { serverName: 'TestServer', env: { AMD_ENTRYPOINT: 'vs/base/parts/ipc/test/node/testApp', verbose: true } }); @@ -101,4 +101,4 @@ suite('IPC', () => { return always(result, () => client.dispose()); }); }); -}); \ No newline at end of file +}); diff --git a/src/vs/base/test/node/encoding/encoding.test.ts b/src/vs/base/test/node/encoding/encoding.test.ts index 252ee281e37..99d05d437a0 100644 --- a/src/vs/base/test/node/encoding/encoding.test.ts +++ b/src/vs/base/test/node/encoding/encoding.test.ts @@ -10,10 +10,11 @@ import * as fs from 'fs'; import * as encoding from 'vs/base/node/encoding'; import { readExactlyByFile } from 'vs/base/node/stream'; import { Readable } from 'stream'; +import { getPathFromAmdModule } from 'vs/base/common/amd'; suite('Encoding', () => { test('detectBOM UTF-8', () => { - const file = require.toUrl('./fixtures/some_utf8.css'); + const file = getPathFromAmdModule(require, './fixtures/some_utf8.css'); return encoding.detectEncodingByBOM(file).then((encoding: string) => { assert.equal(encoding, 'utf8'); @@ -21,7 +22,7 @@ suite('Encoding', () => { }); test('detectBOM UTF-16 LE', () => { - const file = require.toUrl('./fixtures/some_utf16le.css'); + const file = getPathFromAmdModule(require, './fixtures/some_utf16le.css'); return encoding.detectEncodingByBOM(file).then((encoding: string) => { assert.equal(encoding, 'utf16le'); @@ -29,7 +30,7 @@ suite('Encoding', () => { }); test('detectBOM UTF-16 BE', () => { - const file = require.toUrl('./fixtures/some_utf16be.css'); + const file = getPathFromAmdModule(require, './fixtures/some_utf16be.css'); return encoding.detectEncodingByBOM(file).then((encoding: string) => { assert.equal(encoding, 'utf16be'); @@ -37,7 +38,7 @@ suite('Encoding', () => { }); test('detectBOM ANSI', function () { - const file = require.toUrl('./fixtures/some_ansi.css'); + const file = getPathFromAmdModule(require, './fixtures/some_ansi.css'); return encoding.detectEncodingByBOM(file).then((encoding: string) => { assert.equal(encoding, null); @@ -45,7 +46,7 @@ suite('Encoding', () => { }); test('detectBOM ANSI', function () { - const file = require.toUrl('./fixtures/empty.txt'); + const file = getPathFromAmdModule(require, './fixtures/empty.txt'); return encoding.detectEncodingByBOM(file).then((encoding: string) => { assert.equal(encoding, null); @@ -68,7 +69,7 @@ suite('Encoding', () => { }); test('detectEncodingFromBuffer (JSON saved as PNG)', function () { - const file = require.toUrl('./fixtures/some.json.png'); + const file = getPathFromAmdModule(require, './fixtures/some.json.png'); return readExactlyByFile(file, 512).then(buffer => { const mimes = encoding.detectEncodingFromBuffer(buffer); @@ -77,7 +78,7 @@ suite('Encoding', () => { }); test('detectEncodingFromBuffer (PNG saved as TXT)', function () { - const file = require.toUrl('./fixtures/some.png.txt'); + const file = getPathFromAmdModule(require, './fixtures/some.png.txt'); return readExactlyByFile(file, 512).then(buffer => { const mimes = encoding.detectEncodingFromBuffer(buffer); assert.equal(mimes.seemsBinary, true); @@ -85,7 +86,7 @@ suite('Encoding', () => { }); test('detectEncodingFromBuffer (XML saved as PNG)', function () { - const file = require.toUrl('./fixtures/some.xml.png'); + const file = getPathFromAmdModule(require, './fixtures/some.xml.png'); return readExactlyByFile(file, 512).then(buffer => { const mimes = encoding.detectEncodingFromBuffer(buffer); assert.equal(mimes.seemsBinary, false); @@ -93,7 +94,7 @@ suite('Encoding', () => { }); test('detectEncodingFromBuffer (QWOFF saved as TXT)', function () { - const file = require.toUrl('./fixtures/some.qwoff.txt'); + const file = getPathFromAmdModule(require, './fixtures/some.qwoff.txt'); return readExactlyByFile(file, 512).then(buffer => { const mimes = encoding.detectEncodingFromBuffer(buffer); assert.equal(mimes.seemsBinary, true); @@ -101,7 +102,7 @@ suite('Encoding', () => { }); test('detectEncodingFromBuffer (CSS saved as QWOFF)', function () { - const file = require.toUrl('./fixtures/some.css.qwoff'); + const file = getPathFromAmdModule(require, './fixtures/some.css.qwoff'); return readExactlyByFile(file, 512).then(buffer => { const mimes = encoding.detectEncodingFromBuffer(buffer); assert.equal(mimes.seemsBinary, false); @@ -109,7 +110,7 @@ suite('Encoding', () => { }); test('detectEncodingFromBuffer (PDF)', function () { - const file = require.toUrl('./fixtures/some.pdf'); + const file = getPathFromAmdModule(require, './fixtures/some.pdf'); return readExactlyByFile(file, 512).then(buffer => { const mimes = encoding.detectEncodingFromBuffer(buffer); assert.equal(mimes.seemsBinary, true); @@ -117,7 +118,7 @@ suite('Encoding', () => { }); test('detectEncodingFromBuffer (guess UTF-16 LE from content without BOM)', function () { - const file = require.toUrl('./fixtures/utf16_le_nobom.txt'); + const file = getPathFromAmdModule(require, './fixtures/utf16_le_nobom.txt'); return readExactlyByFile(file, 512).then(buffer => { const mimes = encoding.detectEncodingFromBuffer(buffer); assert.equal(mimes.encoding, encoding.UTF16le); @@ -126,7 +127,7 @@ suite('Encoding', () => { }); test('detectEncodingFromBuffer (guess UTF-16 BE from content without BOM)', function () { - const file = require.toUrl('./fixtures/utf16_be_nobom.txt'); + const file = getPathFromAmdModule(require, './fixtures/utf16_be_nobom.txt'); return readExactlyByFile(file, 512).then(buffer => { const mimes = encoding.detectEncodingFromBuffer(buffer); assert.equal(mimes.encoding, encoding.UTF16be); @@ -135,7 +136,7 @@ suite('Encoding', () => { }); test('autoGuessEncoding (ShiftJIS)', function () { - const file = require.toUrl('./fixtures/some.shiftjis.txt'); + const file = getPathFromAmdModule(require, './fixtures/some.shiftjis.txt'); return readExactlyByFile(file, 512 * 8).then(buffer => { return encoding.detectEncodingFromBuffer(buffer, true).then(mimes => { assert.equal(mimes.encoding, 'shiftjis'); @@ -144,7 +145,7 @@ suite('Encoding', () => { }); test('autoGuessEncoding (CP1252)', function () { - const file = require.toUrl('./fixtures/some.cp1252.txt'); + const file = getPathFromAmdModule(require, './fixtures/some.cp1252.txt'); return readExactlyByFile(file, 512 * 8).then(buffer => { return encoding.detectEncodingFromBuffer(buffer, true).then(mimes => { assert.equal(mimes.encoding, 'windows1252'); @@ -238,7 +239,7 @@ suite('Encoding', () => { test('toDecodeStream - encoding, utf16be', async function () { - let path = require.toUrl('./fixtures/some_utf16be.css'); + let path = getPathFromAmdModule(require, './fixtures/some_utf16be.css'); let source = fs.createReadStream(path); let { detected, stream } = await encoding.toDecodeStream(source, { minBytesRequiredForDetection: 64 }); @@ -254,7 +255,7 @@ suite('Encoding', () => { test('toDecodeStream - empty file', async function () { - let path = require.toUrl('./fixtures/empty.txt'); + let path = getPathFromAmdModule(require, './fixtures/empty.txt'); let source = fs.createReadStream(path); let { detected, stream } = await encoding.toDecodeStream(source, {}); diff --git a/src/vs/base/test/node/extfs/extfs.test.ts b/src/vs/base/test/node/extfs/extfs.test.ts index d5a363f2b5c..d1740085fd0 100644 --- a/src/vs/base/test/node/extfs/extfs.test.ts +++ b/src/vs/base/test/node/extfs/extfs.test.ts @@ -14,6 +14,7 @@ import { canNormalize } from 'vs/base/common/normalization'; import { isLinux, isWindows } from 'vs/base/common/platform'; import * as uuid from 'vs/base/common/uuid'; import * as extfs from 'vs/base/node/extfs'; +import { getPathFromAmdModule } from 'vs/base/common/amd'; @@ -169,7 +170,7 @@ suite('Extfs', () => { test('copy, move and delete', function (done) { const id = uuid.generateUuid(); const id2 = uuid.generateUuid(); - const sourceDir = require.toUrl('./fixtures'); + const sourceDir = getPathFromAmdModule(require, './fixtures'); const parentDir = path.join(os.tmpdir(), 'vsctests', 'extfs'); const targetDir = path.join(parentDir, id); const targetDir2 = path.join(parentDir, id2); @@ -320,7 +321,7 @@ suite('Extfs', () => { test('writeFileAndFlush (file stream)', function (done) { const id = uuid.generateUuid(); const parentDir = path.join(os.tmpdir(), 'vsctests', id); - const sourceFile = require.toUrl('./fixtures/index.html'); + const sourceFile = getPathFromAmdModule(require, './fixtures/index.html'); const newDir = path.join(parentDir, 'extfs', id); const testFile = path.join(newDir, 'flushed.txt'); @@ -453,7 +454,7 @@ suite('Extfs', () => { test('writeFileAndFlush (file stream, error handling)', function (done) { const id = uuid.generateUuid(); const parentDir = path.join(os.tmpdir(), 'vsctests', id); - const sourceFile = require.toUrl('./fixtures/index.html'); + const sourceFile = getPathFromAmdModule(require, './fixtures/index.html'); const newDir = path.join(parentDir, 'extfs', id); const testFile = path.join(newDir, 'flushed.txt'); diff --git a/src/vs/base/test/node/stream/stream.test.ts b/src/vs/base/test/node/stream/stream.test.ts index c2c5f1b2f9a..d52ed4c43b1 100644 --- a/src/vs/base/test/node/stream/stream.test.ts +++ b/src/vs/base/test/node/stream/stream.test.ts @@ -8,10 +8,11 @@ import * as assert from 'assert'; import * as stream from 'vs/base/node/stream'; +import { getPathFromAmdModule } from 'vs/base/common/amd'; suite('Stream', () => { test('readExactlyByFile - ANSI', function () { - const file = require.toUrl('./fixtures/file.css'); + const file = getPathFromAmdModule(require, './fixtures/file.css'); return stream.readExactlyByFile(file, 10).then(({ buffer, bytesRead }) => { assert.equal(bytesRead, 10); @@ -20,7 +21,7 @@ suite('Stream', () => { }); test('readExactlyByFile - empty', function () { - const file = require.toUrl('./fixtures/empty.txt'); + const file = getPathFromAmdModule(require, './fixtures/empty.txt'); return stream.readExactlyByFile(file, 10).then(({ bytesRead }) => { assert.equal(bytesRead, 0); @@ -28,7 +29,7 @@ suite('Stream', () => { }); test('readToMatchingString - ANSI', function () { - const file = require.toUrl('./fixtures/file.css'); + const file = getPathFromAmdModule(require, './fixtures/file.css'); return stream.readToMatchingString(file, '\n', 10, 100).then((result: string) => { // \r may be present on Windows @@ -37,10 +38,10 @@ suite('Stream', () => { }); test('readToMatchingString - empty', function () { - const file = require.toUrl('./fixtures/empty.txt'); + const file = getPathFromAmdModule(require, './fixtures/empty.txt'); return stream.readToMatchingString(file, '\n', 10, 100).then((result: string) => { assert.equal(result, null); }); }); -}); \ No newline at end of file +}); diff --git a/src/vs/base/test/node/zip/zip.test.ts b/src/vs/base/test/node/zip/zip.test.ts index f53894f5ebb..dffcf581723 100644 --- a/src/vs/base/test/node/zip/zip.test.ts +++ b/src/vs/base/test/node/zip/zip.test.ts @@ -27,4 +27,4 @@ suite('Zip', () => { .then(exists => assert(exists)) .then(() => rimraf(target)); }); -}); \ No newline at end of file +}); diff --git a/src/vs/code/test/node/windowsFinder.test.ts b/src/vs/code/test/node/windowsFinder.test.ts index b9b70a3503d..d9d9a683643 100644 --- a/src/vs/code/test/node/windowsFinder.test.ts +++ b/src/vs/code/test/node/windowsFinder.test.ts @@ -11,8 +11,9 @@ import { OpenContext } from 'vs/platform/windows/common/windows'; import { IWorkspaceIdentifier } from 'vs/platform/workspaces/common/workspaces'; import { toWorkspaceFolders } from 'vs/platform/workspace/common/workspace'; import URI from 'vs/base/common/uri'; +import { getPathFromAmdModule } from 'vs/base/common/amd'; -const fixturesFolder = require.toUrl('./fixtures'); +const fixturesFolder = getPathFromAmdModule(require, './fixtures'); const testWorkspace: IWorkspaceIdentifier = { id: Date.now().toString(), diff --git a/src/vs/platform/theme/test/electron-browser/colorRegistry.releaseTest.ts b/src/vs/platform/theme/test/electron-browser/colorRegistry.releaseTest.ts index 39858929cb5..e5658bcaf38 100644 --- a/src/vs/platform/theme/test/electron-browser/colorRegistry.releaseTest.ts +++ b/src/vs/platform/theme/test/electron-browser/colorRegistry.releaseTest.ts @@ -18,6 +18,7 @@ import { request, asText } from 'vs/base/node/request'; import * as pfs from 'vs/base/node/pfs'; import * as path from 'path'; import * as assert from 'assert'; +import { getPathFromAmdModule } from 'vs/base/common/amd'; interface ColorInfo { @@ -103,7 +104,7 @@ function getDescription(color: ColorContribution) { } async function getColorsFromExtension(): Promise<{ [id: string]: string }> { - let extPath = require.toUrl('../../../../../../extensions'); + let extPath = getPathFromAmdModule(require, '../../../../../../extensions'); let extFolders = await pfs.readDirsInDir(extPath); let result: { [id: string]: string } = Object.create(null); for (let folder of extFolders) { @@ -127,4 +128,4 @@ async function getColorsFromExtension(): Promise<{ [id: string]: string }> { } return result; -} \ No newline at end of file +} diff --git a/src/vs/workbench/parts/extensions/test/electron-browser/extensionsWorkbenchService.test.ts b/src/vs/workbench/parts/extensions/test/electron-browser/extensionsWorkbenchService.test.ts index 411ed8b209f..7da387ac880 100644 --- a/src/vs/workbench/parts/extensions/test/electron-browser/extensionsWorkbenchService.test.ts +++ b/src/vs/workbench/parts/extensions/test/electron-browser/extensionsWorkbenchService.test.ts @@ -218,7 +218,7 @@ suite('ExtensionsWorkbenchServiceTest', () => { assert.equal('1.2.0', actual.version); assert.equal('1.2.0', actual.latestVersion); assert.equal('localDescription2', actual.description); - assert.ok(fs.existsSync(actual.iconUrl)); + assert.ok(fs.existsSync(URI.parse(actual.iconUrl).fsPath)); assert.equal(null, actual.licenseUrl); assert.equal(ExtensionState.Installed, actual.state); assert.equal(null, actual.installCount); @@ -311,7 +311,7 @@ suite('ExtensionsWorkbenchServiceTest', () => { assert.equal('1.2.0', actual.version); assert.equal('1.2.0', actual.latestVersion); assert.equal('localDescription2', actual.description); - assert.ok(fs.existsSync(actual.iconUrl)); + assert.ok(fs.existsSync(URI.parse(actual.iconUrl).fsPath)); assert.equal(null, actual.licenseUrl); assert.equal(ExtensionState.Installed, actual.state); assert.equal(null, actual.installCount); @@ -1282,4 +1282,4 @@ suite('ExtensionsWorkbenchServiceTest', () => { }); }); } -}); \ No newline at end of file +}); diff --git a/src/vs/workbench/services/files/test/electron-browser/fileService.test.ts b/src/vs/workbench/services/files/test/electron-browser/fileService.test.ts index e57b8041f6b..6d834e52b6a 100644 --- a/src/vs/workbench/services/files/test/electron-browser/fileService.test.ts +++ b/src/vs/workbench/services/files/test/electron-browser/fileService.test.ts @@ -24,6 +24,7 @@ import { Workspace, toWorkspaceFolders } from 'vs/platform/workspace/common/work import { TestConfigurationService } from 'vs/platform/configuration/test/common/testConfigurationService'; import { TextModel } from 'vs/editor/common/model/textModel'; import { IEncodingOverride } from 'vs/workbench/services/files/electron-browser/encoding'; +import { getPathFromAmdModule } from 'vs/base/common/amd'; suite('FileService', () => { let service: FileService; @@ -33,7 +34,7 @@ suite('FileService', () => { setup(function () { const id = uuid.generateUuid(); testDir = path.join(parentDir, id); - const sourceDir = require.toUrl('./fixtures/service'); + const sourceDir = getPathFromAmdModule(require, './fixtures/service'); return pfs.copy(sourceDir, testDir).then(() => { service = new FileService(new TestContextService(new Workspace(testDir, testDir, toWorkspaceFolders([{ path: testDir }]))), TestEnvironmentService, new TestTextResourceConfigurationService(), new TestConfigurationService(), new TestLifecycleService(), new TestStorageService(), new TestNotificationService(), { disableWatcher: true }); @@ -837,7 +838,7 @@ suite('FileService', () => { // setup const _id = uuid.generateUuid(); const _testDir = path.join(parentDir, _id); - const _sourceDir = require.toUrl('./fixtures/service'); + const _sourceDir = getPathFromAmdModule(require, './fixtures/service'); return pfs.copy(_sourceDir, _testDir).then(() => { const encodingOverride: IEncodingOverride[] = []; @@ -882,7 +883,7 @@ suite('FileService', () => { // setup const _id = uuid.generateUuid(); const _testDir = path.join(parentDir, _id); - const _sourceDir = require.toUrl('./fixtures/service'); + const _sourceDir = getPathFromAmdModule(require, './fixtures/service'); return pfs.copy(_sourceDir, _testDir).then(() => { const encodingOverride: IEncodingOverride[] = []; @@ -927,7 +928,7 @@ suite('FileService', () => { // setup const _id = uuid.generateUuid(); const _testDir = path.join(parentDir, _id); - const _sourceDir = require.toUrl('./fixtures/service'); + const _sourceDir = getPathFromAmdModule(require, './fixtures/service'); const resource = uri.file(path.join(testDir, 'index.html')); const _service = new FileService( diff --git a/src/vs/workbench/services/files/test/electron-browser/resolver.test.ts b/src/vs/workbench/services/files/test/electron-browser/resolver.test.ts index 3a9c19ad869..11222a1f411 100644 --- a/src/vs/workbench/services/files/test/electron-browser/resolver.test.ts +++ b/src/vs/workbench/services/files/test/electron-browser/resolver.test.ts @@ -13,9 +13,10 @@ import { StatResolver } from 'vs/workbench/services/files/electron-browser/fileS import uri from 'vs/base/common/uri'; import { isLinux } from 'vs/base/common/platform'; import * as utils from 'vs/workbench/services/files/test/electron-browser/utils'; +import { getPathFromAmdModule } from 'vs/base/common/amd'; function create(relativePath: string): StatResolver { - let basePath = require.toUrl('./fixtures/resolver'); + let basePath = getPathFromAmdModule(require, './fixtures/resolver'); let absolutePath = relativePath ? path.join(basePath, relativePath) : basePath; let fsStat = fs.statSync(absolutePath); @@ -23,7 +24,7 @@ function create(relativePath: string): StatResolver { } function toResource(relativePath: string): uri { - let basePath = require.toUrl('./fixtures/resolver'); + let basePath = getPathFromAmdModule(require, './fixtures/resolver'); let absolutePath = relativePath ? path.join(basePath, relativePath) : basePath; return uri.file(absolutePath); diff --git a/src/vs/workbench/services/keybinding/test/keyboardMapperTestUtils.ts b/src/vs/workbench/services/keybinding/test/keyboardMapperTestUtils.ts index 6cf36eab48f..5d5bf78f5af 100644 --- a/src/vs/workbench/services/keybinding/test/keyboardMapperTestUtils.ts +++ b/src/vs/workbench/services/keybinding/test/keyboardMapperTestUtils.ts @@ -12,6 +12,7 @@ import { TPromise } from 'vs/base/common/winjs.base'; import { readFile, writeFile } from 'vs/base/node/pfs'; import { IKeyboardEvent } from 'vs/platform/keybinding/common/keybinding'; import { ScanCodeBinding } from 'vs/workbench/services/keybinding/common/scanCode'; +import { getPathFromAmdModule } from 'vs/base/common/amd'; export interface IResolvedKeybinding { label: string; @@ -51,7 +52,7 @@ export function assertResolveUserBinding(mapper: IKeyboardMapper, firstPart: Sim } export function readRawMapping(file: string): TPromise { - return readFile(require.toUrl(`vs/workbench/services/keybinding/test/${file}.js`)).then((buff) => { + return readFile(getPathFromAmdModule(require, `vs/workbench/services/keybinding/test/${file}.js`)).then((buff) => { let contents = buff.toString(); let func = new Function('define', contents); let rawMappings: T = null; @@ -63,7 +64,7 @@ export function readRawMapping(file: string): TPromise { } export function assertMapping(writeFileIfDifferent: boolean, mapper: IKeyboardMapper, file: string): TPromise { - const filePath = require.toUrl(`vs/workbench/services/keybinding/test/${file}`); + const filePath = getPathFromAmdModule(require, `vs/workbench/services/keybinding/test/${file}`); return readFile(filePath).then((buff) => { let expected = buff.toString(); diff --git a/src/vs/workbench/services/search/test/node/search.test.ts b/src/vs/workbench/services/search/test/node/search.test.ts index fda8eed27b0..7e8ded6fe5d 100644 --- a/src/vs/workbench/services/search/test/node/search.test.ts +++ b/src/vs/workbench/services/search/test/node/search.test.ts @@ -13,8 +13,9 @@ import * as platform from 'vs/base/common/platform'; import { FileWalker, Engine as FileSearchEngine } from 'vs/workbench/services/search/node/fileSearch'; import { IRawFileMatch, IFolderSearch } from 'vs/workbench/services/search/node/search'; +import { getPathFromAmdModule } from 'vs/base/common/amd'; -const TEST_FIXTURES = path.normalize(require.toUrl('./fixtures')); +const TEST_FIXTURES = path.normalize(getPathFromAmdModule(require, './fixtures')); const EXAMPLES_FIXTURES = path.join(TEST_FIXTURES, 'examples'); const MORE_FIXTURES = path.join(TEST_FIXTURES, 'more'); const TEST_ROOT_FOLDER: IFolderSearch = { folder: TEST_FIXTURES }; @@ -23,7 +24,7 @@ const ROOT_FOLDER_QUERY: IFolderSearch[] = [ ]; const ROOT_FOLDER_QUERY_36438: IFolderSearch[] = [ - { folder: path.normalize(require.toUrl('./fixtures2/36438')) } + { folder: path.normalize(getPathFromAmdModule(require, './fixtures2/36438')) } ]; const MULTIROOT_QUERIES: IFolderSearch[] = [ @@ -629,9 +630,9 @@ suite('FileSearchEngine', () => { let engine = new FileSearchEngine({ folderQueries: [], extraFiles: [ - path.normalize(path.join(require.toUrl('./fixtures'), 'site.css')), - path.normalize(path.join(require.toUrl('./fixtures'), 'examples', 'company.js')), - path.normalize(path.join(require.toUrl('./fixtures'), 'index.html')) + path.normalize(path.join(getPathFromAmdModule(require, './fixtures'), 'site.css')), + path.normalize(path.join(getPathFromAmdModule(require, './fixtures'), 'examples', 'company.js')), + path.normalize(path.join(getPathFromAmdModule(require, './fixtures'), 'index.html')) ], filePattern: '*.js' }); @@ -656,9 +657,9 @@ suite('FileSearchEngine', () => { let engine = new FileSearchEngine({ folderQueries: [], extraFiles: [ - path.normalize(path.join(require.toUrl('./fixtures'), 'site.css')), - path.normalize(path.join(require.toUrl('./fixtures'), 'examples', 'company.js')), - path.normalize(path.join(require.toUrl('./fixtures'), 'index.html')) + path.normalize(path.join(getPathFromAmdModule(require, './fixtures'), 'site.css')), + path.normalize(path.join(getPathFromAmdModule(require, './fixtures'), 'examples', 'company.js')), + path.normalize(path.join(getPathFromAmdModule(require, './fixtures'), 'index.html')) ], filePattern: '*.*', includePattern: { '**/*.css': true } @@ -684,9 +685,9 @@ suite('FileSearchEngine', () => { let engine = new FileSearchEngine({ folderQueries: [], extraFiles: [ - path.normalize(path.join(require.toUrl('./fixtures'), 'site.css')), - path.normalize(path.join(require.toUrl('./fixtures'), 'examples', 'company.js')), - path.normalize(path.join(require.toUrl('./fixtures'), 'index.html')) + path.normalize(path.join(getPathFromAmdModule(require, './fixtures'), 'site.css')), + path.normalize(path.join(getPathFromAmdModule(require, './fixtures'), 'examples', 'company.js')), + path.normalize(path.join(getPathFromAmdModule(require, './fixtures'), 'index.html')) ], filePattern: '*.*', excludePattern: { '**/*.css': true } @@ -942,4 +943,4 @@ suite('FileWalker', () => { const lines = stdout.split('\n'); return files.every(file => lines.indexOf(file) >= 0); } -}); \ No newline at end of file +}); diff --git a/src/vs/workbench/services/search/test/node/searchService.test.ts b/src/vs/workbench/services/search/test/node/searchService.test.ts index eb205675ab0..23a434569ea 100644 --- a/src/vs/workbench/services/search/test/node/searchService.test.ts +++ b/src/vs/workbench/services/search/test/node/searchService.test.ts @@ -14,12 +14,13 @@ import { SearchService as RawSearchService } from 'vs/workbench/services/search/ import { DiskSearch } from 'vs/workbench/services/search/node/searchService'; import { Emitter, Event } from 'vs/base/common/event'; import { TPromise } from 'vs/base/common/winjs.base'; +import { getPathFromAmdModule } from 'vs/base/common/amd'; const TEST_FOLDER_QUERIES = [ { folder: path.normalize('/some/where') } ]; -const TEST_FIXTURES = path.normalize(require.toUrl('./fixtures')); +const TEST_FIXTURES = path.normalize(getPathFromAmdModule(require, './fixtures')); const MULTIROOT_QUERIES: IFolderSearch[] = [ { folder: path.join(TEST_FIXTURES, 'examples') }, { folder: path.join(TEST_FIXTURES, 'more') } @@ -350,4 +351,4 @@ suite('SearchService', () => { }); }); }); -}); \ No newline at end of file +}); diff --git a/src/vs/workbench/services/search/test/node/textSearch.integrationTest.ts b/src/vs/workbench/services/search/test/node/textSearch.integrationTest.ts index 93a86a86b12..21484acb566 100644 --- a/src/vs/workbench/services/search/test/node/textSearch.integrationTest.ts +++ b/src/vs/workbench/services/search/test/node/textSearch.integrationTest.ts @@ -15,12 +15,13 @@ import { ISerializedFileMatch, IRawSearch, IFolderSearch } from 'vs/workbench/se import { Engine as TextSearchEngine } from 'vs/workbench/services/search/node/textSearch'; import { RipgrepEngine } from 'vs/workbench/services/search/node/ripgrepTextSearch'; import { TextSearchWorkerProvider } from 'vs/workbench/services/search/node/textSearchWorkerProvider'; +import { getPathFromAmdModule } from 'vs/base/common/amd'; function countAll(matches: ISerializedFileMatch[]): number { return matches.reduce((acc, m) => acc + m.numMatches, 0); } -const TEST_FIXTURES = path.normalize(require.toUrl('./fixtures')); +const TEST_FIXTURES = path.normalize(getPathFromAmdModule(require, './fixtures')); const EXAMPLES_FIXTURES = path.join(TEST_FIXTURES, 'examples'); const MORE_FIXTURES = path.join(TEST_FIXTURES, 'more'); const TEST_ROOT_FOLDER: IFolderSearch = { folder: TEST_FIXTURES }; diff --git a/test/electron/renderer.js b/test/electron/renderer.js index 63729010808..b5d940e58bd 100644 --- a/test/electron/renderer.js +++ b/test/electron/renderer.js @@ -33,7 +33,7 @@ function initLoader(opts) { nodeRequire: require, nodeMain: __filename, catchError: true, - baseUrl: path.join(__dirname, '../../src'), + baseUrl: `file://${path.posix.join(__dirname, '../../src')}`, paths: { 'vs': `../${outdir}/vs`, 'lib': `../${outdir}/lib`, From e9ed5e19f69b4d2807f0d5850a86cec9acc1eb2d Mon Sep 17 00:00:00 2001 From: Johannes Rieken Date: Tue, 7 Aug 2018 11:33:54 +0200 Subject: [PATCH 0536/1276] towards scheme-enforcement in URIs, related to #55891 --- src/vs/base/common/uri.ts | 6 ++ src/vs/base/test/common/network.test.ts | 92 ------------------- src/vs/base/test/common/uri.test.ts | 48 ++-------- .../markers/test/common/markerService.test.ts | 12 +-- 4 files changed, 21 insertions(+), 137 deletions(-) delete mode 100644 src/vs/base/test/common/network.test.ts diff --git a/src/vs/base/common/uri.ts b/src/vs/base/common/uri.ts index 412efc17388..7ead50439d3 100644 --- a/src/vs/base/common/uri.ts +++ b/src/vs/base/common/uri.ts @@ -12,6 +12,12 @@ const _singleSlashStart = /^\//; const _doubleSlashStart = /^\/\//; function _validateUri(ret: URI): void { + + // // scheme, must be set + // if (!ret.scheme) { + // throw new Error('[UriError]: Scheme is missing.'); + // } + // scheme, https://tools.ietf.org/html/rfc3986#section-3.1 // ALPHA *( ALPHA / DIGIT / "+" / "-" / "." ) if (ret.scheme && !_schemePattern.test(ret.scheme)) { diff --git a/src/vs/base/test/common/network.test.ts b/src/vs/base/test/common/network.test.ts deleted file mode 100644 index 7aba51f153b..00000000000 --- a/src/vs/base/test/common/network.test.ts +++ /dev/null @@ -1,92 +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'; - -import * as assert from 'assert'; -import URI from 'vs/base/common/uri'; - -function assertUrl(raw: string, scheme: string, domain: string, port: string, path: string, queryString: string, fragmentId: string): void { - // check for equivalent behaviour - const uri = URI.parse(raw); - assert.equal(uri.scheme, scheme); - assert.equal(uri.authority, port ? domain + ':' + port : domain); - assert.equal(uri.path, path); - assert.equal(uri.query, queryString); - assert.equal(uri.fragment, fragmentId); -} - -suite('Network', () => { - test('urls', () => { - assertUrl('http://www.test.com:8000/this/that/theother.html?query=foo#hash', - 'http', 'www.test.com', '8000', '/this/that/theother.html', 'query=foo', 'hash' - ); - - assertUrl('http://www.test.com:8000/this/that/theother.html?query=foo', - 'http', 'www.test.com', '8000', '/this/that/theother.html', 'query=foo', '' - ); - - assertUrl('http://www.test.com:8000/this/that/theother.html#hash', - 'http', 'www.test.com', '8000', '/this/that/theother.html', '', 'hash' - ); - - assertUrl('http://www.test.com:8000/#hash', - 'http', 'www.test.com', '8000', '/', '', 'hash' - ); - - assertUrl('http://www.test.com:8000#hash', - 'http', 'www.test.com', '8000', '/', '', 'hash' - ); - - assertUrl('http://www.test.com/#hash', - 'http', 'www.test.com', '', '/', '', 'hash' - ); - - assertUrl('http://www.test.com#hash', - 'http', 'www.test.com', '', '/', '', 'hash' - ); - - assertUrl('http://www.test.com:8000/this/that/theother.html', - 'http', 'www.test.com', '8000', '/this/that/theother.html', '', '' - ); - - assertUrl('http://www.test.com:8000/', - 'http', 'www.test.com', '8000', '/', '', '' - ); - - assertUrl('http://www.test.com:8000', - 'http', 'www.test.com', '8000', '/', '', '' - ); - - assertUrl('http://www.test.com/', - 'http', 'www.test.com', '', '/', '', '' - ); - - assertUrl('//www.test.com/', - '', 'www.test.com', '', '/', '', '' - ); - - assertUrl('//www.test.com:8000/this/that/theother.html?query=foo#hash', - '', 'www.test.com', '8000', '/this/that/theother.html', 'query=foo', 'hash' - ); - - assertUrl('//www.test.com/this/that/theother.html?query=foo#hash', - '', 'www.test.com', '', '/this/that/theother.html', 'query=foo', 'hash' - ); - - assertUrl('https://www.test.com:8000/this/that/theother.html?query=foo#hash', - 'https', 'www.test.com', '8000', '/this/that/theother.html', 'query=foo', 'hash' - ); - - assertUrl('f12://www.test.com:8000/this/that/theother.html?query=foo#hash', - 'f12', 'www.test.com', '8000', '/this/that/theother.html', 'query=foo', 'hash' - ); - - assertUrl('inmemory://model/0', - 'inmemory', 'model', '', '/0', '', '' - ); - - assertUrl('file:///c/far/boo/file.cs', 'file', '', '', '/c/far/boo/file.cs', '', ''); - }); -}); diff --git a/src/vs/base/test/common/uri.test.ts b/src/vs/base/test/common/uri.test.ts index 618a56a1493..e74f82046d0 100644 --- a/src/vs/base/test/common/uri.test.ts +++ b/src/vs/base/test/common/uri.test.ts @@ -65,8 +65,6 @@ suite('URI', () => { assert.equal(URI.from({ scheme: 'http', authority: 'www.MSFT.com', path: '/my/path' }).toString(), 'http://www.msft.com/my/path'); assert.equal(URI.from({ scheme: 'http', authority: '', path: 'my/path' }).toString(), 'http:/my/path'); assert.equal(URI.from({ scheme: 'http', authority: '', path: '/my/path' }).toString(), 'http:/my/path'); - assert.equal(URI.from({ scheme: '', authority: '', path: 'my/path' }).toString(), 'my/path'); - assert.equal(URI.from({ scheme: '', authority: '', path: '/my/path' }).toString(), '/my/path'); //http://a-test-site.com/#test=true assert.equal(URI.from({ scheme: 'http', authority: 'a-test-site.com', path: '/', query: 'test=true' }).toString(), 'http://a-test-site.com/?test%3Dtrue'); assert.equal(URI.from({ scheme: 'http', authority: 'a-test-site.com', path: '/', query: '', fragment: 'test=true' }).toString(), 'http://a-test-site.com/#test%3Dtrue'); @@ -75,7 +73,7 @@ suite('URI', () => { test('http#toString, encode=FALSE', () => { assert.equal(URI.from({ scheme: 'http', authority: 'a-test-site.com', path: '/', query: 'test=true' }).toString(true), 'http://a-test-site.com/?test=true'); assert.equal(URI.from({ scheme: 'http', authority: 'a-test-site.com', path: '/', query: '', fragment: 'test=true' }).toString(true), 'http://a-test-site.com/#test=true'); - assert.equal(URI.from({}).with({ scheme: 'http', path: '/api/files/test.me', query: 't=1234' }).toString(true), 'http:/api/files/test.me?t=1234'); + assert.equal(URI.from({ scheme: 'http', path: '/api/files/test.me', query: 't=1234' }).toString(true), 'http:/api/files/test.me?t=1234'); var value = URI.parse('file://shares/pröjects/c%23/#l12'); assert.equal(value.authority, 'shares'); @@ -107,12 +105,12 @@ suite('URI', () => { test('with, changes', () => { assert.equal(URI.parse('before:some/file/path').with({ scheme: 'after' }).toString(), 'after:some/file/path'); - assert.equal(URI.from({}).with({ scheme: 'http', path: '/api/files/test.me', query: 't=1234' }).toString(), 'http:/api/files/test.me?t%3D1234'); - assert.equal(URI.from({}).with({ scheme: 'http', authority: '', path: '/api/files/test.me', query: 't=1234', fragment: '' }).toString(), 'http:/api/files/test.me?t%3D1234'); - assert.equal(URI.from({}).with({ scheme: 'https', authority: '', path: '/api/files/test.me', query: 't=1234', fragment: '' }).toString(), 'https:/api/files/test.me?t%3D1234'); - assert.equal(URI.from({}).with({ scheme: 'HTTP', authority: '', path: '/api/files/test.me', query: 't=1234', fragment: '' }).toString(), 'HTTP:/api/files/test.me?t%3D1234'); - assert.equal(URI.from({}).with({ scheme: 'HTTPS', authority: '', path: '/api/files/test.me', query: 't=1234', fragment: '' }).toString(), 'HTTPS:/api/files/test.me?t%3D1234'); - assert.equal(URI.from({}).with({ scheme: 'boo', authority: '', path: '/api/files/test.me', query: 't=1234', fragment: '' }).toString(), 'boo:/api/files/test.me?t%3D1234'); + assert.equal(URI.from({ scheme: 's' }).with({ scheme: 'http', path: '/api/files/test.me', query: 't=1234' }).toString(), 'http:/api/files/test.me?t%3D1234'); + assert.equal(URI.from({ scheme: 's' }).with({ scheme: 'http', authority: '', path: '/api/files/test.me', query: 't=1234', fragment: '' }).toString(), 'http:/api/files/test.me?t%3D1234'); + assert.equal(URI.from({ scheme: 's' }).with({ scheme: 'https', authority: '', path: '/api/files/test.me', query: 't=1234', fragment: '' }).toString(), 'https:/api/files/test.me?t%3D1234'); + assert.equal(URI.from({ scheme: 's' }).with({ scheme: 'HTTP', authority: '', path: '/api/files/test.me', query: 't=1234', fragment: '' }).toString(), 'HTTP:/api/files/test.me?t%3D1234'); + assert.equal(URI.from({ scheme: 's' }).with({ scheme: 'HTTPS', authority: '', path: '/api/files/test.me', query: 't=1234', fragment: '' }).toString(), 'HTTPS:/api/files/test.me?t%3D1234'); + assert.equal(URI.from({ scheme: 's' }).with({ scheme: 'boo', authority: '', path: '/api/files/test.me', query: 't=1234', fragment: '' }).toString(), 'boo:/api/files/test.me?t%3D1234'); }); test('with, remove components #8465', () => { @@ -186,34 +184,13 @@ suite('URI', () => { assert.equal(value.query, ''); assert.equal(value.fragment, ''); - value = URI.parse('api/files/test'); - assert.equal(value.scheme, ''); + value = URI.parse('foo:api/files/test'); + assert.equal(value.scheme, 'foo'); assert.equal(value.authority, ''); assert.equal(value.path, 'api/files/test'); assert.equal(value.query, ''); assert.equal(value.fragment, ''); - value = URI.parse('api'); - assert.equal(value.scheme, ''); - assert.equal(value.authority, ''); - assert.equal(value.path, 'api'); - assert.equal(value.query, ''); - assert.equal(value.fragment, ''); - - value = URI.parse('/api/files/test'); - assert.equal(value.scheme, ''); - assert.equal(value.authority, ''); - assert.equal(value.path, '/api/files/test'); - assert.equal(value.query, ''); - assert.equal(value.fragment, ''); - - value = URI.parse('?test'); - assert.equal(value.scheme, ''); - assert.equal(value.authority, ''); - assert.equal(value.path, ''); - assert.equal(value.query, 'test'); - assert.equal(value.fragment, ''); - value = URI.parse('file:?q'); assert.equal(value.scheme, 'file'); assert.equal(value.authority, ''); @@ -221,13 +198,6 @@ suite('URI', () => { assert.equal(value.query, 'q'); assert.equal(value.fragment, ''); - value = URI.parse('#test'); - assert.equal(value.scheme, ''); - assert.equal(value.authority, ''); - assert.equal(value.path, ''); - assert.equal(value.query, ''); - assert.equal(value.fragment, 'test'); - value = URI.parse('file:#d'); assert.equal(value.scheme, 'file'); assert.equal(value.authority, ''); diff --git a/src/vs/platform/markers/test/common/markerService.test.ts b/src/vs/platform/markers/test/common/markerService.test.ts index 06495c239e4..25cb2e933a2 100644 --- a/src/vs/platform/markers/test/common/markerService.test.ts +++ b/src/vs/platform/markers/test/common/markerService.test.ts @@ -58,16 +58,16 @@ suite('Marker Service', () => { test('changeOne override', () => { let service = new markerService.MarkerService(); - service.changeOne('far', URI.parse('/path/only.cs'), [randomMarkerData()]); + service.changeOne('far', URI.parse('file:///path/only.cs'), [randomMarkerData()]); assert.equal(service.read().length, 1); assert.equal(service.read({ owner: 'far' }).length, 1); - service.changeOne('boo', URI.parse('/path/only.cs'), [randomMarkerData()]); + service.changeOne('boo', URI.parse('file:///path/only.cs'), [randomMarkerData()]); assert.equal(service.read().length, 2); assert.equal(service.read({ owner: 'far' }).length, 1); assert.equal(service.read({ owner: 'boo' }).length, 1); - service.changeOne('far', URI.parse('/path/only.cs'), [randomMarkerData(), randomMarkerData()]); + service.changeOne('far', URI.parse('file:///path/only.cs'), [randomMarkerData(), randomMarkerData()]); assert.equal(service.read({ owner: 'far' }).length, 2); assert.equal(service.read({ owner: 'boo' }).length, 1); @@ -76,13 +76,13 @@ suite('Marker Service', () => { test('changeOne/All clears', () => { let service = new markerService.MarkerService(); - service.changeOne('far', URI.parse('/path/only.cs'), [randomMarkerData()]); - service.changeOne('boo', URI.parse('/path/only.cs'), [randomMarkerData()]); + service.changeOne('far', URI.parse('file:///path/only.cs'), [randomMarkerData()]); + service.changeOne('boo', URI.parse('file:///path/only.cs'), [randomMarkerData()]); assert.equal(service.read({ owner: 'far' }).length, 1); assert.equal(service.read({ owner: 'boo' }).length, 1); assert.equal(service.read().length, 2); - service.changeOne('far', URI.parse('/path/only.cs'), []); + service.changeOne('far', URI.parse('file:///path/only.cs'), []); assert.equal(service.read({ owner: 'far' }).length, 0); assert.equal(service.read({ owner: 'boo' }).length, 1); assert.equal(service.read().length, 1); From 36883965769fadb53111d17efdada5cf0da6e256 Mon Sep 17 00:00:00 2001 From: Johannes Rieken Date: Tue, 7 Aug 2018 11:55:21 +0200 Subject: [PATCH 0537/1276] debt - use getPathFromAmdModule instead of 'URI.parse(require.toUrl(xxx)).fsPath' --- src/vs/base/node/paths.ts | 6 +++--- src/vs/base/node/processes.ts | 4 ++-- src/vs/base/node/ps.ts | 5 +++-- src/vs/base/node/stdFork.ts | 4 ++-- src/vs/base/parts/ipc/test/node/ipc.perf.ts | 6 +++--- src/vs/base/test/node/processes/processes.test.ts | 4 ++-- src/vs/base/test/node/uri.test.perf.ts | 3 ++- src/vs/base/test/node/zip/zip.test.ts | 4 ++-- src/vs/platform/environment/node/environmentService.ts | 4 ++-- .../extensionManagement/node/extensionManagementService.ts | 3 ++- src/vs/platform/node/package.ts | 6 +++--- src/vs/platform/node/product.ts | 4 ++-- .../parts/cli/electron-browser/cli.contribution.ts | 4 ++-- src/vs/workbench/parts/debug/node/debugger.ts | 4 ++-- src/vs/workbench/parts/debug/node/terminals.ts | 6 +++--- .../parts/execution/electron-browser/terminalService.ts | 4 ++-- .../services/extensions/electron-browser/extensionHost.ts | 4 ++-- .../extensions/electron-browser/extensionService.ts | 7 ++++--- .../services/files/node/watcher/nsfw/watcherService.ts | 4 ++-- .../services/files/node/watcher/unix/watcherService.ts | 6 +++--- .../files/node/watcher/win32/csharpWatcherService.ts | 6 +++--- src/vs/workbench/services/search/node/searchService.ts | 3 ++- .../services/search/node/textSearchWorkerProvider.ts | 6 +++--- 23 files changed, 56 insertions(+), 51 deletions(-) diff --git a/src/vs/base/node/paths.ts b/src/vs/base/node/paths.ts index dfdc28def8a..66930cdaf4b 100644 --- a/src/vs/base/node/paths.ts +++ b/src/vs/base/node/paths.ts @@ -3,14 +3,14 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -import uri from 'vs/base/common/uri'; +import { getPathFromAmdModule } from 'vs/base/common/amd'; interface IPaths { getAppDataPath(platform: string): string; getDefaultUserDataPath(platform: string): string; } -const pathsPath = uri.parse(require.toUrl('paths')).fsPath; +const pathsPath = getPathFromAmdModule(require, 'paths'); const paths = require.__$__nodeRequire(pathsPath); export const getAppDataPath = paths.getAppDataPath; -export const getDefaultUserDataPath = paths.getDefaultUserDataPath; \ No newline at end of file +export const getDefaultUserDataPath = paths.getDefaultUserDataPath; diff --git a/src/vs/base/node/processes.ts b/src/vs/base/node/processes.ts index ebe0dff4cc4..c08d79aaf2d 100644 --- a/src/vs/base/node/processes.ts +++ b/src/vs/base/node/processes.ts @@ -11,12 +11,12 @@ import * as nls from 'vs/nls'; import { TPromise, TValueCallback, ErrorCallback } from 'vs/base/common/winjs.base'; import * as Types from 'vs/base/common/types'; import { IStringDictionary } from 'vs/base/common/collections'; -import URI from 'vs/base/common/uri'; import * as Objects from 'vs/base/common/objects'; import * as TPath from 'vs/base/common/paths'; import * as Platform from 'vs/base/common/platform'; import { LineDecoder } from 'vs/base/node/decoder'; import { CommandOptions, ForkOptions, SuccessData, Source, TerminateResponse, TerminateResponseCode, Executable } from 'vs/base/common/processes'; +import { getPathFromAmdModule } from 'vs/base/common/amd'; export { CommandOptions, ForkOptions, SuccessData, Source, TerminateResponse, TerminateResponseCode }; export type TProgressCallback = (progress: T) => void; @@ -54,7 +54,7 @@ export function terminateProcess(process: cp.ChildProcess, cwd?: string): Termin } } else if (Platform.isLinux || Platform.isMacintosh) { try { - let cmd = URI.parse(require.toUrl('vs/base/node/terminateProcess.sh')).fsPath; + let cmd = getPathFromAmdModule(require, 'vs/base/node/terminateProcess.sh'); let result = cp.spawnSync(cmd, [process.pid.toString()]); if (result.error) { return { success: false, error: result.error }; diff --git a/src/vs/base/node/ps.ts b/src/vs/base/node/ps.ts index a7d2d36d0ca..fc8c25a1153 100644 --- a/src/vs/base/node/ps.ts +++ b/src/vs/base/node/ps.ts @@ -6,7 +6,8 @@ 'use strict'; import { exec } from 'child_process'; -import URI from 'vs/base/common/uri'; + +import { getPathFromAmdModule } from 'vs/base/common/amd'; export interface ProcessItem { name: string; @@ -207,7 +208,7 @@ export function listProcesses(rootPid: number): Promise { // The cpu usage value reported on Linux is the average over the process lifetime, // recalculate the usage over a one second interval // JSON.stringify is needed to escape spaces, https://github.com/nodejs/node/issues/6803 - let cmd = JSON.stringify(URI.parse(require.toUrl('vs/base/node/cpuUsage.sh')).fsPath); + let cmd = JSON.stringify(getPathFromAmdModule(require, 'vs/base/node/cpuUsage.sh')); cmd += ' ' + pids.join(' '); exec(cmd, {}, (err, stdout, stderr) => { diff --git a/src/vs/base/node/stdFork.ts b/src/vs/base/node/stdFork.ts index c7c36559465..17782445328 100644 --- a/src/vs/base/node/stdFork.ts +++ b/src/vs/base/node/stdFork.ts @@ -9,7 +9,7 @@ import * as path from 'path'; import * as os from 'os'; import * as net from 'net'; import * as cp from 'child_process'; -import uri from 'vs/base/common/uri'; +import { getPathFromAmdModule } from 'vs/base/common/amd'; export interface IForkOpts { cwd?: string; @@ -117,7 +117,7 @@ export function fork(modulePath: string, args: string[], options: IForkOpts, cal }; // Create the process - let bootstrapperPath = (uri.parse(require.toUrl('./stdForkStart.js')).fsPath); + let bootstrapperPath = (getPathFromAmdModule(require, './stdForkStart.js')); childProcess = cp.fork(bootstrapperPath, [modulePath].concat(args), { silent: true, cwd: options.cwd, diff --git a/src/vs/base/parts/ipc/test/node/ipc.perf.ts b/src/vs/base/parts/ipc/test/node/ipc.perf.ts index 2e1fcbcbd83..4fc8ae5966e 100644 --- a/src/vs/base/parts/ipc/test/node/ipc.perf.ts +++ b/src/vs/base/parts/ipc/test/node/ipc.perf.ts @@ -7,12 +7,12 @@ import * as assert from 'assert'; import { Client } from 'vs/base/parts/ipc/node/ipc.cp'; -import uri from 'vs/base/common/uri'; import { always } from 'vs/base/common/async'; import { ITestChannel, TestServiceClient, ITestService } from './testService'; +import { getPathFromAmdModule } from 'vs/base/common/amd'; function createClient(): Client { - return new Client(uri.parse(require.toUrl('bootstrap')).fsPath, { + return new Client(getPathFromAmdModule(require, 'bootstrap'), { serverName: 'TestServer', env: { AMD_ENTRYPOINT: 'vs/base/parts/ipc/test/node/testApp', verbose: true } }); @@ -111,4 +111,4 @@ suite('IPC performance', () => { count += batch.length; }); } -}); \ No newline at end of file +}); diff --git a/src/vs/base/test/node/processes/processes.test.ts b/src/vs/base/test/node/processes/processes.test.ts index 332bdcdbff7..ae4f062bd1c 100644 --- a/src/vs/base/test/node/processes/processes.test.ts +++ b/src/vs/base/test/node/processes/processes.test.ts @@ -9,8 +9,8 @@ import * as assert from 'assert'; import * as cp from 'child_process'; import * as objects from 'vs/base/common/objects'; import * as platform from 'vs/base/common/platform'; -import URI from 'vs/base/common/uri'; import * as processes from 'vs/base/node/processes'; +import { getPathFromAmdModule } from 'vs/base/common/amd'; function fork(id: string): cp.ChildProcess { const opts: any = { @@ -21,7 +21,7 @@ function fork(id: string): cp.ChildProcess { }) }; - return cp.fork(URI.parse(require.toUrl('bootstrap')).fsPath, ['--type=processTests'], opts); + return cp.fork(getPathFromAmdModule(require, 'bootstrap'), ['--type=processTests'], opts); } suite('Processes', () => { diff --git a/src/vs/base/test/node/uri.test.perf.ts b/src/vs/base/test/node/uri.test.perf.ts index 3689d197b4d..492a676322a 100644 --- a/src/vs/base/test/node/uri.test.perf.ts +++ b/src/vs/base/test/node/uri.test.perf.ts @@ -7,13 +7,14 @@ import * as assert from 'assert'; import URI from 'vs/base/common/uri'; import { readFileSync } from 'fs'; +import { getPathFromAmdModule } from 'vs/base/common/amd'; suite('URI - perf', function () { let manyFileUris: URI[]; setup(function () { manyFileUris = []; - let data = readFileSync(URI.parse(require.toUrl('./uri.test.data.txt')).fsPath).toString(); + let data = readFileSync(getPathFromAmdModule(require, './uri.test.data.txt')).toString(); let lines = data.split('\n'); for (let line of lines) { manyFileUris.push(URI.file(line)); diff --git a/src/vs/base/test/node/zip/zip.test.ts b/src/vs/base/test/node/zip/zip.test.ts index dffcf581723..21adac26149 100644 --- a/src/vs/base/test/node/zip/zip.test.ts +++ b/src/vs/base/test/node/zip/zip.test.ts @@ -8,13 +8,13 @@ import * as assert from 'assert'; import * as path from 'path'; import * as os from 'os'; -import URI from 'vs/base/common/uri'; import { extract } from 'vs/base/node/zip'; import { generateUuid } from 'vs/base/common/uuid'; import { rimraf, exists } from 'vs/base/node/pfs'; import { NullLogService } from 'vs/platform/log/common/log'; +import { getPathFromAmdModule } from 'vs/base/common/amd'; -const fixtures = URI.parse(require.toUrl('./fixtures')).fsPath; +const fixtures = getPathFromAmdModule(require, './fixtures'); suite('Zip', () => { diff --git a/src/vs/platform/environment/node/environmentService.ts b/src/vs/platform/environment/node/environmentService.ts index 5625ae2ca2d..2224b6afd17 100644 --- a/src/vs/platform/environment/node/environmentService.ts +++ b/src/vs/platform/environment/node/environmentService.ts @@ -8,12 +8,12 @@ import * as crypto from 'crypto'; import * as paths from 'vs/base/node/paths'; import * as os from 'os'; import * as path from 'path'; -import URI from 'vs/base/common/uri'; import { memoize } from 'vs/base/common/decorators'; import pkg from 'vs/platform/node/package'; import product from 'vs/platform/node/product'; import { toLocalISOString } from 'vs/base/common/date'; import { isWindows, isLinux } from 'vs/base/common/platform'; +import { getPathFromAmdModule } from 'vs/base/common/amd'; // Read this before there's any chance it is overwritten // Related to https://github.com/Microsoft/vscode/issues/30624 @@ -77,7 +77,7 @@ export class EnvironmentService implements IEnvironmentService { get args(): ParsedArgs { return this._args; } @memoize - get appRoot(): string { return path.dirname(URI.parse(require.toUrl('')).fsPath); } + get appRoot(): string { return path.dirname(getPathFromAmdModule(require, '')); } get execPath(): string { return this._execPath; } diff --git a/src/vs/platform/extensionManagement/node/extensionManagementService.ts b/src/vs/platform/extensionManagement/node/extensionManagementService.ts index 2ff1e3bb3f2..fca1b8fcc1e 100644 --- a/src/vs/platform/extensionManagement/node/extensionManagementService.ts +++ b/src/vs/platform/extensionManagement/node/extensionManagementService.ts @@ -40,8 +40,9 @@ import { ExtensionsLifecycle } from 'vs/platform/extensionManagement/node/extens import { toErrorMessage } from 'vs/base/common/errorMessage'; import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry'; import { isEngineValid } from 'vs/platform/extensions/node/extensionValidator'; +import { getPathFromAmdModule } from 'vs/base/common/amd'; -const SystemExtensionsRoot = path.normalize(path.join(URI.parse(require.toUrl('')).fsPath, '..', 'extensions')); +const SystemExtensionsRoot = path.normalize(path.join(getPathFromAmdModule(require, ''), '..', 'extensions')); const ERROR_SCANNING_SYS_EXTENSIONS = 'scanningSystem'; const ERROR_SCANNING_USER_EXTENSIONS = 'scanningUser'; const INSTALL_ERROR_UNSET_UNINSTALLED = 'unsetUninstalled'; diff --git a/src/vs/platform/node/package.ts b/src/vs/platform/node/package.ts index fff85d911f2..93c32bc7117 100644 --- a/src/vs/platform/node/package.ts +++ b/src/vs/platform/node/package.ts @@ -4,13 +4,13 @@ *--------------------------------------------------------------------------------------------*/ import * as path from 'path'; -import uri from 'vs/base/common/uri'; +import { getPathFromAmdModule } from 'vs/base/common/amd'; export interface IPackageConfiguration { name: string; version: string; } -const rootPath = path.dirname(uri.parse(require.toUrl('')).fsPath); +const rootPath = path.dirname(getPathFromAmdModule(require, '')); const packageJsonPath = path.join(rootPath, 'package.json'); -export default require.__$__nodeRequire(packageJsonPath) as IPackageConfiguration; \ No newline at end of file +export default require.__$__nodeRequire(packageJsonPath) as IPackageConfiguration; diff --git a/src/vs/platform/node/product.ts b/src/vs/platform/node/product.ts index b4ed6f55eab..d3ed91503ba 100644 --- a/src/vs/platform/node/product.ts +++ b/src/vs/platform/node/product.ts @@ -4,7 +4,7 @@ *--------------------------------------------------------------------------------------------*/ import * as path from 'path'; -import uri from 'vs/base/common/uri'; +import { getPathFromAmdModule } from 'vs/base/common/amd'; export interface IProductConfiguration { nameShort: string; @@ -86,7 +86,7 @@ export interface ISurveyData { userProbability: number; } -const rootPath = path.dirname(uri.parse(require.toUrl('')).fsPath); +const rootPath = path.dirname(getPathFromAmdModule(require, '')); const productJsonPath = path.join(rootPath, 'product.json'); const product = require.__$__nodeRequire(productJsonPath) as IProductConfiguration; diff --git a/src/vs/workbench/parts/cli/electron-browser/cli.contribution.ts b/src/vs/workbench/parts/cli/electron-browser/cli.contribution.ts index 54006b5ff83..513c3d605ce 100644 --- a/src/vs/workbench/parts/cli/electron-browser/cli.contribution.ts +++ b/src/vs/workbench/parts/cli/electron-browser/cli.contribution.ts @@ -10,7 +10,6 @@ import * as pfs from 'vs/base/node/pfs'; import * as platform from 'vs/base/common/platform'; import { nfcall } from 'vs/base/common/async'; import { TPromise } from 'vs/base/common/winjs.base'; -import URI from 'vs/base/common/uri'; import { Action } from 'vs/base/common/actions'; import { IWorkbenchActionRegistry, Extensions as ActionExtensions } from 'vs/workbench/common/actions'; import { Registry } from 'vs/platform/registry/common/platform'; @@ -20,6 +19,7 @@ import { INotificationService } from 'vs/platform/notification/common/notificati import { IDialogService } from 'vs/platform/dialogs/common/dialogs'; import Severity from 'vs/base/common/severity'; import { ILogService } from 'vs/platform/log/common/log'; +import { getPathFromAmdModule } from 'vs/base/common/amd'; function ignore(code: string, value: T = null): (err: any) => TPromise { return err => err.code === code ? TPromise.as(value) : TPromise.wrapError(err); @@ -28,7 +28,7 @@ function ignore(code: string, value: T = null): (err: any) => TPromise { let _source: string = null; function getSource(): string { if (!_source) { - const root = URI.parse(require.toUrl('')).fsPath; + const root = getPathFromAmdModule(require, ''); _source = path.resolve(root, '..', 'bin', 'code'); } return _source; diff --git a/src/vs/workbench/parts/debug/node/debugger.ts b/src/vs/workbench/parts/debug/node/debugger.ts index cde530adaef..a341ff73572 100644 --- a/src/vs/workbench/parts/debug/node/debugger.ts +++ b/src/vs/workbench/parts/debug/node/debugger.ts @@ -19,10 +19,10 @@ import { IOutputService } from 'vs/workbench/parts/output/common/output'; import { DebugAdapter, SocketDebugAdapter } from 'vs/workbench/parts/debug/node/debugAdapter'; import { IConfigurationResolverService } from 'vs/workbench/services/configurationResolver/common/configurationResolver'; import { TelemetryService } from 'vs/platform/telemetry/common/telemetryService'; -import uri from 'vs/base/common/uri'; import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry'; import { memoize } from 'vs/base/common/decorators'; import { TaskDefinitionRegistry } from 'vs/workbench/parts/tasks/common/taskDefinitionRegistry'; +import { getPathFromAmdModule } from 'vs/base/common/amd'; export class Debugger { @@ -173,7 +173,7 @@ export class Debugger { return telemetryInfo; }).then(data => { const client = new TelemetryClient( - uri.parse(require.toUrl('bootstrap')).fsPath, + getPathFromAmdModule(require, 'bootstrap'), { serverName: 'Debug Telemetry', timeout: 1000 * 60 * 5, diff --git a/src/vs/workbench/parts/debug/node/terminals.ts b/src/vs/workbench/parts/debug/node/terminals.ts index a46ea642248..00ff6960cb4 100644 --- a/src/vs/workbench/parts/debug/node/terminals.ts +++ b/src/vs/workbench/parts/debug/node/terminals.ts @@ -11,8 +11,8 @@ import * as env from 'vs/base/common/platform'; import * as pfs from 'vs/base/node/pfs'; import { assign } from 'vs/base/common/objects'; import { TPromise } from 'vs/base/common/winjs.base'; -import uri from 'vs/base/common/uri'; import { ITerminalLauncher, ITerminalSettings } from 'vs/workbench/parts/debug/common/debug'; +import { getPathFromAmdModule } from 'vs/base/common/amd'; const TERMINAL_TITLE = nls.localize('console.title', "VS Code Console"); @@ -132,7 +132,7 @@ class MacTerminalService extends TerminalLauncher { // and then launches the program inside that window. const script = terminalApp === MacTerminalService.DEFAULT_TERMINAL_OSX ? 'TerminalHelper' : 'iTermHelper'; - const scriptpath = uri.parse(require.toUrl(`vs/workbench/parts/execution/electron-browser/${script}.scpt`)).fsPath; + const scriptpath = getPathFromAmdModule(require, `vs/workbench/parts/execution/electron-browser/${script}.scpt`); const osaArgs = [ scriptpath, @@ -415,4 +415,4 @@ export function prepareCommand(args: DebugProtocol.RunInTerminalRequestArguments } return command; -} \ No newline at end of file +} diff --git a/src/vs/workbench/parts/execution/electron-browser/terminalService.ts b/src/vs/workbench/parts/execution/electron-browser/terminalService.ts index 275f11a662e..b1835830812 100644 --- a/src/vs/workbench/parts/execution/electron-browser/terminalService.ts +++ b/src/vs/workbench/parts/execution/electron-browser/terminalService.ts @@ -15,8 +15,8 @@ import { TPromise } from 'vs/base/common/winjs.base'; import { ITerminalService } from 'vs/workbench/parts/execution/common/execution'; import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; import { ITerminalConfiguration, getDefaultTerminalWindows, getDefaultTerminalLinuxReady, DEFAULT_TERMINAL_OSX } from 'vs/workbench/parts/execution/electron-browser/terminal'; -import uri from 'vs/base/common/uri'; import { IProcessEnvironment } from 'vs/base/common/platform'; +import { getPathFromAmdModule } from 'vs/base/common/amd'; const TERMINAL_TITLE = nls.localize('console.title', "VS Code Console"); @@ -143,7 +143,7 @@ export class MacTerminalService implements ITerminalService { // and then launches the program inside that window. const script = terminalApp === DEFAULT_TERMINAL_OSX ? 'TerminalHelper' : 'iTermHelper'; - const scriptpath = uri.parse(require.toUrl(`vs/workbench/parts/execution/electron-browser/${script}.scpt`)).fsPath; + const scriptpath = getPathFromAmdModule(require, `vs/workbench/parts/execution/electron-browser/${script}.scpt`); const osaArgs = [ scriptpath, diff --git a/src/vs/workbench/services/extensions/electron-browser/extensionHost.ts b/src/vs/workbench/services/extensions/electron-browser/extensionHost.ts index 84a39c92a4b..16a25f5dbea 100644 --- a/src/vs/workbench/services/extensions/electron-browser/extensionHost.ts +++ b/src/vs/workbench/services/extensions/electron-browser/extensionHost.ts @@ -8,7 +8,6 @@ import * as nls from 'vs/nls'; import { toErrorMessage } from 'vs/base/common/errorMessage'; import * as objects from 'vs/base/common/objects'; -import URI from 'vs/base/common/uri'; import { TPromise } from 'vs/base/common/winjs.base'; import { isWindows, isLinux } from 'vs/base/common/platform'; import { findFreePort } from 'vs/base/node/ports'; @@ -36,6 +35,7 @@ import { IRemoteConsoleLog, log, parse } from 'vs/base/node/console'; import { getScopes } from 'vs/platform/configuration/common/configurationRegistry'; import { ILogService } from 'vs/platform/log/common/log'; import { INotificationService, Severity } from 'vs/platform/notification/common/notification'; +import { getPathFromAmdModule } from 'vs/base/common/amd'; export class ExtensionHostProcessWorker { @@ -171,7 +171,7 @@ export class ExtensionHostProcessWorker { } // Run Extension Host as fork of current process - this._extensionHostProcess = fork(URI.parse(require.toUrl('bootstrap')).fsPath, ['--type=extensionHost'], opts); + this._extensionHostProcess = fork(getPathFromAmdModule(require, 'bootstrap'), ['--type=extensionHost'], opts); // Catch all output coming from the extension host process type Output = { data: string, format: string[] }; diff --git a/src/vs/workbench/services/extensions/electron-browser/extensionService.ts b/src/vs/workbench/services/extensions/electron-browser/extensionService.ts index 35e8c870c9b..a46a116e22e 100644 --- a/src/vs/workbench/services/extensions/electron-browser/extensionService.ts +++ b/src/vs/workbench/services/extensions/electron-browser/extensionService.ts @@ -43,18 +43,19 @@ import { RPCProtocol } from 'vs/workbench/services/extensions/node/rpcProtocol'; import { INotificationService, Severity } from 'vs/platform/notification/common/notification'; import { isFalsyOrEmpty } from 'vs/base/common/arrays'; import { Schemas } from 'vs/base/common/network'; +import { getPathFromAmdModule } from 'vs/base/common/amd'; let _SystemExtensionsRoot: string = null; function getSystemExtensionsRoot(): string { if (!_SystemExtensionsRoot) { - _SystemExtensionsRoot = path.normalize(path.join(URI.parse(require.toUrl('')).fsPath, '..', 'extensions')); + _SystemExtensionsRoot = path.normalize(path.join(getPathFromAmdModule(require, ''), '..', 'extensions')); } return _SystemExtensionsRoot; } let _ExtraDevSystemExtensionsRoot: string = null; function getExtraDevSystemExtensionsRoot(): string { if (!_ExtraDevSystemExtensionsRoot) { - _ExtraDevSystemExtensionsRoot = path.normalize(path.join(URI.parse(require.toUrl('')).fsPath, '..', '.build', 'builtInExtensions')); + _ExtraDevSystemExtensionsRoot = path.normalize(path.join(getPathFromAmdModule(require, ''), '..', '.build', 'builtInExtensions')); } return _ExtraDevSystemExtensionsRoot; } @@ -796,7 +797,7 @@ export class ExtensionService extends Disposable implements IExtensionService { let finalBuiltinExtensions: TPromise = TPromise.wrap(builtinExtensions); if (devMode) { - const builtInExtensionsFilePath = path.normalize(path.join(URI.parse(require.toUrl('')).fsPath, '..', 'build', 'builtInExtensions.json')); + const builtInExtensionsFilePath = path.normalize(path.join(getPathFromAmdModule(require, ''), '..', 'build', 'builtInExtensions.json')); const builtInExtensions = pfs.readFile(builtInExtensionsFilePath, 'utf8') .then(raw => JSON.parse(raw)); diff --git a/src/vs/workbench/services/files/node/watcher/nsfw/watcherService.ts b/src/vs/workbench/services/files/node/watcher/nsfw/watcherService.ts index d2791142347..f522fba51c8 100644 --- a/src/vs/workbench/services/files/node/watcher/nsfw/watcherService.ts +++ b/src/vs/workbench/services/files/node/watcher/nsfw/watcherService.ts @@ -7,7 +7,6 @@ import { getNextTickChannel } from 'vs/base/parts/ipc/common/ipc'; import { Client } from 'vs/base/parts/ipc/node/ipc.cp'; -import uri from 'vs/base/common/uri'; import { toFileChangesEvent, IRawFileChange } from 'vs/workbench/services/files/node/watcher/common'; import { IWatcherChannel, WatcherChannelClient } from 'vs/workbench/services/files/node/watcher/nsfw/watcherIpc'; import { FileChangesEvent, IFilesConfiguration } from 'vs/platform/files/common/files'; @@ -17,6 +16,7 @@ import { IDisposable, dispose } from 'vs/base/common/lifecycle'; import { Schemas } from 'vs/base/common/network'; import { filterEvent } from 'vs/base/common/event'; import { IWatchError } from 'vs/workbench/services/files/node/watcher/nsfw/watcher'; +import { getPathFromAmdModule } from 'vs/base/common/amd'; export class FileWatcher { private static readonly MAX_RESTARTS = 5; @@ -39,7 +39,7 @@ export class FileWatcher { public startWatching(): () => void { const client = new Client( - uri.parse(require.toUrl('bootstrap')).fsPath, + getPathFromAmdModule(require, 'bootstrap'), { serverName: 'Watcher', args: ['--type=watcherService'], 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 45ca79e02f5..2dc1effa571 100644 --- a/src/vs/workbench/services/files/node/watcher/unix/watcherService.ts +++ b/src/vs/workbench/services/files/node/watcher/unix/watcherService.ts @@ -7,7 +7,6 @@ import { getNextTickChannel } from 'vs/base/parts/ipc/common/ipc'; import { Client } from 'vs/base/parts/ipc/node/ipc.cp'; -import uri from 'vs/base/common/uri'; import { toFileChangesEvent, IRawFileChange } from 'vs/workbench/services/files/node/watcher/common'; import { IWatcherChannel, WatcherChannelClient } from 'vs/workbench/services/files/node/watcher/unix/watcherIpc'; import { FileChangesEvent, IFilesConfiguration } from 'vs/platform/files/common/files'; @@ -17,6 +16,7 @@ import { IConfigurationService } from 'vs/platform/configuration/common/configur import { Schemas } from 'vs/base/common/network'; import { filterEvent } from 'vs/base/common/event'; import { IWatchError } from 'vs/workbench/services/files/node/watcher/unix/watcher'; +import { getPathFromAmdModule } from 'vs/base/common/amd'; export class FileWatcher { private static readonly MAX_RESTARTS = 5; @@ -42,7 +42,7 @@ export class FileWatcher { const args = ['--type=watcherService']; const client = new Client( - uri.parse(require.toUrl('bootstrap')).fsPath, + getPathFromAmdModule(require, 'bootstrap'), { serverName: 'Watcher', args, @@ -122,4 +122,4 @@ export class FileWatcher { this.isDisposed = true; this.toDispose = dispose(this.toDispose); } -} \ No newline at end of file +} diff --git a/src/vs/workbench/services/files/node/watcher/win32/csharpWatcherService.ts b/src/vs/workbench/services/files/node/watcher/win32/csharpWatcherService.ts index 949c3d1b36f..8c18ce5b640 100644 --- a/src/vs/workbench/services/files/node/watcher/win32/csharpWatcherService.ts +++ b/src/vs/workbench/services/files/node/watcher/win32/csharpWatcherService.ts @@ -10,9 +10,9 @@ import * as cp from 'child_process'; import { FileChangeType } from 'vs/platform/files/common/files'; import * as decoder from 'vs/base/node/decoder'; import * as glob from 'vs/base/common/glob'; -import uri from 'vs/base/common/uri'; import { IRawFileChange } from 'vs/workbench/services/files/node/watcher/common'; +import { getPathFromAmdModule } from 'vs/base/common/amd'; export class OutOfProcessWin32FolderWatcher { @@ -41,7 +41,7 @@ export class OutOfProcessWin32FolderWatcher { args.push('-verbose'); } - this.handle = cp.spawn(uri.parse(require.toUrl('vs/workbench/services/files/node/watcher/win32/CodeHelper.exe')).fsPath, args); + this.handle = cp.spawn(getPathFromAmdModule(require, 'vs/workbench/services/files/node/watcher/win32/CodeHelper.exe'), args); const stdoutLineDecoder = new decoder.LineDecoder(); @@ -116,4 +116,4 @@ export class OutOfProcessWin32FolderWatcher { this.handle = null; } } -} \ No newline at end of file +} diff --git a/src/vs/workbench/services/search/node/searchService.ts b/src/vs/workbench/services/search/node/searchService.ts index f89264988a1..5d0ce0948d9 100644 --- a/src/vs/workbench/services/search/node/searchService.ts +++ b/src/vs/workbench/services/search/node/searchService.ts @@ -26,6 +26,7 @@ import { IExtensionService } from 'vs/workbench/services/extensions/common/exten import { IUntitledEditorService } from 'vs/workbench/services/untitled/common/untitledEditorService'; import { IRawSearch, IRawSearchService, ISerializedFileMatch, ISerializedSearchComplete, ISerializedSearchProgressItem, isSerializedSearchComplete, isSerializedSearchSuccess, ITelemetryEvent } from './search'; import { ISearchChannel, SearchChannelClient } from './searchIpc'; +import { getPathFromAmdModule } from 'vs/base/common/amd'; export class SearchService extends Disposable implements ISearchService { public _serviceBrand: any; @@ -331,7 +332,7 @@ export class DiskSearch implements ISearchResultProvider { } const client = new Client( - uri.parse(require.toUrl('bootstrap')).fsPath, + getPathFromAmdModule(require, 'bootstrap'), opts); const channel = getNextTickChannel(client.getChannel('search')); diff --git a/src/vs/workbench/services/search/node/textSearchWorkerProvider.ts b/src/vs/workbench/services/search/node/textSearchWorkerProvider.ts index 1b7b03ef9a7..14a7e52b6d6 100644 --- a/src/vs/workbench/services/search/node/textSearchWorkerProvider.ts +++ b/src/vs/workbench/services/search/node/textSearchWorkerProvider.ts @@ -7,11 +7,11 @@ import * as os from 'os'; -import uri from 'vs/base/common/uri'; import * as ipc from 'vs/base/parts/ipc/common/ipc'; import { Client } from 'vs/base/parts/ipc/node/ipc.cp'; import { ISearchWorker, ISearchWorkerChannel, SearchWorkerChannelClient } from './worker/searchWorkerIpc'; +import { getPathFromAmdModule } from 'vs/base/common/amd'; export interface ITextSearchWorkerProvider { getWorkers(): ISearchWorker[]; @@ -31,7 +31,7 @@ export class TextSearchWorkerProvider implements ITextSearchWorkerProvider { private createWorker(): void { let client = new Client( - uri.parse(require.toUrl('bootstrap')).fsPath, + getPathFromAmdModule(require, 'bootstrap'), { serverName: 'Search Worker ' + this.workers.length, args: ['--type=searchWorker'], @@ -49,4 +49,4 @@ export class TextSearchWorkerProvider implements ITextSearchWorkerProvider { this.workers.push(channelClient); } -} \ No newline at end of file +} From 96a0a437b2123cdab45101b2d7cb1afe04065dd9 Mon Sep 17 00:00:00 2001 From: Johannes Rieken Date: Tue, 7 Aug 2018 12:03:53 +0200 Subject: [PATCH 0538/1276] fix #55888 --- src/vs/workbench/browser/parts/editor/breadcrumbsPicker.ts | 3 ++- .../browser/parts/editor/media/breadcrumbscontrol.css | 4 ++++ 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/src/vs/workbench/browser/parts/editor/breadcrumbsPicker.ts b/src/vs/workbench/browser/parts/editor/breadcrumbsPicker.ts index 301be5ddb44..e6eef49b484 100644 --- a/src/vs/workbench/browser/parts/editor/breadcrumbsPicker.ts +++ b/src/vs/workbench/browser/parts/editor/breadcrumbsPicker.ts @@ -239,7 +239,8 @@ export class FileRenderer implements IRenderer, IHighlightingRenderer { fileKind, hidePath: true, fileDecorations: fileDecorations, - matches: createMatches((this._scores.get(resource.toString()) || [, []])[1]) + matches: createMatches((this._scores.get(resource.toString()) || [, []])[1]), + extraClasses: ['picker-item'] }); } diff --git a/src/vs/workbench/browser/parts/editor/media/breadcrumbscontrol.css b/src/vs/workbench/browser/parts/editor/media/breadcrumbscontrol.css index 2aa84dbc6ec..e03eee35663 100644 --- a/src/vs/workbench/browser/parts/editor/media/breadcrumbscontrol.css +++ b/src/vs/workbench/browser/parts/editor/media/breadcrumbscontrol.css @@ -23,6 +23,10 @@ /* todo@joh move somewhere else */ +.monaco-workbench .monaco-breadcrumbs-picker .picker-item { + line-height: 22px; +} + .monaco-workbench .monaco-breadcrumbs-picker .highlighting-tree { height: 100%; overflow: hidden; From edfda964e0d17ef2b16caea9c6c11c94ed92a90b Mon Sep 17 00:00:00 2001 From: Andre Weinand Date: Tue, 7 Aug 2018 12:28:30 +0200 Subject: [PATCH 0539/1276] use terminal.processId for auto-attach; fixes #55918 --- .../debug-auto-launch/src/autoAttach.ts | 24 -------------- .../debug-auto-launch/src/nodeProcessTree.ts | 33 +++++-------------- 2 files changed, 9 insertions(+), 48 deletions(-) delete mode 100644 extensions/debug-auto-launch/src/autoAttach.ts diff --git a/extensions/debug-auto-launch/src/autoAttach.ts b/extensions/debug-auto-launch/src/autoAttach.ts deleted file mode 100644 index a6bb925ef4f..00000000000 --- a/extensions/debug-auto-launch/src/autoAttach.ts +++ /dev/null @@ -1,24 +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'; - -import * as vscode from 'vscode'; -import * as nls from 'vscode-nls'; -import { basename } from 'path'; -import { pollProcesses, attachToProcess } from './nodeProcessTree'; - -const localize = nls.loadMessageBundle(); - -export function startAutoAttach(rootPid: number): vscode.Disposable { - - return pollProcesses(rootPid, true, (pid, cmdPath, args) => { - const cmdName = basename(cmdPath, '.exe'); - if (cmdName === 'node') { - const name = localize('process.with.pid.label', "Process {0}", pid); - attachToProcess(undefined, name, pid, args); - } - }); -} diff --git a/extensions/debug-auto-launch/src/nodeProcessTree.ts b/extensions/debug-auto-launch/src/nodeProcessTree.ts index d803ddd1bcd..1a62971bc30 100644 --- a/extensions/debug-auto-launch/src/nodeProcessTree.ts +++ b/extensions/debug-auto-launch/src/nodeProcessTree.ts @@ -95,10 +95,10 @@ export function attachToProcess(folder: vscode.WorkspaceFolder | undefined, name function findChildProcesses(rootPid: number, inTerminal: boolean, cb: (pid: number, cmd: string, args: string) => void): Promise { - function walker(node: ProcessTreeNode, terminal: boolean, renderer: number) { + function walker(node: ProcessTreeNode, terminal: boolean, terminalPids: number[]) { - if ((node.args.indexOf('--type=terminal') >= 0 || node.command.indexOf('\\winpty-agent.exe') >= 0) && (renderer === 0 || node.ppid === renderer)) { - terminal = true; + if (terminalPids.indexOf(node.pid) >= 0) { + terminal = true; // found the terminal shell } let { protocol } = analyseArguments(node.args); @@ -107,32 +107,17 @@ function findChildProcesses(rootPid: number, inTerminal: boolean, cb: (pid: numb } for (const child of node.children || []) { - walker(child, terminal, renderer); + walker(child, terminal, terminalPids); } } - function finder(node: ProcessTreeNode, pid: number): ProcessTreeNode | undefined { - if (node.pid === pid) { - return node; - } - for (const child of node.children || []) { - const p = finder(child, pid); - if (p) { - return p; - } - } - return undefined; - } - return getProcessTree(rootPid).then(tree => { if (tree) { - - // find the pid of the renderer process - const extensionHost = finder(tree, process.pid); - let rendererPid = extensionHost ? extensionHost.ppid : 0; - - for (const child of tree.children || []) { - walker(child, !inTerminal, rendererPid); + const terminals = vscode.window.terminals; + if (terminals.length > 0) { + Promise.all(terminals.map(terminal => terminal.processId)).then(terminalPids => { + walker(tree, !inTerminal, terminalPids); + }); } } }); From cb0fdd1628244ef8522a177d0bc44b1042db0c34 Mon Sep 17 00:00:00 2001 From: Joao Moreno Date: Tue, 7 Aug 2018 03:32:57 -0700 Subject: [PATCH 0540/1276] fixes #55840 --- build/win32/code.iss | 2 +- package.json | 1 + src/typings/winreg.d.ts | 338 ++++++++++++++++++ src/vs/platform/node/product.ts | 4 + .../parts/update/electron-browser/update.ts | 99 +++-- yarn.lock | 4 + 6 files changed, 421 insertions(+), 27 deletions(-) create mode 100644 src/typings/winreg.d.ts diff --git a/build/win32/code.iss b/build/win32/code.iss index cad2e27d65e..baca2f28cbd 100644 --- a/build/win32/code.iss +++ b/build/win32/code.iss @@ -975,7 +975,7 @@ begin RegKey := 'SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\' + copy('{#IncompatibleTargetAppId}', 2, 38) + '_is1'; if RegKeyExists({#IncompatibleArchRootKey}, RegKey) then begin - if MsgBox('{#NameShort} is already installed on this system for all users. Are you sure you want to install it for this user?', mbConfirmation, MB_YESNO) = IDNO then begin + if MsgBox('{#NameShort} is already installed on this system for all users. Note that both versions will be installed simultaneously; you might want to first uninstall the system-wide installation. Are you sure you want to continue?', mbConfirmation, MB_YESNO) = IDNO then begin Result := false; end; end; diff --git a/package.json b/package.json index 8042314a7e6..f13936cd4e8 100644 --- a/package.json +++ b/package.json @@ -51,6 +51,7 @@ "vscode-ripgrep": "^1.0.1", "vscode-textmate": "^4.0.1", "vscode-xterm": "3.7.0-beta2", + "winreg": "^1.2.4", "yauzl": "^2.9.1" }, "devDependencies": { diff --git a/src/typings/winreg.d.ts b/src/typings/winreg.d.ts new file mode 100644 index 00000000000..70047d8b50f --- /dev/null +++ b/src/typings/winreg.d.ts @@ -0,0 +1,338 @@ +// Type definitions for Winreg v1.2.0 +// Project: http://fresc81.github.io/node-winreg/ +// Definitions by: RX14 , BobBuehler +// Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped + +declare var Winreg: WinregStatic; + +interface WinregStatic { + /** + * Creates a registry object, which provides access to a single registry key. + * Note: This class is returned by a call to ```require('winreg')```. + * + * @public + * @class + * + * @param {@link Options} options - the options + * + * @example + * var Registry = require('winreg') + * , autoStartCurrentUser = new Registry({ + * hive: Registry.HKCU, + * key: '\\Software\\Microsoft\\Windows\\CurrentVersion\\Run' + * }); + */ + new (options: Winreg.Options): Winreg.Registry; + + /** + * Registry hive key HKEY_LOCAL_MACHINE. + * Note: For writing to this hive your program has to run with admin privileges. + */ + HKLM: string; + + /** + * Registry hive key HKEY_CURRENT_USER. + */ + HKCU: string; + + /** + * Registry hive key HKEY_CLASSES_ROOT. + * Note: For writing to this hive your program has to run with admin privileges. + */ + HKCR: string; + + /** + * Registry hive key HKEY_USERS. + * Note: For writing to this hive your program has to run with admin privileges. + */ + HKU: string; + + /** + * Registry hive key HKEY_CURRENT_CONFIG. + * Note: For writing to this hive your program has to run with admin privileges. + */ + HKCC: string; + + /** + * Collection of available registry hive keys. + */ + HIVES: Array; + + /** + * Registry value type STRING. + * + * Values of this type contain a string. + */ + REG_SZ: string; + + /** + * Registry value type MULTILINE_STRING. + * + * Values of this type contain a multiline string. + */ + REG_MULTI_SZ: string; + + /** + * Registry value type EXPANDABLE_STRING. + * + * Values of this type contain an expandable string. + */ + REG_EXPAND_SZ: string; + + /** + * Registry value type DOUBLE_WORD. + * + * Values of this type contain a double word (32 bit integer). + */ + REG_DWORD: string; + + /** + * Registry value type QUAD_WORD. + * + * Values of this type contain a quad word (64 bit integer). + */ + REG_QWORD: string; + + /** + * Registry value type BINARY. + * + * Values of this type contain a binary value. + */ + REG_BINARY: string; + + /** + * Registry value type UNKNOWN. + * + * Values of this type contain a value of an unknown type. + */ + REG_NONE: string; + + /** + * Collection of available registry value types. + */ + REG_TYPES: Array; + + /** + * The name of the default value. May be used instead of the empty string literal for better readability. + */ + DEFAULT_VALUE: string; +} + +declare namespace Winreg { + export interface Options { + /** + * Optional hostname, must start with '\\' sequence. + */ + host?: string; + + /** + * Optional hive ID, default is HKLM. + */ + hive?: string; + + /** + * Optional key, default is the root key. + */ + key?: string; + + /** + * Optional registry hive architecture ('x86' or 'x64'; only valid on Windows 64 Bit Operating Systems). + */ + arch?: string; + } + + /** + * A registry object, which provides access to a single registry key. + */ + export interface Registry { + /** + * The hostname. + * @readonly + */ + host: string; + + /** + * The hive id. + * @readonly + */ + hive: string; + + /** + * The registry key name. + * @readonly + */ + key: string; + + /** + * The full path to the registry key. + * @readonly + */ + path: string; + + /** + * The registry hive architecture ('x86' or 'x64'). + * @readonly + */ + arch: string; + + /** + * Creates a new {@link Registry} instance that points to the parent registry key. + * @readonly + */ + parent: Registry; + + /** + * Retrieve all values from this registry key. + * @param {valuesCallback} cb - callback function + * @param {error=} cb.err - error object or null if successful + * @param {array=} cb.items - an array of {@link RegistryItem} objects + * @returns {Registry} this registry key object + */ + values(cb: (err: Error, result: Array) => void): Registry; + + /** + * Retrieve all subkeys from this registry key. + * @param {function (err, items)} cb - callback function + * @param {error=} cb.err - error object or null if successful + * @param {array=} cb.items - an array of {@link Registry} objects + * @returns {Registry} this registry key object + */ + keys(cb: (err: Error, result: Array) => void): Registry; + + /** + * Gets a named value from this registry key. + * @param {string} name - the value name, use {@link Registry.DEFAULT_VALUE} or an empty string for the default value + * @param {function (err, item)} cb - callback function + * @param {error=} cb.err - error object or null if successful + * @param {RegistryItem=} cb.item - the retrieved registry item + * @returns {Registry} this registry key object + */ + get(name: string, cb: (err: Error, result: Winreg.RegistryItem) => void): Registry; + + /** + * Sets a named value in this registry key, overwriting an already existing value. + * @param {string} name - the value name, use {@link Registry.DEFAULT_VALUE} or an empty string for the default value + * @param {string} type - the value type + * @param {string} value - the value + * @param {function (err)} cb - callback function + * @param {error=} cb.err - error object or null if successful + * @returns {Registry} this registry key object + */ + set(name: string, type: string, value: string, cb: (err: Error) => void): Registry; + + /** + * Remove a named value from this registry key. If name is empty, sets the default value of this key. + * Note: This key must be already existing. + * @param {string} name - the value name, use {@link Registry.DEFAULT_VALUE} or an empty string for the default value + * @param {function (err)} cb - callback function + * @param {error=} cb.err - error object or null if successful + * @returns {Registry} this registry key object + */ + remove(name: string, cb: (err: Error) => void): Registry; + + /** + * Remove all subkeys and values (including the default value) from this registry key. + * @param {function (err)} cb - callback function + * @param {error=} cb.err - error object or null if successful + * @returns {Registry} this registry key object + */ + clear(cb: (err: Error) => void): Registry; + + /** + * Alias for the clear method to keep it backward compatible. + * @method + * @deprecated Use {@link Registry#clear} or {@link Registry#destroy} in favour of this method. + * @param {function (err)} cb - callback function + * @param {error=} cb.err - error object or null if successful + * @returns {Registry} this registry key object + */ + erase(cb: (err: Error) => void): Registry; + + /** + * Delete this key and all subkeys from the registry. + * @param {function (err)} cb - callback function + * @param {error=} cb.err - error object or null if successful + * @returns {Registry} this registry key object + */ + destroy(cb: (err: Error) => void): Registry; + + /** + * Create this registry key. Note that this is a no-op if the key already exists. + * @param {function (err)} cb - callback function + * @param {error=} cb.err - error object or null if successful + * @returns {Registry} this registry key object + */ + create(cb: (err: Error) => void): Registry; + + /** + * Checks if this key already exists. + * @param {function (err, exists)} cb - callback function + * @param {error=} cb.err - error object or null if successful + * @param {boolean=} cb.exists - true if a registry key with this name already exists + * @returns {Registry} this registry key object + */ + keyExists(cb: (err: Error, exists: boolean) => void): Registry; + + /** + * Checks if a value with the given name already exists within this key. + * @param {string} name - the value name, use {@link Registry.DEFAULT_VALUE} or an empty string for the default value + * @param {function (err, exists)} cb - callback function + * @param {error=} cb.err - error object or null if successful + * @param {boolean=} cb.exists - true if a value with the given name was found in this key + * @returns {Registry} this registry key object + */ + valueExists(name: string, cb: (err: Error, exists: boolean) => void): Registry; + } + + /** + * A single registry value record. + * Objects of this type are created internally and returned by methods of {@link Registry} objects. + */ + export interface RegistryItem { + /** + * The hostname. + * @readonly + */ + host: string; + + /** + * The hive id. + * @readonly + */ + hive: string; + + /** + * The registry key. + * @readonly + */ + key: string; + + /** + * The value name. + * @readonly + */ + name: string; + + /** + * The value type. + * @readonly + */ + type: string; + + /** + * The value. + * @readonly + */ + value: string; + + /** + * The hive architecture. + * @readonly + */ + arch: string; + } +} + +declare module "winreg" { + export = Winreg; +} \ No newline at end of file diff --git a/src/vs/platform/node/product.ts b/src/vs/platform/node/product.ts index b4ed6f55eab..a3dce3929b2 100644 --- a/src/vs/platform/node/product.ts +++ b/src/vs/platform/node/product.ts @@ -10,6 +10,10 @@ export interface IProductConfiguration { nameShort: string; nameLong: string; applicationName: string; + win32AppId: string; + win32x64AppId: string; + win32UserAppId: string; + win32x64UserAppId: string; win32AppUserModelId: string; win32MutexName: string; darwinBundleIdentifier: string; diff --git a/src/vs/workbench/parts/update/electron-browser/update.ts b/src/vs/workbench/parts/update/electron-browser/update.ts index 2ce9bd83b96..9aa410943f5 100644 --- a/src/vs/workbench/parts/update/electron-browser/update.ts +++ b/src/vs/workbench/parts/update/electron-browser/update.ts @@ -30,6 +30,7 @@ import { IWindowService } from 'vs/platform/windows/common/windows'; import { ReleaseNotesManager } from './releaseNotesEditor'; import { isWindows } from 'vs/base/common/platform'; import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; +import * as Registry from 'winreg'; let releaseNotesManager: ReleaseNotesManager | undefined = undefined; @@ -209,9 +210,27 @@ export class Win3264BitContribution implements IWorkbenchContribution { } } +async function isUserSetupInstalled(): Promise { + const rawUserAppId = process.arch === 'x64' ? product.win32x64UserAppId : product.win32UserAppId; + const userAppId = rawUserAppId.replace(/^\{\{/, '{'); + const key = new Registry({ + hive: Registry.HKCU, + key: `\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\${userAppId}_is1` + }); + + try { + await new Promise((c, e) => key.get('', (err, result) => err ? e(err) : c(result))); + } catch (err) { + return false; + } + + return true; +} + export class WinUserSetupContribution implements IWorkbenchContribution { private static readonly KEY = 'update/win32-usersetup'; + private static readonly KEY_BOTH = 'update/win32-usersetup-both'; private static readonly STABLE_URL = 'https://vscode-update.azurewebsites.net/latest/win32-x64-user/stable'; private static readonly STABLE_URL_32BIT = 'https://vscode-update.azurewebsites.net/latest/win32-user/stable'; @@ -247,35 +266,63 @@ export class WinUserSetupContribution implements IWorkbenchContribution { return; } - const neverShowAgain = new NeverShowAgain(WinUserSetupContribution.KEY, this.storageService); + isUserSetupInstalled().then(userSetupIsInstalled => { + if (userSetupIsInstalled) { + const neverShowAgain = new NeverShowAgain(WinUserSetupContribution.KEY_BOTH, this.storageService); - if (!neverShowAgain.shouldShow()) { - return; - } + if (!neverShowAgain.shouldShow()) { + return; + } - const handle = this.notificationService.prompt( - severity.Info, - nls.localize('usersetup', "We recommend switching to our new User Setup distribution of {0} for Windows! Click [here]({1}) to learn more.", product.nameShort, WinUserSetupContribution.READ_MORE), - [ - { - label: nls.localize('downloadnow', "Download"), - run: () => { - const url = product.quality === 'insider' - ? (process.arch === 'ia32' ? WinUserSetupContribution.INSIDER_URL_32BIT : WinUserSetupContribution.INSIDER_URL) - : (process.arch === 'ia32' ? WinUserSetupContribution.STABLE_URL_32BIT : WinUserSetupContribution.STABLE_URL); + const handle = this.notificationService.prompt( + severity.Warning, + nls.localize('usersetupsystem', "You are running the system-wide installation of {0}, while having the user-wide distribution installed as well. Make sure you're running the {0} version you expect.", product.nameShort), + [ + { + label: nls.localize('ok', "OK"), + run: () => null + }, + { + label: nls.localize('neveragain', "Don't Show Again"), + isSecondary: true, + run: () => { + neverShowAgain.action.run(handle); + neverShowAgain.action.dispose(); + } + }] + ); + } else { + const neverShowAgain = new NeverShowAgain(WinUserSetupContribution.KEY, this.storageService); - return this.openerService.open(URI.parse(url)); - } - }, - { - label: nls.localize('neveragain', "Don't Show Again"), - isSecondary: true, - run: () => { - neverShowAgain.action.run(handle); - neverShowAgain.action.dispose(); - } - }] - ); + if (!neverShowAgain.shouldShow()) { + return; + } + + const handle = this.notificationService.prompt( + severity.Info, + nls.localize('usersetup', "We recommend switching to our new User Setup distribution of {0} for Windows! Click [here]({1}) to learn more.", product.nameShort, WinUserSetupContribution.READ_MORE), + [ + { + label: nls.localize('downloadnow', "Download"), + run: () => { + const url = product.quality === 'insider' + ? (process.arch === 'ia32' ? WinUserSetupContribution.INSIDER_URL_32BIT : WinUserSetupContribution.INSIDER_URL) + : (process.arch === 'ia32' ? WinUserSetupContribution.STABLE_URL_32BIT : WinUserSetupContribution.STABLE_URL); + + return this.openerService.open(URI.parse(url)); + } + }, + { + label: nls.localize('neveragain', "Don't Show Again"), + isSecondary: true, + run: () => { + neverShowAgain.action.run(handle); + neverShowAgain.action.dispose(); + } + }] + ); + } + }); } dispose(): void { diff --git a/yarn.lock b/yarn.lock index 6dcbc60e044..1d81bc278d2 100644 --- a/yarn.lock +++ b/yarn.lock @@ -6183,6 +6183,10 @@ windows-process-tree@0.2.2: dependencies: nan "^2.6.2" +winreg@^1.2.4: + version "1.2.4" + resolved "https://registry.yarnpkg.com/winreg/-/winreg-1.2.4.tgz#ba065629b7a925130e15779108cf540990e98d1b" + wordwrap@0.0.2: version "0.0.2" resolved "https://registry.yarnpkg.com/wordwrap/-/wordwrap-0.0.2.tgz#b79669bb42ecb409f83d583cad52ca17eaa1643f" From 57298ffbc56ca62dc9c5a1ce853800d8c11b49c6 Mon Sep 17 00:00:00 2001 From: Benjamin Pasero Date: Tue, 7 Aug 2018 12:56:32 +0200 Subject: [PATCH 0541/1276] debt - reduce usage of builder --- .../parts/activitybar/activitybarPart.ts | 36 +++--- .../browser/parts/panel/panelPart.ts | 11 +- .../browser/parts/sidebar/sidebarPart.ts | 26 ++-- .../browser/parts/statusbar/statusbarPart.ts | 14 +-- .../workbench/electron-browser/workbench.ts | 114 ++++++++---------- 5 files changed, 96 insertions(+), 105 deletions(-) diff --git a/src/vs/workbench/browser/parts/activitybar/activitybarPart.ts b/src/vs/workbench/browser/parts/activitybar/activitybarPart.ts index 298c940d475..8577c13caaa 100644 --- a/src/vs/workbench/browser/parts/activitybar/activitybarPart.ts +++ b/src/vs/workbench/browser/parts/activitybar/activitybarPart.ts @@ -8,7 +8,6 @@ import 'vs/css!./media/activitybarpart'; import * as nls from 'vs/nls'; import { illegalArgument } from 'vs/base/common/errors'; -import { $ } from 'vs/base/browser/builder'; import { ActionsOrientation, ActionBar } from 'vs/base/browser/ui/actionbar/actionbar'; import { GlobalActivityExtensions, IGlobalActivityRegistry } from 'vs/workbench/common/activity'; import { Registry } from 'vs/platform/registry/common/platform'; @@ -26,7 +25,7 @@ import { contrastBorder } from 'vs/platform/theme/common/colorRegistry'; import { CompositeBar } from 'vs/workbench/browser/parts/compositebar/compositeBar'; import { isMacintosh } from 'vs/base/common/platform'; import { ILifecycleService, LifecyclePhase } from 'vs/platform/lifecycle/common/lifecycle'; -import { scheduleAtNextAnimationFrame, Dimension } from 'vs/base/browser/dom'; +import { scheduleAtNextAnimationFrame, Dimension, addClass } from 'vs/base/browser/dom'; import { Color } from 'vs/base/common/color'; import { IStorageService, StorageScope } from 'vs/platform/storage/common/storage'; import { IExtensionService } from 'vs/workbench/services/extensions/common/extensions'; @@ -156,14 +155,19 @@ export class ActivitybarPart extends Part { } createContentArea(parent: HTMLElement): HTMLElement { - const $el = $(parent); - const $result = $('.content').appendTo($el); + const content = document.createElement('div'); + addClass(content, 'content'); + parent.appendChild(content); // Top Actionbar with action items for each viewlet action - this.compositeBar.create($result.getHTMLElement()); + this.compositeBar.create(content); // Top Actionbar with action items for each viewlet action - this.createGlobalActivityActionBar($('.global-activity').appendTo($result).getHTMLElement()); + const globalActivities = document.createElement('div'); + addClass(globalActivities, 'global-activity'); + content.appendChild(globalActivities); + + this.createGlobalActivityActionBar(globalActivities); // TODO@Ben: workaround for https://github.com/Microsoft/vscode/issues/45700 // It looks like there are rendering glitches on macOS with Chrome 61 when @@ -186,26 +190,26 @@ export class ActivitybarPart extends Part { }); } - return $result.getHTMLElement(); + return content; } updateStyles(): void { super.updateStyles(); // Part container - const container = $(this.getContainer()); + const container = this.getContainer(); const background = this.getColor(ACTIVITY_BAR_BACKGROUND); - container.style('background-color', background); + container.style.backgroundColor = background; const borderColor = this.getColor(ACTIVITY_BAR_BORDER) || this.getColor(contrastBorder); const isPositionLeft = this.partService.getSideBarPosition() === SideBarPosition.LEFT; - container.style('box-sizing', borderColor && isPositionLeft ? 'border-box' : null); - container.style('border-right-width', borderColor && isPositionLeft ? '1px' : null); - container.style('border-right-style', borderColor && isPositionLeft ? 'solid' : null); - container.style('border-right-color', isPositionLeft ? borderColor : null); - container.style('border-left-width', borderColor && !isPositionLeft ? '1px' : null); - container.style('border-left-style', borderColor && !isPositionLeft ? 'solid' : null); - container.style('border-left-color', !isPositionLeft ? borderColor : null); + container.style.boxSizing = borderColor && isPositionLeft ? 'border-box' : null; + container.style.borderRightWidth = borderColor && isPositionLeft ? '1px' : null; + container.style.borderRightStyle = borderColor && isPositionLeft ? 'solid' : null; + container.style.borderRightColor = isPositionLeft ? borderColor : null; + container.style.borderLeftWidth = borderColor && !isPositionLeft ? '1px' : null; + container.style.borderLeftStyle = borderColor && !isPositionLeft ? 'solid' : null; + container.style.borderLeftColor = !isPositionLeft ? borderColor : null; } private createGlobalActivityActionBar(container: HTMLElement): void { diff --git a/src/vs/workbench/browser/parts/panel/panelPart.ts b/src/vs/workbench/browser/parts/panel/panelPart.ts index 40c3fa928ea..094b9b2aa89 100644 --- a/src/vs/workbench/browser/parts/panel/panelPart.ts +++ b/src/vs/workbench/browser/parts/panel/panelPart.ts @@ -7,7 +7,6 @@ import 'vs/css!./media/panelpart'; import { TPromise } from 'vs/base/common/winjs.base'; import { IAction } from 'vs/base/common/actions'; import { Event } from 'vs/base/common/event'; -import { $ } from 'vs/base/browser/builder'; import { Registry } from 'vs/platform/registry/common/platform'; import { ActionsOrientation } from 'vs/base/browser/ui/actionbar/actionbar'; import { IPanel } from 'vs/workbench/common/panel'; @@ -151,12 +150,12 @@ export class PanelPart extends CompositePart implements IPanelService { updateStyles(): void { super.updateStyles(); - const container = $(this.getContainer()); - container.style('background-color', this.getColor(PANEL_BACKGROUND)); - container.style('border-left-color', this.getColor(PANEL_BORDER) || this.getColor(contrastBorder)); + const container = this.getContainer(); + container.style.backgroundColor = this.getColor(PANEL_BACKGROUND); + container.style.borderLeftColor = this.getColor(PANEL_BORDER) || this.getColor(contrastBorder); - const title = $(this.getTitleArea()); - title.style('border-top-color', this.getColor(PANEL_BORDER) || this.getColor(contrastBorder)); + const title = this.getTitleArea(); + title.style.borderTopColor = this.getColor(PANEL_BORDER) || this.getColor(contrastBorder); } openPanel(id: string, focus?: boolean): TPromise { diff --git a/src/vs/workbench/browser/parts/sidebar/sidebarPart.ts b/src/vs/workbench/browser/parts/sidebar/sidebarPart.ts index 88e7acb9c01..556cdfd222e 100644 --- a/src/vs/workbench/browser/parts/sidebar/sidebarPart.ts +++ b/src/vs/workbench/browser/parts/sidebar/sidebarPart.ts @@ -26,8 +26,7 @@ import { IThemeService } from 'vs/platform/theme/common/themeService'; import { contrastBorder } from 'vs/platform/theme/common/colorRegistry'; import { SIDE_BAR_TITLE_FOREGROUND, SIDE_BAR_BACKGROUND, SIDE_BAR_FOREGROUND, SIDE_BAR_BORDER } from 'vs/workbench/common/theme'; import { INotificationService } from 'vs/platform/notification/common/notification'; -import { Dimension, EventType } from 'vs/base/browser/dom'; -import { $ } from 'vs/base/browser/builder'; +import { Dimension, EventType, addDisposableListener } from 'vs/base/browser/dom'; import { StandardMouseEvent } from 'vs/base/browser/mouseEvent'; export class SidebarPart extends CompositePart { @@ -77,7 +76,10 @@ export class SidebarPart extends CompositePart { createTitleArea(parent: HTMLElement): HTMLElement { const titleArea = super.createTitleArea(parent); - $(titleArea).on(EventType.CONTEXT_MENU, (e: MouseEvent) => this.onTitleAreaContextMenu(new StandardMouseEvent(e)), this.toDispose); + + this._register(addDisposableListener(titleArea, EventType.CONTEXT_MENU, e => { + this.onTitleAreaContextMenu(new StandardMouseEvent(e)); + })); return titleArea; } @@ -86,19 +88,19 @@ export class SidebarPart extends CompositePart { super.updateStyles(); // Part container - const container = $(this.getContainer()); + const container = this.getContainer(); - container.style('background-color', this.getColor(SIDE_BAR_BACKGROUND)); - container.style('color', this.getColor(SIDE_BAR_FOREGROUND)); + container.style.backgroundColor = this.getColor(SIDE_BAR_BACKGROUND); + container.style.color = this.getColor(SIDE_BAR_FOREGROUND); const borderColor = this.getColor(SIDE_BAR_BORDER) || this.getColor(contrastBorder); const isPositionLeft = this.partService.getSideBarPosition() === SideBarPosition.LEFT; - container.style('border-right-width', borderColor && isPositionLeft ? '1px' : null); - container.style('border-right-style', borderColor && isPositionLeft ? 'solid' : null); - container.style('border-right-color', isPositionLeft ? borderColor : null); - container.style('border-left-width', borderColor && !isPositionLeft ? '1px' : null); - container.style('border-left-style', borderColor && !isPositionLeft ? 'solid' : null); - container.style('border-left-color', !isPositionLeft ? borderColor : null); + container.style.borderRightWidth = borderColor && isPositionLeft ? '1px' : null; + container.style.borderRightStyle = borderColor && isPositionLeft ? 'solid' : null; + container.style.borderRightColor = isPositionLeft ? borderColor : null; + container.style.borderLeftWidth = borderColor && !isPositionLeft ? '1px' : null; + container.style.borderLeftStyle = borderColor && !isPositionLeft ? 'solid' : null; + container.style.borderLeftColor = !isPositionLeft ? borderColor : null; } openViewlet(id: string, focus?: boolean): TPromise { diff --git a/src/vs/workbench/browser/parts/statusbar/statusbarPart.ts b/src/vs/workbench/browser/parts/statusbar/statusbarPart.ts index 175276033e2..d0c0302f07c 100644 --- a/src/vs/workbench/browser/parts/statusbar/statusbarPart.ts +++ b/src/vs/workbench/browser/parts/statusbar/statusbarPart.ts @@ -134,22 +134,22 @@ export class StatusbarPart extends Part implements IStatusbarService { protected updateStyles(): void { super.updateStyles(); - const container = $(this.getContainer()); + const container = this.getContainer(); // Background colors const backgroundColor = this.getColor(this.contextService.getWorkbenchState() !== WorkbenchState.EMPTY ? STATUS_BAR_BACKGROUND : STATUS_BAR_NO_FOLDER_BACKGROUND); - container.style('background-color', backgroundColor); - container.style('color', this.getColor(this.contextService.getWorkbenchState() !== WorkbenchState.EMPTY ? STATUS_BAR_FOREGROUND : STATUS_BAR_NO_FOLDER_FOREGROUND)); + container.style.backgroundColor = backgroundColor; + container.style.color = this.getColor(this.contextService.getWorkbenchState() !== WorkbenchState.EMPTY ? STATUS_BAR_FOREGROUND : STATUS_BAR_NO_FOLDER_FOREGROUND); // Border color const borderColor = this.getColor(this.contextService.getWorkbenchState() !== WorkbenchState.EMPTY ? STATUS_BAR_BORDER : STATUS_BAR_NO_FOLDER_BORDER) || this.getColor(contrastBorder); - container.style('border-top-width', borderColor ? '1px' : null); - container.style('border-top-style', borderColor ? 'solid' : null); - container.style('border-top-color', borderColor); + container.style.borderTopWidth = borderColor ? '1px' : null; + container.style.borderTopStyle = borderColor ? 'solid' : null; + container.style.borderTopColor = borderColor; // Notification Beak if (!this.styleElement) { - this.styleElement = createStyleSheet(container.getHTMLElement()); + this.styleElement = createStyleSheet(container); } this.styleElement.innerHTML = `.monaco-workbench > .part.statusbar > .statusbar-item.has-beak:before { border-bottom-color: ${backgroundColor}; }`; diff --git a/src/vs/workbench/electron-browser/workbench.ts b/src/vs/workbench/electron-browser/workbench.ts index ed8d5ba2f2b..da185db3fc8 100644 --- a/src/vs/workbench/electron-browser/workbench.ts +++ b/src/vs/workbench/electron-browser/workbench.ts @@ -12,7 +12,6 @@ import { TPromise } from 'vs/base/common/winjs.base'; import { IDisposable, dispose, toDisposable, Disposable } from 'vs/base/common/lifecycle'; import { Event, Emitter } from 'vs/base/common/event'; import * as DOM from 'vs/base/browser/dom'; -import { Builder, $ } from 'vs/base/browser/builder'; import { RunOnceScheduler } from 'vs/base/common/async'; import * as browser from 'vs/base/browser/browser'; import * as perf from 'vs/base/common/performance'; @@ -190,7 +189,7 @@ export class Workbench extends Disposable implements IPartService { _serviceBrand: any; private workbenchParams: WorkbenchParams; - private workbench: Builder; + private workbench: HTMLElement; private workbenchStarted: boolean; private workbenchCreated: boolean; private workbenchShutdown: boolean; @@ -296,12 +295,13 @@ export class Workbench extends Disposable implements IPartService { } private createWorkbench(): void { - this.workbench = $().div({ - 'class': `monaco-workbench ${isWindows ? 'windows' : isLinux ? 'linux' : 'mac'}`, - id: Identifiers.WORKBENCH_CONTAINER - }); + this.workbench = document.createElement('div'); + this.workbench.id = Identifiers.WORKBENCH_CONTAINER; + DOM.addClasses(this.workbench, 'monaco-workbench', isWindows ? 'windows' : isLinux ? 'linux' : 'mac'); - this.workbench.on(DOM.EventType.SCROLL, e => { this.workbench.getHTMLElement().scrollTop = 0; }); // Prevent workbench from scrolling #55456 + this._register(DOM.addDisposableListener(this.workbench, DOM.EventType.SCROLL, () => { + this.workbench.scrollTop = 0; // Prevent workbench from scrolling #55456 + })); } private createGlobalActions(): void { @@ -358,7 +358,7 @@ export class Workbench extends Disposable implements IPartService { serviceCollection.set(IListService, this.instantiationService.createInstance(ListService)); // Context view service - this.contextViewService = this.instantiationService.createInstance(ContextViewService, this.workbench.getHTMLElement()); + this.contextViewService = this.instantiationService.createInstance(ContextViewService, this.workbench); serviceCollection.set(IContextViewService, this.contextViewService); // Use themable context menus when custom titlebar is enabled to match custom menubar @@ -514,9 +514,10 @@ export class Workbench extends Disposable implements IPartService { // Apply as CSS class const isFullscreen = browser.isFullscreen(); if (isFullscreen) { - this.workbench.addClass('fullscreen'); + DOM.addClass(this.workbench, 'fullscreen'); } else { - this.workbench.removeClass('fullscreen'); + DOM.removeClass(this.workbench, 'fullscreen'); + if (this.zenMode.transitionedToFullScreen && this.zenMode.active) { this.toggleZenMode(); } @@ -925,9 +926,9 @@ export class Workbench extends Disposable implements IPartService { // Adjust CSS if (hidden) { - this.workbench.addClass('nostatusbar'); + DOM.addClass(this.workbench, 'nostatusbar'); } else { - this.workbench.removeClass('nostatusbar'); + DOM.removeClass(this.workbench, 'nostatusbar'); } // Layout @@ -952,7 +953,7 @@ export class Workbench extends Disposable implements IPartService { this.workbenchLayout = this.instantiationService.createInstance( WorkbenchLayout, this.container, - this.workbench.getHTMLElement(), + this.workbench, { titlebar: this.titlebarPart, activitybar: this.activitybarPart, @@ -972,13 +973,15 @@ export class Workbench extends Disposable implements IPartService { // Apply sidebar state as CSS class if (this.sideBarHidden) { - this.workbench.addClass('nosidebar'); + DOM.addClass(this.workbench, 'nosidebar'); } + if (this.panelHidden) { - this.workbench.addClass('nopanel'); + DOM.addClass(this.workbench, 'nopanel'); } + if (this.statusBarHidden) { - this.workbench.addClass('nostatusbar'); + DOM.addClass(this.workbench, 'nostatusbar'); } // Apply font aliasing @@ -986,7 +989,7 @@ export class Workbench extends Disposable implements IPartService { // Apply fullscreen state if (browser.isFullscreen()) { - this.workbench.addClass('fullscreen'); + DOM.addClass(this.workbench, 'fullscreen'); } // Create Parts @@ -1001,80 +1004,63 @@ export class Workbench extends Disposable implements IPartService { this.createNotificationsHandlers(); // Add Workbench to DOM - this.workbench.appendTo(this.container); + this.container.appendChild(this.workbench); } private createTitlebarPart(): void { - const titlebarContainer = $(this.workbench).div({ - 'class': ['part', 'titlebar'], - id: Identifiers.TITLEBAR_PART, - role: 'contentinfo' - }); + const titlebarContainer = this.createPart(Identifiers.TITLEBAR_PART, ['part', 'titlebar'], 'contentinfo'); - this.titlebarPart.create(titlebarContainer.getHTMLElement()); + this.titlebarPart.create(titlebarContainer); } private createActivityBarPart(): void { - const activitybarPartContainer = $(this.workbench) - .div({ - 'class': ['part', 'activitybar', this.sideBarPosition === Position.LEFT ? 'left' : 'right'], - id: Identifiers.ACTIVITYBAR_PART, - role: 'navigation' - }); + const activitybarPartContainer = this.createPart(Identifiers.ACTIVITYBAR_PART, ['part', 'activitybar', this.sideBarPosition === Position.LEFT ? 'left' : 'right'], 'navigation'); - this.activitybarPart.create(activitybarPartContainer.getHTMLElement()); + this.activitybarPart.create(activitybarPartContainer); } private createSidebarPart(): void { - const sidebarPartContainer = $(this.workbench) - .div({ - 'class': ['part', 'sidebar', this.sideBarPosition === Position.LEFT ? 'left' : 'right'], - id: Identifiers.SIDEBAR_PART, - role: 'complementary' - }); + const sidebarPartContainer = this.createPart(Identifiers.SIDEBAR_PART, ['part', 'sidebar', this.sideBarPosition === Position.LEFT ? 'left' : 'right'], 'complementary'); - this.sidebarPart.create(sidebarPartContainer.getHTMLElement()); + this.sidebarPart.create(sidebarPartContainer); } private createPanelPart(): void { - const panelPartContainer = $(this.workbench) - .div({ - 'class': ['part', 'panel', this.panelPosition === Position.BOTTOM ? 'bottom' : 'right'], - id: Identifiers.PANEL_PART, - role: 'complementary' - }); + const panelPartContainer = this.createPart(Identifiers.PANEL_PART, ['part', 'panel', this.panelPosition === Position.BOTTOM ? 'bottom' : 'right'], 'complementary'); - this.panelPart.create(panelPartContainer.getHTMLElement()); + this.panelPart.create(panelPartContainer); } private createEditorPart(): void { - const editorContainer = $(this.workbench) - .div({ - 'class': ['part', 'editor'], - id: Identifiers.EDITOR_PART, - role: 'main' - }); + const editorContainer = this.createPart(Identifiers.EDITOR_PART, ['part', 'editor'], 'main'); - this.editorPart.create(editorContainer.getHTMLElement()); + this.editorPart.create(editorContainer); } private createStatusbarPart(): void { - const statusbarContainer = $(this.workbench).div({ - 'class': ['part', 'statusbar'], - id: Identifiers.STATUSBAR_PART, - role: 'contentinfo' - }); + const statusbarContainer = this.createPart(Identifiers.STATUSBAR_PART, ['part', 'statusbar'], 'contentinfo'); - this.statusbarPart.create(statusbarContainer.getHTMLElement()); + this.statusbarPart.create(statusbarContainer); + } + + private createPart(id: string, classes: string[], role: string): HTMLElement { + const part = document.createElement('div'); + classes.forEach(clazz => DOM.addClass(part, clazz)); + part.id = id; + part.setAttribute('role', role); + + this.workbench.appendChild(part); + + return part; } private createNotificationsHandlers(): void { // Notifications Center - this.notificationsCenter = this._register(this.instantiationService.createInstance(NotificationsCenter, this.workbench.getHTMLElement(), this.notificationService.model)); + this.notificationsCenter = this._register(this.instantiationService.createInstance(NotificationsCenter, this.workbench, this.notificationService.model)); // Notifications Toasts - this.notificationsToasts = this._register(this.instantiationService.createInstance(NotificationsToasts, this.workbench.getHTMLElement(), this.notificationService.model)); + this.notificationsToasts = this._register(this.instantiationService.createInstance(NotificationsToasts, this.workbench, this.notificationService.model)); // Notifications Alerts this._register(this.instantiationService.createInstance(NotificationsAlerts, this.notificationService.model)); @@ -1324,9 +1310,9 @@ export class Workbench extends Disposable implements IPartService { // Adjust CSS if (hidden) { - this.workbench.addClass('nosidebar'); + DOM.addClass(this.workbench, 'nosidebar'); } else { - this.workbench.removeClass('nosidebar'); + DOM.removeClass(this.workbench, 'nosidebar'); } // If sidebar becomes hidden, also hide the current active Viewlet if any @@ -1375,9 +1361,9 @@ export class Workbench extends Disposable implements IPartService { // Adjust CSS if (hidden) { - this.workbench.addClass('nopanel'); + DOM.addClass(this.workbench, 'nopanel'); } else { - this.workbench.removeClass('nopanel'); + DOM.removeClass(this.workbench, 'nopanel'); } // If panel part becomes hidden, also hide the current active panel if any From 5ddf33c7d3da6ccc2eb2ae3f6523f9efd376a41a Mon Sep 17 00:00:00 2001 From: Martin Aeschlimann Date: Tue, 7 Aug 2018 12:56:19 +0200 Subject: [PATCH 0542/1276] Reject invalid URI with vscode.openFolder (for #55891) --- src/vs/workbench/api/node/apiCommands.ts | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/vs/workbench/api/node/apiCommands.ts b/src/vs/workbench/api/node/apiCommands.ts index 98eaf7888ca..e423299e951 100644 --- a/src/vs/workbench/api/node/apiCommands.ts +++ b/src/vs/workbench/api/node/apiCommands.ts @@ -48,6 +48,9 @@ export class OpenFolderAPICommand { if (!uri) { return executor.executeCommand('_files.pickFolderAndOpen', forceNewWindow); } + if (!uri.scheme) { + throw new Error(`Invalid URI, schema required: '${uri.toString()}'.`); + } return executor.executeCommand('_files.windowOpen', [uri], forceNewWindow); } From cd3b0bfa48a81679c664f1fc6045f8339a029934 Mon Sep 17 00:00:00 2001 From: Christof Marti Date: Tue, 7 Aug 2018 11:47:54 +0200 Subject: [PATCH 0543/1276] Fix listener lifecycle --- src/vs/workbench/browser/parts/quickinput/quickInput.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vs/workbench/browser/parts/quickinput/quickInput.ts b/src/vs/workbench/browser/parts/quickinput/quickInput.ts index 7e6021ce4a4..6e67c925f40 100644 --- a/src/vs/workbench/browser/parts/quickinput/quickInput.ts +++ b/src/vs/workbench/browser/parts/quickinput/quickInput.ts @@ -182,7 +182,7 @@ class QuickInput implements IQuickInput { if (this.visible) { return; } - this.disposables.push( + this.visibleDisposables.push( this.ui.onDidTriggerButton(button => { if (this.buttons.indexOf(button) !== -1) { this.onDidTriggerButtonEmitter.fire(button); From 756f897e3c4dd6827e8b8af3241cb95dc43873fd Mon Sep 17 00:00:00 2001 From: Christof Marti Date: Tue, 7 Aug 2018 14:46:03 +0200 Subject: [PATCH 0544/1276] Icons (#29096) --- src/vs/platform/quickinput/common/quickInput.ts | 7 +------ .../browser/actions/workspaceCommands.ts | 16 ++++++++++------ .../browser/parts/quickinput/quickInput.ts | 2 +- .../browser/parts/quickinput/quickInputList.ts | 1 + 4 files changed, 13 insertions(+), 13 deletions(-) diff --git a/src/vs/platform/quickinput/common/quickInput.ts b/src/vs/platform/quickinput/common/quickInput.ts index 24d730db9b4..49c079ab126 100644 --- a/src/vs/platform/quickinput/common/quickInput.ts +++ b/src/vs/platform/quickinput/common/quickInput.ts @@ -10,21 +10,16 @@ import { CancellationToken } from 'vs/base/common/cancellation'; import { ResolvedKeybinding } from 'vs/base/common/keyCodes'; import URI from 'vs/base/common/uri'; import { Event } from 'vs/base/common/event'; -import { FileKind } from 'vs/platform/files/common/files'; export interface IQuickPickItem { id?: string; label: string; description?: string; detail?: string; + iconClasses?: string[]; picked?: boolean; } -export interface IFilePickItem extends IQuickPickItem { - resource: URI; - fileKind?: FileKind; -} - export interface IQuickNavigateConfiguration { keybindings: ResolvedKeybinding[]; } diff --git a/src/vs/workbench/browser/actions/workspaceCommands.ts b/src/vs/workbench/browser/actions/workspaceCommands.ts index 268890850d4..955717730e0 100644 --- a/src/vs/workbench/browser/actions/workspaceCommands.ts +++ b/src/vs/workbench/browser/actions/workspaceCommands.ts @@ -23,7 +23,10 @@ import { IEnvironmentService } from 'vs/platform/environment/common/environment' import { ServicesAccessor } from 'vs/platform/instantiation/common/instantiation'; import { isLinux } from 'vs/base/common/platform'; import { IUriDisplayService } from 'vs/platform/uriDisplay/common/uriDisplay'; -import { IQuickInputService, IPickOptions, IFilePickItem } from 'vs/platform/quickinput/common/quickInput'; +import { IQuickInputService, IPickOptions, IQuickPickItem } from 'vs/platform/quickinput/common/quickInput'; +import { getIconClasses } from 'vs/workbench/browser/labels'; +import { IModelService } from 'vs/editor/common/services/modelService'; +import { IModeService } from 'vs/editor/common/services/modeService'; export const ADD_ROOT_FOLDER_COMMAND_ID = 'addRootFolder'; export const ADD_ROOT_FOLDER_LABEL = nls.localize('addFolderToWorkspace', "Add Folder to Workspace..."); @@ -158,10 +161,12 @@ CommandsRegistry.registerCommand({ } }); -CommandsRegistry.registerCommand(PICK_WORKSPACE_FOLDER_COMMAND_ID, function (accessor, args?: [IPickOptions, CancellationToken]) { +CommandsRegistry.registerCommand(PICK_WORKSPACE_FOLDER_COMMAND_ID, function (accessor, args?: [IPickOptions, CancellationToken]) { const quickInputService = accessor.get(IQuickInputService); const uriDisplayService = accessor.get(IUriDisplayService); const contextService = accessor.get(IWorkspaceContextService); + const modelService = accessor.get(IModelService); + const modeService = accessor.get(IModeService); const folders = contextService.getWorkspace().folders; if (!folders.length) { @@ -173,12 +178,11 @@ CommandsRegistry.registerCommand(PICK_WORKSPACE_FOLDER_COMMAND_ID, function (acc label: folder.name, description: uriDisplayService.getLabel(resources.dirname(folder.uri), true), folder, - resource: folder.uri, - fileKind: FileKind.ROOT_FOLDER - } as IFilePickItem; + iconClasses: getIconClasses(modelService, modeService, folder.uri, FileKind.ROOT_FOLDER) + } as IQuickPickItem; }); - let options: IPickOptions; + let options: IPickOptions; if (args) { options = args[0]; } diff --git a/src/vs/workbench/browser/parts/quickinput/quickInput.ts b/src/vs/workbench/browser/parts/quickinput/quickInput.ts index 6e67c925f40..50da9587f5a 100644 --- a/src/vs/workbench/browser/parts/quickinput/quickInput.ts +++ b/src/vs/workbench/browser/parts/quickinput/quickInput.ts @@ -785,7 +785,7 @@ export class QuickInputService extends Component implements IQuickInputService { } const workbench = document.getElementById(this.partService.getWorkbenchElementId()); - const container = dom.append(workbench, $('.quick-input-widget')); + const container = dom.append(workbench, $('.quick-input-widget.show-file-icons')); container.tabIndex = -1; container.style.display = 'none'; diff --git a/src/vs/workbench/browser/parts/quickinput/quickInputList.ts b/src/vs/workbench/browser/parts/quickinput/quickInputList.ts index f4a3a8fdf99..dd5dd3fe3be 100644 --- a/src/vs/workbench/browser/parts/quickinput/quickInputList.ts +++ b/src/vs/workbench/browser/parts/quickinput/quickInputList.ts @@ -121,6 +121,7 @@ class ListElementRenderer implements IRenderer Date: Tue, 7 Aug 2018 14:49:10 +0200 Subject: [PATCH 0545/1276] delay winreg import related to #55840 --- src/vs/workbench/parts/update/electron-browser/update.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vs/workbench/parts/update/electron-browser/update.ts b/src/vs/workbench/parts/update/electron-browser/update.ts index 9aa410943f5..8796a509102 100644 --- a/src/vs/workbench/parts/update/electron-browser/update.ts +++ b/src/vs/workbench/parts/update/electron-browser/update.ts @@ -30,7 +30,6 @@ import { IWindowService } from 'vs/platform/windows/common/windows'; import { ReleaseNotesManager } from './releaseNotesEditor'; import { isWindows } from 'vs/base/common/platform'; import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; -import * as Registry from 'winreg'; let releaseNotesManager: ReleaseNotesManager | undefined = undefined; @@ -213,6 +212,7 @@ export class Win3264BitContribution implements IWorkbenchContribution { async function isUserSetupInstalled(): Promise { const rawUserAppId = process.arch === 'x64' ? product.win32x64UserAppId : product.win32UserAppId; const userAppId = rawUserAppId.replace(/^\{\{/, '{'); + const Registry = await import('winreg'); const key = new Registry({ hive: Registry.HKCU, key: `\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\${userAppId}_is1` From bb05371ae9043f0949a8365f50f8da43900a1813 Mon Sep 17 00:00:00 2001 From: Joao Moreno Date: Tue, 7 Aug 2018 14:55:19 +0200 Subject: [PATCH 0546/1276] show notification earlier related to #55840 --- .../parts/update/electron-browser/update.ts | 107 +++++++++--------- 1 file changed, 53 insertions(+), 54 deletions(-) diff --git a/src/vs/workbench/parts/update/electron-browser/update.ts b/src/vs/workbench/parts/update/electron-browser/update.ts index 8796a509102..39fbedf65b0 100644 --- a/src/vs/workbench/parts/update/electron-browser/update.ts +++ b/src/vs/workbench/parts/update/electron-browser/update.ts @@ -251,6 +251,33 @@ export class WinUserSetupContribution implements IWorkbenchContribution { ) { updateService.onStateChange(this.onUpdateStateChange, this, this.disposables); this.onUpdateStateChange(this.updateService.state); + + const neverShowAgain = new NeverShowAgain(WinUserSetupContribution.KEY_BOTH, this.storageService); + + if (!neverShowAgain.shouldShow()) { + return; + } + + isUserSetupInstalled().then(userSetupIsInstalled => { + if (!userSetupIsInstalled) { + return; + } + + const handle = this.notificationService.prompt( + severity.Warning, + nls.localize('usersetupsystem', "You are running the system-wide installation of {0}, while having the user-wide distribution installed as well. Make sure you're running the {0} version you expect.", product.nameShort), + [ + { label: nls.localize('ok', "OK"), run: () => null }, + { + label: nls.localize('neveragain', "Don't Show Again"), + isSecondary: true, + run: () => { + neverShowAgain.action.run(handle); + neverShowAgain.action.dispose(); + } + }] + ); + }); } private onUpdateStateChange(state: UpdateState): void { @@ -266,63 +293,35 @@ export class WinUserSetupContribution implements IWorkbenchContribution { return; } - isUserSetupInstalled().then(userSetupIsInstalled => { - if (userSetupIsInstalled) { - const neverShowAgain = new NeverShowAgain(WinUserSetupContribution.KEY_BOTH, this.storageService); + const neverShowAgain = new NeverShowAgain(WinUserSetupContribution.KEY, this.storageService); - if (!neverShowAgain.shouldShow()) { - return; - } + if (!neverShowAgain.shouldShow()) { + return; + } - const handle = this.notificationService.prompt( - severity.Warning, - nls.localize('usersetupsystem', "You are running the system-wide installation of {0}, while having the user-wide distribution installed as well. Make sure you're running the {0} version you expect.", product.nameShort), - [ - { - label: nls.localize('ok', "OK"), - run: () => null - }, - { - label: nls.localize('neveragain', "Don't Show Again"), - isSecondary: true, - run: () => { - neverShowAgain.action.run(handle); - neverShowAgain.action.dispose(); - } - }] - ); - } else { - const neverShowAgain = new NeverShowAgain(WinUserSetupContribution.KEY, this.storageService); + const handle = this.notificationService.prompt( + severity.Info, + nls.localize('usersetup', "We recommend switching to our new User Setup distribution of {0} for Windows! Click [here]({1}) to learn more.", product.nameShort, WinUserSetupContribution.READ_MORE), + [ + { + label: nls.localize('downloadnow', "Download"), + run: () => { + const url = product.quality === 'insider' + ? (process.arch === 'ia32' ? WinUserSetupContribution.INSIDER_URL_32BIT : WinUserSetupContribution.INSIDER_URL) + : (process.arch === 'ia32' ? WinUserSetupContribution.STABLE_URL_32BIT : WinUserSetupContribution.STABLE_URL); - if (!neverShowAgain.shouldShow()) { - return; - } - - const handle = this.notificationService.prompt( - severity.Info, - nls.localize('usersetup', "We recommend switching to our new User Setup distribution of {0} for Windows! Click [here]({1}) to learn more.", product.nameShort, WinUserSetupContribution.READ_MORE), - [ - { - label: nls.localize('downloadnow', "Download"), - run: () => { - const url = product.quality === 'insider' - ? (process.arch === 'ia32' ? WinUserSetupContribution.INSIDER_URL_32BIT : WinUserSetupContribution.INSIDER_URL) - : (process.arch === 'ia32' ? WinUserSetupContribution.STABLE_URL_32BIT : WinUserSetupContribution.STABLE_URL); - - return this.openerService.open(URI.parse(url)); - } - }, - { - label: nls.localize('neveragain', "Don't Show Again"), - isSecondary: true, - run: () => { - neverShowAgain.action.run(handle); - neverShowAgain.action.dispose(); - } - }] - ); - } - }); + return this.openerService.open(URI.parse(url)); + } + }, + { + label: nls.localize('neveragain', "Don't Show Again"), + isSecondary: true, + run: () => { + neverShowAgain.action.run(handle); + neverShowAgain.action.dispose(); + } + }] + ); } dispose(): void { From 2260875ab2d511762aa63c40fb064123201453e9 Mon Sep 17 00:00:00 2001 From: Joao Moreno Date: Tue, 7 Aug 2018 06:43:25 -0700 Subject: [PATCH 0547/1276] fix unit tests on windows --- test/electron/renderer.js | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/test/electron/renderer.js b/test/electron/renderer.js index b5d940e58bd..35f970c5c8c 100644 --- a/test/electron/renderer.js +++ b/test/electron/renderer.js @@ -23,6 +23,15 @@ let _tests_glob = '**/test/**/*.test.js'; let loader; let _out; +function uriFromPath(_path) { + var pathName = path.resolve(_path).replace(/\\/g, '/'); + if (pathName.length > 0 && pathName.charAt(0) !== '/') { + pathName = '/' + pathName; + } + + return encodeURI('file://' + pathName); +} + function initLoader(opts) { let outdir = opts.build ? 'out-build' : 'out'; _out = path.join(__dirname, `../../${outdir}`); @@ -33,7 +42,7 @@ function initLoader(opts) { nodeRequire: require, nodeMain: __filename, catchError: true, - baseUrl: `file://${path.posix.join(__dirname, '../../src')}`, + baseUrl: uriFromPath(path.join(__dirname, '../../src')), paths: { 'vs': `../${outdir}/vs`, 'lib': `../${outdir}/lib`, From a8b426471a4a251232c971571b885d5453d4d88d Mon Sep 17 00:00:00 2001 From: Joao Moreno Date: Tue, 7 Aug 2018 16:16:11 +0200 Subject: [PATCH 0548/1276] fixes #55696 --- extensions/git/package.json | 10 +++++++++- extensions/git/package.nls.json | 6 +++++- 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/extensions/git/package.json b/extensions/git/package.json index 371637af774..33a565f0914 100644 --- a/extensions/git/package.json +++ b/extensions/git/package.json @@ -900,6 +900,12 @@ "subFolders", "openEditors" ], + "enumDescriptions": [ + "%config.autoRepositoryDetection.true%", + "%config.autoRepositoryDetection.false%", + "%config.autoRepositoryDetection.subFolders%", + "%config.autoRepositoryDetection.openEditors%" + ], "description": "%config.autoRepositoryDetection%", "default": true }, @@ -912,7 +918,9 @@ "type": "boolean", "description": "%config.autofetch%", "default": false, - "tags": ["usesOnlineServices"] + "tags": [ + "usesOnlineServices" + ] }, "git.confirmSync": { "type": "boolean", diff --git a/extensions/git/package.nls.json b/extensions/git/package.nls.json index 2224d3a718c..bc4c812d75b 100644 --- a/extensions/git/package.nls.json +++ b/extensions/git/package.nls.json @@ -52,7 +52,11 @@ "command.stashPopLatest": "Pop Latest Stash", "config.enabled": "Whether git is enabled.", "config.path": "Path and filename of the git executable, e.g. `C:\\Program Files\\Git\\bin\\git.exe` (Windows).", - "config.autoRepositoryDetection": "Configures when repositories should be automatically detected. `subFolders` will scan for subfolders of the currently opened folder. `openEditors` will scan for parent folders of open files. `true` will scan in all cases. `false` will disable scanning.", + "config.autoRepositoryDetection": "Configures when repositories should be automatically detected.", + "config.autoRepositoryDetection.true": "Scan for both subfolders of the current opened folder and parent folders of open files.", + "config.autoRepositoryDetection.false": "Disable automatic repository scanning.", + "config.autoRepositoryDetection.subFolders": "Scan for subfolders of the currently opened folder.", + "config.autoRepositoryDetection.openEditors": "Scan for parent folders of open files.", "config.autorefresh": "Whether auto refreshing is enabled.", "config.autofetch": "Whether auto fetching is enabled.", "config.enableLongCommitWarning": "Whether long commit messages should be warned about.", From 1a6fabd83f013deb7aad5aaadc16c655909c6171 Mon Sep 17 00:00:00 2001 From: Joao Moreno Date: Tue, 7 Aug 2018 16:29:31 +0200 Subject: [PATCH 0549/1276] fix #55840 --- src/vs/workbench/parts/update/electron-browser/update.ts | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/vs/workbench/parts/update/electron-browser/update.ts b/src/vs/workbench/parts/update/electron-browser/update.ts index 39fbedf65b0..04edd26fd77 100644 --- a/src/vs/workbench/parts/update/electron-browser/update.ts +++ b/src/vs/workbench/parts/update/electron-browser/update.ts @@ -249,9 +249,6 @@ export class WinUserSetupContribution implements IWorkbenchContribution { @IOpenerService private openerService: IOpenerService, @IUpdateService private updateService: IUpdateService ) { - updateService.onStateChange(this.onUpdateStateChange, this, this.disposables); - this.onUpdateStateChange(this.updateService.state); - const neverShowAgain = new NeverShowAgain(WinUserSetupContribution.KEY_BOTH, this.storageService); if (!neverShowAgain.shouldShow()) { @@ -260,6 +257,8 @@ export class WinUserSetupContribution implements IWorkbenchContribution { isUserSetupInstalled().then(userSetupIsInstalled => { if (!userSetupIsInstalled) { + updateService.onStateChange(this.onUpdateStateChange, this, this.disposables); + this.onUpdateStateChange(this.updateService.state); return; } From 34159e797bd695fcfcf12db4bdaa88738faacee6 Mon Sep 17 00:00:00 2001 From: Johannes Rieken Date: Tue, 7 Aug 2018 17:07:01 +0200 Subject: [PATCH 0550/1276] adding webpack.config.js --- extensions/git/.gitignore | 1 + extensions/git/package.json | 12 +- extensions/git/src/main.ts | 2 +- extensions/git/webpack.config.js | 23 + extensions/git/yarn.lock | 2456 +++++++++++++++++++++++++++++- 5 files changed, 2483 insertions(+), 11 deletions(-) create mode 100644 extensions/git/.gitignore create mode 100644 extensions/git/webpack.config.js diff --git a/extensions/git/.gitignore b/extensions/git/.gitignore new file mode 100644 index 00000000000..1521c8b7652 --- /dev/null +++ b/extensions/git/.gitignore @@ -0,0 +1 @@ +dist diff --git a/extensions/git/package.json b/extensions/git/package.json index 371637af774..6d03266a459 100644 --- a/extensions/git/package.json +++ b/extensions/git/package.json @@ -15,7 +15,7 @@ "activationEvents": [ "*" ], - "main": "./out/main", + "main": "./dist/main", "icon": "resources/icons/git.png", "scripts": { "compile": "gulp compile-extension:git", @@ -912,7 +912,9 @@ "type": "boolean", "description": "%config.autofetch%", "default": false, - "tags": ["usesOnlineServices"] + "tags": [ + "usesOnlineServices" + ] }, "git.confirmSync": { "type": "boolean", @@ -1199,6 +1201,8 @@ "@types/mocha": "2.2.43", "@types/node": "7.0.43", "@types/which": "^1.0.28", - "mocha": "^3.2.0" + "mocha": "^3.2.0", + "webpack": "^4.16.5", + "webpack-cli": "^3.1.0" } -} \ No newline at end of file +} diff --git a/extensions/git/src/main.ts b/extensions/git/src/main.ts index 6eae1da2c9d..186dd806118 100644 --- a/extensions/git/src/main.ts +++ b/extensions/git/src/main.ts @@ -77,7 +77,7 @@ export async function activate(context: ExtensionContext): Promise { commands.registerCommand('git.showOutput', () => outputChannel.show()); disposables.push(outputChannel); - const { name, version, aiKey } = require(context.asAbsolutePath('./package.json')) as { name: string, version: string, aiKey: string }; + const { name, version, aiKey } = require('../package.json') as { name: string, version: string, aiKey: string }; const telemetryReporter = new TelemetryReporter(name, version, aiKey); deactivateTasks.push(() => telemetryReporter.dispose()); diff --git a/extensions/git/webpack.config.js b/extensions/git/webpack.config.js new file mode 100644 index 00000000000..175d663dd04 --- /dev/null +++ b/extensions/git/webpack.config.js @@ -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. + *--------------------------------------------------------------------------------------------*/ + +'use strict'; + +const path = require('path'); + +module.exports = { + mode: 'production', + target: 'node', + entry: './out/main.js', + output: { + filename: 'main.js', + path: path.resolve(__dirname, 'dist'), + libraryTarget: "commonjs" + }, + externals: { + 'vscode': 'commonjs vscode', + }, + devtool: 'source-map' +}; diff --git a/extensions/git/yarn.lock b/extensions/git/yarn.lock index 497e26b21d6..e66f5067101 100644 --- a/extensions/git/yarn.lock +++ b/extensions/git/yarn.lock @@ -30,6 +30,194 @@ version "1.0.28" resolved "https://registry.yarnpkg.com/@types/which/-/which-1.0.28.tgz#016e387629b8817bed653fe32eab5d11279c8df6" +"@webassemblyjs/ast@1.5.13": + version "1.5.13" + resolved "https://registry.yarnpkg.com/@webassemblyjs/ast/-/ast-1.5.13.tgz#81155a570bd5803a30ec31436bc2c9c0ede38f25" + dependencies: + "@webassemblyjs/helper-module-context" "1.5.13" + "@webassemblyjs/helper-wasm-bytecode" "1.5.13" + "@webassemblyjs/wast-parser" "1.5.13" + debug "^3.1.0" + mamacro "^0.0.3" + +"@webassemblyjs/floating-point-hex-parser@1.5.13": + version "1.5.13" + resolved "https://registry.yarnpkg.com/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.5.13.tgz#29ce0baa97411f70e8cce68ce9c0f9d819a4e298" + +"@webassemblyjs/helper-api-error@1.5.13": + version "1.5.13" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-api-error/-/helper-api-error-1.5.13.tgz#e49b051d67ee19a56e29b9aa8bd949b5b4442a59" + +"@webassemblyjs/helper-buffer@1.5.13": + version "1.5.13" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-buffer/-/helper-buffer-1.5.13.tgz#873bb0a1b46449231137c1262ddfd05695195a1e" + dependencies: + debug "^3.1.0" + +"@webassemblyjs/helper-code-frame@1.5.13": + version "1.5.13" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-code-frame/-/helper-code-frame-1.5.13.tgz#1bd2181b6a0be14e004f0fe9f5a660d265362b58" + dependencies: + "@webassemblyjs/wast-printer" "1.5.13" + +"@webassemblyjs/helper-fsm@1.5.13": + version "1.5.13" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-fsm/-/helper-fsm-1.5.13.tgz#cdf3d9d33005d543a5c5e5adaabf679ffa8db924" + +"@webassemblyjs/helper-module-context@1.5.13": + version "1.5.13" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-module-context/-/helper-module-context-1.5.13.tgz#dc29ddfb51ed657655286f94a5d72d8a489147c5" + dependencies: + debug "^3.1.0" + mamacro "^0.0.3" + +"@webassemblyjs/helper-wasm-bytecode@1.5.13": + version "1.5.13" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.5.13.tgz#03245817f0a762382e61733146f5773def15a747" + +"@webassemblyjs/helper-wasm-section@1.5.13": + version "1.5.13" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.5.13.tgz#efc76f44a10d3073b584b43c38a179df173d5c7d" + dependencies: + "@webassemblyjs/ast" "1.5.13" + "@webassemblyjs/helper-buffer" "1.5.13" + "@webassemblyjs/helper-wasm-bytecode" "1.5.13" + "@webassemblyjs/wasm-gen" "1.5.13" + debug "^3.1.0" + +"@webassemblyjs/ieee754@1.5.13": + version "1.5.13" + resolved "https://registry.yarnpkg.com/@webassemblyjs/ieee754/-/ieee754-1.5.13.tgz#573e97c8c12e4eebb316ca5fde0203ddd90b0364" + dependencies: + ieee754 "^1.1.11" + +"@webassemblyjs/leb128@1.5.13": + version "1.5.13" + resolved "https://registry.yarnpkg.com/@webassemblyjs/leb128/-/leb128-1.5.13.tgz#ab52ebab9cec283c1c1897ac1da833a04a3f4cee" + dependencies: + long "4.0.0" + +"@webassemblyjs/utf8@1.5.13": + version "1.5.13" + resolved "https://registry.yarnpkg.com/@webassemblyjs/utf8/-/utf8-1.5.13.tgz#6b53d2cd861cf94fa99c1f12779dde692fbc2469" + +"@webassemblyjs/wasm-edit@1.5.13": + version "1.5.13" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-edit/-/wasm-edit-1.5.13.tgz#c9cef5664c245cf11b3b3a73110c9155831724a8" + dependencies: + "@webassemblyjs/ast" "1.5.13" + "@webassemblyjs/helper-buffer" "1.5.13" + "@webassemblyjs/helper-wasm-bytecode" "1.5.13" + "@webassemblyjs/helper-wasm-section" "1.5.13" + "@webassemblyjs/wasm-gen" "1.5.13" + "@webassemblyjs/wasm-opt" "1.5.13" + "@webassemblyjs/wasm-parser" "1.5.13" + "@webassemblyjs/wast-printer" "1.5.13" + debug "^3.1.0" + +"@webassemblyjs/wasm-gen@1.5.13": + version "1.5.13" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-gen/-/wasm-gen-1.5.13.tgz#8e6ea113c4b432fa66540189e79b16d7a140700e" + dependencies: + "@webassemblyjs/ast" "1.5.13" + "@webassemblyjs/helper-wasm-bytecode" "1.5.13" + "@webassemblyjs/ieee754" "1.5.13" + "@webassemblyjs/leb128" "1.5.13" + "@webassemblyjs/utf8" "1.5.13" + +"@webassemblyjs/wasm-opt@1.5.13": + version "1.5.13" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-opt/-/wasm-opt-1.5.13.tgz#147aad7717a7ee4211c36b21a5f4c30dddf33138" + dependencies: + "@webassemblyjs/ast" "1.5.13" + "@webassemblyjs/helper-buffer" "1.5.13" + "@webassemblyjs/wasm-gen" "1.5.13" + "@webassemblyjs/wasm-parser" "1.5.13" + debug "^3.1.0" + +"@webassemblyjs/wasm-parser@1.5.13": + version "1.5.13" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-parser/-/wasm-parser-1.5.13.tgz#6f46516c5bb23904fbdf58009233c2dd8a54c72f" + dependencies: + "@webassemblyjs/ast" "1.5.13" + "@webassemblyjs/helper-api-error" "1.5.13" + "@webassemblyjs/helper-wasm-bytecode" "1.5.13" + "@webassemblyjs/ieee754" "1.5.13" + "@webassemblyjs/leb128" "1.5.13" + "@webassemblyjs/utf8" "1.5.13" + +"@webassemblyjs/wast-parser@1.5.13": + version "1.5.13" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wast-parser/-/wast-parser-1.5.13.tgz#5727a705d397ae6a3ae99d7f5460acf2ec646eea" + dependencies: + "@webassemblyjs/ast" "1.5.13" + "@webassemblyjs/floating-point-hex-parser" "1.5.13" + "@webassemblyjs/helper-api-error" "1.5.13" + "@webassemblyjs/helper-code-frame" "1.5.13" + "@webassemblyjs/helper-fsm" "1.5.13" + long "^3.2.0" + mamacro "^0.0.3" + +"@webassemblyjs/wast-printer@1.5.13": + version "1.5.13" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wast-printer/-/wast-printer-1.5.13.tgz#bb34d528c14b4f579e7ec11e793ec50ad7cd7c95" + dependencies: + "@webassemblyjs/ast" "1.5.13" + "@webassemblyjs/wast-parser" "1.5.13" + long "^3.2.0" + +abbrev@1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/abbrev/-/abbrev-1.1.1.tgz#f8f2c887ad10bf67f634f005b6987fed3179aac8" + +acorn-dynamic-import@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/acorn-dynamic-import/-/acorn-dynamic-import-3.0.0.tgz#901ceee4c7faaef7e07ad2a47e890675da50a278" + dependencies: + acorn "^5.0.0" + +acorn@^5.0.0, acorn@^5.6.2: + version "5.7.1" + resolved "https://registry.yarnpkg.com/acorn/-/acorn-5.7.1.tgz#f095829297706a7c9776958c0afc8930a9b9d9d8" + +ajv-keywords@^3.1.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/ajv-keywords/-/ajv-keywords-3.2.0.tgz#e86b819c602cf8821ad637413698f1dec021847a" + +ajv@^6.1.0: + version "6.5.2" + resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.5.2.tgz#678495f9b82f7cca6be248dd92f59bff5e1f4360" + dependencies: + fast-deep-equal "^2.0.1" + fast-json-stable-stringify "^2.0.0" + json-schema-traverse "^0.4.1" + uri-js "^4.2.1" + +ansi-escapes@^3.0.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/ansi-escapes/-/ansi-escapes-3.1.0.tgz#f73207bb81207d75fd6c83f125af26eea378ca30" + +ansi-regex@^2.0.0: + version "2.1.1" + resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-2.1.1.tgz#c3b33ab5ee360d86e0e628f0468ae7ef27d654df" + +ansi-regex@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-3.0.0.tgz#ed0317c322064f79466c02966bddb605ab37d998" + +ansi-styles@^3.2.1: + version "3.2.1" + resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-3.2.1.tgz#41fbb20243e50b12be0f04b8dedbf07520ce841d" + dependencies: + color-convert "^1.9.0" + +anymatch@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-2.0.0.tgz#bcb24b4f37934d9aa7ac17b4adaf89e7c76ef2eb" + dependencies: + micromatch "^3.1.4" + normalize-path "^2.1.1" + applicationinsights@1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/applicationinsights/-/applicationinsights-1.0.1.tgz#53446b830fe8d5d619eee2a278b31d3d25030927" @@ -38,10 +226,95 @@ applicationinsights@1.0.1: diagnostic-channel-publishers "0.2.1" zone.js "0.7.6" +aproba@^1.0.3, aproba@^1.1.1: + version "1.2.0" + resolved "https://registry.yarnpkg.com/aproba/-/aproba-1.2.0.tgz#6802e6264efd18c790a1b0d517f0f2627bf2c94a" + +are-we-there-yet@~1.1.2: + version "1.1.5" + resolved "https://registry.yarnpkg.com/are-we-there-yet/-/are-we-there-yet-1.1.5.tgz#4b35c2944f062a8bfcda66410760350fe9ddfc21" + dependencies: + delegates "^1.0.0" + readable-stream "^2.0.6" + +arr-diff@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/arr-diff/-/arr-diff-4.0.0.tgz#d6461074febfec71e7e15235761a329a5dc7c520" + +arr-flatten@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/arr-flatten/-/arr-flatten-1.1.0.tgz#36048bbff4e7b47e136644316c99669ea5ae91f1" + +arr-union@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/arr-union/-/arr-union-3.1.0.tgz#e39b09aea9def866a8f206e288af63919bae39c4" + +array-unique@^0.3.2: + version "0.3.2" + resolved "https://registry.yarnpkg.com/array-unique/-/array-unique-0.3.2.tgz#a894b75d4bc4f6cd679ef3244a9fd8f46ae2d428" + +asn1.js@^4.0.0: + version "4.10.1" + resolved "https://registry.yarnpkg.com/asn1.js/-/asn1.js-4.10.1.tgz#b9c2bf5805f1e64aadeed6df3a2bfafb5a73f5a0" + dependencies: + bn.js "^4.0.0" + inherits "^2.0.1" + minimalistic-assert "^1.0.0" + +assert@^1.1.1: + version "1.4.1" + resolved "https://registry.yarnpkg.com/assert/-/assert-1.4.1.tgz#99912d591836b5a6f5b345c0f07eefc08fc65d91" + dependencies: + util "0.10.3" + +assign-symbols@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/assign-symbols/-/assign-symbols-1.0.0.tgz#59667f41fadd4f20ccbc2bb96b8d4f7f78ec0367" + +async-each@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/async-each/-/async-each-1.0.1.tgz#19d386a1d9edc6e7c1c85d388aedbcc56d33602d" + +atob@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/atob/-/atob-2.1.1.tgz#ae2d5a729477f289d60dd7f96a6314a22dd6c22a" + balanced-match@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.0.tgz#89b4d199ab2bee49de164ea02b89ce462d71b767" +base64-js@^1.0.2: + version "1.3.0" + resolved "https://registry.yarnpkg.com/base64-js/-/base64-js-1.3.0.tgz#cab1e6118f051095e58b5281aea8c1cd22bfc0e3" + +base@^0.11.1: + version "0.11.2" + resolved "https://registry.yarnpkg.com/base/-/base-0.11.2.tgz#7bde5ced145b6d551a90db87f83c558b4eb48a8f" + dependencies: + cache-base "^1.0.1" + class-utils "^0.3.5" + component-emitter "^1.2.1" + define-property "^1.0.0" + isobject "^3.0.1" + mixin-deep "^1.2.0" + pascalcase "^0.1.1" + +big.js@^3.1.3: + version "3.2.0" + resolved "https://registry.yarnpkg.com/big.js/-/big.js-3.2.0.tgz#a5fc298b81b9e0dca2e458824784b65c52ba588e" + +binary-extensions@^1.0.0: + version "1.11.0" + resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-1.11.0.tgz#46aa1751fb6a2f93ee5e689bb1087d4b14c6c205" + +bluebird@^3.5.1: + version "3.5.1" + resolved "https://registry.yarnpkg.com/bluebird/-/bluebird-3.5.1.tgz#d9551f9de98f1fcda1e683d17ee91a0602ee2eb9" + +bn.js@^4.0.0, bn.js@^4.1.0, bn.js@^4.1.1, bn.js@^4.4.0: + version "4.11.8" + resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-4.11.8.tgz#2cde09eb5ee341f484746bb0309b3253b1b1442f" + brace-expansion@^1.1.7: version "1.1.8" resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.8.tgz#c07b211c7c952ec1f8efd51a77ef0d1d3990a292" @@ -49,30 +322,438 @@ brace-expansion@^1.1.7: balanced-match "^1.0.0" concat-map "0.0.1" +braces@^2.3.0, braces@^2.3.1: + version "2.3.2" + resolved "https://registry.yarnpkg.com/braces/-/braces-2.3.2.tgz#5979fd3f14cd531565e5fa2df1abfff1dfaee729" + dependencies: + arr-flatten "^1.1.0" + array-unique "^0.3.2" + extend-shallow "^2.0.1" + fill-range "^4.0.0" + isobject "^3.0.1" + repeat-element "^1.1.2" + snapdragon "^0.8.1" + snapdragon-node "^2.0.1" + split-string "^3.0.2" + to-regex "^3.0.1" + +brorand@^1.0.1: + version "1.1.0" + resolved "https://registry.yarnpkg.com/brorand/-/brorand-1.1.0.tgz#12c25efe40a45e3c323eb8675a0a0ce57b22371f" + browser-stdout@1.3.0: version "1.3.0" resolved "https://registry.yarnpkg.com/browser-stdout/-/browser-stdout-1.3.0.tgz#f351d32969d32fa5d7a5567154263d928ae3bd1f" +browserify-aes@^1.0.0, browserify-aes@^1.0.4: + version "1.2.0" + resolved "https://registry.yarnpkg.com/browserify-aes/-/browserify-aes-1.2.0.tgz#326734642f403dabc3003209853bb70ad428ef48" + dependencies: + buffer-xor "^1.0.3" + cipher-base "^1.0.0" + create-hash "^1.1.0" + evp_bytestokey "^1.0.3" + inherits "^2.0.1" + safe-buffer "^5.0.1" + +browserify-cipher@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/browserify-cipher/-/browserify-cipher-1.0.1.tgz#8d6474c1b870bfdabcd3bcfcc1934a10e94f15f0" + dependencies: + browserify-aes "^1.0.4" + browserify-des "^1.0.0" + evp_bytestokey "^1.0.0" + +browserify-des@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/browserify-des/-/browserify-des-1.0.2.tgz#3af4f1f59839403572f1c66204375f7a7f703e9c" + dependencies: + cipher-base "^1.0.1" + des.js "^1.0.0" + inherits "^2.0.1" + safe-buffer "^5.1.2" + +browserify-rsa@^4.0.0: + version "4.0.1" + resolved "https://registry.yarnpkg.com/browserify-rsa/-/browserify-rsa-4.0.1.tgz#21e0abfaf6f2029cf2fafb133567a701d4135524" + dependencies: + bn.js "^4.1.0" + randombytes "^2.0.1" + +browserify-sign@^4.0.0: + version "4.0.4" + resolved "https://registry.yarnpkg.com/browserify-sign/-/browserify-sign-4.0.4.tgz#aa4eb68e5d7b658baa6bf6a57e630cbd7a93d298" + dependencies: + bn.js "^4.1.1" + browserify-rsa "^4.0.0" + create-hash "^1.1.0" + create-hmac "^1.1.2" + elliptic "^6.0.0" + inherits "^2.0.1" + parse-asn1 "^5.0.0" + +browserify-zlib@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/browserify-zlib/-/browserify-zlib-0.2.0.tgz#2869459d9aa3be245fe8fe2ca1f46e2e7f54d73f" + dependencies: + pako "~1.0.5" + +buffer-from@^1.0.0: + version "1.1.1" + resolved "https://registry.yarnpkg.com/buffer-from/-/buffer-from-1.1.1.tgz#32713bc028f75c02fdb710d7c7bcec1f2c6070ef" + +buffer-xor@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/buffer-xor/-/buffer-xor-1.0.3.tgz#26e61ed1422fb70dd42e6e36729ed51d855fe8d9" + +buffer@^4.3.0: + version "4.9.1" + resolved "https://registry.yarnpkg.com/buffer/-/buffer-4.9.1.tgz#6d1bb601b07a4efced97094132093027c95bc298" + dependencies: + base64-js "^1.0.2" + ieee754 "^1.1.4" + isarray "^1.0.0" + +builtin-status-codes@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/builtin-status-codes/-/builtin-status-codes-3.0.0.tgz#85982878e21b98e1c66425e03d0174788f569ee8" + byline@^5.0.0: version "5.0.0" resolved "https://registry.yarnpkg.com/byline/-/byline-5.0.0.tgz#741c5216468eadc457b03410118ad77de8c1ddb1" +cacache@^10.0.4: + version "10.0.4" + resolved "https://registry.yarnpkg.com/cacache/-/cacache-10.0.4.tgz#6452367999eff9d4188aefd9a14e9d7c6a263460" + dependencies: + bluebird "^3.5.1" + chownr "^1.0.1" + glob "^7.1.2" + graceful-fs "^4.1.11" + lru-cache "^4.1.1" + mississippi "^2.0.0" + mkdirp "^0.5.1" + move-concurrently "^1.0.1" + promise-inflight "^1.0.1" + rimraf "^2.6.2" + ssri "^5.2.4" + unique-filename "^1.1.0" + y18n "^4.0.0" + +cache-base@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/cache-base/-/cache-base-1.0.1.tgz#0a7f46416831c8b662ee36fe4e7c59d76f666ab2" + dependencies: + collection-visit "^1.0.0" + component-emitter "^1.2.1" + get-value "^2.0.6" + has-value "^1.0.0" + isobject "^3.0.1" + set-value "^2.0.0" + to-object-path "^0.3.0" + union-value "^1.0.0" + unset-value "^1.0.0" + +camelcase@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-4.1.0.tgz#d545635be1e33c542649c69173e5de6acfae34dd" + +chalk@^2.0.0, chalk@^2.4.1: + version "2.4.1" + resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.1.tgz#18c49ab16a037b6eb0152cc83e3471338215b66e" + dependencies: + ansi-styles "^3.2.1" + escape-string-regexp "^1.0.5" + supports-color "^5.3.0" + +chardet@^0.5.0: + version "0.5.0" + resolved "https://registry.yarnpkg.com/chardet/-/chardet-0.5.0.tgz#fe3ac73c00c3d865ffcc02a0682e2c20b6a06029" + +chokidar@^2.0.2: + version "2.0.4" + resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-2.0.4.tgz#356ff4e2b0e8e43e322d18a372460bbcf3accd26" + dependencies: + anymatch "^2.0.0" + async-each "^1.0.0" + braces "^2.3.0" + glob-parent "^3.1.0" + inherits "^2.0.1" + is-binary-path "^1.0.0" + is-glob "^4.0.0" + lodash.debounce "^4.0.8" + normalize-path "^2.1.1" + path-is-absolute "^1.0.0" + readdirp "^2.0.0" + upath "^1.0.5" + optionalDependencies: + fsevents "^1.2.2" + +chownr@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/chownr/-/chownr-1.0.1.tgz#e2a75042a9551908bebd25b8523d5f9769d79181" + +chrome-trace-event@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/chrome-trace-event/-/chrome-trace-event-1.0.0.tgz#45a91bd2c20c9411f0963b5aaeb9a1b95e09cc48" + dependencies: + tslib "^1.9.0" + +cipher-base@^1.0.0, cipher-base@^1.0.1, cipher-base@^1.0.3: + version "1.0.4" + resolved "https://registry.yarnpkg.com/cipher-base/-/cipher-base-1.0.4.tgz#8760e4ecc272f4c363532f926d874aae2c1397de" + dependencies: + inherits "^2.0.1" + safe-buffer "^5.0.1" + +class-utils@^0.3.5: + version "0.3.6" + resolved "https://registry.yarnpkg.com/class-utils/-/class-utils-0.3.6.tgz#f93369ae8b9a7ce02fd41faad0ca83033190c463" + dependencies: + arr-union "^3.1.0" + define-property "^0.2.5" + isobject "^3.0.0" + static-extend "^0.1.1" + +cli-cursor@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/cli-cursor/-/cli-cursor-2.1.0.tgz#b35dac376479facc3e94747d41d0d0f5238ffcb5" + dependencies: + restore-cursor "^2.0.0" + +cli-width@^2.0.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/cli-width/-/cli-width-2.2.0.tgz#ff19ede8a9a5e579324147b0c11f0fbcbabed639" + +cliui@^4.0.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/cliui/-/cliui-4.1.0.tgz#348422dbe82d800b3022eef4f6ac10bf2e4d1b49" + dependencies: + string-width "^2.1.1" + strip-ansi "^4.0.0" + wrap-ansi "^2.0.0" + +code-point-at@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/code-point-at/-/code-point-at-1.1.0.tgz#0d070b4d043a5bea33a2f1a40e2edb3d9a4ccf77" + +collection-visit@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/collection-visit/-/collection-visit-1.0.0.tgz#4bc0373c164bc3291b4d368c829cf1a80a59dca0" + dependencies: + map-visit "^1.0.0" + object-visit "^1.0.0" + +color-convert@^1.9.0: + version "1.9.2" + resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-1.9.2.tgz#49881b8fba67df12a96bdf3f56c0aab9e7913147" + dependencies: + color-name "1.1.1" + +color-name@1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.1.tgz#4b1415304cf50028ea81643643bd82ea05803689" + commander@2.9.0: version "2.9.0" resolved "https://registry.yarnpkg.com/commander/-/commander-2.9.0.tgz#9c99094176e12240cb22d6c5146098400fe0f7d4" dependencies: graceful-readlink ">= 1.0.0" +commander@~2.13.0: + version "2.13.0" + resolved "https://registry.yarnpkg.com/commander/-/commander-2.13.0.tgz#6964bca67685df7c1f1430c584f07d7597885b9c" + +commondir@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/commondir/-/commondir-1.0.1.tgz#ddd800da0c66127393cca5950ea968a3aaf1253b" + +component-emitter@^1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/component-emitter/-/component-emitter-1.2.1.tgz#137918d6d78283f7df7a6b7c5a63e140e69425e6" + concat-map@0.0.1: version "0.0.1" resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" +concat-stream@^1.5.0: + version "1.6.2" + resolved "https://registry.yarnpkg.com/concat-stream/-/concat-stream-1.6.2.tgz#904bdf194cd3122fc675c77fc4ac3d4ff0fd1a34" + dependencies: + buffer-from "^1.0.0" + inherits "^2.0.3" + readable-stream "^2.2.2" + typedarray "^0.0.6" + +console-browserify@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/console-browserify/-/console-browserify-1.1.0.tgz#f0241c45730a9fc6323b206dbf38edc741d0bb10" + dependencies: + date-now "^0.1.4" + +console-control-strings@^1.0.0, console-control-strings@~1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/console-control-strings/-/console-control-strings-1.1.0.tgz#3d7cf4464db6446ea644bf4b39507f9851008e8e" + +constants-browserify@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/constants-browserify/-/constants-browserify-1.0.0.tgz#c20b96d8c617748aaf1c16021760cd27fcb8cb75" + +copy-concurrently@^1.0.0: + version "1.0.5" + resolved "https://registry.yarnpkg.com/copy-concurrently/-/copy-concurrently-1.0.5.tgz#92297398cae34937fcafd6ec8139c18051f0b5e0" + dependencies: + aproba "^1.1.1" + fs-write-stream-atomic "^1.0.8" + iferr "^0.1.5" + mkdirp "^0.5.1" + rimraf "^2.5.4" + run-queue "^1.0.0" + +copy-descriptor@^0.1.0: + version "0.1.1" + resolved "https://registry.yarnpkg.com/copy-descriptor/-/copy-descriptor-0.1.1.tgz#676f6eb3c39997c2ee1ac3a924fd6124748f578d" + +core-util-is@~1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7" + +create-ecdh@^4.0.0: + version "4.0.3" + resolved "https://registry.yarnpkg.com/create-ecdh/-/create-ecdh-4.0.3.tgz#c9111b6f33045c4697f144787f9254cdc77c45ff" + dependencies: + bn.js "^4.1.0" + elliptic "^6.0.0" + +create-hash@^1.1.0, create-hash@^1.1.2: + version "1.2.0" + resolved "https://registry.yarnpkg.com/create-hash/-/create-hash-1.2.0.tgz#889078af11a63756bcfb59bd221996be3a9ef196" + dependencies: + cipher-base "^1.0.1" + inherits "^2.0.1" + md5.js "^1.3.4" + ripemd160 "^2.0.1" + sha.js "^2.4.0" + +create-hmac@^1.1.0, create-hmac@^1.1.2, create-hmac@^1.1.4: + version "1.1.7" + resolved "https://registry.yarnpkg.com/create-hmac/-/create-hmac-1.1.7.tgz#69170c78b3ab957147b2b8b04572e47ead2243ff" + dependencies: + cipher-base "^1.0.3" + create-hash "^1.1.0" + inherits "^2.0.1" + ripemd160 "^2.0.0" + safe-buffer "^5.0.1" + sha.js "^2.4.8" + +cross-spawn@^5.0.1: + version "5.1.0" + resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-5.1.0.tgz#e8bd0efee58fcff6f8f94510a0a554bbfa235449" + dependencies: + lru-cache "^4.0.1" + shebang-command "^1.2.0" + which "^1.2.9" + +cross-spawn@^6.0.5: + version "6.0.5" + resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-6.0.5.tgz#4a5ec7c64dfae22c3a14124dbacdee846d80cbc4" + dependencies: + nice-try "^1.0.4" + path-key "^2.0.1" + semver "^5.5.0" + shebang-command "^1.2.0" + which "^1.2.9" + +crypto-browserify@^3.11.0: + version "3.12.0" + resolved "https://registry.yarnpkg.com/crypto-browserify/-/crypto-browserify-3.12.0.tgz#396cf9f3137f03e4b8e532c58f698254e00f80ec" + dependencies: + browserify-cipher "^1.0.0" + browserify-sign "^4.0.0" + create-ecdh "^4.0.0" + create-hash "^1.1.0" + create-hmac "^1.1.0" + diffie-hellman "^5.0.0" + inherits "^2.0.1" + pbkdf2 "^3.0.3" + public-encrypt "^4.0.0" + randombytes "^2.0.0" + randomfill "^1.0.3" + +cyclist@~0.2.2: + version "0.2.2" + resolved "https://registry.yarnpkg.com/cyclist/-/cyclist-0.2.2.tgz#1b33792e11e914a2fd6d6ed6447464444e5fa640" + +date-now@^0.1.4: + version "0.1.4" + resolved "https://registry.yarnpkg.com/date-now/-/date-now-0.1.4.tgz#eaf439fd4d4848ad74e5cc7dbef200672b9e345b" + debug@2.6.8: version "2.6.8" resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.8.tgz#e731531ca2ede27d188222427da17821d68ff4fc" dependencies: ms "2.0.0" +debug@^2.1.2, debug@^2.2.0, debug@^2.3.3: + version "2.6.9" + resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f" + dependencies: + ms "2.0.0" + +debug@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/debug/-/debug-3.1.0.tgz#5bb5a0672628b64149566ba16819e61518c67261" + dependencies: + ms "2.0.0" + +decamelize@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-2.0.0.tgz#656d7bbc8094c4c788ea53c5840908c9c7d063c7" + dependencies: + xregexp "4.0.0" + +decode-uri-component@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/decode-uri-component/-/decode-uri-component-0.2.0.tgz#eb3913333458775cb84cd1a1fae062106bb87545" + +deep-extend@^0.6.0: + version "0.6.0" + resolved "https://registry.yarnpkg.com/deep-extend/-/deep-extend-0.6.0.tgz#c4fa7c95404a17a9c3e8ca7e1537312b736330ac" + +define-property@^0.2.5: + version "0.2.5" + resolved "https://registry.yarnpkg.com/define-property/-/define-property-0.2.5.tgz#c35b1ef918ec3c990f9a5bc57be04aacec5c8116" + dependencies: + is-descriptor "^0.1.0" + +define-property@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/define-property/-/define-property-1.0.0.tgz#769ebaaf3f4a63aad3af9e8d304c9bbe79bfb0e6" + dependencies: + is-descriptor "^1.0.0" + +define-property@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/define-property/-/define-property-2.0.2.tgz#d459689e8d654ba77e02a817f8710d702cb16e9d" + dependencies: + is-descriptor "^1.0.2" + isobject "^3.0.1" + +delegates@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/delegates/-/delegates-1.0.0.tgz#84c6e159b81904fdca59a0ef44cd870d31250f9a" + +des.js@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/des.js/-/des.js-1.0.0.tgz#c074d2e2aa6a8a9a07dbd61f9a15c2cd83ec8ecc" + dependencies: + inherits "^2.0.1" + minimalistic-assert "^1.0.0" + +detect-libc@^1.0.2: + version "1.0.3" + resolved "https://registry.yarnpkg.com/detect-libc/-/detect-libc-1.0.3.tgz#fa137c4bd698edf55cd5cd02ac559f91a4c4ba9b" + diagnostic-channel-publishers@0.2.1: version "0.2.1" resolved "https://registry.yarnpkg.com/diagnostic-channel-publishers/-/diagnostic-channel-publishers-0.2.1.tgz#8e2d607a8b6d79fe880b548bc58cc6beb288c4f3" @@ -87,18 +768,282 @@ diff@3.2.0: version "3.2.0" resolved "https://registry.yarnpkg.com/diff/-/diff-3.2.0.tgz#c9ce393a4b7cbd0b058a725c93df299027868ff9" -escape-string-regexp@1.0.5: +diffie-hellman@^5.0.0: + version "5.0.3" + resolved "https://registry.yarnpkg.com/diffie-hellman/-/diffie-hellman-5.0.3.tgz#40e8ee98f55a2149607146921c63e1ae5f3d2875" + dependencies: + bn.js "^4.1.0" + miller-rabin "^4.0.0" + randombytes "^2.0.0" + +domain-browser@^1.1.1: + version "1.2.0" + resolved "https://registry.yarnpkg.com/domain-browser/-/domain-browser-1.2.0.tgz#3d31f50191a6749dd1375a7f522e823d42e54eda" + +duplexify@^3.4.2, duplexify@^3.6.0: + version "3.6.0" + resolved "https://registry.yarnpkg.com/duplexify/-/duplexify-3.6.0.tgz#592903f5d80b38d037220541264d69a198fb3410" + dependencies: + end-of-stream "^1.0.0" + inherits "^2.0.1" + readable-stream "^2.0.0" + stream-shift "^1.0.0" + +elliptic@^6.0.0: + version "6.4.0" + resolved "https://registry.yarnpkg.com/elliptic/-/elliptic-6.4.0.tgz#cac9af8762c85836187003c8dfe193e5e2eae5df" + dependencies: + bn.js "^4.4.0" + brorand "^1.0.1" + hash.js "^1.0.0" + hmac-drbg "^1.0.0" + inherits "^2.0.1" + minimalistic-assert "^1.0.0" + minimalistic-crypto-utils "^1.0.0" + +emojis-list@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/emojis-list/-/emojis-list-2.1.0.tgz#4daa4d9db00f9819880c79fa457ae5b09a1fd389" + +end-of-stream@^1.0.0, end-of-stream@^1.1.0: + version "1.4.1" + resolved "https://registry.yarnpkg.com/end-of-stream/-/end-of-stream-1.4.1.tgz#ed29634d19baba463b6ce6b80a37213eab71ec43" + dependencies: + once "^1.4.0" + +enhanced-resolve@^4.0.0, enhanced-resolve@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/enhanced-resolve/-/enhanced-resolve-4.1.0.tgz#41c7e0bfdfe74ac1ffe1e57ad6a5c6c9f3742a7f" + dependencies: + graceful-fs "^4.1.2" + memory-fs "^0.4.0" + tapable "^1.0.0" + +errno@^0.1.3, errno@~0.1.7: + version "0.1.7" + resolved "https://registry.yarnpkg.com/errno/-/errno-0.1.7.tgz#4684d71779ad39af177e3f007996f7c67c852618" + dependencies: + prr "~1.0.1" + +escape-string-regexp@1.0.5, escape-string-regexp@^1.0.5: version "1.0.5" resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4" +eslint-scope@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-4.0.0.tgz#50bf3071e9338bcdc43331794a0cb533f0136172" + dependencies: + esrecurse "^4.1.0" + estraverse "^4.1.1" + +esrecurse@^4.1.0: + version "4.2.1" + resolved "https://registry.yarnpkg.com/esrecurse/-/esrecurse-4.2.1.tgz#007a3b9fdbc2b3bb87e4879ea19c92fdbd3942cf" + dependencies: + estraverse "^4.1.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" + +events@^1.0.0: + version "1.1.1" + resolved "https://registry.yarnpkg.com/events/-/events-1.1.1.tgz#9ebdb7635ad099c70dcc4c2a1f5004288e8bd924" + +evp_bytestokey@^1.0.0, evp_bytestokey@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/evp_bytestokey/-/evp_bytestokey-1.0.3.tgz#7fcbdb198dc71959432efe13842684e0525acb02" + dependencies: + md5.js "^1.3.4" + safe-buffer "^5.1.1" + +execa@^0.7.0: + version "0.7.0" + resolved "https://registry.yarnpkg.com/execa/-/execa-0.7.0.tgz#944becd34cc41ee32a63a9faf27ad5a65fc59777" + dependencies: + cross-spawn "^5.0.1" + get-stream "^3.0.0" + is-stream "^1.1.0" + npm-run-path "^2.0.0" + p-finally "^1.0.0" + signal-exit "^3.0.0" + strip-eof "^1.0.0" + +expand-brackets@^2.1.4: + version "2.1.4" + resolved "https://registry.yarnpkg.com/expand-brackets/-/expand-brackets-2.1.4.tgz#b77735e315ce30f6b6eff0f83b04151a22449622" + dependencies: + debug "^2.3.3" + define-property "^0.2.5" + extend-shallow "^2.0.1" + posix-character-classes "^0.1.0" + regex-not "^1.0.0" + snapdragon "^0.8.1" + to-regex "^3.0.1" + +extend-shallow@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/extend-shallow/-/extend-shallow-2.0.1.tgz#51af7d614ad9a9f610ea1bafbb989d6b1c56890f" + dependencies: + is-extendable "^0.1.0" + +extend-shallow@^3.0.0, extend-shallow@^3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/extend-shallow/-/extend-shallow-3.0.2.tgz#26a71aaf073b39fb2127172746131c2704028db8" + dependencies: + assign-symbols "^1.0.0" + is-extendable "^1.0.1" + +external-editor@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/external-editor/-/external-editor-3.0.0.tgz#dc35c48c6f98a30ca27a20e9687d7f3c77704bb6" + dependencies: + chardet "^0.5.0" + iconv-lite "^0.4.22" + tmp "^0.0.33" + +extglob@^2.0.4: + version "2.0.4" + resolved "https://registry.yarnpkg.com/extglob/-/extglob-2.0.4.tgz#ad00fe4dc612a9232e8718711dc5cb5ab0285543" + dependencies: + array-unique "^0.3.2" + define-property "^1.0.0" + expand-brackets "^2.1.4" + extend-shallow "^2.0.1" + fragment-cache "^0.2.1" + regex-not "^1.0.0" + snapdragon "^0.8.1" + to-regex "^3.0.1" + +fast-deep-equal@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-2.0.1.tgz#7b05218ddf9667bf7f370bf7fdb2cb15fdd0aa49" + +fast-json-stable-stringify@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz#d5142c0caee6b1189f87d3a76111064f86c8bbf2" + +figures@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/figures/-/figures-2.0.0.tgz#3ab1a2d2a62c8bfb431a0c94cb797a2fce27c962" + dependencies: + escape-string-regexp "^1.0.5" + file-type@^7.2.0: version "7.2.0" resolved "https://registry.yarnpkg.com/file-type/-/file-type-7.2.0.tgz#113cfed52e1d6959ab80248906e2f25a8cdccb74" +fill-range@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-4.0.0.tgz#d544811d428f98eb06a63dc402d2403c328c38f7" + dependencies: + extend-shallow "^2.0.1" + is-number "^3.0.0" + repeat-string "^1.6.1" + to-regex-range "^2.1.0" + +find-cache-dir@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/find-cache-dir/-/find-cache-dir-1.0.0.tgz#9288e3e9e3cc3748717d39eade17cf71fc30ee6f" + dependencies: + commondir "^1.0.1" + make-dir "^1.0.0" + pkg-dir "^2.0.0" + +find-up@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/find-up/-/find-up-2.1.0.tgz#45d1b7e506c717ddd482775a2b77920a3c0c57a7" + dependencies: + locate-path "^2.0.0" + +find-up@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/find-up/-/find-up-3.0.0.tgz#49169f1d7993430646da61ecc5ae355c21c97b73" + dependencies: + locate-path "^3.0.0" + +flush-write-stream@^1.0.0: + version "1.0.3" + resolved "https://registry.yarnpkg.com/flush-write-stream/-/flush-write-stream-1.0.3.tgz#c5d586ef38af6097650b49bc41b55fabb19f35bd" + dependencies: + inherits "^2.0.1" + readable-stream "^2.0.4" + +for-in@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/for-in/-/for-in-1.0.2.tgz#81068d295a8142ec0ac726c6e2200c30fb6d5e80" + +fragment-cache@^0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/fragment-cache/-/fragment-cache-0.2.1.tgz#4290fad27f13e89be7f33799c6bc5a0abfff0d19" + dependencies: + map-cache "^0.2.2" + +from2@^2.1.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/from2/-/from2-2.3.0.tgz#8bfb5502bde4a4d36cfdeea007fcca21d7e382af" + dependencies: + inherits "^2.0.1" + readable-stream "^2.0.0" + +fs-minipass@^1.2.5: + version "1.2.5" + resolved "https://registry.yarnpkg.com/fs-minipass/-/fs-minipass-1.2.5.tgz#06c277218454ec288df77ada54a03b8702aacb9d" + dependencies: + minipass "^2.2.1" + +fs-write-stream-atomic@^1.0.8: + version "1.0.10" + resolved "https://registry.yarnpkg.com/fs-write-stream-atomic/-/fs-write-stream-atomic-1.0.10.tgz#b47df53493ef911df75731e70a9ded0189db40c9" + dependencies: + graceful-fs "^4.1.2" + iferr "^0.1.5" + imurmurhash "^0.1.4" + readable-stream "1 || 2" + fs.realpath@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" +fsevents@^1.2.2: + version "1.2.4" + resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-1.2.4.tgz#f41dcb1af2582af3692da36fc55cbd8e1041c426" + dependencies: + nan "^2.9.2" + node-pre-gyp "^0.10.0" + +gauge@~2.7.3: + version "2.7.4" + resolved "https://registry.yarnpkg.com/gauge/-/gauge-2.7.4.tgz#2c03405c7538c39d7eb37b317022e325fb018bf7" + dependencies: + aproba "^1.0.3" + console-control-strings "^1.0.0" + has-unicode "^2.0.0" + object-assign "^4.1.0" + signal-exit "^3.0.0" + string-width "^1.0.1" + strip-ansi "^3.0.1" + wide-align "^1.1.0" + +get-caller-file@^1.0.1: + version "1.0.3" + resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-1.0.3.tgz#f978fa4c90d1dfe7ff2d6beda2a515e713bdcf4a" + +get-stream@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-3.0.0.tgz#8e943d1358dc37555054ecbe2edb05aa174ede14" + +get-value@^2.0.3, get-value@^2.0.6: + version "2.0.6" + resolved "https://registry.yarnpkg.com/get-value/-/get-value-2.0.6.tgz#dc15ca1c672387ca76bd37ac0a395ba2042a2c28" + +glob-parent@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-3.1.0.tgz#9e6af6299d8d3bd2bd40430832bd113df906c5ae" + dependencies: + is-glob "^3.1.0" + path-dirname "^1.0.0" + glob@7.1.1: version "7.1.1" resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.1.tgz#805211df04faaf1c63a3600306cdf5ade50b2ec8" @@ -110,6 +1055,25 @@ glob@7.1.1: once "^1.3.0" path-is-absolute "^1.0.0" +glob@^7.0.5, glob@^7.1.2: + version "7.1.2" + resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.2.tgz#c19c9df9a028702d678612384a6552404c636d15" + dependencies: + fs.realpath "^1.0.0" + inflight "^1.0.4" + inherits "2" + minimatch "^3.0.4" + once "^1.3.0" + path-is-absolute "^1.0.0" + +global-modules-path@^2.1.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/global-modules-path/-/global-modules-path-2.3.0.tgz#b0e2bac6beac39745f7db5c59d26a36a0b94f7dc" + +graceful-fs@^4.1.11, graceful-fs@^4.1.2: + version "4.1.11" + resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.1.11.tgz#0e8bdfe4d1ddb8854d64e04ea7c00e2a026e5658" + "graceful-readlink@>= 1.0.0": version "1.0.1" resolved "https://registry.yarnpkg.com/graceful-readlink/-/graceful-readlink-1.0.1.tgz#4cafad76bc62f02fa039b2f94e9a3dd3a391a725" @@ -122,14 +1086,110 @@ has-flag@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-1.0.0.tgz#9d9e793165ce017a00f00418c43f942a7b1d11fa" +has-flag@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-3.0.0.tgz#b5d454dc2199ae225699f3467e5a07f3b955bafd" + +has-unicode@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/has-unicode/-/has-unicode-2.0.1.tgz#e0e6fe6a28cf51138855e086d1691e771de2a8b9" + +has-value@^0.3.1: + version "0.3.1" + resolved "https://registry.yarnpkg.com/has-value/-/has-value-0.3.1.tgz#7b1f58bada62ca827ec0a2078025654845995e1f" + dependencies: + get-value "^2.0.3" + has-values "^0.1.4" + isobject "^2.0.0" + +has-value@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/has-value/-/has-value-1.0.0.tgz#18b281da585b1c5c51def24c930ed29a0be6b177" + dependencies: + get-value "^2.0.6" + has-values "^1.0.0" + isobject "^3.0.0" + +has-values@^0.1.4: + version "0.1.4" + resolved "https://registry.yarnpkg.com/has-values/-/has-values-0.1.4.tgz#6d61de95d91dfca9b9a02089ad384bff8f62b771" + +has-values@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/has-values/-/has-values-1.0.0.tgz#95b0b63fec2146619a6fe57fe75628d5a39efe4f" + dependencies: + is-number "^3.0.0" + kind-of "^4.0.0" + +hash-base@^3.0.0: + version "3.0.4" + resolved "https://registry.yarnpkg.com/hash-base/-/hash-base-3.0.4.tgz#5fc8686847ecd73499403319a6b0a3f3f6ae4918" + dependencies: + inherits "^2.0.1" + safe-buffer "^5.0.1" + +hash.js@^1.0.0, hash.js@^1.0.3: + version "1.1.5" + resolved "https://registry.yarnpkg.com/hash.js/-/hash.js-1.1.5.tgz#e38ab4b85dfb1e0c40fe9265c0e9b54854c23812" + dependencies: + inherits "^2.0.3" + minimalistic-assert "^1.0.1" + he@1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/he/-/he-1.1.1.tgz#93410fd21b009735151f8868c2f271f3427e23fd" +hmac-drbg@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/hmac-drbg/-/hmac-drbg-1.0.1.tgz#d2745701025a6c775a6c545793ed502fc0c649a1" + dependencies: + hash.js "^1.0.3" + minimalistic-assert "^1.0.0" + minimalistic-crypto-utils "^1.0.1" + +https-browserify@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/https-browserify/-/https-browserify-1.0.0.tgz#ec06c10e0a34c0f2faf199f7fd7fc78fffd03c73" + iconv-lite@0.4.19: version "0.4.19" resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.19.tgz#f7468f60135f5e5dad3399c0a81be9a1603a082b" +iconv-lite@^0.4.22, iconv-lite@^0.4.4: + version "0.4.23" + resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.23.tgz#297871f63be507adcfbfca715d0cd0eed84e9a63" + dependencies: + safer-buffer ">= 2.1.2 < 3" + +ieee754@^1.1.11, ieee754@^1.1.4: + version "1.1.12" + resolved "https://registry.yarnpkg.com/ieee754/-/ieee754-1.1.12.tgz#50bf24e5b9c8bb98af4964c941cdb0918da7b60b" + +iferr@^0.1.5: + version "0.1.5" + resolved "https://registry.yarnpkg.com/iferr/-/iferr-0.1.5.tgz#c60eed69e6d8fdb6b3104a1fcbca1c192dc5b501" + +ignore-walk@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/ignore-walk/-/ignore-walk-3.0.1.tgz#a83e62e7d272ac0e3b551aaa82831a19b69f82f8" + dependencies: + minimatch "^3.0.4" + +import-local@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/import-local/-/import-local-1.0.0.tgz#5e4ffdc03f4fe6c009c6729beb29631c2f8227bc" + dependencies: + pkg-dir "^2.0.0" + resolve-cwd "^2.0.0" + +imurmurhash@^0.1.4: + version "0.1.4" + resolved "https://registry.yarnpkg.com/imurmurhash/-/imurmurhash-0.1.4.tgz#9218b9b2b928a238b13dc4fb6b6d576f231453ea" + +indexof@0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/indexof/-/indexof-0.0.1.tgz#82dc336d232b9062179d05ab3293a66059fd435d" + inflight@^1.0.4: version "1.0.6" resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9" @@ -137,22 +1197,244 @@ inflight@^1.0.4: once "^1.3.0" wrappy "1" -inherits@2: +inherits@2, inherits@2.0.3, inherits@^2.0.1, inherits@^2.0.3, inherits@~2.0.1, inherits@~2.0.3: version "2.0.3" resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.3.tgz#633c2c83e3da42a502f52466022480f4208261de" +inherits@2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.1.tgz#b17d08d326b4423e568eff719f91b0b1cbdf69f1" + +ini@~1.3.0: + version "1.3.5" + resolved "https://registry.yarnpkg.com/ini/-/ini-1.3.5.tgz#eee25f56db1c9ec6085e0c22778083f596abf927" + +inquirer@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/inquirer/-/inquirer-6.0.0.tgz#e8c20303ddc15bbfc2c12a6213710ccd9e1413d8" + dependencies: + ansi-escapes "^3.0.0" + chalk "^2.0.0" + cli-cursor "^2.1.0" + cli-width "^2.0.0" + external-editor "^3.0.0" + figures "^2.0.0" + lodash "^4.3.0" + mute-stream "0.0.7" + run-async "^2.2.0" + rxjs "^6.1.0" + string-width "^2.1.0" + strip-ansi "^4.0.0" + through "^2.3.6" + +interpret@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/interpret/-/interpret-1.1.0.tgz#7ed1b1410c6a0e0f78cf95d3b8440c63f78b8614" + +invert-kv@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/invert-kv/-/invert-kv-1.0.0.tgz#104a8e4aaca6d3d8cd157a8ef8bfab2d7a3ffdb6" + +is-accessor-descriptor@^0.1.6: + version "0.1.6" + resolved "https://registry.yarnpkg.com/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz#a9e12cb3ae8d876727eeef3843f8a0897b5c98d6" + dependencies: + kind-of "^3.0.2" + +is-accessor-descriptor@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz#169c2f6d3df1f992618072365c9b0ea1f6878656" + dependencies: + kind-of "^6.0.0" + +is-binary-path@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/is-binary-path/-/is-binary-path-1.0.1.tgz#75f16642b480f187a711c814161fd3a4a7655898" + dependencies: + binary-extensions "^1.0.0" + +is-buffer@^1.1.5: + version "1.1.6" + resolved "https://registry.yarnpkg.com/is-buffer/-/is-buffer-1.1.6.tgz#efaa2ea9daa0d7ab2ea13a97b2b8ad51fefbe8be" + +is-data-descriptor@^0.1.4: + version "0.1.4" + resolved "https://registry.yarnpkg.com/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz#0b5ee648388e2c860282e793f1856fec3f301b56" + dependencies: + kind-of "^3.0.2" + +is-data-descriptor@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz#d84876321d0e7add03990406abbbbd36ba9268c7" + dependencies: + kind-of "^6.0.0" + +is-descriptor@^0.1.0: + version "0.1.6" + resolved "https://registry.yarnpkg.com/is-descriptor/-/is-descriptor-0.1.6.tgz#366d8240dde487ca51823b1ab9f07a10a78251ca" + dependencies: + is-accessor-descriptor "^0.1.6" + is-data-descriptor "^0.1.4" + kind-of "^5.0.0" + +is-descriptor@^1.0.0, is-descriptor@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/is-descriptor/-/is-descriptor-1.0.2.tgz#3b159746a66604b04f8c81524ba365c5f14d86ec" + dependencies: + is-accessor-descriptor "^1.0.0" + is-data-descriptor "^1.0.0" + kind-of "^6.0.2" + +is-extendable@^0.1.0, is-extendable@^0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/is-extendable/-/is-extendable-0.1.1.tgz#62b110e289a471418e3ec36a617d472e301dfc89" + +is-extendable@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/is-extendable/-/is-extendable-1.0.1.tgz#a7470f9e426733d81bd81e1155264e3a3507cab4" + dependencies: + is-plain-object "^2.0.4" + +is-extglob@^2.1.0, is-extglob@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-2.1.1.tgz#a88c02535791f02ed37c76a1b9ea9773c833f8c2" + +is-fullwidth-code-point@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz#ef9e31386f031a7f0d643af82fde50c457ef00cb" + dependencies: + number-is-nan "^1.0.0" + +is-fullwidth-code-point@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz#a3b30a5c4f199183167aaab93beefae3ddfb654f" + +is-glob@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-3.1.0.tgz#7ba5ae24217804ac70707b96922567486cc3e84a" + dependencies: + is-extglob "^2.1.0" + +is-glob@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-4.0.0.tgz#9521c76845cc2610a85203ddf080a958c2ffabc0" + dependencies: + is-extglob "^2.1.1" + +is-number@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/is-number/-/is-number-3.0.0.tgz#24fd6201a4782cf50561c810276afc7d12d71195" + dependencies: + kind-of "^3.0.2" + +is-plain-object@^2.0.1, is-plain-object@^2.0.3, is-plain-object@^2.0.4: + version "2.0.4" + resolved "https://registry.yarnpkg.com/is-plain-object/-/is-plain-object-2.0.4.tgz#2c163b3fafb1b606d9d17928f05c2a1c38e07677" + dependencies: + isobject "^3.0.1" + +is-promise@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/is-promise/-/is-promise-2.1.0.tgz#79a2a9ece7f096e80f36d2b2f3bc16c1ff4bf3fa" + +is-stream@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-1.1.0.tgz#12d4a3dd4e68e0b79ceb8dbc84173ae80d91ca44" + +is-windows@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/is-windows/-/is-windows-1.0.2.tgz#d1850eb9791ecd18e6182ce12a30f396634bb19d" + +isarray@1.0.0, isarray@^1.0.0, isarray@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/isarray/-/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11" + isexe@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10" +isobject@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/isobject/-/isobject-2.1.0.tgz#f065561096a3f1da2ef46272f815c840d87e0c89" + dependencies: + isarray "1.0.0" + +isobject@^3.0.0, isobject@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/isobject/-/isobject-3.0.1.tgz#4e431e92b11a9731636aa1f9c8d1ccbcfdab78df" + jschardet@^1.6.0: version "1.6.0" resolved "https://registry.yarnpkg.com/jschardet/-/jschardet-1.6.0.tgz#c7d1a71edcff2839db2f9ec30fc5d5ebd3c1a678" +json-parse-better-errors@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz#bb867cfb3450e69107c131d1c514bab3dc8bcaa9" + +json-schema-traverse@^0.4.1: + version "0.4.1" + resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz#69f6a87d9513ab8bb8fe63bdb0979c448e684660" + json3@3.3.2: version "3.3.2" resolved "https://registry.yarnpkg.com/json3/-/json3-3.3.2.tgz#3c0434743df93e2f5c42aee7b19bcb483575f4e1" +json5@^0.5.0: + version "0.5.1" + resolved "https://registry.yarnpkg.com/json5/-/json5-0.5.1.tgz#1eade7acc012034ad84e2396767ead9fa5495821" + +kind-of@^3.0.2, kind-of@^3.0.3, kind-of@^3.2.0: + version "3.2.2" + resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-3.2.2.tgz#31ea21a734bab9bbb0f32466d893aea51e4a3c64" + dependencies: + is-buffer "^1.1.5" + +kind-of@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-4.0.0.tgz#20813df3d712928b207378691a45066fae72dd57" + dependencies: + is-buffer "^1.1.5" + +kind-of@^5.0.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-5.1.0.tgz#729c91e2d857b7a419a1f9aa65685c4c33f5845d" + +kind-of@^6.0.0, kind-of@^6.0.2: + version "6.0.2" + resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-6.0.2.tgz#01146b36a6218e64e58f3a8d66de5d7fc6f6d051" + +lcid@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/lcid/-/lcid-1.0.0.tgz#308accafa0bc483a3867b4b6f2b9506251d1b835" + dependencies: + invert-kv "^1.0.0" + +loader-runner@^2.3.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/loader-runner/-/loader-runner-2.3.0.tgz#f482aea82d543e07921700d5a46ef26fdac6b8a2" + +loader-utils@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/loader-utils/-/loader-utils-1.1.0.tgz#c98aef488bcceda2ffb5e2de646d6a754429f5cd" + dependencies: + big.js "^3.1.3" + emojis-list "^2.0.0" + json5 "^0.5.0" + +locate-path@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-2.0.0.tgz#2b568b265eec944c6d9c0de9c3dbbbca0354cd8e" + dependencies: + p-locate "^2.0.0" + path-exists "^3.0.0" + +locate-path@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-3.0.0.tgz#dbec3b3ab759758071b58fe59fc41871af21400e" + dependencies: + p-locate "^3.0.0" + path-exists "^3.0.0" + lodash._baseassign@^3.0.0: version "3.2.0" resolved "https://registry.yarnpkg.com/lodash._baseassign/-/lodash._baseassign-3.2.0.tgz#8c38a099500f215ad09e59f1722fd0c52bfe0a4e" @@ -184,6 +1466,10 @@ lodash.create@3.1.1: lodash._basecreate "^3.0.0" lodash._isiterateecall "^3.0.0" +lodash.debounce@^4.0.8: + version "4.0.8" + resolved "https://registry.yarnpkg.com/lodash.debounce/-/lodash.debounce-4.0.8.tgz#82d79bff30a67c4005ffd5e2515300ad9ca4d7af" + lodash.isarguments@^3.0.0: version "3.1.0" resolved "https://registry.yarnpkg.com/lodash.isarguments/-/lodash.isarguments-3.1.0.tgz#2f573d85c6a24289ff00663b491c1d338ff3458a" @@ -200,7 +1486,103 @@ lodash.keys@^3.0.0: lodash.isarguments "^3.0.0" lodash.isarray "^3.0.0" -minimatch@^3.0.2: +lodash@^4.3.0: + version "4.17.10" + resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.10.tgz#1b7793cf7259ea38fb3661d4d38b3260af8ae4e7" + +long@4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/long/-/long-4.0.0.tgz#9a7b71cfb7d361a194ea555241c92f7468d5bf28" + +long@^3.2.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/long/-/long-3.2.0.tgz#d821b7138ca1cb581c172990ef14db200b5c474b" + +lru-cache@^4.0.1, lru-cache@^4.1.1: + version "4.1.3" + resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-4.1.3.tgz#a1175cf3496dfc8436c156c334b4955992bce69c" + dependencies: + pseudomap "^1.0.2" + yallist "^2.1.2" + +make-dir@^1.0.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/make-dir/-/make-dir-1.3.0.tgz#79c1033b80515bd6d24ec9933e860ca75ee27f0c" + dependencies: + pify "^3.0.0" + +mamacro@^0.0.3: + version "0.0.3" + resolved "https://registry.yarnpkg.com/mamacro/-/mamacro-0.0.3.tgz#ad2c9576197c9f1abf308d0787865bd975a3f3e4" + +map-cache@^0.2.2: + version "0.2.2" + resolved "https://registry.yarnpkg.com/map-cache/-/map-cache-0.2.2.tgz#c32abd0bd6525d9b051645bb4f26ac5dc98a0dbf" + +map-visit@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/map-visit/-/map-visit-1.0.0.tgz#ecdca8f13144e660f1b5bd41f12f3479d98dfb8f" + dependencies: + object-visit "^1.0.0" + +md5.js@^1.3.4: + version "1.3.4" + resolved "https://registry.yarnpkg.com/md5.js/-/md5.js-1.3.4.tgz#e9bdbde94a20a5ac18b04340fc5764d5b09d901d" + dependencies: + hash-base "^3.0.0" + inherits "^2.0.1" + +mem@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/mem/-/mem-1.1.0.tgz#5edd52b485ca1d900fe64895505399a0dfa45f76" + dependencies: + mimic-fn "^1.0.0" + +memory-fs@^0.4.0, memory-fs@~0.4.1: + version "0.4.1" + resolved "https://registry.yarnpkg.com/memory-fs/-/memory-fs-0.4.1.tgz#3a9a20b8462523e447cfbc7e8bb80ed667bfc552" + dependencies: + errno "^0.1.3" + readable-stream "^2.0.1" + +micromatch@^3.1.4, micromatch@^3.1.8: + version "3.1.10" + resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-3.1.10.tgz#70859bc95c9840952f359a068a3fc49f9ecfac23" + dependencies: + arr-diff "^4.0.0" + array-unique "^0.3.2" + braces "^2.3.1" + define-property "^2.0.2" + extend-shallow "^3.0.2" + extglob "^2.0.4" + fragment-cache "^0.2.1" + kind-of "^6.0.2" + nanomatch "^1.2.9" + object.pick "^1.3.0" + regex-not "^1.0.0" + snapdragon "^0.8.1" + to-regex "^3.0.2" + +miller-rabin@^4.0.0: + version "4.0.1" + resolved "https://registry.yarnpkg.com/miller-rabin/-/miller-rabin-4.0.1.tgz#f080351c865b0dc562a8462966daa53543c78a4d" + dependencies: + bn.js "^4.0.0" + brorand "^1.0.1" + +mimic-fn@^1.0.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-1.2.0.tgz#820c86a39334640e99516928bd03fca88057d022" + +minimalistic-assert@^1.0.0, minimalistic-assert@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz#2e194de044626d4a10e7f7fbc00ce73e83e4d5c7" + +minimalistic-crypto-utils@^1.0.0, minimalistic-crypto-utils@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz#f6c00c1c0b082246e5c4d99dfb8c7c083b2b582a" + +minimatch@^3.0.2, minimatch@^3.0.4: version "3.0.4" resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.4.tgz#5166e286457f03306064be5497e8dbb0c3d32083" dependencies: @@ -210,7 +1592,46 @@ minimist@0.0.8: version "0.0.8" resolved "https://registry.yarnpkg.com/minimist/-/minimist-0.0.8.tgz#857fcabfc3397d2625b8228262e86aa7a011b05d" -mkdirp@0.5.1: +minimist@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.0.tgz#a35008b20f41383eec1fb914f4cd5df79a264284" + +minipass@^2.2.1, minipass@^2.3.3: + version "2.3.3" + resolved "https://registry.yarnpkg.com/minipass/-/minipass-2.3.3.tgz#a7dcc8b7b833f5d368759cce544dccb55f50f233" + dependencies: + safe-buffer "^5.1.2" + yallist "^3.0.0" + +minizlib@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/minizlib/-/minizlib-1.1.0.tgz#11e13658ce46bc3a70a267aac58359d1e0c29ceb" + dependencies: + minipass "^2.2.1" + +mississippi@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/mississippi/-/mississippi-2.0.0.tgz#3442a508fafc28500486feea99409676e4ee5a6f" + dependencies: + concat-stream "^1.5.0" + duplexify "^3.4.2" + end-of-stream "^1.1.0" + flush-write-stream "^1.0.0" + from2 "^2.1.0" + parallel-transform "^1.1.0" + pump "^2.0.1" + pumpify "^1.3.3" + stream-each "^1.1.0" + through2 "^2.0.0" + +mixin-deep@^1.2.0: + version "1.3.1" + resolved "https://registry.yarnpkg.com/mixin-deep/-/mixin-deep-1.3.1.tgz#a49e7268dce1a0d9698e45326c5626df3543d0fe" + dependencies: + for-in "^1.0.2" + is-extendable "^1.0.1" + +mkdirp@0.5.1, mkdirp@^0.5.0, mkdirp@^0.5.1, mkdirp@~0.5.0: version "0.5.1" resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.1.tgz#30057438eac6cf7f8c4767f38648d6697d75c903" dependencies: @@ -233,30 +1654,920 @@ mocha@^3.2.0: mkdirp "0.5.1" supports-color "3.1.2" +move-concurrently@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/move-concurrently/-/move-concurrently-1.0.1.tgz#be2c005fda32e0b29af1f05d7c4b33214c701f92" + dependencies: + aproba "^1.1.1" + copy-concurrently "^1.0.0" + fs-write-stream-atomic "^1.0.8" + mkdirp "^0.5.1" + rimraf "^2.5.4" + run-queue "^1.0.3" + ms@2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8" -once@^1.3.0: +mute-stream@0.0.7: + version "0.0.7" + resolved "https://registry.yarnpkg.com/mute-stream/-/mute-stream-0.0.7.tgz#3075ce93bc21b8fab43e1bc4da7e8115ed1e7bab" + +nan@^2.9.2: + version "2.10.0" + resolved "https://registry.yarnpkg.com/nan/-/nan-2.10.0.tgz#96d0cd610ebd58d4b4de9cc0c6828cda99c7548f" + +nanomatch@^1.2.9: + version "1.2.13" + resolved "https://registry.yarnpkg.com/nanomatch/-/nanomatch-1.2.13.tgz#b87a8aa4fc0de8fe6be88895b38983ff265bd119" + dependencies: + arr-diff "^4.0.0" + array-unique "^0.3.2" + define-property "^2.0.2" + extend-shallow "^3.0.2" + fragment-cache "^0.2.1" + is-windows "^1.0.2" + kind-of "^6.0.2" + object.pick "^1.3.0" + regex-not "^1.0.0" + snapdragon "^0.8.1" + to-regex "^3.0.1" + +needle@^2.2.1: + version "2.2.1" + resolved "https://registry.yarnpkg.com/needle/-/needle-2.2.1.tgz#b5e325bd3aae8c2678902fa296f729455d1d3a7d" + dependencies: + debug "^2.1.2" + iconv-lite "^0.4.4" + sax "^1.2.4" + +neo-async@^2.5.0: + version "2.5.1" + resolved "https://registry.yarnpkg.com/neo-async/-/neo-async-2.5.1.tgz#acb909e327b1e87ec9ef15f41b8a269512ad41ee" + +nice-try@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/nice-try/-/nice-try-1.0.4.tgz#d93962f6c52f2c1558c0fbda6d512819f1efe1c4" + +node-libs-browser@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/node-libs-browser/-/node-libs-browser-2.1.0.tgz#5f94263d404f6e44767d726901fff05478d600df" + dependencies: + assert "^1.1.1" + browserify-zlib "^0.2.0" + buffer "^4.3.0" + console-browserify "^1.1.0" + constants-browserify "^1.0.0" + crypto-browserify "^3.11.0" + domain-browser "^1.1.1" + events "^1.0.0" + https-browserify "^1.0.0" + os-browserify "^0.3.0" + path-browserify "0.0.0" + process "^0.11.10" + punycode "^1.2.4" + querystring-es3 "^0.2.0" + readable-stream "^2.3.3" + stream-browserify "^2.0.1" + stream-http "^2.7.2" + string_decoder "^1.0.0" + timers-browserify "^2.0.4" + tty-browserify "0.0.0" + url "^0.11.0" + util "^0.10.3" + vm-browserify "0.0.4" + +node-pre-gyp@^0.10.0: + version "0.10.3" + resolved "https://registry.yarnpkg.com/node-pre-gyp/-/node-pre-gyp-0.10.3.tgz#3070040716afdc778747b61b6887bf78880b80fc" + dependencies: + detect-libc "^1.0.2" + mkdirp "^0.5.1" + needle "^2.2.1" + nopt "^4.0.1" + npm-packlist "^1.1.6" + npmlog "^4.0.2" + rc "^1.2.7" + rimraf "^2.6.1" + semver "^5.3.0" + tar "^4" + +nopt@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/nopt/-/nopt-4.0.1.tgz#d0d4685afd5415193c8c7505602d0d17cd64474d" + dependencies: + abbrev "1" + osenv "^0.1.4" + +normalize-path@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-2.1.1.tgz#1ab28b556e198363a8c1a6f7e6fa20137fe6aed9" + dependencies: + remove-trailing-separator "^1.0.1" + +npm-bundled@^1.0.1: + version "1.0.3" + resolved "https://registry.yarnpkg.com/npm-bundled/-/npm-bundled-1.0.3.tgz#7e71703d973af3370a9591bafe3a63aca0be2308" + +npm-packlist@^1.1.6: + version "1.1.11" + resolved "https://registry.yarnpkg.com/npm-packlist/-/npm-packlist-1.1.11.tgz#84e8c683cbe7867d34b1d357d893ce29e28a02de" + dependencies: + ignore-walk "^3.0.1" + npm-bundled "^1.0.1" + +npm-run-path@^2.0.0: + version "2.0.2" + resolved "https://registry.yarnpkg.com/npm-run-path/-/npm-run-path-2.0.2.tgz#35a9232dfa35d7067b4cb2ddf2357b1871536c5f" + dependencies: + path-key "^2.0.0" + +npmlog@^4.0.2: + version "4.1.2" + resolved "https://registry.yarnpkg.com/npmlog/-/npmlog-4.1.2.tgz#08a7f2a8bf734604779a9efa4ad5cc717abb954b" + dependencies: + are-we-there-yet "~1.1.2" + console-control-strings "~1.1.0" + gauge "~2.7.3" + set-blocking "~2.0.0" + +number-is-nan@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/number-is-nan/-/number-is-nan-1.0.1.tgz#097b602b53422a522c1afb8790318336941a011d" + +object-assign@^4.1.0: + version "4.1.1" + resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863" + +object-copy@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/object-copy/-/object-copy-0.1.0.tgz#7e7d858b781bd7c991a41ba975ed3812754e998c" + dependencies: + copy-descriptor "^0.1.0" + define-property "^0.2.5" + kind-of "^3.0.3" + +object-visit@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/object-visit/-/object-visit-1.0.1.tgz#f79c4493af0c5377b59fe39d395e41042dd045bb" + dependencies: + isobject "^3.0.0" + +object.pick@^1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/object.pick/-/object.pick-1.3.0.tgz#87a10ac4c1694bd2e1cbf53591a66141fb5dd747" + dependencies: + isobject "^3.0.1" + +once@^1.3.0, once@^1.3.1, once@^1.4.0: version "1.4.0" resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1" dependencies: wrappy "1" +onetime@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/onetime/-/onetime-2.0.1.tgz#067428230fd67443b2794b22bba528b6867962d4" + dependencies: + mimic-fn "^1.0.0" + +os-browserify@^0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/os-browserify/-/os-browserify-0.3.0.tgz#854373c7f5c2315914fc9bfc6bd8238fdda1ec27" + +os-homedir@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/os-homedir/-/os-homedir-1.0.2.tgz#ffbc4988336e0e833de0c168c7ef152121aa7fb3" + +os-locale@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/os-locale/-/os-locale-2.1.0.tgz#42bc2900a6b5b8bd17376c8e882b65afccf24bf2" + dependencies: + execa "^0.7.0" + lcid "^1.0.0" + mem "^1.1.0" + +os-tmpdir@^1.0.0, os-tmpdir@~1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/os-tmpdir/-/os-tmpdir-1.0.2.tgz#bbe67406c79aa85c5cfec766fe5734555dfa1274" + +osenv@^0.1.4: + version "0.1.5" + resolved "https://registry.yarnpkg.com/osenv/-/osenv-0.1.5.tgz#85cdfafaeb28e8677f416e287592b5f3f49ea410" + dependencies: + os-homedir "^1.0.0" + os-tmpdir "^1.0.0" + +p-finally@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/p-finally/-/p-finally-1.0.0.tgz#3fbcfb15b899a44123b34b6dcc18b724336a2cae" + +p-limit@^1.1.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-1.3.0.tgz#b86bd5f0c25690911c7590fcbfc2010d54b3ccb8" + dependencies: + p-try "^1.0.0" + +p-limit@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-2.0.0.tgz#e624ed54ee8c460a778b3c9f3670496ff8a57aec" + dependencies: + p-try "^2.0.0" + +p-locate@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-2.0.0.tgz#20a0103b222a70c8fd39cc2e580680f3dde5ec43" + dependencies: + p-limit "^1.1.0" + +p-locate@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-3.0.0.tgz#322d69a05c0264b25997d9f40cd8a891ab0064a4" + dependencies: + p-limit "^2.0.0" + +p-try@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/p-try/-/p-try-1.0.0.tgz#cbc79cdbaf8fd4228e13f621f2b1a237c1b207b3" + +p-try@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/p-try/-/p-try-2.0.0.tgz#85080bb87c64688fa47996fe8f7dfbe8211760b1" + +pako@~1.0.5: + version "1.0.6" + resolved "https://registry.yarnpkg.com/pako/-/pako-1.0.6.tgz#0101211baa70c4bca4a0f63f2206e97b7dfaf258" + +parallel-transform@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/parallel-transform/-/parallel-transform-1.1.0.tgz#d410f065b05da23081fcd10f28854c29bda33b06" + dependencies: + cyclist "~0.2.2" + inherits "^2.0.3" + readable-stream "^2.1.5" + +parse-asn1@^5.0.0: + version "5.1.1" + resolved "https://registry.yarnpkg.com/parse-asn1/-/parse-asn1-5.1.1.tgz#f6bf293818332bd0dab54efb16087724745e6ca8" + dependencies: + asn1.js "^4.0.0" + browserify-aes "^1.0.0" + create-hash "^1.1.0" + evp_bytestokey "^1.0.0" + pbkdf2 "^3.0.3" + +pascalcase@^0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/pascalcase/-/pascalcase-0.1.1.tgz#b363e55e8006ca6fe21784d2db22bd15d7917f14" + +path-browserify@0.0.0: + version "0.0.0" + resolved "https://registry.yarnpkg.com/path-browserify/-/path-browserify-0.0.0.tgz#a0b870729aae214005b7d5032ec2cbbb0fb4451a" + +path-dirname@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/path-dirname/-/path-dirname-1.0.2.tgz#cc33d24d525e099a5388c0336c6e32b9160609e0" + +path-exists@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-3.0.0.tgz#ce0ebeaa5f78cb18925ea7d810d7b59b010fd515" + path-is-absolute@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f" -semver@^5.3.0: +path-key@^2.0.0, path-key@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/path-key/-/path-key-2.0.1.tgz#411cadb574c5a140d3a4b1910d40d80cc9f40b40" + +pbkdf2@^3.0.3: + version "3.0.16" + resolved "https://registry.yarnpkg.com/pbkdf2/-/pbkdf2-3.0.16.tgz#7404208ec6b01b62d85bf83853a8064f8d9c2a5c" + dependencies: + create-hash "^1.1.2" + create-hmac "^1.1.4" + ripemd160 "^2.0.1" + safe-buffer "^5.0.1" + sha.js "^2.4.8" + +pify@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/pify/-/pify-3.0.0.tgz#e5a4acd2c101fdf3d9a4d07f0dbc4db49dd28176" + +pkg-dir@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/pkg-dir/-/pkg-dir-2.0.0.tgz#f6d5d1109e19d63edf428e0bd57e12777615334b" + dependencies: + find-up "^2.1.0" + +posix-character-classes@^0.1.0: + version "0.1.1" + resolved "https://registry.yarnpkg.com/posix-character-classes/-/posix-character-classes-0.1.1.tgz#01eac0fe3b5af71a2a6c02feabb8c1fef7e00eab" + +process-nextick-args@~2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-2.0.0.tgz#a37d732f4271b4ab1ad070d35508e8290788ffaa" + +process@^0.11.10: + version "0.11.10" + resolved "https://registry.yarnpkg.com/process/-/process-0.11.10.tgz#7332300e840161bda3e69a1d1d91a7d4bc16f182" + +promise-inflight@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/promise-inflight/-/promise-inflight-1.0.1.tgz#98472870bf228132fcbdd868129bad12c3c029e3" + +prr@~1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/prr/-/prr-1.0.1.tgz#d3fc114ba06995a45ec6893f484ceb1d78f5f476" + +pseudomap@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/pseudomap/-/pseudomap-1.0.2.tgz#f052a28da70e618917ef0a8ac34c1ae5a68286b3" + +public-encrypt@^4.0.0: + version "4.0.2" + resolved "https://registry.yarnpkg.com/public-encrypt/-/public-encrypt-4.0.2.tgz#46eb9107206bf73489f8b85b69d91334c6610994" + dependencies: + bn.js "^4.1.0" + browserify-rsa "^4.0.0" + create-hash "^1.1.0" + parse-asn1 "^5.0.0" + randombytes "^2.0.1" + +pump@^2.0.0, pump@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/pump/-/pump-2.0.1.tgz#12399add6e4cf7526d973cbc8b5ce2e2908b3909" + dependencies: + end-of-stream "^1.1.0" + once "^1.3.1" + +pumpify@^1.3.3: + version "1.5.1" + resolved "https://registry.yarnpkg.com/pumpify/-/pumpify-1.5.1.tgz#36513be246ab27570b1a374a5ce278bfd74370ce" + dependencies: + duplexify "^3.6.0" + inherits "^2.0.3" + pump "^2.0.0" + +punycode@1.3.2: + version "1.3.2" + resolved "https://registry.yarnpkg.com/punycode/-/punycode-1.3.2.tgz#9653a036fb7c1ee42342f2325cceefea3926c48d" + +punycode@^1.2.4: + version "1.4.1" + resolved "https://registry.yarnpkg.com/punycode/-/punycode-1.4.1.tgz#c0d5a63b2718800ad8e1eb0fa5269c84dd41845e" + +punycode@^2.1.0: + version "2.1.1" + resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.1.1.tgz#b58b010ac40c22c5657616c8d2c2c02c7bf479ec" + +querystring-es3@^0.2.0: + version "0.2.1" + resolved "https://registry.yarnpkg.com/querystring-es3/-/querystring-es3-0.2.1.tgz#9ec61f79049875707d69414596fd907a4d711e73" + +querystring@0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/querystring/-/querystring-0.2.0.tgz#b209849203bb25df820da756e747005878521620" + +randombytes@^2.0.0, randombytes@^2.0.1, randombytes@^2.0.5: + version "2.0.6" + resolved "https://registry.yarnpkg.com/randombytes/-/randombytes-2.0.6.tgz#d302c522948588848a8d300c932b44c24231da80" + dependencies: + safe-buffer "^5.1.0" + +randomfill@^1.0.3: + version "1.0.4" + resolved "https://registry.yarnpkg.com/randomfill/-/randomfill-1.0.4.tgz#c92196fc86ab42be983f1bf31778224931d61458" + dependencies: + randombytes "^2.0.5" + safe-buffer "^5.1.0" + +rc@^1.2.7: + version "1.2.8" + resolved "https://registry.yarnpkg.com/rc/-/rc-1.2.8.tgz#cd924bf5200a075b83c188cd6b9e211b7fc0d3ed" + dependencies: + deep-extend "^0.6.0" + ini "~1.3.0" + minimist "^1.2.0" + strip-json-comments "~2.0.1" + +"readable-stream@1 || 2", readable-stream@^2.0.0, readable-stream@^2.0.1, readable-stream@^2.0.2, readable-stream@^2.0.4, readable-stream@^2.0.6, readable-stream@^2.1.5, readable-stream@^2.2.2, readable-stream@^2.3.3, readable-stream@^2.3.6: + version "2.3.6" + resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.6.tgz#b11c27d88b8ff1fbe070643cf94b0c79ae1b0aaf" + dependencies: + core-util-is "~1.0.0" + inherits "~2.0.3" + isarray "~1.0.0" + process-nextick-args "~2.0.0" + safe-buffer "~5.1.1" + string_decoder "~1.1.1" + util-deprecate "~1.0.1" + +readdirp@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-2.1.0.tgz#4ed0ad060df3073300c48440373f72d1cc642d78" + dependencies: + graceful-fs "^4.1.2" + minimatch "^3.0.2" + readable-stream "^2.0.2" + set-immediate-shim "^1.0.1" + +regex-not@^1.0.0, regex-not@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/regex-not/-/regex-not-1.0.2.tgz#1f4ece27e00b0b65e0247a6810e6a85d83a5752c" + dependencies: + extend-shallow "^3.0.2" + safe-regex "^1.1.0" + +remove-trailing-separator@^1.0.1: + version "1.1.0" + resolved "https://registry.yarnpkg.com/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz#c24bce2a283adad5bc3f58e0d48249b92379d8ef" + +repeat-element@^1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/repeat-element/-/repeat-element-1.1.2.tgz#ef089a178d1483baae4d93eb98b4f9e4e11d990a" + +repeat-string@^1.6.1: + version "1.6.1" + resolved "https://registry.yarnpkg.com/repeat-string/-/repeat-string-1.6.1.tgz#8dcae470e1c88abc2d600fff4a776286da75e637" + +require-directory@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/require-directory/-/require-directory-2.1.1.tgz#8c64ad5fd30dab1c976e2344ffe7f792a6a6df42" + +require-main-filename@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/require-main-filename/-/require-main-filename-1.0.1.tgz#97f717b69d48784f5f526a6c5aa8ffdda055a4d1" + +resolve-cwd@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/resolve-cwd/-/resolve-cwd-2.0.0.tgz#00a9f7387556e27038eae232caa372a6a59b665a" + dependencies: + resolve-from "^3.0.0" + +resolve-from@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-3.0.0.tgz#b22c7af7d9d6881bc8b6e653335eebcb0a188748" + +resolve-url@^0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/resolve-url/-/resolve-url-0.2.1.tgz#2c637fe77c893afd2a663fe21aa9080068e2052a" + +restore-cursor@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/restore-cursor/-/restore-cursor-2.0.0.tgz#9f7ee287f82fd326d4fd162923d62129eee0dfaf" + dependencies: + onetime "^2.0.0" + signal-exit "^3.0.2" + +ret@~0.1.10: + version "0.1.15" + resolved "https://registry.yarnpkg.com/ret/-/ret-0.1.15.tgz#b8a4825d5bdb1fc3f6f53c2bc33f81388681c7bc" + +rimraf@^2.5.4, rimraf@^2.6.1, rimraf@^2.6.2: + version "2.6.2" + resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.6.2.tgz#2ed8150d24a16ea8651e6d6ef0f47c4158ce7a36" + dependencies: + glob "^7.0.5" + +ripemd160@^2.0.0, ripemd160@^2.0.1: + version "2.0.2" + resolved "https://registry.yarnpkg.com/ripemd160/-/ripemd160-2.0.2.tgz#a1c1a6f624751577ba5d07914cbc92850585890c" + dependencies: + hash-base "^3.0.0" + inherits "^2.0.1" + +run-async@^2.2.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/run-async/-/run-async-2.3.0.tgz#0371ab4ae0bdd720d4166d7dfda64ff7a445a6c0" + dependencies: + is-promise "^2.1.0" + +run-queue@^1.0.0, run-queue@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/run-queue/-/run-queue-1.0.3.tgz#e848396f057d223f24386924618e25694161ec47" + dependencies: + aproba "^1.1.1" + +rxjs@^6.1.0: + version "6.2.2" + resolved "https://registry.yarnpkg.com/rxjs/-/rxjs-6.2.2.tgz#eb75fa3c186ff5289907d06483a77884586e1cf9" + dependencies: + tslib "^1.9.0" + +safe-buffer@^5.0.1, safe-buffer@^5.1.0, safe-buffer@^5.1.1, safe-buffer@^5.1.2, safe-buffer@~5.1.0, safe-buffer@~5.1.1: + version "5.1.2" + resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.2.tgz#991ec69d296e0313747d59bdfd2b745c35f8828d" + +safe-regex@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/safe-regex/-/safe-regex-1.1.0.tgz#40a3669f3b077d1e943d44629e157dd48023bf2e" + dependencies: + ret "~0.1.10" + +"safer-buffer@>= 2.1.2 < 3": + version "2.1.2" + resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a" + +sax@^1.2.4: + version "1.2.4" + resolved "https://registry.yarnpkg.com/sax/-/sax-1.2.4.tgz#2816234e2378bddc4e5354fab5caa895df7100d9" + +schema-utils@^0.4.4, schema-utils@^0.4.5: + version "0.4.6" + resolved "https://registry.yarnpkg.com/schema-utils/-/schema-utils-0.4.6.tgz#dab4516a656310a964ca772bd3771819ba2b5cec" + dependencies: + ajv "^6.1.0" + ajv-keywords "^3.1.0" + +semver@^5.3.0, semver@^5.5.0: version "5.5.0" resolved "https://registry.yarnpkg.com/semver/-/semver-5.5.0.tgz#dc4bbc7a6ca9d916dee5d43516f0092b58f7b8ab" +serialize-javascript@^1.4.0: + version "1.5.0" + resolved "https://registry.yarnpkg.com/serialize-javascript/-/serialize-javascript-1.5.0.tgz#1aa336162c88a890ddad5384baebc93a655161fe" + +set-blocking@^2.0.0, set-blocking@~2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/set-blocking/-/set-blocking-2.0.0.tgz#045f9782d011ae9a6803ddd382b24392b3d890f7" + +set-immediate-shim@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/set-immediate-shim/-/set-immediate-shim-1.0.1.tgz#4b2b1b27eb808a9f8dcc481a58e5e56f599f3f61" + +set-value@^0.4.3: + version "0.4.3" + resolved "https://registry.yarnpkg.com/set-value/-/set-value-0.4.3.tgz#7db08f9d3d22dc7f78e53af3c3bf4666ecdfccf1" + dependencies: + extend-shallow "^2.0.1" + is-extendable "^0.1.1" + is-plain-object "^2.0.1" + to-object-path "^0.3.0" + +set-value@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/set-value/-/set-value-2.0.0.tgz#71ae4a88f0feefbbf52d1ea604f3fb315ebb6274" + dependencies: + extend-shallow "^2.0.1" + is-extendable "^0.1.1" + is-plain-object "^2.0.3" + split-string "^3.0.1" + +setimmediate@^1.0.4: + version "1.0.5" + resolved "https://registry.yarnpkg.com/setimmediate/-/setimmediate-1.0.5.tgz#290cbb232e306942d7d7ea9b83732ab7856f8285" + +sha.js@^2.4.0, sha.js@^2.4.8: + version "2.4.11" + resolved "https://registry.yarnpkg.com/sha.js/-/sha.js-2.4.11.tgz#37a5cf0b81ecbc6943de109ba2960d1b26584ae7" + dependencies: + inherits "^2.0.1" + safe-buffer "^5.0.1" + +shebang-command@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/shebang-command/-/shebang-command-1.2.0.tgz#44aac65b695b03398968c39f363fee5deafdf1ea" + dependencies: + shebang-regex "^1.0.0" + +shebang-regex@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-1.0.0.tgz#da42f49740c0b42db2ca9728571cb190c98efea3" + +signal-exit@^3.0.0, signal-exit@^3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.2.tgz#b5fdc08f1287ea1178628e415e25132b73646c6d" + +snapdragon-node@^2.0.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/snapdragon-node/-/snapdragon-node-2.1.1.tgz#6c175f86ff14bdb0724563e8f3c1b021a286853b" + dependencies: + define-property "^1.0.0" + isobject "^3.0.0" + snapdragon-util "^3.0.1" + +snapdragon-util@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/snapdragon-util/-/snapdragon-util-3.0.1.tgz#f956479486f2acd79700693f6f7b805e45ab56e2" + dependencies: + kind-of "^3.2.0" + +snapdragon@^0.8.1: + version "0.8.2" + resolved "https://registry.yarnpkg.com/snapdragon/-/snapdragon-0.8.2.tgz#64922e7c565b0e14204ba1aa7d6964278d25182d" + dependencies: + base "^0.11.1" + debug "^2.2.0" + define-property "^0.2.5" + extend-shallow "^2.0.1" + map-cache "^0.2.2" + source-map "^0.5.6" + source-map-resolve "^0.5.0" + use "^3.1.0" + +source-list-map@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/source-list-map/-/source-list-map-2.0.0.tgz#aaa47403f7b245a92fbc97ea08f250d6087ed085" + +source-map-resolve@^0.5.0: + version "0.5.2" + resolved "https://registry.yarnpkg.com/source-map-resolve/-/source-map-resolve-0.5.2.tgz#72e2cc34095543e43b2c62b2c4c10d4a9054f259" + dependencies: + atob "^2.1.1" + decode-uri-component "^0.2.0" + resolve-url "^0.2.1" + source-map-url "^0.4.0" + urix "^0.1.0" + +source-map-url@^0.4.0: + version "0.4.0" + resolved "https://registry.yarnpkg.com/source-map-url/-/source-map-url-0.4.0.tgz#3e935d7ddd73631b97659956d55128e87b5084a3" + +source-map@^0.5.6: + version "0.5.7" + resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.5.7.tgz#8a039d2d1021d22d1ea14c80d8ea468ba2ef3fcc" + +source-map@^0.6.1, source-map@~0.6.1: + version "0.6.1" + resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263" + +split-string@^3.0.1, split-string@^3.0.2: + version "3.1.0" + resolved "https://registry.yarnpkg.com/split-string/-/split-string-3.1.0.tgz#7cb09dda3a86585705c64b39a6466038682e8fe2" + dependencies: + extend-shallow "^3.0.0" + +ssri@^5.2.4: + version "5.3.0" + resolved "https://registry.yarnpkg.com/ssri/-/ssri-5.3.0.tgz#ba3872c9c6d33a0704a7d71ff045e5ec48999d06" + dependencies: + safe-buffer "^5.1.1" + +static-extend@^0.1.1: + version "0.1.2" + resolved "https://registry.yarnpkg.com/static-extend/-/static-extend-0.1.2.tgz#60809c39cbff55337226fd5e0b520f341f1fb5c6" + dependencies: + define-property "^0.2.5" + object-copy "^0.1.0" + +stream-browserify@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/stream-browserify/-/stream-browserify-2.0.1.tgz#66266ee5f9bdb9940a4e4514cafb43bb71e5c9db" + dependencies: + inherits "~2.0.1" + readable-stream "^2.0.2" + +stream-each@^1.1.0: + version "1.2.3" + resolved "https://registry.yarnpkg.com/stream-each/-/stream-each-1.2.3.tgz#ebe27a0c389b04fbcc233642952e10731afa9bae" + dependencies: + end-of-stream "^1.1.0" + stream-shift "^1.0.0" + +stream-http@^2.7.2: + version "2.8.3" + resolved "https://registry.yarnpkg.com/stream-http/-/stream-http-2.8.3.tgz#b2d242469288a5a27ec4fe8933acf623de6514fc" + dependencies: + builtin-status-codes "^3.0.0" + inherits "^2.0.1" + readable-stream "^2.3.6" + to-arraybuffer "^1.0.0" + xtend "^4.0.0" + +stream-shift@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/stream-shift/-/stream-shift-1.0.0.tgz#d5c752825e5367e786f78e18e445ea223a155952" + +string-width@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/string-width/-/string-width-1.0.2.tgz#118bdf5b8cdc51a2a7e70d211e07e2b0b9b107d3" + dependencies: + code-point-at "^1.0.0" + is-fullwidth-code-point "^1.0.0" + strip-ansi "^3.0.0" + +"string-width@^1.0.2 || 2", string-width@^2.0.0, string-width@^2.1.0, string-width@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/string-width/-/string-width-2.1.1.tgz#ab93f27a8dc13d28cac815c462143a6d9012ae9e" + dependencies: + is-fullwidth-code-point "^2.0.0" + strip-ansi "^4.0.0" + +string_decoder@^1.0.0, string_decoder@~1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.1.1.tgz#9cf1611ba62685d7030ae9e4ba34149c3af03fc8" + dependencies: + safe-buffer "~5.1.0" + +strip-ansi@^3.0.0, strip-ansi@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-3.0.1.tgz#6a385fb8853d952d5ff05d0e8aaf94278dc63dcf" + dependencies: + ansi-regex "^2.0.0" + +strip-ansi@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-4.0.0.tgz#a8479022eb1ac368a871389b635262c505ee368f" + dependencies: + ansi-regex "^3.0.0" + +strip-eof@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/strip-eof/-/strip-eof-1.0.0.tgz#bb43ff5598a6eb05d89b59fcd129c983313606bf" + +strip-json-comments@~2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-2.0.1.tgz#3c531942e908c2697c0ec344858c286c7ca0a60a" + supports-color@3.1.2: version "3.1.2" resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-3.1.2.tgz#72a262894d9d408b956ca05ff37b2ed8a6e2a2d5" dependencies: has-flag "^1.0.0" +supports-color@^5.3.0, supports-color@^5.4.0: + version "5.4.0" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-5.4.0.tgz#1c6b337402c2137605efe19f10fec390f6faab54" + dependencies: + has-flag "^3.0.0" + +tapable@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/tapable/-/tapable-1.0.0.tgz#cbb639d9002eed9c6b5975eb20598d7936f1f9f2" + +tar@^4: + version "4.4.6" + resolved "https://registry.yarnpkg.com/tar/-/tar-4.4.6.tgz#63110f09c00b4e60ac8bcfe1bf3c8660235fbc9b" + dependencies: + chownr "^1.0.1" + fs-minipass "^1.2.5" + minipass "^2.3.3" + minizlib "^1.1.0" + mkdirp "^0.5.0" + safe-buffer "^5.1.2" + yallist "^3.0.2" + +through2@^2.0.0: + version "2.0.3" + resolved "https://registry.yarnpkg.com/through2/-/through2-2.0.3.tgz#0004569b37c7c74ba39c43f3ced78d1ad94140be" + dependencies: + readable-stream "^2.1.5" + xtend "~4.0.1" + +through@^2.3.6: + version "2.3.8" + resolved "https://registry.yarnpkg.com/through/-/through-2.3.8.tgz#0dd4c9ffaabc357960b1b724115d7e0e86a2e1f5" + +timers-browserify@^2.0.4: + version "2.0.10" + resolved "https://registry.yarnpkg.com/timers-browserify/-/timers-browserify-2.0.10.tgz#1d28e3d2aadf1d5a5996c4e9f95601cd053480ae" + dependencies: + setimmediate "^1.0.4" + +tmp@^0.0.33: + version "0.0.33" + resolved "https://registry.yarnpkg.com/tmp/-/tmp-0.0.33.tgz#6d34335889768d21b2bcda0aa277ced3b1bfadf9" + dependencies: + os-tmpdir "~1.0.2" + +to-arraybuffer@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/to-arraybuffer/-/to-arraybuffer-1.0.1.tgz#7d229b1fcc637e466ca081180836a7aabff83f43" + +to-object-path@^0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/to-object-path/-/to-object-path-0.3.0.tgz#297588b7b0e7e0ac08e04e672f85c1f4999e17af" + dependencies: + kind-of "^3.0.2" + +to-regex-range@^2.1.0: + version "2.1.1" + resolved "https://registry.yarnpkg.com/to-regex-range/-/to-regex-range-2.1.1.tgz#7c80c17b9dfebe599e27367e0d4dd5590141db38" + dependencies: + is-number "^3.0.0" + repeat-string "^1.6.1" + +to-regex@^3.0.1, to-regex@^3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/to-regex/-/to-regex-3.0.2.tgz#13cfdd9b336552f30b51f33a8ae1b42a7a7599ce" + dependencies: + define-property "^2.0.2" + extend-shallow "^3.0.2" + regex-not "^1.0.2" + safe-regex "^1.1.0" + +tslib@^1.9.0: + version "1.9.3" + resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.9.3.tgz#d7e4dd79245d85428c4d7e4822a79917954ca286" + +tty-browserify@0.0.0: + version "0.0.0" + resolved "https://registry.yarnpkg.com/tty-browserify/-/tty-browserify-0.0.0.tgz#a157ba402da24e9bf957f9aa69d524eed42901a6" + +typedarray@^0.0.6: + version "0.0.6" + resolved "https://registry.yarnpkg.com/typedarray/-/typedarray-0.0.6.tgz#867ac74e3864187b1d3d47d996a78ec5c8830777" + +uglify-es@^3.3.4: + version "3.3.9" + resolved "https://registry.yarnpkg.com/uglify-es/-/uglify-es-3.3.9.tgz#0c1c4f0700bed8dbc124cdb304d2592ca203e677" + dependencies: + commander "~2.13.0" + source-map "~0.6.1" + +uglifyjs-webpack-plugin@^1.2.4: + version "1.2.7" + resolved "https://registry.yarnpkg.com/uglifyjs-webpack-plugin/-/uglifyjs-webpack-plugin-1.2.7.tgz#57638dd99c853a1ebfe9d97b42160a8a507f9d00" + dependencies: + cacache "^10.0.4" + find-cache-dir "^1.0.0" + schema-utils "^0.4.5" + serialize-javascript "^1.4.0" + source-map "^0.6.1" + uglify-es "^3.3.4" + webpack-sources "^1.1.0" + worker-farm "^1.5.2" + +union-value@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/union-value/-/union-value-1.0.0.tgz#5c71c34cb5bad5dcebe3ea0cd08207ba5aa1aea4" + dependencies: + arr-union "^3.1.0" + get-value "^2.0.6" + is-extendable "^0.1.1" + set-value "^0.4.3" + +unique-filename@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/unique-filename/-/unique-filename-1.1.0.tgz#d05f2fe4032560871f30e93cbe735eea201514f3" + dependencies: + unique-slug "^2.0.0" + +unique-slug@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/unique-slug/-/unique-slug-2.0.0.tgz#db6676e7c7cc0629878ff196097c78855ae9f4ab" + dependencies: + imurmurhash "^0.1.4" + +unset-value@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/unset-value/-/unset-value-1.0.0.tgz#8376873f7d2335179ffb1e6fc3a8ed0dfc8ab559" + dependencies: + has-value "^0.3.1" + isobject "^3.0.0" + +upath@^1.0.5: + version "1.1.0" + resolved "https://registry.yarnpkg.com/upath/-/upath-1.1.0.tgz#35256597e46a581db4793d0ce47fa9aebfc9fabd" + +uri-js@^4.2.1: + version "4.2.2" + resolved "https://registry.yarnpkg.com/uri-js/-/uri-js-4.2.2.tgz#94c540e1ff772956e2299507c010aea6c8838eb0" + dependencies: + punycode "^2.1.0" + +urix@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/urix/-/urix-0.1.0.tgz#da937f7a62e21fec1fd18d49b35c2935067a6c72" + +url@^0.11.0: + version "0.11.0" + resolved "https://registry.yarnpkg.com/url/-/url-0.11.0.tgz#3838e97cfc60521eb73c525a8e55bfdd9e2e28f1" + dependencies: + punycode "1.3.2" + querystring "0.2.0" + +use@^3.1.0: + version "3.1.1" + resolved "https://registry.yarnpkg.com/use/-/use-3.1.1.tgz#d50c8cac79a19fbc20f2911f56eb973f4e10070f" + +util-deprecate@~1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf" + +util@0.10.3: + version "0.10.3" + resolved "https://registry.yarnpkg.com/util/-/util-0.10.3.tgz#7afb1afe50805246489e3db7fe0ed379336ac0f9" + dependencies: + inherits "2.0.1" + +util@^0.10.3: + version "0.10.4" + resolved "https://registry.yarnpkg.com/util/-/util-0.10.4.tgz#3aa0125bfe668a4672de58857d3ace27ecb76901" + dependencies: + inherits "2.0.3" + +v8-compile-cache@^2.0.0: + version "2.0.2" + resolved "https://registry.yarnpkg.com/v8-compile-cache/-/v8-compile-cache-2.0.2.tgz#a428b28bb26790734c4fc8bc9fa106fccebf6a6c" + +vm-browserify@0.0.4: + version "0.0.4" + resolved "https://registry.yarnpkg.com/vm-browserify/-/vm-browserify-0.0.4.tgz#5d7ea45bbef9e4a6ff65f95438e0a87c357d5a73" + dependencies: + indexof "0.0.1" + vscode-extension-telemetry@0.0.18: version "0.0.18" resolved "https://registry.yarnpkg.com/vscode-extension-telemetry/-/vscode-extension-telemetry-0.0.18.tgz#602ba20d8c71453aa34533a291e7638f6e5c0327" @@ -267,16 +2578,149 @@ vscode-nls@^3.2.4: version "3.2.4" resolved "https://registry.yarnpkg.com/vscode-nls/-/vscode-nls-3.2.4.tgz#2166b4183c8aea884d20727f5449e62be69fd398" +watchpack@^1.5.0: + version "1.6.0" + resolved "https://registry.yarnpkg.com/watchpack/-/watchpack-1.6.0.tgz#4bc12c2ebe8aa277a71f1d3f14d685c7b446cd00" + dependencies: + chokidar "^2.0.2" + graceful-fs "^4.1.2" + neo-async "^2.5.0" + +webpack-cli@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/webpack-cli/-/webpack-cli-3.1.0.tgz#d71a83687dcfeb758fdceeb0fe042f96bcf62994" + dependencies: + chalk "^2.4.1" + cross-spawn "^6.0.5" + enhanced-resolve "^4.0.0" + global-modules-path "^2.1.0" + import-local "^1.0.0" + inquirer "^6.0.0" + interpret "^1.1.0" + loader-utils "^1.1.0" + supports-color "^5.4.0" + v8-compile-cache "^2.0.0" + yargs "^12.0.1" + +webpack-sources@^1.0.1, webpack-sources@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/webpack-sources/-/webpack-sources-1.1.0.tgz#a101ebae59d6507354d71d8013950a3a8b7a5a54" + dependencies: + source-list-map "^2.0.0" + source-map "~0.6.1" + +webpack@^4.16.5: + version "4.16.5" + resolved "https://registry.yarnpkg.com/webpack/-/webpack-4.16.5.tgz#29fb39462823d7eb8aefcab8b45f7f241db0d092" + dependencies: + "@webassemblyjs/ast" "1.5.13" + "@webassemblyjs/helper-module-context" "1.5.13" + "@webassemblyjs/wasm-edit" "1.5.13" + "@webassemblyjs/wasm-opt" "1.5.13" + "@webassemblyjs/wasm-parser" "1.5.13" + acorn "^5.6.2" + acorn-dynamic-import "^3.0.0" + ajv "^6.1.0" + ajv-keywords "^3.1.0" + chrome-trace-event "^1.0.0" + enhanced-resolve "^4.1.0" + eslint-scope "^4.0.0" + json-parse-better-errors "^1.0.2" + loader-runner "^2.3.0" + loader-utils "^1.1.0" + memory-fs "~0.4.1" + micromatch "^3.1.8" + mkdirp "~0.5.0" + neo-async "^2.5.0" + node-libs-browser "^2.0.0" + schema-utils "^0.4.4" + tapable "^1.0.0" + uglifyjs-webpack-plugin "^1.2.4" + watchpack "^1.5.0" + webpack-sources "^1.0.1" + +which-module@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/which-module/-/which-module-2.0.0.tgz#d9ef07dce77b9902b8a3a8fa4b31c3e3f7e6e87a" + +which@^1.2.9: + version "1.3.1" + resolved "https://registry.yarnpkg.com/which/-/which-1.3.1.tgz#a45043d54f5805316da8d62f9f50918d3da70b0a" + dependencies: + isexe "^2.0.0" + which@^1.3.0: version "1.3.0" resolved "https://registry.yarnpkg.com/which/-/which-1.3.0.tgz#ff04bdfc010ee547d780bec38e1ac1c2777d253a" dependencies: isexe "^2.0.0" +wide-align@^1.1.0: + version "1.1.3" + resolved "https://registry.yarnpkg.com/wide-align/-/wide-align-1.1.3.tgz#ae074e6bdc0c14a431e804e624549c633b000457" + dependencies: + string-width "^1.0.2 || 2" + +worker-farm@^1.5.2: + version "1.6.0" + resolved "https://registry.yarnpkg.com/worker-farm/-/worker-farm-1.6.0.tgz#aecc405976fab5a95526180846f0dba288f3a4a0" + dependencies: + errno "~0.1.7" + +wrap-ansi@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-2.1.0.tgz#d8fc3d284dd05794fe84973caecdd1cf824fdd85" + dependencies: + string-width "^1.0.1" + strip-ansi "^3.0.1" + wrappy@1: version "1.0.2" resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" +xregexp@4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/xregexp/-/xregexp-4.0.0.tgz#e698189de49dd2a18cc5687b05e17c8e43943020" + +xtend@^4.0.0, xtend@~4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/xtend/-/xtend-4.0.1.tgz#a5c6d532be656e23db820efb943a1f04998d63af" + +"y18n@^3.2.1 || ^4.0.0", y18n@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/y18n/-/y18n-4.0.0.tgz#95ef94f85ecc81d007c264e190a120f0a3c8566b" + +yallist@^2.1.2: + version "2.1.2" + resolved "https://registry.yarnpkg.com/yallist/-/yallist-2.1.2.tgz#1c11f9218f076089a47dd512f93c6699a6a81d52" + +yallist@^3.0.0, yallist@^3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/yallist/-/yallist-3.0.2.tgz#8452b4bb7e83c7c188d8041c1a837c773d6d8bb9" + +yargs-parser@^10.1.0: + version "10.1.0" + resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-10.1.0.tgz#7202265b89f7e9e9f2e5765e0fe735a905edbaa8" + dependencies: + camelcase "^4.1.0" + +yargs@^12.0.1: + version "12.0.1" + resolved "https://registry.yarnpkg.com/yargs/-/yargs-12.0.1.tgz#6432e56123bb4e7c3562115401e98374060261c2" + dependencies: + cliui "^4.0.0" + decamelize "^2.0.0" + find-up "^3.0.0" + get-caller-file "^1.0.1" + os-locale "^2.0.0" + require-directory "^2.1.1" + require-main-filename "^1.0.1" + set-blocking "^2.0.0" + string-width "^2.0.0" + which-module "^2.0.0" + y18n "^3.2.1 || ^4.0.0" + yargs-parser "^10.1.0" + zone.js@0.7.6: version "0.7.6" resolved "https://registry.yarnpkg.com/zone.js/-/zone.js-0.7.6.tgz#fbbc39d3e0261d0986f1ba06306eb3aeb0d22009" From c0d9a50ef372ba8692dd7700288d2cb85967cf13 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Moreno?= Date: Tue, 7 Aug 2018 17:20:12 +0200 Subject: [PATCH 0551/1276] update inno setup message related to #55840 --- build/win32/code.iss | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/build/win32/code.iss b/build/win32/code.iss index baca2f28cbd..4be0ea854b5 100644 --- a/build/win32/code.iss +++ b/build/win32/code.iss @@ -975,7 +975,7 @@ begin RegKey := 'SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\' + copy('{#IncompatibleTargetAppId}', 2, 38) + '_is1'; if RegKeyExists({#IncompatibleArchRootKey}, RegKey) then begin - if MsgBox('{#NameShort} is already installed on this system for all users. Note that both versions will be installed simultaneously; you might want to first uninstall the system-wide installation. Are you sure you want to continue?', mbConfirmation, MB_YESNO) = IDNO then begin + if MsgBox('{#NameShort} is already installed on this system for all users. We recommend first uninstalling that version before installing this one. Are you sure you want to continue the installation?', mbConfirmation, MB_YESNO) = IDNO then begin Result := false; end; end; @@ -1139,4 +1139,4 @@ end; #ifdef Debug #expr SaveToFile(AddBackslash(SourcePath) + "code-processed.iss") -#endif \ No newline at end of file +#endif From ac60be30a7283ab21d67ad640b8702bd7751d6ef Mon Sep 17 00:00:00 2001 From: Benjamin Pasero Date: Tue, 7 Aug 2018 17:30:47 +0200 Subject: [PATCH 0552/1276] :lipstick: --- src/vs/workbench/browser/parts/editor/breadcrumbsControl.ts | 3 ++- src/vs/workbench/browser/parts/editor/editorGroupView.ts | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/src/vs/workbench/browser/parts/editor/breadcrumbsControl.ts b/src/vs/workbench/browser/parts/editor/breadcrumbsControl.ts index 16a103c59d0..ad040a10a27 100644 --- a/src/vs/workbench/browser/parts/editor/breadcrumbsControl.ts +++ b/src/vs/workbench/browser/parts/editor/breadcrumbsControl.ts @@ -365,7 +365,8 @@ export class BreadcrumbsControl { MenuRegistry.appendMenuItem(MenuId.CommandPalette, { command: { id: 'breadcrumbs.toggle', - title: localize('cmd.toggle', "Toggle Breadcrumbs") + title: localize('cmd.toggle', "Toggle Breadcrumbs"), + category: localize('cmd.category', "View") } }); MenuRegistry.appendMenuItem(MenuId.MenubarViewMenu, { diff --git a/src/vs/workbench/browser/parts/editor/editorGroupView.ts b/src/vs/workbench/browser/parts/editor/editorGroupView.ts index f699ad2c76a..2f4c869314a 100644 --- a/src/vs/workbench/browser/parts/editor/editorGroupView.ts +++ b/src/vs/workbench/browser/parts/editor/editorGroupView.ts @@ -958,7 +958,7 @@ export class EditorGroupView extends Themable implements IEditorGroupView { this.doCloseInactiveEditor(editor); } - // Forward to title control & breadcrumbs + // Forward to title control this.titleAreaControl.closeEditor(editor); } From 6f3f9edcfa917530562d83bc4744fcdbe9159404 Mon Sep 17 00:00:00 2001 From: Benjamin Pasero Date: Tue, 7 Aug 2018 18:04:50 +0200 Subject: [PATCH 0553/1276] Add a command to open a new window as tab (Sierra tabs) (fixes #25919) --- src/vs/code/electron-main/menubar.ts | 1 + src/vs/code/electron-main/window.ts | 6 ++++ src/vs/code/electron-main/windows.ts | 29 +++++++++++++++---- src/vs/platform/windows/common/windows.ts | 1 + src/vs/platform/windows/common/windowsIpc.ts | 6 ++++ .../platform/windows/electron-main/windows.ts | 4 +++ .../windows/electron-main/windowsService.ts | 10 +++++++ src/vs/workbench/electron-browser/actions.ts | 18 ++++++++++++ .../workbench/electron-browser/workbench.ts | 3 +- .../workbench/test/workbenchTestServices.ts | 4 +++ 10 files changed, 76 insertions(+), 6 deletions(-) diff --git a/src/vs/code/electron-main/menubar.ts b/src/vs/code/electron-main/menubar.ts index b4bd6f0412b..1e9c908a4e3 100644 --- a/src/vs/code/electron-main/menubar.ts +++ b/src/vs/code/electron-main/menubar.ts @@ -607,6 +607,7 @@ export class Menubar { if (this.currentEnableNativeTabs) { const hasMultipleWindows = this.windowsMainService.getWindowCount() > 1; + this.nativeTabMenuItems.push(this.createMenuItem(nls.localize('mNewTab', "New Tab"), 'workbench.action.newWindowTab')); this.nativeTabMenuItems.push(this.createMenuItem(nls.localize('mShowPreviousTab', "Show Previous Tab"), 'workbench.action.showPreviousWindowTab', hasMultipleWindows)); this.nativeTabMenuItems.push(this.createMenuItem(nls.localize('mShowNextTab', "Show Next Tab"), 'workbench.action.showNextWindowTab', hasMultipleWindows)); this.nativeTabMenuItems.push(this.createMenuItem(nls.localize('mMoveTabToNewWindow', "Move Tab to New Window"), 'workbench.action.moveWindowTabToNewWindow', hasMultipleWindows)); diff --git a/src/vs/code/electron-main/window.ts b/src/vs/code/electron-main/window.ts index a3cd3bc01d4..d0151137c0b 100644 --- a/src/vs/code/electron-main/window.ts +++ b/src/vs/code/electron-main/window.ts @@ -500,6 +500,12 @@ export class CodeWindow implements ICodeWindow { }); } + addTabbedWindow(window: ICodeWindow): void { + if (isMacintosh) { + this._win.addTabbedWindow(window.win); + } + } + load(config: IWindowConfiguration, isReload?: boolean, disableExtensions?: boolean): void { // If this is the first time the window is loaded, we associate the paths diff --git a/src/vs/code/electron-main/windows.ts b/src/vs/code/electron-main/windows.ts index 482676324a4..e4e44ab6d10 100644 --- a/src/vs/code/electron-main/windows.ts +++ b/src/vs/code/electron-main/windows.ts @@ -81,6 +81,7 @@ interface IOpenBrowserWindowOptions { filesToWait?: IPathsToWaitFor; forceNewWindow?: boolean; + forceNewTabbedWindow?: boolean; windowToUse?: ICodeWindow; emptyWindowBackupFolder?: string; @@ -546,7 +547,7 @@ export class WindowsManager implements IWindowsMainService { // Special case: we started with --wait and we got back a folder to open. In this case // we actually prefer to not open the folder but operate purely on the file. if (typeof bestWindowOrFolder === 'string' && filesToWait) { - //TODO: #54483 Ben This should not happen + //TODO@Ben: #54483 This should not happen console.error(`This should not happen`, bestWindowOrFolder, WindowsManager.WINDOWS); bestWindowOrFolder = !openFilesInNewWindow ? this.getLastActiveWindow() : null; } @@ -580,7 +581,7 @@ export class WindowsManager implements IWindowsMainService { // We found a suitable folder to open: add it to foldersToOpen else if (typeof bestWindowOrFolder === 'string') { - //TODO: #54483 Ben This should not happen + //TODO@Ben: #54483 Ben This should not happen // foldersToOpen.push(bestWindowOrFolder); console.error(`This should not happen`, bestWindowOrFolder, WindowsManager.WINDOWS); } @@ -595,7 +596,8 @@ export class WindowsManager implements IWindowsMainService { filesToCreate, filesToDiff, filesToWait, - forceNewWindow: true + forceNewWindow: true, + forceNewTabbedWindow: openConfig.forceNewTabbedWindow })); // Reset these because we handled them @@ -700,6 +702,7 @@ export class WindowsManager implements IWindowsMainService { filesToDiff, filesToWait, forceNewWindow: true, + forceNewTabbedWindow: openConfig.forceNewTabbedWindow, emptyWindowBackupFolder })); @@ -720,7 +723,8 @@ export class WindowsManager implements IWindowsMainService { userEnv: openConfig.userEnv, cli: openConfig.cli, initialStartup: openConfig.initialStartup, - forceNewWindow: openFolderInNewWindow + forceNewWindow: openFolderInNewWindow, + forceNewTabbedWindow: openConfig.forceNewTabbedWindow })); openFolderInNewWindow = true; // any other window to open must open in new window then @@ -767,6 +771,7 @@ export class WindowsManager implements IWindowsMainService { filesToDiff, filesToWait, forceNewWindow, + forceNewTabbedWindow: openConfig.forceNewTabbedWindow, windowToUse }); @@ -1128,6 +1133,7 @@ export class WindowsManager implements IWindowsMainService { } private openInBrowserWindow(options: IOpenBrowserWindowOptions): ICodeWindow { + // Build IWindowConfiguration from config and options const configuration: IWindowConfiguration = mixin({}, options.cli); // inherit all properties from CLI configuration.appRoot = this.environmentService.appRoot; @@ -1152,7 +1158,7 @@ export class WindowsManager implements IWindowsMainService { } let window: ICodeWindow; - if (!options.forceNewWindow) { + if (!options.forceNewWindow && !options.forceNewTabbedWindow) { window = options.windowToUse || this.getLastActiveWindow(); if (window) { window.focus(); @@ -1179,12 +1185,21 @@ export class WindowsManager implements IWindowsMainService { state.mode = WindowMode.Normal; } + // Create the window window = this.instantiationService.createInstance(CodeWindow, { state, extensionDevelopmentPath: configuration.extensionDevelopmentPath, isExtensionTestHost: !!configuration.extensionTestsPath }); + // Add as window tab if configured (macOS only) + if (options.forceNewTabbedWindow) { + const activeWindow = this.getLastActiveWindow(); + if (activeWindow) { + activeWindow.addTabbedWindow(window); + } + } + // Add to our list of windows WindowsManager.WINDOWS.push(window); @@ -1475,6 +1490,10 @@ export class WindowsManager implements IWindowsMainService { return this.open({ context, cli: this.environmentService.args, forceNewWindow: true, forceEmpty: true }); } + openNewTabbedWindow(context: OpenContext): ICodeWindow[] { + return this.open({ context, cli: this.environmentService.args, forceNewTabbedWindow: true, forceEmpty: true }); + } + waitForWindowCloseOrLoad(windowId: number): TPromise { return new TPromise(c => { function handler(id: number) { diff --git a/src/vs/platform/windows/common/windows.ts b/src/vs/platform/windows/common/windows.ts index d5ce1f512ac..0a289de0b97 100644 --- a/src/vs/platform/windows/common/windows.ts +++ b/src/vs/platform/windows/common/windows.ts @@ -143,6 +143,7 @@ export interface IWindowsService { relaunch(options: { addArgs?: string[], removeArgs?: string[] }): TPromise; // macOS Native Tabs + newWindowTab(): TPromise; showPreviousWindowTab(): TPromise; showNextWindowTab(): TPromise; moveWindowTabToNewWindow(): TPromise; diff --git a/src/vs/platform/windows/common/windowsIpc.ts b/src/vs/platform/windows/common/windowsIpc.ts index 30c4b7527fd..09a3958cc3b 100644 --- a/src/vs/platform/windows/common/windowsIpc.ts +++ b/src/vs/platform/windows/common/windowsIpc.ts @@ -44,6 +44,7 @@ export interface IWindowsChannel extends IChannel { call(command: 'removeFromRecentlyOpened', arg: (IWorkspaceIdentifier | ISingleFolderWorkspaceIdentifier | string)[]): TPromise; call(command: 'clearRecentlyOpened'): TPromise; call(command: 'getRecentlyOpened', arg: number): TPromise; + call(command: 'newWindowTab'): TPromise; call(command: 'showPreviousWindowTab'): TPromise; call(command: 'showNextWindowTab'): TPromise; call(command: 'moveWindowTabToNewWindow'): TPromise; @@ -147,6 +148,7 @@ export class WindowsChannel implements IWindowsChannel { return this.service.removeFromRecentlyOpened(paths); } case 'clearRecentlyOpened': return this.service.clearRecentlyOpened(); + case 'newWindowTab': return this.service.newWindowTab(); case 'showPreviousWindowTab': return this.service.showPreviousWindowTab(); case 'showNextWindowTab': return this.service.showNextWindowTab(); case 'moveWindowTabToNewWindow': return this.service.moveWindowTabToNewWindow(); @@ -280,6 +282,10 @@ export class WindowsChannelClient implements IWindowsService { }); } + newWindowTab(): TPromise { + return this.channel.call('newWindowTab'); + } + showPreviousWindowTab(): TPromise { return this.channel.call('showPreviousWindowTab'); } diff --git a/src/vs/platform/windows/electron-main/windows.ts b/src/vs/platform/windows/electron-main/windows.ts index 1c38b451768..20b7711912c 100644 --- a/src/vs/platform/windows/electron-main/windows.ts +++ b/src/vs/platform/windows/electron-main/windows.ts @@ -48,6 +48,8 @@ export interface ICodeWindow { readyState: ReadyState; ready(): TPromise; + addTabbedWindow(window: ICodeWindow): void; + load(config: IWindowConfiguration, isReload?: boolean, disableExtensions?: boolean): void; reload(configuration?: IWindowConfiguration, cli?: ParsedArgs): void; @@ -110,6 +112,7 @@ export interface IWindowsMainService { getLastActiveWindow(): ICodeWindow; waitForWindowCloseOrLoad(windowId: number): TPromise; openNewWindow(context: OpenContext): ICodeWindow[]; + openNewTabbedWindow(context: OpenContext): ICodeWindow[]; sendToFocused(channel: string, ...args: any[]): void; sendToAll(channel: string, payload: any, windowIdsToIgnore?: number[]): void; getFocusedWindow(): ICodeWindow; @@ -127,6 +130,7 @@ export interface IOpenConfiguration { urisToOpen?: URI[]; preferNewWindow?: boolean; forceNewWindow?: boolean; + forceNewTabbedWindow?: boolean; forceReuseWindow?: boolean; forceEmpty?: boolean; diffMode?: boolean; diff --git a/src/vs/platform/windows/electron-main/windowsService.ts b/src/vs/platform/windows/electron-main/windowsService.ts index 1cf5341aac2..25960e94c67 100644 --- a/src/vs/platform/windows/electron-main/windowsService.ts +++ b/src/vs/platform/windows/electron-main/windowsService.ts @@ -258,6 +258,14 @@ export class WindowsService implements IWindowsService, IURLHandler, IDisposable return TPromise.as(this.historyService.getRecentlyOpened()); } + newWindowTab(): TPromise { + this.logService.trace('windowsService#newWindowTab'); + + this.windowsMainService.openNewTabbedWindow(OpenContext.API); + + return TPromise.as(void 0); + } + showPreviousWindowTab(): TPromise { this.logService.trace('windowsService#showPreviousWindowTab'); Menu.sendActionToFirstResponder('selectPreviousTab:'); @@ -413,7 +421,9 @@ export class WindowsService implements IWindowsService, IURLHandler, IDisposable openNewWindow(): TPromise { this.logService.trace('windowsService#openNewWindow'); + this.windowsMainService.openNewWindow(OpenContext.API); + return TPromise.as(null); } diff --git a/src/vs/workbench/electron-browser/actions.ts b/src/vs/workbench/electron-browser/actions.ts index 161acfd709d..a05268d666f 100644 --- a/src/vs/workbench/electron-browser/actions.ts +++ b/src/vs/workbench/electron-browser/actions.ts @@ -1459,6 +1459,24 @@ export class DecreaseViewSizeAction extends BaseResizeViewAction { } } +export class NewWindowTab extends Action { + + static readonly ID = 'workbench.action.newWindowTab'; + static readonly LABEL = nls.localize('newTab', "New Window Tab"); + + constructor( + id: string, + label: string, + @IWindowsService private windowsService: IWindowsService + ) { + super(NewWindowTab.ID, NewWindowTab.LABEL); + } + + run(): TPromise { + return this.windowsService.newWindowTab().then(() => true); + } +} + export class ShowPreviousWindowTab extends Action { static readonly ID = 'workbench.action.showPreviousWindowTab'; diff --git a/src/vs/workbench/electron-browser/workbench.ts b/src/vs/workbench/electron-browser/workbench.ts index da185db3fc8..dae70324dbf 100644 --- a/src/vs/workbench/electron-browser/workbench.ts +++ b/src/vs/workbench/electron-browser/workbench.ts @@ -84,7 +84,7 @@ import { MenuService } from 'vs/workbench/services/actions/common/menuService'; import { IContextMenuService, IContextViewService } from 'vs/platform/contextview/browser/contextView'; import { IEnvironmentService } from 'vs/platform/environment/common/environment'; import { IWorkbenchActionRegistry, Extensions } from 'vs/workbench/common/actions'; -import { OpenRecentAction, ToggleDevToolsAction, ReloadWindowAction, ShowPreviousWindowTab, MoveWindowTabToNewWindow, MergeAllWindowTabs, ShowNextWindowTab, ToggleWindowTabsBar, ReloadWindowWithExtensionsDisabledAction } from 'vs/workbench/electron-browser/actions'; +import { OpenRecentAction, ToggleDevToolsAction, ReloadWindowAction, ShowPreviousWindowTab, MoveWindowTabToNewWindow, MergeAllWindowTabs, ShowNextWindowTab, ToggleWindowTabsBar, ReloadWindowWithExtensionsDisabledAction, NewWindowTab } from 'vs/workbench/electron-browser/actions'; import { KeyMod, KeyCode } from 'vs/base/common/keyCodes'; import { IWorkspaceEditingService } from 'vs/workbench/services/workspace/common/workspaceEditing'; import { WorkspaceEditingService } from 'vs/workbench/services/workspace/node/workspaceEditingService'; @@ -317,6 +317,7 @@ export class Workbench extends Disposable implements IPartService { // Actions for macOS native tabs management (only when enabled) const windowConfig = this.configurationService.getValue(); if (windowConfig && windowConfig.window && windowConfig.window.nativeTabs) { + registry.registerWorkbenchAction(new SyncActionDescriptor(NewWindowTab, NewWindowTab.ID, NewWindowTab.LABEL), 'New Window Tab'); registry.registerWorkbenchAction(new SyncActionDescriptor(ShowPreviousWindowTab, ShowPreviousWindowTab.ID, ShowPreviousWindowTab.LABEL), 'Show Previous Window Tab'); registry.registerWorkbenchAction(new SyncActionDescriptor(ShowNextWindowTab, ShowNextWindowTab.ID, ShowNextWindowTab.LABEL), 'Show Next Window Tab'); registry.registerWorkbenchAction(new SyncActionDescriptor(MoveWindowTabToNewWindow, MoveWindowTabToNewWindow.ID, MoveWindowTabToNewWindow.LABEL), 'Move Window Tab to New Window'); diff --git a/src/vs/workbench/test/workbenchTestServices.ts b/src/vs/workbench/test/workbenchTestServices.ts index ef4a6a4501f..326271a125f 100644 --- a/src/vs/workbench/test/workbenchTestServices.ts +++ b/src/vs/workbench/test/workbenchTestServices.ts @@ -1292,6 +1292,10 @@ export class TestWindowsService implements IWindowsService { return TPromise.as(void 0); } + newWindowTab(): TPromise { + return TPromise.as(void 0); + } + showPreviousWindowTab(): TPromise { return TPromise.as(void 0); } From 869dafb1bcf1c4620ba83d161195d832b33f261d Mon Sep 17 00:00:00 2001 From: Krzysztof Cieslak Date: Tue, 7 Aug 2018 19:20:18 +0200 Subject: [PATCH 0554/1276] Make sure prefix detection starts from start of the file name --- .../parts/files/electron-browser/fileActions.ts | 4 ++-- .../files/test/electron-browser/fileActions.test.ts | 12 ++++++++++++ 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/src/vs/workbench/parts/files/electron-browser/fileActions.ts b/src/vs/workbench/parts/files/electron-browser/fileActions.ts index 04b6594db4e..1c10b800ef4 100644 --- a/src/vs/workbench/parts/files/electron-browser/fileActions.ts +++ b/src/vs/workbench/parts/files/electron-browser/fileActions.ts @@ -1049,7 +1049,7 @@ export function incrementFileName(name: string, isFolder: boolean): string { } // 1.file.txt=>2.file.txt - let prefixFileRegex = RegExp('(\\d+)(' + separators + '.*)(\\..*)$'); + let prefixFileRegex = RegExp('^(\\d+)(' + separators + '.*)(\\..*)$'); if (!isFolder && name.match(prefixFileRegex)) { return name.replace(prefixFileRegex, (match, g1?, g2?, g3?) => { let number = parseInt(g1); @@ -1060,7 +1060,7 @@ export function incrementFileName(name: string, isFolder: boolean): string { } // 1.txt=>2.txt - let prefixFileNoNameRegex = RegExp('(\\d+)(\\..*)$'); + let prefixFileNoNameRegex = RegExp('^(\\d+)(\\..*)$'); if (!isFolder && name.match(prefixFileNoNameRegex)) { return name.replace(prefixFileNoNameRegex, (match, g1?, g2?) => { let number = parseInt(g1); diff --git a/src/vs/workbench/parts/files/test/electron-browser/fileActions.test.ts b/src/vs/workbench/parts/files/test/electron-browser/fileActions.test.ts index 48bd1f7cc23..60120a22edd 100644 --- a/src/vs/workbench/parts/files/test/electron-browser/fileActions.test.ts +++ b/src/vs/workbench/parts/files/test/electron-browser/fileActions.test.ts @@ -106,12 +106,24 @@ suite('Files - Increment file name', () => { assert.strictEqual(result, '2.test.js'); }); + test('Increment file name with prefix version - check if starting from digit', function () { + const name = 'F1.test.js'; + const result = incrementFileName(name, false); + assert.strictEqual(result, 'F1.test.1.js'); + }); + test('Increment file name with just version in name', function () { const name = '1.js'; const result = incrementFileName(name, false); assert.strictEqual(result, '2.js'); }); + test('Increment file name with just version in name - check if starting from digit', function () { + const name = 'F1.js'; + const result = incrementFileName(name, false); + assert.strictEqual(result, 'F1.1.js'); + }); + test('Increment file name with just version in name, too big number', function () { const name = '9007199254740992.js'; const result = incrementFileName(name, false); From dc3747c382200a5546372274f6bba19a35051b2f Mon Sep 17 00:00:00 2001 From: Rob Lourens Date: Tue, 7 Aug 2018 10:55:03 -0700 Subject: [PATCH 0555/1276] Fix #55593 - this code only operates on local paths, so use fsPath and Uri.file instead --- extensions/search-rg/src/utils.ts | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/extensions/search-rg/src/utils.ts b/extensions/search-rg/src/utils.ts index fd083fe075f..d06e4f1ab8a 100644 --- a/extensions/search-rg/src/utils.ts +++ b/extensions/search-rg/src/utils.ts @@ -20,8 +20,6 @@ export function anchorGlob(glob: string): string { } export function joinPath(resource: vscode.Uri, pathFragment: string): vscode.Uri { - const joinedPath = path.join(resource.path || '/', pathFragment); - return resource.with({ - path: joinedPath - }); + const joinedPath = path.join(resource.fsPath || '/', pathFragment); + return vscode.Uri.file(joinedPath); } From 92521b228673cbcb5b7f2642ae156c3f4c9b34ef Mon Sep 17 00:00:00 2001 From: SteVen Batten <6561887+sbatten@users.noreply.github.com> Date: Tue, 7 Aug 2018 11:13:08 -0700 Subject: [PATCH 0556/1276] Bring back the old menu due to electron 2.0 issues (#55913) * add the old menu back for native menus * make menu labels match --- src/vs/code/electron-main/app.ts | 9 + src/vs/code/electron-main/keyboard.ts | 114 +- src/vs/code/electron-main/menus.ts | 1319 +++++++++++++++++ .../menubar/electron-main/menubarService.ts | 5 +- .../parts/menubar/menubar.contribution.ts | 4 +- .../browser/parts/menubar/menubarPart.ts | 64 +- 6 files changed, 1480 insertions(+), 35 deletions(-) create mode 100644 src/vs/code/electron-main/menus.ts diff --git a/src/vs/code/electron-main/app.ts b/src/vs/code/electron-main/app.ts index 1b10a58da57..a52ce64b90d 100644 --- a/src/vs/code/electron-main/app.ts +++ b/src/vs/code/electron-main/app.ts @@ -64,6 +64,7 @@ import { IMenubarService } from 'vs/platform/menubar/common/menubar'; import { MenubarService } from 'vs/platform/menubar/electron-main/menubarService'; import { MenubarChannel } from 'vs/platform/menubar/common/menubarIpc'; import { IUriDisplayService } from 'vs/platform/uriDisplay/common/uriDisplay'; +import { CodeMenu } from 'vs/code/electron-main/menus'; export class CodeApplication { @@ -515,6 +516,14 @@ export class CodeApplication { } } + // TODO@sbatten: Remove when switching back to dynamic menu + // Install Menu + const instantiationService = accessor.get(IInstantiationService); + const configurationService = accessor.get(IConfigurationService); + if (platform.isMacintosh || configurationService.getValue('window.titleBarStyle') !== 'custom') { + instantiationService.createInstance(CodeMenu); + } + // Jump List this.historyMainService.updateWindowsJumpList(); this.historyMainService.onRecentlyOpenedChange(() => this.historyMainService.updateWindowsJumpList()); diff --git a/src/vs/code/electron-main/keyboard.ts b/src/vs/code/electron-main/keyboard.ts index 9400d80b5a1..ecd7e284db6 100644 --- a/src/vs/code/electron-main/keyboard.ts +++ b/src/vs/code/electron-main/keyboard.ts @@ -7,7 +7,14 @@ import * as nativeKeymap from 'native-keymap'; import { IDisposable } from 'vs/base/common/lifecycle'; -import { Emitter } from 'vs/base/common/event'; +import { IStateService } from 'vs/platform/state/common/state'; +import { Event, Emitter, once } from 'vs/base/common/event'; +import { ConfigWatcher } from 'vs/base/node/config'; +import { IUserFriendlyKeybinding } from 'vs/platform/keybinding/common/keybinding'; +import { IEnvironmentService } from 'vs/platform/environment/common/environment'; +import { ipcMain as ipc } from 'electron'; +import { IWindowsMainService } from 'vs/platform/windows/electron-main/windows'; +import { ILogService } from 'vs/platform/log/common/log'; export class KeyboardLayoutMonitor { @@ -31,4 +38,109 @@ export class KeyboardLayoutMonitor { } return this._emitter.event(callback); } +} + +export interface IKeybinding { + id: string; + label: string; + isNative: boolean; +} + +export class KeybindingsResolver { + + private static readonly lastKnownKeybindingsMapStorageKey = 'lastKnownKeybindings'; + + private commandIds: Set; + private keybindings: { [commandId: string]: IKeybinding }; + private keybindingsWatcher: ConfigWatcher; + + private _onKeybindingsChanged = new Emitter(); + onKeybindingsChanged: Event = this._onKeybindingsChanged.event; + + constructor( + @IStateService private stateService: IStateService, + @IEnvironmentService environmentService: IEnvironmentService, + @IWindowsMainService private windowsMainService: IWindowsMainService, + @ILogService private logService: ILogService + ) { + this.commandIds = new Set(); + this.keybindings = this.stateService.getItem<{ [id: string]: string; }>(KeybindingsResolver.lastKnownKeybindingsMapStorageKey) || Object.create(null); + this.keybindingsWatcher = new ConfigWatcher(environmentService.appKeybindingsPath, { changeBufferDelay: 100, onError: error => this.logService.error(error) }); + + this.registerListeners(); + } + + private registerListeners(): void { + + // Listen to resolved keybindings from window + ipc.on('vscode:keybindingsResolved', (event, rawKeybindings: string) => { + let keybindings: IKeybinding[] = []; + try { + keybindings = JSON.parse(rawKeybindings); + } catch (error) { + // Should not happen + } + + // Fill hash map of resolved keybindings and check for changes + let keybindingsChanged = false; + let keybindingsCount = 0; + const resolvedKeybindings: { [commandId: string]: IKeybinding } = Object.create(null); + keybindings.forEach(keybinding => { + keybindingsCount++; + + resolvedKeybindings[keybinding.id] = keybinding; + + if (!this.keybindings[keybinding.id] || keybinding.label !== this.keybindings[keybinding.id].label) { + keybindingsChanged = true; + } + }); + + // A keybinding might have been unassigned, so we have to account for that too + if (Object.keys(this.keybindings).length !== keybindingsCount) { + keybindingsChanged = true; + } + + if (keybindingsChanged) { + this.keybindings = resolvedKeybindings; + this.stateService.setItem(KeybindingsResolver.lastKnownKeybindingsMapStorageKey, this.keybindings); // keep to restore instantly after restart + + this._onKeybindingsChanged.fire(); + } + }); + + // Resolve keybindings when any first window is loaded + const onceOnWindowReady = once(this.windowsMainService.onWindowReady); + onceOnWindowReady(win => this.resolveKeybindings(win)); + + // Resolve keybindings again when keybindings.json changes + this.keybindingsWatcher.onDidUpdateConfiguration(() => this.resolveKeybindings()); + + // Resolve keybindings when window reloads because an installed extension could have an impact + this.windowsMainService.onWindowReload(() => this.resolveKeybindings()); + } + + private resolveKeybindings(win = this.windowsMainService.getLastActiveWindow()): void { + if (this.commandIds.size && win) { + const commandIds: string[] = []; + this.commandIds.forEach(id => commandIds.push(id)); + win.sendWhenReady('vscode:resolveKeybindings', JSON.stringify(commandIds)); + } + } + + public getKeybinding(commandId: string): IKeybinding { + if (!commandId) { + return void 0; + } + + if (!this.commandIds.has(commandId)) { + this.commandIds.add(commandId); + } + + return this.keybindings[commandId]; + } + + public dispose(): void { + this._onKeybindingsChanged.dispose(); + this.keybindingsWatcher.dispose(); + } } \ No newline at end of file diff --git a/src/vs/code/electron-main/menus.ts b/src/vs/code/electron-main/menus.ts new file mode 100644 index 00000000000..093d44f0587 --- /dev/null +++ b/src/vs/code/electron-main/menus.ts @@ -0,0 +1,1319 @@ +/*--------------------------------------------------------------------------------------------- + * 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 * as nls from 'vs/nls'; +import { isMacintosh, isLinux, isWindows, language } from 'vs/base/common/platform'; +import * as arrays from 'vs/base/common/arrays'; +import { IEnvironmentService } from 'vs/platform/environment/common/environment'; +import { app, shell, Menu, MenuItem, BrowserWindow } from 'electron'; +import { OpenContext, IRunActionInWindowRequest, IWindowsService } from 'vs/platform/windows/common/windows'; +import { IConfigurationService, IConfigurationChangeEvent } from 'vs/platform/configuration/common/configuration'; +import { AutoSaveConfiguration } from 'vs/platform/files/common/files'; +import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry'; +import { IUpdateService, StateType } from 'vs/platform/update/common/update'; +import product from 'vs/platform/node/product'; +import { RunOnceScheduler } from 'vs/base/common/async'; +import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; +import { mnemonicMenuLabel as baseMnemonicLabel, unmnemonicLabel } from 'vs/base/common/labels'; +import { KeybindingsResolver } from 'vs/code/electron-main/keyboard'; +import { IWindowsMainService, IWindowsCountChangedEvent } from 'vs/platform/windows/electron-main/windows'; +import { IHistoryMainService } from 'vs/platform/history/common/history'; +import { IWorkspaceIdentifier, getWorkspaceLabel, ISingleFolderWorkspaceIdentifier, isSingleFolderWorkspaceIdentifier, isWorkspaceIdentifier } from 'vs/platform/workspaces/common/workspaces'; +import URI from 'vs/base/common/uri'; +import { IUriDisplayService } from 'vs/platform/uriDisplay/common/uriDisplay'; + +interface IMenuItemClickHandler { + inDevTools: (contents: Electron.WebContents) => void; + inNoWindow: () => void; +} + +const telemetryFrom = 'menu'; + +export class CodeMenu { + + private static readonly MAX_MENU_RECENT_ENTRIES = 10; + + private keys = [ + 'files.autoSave', + 'editor.multiCursorModifier', + 'workbench.sideBar.location', + 'workbench.statusBar.visible', + 'workbench.activityBar.visible', + 'window.enableMenuBarMnemonics', + 'window.nativeTabs' + ]; + + private isQuitting: boolean; + private appMenuInstalled: boolean; + + private menuUpdater: RunOnceScheduler; + + private keybindingsResolver: KeybindingsResolver; + + private closeFolder: Electron.MenuItem; + private closeWorkspace: Electron.MenuItem; + + private nativeTabMenuItems: Electron.MenuItem[]; + + constructor( + @IUpdateService private updateService: IUpdateService, + @IInstantiationService instantiationService: IInstantiationService, + @IConfigurationService private configurationService: IConfigurationService, + @IWindowsMainService private windowsMainService: IWindowsMainService, + @IWindowsService private windowsService: IWindowsService, + @IEnvironmentService private environmentService: IEnvironmentService, + @ITelemetryService private telemetryService: ITelemetryService, + @IHistoryMainService private historyMainService: IHistoryMainService, + @IUriDisplayService private uriDisplayService: IUriDisplayService + ) { + this.nativeTabMenuItems = []; + + this.menuUpdater = new RunOnceScheduler(() => this.doUpdateMenu(), 0); + this.keybindingsResolver = instantiationService.createInstance(KeybindingsResolver); + + this.install(); + + this.registerListeners(); + } + + private registerListeners(): void { + + // Keep flag when app quits + app.on('will-quit', () => { + this.isQuitting = true; + }); + + // Listen to some events from window service to update menu + this.historyMainService.onRecentlyOpenedChange(() => this.updateMenu()); + this.windowsMainService.onWindowsCountChanged(e => this.onWindowsCountChanged(e)); + this.windowsMainService.onActiveWindowChanged(() => this.updateWorkspaceMenuItems()); + this.windowsMainService.onWindowReady(() => this.updateWorkspaceMenuItems()); + this.windowsMainService.onWindowClose(() => this.updateWorkspaceMenuItems()); + + // Update when auto save config changes + this.configurationService.onDidChangeConfiguration(e => this.onConfigurationUpdated(e)); + + // Listen to update service + this.updateService.onStateChange(() => this.updateMenu()); + + // Listen to keybindings change + this.keybindingsResolver.onKeybindingsChanged(() => this.updateMenu()); + } + + private onConfigurationUpdated(event: IConfigurationChangeEvent): void { + if (this.keys.some(key => event.affectsConfiguration(key))) { + this.updateMenu(); + } + } + + private get currentAutoSaveSetting(): string { + return this.configurationService.getValue('files.autoSave'); + } + + private get currentMultiCursorModifierSetting(): string { + return this.configurationService.getValue('editor.multiCursorModifier'); + } + + private get currentSidebarLocation(): string { + return this.configurationService.getValue('workbench.sideBar.location') || 'left'; + } + + private get currentStatusbarVisible(): boolean { + let statusbarVisible = this.configurationService.getValue('workbench.statusBar.visible'); + if (typeof statusbarVisible !== 'boolean') { + statusbarVisible = true; + } + return statusbarVisible; + } + + private get currentActivityBarVisible(): boolean { + let activityBarVisible = this.configurationService.getValue('workbench.activityBar.visible'); + if (typeof activityBarVisible !== 'boolean') { + activityBarVisible = true; + } + return activityBarVisible; + } + + private get currentEnableMenuBarMnemonics(): boolean { + let enableMenuBarMnemonics = this.configurationService.getValue('window.enableMenuBarMnemonics'); + if (typeof enableMenuBarMnemonics !== 'boolean') { + enableMenuBarMnemonics = true; + } + return enableMenuBarMnemonics; + } + + private get currentEnableNativeTabs(): boolean { + let enableNativeTabs = this.configurationService.getValue('window.nativeTabs'); + if (typeof enableNativeTabs !== 'boolean') { + enableNativeTabs = false; + } + return enableNativeTabs; + } + + private updateMenu(): void { + this.menuUpdater.schedule(); // buffer multiple attempts to update the menu + } + + private doUpdateMenu(): void { + + // Due to limitations in Electron, it is not possible to update menu items dynamically. The suggested + // workaround from Electron is to set the application menu again. + // See also https://github.com/electron/electron/issues/846 + // + // Run delayed to prevent updating menu while it is open + if (!this.isQuitting) { + setTimeout(() => { + if (!this.isQuitting) { + this.install(); + } + }, 10 /* delay this because there is an issue with updating a menu when it is open */); + } + } + + private onWindowsCountChanged(e: IWindowsCountChangedEvent): void { + if (!isMacintosh) { + return; + } + + // Update menu if window count goes from N > 0 or 0 > N to update menu item enablement + if ((e.oldCount === 0 && e.newCount > 0) || (e.oldCount > 0 && e.newCount === 0)) { + this.updateMenu(); + } + + // Update specific items that are dependent on window count + else if (this.currentEnableNativeTabs) { + this.nativeTabMenuItems.forEach(item => { + if (item) { + item.enabled = e.newCount > 1; + } + }); + } + } + + private updateWorkspaceMenuItems(): void { + const window = this.windowsMainService.getLastActiveWindow(); + const isInWorkspaceContext = window && !!window.openedWorkspace; + const isInFolderContext = window && !!window.openedFolderUri; + + this.closeWorkspace.visible = isInWorkspaceContext; + this.closeFolder.visible = !isInWorkspaceContext; + this.closeFolder.enabled = isInFolderContext || isLinux /* https://github.com/Microsoft/vscode/issues/36431 */; + } + + private install(): void { + + // Menus + const menubar = new Menu(); + + // Mac: Application + let macApplicationMenuItem: Electron.MenuItem; + if (isMacintosh) { + const applicationMenu = new Menu(); + macApplicationMenuItem = new MenuItem({ label: product.nameShort, submenu: applicationMenu }); + this.setMacApplicationMenu(applicationMenu); + } + + // File + const fileMenu = new Menu(); + const fileMenuItem = new MenuItem({ label: this.mnemonicLabel(nls.localize({ key: 'mFile', comment: ['&& denotes a mnemonic'] }, "&&File")), submenu: fileMenu }); + this.setFileMenu(fileMenu); + + // Edit + const editMenu = new Menu(); + const editMenuItem = new MenuItem({ label: this.mnemonicLabel(nls.localize({ key: 'mEdit', comment: ['&& denotes a mnemonic'] }, "&&Edit")), submenu: editMenu }); + this.setEditMenu(editMenu); + + // Selection + const selectionMenu = new Menu(); + const selectionMenuItem = new MenuItem({ label: this.mnemonicLabel(nls.localize({ key: 'mSelection', comment: ['&& denotes a mnemonic'] }, "&&Selection")), submenu: selectionMenu }); + this.setSelectionMenu(selectionMenu); + + // View + const viewMenu = new Menu(); + const viewMenuItem = new MenuItem({ label: this.mnemonicLabel(nls.localize({ key: 'mView', comment: ['&& denotes a mnemonic'] }, "&&View")), submenu: viewMenu }); + this.setViewMenu(viewMenu); + + // Goto + const gotoMenu = new Menu(); + const gotoMenuItem = new MenuItem({ label: this.mnemonicLabel(nls.localize({ key: 'mGoto', comment: ['&& denotes a mnemonic'] }, "&&Go")), submenu: gotoMenu }); + this.setGotoMenu(gotoMenu); + + // Terminal + const terminalMenu = new Menu(); + const terminalMenuItem = new MenuItem({ label: this.mnemonicLabel(nls.localize({ key: 'mTerminal', comment: ['&& denotes a mnemonic'] }, "Ter&&minal")), submenu: terminalMenu }); + this.setTerminalMenu(terminalMenu); + + // Debug + const debugMenu = new Menu(); + const debugMenuItem = new MenuItem({ label: this.mnemonicLabel(nls.localize({ key: 'mDebug', comment: ['&& denotes a mnemonic'] }, "&&Debug")), submenu: debugMenu }); + this.setDebugMenu(debugMenu); + + // Mac: Window + let macWindowMenuItem: Electron.MenuItem; + if (isMacintosh) { + const windowMenu = new Menu(); + macWindowMenuItem = new MenuItem({ label: this.mnemonicLabel(nls.localize('mWindow', "Window")), submenu: windowMenu, role: 'window' }); + this.setMacWindowMenu(windowMenu); + } + + // Help + const helpMenu = new Menu(); + const helpMenuItem = new MenuItem({ label: this.mnemonicLabel(nls.localize({ key: 'mHelp', comment: ['&& denotes a mnemonic'] }, "&&Help")), submenu: helpMenu, role: 'help' }); + this.setHelpMenu(helpMenu); + + // Tasks + const taskMenu = new Menu(); + const taskMenuItem = new MenuItem({ label: this.mnemonicLabel(nls.localize({ key: 'mTask', comment: ['&& denotes a mnemonic'] }, "&&Tasks")), submenu: taskMenu }); + this.setTaskMenu(taskMenu); + + // Menu Structure + if (macApplicationMenuItem) { + menubar.append(macApplicationMenuItem); + } + + menubar.append(fileMenuItem); + menubar.append(editMenuItem); + menubar.append(selectionMenuItem); + menubar.append(viewMenuItem); + menubar.append(gotoMenuItem); + menubar.append(terminalMenuItem); + menubar.append(debugMenuItem); + menubar.append(taskMenuItem); + + if (macWindowMenuItem) { + menubar.append(macWindowMenuItem); + } + + menubar.append(helpMenuItem); + + Menu.setApplicationMenu(menubar); + + // Dock Menu + if (isMacintosh && !this.appMenuInstalled) { + this.appMenuInstalled = true; + + const dockMenu = new Menu(); + dockMenu.append(new MenuItem({ label: this.mnemonicLabel(nls.localize({ key: 'miNewWindow', comment: ['&& denotes a mnemonic'] }, "New &&Window")), click: () => this.windowsMainService.openNewWindow(OpenContext.DOCK) })); + + app.dock.setMenu(dockMenu); + } + } + + private setMacApplicationMenu(macApplicationMenu: Electron.Menu): void { + const about = new MenuItem({ label: nls.localize('mAbout', "About {0}", product.nameLong), role: 'about' }); + const checkForUpdates = this.getUpdateMenuItems(); + const preferences = this.getPreferencesMenu(); + const servicesMenu = new Menu(); + const services = new MenuItem({ label: nls.localize('mServices', "Services"), role: 'services', submenu: servicesMenu }); + const hide = new MenuItem({ label: nls.localize('mHide', "Hide {0}", product.nameLong), role: 'hide', accelerator: 'Command+H' }); + const hideOthers = new MenuItem({ label: nls.localize('mHideOthers', "Hide Others"), role: 'hideothers', accelerator: 'Command+Alt+H' }); + const showAll = new MenuItem({ label: nls.localize('mShowAll', "Show All"), role: 'unhide' }); + const quit = new MenuItem(this.likeAction('workbench.action.quit', { + label: nls.localize('miQuit', "Quit {0}", product.nameLong), click: () => { + if (this.windowsMainService.getWindowCount() === 0 || !!BrowserWindow.getFocusedWindow()) { + this.windowsMainService.quit(); // fix for https://github.com/Microsoft/vscode/issues/39191 + } + } + })); + + const actions = [about]; + actions.push(...checkForUpdates); + actions.push(...[ + __separator__(), + preferences, + __separator__(), + services, + __separator__(), + hide, + hideOthers, + showAll, + __separator__(), + quit + ]); + + actions.forEach(i => macApplicationMenu.append(i)); + } + + private setFileMenu(fileMenu: Electron.Menu): void { + const hasNoWindows = (this.windowsMainService.getWindowCount() === 0); + + let newFile: Electron.MenuItem; + if (hasNoWindows) { + newFile = new MenuItem(this.likeAction('workbench.action.files.newUntitledFile', { label: this.mnemonicLabel(nls.localize({ key: 'miNewFile', comment: ['&& denotes a mnemonic'] }, "&&New File")), click: () => this.windowsMainService.openNewWindow(OpenContext.MENU) })); + } else { + newFile = this.createMenuItem(nls.localize({ key: 'miNewFile', comment: ['&& denotes a mnemonic'] }, "&&New File"), 'workbench.action.files.newUntitledFile'); + } + + let open: Electron.MenuItem; + if (hasNoWindows) { + open = new MenuItem(this.likeAction('workbench.action.files.openFileFolder', { label: this.mnemonicLabel(nls.localize({ key: 'miOpen', comment: ['&& denotes a mnemonic'] }, "&&Open...")), click: (menuItem, win, event) => this.windowsMainService.pickFileFolderAndOpen({ forceNewWindow: this.isOptionClick(event), telemetryExtraData: { from: telemetryFrom } }) })); + } else { + open = this.createMenuItem(nls.localize({ key: 'miOpen', comment: ['&& denotes a mnemonic'] }, "&&Open..."), ['workbench.action.files.openFileFolder', 'workbench.action.files.openFileFolderInNewWindow']); + } + + let openWorkspace: Electron.MenuItem; + if (hasNoWindows) { + openWorkspace = new MenuItem(this.likeAction('workbench.action.openWorkspace', { label: this.mnemonicLabel(nls.localize({ key: 'miOpenWorkspace', comment: ['&& denotes a mnemonic'] }, "Open Wor&&kspace...")), click: (menuItem, win, event) => this.windowsMainService.pickWorkspaceAndOpen({ forceNewWindow: this.isOptionClick(event), telemetryExtraData: { from: telemetryFrom } }) })); + } else { + openWorkspace = this.createMenuItem(nls.localize({ key: 'miOpenWorkspace', comment: ['&& denotes a mnemonic'] }, "Open Wor&&kspace..."), ['workbench.action.openWorkspace', 'workbench.action.openWorkspaceInNewWindow']); + } + + let openFolder: Electron.MenuItem; + if (hasNoWindows) { + openFolder = new MenuItem(this.likeAction('workbench.action.files.openFolder', { label: this.mnemonicLabel(nls.localize({ key: 'miOpenFolder', comment: ['&& denotes a mnemonic'] }, "Open &&Folder...")), click: (menuItem, win, event) => this.windowsMainService.pickFolderAndOpen({ forceNewWindow: this.isOptionClick(event), telemetryExtraData: { from: telemetryFrom } }) })); + } else { + openFolder = this.createMenuItem(nls.localize({ key: 'miOpenFolder', comment: ['&& denotes a mnemonic'] }, "Open &&Folder..."), ['workbench.action.files.openFolder', 'workbench.action.files.openFolderInNewWindow']); + } + + let openFile: Electron.MenuItem; + if (hasNoWindows) { + openFile = new MenuItem(this.likeAction('workbench.action.files.openFile', { label: this.mnemonicLabel(nls.localize({ key: 'miOpenFile', comment: ['&& denotes a mnemonic'] }, "&&Open File...")), click: (menuItem, win, event) => this.windowsMainService.pickFileAndOpen({ forceNewWindow: this.isOptionClick(event), telemetryExtraData: { from: telemetryFrom } }) })); + } else { + openFile = this.createMenuItem(nls.localize({ key: 'miOpenFile', comment: ['&& denotes a mnemonic'] }, "&&Open File..."), ['workbench.action.files.openFile', 'workbench.action.files.openFileInNewWindow']); + } + + const openRecentMenu = new Menu(); + this.setOpenRecentMenu(openRecentMenu); + const openRecent = new MenuItem({ label: this.mnemonicLabel(nls.localize({ key: 'miOpenRecent', comment: ['&& denotes a mnemonic'] }, "Open &&Recent")), submenu: openRecentMenu, enabled: openRecentMenu.items.length > 0 }); + + const saveWorkspaceAs = this.createMenuItem(nls.localize('miSaveWorkspaceAs', "Save Workspace As..."), 'workbench.action.saveWorkspaceAs'); + const addFolder = this.createMenuItem(nls.localize({ key: 'miAddFolderToWorkspace', comment: ['&& denotes a mnemonic'] }, "A&&dd Folder to Workspace..."), 'workbench.action.addRootFolder'); + + const saveFile = this.createMenuItem(nls.localize({ key: 'miSave', comment: ['&& denotes a mnemonic'] }, "&&Save"), 'workbench.action.files.save'); + const saveFileAs = this.createMenuItem(nls.localize({ key: 'miSaveAs', comment: ['&& denotes a mnemonic'] }, "Save &&As..."), 'workbench.action.files.saveAs'); + const saveAllFiles = this.createMenuItem(nls.localize({ key: 'miSaveAll', comment: ['&& denotes a mnemonic'] }, "Save A&&ll"), 'workbench.action.files.saveAll'); + + const autoSaveEnabled = [AutoSaveConfiguration.AFTER_DELAY, AutoSaveConfiguration.ON_FOCUS_CHANGE, AutoSaveConfiguration.ON_WINDOW_CHANGE].some(s => this.currentAutoSaveSetting === s); + + const autoSave = this.createMenuItem(this.mnemonicLabel(nls.localize('miAutoSave', "Auto Save")), 'workbench.action.toggleAutoSave', this.windowsMainService.getWindowCount() > 0, autoSaveEnabled); + + const preferences = this.getPreferencesMenu(); + + const newWindow = new MenuItem(this.likeAction('workbench.action.newWindow', { label: this.mnemonicLabel(nls.localize({ key: 'miNewWindow', comment: ['&& denotes a mnemonic'] }, "New &&Window")), click: () => this.windowsMainService.openNewWindow(OpenContext.MENU) })); + const revertFile = this.createMenuItem(nls.localize({ key: 'miRevert', comment: ['&& denotes a mnemonic'] }, "Re&&vert File"), 'workbench.action.files.revert'); + const closeWindow = new MenuItem(this.likeAction('workbench.action.closeWindow', { label: this.mnemonicLabel(nls.localize({ key: 'miCloseWindow', comment: ['&& denotes a mnemonic'] }, "Clos&&e Window")), click: () => this.windowsMainService.getLastActiveWindow().win.close(), enabled: this.windowsMainService.getWindowCount() > 0 })); + + this.closeWorkspace = this.createMenuItem(nls.localize({ key: 'miCloseWorkspace', comment: ['&& denotes a mnemonic'] }, "Close &&Workspace"), 'workbench.action.closeFolder'); + this.closeFolder = this.createMenuItem(nls.localize({ key: 'miCloseFolder', comment: ['&& denotes a mnemonic'] }, "Close &&Folder"), 'workbench.action.closeFolder'); + + const closeEditor = this.createMenuItem(nls.localize({ key: 'miCloseEditor', comment: ['&& denotes a mnemonic'] }, "&&Close Editor"), 'workbench.action.closeActiveEditor'); + + const exit = new MenuItem(this.likeAction('workbench.action.quit', { label: this.mnemonicLabel(nls.localize({ key: 'miExit', comment: ['&& denotes a mnemonic'] }, "E&&xit")), click: () => this.windowsMainService.quit() })); + + this.updateWorkspaceMenuItems(); + + arrays.coalesce([ + newFile, + newWindow, + __separator__(), + isMacintosh ? open : null, + !isMacintosh ? openFile : null, + !isMacintosh ? openFolder : null, + openWorkspace, + openRecent, + __separator__(), + addFolder, + saveWorkspaceAs, + __separator__(), + saveFile, + saveFileAs, + saveAllFiles, + __separator__(), + autoSave, + __separator__(), + !isMacintosh ? preferences : null, + !isMacintosh ? __separator__() : null, + revertFile, + closeEditor, + this.closeWorkspace, + this.closeFolder, + closeWindow, + !isMacintosh ? __separator__() : null, + !isMacintosh ? exit : null + ]).forEach(item => fileMenu.append(item)); + } + + private getPreferencesMenu(): Electron.MenuItem { + const settings = this.createMenuItem(nls.localize({ key: 'miOpenSettings', comment: ['&& denotes a mnemonic'] }, "&&Settings"), 'workbench.action.openSettings2'); + const kebindingSettings = this.createMenuItem(nls.localize({ key: 'miOpenKeymap', comment: ['&& denotes a mnemonic'] }, "&&Keyboard Shortcuts"), 'workbench.action.openGlobalKeybindings'); + const keymapExtensions = this.createMenuItem(nls.localize({ key: 'miOpenKeymapExtensions', comment: ['&& denotes a mnemonic'] }, "&&Keymap Extensions"), 'workbench.extensions.action.showRecommendedKeymapExtensions'); + const snippetsSettings = this.createMenuItem(nls.localize({ key: 'miOpenSnippets', comment: ['&& denotes a mnemonic'] }, "User &&Snippets"), 'workbench.action.openSnippets'); + const colorThemeSelection = this.createMenuItem(nls.localize({ key: 'miSelectColorTheme', comment: ['&& denotes a mnemonic'] }, "&&Color Theme"), 'workbench.action.selectTheme'); + const iconThemeSelection = this.createMenuItem(nls.localize({ key: 'miSelectIconTheme', comment: ['&& denotes a mnemonic'] }, "File &&Icon Theme"), 'workbench.action.selectIconTheme'); + + const preferencesMenu = new Menu(); + preferencesMenu.append(settings); + preferencesMenu.append(__separator__()); + preferencesMenu.append(kebindingSettings); + preferencesMenu.append(keymapExtensions); + preferencesMenu.append(__separator__()); + preferencesMenu.append(snippetsSettings); + preferencesMenu.append(__separator__()); + preferencesMenu.append(colorThemeSelection); + preferencesMenu.append(iconThemeSelection); + + return new MenuItem({ label: this.mnemonicLabel(nls.localize({ key: 'miPreferences', comment: ['&& denotes a mnemonic'] }, "&&Preferences")), submenu: preferencesMenu }); + } + + private setOpenRecentMenu(openRecentMenu: Electron.Menu): void { + openRecentMenu.append(this.createMenuItem(nls.localize({ key: 'miReopenClosedEditor', comment: ['&& denotes a mnemonic'] }, "&&Reopen Closed Editor"), 'workbench.action.reopenClosedEditor')); + + const { workspaces, files } = this.historyMainService.getRecentlyOpened(); + + // Workspaces + if (workspaces.length > 0) { + openRecentMenu.append(__separator__()); + + for (let i = 0; i < CodeMenu.MAX_MENU_RECENT_ENTRIES && i < workspaces.length; i++) { + openRecentMenu.append(this.createOpenRecentMenuItem(workspaces[i], 'openRecentWorkspace', false)); + } + } + + // Files + if (files.length > 0) { + openRecentMenu.append(__separator__()); + + for (let i = 0; i < CodeMenu.MAX_MENU_RECENT_ENTRIES && i < files.length; i++) { + openRecentMenu.append(this.createOpenRecentMenuItem(files[i], 'openRecentFile', true)); + } + } + + if (workspaces.length || files.length) { + openRecentMenu.append(__separator__()); + openRecentMenu.append(this.createMenuItem(nls.localize({ key: 'miMore', comment: ['&& denotes a mnemonic'] }, "&&More..."), 'workbench.action.openRecent')); + openRecentMenu.append(__separator__()); + openRecentMenu.append(new MenuItem(this.likeAction('workbench.action.clearRecentFiles', { label: this.mnemonicLabel(nls.localize({ key: 'miClearRecentOpen', comment: ['&& denotes a mnemonic'] }, "&&Clear Recently Opened")), click: () => this.historyMainService.clearRecentlyOpened() }))); + } + } + + private createOpenRecentMenuItem(workspace: IWorkspaceIdentifier | ISingleFolderWorkspaceIdentifier | string, commandId: string, isFile: boolean): Electron.MenuItem { + let label: string; + let uri: URI; + if (isSingleFolderWorkspaceIdentifier(workspace)) { + label = unmnemonicLabel(getWorkspaceLabel(workspace, this.environmentService, this.uriDisplayService, { verbose: true })); + uri = workspace; + } else if (isWorkspaceIdentifier(workspace)) { + label = getWorkspaceLabel(workspace, this.environmentService, this.uriDisplayService, { verbose: true }); + uri = URI.file(workspace.configPath); + } else { + uri = URI.file(workspace); + label = unmnemonicLabel(this.uriDisplayService.getLabel(uri)); + } + + return new MenuItem(this.likeAction(commandId, { + label, + click: (menuItem, win, event) => { + const openInNewWindow = this.isOptionClick(event); + const success = this.windowsMainService.open({ + context: OpenContext.MENU, + cli: this.environmentService.args, + urisToOpen: [uri], + forceNewWindow: openInNewWindow, + forceOpenWorkspaceAsFile: isFile + }).length > 0; + + if (!success) { + this.historyMainService.removeFromRecentlyOpened([workspace]); + } + } + }, false)); + } + + private isOptionClick(event: Electron.Event): boolean { + return event && ((!isMacintosh && (event.ctrlKey || event.shiftKey)) || (isMacintosh && (event.metaKey || event.altKey))); + } + + private createRoleMenuItem(label: string, commandId: string, role: Electron.MenuItemRole): Electron.MenuItem { + const options: Electron.MenuItemConstructorOptions = { + label: this.mnemonicLabel(label), + role, + enabled: true + }; + + return new MenuItem(this.withKeybinding(commandId, options)); + } + + private setEditMenu(winLinuxEditMenu: Electron.Menu): void { + let undo: Electron.MenuItem; + let redo: Electron.MenuItem; + let cut: Electron.MenuItem; + let copy: Electron.MenuItem; + let paste: Electron.MenuItem; + + if (isMacintosh) { + undo = this.createContextAwareMenuItem(nls.localize({ key: 'miUndo', comment: ['&& denotes a mnemonic'] }, "&&Undo"), 'undo', { + inDevTools: devTools => devTools.undo(), + inNoWindow: () => Menu.sendActionToFirstResponder('undo:') + }); + redo = this.createContextAwareMenuItem(nls.localize({ key: 'miRedo', comment: ['&& denotes a mnemonic'] }, "&&Redo"), 'redo', { + inDevTools: devTools => devTools.redo(), + inNoWindow: () => Menu.sendActionToFirstResponder('redo:') + }); + cut = this.createRoleMenuItem(nls.localize({ key: 'miCut', comment: ['&& denotes a mnemonic'] }, "Cu&&t"), 'editor.action.clipboardCutAction', 'cut'); + copy = this.createRoleMenuItem(nls.localize({ key: 'miCopy', comment: ['&& denotes a mnemonic'] }, "&&Copy"), 'editor.action.clipboardCopyAction', 'copy'); + paste = this.createRoleMenuItem(nls.localize({ key: 'miPaste', comment: ['&& denotes a mnemonic'] }, "&&Paste"), 'editor.action.clipboardPasteAction', 'paste'); + } else { + undo = this.createMenuItem(nls.localize({ key: 'miUndo', comment: ['&& denotes a mnemonic'] }, "&&Undo"), 'undo'); + redo = this.createMenuItem(nls.localize({ key: 'miRedo', comment: ['&& denotes a mnemonic'] }, "&&Redo"), 'redo'); + cut = this.createMenuItem(nls.localize({ key: 'miCut', comment: ['&& denotes a mnemonic'] }, "Cu&&t"), 'editor.action.clipboardCutAction'); + copy = this.createMenuItem(nls.localize({ key: 'miCopy', comment: ['&& denotes a mnemonic'] }, "&&Copy"), 'editor.action.clipboardCopyAction'); + paste = this.createMenuItem(nls.localize({ key: 'miPaste', comment: ['&& denotes a mnemonic'] }, "&&Paste"), 'editor.action.clipboardPasteAction'); + } + + const find = this.createMenuItem(nls.localize({ key: 'miFind', comment: ['&& denotes a mnemonic'] }, "&&Find"), 'actions.find'); + const replace = this.createMenuItem(nls.localize({ key: 'miReplace', comment: ['&& denotes a mnemonic'] }, "&&Replace"), 'editor.action.startFindReplaceAction'); + const findInFiles = this.createMenuItem(nls.localize({ key: 'miFindInFiles', comment: ['&& denotes a mnemonic'] }, "Find &&in Files"), 'workbench.action.findInFiles'); + const replaceInFiles = this.createMenuItem(nls.localize({ key: 'miReplaceInFiles', comment: ['&& denotes a mnemonic'] }, "Replace &&in Files"), 'workbench.action.replaceInFiles'); + + const emmetExpandAbbreviation = this.createMenuItem(nls.localize({ key: 'miEmmetExpandAbbreviation', comment: ['&& denotes a mnemonic'] }, "Emmet: E&&xpand Abbreviation"), 'editor.emmet.action.expandAbbreviation'); + const showEmmetCommands = this.createMenuItem(nls.localize({ key: 'miShowEmmetCommands', comment: ['&& denotes a mnemonic'] }, "E&&mmet..."), 'workbench.action.showEmmetCommands'); + const toggleLineComment = this.createMenuItem(nls.localize({ key: 'miToggleLineComment', comment: ['&& denotes a mnemonic'] }, "&&Toggle Line Comment"), 'editor.action.commentLine'); + const toggleBlockComment = this.createMenuItem(nls.localize({ key: 'miToggleBlockComment', comment: ['&& denotes a mnemonic'] }, "Toggle &&Block Comment"), 'editor.action.blockComment'); + + [ + undo, + redo, + __separator__(), + cut, + copy, + paste, + __separator__(), + find, + replace, + __separator__(), + findInFiles, + replaceInFiles, + __separator__(), + toggleLineComment, + toggleBlockComment, + emmetExpandAbbreviation, + showEmmetCommands + ].forEach(item => winLinuxEditMenu.append(item)); + } + + private setSelectionMenu(winLinuxEditMenu: Electron.Menu): void { + let multiCursorModifierLabel: string; + if (this.currentMultiCursorModifierSetting === 'ctrlCmd') { + multiCursorModifierLabel = nls.localize('miMultiCursorAlt', "Switch to Alt+Click for Multi-Cursor"); // The default has been overwritten + } else { + multiCursorModifierLabel = ( + isMacintosh + ? nls.localize('miMultiCursorCmd', "Switch to Cmd+Click for Multi-Cursor") + : nls.localize('miMultiCursorCtrl', "Switch to Ctrl+Click for Multi-Cursor") + ); + } + + const multicursorModifier = this.createMenuItem(multiCursorModifierLabel, 'workbench.action.toggleMultiCursorModifier'); + const insertCursorAbove = this.createMenuItem(nls.localize({ key: 'miInsertCursorAbove', comment: ['&& denotes a mnemonic'] }, "&&Add Cursor Above"), 'editor.action.insertCursorAbove'); + const insertCursorBelow = this.createMenuItem(nls.localize({ key: 'miInsertCursorBelow', comment: ['&& denotes a mnemonic'] }, "A&&dd Cursor Below"), 'editor.action.insertCursorBelow'); + const insertCursorAtEndOfEachLineSelected = this.createMenuItem(nls.localize({ key: 'miInsertCursorAtEndOfEachLineSelected', comment: ['&& denotes a mnemonic'] }, "Add C&&ursors to Line Ends"), 'editor.action.insertCursorAtEndOfEachLineSelected'); + const addSelectionToNextFindMatch = this.createMenuItem(nls.localize({ key: 'miAddSelectionToNextFindMatch', comment: ['&& denotes a mnemonic'] }, "Add &&Next Occurrence"), 'editor.action.addSelectionToNextFindMatch'); + const addSelectionToPreviousFindMatch = this.createMenuItem(nls.localize({ key: 'miAddSelectionToPreviousFindMatch', comment: ['&& denotes a mnemonic'] }, "Add P&&revious Occurrence"), 'editor.action.addSelectionToPreviousFindMatch'); + const selectHighlights = this.createMenuItem(nls.localize({ key: 'miSelectHighlights', comment: ['&& denotes a mnemonic'] }, "Select All &&Occurrences"), 'editor.action.selectHighlights'); + + const copyLinesUp = this.createMenuItem(nls.localize({ key: 'miCopyLinesUp', comment: ['&& denotes a mnemonic'] }, "&&Copy Line Up"), 'editor.action.copyLinesUpAction'); + const copyLinesDown = this.createMenuItem(nls.localize({ key: 'miCopyLinesDown', comment: ['&& denotes a mnemonic'] }, "Co&&py Line Down"), 'editor.action.copyLinesDownAction'); + const moveLinesUp = this.createMenuItem(nls.localize({ key: 'miMoveLinesUp', comment: ['&& denotes a mnemonic'] }, "Mo&&ve Line Up"), 'editor.action.moveLinesUpAction'); + const moveLinesDown = this.createMenuItem(nls.localize({ key: 'miMoveLinesDown', comment: ['&& denotes a mnemonic'] }, "Move &&Line Down"), 'editor.action.moveLinesDownAction'); + + let selectAll: Electron.MenuItem; + if (isMacintosh) { + selectAll = this.createContextAwareMenuItem(nls.localize({ key: 'miSelectAll', comment: ['&& denotes a mnemonic'] }, "&&Select All"), 'editor.action.selectAll', { + inDevTools: devTools => devTools.selectAll(), + inNoWindow: () => Menu.sendActionToFirstResponder('selectAll:') + }); + } else { + selectAll = this.createMenuItem(nls.localize({ key: 'miSelectAll', comment: ['&& denotes a mnemonic'] }, "&&Select All"), 'editor.action.selectAll'); + } + const smartSelectGrow = this.createMenuItem(nls.localize({ key: 'miSmartSelectGrow', comment: ['&& denotes a mnemonic'] }, "&&Expand Selection"), 'editor.action.smartSelect.grow'); + const smartSelectshrink = this.createMenuItem(nls.localize({ key: 'miSmartSelectShrink', comment: ['&& denotes a mnemonic'] }, "&&Shrink Selection"), 'editor.action.smartSelect.shrink'); + + [ + selectAll, + smartSelectGrow, + smartSelectshrink, + __separator__(), + copyLinesUp, + copyLinesDown, + moveLinesUp, + moveLinesDown, + __separator__(), + multicursorModifier, + insertCursorAbove, + insertCursorBelow, + insertCursorAtEndOfEachLineSelected, + addSelectionToNextFindMatch, + addSelectionToPreviousFindMatch, + selectHighlights, + ].forEach(item => winLinuxEditMenu.append(item)); + } + + private setViewMenu(viewMenu: Electron.Menu): void { + const commands = this.createMenuItem(nls.localize({ key: 'miCommandPalette', comment: ['&& denotes a mnemonic'] }, "&&Command Palette..."), 'workbench.action.showCommands'); + const openView = this.createMenuItem(nls.localize({ key: 'miOpenView', comment: ['&& denotes a mnemonic'] }, "&&Open View..."), 'workbench.action.openView'); + + // Views + const explorer = this.createMenuItem(nls.localize({ key: 'miViewExplorer', comment: ['&& denotes a mnemonic'] }, "&&Explorer"), 'workbench.view.explorer'); + const search = this.createMenuItem(nls.localize({ key: 'miViewSearch', comment: ['&& denotes a mnemonic'] }, "&&Search"), 'workbench.view.search'); + const scm = this.createMenuItem(nls.localize({ key: 'miViewSCM', comment: ['&& denotes a mnemonic'] }, "S&&CM"), 'workbench.view.scm'); + const debug = this.createMenuItem(nls.localize({ key: 'miViewDebug', comment: ['&& denotes a mnemonic'] }, "&&Debug"), 'workbench.view.debug'); + const extensions = this.createMenuItem(nls.localize({ key: 'miViewExtensions', comment: ['&& denotes a mnemonic'] }, "E&&xtensions"), 'workbench.view.extensions'); + + // Panels + const output = this.createMenuItem(nls.localize({ key: 'miToggleOutput', comment: ['&& denotes a mnemonic'] }, "&&Output"), 'workbench.action.output.toggleOutput'); + const debugConsole = this.createMenuItem(nls.localize({ key: 'miToggleDebugConsole', comment: ['&& denotes a mnemonic'] }, "De&&bug Console"), 'workbench.debug.action.toggleRepl'); + const terminal = this.createMenuItem(nls.localize({ key: 'miToggleTerminal', comment: ['&& denotes a mnemonic'] }, "&&Terminal"), 'workbench.action.terminal.toggleTerminal'); + const problems = this.createMenuItem(nls.localize({ key: 'miMarker', comment: ['&& denotes a mnemonic'] }, "&&Problems"), 'workbench.actions.view.problems'); + + // Appearance + + const appearanceMenu = new Menu(); + + const fullscreen = new MenuItem(this.withKeybinding('workbench.action.toggleFullScreen', { label: this.mnemonicLabel(nls.localize({ key: 'miToggleFullScreen', comment: ['&& denotes a mnemonic'] }, "Toggle &&Full Screen")), click: () => this.windowsMainService.getLastActiveWindow().toggleFullScreen(), enabled: this.windowsMainService.getWindowCount() > 0 })); + const toggleZenMode = this.createMenuItem(nls.localize('miToggleZenMode', "Toggle Zen Mode"), 'workbench.action.toggleZenMode'); + const toggleCenteredLayout = this.createMenuItem(nls.localize('miToggleCenteredLayout', "Toggle Centered Layout"), 'workbench.action.toggleCenteredLayout'); + const toggleMenuBar = this.createMenuItem(nls.localize({ key: 'miToggleMenuBar', comment: ['&& denotes a mnemonic'] }, "Toggle Menu &&Bar"), 'workbench.action.toggleMenuBar'); + + const toggleSidebar = this.createMenuItem(nls.localize({ key: 'miToggleSidebar', comment: ['&& denotes a mnemonic'] }, "&&Toggle Side Bar"), 'workbench.action.toggleSidebarVisibility'); + + let moveSideBarLabel: string; + if (this.currentSidebarLocation !== 'right') { + moveSideBarLabel = nls.localize({ key: 'miMoveSidebarRight', comment: ['&& denotes a mnemonic'] }, "&&Move Side Bar Right"); + } else { + moveSideBarLabel = nls.localize({ key: 'miMoveSidebarLeft', comment: ['&& denotes a mnemonic'] }, "&&Move Side Bar Left"); + } + + const moveSidebar = this.createMenuItem(moveSideBarLabel, 'workbench.action.toggleSidebarPosition'); + const togglePanel = this.createMenuItem(nls.localize({ key: 'miTogglePanel', comment: ['&& denotes a mnemonic'] }, "Toggle &&Panel"), 'workbench.action.togglePanel'); + + let statusBarLabel: string; + if (this.currentStatusbarVisible) { + statusBarLabel = nls.localize({ key: 'miHideStatusbar', comment: ['&& denotes a mnemonic'] }, "&&Hide Status Bar"); + } else { + statusBarLabel = nls.localize({ key: 'miShowStatusbar', comment: ['&& denotes a mnemonic'] }, "&&Show Status Bar"); + } + const toggleStatusbar = this.createMenuItem(statusBarLabel, 'workbench.action.toggleStatusbarVisibility'); + + let activityBarLabel: string; + if (this.currentActivityBarVisible) { + activityBarLabel = nls.localize({ key: 'miHideActivityBar', comment: ['&& denotes a mnemonic'] }, "Hide &&Activity Bar"); + } else { + activityBarLabel = nls.localize({ key: 'miShowActivityBar', comment: ['&& denotes a mnemonic'] }, "Show &&Activity Bar"); + } + const toggleActivtyBar = this.createMenuItem(activityBarLabel, 'workbench.action.toggleActivityBarVisibility'); + + const zoomIn = this.createMenuItem(nls.localize({ key: 'miZoomIn', comment: ['&& denotes a mnemonic'] }, "&&Zoom In"), 'workbench.action.zoomIn'); + const zoomOut = this.createMenuItem(nls.localize({ key: 'miZoomOut', comment: ['&& denotes a mnemonic'] }, "Zoom O&&ut"), 'workbench.action.zoomOut'); + const resetZoom = this.createMenuItem(nls.localize({ key: 'miZoomReset', comment: ['&& denotes a mnemonic'] }, "&&Reset Zoom"), 'workbench.action.zoomReset'); + + arrays.coalesce([ + fullscreen, + toggleZenMode, + toggleCenteredLayout, + isWindows || isLinux ? toggleMenuBar : void 0, + __separator__(), + moveSidebar, + toggleSidebar, + togglePanel, + toggleStatusbar, + toggleActivtyBar, + __separator__(), + zoomIn, + zoomOut, + resetZoom + ]).forEach(item => appearanceMenu.append(item)); + + const appearance = new MenuItem({ label: this.mnemonicLabel(nls.localize({ key: 'miAppearance', comment: ['&& denotes a mnemonic'] }, "&&Appearance")), submenu: appearanceMenu }); + + // Editor Layout + + const editorLayoutMenu = new Menu(); + + const splitEditorUp = this.createMenuItem(nls.localize({ key: 'miSplitEditorUp', comment: ['&& denotes a mnemonic'] }, "Split &&Up"), 'workbench.action.splitEditorUp'); + const splitEditorDown = this.createMenuItem(nls.localize({ key: 'miSplitEditorDown', comment: ['&& denotes a mnemonic'] }, "Split &&Down"), 'workbench.action.splitEditorDown'); + const splitEditorLeft = this.createMenuItem(nls.localize({ key: 'miSplitEditorLeft', comment: ['&& denotes a mnemonic'] }, "Split &&Left"), 'workbench.action.splitEditorLeft'); + const splitEditorRight = this.createMenuItem(nls.localize({ key: 'miSplitEditorRight', comment: ['&& denotes a mnemonic'] }, "Split &&Right"), 'workbench.action.splitEditorRight'); + + const singleColumnEditorLayout = this.createMenuItem(nls.localize({ key: 'miSingleColumnEditorLayout', comment: ['&& denotes a mnemonic'] }, "&&Single"), 'workbench.action.editorLayoutSingle'); + const twoColumnsEditorLayout = this.createMenuItem(nls.localize({ key: 'miTwoColumnsEditorLayout', comment: ['&& denotes a mnemonic'] }, "&&Two Columns"), 'workbench.action.editorLayoutTwoColumns'); + const threeColumnsEditorLayout = this.createMenuItem(nls.localize({ key: 'miThreeColumnsEditorLayout', comment: ['&& denotes a mnemonic'] }, "T&&hree Columns"), 'workbench.action.editorLayoutThreeColumns'); + const twoRowsEditorLayout = this.createMenuItem(nls.localize({ key: 'miTwoRowsEditorLayout', comment: ['&& denotes a mnemonic'] }, "T&&wo Rows"), 'workbench.action.editorLayoutTwoRows'); + const threeRowsEditorLayout = this.createMenuItem(nls.localize({ key: 'miThreeRowsEditorLayout', comment: ['&& denotes a mnemonic'] }, "Three &&Rows"), 'workbench.action.editorLayoutThreeRows'); + const twoByTwoGridEditorLayout = this.createMenuItem(nls.localize({ key: 'miTwoByTwoGridEditorLayout', comment: ['&& denotes a mnemonic'] }, "&&Grid (2x2)"), 'workbench.action.editorLayoutTwoByTwoGrid'); + const twoRowsRightEditorLayout = this.createMenuItem(nls.localize({ key: 'miTwoRowsRightEditorLayout', comment: ['&& denotes a mnemonic'] }, "Two R&&ows Right"), 'workbench.action.editorLayoutTwoRowsRight'); + const twoColumnsBottomEditorLayout = this.createMenuItem(nls.localize({ key: 'miTwoColumnsBottomEditorLayout', comment: ['&& denotes a mnemonic'] }, "Two &&Columns Bottom"), 'workbench.action.editorLayoutTwoColumnsBottom'); + + const toggleEditorLayout = this.createMenuItem(nls.localize({ key: 'miToggleEditorLayout', comment: ['&& denotes a mnemonic'] }, "Flip &&Layout"), 'workbench.action.toggleEditorGroupLayout'); + + [ + splitEditorUp, + splitEditorDown, + splitEditorLeft, + splitEditorRight, + __separator__(), + singleColumnEditorLayout, + twoColumnsEditorLayout, + threeColumnsEditorLayout, + twoRowsEditorLayout, + threeRowsEditorLayout, + twoByTwoGridEditorLayout, + twoRowsRightEditorLayout, + twoColumnsBottomEditorLayout, + __separator__(), + toggleEditorLayout + ].forEach(item => editorLayoutMenu.append(item)); + + const editorLayout = new MenuItem({ label: this.mnemonicLabel(nls.localize({ key: 'miEditorLayout', comment: ['&& denotes a mnemonic'] }, "Editor &&Layout")), submenu: editorLayoutMenu }); + + const toggleWordWrap = this.createMenuItem(nls.localize({ key: 'miToggleWordWrap', comment: ['&& denotes a mnemonic'] }, "Toggle &&Word Wrap"), 'editor.action.toggleWordWrap'); + const toggleMinimap = this.createMenuItem(nls.localize({ key: 'miToggleMinimap', comment: ['&& denotes a mnemonic'] }, "Toggle &&Minimap"), 'editor.action.toggleMinimap'); + const toggleRenderWhitespace = this.createMenuItem(nls.localize({ key: 'miToggleRenderWhitespace', comment: ['&& denotes a mnemonic'] }, "Toggle &&Render Whitespace"), 'editor.action.toggleRenderWhitespace'); + const toggleRenderControlCharacters = this.createMenuItem(nls.localize({ key: 'miToggleRenderControlCharacters', comment: ['&& denotes a mnemonic'] }, "Toggle &&Control Characters"), 'editor.action.toggleRenderControlCharacter'); + const toggleBreadcrumbs = this.createMenuItem(nls.localize({ key: 'miToggleBreadcrumbs', comment: ['&& denotes a mnemonic'] }, "Toggle &&Breadcrumbs"), 'breadcrumbs.toggle'); + + arrays.coalesce([ + commands, + openView, + __separator__(), + appearance, + editorLayout, + __separator__(), + explorer, + search, + scm, + debug, + extensions, + __separator__(), + output, + problems, + debugConsole, + terminal, + __separator__(), + toggleWordWrap, + toggleMinimap, + toggleRenderWhitespace, + toggleRenderControlCharacters, + toggleBreadcrumbs + ]).forEach(item => viewMenu.append(item)); + } + + private setGotoMenu(gotoMenu: Electron.Menu): void { + const back = this.createMenuItem(nls.localize({ key: 'miBack', comment: ['&& denotes a mnemonic'] }, "&&Back"), 'workbench.action.navigateBack'); + const forward = this.createMenuItem(nls.localize({ key: 'miForward', comment: ['&& denotes a mnemonic'] }, "&&Forward"), 'workbench.action.navigateForward'); + + const switchEditorMenu = new Menu(); + + const nextEditor = this.createMenuItem(nls.localize({ key: 'miNextEditor', comment: ['&& denotes a mnemonic'] }, "&&Next Editor"), 'workbench.action.nextEditor'); + const previousEditor = this.createMenuItem(nls.localize({ key: 'miPreviousEditor', comment: ['&& denotes a mnemonic'] }, "&&Previous Editor"), 'workbench.action.previousEditor'); + const nextEditorInGroup = this.createMenuItem(nls.localize({ key: 'miNextEditorInGroup', comment: ['&& denotes a mnemonic'] }, "&&Next Used Editor in Group"), 'workbench.action.openNextRecentlyUsedEditorInGroup'); + const previousEditorInGroup = this.createMenuItem(nls.localize({ key: 'miPreviousEditorInGroup', comment: ['&& denotes a mnemonic'] }, "&&Previous Used Editor in Group"), 'workbench.action.openPreviousRecentlyUsedEditorInGroup'); + + [ + nextEditor, + previousEditor, + __separator__(), + nextEditorInGroup, + previousEditorInGroup + ].forEach(item => switchEditorMenu.append(item)); + + const switchEditor = new MenuItem({ label: this.mnemonicLabel(nls.localize({ key: 'miSwitchEditor', comment: ['&& denotes a mnemonic'] }, "Switch &&Editor")), submenu: switchEditorMenu, enabled: true }); + + const switchGroupMenu = new Menu(); + + const focusFirstGroup = this.createMenuItem(nls.localize({ key: 'miFocusFirstGroup', comment: ['&& denotes a mnemonic'] }, "Group &&1"), 'workbench.action.focusFirstEditorGroup'); + const focusSecondGroup = this.createMenuItem(nls.localize({ key: 'miFocusSecondGroup', comment: ['&& denotes a mnemonic'] }, "Group &&2"), 'workbench.action.focusSecondEditorGroup'); + const focusThirdGroup = this.createMenuItem(nls.localize({ key: 'miFocusThirdGroup', comment: ['&& denotes a mnemonic'] }, "Group &&3"), 'workbench.action.focusThirdEditorGroup'); + const focusFourthGroup = this.createMenuItem(nls.localize({ key: 'miFocusFourthGroup', comment: ['&& denotes a mnemonic'] }, "Group &&4"), 'workbench.action.focusFourthEditorGroup'); + const focusFifthGroup = this.createMenuItem(nls.localize({ key: 'miFocusFifthGroup', comment: ['&& denotes a mnemonic'] }, "Group &&5"), 'workbench.action.focusFifthEditorGroup'); + const nextGroup = this.createMenuItem(nls.localize({ key: 'miNextGroup', comment: ['&& denotes a mnemonic'] }, "&&Next Group"), 'workbench.action.focusNextGroup'); + const previousGroup = this.createMenuItem(nls.localize({ key: 'miPreviousGroup', comment: ['&& denotes a mnemonic'] }, "&&Previous Group"), 'workbench.action.focusPreviousGroup'); + + const focusLeftGroup = this.createMenuItem(nls.localize({ key: 'miFocusLeftGroup', comment: ['&& denotes a mnemonic'] }, "Group &&Left"), 'workbench.action.focusLeftGroup'); + const focusRightGroup = this.createMenuItem(nls.localize({ key: 'miFocusRightGroup', comment: ['&& denotes a mnemonic'] }, "Group &&Right"), 'workbench.action.focusRightGroup'); + const focusAboveGroup = this.createMenuItem(nls.localize({ key: 'miFocusAboveGroup', comment: ['&& denotes a mnemonic'] }, "Group &&Above"), 'workbench.action.focusAboveGroup'); + const focusBelowGroup = this.createMenuItem(nls.localize({ key: 'miFocusBelowGroup', comment: ['&& denotes a mnemonic'] }, "Group &&Below"), 'workbench.action.focusBelowGroup'); + + [ + focusFirstGroup, + focusSecondGroup, + focusThirdGroup, + focusFourthGroup, + focusFifthGroup, + __separator__(), + nextGroup, + previousGroup, + __separator__(), + focusAboveGroup, + focusBelowGroup, + focusLeftGroup, + focusRightGroup + ].forEach(item => switchGroupMenu.append(item)); + + const switchGroup = new MenuItem({ label: this.mnemonicLabel(nls.localize({ key: 'miSwitchGroup', comment: ['&& denotes a mnemonic'] }, "Switch &&Group")), submenu: switchGroupMenu, enabled: true }); + + const gotoFile = this.createMenuItem(nls.localize({ key: 'miGotoFile', comment: ['&& denotes a mnemonic'] }, "Go to &&File..."), 'workbench.action.quickOpen'); + const gotoSymbolInFile = this.createMenuItem(nls.localize({ key: 'miGotoSymbolInFile', comment: ['&& denotes a mnemonic'] }, "Go to &&Symbol in File..."), 'workbench.action.gotoSymbol'); + const gotoSymbolInWorkspace = this.createMenuItem(nls.localize({ key: 'miGotoSymbolInWorkspace', comment: ['&& denotes a mnemonic'] }, "Go to Symbol in &&Workspace..."), 'workbench.action.showAllSymbols'); + const gotoDefinition = this.createMenuItem(nls.localize({ key: 'miGotoDefinition', comment: ['&& denotes a mnemonic'] }, "Go to &&Definition"), 'editor.action.goToDeclaration'); + const gotoTypeDefinition = this.createMenuItem(nls.localize({ key: 'miGotoTypeDefinition', comment: ['&& denotes a mnemonic'] }, "Go to &&Type Definition"), 'editor.action.goToTypeDefinition'); + const goToImplementation = this.createMenuItem(nls.localize({ key: 'miGotoImplementation', comment: ['&& denotes a mnemonic'] }, "Go to &&Implementation"), 'editor.action.goToImplementation'); + const gotoLine = this.createMenuItem(nls.localize({ key: 'miGotoLine', comment: ['&& denotes a mnemonic'] }, "Go to &&Line..."), 'workbench.action.gotoLine'); + + [ + back, + forward, + __separator__(), + switchEditor, + switchGroup, + __separator__(), + gotoFile, + gotoSymbolInFile, + gotoSymbolInWorkspace, + gotoDefinition, + gotoTypeDefinition, + goToImplementation, + gotoLine + ].forEach(item => gotoMenu.append(item)); + } + + private setTerminalMenu(terminalMenu: Electron.Menu): void { + const newTerminal = this.createMenuItem(nls.localize({ key: 'miNewTerminal', comment: ['&& denotes a mnemonic'] }, "&&New Terminal"), 'workbench.action.terminal.new'); + const splitTerminal = this.createMenuItem(nls.localize({ key: 'miSplitTerminal', comment: ['&& denotes a mnemonic'] }, "&&Split Terminal"), 'workbench.action.terminal.split'); + const killTerminal = this.createMenuItem(nls.localize({ key: 'miKillTerminal', comment: ['&& denotes a mnemonic'] }, "&&Kill Terminal"), 'workbench.action.terminal.kill'); + const clear = this.createMenuItem(nls.localize({ key: 'miClear', comment: ['&& denotes a mnemonic'] }, "&&Clear"), 'workbench.action.terminal.clear'); + const runActiveFile = this.createMenuItem(nls.localize({ key: 'miRunActiveFile', comment: ['&& denotes a mnemonic'] }, "Run &&Active File"), 'workbench.action.terminal.runActiveFile'); + const runSelectedText = this.createMenuItem(nls.localize({ key: 'miRunSelectedText', comment: ['&& denotes a mnemonic'] }, "Run &&Selected Text"), 'workbench.action.terminal.runSelectedText'); + const scrollToPreviousCommand = this.createMenuItem(nls.localize({ key: 'miScrollToPreviousCommand', comment: ['&& denotes a mnemonic'] }, "Scroll To Previous Command"), 'workbench.action.terminal.scrollToPreviousCommand'); + const scrollToNextCommand = this.createMenuItem(nls.localize({ key: 'miScrollToNextCommand', comment: ['&& denotes a mnemonic'] }, "Scroll To Next Command"), 'workbench.action.terminal.scrollToNextCommand'); + const selectToPreviousCommand = this.createMenuItem(nls.localize({ key: 'miSelectToPreviousCommand', comment: ['&& denotes a mnemonic'] }, "Select To Previous Command"), 'workbench.action.terminal.selectToPreviousCommand'); + const selectToNextCommand = this.createMenuItem(nls.localize({ key: 'miSelectToNextCommand', comment: ['&& denotes a mnemonic'] }, "Select To Next Command"), 'workbench.action.terminal.selectToNextCommand'); + + const menuItems: MenuItem[] = [ + newTerminal, + splitTerminal, + killTerminal, + __separator__(), + clear, + runActiveFile, + runSelectedText, + __separator__(), + scrollToPreviousCommand, + scrollToNextCommand, + selectToPreviousCommand, + selectToNextCommand + ]; + + menuItems.forEach(item => terminalMenu.append(item)); + } + + private setDebugMenu(debugMenu: Electron.Menu): void { + const start = this.createMenuItem(nls.localize({ key: 'miStartDebugging', comment: ['&& denotes a mnemonic'] }, "&&Start Debugging"), 'workbench.action.debug.start'); + const startWithoutDebugging = this.createMenuItem(nls.localize({ key: 'miStartWithoutDebugging', comment: ['&& denotes a mnemonic'] }, "Start &&Without Debugging"), 'workbench.action.debug.run'); + const stop = this.createMenuItem(nls.localize({ key: 'miStopDebugging', comment: ['&& denotes a mnemonic'] }, "&&Stop Debugging"), 'workbench.action.debug.stop'); + const restart = this.createMenuItem(nls.localize({ key: 'miRestart Debugging', comment: ['&& denotes a mnemonic'] }, "&&Restart Debugging"), 'workbench.action.debug.restart'); + + const openConfigurations = this.createMenuItem(nls.localize({ key: 'miOpenConfigurations', comment: ['&& denotes a mnemonic'] }, "Open &&Configurations"), 'workbench.action.debug.configure'); + const addConfiguration = this.createMenuItem(nls.localize({ key: 'miAddConfiguration', comment: ['&& denotes a mnemonic'] }, "Add Configuration..."), 'debug.addConfiguration'); + + const stepOver = this.createMenuItem(nls.localize({ key: 'miStepOver', comment: ['&& denotes a mnemonic'] }, "Step &&Over"), 'workbench.action.debug.stepOver'); + const stepInto = this.createMenuItem(nls.localize({ key: 'miStepInto', comment: ['&& denotes a mnemonic'] }, "Step &&Into"), 'workbench.action.debug.stepInto'); + const stepOut = this.createMenuItem(nls.localize({ key: 'miStepOut', comment: ['&& denotes a mnemonic'] }, "Step O&&ut"), 'workbench.action.debug.stepOut'); + const continueAction = this.createMenuItem(nls.localize({ key: 'miContinue', comment: ['&& denotes a mnemonic'] }, "&&Continue"), 'workbench.action.debug.continue'); + + const toggleBreakpoint = this.createMenuItem(nls.localize({ key: 'miToggleBreakpoint', comment: ['&& denotes a mnemonic'] }, "Toggle &&Breakpoint"), 'editor.debug.action.toggleBreakpoint'); + const breakpointsMenu = new Menu(); + breakpointsMenu.append(this.createMenuItem(nls.localize({ key: 'miConditionalBreakpoint', comment: ['&& denotes a mnemonic'] }, "&&Conditional Breakpoint..."), 'editor.debug.action.conditionalBreakpoint')); + breakpointsMenu.append(this.createMenuItem(nls.localize({ key: 'miInlineBreakpoint', comment: ['&& denotes a mnemonic'] }, "Inline Breakp&&oint"), 'editor.debug.action.toggleInlineBreakpoint')); + breakpointsMenu.append(this.createMenuItem(nls.localize({ key: 'miFunctionBreakpoint', comment: ['&& denotes a mnemonic'] }, "&&Function Breakpoint..."), 'workbench.debug.viewlet.action.addFunctionBreakpointAction')); + breakpointsMenu.append(this.createMenuItem(nls.localize({ key: 'miLogPoint', comment: ['&& denotes a mnemonic'] }, "&&Logpoint..."), 'editor.debug.action.toggleLogPoint')); + const newBreakpoints = new MenuItem({ label: this.mnemonicLabel(nls.localize({ key: 'miNewBreakpoint', comment: ['&& denotes a mnemonic'] }, "&&New Breakpoint")), submenu: breakpointsMenu }); + const enableAllBreakpoints = this.createMenuItem(nls.localize({ key: 'miEnableAllBreakpoints', comment: ['&& denotes a mnemonic'] }, "Enable All Breakpoints"), 'workbench.debug.viewlet.action.enableAllBreakpoints'); + const disableAllBreakpoints = this.createMenuItem(nls.localize({ key: 'miDisableAllBreakpoints', comment: ['&& denotes a mnemonic'] }, "Disable A&&ll Breakpoints"), 'workbench.debug.viewlet.action.disableAllBreakpoints'); + const removeAllBreakpoints = this.createMenuItem(nls.localize({ key: 'miRemoveAllBreakpoints', comment: ['&& denotes a mnemonic'] }, "Remove &&All Breakpoints"), 'workbench.debug.viewlet.action.removeAllBreakpoints'); + + const installAdditionalDebuggers = this.createMenuItem(nls.localize({ key: 'miInstallAdditionalDebuggers', comment: ['&& denotes a mnemonic'] }, "&&Install Additional Debuggers..."), 'debug.installAdditionalDebuggers'); + [ + start, + startWithoutDebugging, + stop, + restart, + __separator__(), + openConfigurations, + addConfiguration, + __separator__(), + stepOver, + stepInto, + stepOut, + continueAction, + __separator__(), + toggleBreakpoint, + newBreakpoints, + enableAllBreakpoints, + disableAllBreakpoints, + removeAllBreakpoints, + __separator__(), + installAdditionalDebuggers + ].forEach(item => debugMenu.append(item)); + } + + private setMacWindowMenu(macWindowMenu: Electron.Menu): void { + const minimize = new MenuItem({ label: nls.localize('mMinimize', "Minimize"), role: 'minimize', accelerator: 'Command+M', enabled: this.windowsMainService.getWindowCount() > 0 }); + const zoom = new MenuItem({ label: nls.localize('mZoom', "Zoom"), role: 'zoom', enabled: this.windowsMainService.getWindowCount() > 0 }); + const bringAllToFront = new MenuItem({ label: nls.localize('mBringToFront', "Bring All to Front"), role: 'front', enabled: this.windowsMainService.getWindowCount() > 0 }); + const switchWindow = this.createMenuItem(nls.localize({ key: 'miSwitchWindow', comment: ['&& denotes a mnemonic'] }, "Switch &&Window..."), 'workbench.action.switchWindow'); + + this.nativeTabMenuItems = []; + const nativeTabMenuItems: Electron.MenuItem[] = []; + if (this.currentEnableNativeTabs) { + const hasMultipleWindows = this.windowsMainService.getWindowCount() > 1; + + this.nativeTabMenuItems.push(this.createMenuItem(nls.localize('mShowPreviousTab', "Show Previous Tab"), 'workbench.action.showPreviousWindowTab', hasMultipleWindows)); + this.nativeTabMenuItems.push(this.createMenuItem(nls.localize('mShowNextTab', "Show Next Tab"), 'workbench.action.showNextWindowTab', hasMultipleWindows)); + this.nativeTabMenuItems.push(this.createMenuItem(nls.localize('mMoveTabToNewWindow', "Move Tab to New Window"), 'workbench.action.moveWindowTabToNewWindow', hasMultipleWindows)); + this.nativeTabMenuItems.push(this.createMenuItem(nls.localize('mMergeAllWindows', "Merge All Windows"), 'workbench.action.mergeAllWindowTabs', hasMultipleWindows)); + + nativeTabMenuItems.push(__separator__(), ...this.nativeTabMenuItems); + } else { + this.nativeTabMenuItems = []; + } + + [ + minimize, + zoom, + switchWindow, + ...nativeTabMenuItems, + __separator__(), + bringAllToFront + ].forEach(item => macWindowMenu.append(item)); + } + + private toggleDevTools(): void { + const w = this.windowsMainService.getFocusedWindow(); + if (w && w.win) { + const contents = w.win.webContents; + if (isMacintosh && w.hasHiddenTitleBarStyle() && !w.win.isFullScreen() && !contents.isDevToolsOpened()) { + contents.openDevTools({ mode: 'undocked' }); // due to https://github.com/electron/electron/issues/3647 + } else { + contents.toggleDevTools(); + } + } + } + + private setHelpMenu(helpMenu: Electron.Menu): void { + const toggleDevToolsItem = new MenuItem(this.likeAction('workbench.action.toggleDevTools', { + label: this.mnemonicLabel(nls.localize({ key: 'miToggleDevTools', comment: ['&& denotes a mnemonic'] }, "&&Toggle Developer Tools")), + click: () => this.toggleDevTools(), + enabled: (this.windowsMainService.getWindowCount() > 0) + })); + + const showAccessibilityOptions = new MenuItem(this.likeAction('accessibilityOptions', { + label: this.mnemonicLabel(nls.localize({ key: 'miAccessibilityOptions', comment: ['&& denotes a mnemonic'] }, "Accessibility &&Options")), + accelerator: null, + click: () => { + this.openAccessibilityOptions(); + } + }, false)); + + const openProcessExplorer = new MenuItem({ label: this.mnemonicLabel(nls.localize({ key: 'miOpenProcessExplorerer', comment: ['&& denotes a mnemonic'] }, "Open &&Process Explorer")), click: () => this.runActionInRenderer('workbench.action.openProcessExplorer') }); + + let reportIssuesItem: Electron.MenuItem = null; + if (product.reportIssueUrl) { + const label = nls.localize({ key: 'miReportIssue', comment: ['&& denotes a mnemonic', 'Translate this to "Report Issue in English" in all languages please!'] }, "Report &&Issue"); + + if (this.windowsMainService.getWindowCount() > 0) { + reportIssuesItem = this.createMenuItem(label, 'workbench.action.openIssueReporter'); + } else { + reportIssuesItem = new MenuItem({ label: this.mnemonicLabel(label), click: () => this.openUrl(product.reportIssueUrl, 'openReportIssues') }); + } + } + + const keyboardShortcutsUrl = isLinux ? product.keyboardShortcutsUrlLinux : isMacintosh ? product.keyboardShortcutsUrlMac : product.keyboardShortcutsUrlWin; + arrays.coalesce([ + new MenuItem({ label: this.mnemonicLabel(nls.localize({ key: 'miWelcome', comment: ['&& denotes a mnemonic'] }, "&&Welcome")), click: () => this.runActionInRenderer('workbench.action.showWelcomePage'), enabled: (this.windowsMainService.getWindowCount() > 0) }), + new MenuItem({ label: this.mnemonicLabel(nls.localize({ key: 'miInteractivePlayground', comment: ['&& denotes a mnemonic'] }, "&&Interactive Playground")), click: () => this.runActionInRenderer('workbench.action.showInteractivePlayground'), enabled: (this.windowsMainService.getWindowCount() > 0) }), + product.documentationUrl ? new MenuItem({ label: this.mnemonicLabel(nls.localize({ key: 'miDocumentation', comment: ['&& denotes a mnemonic'] }, "&&Documentation")), click: () => this.runActionInRenderer('workbench.action.openDocumentationUrl'), enabled: (this.windowsMainService.getWindowCount() > 0) }) : null, + product.releaseNotesUrl ? new MenuItem({ label: this.mnemonicLabel(nls.localize({ key: 'miReleaseNotes', comment: ['&& denotes a mnemonic'] }, "&&Release Notes")), click: () => this.runActionInRenderer('update.showCurrentReleaseNotes'), enabled: (this.windowsMainService.getWindowCount() > 0) }) : null, + __separator__(), + keyboardShortcutsUrl ? new MenuItem({ label: this.mnemonicLabel(nls.localize({ key: 'miKeyboardShortcuts', comment: ['&& denotes a mnemonic'] }, "&&Keyboard Shortcuts Reference")), click: () => this.runActionInRenderer('workbench.action.keybindingsReference'), enabled: (this.windowsMainService.getWindowCount() > 0) }) : null, + product.introductoryVideosUrl ? new MenuItem({ label: this.mnemonicLabel(nls.localize({ key: 'miIntroductoryVideos', comment: ['&& denotes a mnemonic'] }, "Introductory &&Videos")), click: () => this.runActionInRenderer('workbench.action.openIntroductoryVideosUrl'), enabled: (this.windowsMainService.getWindowCount() > 0) }) : null, + product.tipsAndTricksUrl ? new MenuItem({ label: this.mnemonicLabel(nls.localize({ key: 'miTipsAndTricks', comment: ['&& denotes a mnemonic'] }, "&&Tips and Tricks")), click: () => this.runActionInRenderer('workbench.action.openTipsAndTricksUrl'), enabled: (this.windowsMainService.getWindowCount() > 0) }) : null, + (product.introductoryVideosUrl || keyboardShortcutsUrl) ? __separator__() : null, + product.twitterUrl ? new MenuItem({ label: this.mnemonicLabel(nls.localize({ key: 'miTwitter', comment: ['&& denotes a mnemonic'] }, "&&Join us on Twitter")), click: () => this.openUrl(product.twitterUrl, 'openTwitterUrl') }) : null, + product.requestFeatureUrl ? new MenuItem({ label: this.mnemonicLabel(nls.localize({ key: 'miUserVoice', comment: ['&& denotes a mnemonic'] }, "&&Search Feature Requests")), click: () => this.openUrl(product.requestFeatureUrl, 'openUserVoiceUrl') }) : null, + reportIssuesItem, + (product.twitterUrl || product.requestFeatureUrl || product.reportIssueUrl) ? __separator__() : null, + product.licenseUrl ? new MenuItem({ + label: this.mnemonicLabel(nls.localize({ key: 'miLicense', comment: ['&& denotes a mnemonic'] }, "View &&License")), click: () => { + if (language) { + const queryArgChar = product.licenseUrl.indexOf('?') > 0 ? '&' : '?'; + this.openUrl(`${product.licenseUrl}${queryArgChar}lang=${language}`, 'openLicenseUrl'); + } else { + this.openUrl(product.licenseUrl, 'openLicenseUrl'); + } + } + }) : null, + product.privacyStatementUrl ? new MenuItem({ + label: this.mnemonicLabel(nls.localize({ key: 'miPrivacyStatement', comment: ['&& denotes a mnemonic'] }, "&&Privacy Statement")), click: () => { + if (language) { + const queryArgChar = product.licenseUrl.indexOf('?') > 0 ? '&' : '?'; + this.openUrl(`${product.privacyStatementUrl}${queryArgChar}lang=${language}`, 'openPrivacyStatement'); + } else { + this.openUrl(product.privacyStatementUrl, 'openPrivacyStatement'); + } + } + }) : null, + (product.licenseUrl || product.privacyStatementUrl) ? __separator__() : null, + toggleDevToolsItem, + openProcessExplorer, + isWindows && product.quality !== 'stable' ? showAccessibilityOptions : null, + ]).forEach(item => helpMenu.append(item)); + + if (!isMacintosh) { + const updateMenuItems = this.getUpdateMenuItems(); + if (updateMenuItems.length) { + helpMenu.append(__separator__()); + updateMenuItems.forEach(i => helpMenu.append(i)); + } + + helpMenu.append(__separator__()); + helpMenu.append(new MenuItem({ label: this.mnemonicLabel(nls.localize({ key: 'miAbout', comment: ['&& denotes a mnemonic'] }, "&&About")), click: () => this.windowsService.openAboutDialog() })); + } + } + + private setTaskMenu(taskMenu: Electron.Menu): void { + const runTask = this.createMenuItem(nls.localize({ key: 'miRunTask', comment: ['&& denotes a mnemonic'] }, "&&Run Task..."), 'workbench.action.tasks.runTask'); + const buildTask = this.createMenuItem(nls.localize({ key: 'miBuildTask', comment: ['&& denotes a mnemonic'] }, "Run &&Build Task..."), 'workbench.action.tasks.build'); + const showTasks = this.createMenuItem(nls.localize({ key: 'miRunningTask', comment: ['&& denotes a mnemonic'] }, "Show Runnin&&g Tasks..."), 'workbench.action.tasks.showTasks'); + const restartTask = this.createMenuItem(nls.localize({ key: 'miRestartTask', comment: ['&& denotes a mnemonic'] }, "R&&estart Running Task..."), 'workbench.action.tasks.restartTask'); + const terminateTask = this.createMenuItem(nls.localize({ key: 'miTerminateTask', comment: ['&& denotes a mnemonic'] }, "&&Terminate Task..."), 'workbench.action.tasks.terminate'); + const configureTask = this.createMenuItem(nls.localize({ key: 'miConfigureTask', comment: ['&& denotes a mnemonic'] }, "&&Configure Tasks..."), 'workbench.action.tasks.configureTaskRunner'); + const configureBuildTask = this.createMenuItem(nls.localize({ key: 'miConfigureBuildTask', comment: ['&& denotes a mnemonic'] }, "Configure De&&fault Build Task..."), 'workbench.action.tasks.configureDefaultBuildTask'); + + [ + //__separator__(), + runTask, + buildTask, + __separator__(), + terminateTask, + restartTask, + showTasks, + __separator__(), + configureTask, + configureBuildTask + ].forEach(item => taskMenu.append(item)); + } + + private openAccessibilityOptions(): void { + const win = new BrowserWindow({ + alwaysOnTop: true, + skipTaskbar: true, + resizable: false, + width: 450, + height: 300, + show: true, + title: nls.localize('accessibilityOptionsWindowTitle', "Accessibility Options"), + webPreferences: { + disableBlinkFeatures: 'Auxclick' + } + }); + + win.setMenuBarVisibility(false); + + win.loadURL('chrome://accessibility'); + } + + private getUpdateMenuItems(): Electron.MenuItem[] { + const state = this.updateService.state; + + switch (state.type) { + case StateType.Uninitialized: + return []; + + case StateType.Idle: + return [new MenuItem({ + label: nls.localize('miCheckForUpdates', "Check for Updates..."), click: () => setTimeout(() => { + this.reportMenuActionTelemetry('CheckForUpdate'); + + const focusedWindow = this.windowsMainService.getFocusedWindow(); + const context = focusedWindow ? { windowId: focusedWindow.id } : null; + this.updateService.checkForUpdates(context); + }, 0) + })]; + + case StateType.CheckingForUpdates: + return [new MenuItem({ label: nls.localize('miCheckingForUpdates', "Checking For Updates..."), enabled: false })]; + + case StateType.AvailableForDownload: + return [new MenuItem({ + label: nls.localize('miDownloadUpdate', "Download Available Update"), click: () => { + this.updateService.downloadUpdate(); + } + })]; + + case StateType.Downloading: + return [new MenuItem({ label: nls.localize('miDownloadingUpdate', "Downloading Update..."), enabled: false })]; + + case StateType.Downloaded: + return [new MenuItem({ + label: nls.localize('miInstallUpdate', "Install Update..."), click: () => { + this.reportMenuActionTelemetry('InstallUpdate'); + this.updateService.applyUpdate(); + } + })]; + + case StateType.Updating: + return [new MenuItem({ label: nls.localize('miInstallingUpdate', "Installing Update..."), enabled: false })]; + + case StateType.Ready: + return [new MenuItem({ + label: nls.localize('miRestartToUpdate', "Restart to Update..."), click: () => { + this.reportMenuActionTelemetry('RestartToUpdate'); + this.updateService.quitAndInstall(); + } + })]; + } + } + + private createMenuItem(label: string, commandId: string | string[], enabled?: boolean, checked?: boolean): Electron.MenuItem; + private createMenuItem(label: string, click: () => void, enabled?: boolean, checked?: boolean): Electron.MenuItem; + private createMenuItem(arg1: string, arg2: any, arg3?: boolean, arg4?: boolean): Electron.MenuItem { + const label = this.mnemonicLabel(arg1); + const click: () => void = (typeof arg2 === 'function') ? arg2 : (menuItem: Electron.MenuItem, win: Electron.BrowserWindow, event: Electron.Event) => { + let commandId = arg2; + if (Array.isArray(arg2)) { + commandId = this.isOptionClick(event) ? arg2[1] : arg2[0]; // support alternative action if we got multiple action Ids and the option key was pressed while invoking + } + + this.runActionInRenderer(commandId); + }; + const enabled = typeof arg3 === 'boolean' ? arg3 : this.windowsMainService.getWindowCount() > 0; + const checked = typeof arg4 === 'boolean' ? arg4 : false; + + const options: Electron.MenuItemConstructorOptions = { + label, + click, + enabled + }; + + if (checked) { + options['type'] = 'checkbox'; + options['checked'] = checked; + } + + let commandId: string; + if (typeof arg2 === 'string') { + commandId = arg2; + } else if (Array.isArray(arg2)) { + commandId = arg2[0]; + } + + return new MenuItem(this.withKeybinding(commandId, options)); + } + + private createContextAwareMenuItem(label: string, commandId: string, clickHandler: IMenuItemClickHandler): Electron.MenuItem { + return new MenuItem(this.withKeybinding(commandId, { + label: this.mnemonicLabel(label), + enabled: this.windowsMainService.getWindowCount() > 0, + click: () => { + + // No Active Window + const activeWindow = this.windowsMainService.getFocusedWindow(); + if (!activeWindow) { + return clickHandler.inNoWindow(); + } + + // DevTools focused + if (activeWindow.win.webContents.isDevToolsFocused()) { + return clickHandler.inDevTools(activeWindow.win.webContents.devToolsWebContents); + } + + // Finally execute command in Window + this.runActionInRenderer(commandId); + } + })); + } + + private runActionInRenderer(id: string): void { + // We make sure to not run actions when the window has no focus, this helps + // for https://github.com/Microsoft/vscode/issues/25907 and specifically for + // https://github.com/Microsoft/vscode/issues/11928 + const activeWindow = this.windowsMainService.getFocusedWindow(); + if (activeWindow) { + this.windowsMainService.sendToFocused('vscode:runAction', { id, from: 'menu' } as IRunActionInWindowRequest); + } + } + + private withKeybinding(commandId: string, options: Electron.MenuItemConstructorOptions): Electron.MenuItemConstructorOptions { + const binding = this.keybindingsResolver.getKeybinding(commandId); + + // Apply binding if there is one + if (binding && binding.label) { + + // if the binding is native, we can just apply it + if (binding.isNative) { + options.accelerator = binding.label; + } + + // the keybinding is not native so we cannot show it as part of the accelerator of + // the menu item. we fallback to a different strategy so that we always display it + else { + const bindingIndex = options.label.indexOf('['); + if (bindingIndex >= 0) { + options.label = `${options.label.substr(0, bindingIndex)} [${binding.label}]`; + } else { + options.label = `${options.label} [${binding.label}]`; + } + } + } + + // Unset bindings if there is none + else { + options.accelerator = void 0; + } + + return options; + } + + private likeAction(commandId: string, options: Electron.MenuItemConstructorOptions, setAccelerator = !options.accelerator): Electron.MenuItemConstructorOptions { + if (setAccelerator) { + options = this.withKeybinding(commandId, options); + } + + const originalClick = options.click; + options.click = (item, window, event) => { + this.reportMenuActionTelemetry(commandId); + if (originalClick) { + originalClick(item, window, event); + } + }; + + return options; + } + + private openUrl(url: string, id: string): void { + shell.openExternal(url); + this.reportMenuActionTelemetry(id); + } + + private reportMenuActionTelemetry(id: string): void { + /* __GDPR__ + "workbenchActionExecuted" : { + "id" : { "classification": "SystemMetaData", "purpose": "FeatureInsight" }, + "from": { "classification": "SystemMetaData", "purpose": "FeatureInsight" } + } + */ + this.telemetryService.publicLog('workbenchActionExecuted', { id, from: telemetryFrom }); + } + + private mnemonicLabel(label: string): string { + return baseMnemonicLabel(label, !this.currentEnableMenuBarMnemonics); + } +} + +function __separator__(): Electron.MenuItem { + return new MenuItem({ type: 'separator' }); +} \ No newline at end of file diff --git a/src/vs/platform/menubar/electron-main/menubarService.ts b/src/vs/platform/menubar/electron-main/menubarService.ts index 41bffbb3c69..7d7997c6812 100644 --- a/src/vs/platform/menubar/electron-main/menubarService.ts +++ b/src/vs/platform/menubar/electron-main/menubarService.ts @@ -10,6 +10,7 @@ import { Menubar } from 'vs/code/electron-main/menubar'; import { ILogService } from 'vs/platform/log/common/log'; import { TPromise } from 'vs/base/common/winjs.base'; import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; +import { isMacintosh, isWindows } from 'vs/base/common/platform'; export class MenubarService implements IMenubarService { _serviceBrand: any; @@ -21,7 +22,9 @@ export class MenubarService implements IMenubarService { @ILogService private logService: ILogService ) { // Install Menu - this._menubar = this.instantiationService.createInstance(Menubar); + if (isMacintosh && isWindows) { + this._menubar = this.instantiationService.createInstance(Menubar); + } } updateMenubar(windowId: number, menus: IMenubarData, additionalKeybindings?: Array): TPromise { diff --git a/src/vs/workbench/browser/parts/menubar/menubar.contribution.ts b/src/vs/workbench/browser/parts/menubar/menubar.contribution.ts index 39c87100cce..04235f1557d 100644 --- a/src/vs/workbench/browser/parts/menubar/menubar.contribution.ts +++ b/src/vs/workbench/browser/parts/menubar/menubar.contribution.ts @@ -171,7 +171,7 @@ function goMenuRegistration() { order: 3 }); - MenuRegistry.appendMenuItem(MenuId.MenubarGoMenu, { + MenuRegistry.appendMenuItem(MenuId.MenubarSwitchGroupMenu, { group: '3_directional', command: { id: 'workbench.action.focusBelowGroup', @@ -228,7 +228,7 @@ function goMenuRegistration() { group: 'z_go_to', command: { id: 'editor.action.goToTypeDefinition', - title: nls.localize({ key: 'miGotoDefinition', comment: ['&& denotes a mnemonic'] }, "Go to &&Definition") + title: nls.localize({ key: 'miGotoTypeDefinition', comment: ['&& denotes a mnemonic'] }, "Go to &&Type Definition") }, order: 5 }); diff --git a/src/vs/workbench/browser/parts/menubar/menubarPart.ts b/src/vs/workbench/browser/parts/menubar/menubarPart.ts index 00f43d61a10..a8c386c9e9a 100644 --- a/src/vs/workbench/browser/parts/menubar/menubarPart.ts +++ b/src/vs/workbench/browser/parts/menubar/menubarPart.ts @@ -10,7 +10,7 @@ import 'vs/css!./media/menubarpart'; import * as nls from 'vs/nls'; import * as browser from 'vs/base/browser/browser'; import { Part } from 'vs/workbench/browser/part'; -import { IMenubarService, IMenubarMenu, IMenubarMenuItemAction, IMenubarData, IMenubarMenuItemSubmenu, IMenubarKeybinding } from 'vs/platform/menubar/common/menubar'; +import { IMenubarMenu, IMenubarMenuItemAction, IMenubarMenuItemSubmenu, IMenubarKeybinding } from 'vs/platform/menubar/common/menubar'; import { IMenuService, MenuId, IMenu, SubmenuItemAction } from 'vs/platform/actions/common/actions'; import { IThemeService, registerThemingParticipant, ITheme, ICssStyleCollector } from 'vs/platform/theme/common/themeService'; import { IWindowService, MenuBarVisibility, IWindowsService } from 'vs/platform/windows/common/windows'; @@ -116,7 +116,6 @@ export class MenubarPart extends Part { constructor( id: string, @IThemeService themeService: IThemeService, - @IMenubarService private menubarService: IMenubarService, @IMenuService private menuService: IMenuService, @IWindowService private windowService: IWindowService, @IWindowsService private windowsService: IWindowsService, @@ -421,13 +420,16 @@ export class MenubarPart extends Part { private doSetupMenubar(): void { if (!isMacintosh && this.currentTitlebarStyleSetting === 'custom') { this.setupCustomMenubar(); - } else { - // Send menus to main process to be rendered by Electron - const menubarData = {}; - if (this.getMenubarMenus(menubarData)) { - this.menubarService.updateMenubar(this.windowService.getCurrentWindowId(), menubarData, this.getAdditionalKeybindings()); - } } + + // TODO@sbatten Uncomment to bring back dynamic menubar + // else { + // // Send menus to main process to be rendered by Electron + // const menubarData = {}; + // if (this.getMenubarMenus(menubarData)) { + // this.menubarService.updateMenubar(this.windowService.getCurrentWindowId(), menubarData, this.getAdditionalKeybindings()); + // } + // } } private setupMenubar(): void { @@ -894,33 +896,33 @@ export class MenubarPart extends Part { } } - private getAdditionalKeybindings(): Array { - const keybindings = []; - if (isMacintosh) { - keybindings.push(this.getMenubarKeybinding('workbench.action.quit')); - } + // private getAdditionalKeybindings(): Array { + // const keybindings = []; + // if (isMacintosh) { + // keybindings.push(this.getMenubarKeybinding('workbench.action.quit')); + // } - return keybindings; - } + // return keybindings; + // } - private getMenubarMenus(menubarData: IMenubarData): boolean { - if (!menubarData) { - return false; - } + // private getMenubarMenus(menubarData: IMenubarData): boolean { + // if (!menubarData) { + // return false; + // } - for (let topLevelMenuName of Object.keys(this.topLevelMenus)) { - const menu = this.topLevelMenus[topLevelMenuName]; - let menubarMenu: IMenubarMenu = { items: [] }; - this.populateMenuItems(menu, menubarMenu); - if (menubarMenu.items.length === 0) { - // Menus are incomplete - return false; - } - menubarData[topLevelMenuName] = menubarMenu; - } + // for (let topLevelMenuName of Object.keys(this.topLevelMenus)) { + // const menu = this.topLevelMenus[topLevelMenuName]; + // let menubarMenu: IMenubarMenu = { items: [] }; + // this.populateMenuItems(menu, menubarMenu); + // if (menubarMenu.items.length === 0) { + // // Menus are incomplete + // return false; + // } + // menubarData[topLevelMenuName] = menubarMenu; + // } - return true; - } + // return true; + // } private isCurrentMenu(menuIndex: number): boolean { if (!this.focusedMenu) { From c22bcdb82c16e129ed7e52f96e24b20fa1a87176 Mon Sep 17 00:00:00 2001 From: Martin Aeschlimann Date: Tue, 7 Aug 2018 20:50:54 +0200 Subject: [PATCH 0557/1276] resources must not use path library --- src/vs/base/common/resources.ts | 61 +++++++++++++++++++-- src/vs/base/test/common/resources.test.ts | 67 +++++++++++++++++------ 2 files changed, 106 insertions(+), 22 deletions(-) diff --git a/src/vs/base/common/resources.ts b/src/vs/base/common/resources.ts index 4afd24287ba..929349ba832 100644 --- a/src/vs/base/common/resources.ts +++ b/src/vs/base/common/resources.ts @@ -9,6 +9,7 @@ import URI from 'vs/base/common/uri'; import { equalsIgnoreCase } from 'vs/base/common/strings'; import { Schemas } from 'vs/base/common/network'; import { isLinux } from 'vs/base/common/platform'; +import { CharCode } from 'vs/base/common/charCode'; export function getComparisonKey(resource: URI): string { return hasToIgnoreCase(resource) ? resource.toString().toLowerCase() : resource.toString(); @@ -21,7 +22,7 @@ export function hasToIgnoreCase(resource: URI): boolean { } export function basenameOrAuthority(resource: URI): string { - return paths.basename(resource.path) || resource.authority; + return basename_urlpath(resource.path) || resource.authority; } export function isEqualOrParent(resource: URI, candidate: URI, ignoreCase?: boolean): boolean { @@ -53,21 +54,45 @@ export function isEqual(first: URI, second: URI, ignoreCase?: boolean): boolean return first.toString() === second.toString(); } +export function basename(resource: URI): string { + if (resource.scheme === 'file') { + return paths.basename(resource.fsPath); + } + return basename_urlpath(resource.path); +} + export function dirname(resource: URI): URI { - const dirname = paths.dirname(resource.path); - if (resource.authority && dirname && !paths.isAbsolute(dirname)) { + if (resource.scheme === 'file') { + return URI.file(paths.dirname(resource.fsPath)); + } + let dirname = dirname_urlpath(resource.path); + if (resource.authority && dirname.length && dirname.charCodeAt(0) !== CharCode.Slash) { return null; // If a URI contains an authority component, then the path component must either be empty or begin with a slash ("/") character } - return resource.with({ path: dirname }); } export function joinPath(resource: URI, pathFragment: string): URI { - const joinedPath = paths.join(resource.path || '/', pathFragment); + if (resource.scheme === 'file') { + return URI.file(paths.join(resource.path || '/', pathFragment)); + } + + let path = resource.path || ''; + let last = path.charCodeAt(path.length - 1); + let next = pathFragment.charCodeAt(0); + if (last !== CharCode.Slash) { + if (next !== CharCode.Slash) { + path += '/'; + } + } else { + if (next === CharCode.Slash) { + pathFragment = pathFragment.substr(1); + } + } return resource.with({ - path: joinedPath + path: path + pathFragment }); } @@ -90,3 +115,27 @@ export function distinctParents(items: T[], resourceAccessor: (item: T) => UR return distinctParents; } + +function dirname_urlpath(path: string): string { + const idx = ~path.lastIndexOf('/'); + if (idx === 0) { + return ''; + } else if (~idx === 0) { + return path[0]; + } else if (~idx === path.length - 1) { + return dirname_urlpath(path.substring(0, path.length - 1)); + } else { + return path.substring(0, ~idx); + } +} + +function basename_urlpath(path: string): string { + const idx = ~path.lastIndexOf('/'); + if (idx === 0) { + return path; + } else if (~idx === path.length - 1) { + return basename_urlpath(path.substring(0, path.length - 1)); + } else { + return path.substr(~idx + 1); + } +} diff --git a/src/vs/base/test/common/resources.test.ts b/src/vs/base/test/common/resources.test.ts index 2c5509a740a..42026e111c3 100644 --- a/src/vs/base/test/common/resources.test.ts +++ b/src/vs/base/test/common/resources.test.ts @@ -5,8 +5,7 @@ 'use strict'; import * as assert from 'assert'; -import { normalize } from 'vs/base/common/paths'; -import { dirname, distinctParents, joinPath, isEqual, isEqualOrParent, hasToIgnoreCase } from 'vs/base/common/resources'; +import { dirname, basename, distinctParents, joinPath, isEqual, isEqualOrParent, hasToIgnoreCase } from 'vs/base/common/resources'; import URI from 'vs/base/common/uri'; import { isWindows } from 'vs/base/common/platform'; @@ -44,26 +43,62 @@ suite('Resources', () => { }); test('dirname', () => { - const f = URI.file('/some/file/test.txt'); - const d = dirname(f); - assert.equal(d.fsPath, normalize('/some/file', true)); + if (isWindows) { + assert.equal(dirname(URI.file('c:\\some\\file\\test.txt')).toString(), 'file:///c%3A/some/file'); + assert.equal(dirname(URI.file('c:\\some\\file')).toString(), 'file:///c%3A/some'); + assert.equal(dirname(URI.file('c:\\some\\file\\')).toString(), 'file:///c%3A/some'); + assert.equal(dirname(URI.file('c:\\some')).toString(), 'file:///c%3A/'); + } else { + assert.equal(dirname(URI.file('/some/file/test.txt')).toString(), 'file:///some/file'); + assert.equal(dirname(URI.file('/some/file/')).toString(), 'file:///some'); + assert.equal(dirname(URI.file('/some/file')).toString(), 'file:///some'); + assert.equal(dirname(URI.file('/some/file')).toString(), 'file:///some'); + } + assert.equal(dirname(URI.parse('foo://a/some/file/test.txt')).toString(), 'foo://a/some/file'); + assert.equal(dirname(URI.parse('foo://a/some/file/')).toString(), 'foo://a/some'); + assert.equal(dirname(URI.parse('foo://a/some/file')).toString(), 'foo://a/some'); + assert.equal(dirname(URI.parse('foo://a/some')).toString(), 'foo://a/'); + + // does not explode (https://github.com/Microsoft/vscode/issues/41987) + dirname(URI.from({ scheme: 'file', authority: '/users/someone/portal.h' })); + }); + + test('basename', () => { + if (isWindows) { + assert.equal(basename(URI.file('c:\\some\\file\\test.txt')).toString(), 'test.txt'); + assert.equal(basename(URI.file('c:\\some\\file')).toString(), 'file'); + assert.equal(basename(URI.file('c:\\some\\file\\')).toString(), 'file'); + } else { + assert.equal(basename(URI.file('/some/file/test.txt')).toString(), 'test.txt'); + assert.equal(basename(URI.file('/some/file/')).toString(), 'file'); + assert.equal(basename(URI.file('/some/file')).toString(), 'file'); + assert.equal(basename(URI.file('/some')).toString(), 'some'); + } + assert.equal(basename(URI.parse('foo://a/some/file/test.txt')).toString(), 'test.txt'); + assert.equal(basename(URI.parse('foo://a/some/file/')).toString(), 'file'); + assert.equal(basename(URI.parse('foo://a/some/file')).toString(), 'file'); + assert.equal(basename(URI.parse('foo://a/some')).toString(), 'some'); // does not explode (https://github.com/Microsoft/vscode/issues/41987) dirname(URI.from({ scheme: 'file', authority: '/users/someone/portal.h' })); }); test('joinPath', () => { - assert.equal( - joinPath(URI.file('/foo/bar'), '/file.js').toString(), - 'file:///foo/bar/file.js'); - - assert.equal( - joinPath(URI.file('/foo/bar/'), '/file.js').toString(), - 'file:///foo/bar/file.js'); - - assert.equal( - joinPath(URI.file('/'), '/file.js').toString(), - 'file:///file.js'); + if (isWindows) { + assert.equal(joinPath(URI.file('c:\\foo\\bar'), '/file.js').toString(), 'file:///c%3A/foo/bar/file.js'); + assert.equal(joinPath(URI.file('c:\\foo\\bar\\'), 'file.js').toString(), 'file:///c%3A/foo/bar/file.js'); + assert.equal(joinPath(URI.file('c:\\foo\\bar\\'), '/file.js').toString(), 'file:///c%3A/foo/bar/file.js'); + assert.equal(joinPath(URI.file('c:\\'), '/file.js').toString(), 'file:///c%3A/file.js'); + } else { + assert.equal(joinPath(URI.file('/foo/bar'), '/file.js').toString(), 'file:///foo/bar/file.js'); + assert.equal(joinPath(URI.file('/foo/bar'), 'file.js').toString(), 'file:///foo/bar/file.js'); + assert.equal(joinPath(URI.file('/foo/bar/'), '/file.js').toString(), 'file:///foo/bar/file.js'); + assert.equal(joinPath(URI.file('/'), '/file.js').toString(), 'file:///file.js'); + } + assert.equal(joinPath(URI.parse('foo://a/foo/bar'), '/file.js').toString(), 'foo://a/foo/bar/file.js'); + assert.equal(joinPath(URI.parse('foo://a/foo/bar'), 'file.js').toString(), 'foo://a/foo/bar/file.js'); + assert.equal(joinPath(URI.parse('foo://a/foo/bar/'), '/file.js').toString(), 'foo://a/foo/bar/file.js'); + assert.equal(joinPath(URI.parse('foo://a/'), '/file.js').toString(), 'foo://a/file.js'); assert.equal( joinPath(URI.from({ scheme: 'myScheme', authority: 'authority', path: '/path', query: 'query', fragment: 'fragment' }), '/file.js').toString(), From 753e9a7cb82d215d79e8aa5c302de79c0b656e4c Mon Sep 17 00:00:00 2001 From: Peng Lyu Date: Tue, 7 Aug 2018 11:58:55 -0700 Subject: [PATCH 0558/1276] Fix microsoft/vscode-pull-request-github#129. Diff Editor should not reset the gutter width everytime. --- src/vs/editor/browser/widget/diffEditorWidget.ts | 2 +- src/vs/workbench/browser/parts/editor/textDiffEditor.ts | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/src/vs/editor/browser/widget/diffEditorWidget.ts b/src/vs/editor/browser/widget/diffEditorWidget.ts index dbd07dd8a74..1a0970f501d 100644 --- a/src/vs/editor/browser/widget/diffEditorWidget.ts +++ b/src/vs/editor/browser/widget/diffEditorWidget.ts @@ -944,7 +944,7 @@ export class DiffEditorWidget extends Disposable implements editorBrowser.IDiffE clonedOptions.folding = false; clonedOptions.codeLens = false; clonedOptions.fixedOverflowWidgets = true; - clonedOptions.lineDecorationsWidth = '2ch'; + // clonedOptions.lineDecorationsWidth = '2ch'; if (!clonedOptions.minimap) { clonedOptions.minimap = {}; } diff --git a/src/vs/workbench/browser/parts/editor/textDiffEditor.ts b/src/vs/workbench/browser/parts/editor/textDiffEditor.ts index f59bae6f10b..de98bed575e 100644 --- a/src/vs/workbench/browser/parts/editor/textDiffEditor.ts +++ b/src/vs/workbench/browser/parts/editor/textDiffEditor.ts @@ -232,6 +232,7 @@ export class TextDiffEditor extends BaseTextEditor implements ITextDiffEditor { const options: IDiffEditorOptions = super.getConfigurationOverrides(); options.readOnly = this.isReadOnly(); + options.lineDecorationsWidth = '2ch'; return options; } From b133355cb1c8999cc83d78d444d1427588cdc8c6 Mon Sep 17 00:00:00 2001 From: Ramya Achutha Rao Date: Tue, 7 Aug 2018 12:18:22 -0700 Subject: [PATCH 0559/1276] Mark all json files under appSettingsHome as settings --- .../textfile/common/textFileEditorModel.ts | 55 ++++++++++++++----- 1 file changed, 42 insertions(+), 13 deletions(-) diff --git a/src/vs/workbench/services/textfile/common/textFileEditorModel.ts b/src/vs/workbench/services/textfile/common/textFileEditorModel.ts index aea7e08e8f0..08d9ae4bc7a 100644 --- a/src/vs/workbench/services/textfile/common/textFileEditorModel.ts +++ b/src/vs/workbench/services/textfile/common/textFileEditorModel.ts @@ -43,6 +43,7 @@ export class TextFileEditorModel extends BaseTextEditorModel implements ITextFil static DEFAULT_CONTENT_CHANGE_BUFFER_DELAY = CONTENT_CHANGE_EVENT_BUFFER_DELAY; static DEFAULT_ORPHANED_CHANGE_BUFFER_DELAY = 100; static WHITELIST_JSON = ['package.json', 'package-lock.json', 'tsconfig.json', 'jsconfig.json', 'bower.json', '.eslintrc.json', 'tslint.json', 'composer.json']; + static WHITELIST_WORKSPACE_JSON = ['settings.json', 'extensions.json', 'tasks.json', 'launch.json']; private static saveErrorHandler: ISaveErrorHandler; static setSaveErrorHandler(handler: ISaveErrorHandler): void { TextFileEditorModel.saveErrorHandler = handler; } @@ -351,13 +352,15 @@ export class TextFileEditorModel extends BaseTextEditorModel implements ITextFil private loadWithContent(content: IRawTextContent, options?: ILoadOptions, backup?: URI): TPromise { return this.doLoadWithContent(content, backup).then(model => { - // Telemetry: We log the fileGet telemetry event after the model has been loaded to ensure a good mimetype - if (this.isSettingsFile()) { + const settingsType = this.getTypeIfSettings(); + if (settingsType) { /* __GDPR__ - "settingsRead" : {} + "settingsRead" : { + "settingsType": { "classification": "SystemMetaData", "purpose": "FeatureInsight" }, + } */ - this.telemetryService.publicLog('settingsRead'); // Do not log read to user settings.json and .vscode folder as a fileGet event as it ruins our JSON usage data + this.telemetryService.publicLog('settingsRead', { settingsType }); // Do not log read to user settings.json and .vscode folder as a fileGet event as it ruins our JSON usage data } else { /* __GDPR__ "fileGet" : { @@ -712,11 +715,14 @@ export class TextFileEditorModel extends BaseTextEditorModel implements ITextFil this.logService.trace(`doSave(${versionId}) - after updateContent()`, this.resource); // Telemetry - if (this.isSettingsFile()) { + const settingsType = this.getTypeIfSettings(); + if (settingsType) { /* __GDPR__ - "settingsWritten" : {} + "settingsWritten" : { + "settingsType": { "classification": "SystemMetaData", "purpose": "FeatureInsight" }, + } */ - this.telemetryService.publicLog('settingsWritten'); // Do not log write to user settings.json and .vscode folder as a filePUT event as it ruins our JSON usage data + this.telemetryService.publicLog('settingsWritten', { settingsType }); // Do not log write to user settings.json and .vscode folder as a filePUT event as it ruins our JSON usage data } else { /* __GDPR__ "filePUT" : { @@ -770,20 +776,43 @@ export class TextFileEditorModel extends BaseTextEditorModel implements ITextFil })); } - private isSettingsFile(): boolean { + private getTypeIfSettings(): string { if (path.extname(this.resource.fsPath) !== '.json') { - return false; + return ''; } // Check for global settings file if (isEqual(this.resource, URI.file(this.environmentService.appSettingsPath), !isLinux)) { - return true; + return 'global-settings'; + } + + // Check for keybindings file + if (isEqual(this.resource, URI.file(this.environmentService.appKeybindingsPath), !isLinux)) { + return 'keybindings'; + } + + // Check for locale file + if (isEqual(this.resource, URI.file(path.join(this.environmentService.appSettingsHome, 'locale.json')), !isLinux)) { + return 'locale'; + } + + // Check for snippets + if (isEqualOrParent(this.resource, URI.file(path.join(this.environmentService.appSettingsHome, 'snippets')), hasToIgnoreCase(this.resource))) { + return 'snippets'; } // Check for workspace settings file - return this.contextService.getWorkspace().folders.some(folder => { - return isEqualOrParent(this.resource, folder.toResource('.vscode'), hasToIgnoreCase(this.resource)); - }); + const folders = this.contextService.getWorkspace().folders; + for (let i = 0; i < folders.length; i++) { + if (isEqualOrParent(this.resource, folders[i].toResource('.vscode'), hasToIgnoreCase(this.resource))) { + const filename = path.basename(this.resource.fsPath); + if (TextFileEditorModel.WHITELIST_WORKSPACE_JSON.indexOf(filename) > -1) { + return `.vscode/${filename}`; + } + } + } + + return ''; } private getTelemetryData(reason: number): Object { From 868140430de969ad554e66f9df1e1f6a30c8f4cb Mon Sep 17 00:00:00 2001 From: Martin Aeschlimann Date: Tue, 7 Aug 2018 21:36:06 +0200 Subject: [PATCH 0560/1276] `vscode.openFolder`: treat missing URI schema gracefully (for #55891) --- src/vs/workbench/api/node/apiCommands.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/vs/workbench/api/node/apiCommands.ts b/src/vs/workbench/api/node/apiCommands.ts index e423299e951..9adcf231889 100644 --- a/src/vs/workbench/api/node/apiCommands.ts +++ b/src/vs/workbench/api/node/apiCommands.ts @@ -49,7 +49,8 @@ export class OpenFolderAPICommand { return executor.executeCommand('_files.pickFolderAndOpen', forceNewWindow); } if (!uri.scheme) { - throw new Error(`Invalid URI, schema required: '${uri.toString()}'.`); + console.warn('`vscode.openFolder` command invoked with an invalid URI (scheme missing): `${uri}`. Converted to a `file://` URI.'); + uri = URI.file(uri.fsPath); } return executor.executeCommand('_files.windowOpen', [uri], forceNewWindow); From 6a1515671fcc3f28ca1682cd9ea6ca24b47f0b8b Mon Sep 17 00:00:00 2001 From: Jackson Kearl Date: Tue, 7 Aug 2018 13:47:29 -0700 Subject: [PATCH 0561/1276] Markdown region folding (#55399) * Add foldin g of regions to markdown * Add test for region folding * Tweak region identification regex --- .../src/features/foldingProvider.ts | 39 ++++++++++++++++--- .../src/test/foldingProvider.test.ts | 25 ++++++++++++ 2 files changed, 59 insertions(+), 5 deletions(-) diff --git a/extensions/markdown-language-features/src/features/foldingProvider.ts b/extensions/markdown-language-features/src/features/foldingProvider.ts index 236908a1f1f..5f0d6480ff3 100644 --- a/extensions/markdown-language-features/src/features/foldingProvider.ts +++ b/extensions/markdown-language-features/src/features/foldingProvider.ts @@ -7,6 +7,7 @@ import * as vscode from 'vscode'; import { MarkdownEngine } from '../markdownEngine'; import { TableOfContentsProvider } from '../tableOfContentsProvider'; +import { Token } from 'markdown-it'; const rangeLimit = 5000; @@ -16,15 +17,44 @@ export default class MarkdownFoldingProvider implements vscode.FoldingRangeProvi private readonly engine: MarkdownEngine ) { } + private async getRegions(document: vscode.TextDocument): Promise { + + const isStartRegion = (t: string) => /^\s*/.test(t); + const isEndRegion = (t: string) => /^\s*/.test(t); + + const isRegionMarker = (token: Token) => token.type === 'html_block' && + (isStartRegion(token.content) || isEndRegion(token.content)); + + + const tokens = await this.engine.parse(document.uri, document.getText()); + const regionMarkers = tokens.filter(isRegionMarker) + .map(token => ({ line: token.map[0], isStart: isStartRegion(token.content) })); + + const nestingStack: { line: number, isStart: boolean }[] = []; + return regionMarkers + .map(marker => { + if (marker.isStart) { + nestingStack.push(marker); + } else if (nestingStack.length && nestingStack[nestingStack.length - 1].isStart) { + return new vscode.FoldingRange(nestingStack.pop()!.line, marker.line, vscode.FoldingRangeKind.Region); + } else { + // noop: invalid nesting (i.e. [end, start] or [start, end, end]) + } + return null; + }) + .filter((region: vscode.FoldingRange | null): region is vscode.FoldingRange => !!region); + } + public async provideFoldingRanges( document: vscode.TextDocument, _: vscode.FoldingContext, _token: vscode.CancellationToken ): Promise { const tocProvider = new TableOfContentsProvider(this.engine, document); - let toc = await tocProvider.getToc(); - if (toc.length > rangeLimit) { - toc = toc.slice(0, rangeLimit); + let [regions, toc] = await Promise.all([this.getRegions(document), tocProvider.getToc()]); + + if (toc.length > rangeLimit - regions.length) { + toc = toc.slice(0, rangeLimit - regions.length); } const foldingRanges = toc.map((entry, startIndex) => { @@ -44,7 +74,6 @@ export default class MarkdownFoldingProvider implements vscode.FoldingRangeProvi typeof end === 'number' ? end : document.lineCount - 1); }); - - return foldingRanges; + return [...regions, ...foldingRanges]; } } \ No newline at end of file diff --git a/extensions/markdown-language-features/src/test/foldingProvider.test.ts b/extensions/markdown-language-features/src/test/foldingProvider.test.ts index 44c570d64d4..cd3b82d599e 100644 --- a/extensions/markdown-language-features/src/test/foldingProvider.test.ts +++ b/extensions/markdown-language-features/src/test/foldingProvider.test.ts @@ -78,6 +78,31 @@ y`); assert.strictEqual(firstFold.end, 2); }); + test('Should fold nested markers', async () => { + const folds = await getFoldsForDocument(`a + +b + +b.a + +b + +b.b + +b + +a`); + assert.strictEqual(folds.length, 3); + const [outer, first, second] = folds.sort((a, b) => a.start - b.start); + + assert.strictEqual(outer.start, 1); + assert.strictEqual(outer.end, 11); + assert.strictEqual(first.start, 3); + assert.strictEqual(first.end, 5); + assert.strictEqual(second.start, 7); + assert.strictEqual(second.end, 9); + }); + }); From b819b81388538988255c7e9b1fd57d2a90412702 Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Tue, 7 Aug 2018 14:14:43 -0700 Subject: [PATCH 0562/1276] vscode-xterm@3.7.0-beta3 Fixes #55320 --- package.json | 2 +- yarn.lock | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/package.json b/package.json index f13936cd4e8..11eeb0c2ecd 100644 --- a/package.json +++ b/package.json @@ -50,7 +50,7 @@ "vscode-nsfw": "1.0.17", "vscode-ripgrep": "^1.0.1", "vscode-textmate": "^4.0.1", - "vscode-xterm": "3.7.0-beta2", + "vscode-xterm": "3.7.0-beta3", "winreg": "^1.2.4", "yauzl": "^2.9.1" }, diff --git a/yarn.lock b/yarn.lock index 1d81bc278d2..9cb248b5d3f 100644 --- a/yarn.lock +++ b/yarn.lock @@ -6125,9 +6125,9 @@ vscode-textmate@^4.0.1: dependencies: oniguruma "^7.0.0" -vscode-xterm@3.7.0-beta2: - version "3.7.0-beta2" - resolved "https://registry.yarnpkg.com/vscode-xterm/-/vscode-xterm-3.7.0-beta2.tgz#b46417f740ee6a90875ab956b4583f20a09cc2db" +vscode-xterm@3.7.0-beta3: + version "3.7.0-beta3" + resolved "https://registry.yarnpkg.com/vscode-xterm/-/vscode-xterm-3.7.0-beta3.tgz#2306f9650ee2f55637ba1804d10c5ffb9ef944f6" vso-node-api@^6.1.2-preview: version "6.1.2-preview" From 37199daa9f0c6eb199c4a9e5644c2cc8873f4e23 Mon Sep 17 00:00:00 2001 From: Ramya Achutha Rao Date: Tue, 7 Aug 2018 14:55:41 -0700 Subject: [PATCH 0563/1276] Use localized strings for telemetry opt-out --- .../electron-browser/telemetryOptOut.ts | 122 ++++++++++++------ 1 file changed, 85 insertions(+), 37 deletions(-) diff --git a/src/vs/workbench/parts/welcome/gettingStarted/electron-browser/telemetryOptOut.ts b/src/vs/workbench/parts/welcome/gettingStarted/electron-browser/telemetryOptOut.ts index 3c76c9bedb4..62b0d5e5916 100644 --- a/src/vs/workbench/parts/welcome/gettingStarted/electron-browser/telemetryOptOut.ts +++ b/src/vs/workbench/parts/welcome/gettingStarted/electron-browser/telemetryOptOut.ts @@ -16,20 +16,26 @@ import { onUnexpectedError } from 'vs/base/common/errors'; import { IWindowService, IWindowsService } from 'vs/platform/windows/common/windows'; import { IExperimentService, ExperimentState } from 'vs/workbench/parts/experiments/node/experimentService'; import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; +import { language, locale } from 'vs/base/common/platform'; +import { TPromise } from 'vs/base/common/winjs.base'; +import { IExtensionGalleryService } from 'vs/platform/extensionManagement/common/extensionManagement'; export class TelemetryOptOut implements IWorkbenchContribution { private static TELEMETRY_OPT_OUT_SHOWN = 'workbench.telemetryOptOutShown'; + private privacyUrl: string; + private optOutUrl: string; constructor( @IStorageService storageService: IStorageService, @IOpenerService openerService: IOpenerService, - @INotificationService notificationService: INotificationService, + @INotificationService private notificationService: INotificationService, @IWindowService windowService: IWindowService, @IWindowsService windowsService: IWindowsService, - @ITelemetryService telemetryService: ITelemetryService, - @IExperimentService experimentService: IExperimentService, - @IConfigurationService configurationService: IConfigurationService + @ITelemetryService private telemetryService: ITelemetryService, + @IExperimentService private experimentService: IExperimentService, + @IConfigurationService private configurationService: IConfigurationService, + @IExtensionGalleryService private galleryService: IExtensionGalleryService ) { if (!product.telemetryOptOutUrl || storageService.get(TelemetryOptOut.TELEMETRY_OPT_OUT_SHOWN)) { return; @@ -45,53 +51,95 @@ export class TelemetryOptOut implements IWorkbenchContribution { } storageService.store(TelemetryOptOut.TELEMETRY_OPT_OUT_SHOWN, true); - const optOutUrl = product.telemetryOptOutUrl; - const privacyUrl = product.privacyStatementUrl || product.telemetryOptOutUrl; + this.optOutUrl = product.telemetryOptOutUrl; + this.privacyUrl = product.privacyStatementUrl || product.telemetryOptOutUrl; if (experimentState && experimentState.state === ExperimentState.Run && telemetryService.isOptedIn) { - const logTelemetry = (optout: boolean) => { - /* __GDPR__ - "experiments:optout" : { - "optOut": { "classification": "SystemMetaData", "purpose": "FeatureInsight", "isMeasurement": true } - } - */ - telemetryService.publicLog('experiments:optout', { optout }); - }; - notificationService.prompt( - Severity.Info, - localize('telemetryOptOut.optOutOption', "Please help Microsoft improve Visual Studio Code by allowing the collection of usage data. Read our [privacy statement]({0}) for more details.", privacyUrl), - [ - { - label: localize('telemetryOptOut.OptIn', "Yes, glad to help"), - run: () => { - logTelemetry(false); - } - }, - { - label: localize('telemetryOptOut.OptOut', "No, thanks"), - run: () => { - logTelemetry(true); - configurationService.updateValue('telemetry.enableTelemetry', false); - configurationService.updateValue('telemetry.enableCrashReporter', false); - } - }] - ); - experimentService.markAsCompleted(experimentId); + this.runExperiment(experimentId); return; } - const optOutNotice = localize('telemetryOptOut.optOutNotice', "Help improve VS Code by allowing Microsoft to collect usage data. Read our [privacy statement]({0}) and learn how to [opt out]({1}).", privacyUrl, optOutUrl); - const optInNotice = localize('telemetryOptOut.optInNotice', "Help improve VS Code by allowing Microsoft to collect usage data. Read our [privacy statement]({0}) and learn how to [opt in]({1}).", privacyUrl, optOutUrl); + const optOutNotice = localize('telemetryOptOut.optOutNotice', "Help improve VS Code by allowing Microsoft to collect usage data. Read our [privacy statement]({0}) and learn how to [opt out]({1}).", this.privacyUrl, this.optOutUrl); + const optInNotice = localize('telemetryOptOut.optInNotice', "Help improve VS Code by allowing Microsoft to collect usage data. Read our [privacy statement]({0}) and learn how to [opt in]({1}).", this.privacyUrl, this.optOutUrl); notificationService.prompt( Severity.Info, telemetryService.isOptedIn ? optOutNotice : optInNotice, [{ label: localize('telemetryOptOut.readMore', "Read More"), - run: () => openerService.open(URI.parse(optOutUrl)) + run: () => openerService.open(URI.parse(this.optOutUrl)) }] ); }) .then(null, onUnexpectedError); } + + private runExperiment(experimentId: string) { + const promptMessageKey = 'telemetryOptOut.optOutOption'; + const yesLabelKey = 'telemetryOptOut.OptIn'; + const noLabelKey = 'telemetryOptOut.OptOut'; + + let promptMessage = localize('telemetryOptOut.optOutOption', "Please help Microsoft improve Visual Studio Code by allowing the collection of usage data. Read our [privacy statement]({0}) for more details.", this.privacyUrl); + let yesLabel = localize('telemetryOptOut.OptIn', "Yes, glad to help"); + let noLabel = localize('telemetryOptOut.OptOut', "No, thanks"); + + let queryPromise = TPromise.as(undefined); + if ((locale !== language && locale !== 'en' && locale.indexOf('en-') === -1)) { + queryPromise = this.galleryService.query({ text: `tag:lp-${locale}` }).then(tagResult => { + if (!tagResult || !tagResult.total) { + return undefined; + } + const extensionToFetchTranslationsFrom = tagResult.firstPage.filter(e => e.publisher === 'MS-CEINTL' && e.name.indexOf('vscode-language-pack') === 0)[0] || tagResult.firstPage[0]; + if (!extensionToFetchTranslationsFrom.assets || !extensionToFetchTranslationsFrom.assets.coreTranslations) { + return undefined; + } + + return this.galleryService.getCoreTranslation(extensionToFetchTranslationsFrom, locale) + .then(translation => { + const translationsFromPack = translation && translation.contents ? translation.contents['vs/workbench/parts/welcome/gettingStarted/electron-browser/telemetryOptOut'] : {}; + if (!!translationsFromPack[promptMessageKey] && !!translationsFromPack[yesLabelKey] && !!translationsFromPack[noLabelKey]) { + promptMessage = translationsFromPack[promptMessageKey].replace('{0}', this.privacyUrl) + ' (Please help Microsoft improve Visual Studio Code by allowing the collection of usage data.)'; + yesLabel = translationsFromPack[yesLabelKey] + ' (Yes)'; + noLabel = translationsFromPack[noLabelKey] + ' (No)'; + } + return undefined; + }); + + }); + } + + const logTelemetry = (optout?: boolean) => { + /* __GDPR__ + "experiments:optout" : { + "optOut": { "classification": "SystemMetaData", "purpose": "FeatureInsight", "isMeasurement": true } + } + */ + this.telemetryService.publicLog('experiments:optout', typeof optout === 'boolean' ? { optout } : {}); + }; + + queryPromise.then(() => { + this.notificationService.prompt( + Severity.Info, + promptMessage, + [ + { + label: yesLabel, + run: () => { + logTelemetry(false); + } + }, + { + label: noLabel, + run: () => { + logTelemetry(true); + this.configurationService.updateValue('telemetry.enableTelemetry', false); + this.configurationService.updateValue('telemetry.enableCrashReporter', false); + } + } + ], + logTelemetry + ); + this.experimentService.markAsCompleted(experimentId); + }); + } } From 9cb6826535ac9091256440b05d1bede126dac753 Mon Sep 17 00:00:00 2001 From: Rachel Macfarlane Date: Tue, 7 Aug 2018 15:03:53 -0700 Subject: [PATCH 0564/1276] Improve handling for comment creation failure --- .../electron-browser/commentThreadWidget.ts | 114 +++++++++++------- .../electron-browser/media/review.css | 23 ++++ 2 files changed, 92 insertions(+), 45 deletions(-) diff --git a/src/vs/workbench/parts/comments/electron-browser/commentThreadWidget.ts b/src/vs/workbench/parts/comments/electron-browser/commentThreadWidget.ts index 3bdfec6fc9c..0d7cb1eea2d 100644 --- a/src/vs/workbench/parts/comments/electron-browser/commentThreadWidget.ts +++ b/src/vs/workbench/parts/comments/electron-browser/commentThreadWidget.ts @@ -25,7 +25,7 @@ import { IInstantiationService } from 'vs/platform/instantiation/common/instanti import { IModelService } from 'vs/editor/common/services/modelService'; import { SimpleCommentEditor } from './simpleCommentEditor'; import URI from 'vs/base/common/uri'; -import { transparent, editorForeground, inputValidationErrorBorder, textLinkActiveForeground, textLinkForeground, focusBorder, textBlockQuoteBackground, textBlockQuoteBorder, contrastBorder } from 'vs/platform/theme/common/colorRegistry'; +import { transparent, editorForeground, inputValidationErrorBorder, textLinkActiveForeground, textLinkForeground, focusBorder, textBlockQuoteBackground, textBlockQuoteBorder, contrastBorder, inputValidationErrorBackground } from 'vs/platform/theme/common/colorRegistry'; import { IModeService } from 'vs/editor/common/services/modeService'; import { IKeyboardEvent } from 'vs/base/browser/keyboardEvent'; import { KeyCode } from 'vs/base/common/keyCodes'; @@ -47,9 +47,11 @@ export class CommentNode { private _body: HTMLElement; private _md: HTMLElement; private _clearTimeout: any; + public get domNode(): HTMLElement { return this._domNode; } + constructor( public comment: modes.Comment, private markdownRenderer: MarkdownRenderer, @@ -117,6 +119,7 @@ export class ReviewZoneWidget extends ZoneWidget { private _localToDispose: IDisposable[]; private _markdownRenderer: MarkdownRenderer; private _styleElement: HTMLStyleElement; + private _error: HTMLElement; public get owner(): number { return this._owner; @@ -286,7 +289,7 @@ export class ReviewZoneWidget extends ZoneWidget { } protected _doLayout(heightInPixel: number, widthInPixel: number): void { - this._commentEditor.layout({ height: (this._commentEditor.hasWidgetFocus() ? 5 : 1) * 18, width: widthInPixel - 40 /* margin */ }); + this._commentEditor.layout({ height: (this._commentEditor.hasWidgetFocus() ? 5 : 1) * 18, width: widthInPixel - 42 /* margin */ }); } display(lineNumber: number, commentsOptions: ModelDecorationOptions) { @@ -365,58 +368,25 @@ export class ReviewZoneWidget extends ZoneWidget { } })); + this._error = $('.validation-error.hidden').appendTo(this._commentForm).getHTMLElement(); + const formActions = $('.form-actions').appendTo(this._commentForm).getHTMLElement(); const button = new Button(formActions); attachButtonStyler(button, this.themeService); button.label = 'Add comment'; - button.onDidClick(async () => { - if (!this._commentEditor.getValue()) { - this._commentEditor.focus(); - this._commentEditor.getDomNode().style.outline = `1px solid ${this.themeService.getTheme().getColor(inputValidationErrorBorder)}`; - - this._disposables.push(this._commentEditor.onDidChangeModelContent(_ => { - if (!this._commentEditor.getValue()) { - this._commentEditor.getDomNode().style.outline = `1px solid ${this.themeService.getTheme().getColor(inputValidationErrorBorder)}`; - } else { - this._commentEditor.getDomNode().style.outline = ''; - } - })); - - return; - } - - let newCommentThread; - if (this._commentThread.threadId) { - // reply - newCommentThread = await this.commentService.replyToCommentThread( - this._owner, - this.editor.getModel().uri, - new Range(lineNumber, 1, lineNumber, 1), - this._commentThread, - this._commentEditor.getValue() - ); + button.enabled = false; + this._localToDispose.push(this._commentEditor.onDidChangeModelContent(_ => { + if (this._commentEditor.getValue()) { + button.enabled = true; } else { - newCommentThread = await this.commentService.createNewCommentThread( - this._owner, - this.editor.getModel().uri, - new Range(lineNumber, 1, lineNumber, 1), - this._commentEditor.getValue() - ); - - this.createReplyButton(); - this.createParticipantsLabel(); + button.enabled = false; } + })); - this._commentEditor.setValue(''); - if (dom.hasClass(this._commentForm, 'expand')) { - dom.removeClass(this._commentForm, 'expand'); - } - - if (newCommentThread) { - this.update(newCommentThread); - } + button.onDidClick(async () => { + this.createComment(lineNumber); }); this._resizeObserver = new MutationObserver(this._refresh.bind(this)); @@ -438,6 +408,50 @@ export class ReviewZoneWidget extends ZoneWidget { } } + private async createComment(lineNumber: number): Promise { + let newCommentThread; + + if (this._commentThread.threadId) { + // reply + newCommentThread = await this.commentService.replyToCommentThread( + this._owner, + this.editor.getModel().uri, + new Range(lineNumber, 1, lineNumber, 1), + this._commentThread, + this._commentEditor.getValue() + ); + } else { + newCommentThread = await this.commentService.createNewCommentThread( + this._owner, + this.editor.getModel().uri, + new Range(lineNumber, 1, lineNumber, 1), + this._commentEditor.getValue() + ); + + if (newCommentThread) { + this.createReplyButton(); + this.createParticipantsLabel(); + } + } + + if (newCommentThread) { + this._commentEditor.setValue(''); + if (dom.hasClass(this._commentForm, 'expand')) { + dom.removeClass(this._commentForm, 'expand'); + } + + this._commentEditor.getDomNode().style.outline = ''; + this._error.textContent = ''; + dom.addClass(this._error, 'hidden'); + + this.update(newCommentThread); + } else { + this._commentEditor.getDomNode().style.outline = `1px solid ${this.themeService.getTheme().getColor(inputValidationErrorBorder)}`; + this._error.textContent = nls.localize('commentCreationError', "Adding a comment failed. Please try again or report an issue with the extension if the problem persists."); + dom.removeClass(this._error, 'hidden'); + } + } + createParticipantsLabel() { const primaryHeading = 'Participants:'; $(this._primaryHeading).safeInnerHtml(primaryHeading); @@ -611,6 +625,16 @@ export class ReviewZoneWidget extends ZoneWidget { content.push(`.monaco-editor .review-widget .body .comment-form .monaco-editor { outline: 1px solid ${hcBorder}; }`); } + const errorBorder = theme.getColor(inputValidationErrorBorder); + if (errorBorder) { + content.push(`.monaco-editor .review-widget .body .comment-form .validation-error { border: 1px solid ${errorBorder}; }`); + } + + const errorBackground = theme.getColor(inputValidationErrorBackground); + if (errorBackground) { + content.push(`.monaco-editor .review-widget .body .comment-form .validation-error { background: ${errorBackground}; }`); + } + this._styleElement.innerHTML = content.join('\n'); // Editor decorations should also be responsive to theme changes diff --git a/src/vs/workbench/parts/comments/electron-browser/media/review.css b/src/vs/workbench/parts/comments/electron-browser/media/review.css index c2658cc248c..cb249b33a09 100644 --- a/src/vs/workbench/parts/comments/electron-browser/media/review.css +++ b/src/vs/workbench/parts/comments/electron-browser/media/review.css @@ -126,6 +126,29 @@ padding: 8px 0; } +.monaco-editor .review-widget .body .comment-form .validation-error { + display: inline-block; + overflow: hidden; + text-align: left; + width: 100%; + box-sizing: border-box; + -webkit-box-sizing: border-box; + -o-box-sizing: border-box; + -moz-box-sizing: border-box; + -ms-box-sizing: border-box; + padding: 0.4em; + font-size: 12px; + line-height: 17px; + min-height: 34px; + margin-top: -1px; + margin-left: -1px; + word-wrap: break-word; +} + +.monaco-editor .review-widget .body .comment-form .validation-error.hidden { + display: none; +} + .monaco-editor .review-widget .body .comment-form.expand .review-thread-reply-button { display: none; } From a40bfc947cb554c2df93486ba6166fd4339be0d6 Mon Sep 17 00:00:00 2001 From: Pine Wu Date: Tue, 7 Aug 2018 16:01:21 -0700 Subject: [PATCH 0565/1276] @import completion for css/scss/less. Fix #51331 --- .../css-language-features/.vscode/launch.json | 20 ++++++ extensions/css-language-features/package.json | 1 + .../server/src/pathCompletion.ts | 71 +++++++++++++++---- .../server/src/test/completion.test.ts | 54 ++++++++++++-- .../server/src/utils/strings.ts | 14 ++++ .../pathCompletionFixtures/scss/_foo.scss | 4 ++ .../pathCompletionFixtures/scss/main.scss | 4 ++ .../css-language-features/test/mocha.opts | 3 + 8 files changed, 152 insertions(+), 19 deletions(-) create mode 100644 extensions/css-language-features/server/test/pathCompletionFixtures/scss/_foo.scss create mode 100644 extensions/css-language-features/server/test/pathCompletionFixtures/scss/main.scss create mode 100644 extensions/css-language-features/test/mocha.opts diff --git a/extensions/css-language-features/.vscode/launch.json b/extensions/css-language-features/.vscode/launch.json index 9aad19d5b4e..d6393141c5d 100644 --- a/extensions/css-language-features/.vscode/launch.json +++ b/extensions/css-language-features/.vscode/launch.json @@ -54,6 +54,26 @@ ], "smartStep": true, "restart": true + }, + { + "name": "Server Unit Tests", + "type": "node", + "request": "launch", + "program": "${workspaceRoot}/node_modules/mocha/bin/_mocha", + "stopOnEntry": false, + "args": [ + "--timeout", + "999999", + "--colors" + ], + "cwd": "${workspaceRoot}", + "runtimeExecutable": null, + "runtimeArgs": [], + "env": {}, + "sourceMaps": true, + "outFiles": [ + "${workspaceRoot}/server/out/**" + ] } ] } \ No newline at end of file diff --git a/extensions/css-language-features/package.json b/extensions/css-language-features/package.json index 4c1b1a151c9..76da6212d8f 100644 --- a/extensions/css-language-features/package.json +++ b/extensions/css-language-features/package.json @@ -19,6 +19,7 @@ "scripts": { "compile": "gulp compile-extension:css-language-features-client compile-extension:css-language-features-server", "watch": "gulp watch-extension:css-language-features-client watch-extension:css-language-features-server", + "test": "mocha", "postinstall": "cd server && yarn install", "install-client-next": "yarn add vscode-languageclient@next" }, diff --git a/extensions/css-language-features/server/src/pathCompletion.ts b/extensions/css-language-features/server/src/pathCompletion.ts index b072c4136f6..4ea06882be2 100644 --- a/extensions/css-language-features/server/src/pathCompletion.ts +++ b/extensions/css-language-features/server/src/pathCompletion.ts @@ -12,7 +12,7 @@ import { TextDocument, CompletionList, CompletionItemKind, CompletionItem, TextE import { WorkspaceFolder } from 'vscode-languageserver'; import { ICompletionParticipant } from 'vscode-css-languageservice'; -import { startsWith } from './utils/strings'; +import { startsWith, endsWith } from './utils/strings'; export function getPathCompletionParticipant( document: TextDocument, @@ -21,32 +21,73 @@ export function getPathCompletionParticipant( ): ICompletionParticipant { return { onCssURILiteralValue: ({ position, range, uriValue }) => { - const isValueQuoted = startsWith(uriValue, `'`) || startsWith(uriValue, `"`); const fullValue = stripQuotes(uriValue); - const valueBeforeCursor = isValueQuoted - ? fullValue.slice(0, position.character - (range.start.character + 1)) - : fullValue.slice(0, position.character - range.start.character); - - if (fullValue === '.' || fullValue === '..') { - result.isIncomplete = true; + if (!shouldDoPathCompletion(uriValue, workspaceFolders)) { + if (fullValue === '.' || fullValue === '..') { + result.isIncomplete = true; + } return; } - if (!workspaceFolders || workspaceFolders.length === 0) { + let suggestions = providePathSuggestions(uriValue, position, range, document, workspaceFolders); + result.items = [...suggestions, ...result.items]; + }, + onCssImportPath: ({ position, range, pathValue }) => { + const fullValue = stripQuotes(pathValue); + if (!shouldDoPathCompletion(pathValue, workspaceFolders)) { + if (fullValue === '.' || fullValue === '..') { + result.isIncomplete = true; + } return; } - const workspaceRoot = resolveWorkspaceRoot(document, workspaceFolders); - const paths = providePaths(valueBeforeCursor, URI.parse(document.uri).fsPath, workspaceRoot); - const fullValueRange = isValueQuoted ? shiftRange(range, 1, -1) : range; - const replaceRange = pathToReplaceRange(valueBeforeCursor, fullValue, fullValueRange); - const suggestions = paths.map(p => pathToSuggestion(p, replaceRange)); + let suggestions = providePathSuggestions(pathValue, position, range, document, workspaceFolders); + + if (document.languageId === 'scss') { + suggestions.forEach(s => { + if (startsWith(s.label, '_') && endsWith(s.label, '.scss')) { + if (s.textEdit) { + s.textEdit.newText = s.label.slice(1, -5); + } else { + s.label = s.label.slice(1, -5); + } + } + }); + } result.items = [...suggestions, ...result.items]; } - }; } +function providePathSuggestions(pathValue: string, position: Position, range: Range, document: TextDocument, workspaceFolders: WorkspaceFolder[]) { + const fullValue = stripQuotes(pathValue); + const isValueQuoted = startsWith(pathValue, `'`) || startsWith(pathValue, `"`); + const valueBeforeCursor = isValueQuoted + ? fullValue.slice(0, position.character - (range.start.character + 1)) + : fullValue.slice(0, position.character - range.start.character); + const workspaceRoot = resolveWorkspaceRoot(document, workspaceFolders); + + const paths = providePaths(valueBeforeCursor, URI.parse(document.uri).fsPath, workspaceRoot); + const fullValueRange = isValueQuoted ? shiftRange(range, 1, -1) : range; + const replaceRange = pathToReplaceRange(valueBeforeCursor, fullValue, fullValueRange); + + const suggestions = paths.map(p => pathToSuggestion(p, replaceRange)); + return suggestions; +} + +function shouldDoPathCompletion(pathValue: string, workspaceFolders: WorkspaceFolder[]): boolean { + const fullValue = stripQuotes(pathValue); + if (fullValue === '.' || fullValue === '..') { + return false; + } + + if (!workspaceFolders || workspaceFolders.length === 0) { + return false; + } + + return true; +} + function stripQuotes(fullValue: string) { if (startsWith(fullValue, `'`) || startsWith(fullValue, `"`)) { return fullValue.slice(1, -1); diff --git a/extensions/css-language-features/server/src/test/completion.test.ts b/extensions/css-language-features/server/src/test/completion.test.ts index 62094de6b5b..2a68b5797cf 100644 --- a/extensions/css-language-features/server/src/test/completion.test.ts +++ b/extensions/css-language-features/server/src/test/completion.test.ts @@ -33,11 +33,11 @@ suite('Completions', () => { } }; - function assertCompletions(value: string, expected: { count?: number, items?: ItemDescription[] }, testUri: string, workspaceFolders?: WorkspaceFolder[]): void { + function assertCompletions(value: string, expected: { count?: number, items?: ItemDescription[] }, testUri: string, workspaceFolders?: WorkspaceFolder[], lang: string = 'css'): void { const offset = value.indexOf('|'); value = value.substr(0, offset) + value.substr(offset + 1); - const document = TextDocument.create(testUri, 'css', 0, value); + const document = TextDocument.create(testUri, lang, 0, value); const position = document.positionAt(offset); if (!workspaceFolders) { @@ -61,7 +61,7 @@ suite('Completions', () => { } } - test('CSS Path completion', function () { + test('CSS url() Path completion', function () { let testUri = Uri.file(path.resolve(__dirname, '../../test/pathCompletionFixtures/about/about.css')).toString(); let folders = [{ name: 'x', uri: Uri.file(path.resolve(__dirname, '../../test')).toString() }]; @@ -121,7 +121,7 @@ suite('Completions', () => { }, testUri, folders); }); - test('CSS Path Completion - Unquoted url', function () { + test('CSS url() Path Completion - Unquoted url', function () { let testUri = Uri.file(path.resolve(__dirname, '../../test/pathCompletionFixtures/about/about.css')).toString(); let folders = [{ name: 'x', uri: Uri.file(path.resolve(__dirname, '../../test')).toString() }]; @@ -149,4 +149,50 @@ suite('Completions', () => { ] }, testUri, folders); }); + + test('CSS @import Path completion', function () { + let testUri = Uri.file(path.resolve(__dirname, '../../test/pathCompletionFixtures/about/about.css')).toString(); + let folders = [{ name: 'x', uri: Uri.file(path.resolve(__dirname, '../../test')).toString() }]; + + assertCompletions(`@import './|'`, { + items: [ + { label: 'about.css', resultText: `@import './about.css'` }, + { label: 'about.html', resultText: `@import './about.html'` }, + ] + }, testUri, folders); + + assertCompletions(`@import '../|'`, { + items: [ + { label: 'about/', resultText: `@import '../about/'` }, + { label: 'scss/', resultText: `@import '../scss/'` }, + { label: 'index.html', resultText: `@import '../index.html'` }, + { label: 'src/', resultText: `@import '../src/'` } + ] + }, testUri, folders); + }); + + /** + * For SCSS, `@import 'foo';` can be used for importing partial file `_foo.scss` + */ + test('SCSS @import Path completion', function () { + let testCSSUri = Uri.file(path.resolve(__dirname, '../../test/pathCompletionFixtures/about/about.css')).toString(); + let folders = [{ name: 'x', uri: Uri.file(path.resolve(__dirname, '../../test')).toString() }]; + + /** + * We are in a CSS file, so no special treatment for SCSS partial files + */ + assertCompletions(`@import '../scss/|'`, { + items: [ + { label: 'main.scss', resultText: `@import '../scss/main.scss'` }, + { label: '_foo.scss', resultText: `@import '../scss/_foo.scss'` } + ] + }, testCSSUri, folders); + + let testSCSSUri = Uri.file(path.resolve(__dirname, '../../test/pathCompletionFixtures/scss/main.scss')).toString(); + assertCompletions(`@import './|'`, { + items: [ + { label: '_foo.scss', resultText: `@import './foo'` } + ] + }, testSCSSUri, folders, 'scss'); + }); }); \ No newline at end of file diff --git a/extensions/css-language-features/server/src/utils/strings.ts b/extensions/css-language-features/server/src/utils/strings.ts index f7ad0845cc8..114fb4f0808 100644 --- a/extensions/css-language-features/server/src/utils/strings.ts +++ b/extensions/css-language-features/server/src/utils/strings.ts @@ -17,3 +17,17 @@ export function startsWith(haystack: string, needle: string): boolean { return true; } + +/** + * Determines if haystack ends with needle. + */ +export function endsWith(haystack: string, needle: string): boolean { + let diff = haystack.length - needle.length; + if (diff > 0) { + return haystack.lastIndexOf(needle) === diff; + } else if (diff === 0) { + return haystack === needle; + } else { + return false; + } +} diff --git a/extensions/css-language-features/server/test/pathCompletionFixtures/scss/_foo.scss b/extensions/css-language-features/server/test/pathCompletionFixtures/scss/_foo.scss new file mode 100644 index 00000000000..adae63e647c --- /dev/null +++ b/extensions/css-language-features/server/test/pathCompletionFixtures/scss/_foo.scss @@ -0,0 +1,4 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ \ No newline at end of file diff --git a/extensions/css-language-features/server/test/pathCompletionFixtures/scss/main.scss b/extensions/css-language-features/server/test/pathCompletionFixtures/scss/main.scss new file mode 100644 index 00000000000..adae63e647c --- /dev/null +++ b/extensions/css-language-features/server/test/pathCompletionFixtures/scss/main.scss @@ -0,0 +1,4 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ \ No newline at end of file diff --git a/extensions/css-language-features/test/mocha.opts b/extensions/css-language-features/test/mocha.opts new file mode 100644 index 00000000000..20fcfb6eef6 --- /dev/null +++ b/extensions/css-language-features/test/mocha.opts @@ -0,0 +1,3 @@ +--ui tdd +--useColors true +server/out/test/**.test.js \ No newline at end of file From 3f9ec5f54bc65420de6951c4e3a3fec41c34ee22 Mon Sep 17 00:00:00 2001 From: Miguel Solorio Date: Tue, 7 Aug 2018 16:05:15 -0700 Subject: [PATCH 0566/1276] Allow text color in outline view to inheirt default foreground color --- .../parts/outline/electron-browser/outlinePanel.css | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/vs/workbench/parts/outline/electron-browser/outlinePanel.css b/src/vs/workbench/parts/outline/electron-browser/outlinePanel.css index 858ba8e3266..278df4543ae 100644 --- a/src/vs/workbench/parts/outline/electron-browser/outlinePanel.css +++ b/src/vs/workbench/parts/outline/electron-browser/outlinePanel.css @@ -71,11 +71,16 @@ display: none; } -.monaco-tree.focused .selected .outline-element-label, .monaco-tree.focused .selected .outline-element-decoration { +.monaco-tree.focused .selected .outline-element-label, .monaco-tree.focused .selected .outline-element-decoration{ /* make sure selection color wins when a label is being selected */ color: inherit !important; } +.monaco-tree.focused .selected .outline-element-label .monaco-highlighted-label .highlight{ + /* allows text color to overwrite highlight text when selected */ + color: inherit !important; +} + .monaco-workbench .outline-panel.no-icons .outline-element .outline-element-icon { display: none; } From 1bb3ff9ff2c1d0e996b2519b905d5664a8904221 Mon Sep 17 00:00:00 2001 From: Peng Lyu Date: Tue, 7 Aug 2018 16:32:45 -0700 Subject: [PATCH 0567/1276] comment range decorations should have its own color id. --- .../comments/electron-browser/commentsEditorContribution.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vs/workbench/parts/comments/electron-browser/commentsEditorContribution.ts b/src/vs/workbench/parts/comments/electron-browser/commentsEditorContribution.ts index 094367fe97b..67c5564c499 100644 --- a/src/vs/workbench/parts/comments/electron-browser/commentsEditorContribution.ts +++ b/src/vs/workbench/parts/comments/electron-browser/commentsEditorContribution.ts @@ -58,7 +58,7 @@ export class ReviewViewZone implements IViewZone { const overviewRulerDefault = new Color(new RGBA(197, 197, 197, 1)); -export const overviewRulerCommentingRangeForeground = registerColor('editorOverviewRuler.addedForeground', { dark: overviewRulerDefault, light: overviewRulerDefault, hc: overviewRulerDefault }, nls.localize('overviewRulerAddedForeground', 'Overview ruler marker color for added content.')); +export const overviewRulerCommentingRangeForeground = registerColor('editorGutter.commentRangeForeground', { dark: overviewRulerDefault, light: overviewRulerDefault, hc: overviewRulerDefault }, nls.localize('editorGutterCommentRangeForeground', 'Editor gutter decoration color for commenting ranges.')); class CommentingRangeDecoration { private _decorationId: string; From 1aab8e140e17f30a60b95df32264a39eb155765d Mon Sep 17 00:00:00 2001 From: Peng Lyu Date: Tue, 7 Aug 2018 17:25:17 -0700 Subject: [PATCH 0568/1276] revert monaco.d.ts change --- src/vs/monaco.d.ts | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/src/vs/monaco.d.ts b/src/vs/monaco.d.ts index d08e748ebe1..cb169b9e99f 100644 --- a/src/vs/monaco.d.ts +++ b/src/vs/monaco.d.ts @@ -49,23 +49,20 @@ declare namespace monaco { export type TValueCallback = (value: T | PromiseLike) => void; - export class Promise { + export class Promise { constructor( executor: ( resolve: (value: T | PromiseLike) => void, - reject: (reason: any) => void, - progress: (progress: TProgress) => void) => void, + reject: (reason: any) => void) => void, oncancel?: () => void); public then( onfulfilled?: ((value: T) => TResult1 | PromiseLike) | null, - onrejected?: ((reason: any) => TResult2 | PromiseLike) | null, - onprogress?: (progress: TProgress) => void): Promise; + onrejected?: ((reason: any) => TResult2 | PromiseLike) | null): Promise; public done( onfulfilled?: (value: T) => void, - onrejected?: (reason: any) => void, - onprogress?: (progress: TProgress) => void): void; + onrejected?: (reason: any) => void): void; public cancel(): void; From 9d3d20c3cd9ac1cdc6ea8df7a02a6f1303f3be5e Mon Sep 17 00:00:00 2001 From: SteVen Batten Date: Tue, 7 Aug 2018 17:46:53 -0700 Subject: [PATCH 0569/1276] fixes #52537 --- .../electron-browser/media/shell.css | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/src/vs/workbench/electron-browser/media/shell.css b/src/vs/workbench/electron-browser/media/shell.css index fcadf9c40ac..7a2b1a8207e 100644 --- a/src/vs/workbench/electron-browser/media/shell.css +++ b/src/vs/workbench/electron-browser/media/shell.css @@ -15,11 +15,16 @@ /* Font Families (with CJK support) */ -.monaco-shell { font-family: -apple-system, BlinkMacSystemFont, "Segoe WPC", "Segoe UI", "HelveticaNeue-Light", "Ubuntu", "Droid Sans", sans-serif; } -.monaco-shell:lang(zh-Hans) { font-family: -apple-system, BlinkMacSystemFont, "Segoe WPC", "Segoe UI", "HelveticaNeue-Light", "Noto Sans", "Microsoft YaHei", "PingFang SC", "Hiragino Sans GB", "Source Han Sans SC", "Source Han Sans CN", "Source Han Sans", sans-serif; } -.monaco-shell:lang(zh-Hant) { font-family: -apple-system, BlinkMacSystemFont, "Segoe WPC", "Segoe UI", "HelveticaNeue-Light", "Noto Sans", "Microsoft Jhenghei", "PingFang TC", "Source Han Sans TC", "Source Han Sans", "Source Han Sans TW", sans-serif; } -.monaco-shell:lang(ja) { font-family: -apple-system, BlinkMacSystemFont, "Segoe WPC", "Segoe UI", "HelveticaNeue-Light", "Noto Sans", "Meiryo", "Hiragino Kaku Gothic Pro", "Source Han Sans J", "Source Han Sans JP", "Source Han Sans", "Sazanami Gothic", "IPA Gothic", sans-serif; } -.monaco-shell:lang(ko) { font-family: -apple-system, BlinkMacSystemFont, "Segoe WPC", "Segoe UI", "HelveticaNeue-Light", "Noto Sans", "Malgun Gothic", "Nanum Gothic", "Dotom", "Apple SD Gothic Neo", "AppleGothic", "Source Han Sans K", "Source Han Sans JR", "Source Han Sans", "UnDotum", "FBaekmuk Gulim", sans-serif; } +.monaco-shell, +.monaco-shell .monaco-menu-container .monaco-menu { font-family: -apple-system, BlinkMacSystemFont, "Segoe WPC", "Segoe UI", "HelveticaNeue-Light", "Ubuntu", "Droid Sans", sans-serif; } +.monaco-shell:lang(zh-Hans), +.monaco-shell:lang(zh-Hans) .monaco-menu-container .monaco-menu { font-family: -apple-system, BlinkMacSystemFont, "Segoe WPC", "Segoe UI", "HelveticaNeue-Light", "Noto Sans", "Microsoft YaHei", "PingFang SC", "Hiragino Sans GB", "Source Han Sans SC", "Source Han Sans CN", "Source Han Sans", sans-serif; } +.monaco-shell:lang(zh-Hant), +.monaco-shell:lang(zh-Hant) .monaco-menu-container .monaco-menu { font-family: -apple-system, BlinkMacSystemFont, "Segoe WPC", "Segoe UI", "HelveticaNeue-Light", "Noto Sans", "Microsoft Jhenghei", "PingFang TC", "Source Han Sans TC", "Source Han Sans", "Source Han Sans TW", sans-serif; } +.monaco-shell:lang(ja), +.monaco-shell:lang(ja) .monaco-menu-container .monaco-menu { font-family: -apple-system, BlinkMacSystemFont, "Segoe WPC", "Segoe UI", "HelveticaNeue-Light", "Noto Sans", "Meiryo", "Hiragino Kaku Gothic Pro", "Source Han Sans J", "Source Han Sans JP", "Source Han Sans", "Sazanami Gothic", "IPA Gothic", sans-serif; } +.monaco-shell:lang(ko), +.monaco-shell:lang(ko) .monaco-menu-container .monaco-menu { font-family: -apple-system, BlinkMacSystemFont, "Segoe WPC", "Segoe UI", "HelveticaNeue-Light", "Noto Sans", "Malgun Gothic", "Nanum Gothic", "Dotom", "Apple SD Gothic Neo", "AppleGothic", "Source Han Sans K", "Source Han Sans JR", "Source Han Sans", "UnDotum", "FBaekmuk Gulim", sans-serif; } @keyframes fadeIn { from { opacity: 0; } to { opacity: 1; } } @@ -65,10 +70,6 @@ cursor: pointer; } -.monaco-shell .monaco-menu-container .monaco-menu { - font-family: -apple-system, BlinkMacSystemFont, "Segoe WPC", "Segoe UI", "HelveticaNeue-Light", "Ubuntu", "Droid Sans", sans-serif; -} - .monaco-shell .monaco-menu .monaco-action-bar.vertical { padding: .5em 0; } From e9b3304774fc262fad113895d5c149b73619e80a Mon Sep 17 00:00:00 2001 From: Benjamin Pasero Date: Wed, 8 Aug 2018 08:22:41 +0200 Subject: [PATCH 0570/1276] fix #25919 for the old menu --- src/vs/code/electron-main/menus.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/src/vs/code/electron-main/menus.ts b/src/vs/code/electron-main/menus.ts index 093d44f0587..f2cd26b67f1 100644 --- a/src/vs/code/electron-main/menus.ts +++ b/src/vs/code/electron-main/menus.ts @@ -971,6 +971,7 @@ export class CodeMenu { if (this.currentEnableNativeTabs) { const hasMultipleWindows = this.windowsMainService.getWindowCount() > 1; + this.nativeTabMenuItems.push(this.createMenuItem(nls.localize('mNewTab', "New Tab"), 'workbench.action.newWindowTab')); this.nativeTabMenuItems.push(this.createMenuItem(nls.localize('mShowPreviousTab', "Show Previous Tab"), 'workbench.action.showPreviousWindowTab', hasMultipleWindows)); this.nativeTabMenuItems.push(this.createMenuItem(nls.localize('mShowNextTab', "Show Next Tab"), 'workbench.action.showNextWindowTab', hasMultipleWindows)); this.nativeTabMenuItems.push(this.createMenuItem(nls.localize('mMoveTabToNewWindow', "Move Tab to New Window"), 'workbench.action.moveWindowTabToNewWindow', hasMultipleWindows)); From cff0e30bf85214c2b93da930ea94ab7524ffbf22 Mon Sep 17 00:00:00 2001 From: Alex Dima Date: Wed, 8 Aug 2018 09:52:58 +0200 Subject: [PATCH 0571/1276] Remove extraneuous declare --- src/vs/base/common/winjs.base.d.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vs/base/common/winjs.base.d.ts b/src/vs/base/common/winjs.base.d.ts index 3dd01d954f7..c568d4d7b05 100644 --- a/src/vs/base/common/winjs.base.d.ts +++ b/src/vs/base/common/winjs.base.d.ts @@ -6,7 +6,7 @@ export type ErrorCallback = (error: any) => void; -export declare class Promise { +export class Promise { constructor( executor: ( resolve: (value: T | PromiseLike) => void, From dcd17d8b8b6930f9a1547c2322ae2fdb3dcdf2a8 Mon Sep 17 00:00:00 2001 From: Martin Aeschlimann Date: Wed, 8 Aug 2018 08:45:44 +0200 Subject: [PATCH 0572/1276] [css] update service --- extensions/css-language-features/server/package.json | 2 +- extensions/css-language-features/server/yarn.lock | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/extensions/css-language-features/server/package.json b/extensions/css-language-features/server/package.json index 2a42529da61..7b98111d447 100644 --- a/extensions/css-language-features/server/package.json +++ b/extensions/css-language-features/server/package.json @@ -8,7 +8,7 @@ "node": "*" }, "dependencies": { - "vscode-css-languageservice": "^3.0.10-next.1", + "vscode-css-languageservice": "^3.0.10-next.2", "vscode-languageserver": "^4.4.0" }, "devDependencies": { diff --git a/extensions/css-language-features/server/yarn.lock b/extensions/css-language-features/server/yarn.lock index b8f4a686759..6878038d8f8 100644 --- a/extensions/css-language-features/server/yarn.lock +++ b/extensions/css-language-features/server/yarn.lock @@ -194,9 +194,9 @@ supports-color@5.4.0: dependencies: has-flag "^3.0.0" -vscode-css-languageservice@^3.0.10-next.1: - version "3.0.10-next.1" - resolved "https://registry.yarnpkg.com/vscode-css-languageservice/-/vscode-css-languageservice-3.0.10-next.1.tgz#1df5c9f306ad22f5c4f45ea8a2f96664ecc19de8" +vscode-css-languageservice@^3.0.10-next.2: + version "3.0.10-next.2" + resolved "https://registry.yarnpkg.com/vscode-css-languageservice/-/vscode-css-languageservice-3.0.10-next.2.tgz#b703af89be433507836178efd7f88bb0669fc4e8" dependencies: vscode-languageserver-types "^3.10.0" vscode-nls "^3.2.4" From 0659543626c0906e8effe4221174c612836d743b Mon Sep 17 00:00:00 2001 From: Christof Marti Date: Tue, 7 Aug 2018 11:46:11 +0200 Subject: [PATCH 0573/1276] Add contextKey (#29096) --- .../platform/quickinput/common/quickInput.ts | 7 +++ .../browser/parts/quickinput/quickInput.ts | 49 ++++++++++++++++++- 2 files changed, 55 insertions(+), 1 deletion(-) diff --git a/src/vs/platform/quickinput/common/quickInput.ts b/src/vs/platform/quickinput/common/quickInput.ts index 49c079ab126..0e877b51bf4 100644 --- a/src/vs/platform/quickinput/common/quickInput.ts +++ b/src/vs/platform/quickinput/common/quickInput.ts @@ -51,6 +51,11 @@ export interface IPickOptions { */ canPickMany?: boolean; + /** + * a context key to set when this picker is active + */ + contextKey?: string; + /** * an optional property for the item to focus initially. */ @@ -104,6 +109,8 @@ export interface IQuickInput { enabled: boolean; + contextKey: string | undefined; + busy: boolean; ignoreFocusOut: boolean; diff --git a/src/vs/workbench/browser/parts/quickinput/quickInput.ts b/src/vs/workbench/browser/parts/quickinput/quickInput.ts index 50da9587f5a..b668f260e62 100644 --- a/src/vs/workbench/browser/parts/quickinput/quickInput.ts +++ b/src/vs/workbench/browser/parts/quickinput/quickInput.ts @@ -73,6 +73,7 @@ interface QuickInputUI { show(controller: QuickInput): void; setVisibilities(visibilities: Visibilities): void; setEnabled(enabled: boolean): void; + setContextKey(contextKey?: string): void; hide(): void; } @@ -94,6 +95,7 @@ class QuickInput implements IQuickInput { private _totalSteps: number; protected visible = false; private _enabled = true; + private _contextKey: string; private _busy = false; private _ignoreFocusOut = false; private _buttons: IQuickInputButton[] = []; @@ -148,6 +150,15 @@ class QuickInput implements IQuickInput { this.update(); } + get contextKey() { + return this._contextKey; + } + + set contextKey(contextKey: string) { + this._contextKey = contextKey; + this.update(); + } + get busy() { return this._busy; } @@ -249,6 +260,7 @@ class QuickInput implements IQuickInput { } this.ui.ignoreFocusOut = this.ignoreFocusOut; this.ui.setEnabled(this.enabled); + this.ui.setContextKey(this.contextKey); } private getTitle() { @@ -740,6 +752,7 @@ export class QuickInputService extends Component implements IQuickInputService { private enabled = true; private inQuickOpenWidgets: Record = {}; private inQuickOpenContext: IContextKey; + private contexts: { [id: string]: IContextKey; } = Object.create(null); private onDidAcceptEmitter = this._register(new Emitter()); private onDidTriggerButtonEmitter = this._register(new Emitter()); @@ -753,7 +766,7 @@ export class QuickInputService extends Component implements IQuickInputService { @IQuickOpenService private quickOpenService: IQuickOpenService, @IEditorGroupsService private editorGroupService: IEditorGroupsService, @IKeybindingService private keybindingService: IKeybindingService, - @IContextKeyService contextKeyService: IContextKeyService, + @IContextKeyService private contextKeyService: IContextKeyService, @IThemeService themeService: IThemeService ) { super(QuickInputService.ID, themeService); @@ -779,6 +792,36 @@ export class QuickInputService extends Component implements IQuickInputService { } } + private setContextKey(id?: string) { + let key: IContextKey; + if (id) { + key = this.contexts[id]; + if (!key) { + key = new RawContextKey(id, false) + .bindTo(this.contextKeyService); + this.contexts[id] = key; + } + } + + if (key && key.get()) { + return; // already active context + } + + this.resetContextKeys(); + + if (key) { + key.set(true); + } + } + + private resetContextKeys() { + for (const key in this.contexts) { + if (this.contexts[key].get()) { + this.contexts[key].reset(); + } + } + } + private create() { if (this.ui) { return; @@ -923,6 +966,7 @@ export class QuickInputService extends Component implements IQuickInputService { hide: () => this.hide(), setVisibilities: visibilities => this.setVisibilities(visibilities), setEnabled: enabled => this.setEnabled(enabled), + setContextKey: contextKey => this.setContextKey(contextKey), }; this.updateStyles(); } @@ -976,6 +1020,7 @@ export class QuickInputService extends Component implements IQuickInputService { input.ignoreFocusOut = options.ignoreFocusLost; input.matchOnDescription = options.matchOnDescription; input.matchOnDetail = options.matchOnDetail; + input.contextKey = options.contextKey; input.busy = true; TPromise.join([picks, options.activeItem]) .then(([items, activeItem]) => { @@ -1096,6 +1141,7 @@ export class QuickInputService extends Component implements IQuickInputService { backButton.tooltip = keybinding ? localize('quickInput.backWithKeybinding', "Back ({0})", keybinding.getLabel()) : localize('quickInput.back', "Back"); this.inQuickOpen('quickInput', true); + this.resetContextKeys(); this.ui.container.style.display = ''; this.updateLayout(); @@ -1136,6 +1182,7 @@ export class QuickInputService extends Component implements IQuickInputService { if (controller) { this.controller = null; this.inQuickOpen('quickInput', false); + this.resetContextKeys(); this.ui.container.style.display = 'none'; if (!focusLost) { this.editorGroupService.activeGroup.focus(); From 772cd466a01f01020ca78ec996160892631e0f1a Mon Sep 17 00:00:00 2001 From: Christof Marti Date: Tue, 7 Aug 2018 11:46:58 +0200 Subject: [PATCH 0574/1276] Add quickNavigate (#29096) --- .../platform/quickinput/common/quickInput.ts | 7 ++ .../browser/parts/quickinput/quickInput.ts | 104 +++++++++--------- 2 files changed, 60 insertions(+), 51 deletions(-) diff --git a/src/vs/platform/quickinput/common/quickInput.ts b/src/vs/platform/quickinput/common/quickInput.ts index 0e877b51bf4..3c792727692 100644 --- a/src/vs/platform/quickinput/common/quickInput.ts +++ b/src/vs/platform/quickinput/common/quickInput.ts @@ -51,6 +51,11 @@ export interface IPickOptions { */ canPickMany?: boolean; + /** + * enables quick navigate in the picker to open an element without typing + */ + quickNavigate?: IQuickNavigateConfiguration; + /** * a context key to set when this picker is active */ @@ -146,6 +151,8 @@ export interface IQuickPick extends IQuickInput { matchOnDetail: boolean; + quickNavigate: IQuickNavigateConfiguration | undefined; + activeItems: ReadonlyArray; readonly onDidChangeActive: Event; diff --git a/src/vs/workbench/browser/parts/quickinput/quickInput.ts b/src/vs/workbench/browser/parts/quickinput/quickInput.ts index b668f260e62..3977c0b8d0a 100644 --- a/src/vs/workbench/browser/parts/quickinput/quickInput.ts +++ b/src/vs/workbench/browser/parts/quickinput/quickInput.ts @@ -311,7 +311,8 @@ class QuickPick extends QuickInput implements IQuickPi private selectedItemsUpdated = false; private selectedItemsToConfirm: T[] = []; private onDidChangeSelectionEmitter = new Emitter(); - private quickNavigate = false; + + quickNavigate: IQuickNavigateConfiguration; constructor(ui: QuickInputUI) { super(ui); @@ -498,11 +499,60 @@ class QuickPick extends QuickInput implements IQuickPi this._selectedItems = checkedItems as T[]; this.onDidChangeSelectionEmitter.fire(checkedItems as T[]); }), + this.registerQuickNavigation() ); } super.show(); } + private registerQuickNavigation() { + return dom.addDisposableListener(this.ui.container, dom.EventType.KEY_UP, (e: KeyboardEvent) => { + if (this.canSelectMany || !this.quickNavigate) { + return; + } + + const keyboardEvent: StandardKeyboardEvent = new StandardKeyboardEvent(e as KeyboardEvent); + const keyCode = keyboardEvent.keyCode; + + // Select element when keys are pressed that signal it + const quickNavKeys = this.quickNavigate.keybindings; + const wasTriggerKeyPressed = keyCode === KeyCode.Enter || quickNavKeys.some(k => { + const [firstPart, chordPart] = k.getParts(); + if (chordPart) { + return false; + } + + if (firstPart.shiftKey && keyCode === KeyCode.Shift) { + if (keyboardEvent.ctrlKey || keyboardEvent.altKey || keyboardEvent.metaKey) { + return false; // this is an optimistic check for the shift key being used to navigate back in quick open + } + + return true; + } + + if (firstPart.altKey && keyCode === KeyCode.Alt) { + return true; + } + + if (firstPart.ctrlKey && keyCode === KeyCode.Ctrl) { + return true; + } + + if (firstPart.metaKey && keyCode === KeyCode.Meta) { + return true; + } + + return false; + }); + + if (wasTriggerKeyPressed && this.activeItems[0]) { + this._selectedItems = [this.activeItems[0]]; + this.onDidChangeSelectionEmitter.fire(this.selectedItems); + this.onDidAcceptEmitter.fire(); + } + }); + } + protected update() { super.update(); if (!this.visible) { @@ -556,55 +606,6 @@ class QuickPick extends QuickInput implements IQuickPi this.ui.list.matchOnDetail = this.matchOnDetail; this.ui.setVisibilities(this.canSelectMany ? { title: !!this.title || !!this.step, checkAll: true, inputBox: true, visibleCount: true, count: true, ok: true, list: true } : { title: !!this.title || !!this.step, inputBox: true, visibleCount: true, list: true }); } - - configureQuickNavigate(quickNavigate: IQuickNavigateConfiguration) { - if (this.canSelectMany || this.quickNavigate) { - return; - } - this.quickNavigate = true; - - this.disposables.push(dom.addDisposableListener(this.ui.container, dom.EventType.KEY_UP, (e: KeyboardEvent) => { - const keyboardEvent: StandardKeyboardEvent = new StandardKeyboardEvent(e as KeyboardEvent); - const keyCode = keyboardEvent.keyCode; - - // Select element when keys are pressed that signal it - const quickNavKeys = quickNavigate.keybindings; - const wasTriggerKeyPressed = keyCode === KeyCode.Enter || quickNavKeys.some(k => { - const [firstPart, chordPart] = k.getParts(); - if (chordPart) { - return false; - } - - if (firstPart.shiftKey && keyCode === KeyCode.Shift) { - if (keyboardEvent.ctrlKey || keyboardEvent.altKey || keyboardEvent.metaKey) { - return false; // this is an optimistic check for the shift key being used to navigate back in quick open - } - - return true; - } - - if (firstPart.altKey && keyCode === KeyCode.Alt) { - return true; - } - - if (firstPart.ctrlKey && keyCode === KeyCode.Ctrl) { - return true; - } - - if (firstPart.metaKey && keyCode === KeyCode.Meta) { - return true; - } - - return false; - }); - - if (wasTriggerKeyPressed && this.activeItems[0]) { - this._selectedItems = [this.activeItems[0]]; - this.onDidChangeSelectionEmitter.fire(this.selectedItems); - this.onDidAcceptEmitter.fire(); - } - })); - } } class InputBox extends QuickInput implements IInputBox { @@ -1020,6 +1021,7 @@ export class QuickInputService extends Component implements IQuickInputService { input.ignoreFocusOut = options.ignoreFocusLost; input.matchOnDescription = options.matchOnDescription; input.matchOnDetail = options.matchOnDetail; + input.quickNavigate = options.quickNavigate; input.contextKey = options.contextKey; input.busy = true; TPromise.join([picks, options.activeItem]) @@ -1207,7 +1209,7 @@ export class QuickInputService extends Component implements IQuickInputService { if (this.isDisplayed() && this.ui.list.isDisplayed()) { this.ui.list.focus(next ? 'Next' : 'Previous'); if (quickNavigate && this.controller instanceof QuickPick) { - this.controller.configureQuickNavigate(quickNavigate); + this.controller.quickNavigate = quickNavigate; } } } From 2afa8ce3d34885b1bac1f6638c1d01c9d5f382f5 Mon Sep 17 00:00:00 2001 From: Christof Marti Date: Wed, 8 Aug 2018 15:40:28 +0200 Subject: [PATCH 0575/1276] Make use of disposeElement() --- src/vs/workbench/browser/parts/quickinput/quickInputList.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/vs/workbench/browser/parts/quickinput/quickInputList.ts b/src/vs/workbench/browser/parts/quickinput/quickInputList.ts index dd5dd3fe3be..0ec57371d67 100644 --- a/src/vs/workbench/browser/parts/quickinput/quickInputList.ts +++ b/src/vs/workbench/browser/parts/quickinput/quickInputList.ts @@ -128,8 +128,8 @@ class ListElementRenderer implements IRenderer Date: Wed, 8 Aug 2018 15:40:58 +0200 Subject: [PATCH 0576/1276] Item action bar (#29096) --- .../platform/quickinput/common/quickInput.ts | 18 +++++++- .../browser/parts/quickinput/quickInput.css | 25 ++++++++++- .../browser/parts/quickinput/quickInput.ts | 43 +++++++++---------- .../parts/quickinput/quickInputList.ts | 39 ++++++++++++++++- .../parts/quickinput/quickInputUtils.ts | 28 ++++++++++++ 5 files changed, 125 insertions(+), 28 deletions(-) create mode 100644 src/vs/workbench/browser/parts/quickinput/quickInputUtils.ts diff --git a/src/vs/platform/quickinput/common/quickInput.ts b/src/vs/platform/quickinput/common/quickInput.ts index 3c792727692..8b88046261d 100644 --- a/src/vs/platform/quickinput/common/quickInput.ts +++ b/src/vs/platform/quickinput/common/quickInput.ts @@ -17,6 +17,7 @@ export interface IQuickPickItem { description?: string; detail?: string; iconClasses?: string[]; + buttons?: IQuickInputButton[]; picked?: boolean; } @@ -67,6 +68,7 @@ export interface IPickOptions { activeItem?: TPromise | T; onDidFocus?: (entry: T) => void; + onDidTriggerItemButton?: (context: IQuickPickItemButtonContext) => void; } export interface IInputOptions { @@ -143,6 +145,8 @@ export interface IQuickPick extends IQuickInput { readonly onDidTriggerButton: Event; + readonly onDidTriggerItemButton: Event>; + items: ReadonlyArray; canSelectMany: boolean; @@ -186,8 +190,18 @@ export interface IInputBox extends IQuickInput { } export interface IQuickInputButton { - iconPath: { dark: URI; light?: URI; }; - tooltip?: string | undefined; + iconPath?: { dark: URI; light?: URI; }; + iconClass?: string; + tooltip?: string; +} + +export interface IQuickPickItemButtonEvent { + button: IQuickInputButton; + item: T; +} + +export interface IQuickPickItemButtonContext extends IQuickPickItemButtonEvent { + removeItem(): void; } export const IQuickInputService = createDecorator('quickInputService'); diff --git a/src/vs/workbench/browser/parts/quickinput/quickInput.css b/src/vs/workbench/browser/parts/quickinput/quickInput.css index 133ce19e8fc..35094940935 100644 --- a/src/vs/workbench/browser/parts/quickinput/quickInput.css +++ b/src/vs/workbench/browser/parts/quickinput/quickInput.css @@ -168,4 +168,27 @@ .quick-input-list .monaco-highlighted-label .highlight { font-weight: bold; -} \ No newline at end of file +} + +.quick-input-list .quick-input-list-entry-action-bar { + display: none; + flex: 0; + overflow: visible; +} + +.quick-input-list .quick-input-list-entry-action-bar .action-label.icon { + margin: 0; + width: 19px; + height: 100%; + background-position: center; + background-repeat: no-repeat; +} + +.quick-input-list .quick-input-list-entry-action-bar ul:last-child .action-label.icon { + margin-right: 3px; +} + +.quick-input-list .quick-input-list-entry:hover .quick-input-list-entry-action-bar, +.quick-input-list .monaco-list-row.focused .quick-input-list-entry-action-bar { + display: flex; +} diff --git a/src/vs/workbench/browser/parts/quickinput/quickInput.ts b/src/vs/workbench/browser/parts/quickinput/quickInput.ts index 3977c0b8d0a..0746e309b9e 100644 --- a/src/vs/workbench/browser/parts/quickinput/quickInput.ts +++ b/src/vs/workbench/browser/parts/quickinput/quickInput.ts @@ -7,7 +7,7 @@ import 'vs/css!./quickInput'; import { Component } from 'vs/workbench/common/component'; -import { IQuickInputService, IQuickPickItem, IPickOptions, IInputOptions, IQuickNavigateConfiguration, IQuickPick, IQuickInput, IQuickInputButton, IInputBox } from 'vs/platform/quickinput/common/quickInput'; +import { IQuickInputService, IQuickPickItem, IPickOptions, IInputOptions, IQuickNavigateConfiguration, IQuickPick, IQuickInput, IQuickInputButton, IInputBox, IQuickPickItemButtonEvent } from 'vs/platform/quickinput/common/quickInput'; import { IPartService } from 'vs/workbench/services/part/common/partService'; import * as dom from 'vs/base/browser/dom'; import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; @@ -39,10 +39,10 @@ import { inQuickOpenContext } from 'vs/workbench/browser/parts/quickopen/quickop import { ActionBar, ActionItem } from 'vs/base/browser/ui/actionbar/actionbar'; import { Action } from 'vs/base/common/actions'; import URI from 'vs/base/common/uri'; -import { IdGenerator } from 'vs/base/common/idGenerator'; import { IKeybindingService } from 'vs/platform/keybinding/common/keybinding'; import { equals } from 'vs/base/common/arrays'; import { TimeoutTimer } from 'vs/base/common/async'; +import { getIconClass } from 'vs/workbench/browser/parts/quickinput/quickInputUtils'; const $ = dom.$; @@ -246,14 +246,14 @@ class QuickInput implements IQuickInput { this.ui.leftActionBar.clear(); const leftButtons = this.buttons.filter(button => button === backButton); this.ui.leftActionBar.push(leftButtons.map((button, index) => { - const action = new Action(`id-${index}`, '', getIconClass(button.iconPath), true, () => this.onDidTriggerButtonEmitter.fire(button)); + const action = new Action(`id-${index}`, '', button.iconClass || getIconClass(button.iconPath), true, () => this.onDidTriggerButtonEmitter.fire(button)); action.tooltip = button.tooltip; return action; }), { icon: true, label: false }); this.ui.rightActionBar.clear(); const rightButtons = this.buttons.filter(button => button !== backButton); this.ui.rightActionBar.push(rightButtons.map((button, index) => { - const action = new Action(`id-${index}`, '', getIconClass(button.iconPath), true, () => this.onDidTriggerButtonEmitter.fire(button)); + const action = new Action(`id-${index}`, '', button.iconClass || getIconClass(button.iconPath), true, () => this.onDidTriggerButtonEmitter.fire(button)); action.tooltip = button.tooltip; return action; }), { icon: true, label: false }); @@ -311,6 +311,7 @@ class QuickPick extends QuickInput implements IQuickPi private selectedItemsUpdated = false; private selectedItemsToConfirm: T[] = []; private onDidChangeSelectionEmitter = new Emitter(); + private onDidTriggerItemButtonEmitter = new Emitter>(); quickNavigate: IQuickNavigateConfiguration; @@ -321,6 +322,7 @@ class QuickPick extends QuickInput implements IQuickPi this.onDidAcceptEmitter, this.onDidChangeActiveEmitter, this.onDidChangeSelectionEmitter, + this.onDidTriggerItemButtonEmitter, ); } @@ -407,6 +409,8 @@ class QuickPick extends QuickInput implements IQuickPi onDidChangeSelection = this.onDidChangeSelectionEmitter.event; + onDidTriggerItemButton = this.onDidTriggerItemButtonEmitter.event; + show() { if (!this.visible) { this.visibleDisposables.push( @@ -499,6 +503,7 @@ class QuickPick extends QuickInput implements IQuickPi this._selectedItems = checkedItems as T[]; this.onDidChangeSelectionEmitter.fire(checkedItems as T[]); }), + this.ui.list.onButtonTriggered(event => this.onDidTriggerItemButtonEmitter.fire(event as IQuickPickItemButtonEvent)), this.registerQuickNavigation() ); } @@ -1008,6 +1013,17 @@ export class QuickInputService extends Component implements IQuickInputService { } } }), + input.onDidTriggerItemButton(event => options.onDidTriggerItemButton && options.onDidTriggerItemButton({ + ...event, + removeItem: () => { + const index = input.items.indexOf(event.item); + if (index !== -1) { + const items = input.items.slice(); + items.splice(index, 1); + input.items = items; + } + } + })), token.onCancellationRequested(() => { input.hide(); }), @@ -1272,25 +1288,6 @@ export class QuickInputService extends Component implements IQuickInputService { } } -const iconPathToClass = {}; -const iconClassGenerator = new IdGenerator('quick-input-button-icon-'); - -function getIconClass(iconPath: { dark: URI; light?: URI; }) { - let iconClass: string; - - const key = iconPath.dark.toString(); - if (iconPathToClass[key]) { - iconClass = iconPathToClass[key]; - } else { - iconClass = iconClassGenerator.nextId(); - dom.createCSSRule(`.${iconClass}`, `background-image: url("${(iconPath.light || iconPath.dark).toString()}")`); - dom.createCSSRule(`.vs-dark .${iconClass}, .hc-black .${iconClass}`, `background-image: url("${iconPath.dark.toString()}")`); - iconPathToClass[key] = iconClass; - } - - return iconClass; -} - export const QuickPickManyToggle: ICommandAndKeybindingRule = { id: 'workbench.action.quickPickManyToggle', weight: KeybindingWeight.WorkbenchContrib, diff --git a/src/vs/workbench/browser/parts/quickinput/quickInputList.ts b/src/vs/workbench/browser/parts/quickinput/quickInputList.ts index 0ec57371d67..ff832f65ebe 100644 --- a/src/vs/workbench/browser/parts/quickinput/quickInputList.ts +++ b/src/vs/workbench/browser/parts/quickinput/quickInputList.ts @@ -11,7 +11,7 @@ import * as dom from 'vs/base/browser/dom'; import { dispose, IDisposable } from 'vs/base/common/lifecycle'; import { WorkbenchList } from 'vs/platform/list/browser/listService'; import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; -import { IQuickPickItem } from 'vs/platform/quickinput/common/quickInput'; +import { IQuickPickItem, IQuickPickItemButtonEvent } from 'vs/platform/quickinput/common/quickInput'; import { IMatch } from 'vs/base/common/filters'; import { matchesFuzzyOcticonAware, parseOcticons } from 'vs/base/common/octicon'; import { compareAnything } from 'vs/base/common/comparers'; @@ -26,6 +26,9 @@ import { range } from 'vs/base/common/arrays'; import * as platform from 'vs/base/common/platform'; import { listFocusBackground } from 'vs/platform/theme/common/colorRegistry'; import { registerThemingParticipant } from 'vs/platform/theme/common/themeService'; +import { ActionBar } from 'vs/base/browser/ui/actionbar/actionbar'; +import { Action } from 'vs/base/common/actions'; +import { getIconClass } from 'vs/workbench/browser/parts/quickinput/quickInputUtils'; const $ = dom.$; @@ -33,6 +36,7 @@ interface IListElement { index: number; item: IQuickPickItem; checked: boolean; + fireButtonTriggered: (event: IQuickPickItemButtonEvent) => void; } class ListElement implements IListElement { @@ -55,6 +59,7 @@ class ListElement implements IListElement { labelHighlights?: IMatch[]; descriptionHighlights?: IMatch[]; detailHighlights?: IMatch[]; + fireButtonTriggered: (event: IQuickPickItemButtonEvent) => void; constructor(init: IListElement) { assign(this, init); @@ -65,6 +70,7 @@ interface IListElementTemplateData { checkbox: HTMLInputElement; label: IconLabel; detail: HighlightedLabel; + actionBar: ActionBar; element: ListElement; toDisposeElement: IDisposable[]; toDisposeTemplate: IDisposable[]; @@ -105,6 +111,11 @@ class ListElementRenderer implements IRenderer { + const action = new Action(`id-${index}`, '', button.iconClass || getIconClass(button.iconPath), true, () => { + element.fireButtonTriggered({ + button, + item: element.item + }); + return null; + }); + action.tooltip = button.tooltip; + return action; + }), { icon: true, label: false }); + } } disposeElement(element: ListElement, index: number, data: IListElementTemplateData): void { @@ -165,6 +192,8 @@ export class QuickInputList { onChangedVisibleCount: Event = this._onChangedVisibleCount.event; private _onChangedCheckedElements = new Emitter(); onChangedCheckedElements: Event = this._onChangedCheckedElements.event; + private _onButtonTriggered = new Emitter>(); + onButtonTriggered = this._onButtonTriggered.event; private _onLeave = new Emitter(); onLeave: Event = this._onLeave.event; private _fireCheckedEvents = true; @@ -287,10 +316,12 @@ export class QuickInputList { setElements(elements: IQuickPickItem[]): void { this.elementDisposables = dispose(this.elementDisposables); + const fireButtonTriggered = (event: IQuickPickItemButtonEvent) => this.fireButtonTriggered(event); this.elements = elements.map((item, index) => new ListElement({ index, item, - checked: false + checked: false, + fireButtonTriggered })); this.elementDisposables.push(...this.elements.map(element => element.onChecked(() => this.fireCheckedEvents()))); @@ -469,6 +500,10 @@ export class QuickInputList { this._onChangedCheckedElements.fire(this.getCheckedElements()); } } + + private fireButtonTriggered(event: IQuickPickItemButtonEvent) { + this._onButtonTriggered.fire(event); + } } function compareEntries(elementA: ListElement, elementB: ListElement, lookFor: string): number { diff --git a/src/vs/workbench/browser/parts/quickinput/quickInputUtils.ts b/src/vs/workbench/browser/parts/quickinput/quickInputUtils.ts new file mode 100644 index 00000000000..ef37fbf76dc --- /dev/null +++ b/src/vs/workbench/browser/parts/quickinput/quickInputUtils.ts @@ -0,0 +1,28 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import 'vs/css!./quickInput'; +import * as dom from 'vs/base/browser/dom'; +import URI from 'vs/base/common/uri'; +import { IdGenerator } from 'vs/base/common/idGenerator'; + +const iconPathToClass = {}; +const iconClassGenerator = new IdGenerator('quick-input-button-icon-'); + +export function getIconClass(iconPath: { dark: URI; light?: URI; }) { + let iconClass: string; + + const key = iconPath.dark.toString(); + if (iconPathToClass[key]) { + iconClass = iconPathToClass[key]; + } else { + iconClass = iconClassGenerator.nextId(); + dom.createCSSRule(`.${iconClass}`, `background-image: url("${(iconPath.light || iconPath.dark).toString()}")`); + dom.createCSSRule(`.vs-dark .${iconClass}, .hc-black .${iconClass}`, `background-image: url("${iconPath.dark.toString()}")`); + iconPathToClass[key] = iconClass; + } + + return iconClass; +} From 60ef4f5d82f71d68b70feeaaa987e4aac49e23a4 Mon Sep 17 00:00:00 2001 From: Christof Marti Date: Wed, 8 Aug 2018 15:43:24 +0200 Subject: [PATCH 0577/1276] Use QuickInput (#29096) --- src/vs/workbench/electron-browser/actions.ts | 97 +++++++++----------- 1 file changed, 43 insertions(+), 54 deletions(-) diff --git a/src/vs/workbench/electron-browser/actions.ts b/src/vs/workbench/electron-browser/actions.ts index a05268d666f..5e747f6ff7f 100644 --- a/src/vs/workbench/electron-browser/actions.ts +++ b/src/vs/workbench/electron-browser/actions.ts @@ -52,6 +52,10 @@ import { IWorkbenchIssueService } from 'vs/workbench/services/issue/common/issue import { INotificationService } from 'vs/platform/notification/common/notification'; import { IUriDisplayService } from 'vs/platform/uriDisplay/common/uriDisplay'; import { dirname } from 'vs/base/common/resources'; +import { IModelService } from 'vs/editor/common/services/modelService'; +import { IModeService } from 'vs/editor/common/services/modeService'; +import { IQuickInputService, IQuickPickItem, IQuickInputButton } from 'vs/platform/quickinput/common/quickInput'; +import { getIconClasses } from 'vs/workbench/browser/labels'; // --- actions @@ -577,20 +581,24 @@ export class ReloadWindowWithExtensionsDisabledAction extends Action { } export abstract class BaseSwitchWindow extends Action { - private closeWindowAction: CloseWindowAction; + + private closeWindowAction: IQuickInputButton = { + iconClass: 'action-remove-from-recently-opened', + tooltip: nls.localize('close', "Close Window") + }; constructor( id: string, label: string, private windowsService: IWindowsService, private windowService: IWindowService, - private quickOpenService: IQuickOpenService, + private quickInputService: IQuickInputService, private keybindingService: IKeybindingService, - private instantiationService: IInstantiationService + private modelService: IModelService, + private modeService: IModeService, ) { super(id, label); - this.closeWindowAction = this.instantiationService.createInstance(CloseWindowAction); } protected abstract isQuickNavigate(): boolean; @@ -600,58 +608,35 @@ export abstract class BaseSwitchWindow extends Action { return this.windowsService.getWindows().then(windows => { const placeHolder = nls.localize('switchWindowPlaceHolder', "Select a window to switch to"); - const picks = windows.map(win => ({ - payload: win.id, - resource: win.filename ? URI.file(win.filename) : win.folderUri ? win.folderUri : win.workspace ? URI.file(win.workspace.configPath) : void 0, - fileKind: win.filename ? FileKind.FILE : win.workspace ? FileKind.ROOT_FOLDER : win.folderUri ? FileKind.FOLDER : FileKind.FILE, - label: win.title, - description: (currentWindowId === win.id) ? nls.localize('current', "Current Window") : void 0, - run: () => { - setTimeout(() => { - // Bug: somehow when not running this code in a timeout, it is not possible to use this picker - // with quick navigate keys (not able to trigger quick navigate once running it once). - this.windowsService.showWindow(win.id).done(null, errors.onUnexpectedError); - }); - }, - action: (!this.isQuickNavigate() && currentWindowId !== win.id) ? this.closeWindowAction : void 0 - } as IFilePickOpenEntry)); + const picks = windows.map(win => { + const resource = win.filename ? URI.file(win.filename) : win.folderUri ? win.folderUri : win.workspace ? URI.file(win.workspace.configPath) : void 0; + const fileKind = win.filename ? FileKind.FILE : win.workspace ? FileKind.ROOT_FOLDER : win.folderUri ? FileKind.FOLDER : FileKind.FILE; + return { + payload: win.id, + label: win.title, + iconClasses: getIconClasses(this.modelService, this.modeService, resource, fileKind), + description: (currentWindowId === win.id) ? nls.localize('current', "Current Window") : void 0, + buttons: (!this.isQuickNavigate() && currentWindowId !== win.id) ? [this.closeWindowAction] : void 0 + } as (IQuickPickItem & { payload: number }); + }); const autoFocusIndex = (picks.indexOf(picks.filter(pick => pick.payload === currentWindowId)[0]) + 1) % picks.length; - this.quickOpenService.pick(picks, { + return this.quickInputService.pick(picks, { contextKey: 'inWindowsPicker', - autoFocus: { autoFocusIndex }, + activeItem: picks[autoFocusIndex], placeHolder, - quickNavigateConfiguration: this.isQuickNavigate() ? { keybindings: this.keybindingService.lookupKeybindings(this.id) } : void 0 + quickNavigate: this.isQuickNavigate() ? { keybindings: this.keybindingService.lookupKeybindings(this.id) } : void 0, + onDidTriggerItemButton: context => { + this.windowsService.closeWindow(context.item.payload).then(() => { + context.removeItem(); + }); + } }); - }); - } - - dispose(): void { - super.dispose(); - - this.closeWindowAction.dispose(); - } -} - -class CloseWindowAction extends Action implements IPickOpenAction { - - static readonly ID = 'workbench.action.closeWindow'; - static readonly LABEL = nls.localize('close', "Close Window"); - - constructor( - @IWindowsService private windowsService: IWindowsService - ) { - super(CloseWindowAction.ID, CloseWindowAction.LABEL); - - this.class = 'action-remove-from-recently-opened'; - } - - run(item: IPickOpenItem): TPromise { - return this.windowsService.closeWindow(item.getPayload()).then(() => { - item.remove(); - - return true; + }).then(pick => { + if (pick) { + this.windowsService.showWindow(pick.payload).done(null, errors.onUnexpectedError); + } }); } } @@ -666,11 +651,13 @@ export class SwitchWindow extends BaseSwitchWindow { label: string, @IWindowsService windowsService: IWindowsService, @IWindowService windowService: IWindowService, - @IQuickOpenService quickOpenService: IQuickOpenService, + @IQuickInputService quickInputService: IQuickInputService, @IKeybindingService keybindingService: IKeybindingService, + @IModelService modelService: IModelService, + @IModeService modeService: IModeService, @IInstantiationService instantiationService: IInstantiationService ) { - super(id, label, windowsService, windowService, quickOpenService, keybindingService, instantiationService); + super(id, label, windowsService, windowService, quickInputService, keybindingService, modelService, modeService); } protected isQuickNavigate(): boolean { @@ -688,11 +675,13 @@ export class QuickSwitchWindow extends BaseSwitchWindow { label: string, @IWindowsService windowsService: IWindowsService, @IWindowService windowService: IWindowService, - @IQuickOpenService quickOpenService: IQuickOpenService, + @IQuickInputService quickInputService: IQuickInputService, @IKeybindingService keybindingService: IKeybindingService, + @IModelService modelService: IModelService, + @IModeService modeService: IModeService, @IInstantiationService instantiationService: IInstantiationService ) { - super(id, label, windowsService, windowService, quickOpenService, keybindingService, instantiationService); + super(id, label, windowsService, windowService, quickInputService, keybindingService, modelService, modeService); } protected isQuickNavigate(): boolean { From 62c5e45b18b53c51dc146526efdaa965807c6524 Mon Sep 17 00:00:00 2001 From: Martin Aeschlimann Date: Wed, 8 Aug 2018 16:06:16 +0200 Subject: [PATCH 0578/1276] Use `resources` instead of `paths` for dirname, basename, joinPath, normalizePath, isAbsolutePath --- src/vs/base/common/paths.ts | 9 +- src/vs/base/common/resources.ts | 94 ++++++++----------- src/vs/base/test/common/resources.test.ts | 86 +++++++++++++---- .../editor/browser/services/openerService.ts | 4 +- src/vs/platform/workspace/common/workspace.ts | 4 +- src/vs/workbench/api/node/extHostWorkspace.ts | 6 +- .../browser/parts/editor/breadcrumbsModel.ts | 5 +- src/vs/workbench/electron-browser/actions.ts | 3 +- .../debugConfigurationManager.ts | 4 +- .../node/extensionsWorkbenchService.ts | 4 +- .../browser/editors/fileEditorTracker.ts | 10 +- .../parts/files/common/explorerModel.ts | 4 +- .../files/electron-browser/fileActions.ts | 29 +++--- .../electron-browser/views/explorerViewer.ts | 6 +- .../parts/output/common/outputLinkComputer.ts | 3 +- .../parts/search/common/queryBuilder.ts | 7 +- .../configuration/node/configuration.ts | 12 +-- .../electron-browser/remoteFileService.ts | 20 ++-- 18 files changed, 177 insertions(+), 133 deletions(-) diff --git a/src/vs/base/common/paths.ts b/src/vs/base/common/paths.ts index 0cabea33b62..e114052fba7 100644 --- a/src/vs/base/common/paths.ts +++ b/src/vs/base/common/paths.ts @@ -19,9 +19,12 @@ export const sep = '/'; export const nativeSep = isWindows ? '\\' : '/'; /** + * @param path the path to get the dirname from + * @param separator the separator to use * @returns the directory name of a path. + * */ -export function dirname(path: string): string { +export function dirname(path: string, separator = nativeSep): string { const idx = ~path.lastIndexOf('/') || ~path.lastIndexOf('\\'); if (idx === 0) { return '.'; @@ -31,8 +34,8 @@ export function dirname(path: string): string { return dirname(path.substring(0, path.length - 1)); } else { let res = path.substring(0, ~idx); - if (isWindows && res[res.length - 1] === ':') { - res += nativeSep; // make sure drive letters end with backslash + if (isWindows && res.length === 2 && res[res.length - 1] === ':') { + res += separator; // make sure drive letters end with backslash } return res; } diff --git a/src/vs/base/common/resources.ts b/src/vs/base/common/resources.ts index 929349ba832..f7e3ef3d8da 100644 --- a/src/vs/base/common/resources.ts +++ b/src/vs/base/common/resources.ts @@ -22,13 +22,13 @@ export function hasToIgnoreCase(resource: URI): boolean { } export function basenameOrAuthority(resource: URI): string { - return basename_urlpath(resource.path) || resource.authority; + return basename(resource) || resource.authority; } export function isEqualOrParent(resource: URI, candidate: URI, ignoreCase?: boolean): boolean { if (resource.scheme === candidate.scheme && resource.authority === candidate.authority) { - if (resource.scheme === 'file') { - return paths.isEqualOrParent(resource.fsPath, candidate.fsPath, ignoreCase); + if (resource.scheme === Schemas.file) { + return paths.isEqualOrParent(resource.path, candidate.path, ignoreCase); } return paths.isEqualOrParent(resource.path, candidate.path, ignoreCase, '/'); @@ -55,47 +55,59 @@ export function isEqual(first: URI, second: URI, ignoreCase?: boolean): boolean } export function basename(resource: URI): string { - if (resource.scheme === 'file') { - return paths.basename(resource.fsPath); - } - return basename_urlpath(resource.path); + return paths.basename(resource.path); } +/** + * Return a URI representing the directory of a URI path. + * + * @param resource The input URI. + * @returns The URI representing the directory of the input URI. + */ export function dirname(resource: URI): URI { - if (resource.scheme === 'file') { - return URI.file(paths.dirname(resource.fsPath)); - } - let dirname = dirname_urlpath(resource.path); + let dirname = paths.dirname(resource.path, '/'); if (resource.authority && dirname.length && dirname.charCodeAt(0) !== CharCode.Slash) { - return null; // If a URI contains an authority component, then the path component must either be empty or begin with a slash ("/") character + return null; // If a URI contains an authority component, then the path component must either be empty or begin with a CharCode.Slash ("/") character } return resource.with({ path: dirname }); } +/** + * Join a URI path with a path fragment and normalizes the resulting path. + * + * @param resource The input URI. + * @param pathFragment The path fragment to add to the URI path. + * @returns The resulting URI. + */ export function joinPath(resource: URI, pathFragment: string): URI { - if (resource.scheme === 'file') { - return URI.file(paths.join(resource.path || '/', pathFragment)); - } - - let path = resource.path || ''; - let last = path.charCodeAt(path.length - 1); - let next = pathFragment.charCodeAt(0); - if (last !== CharCode.Slash) { - if (next !== CharCode.Slash) { - path += '/'; - } - } else { - if (next === CharCode.Slash) { - pathFragment = pathFragment.substr(1); - } - } + const joinedPath = paths.join(resource.path || '/', pathFragment); return resource.with({ - path: path + pathFragment + path: joinedPath }); } +/** + * Normalizes the path part of a URI: Resolves `.` and `..` elements with directory names. + * + * @param resource The URI to normalize the path. + * @returns The URI with the normalized path. + */ +export function normalizePath(resource: URI): URI { + const normalizedPath = paths.normalize(resource.path, false); + return resource.with({ + path: normalizedPath + }); +} + +/** + * Returns true if the URI path is absolute. + */ +export function isAbsolutePath(resource: URI): boolean { + return paths.isAbsolute(resource.path); +} + export function distinctParents(items: T[], resourceAccessor: (item: T) => URI): T[] { const distinctParents: T[] = []; for (let i = 0; i < items.length; i++) { @@ -115,27 +127,3 @@ export function distinctParents(items: T[], resourceAccessor: (item: T) => UR return distinctParents; } - -function dirname_urlpath(path: string): string { - const idx = ~path.lastIndexOf('/'); - if (idx === 0) { - return ''; - } else if (~idx === 0) { - return path[0]; - } else if (~idx === path.length - 1) { - return dirname_urlpath(path.substring(0, path.length - 1)); - } else { - return path.substring(0, ~idx); - } -} - -function basename_urlpath(path: string): string { - const idx = ~path.lastIndexOf('/'); - if (idx === 0) { - return path; - } else if (~idx === path.length - 1) { - return basename_urlpath(path.substring(0, path.length - 1)); - } else { - return path.substr(~idx + 1); - } -} diff --git a/src/vs/base/test/common/resources.test.ts b/src/vs/base/test/common/resources.test.ts index 42026e111c3..ac6c9db534d 100644 --- a/src/vs/base/test/common/resources.test.ts +++ b/src/vs/base/test/common/resources.test.ts @@ -5,7 +5,7 @@ 'use strict'; import * as assert from 'assert'; -import { dirname, basename, distinctParents, joinPath, isEqual, isEqualOrParent, hasToIgnoreCase } from 'vs/base/common/resources'; +import { dirname, basename, distinctParents, joinPath, isEqual, isEqualOrParent, hasToIgnoreCase, normalizePath, isAbsolutePath } from 'vs/base/common/resources'; import URI from 'vs/base/common/uri'; import { isWindows } from 'vs/base/common/platform'; @@ -52,7 +52,6 @@ suite('Resources', () => { assert.equal(dirname(URI.file('/some/file/test.txt')).toString(), 'file:///some/file'); assert.equal(dirname(URI.file('/some/file/')).toString(), 'file:///some'); assert.equal(dirname(URI.file('/some/file')).toString(), 'file:///some'); - assert.equal(dirname(URI.file('/some/file')).toString(), 'file:///some'); } assert.equal(dirname(URI.parse('foo://a/some/file/test.txt')).toString(), 'foo://a/some/file'); assert.equal(dirname(URI.parse('foo://a/some/file/')).toString(), 'foo://a/some'); @@ -65,22 +64,21 @@ suite('Resources', () => { test('basename', () => { if (isWindows) { - assert.equal(basename(URI.file('c:\\some\\file\\test.txt')).toString(), 'test.txt'); - assert.equal(basename(URI.file('c:\\some\\file')).toString(), 'file'); - assert.equal(basename(URI.file('c:\\some\\file\\')).toString(), 'file'); + assert.equal(basename(URI.file('c:\\some\\file\\test.txt')), 'test.txt'); + assert.equal(basename(URI.file('c:\\some\\file')), 'file'); + assert.equal(basename(URI.file('c:\\some\\file\\')), 'file'); } else { - assert.equal(basename(URI.file('/some/file/test.txt')).toString(), 'test.txt'); - assert.equal(basename(URI.file('/some/file/')).toString(), 'file'); - assert.equal(basename(URI.file('/some/file')).toString(), 'file'); - assert.equal(basename(URI.file('/some')).toString(), 'some'); + assert.equal(basename(URI.file('/some/file/test.txt')), 'test.txt'); + assert.equal(basename(URI.file('/some/file/')), 'file'); + assert.equal(basename(URI.file('/some/file')), 'file'); + assert.equal(basename(URI.file('/some')), 'some'); } - assert.equal(basename(URI.parse('foo://a/some/file/test.txt')).toString(), 'test.txt'); - assert.equal(basename(URI.parse('foo://a/some/file/')).toString(), 'file'); - assert.equal(basename(URI.parse('foo://a/some/file')).toString(), 'file'); - assert.equal(basename(URI.parse('foo://a/some')).toString(), 'some'); - - // does not explode (https://github.com/Microsoft/vscode/issues/41987) - dirname(URI.from({ scheme: 'file', authority: '/users/someone/portal.h' })); + assert.equal(basename(URI.parse('foo://a/some/file/test.txt')), 'test.txt'); + assert.equal(basename(URI.parse('foo://a/some/file/')), 'file'); + assert.equal(basename(URI.parse('foo://a/some/file')), 'file'); + assert.equal(basename(URI.parse('foo://a/some')), 'some'); + assert.equal(basename(URI.parse('foo://a/')), ''); + assert.equal(basename(URI.parse('foo://a')), ''); }); test('joinPath', () => { @@ -89,22 +87,78 @@ suite('Resources', () => { assert.equal(joinPath(URI.file('c:\\foo\\bar\\'), 'file.js').toString(), 'file:///c%3A/foo/bar/file.js'); assert.equal(joinPath(URI.file('c:\\foo\\bar\\'), '/file.js').toString(), 'file:///c%3A/foo/bar/file.js'); assert.equal(joinPath(URI.file('c:\\'), '/file.js').toString(), 'file:///c%3A/file.js'); + assert.equal(joinPath(URI.file('c:\\'), 'bar/file.js').toString(), 'file:///c%3A/bar/file.js'); + assert.equal(joinPath(URI.file('c:\\foo'), './file.js').toString(), 'file:///c%3A/foo/file.js'); + assert.equal(joinPath(URI.file('c:\\foo'), '/./file.js').toString(), 'file:///c%3A/foo/file.js'); + assert.equal(joinPath(URI.file('c:\\foo'), '../file.js').toString(), 'file:///c%3A/file.js'); + assert.equal(joinPath(URI.file('c:\\foo\\.'), '../file.js').toString(), 'file:///c%3A/file.js'); } else { assert.equal(joinPath(URI.file('/foo/bar'), '/file.js').toString(), 'file:///foo/bar/file.js'); assert.equal(joinPath(URI.file('/foo/bar'), 'file.js').toString(), 'file:///foo/bar/file.js'); assert.equal(joinPath(URI.file('/foo/bar/'), '/file.js').toString(), 'file:///foo/bar/file.js'); assert.equal(joinPath(URI.file('/'), '/file.js').toString(), 'file:///file.js'); + assert.equal(joinPath(URI.file('/foo/bar'), './file.js').toString(), 'file:///foo/bar/file.js'); + assert.equal(joinPath(URI.file('/foo/bar'), '/./file.js').toString(), 'file:///foo/bar/file.js'); + assert.equal(joinPath(URI.file('/foo/bar'), '../file.js').toString(), 'file:///foo/file.js'); } assert.equal(joinPath(URI.parse('foo://a/foo/bar'), '/file.js').toString(), 'foo://a/foo/bar/file.js'); assert.equal(joinPath(URI.parse('foo://a/foo/bar'), 'file.js').toString(), 'foo://a/foo/bar/file.js'); assert.equal(joinPath(URI.parse('foo://a/foo/bar/'), '/file.js').toString(), 'foo://a/foo/bar/file.js'); assert.equal(joinPath(URI.parse('foo://a/'), '/file.js').toString(), 'foo://a/file.js'); + assert.equal(joinPath(URI.parse('foo://a/foo/bar/'), './file.js').toString(), 'foo://a/foo/bar/file.js'); + assert.equal(joinPath(URI.parse('foo://a/foo/bar/'), '/./file.js').toString(), 'foo://a/foo/bar/file.js'); + assert.equal(joinPath(URI.parse('foo://a/foo/bar/'), '../file.js').toString(), 'foo://a/foo/file.js'); assert.equal( joinPath(URI.from({ scheme: 'myScheme', authority: 'authority', path: '/path', query: 'query', fragment: 'fragment' }), '/file.js').toString(), 'myScheme://authority/path/file.js?query#fragment'); }); + test('normalizePath', () => { + if (isWindows) { + assert.equal(normalizePath(URI.file('c:\\foo\\.\\bar')).toString(), 'file:///c%3A/foo/bar'); + assert.equal(normalizePath(URI.file('c:\\foo\\.')).toString(), 'file:///c%3A/foo'); + assert.equal(normalizePath(URI.file('c:\\foo\\.\\')).toString(), 'file:///c%3A/foo/'); + assert.equal(normalizePath(URI.file('c:\\foo\\..')).toString(), 'file:///c%3A/'); + assert.equal(normalizePath(URI.file('c:\\foo\\..\\bar')).toString(), 'file:///c%3A/bar'); + assert.equal(normalizePath(URI.file('c:\\foo\\..\\..\\bar')).toString(), 'file:///c%3A/bar'); + assert.equal(normalizePath(URI.file('c:\\foo\\foo\\..\\..\\bar')).toString(), 'file:///c%3A/bar'); + assert.equal(normalizePath(URI.file('c:\\foo\\foo\\.\\..\\..\\bar')).toString(), 'file:///c%3A/bar'); + assert.equal(normalizePath(URI.file('c:\\foo\\foo\\.\\..\\some\\..\\bar')).toString(), 'file:///c%3A/foo/bar'); + } else { + assert.equal(normalizePath(URI.file('/foo/./bar')).toString(), 'file:///foo/bar'); + assert.equal(normalizePath(URI.file('/foo/.')).toString(), 'file:///foo'); + assert.equal(normalizePath(URI.file('/foo/./')).toString(), 'file:///foo/'); + assert.equal(normalizePath(URI.file('/foo/..')).toString(), 'file:///'); + assert.equal(normalizePath(URI.file('/foo/../bar')).toString(), 'file:///bar'); + assert.equal(normalizePath(URI.file('/foo/../../bar')).toString(), 'file:///bar'); + assert.equal(normalizePath(URI.file('/foo/foo/../../bar')).toString(), 'file:///bar'); + assert.equal(normalizePath(URI.file('/foo/foo/./../../bar')).toString(), 'file:///bar'); + assert.equal(normalizePath(URI.file('/foo/foo/./../some/../bar')).toString(), 'file:///foo/bar'); + } + assert.equal(normalizePath(URI.parse('foo://a/foo/./bar')).toString(), 'foo://a/foo/bar'); + assert.equal(normalizePath(URI.parse('foo://a/foo/.')).toString(), 'foo://a/foo'); + assert.equal(normalizePath(URI.parse('foo://a/foo/./')).toString(), 'foo://a/foo/'); + assert.equal(normalizePath(URI.parse('foo://a/foo/..')).toString(), 'foo://a/'); + assert.equal(normalizePath(URI.parse('foo://a/foo/../bar')).toString(), 'foo://a/bar'); + assert.equal(normalizePath(URI.parse('foo://a/foo/../../bar')).toString(), 'foo://a/bar'); + assert.equal(normalizePath(URI.parse('foo://a/foo/foo/../../bar')).toString(), 'foo://a/bar'); + assert.equal(normalizePath(URI.parse('foo://a/foo/foo/./../../bar')).toString(), 'foo://a/bar'); + assert.equal(normalizePath(URI.parse('foo://a/foo/foo/./../some/../bar')).toString(), 'foo://a/foo/bar'); + }); + + test('isAbsolute', () => { + if (isWindows) { + assert.equal(isAbsolutePath(URI.file('c:\\foo\\')), true); + assert.equal(isAbsolutePath(URI.file('bar')), true); // URI normalizes all file URIs to be absolute + } else { + assert.equal(isAbsolutePath(URI.file('/foo/bar')), true); + assert.equal(isAbsolutePath(URI.file('bar')), true); // URI normalizes all file URIs to be absolute + } + assert.equal(isAbsolutePath(URI.parse('foo:foo')), false); + assert.equal(isAbsolutePath(URI.parse('foo://a/foo/.')), true); + }); + test('isEqual', () => { let fileURI = URI.file('/foo/bar'); let fileURI2 = URI.file('/foo/Bar'); diff --git a/src/vs/editor/browser/services/openerService.ts b/src/vs/editor/browser/services/openerService.ts index 931531d2719..d5797c01a92 100644 --- a/src/vs/editor/browser/services/openerService.ts +++ b/src/vs/editor/browser/services/openerService.ts @@ -6,11 +6,11 @@ import URI from 'vs/base/common/uri'; import * as dom from 'vs/base/browser/dom'; +import * as resources from 'vs/base/common/resources'; import { parse } from 'vs/base/common/marshalling'; import { Schemas } from 'vs/base/common/network'; import { TPromise } from 'vs/base/common/winjs.base'; import { ICodeEditorService } from 'vs/editor/browser/services/codeEditorService'; -import { normalize } from 'vs/base/common/paths'; import { ICommandService, CommandsRegistry } from 'vs/platform/commands/common/commands'; import { IOpenerService } from 'vs/platform/opener/common/opener'; import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry'; @@ -79,7 +79,7 @@ export class OpenerService implements IOpenerService { return TPromise.as(undefined); } else if (resource.scheme === Schemas.file) { - resource = resource.with({ path: normalize(resource.path) }); // workaround for non-normalized paths (https://github.com/Microsoft/vscode/issues/12954) + resource = resources.normalizePath(resource); // workaround for non-normalized paths (https://github.com/Microsoft/vscode/issues/12954) } promise = this._editorService.openCodeEditor({ resource, options: { selection, } }, this._editorService.getFocusedCodeEditor(), options && options.openToSide); } diff --git a/src/vs/platform/workspace/common/workspace.ts b/src/vs/platform/workspace/common/workspace.ts index 4d2a8cc88d5..35d10686eb3 100644 --- a/src/vs/platform/workspace/common/workspace.ts +++ b/src/vs/platform/workspace/common/workspace.ts @@ -234,7 +234,7 @@ export class WorkspaceFolder implements IWorkspaceFolder { } toResource(relativePath: string): URI { - return this.uri.with({ path: paths.join(this.uri.path, relativePath) }); + return resources.joinPath(this.uri, relativePath); } toJSON(): IWorkspaceFolderData { @@ -278,7 +278,7 @@ function toUri(path: string, relativeTo: URI): URI { return URI.file(path); } if (relativeTo) { - return relativeTo.with({ path: paths.join(relativeTo.path, path) }); + return resources.joinPath(relativeTo, path); } } return null; diff --git a/src/vs/workbench/api/node/extHostWorkspace.ts b/src/vs/workbench/api/node/extHostWorkspace.ts index 13de47ac058..56e9d91c15c 100644 --- a/src/vs/workbench/api/node/extHostWorkspace.ts +++ b/src/vs/workbench/api/node/extHostWorkspace.ts @@ -4,13 +4,13 @@ *--------------------------------------------------------------------------------------------*/ 'use strict'; -import { posix, relative, join } from 'path'; +import { relative, join } from 'path'; import { delta as arrayDelta } from 'vs/base/common/arrays'; import { Emitter, Event } from 'vs/base/common/event'; import { TernarySearchTree } from 'vs/base/common/map'; import { normalize } from 'vs/base/common/paths'; import { isLinux } from 'vs/base/common/platform'; -import { basenameOrAuthority, isEqual } from 'vs/base/common/resources'; +import { basenameOrAuthority, isEqual, dirname } from 'vs/base/common/resources'; import { compare } from 'vs/base/common/strings'; import URI from 'vs/base/common/uri'; import { TPromise } from 'vs/base/common/winjs.base'; @@ -124,7 +124,7 @@ class ExtHostWorkspaceImpl extends Workspace { getWorkspaceFolder(uri: URI, resolveParent?: boolean): vscode.WorkspaceFolder { if (resolveParent && this._structure.get(uri.toString())) { // `uri` is a workspace folder so we check for its parent - uri = uri.with({ path: posix.dirname(uri.path) }); + uri = dirname(uri); } return this._structure.findSubstr(uri.toString()); } diff --git a/src/vs/workbench/browser/parts/editor/breadcrumbsModel.ts b/src/vs/workbench/browser/parts/editor/breadcrumbsModel.ts index 40d9babb573..142765257c1 100644 --- a/src/vs/workbench/browser/parts/editor/breadcrumbsModel.ts +++ b/src/vs/workbench/browser/parts/editor/breadcrumbsModel.ts @@ -12,8 +12,7 @@ import { size } from 'vs/base/common/collections'; import { onUnexpectedError } from 'vs/base/common/errors'; import { debounceEvent, Emitter, Event } from 'vs/base/common/event'; import { dispose, IDisposable } from 'vs/base/common/lifecycle'; -import * as paths from 'vs/base/common/paths'; -import { isEqual } from 'vs/base/common/resources'; +import { isEqual, dirname } from 'vs/base/common/resources'; import URI from 'vs/base/common/uri'; import { ICodeEditor } from 'vs/editor/browser/editorBrowser'; import { IPosition } from 'vs/editor/common/core/position'; @@ -117,7 +116,7 @@ export class EditorBreadcrumbsModel { break; } info.path.unshift(new FileElement(uri, info.path.length === 0 ? FileKind.FILE : FileKind.FOLDER)); - uri = uri.with({ path: paths.dirname(uri.path) }); + uri = dirname(uri); } if (info.folder && workspaceService.getWorkbenchState() === WorkbenchState.WORKSPACE) { diff --git a/src/vs/workbench/electron-browser/actions.ts b/src/vs/workbench/electron-browser/actions.ts index 5e747f6ff7f..c8e4a2288f6 100644 --- a/src/vs/workbench/electron-browser/actions.ts +++ b/src/vs/workbench/electron-browser/actions.ts @@ -19,7 +19,6 @@ import { IWorkspaceContextService, WorkbenchState } from 'vs/platform/workspace/ import { IEnvironmentService } from 'vs/platform/environment/common/environment'; import { IConfigurationService, ConfigurationTarget } from 'vs/platform/configuration/common/configuration'; import { IWorkspaceConfigurationService } from 'vs/workbench/services/configuration/common/configuration'; -import * as paths from 'vs/base/common/paths'; import { isMacintosh, isLinux, language } from 'vs/base/common/platform'; import { IQuickOpenService, IFilePickOpenEntry, ISeparator, IPickOpenAction, IPickOpenItem } from 'vs/platform/quickOpen/common/quickOpen'; import * as browser from 'vs/base/browser/browser'; @@ -723,7 +722,7 @@ export abstract class BaseOpenRecentAction extends Action { if (isSingleFolderWorkspaceIdentifier(workspace)) { resource = workspace; label = getWorkspaceLabel(workspace, environmentService, uriDisplayService); - description = uriDisplayService.getLabel(resource.with({ path: paths.dirname(resource.path) })); + description = uriDisplayService.getLabel(dirname(resource)); } else if (isWorkspaceIdentifier(workspace)) { resource = URI.file(workspace.configPath); label = getWorkspaceLabel(workspace, environmentService, uriDisplayService); diff --git a/src/vs/workbench/parts/debug/electron-browser/debugConfigurationManager.ts b/src/vs/workbench/parts/debug/electron-browser/debugConfigurationManager.ts index f40406a23ba..f847d1a6830 100644 --- a/src/vs/workbench/parts/debug/electron-browser/debugConfigurationManager.ts +++ b/src/vs/workbench/parts/debug/electron-browser/debugConfigurationManager.ts @@ -10,7 +10,7 @@ import { TPromise } from 'vs/base/common/winjs.base'; import * as strings from 'vs/base/common/strings'; import * as objects from 'vs/base/common/objects'; import uri from 'vs/base/common/uri'; -import * as paths from 'vs/base/common/paths'; +import * as resources from 'vs/base/common/resources'; import { IJSONSchema } from 'vs/base/common/jsonSchema'; import { ITextModel } from 'vs/editor/common/model'; import { IEditor } from 'vs/workbench/common/editor'; @@ -390,7 +390,7 @@ class Launch implements ILaunch { } public get uri(): uri { - return this.workspace.uri.with({ path: paths.join(this.workspace.uri.path, '/.vscode/launch.json') }); + return resources.joinPath(this.workspace.uri, '/.vscode/launch.json'); } public get name(): string { diff --git a/src/vs/workbench/parts/extensions/node/extensionsWorkbenchService.ts b/src/vs/workbench/parts/extensions/node/extensionsWorkbenchService.ts index 5930310b95e..eaf82c0f793 100644 --- a/src/vs/workbench/parts/extensions/node/extensionsWorkbenchService.ts +++ b/src/vs/workbench/parts/extensions/node/extensionsWorkbenchService.ts @@ -38,7 +38,7 @@ import { INotificationService } from 'vs/platform/notification/common/notificati import { IExtensionService } from 'vs/workbench/services/extensions/common/extensions'; import { groupBy } from 'vs/base/common/collections'; import { Schemas } from 'vs/base/common/network'; -import { posix } from 'path'; +import * as resources from 'vs/base/common/resources'; interface IExtensionStateProvider { (extension: Extension): T; @@ -131,7 +131,7 @@ class Extension implements IExtension { private get localIconUrl(): string { if (this.local && this.local.manifest.icon) { - return this.local.location.with({ path: posix.join(this.local.location.path, this.local.manifest.icon) }).toString(); + return resources.joinPath(this.local.location, this.local.manifest.icon).toString(); } return null; } diff --git a/src/vs/workbench/parts/files/browser/editors/fileEditorTracker.ts b/src/vs/workbench/parts/files/browser/editors/fileEditorTracker.ts index 8b16509b50c..9f6bd55fff9 100644 --- a/src/vs/workbench/parts/files/browser/editors/fileEditorTracker.ts +++ b/src/vs/workbench/parts/files/browser/editors/fileEditorTracker.ts @@ -7,7 +7,7 @@ import { TPromise } from 'vs/base/common/winjs.base'; import { IWorkbenchContribution } from 'vs/workbench/common/contributions'; import URI from 'vs/base/common/uri'; -import * as paths from 'vs/base/common/paths'; +import * as resources from 'vs/base/common/resources'; import { IEditorViewState } from 'vs/editor/common/editorCommon'; import { toResource, SideBySideEditorInput, IWorkbenchEditorConfiguration } from 'vs/workbench/common/editor'; import { ITextFileService, ITextFileEditorModel } from 'vs/workbench/services/textfile/common/textfiles'; @@ -149,7 +149,7 @@ export class FileEditorTracker extends Disposable implements IWorkbenchContribut // Do NOT close any opened editor that matches the resource path (either equal or being parent) of the // resource we move to (movedTo). Otherwise we would close a resource that has been renamed to the same // path but different casing. - if (movedTo && paths.isEqualOrParent(resource.fsPath, movedTo.fsPath, !isLinux /* ignorecase */) && resource.fsPath.indexOf(movedTo.fsPath) === 0) { + if (movedTo && resources.isEqualOrParent(resource, movedTo, resources.hasToIgnoreCase(resource)) && resource.path.indexOf(movedTo.path) === 0) { return; } @@ -157,7 +157,7 @@ export class FileEditorTracker extends Disposable implements IWorkbenchContribut if (arg1 instanceof FileChangesEvent) { matches = arg1.contains(resource, FileChangeType.DELETED); } else { - matches = paths.isEqualOrParent(resource.fsPath, arg1.fsPath, !isLinux /* ignorecase */); + matches = resources.isEqualOrParent(resource, arg1, resources.hasToIgnoreCase(resource)); } if (!matches) { @@ -224,13 +224,13 @@ export class FileEditorTracker extends Disposable implements IWorkbenchContribut const resource = input.getResource(); // Update Editor if file (or any parent of the input) got renamed or moved - if (paths.isEqualOrParent(resource.fsPath, oldResource.fsPath, !isLinux /* ignorecase */)) { + if (resources.isEqualOrParent(resource, oldResource, resources.hasToIgnoreCase(resource))) { let reopenFileResource: URI; if (oldResource.toString() === resource.toString()) { reopenFileResource = newResource; // file got moved } else { const index = this.getIndexOfPath(resource.path, oldResource.path); - reopenFileResource = newResource.with({ path: paths.join(newResource.path, resource.path.substr(index + oldResource.path.length + 1)) }); // parent folder got moved + reopenFileResource = resources.joinPath(newResource, resource.path.substr(index + oldResource.path.length + 1)); // parent folder got moved } // Reopen diff --git a/src/vs/workbench/parts/files/common/explorerModel.ts b/src/vs/workbench/parts/files/common/explorerModel.ts index 92490a50246..249e572bc0d 100644 --- a/src/vs/workbench/parts/files/common/explorerModel.ts +++ b/src/vs/workbench/parts/files/common/explorerModel.ts @@ -157,7 +157,7 @@ export class ExplorerItem { // the folder is fully resolved if either it has a list of children or the client requested this by using the resolveTo // array of resource path to resolve. stat.isDirectoryResolved = !!raw.children || (!!resolveTo && resolveTo.some((r) => { - return resources.isEqualOrParent(r, stat.resource, !isLinux /* ignorecase */); + return resources.isEqualOrParent(r, stat.resource, resources.hasToIgnoreCase(r)); })); // Recurse into children @@ -311,7 +311,7 @@ export class ExplorerItem { } private updateResource(recursive: boolean): void { - this.resource = this.parent.resource.with({ path: paths.join(this.parent.resource.path, this.name) }); + this.resource = resources.joinPath(this.parent.resource, this.name); if (recursive) { if (this.isDirectory && this.children) { diff --git a/src/vs/workbench/parts/files/electron-browser/fileActions.ts b/src/vs/workbench/parts/files/electron-browser/fileActions.ts index 04b6594db4e..ba7e84bb2f5 100644 --- a/src/vs/workbench/parts/files/electron-browser/fileActions.ts +++ b/src/vs/workbench/parts/files/electron-browser/fileActions.ts @@ -14,7 +14,6 @@ import { sequence, ITask, always } from 'vs/base/common/async'; import * as paths from 'vs/base/common/paths'; import * as resources from 'vs/base/common/resources'; import URI from 'vs/base/common/uri'; -import { posix } from 'path'; import * as errors from 'vs/base/common/errors'; import { toErrorMessage } from 'vs/base/common/errorMessage'; import * as strings from 'vs/base/common/strings'; @@ -300,7 +299,7 @@ class RenameFileAction extends BaseRenameAction { public runAction(newName: string): TPromise { const parentResource = this.element.parent.resource; - const targetResource = parentResource.with({ path: paths.join(parentResource.path, newName) }); + const targetResource = resources.joinPath(parentResource, newName); return this.textFileService.move(this.element.resource, targetResource); } @@ -496,7 +495,7 @@ class CreateFileAction extends BaseCreateAction { public runAction(fileName: string): TPromise { const resource = this.element.parent.resource; - return this.fileService.createFile(resource.with({ path: paths.join(resource.path, fileName) })).then(stat => { + return this.fileService.createFile(resources.joinPath(resource, fileName)).then(stat => { return this.editorService.openEditor({ resource: stat.resource, options: { pinned: true } }); }, (error) => { this.onErrorWithRetry(error, () => this.runAction(fileName)); @@ -523,7 +522,7 @@ class CreateFolderAction extends BaseCreateAction { public runAction(fileName: string): TPromise { const resource = this.element.parent.resource; - return this.fileService.createFolder(resource.with({ path: paths.join(resource.path, fileName) })).then(null, (error) => { + return this.fileService.createFolder(resources.joinPath(resource, fileName)).then(null, (error) => { this.onErrorWithRetry(error, () => this.runAction(fileName)); }); } @@ -784,9 +783,9 @@ export class AddFilesAction extends BaseFileAction { this._updateEnablement(); } - public run(resources: URI[]): TPromise { + public run(resourcesToAdd: URI[]): TPromise { const addPromise = TPromise.as(null).then(() => { - if (resources && resources.length > 0) { + if (resourcesToAdd && resourcesToAdd.length > 0) { // Find parent to add to let targetElement: ExplorerItem; @@ -811,8 +810,8 @@ export class AddFilesAction extends BaseFileAction { }); let overwritePromise: TPromise = TPromise.as({ confirmed: true }); - if (resources.some(resource => { - return targetNames.has(isLinux ? paths.basename(resource.fsPath) : paths.basename(resource.fsPath).toLowerCase()); + if (resourcesToAdd.some(resource => { + return targetNames.has(!resources.hasToIgnoreCase(resource) ? resources.basename(resource) : resources.basename(resource).toLowerCase()); })) { const confirm: IConfirmation = { message: nls.localize('confirmOverwrite', "A file or folder with the same name already exists in the destination folder. Do you want to replace it?"), @@ -831,10 +830,10 @@ export class AddFilesAction extends BaseFileAction { // Run add in sequence const addPromisesFactory: ITask>[] = []; - resources.forEach(resource => { + resourcesToAdd.forEach(resource => { addPromisesFactory.push(() => { const sourceFile = resource; - const targetFile = targetElement.resource.with({ path: paths.join(targetElement.resource.path, paths.basename(sourceFile.path)) }); + const targetFile = resources.joinPath(targetElement.resource, resources.basename(sourceFile)); // if the target exists and is dirty, make sure to revert it. otherwise the dirty contents // of the target file would replace the contents of the added file. since we already @@ -845,11 +844,11 @@ export class AddFilesAction extends BaseFileAction { } return revertPromise.then(() => { - const target = targetElement.resource.with({ path: posix.join(targetElement.resource.path, posix.basename(sourceFile.path)) }); + const target = resources.joinPath(targetElement.resource, resources.basename(sourceFile)); return this.fileService.copyFile(sourceFile, target, true).then(stat => { // if we only add one file, just open it directly - if (resources.length === 1) { + if (resourcesToAdd.length === 1) { this.editorService.openEditor({ resource: stat.resource, options: { pinned: true } }); } }, error => this.onError(error)); @@ -1020,14 +1019,14 @@ export class DuplicateFileAction extends BaseFileAction { function findValidPasteFileTarget(targetFolder: ExplorerItem, fileToPaste: { resource: URI, isDirectory?: boolean }): URI { let name = resources.basenameOrAuthority(fileToPaste.resource); - let candidate = targetFolder.resource.with({ path: paths.join(targetFolder.resource.path, name) }); + let candidate = resources.joinPath(targetFolder.resource, name); while (true) { if (!targetFolder.root.find(candidate)) { break; } name = incrementFileName(name, fileToPaste.isDirectory); - candidate = targetFolder.resource.with({ path: paths.join(targetFolder.resource.path, name) }); + candidate = resources.joinPath(targetFolder.resource, name); } return candidate; @@ -1545,7 +1544,7 @@ export class CompareWithClipboardAction extends Action { this.registrationDisposal = this.textModelService.registerTextModelContentProvider(CompareWithClipboardAction.SCHEME, provider); } - const name = paths.basename(resource.fsPath); + const name = resources.basename(resource); const editorLabel = nls.localize('clipboardComparisonLabel', "Clipboard ↔ {0}", name); const cleanUp = () => { diff --git a/src/vs/workbench/parts/files/electron-browser/views/explorerViewer.ts b/src/vs/workbench/parts/files/electron-browser/views/explorerViewer.ts index ffaeaf38297..af257952938 100644 --- a/src/vs/workbench/parts/files/electron-browser/views/explorerViewer.ts +++ b/src/vs/workbench/parts/files/electron-browser/views/explorerViewer.ts @@ -279,7 +279,7 @@ export class FileRenderer implements IRenderer { const parent = stat.name ? resources.dirname(stat.resource) : stat.resource; const value = stat.name || ''; - label.setFile(parent.with({ path: paths.join(parent.path, value || ' ') }), labelOptions); // Use icon for ' ' if name is empty. + label.setFile(resources.joinPath(parent, value || ' '), labelOptions); // Use icon for ' ' if name is empty. // Input field for name const inputBox = new InputBox(label.element, this.contextViewService, { @@ -291,7 +291,7 @@ export class FileRenderer implements IRenderer { const styler = attachInputBoxStyler(inputBox, this.themeService); inputBox.onDidChange(value => { - label.setFile(parent.with({ path: paths.join(parent.path, value || ' ') }), labelOptions); // update label icon while typing! + label.setFile(resources.joinPath(parent, value || ' '), labelOptions); // update label icon while typing! }); const lastDot = value.lastIndexOf('.'); @@ -1058,7 +1058,7 @@ export class FileDragAndDrop extends SimpleFileResourceDragAndDrop { } // Otherwise move - const targetResource = target.resource.with({ path: paths.join(target.resource.path, source.name) }); + const targetResource = resources.joinPath(target.resource, source.name); return this.textFileService.move(source.resource, targetResource).then(null, error => { diff --git a/src/vs/workbench/parts/output/common/outputLinkComputer.ts b/src/vs/workbench/parts/output/common/outputLinkComputer.ts index 54334478c76..71cba0a3ce8 100644 --- a/src/vs/workbench/parts/output/common/outputLinkComputer.ts +++ b/src/vs/workbench/parts/output/common/outputLinkComputer.ts @@ -9,6 +9,7 @@ import { ILink } from 'vs/editor/common/modes'; import { TPromise } from 'vs/base/common/winjs.base'; import URI from 'vs/base/common/uri'; import * as paths from 'vs/base/common/paths'; +import * as resources from 'vs/base/common/resources'; import * as strings from 'vs/base/common/strings'; import * as arrays from 'vs/base/common/arrays'; import { Range } from 'vs/editor/common/core/range'; @@ -70,7 +71,7 @@ export class OutputLinkComputer { const resourceCreator: IResourceCreator = { toResource: (folderRelativePath: string): URI => { if (typeof folderRelativePath === 'string') { - return folderUri.with({ path: paths.join(folderUri.path, folderRelativePath) }); + return resources.joinPath(folderUri, folderRelativePath); } return null; diff --git a/src/vs/workbench/parts/search/common/queryBuilder.ts b/src/vs/workbench/parts/search/common/queryBuilder.ts index 8d13bef82a3..08bea8ac1cd 100644 --- a/src/vs/workbench/parts/search/common/queryBuilder.ts +++ b/src/vs/workbench/parts/search/common/queryBuilder.ts @@ -11,6 +11,7 @@ import * as collections from 'vs/base/common/collections'; import * as strings from 'vs/base/common/strings'; import * as glob from 'vs/base/common/glob'; import * as paths from 'vs/base/common/paths'; +import * as resources from 'vs/base/common/resources'; import uri from 'vs/base/common/uri'; import { untildify } from 'vs/base/common/labels'; import { IWorkspaceContextService, WorkbenchState } from 'vs/platform/workspace/common/workspace'; @@ -274,18 +275,18 @@ export class QueryBuilder { if (this.workspaceContextService.getWorkbenchState() === WorkbenchState.FOLDER) { // TODO: @Sandy Try checking workspace folders length instead. const workspaceUri = this.workspaceContextService.getWorkspace().folders[0].uri; - return [workspaceUri.with({ path: paths.normalize(paths.join(workspaceUri.path, searchPath)) })]; + return [resources.joinPath(workspaceUri, searchPath)]; } else if (searchPath === './') { return []; // ./ or ./**/foo makes sense for single-folder but not multi-folder workspaces } else { const relativeSearchPathMatch = searchPath.match(/\.[\/\\]([^\/\\]+)([\/\\].+)?/); if (relativeSearchPathMatch) { const searchPathRoot = relativeSearchPathMatch[1]; - const matchingRoots = this.workspaceContextService.getWorkspace().folders.filter(folder => paths.basename(folder.uri.fsPath) === searchPathRoot || folder.name === searchPathRoot); + const matchingRoots = this.workspaceContextService.getWorkspace().folders.filter(folder => resources.basename(folder.uri) === searchPathRoot || folder.name === searchPathRoot); if (matchingRoots.length) { return matchingRoots.map(root => { return relativeSearchPathMatch[2] ? - root.uri.with({ path: paths.normalize(paths.join(root.uri.path, relativeSearchPathMatch[2])) }) : + resources.joinPath(root.uri, relativeSearchPathMatch[2]) : root.uri; }); } else { diff --git a/src/vs/workbench/services/configuration/node/configuration.ts b/src/vs/workbench/services/configuration/node/configuration.ts index 947dd50a25a..2df1c8ad96e 100644 --- a/src/vs/workbench/services/configuration/node/configuration.ts +++ b/src/vs/workbench/services/configuration/node/configuration.ts @@ -125,7 +125,7 @@ export class WorkspaceConfiguration extends Disposable { } function isFolderConfigurationFile(resource: URI): boolean { - const name = paths.basename(resource.path); + const name = resources.basename(resource); return [`${FOLDER_SETTINGS_NAME}.json`, `${TASKS_CONFIGURATION_KEY}.json`, `${LAUNCH_CONFIGURATION_KEY}.json`].some(p => p === name);// only workspace config files } @@ -193,7 +193,7 @@ export abstract class AbstractFolderConfiguration extends Disposable implements private parseContents(contents: { resource: URI, value: string }[]): void { for (const content of contents) { - const name = paths.basename(content.resource.path); + const name = resources.basename(content.resource); if (name === `${FOLDER_SETTINGS_NAME}.json`) { this._folderSettingsModelParser.parse(content.value); } else { @@ -216,7 +216,7 @@ export class NodeBasedFolderConfiguration extends AbstractFolderConfiguration { constructor(folder: URI, configFolderRelativePath: string, workbenchState: WorkbenchState) { super(folder, workbenchState); - this.folderConfigurationPath = URI.file(paths.join(this.folder.fsPath, configFolderRelativePath)); + this.folderConfigurationPath = resources.joinPath(folder, configFolderRelativePath); } protected loadFolderConfigurationContents(): TPromise<{ resource: URI, value: string }[]> { @@ -249,7 +249,7 @@ export class NodeBasedFolderConfiguration extends AbstractFolderConfiguration { c({ resource, isDirectory: true, - children: children.map(child => { return { resource: URI.file(paths.join(resource.fsPath, child)) }; }) + children: children.map(child => { return { resource: resources.joinPath(resource, child) }; }) }); } }); @@ -265,7 +265,7 @@ export class FileServiceBasedFolderConfiguration extends AbstractFolderConfigura constructor(folder: URI, private configFolderRelativePath: string, workbenchState: WorkbenchState, private fileService: IFileService, from?: AbstractFolderConfiguration) { super(folder, workbenchState, from); - this.folderConfigurationPath = folder.with({ path: paths.join(this.folder.path, configFolderRelativePath) }); + this.folderConfigurationPath = resources.joinPath(folder, configFolderRelativePath); this.reloadConfigurationScheduler = this._register(new RunOnceScheduler(() => this._onDidChange.fire(), 50)); this._register(fileService.onFileChanges(e => this.handleWorkspaceFileEvents(e))); } @@ -296,7 +296,7 @@ export class FileServiceBasedFolderConfiguration extends AbstractFolderConfigura for (let i = 0, len = events.length; i < len; i++) { const resource = events[i].resource; - const basename = paths.basename(resource.path); + const basename = resources.basename(resource); const isJson = paths.extname(basename) === '.json'; const isDeletedSettingsFolder = (events[i].type === FileChangeType.DELETED && basename === this.configFolderRelativePath); diff --git a/src/vs/workbench/services/files/electron-browser/remoteFileService.ts b/src/vs/workbench/services/files/electron-browser/remoteFileService.ts index 295a9182a39..0722e8dfc97 100644 --- a/src/vs/workbench/services/files/electron-browser/remoteFileService.ts +++ b/src/vs/workbench/services/files/electron-browser/remoteFileService.ts @@ -4,11 +4,11 @@ *--------------------------------------------------------------------------------------------*/ 'use strict'; -import { posix } from 'path'; import { flatten, isFalsyOrEmpty } from 'vs/base/common/arrays'; import { IDisposable, dispose, Disposable } from 'vs/base/common/lifecycle'; import { TernarySearchTree, keys } from 'vs/base/common/map'; import { Schemas } from 'vs/base/common/network'; +import * as resources from 'vs/base/common/resources'; import URI from 'vs/base/common/uri'; import { TPromise } from 'vs/base/common/winjs.base'; import { IDecodeStreamOptions, toDecodeStream, encodeStream } from 'vs/base/node/encoding'; @@ -42,7 +42,7 @@ function toIFileStat(provider: IFileSystemProvider, tuple: [URI, IStat], recurse const [resource, stat] = tuple; const fileStat: IFileStat = { resource, - name: posix.basename(resource.path), + name: resources.basename(resource), isDirectory: (stat.type & FileType.Directory) !== 0, isSymbolicLink: (stat.type & FileType.SymbolicLink) !== 0, isReadonly: !!(provider.capabilities & FileSystemProviderCapabilities.Readonly), @@ -58,7 +58,7 @@ function toIFileStat(provider: IFileSystemProvider, tuple: [URI, IStat], recurse // resolve children if requested return TPromise.join(entries.map(tuple => { const [name, type] = tuple; - const childResource = resource.with({ path: posix.join(resource.path, name) }); + const childResource = resources.joinPath(resource, name); return toIFileStat(provider, [childResource, new TypeOnlyStat(type)], recurse); })).then(children => { fileStat.children = children; @@ -261,7 +261,7 @@ export class RemoteFileService extends FileService { private _withProvider(resource: URI): TPromise { - if (!posix.isAbsolute(resource.path)) { + if (!resources.isAbsolutePath(resource)) { throw new FileOperationError( localize('invalidPath', "The path of resource '{0}' must be absolute", resource.toString(true)), FileOperationResult.FILE_INVALID_PATH @@ -434,12 +434,12 @@ export class RemoteFileService extends FileService { break; // we have hit a directory -> good } catch (e) { // ENOENT - basenames.push(posix.basename(directory.path)); - directory = directory.with({ path: posix.dirname(directory.path) }); + basenames.push(resources.basename(directory)); + directory = resources.dirname(directory); } } for (let i = basenames.length - 1; i >= 0; i--) { - directory = directory.with({ path: posix.join(directory.path, basenames[i]) }); + directory = resources.joinPath(directory, basenames[i]); await provider.mkdir(directory); } } @@ -458,7 +458,7 @@ export class RemoteFileService extends FileService { return this._withProvider(resource).then(RemoteFileService._throwIfFileSystemIsReadonly).then(provider => { - return RemoteFileService._mkdirp(provider, resource.with({ path: posix.dirname(resource.path) })).then(() => { + return RemoteFileService._mkdirp(provider, resources.dirname(resource)).then(() => { const encoding = this.encoding.getWriteEncoding(resource); return this._writeFile(provider, resource, new StringSnapshot(content), encoding, { create: true, overwrite: Boolean(options && options.overwrite) }); }); @@ -479,7 +479,7 @@ export class RemoteFileService extends FileService { return super.updateContent(resource, value, options); } else { return this._withProvider(resource).then(RemoteFileService._throwIfFileSystemIsReadonly).then(provider => { - return RemoteFileService._mkdirp(provider, resource.with({ path: posix.dirname(resource.path) })).then(() => { + return RemoteFileService._mkdirp(provider, resources.dirname(resource)).then(() => { const snapshot = typeof value === 'string' ? new StringSnapshot(value) : value; return this._writeFile(provider, resource, snapshot, options && options.encoding, { create: true, overwrite: true }); }); @@ -537,7 +537,7 @@ export class RemoteFileService extends FileService { return super.createFolder(resource); } else { return this._withProvider(resource).then(RemoteFileService._throwIfFileSystemIsReadonly).then(provider => { - return RemoteFileService._mkdirp(provider, resource.with({ path: posix.dirname(resource.path) })).then(() => { + return RemoteFileService._mkdirp(provider, resources.dirname(resource)).then(() => { return provider.mkdir(resource).then(() => { return this.resolveFile(resource); }); From 6872621c568d6b78df0421870d28d33aaa60f9ff Mon Sep 17 00:00:00 2001 From: Martin Aeschlimann Date: Wed, 8 Aug 2018 16:08:50 +0200 Subject: [PATCH 0579/1276] fix monaco.FoldingRange spec (fixes Microsoft/monaco-editor#984) --- src/vs/editor/common/modes.ts | 4 ++-- src/vs/monaco.d.ts | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/vs/editor/common/modes.ts b/src/vs/editor/common/modes.ts index 02c236a53c2..0f643685413 100644 --- a/src/vs/editor/common/modes.ts +++ b/src/vs/editor/common/modes.ts @@ -848,12 +848,12 @@ export interface FoldingRangeProvider { export interface FoldingRange { /** - * The zero-based start line of the range to fold. The folded area starts after the line's last character. + * The one-based start line of the range to fold. The folded area starts after the line's last character. */ start: number; /** - * The zero-based end line of the range to fold. The folded area ends with the line's last character. + * The one-based end line of the range to fold. The folded area ends with the line's last character. */ end: number; diff --git a/src/vs/monaco.d.ts b/src/vs/monaco.d.ts index cb169b9e99f..0642820ecfc 100644 --- a/src/vs/monaco.d.ts +++ b/src/vs/monaco.d.ts @@ -5182,11 +5182,11 @@ declare namespace monaco.languages { export interface FoldingRange { /** - * The zero-based start line of the range to fold. The folded area starts after the line's last character. + * The one-based start line of the range to fold. The folded area starts after the line's last character. */ start: number; /** - * The zero-based end line of the range to fold. The folded area ends with the line's last character. + * The one-based end line of the range to fold. The folded area ends with the line's last character. */ end: number; /** From 84a9a8fd0df0930fb80d5a914755207e11ac53b7 Mon Sep 17 00:00:00 2001 From: Joao Moreno Date: Wed, 8 Aug 2018 16:10:12 +0200 Subject: [PATCH 0580/1276] scm: selected repositories --- .../parts/scm/electron-browser/scmViewlet.ts | 5 +++ src/vs/workbench/services/scm/common/scm.ts | 5 +++ .../services/scm/common/scmService.ts | 39 +++++++++++++++++++ 3 files changed, 49 insertions(+) diff --git a/src/vs/workbench/parts/scm/electron-browser/scmViewlet.ts b/src/vs/workbench/parts/scm/electron-browser/scmViewlet.ts index 102c393dddb..4a9da7a25f7 100644 --- a/src/vs/workbench/parts/scm/electron-browser/scmViewlet.ts +++ b/src/vs/workbench/parts/scm/electron-browser/scmViewlet.ts @@ -1321,6 +1321,11 @@ export class SCMViewlet extends PanelViewlet implements IViewModel, IViewsViewle this.updateTitleArea(); } + + if (this.isVisible()) { + panelsToRemove.forEach(p => p.repository.setSelected(false)); + newRepositoryPanels.forEach(p => p.repository.setSelected(true)); + } } private getContributableViewsSize(): number { diff --git a/src/vs/workbench/services/scm/common/scm.ts b/src/vs/workbench/services/scm/common/scm.ts index 6a01974b0ee..40aba5a08c0 100644 --- a/src/vs/workbench/services/scm/common/scm.ts +++ b/src/vs/workbench/services/scm/common/scm.ts @@ -96,9 +96,12 @@ export interface ISCMInput { export interface ISCMRepository extends IDisposable { readonly onDidFocus: Event; + readonly selected: boolean; + readonly onDidChangeSelection: Event; readonly provider: ISCMProvider; readonly input: ISCMInput; focus(): void; + setSelected(selected: boolean): void; } export interface ISCMService { @@ -108,6 +111,8 @@ export interface ISCMService { readonly onDidRemoveRepository: Event; readonly repositories: ISCMRepository[]; + readonly selectedRepositories: ISCMRepository[]; + readonly onDidChangeSelectedRepositories: Event; registerSCMProvider(provider: ISCMProvider): ISCMRepository; } diff --git a/src/vs/workbench/services/scm/common/scmService.ts b/src/vs/workbench/services/scm/common/scmService.ts index d062ae05633..b93c088a9d4 100644 --- a/src/vs/workbench/services/scm/common/scmService.ts +++ b/src/vs/workbench/services/scm/common/scmService.ts @@ -10,6 +10,7 @@ import { Event, Emitter } from 'vs/base/common/event'; import { ISCMService, ISCMProvider, ISCMInput, ISCMRepository, IInputValidator } from './scm'; import { ILogService } from 'vs/platform/log/common/log'; import { TPromise } from 'vs/base/common/winjs.base'; +import { equals } from 'vs/base/common/arrays'; class SCMInput implements ISCMInput { @@ -61,6 +62,14 @@ class SCMRepository implements ISCMRepository { private _onDidFocus = new Emitter(); readonly onDidFocus: Event = this._onDidFocus.event; + private _selected = false; + get selected(): boolean { + return this._selected; + } + + private _onDidChangeSelection = new Emitter(); + readonly onDidChangeSelection: Event = this._onDidChangeSelection.event; + readonly input: ISCMInput = new SCMInput(); constructor( @@ -72,6 +81,11 @@ class SCMRepository implements ISCMRepository { this._onDidFocus.fire(); } + setSelected(selected: boolean): void { + this._selected = selected; + this._onDidChangeSelection.fire(selected); + } + dispose(): void { this.disposable.dispose(); this.provider.dispose(); @@ -86,6 +100,12 @@ export class SCMService implements ISCMService { private _repositories: ISCMRepository[] = []; get repositories(): ISCMRepository[] { return [...this._repositories]; } + private _selectedRepositories: ISCMRepository[] = []; + get selectedRepositories(): ISCMRepository[] { return [...this._selectedRepositories]; } + + private _onDidChangeSelectedRepositories = new Emitter(); + readonly onDidChangeSelectedRepositories: Event = this._onDidChangeSelectedRepositories.event; + private _onDidAddProvider = new Emitter(); get onDidAddRepository(): Event { return this._onDidAddProvider.event; } @@ -110,15 +130,34 @@ export class SCMService implements ISCMService { return; } + selectedDisposable.dispose(); this._providerIds.delete(provider.id); this._repositories.splice(index, 1); this._onDidRemoveProvider.fire(repository); }); const repository = new SCMRepository(provider, disposable); + const selectedDisposable = repository.onDidChangeSelection(this.onDidChangeSelection, this); + this._repositories.push(repository); this._onDidAddProvider.fire(repository); + // automatically select the first repository + if (this._repositories.length === 1) { + repository.setSelected(true); + } + return repository; } + + private onDidChangeSelection(): void { + const selectedRepositories = this._repositories.filter(r => r.selected); + + if (equals(this._selectedRepositories, selectedRepositories)) { + return; + } + + this._selectedRepositories = this._repositories.filter(r => r.selected); + this._onDidChangeSelectedRepositories.fire(this.selectedRepositories); + } } From f0d05f55b3699cecfd7491ac728e0c0b5413bbca Mon Sep 17 00:00:00 2001 From: Joao Moreno Date: Wed, 8 Aug 2018 16:21:37 +0200 Subject: [PATCH 0581/1276] scm service: update selection on repository disposal --- src/vs/workbench/services/scm/common/scmService.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/src/vs/workbench/services/scm/common/scmService.ts b/src/vs/workbench/services/scm/common/scmService.ts index b93c088a9d4..83b3e88e06d 100644 --- a/src/vs/workbench/services/scm/common/scmService.ts +++ b/src/vs/workbench/services/scm/common/scmService.ts @@ -134,6 +134,7 @@ export class SCMService implements ISCMService { this._providerIds.delete(provider.id); this._repositories.splice(index, 1); this._onDidRemoveProvider.fire(repository); + this.onDidChangeSelection(); }); const repository = new SCMRepository(provider, disposable); From a736955e6e7f50e0c417586c01ee7efd81861f24 Mon Sep 17 00:00:00 2001 From: Joao Moreno Date: Wed, 8 Aug 2018 16:22:02 +0200 Subject: [PATCH 0582/1276] scm: SourceControl.selected and event --- src/vs/vscode.proposed.d.ts | 17 ++++++ .../api/electron-browser/mainThreadSCM.ts | 13 ++++- src/vs/workbench/api/node/extHost.protocol.ts | 1 + src/vs/workbench/api/node/extHostSCM.ts | 53 +++++++++++++++++++ 4 files changed, 83 insertions(+), 1 deletion(-) diff --git a/src/vs/vscode.proposed.d.ts b/src/vs/vscode.proposed.d.ts index 64859f24589..03f3b993f60 100644 --- a/src/vs/vscode.proposed.d.ts +++ b/src/vs/vscode.proposed.d.ts @@ -523,6 +523,23 @@ declare module 'vscode' { //#endregion + //#region Joao: SCM selected provider + + export interface SourceControl { + + /** + * Whether the source control is selected. + */ + readonly selected: boolean; + + /** + * An event signaling when the selection state changes. + */ + readonly onDidChangeSelection: Event; + } + + //#endregion + //#region Comments /** * Comments provider related APIs are still in early stages, they may be changed significantly during our API experiments. diff --git a/src/vs/workbench/api/electron-browser/mainThreadSCM.ts b/src/vs/workbench/api/electron-browser/mainThreadSCM.ts index 8ee8daaee7a..a6c6f1caa69 100644 --- a/src/vs/workbench/api/electron-browser/mainThreadSCM.ts +++ b/src/vs/workbench/api/electron-browser/mainThreadSCM.ts @@ -7,7 +7,7 @@ import { TPromise } from 'vs/base/common/winjs.base'; import URI, { UriComponents } from 'vs/base/common/uri'; -import { Event, Emitter } from 'vs/base/common/event'; +import { Event, Emitter, debounceEvent } from 'vs/base/common/event'; import { assign } from 'vs/base/common/objects'; import { IDisposable, dispose } from 'vs/base/common/lifecycle'; import { ISCMService, ISCMRepository, ISCMProvider, ISCMResource, ISCMResourceGroup, ISCMResourceDecorations, IInputValidation } from 'vs/workbench/services/scm/common/scm'; @@ -270,6 +270,9 @@ export class MainThreadSCM implements MainThreadSCMShape { @ISCMService private scmService: ISCMService ) { this._proxy = extHostContext.getProxy(ExtHostContext.ExtHostSCM); + + debounceEvent(scmService.onDidChangeSelectedRepositories, (_, e) => e, 100) + (this.onDidChangeSelectedRepositories, this, this._disposables); } dispose(): void { @@ -417,4 +420,12 @@ export class MainThreadSCM implements MainThreadSCMShape { repository.input.validateInput = () => TPromise.as(undefined); } } + + private onDidChangeSelectedRepositories(repositories: ISCMRepository[]): void { + const handles = repositories + .filter(r => r.provider instanceof MainThreadSCMProvider) + .map(r => (r.provider as MainThreadSCMProvider).handle); + + this._proxy.$setSelectedSourceControls(handles); + } } diff --git a/src/vs/workbench/api/node/extHost.protocol.ts b/src/vs/workbench/api/node/extHost.protocol.ts index 3d55724ba44..0afcb94f377 100644 --- a/src/vs/workbench/api/node/extHost.protocol.ts +++ b/src/vs/workbench/api/node/extHost.protocol.ts @@ -882,6 +882,7 @@ export interface ExtHostSCMShape { $onInputBoxValueChange(sourceControlHandle: number, value: string): TPromise; $executeResourceCommand(sourceControlHandle: number, groupHandle: number, handle: number): TPromise; $validateInput(sourceControlHandle: number, value: string, cursorPosition: number): TPromise<[string, number] | undefined>; + $setSelectedSourceControls(selectedSourceControlHandles: number[]): TPromise; } export interface ExtHostTaskShape { diff --git a/src/vs/workbench/api/node/extHostSCM.ts b/src/vs/workbench/api/node/extHostSCM.ts index eeafdc4a416..2ce26e50530 100644 --- a/src/vs/workbench/api/node/extHostSCM.ts +++ b/src/vs/workbench/api/node/extHostSCM.ts @@ -395,6 +395,15 @@ class ExtHostSourceControl implements vscode.SourceControl { this._proxy.$updateSourceControl(this.handle, { statusBarCommands: internal }); } + private _selected: boolean = false; + + get selected(): boolean { + return this._selected; + } + + private _onDidChangeSelection = new Emitter(); + readonly onDidChangeSelection = this._onDidChangeSelection.event; + private handle: number = ExtHostSourceControl._handlePool++; constructor( @@ -454,6 +463,11 @@ class ExtHostSourceControl implements vscode.SourceControl { return this._groups.get(handle); } + setSelectionState(selected: boolean): void { + this._selected = selected; + this._onDidChangeSelection.fire(selected); + } + dispose(): void { this._groups.forEach(group => group.dispose()); this._proxy.$unregisterSourceControl(this.handle); @@ -471,6 +485,8 @@ export class ExtHostSCM implements ExtHostSCMShape { private _onDidChangeActiveProvider = new Emitter(); get onDidChangeActiveProvider(): Event { return this._onDidChangeActiveProvider.event; } + private _selectedSourceControlHandles = new Set(); + constructor( mainContext: IMainContext, private _commands: ExtHostCommands, @@ -607,4 +623,41 @@ export class ExtHostSCM implements ExtHostSCMShape { return TPromise.as<[string, number]>([result.message, result.type]); }); } + + $setSelectedSourceControls(selectedSourceControlHandles: number[]): TPromise { + this.logService.trace('ExtHostSCM#$setSelectedSourceControls', selectedSourceControlHandles); + + const set = new Set(); + + for (const handle of selectedSourceControlHandles) { + set.add(handle); + } + + set.forEach(handle => { + if (!this._selectedSourceControlHandles.has(handle)) { + const sourceControl = this._sourceControls.get(handle); + + if (!sourceControl) { + return; + } + + sourceControl.setSelectionState(true); + } + }); + + this._selectedSourceControlHandles.forEach(handle => { + if (!set.has(handle)) { + const sourceControl = this._sourceControls.get(handle); + + if (!sourceControl) { + return; + } + + sourceControl.setSelectionState(false); + } + }); + + this._selectedSourceControlHandles = set; + return TPromise.as(null); + } } From 23dca7373ac85344c4d6dea376ca1609d32130b0 Mon Sep 17 00:00:00 2001 From: Benjamin Pasero Date: Wed, 8 Aug 2018 16:28:11 +0200 Subject: [PATCH 0583/1276] Exception when saving file editor opened from remote file provider (fixes #55051) --- .../services/textfile/common/textFileEditorModel.ts | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/vs/workbench/services/textfile/common/textFileEditorModel.ts b/src/vs/workbench/services/textfile/common/textFileEditorModel.ts index 08d9ae4bc7a..0c3642145b3 100644 --- a/src/vs/workbench/services/textfile/common/textFileEditorModel.ts +++ b/src/vs/workbench/services/textfile/common/textFileEditorModel.ts @@ -751,10 +751,8 @@ export class TextFileEditorModel extends BaseTextEditorModel implements ITextFil // Emit File Saved Event this._onDidStateChange.fire(StateChange.SAVED); }, error => { - if (!FileOperationError.isFileOperationError(error)) { - // TODO@ben, workaround issue #55051 - this.logService.error(`doSave(${versionId}) - Unexpected error type ${error}`, this.resource); - return; + if (!error) { + error = new Error('Unknown Save Error'); // TODO@remote we should never get null as error (https://github.com/Microsoft/vscode/issues/55051) } this.logService.error(`doSave(${versionId}) - exit - resulted in a save error: ${error.toString()}`, this.resource); From 3f5a4bc315ad6598f75f66e5da699179cf5612a0 Mon Sep 17 00:00:00 2001 From: Benjamin Pasero Date: Wed, 8 Aug 2018 16:34:02 +0200 Subject: [PATCH 0584/1276] :lipstick: --- .../browser/parts/editor/editorPart.ts | 133 +----------------- src/vs/workbench/common/theme.ts | 6 + 2 files changed, 11 insertions(+), 128 deletions(-) diff --git a/src/vs/workbench/browser/parts/editor/editorPart.ts b/src/vs/workbench/browser/parts/editor/editorPart.ts index 36d3ffb96b5..c244fec9635 100644 --- a/src/vs/workbench/browser/parts/editor/editorPart.ts +++ b/src/vs/workbench/browser/parts/editor/editorPart.ts @@ -10,20 +10,20 @@ import { IThemeService } from 'vs/platform/theme/common/themeService'; import { Part } from 'vs/workbench/browser/part'; import { Dimension, isAncestor, toggleClass, addClass, $ } from 'vs/base/browser/dom'; import { Event, Emitter, once, Relay, anyEvent } from 'vs/base/common/event'; -import { contrastBorder, editorBackground, registerColor } from 'vs/platform/theme/common/colorRegistry'; +import { contrastBorder, editorBackground } from 'vs/platform/theme/common/colorRegistry'; import { GroupDirection, IAddGroupOptions, GroupsArrangement, GroupOrientation, IMergeGroupOptions, MergeGroupMode, ICopyEditorOptions, GroupsOrder, GroupChangeKind, GroupLocation, IFindGroupScope, EditorGroupLayout, GroupLayoutArgument } from 'vs/workbench/services/group/common/editorGroupsService'; import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; -import { Direction, SerializableGrid, Sizing, ISerializedGrid, Orientation, ISerializedNode, GridBranchNode, isGridBranchNode, GridNode, createSerializedGrid, Grid } from 'vs/base/browser/ui/grid/grid'; +import { Direction, SerializableGrid, Sizing, ISerializedGrid, Orientation, GridBranchNode, isGridBranchNode, GridNode, createSerializedGrid, Grid } from 'vs/base/browser/ui/grid/grid'; import { GroupIdentifier, IWorkbenchEditorConfiguration } from 'vs/workbench/common/editor'; import { values } from 'vs/base/common/map'; -import { EDITOR_GROUP_BORDER } from 'vs/workbench/common/theme'; +import { EDITOR_GROUP_BORDER, EDITOR_PANE_BACKGROUND } from 'vs/workbench/common/theme'; import { distinct } from 'vs/base/common/arrays'; import { IEditorGroupsAccessor, IEditorGroupView, IEditorPartOptions, getEditorPartOptions, impactsEditorPartOptions, IEditorPartOptionsChangeEvent, EditorGroupsServiceImpl } from 'vs/workbench/browser/parts/editor/editor'; import { EditorGroupView } from 'vs/workbench/browser/parts/editor/editorGroupView'; import { IConfigurationService, IConfigurationChangeEvent } from 'vs/platform/configuration/common/configuration'; import { IDisposable, dispose, toDisposable } from 'vs/base/common/lifecycle'; import { assign } from 'vs/base/common/objects'; -import { IStorageService, StorageScope } from 'vs/platform/storage/common/storage'; +import { IStorageService } from 'vs/platform/storage/common/storage'; import { Scope } from 'vs/workbench/common/memento'; import { ISerializedEditorGroup, isSerializedEditorGroup } from 'vs/workbench/common/editor/editorGroup'; import { TValueCallback, TPromise } from 'vs/base/common/winjs.base'; @@ -82,12 +82,6 @@ class GridWidgetView implements IView { } } -export const EDITOR_PANE_BACKGROUND = registerColor('editorPane.background', { - dark: editorBackground, - light: editorBackground, - hc: editorBackground -}, localize('editorPaneBackground', "Background color of the editor pane visible on the left and right side of the centered editor layout.")); - export class EditorPart extends Part implements EditorGroupsServiceImpl, IEditorGroupsAccessor { _serviceBrand: any; @@ -828,7 +822,7 @@ export class EditorPart extends Part implements EditorGroupsServiceImpl, IEditor } private doCreateGridControlWithPreviousState(): void { - const uiState = this.doGetPreviousState(); + const uiState = this.memento[EditorPart.EDITOR_PART_UI_STATE_STORAGE_KEY] as IEditorPartUIState; if (uiState && uiState.serializedGrid) { // MRU @@ -889,123 +883,6 @@ export class EditorPart extends Part implements EditorGroupsServiceImpl, IEditor this.onDidSetGridWidget.fire(); } - private doGetPreviousState(): IEditorPartUIState { - const legacyState = this.doGetPreviousLegacyState(); - if (legacyState) { - return legacyState; // TODO@ben remove after a while - } - - return this.memento[EditorPart.EDITOR_PART_UI_STATE_STORAGE_KEY] as IEditorPartUIState; - } - - private doGetPreviousLegacyState(): IEditorPartUIState { - const LEGACY_EDITOR_PART_UI_STATE_STORAGE_KEY = 'editorpart.uiState'; - const LEGACY_STACKS_MODEL_STORAGE_KEY = 'editorStacks.model'; - - interface ILegacyEditorPartUIState { - ratio: number[]; - groupOrientation: 'vertical' | 'horizontal'; - } - - interface ISerializedLegacyEditorStacksModel { - groups: ISerializedEditorGroup[]; - active: number; - } - - let legacyUIState: ISerializedLegacyEditorStacksModel; - const legacyUIStateRaw = this.storageService.get(LEGACY_STACKS_MODEL_STORAGE_KEY, StorageScope.WORKSPACE); - if (legacyUIStateRaw) { - try { - legacyUIState = JSON.parse(legacyUIStateRaw); - } catch (error) { /* ignore */ } - } - - if (legacyUIState) { - this.storageService.remove(LEGACY_STACKS_MODEL_STORAGE_KEY, StorageScope.WORKSPACE); - } - - const legacyPartState = this.memento[LEGACY_EDITOR_PART_UI_STATE_STORAGE_KEY] as ILegacyEditorPartUIState; - if (legacyPartState) { - delete this.memento[LEGACY_EDITOR_PART_UI_STATE_STORAGE_KEY]; - } - - if (legacyUIState && Array.isArray(legacyUIState.groups) && legacyUIState.groups.length > 0) { - const splitHorizontally = legacyPartState && legacyPartState.groupOrientation === 'horizontal'; - - const legacyState: IEditorPartUIState = Object.create(null); - - const positionOneGroup = legacyUIState.groups[0]; - const positionTwoGroup = legacyUIState.groups[1]; - const positionThreeGroup = legacyUIState.groups[2]; - - legacyState.activeGroup = legacyUIState.active; - legacyState.mostRecentActiveGroups = [legacyUIState.active]; - - if (positionTwoGroup || positionThreeGroup) { - if (!positionThreeGroup) { - legacyState.mostRecentActiveGroups.push(legacyState.activeGroup === 0 ? 1 : 0); - } else { - if (legacyState.activeGroup === 0) { - legacyState.mostRecentActiveGroups.push(1, 2); - } else if (legacyState.activeGroup === 1) { - legacyState.mostRecentActiveGroups.push(0, 2); - } else { - legacyState.mostRecentActiveGroups.push(0, 1); - } - } - } - - const toNode = function (group: ISerializedEditorGroup, size: number): ISerializedNode { - return { - data: group, - size, - type: 'leaf' - }; - }; - - const baseSize = 1200; // just some number because layout() was not called yet, but we only need the proportions - - // No split editor - if (!positionTwoGroup) { - legacyState.serializedGrid = { - width: baseSize, - height: baseSize, - orientation: splitHorizontally ? Orientation.VERTICAL : Orientation.HORIZONTAL, - root: toNode(positionOneGroup, baseSize) - }; - } - - // Split editor (2 or 3 columns) - else { - const children: ISerializedNode[] = []; - - const size = positionThreeGroup ? baseSize / 3 : baseSize / 2; - - children.push(toNode(positionOneGroup, size)); - children.push(toNode(positionTwoGroup, size)); - - if (positionThreeGroup) { - children.push(toNode(positionThreeGroup, size)); - } - - legacyState.serializedGrid = { - width: baseSize, - height: baseSize, - orientation: splitHorizontally ? Orientation.VERTICAL : Orientation.HORIZONTAL, - root: { - data: children, - size: baseSize, - type: 'branch' - } - }; - } - - return legacyState; - } - - return void 0; - } - private updateContainer(): void { toggleClass(this.container, 'empty', this.isEmpty()); } diff --git a/src/vs/workbench/common/theme.ts b/src/vs/workbench/common/theme.ts index 8dfe3cd10c7..8dbf7693c79 100644 --- a/src/vs/workbench/common/theme.ts +++ b/src/vs/workbench/common/theme.ts @@ -117,6 +117,12 @@ export const TAB_UNFOCUSED_INACTIVE_FOREGROUND = registerColor('tab.unfocusedIna // < --- Editors --- > +export const EDITOR_PANE_BACKGROUND = registerColor('editorPane.background', { + dark: editorBackground, + light: editorBackground, + hc: editorBackground +}, nls.localize('editorPaneBackground', "Background color of the editor pane visible on the left and right side of the centered editor layout.")); + registerColor('editorGroup.background', { dark: null, light: null, From fdb7b4bcf4adf65e819beddd7738c8224b8f6449 Mon Sep 17 00:00:00 2001 From: Johannes Rieken Date: Wed, 8 Aug 2018 16:53:55 +0200 Subject: [PATCH 0585/1276] invoke webpack when bundling extensions --- build/lib/extensions.js | 37 +- build/lib/extensions.ts | 59 +- extensions/git/.vscodeignore | 5 +- ....config.js => extension.webpack.config.js} | 14 +- extensions/git/package.json | 2 +- extensions/git/yarn.lock | 8 +- package.json | 5 +- yarn.lock | 1942 ++++++++++++++++- 8 files changed, 1993 insertions(+), 79 deletions(-) rename extensions/git/{webpack.config.js => extension.webpack.config.js} (72%) diff --git a/build/lib/extensions.js b/build/lib/extensions.js index ce74ac25ee6..e923869d6d9 100644 --- a/build/lib/extensions.js +++ b/build/lib/extensions.js @@ -14,14 +14,15 @@ var rename = require('gulp-rename'); var util = require('gulp-util'); var buffer = require('gulp-buffer'); var json = require('gulp-json-editor'); +var webpack = require('webpack'); +var webpackGulp = require('webpack-stream'); var fs = require("fs"); var path = require("path"); var vsce = require("vsce"); var File = require("vinyl"); function fromLocal(extensionPath) { var result = es.through(); - vsce.listFiles({ cwd: extensionPath, packageManager: vsce.PackageManager.Yarn }) - .then(function (fileNames) { + vsce.listFiles({ cwd: extensionPath, packageManager: vsce.PackageManager.Yarn }).then(function (fileNames) { var files = fileNames .map(function (fileName) { return path.join(extensionPath, fileName); }) .map(function (filePath) { return new File({ @@ -30,9 +31,35 @@ function fromLocal(extensionPath) { base: extensionPath, contents: fs.createReadStream(filePath) }); }); - es.readArray(files).pipe(result); - }) - .catch(function (err) { return result.emit('error', err); }); + var filesStream = es.readArray(files); + // check for a webpack configuration file, then invoke webpack + // and merge its output with the files stream. also rewrite the package.json + // file to a new entry point + if (fs.existsSync(path.join(extensionPath, 'extension.webpack.config.js'))) { + var packageJsonFilter = filter('package.json', { restore: true }); + var patchFilesStream = filesStream + .pipe(packageJsonFilter) + .pipe(buffer()) + .pipe(json({ main: './dist/main.bundle' })) // hardcoded entry point! + .pipe(packageJsonFilter.restore); + var webpackConfig = require(path.join(extensionPath, 'extension.webpack.config.js')); + var webpackStream = webpackGulp(webpackConfig, webpack) + .pipe(es.through(function (data) { + data.base = extensionPath; + this.emit('data', data); + })); + es.merge(webpackStream, patchFilesStream) + // .pipe(es.through(function (data) { + // // debug + // console.log('out', data.path, data.base, data.contents.length); + // this.emit('data', data); + // })) + .pipe(result); + } + else { + filesStream.pipe(result); + } + }).catch(function (err) { return result.emit('error', err); }); return result; } exports.fromLocal = fromLocal; diff --git a/build/lib/extensions.ts b/build/lib/extensions.ts index 4b05bea1979..500d57517d3 100644 --- a/build/lib/extensions.ts +++ b/build/lib/extensions.ts @@ -14,28 +14,61 @@ const rename = require('gulp-rename'); const util = require('gulp-util'); const buffer = require('gulp-buffer'); const json = require('gulp-json-editor'); +const webpack = require('webpack'); +const webpackGulp = require('webpack-stream'); import * as fs from 'fs'; import * as path from 'path'; import * as vsce from 'vsce'; import * as File from 'vinyl'; +import { rebase } from './util'; export function fromLocal(extensionPath: string): Stream { - const result = es.through(); + let result = es.through(); - vsce.listFiles({ cwd: extensionPath, packageManager: vsce.PackageManager.Yarn }) - .then(fileNames => { - const files = fileNames - .map(fileName => path.join(extensionPath, fileName)) - .map(filePath => new File({ - path: filePath, - stat: fs.statSync(filePath), - base: extensionPath, - contents: fs.createReadStream(filePath) as any + vsce.listFiles({ cwd: extensionPath, packageManager: vsce.PackageManager.Yarn }).then(fileNames => { + const files = fileNames + .map(fileName => path.join(extensionPath, fileName)) + .map(filePath => new File({ + path: filePath, + stat: fs.statSync(filePath), + base: extensionPath, + contents: fs.createReadStream(filePath) as any + })); + + const filesStream = es.readArray(files); + + // check for a webpack configuration file, then invoke webpack + // and merge its output with the files stream. also rewrite the package.json + // file to a new entry point + if (fs.existsSync(path.join(extensionPath, 'extension.webpack.config.js'))) { + const packageJsonFilter = filter('package.json', { restore: true }); + + const patchFilesStream = filesStream + .pipe(packageJsonFilter) + .pipe(buffer()) + .pipe(json({ main: './dist/main.bundle' })) // hardcoded entry point! + .pipe(packageJsonFilter.restore); + + const webpackConfig = require(path.join(extensionPath, 'extension.webpack.config.js')); + const webpackStream = webpackGulp(webpackConfig, webpack) + .pipe(es.through(function (data) { + data.base = extensionPath; + this.emit('data', data); })); - es.readArray(files).pipe(result); - }) - .catch(err => result.emit('error', err)); + es.merge(webpackStream, patchFilesStream) + // .pipe(es.through(function (data) { + // // debug + // console.log('out', data.path, data.base, data.contents.length); + // this.emit('data', data); + // })) + .pipe(result); + + } else { + filesStream.pipe(result); + } + + }).catch(err => result.emit('error', err)); return result; } diff --git a/extensions/git/.vscodeignore b/extensions/git/.vscodeignore index 436567b7d69..1b352bc4ec1 100644 --- a/extensions/git/.vscodeignore +++ b/extensions/git/.vscodeignore @@ -1,5 +1,6 @@ src/** test/** -out/test/** +out/** tsconfig.json -build/** \ No newline at end of file +build/** +node_modules/** diff --git a/extensions/git/webpack.config.js b/extensions/git/extension.webpack.config.js similarity index 72% rename from extensions/git/webpack.config.js rename to extensions/git/extension.webpack.config.js index 175d663dd04..56b5787a7bd 100644 --- a/extensions/git/webpack.config.js +++ b/extensions/git/extension.webpack.config.js @@ -8,16 +8,20 @@ const path = require('path'); module.exports = { - mode: 'production', + mode: 'none', target: 'node', - entry: './out/main.js', + context: __dirname, + entry: { + main: './out/main.js', + askpass: './out/askpass-main.js' + }, output: { - filename: 'main.js', - path: path.resolve(__dirname, 'dist'), + filename: '[name].bundle.js', + path: path.join(__dirname, 'dist'), libraryTarget: "commonjs" }, externals: { 'vscode': 'commonjs vscode', }, - devtool: 'source-map' + stats: 'errors-only' }; diff --git a/extensions/git/package.json b/extensions/git/package.json index 6d03266a459..3d15e3cf968 100644 --- a/extensions/git/package.json +++ b/extensions/git/package.json @@ -15,7 +15,7 @@ "activationEvents": [ "*" ], - "main": "./dist/main", + "main": "./out/main", "icon": "resources/icons/git.png", "scripts": { "compile": "gulp compile-extension:git", diff --git a/extensions/git/yarn.lock b/extensions/git/yarn.lock index e66f5067101..0d0c3aff34b 100644 --- a/extensions/git/yarn.lock +++ b/extensions/git/yarn.lock @@ -1210,8 +1210,8 @@ ini@~1.3.0: resolved "https://registry.yarnpkg.com/ini/-/ini-1.3.5.tgz#eee25f56db1c9ec6085e0c22778083f596abf927" inquirer@^6.0.0: - version "6.0.0" - resolved "https://registry.yarnpkg.com/inquirer/-/inquirer-6.0.0.tgz#e8c20303ddc15bbfc2c12a6213710ccd9e1413d8" + version "6.1.0" + resolved "https://registry.yarnpkg.com/inquirer/-/inquirer-6.1.0.tgz#8f65c7b31c498285f4ddf3b742ad8c487892040b" dependencies: ansi-escapes "^3.0.0" chalk "^2.0.0" @@ -2174,8 +2174,8 @@ sax@^1.2.4: resolved "https://registry.yarnpkg.com/sax/-/sax-1.2.4.tgz#2816234e2378bddc4e5354fab5caa895df7100d9" schema-utils@^0.4.4, schema-utils@^0.4.5: - version "0.4.6" - resolved "https://registry.yarnpkg.com/schema-utils/-/schema-utils-0.4.6.tgz#dab4516a656310a964ca772bd3771819ba2b5cec" + version "0.4.7" + resolved "https://registry.yarnpkg.com/schema-utils/-/schema-utils-0.4.7.tgz#ba74f597d2be2ea880131746ee17d0a093c68187" dependencies: ajv "^6.1.0" ajv-keywords "^3.1.0" diff --git a/package.json b/package.json index 8042314a7e6..8696dbcaec8 100644 --- a/package.json +++ b/package.json @@ -123,7 +123,10 @@ "vinyl": "^0.4.5", "vinyl-fs": "^2.4.3", "vsce": "1.33.2", - "vscode-nls-dev": "3.0.7" + "vscode-nls-dev": "3.0.7", + "webpack": "^4.16.5", + "webpack-cli": "^3.1.0", + "webpack-stream": "^5.1.1" }, "repository": { "type": "git", diff --git a/yarn.lock b/yarn.lock index 6dcbc60e044..5174f81e1f4 100644 --- a/yarn.lock +++ b/yarn.lock @@ -43,6 +43,142 @@ version "1.16.34" resolved "https://registry.yarnpkg.com/@types/sinon/-/sinon-1.16.34.tgz#a9761fff33d0f7b3fe61875b577778a2576a9a03" +"@webassemblyjs/ast@1.5.13": + version "1.5.13" + resolved "https://registry.yarnpkg.com/@webassemblyjs/ast/-/ast-1.5.13.tgz#81155a570bd5803a30ec31436bc2c9c0ede38f25" + dependencies: + "@webassemblyjs/helper-module-context" "1.5.13" + "@webassemblyjs/helper-wasm-bytecode" "1.5.13" + "@webassemblyjs/wast-parser" "1.5.13" + debug "^3.1.0" + mamacro "^0.0.3" + +"@webassemblyjs/floating-point-hex-parser@1.5.13": + version "1.5.13" + resolved "https://registry.yarnpkg.com/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.5.13.tgz#29ce0baa97411f70e8cce68ce9c0f9d819a4e298" + +"@webassemblyjs/helper-api-error@1.5.13": + version "1.5.13" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-api-error/-/helper-api-error-1.5.13.tgz#e49b051d67ee19a56e29b9aa8bd949b5b4442a59" + +"@webassemblyjs/helper-buffer@1.5.13": + version "1.5.13" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-buffer/-/helper-buffer-1.5.13.tgz#873bb0a1b46449231137c1262ddfd05695195a1e" + dependencies: + debug "^3.1.0" + +"@webassemblyjs/helper-code-frame@1.5.13": + version "1.5.13" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-code-frame/-/helper-code-frame-1.5.13.tgz#1bd2181b6a0be14e004f0fe9f5a660d265362b58" + dependencies: + "@webassemblyjs/wast-printer" "1.5.13" + +"@webassemblyjs/helper-fsm@1.5.13": + version "1.5.13" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-fsm/-/helper-fsm-1.5.13.tgz#cdf3d9d33005d543a5c5e5adaabf679ffa8db924" + +"@webassemblyjs/helper-module-context@1.5.13": + version "1.5.13" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-module-context/-/helper-module-context-1.5.13.tgz#dc29ddfb51ed657655286f94a5d72d8a489147c5" + dependencies: + debug "^3.1.0" + mamacro "^0.0.3" + +"@webassemblyjs/helper-wasm-bytecode@1.5.13": + version "1.5.13" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.5.13.tgz#03245817f0a762382e61733146f5773def15a747" + +"@webassemblyjs/helper-wasm-section@1.5.13": + version "1.5.13" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.5.13.tgz#efc76f44a10d3073b584b43c38a179df173d5c7d" + dependencies: + "@webassemblyjs/ast" "1.5.13" + "@webassemblyjs/helper-buffer" "1.5.13" + "@webassemblyjs/helper-wasm-bytecode" "1.5.13" + "@webassemblyjs/wasm-gen" "1.5.13" + debug "^3.1.0" + +"@webassemblyjs/ieee754@1.5.13": + version "1.5.13" + resolved "https://registry.yarnpkg.com/@webassemblyjs/ieee754/-/ieee754-1.5.13.tgz#573e97c8c12e4eebb316ca5fde0203ddd90b0364" + dependencies: + ieee754 "^1.1.11" + +"@webassemblyjs/leb128@1.5.13": + version "1.5.13" + resolved "https://registry.yarnpkg.com/@webassemblyjs/leb128/-/leb128-1.5.13.tgz#ab52ebab9cec283c1c1897ac1da833a04a3f4cee" + dependencies: + long "4.0.0" + +"@webassemblyjs/utf8@1.5.13": + version "1.5.13" + resolved "https://registry.yarnpkg.com/@webassemblyjs/utf8/-/utf8-1.5.13.tgz#6b53d2cd861cf94fa99c1f12779dde692fbc2469" + +"@webassemblyjs/wasm-edit@1.5.13": + version "1.5.13" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-edit/-/wasm-edit-1.5.13.tgz#c9cef5664c245cf11b3b3a73110c9155831724a8" + dependencies: + "@webassemblyjs/ast" "1.5.13" + "@webassemblyjs/helper-buffer" "1.5.13" + "@webassemblyjs/helper-wasm-bytecode" "1.5.13" + "@webassemblyjs/helper-wasm-section" "1.5.13" + "@webassemblyjs/wasm-gen" "1.5.13" + "@webassemblyjs/wasm-opt" "1.5.13" + "@webassemblyjs/wasm-parser" "1.5.13" + "@webassemblyjs/wast-printer" "1.5.13" + debug "^3.1.0" + +"@webassemblyjs/wasm-gen@1.5.13": + version "1.5.13" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-gen/-/wasm-gen-1.5.13.tgz#8e6ea113c4b432fa66540189e79b16d7a140700e" + dependencies: + "@webassemblyjs/ast" "1.5.13" + "@webassemblyjs/helper-wasm-bytecode" "1.5.13" + "@webassemblyjs/ieee754" "1.5.13" + "@webassemblyjs/leb128" "1.5.13" + "@webassemblyjs/utf8" "1.5.13" + +"@webassemblyjs/wasm-opt@1.5.13": + version "1.5.13" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-opt/-/wasm-opt-1.5.13.tgz#147aad7717a7ee4211c36b21a5f4c30dddf33138" + dependencies: + "@webassemblyjs/ast" "1.5.13" + "@webassemblyjs/helper-buffer" "1.5.13" + "@webassemblyjs/wasm-gen" "1.5.13" + "@webassemblyjs/wasm-parser" "1.5.13" + debug "^3.1.0" + +"@webassemblyjs/wasm-parser@1.5.13": + version "1.5.13" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-parser/-/wasm-parser-1.5.13.tgz#6f46516c5bb23904fbdf58009233c2dd8a54c72f" + dependencies: + "@webassemblyjs/ast" "1.5.13" + "@webassemblyjs/helper-api-error" "1.5.13" + "@webassemblyjs/helper-wasm-bytecode" "1.5.13" + "@webassemblyjs/ieee754" "1.5.13" + "@webassemblyjs/leb128" "1.5.13" + "@webassemblyjs/utf8" "1.5.13" + +"@webassemblyjs/wast-parser@1.5.13": + version "1.5.13" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wast-parser/-/wast-parser-1.5.13.tgz#5727a705d397ae6a3ae99d7f5460acf2ec646eea" + dependencies: + "@webassemblyjs/ast" "1.5.13" + "@webassemblyjs/floating-point-hex-parser" "1.5.13" + "@webassemblyjs/helper-api-error" "1.5.13" + "@webassemblyjs/helper-code-frame" "1.5.13" + "@webassemblyjs/helper-fsm" "1.5.13" + long "^3.2.0" + mamacro "^0.0.3" + +"@webassemblyjs/wast-printer@1.5.13": + version "1.5.13" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wast-printer/-/wast-printer-1.5.13.tgz#bb34d528c14b4f579e7ec11e793ec50ad7cd7c95" + dependencies: + "@webassemblyjs/ast" "1.5.13" + "@webassemblyjs/wast-parser" "1.5.13" + long "^3.2.0" + abbrev@1: version "1.1.1" resolved "https://registry.yarnpkg.com/abbrev/-/abbrev-1.1.1.tgz#f8f2c887ad10bf67f634f005b6987fed3179aac8" @@ -58,6 +194,12 @@ accepts@~1.3.4: mime-types "~2.1.16" negotiator "0.6.1" +acorn-dynamic-import@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/acorn-dynamic-import/-/acorn-dynamic-import-3.0.0.tgz#901ceee4c7faaef7e07ad2a47e890675da50a278" + dependencies: + acorn "^5.0.0" + acorn-jsx@^3.0.0: version "3.0.1" resolved "https://registry.yarnpkg.com/acorn-jsx/-/acorn-jsx-3.0.1.tgz#afdf9488fb1ecefc8348f6fb22f464e32a58b36b" @@ -72,6 +214,10 @@ acorn@^3.0.4: version "3.3.0" resolved "https://registry.yarnpkg.com/acorn/-/acorn-3.3.0.tgz#45e37fb39e8da3f25baee3ff5369e2bb5f22017a" +acorn@^5.0.0, acorn@^5.6.2: + version "5.7.1" + resolved "https://registry.yarnpkg.com/acorn/-/acorn-5.7.1.tgz#f095829297706a7c9776958c0afc8930a9b9d9d8" + acorn@^5.2.1: version "5.2.1" resolved "https://registry.yarnpkg.com/acorn/-/acorn-5.2.1.tgz#317ac7821826c22c702d66189ab8359675f135d7" @@ -86,6 +232,10 @@ ajv-keywords@^1.0.0: version "1.5.1" resolved "https://registry.yarnpkg.com/ajv-keywords/-/ajv-keywords-1.5.1.tgz#314dd0a4b3368fad3dfcdc54ede6171b886daf3c" +ajv-keywords@^3.1.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/ajv-keywords/-/ajv-keywords-3.2.0.tgz#e86b819c602cf8821ad637413698f1dec021847a" + ajv@^4.7.0, ajv@^4.9.1: version "4.11.8" resolved "https://registry.yarnpkg.com/ajv/-/ajv-4.11.8.tgz#82ffb02b29e662ae53bdc20af15947706739c536" @@ -102,6 +252,15 @@ ajv@^5.1.0: fast-json-stable-stringify "^2.0.0" json-schema-traverse "^0.3.0" +ajv@^6.1.0: + version "6.5.2" + resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.5.2.tgz#678495f9b82f7cca6be248dd92f59bff5e1f4360" + dependencies: + fast-deep-equal "^2.0.1" + fast-json-stable-stringify "^2.0.0" + json-schema-traverse "^0.4.1" + uri-js "^4.2.1" + align-text@^0.1.1, align-text@^0.1.3: version "0.1.4" resolved "https://registry.yarnpkg.com/align-text/-/align-text-0.1.4.tgz#0cd90a561093f35d0a99256c22b7069433fad117" @@ -122,6 +281,12 @@ amdefine@>=0.0.4: version "1.0.1" resolved "https://registry.yarnpkg.com/amdefine/-/amdefine-1.0.1.tgz#4a5282ac164729e93619bcfd3ad151f817ce91f5" +ansi-colors@^1.0.1: + version "1.1.0" + resolved "https://registry.yarnpkg.com/ansi-colors/-/ansi-colors-1.1.0.tgz#6374b4dd5d4718ff3ce27a671a3b1cad077132a9" + dependencies: + ansi-wrap "^0.1.0" + ansi-cyan@^0.1.1: version "0.1.1" resolved "https://registry.yarnpkg.com/ansi-cyan/-/ansi-cyan-0.1.1.tgz#538ae528af8982f28ae30d86f2f17456d2609873" @@ -132,6 +297,10 @@ ansi-escapes@^1.1.0: version "1.4.0" resolved "https://registry.yarnpkg.com/ansi-escapes/-/ansi-escapes-1.4.0.tgz#d3a8a83b319aa67793662b13e761c7911422306e" +ansi-escapes@^3.0.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/ansi-escapes/-/ansi-escapes-3.1.0.tgz#f73207bb81207d75fd6c83f125af26eea378ca30" + ansi-gray@^0.1.1: version "0.1.1" resolved "https://registry.yarnpkg.com/ansi-gray/-/ansi-gray-0.1.1.tgz#2962cf54ec9792c48510a3deb524436861ef7251" @@ -170,7 +339,13 @@ ansi-styles@^3.1.0: dependencies: color-convert "^1.9.0" -ansi-wrap@0.1.0: +ansi-styles@^3.2.1: + version "3.2.1" + resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-3.2.1.tgz#41fbb20243e50b12be0f04b8dedbf07520ce841d" + dependencies: + color-convert "^1.9.0" + +ansi-wrap@0.1.0, ansi-wrap@^0.1.0: version "0.1.0" resolved "https://registry.yarnpkg.com/ansi-wrap/-/ansi-wrap-0.1.0.tgz#a82250ddb0015e9a27ca82e82ea603bbfa45efaf" @@ -181,11 +356,18 @@ anymatch@^1.3.0: micromatch "^2.1.5" normalize-path "^2.0.0" +anymatch@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-2.0.0.tgz#bcb24b4f37934d9aa7ac17b4adaf89e7c76ef2eb" + dependencies: + micromatch "^3.1.4" + normalize-path "^2.1.1" + applicationinsights@0.18.0: version "0.18.0" resolved "https://registry.yarnpkg.com/applicationinsights/-/applicationinsights-0.18.0.tgz#162ebb48a383408bc4de44db32b417307f45bbc1" -aproba@^1.0.3: +aproba@^1.0.3, aproba@^1.1.1: version "1.2.0" resolved "https://registry.yarnpkg.com/aproba/-/aproba-1.2.0.tgz#6802e6264efd18c790a1b0d517f0f2627bf2c94a" @@ -219,14 +401,26 @@ arr-diff@^2.0.0: dependencies: arr-flatten "^1.0.1" +arr-diff@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/arr-diff/-/arr-diff-4.0.0.tgz#d6461074febfec71e7e15235761a329a5dc7c520" + arr-flatten@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/arr-flatten/-/arr-flatten-1.0.1.tgz#e5ffe54d45e19f32f216e91eb99c8ce892bb604b" +arr-flatten@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/arr-flatten/-/arr-flatten-1.1.0.tgz#36048bbff4e7b47e136644316c99669ea5ae91f1" + arr-union@^2.0.1: version "2.1.0" resolved "https://registry.yarnpkg.com/arr-union/-/arr-union-2.1.0.tgz#20f9eab5ec70f5c7d215b1077b1c39161d292c7d" +arr-union@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/arr-union/-/arr-union-3.1.0.tgz#e39b09aea9def866a8f206e288af63919bae39c4" + array-differ@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/array-differ/-/array-differ-1.0.0.tgz#eff52e3758249d33be402b8bb8e564bb2b5d4031" @@ -273,6 +467,10 @@ array-unique@^0.2.1: version "0.2.1" resolved "https://registry.yarnpkg.com/array-unique/-/array-unique-0.2.1.tgz#a1d97ccafcbc2625cc70fadceb36a50c58b01a53" +array-unique@^0.3.2: + version "0.3.2" + resolved "https://registry.yarnpkg.com/array-unique/-/array-unique-0.3.2.tgz#a894b75d4bc4f6cd679ef3244a9fd8f46ae2d428" + arrify@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/arrify/-/arrify-1.0.1.tgz#898508da2226f380df904728456849c1501a4b0d" @@ -294,6 +492,14 @@ asar@^0.14.0: mksnapshot "^0.3.0" tmp "0.0.28" +asn1.js@^4.0.0: + version "4.10.1" + resolved "https://registry.yarnpkg.com/asn1.js/-/asn1.js-4.10.1.tgz#b9c2bf5805f1e64aadeed6df3a2bfafb5a73f5a0" + dependencies: + bn.js "^4.0.0" + inherits "^2.0.1" + minimalistic-assert "^1.0.0" + asn1@~0.2.3: version "0.2.3" resolved "https://registry.yarnpkg.com/asn1/-/asn1-0.2.3.tgz#dac8787713c9966849fc8180777ebe9c1ddf3b86" @@ -306,6 +512,16 @@ assert-plus@^0.2.0: version "0.2.0" resolved "https://registry.yarnpkg.com/assert-plus/-/assert-plus-0.2.0.tgz#d74e1b87e7affc0db8aadb7021f3fe48101ab234" +assert@^1.1.1: + version "1.4.1" + resolved "https://registry.yarnpkg.com/assert/-/assert-1.4.1.tgz#99912d591836b5a6f5b345c0f07eefc08fc65d91" + dependencies: + util "0.10.3" + +assign-symbols@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/assign-symbols/-/assign-symbols-1.0.0.tgz#59667f41fadd4f20ccbc2bb96b8d4f7f78ec0367" + async-each@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/async-each/-/async-each-1.0.1.tgz#19d386a1d9edc6e7c1c85d388aedbcc56d33602d" @@ -332,6 +548,10 @@ asynckit@^0.4.0: version "0.4.0" resolved "https://registry.yarnpkg.com/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79" +atob@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/atob/-/atob-2.1.1.tgz#ae2d5a729477f289d60dd7f96a6314a22dd6c22a" + atob@~1.1.0: version "1.1.3" resolved "https://registry.yarnpkg.com/atob/-/atob-1.1.3.tgz#95f13629b12c3a51a5d215abdce2aa9f32f80773" @@ -394,6 +614,22 @@ base64-js@0.0.8: version "0.0.8" resolved "https://registry.yarnpkg.com/base64-js/-/base64-js-0.0.8.tgz#1101e9544f4a76b1bc3b26d452ca96d7a35e7978" +base64-js@^1.0.2: + version "1.3.0" + resolved "https://registry.yarnpkg.com/base64-js/-/base64-js-1.3.0.tgz#cab1e6118f051095e58b5281aea8c1cd22bfc0e3" + +base@^0.11.1: + version "0.11.2" + resolved "https://registry.yarnpkg.com/base/-/base-0.11.2.tgz#7bde5ced145b6d551a90db87f83c558b4eb48a8f" + dependencies: + cache-base "^1.0.1" + class-utils "^0.3.5" + component-emitter "^1.2.1" + define-property "^1.0.0" + isobject "^3.0.1" + mixin-deep "^1.2.0" + pascalcase "^0.1.1" + bcrypt-pbkdf@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.1.tgz#63bc5dcb61331b92bc05fd528953c33462a06f8d" @@ -408,6 +644,10 @@ big-integer@^1.6.25: version "1.6.25" resolved "https://registry.yarnpkg.com/big-integer/-/big-integer-1.6.25.tgz#1de45a9f57542ac20121c682f8d642220a34e823" +big.js@^3.1.3: + version "3.2.0" + resolved "https://registry.yarnpkg.com/big.js/-/big.js-3.2.0.tgz#a5fc298b81b9e0dca2e458824784b65c52ba588e" + binary-extensions@^1.0.0: version "1.10.0" resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-1.10.0.tgz#9aeb9a6c5e88638aad171e167f5900abe24835d0" @@ -444,6 +684,14 @@ bl@~1.1.2: dependencies: readable-stream "~2.0.5" +bluebird@^3.5.1: + version "3.5.1" + resolved "https://registry.yarnpkg.com/bluebird/-/bluebird-3.5.1.tgz#d9551f9de98f1fcda1e683d17ee91a0602ee2eb9" + +bn.js@^4.0.0, bn.js@^4.1.0, bn.js@^4.1.1, bn.js@^4.4.0: + version "4.11.8" + resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-4.11.8.tgz#2cde09eb5ee341f484746bb0309b3253b1b1442f" + body-parser@1.18.2: version "1.18.2" resolved "https://registry.yarnpkg.com/body-parser/-/body-parser-1.18.2.tgz#87678a19d84b47d859b83199bd59bce222b10454" @@ -496,14 +744,86 @@ braces@^1.8.2: preserve "^0.2.0" repeat-element "^1.1.2" +braces@^2.3.0, braces@^2.3.1: + version "2.3.2" + resolved "https://registry.yarnpkg.com/braces/-/braces-2.3.2.tgz#5979fd3f14cd531565e5fa2df1abfff1dfaee729" + dependencies: + arr-flatten "^1.1.0" + array-unique "^0.3.2" + extend-shallow "^2.0.1" + fill-range "^4.0.0" + isobject "^3.0.1" + repeat-element "^1.1.2" + snapdragon "^0.8.1" + snapdragon-node "^2.0.1" + split-string "^3.0.2" + to-regex "^3.0.1" + +brorand@^1.0.1: + version "1.1.0" + resolved "https://registry.yarnpkg.com/brorand/-/brorand-1.1.0.tgz#12c25efe40a45e3c323eb8675a0a0ce57b22371f" + "browser-request@>= 0.3.1 < 0.4.0": version "0.3.3" resolved "https://registry.yarnpkg.com/browser-request/-/browser-request-0.3.3.tgz#9ece5b5aca89a29932242e18bf933def9876cc17" +browserify-aes@^1.0.0, browserify-aes@^1.0.4: + version "1.2.0" + resolved "https://registry.yarnpkg.com/browserify-aes/-/browserify-aes-1.2.0.tgz#326734642f403dabc3003209853bb70ad428ef48" + dependencies: + buffer-xor "^1.0.3" + cipher-base "^1.0.0" + create-hash "^1.1.0" + evp_bytestokey "^1.0.3" + inherits "^2.0.1" + safe-buffer "^5.0.1" + +browserify-cipher@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/browserify-cipher/-/browserify-cipher-1.0.1.tgz#8d6474c1b870bfdabcd3bcfcc1934a10e94f15f0" + dependencies: + browserify-aes "^1.0.4" + browserify-des "^1.0.0" + evp_bytestokey "^1.0.0" + +browserify-des@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/browserify-des/-/browserify-des-1.0.2.tgz#3af4f1f59839403572f1c66204375f7a7f703e9c" + dependencies: + cipher-base "^1.0.1" + des.js "^1.0.0" + inherits "^2.0.1" + safe-buffer "^5.1.2" + browserify-mime@~1.2.9: version "1.2.9" resolved "https://registry.yarnpkg.com/browserify-mime/-/browserify-mime-1.2.9.tgz#aeb1af28de6c0d7a6a2ce40adb68ff18422af31f" +browserify-rsa@^4.0.0: + version "4.0.1" + resolved "https://registry.yarnpkg.com/browserify-rsa/-/browserify-rsa-4.0.1.tgz#21e0abfaf6f2029cf2fafb133567a701d4135524" + dependencies: + bn.js "^4.1.0" + randombytes "^2.0.1" + +browserify-sign@^4.0.0: + version "4.0.4" + resolved "https://registry.yarnpkg.com/browserify-sign/-/browserify-sign-4.0.4.tgz#aa4eb68e5d7b658baa6bf6a57e630cbd7a93d298" + dependencies: + bn.js "^4.1.1" + browserify-rsa "^4.0.0" + create-hash "^1.1.0" + create-hmac "^1.1.2" + elliptic "^6.0.0" + inherits "^2.0.1" + parse-asn1 "^5.0.0" + +browserify-zlib@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/browserify-zlib/-/browserify-zlib-0.2.0.tgz#2869459d9aa3be245fe8fe2ca1f46e2e7f54d73f" + dependencies: + pako "~1.0.5" + browserslist@^1.3.6, browserslist@^1.5.2, browserslist@^1.7.6: version "1.7.7" resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-1.7.7.tgz#0bd76704258be829b2398bb50e4b62d1a166b0b9" @@ -530,6 +850,22 @@ buffer-fill@^0.1.0: version "0.1.1" resolved "https://registry.yarnpkg.com/buffer-fill/-/buffer-fill-0.1.1.tgz#76d825c4d6e50e06b7a31eb520c04d08cc235071" +buffer-from@^1.0.0: + version "1.1.1" + resolved "https://registry.yarnpkg.com/buffer-from/-/buffer-from-1.1.1.tgz#32713bc028f75c02fdb710d7c7bcec1f2c6070ef" + +buffer-xor@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/buffer-xor/-/buffer-xor-1.0.3.tgz#26e61ed1422fb70dd42e6e36729ed51d855fe8d9" + +buffer@^4.3.0: + version "4.9.1" + resolved "https://registry.yarnpkg.com/buffer/-/buffer-4.9.1.tgz#6d1bb601b07a4efced97094132093027c95bc298" + dependencies: + base64-js "^1.0.2" + ieee754 "^1.1.4" + isarray "^1.0.0" + buffers@~0.1.1: version "0.1.1" resolved "https://registry.yarnpkg.com/buffers/-/buffers-0.1.1.tgz#b24579c3bed4d6d396aeee6d9a8ae7f5482ab7bb" @@ -544,10 +880,46 @@ builtin-modules@^1.0.0, builtin-modules@^1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/builtin-modules/-/builtin-modules-1.1.1.tgz#270f076c5a72c02f5b65a47df94c5fe3a278892f" +builtin-status-codes@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/builtin-status-codes/-/builtin-status-codes-3.0.0.tgz#85982878e21b98e1c66425e03d0174788f569ee8" + bytes@3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/bytes/-/bytes-3.0.0.tgz#d32815404d689699f85a4ea4fa8755dd13a96048" +cacache@^10.0.4: + version "10.0.4" + resolved "https://registry.yarnpkg.com/cacache/-/cacache-10.0.4.tgz#6452367999eff9d4188aefd9a14e9d7c6a263460" + dependencies: + bluebird "^3.5.1" + chownr "^1.0.1" + glob "^7.1.2" + graceful-fs "^4.1.11" + lru-cache "^4.1.1" + mississippi "^2.0.0" + mkdirp "^0.5.1" + move-concurrently "^1.0.1" + promise-inflight "^1.0.1" + rimraf "^2.6.2" + ssri "^5.2.4" + unique-filename "^1.1.0" + y18n "^4.0.0" + +cache-base@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/cache-base/-/cache-base-1.0.1.tgz#0a7f46416831c8b662ee36fe4e7c59d76f666ab2" + dependencies: + collection-visit "^1.0.0" + component-emitter "^1.2.1" + get-value "^2.0.6" + has-value "^1.0.0" + isobject "^3.0.1" + set-value "^2.0.0" + to-object-path "^0.3.0" + union-value "^1.0.0" + unset-value "^1.0.0" + caller-path@^0.1.0: version "0.1.0" resolved "https://registry.yarnpkg.com/caller-path/-/caller-path-0.1.0.tgz#94085ef63581ecd3daa92444a8fe94e82577751f" @@ -631,6 +1003,14 @@ chalk@^1.0.0, chalk@^1.1.1, chalk@^1.1.3: strip-ansi "^3.0.0" supports-color "^2.0.0" +chalk@^2.0.0, chalk@^2.4.1: + version "2.4.1" + resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.1.tgz#18c49ab16a037b6eb0152cc83e3471338215b66e" + dependencies: + ansi-styles "^3.2.1" + escape-string-regexp "^1.0.5" + supports-color "^5.3.0" + chalk@^2.3.0: version "2.3.0" resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.3.0.tgz#b5ea48efc9c1793dccc9b4767c93914d3f2d52ba" @@ -639,6 +1019,10 @@ chalk@^2.3.0: escape-string-regexp "^1.0.5" supports-color "^4.0.0" +chardet@^0.5.0: + version "0.5.0" + resolved "https://registry.yarnpkg.com/chardet/-/chardet-0.5.0.tgz#fe3ac73c00c3d865ffcc02a0682e2c20b6a06029" + charenc@~0.0.1: version "0.0.2" resolved "https://registry.yarnpkg.com/charenc/-/charenc-0.0.2.tgz#c0a1d2f3a7092e03774bfa83f14c0fc5790a8667" @@ -654,6 +1038,25 @@ cheerio@^1.0.0-rc.1: lodash "^4.15.0" parse5 "^3.0.1" +chokidar@^2.0.2: + version "2.0.4" + resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-2.0.4.tgz#356ff4e2b0e8e43e322d18a372460bbcf3accd26" + dependencies: + anymatch "^2.0.0" + async-each "^1.0.0" + braces "^2.3.0" + glob-parent "^3.1.0" + inherits "^2.0.1" + is-binary-path "^1.0.0" + is-glob "^4.0.0" + lodash.debounce "^4.0.8" + normalize-path "^2.1.1" + path-is-absolute "^1.0.0" + readdirp "^2.0.0" + upath "^1.0.5" + optionalDependencies: + fsevents "^1.2.2" + chownr@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/chownr/-/chownr-1.0.1.tgz#e2a75042a9551908bebd25b8523d5f9769d79181" @@ -665,6 +1068,12 @@ chrome-remote-interface@^0.25.3: commander "2.11.x" ws "3.3.x" +chrome-trace-event@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/chrome-trace-event/-/chrome-trace-event-1.0.0.tgz#45a91bd2c20c9411f0963b5aaeb9a1b95e09cc48" + dependencies: + tslib "^1.9.0" + chromium-pickle-js@^0.2.0: version "0.2.0" resolved "https://registry.yarnpkg.com/chromium-pickle-js/-/chromium-pickle-js-0.2.0.tgz#04a106672c18b085ab774d983dfa3ea138f22205" @@ -673,6 +1082,13 @@ ci-info@^1.0.0: version "1.1.1" resolved "https://registry.yarnpkg.com/ci-info/-/ci-info-1.1.1.tgz#47b44df118c48d2597b56d342e7e25791060171a" +cipher-base@^1.0.0, cipher-base@^1.0.1, cipher-base@^1.0.3: + version "1.0.4" + resolved "https://registry.yarnpkg.com/cipher-base/-/cipher-base-1.0.4.tgz#8760e4ecc272f4c363532f926d874aae2c1397de" + dependencies: + inherits "^2.0.1" + safe-buffer "^5.0.1" + circular-json@^0.3.1: version "0.3.3" resolved "https://registry.yarnpkg.com/circular-json/-/circular-json-0.3.3.tgz#815c99ea84f6809529d2f45791bdf82711352d66" @@ -683,6 +1099,15 @@ clap@^1.0.9: dependencies: chalk "^1.1.3" +class-utils@^0.3.5: + version "0.3.6" + resolved "https://registry.yarnpkg.com/class-utils/-/class-utils-0.3.6.tgz#f93369ae8b9a7ce02fd41faad0ca83033190c463" + dependencies: + arr-union "^3.1.0" + define-property "^0.2.5" + isobject "^3.0.0" + static-extend "^0.1.1" + clean-css@3.4.6: version "3.4.6" resolved "https://registry.yarnpkg.com/clean-css/-/clean-css-3.4.6.tgz#fcb4f17057ddb7f8721616f70b07b294d95ffc45" @@ -696,6 +1121,12 @@ cli-cursor@^1.0.1: 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" + dependencies: + restore-cursor "^2.0.0" + cli-width@^2.0.0: version "2.2.0" resolved "https://registry.yarnpkg.com/cli-width/-/cli-width-2.2.0.tgz#ff19ede8a9a5e579324147b0c11f0fbcbabed639" @@ -766,6 +1197,13 @@ coffee-script@^1.10.0: version "1.12.7" resolved "https://registry.yarnpkg.com/coffee-script/-/coffee-script-1.12.7.tgz#c05dae0cb79591d05b3070a8433a98c9a89ccc53" +collection-visit@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/collection-visit/-/collection-visit-1.0.0.tgz#4bc0373c164bc3291b4d368c829cf1a80a59dca0" + dependencies: + map-visit "^1.0.0" + object-visit "^1.0.0" + color-convert@^1.3.0, color-convert@^1.9.0: version "1.9.1" resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-1.9.1.tgz#c1261107aeb2f294ebffec9ed9ecad529a6097ed" @@ -838,7 +1276,7 @@ commander@2.8.x: dependencies: graceful-readlink ">= 1.0.0" -commander@^2.12.1: +commander@^2.12.1, commander@~2.13.0: version "2.13.0" resolved "https://registry.yarnpkg.com/commander/-/commander-2.13.0.tgz#6964bca67685df7c1f1430c584f07d7597885b9c" @@ -846,6 +1284,14 @@ commandpost@^1.0.0: version "1.2.1" resolved "https://registry.yarnpkg.com/commandpost/-/commandpost-1.2.1.tgz#2e9c4c7508b9dc704afefaa91cab92ee6054cc68" +commondir@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/commondir/-/commondir-1.0.1.tgz#ddd800da0c66127393cca5950ea968a3aaf1253b" + +component-emitter@^1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/component-emitter/-/component-emitter-1.2.1.tgz#137918d6d78283f7df7a6b7c5a63e140e69425e6" + concat-map@0.0.1: version "0.0.1" resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" @@ -858,6 +1304,15 @@ concat-stream@1.6.0, concat-stream@^1.5.2: readable-stream "^2.2.2" typedarray "^0.0.6" +concat-stream@^1.5.0: + version "1.6.2" + resolved "https://registry.yarnpkg.com/concat-stream/-/concat-stream-1.6.2.tgz#904bdf194cd3122fc675c77fc4ac3d4ff0fd1a34" + dependencies: + buffer-from "^1.0.0" + inherits "^2.0.3" + readable-stream "^2.2.2" + typedarray "^0.0.6" + concat-with-sourcemaps@^1.0.0: version "1.0.4" resolved "https://registry.yarnpkg.com/concat-with-sourcemaps/-/concat-with-sourcemaps-1.0.4.tgz#f55b3be2aeb47601b10a2d5259ccfb70fd2f1dd6" @@ -871,10 +1326,20 @@ config-chain@~1.1.5: ini "^1.3.4" proto-list "~1.2.1" +console-browserify@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/console-browserify/-/console-browserify-1.1.0.tgz#f0241c45730a9fc6323b206dbf38edc741d0bb10" + dependencies: + date-now "^0.1.4" + console-control-strings@^1.0.0, console-control-strings@~1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/console-control-strings/-/console-control-strings-1.1.0.tgz#3d7cf4464db6446ea644bf4b39507f9851008e8e" +constants-browserify@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/constants-browserify/-/constants-browserify-1.0.0.tgz#c20b96d8c617748aaf1c16021760cd27fcb8cb75" + content-disposition@0.5.2: version "0.5.2" resolved "https://registry.yarnpkg.com/content-disposition/-/content-disposition-0.5.2.tgz#0cf68bb9ddf5f2be7961c3a85178cb85dba78cb4" @@ -895,6 +1360,21 @@ cookie@0.3.1: version "0.3.1" resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.3.1.tgz#e7e0a1f9ef43b4c8ba925c5c5a96e806d16873bb" +copy-concurrently@^1.0.0: + version "1.0.5" + resolved "https://registry.yarnpkg.com/copy-concurrently/-/copy-concurrently-1.0.5.tgz#92297398cae34937fcafd6ec8139c18051f0b5e0" + dependencies: + aproba "^1.1.1" + fs-write-stream-atomic "^1.0.8" + iferr "^0.1.5" + mkdirp "^0.5.1" + rimraf "^2.5.4" + run-queue "^1.0.0" + +copy-descriptor@^0.1.0: + version "0.1.1" + resolved "https://registry.yarnpkg.com/copy-descriptor/-/copy-descriptor-0.1.1.tgz#676f6eb3c39997c2ee1ac3a924fd6124748f578d" + core-util-is@1.0.2, core-util-is@~1.0.0: version "1.0.2" resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7" @@ -909,6 +1389,34 @@ coveralls@^2.11.11: minimist "1.2.0" request "2.79.0" +create-ecdh@^4.0.0: + version "4.0.3" + resolved "https://registry.yarnpkg.com/create-ecdh/-/create-ecdh-4.0.3.tgz#c9111b6f33045c4697f144787f9254cdc77c45ff" + dependencies: + bn.js "^4.1.0" + elliptic "^6.0.0" + +create-hash@^1.1.0, create-hash@^1.1.2: + version "1.2.0" + resolved "https://registry.yarnpkg.com/create-hash/-/create-hash-1.2.0.tgz#889078af11a63756bcfb59bd221996be3a9ef196" + dependencies: + cipher-base "^1.0.1" + inherits "^2.0.1" + md5.js "^1.3.4" + ripemd160 "^2.0.1" + sha.js "^2.4.0" + +create-hmac@^1.1.0, create-hmac@^1.1.2, create-hmac@^1.1.4: + version "1.1.7" + resolved "https://registry.yarnpkg.com/create-hmac/-/create-hmac-1.1.7.tgz#69170c78b3ab957147b2b8b04572e47ead2243ff" + dependencies: + cipher-base "^1.0.3" + create-hash "^1.1.0" + inherits "^2.0.1" + ripemd160 "^2.0.0" + safe-buffer "^5.0.1" + sha.js "^2.4.8" + cross-spawn@^4.0.0: version "4.0.2" resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-4.0.2.tgz#7b9247621c23adfdd3856004a823cbe397424d41" @@ -924,6 +1432,16 @@ cross-spawn@^5.0.1: shebang-command "^1.2.0" which "^1.2.9" +cross-spawn@^6.0.5: + version "6.0.5" + resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-6.0.5.tgz#4a5ec7c64dfae22c3a14124dbacdee846d80cbc4" + dependencies: + nice-try "^1.0.4" + path-key "^2.0.1" + semver "^5.5.0" + shebang-command "^1.2.0" + which "^1.2.9" + crypt@~0.0.1: version "0.0.2" resolved "https://registry.yarnpkg.com/crypt/-/crypt-0.0.2.tgz#88d7ff7ec0dfb86f713dc87bbb42d044d3e6c41b" @@ -940,6 +1458,22 @@ cryptiles@3.x.x: dependencies: boom "5.x.x" +crypto-browserify@^3.11.0: + version "3.12.0" + resolved "https://registry.yarnpkg.com/crypto-browserify/-/crypto-browserify-3.12.0.tgz#396cf9f3137f03e4b8e532c58f698254e00f80ec" + dependencies: + browserify-cipher "^1.0.0" + browserify-sign "^4.0.0" + create-ecdh "^4.0.0" + create-hash "^1.1.0" + create-hmac "^1.1.0" + diffie-hellman "^5.0.0" + inherits "^2.0.1" + pbkdf2 "^3.0.3" + public-encrypt "^4.0.0" + randombytes "^2.0.0" + randomfill "^1.0.3" + cson-parser@^1.3.3: version "1.3.5" resolved "https://registry.yarnpkg.com/cson-parser/-/cson-parser-1.3.5.tgz#7ec675e039145533bf2a6a856073f1599d9c2d24" @@ -1036,6 +1570,10 @@ currently-unhandled@^0.4.1: dependencies: array-find-index "^1.0.1" +cyclist@~0.2.2: + version "0.2.2" + resolved "https://registry.yarnpkg.com/cyclist/-/cyclist-0.2.2.tgz#1b33792e11e914a2fd6d6ed6447464444e5fa640" + d@1: version "1.0.0" resolved "https://registry.yarnpkg.com/d/-/d-1.0.0.tgz#754bb5bfe55451da69a58b94d45f4c5b0462d58f" @@ -1048,6 +1586,10 @@ dashdash@^1.12.0: dependencies: assert-plus "^1.0.0" +date-now@^0.1.4: + version "0.1.4" + resolved "https://registry.yarnpkg.com/date-now/-/date-now-0.1.4.tgz#eaf439fd4d4848ad74e5cc7dbef200672b9e345b" + dateformat@^1.0.11, dateformat@^1.0.7-1.2.3: version "1.0.12" resolved "https://registry.yarnpkg.com/dateformat/-/dateformat-1.0.12.tgz#9f124b67594c937ff706932e4a642cca8dbbfee9" @@ -1077,7 +1619,7 @@ debug@2.2.0, debug@~2.2.0: dependencies: ms "0.7.1" -debug@2.6.9, debug@2.X, debug@^2.1.1, debug@^2.1.3, debug@^2.2.0: +debug@2.6.9, debug@2.X, debug@^2.1.1, 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" dependencies: @@ -1093,6 +1635,16 @@ decamelize@^1.0.0, decamelize@^1.1.1, decamelize@^1.1.2: version "1.2.0" resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-1.2.0.tgz#f6534d15148269b20352e7bee26f501f9a191290" +decamelize@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-2.0.0.tgz#656d7bbc8094c4c788ea53c5840908c9c7d063c7" + dependencies: + xregexp "4.0.0" + +decode-uri-component@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/decode-uri-component/-/decode-uri-component-0.2.0.tgz#eb3913333458775cb84cd1a1fae062106bb87545" + decompress-response@^3.3.0: version "3.3.0" resolved "https://registry.yarnpkg.com/decompress-response/-/decompress-response-3.3.0.tgz#80a4dd323748384bfa248083622aedec982adff3" @@ -1133,6 +1685,25 @@ defaults@^1.0.0: dependencies: clone "^1.0.2" +define-property@^0.2.5: + version "0.2.5" + resolved "https://registry.yarnpkg.com/define-property/-/define-property-0.2.5.tgz#c35b1ef918ec3c990f9a5bc57be04aacec5c8116" + dependencies: + is-descriptor "^0.1.0" + +define-property@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/define-property/-/define-property-1.0.0.tgz#769ebaaf3f4a63aad3af9e8d304c9bbe79bfb0e6" + dependencies: + is-descriptor "^1.0.0" + +define-property@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/define-property/-/define-property-2.0.2.tgz#d459689e8d654ba77e02a817f8710d702cb16e9d" + dependencies: + is-descriptor "^1.0.2" + isobject "^3.0.1" + defined@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/defined/-/defined-1.0.0.tgz#c98d9bcef75674188e110969151199e39b1fa693" @@ -1173,6 +1744,13 @@ deprecated@^0.0.1: version "0.0.1" resolved "https://registry.yarnpkg.com/deprecated/-/deprecated-0.0.1.tgz#f9c9af5464afa1e7a971458a8bdef2aa94d5bb19" +des.js@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/des.js/-/des.js-1.0.0.tgz#c074d2e2aa6a8a9a07dbd61f9a15c2cd83ec8ecc" + dependencies: + inherits "^2.0.1" + minimalistic-assert "^1.0.0" + destroy@~1.0.4: version "1.0.4" resolved "https://registry.yarnpkg.com/destroy/-/destroy-1.0.4.tgz#978857442c44749e4206613e37946205826abd80" @@ -1191,7 +1769,7 @@ detect-indent@^2.0.0: minimist "^1.1.0" repeating "^1.1.0" -detect-libc@^1.0.3: +detect-libc@^1.0.2, detect-libc@^1.0.3: version "1.0.3" resolved "https://registry.yarnpkg.com/detect-libc/-/detect-libc-1.0.3.tgz#fa137c4bd698edf55cd5cd02ac559f91a4c4ba9b" @@ -1207,6 +1785,14 @@ diff@^3.2.0: version "3.4.0" resolved "https://registry.yarnpkg.com/diff/-/diff-3.4.0.tgz#b1d85507daf3964828de54b37d0d73ba67dda56c" +diffie-hellman@^5.0.0: + version "5.0.3" + resolved "https://registry.yarnpkg.com/diffie-hellman/-/diffie-hellman-5.0.3.tgz#40e8ee98f55a2149607146921c63e1ae5f3d2875" + dependencies: + bn.js "^4.1.0" + miller-rabin "^4.0.0" + randombytes "^2.0.0" + doctrine@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/doctrine/-/doctrine-2.0.0.tgz#c73d8d2909d22291e1a007a395804da8b665fe63" @@ -1232,6 +1818,10 @@ dom-serializer@0, dom-serializer@~0.1.0: domelementtype "~1.1.1" entities "~1.1.1" +domain-browser@^1.1.1: + version "1.2.0" + resolved "https://registry.yarnpkg.com/domain-browser/-/domain-browser-1.2.0.tgz#3d31f50191a6749dd1375a7f522e823d42e54eda" + domelementtype@1, domelementtype@^1.3.0: version "1.3.0" resolved "https://registry.yarnpkg.com/domelementtype/-/domelementtype-1.3.0.tgz#b17aed82e8ab59e52dd9c19b1756e0fc187204c2" @@ -1279,6 +1869,15 @@ duplexify@^3.2.0: readable-stream "^2.0.0" stream-shift "^1.0.0" +duplexify@^3.4.2, duplexify@^3.6.0: + version "3.6.0" + resolved "https://registry.yarnpkg.com/duplexify/-/duplexify-3.6.0.tgz#592903f5d80b38d037220541264d69a198fb3410" + dependencies: + end-of-stream "^1.0.0" + inherits "^2.0.1" + readable-stream "^2.0.0" + stream-shift "^1.0.0" + eachr@^3.2.0: version "3.2.0" resolved "https://registry.yarnpkg.com/eachr/-/eachr-3.2.0.tgz#2c35e43ea086516f7997cf80b7aa64d55a4a4484" @@ -1336,6 +1935,22 @@ electron-to-chromium@^1.2.7: version "1.3.27" resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.27.tgz#78ecb8a399066187bb374eede35d9c70565a803d" +elliptic@^6.0.0: + version "6.4.0" + resolved "https://registry.yarnpkg.com/elliptic/-/elliptic-6.4.0.tgz#cac9af8762c85836187003c8dfe193e5e2eae5df" + dependencies: + bn.js "^4.4.0" + brorand "^1.0.1" + hash.js "^1.0.0" + hmac-drbg "^1.0.0" + inherits "^2.0.1" + minimalistic-assert "^1.0.0" + minimalistic-crypto-utils "^1.0.0" + +emojis-list@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/emojis-list/-/emojis-list-2.1.0.tgz#4daa4d9db00f9819880c79fa457ae5b09a1fd389" + encodeurl@~1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/encodeurl/-/encodeurl-1.0.1.tgz#79e3d58655346909fe6f0f45a5de68103b294d20" @@ -1352,6 +1967,14 @@ end-of-stream@~0.1.5: dependencies: once "~1.3.0" +enhanced-resolve@^4.0.0, enhanced-resolve@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/enhanced-resolve/-/enhanced-resolve-4.1.0.tgz#41c7e0bfdfe74ac1ffe1e57ad6a5c6c9f3742a7f" + dependencies: + graceful-fs "^4.1.2" + memory-fs "^0.4.0" + tapable "^1.0.0" + entities@^1.1.1, entities@~1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/entities/-/entities-1.1.1.tgz#6e5c2d0a5621b5dadaecef80b90edfb5cd7772f0" @@ -1360,6 +1983,12 @@ env-paths@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/env-paths/-/env-paths-1.0.0.tgz#4168133b42bb05c38a35b1ae4397c8298ab369e0" +errno@^0.1.3, errno@~0.1.7: + version "0.1.7" + resolved "https://registry.yarnpkg.com/errno/-/errno-0.1.7.tgz#4684d71779ad39af177e3f007996f7c67c852618" + dependencies: + prr "~1.0.1" + error-ex@^1.2.0: version "1.3.1" resolved "https://registry.yarnpkg.com/error-ex/-/error-ex-1.3.1.tgz#f855a86ce61adc4e8621c3cda21e7a7612c3a8dc" @@ -1471,6 +2100,13 @@ escope@^3.6.0: esrecurse "^4.1.0" estraverse "^4.1.1" +eslint-scope@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-4.0.0.tgz#50bf3071e9338bcdc43331794a0cb533f0136172" + dependencies: + esrecurse "^4.1.0" + estraverse "^4.1.1" + eslint@^3.0.0, eslint@^3.4.0: version "3.19.0" resolved "https://registry.yarnpkg.com/eslint/-/eslint-3.19.0.tgz#c8fc6201c7f40dd08941b87c085767386a679acc" @@ -1582,6 +2218,17 @@ event-stream@^3.1.7, event-stream@^3.3.1, event-stream@^3.3.4, event-stream@~3.3 stream-combiner "~0.0.4" through "~2.3.1" +events@^1.0.0: + version "1.1.1" + resolved "https://registry.yarnpkg.com/events/-/events-1.1.1.tgz#9ebdb7635ad099c70dcc4c2a1f5004288e8bd924" + +evp_bytestokey@^1.0.0, evp_bytestokey@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/evp_bytestokey/-/evp_bytestokey-1.0.3.tgz#7fcbdb198dc71959432efe13842684e0525acb02" + dependencies: + md5.js "^1.3.4" + safe-buffer "^5.1.1" + execa@^0.7.0: version "0.7.0" resolved "https://registry.yarnpkg.com/execa/-/execa-0.7.0.tgz#944becd34cc41ee32a63a9faf27ad5a65fc59777" @@ -1604,6 +2251,18 @@ expand-brackets@^0.1.4: dependencies: is-posix-bracket "^0.1.0" +expand-brackets@^2.1.4: + version "2.1.4" + resolved "https://registry.yarnpkg.com/expand-brackets/-/expand-brackets-2.1.4.tgz#b77735e315ce30f6b6eff0f83b04151a22449622" + dependencies: + debug "^2.3.3" + define-property "^0.2.5" + extend-shallow "^2.0.1" + posix-character-classes "^0.1.0" + regex-not "^1.0.0" + snapdragon "^0.8.1" + to-regex "^3.0.1" + expand-range@^1.8.1: version "1.8.2" resolved "https://registry.yarnpkg.com/expand-range/-/expand-range-1.8.2.tgz#a299effd335fe2721ebae8e257ec79644fc85337" @@ -1673,6 +2332,13 @@ extend-shallow@^2.0.1: dependencies: is-extendable "^0.1.0" +extend-shallow@^3.0.0, extend-shallow@^3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/extend-shallow/-/extend-shallow-3.0.2.tgz#26a71aaf073b39fb2127172746131c2704028db8" + dependencies: + assign-symbols "^1.0.0" + is-extendable "^1.0.1" + extend@^3.0.0, extend@~3.0.0, extend@~3.0.1: version "3.0.1" resolved "https://registry.yarnpkg.com/extend/-/extend-3.0.1.tgz#a755ea7bc1adfcc5a31ce7e762dbaadc5e636444" @@ -1681,12 +2347,33 @@ extend@~1.2.1: version "1.2.1" resolved "https://registry.yarnpkg.com/extend/-/extend-1.2.1.tgz#a0f5fd6cfc83a5fe49ef698d60ec8a624dd4576c" +external-editor@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/external-editor/-/external-editor-3.0.0.tgz#dc35c48c6f98a30ca27a20e9687d7f3c77704bb6" + dependencies: + chardet "^0.5.0" + iconv-lite "^0.4.22" + tmp "^0.0.33" + extglob@^0.3.1: version "0.3.2" resolved "https://registry.yarnpkg.com/extglob/-/extglob-0.3.2.tgz#2e18ff3d2f49ab2765cec9023f011daa8d8349a1" dependencies: is-extglob "^1.0.0" +extglob@^2.0.4: + version "2.0.4" + resolved "https://registry.yarnpkg.com/extglob/-/extglob-2.0.4.tgz#ad00fe4dc612a9232e8718711dc5cb5ab0285543" + dependencies: + array-unique "^0.3.2" + define-property "^1.0.0" + expand-brackets "^2.1.4" + extend-shallow "^2.0.1" + fragment-cache "^0.2.1" + regex-not "^1.0.0" + snapdragon "^0.8.1" + to-regex "^3.0.1" + extract-opts@^3.2.0: version "3.3.1" resolved "https://registry.yarnpkg.com/extract-opts/-/extract-opts-3.3.1.tgz#5abbedc98c0d5202e3278727f9192d7e086c6be1" @@ -1727,6 +2414,10 @@ fast-deep-equal@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-1.0.0.tgz#96256a3bc975595eb36d82e9929d060d893439ff" +fast-deep-equal@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-2.0.1.tgz#7b05218ddf9667bf7f370bf7fdb2cb15fdd0aa49" + fast-json-stable-stringify@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz#d5142c0caee6b1189f87d3a76111064f86c8bbf2" @@ -1756,6 +2447,12 @@ figures@^1.3.5: 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" + dependencies: + escape-string-regexp "^1.0.5" + file-entry-cache@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/file-entry-cache/-/file-entry-cache-2.0.0.tgz#c392990c3e684783d838b8c84a45d8a048458361" @@ -1784,6 +2481,15 @@ fill-range@^2.1.0: repeat-element "^1.1.2" repeat-string "^1.5.2" +fill-range@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-4.0.0.tgz#d544811d428f98eb06a63dc402d2403c328c38f7" + dependencies: + extend-shallow "^2.0.1" + is-number "^3.0.0" + repeat-string "^1.6.1" + to-regex-range "^2.1.0" + finalhandler@1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/finalhandler/-/finalhandler-1.1.0.tgz#ce0b6855b45853e791b2fcc680046d88253dd7f5" @@ -1796,6 +2502,14 @@ finalhandler@1.1.0: statuses "~1.3.1" unpipe "~1.0.0" +find-cache-dir@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/find-cache-dir/-/find-cache-dir-1.0.0.tgz#9288e3e9e3cc3748717d39eade17cf71fc30ee6f" + dependencies: + commondir "^1.0.1" + make-dir "^1.0.0" + pkg-dir "^2.0.0" + find-index@^0.1.1: version "0.1.1" resolved "https://registry.yarnpkg.com/find-index/-/find-index-0.1.1.tgz#675d358b2ca3892d795a1ab47232f8b6e2e0dde4" @@ -1817,6 +2531,12 @@ find-up@^2.1.0: dependencies: locate-path "^2.0.0" +find-up@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/find-up/-/find-up-3.0.0.tgz#49169f1d7993430646da61ecc5ae355c21c97b73" + dependencies: + locate-path "^3.0.0" + findup-sync@^0.4.2: version "0.4.3" resolved "https://registry.yarnpkg.com/findup-sync/-/findup-sync-0.4.3.tgz#40043929e7bc60adf0b7f4827c4c6e75a0deca12" @@ -1857,11 +2577,18 @@ flatten@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/flatten/-/flatten-1.0.2.tgz#dae46a9d78fbe25292258cc1e780a41d95c03782" +flush-write-stream@^1.0.0: + version "1.0.3" + resolved "https://registry.yarnpkg.com/flush-write-stream/-/flush-write-stream-1.0.3.tgz#c5d586ef38af6097650b49bc41b55fabb19f35bd" + dependencies: + inherits "^2.0.1" + readable-stream "^2.0.4" + for-in@^0.1.5: version "0.1.5" resolved "https://registry.yarnpkg.com/for-in/-/for-in-0.1.5.tgz#007374e2b6d5c67420a1479bdb75a04872b738c4" -for-in@^1.0.1: +for-in@^1.0.1, for-in@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/for-in/-/for-in-1.0.2.tgz#81068d295a8142ec0ac726c6e2200c30fb6d5e80" @@ -1915,10 +2642,23 @@ forwarded@~0.1.2: version "0.1.2" resolved "https://registry.yarnpkg.com/forwarded/-/forwarded-0.1.2.tgz#98c23dab1175657b8c0573e8ceccd91b0ff18c84" +fragment-cache@^0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/fragment-cache/-/fragment-cache-0.2.1.tgz#4290fad27f13e89be7f33799c6bc5a0abfff0d19" + dependencies: + map-cache "^0.2.2" + fresh@0.5.2: version "0.5.2" resolved "https://registry.yarnpkg.com/fresh/-/fresh-0.5.2.tgz#3d8cadd90d976569fa835ab1f8e4b23a105605a7" +from2@^2.1.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/from2/-/from2-2.3.0.tgz#8bfb5502bde4a4d36cfdeea007fcca21d7e382af" + dependencies: + inherits "^2.0.1" + readable-stream "^2.0.0" + from@~0: version "0.1.7" resolved "https://registry.yarnpkg.com/from/-/from-0.1.7.tgz#83c60afc58b9c56997007ed1a768b3ab303a44fe" @@ -1948,10 +2688,32 @@ fs-extra@^2.0.0: graceful-fs "^4.1.2" jsonfile "^2.1.0" +fs-minipass@^1.2.5: + version "1.2.5" + resolved "https://registry.yarnpkg.com/fs-minipass/-/fs-minipass-1.2.5.tgz#06c277218454ec288df77ada54a03b8702aacb9d" + dependencies: + minipass "^2.2.1" + +fs-write-stream-atomic@^1.0.8: + version "1.0.10" + resolved "https://registry.yarnpkg.com/fs-write-stream-atomic/-/fs-write-stream-atomic-1.0.10.tgz#b47df53493ef911df75731e70a9ded0189db40c9" + dependencies: + graceful-fs "^4.1.2" + iferr "^0.1.5" + imurmurhash "^0.1.4" + readable-stream "1 || 2" + fs.realpath@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" +fsevents@^1.2.2: + version "1.2.4" + resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-1.2.4.tgz#f41dcb1af2582af3692da36fc55cbd8e1041c426" + dependencies: + nan "^2.9.2" + node-pre-gyp "^0.10.0" + function-bind@^1.0.2: version "1.1.1" resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.1.tgz#a56899d3ea3c9bab874bb9773b7c5ede92f4895d" @@ -2005,6 +2767,10 @@ get-stream@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-3.0.0.tgz#8e943d1358dc37555054ecbe2edb05aa174ede14" +get-value@^2.0.3, get-value@^2.0.6: + version "2.0.6" + resolved "https://registry.yarnpkg.com/get-value/-/get-value-2.0.6.tgz#dc15ca1c672387ca76bd37ac0a395ba2042a2c28" + getmac@1.4.1: version "1.4.1" resolved "https://registry.yarnpkg.com/getmac/-/getmac-1.4.1.tgz#cfefcb3ee7d7a73cba5292129cb100c19afbe17a" @@ -2044,7 +2810,7 @@ glob-parent@^2.0.0: dependencies: is-glob "^2.0.0" -glob-parent@^3.0.0: +glob-parent@^3.0.0, glob-parent@^3.1.0: version "3.1.0" resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-3.1.0.tgz#9e6af6299d8d3bd2bd40430832bd113df906c5ae" dependencies: @@ -2142,6 +2908,10 @@ glob@~3.1.21: inherits "1" minimatch "~0.2.11" +global-modules-path@^2.1.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/global-modules-path/-/global-modules-path-2.3.0.tgz#b0e2bac6beac39745f7db5c59d26a36a0b94f7dc" + global-modules@^0.2.3: version "0.2.3" resolved "https://registry.yarnpkg.com/global-modules/-/global-modules-0.2.3.tgz#ea5a3bed42c6d6ce995a4f8a1269b5dae223828d" @@ -2196,7 +2966,7 @@ gm@^1.14.2: cross-spawn "^4.0.0" debug "~2.2.0" -graceful-fs@4.1.11, graceful-fs@4.X, graceful-fs@^4.0.0, graceful-fs@^4.1.2, graceful-fs@^4.1.3, graceful-fs@^4.1.6, graceful-fs@^4.1.9: +graceful-fs@4.1.11, graceful-fs@4.X, graceful-fs@^4.0.0, graceful-fs@^4.1.11, graceful-fs@^4.1.2, graceful-fs@^4.1.3, graceful-fs@^4.1.6, graceful-fs@^4.1.9: version "4.1.11" resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.1.11.tgz#0e8bdfe4d1ddb8854d64e04ea7c00e2a026e5658" @@ -2612,6 +3382,10 @@ has-flag@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-2.0.0.tgz#e8207af1cc7b30d446cc70b734b5e8be18f88d51" +has-flag@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-3.0.0.tgz#b5d454dc2199ae225699f3467e5a07f3b955bafd" + has-gulplog@^0.1.0: version "0.1.0" resolved "https://registry.yarnpkg.com/has-gulplog/-/has-gulplog-0.1.0.tgz#6414c82913697da51590397dafb12f22967811ce" @@ -2622,12 +3396,53 @@ has-unicode@^2.0.0: version "2.0.1" resolved "https://registry.yarnpkg.com/has-unicode/-/has-unicode-2.0.1.tgz#e0e6fe6a28cf51138855e086d1691e771de2a8b9" +has-value@^0.3.1: + version "0.3.1" + resolved "https://registry.yarnpkg.com/has-value/-/has-value-0.3.1.tgz#7b1f58bada62ca827ec0a2078025654845995e1f" + dependencies: + get-value "^2.0.3" + has-values "^0.1.4" + isobject "^2.0.0" + +has-value@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/has-value/-/has-value-1.0.0.tgz#18b281da585b1c5c51def24c930ed29a0be6b177" + dependencies: + get-value "^2.0.6" + has-values "^1.0.0" + isobject "^3.0.0" + +has-values@^0.1.4: + version "0.1.4" + resolved "https://registry.yarnpkg.com/has-values/-/has-values-0.1.4.tgz#6d61de95d91dfca9b9a02089ad384bff8f62b771" + +has-values@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/has-values/-/has-values-1.0.0.tgz#95b0b63fec2146619a6fe57fe75628d5a39efe4f" + dependencies: + is-number "^3.0.0" + kind-of "^4.0.0" + has@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/has/-/has-1.0.1.tgz#8461733f538b0837c9361e39a9ab9e9704dc2f28" dependencies: function-bind "^1.0.2" +hash-base@^3.0.0: + version "3.0.4" + resolved "https://registry.yarnpkg.com/hash-base/-/hash-base-3.0.4.tgz#5fc8686847ecd73499403319a6b0a3f3f6ae4918" + dependencies: + inherits "^2.0.1" + safe-buffer "^5.0.1" + +hash.js@^1.0.0, hash.js@^1.0.3: + version "1.1.5" + resolved "https://registry.yarnpkg.com/hash.js/-/hash.js-1.1.5.tgz#e38ab4b85dfb1e0c40fe9265c0e9b54854c23812" + dependencies: + inherits "^2.0.3" + minimalistic-assert "^1.0.1" + hawk@~3.1.3: version "3.1.3" resolved "https://registry.yarnpkg.com/hawk/-/hawk-3.1.3.tgz#078444bd7c1640b0fe540d2c9b73d59678e8e1c4" @@ -2646,6 +3461,14 @@ hawk@~6.0.2: hoek "4.x.x" sntp "2.x.x" +hmac-drbg@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/hmac-drbg/-/hmac-drbg-1.0.1.tgz#d2745701025a6c775a6c545793ed502fc0c649a1" + dependencies: + hash.js "^1.0.3" + minimalistic-assert "^1.0.0" + minimalistic-crypto-utils "^1.0.1" + hoek@2.x.x: version "2.16.3" resolved "https://registry.yarnpkg.com/hoek/-/hoek-2.16.3.tgz#20bb7403d3cea398e91dc4710a8ff1b8274a25ed" @@ -2711,6 +3534,10 @@ http-signature@~1.2.0: jsprim "^1.2.2" sshpk "^1.7.0" +https-browserify@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/https-browserify/-/https-browserify-1.0.0.tgz#ec06c10e0a34c0f2faf199f7fd7fc78fffd03c73" + https-proxy-agent@^2.2.1: version "2.2.1" resolved "https://registry.yarnpkg.com/https-proxy-agent/-/https-proxy-agent-2.2.1.tgz#51552970fa04d723e04c56d04178c3f92592bbc0" @@ -2731,16 +3558,37 @@ iconv-lite@0.4.19, iconv-lite@^0.4.19: version "0.4.19" resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.19.tgz#f7468f60135f5e5dad3399c0a81be9a1603a082b" -iconv-lite@0.4.23: +iconv-lite@0.4.23, iconv-lite@^0.4.22, iconv-lite@^0.4.4: version "0.4.23" resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.23.tgz#297871f63be507adcfbfca715d0cd0eed84e9a63" dependencies: safer-buffer ">= 2.1.2 < 3" +ieee754@^1.1.11, ieee754@^1.1.4: + version "1.1.12" + resolved "https://registry.yarnpkg.com/ieee754/-/ieee754-1.1.12.tgz#50bf24e5b9c8bb98af4964c941cdb0918da7b60b" + +iferr@^0.1.5: + version "0.1.5" + resolved "https://registry.yarnpkg.com/iferr/-/iferr-0.1.5.tgz#c60eed69e6d8fdb6b3104a1fcbca1c192dc5b501" + +ignore-walk@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/ignore-walk/-/ignore-walk-3.0.1.tgz#a83e62e7d272ac0e3b551aaa82831a19b69f82f8" + 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" +import-local@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/import-local/-/import-local-1.0.0.tgz#5e4ffdc03f4fe6c009c6729beb29631c2f8227bc" + dependencies: + pkg-dir "^2.0.0" + resolve-cwd "^2.0.0" + imurmurhash@^0.1.4: version "0.1.4" resolved "https://registry.yarnpkg.com/imurmurhash/-/imurmurhash-0.1.4.tgz#9218b9b2b928a238b13dc4fb6b6d576f231453ea" @@ -2755,6 +3603,10 @@ indexes-of@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/indexes-of/-/indexes-of-1.0.1.tgz#f30f716c8e2bd346c7b67d3df3915566a7c05607" +indexof@0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/indexof/-/indexof-0.0.1.tgz#82dc336d232b9062179d05ab3293a66059fd435d" + inflight@^1.0.4: version "1.0.6" resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9" @@ -2800,6 +3652,24 @@ inquirer@^0.12.0: strip-ansi "^3.0.0" through "^2.3.6" +inquirer@^6.0.0: + version "6.1.0" + resolved "https://registry.yarnpkg.com/inquirer/-/inquirer-6.1.0.tgz#8f65c7b31c498285f4ddf3b742ad8c487892040b" + dependencies: + ansi-escapes "^3.0.0" + chalk "^2.0.0" + cli-cursor "^2.1.0" + cli-width "^2.0.0" + external-editor "^3.0.0" + figures "^2.0.0" + lodash "^4.3.0" + mute-stream "0.0.7" + run-async "^2.2.0" + rxjs "^6.1.0" + string-width "^2.1.0" + strip-ansi "^4.0.0" + through "^2.3.6" + int64-buffer@^0.1.9: version "0.1.9" resolved "https://registry.yarnpkg.com/int64-buffer/-/int64-buffer-0.1.9.tgz#9e039da043b24f78b196b283e04653ef5e990f61" @@ -2808,6 +3678,10 @@ interpret@^1.0.0: version "1.0.4" resolved "https://registry.yarnpkg.com/interpret/-/interpret-1.0.4.tgz#820cdd588b868ffb191a809506d6c9c8f212b1b0" +interpret@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/interpret/-/interpret-1.1.0.tgz#7ed1b1410c6a0e0f78cf95d3b8440c63f78b8614" + invert-kv@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/invert-kv/-/invert-kv-1.0.0.tgz#104a8e4aaca6d3d8cd157a8ef8bfab2d7a3ffdb6" @@ -2831,6 +3705,18 @@ is-absolute@^0.2.3: is-relative "^0.2.1" is-windows "^0.2.0" +is-accessor-descriptor@^0.1.6: + version "0.1.6" + resolved "https://registry.yarnpkg.com/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz#a9e12cb3ae8d876727eeef3843f8a0897b5c98d6" + dependencies: + kind-of "^3.0.2" + +is-accessor-descriptor@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz#169c2f6d3df1f992618072365c9b0ea1f6878656" + dependencies: + kind-of "^6.0.0" + is-arrayish@^0.2.1: version "0.2.1" resolved "https://registry.yarnpkg.com/is-arrayish/-/is-arrayish-0.2.1.tgz#77c99840527aa8ecb1a8ba697b80645a7a926a9d" @@ -2845,7 +3731,7 @@ is-buffer@^1.0.2: version "1.1.4" resolved "https://registry.yarnpkg.com/is-buffer/-/is-buffer-1.1.4.tgz#cfc86ccd5dc5a52fa80489111c6920c457e2d98b" -is-buffer@~1.1.1: +is-buffer@^1.1.5, is-buffer@~1.1.1: version "1.1.6" resolved "https://registry.yarnpkg.com/is-buffer/-/is-buffer-1.1.6.tgz#efaa2ea9daa0d7ab2ea13a97b2b8ad51fefbe8be" @@ -2861,6 +3747,34 @@ is-ci@^1.0.9: dependencies: ci-info "^1.0.0" +is-data-descriptor@^0.1.4: + version "0.1.4" + resolved "https://registry.yarnpkg.com/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz#0b5ee648388e2c860282e793f1856fec3f301b56" + dependencies: + kind-of "^3.0.2" + +is-data-descriptor@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz#d84876321d0e7add03990406abbbbd36ba9268c7" + dependencies: + kind-of "^6.0.0" + +is-descriptor@^0.1.0: + version "0.1.6" + resolved "https://registry.yarnpkg.com/is-descriptor/-/is-descriptor-0.1.6.tgz#366d8240dde487ca51823b1ab9f07a10a78251ca" + dependencies: + is-accessor-descriptor "^0.1.6" + is-data-descriptor "^0.1.4" + kind-of "^5.0.0" + +is-descriptor@^1.0.0, is-descriptor@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/is-descriptor/-/is-descriptor-1.0.2.tgz#3b159746a66604b04f8c81524ba365c5f14d86ec" + dependencies: + is-accessor-descriptor "^1.0.0" + is-data-descriptor "^1.0.0" + kind-of "^6.0.2" + is-dotfile@^1.0.0: version "1.0.2" resolved "https://registry.yarnpkg.com/is-dotfile/-/is-dotfile-1.0.2.tgz#2c132383f39199f8edc268ca01b9b007d205cc4d" @@ -2875,11 +3789,17 @@ is-extendable@^0.1.0, is-extendable@^0.1.1: version "0.1.1" resolved "https://registry.yarnpkg.com/is-extendable/-/is-extendable-0.1.1.tgz#62b110e289a471418e3ec36a617d472e301dfc89" +is-extendable@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/is-extendable/-/is-extendable-1.0.1.tgz#a7470f9e426733d81bd81e1155264e3a3507cab4" + dependencies: + is-plain-object "^2.0.4" + is-extglob@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-1.0.0.tgz#ac468177c4943405a092fc8f29760c6ffc6206c0" -is-extglob@^2.1.0: +is-extglob@^2.1.0, is-extglob@^2.1.1: version "2.1.1" resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-2.1.1.tgz#a88c02535791f02ed37c76a1b9ea9773c833f8c2" @@ -2911,6 +3831,12 @@ is-glob@^3.1.0: dependencies: is-extglob "^2.1.0" +is-glob@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-4.0.0.tgz#9521c76845cc2610a85203ddf080a958c2ffabc0" + dependencies: + is-extglob "^2.1.1" + is-my-json-valid@^2.10.0, 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" @@ -2926,6 +3852,12 @@ is-number@^2.0.2, is-number@^2.1.0: dependencies: kind-of "^3.0.2" +is-number@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/is-number/-/is-number-3.0.0.tgz#24fd6201a4782cf50561c810276afc7d12d71195" + dependencies: + kind-of "^3.0.2" + is-path-cwd@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/is-path-cwd/-/is-path-cwd-1.0.0.tgz#d225ec23132e89edd38fda767472e62e65f1106d" @@ -2946,7 +3878,7 @@ is-plain-obj@^1.0.0: version "1.1.0" resolved "https://registry.yarnpkg.com/is-plain-obj/-/is-plain-obj-1.1.0.tgz#71a50c8429dfca773c92a390a4a03b39fcd51d3e" -is-plain-object@^2.0.3: +is-plain-object@^2.0.1, is-plain-object@^2.0.3, is-plain-object@^2.0.4: version "2.0.4" resolved "https://registry.yarnpkg.com/is-plain-object/-/is-plain-object-2.0.4.tgz#2c163b3fafb1b606d9d17928f05c2a1c38e07677" dependencies: @@ -2960,6 +3892,10 @@ is-primitive@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/is-primitive/-/is-primitive-2.0.0.tgz#207bab91638499c07b2adf240a41a87210034575" +is-promise@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/is-promise/-/is-promise-2.1.0.tgz#79a2a9ece7f096e80f36d2b2f3bc16c1ff4bf3fa" + is-property@^1.0.0: version "1.0.2" resolved "https://registry.yarnpkg.com/is-property/-/is-property-1.0.2.tgz#57fe1c4e48474edd65b09911f26b1cd4095dda84" @@ -3008,6 +3944,10 @@ is-windows@^0.2.0: version "0.2.0" resolved "https://registry.yarnpkg.com/is-windows/-/is-windows-0.2.0.tgz#de1aa6d63ea29dd248737b69f1ff8b8002d2108c" +is-windows@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/is-windows/-/is-windows-1.0.2.tgz#d1850eb9791ecd18e6182ce12a30f396634bb19d" + is@^3.1.0, is@^3.2.1: version "3.2.1" resolved "https://registry.yarnpkg.com/is/-/is-3.2.1.tgz#d0ac2ad55eb7b0bec926a5266f6c662aaa83dca5" @@ -3155,10 +4095,18 @@ json-edm-parser@0.1.2: dependencies: jsonparse "~1.2.0" +json-parse-better-errors@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz#bb867cfb3450e69107c131d1c514bab3dc8bcaa9" + json-schema-traverse@^0.3.0: version "0.3.1" resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-0.3.1.tgz#349a6d44c53a51de89b40805c5d5e59b417d3340" +json-schema-traverse@^0.4.1: + version "0.4.1" + resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz#69f6a87d9513ab8bb8fe63bdb0979c448e684660" + json-schema@0.2.3: version "0.2.3" resolved "https://registry.yarnpkg.com/json-schema/-/json-schema-0.2.3.tgz#b480c892e59a2f05954ce727bd3f2a4e882f9e13" @@ -3173,6 +4121,10 @@ json-stringify-safe@~5.0.1: version "5.0.1" resolved "https://registry.yarnpkg.com/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz#1296a2d58fd45f19a0f6ce01d65701e2c735b6eb" +json5@^0.5.0: + version "0.5.1" + resolved "https://registry.yarnpkg.com/json5/-/json5-0.5.1.tgz#1eade7acc012034ad84e2396767ead9fa5495821" + jsonfile@^2.1.0: version "2.4.0" resolved "https://registry.yarnpkg.com/jsonfile/-/jsonfile-2.4.0.tgz#3736a2b428b87bbda0cc83b53fa3d633a35c2ae8" @@ -3217,6 +4169,26 @@ kind-of@^3.0.2: dependencies: is-buffer "^1.0.2" +kind-of@^3.0.3, kind-of@^3.2.0: + version "3.2.2" + resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-3.2.2.tgz#31ea21a734bab9bbb0f32466d893aea51e4a3c64" + dependencies: + is-buffer "^1.1.5" + +kind-of@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-4.0.0.tgz#20813df3d712928b207378691a45066fae72dd57" + dependencies: + is-buffer "^1.1.5" + +kind-of@^5.0.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-5.1.0.tgz#729c91e2d857b7a419a1f9aa65685c4c33f5845d" + +kind-of@^6.0.0, kind-of@^6.0.2: + version "6.0.2" + resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-6.0.2.tgz#01146b36a6218e64e58f3a8d66de5d7fc6f6d051" + klaw@^1.0.0: version "1.3.1" resolved "https://registry.yarnpkg.com/klaw/-/klaw-1.3.1.tgz#4088433b46b3b1ba259d78785d8e96f73ba02439" @@ -3295,6 +4267,18 @@ load-json-file@^1.0.0: pinkie-promise "^2.0.0" strip-bom "^2.0.0" +loader-runner@^2.3.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/loader-runner/-/loader-runner-2.3.0.tgz#f482aea82d543e07921700d5a46ef26fdac6b8a2" + +loader-utils@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/loader-utils/-/loader-utils-1.1.0.tgz#c98aef488bcceda2ffb5e2de646d6a754429f5cd" + dependencies: + big.js "^3.1.3" + emojis-list "^2.0.0" + json5 "^0.5.0" + locate-path@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-2.0.0.tgz#2b568b265eec944c6d9c0de9c3dbbbca0354cd8e" @@ -3302,6 +4286,13 @@ locate-path@^2.0.0: p-locate "^2.0.0" path-exists "^3.0.0" +locate-path@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-3.0.0.tgz#dbec3b3ab759758071b58fe59fc41871af21400e" + dependencies: + p-locate "^3.0.0" + path-exists "^3.0.0" + lodash._basecopy@^3.0.0: version "3.0.1" resolved "https://registry.yarnpkg.com/lodash._basecopy/-/lodash._basecopy-3.0.1.tgz#8da0e6a876cf344c0ad8a54882111dd3c5c7ca36" @@ -3377,6 +4368,14 @@ lodash._shimkeys@~2.4.1: dependencies: lodash._objecttypes "~2.4.1" +lodash.clone@^4.3.2: + version "4.5.0" + resolved "https://registry.yarnpkg.com/lodash.clone/-/lodash.clone-4.5.0.tgz#195870450f5a13192478df4bc3d23d2dea1907b6" + +lodash.debounce@^4.0.8: + version "4.0.8" + resolved "https://registry.yarnpkg.com/lodash.debounce/-/lodash.debounce-4.0.8.tgz#82d79bff30a67c4005ffd5e2515300ad9ca4d7af" + lodash.defaults@~2.4.1: version "2.4.1" resolved "https://registry.yarnpkg.com/lodash.defaults/-/lodash.defaults-2.4.1.tgz#a7e8885f05e68851144b6e12a8f3678026bc4c54" @@ -3460,6 +4459,10 @@ lodash.restparam@^3.0.0: version "3.6.1" resolved "https://registry.yarnpkg.com/lodash.restparam/-/lodash.restparam-3.6.1.tgz#936a4e309ef330a7645ed4145986c85ae5b20805" +lodash.some@^4.2.2: + version "4.6.0" + resolved "https://registry.yarnpkg.com/lodash.some/-/lodash.some-4.6.0.tgz#1bb9f314ef6b8baded13b549169b2a945eb68e4d" + lodash.template@^2.4.1: version "2.4.1" resolved "https://registry.yarnpkg.com/lodash.template/-/lodash.template-2.4.1.tgz#9e611007edf629129a974ab3c48b817b3e1cf20d" @@ -3534,6 +4537,14 @@ lolex@1.3.2: version "1.3.2" resolved "https://registry.yarnpkg.com/lolex/-/lolex-1.3.2.tgz#7c3da62ffcb30f0f5a80a2566ca24e45d8a01f31" +long@4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/long/-/long-4.0.0.tgz#9a7b71cfb7d361a194ea555241c92f7468d5bf28" + +long@^3.2.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/long/-/long-3.2.0.tgz#d821b7138ca1cb581c172990ef14db200b5c474b" + longest@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/longest/-/longest-1.0.1.tgz#30a0b2da38f73770e8294a0d22e6625ed77d0097" @@ -3567,6 +4578,12 @@ macaddress@^0.2.8: version "0.2.8" resolved "https://registry.yarnpkg.com/macaddress/-/macaddress-0.2.8.tgz#5904dc537c39ec6dbefeae902327135fa8511f12" +make-dir@^1.0.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/make-dir/-/make-dir-1.3.0.tgz#79c1033b80515bd6d24ec9933e860ca75ee27f0c" + dependencies: + pify "^3.0.0" + make-error-cause@^1.1.1: version "1.2.2" resolved "https://registry.yarnpkg.com/make-error-cause/-/make-error-cause-1.2.2.tgz#df0388fcd0b37816dff0a5fb8108939777dcbc9d" @@ -3577,7 +4594,11 @@ make-error@^1.2.0: version "1.3.0" resolved "https://registry.yarnpkg.com/make-error/-/make-error-1.3.0.tgz#52ad3a339ccf10ce62b4040b708fe707244b8b96" -map-cache@^0.2.0: +mamacro@^0.0.3: + version "0.0.3" + resolved "https://registry.yarnpkg.com/mamacro/-/mamacro-0.0.3.tgz#ad2c9576197c9f1abf308d0787865bd975a3f3e4" + +map-cache@^0.2.0, map-cache@^0.2.2: version "0.2.2" resolved "https://registry.yarnpkg.com/map-cache/-/map-cache-0.2.2.tgz#c32abd0bd6525d9b051645bb4f26ac5dc98a0dbf" @@ -3593,6 +4614,12 @@ map-stream@~0.1.0: version "0.1.0" resolved "https://registry.yarnpkg.com/map-stream/-/map-stream-0.1.0.tgz#e56aa94c4c8055a16404a0674b78f215f7c8e194" +map-visit@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/map-visit/-/map-visit-1.0.0.tgz#ecdca8f13144e660f1b5bd41f12f3479d98dfb8f" + dependencies: + object-visit "^1.0.0" + markdown-it@^8.3.1: version "8.4.0" resolved "https://registry.yarnpkg.com/markdown-it/-/markdown-it-8.4.0.tgz#e2400881bf171f7018ed1bd9da441dac8af6306d" @@ -3607,6 +4634,13 @@ math-expression-evaluator@^1.2.14: version "1.2.17" resolved "https://registry.yarnpkg.com/math-expression-evaluator/-/math-expression-evaluator-1.2.17.tgz#de819fdbcd84dccd8fae59c6aeb79615b9d266ac" +md5.js@^1.3.4: + version "1.3.4" + resolved "https://registry.yarnpkg.com/md5.js/-/md5.js-1.3.4.tgz#e9bdbde94a20a5ac18b04340fc5764d5b09d901d" + dependencies: + hash-base "^3.0.0" + inherits "^2.0.1" + md5@^2.1.0: version "2.2.1" resolved "https://registry.yarnpkg.com/md5/-/md5-2.2.1.tgz#53ab38d5fe3c8891ba465329ea23fac0540126f9" @@ -3629,6 +4663,13 @@ mem@^1.1.0: dependencies: mimic-fn "^1.0.0" +memory-fs@^0.4.0, memory-fs@^0.4.1, memory-fs@~0.4.1: + version "0.4.1" + resolved "https://registry.yarnpkg.com/memory-fs/-/memory-fs-0.4.1.tgz#3a9a20b8462523e447cfbc7e8bb80ed667bfc552" + dependencies: + errno "^0.1.3" + readable-stream "^2.0.1" + meow@^3.1.0, meow@^3.3.0: version "3.7.0" resolved "https://registry.yarnpkg.com/meow/-/meow-3.7.0.tgz#72cb668b425228290abbfa856892587308a801fb" @@ -3676,6 +4717,31 @@ micromatch@^2.1.5, micromatch@^2.3.7: parse-glob "^3.0.4" regex-cache "^0.4.2" +micromatch@^3.1.4, micromatch@^3.1.8: + version "3.1.10" + resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-3.1.10.tgz#70859bc95c9840952f359a068a3fc49f9ecfac23" + dependencies: + arr-diff "^4.0.0" + array-unique "^0.3.2" + braces "^2.3.1" + define-property "^2.0.2" + extend-shallow "^3.0.2" + extglob "^2.0.4" + fragment-cache "^0.2.1" + kind-of "^6.0.2" + nanomatch "^1.2.9" + object.pick "^1.3.0" + regex-not "^1.0.0" + snapdragon "^0.8.1" + to-regex "^3.0.2" + +miller-rabin@^4.0.0: + version "4.0.1" + resolved "https://registry.yarnpkg.com/miller-rabin/-/miller-rabin-4.0.1.tgz#f080351c865b0dc562a8462966daa53543c78a4d" + dependencies: + bn.js "^4.0.0" + brorand "^1.0.1" + mime-db@~1.30.0: version "1.30.0" resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.30.0.tgz#74c643da2dd9d6a45399963465b26d5ca7d71f01" @@ -3702,6 +4768,14 @@ mimic-response@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/mimic-response/-/mimic-response-1.0.0.tgz#df3d3652a73fded6b9b0b24146e6fd052353458e" +minimalistic-assert@^1.0.0, minimalistic-assert@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz#2e194de044626d4a10e7f7fbc00ce73e83e4d5c7" + +minimalistic-crypto-utils@^1.0.0, minimalistic-crypto-utils@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz#f6c00c1c0b082246e5c4d99dfb8c7c083b2b582a" + minimatch@0.3: version "0.3.0" resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-0.3.0.tgz#275d8edaac4f1bb3326472089e7949c8394699dd" @@ -3744,6 +4818,41 @@ minimist@~0.0.1: version "0.0.10" resolved "https://registry.yarnpkg.com/minimist/-/minimist-0.0.10.tgz#de3f98543dbf96082be48ad1a0c7cda836301dcf" +minipass@^2.2.1, minipass@^2.3.3: + version "2.3.3" + resolved "https://registry.yarnpkg.com/minipass/-/minipass-2.3.3.tgz#a7dcc8b7b833f5d368759cce544dccb55f50f233" + dependencies: + safe-buffer "^5.1.2" + yallist "^3.0.0" + +minizlib@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/minizlib/-/minizlib-1.1.0.tgz#11e13658ce46bc3a70a267aac58359d1e0c29ceb" + dependencies: + minipass "^2.2.1" + +mississippi@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/mississippi/-/mississippi-2.0.0.tgz#3442a508fafc28500486feea99409676e4ee5a6f" + dependencies: + concat-stream "^1.5.0" + duplexify "^3.4.2" + end-of-stream "^1.1.0" + flush-write-stream "^1.0.0" + from2 "^2.1.0" + parallel-transform "^1.1.0" + pump "^2.0.1" + pumpify "^1.3.3" + stream-each "^1.1.0" + through2 "^2.0.0" + +mixin-deep@^1.2.0: + version "1.3.1" + resolved "https://registry.yarnpkg.com/mixin-deep/-/mixin-deep-1.3.1.tgz#a49e7268dce1a0d9698e45326c5626df3543d0fe" + dependencies: + for-in "^1.0.2" + is-extendable "^1.0.1" + mkdirp@0.3.0: version "0.3.0" resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.3.0.tgz#1bbf5ab1ba827af23575143490426455f481fe1e" @@ -3797,6 +4906,17 @@ mocha@^2.0.1, mocha@^2.2.5: supports-color "1.2.0" to-iso-string "0.0.2" +move-concurrently@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/move-concurrently/-/move-concurrently-1.0.1.tgz#be2c005fda32e0b29af1f05d7c4b33214c701f92" + dependencies: + aproba "^1.1.1" + copy-concurrently "^1.0.0" + fs-write-stream-atomic "^1.0.8" + mkdirp "^0.5.1" + rimraf "^2.5.4" + run-queue "^1.0.3" + ms@0.7.1: version "0.7.1" resolved "https://registry.yarnpkg.com/ms/-/ms-0.7.1.tgz#9cd13c03adbff25b65effde7ce864ee952017098" @@ -3824,11 +4944,11 @@ mute-stream@0.0.5: version "0.0.5" resolved "https://registry.yarnpkg.com/mute-stream/-/mute-stream-0.0.5.tgz#8fbfabb0a98a253d3184331f9e8deb7372fac6c0" -mute-stream@~0.0.4: +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" -nan@2.10.0: +nan@2.10.0, nan@^2.9.2: version "2.10.0" resolved "https://registry.yarnpkg.com/nan/-/nan-2.10.0.tgz#96d0cd610ebd58d4b4de9cc0c6828cda99c7548f" @@ -3852,6 +4972,22 @@ nan@^2.6.2: version "2.6.2" resolved "https://registry.yarnpkg.com/nan/-/nan-2.6.2.tgz#e4ff34e6c95fdfb5aecc08de6596f43605a7db45" +nanomatch@^1.2.9: + version "1.2.13" + resolved "https://registry.yarnpkg.com/nanomatch/-/nanomatch-1.2.13.tgz#b87a8aa4fc0de8fe6be88895b38983ff265bd119" + dependencies: + arr-diff "^4.0.0" + array-unique "^0.3.2" + define-property "^2.0.2" + extend-shallow "^3.0.2" + fragment-cache "^0.2.1" + is-windows "^1.0.2" + kind-of "^6.0.2" + object.pick "^1.3.0" + regex-not "^1.0.0" + snapdragon "^0.8.1" + to-regex "^3.0.1" + native-is-elevated@^0.2.1: version "0.2.1" resolved "https://registry.yarnpkg.com/native-is-elevated/-/native-is-elevated-0.2.1.tgz#70a2123a8575b9f624a3ef465d98cb74ae017385" @@ -3872,16 +5008,75 @@ natural-compare@^1.4.0: version "1.4.0" resolved "https://registry.yarnpkg.com/natural-compare/-/natural-compare-1.4.0.tgz#4abebfeed7541f2c27acfb29bdbbd15c8d5ba4f7" +needle@^2.2.1: + version "2.2.1" + resolved "https://registry.yarnpkg.com/needle/-/needle-2.2.1.tgz#b5e325bd3aae8c2678902fa296f729455d1d3a7d" + dependencies: + debug "^2.1.2" + iconv-lite "^0.4.4" + sax "^1.2.4" + negotiator@0.6.1: version "0.6.1" resolved "https://registry.yarnpkg.com/negotiator/-/negotiator-0.6.1.tgz#2b327184e8992101177b28563fb5e7102acd0ca9" +neo-async@^2.5.0: + version "2.5.1" + resolved "https://registry.yarnpkg.com/neo-async/-/neo-async-2.5.1.tgz#acb909e327b1e87ec9ef15f41b8a269512ad41ee" + +nice-try@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/nice-try/-/nice-try-1.0.4.tgz#d93962f6c52f2c1558c0fbda6d512819f1efe1c4" + node-abi@^2.2.0: version "2.4.1" resolved "https://registry.yarnpkg.com/node-abi/-/node-abi-2.4.1.tgz#7628c4d4ec4e9cd3764ceb3652f36b2e7f8d4923" dependencies: semver "^5.4.1" +node-libs-browser@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/node-libs-browser/-/node-libs-browser-2.1.0.tgz#5f94263d404f6e44767d726901fff05478d600df" + dependencies: + assert "^1.1.1" + browserify-zlib "^0.2.0" + buffer "^4.3.0" + console-browserify "^1.1.0" + constants-browserify "^1.0.0" + crypto-browserify "^3.11.0" + domain-browser "^1.1.1" + events "^1.0.0" + https-browserify "^1.0.0" + os-browserify "^0.3.0" + path-browserify "0.0.0" + process "^0.11.10" + punycode "^1.2.4" + querystring-es3 "^0.2.0" + readable-stream "^2.3.3" + stream-browserify "^2.0.1" + stream-http "^2.7.2" + string_decoder "^1.0.0" + timers-browserify "^2.0.4" + tty-browserify "0.0.0" + url "^0.11.0" + util "^0.10.3" + vm-browserify "0.0.4" + +node-pre-gyp@^0.10.0: + version "0.10.3" + resolved "https://registry.yarnpkg.com/node-pre-gyp/-/node-pre-gyp-0.10.3.tgz#3070040716afdc778747b61b6887bf78880b80fc" + dependencies: + detect-libc "^1.0.2" + mkdirp "^0.5.1" + needle "^2.2.1" + nopt "^4.0.1" + npm-packlist "^1.1.6" + npmlog "^4.0.2" + rc "^1.2.7" + rimraf "^2.6.1" + semver "^5.3.0" + tar "^4" + node-pty@0.7.6: version "0.7.6" resolved "https://registry.yarnpkg.com/node-pty/-/node-pty-0.7.6.tgz#bff6148c9c5836ca7e73c7aaaec067dcbdac2f7b" @@ -3914,6 +5109,13 @@ nopt@3.x, nopt@^3.0.1, nopt@~3.0.1: dependencies: abbrev "1" +nopt@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/nopt/-/nopt-4.0.1.tgz#d0d4685afd5415193c8c7505602d0d17cd64474d" + dependencies: + abbrev "1" + osenv "^0.1.4" + nopt@~1.0.10: version "1.0.10" resolved "https://registry.yarnpkg.com/nopt/-/nopt-1.0.10.tgz#6ddd21bd2a31417b92727dd585f8a6f37608ebee" @@ -3933,7 +5135,7 @@ normalize-path@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-1.0.0.tgz#32d0e472f91ff345701c15a8311018d3b0a90379" -normalize-path@^2.0.0: +normalize-path@^2.0.0, normalize-path@^2.1.1: version "2.1.1" resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-2.1.1.tgz#1ab28b556e198363a8c1a6f7e6fa20137fe6aed9" dependencies: @@ -3956,13 +5158,24 @@ normalize-url@^1.4.0: query-string "^4.1.0" sort-keys "^1.0.0" +npm-bundled@^1.0.1: + version "1.0.3" + resolved "https://registry.yarnpkg.com/npm-bundled/-/npm-bundled-1.0.3.tgz#7e71703d973af3370a9591bafe3a63aca0be2308" + +npm-packlist@^1.1.6: + version "1.1.11" + resolved "https://registry.yarnpkg.com/npm-packlist/-/npm-packlist-1.1.11.tgz#84e8c683cbe7867d34b1d357d893ce29e28a02de" + dependencies: + ignore-walk "^3.0.1" + npm-bundled "^1.0.1" + npm-run-path@^2.0.0: version "2.0.2" resolved "https://registry.yarnpkg.com/npm-run-path/-/npm-run-path-2.0.2.tgz#35a9232dfa35d7067b4cb2ddf2357b1871536c5f" dependencies: path-key "^2.0.0" -npmlog@^4.0.1: +npmlog@^4.0.1, npmlog@^4.0.2: version "4.1.2" resolved "https://registry.yarnpkg.com/npmlog/-/npmlog-4.1.2.tgz#08a7f2a8bf734604779a9efa4ad5cc717abb954b" dependencies: @@ -4017,10 +5230,24 @@ object-assign@^4.0.0, object-assign@^4.0.1, object-assign@^4.1.0: version "4.1.1" resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863" +object-copy@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/object-copy/-/object-copy-0.1.0.tgz#7e7d858b781bd7c991a41ba975ed3812754e998c" + dependencies: + copy-descriptor "^0.1.0" + define-property "^0.2.5" + kind-of "^3.0.3" + object-keys@~0.4.0: version "0.4.0" resolved "https://registry.yarnpkg.com/object-keys/-/object-keys-0.4.0.tgz#28a6aae7428dd2c3a92f3d95f21335dd204e0336" +object-visit@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/object-visit/-/object-visit-1.0.1.tgz#f79c4493af0c5377b59fe39d395e41042dd045bb" + dependencies: + isobject "^3.0.0" + object.defaults@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/object.defaults/-/object.defaults-1.1.0.tgz#3a7f868334b407dea06da16d88d5cd29e435fecf" @@ -4037,7 +5264,7 @@ object.omit@^2.0.0: for-own "^0.1.3" is-extendable "^0.1.1" -object.pick@^1.2.0: +object.pick@^1.2.0, object.pick@^1.3.0: version "1.3.0" resolved "https://registry.yarnpkg.com/object.pick/-/object.pick-1.3.0.tgz#87a10ac4c1694bd2e1cbf53591a66141fb5dd747" dependencies: @@ -4065,6 +5292,12 @@ onetime@^1.0.0: version "1.1.0" resolved "https://registry.yarnpkg.com/onetime/-/onetime-1.1.0.tgz#a1f7838f8314c516f05ecefcbc4ccfe04b4ed789" +onetime@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/onetime/-/onetime-2.0.1.tgz#067428230fd67443b2794b22bba528b6867962d4" + dependencies: + mimic-fn "^1.0.0" + oniguruma@^7.0.0: version "7.0.0" resolved "https://registry.yarnpkg.com/oniguruma/-/oniguruma-7.0.0.tgz#cf258a8b1a2ec1d0d68964d6336df264008ebf4c" @@ -4125,6 +5358,10 @@ ordered-read-streams@^0.3.0: is-stream "^1.0.1" readable-stream "^2.0.1" +os-browserify@^0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/os-browserify/-/os-browserify-0.3.0.tgz#854373c7f5c2315914fc9bfc6bd8238fdda1ec27" + os-homedir@^1.0.0, os-homedir@^1.0.1: version "1.0.2" resolved "https://registry.yarnpkg.com/os-homedir/-/os-homedir-1.0.2.tgz#ffbc4988336e0e833de0c168c7ef152121aa7fb3" @@ -4137,7 +5374,7 @@ os-locale@^2.0.0: lcid "^1.0.0" mem "^1.1.0" -os-tmpdir@^1.0.0, os-tmpdir@~1.0.1: +os-tmpdir@^1.0.0, os-tmpdir@~1.0.1, os-tmpdir@~1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/os-tmpdir/-/os-tmpdir-1.0.2.tgz#bbe67406c79aa85c5cfec766fe5734555dfa1274" @@ -4148,6 +5385,13 @@ osenv@^0.1.3: os-homedir "^1.0.0" os-tmpdir "^1.0.0" +osenv@^0.1.4: + version "0.1.5" + resolved "https://registry.yarnpkg.com/osenv/-/osenv-0.1.5.tgz#85cdfafaeb28e8677f416e287592b5f3f49ea410" + dependencies: + os-homedir "^1.0.0" + os-tmpdir "^1.0.0" + p-all@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/p-all/-/p-all-1.0.0.tgz#93bdf53a55a23821fdfa98b4174a99bf7f31df8d" @@ -4164,12 +5408,24 @@ p-limit@^1.1.0: dependencies: p-try "^1.0.0" +p-limit@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-2.0.0.tgz#e624ed54ee8c460a778b3c9f3670496ff8a57aec" + dependencies: + p-try "^2.0.0" + p-locate@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-2.0.0.tgz#20a0103b222a70c8fd39cc2e580680f3dde5ec43" dependencies: p-limit "^1.1.0" +p-locate@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-3.0.0.tgz#322d69a05c0264b25997d9f40cd8a891ab0064a4" + dependencies: + p-limit "^2.0.0" + p-map@^1.0.0: version "1.2.0" resolved "https://registry.yarnpkg.com/p-map/-/p-map-1.2.0.tgz#e4e94f311eabbc8633a1e79908165fca26241b6b" @@ -4178,6 +5434,32 @@ p-try@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/p-try/-/p-try-1.0.0.tgz#cbc79cdbaf8fd4228e13f621f2b1a237c1b207b3" +p-try@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/p-try/-/p-try-2.0.0.tgz#85080bb87c64688fa47996fe8f7dfbe8211760b1" + +pako@~1.0.5: + version "1.0.6" + resolved "https://registry.yarnpkg.com/pako/-/pako-1.0.6.tgz#0101211baa70c4bca4a0f63f2206e97b7dfaf258" + +parallel-transform@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/parallel-transform/-/parallel-transform-1.1.0.tgz#d410f065b05da23081fcd10f28854c29bda33b06" + dependencies: + cyclist "~0.2.2" + inherits "^2.0.3" + readable-stream "^2.1.5" + +parse-asn1@^5.0.0: + version "5.1.1" + resolved "https://registry.yarnpkg.com/parse-asn1/-/parse-asn1-5.1.1.tgz#f6bf293818332bd0dab54efb16087724745e6ca8" + dependencies: + asn1.js "^4.0.0" + browserify-aes "^1.0.0" + create-hash "^1.1.0" + evp_bytestokey "^1.0.0" + pbkdf2 "^3.0.3" + parse-filepath@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/parse-filepath/-/parse-filepath-1.0.1.tgz#159d6155d43904d16c10ef698911da1e91969b73" @@ -4225,6 +5507,14 @@ parseurl@~1.3.2: version "1.3.2" resolved "https://registry.yarnpkg.com/parseurl/-/parseurl-1.3.2.tgz#fc289d4ed8993119460c156253262cdc8de65bf3" +pascalcase@^0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/pascalcase/-/pascalcase-0.1.1.tgz#b363e55e8006ca6fe21784d2db22bd15d7917f14" + +path-browserify@0.0.0: + version "0.0.0" + resolved "https://registry.yarnpkg.com/path-browserify/-/path-browserify-0.0.0.tgz#a0b870729aae214005b7d5032ec2cbbb0fb4451a" + path-dirname@^1.0.0: version "1.0.2" resolved "https://registry.yarnpkg.com/path-dirname/-/path-dirname-1.0.2.tgz#cc33d24d525e099a5388c0336c6e32b9160609e0" @@ -4247,7 +5537,7 @@ path-is-inside@^1.0.1: version "1.0.2" resolved "https://registry.yarnpkg.com/path-is-inside/-/path-is-inside-1.0.2.tgz#365417dede44430d1c11af61027facf074bdfc53" -path-key@^2.0.0: +path-key@^2.0.0, path-key@^2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/path-key/-/path-key-2.0.1.tgz#411cadb574c5a140d3a4b1910d40d80cc9f40b40" @@ -4283,6 +5573,16 @@ pause-stream@0.0.11: dependencies: through "~2.3" +pbkdf2@^3.0.3: + version "3.0.16" + resolved "https://registry.yarnpkg.com/pbkdf2/-/pbkdf2-3.0.16.tgz#7404208ec6b01b62d85bf83853a8064f8d9c2a5c" + dependencies: + create-hash "^1.1.2" + create-hmac "^1.1.4" + ripemd160 "^2.0.1" + safe-buffer "^5.0.1" + sha.js "^2.4.8" + pend@~1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/pend/-/pend-1.2.0.tgz#7a57eb550a6783f9115331fcf4663d5c8e007a50" @@ -4299,6 +5599,10 @@ pify@^2.0.0: version "2.3.0" resolved "https://registry.yarnpkg.com/pify/-/pify-2.3.0.tgz#ed141a6ac043a849ea588498e7dca8b15330e90c" +pify@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/pify/-/pify-3.0.0.tgz#e5a4acd2c101fdf3d9a4d07f0dbc4db49dd28176" + pinkie-promise@^2.0.0: version "2.0.1" resolved "https://registry.yarnpkg.com/pinkie-promise/-/pinkie-promise-2.0.1.tgz#2135d6dfa7a358c069ac9b178776288228450ffa" @@ -4309,6 +5613,12 @@ pinkie@^2.0.0: version "2.0.4" resolved "https://registry.yarnpkg.com/pinkie/-/pinkie-2.0.4.tgz#72556b80cfa0d48a974e80e77248e80ed4f7f870" +pkg-dir@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/pkg-dir/-/pkg-dir-2.0.0.tgz#f6d5d1109e19d63edf428e0bd57e12777615334b" + dependencies: + find-up "^2.1.0" + plist@^1.1.0: version "1.2.0" resolved "https://registry.yarnpkg.com/plist/-/plist-1.2.0.tgz#084b5093ddc92506e259f874b8d9b1afb8c79593" @@ -4328,6 +5638,15 @@ plugin-error@^0.1.2: arr-union "^2.0.1" extend-shallow "^1.1.2" +plugin-error@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/plugin-error/-/plugin-error-1.0.1.tgz#77016bd8919d0ac377fdcdd0322328953ca5781c" + dependencies: + ansi-colors "^1.0.1" + arr-diff "^4.0.0" + arr-union "^3.1.0" + extend-shallow "^3.0.2" + plur@^2.1.0: version "2.1.2" resolved "https://registry.yarnpkg.com/plur/-/plur-2.1.2.tgz#7482452c1a0f508e3e344eaec312c91c29dc655a" @@ -4338,6 +5657,10 @@ pluralize@^1.2.1: version "1.2.1" resolved "https://registry.yarnpkg.com/pluralize/-/pluralize-1.2.1.tgz#d1a21483fd22bb41e58a12fa3421823140897c45" +posix-character-classes@^0.1.0: + version "0.1.1" + resolved "https://registry.yarnpkg.com/posix-character-classes/-/posix-character-classes-0.1.1.tgz#01eac0fe3b5af71a2a6c02feabb8c1fef7e00eab" + postcss-calc@^5.2.0: version "5.3.1" resolved "https://registry.yarnpkg.com/postcss-calc/-/postcss-calc-5.3.1.tgz#77bae7ca928ad85716e2fda42f261bf7c1d65b5e" @@ -4611,6 +5934,10 @@ process-nextick-args@~2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-2.0.0.tgz#a37d732f4271b4ab1ad070d35508e8290788ffaa" +process@^0.11.10: + version "0.11.10" + resolved "https://registry.yarnpkg.com/process/-/process-0.11.10.tgz#7332300e840161bda3e69a1d1d91a7d4bc16f182" + progress-stream@^1.1.0: version "1.2.0" resolved "https://registry.yarnpkg.com/progress-stream/-/progress-stream-1.2.0.tgz#2cd3cfea33ba3a89c9c121ec3347abe9ab125f77" @@ -4622,6 +5949,10 @@ progress@^1.1.8: version "1.1.8" resolved "https://registry.yarnpkg.com/progress/-/progress-1.1.8.tgz#e260c78f6161cdd9b0e56cc3e0a85de17c7a57be" +promise-inflight@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/promise-inflight/-/promise-inflight-1.0.1.tgz#98472870bf228132fcbdd868129bad12c3c029e3" + promisify-node@^0.3.0: version "0.3.0" resolved "https://registry.yarnpkg.com/promisify-node/-/promisify-node-0.3.0.tgz#b4b55acf90faa7d2b8b90ca396899086c03060cf" @@ -4639,10 +5970,24 @@ proxy-addr@~2.0.2: forwarded "~0.1.2" ipaddr.js "1.5.2" +prr@~1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/prr/-/prr-1.0.1.tgz#d3fc114ba06995a45ec6893f484ceb1d78f5f476" + pseudomap@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/pseudomap/-/pseudomap-1.0.2.tgz#f052a28da70e618917ef0a8ac34c1ae5a68286b3" +public-encrypt@^4.0.0: + version "4.0.2" + resolved "https://registry.yarnpkg.com/public-encrypt/-/public-encrypt-4.0.2.tgz#46eb9107206bf73489f8b85b69d91334c6610994" + dependencies: + bn.js "^4.1.0" + browserify-rsa "^4.0.0" + create-hash "^1.1.0" + parse-asn1 "^5.0.0" + randombytes "^2.0.1" + pump@^1.0.0: version "1.0.3" resolved "https://registry.yarnpkg.com/pump/-/pump-1.0.3.tgz#5dfe8311c33bbf6fc18261f9f34702c47c08a954" @@ -4657,17 +6002,33 @@ pump@^1.0.1: end-of-stream "^1.1.0" once "^1.3.1" -pump@^2.0.1: +pump@^2.0.0, pump@^2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/pump/-/pump-2.0.1.tgz#12399add6e4cf7526d973cbc8b5ce2e2908b3909" dependencies: end-of-stream "^1.1.0" once "^1.3.1" -punycode@^1.4.1: +pumpify@^1.3.3: + version "1.5.1" + resolved "https://registry.yarnpkg.com/pumpify/-/pumpify-1.5.1.tgz#36513be246ab27570b1a374a5ce278bfd74370ce" + dependencies: + duplexify "^3.6.0" + inherits "^2.0.3" + pump "^2.0.0" + +punycode@1.3.2: + version "1.3.2" + resolved "https://registry.yarnpkg.com/punycode/-/punycode-1.3.2.tgz#9653a036fb7c1ee42342f2325cceefea3926c48d" + +punycode@^1.2.4, punycode@^1.4.1: version "1.4.1" resolved "https://registry.yarnpkg.com/punycode/-/punycode-1.4.1.tgz#c0d5a63b2718800ad8e1eb0fa5269c84dd41845e" +punycode@^2.1.0: + version "2.1.1" + resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.1.1.tgz#b58b010ac40c22c5657616c8d2c2c02c7bf479ec" + q@^1.0.1, q@^1.1.2: version "1.5.1" resolved "https://registry.yarnpkg.com/q/-/q-1.5.1.tgz#7e32f75b41381291d04611f1bf14109ac00651d7" @@ -4695,6 +6056,14 @@ query-string@^4.1.0: object-assign "^4.1.0" strict-uri-encode "^1.0.0" +querystring-es3@^0.2.0: + version "0.2.1" + resolved "https://registry.yarnpkg.com/querystring-es3/-/querystring-es3-0.2.1.tgz#9ec61f79049875707d69414596fd907a4d711e73" + +querystring@0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/querystring/-/querystring-0.2.0.tgz#b209849203bb25df820da756e747005878521620" + queue@3.0.6: version "3.0.6" resolved "https://registry.yarnpkg.com/queue/-/queue-3.0.6.tgz#66c0ffd0a1d9d28045adebda966a2d3946ab9f13" @@ -4714,6 +6083,19 @@ randomatic@^1.1.3: is-number "^2.0.2" kind-of "^3.0.2" +randombytes@^2.0.0, randombytes@^2.0.1, randombytes@^2.0.5: + version "2.0.6" + resolved "https://registry.yarnpkg.com/randombytes/-/randombytes-2.0.6.tgz#d302c522948588848a8d300c932b44c24231da80" + dependencies: + safe-buffer "^5.1.0" + +randomfill@^1.0.3: + version "1.0.4" + resolved "https://registry.yarnpkg.com/randomfill/-/randomfill-1.0.4.tgz#c92196fc86ab42be983f1bf31778224931d61458" + dependencies: + randombytes "^2.0.5" + safe-buffer "^5.1.0" + range-parser@~1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/range-parser/-/range-parser-1.2.0.tgz#f49be6b487894ddc40dcc94a322f611092e00d5e" @@ -4736,7 +6118,7 @@ rc@^1.1.2: minimist "^1.2.0" strip-json-comments "~2.0.1" -rc@^1.1.6: +rc@^1.1.6, rc@^1.2.7: version "1.2.8" resolved "https://registry.yarnpkg.com/rc/-/rc-1.2.8.tgz#cd924bf5200a075b83c188cd6b9e211b7fc0d3ed" dependencies: @@ -4770,6 +6152,18 @@ read@^1.0.7: dependencies: mute-stream "~0.0.4" +"readable-stream@1 || 2", readable-stream@^2.0.6, readable-stream@^2.3.0, readable-stream@^2.3.3, readable-stream@^2.3.5, readable-stream@^2.3.6: + version "2.3.6" + resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.6.tgz#b11c27d88b8ff1fbe070643cf94b0c79ae1b0aaf" + dependencies: + core-util-is "~1.0.0" + inherits "~2.0.3" + isarray "~1.0.0" + process-nextick-args "~2.0.0" + safe-buffer "~5.1.1" + string_decoder "~1.1.1" + util-deprecate "~1.0.1" + "readable-stream@>=1.0.33-1 <1.1.0-0", readable-stream@~1.0.17: version "1.0.34" resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-1.0.34.tgz#125820e34bc842d2f2aaafafe4c2916ee32c157c" @@ -4800,18 +6194,6 @@ readable-stream@^2.0.0, readable-stream@^2.0.1, readable-stream@^2.0.2, readable string_decoder "~1.0.3" util-deprecate "~1.0.1" -readable-stream@^2.0.6, readable-stream@^2.3.0, readable-stream@^2.3.5: - version "2.3.6" - resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.6.tgz#b11c27d88b8ff1fbe070643cf94b0c79ae1b0aaf" - dependencies: - core-util-is "~1.0.0" - inherits "~2.0.3" - isarray "~1.0.0" - process-nextick-args "~2.0.0" - safe-buffer "~5.1.1" - string_decoder "~1.1.1" - util-deprecate "~1.0.1" - readable-stream@~2.0.0, readable-stream@~2.0.5: version "2.0.6" resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.0.6.tgz#8f90341e68a53ccc928788dacfcd11b36eb9b78e" @@ -4874,6 +6256,13 @@ regex-cache@^0.4.2: is-equal-shallow "^0.1.3" is-primitive "^2.0.0" +regex-not@^1.0.0, regex-not@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/regex-not/-/regex-not-1.0.2.tgz#1f4ece27e00b0b65e0247a6810e6a85d83a5752c" + dependencies: + extend-shallow "^3.0.2" + safe-regex "^1.1.0" + remap-istanbul@^0.6.4: version "0.6.4" resolved "https://registry.yarnpkg.com/remap-istanbul/-/remap-istanbul-0.6.4.tgz#ac551eff1aa641504b4f318d0303dda61e3bb695" @@ -4896,6 +6285,10 @@ repeat-string@^1.5.2: version "1.5.4" resolved "https://registry.yarnpkg.com/repeat-string/-/repeat-string-1.5.4.tgz#64ec0c91e0f4b475f90d5b643651e3e6e5b6c2d5" +repeat-string@^1.6.1: + version "1.6.1" + resolved "https://registry.yarnpkg.com/repeat-string/-/repeat-string-1.6.1.tgz#8dcae470e1c88abc2d600fff4a776286da75e637" + repeating@^1.1.0: version "1.1.3" resolved "https://registry.yarnpkg.com/repeating/-/repeating-1.1.3.tgz#3d4114218877537494f97f77f9785fab810fa4ac" @@ -5044,6 +6437,12 @@ require-uncached@^1.0.2: caller-path "^0.1.0" resolve-from "^1.0.0" +resolve-cwd@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/resolve-cwd/-/resolve-cwd-2.0.0.tgz#00a9f7387556e27038eae232caa372a6a59b665a" + dependencies: + resolve-from "^3.0.0" + resolve-dir@^0.1.0: version "0.1.1" resolved "https://registry.yarnpkg.com/resolve-dir/-/resolve-dir-0.1.1.tgz#b219259a5602fac5c5c496ad894a6e8cc430261e" @@ -5055,7 +6454,11 @@ resolve-from@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-1.0.1.tgz#26cbfe935d1aeeeabb29bc3fe5aeb01e93d44226" -resolve-url@~0.2.1: +resolve-from@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-3.0.0.tgz#b22c7af7d9d6881bc8b6e653335eebcb0a188748" + +resolve-url@^0.2.1, resolve-url@~0.2.1: version "0.2.1" resolved "https://registry.yarnpkg.com/resolve-url/-/resolve-url-0.2.1.tgz#2c637fe77c893afd2a663fe21aa9080068e2052a" @@ -5076,6 +6479,17 @@ restore-cursor@^1.0.1: 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" + dependencies: + onetime "^2.0.0" + signal-exit "^3.0.2" + +ret@~0.1.10: + version "0.1.15" + resolved "https://registry.yarnpkg.com/ret/-/ret-0.1.15.tgz#b8a4825d5bdb1fc3f6f53c2bc33f81388681c7bc" + right-align@^0.1.1: version "0.1.3" resolved "https://registry.yarnpkg.com/right-align/-/right-align-0.1.3.tgz#61339b722fe6a3515689210d24e14c96148613ef" @@ -5088,7 +6502,7 @@ rimraf@^2.2.8: dependencies: glob "^7.0.5" -rimraf@^2.4.2: +rimraf@^2.4.2, rimraf@^2.5.4, rimraf@^2.6.1, rimraf@^2.6.2: version "2.6.2" resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.6.2.tgz#2ed8150d24a16ea8651e6d6ef0f47c4158ce7a36" dependencies: @@ -5098,20 +6512,55 @@ rimraf@~2.2.6: version "2.2.8" resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.2.8.tgz#e439be2aaee327321952730f99a8929e4fc50582" +ripemd160@^2.0.0, ripemd160@^2.0.1: + version "2.0.2" + resolved "https://registry.yarnpkg.com/ripemd160/-/ripemd160-2.0.2.tgz#a1c1a6f624751577ba5d07914cbc92850585890c" + dependencies: + 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" 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" + dependencies: + is-promise "^2.1.0" + +run-queue@^1.0.0, run-queue@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/run-queue/-/run-queue-1.0.3.tgz#e848396f057d223f24386924618e25694161ec47" + 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" +rxjs@^6.1.0: + version "6.2.2" + resolved "https://registry.yarnpkg.com/rxjs/-/rxjs-6.2.2.tgz#eb75fa3c186ff5289907d06483a77884586e1cf9" + dependencies: + tslib "^1.9.0" + safe-buffer@5.1.1, safe-buffer@^5.0.1, safe-buffer@^5.1.1, safe-buffer@~5.1.0, safe-buffer@~5.1.1: version "5.1.1" resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.1.tgz#893312af69b2123def71f57889001671eeb2c853" +safe-buffer@^5.1.0, safe-buffer@^5.1.2: + version "5.1.2" + resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.2.tgz#991ec69d296e0313747d59bdfd2b745c35f8828d" + +safe-regex@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/safe-regex/-/safe-regex-1.1.0.tgz#40a3669f3b077d1e943d44629e157dd48023bf2e" + dependencies: + ret "~0.1.10" + "safer-buffer@>= 2.1.2 < 3": version "2.1.2" resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a" @@ -5128,10 +6577,17 @@ sax@0.5.2: version "0.5.2" resolved "https://registry.yarnpkg.com/sax/-/sax-0.5.2.tgz#735ffaa39a1cff8ffb9598f0223abdb03a9fb2ea" -sax@>=0.6.0, sax@~1.2.1: +sax@>=0.6.0, sax@^1.2.4, sax@~1.2.1: version "1.2.4" resolved "https://registry.yarnpkg.com/sax/-/sax-1.2.4.tgz#2816234e2378bddc4e5354fab5caa895df7100d9" +schema-utils@^0.4.4, schema-utils@^0.4.5: + version "0.4.7" + resolved "https://registry.yarnpkg.com/schema-utils/-/schema-utils-0.4.7.tgz#ba74f597d2be2ea880131746ee17d0a093c68187" + dependencies: + ajv "^6.1.0" + ajv-keywords "^3.1.0" + semaphore@1.0.5: version "1.0.5" resolved "https://registry.yarnpkg.com/semaphore/-/semaphore-1.0.5.tgz#b492576e66af193db95d65e25ec53f5f19798d60" @@ -5170,6 +6626,10 @@ sequencify@~0.0.7: version "0.0.7" resolved "https://registry.yarnpkg.com/sequencify/-/sequencify-0.0.7.tgz#90cff19d02e07027fd767f5ead3e7b95d1e7380c" +serialize-javascript@^1.4.0: + version "1.5.0" + resolved "https://registry.yarnpkg.com/serialize-javascript/-/serialize-javascript-1.5.0.tgz#1aa336162c88a890ddad5384baebc93a655161fe" + serve-static@1.13.1: version "1.13.1" resolved "https://registry.yarnpkg.com/serve-static/-/serve-static-1.13.1.tgz#4c57d53404a761d8f2e7c1e8a18a47dbf278a719" @@ -5187,6 +6647,28 @@ set-immediate-shim@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/set-immediate-shim/-/set-immediate-shim-1.0.1.tgz#4b2b1b27eb808a9f8dcc481a58e5e56f599f3f61" +set-value@^0.4.3: + version "0.4.3" + resolved "https://registry.yarnpkg.com/set-value/-/set-value-0.4.3.tgz#7db08f9d3d22dc7f78e53af3c3bf4666ecdfccf1" + dependencies: + extend-shallow "^2.0.1" + is-extendable "^0.1.1" + is-plain-object "^2.0.1" + to-object-path "^0.3.0" + +set-value@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/set-value/-/set-value-2.0.0.tgz#71ae4a88f0feefbbf52d1ea604f3fb315ebb6274" + dependencies: + extend-shallow "^2.0.1" + is-extendable "^0.1.1" + is-plain-object "^2.0.3" + split-string "^3.0.1" + +setimmediate@^1.0.4: + version "1.0.5" + resolved "https://registry.yarnpkg.com/setimmediate/-/setimmediate-1.0.5.tgz#290cbb232e306942d7d7ea9b83732ab7856f8285" + setprototypeof@1.0.3: version "1.0.3" resolved "https://registry.yarnpkg.com/setprototypeof/-/setprototypeof-1.0.3.tgz#66567e37043eeb4f04d91bd658c0cbefb55b8e04" @@ -5195,6 +6677,13 @@ setprototypeof@1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/setprototypeof/-/setprototypeof-1.1.0.tgz#d0bd85536887b6fe7c0d818cb962d9d91c54e656" +sha.js@^2.4.0, sha.js@^2.4.8: + version "2.4.11" + resolved "https://registry.yarnpkg.com/sha.js/-/sha.js-2.4.11.tgz#37a5cf0b81ecbc6943de109ba2960d1b26584ae7" + dependencies: + inherits "^2.0.1" + safe-buffer "^5.0.1" + shebang-command@^1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/shebang-command/-/shebang-command-1.2.0.tgz#44aac65b695b03398968c39f363fee5deafdf1ea" @@ -5217,7 +6706,7 @@ sigmund@^1.0.1, sigmund@~1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/sigmund/-/sigmund-1.0.1.tgz#3ff21f198cad2175f9f3b781853fd94d0d19b590" -signal-exit@^3.0.0: +signal-exit@^3.0.0, signal-exit@^3.0.2: version "3.0.2" resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.2.tgz#b5fdc08f1287ea1178628e415e25132b73646c6d" @@ -5252,6 +6741,33 @@ slice-ansi@0.0.4: version "0.0.4" resolved "https://registry.yarnpkg.com/slice-ansi/-/slice-ansi-0.0.4.tgz#edbf8903f66f7ce2f8eafd6ceed65e264c831b35" +snapdragon-node@^2.0.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/snapdragon-node/-/snapdragon-node-2.1.1.tgz#6c175f86ff14bdb0724563e8f3c1b021a286853b" + dependencies: + define-property "^1.0.0" + isobject "^3.0.0" + snapdragon-util "^3.0.1" + +snapdragon-util@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/snapdragon-util/-/snapdragon-util-3.0.1.tgz#f956479486f2acd79700693f6f7b805e45ab56e2" + dependencies: + kind-of "^3.2.0" + +snapdragon@^0.8.1: + version "0.8.2" + resolved "https://registry.yarnpkg.com/snapdragon/-/snapdragon-0.8.2.tgz#64922e7c565b0e14204ba1aa7d6964278d25182d" + dependencies: + base "^0.11.1" + debug "^2.2.0" + define-property "^0.2.5" + extend-shallow "^2.0.1" + map-cache "^0.2.2" + source-map "^0.5.6" + source-map-resolve "^0.5.0" + use "^3.1.0" + sntp@1.x.x: version "1.0.9" resolved "https://registry.yarnpkg.com/sntp/-/sntp-1.0.9.tgz#6541184cc90aeea6c6e7b35e2659082443c66198" @@ -5270,6 +6786,10 @@ sort-keys@^1.0.0: dependencies: is-plain-obj "^1.0.0" +source-list-map@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/source-list-map/-/source-list-map-2.0.0.tgz#aaa47403f7b245a92fbc97ea08f250d6087ed085" + source-map-resolve@^0.3.0: version "0.3.1" resolved "https://registry.yarnpkg.com/source-map-resolve/-/source-map-resolve-0.3.1.tgz#610f6122a445b8dd51535a2a71b783dfc1248761" @@ -5279,6 +6799,20 @@ source-map-resolve@^0.3.0: source-map-url "~0.3.0" urix "~0.1.0" +source-map-resolve@^0.5.0: + version "0.5.2" + resolved "https://registry.yarnpkg.com/source-map-resolve/-/source-map-resolve-0.5.2.tgz#72e2cc34095543e43b2c62b2c4c10d4a9054f259" + dependencies: + atob "^2.1.1" + decode-uri-component "^0.2.0" + resolve-url "^0.2.1" + source-map-url "^0.4.0" + urix "^0.1.0" + +source-map-url@^0.4.0: + version "0.4.0" + resolved "https://registry.yarnpkg.com/source-map-url/-/source-map-url-0.4.0.tgz#3e935d7ddd73631b97659956d55128e87b5084a3" + source-map-url@~0.3.0: version "0.3.0" resolved "https://registry.yarnpkg.com/source-map-url/-/source-map-url-0.3.0.tgz#7ecaf13b57bcd09da8a40c5d269db33799d4aaf9" @@ -5339,6 +6873,12 @@ speedometer@~0.1.2: version "0.1.4" resolved "https://registry.yarnpkg.com/speedometer/-/speedometer-0.1.4.tgz#9876dbd2a169d3115402d48e6ea6329c8816a50d" +split-string@^3.0.1, split-string@^3.0.2: + version "3.1.0" + resolved "https://registry.yarnpkg.com/split-string/-/split-string-3.1.0.tgz#7cb09dda3a86585705c64b39a6466038682e8fe2" + dependencies: + extend-shallow "^3.0.0" + split@0.3: version "0.3.3" resolved "https://registry.yarnpkg.com/split/-/split-0.3.3.tgz#cd0eea5e63a211dfff7eb0f091c4133e2d0dd28f" @@ -5363,6 +6903,19 @@ sshpk@^1.7.0: jsbn "~0.1.0" tweetnacl "~0.14.0" +ssri@^5.2.4: + version "5.3.0" + resolved "https://registry.yarnpkg.com/ssri/-/ssri-5.3.0.tgz#ba3872c9c6d33a0704a7d71ff045e5ec48999d06" + dependencies: + safe-buffer "^5.1.1" + +static-extend@^0.1.1: + version "0.1.2" + resolved "https://registry.yarnpkg.com/static-extend/-/static-extend-0.1.2.tgz#60809c39cbff55337226fd5e0b520f341f1fb5c6" + dependencies: + define-property "^0.2.5" + object-copy "^0.1.0" + "statuses@>= 1.3.1 < 2": version "1.4.0" resolved "https://registry.yarnpkg.com/statuses/-/statuses-1.4.0.tgz#bb73d446da2796106efcc1b601a253d6c46bd087" @@ -5371,6 +6924,13 @@ statuses@~1.3.1: version "1.3.1" resolved "https://registry.yarnpkg.com/statuses/-/statuses-1.3.1.tgz#faf51b9eb74aaef3b3acf4ad5f61abf24cb7b93e" +stream-browserify@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/stream-browserify/-/stream-browserify-2.0.1.tgz#66266ee5f9bdb9940a4e4514cafb43bb71e5c9db" + dependencies: + inherits "~2.0.1" + readable-stream "^2.0.2" + stream-combiner@~0.0.4: version "0.0.4" resolved "https://registry.yarnpkg.com/stream-combiner/-/stream-combiner-0.0.4.tgz#4d5e433c185261dde623ca3f44c586bcf5c4ad14" @@ -5381,6 +6941,23 @@ stream-consume@~0.1.0: version "0.1.0" resolved "https://registry.yarnpkg.com/stream-consume/-/stream-consume-0.1.0.tgz#a41ead1a6d6081ceb79f65b061901b6d8f3d1d0f" +stream-each@^1.1.0: + version "1.2.3" + resolved "https://registry.yarnpkg.com/stream-each/-/stream-each-1.2.3.tgz#ebe27a0c389b04fbcc233642952e10731afa9bae" + dependencies: + end-of-stream "^1.1.0" + stream-shift "^1.0.0" + +stream-http@^2.7.2: + version "2.8.3" + resolved "https://registry.yarnpkg.com/stream-http/-/stream-http-2.8.3.tgz#b2d242469288a5a27ec4fe8933acf623de6514fc" + dependencies: + builtin-status-codes "^3.0.0" + inherits "^2.0.1" + readable-stream "^2.3.6" + to-arraybuffer "^1.0.0" + xtend "^4.0.0" + stream-shift@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/stream-shift/-/stream-shift-1.0.0.tgz#d5c752825e5367e786f78e18e445ea223a155952" @@ -5407,13 +6984,19 @@ string-width@^1.0.1: is-fullwidth-code-point "^1.0.0" strip-ansi "^3.0.0" -"string-width@^1.0.2 || 2", string-width@^2.0.0, string-width@^2.1.1: +"string-width@^1.0.2 || 2", string-width@^2.0.0, string-width@^2.1.0, string-width@^2.1.1: version "2.1.1" resolved "https://registry.yarnpkg.com/string-width/-/string-width-2.1.1.tgz#ab93f27a8dc13d28cac815c462143a6d9012ae9e" dependencies: is-fullwidth-code-point "^2.0.0" strip-ansi "^4.0.0" +string_decoder@^1.0.0, string_decoder@~1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.1.1.tgz#9cf1611ba62685d7030ae9e4ba34149c3af03fc8" + dependencies: + safe-buffer "~5.1.0" + string_decoder@~0.10.x: version "0.10.31" resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-0.10.31.tgz#62e203bc41766c6c28c9fc84301dab1c5310fa94" @@ -5424,12 +7007,6 @@ string_decoder@~1.0.3: dependencies: safe-buffer "~5.1.0" -string_decoder@~1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.1.1.tgz#9cf1611ba62685d7030ae9e4ba34149c3af03fc8" - dependencies: - safe-buffer "~5.1.0" - stringstream@~0.0.4, stringstream@~0.0.5: version "0.0.5" resolved "https://registry.yarnpkg.com/stringstream/-/stringstream-0.0.5.tgz#4e484cd4de5a0bbbee18e46307710a8a81621878" @@ -5524,6 +7101,12 @@ supports-color@^4.0.0: dependencies: has-flag "^2.0.0" +supports-color@^5.3.0, supports-color@^5.4.0: + version "5.4.0" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-5.4.0.tgz#1c6b337402c2137605efe19f10fec390f6faab54" + dependencies: + has-flag "^3.0.0" + svgo@^0.7.0: version "0.7.2" resolved "https://registry.yarnpkg.com/svgo/-/svgo-0.7.2.tgz#9f5772413952135c6fefbf40afe6a4faa88b4bb5" @@ -5547,6 +7130,10 @@ table@^3.7.8: slice-ansi "0.0.4" string-width "^2.0.0" +tapable@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/tapable/-/tapable-1.0.0.tgz#cbb639d9002eed9c6b5975eb20598d7936f1f9f2" + tar-fs@^1.13.0: version "1.16.2" resolved "https://registry.yarnpkg.com/tar-fs/-/tar-fs-1.16.2.tgz#17e5239747e399f7e77344f5f53365f04af53577" @@ -5568,6 +7155,18 @@ tar-stream@^1.1.2: to-buffer "^1.1.0" xtend "^4.0.0" +tar@^4: + version "4.4.6" + resolved "https://registry.yarnpkg.com/tar/-/tar-4.4.6.tgz#63110f09c00b4e60ac8bcfe1bf3c8660235fbc9b" + dependencies: + chownr "^1.0.1" + fs-minipass "^1.2.5" + minipass "^2.3.3" + minizlib "^1.1.0" + mkdirp "^0.5.0" + safe-buffer "^5.1.2" + yallist "^3.0.2" + temp@^0.8.1, temp@^0.8.3: version "0.8.3" resolved "https://registry.yarnpkg.com/temp/-/temp-0.8.3.tgz#e0c6bc4d26b903124410e4fed81103014dfc1f59" @@ -5636,7 +7235,7 @@ through2@~0.2.3: readable-stream "~1.1.9" xtend "~2.1.1" -through@2, through@^2.3.4, through@^2.3.6, through@~2.3, through@~2.3.1, through@~2.3.8: +through@2, through@^2.3.4, through@^2.3.6, through@^2.3.8, through@~2.3, through@~2.3.1, through@~2.3.8: version "2.3.8" resolved "https://registry.yarnpkg.com/through/-/through-2.3.8.tgz#0dd4c9ffaabc357960b1b724115d7e0e86a2e1f5" @@ -5650,6 +7249,12 @@ time-stamp@^1.0.0: version "1.1.0" resolved "https://registry.yarnpkg.com/time-stamp/-/time-stamp-1.1.0.tgz#764a5a11af50561921b133f3b44e618687e0f5c3" +timers-browserify@^2.0.4: + version "2.0.10" + resolved "https://registry.yarnpkg.com/timers-browserify/-/timers-browserify-2.0.10.tgz#1d28e3d2aadf1d5a5996c4e9f95601cd053480ae" + dependencies: + setimmediate "^1.0.4" + tmp@0.0.28: version "0.0.28" resolved "https://registry.yarnpkg.com/tmp/-/tmp-0.0.28.tgz#172735b7f614ea7af39664fa84cf0de4e515d120" @@ -5662,12 +7267,22 @@ tmp@0.0.29: dependencies: os-tmpdir "~1.0.1" +tmp@^0.0.33: + version "0.0.33" + resolved "https://registry.yarnpkg.com/tmp/-/tmp-0.0.33.tgz#6d34335889768d21b2bcda0aa277ced3b1bfadf9" + dependencies: + os-tmpdir "~1.0.2" + to-absolute-glob@^0.1.1: version "0.1.1" resolved "https://registry.yarnpkg.com/to-absolute-glob/-/to-absolute-glob-0.1.1.tgz#1cdfa472a9ef50c239ee66999b662ca0eb39937f" dependencies: extend-shallow "^2.0.1" +to-arraybuffer@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/to-arraybuffer/-/to-arraybuffer-1.0.1.tgz#7d229b1fcc637e466ca081180836a7aabff83f43" + to-buffer@^1.1.0: version "1.1.1" resolved "https://registry.yarnpkg.com/to-buffer/-/to-buffer-1.1.1.tgz#493bd48f62d7c43fcded313a03dcadb2e1213a80" @@ -5676,6 +7291,28 @@ to-iso-string@0.0.2: version "0.0.2" resolved "https://registry.yarnpkg.com/to-iso-string/-/to-iso-string-0.0.2.tgz#4dc19e664dfccbe25bd8db508b00c6da158255d1" +to-object-path@^0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/to-object-path/-/to-object-path-0.3.0.tgz#297588b7b0e7e0ac08e04e672f85c1f4999e17af" + dependencies: + kind-of "^3.0.2" + +to-regex-range@^2.1.0: + version "2.1.1" + resolved "https://registry.yarnpkg.com/to-regex-range/-/to-regex-range-2.1.1.tgz#7c80c17b9dfebe599e27367e0d4dd5590141db38" + dependencies: + is-number "^3.0.0" + repeat-string "^1.6.1" + +to-regex@^3.0.1, to-regex@^3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/to-regex/-/to-regex-3.0.2.tgz#13cfdd9b336552f30b51f33a8ae1b42a7a7599ce" + dependencies: + define-property "^2.0.2" + extend-shallow "^3.0.2" + regex-not "^1.0.2" + safe-regex "^1.1.0" + touch@0.0.3: version "0.0.3" resolved "https://registry.yarnpkg.com/touch/-/touch-0.0.3.tgz#51aef3d449571d4f287a5d87c9c8b49181a0db1d" @@ -5708,6 +7345,10 @@ tslib@^1.8.0: version "1.9.0" resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.9.0.tgz#e37a86fda8cbbaf23a057f473c9f4dc64e5fc2e8" +tslib@^1.9.0: + version "1.9.3" + resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.9.3.tgz#d7e4dd79245d85428c4d7e4822a79917954ca286" + tslint@^5.9.1: version "5.9.1" resolved "https://registry.yarnpkg.com/tslint/-/tslint-5.9.1.tgz#1255f87a3ff57eb0b0e1f0e610a8b4748046c9ae" @@ -5731,6 +7372,10 @@ tsutils@^2.12.1: dependencies: tslib "^1.7.1" +tty-browserify@0.0.0: + version "0.0.0" + resolved "https://registry.yarnpkg.com/tty-browserify/-/tty-browserify-0.0.0.tgz#a157ba402da24e9bf957f9aa69d524eed42901a6" + tunnel-agent@^0.6.0: version "0.6.0" resolved "https://registry.yarnpkg.com/tunnel-agent/-/tunnel-agent-0.6.0.tgz#27a5dea06b36b04a0a9966774b290868f0fc40fd" @@ -5805,6 +7450,13 @@ uglify-es@^3.0.18: commander "~2.11.0" source-map "~0.6.1" +uglify-es@^3.3.4: + version "3.3.9" + resolved "https://registry.yarnpkg.com/uglify-es/-/uglify-es-3.3.9.tgz#0c1c4f0700bed8dbc124cdb304d2592ca203e677" + dependencies: + commander "~2.13.0" + source-map "~0.6.1" + uglify-js@^2.6: version "2.8.29" resolved "https://registry.yarnpkg.com/uglify-js/-/uglify-js-2.8.29.tgz#29c5733148057bb4e1f75df35b7a9cb72e6a59dd" @@ -5825,6 +7477,19 @@ uglify-to-browserify@~1.0.0: version "1.0.2" resolved "https://registry.yarnpkg.com/uglify-to-browserify/-/uglify-to-browserify-1.0.2.tgz#6e0924d6bda6b5afe349e39a6d632850a0f882b7" +uglifyjs-webpack-plugin@^1.2.4: + version "1.2.7" + resolved "https://registry.yarnpkg.com/uglifyjs-webpack-plugin/-/uglifyjs-webpack-plugin-1.2.7.tgz#57638dd99c853a1ebfe9d97b42160a8a507f9d00" + dependencies: + cacache "^10.0.4" + find-cache-dir "^1.0.0" + schema-utils "^0.4.5" + serialize-javascript "^1.4.0" + source-map "^0.6.1" + uglify-es "^3.3.4" + webpack-sources "^1.1.0" + worker-farm "^1.5.2" + ultron@~1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/ultron/-/ultron-1.1.0.tgz#b07a2e6a541a815fc6a34ccd4533baec307ca864" @@ -5841,6 +7506,15 @@ underscore@~1.4.4: version "1.4.4" resolved "https://registry.yarnpkg.com/underscore/-/underscore-1.4.4.tgz#61a6a32010622afa07963bf325203cf12239d604" +union-value@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/union-value/-/union-value-1.0.0.tgz#5c71c34cb5bad5dcebe3ea0cd08207ba5aa1aea4" + dependencies: + arr-union "^3.1.0" + get-value "^2.0.6" + is-extendable "^0.1.1" + set-value "^0.4.3" + uniq@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/uniq/-/uniq-1.0.1.tgz#b31c5ae8254844a3a8281541ce2b04b865a734ff" @@ -5855,6 +7529,18 @@ uniqs@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/uniqs/-/uniqs-2.0.0.tgz#ffede4b36b25290696e6e165d4a59edb998e6b02" +unique-filename@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/unique-filename/-/unique-filename-1.1.0.tgz#d05f2fe4032560871f30e93cbe735eea201514f3" + dependencies: + unique-slug "^2.0.0" + +unique-slug@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/unique-slug/-/unique-slug-2.0.0.tgz#db6676e7c7cc0629878ff196097c78855ae9f4ab" + dependencies: + imurmurhash "^0.1.4" + unique-stream@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/unique-stream/-/unique-stream-1.0.0.tgz#d59a4a75427447d9aa6c91e70263f8d26a4b104b" @@ -5870,6 +7556,23 @@ unpipe@1.0.0, unpipe@~1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/unpipe/-/unpipe-1.0.0.tgz#b2bf4ee8514aae6165b4817829d21b2ef49904ec" +unset-value@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/unset-value/-/unset-value-1.0.0.tgz#8376873f7d2335179ffb1e6fc3a8ed0dfc8ab559" + dependencies: + has-value "^0.3.1" + isobject "^3.0.0" + +upath@^1.0.5: + version "1.1.0" + resolved "https://registry.yarnpkg.com/upath/-/upath-1.1.0.tgz#35256597e46a581db4793d0ce47fa9aebfc9fabd" + +uri-js@^4.2.1: + version "4.2.2" + resolved "https://registry.yarnpkg.com/uri-js/-/uri-js-4.2.2.tgz#94c540e1ff772956e2299507c010aea6c8838eb0" + dependencies: + punycode "^2.1.0" + urix@^0.1.0, urix@~0.1.0: version "0.1.0" resolved "https://registry.yarnpkg.com/urix/-/urix-0.1.0.tgz#da937f7a62e21fec1fd18d49b35c2935067a6c72" @@ -5878,6 +7581,17 @@ url-join@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/url-join/-/url-join-1.1.0.tgz#741c6c2f4596c4830d6718460920d0c92202dc78" +url@^0.11.0: + version "0.11.0" + resolved "https://registry.yarnpkg.com/url/-/url-0.11.0.tgz#3838e97cfc60521eb73c525a8e55bfdd9e2e28f1" + dependencies: + punycode "1.3.2" + querystring "0.2.0" + +use@^3.1.0: + version "3.1.1" + resolved "https://registry.yarnpkg.com/use/-/use-3.1.1.tgz#d50c8cac79a19fbc20f2911f56eb973f4e10070f" + user-home@^1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/user-home/-/user-home-1.1.1.tgz#2b5be23a32b63a7c9deb8d0f28d485724a3df190" @@ -5892,12 +7606,18 @@ util-deprecate@1.0.2, util-deprecate@~1.0.1: version "1.0.2" resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf" -"util@>=0.10.3 <1": +util@0.10.3, "util@>=0.10.3 <1": version "0.10.3" resolved "https://registry.yarnpkg.com/util/-/util-0.10.3.tgz#7afb1afe50805246489e3db7fe0ed379336ac0f9" dependencies: inherits "2.0.1" +util@^0.10.3: + version "0.10.4" + resolved "https://registry.yarnpkg.com/util/-/util-0.10.4.tgz#3aa0125bfe668a4672de58857d3ace27ecb76901" + dependencies: + inherits "2.0.3" + utils-merge@1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/utils-merge/-/utils-merge-1.0.1.tgz#9f95710f50a267947b2ccc124741c1028427e713" @@ -5906,6 +7626,10 @@ uuid@^3.0.0, uuid@^3.1.0: version "3.1.0" resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.1.0.tgz#3dd3d3e790abc24d7b0d3a034ffababe28ebbc04" +v8-compile-cache@^2.0.0: + version "2.0.2" + resolved "https://registry.yarnpkg.com/v8-compile-cache/-/v8-compile-cache-2.0.2.tgz#a428b28bb26790734c4fc8bc9fa106fccebf6a6c" + v8-inspect-profiler@^0.0.8: version "0.0.8" resolved "https://registry.yarnpkg.com/v8-inspect-profiler/-/v8-inspect-profiler-0.0.8.tgz#4d6bedb7c3d1bfc69e5bfdc2ded3d6784a5a76a6" @@ -6042,6 +7766,12 @@ vinyl@~2.0.1: remove-trailing-separator "^1.0.1" replace-ext "^1.0.0" +vm-browserify@0.0.4: + version "0.0.4" + resolved "https://registry.yarnpkg.com/vm-browserify/-/vm-browserify-0.0.4.tgz#5d7ea45bbef9e4a6ff65f95438e0a87c357d5a73" + dependencies: + indexof "0.0.1" + vsce@1.33.2: version "1.33.2" resolved "https://registry.yarnpkg.com/vsce/-/vsce-1.33.2.tgz#3645f69aaf984e22f74ea49d35f38dd18d66ff5f" @@ -6138,6 +7868,81 @@ vso-node-api@^6.1.2-preview: typed-rest-client "^0.9.0" underscore "^1.8.3" +watchpack@^1.5.0: + version "1.6.0" + resolved "https://registry.yarnpkg.com/watchpack/-/watchpack-1.6.0.tgz#4bc12c2ebe8aa277a71f1d3f14d685c7b446cd00" + dependencies: + chokidar "^2.0.2" + graceful-fs "^4.1.2" + neo-async "^2.5.0" + +webpack-cli@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/webpack-cli/-/webpack-cli-3.1.0.tgz#d71a83687dcfeb758fdceeb0fe042f96bcf62994" + dependencies: + chalk "^2.4.1" + cross-spawn "^6.0.5" + enhanced-resolve "^4.0.0" + global-modules-path "^2.1.0" + import-local "^1.0.0" + inquirer "^6.0.0" + interpret "^1.1.0" + loader-utils "^1.1.0" + supports-color "^5.4.0" + v8-compile-cache "^2.0.0" + yargs "^12.0.1" + +webpack-sources@^1.0.1, webpack-sources@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/webpack-sources/-/webpack-sources-1.1.0.tgz#a101ebae59d6507354d71d8013950a3a8b7a5a54" + dependencies: + source-list-map "^2.0.0" + source-map "~0.6.1" + +webpack-stream@^5.1.1: + version "5.1.1" + resolved "https://registry.yarnpkg.com/webpack-stream/-/webpack-stream-5.1.1.tgz#15b1d91da6887a37f6832128383ae0282bd7d0e7" + dependencies: + fancy-log "^1.3.2" + lodash.clone "^4.3.2" + lodash.some "^4.2.2" + memory-fs "^0.4.1" + plugin-error "^1.0.1" + supports-color "^5.3.0" + through "^2.3.8" + vinyl "^2.1.0" + webpack "^4.7.0" + +webpack@^4.16.5, webpack@^4.7.0: + version "4.16.5" + resolved "https://registry.yarnpkg.com/webpack/-/webpack-4.16.5.tgz#29fb39462823d7eb8aefcab8b45f7f241db0d092" + dependencies: + "@webassemblyjs/ast" "1.5.13" + "@webassemblyjs/helper-module-context" "1.5.13" + "@webassemblyjs/wasm-edit" "1.5.13" + "@webassemblyjs/wasm-opt" "1.5.13" + "@webassemblyjs/wasm-parser" "1.5.13" + acorn "^5.6.2" + acorn-dynamic-import "^3.0.0" + ajv "^6.1.0" + ajv-keywords "^3.1.0" + chrome-trace-event "^1.0.0" + enhanced-resolve "^4.1.0" + eslint-scope "^4.0.0" + json-parse-better-errors "^1.0.2" + loader-runner "^2.3.0" + loader-utils "^1.1.0" + memory-fs "~0.4.1" + micromatch "^3.1.8" + mkdirp "~0.5.0" + neo-async "^2.5.0" + node-libs-browser "^2.0.0" + schema-utils "^0.4.4" + tapable "^1.0.0" + uglifyjs-webpack-plugin "^1.2.4" + watchpack "^1.5.0" + webpack-sources "^1.0.1" + whet.extend@~0.9.9: version "0.9.9" resolved "https://registry.yarnpkg.com/whet.extend/-/whet.extend-0.9.9.tgz#f877d5bf648c97e5aa542fadc16d6a259b9c11a1" @@ -6195,6 +8000,12 @@ wordwrap@~0.0.2: version "0.0.3" resolved "https://registry.yarnpkg.com/wordwrap/-/wordwrap-0.0.3.tgz#a3d5da6cd5c0bc0008d37234bbaf1bed63059107" +worker-farm@^1.5.2: + version "1.6.0" + resolved "https://registry.yarnpkg.com/worker-farm/-/worker-farm-1.6.0.tgz#aecc405976fab5a95526180846f0dba288f3a4a0" + dependencies: + errno "~0.1.7" + wrap-ansi@^2.0.0: version "2.1.0" resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-2.1.0.tgz#d8fc3d284dd05794fe84973caecdd1cf824fdd85" @@ -6263,6 +8074,10 @@ xmldom@0.1.x: version "1.8.0" resolved "https://registry.yarnpkg.com/xmlhttprequest/-/xmlhttprequest-1.8.0.tgz#67fe075c5c24fef39f9d65f5f7b7fe75171968fc" +xregexp@4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/xregexp/-/xregexp-4.0.0.tgz#e698189de49dd2a18cc5687b05e17c8e43943020" + "xtend@>=4.0.0 <4.1.0-0", xtend@^4.0.0, xtend@~4.0.0, xtend@~4.0.1: version "4.0.1" resolved "https://registry.yarnpkg.com/xtend/-/xtend-4.0.1.tgz#a5c6d532be656e23db820efb943a1f04998d63af" @@ -6281,10 +8096,24 @@ y18n@^3.2.1: version "3.2.1" resolved "https://registry.yarnpkg.com/y18n/-/y18n-3.2.1.tgz#6d15fba884c08679c0d77e88e7759e811e07fa41" +"y18n@^3.2.1 || ^4.0.0", y18n@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/y18n/-/y18n-4.0.0.tgz#95ef94f85ecc81d007c264e190a120f0a3c8566b" + yallist@^2.1.2: version "2.1.2" resolved "https://registry.yarnpkg.com/yallist/-/yallist-2.1.2.tgz#1c11f9218f076089a47dd512f93c6699a6a81d52" +yallist@^3.0.0, yallist@^3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/yallist/-/yallist-3.0.2.tgz#8452b4bb7e83c7c188d8041c1a837c773d6d8bb9" + +yargs-parser@^10.1.0: + version "10.1.0" + resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-10.1.0.tgz#7202265b89f7e9e9f2e5765e0fe735a905edbaa8" + dependencies: + camelcase "^4.1.0" + yargs-parser@^8.1.0: version "8.1.0" resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-8.1.0.tgz#f1376a33b6629a5d063782944da732631e966950" @@ -6308,6 +8137,23 @@ yargs@^10.1.1: y18n "^3.2.1" yargs-parser "^8.1.0" +yargs@^12.0.1: + version "12.0.1" + resolved "https://registry.yarnpkg.com/yargs/-/yargs-12.0.1.tgz#6432e56123bb4e7c3562115401e98374060261c2" + dependencies: + cliui "^4.0.0" + decamelize "^2.0.0" + find-up "^3.0.0" + get-caller-file "^1.0.1" + os-locale "^2.0.0" + require-directory "^2.1.1" + require-main-filename "^1.0.1" + set-blocking "^2.0.0" + string-width "^2.0.0" + which-module "^2.0.0" + y18n "^3.2.1 || ^4.0.0" + yargs-parser "^10.1.0" + yargs@~3.10.0: version "3.10.0" resolved "https://registry.yarnpkg.com/yargs/-/yargs-3.10.0.tgz#f7ee7bd857dd7c1d2d38c0e74efbd681d1431fd1" From 779f79f68db4560fbf8c9524d683496b7bbff5a4 Mon Sep 17 00:00:00 2001 From: Johannes Rieken Date: Wed, 8 Aug 2018 17:01:10 +0200 Subject: [PATCH 0586/1276] use production-mode for git bundle --- extensions/git/extension.webpack.config.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/extensions/git/extension.webpack.config.js b/extensions/git/extension.webpack.config.js index 56b5787a7bd..3fbe8587fd4 100644 --- a/extensions/git/extension.webpack.config.js +++ b/extensions/git/extension.webpack.config.js @@ -8,7 +8,8 @@ const path = require('path'); module.exports = { - mode: 'none', + // mode: 'none', + mode: 'production', target: 'node', context: __dirname, entry: { From 8600035ba014dc029c69195ee43e311a179a56cc Mon Sep 17 00:00:00 2001 From: Christof Marti Date: Wed, 8 Aug 2018 17:11:17 +0200 Subject: [PATCH 0587/1276] Use QuickInput (#29096) --- .../electron-browser/extensionsActions.ts | 17 +++++++++-------- .../parts/logs/electron-browser/logsActions.ts | 18 +++++++++--------- .../preferences/browser/preferencesActions.ts | 17 ++++++++++------- .../parts/tasks/common/taskTemplates.ts | 4 ++-- .../electron-browser/task.contribution.ts | 4 +++- 5 files changed, 33 insertions(+), 27 deletions(-) diff --git a/src/vs/workbench/parts/extensions/electron-browser/extensionsActions.ts b/src/vs/workbench/parts/extensions/electron-browser/extensionsActions.ts index 35077d1000f..0d74ff218bd 100644 --- a/src/vs/workbench/parts/extensions/electron-browser/extensionsActions.ts +++ b/src/vs/workbench/parts/extensions/electron-browser/extensionsActions.ts @@ -46,12 +46,12 @@ import { INotificationService, Severity } from 'vs/platform/notification/common/ import { IOpenerService } from 'vs/platform/opener/common/opener'; import { mnemonicButtonLabel } from 'vs/base/common/labels'; import { IEnvironmentService } from 'vs/platform/environment/common/environment'; -import { IQuickOpenService, IPickOpenEntry } from 'vs/platform/quickOpen/common/quickOpen'; import { IEditorService } from 'vs/workbench/services/editor/common/editorService'; import { IEditorGroupsService } from 'vs/workbench/services/group/common/editorGroupsService'; import { ExtensionsInput } from 'vs/workbench/parts/extensions/common/extensionsInput'; import product from 'vs/platform/node/product'; import { ContextSubMenu } from 'vs/base/browser/contextmenu'; +import { IQuickPickItem, IQuickInputService } from 'vs/platform/quickinput/common/quickInput'; const promptDownloadManually = (extension: IGalleryExtension, message: string, instantiationService: IInstantiationService, notificationService: INotificationService, openerService: IOpenerService) => { const downloadUrl = `${product.extensionsGallery.serviceUrl}/publishers/${extension.publisher}/vsextensions/${extension.name}/${extension.version}/vspackage`; @@ -2694,7 +2694,7 @@ export class ReinstallAction extends Action { constructor( id: string = ReinstallAction.ID, label: string = ReinstallAction.LABEL, @IExtensionsWorkbenchService private extensionsWorkbenchService: IExtensionsWorkbenchService, - @IQuickOpenService private quickOpenService: IQuickOpenService, + @IQuickInputService private quickInputService: IQuickInputService, @INotificationService private notificationService: INotificationService, @IWindowService private windowService: IWindowService ) { @@ -2706,21 +2706,22 @@ export class ReinstallAction extends Action { } run(): TPromise { - return this.quickOpenService.pick(this.getEntries(), { placeHolder: localize('selectExtension', "Select Extension to Reinstall") }); + return this.quickInputService.pick(this.getEntries(), { placeHolder: localize('selectExtension', "Select Extension to Reinstall") }) + .then(pick => pick && this.reinstallExtension(pick.extension)); } - private getEntries(): TPromise { + private getEntries() { return this.extensionsWorkbenchService.queryLocal() .then(local => { - const entries: IPickOpenEntry[] = local + const entries = local .filter(extension => extension.type === LocalExtensionType.User) .map(extension => { - return { + return { id: extension.id, label: extension.displayName, description: extension.id, - run: () => this.reinstallExtension(extension), - }; + extension, + } as (IQuickPickItem & { extension: IExtension }); }); return entries; }); diff --git a/src/vs/workbench/parts/logs/electron-browser/logsActions.ts b/src/vs/workbench/parts/logs/electron-browser/logsActions.ts index 2fcdc413e3d..e9695b3cde0 100644 --- a/src/vs/workbench/parts/logs/electron-browser/logsActions.ts +++ b/src/vs/workbench/parts/logs/electron-browser/logsActions.ts @@ -9,13 +9,13 @@ import * as paths from 'vs/base/common/paths'; import { IEnvironmentService } from 'vs/platform/environment/common/environment'; import { IWindowsService, IWindowService } from 'vs/platform/windows/common/windows'; import { TPromise } from 'vs/base/common/winjs.base'; -import { IQuickOpenService, IPickOpenEntry } from 'vs/platform/quickOpen/common/quickOpen'; import { ILogService, LogLevel, DEFAULT_LOG_LEVEL } from 'vs/platform/log/common/log'; import { IOutputService, COMMAND_OPEN_LOG_VIEWER } from 'vs/workbench/parts/output/common/output'; import * as Constants from 'vs/workbench/parts/logs/common/logConstants'; import { ICommandService } from 'vs/platform/commands/common/commands'; import URI from 'vs/base/common/uri'; import { IWorkspaceContextService } from 'vs/platform/workspace/common/workspace'; +import { IQuickPickItem, IQuickInputService } from 'vs/platform/quickinput/common/quickInput'; export class OpenLogsFolderAction extends Action { @@ -40,7 +40,7 @@ export class ShowLogsAction extends Action { static LABEL = nls.localize('showLogs', "Show Logs..."); constructor(id: string, label: string, - @IQuickOpenService private quickOpenService: IQuickOpenService, + @IQuickInputService private quickInputService: IQuickInputService, @IOutputService private outputService: IOutputService, @IWorkspaceContextService private contextService: IWorkspaceContextService ) { @@ -48,14 +48,14 @@ export class ShowLogsAction extends Action { } run(): TPromise { - const entries: IPickOpenEntry[] = [ + const entries: IQuickPickItem[] = [ { id: Constants.rendererLogChannelId, label: this.contextService.getWorkspace().name ? nls.localize('rendererProcess', "Window ({0})", this.contextService.getWorkspace().name) : nls.localize('emptyWindow', "Window") }, { id: Constants.extHostLogChannelId, label: nls.localize('extensionHost', "Extension Host") }, { id: Constants.sharedLogChannelId, label: nls.localize('sharedProcess', "Shared") }, { id: Constants.mainLogChannelId, label: nls.localize('mainProcess', "Main") } ]; - return this.quickOpenService.pick(entries, { placeHolder: nls.localize('selectProcess', "Select Log for Process") }) + return this.quickInputService.pick(entries, { placeHolder: nls.localize('selectProcess', "Select Log for Process") }) .then(entry => { if (entry) { return this.outputService.showChannel(entry.id); @@ -71,7 +71,7 @@ export class OpenLogFileAction extends Action { static LABEL = nls.localize('openLogFile', "Open Log File..."); constructor(id: string, label: string, - @IQuickOpenService private quickOpenService: IQuickOpenService, + @IQuickInputService private quickInputService: IQuickInputService, @IEnvironmentService private environmentService: IEnvironmentService, @ICommandService private commandService: ICommandService, @IWindowService private windowService: IWindowService, @@ -81,7 +81,7 @@ export class OpenLogFileAction extends Action { } run(): TPromise { - const entries: IPickOpenEntry[] = [ + const entries: IQuickPickItem[] = [ { id: URI.file(paths.join(this.environmentService.logsPath, `renderer${this.windowService.getCurrentWindowId()}.log`)).fsPath, label: this.contextService.getWorkspace().name ? nls.localize('rendererProcess', "Window ({0})", this.contextService.getWorkspace().name) : nls.localize('emptyWindow', "Window") }, { id: URI.file(paths.join(this.environmentService.logsPath, `exthost${this.windowService.getCurrentWindowId()}.log`)).fsPath, label: nls.localize('extensionHost', "Extension Host") }, { id: URI.file(paths.join(this.environmentService.logsPath, `sharedprocess.log`)).fsPath, label: nls.localize('sharedProcess', "Shared") }, @@ -89,7 +89,7 @@ export class OpenLogFileAction extends Action { { id: URI.file(paths.join(this.environmentService.logsPath, `telemetry.log`)).fsPath, label: nls.localize('telemetry', "Telemetry") } ]; - return this.quickOpenService.pick(entries, { placeHolder: nls.localize('selectProcess', "Select Log for Process") }) + return this.quickInputService.pick(entries, { placeHolder: nls.localize('selectProcess', "Select Log for Process") }) .then(entry => { if (entry) { return this.commandService.executeCommand(COMMAND_OPEN_LOG_VIEWER, URI.file(entry.id)); @@ -105,7 +105,7 @@ export class SetLogLevelAction extends Action { static LABEL = nls.localize('setLogLevel', "Set Log Level..."); constructor(id: string, label: string, - @IQuickOpenService private quickOpenService: IQuickOpenService, + @IQuickInputService private quickInputService: IQuickInputService, @ILogService private logService: ILogService ) { super(id, label); @@ -123,7 +123,7 @@ export class SetLogLevelAction extends Action { { label: nls.localize('off', "Off"), level: LogLevel.Off, description: this.getDescription(LogLevel.Off, current) }, ]; - return this.quickOpenService.pick(entries, { placeHolder: nls.localize('selectLogLevel', "Select log level"), autoFocus: { autoFocusIndex: this.logService.getLevel() } }).then(entry => { + return this.quickInputService.pick(entries, { placeHolder: nls.localize('selectLogLevel', "Select log level"), activeItem: entries[this.logService.getLevel()] }).then(entry => { if (entry) { this.logService.setLevel(entry.level); } diff --git a/src/vs/workbench/parts/preferences/browser/preferencesActions.ts b/src/vs/workbench/parts/preferences/browser/preferencesActions.ts index 70beb50fe4f..95acd99a978 100644 --- a/src/vs/workbench/parts/preferences/browser/preferencesActions.ts +++ b/src/vs/workbench/parts/preferences/browser/preferencesActions.ts @@ -10,11 +10,13 @@ import URI from 'vs/base/common/uri'; import { Action } from 'vs/base/common/actions'; import { IDisposable, dispose } from 'vs/base/common/lifecycle'; import { IModeService } from 'vs/editor/common/services/modeService'; -import { IQuickOpenService, IPickOpenEntry, IFilePickOpenEntry } from 'vs/platform/quickOpen/common/quickOpen'; import { IPreferencesService } from 'vs/workbench/services/preferences/common/preferences'; import { IWorkspaceContextService, WorkbenchState, IWorkspaceFolder } from 'vs/platform/workspace/common/workspace'; import { ICommandService } from 'vs/platform/commands/common/commands'; import { PICK_WORKSPACE_FOLDER_COMMAND_ID } from 'vs/workbench/browser/actions/workspaceCommands'; +import { IQuickInputService, IQuickPickItem } from 'vs/platform/quickinput/common/quickInput'; +import { getIconClasses } from 'vs/workbench/browser/labels'; +import { IModelService } from 'vs/editor/common/services/modelService'; export class OpenRawDefaultSettingsAction extends Action { @@ -225,8 +227,9 @@ export class ConfigureLanguageBasedSettingsAction extends Action { constructor( id: string, label: string, + @IModelService private modelService: IModelService, @IModeService private modeService: IModeService, - @IQuickOpenService private quickOpenService: IQuickOpenService, + @IQuickInputService private quickInputService: IQuickInputService, @IPreferencesService private preferencesService: IPreferencesService ) { super(id, label); @@ -234,7 +237,7 @@ export class ConfigureLanguageBasedSettingsAction extends Action { public run(): TPromise { const languages = this.modeService.getRegisteredLanguageNames(); - const picks: IPickOpenEntry[] = languages.sort().map((lang, index) => { + const picks: IQuickPickItem[] = languages.sort().map((lang, index) => { let description: string = nls.localize('languageDescriptionConfigured', "({0})", this.modeService.getModeIdForLanguageName(lang.toLowerCase())); // construct a fake resource to be able to show nice icons if any let fakeResource: URI; @@ -247,14 +250,14 @@ export class ConfigureLanguageBasedSettingsAction extends Action { fakeResource = URI.file(filenames[0]); } } - return { + return { label: lang, - resource: fakeResource, + iconClasses: getIconClasses(this.modelService, this.modeService, fakeResource), description - }; + } as IQuickPickItem; }); - return this.quickOpenService.pick(picks, { placeHolder: nls.localize('pickLanguage', "Select Language") }) + return this.quickInputService.pick(picks, { placeHolder: nls.localize('pickLanguage', "Select Language") }) .then(pick => { if (pick) { return this.modeService.getOrCreateModeByLanguageName(pick.label) diff --git a/src/vs/workbench/parts/tasks/common/taskTemplates.ts b/src/vs/workbench/parts/tasks/common/taskTemplates.ts index e19cfd42648..77998b88ac6 100644 --- a/src/vs/workbench/parts/tasks/common/taskTemplates.ts +++ b/src/vs/workbench/parts/tasks/common/taskTemplates.ts @@ -6,9 +6,9 @@ import * as nls from 'vs/nls'; -import { IPickOpenEntry } from 'vs/platform/quickOpen/common/quickOpen'; +import { IQuickPickItem } from 'vs/platform/quickinput/common/quickInput'; -export interface TaskEntry extends IPickOpenEntry { +export interface TaskEntry extends IQuickPickItem { sort?: string; autoDetect: boolean; content: string; diff --git a/src/vs/workbench/parts/tasks/electron-browser/task.contribution.ts b/src/vs/workbench/parts/tasks/electron-browser/task.contribution.ts index 7e9cd0c4822..9f8b91f0d45 100644 --- a/src/vs/workbench/parts/tasks/electron-browser/task.contribution.ts +++ b/src/vs/workbench/parts/tasks/electron-browser/task.contribution.ts @@ -90,6 +90,7 @@ import { QuickOpenActionContributor } from '../browser/quickOpen'; import { Themable, STATUS_BAR_FOREGROUND, STATUS_BAR_NO_FOLDER_FOREGROUND } from 'vs/workbench/common/theme'; import { IThemeService } from 'vs/platform/theme/common/themeService'; +import { IQuickInputService } from 'vs/platform/quickinput/common/quickInput'; let tasksCategory = nls.localize('tasksCategory', "Tasks"); @@ -475,6 +476,7 @@ class TaskService implements ITaskService { @IModelService private modelService: IModelService, @IExtensionService private extensionService: IExtensionService, @IQuickOpenService private quickOpenService: IQuickOpenService, + @IQuickInputService private quickInputService: IQuickInputService, @IConfigurationResolverService private configurationResolverService: IConfigurationResolverService, @ITerminalService private terminalService: ITerminalService, @IStorageService private storageService: IStorageService, @@ -2205,7 +2207,7 @@ class TaskService implements ITaskService { if (stat) { return stat.resource; } - return this.quickOpenService.pick(getTaskTemplates(), { placeHolder: nls.localize('TaskService.template', 'Select a Task Template') }).then((selection) => { + return this.quickInputService.pick(getTaskTemplates(), { placeHolder: nls.localize('TaskService.template', 'Select a Task Template') }).then((selection) => { if (!selection) { return undefined; } From 32a051090f0c4aca1f56b424a1453abc45214a15 Mon Sep 17 00:00:00 2001 From: Johannes Rieken Date: Wed, 8 Aug 2018 17:43:07 +0200 Subject: [PATCH 0588/1276] :lipstick: --- build/lib/extensions.js | 2 +- build/lib/extensions.ts | 2 +- extensions/git/extension.webpack.config.js | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/build/lib/extensions.js b/build/lib/extensions.js index e923869d6d9..11c5e0c0b03 100644 --- a/build/lib/extensions.js +++ b/build/lib/extensions.js @@ -40,7 +40,7 @@ function fromLocal(extensionPath) { var patchFilesStream = filesStream .pipe(packageJsonFilter) .pipe(buffer()) - .pipe(json({ main: './dist/main.bundle' })) // hardcoded entry point! + .pipe(json({ main: './out/main.bundle' })) // hardcoded entry point! .pipe(packageJsonFilter.restore); var webpackConfig = require(path.join(extensionPath, 'extension.webpack.config.js')); var webpackStream = webpackGulp(webpackConfig, webpack) diff --git a/build/lib/extensions.ts b/build/lib/extensions.ts index 500d57517d3..90dd5502981 100644 --- a/build/lib/extensions.ts +++ b/build/lib/extensions.ts @@ -46,7 +46,7 @@ export function fromLocal(extensionPath: string): Stream { const patchFilesStream = filesStream .pipe(packageJsonFilter) .pipe(buffer()) - .pipe(json({ main: './dist/main.bundle' })) // hardcoded entry point! + .pipe(json({ main: './out/main.bundle' })) // hardcoded entry point! .pipe(packageJsonFilter.restore); const webpackConfig = require(path.join(extensionPath, 'extension.webpack.config.js')); diff --git a/extensions/git/extension.webpack.config.js b/extensions/git/extension.webpack.config.js index 3fbe8587fd4..d4f5bf626b4 100644 --- a/extensions/git/extension.webpack.config.js +++ b/extensions/git/extension.webpack.config.js @@ -14,11 +14,11 @@ module.exports = { context: __dirname, entry: { main: './out/main.js', - askpass: './out/askpass-main.js' + ['askpass-main']: './out/askpass-main.js' }, output: { filename: '[name].bundle.js', - path: path.join(__dirname, 'dist'), + path: path.join(__dirname, 'out'), libraryTarget: "commonjs" }, externals: { From 2f69a93b9d3231cb16cb71396503459b4894941f Mon Sep 17 00:00:00 2001 From: Benjamin Pasero Date: Wed, 8 Aug 2018 17:46:26 +0200 Subject: [PATCH 0589/1276] Join All Editor Groups should preserve which editor is active (fixes #54955) --- src/vs/workbench/browser/parts/editor/editorPart.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vs/workbench/browser/parts/editor/editorPart.ts b/src/vs/workbench/browser/parts/editor/editorPart.ts index c244fec9635..553ff7e0c65 100644 --- a/src/vs/workbench/browser/parts/editor/editorPart.ts +++ b/src/vs/workbench/browser/parts/editor/editorPart.ts @@ -702,7 +702,7 @@ export class EditorPart extends Part implements EditorGroupsServiceImpl, IEditor // Move/Copy editors over into target let index = (options && typeof options.index === 'number') ? options.index : targetView.count; sourceView.editors.forEach(editor => { - const inactive = !sourceView.isActive(editor); + const inactive = !sourceView.isActive(editor) || this._activeGroup !== sourceView; const copyOptions: ICopyEditorOptions = { index, inactive, preserveFocus: inactive }; if (options && options.mode === MergeGroupMode.COPY_EDITORS) { From 24f04eb738c4499dad55ed282abffb138c49b82b Mon Sep 17 00:00:00 2001 From: Miguel Solorio Date: Wed, 8 Aug 2018 08:49:13 -0700 Subject: [PATCH 0590/1276] Expand default text color to include items in the breadcrumb --- .../parts/outline/electron-browser/outlinePanel.css | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/vs/workbench/parts/outline/electron-browser/outlinePanel.css b/src/vs/workbench/parts/outline/electron-browser/outlinePanel.css index 278df4543ae..23afd397253 100644 --- a/src/vs/workbench/parts/outline/electron-browser/outlinePanel.css +++ b/src/vs/workbench/parts/outline/electron-browser/outlinePanel.css @@ -76,8 +76,9 @@ color: inherit !important; } -.monaco-tree.focused .selected .outline-element-label .monaco-highlighted-label .highlight{ - /* allows text color to overwrite highlight text when selected */ +.monaco-tree.focused .selected .outline-element-label .monaco-highlighted-label .highlight, +.monaco-tree.focused .selected .monaco-icon-label .monaco-highlighted-label .highlight{ + /* allows text color to use the default when selected */ color: inherit !important; } From 5ea0df99698a0a34a5e893be03f715aff3b8fe96 Mon Sep 17 00:00:00 2001 From: Alex Dima Date: Wed, 8 Aug 2018 17:51:51 +0200 Subject: [PATCH 0591/1276] Fixes #54899: Do not attempt to use real css loader in mocha unit tests --- test/all.js | 1 + test/css.mock.js | 12 ++++++++++++ 2 files changed, 13 insertions(+) create mode 100644 test/css.mock.js diff --git a/test/all.js b/test/all.js index 14c6897b197..2222c8995e9 100644 --- a/test/all.js +++ b/test/all.js @@ -49,6 +49,7 @@ function main() { nodeMain: __filename, baseUrl: path.join(path.dirname(__dirname), 'src'), paths: { + 'vs/css': '../test/css.mock', 'vs': `../${ out }/vs`, 'lib': `../${ out }/lib`, 'bootstrap': `../${ out }/bootstrap` diff --git a/test/css.mock.js b/test/css.mock.js new file mode 100644 index 00000000000..1829c6ae48e --- /dev/null +++ b/test/css.mock.js @@ -0,0 +1,12 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +define([], function() { + return { + load: function(name, req, load) { + load({}); + } + }; +}); From c816cc76a9d551f99b575b6e3c8761b2341a88a9 Mon Sep 17 00:00:00 2001 From: Benjamin Pasero Date: Wed, 8 Aug 2018 17:59:27 +0200 Subject: [PATCH 0592/1276] experiment: change default of closeOnFileDelete (for #47930) --- src/vs/workbench/electron-browser/main.contribution.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/vs/workbench/electron-browser/main.contribution.ts b/src/vs/workbench/electron-browser/main.contribution.ts index d6eb49d077a..a302df9185c 100644 --- a/src/vs/workbench/electron-browser/main.contribution.ts +++ b/src/vs/workbench/electron-browser/main.contribution.ts @@ -404,8 +404,8 @@ configurationRegistry.registerConfiguration({ }, 'workbench.editor.closeOnFileDelete': { 'type': 'boolean', - 'description': nls.localize('closeOnFileDelete', "Controls whether editors showing a file should close automatically when the file is deleted or renamed by some other process. Disabling this will keep the editor open as dirty on such an event. Note that deleting from within the application will always close the editor and that dirty files will never close to preserve your data."), - 'default': true + 'description': nls.localize('closeOnFileDelete', "Controls whether editors showing a file that was opened during the session should close automatically when getting deleted or renamed by some other process. Disabling this will keep the editor open on such an event. Note that deleting from within the application will always close the editor and that dirty files will never close to preserve your data."), + 'default': false }, 'workbench.editor.openPositioning': { 'type': 'string', From a8f286bac03ad9a4659dc3d6952638173d616642 Mon Sep 17 00:00:00 2001 From: Ramya Achutha Rao Date: Wed, 8 Aug 2018 09:02:58 -0700 Subject: [PATCH 0593/1276] Removed unused dependencies --- extensions/emmet/package.json | 4 +--- extensions/emmet/yarn.lock | 8 -------- 2 files changed, 1 insertion(+), 11 deletions(-) diff --git a/extensions/emmet/package.json b/extensions/emmet/package.json index ccf17588f3b..4197d1c45c6 100644 --- a/extensions/emmet/package.json +++ b/extensions/emmet/package.json @@ -447,8 +447,6 @@ "@emmetio/html-matcher": "^0.3.3", "@emmetio/math-expression": "^0.1.1", "image-size": "^0.5.2", - "vscode-emmet-helper": "^1.2.11", - "vscode-languageserver-types": "^3.5.0", - "vscode-nls": "3.2.4" + "vscode-emmet-helper": "^1.2.11" } } diff --git a/extensions/emmet/yarn.lock b/extensions/emmet/yarn.lock index 00ba81087eb..e910402265e 100644 --- a/extensions/emmet/yarn.lock +++ b/extensions/emmet/yarn.lock @@ -2123,18 +2123,10 @@ vscode-emmet-helper@^1.2.11: jsonc-parser "^1.0.0" vscode-languageserver-types "^3.6.0-next.1" -vscode-languageserver-types@^3.5.0: - version "3.5.0" - resolved "https://registry.yarnpkg.com/vscode-languageserver-types/-/vscode-languageserver-types-3.5.0.tgz#e48d79962f0b8e02de955e3f524908e2b19c0374" - vscode-languageserver-types@^3.6.0-next.1: version "3.6.0-next.1" resolved "https://registry.yarnpkg.com/vscode-languageserver-types/-/vscode-languageserver-types-3.6.0-next.1.tgz#98e488d3f87b666b4ee1a3d89f0023e246d358f3" -vscode-nls@3.2.4: - version "3.2.4" - resolved "https://registry.yarnpkg.com/vscode-nls/-/vscode-nls-3.2.4.tgz#2166b4183c8aea884d20727f5449e62be69fd398" - vscode@1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/vscode/-/vscode-1.0.1.tgz#3d161200615fe2af1d92ddc650751159411a513b" From a4b67733ecefa0ae73acbee3261a87b40e664406 Mon Sep 17 00:00:00 2001 From: Rachel Macfarlane Date: Wed, 8 Aug 2018 09:10:54 -0700 Subject: [PATCH 0594/1276] Ellipsis on text overflow in comments panel, fixes https://github.com/Microsoft/vscode-pull-request-github/issues/122 --- .../parts/comments/electron-browser/media/panel.css | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/vs/workbench/parts/comments/electron-browser/media/panel.css b/src/vs/workbench/parts/comments/electron-browser/media/panel.css index 45268e182f1..3c2b37bcf3f 100644 --- a/src/vs/workbench/parts/comments/electron-browser/media/panel.css +++ b/src/vs/workbench/parts/comments/electron-browser/media/panel.css @@ -30,8 +30,15 @@ opacity: 0.5; } +.comments-panel .comments-panel-container .tree-container .comment-container .text { + flex: 1; + min-width: 0; +} + .comments-panel .comments-panel-container .tree-container .comment-container .text * { margin: 0; + text-overflow: ellipsis; + overflow: hidden; } .comments-panel .comments-panel-container .message-box-container { @@ -49,6 +56,5 @@ .comments-panel .comments-panel-container .tree-container .comment-container { line-height: 22px; - text-overflow: ellipsis; - overflow: hidden; + margin-right: 5px; } \ No newline at end of file From 7fb22102199cf6f1ff83731bccce278859191fa0 Mon Sep 17 00:00:00 2001 From: Martin Aeschlimann Date: Wed, 8 Aug 2018 16:18:01 +0200 Subject: [PATCH 0595/1276] fix npe in hasToIgnoreCase (for #55916) --- src/vs/base/common/resources.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vs/base/common/resources.ts b/src/vs/base/common/resources.ts index f7e3ef3d8da..f12b995f032 100644 --- a/src/vs/base/common/resources.ts +++ b/src/vs/base/common/resources.ts @@ -18,7 +18,7 @@ export function getComparisonKey(resource: URI): string { export function hasToIgnoreCase(resource: URI): boolean { // A file scheme resource is in the same platform as code, so ignore case for non linux platforms // Resource can be from another platform. Lowering the case as an hack. Should come from File system provider - return resource.scheme === Schemas.file ? !isLinux : true; + return resource && resource.scheme === Schemas.file ? !isLinux : true; } export function basenameOrAuthority(resource: URI): string { From 2525f401ea2dcc88a7c37699ce6cbc5c8609da0a Mon Sep 17 00:00:00 2001 From: Martin Aeschlimann Date: Wed, 8 Aug 2018 18:06:14 +0200 Subject: [PATCH 0596/1276] improve fix for #55891 --- src/vs/workbench/api/node/apiCommands.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/vs/workbench/api/node/apiCommands.ts b/src/vs/workbench/api/node/apiCommands.ts index 9adcf231889..6be39d21aaa 100644 --- a/src/vs/workbench/api/node/apiCommands.ts +++ b/src/vs/workbench/api/node/apiCommands.ts @@ -49,8 +49,8 @@ export class OpenFolderAPICommand { return executor.executeCommand('_files.pickFolderAndOpen', forceNewWindow); } if (!uri.scheme) { - console.warn('`vscode.openFolder` command invoked with an invalid URI (scheme missing): `${uri}`. Converted to a `file://` URI.'); - uri = URI.file(uri.fsPath); + console.warn(`'vscode.openFolder' command invoked with an invalid URI (scheme missing): '${uri}'. Converted to a 'file://' URI.`); + uri = URI.file(uri.toString()); } return executor.executeCommand('_files.windowOpen', [uri], forceNewWindow); From 8634e574c8ee8dc8f98a8bfc1e77168a00138e16 Mon Sep 17 00:00:00 2001 From: Martin Aeschlimann Date: Wed, 8 Aug 2018 17:42:42 +0200 Subject: [PATCH 0597/1276] VSCode Insiders crashes on open with TypeError: Cannot read property 'lastIndexOf' of undefined. Fixes #54933 --- .../electron-main/historyMainService.ts | 54 +++++++++++++------ 1 file changed, 37 insertions(+), 17 deletions(-) diff --git a/src/vs/platform/history/electron-main/historyMainService.ts b/src/vs/platform/history/electron-main/historyMainService.ts index 796cfaffb92..518916342b0 100644 --- a/src/vs/platform/history/electron-main/historyMainService.ts +++ b/src/vs/platform/history/electron-main/historyMainService.ts @@ -26,10 +26,14 @@ import { Schemas } from 'vs/base/common/network'; import { IUriDisplayService } from 'vs/platform/uriDisplay/common/uriDisplay'; interface ISerializedRecentlyOpened { - workspaces: (IWorkspaceIdentifier | string | UriComponents)[]; + workspaces2: (IWorkspaceIdentifier | string)[]; // IWorkspaceIdentifier or URI.toString() files: string[]; } +interface ILegacySerializedRecentlyOpened { + workspaces: (IWorkspaceIdentifier | string | UriComponents)[]; // legacy (UriComponents was also supported for a few insider builds) +} + export class HistoryMainService implements IHistoryMainService { private static readonly MAX_TOTAL_RECENT_ENTRIES = 100; @@ -246,35 +250,51 @@ export class HistoryMainService implements IHistoryMainService { } private getRecentlyOpenedFromStorage(): IRecentlyOpened { - const storedRecents: ISerializedRecentlyOpened = this.stateService.getItem(HistoryMainService.recentlyOpenedStorageKey); + const storedRecents = this.stateService.getItem(HistoryMainService.recentlyOpenedStorageKey); const result: IRecentlyOpened = { workspaces: [], files: [] }; - if (storedRecents && Array.isArray(storedRecents.workspaces)) { - for (const workspace of storedRecents.workspaces) { - if (typeof workspace === 'string') { - result.workspaces.push(URI.file(workspace)); - } else if (isWorkspaceIdentifier(workspace)) { - result.workspaces.push(workspace); - } else { - result.workspaces.push(URI.revive(workspace)); + if (storedRecents) { + if (Array.isArray(storedRecents.workspaces2)) { + for (const workspace of storedRecents.workspaces2) { + if (isWorkspaceIdentifier(workspace)) { + result.workspaces.push(workspace); + } else if (typeof workspace === 'string') { + result.workspaces.push(URI.parse(workspace)); + } + } + } else if (Array.isArray(storedRecents.workspaces)) { + // format of 1.25 and before + for (const workspace of storedRecents.workspaces) { + if (typeof workspace === 'string') { + result.workspaces.push(URI.file(workspace)); + } else if (isWorkspaceIdentifier(workspace)) { + result.workspaces.push(workspace); + } else if (workspace && typeof workspace.path === 'string' && typeof workspace.scheme === 'string') { + // added by 1.26-insiders + result.workspaces.push(URI.revive(workspace)); + } + } + } + if (Array.isArray(storedRecents.files)) { + for (const file of storedRecents.files) { + if (typeof file === 'string') { + result.files.push(file); + } } } - } - if (storedRecents && Array.isArray(storedRecents.files)) { - result.files.push(...storedRecents.files); } return result; } private saveRecentlyOpened(recent: IRecentlyOpened): void { - const serialized: ISerializedRecentlyOpened = { workspaces: [], files: recent.files }; + const serialized: ISerializedRecentlyOpened = { workspaces2: [], files: recent.files }; for (const workspace of recent.workspaces) { if (isSingleFolderWorkspaceIdentifier(workspace)) { - serialized.workspaces.push(workspace.toJSON()); + serialized.workspaces2.push(workspace.toString()); } else { - serialized.workspaces.push(workspace); + serialized.workspaces2.push(workspace); } } - this.stateService.setItem(HistoryMainService.recentlyOpenedStorageKey, recent); + this.stateService.setItem(HistoryMainService.recentlyOpenedStorageKey, serialized); } updateWindowsJumpList(): void { From 75ed96b699897d94fb9b69c339199bfe2ecfa98e Mon Sep 17 00:00:00 2001 From: Martin Aeschlimann Date: Wed, 8 Aug 2018 18:20:57 +0200 Subject: [PATCH 0598/1276] todo to remove legacy support --- src/vs/platform/history/electron-main/historyMainService.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/src/vs/platform/history/electron-main/historyMainService.ts b/src/vs/platform/history/electron-main/historyMainService.ts index 518916342b0..e98b36915e1 100644 --- a/src/vs/platform/history/electron-main/historyMainService.ts +++ b/src/vs/platform/history/electron-main/historyMainService.ts @@ -262,6 +262,7 @@ export class HistoryMainService implements IHistoryMainService { } } } else if (Array.isArray(storedRecents.workspaces)) { + // TODO legacy support can be removed at some point (6 month?) // format of 1.25 and before for (const workspace of storedRecents.workspaces) { if (typeof workspace === 'string') { From 367e841dccd4ecb0ff47a44f19108bc10068579d Mon Sep 17 00:00:00 2001 From: Gopal Goel Date: Wed, 8 Aug 2018 22:51:34 +0530 Subject: [PATCH 0599/1276] Append "for '.xyz' files" in "Don't Show Again" menu item label #55814 (#55984) --- .../parts/extensions/electron-browser/extensionTipsService.ts | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/vs/workbench/parts/extensions/electron-browser/extensionTipsService.ts b/src/vs/workbench/parts/extensions/electron-browser/extensionTipsService.ts index 5550d05036c..79af9338ba2 100644 --- a/src/vs/workbench/parts/extensions/electron-browser/extensionTipsService.ts +++ b/src/vs/workbench/parts/extensions/electron-browser/extensionTipsService.ts @@ -673,8 +673,7 @@ export class ExtensionTipsService extends Disposable implements IExtensionTipsSe }); } }, { - label: choiceNever, - isSecondary: true, + label: localize('dontShowAgainExtension', "Don't Show Again for '.{0}' files", fileExtension), run: () => { fileExtensionSuggestionIgnoreList.push(fileExtension); this.storageService.store( From 7badcf506bcdd215abb64881c4b7bb2199fba637 Mon Sep 17 00:00:00 2001 From: Rachel Macfarlane Date: Wed, 8 Aug 2018 10:23:14 -0700 Subject: [PATCH 0600/1276] Add back changes lost on merge --- .../electron-browser/commentThreadWidget.ts | 81 ++++++++++++------- 1 file changed, 50 insertions(+), 31 deletions(-) diff --git a/src/vs/workbench/parts/comments/electron-browser/commentThreadWidget.ts b/src/vs/workbench/parts/comments/electron-browser/commentThreadWidget.ts index 7f3ab3650f8..2d4ce2edcff 100644 --- a/src/vs/workbench/parts/comments/electron-browser/commentThreadWidget.ts +++ b/src/vs/workbench/parts/comments/electron-browser/commentThreadWidget.ts @@ -119,6 +119,7 @@ export class ReviewZoneWidget extends ZoneWidget { private _localToDispose: IDisposable[]; private _markdownRenderer: MarkdownRenderer; private _styleElement: HTMLStyleElement; + private _error: HTMLElement; public get owner(): number { return this._owner; @@ -367,6 +368,8 @@ export class ReviewZoneWidget extends ZoneWidget { } })); + this._error = $('.validation-error.hidden').appendTo(this._commentForm).getHTMLElement(); + const formActions = $('.form-actions').appendTo(this._commentForm).getHTMLElement(); const button = new Button(formActions); @@ -383,39 +386,9 @@ export class ReviewZoneWidget extends ZoneWidget { })); button.onDidClick(async () => { - let newCommentThread; - if (this._commentThread.threadId) { - // reply - newCommentThread = await this.commentService.replyToCommentThread( - this._owner, - this.editor.getModel().uri, - new Range(lineNumber, 1, lineNumber, 1), - this._commentThread, - this._commentEditor.getValue() - ); - } else { - newCommentThread = await this.commentService.createNewCommentThread( - this._owner, - this.editor.getModel().uri, - new Range(lineNumber, 1, lineNumber, 1), - this._commentEditor.getValue() - ); - - this.createReplyButton(); - this.createParticipantsLabel(); - } - - this._commentEditor.setValue(''); - if (dom.hasClass(this._commentForm, 'expand')) { - dom.removeClass(this._commentForm, 'expand'); - } - - if (newCommentThread) { - this.update(newCommentThread); - } + this.createComment(lineNumber); }); - this._resizeObserver = new MutationObserver(this._refresh.bind(this)); this._resizeObserver.observe(this._bodyElement, { @@ -435,6 +408,52 @@ export class ReviewZoneWidget extends ZoneWidget { } } + private async createComment(lineNumber: number): Promise { + try { + let newCommentThread; + + if (this._commentThread.threadId) { + // reply + newCommentThread = await this.commentService.replyToCommentThread( + this._owner, + this.editor.getModel().uri, + new Range(lineNumber, 1, lineNumber, 1), + this._commentThread, + this._commentEditor.getValue() + ); + } else { + newCommentThread = await this.commentService.createNewCommentThread( + this._owner, + this.editor.getModel().uri, + new Range(lineNumber, 1, lineNumber, 1), + this._commentEditor.getValue() + ); + + if (newCommentThread) { + this.createReplyButton(); + this.createParticipantsLabel(); + } + } + + if (newCommentThread) { + this._commentEditor.setValue(''); + if (dom.hasClass(this._commentForm, 'expand')) { + dom.removeClass(this._commentForm, 'expand'); + } + this._commentEditor.getDomNode().style.outline = ''; + this._error.textContent = ''; + dom.addClass(this._error, 'hidden'); + this.update(newCommentThread); + } + } catch (e) { + this._error.textContent = e.message + ? nls.localize('commentCreationError', "Adding a comment failed: {0}.", e.message) + : nls.localize('commentCreationDefaultError', "Adding a comment failed. Please try again or report an issue with the extension if the problem persists."); + this._commentEditor.getDomNode().style.outline = `1px solid ${this.themeService.getTheme().getColor(inputValidationErrorBorder)}`; + dom.removeClass(this._error, 'hidden'); + } + } + createParticipantsLabel() { const primaryHeading = 'Participants:'; $(this._primaryHeading).safeInnerHtml(primaryHeading); From a6d1949dca839af0f7e1e8cc323c6d9db5982f43 Mon Sep 17 00:00:00 2001 From: Jackson Kearl Date: Wed, 8 Aug 2018 10:32:11 -0700 Subject: [PATCH 0601/1276] Improve UX for deprecated settings (#55977) * New settings editor shows depracted settings (only) when modified * Add localized depracation text to augment the existing (nonlocalized) message * Make deprecation warning less wordy, given they are already localized --- .../parts/preferences/browser/settingsTree.ts | 6 ++++-- .../services/preferences/common/preferences.ts | 1 + .../services/preferences/common/preferencesModels.ts | 11 +++++++++-- 3 files changed, 14 insertions(+), 4 deletions(-) diff --git a/src/vs/workbench/parts/preferences/browser/settingsTree.ts b/src/vs/workbench/parts/preferences/browser/settingsTree.ts index 0afa7baa54c..eaa91fd368b 100644 --- a/src/vs/workbench/parts/preferences/browser/settingsTree.ts +++ b/src/vs/workbench/parts/preferences/browser/settingsTree.ts @@ -145,7 +145,8 @@ export class SettingsTreeModel { if (tocEntry.children) { element.children = tocEntry.children.map(child => this.createSettingsTreeGroupElement(child, element)); } else if (tocEntry.settings) { - element.children = tocEntry.settings.map(s => this.createSettingsTreeSettingElement(s, element)); + element.children = tocEntry.settings.map(s => this.createSettingsTreeSettingElement(s, element)) + .filter(el => el.setting.deprecationMessage ? el.isConfigured : true); } this._treeElementsById.set(element.id, element); @@ -1413,7 +1414,8 @@ export class SearchResultModel { updateChildren(): void { this.children = this.getFlatSettings() - .map(s => createSettingsTreeSettingElement(s, this, this._viewState.settingsTarget, this._configurationService)); + .map(s => createSettingsTreeSettingElement(s, this, this._viewState.settingsTarget, this._configurationService)) + .filter(el => el.setting.deprecationMessage ? el.isConfigured : true); if (this.newExtensionSearchResults) { const newExtElement = new SettingsTreeNewExtensionsElement(); diff --git a/src/vs/workbench/services/preferences/common/preferences.ts b/src/vs/workbench/services/preferences/common/preferences.ts index 45f0caf3b35..9718d8eaf1b 100644 --- a/src/vs/workbench/services/preferences/common/preferences.ts +++ b/src/vs/workbench/services/preferences/common/preferences.ts @@ -44,6 +44,7 @@ export interface ISetting { descriptionRanges: IRange[]; overrides?: ISetting[]; overrideOf?: ISetting; + deprecationMessage?: string; // TODO@roblou maybe need new type and new EditorModel for GUI editor instead of ISetting which is used for text settings editor type?: string | string[]; diff --git a/src/vs/workbench/services/preferences/common/preferencesModels.ts b/src/vs/workbench/services/preferences/common/preferencesModels.ts index 1898d088670..ac27d3ccf50 100644 --- a/src/vs/workbench/services/preferences/common/preferencesModels.ts +++ b/src/vs/workbench/services/preferences/common/preferencesModels.ts @@ -551,9 +551,15 @@ export class DefaultSettings extends Disposable { let result: ISetting[] = []; for (let key in settingsObject) { const prop = settingsObject[key]; - if (!prop.deprecationMessage && this.matchesScope(prop)) { + if (this.matchesScope(prop)) { const value = prop.default; const description = (prop.description || '').split('\n'); + if (prop.deprecationMessage) { + description.push( + '', + prop.deprecationMessage, + nls.localize('deprecatedSetting.unstable', "This setting should not be used, and will be removed in a future release.")); + } const overrides = OVERRIDE_PROPERTY_PATTERN.test(key) ? this.parseOverrideSettings(prop.default) : []; result.push({ key, @@ -567,7 +573,8 @@ export class DefaultSettings extends Disposable { type: prop.type, enum: prop.enum, enumDescriptions: prop.enumDescriptions, - tags: prop.tags + tags: prop.tags, + deprecationMessage: prop.deprecationMessage, }); } } From 4dff8da77b01c16f4bd023883dd99745fc412bda Mon Sep 17 00:00:00 2001 From: Jackson Kearl Date: Wed, 8 Aug 2018 10:43:16 -0700 Subject: [PATCH 0602/1276] remove comments for more proper json --- extensions/javascript/javascript-language-configuration.json | 1 - extensions/typescript-basics/language-configuration.json | 1 - 2 files changed, 2 deletions(-) diff --git a/extensions/javascript/javascript-language-configuration.json b/extensions/javascript/javascript-language-configuration.json index 72fa7c6cc81..b41053843cf 100644 --- a/extensions/javascript/javascript-language-configuration.json +++ b/extensions/javascript/javascript-language-configuration.json @@ -25,7 +25,6 @@ ["\"", "\""], ["`", "`"] ], - // add ` as an autocloseBefore because templated backtick strings are common "autoCloseBefore": ";:.,=}])>` \n\t", "folding": { "markers": { diff --git a/extensions/typescript-basics/language-configuration.json b/extensions/typescript-basics/language-configuration.json index 72fa7c6cc81..b41053843cf 100644 --- a/extensions/typescript-basics/language-configuration.json +++ b/extensions/typescript-basics/language-configuration.json @@ -25,7 +25,6 @@ ["\"", "\""], ["`", "`"] ], - // add ` as an autocloseBefore because templated backtick strings are common "autoCloseBefore": ";:.,=}])>` \n\t", "folding": { "markers": { From ceb720c643eae08c61414240f62c43a774080eb5 Mon Sep 17 00:00:00 2001 From: Peng Lyu Date: Wed, 8 Aug 2018 11:59:21 -0700 Subject: [PATCH 0603/1276] Re Microsoft/vscode-pull-request-github#135. Do not dipose newCommentWidget when collapsed. --- .../parts/comments/electron-browser/commentThreadWidget.ts | 4 +++- .../comments/electron-browser/commentsEditorContribution.ts | 1 - 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/src/vs/workbench/parts/comments/electron-browser/commentThreadWidget.ts b/src/vs/workbench/parts/comments/electron-browser/commentThreadWidget.ts index 2d4ce2edcff..80acb6b6adc 100644 --- a/src/vs/workbench/parts/comments/electron-browser/commentThreadWidget.ts +++ b/src/vs/workbench/parts/comments/electron-browser/commentThreadWidget.ts @@ -582,7 +582,9 @@ export class ReviewZoneWidget extends ZoneWidget { this.show({ lineNumber: lineNumber, column: 1 }, 2); } else { this.hide(); - this._onDidClose.fire(); + if (this._commentThread === null) { + this.dispose(); + } } } } diff --git a/src/vs/workbench/parts/comments/electron-browser/commentsEditorContribution.ts b/src/vs/workbench/parts/comments/electron-browser/commentsEditorContribution.ts index 67c5564c499..175e36282e3 100644 --- a/src/vs/workbench/parts/comments/electron-browser/commentsEditorContribution.ts +++ b/src/vs/workbench/parts/comments/electron-browser/commentsEditorContribution.ts @@ -396,7 +396,6 @@ export class ReviewController implements IEditorContribution { }, {}); this._newCommentWidget.onDidClose(e => { - this._newCommentWidget.dispose(); this._newCommentWidget = null; }); this._newCommentWidget.display(lineNumber, this._commentingRangeDecorator.commentsOptions); From 038b0b86c8ada759ccabe41dea065c1eabcfd38a Mon Sep 17 00:00:00 2001 From: Ilya Rodionov Date: Wed, 8 Aug 2018 23:25:31 +0300 Subject: [PATCH 0604/1276] Middle Click to remove breakpoint. --- .../workbench/parts/debug/browser/breakpointsView.ts | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/vs/workbench/parts/debug/browser/breakpointsView.ts b/src/vs/workbench/parts/debug/browser/breakpointsView.ts index 2a869ab101f..33605695d12 100644 --- a/src/vs/workbench/parts/debug/browser/breakpointsView.ts +++ b/src/vs/workbench/parts/debug/browser/breakpointsView.ts @@ -91,17 +91,29 @@ export class BreakpointsView extends ViewletPanel { this.disposables.push(this.list.onOpen(e => { let isSingleClick = false; let isDoubleClick = false; + let isMiddleClick = false; let openToSide = false; const browserEvent = e.browserEvent; if (browserEvent instanceof MouseEvent) { isSingleClick = browserEvent.detail === 1; isDoubleClick = browserEvent.detail === 2; + isMiddleClick = browserEvent.button === 1; openToSide = (browserEvent.ctrlKey || browserEvent.metaKey || browserEvent.altKey); } const focused = this.list.getFocusedElements(); const element = focused.length ? focused[0] : undefined; + + if (isMiddleClick) { + if (element instanceof Breakpoint) { + this.debugService.removeBreakpoints(element.getId()); + } else if (element instanceof FunctionBreakpoint) { + this.debugService.removeFunctionBreakpoints(element.getId()); + } + return; + } + if (element instanceof Breakpoint) { openBreakpointSource(element, openToSide, isSingleClick, this.debugService, this.editorService).done(undefined, onUnexpectedError); } From 48f33262a61a020c9c7155a3caa92762f45c0c71 Mon Sep 17 00:00:00 2001 From: Rob Lourens Date: Wed, 8 Aug 2018 16:05:29 -0700 Subject: [PATCH 0605/1276] #55478 - render description vs markdownDescription correctly --- .../common/config/commonEditorConfig.ts | 2 +- .../parts/preferences/browser/settingsTree.ts | 25 +++++++++++-------- .../electron-browser/preferencesSearch.ts | 1 + .../preferences/common/preferences.ts | 2 ++ .../preferences/common/preferencesModels.ts | 19 +++++++++++--- 5 files changed, 35 insertions(+), 14 deletions(-) diff --git a/src/vs/editor/common/config/commonEditorConfig.ts b/src/vs/editor/common/config/commonEditorConfig.ts index 08cc4613dfc..b6c7a9941da 100644 --- a/src/vs/editor/common/config/commonEditorConfig.ts +++ b/src/vs/editor/common/config/commonEditorConfig.ts @@ -283,7 +283,7 @@ const editorConfiguration: IConfigurationNode = { 'type': 'number', 'default': EDITOR_MODEL_DEFAULTS.tabSize, 'minimum': 1, - 'description': nls.localize('tabSize', "The number of spaces a tab is equal to. This setting is overridden based on the file contents when `#editor.detectIndentation#` is on."), + 'markdownDescription': nls.localize('tabSize', "The number of spaces a tab is equal to. This setting is overridden based on the file contents when `#editor.detectIndentation#` is on."), 'errorMessage': nls.localize('tabSize.errorMessage', "Expected 'number'. Note that the value \"auto\" has been replaced by the `editor.detectIndentation` setting.") }, 'editor.insertSpaces': { diff --git a/src/vs/workbench/parts/preferences/browser/settingsTree.ts b/src/vs/workbench/parts/preferences/browser/settingsTree.ts index eaa91fd368b..58853e72e65 100644 --- a/src/vs/workbench/parts/preferences/browser/settingsTree.ts +++ b/src/vs/workbench/parts/preferences/browser/settingsTree.ts @@ -1017,18 +1017,23 @@ export class SettingsRenderer implements ITreeRenderer { template.labelElement.textContent = element.displayLabel; template.labelElement.title = titleTooltip; - const renderedDescription = this.renderDescriptionMarkdown(element.description, template.toDispose); - template.descriptionElement.innerHTML = ''; - template.descriptionElement.appendChild(renderedDescription); - (renderedDescription.querySelectorAll('a')).forEach(aElement => { - aElement.tabIndex = isSelected ? 0 : -1; - }); - const result = this.renderValue(element, isSelected, templateId, template); + template.descriptionElement.innerHTML = ''; + let needsManualOverflowIndicator = false; + if (element.setting.descriptionIsMarkdown) { + const renderedDescription = this.renderDescriptionMarkdown(element.description, template.toDispose); + template.descriptionElement.appendChild(renderedDescription); + (renderedDescription.querySelectorAll('a')).forEach(aElement => { + aElement.tabIndex = isSelected ? 0 : -1; + }); + + const firstLineOverflows = renderedDescription.firstElementChild && renderedDescription.firstElementChild.clientHeight > 18; + const hasExtraLines = renderedDescription.childElementCount > 1; + needsManualOverflowIndicator = (hasExtraLines || result.overflows) && !firstLineOverflows && !isSelected; + } else { + template.descriptionElement.innerText = element.description; + } - const firstLineOverflows = renderedDescription.firstElementChild && renderedDescription.firstElementChild.clientHeight > 18; - const hasExtraLines = renderedDescription.childElementCount > 1; - const needsManualOverflowIndicator = (hasExtraLines || result.overflows) && !firstLineOverflows && !isSelected; DOM.toggleClass(template.descriptionElement, 'setting-item-description-artificial-overflow', needsManualOverflowIndicator); template.isConfiguredElement.textContent = element.isConfigured ? localize('configured', "Modified") : ''; diff --git a/src/vs/workbench/parts/preferences/electron-browser/preferencesSearch.ts b/src/vs/workbench/parts/preferences/electron-browser/preferencesSearch.ts index ac1fc3c1c1b..1fffc1a2884 100644 --- a/src/vs/workbench/parts/preferences/electron-browser/preferencesSearch.ts +++ b/src/vs/workbench/parts/preferences/electron-browser/preferencesSearch.ts @@ -405,6 +405,7 @@ function escapeSpecialChars(query: string): string { function remoteSettingToISetting(remoteSetting: IRemoteSetting): IExtensionSetting { return { description: remoteSetting.description.split('\n'), + descriptionIsMarkdown: false, descriptionRanges: null, key: remoteSetting.key, keyRange: null, diff --git a/src/vs/workbench/services/preferences/common/preferences.ts b/src/vs/workbench/services/preferences/common/preferences.ts index 9718d8eaf1b..79610895b83 100644 --- a/src/vs/workbench/services/preferences/common/preferences.ts +++ b/src/vs/workbench/services/preferences/common/preferences.ts @@ -41,6 +41,7 @@ export interface ISetting { value: any; valueRange: IRange; description: string[]; + descriptionIsMarkdown: boolean; descriptionRanges: IRange[]; overrides?: ISetting[]; overrideOf?: ISetting; @@ -50,6 +51,7 @@ export interface ISetting { type?: string | string[]; enum?: string[]; enumDescriptions?: string[]; + enumDescriptionsAreMarkdown?: boolean; tags?: string[]; } diff --git a/src/vs/workbench/services/preferences/common/preferencesModels.ts b/src/vs/workbench/services/preferences/common/preferencesModels.ts index ac27d3ccf50..c762fddfdd8 100644 --- a/src/vs/workbench/services/preferences/common/preferencesModels.ts +++ b/src/vs/workbench/services/preferences/common/preferencesModels.ts @@ -267,6 +267,7 @@ function parse(model: ITextModel, isSettingsProperty: (currentProperty: string, let settingStartPosition = model.getPositionAt(offset); const setting: ISetting = { description: [], + descriptionIsMarkdown: false, key: name, keyRange: { startLineNumber: settingStartPosition.lineNumber, @@ -553,7 +554,7 @@ export class DefaultSettings extends Disposable { const prop = settingsObject[key]; if (this.matchesScope(prop)) { const value = prop.default; - const description = (prop.description || '').split('\n'); + const description = (prop.description || prop.markdownDescription || '').split('\n'); if (prop.deprecationMessage) { description.push( '', @@ -565,6 +566,7 @@ export class DefaultSettings extends Disposable { key, value, description, + descriptionIsMarkdown: !prop.description, range: null, keyRange: null, valueRange: null, @@ -572,7 +574,8 @@ export class DefaultSettings extends Disposable { overrides, type: prop.type, enum: prop.enum, - enumDescriptions: prop.enumDescriptions, + enumDescriptions: prop.enumDescriptions || prop.markdownEnumDescriptions, + enumDescriptionsAreMarkdown: !prop.enumDescriptions, tags: prop.tags, deprecationMessage: prop.deprecationMessage, }); @@ -582,7 +585,17 @@ export class DefaultSettings extends Disposable { } private parseOverrideSettings(overrideSettings: any): ISetting[] { - return Object.keys(overrideSettings).map((key) => ({ key, value: overrideSettings[key], description: [], range: null, keyRange: null, valueRange: null, descriptionRanges: [], overrides: [] })); + return Object.keys(overrideSettings).map((key) => ({ + key, + value: overrideSettings[key], + description: [], + descriptionIsMarkdown: false, + range: null, + keyRange: null, + valueRange: null, + descriptionRanges: [], + overrides: [] + })); } private matchesScope(property: IConfigurationNode): boolean { From a0764210a83adf55e2e307bdc5b5a498c406a1d6 Mon Sep 17 00:00:00 2001 From: Rob Lourens Date: Wed, 8 Aug 2018 17:01:37 -0700 Subject: [PATCH 0606/1276] #55478 - switch all builtin settings to 'markdownDescription' instead of 'description' where needed --- extensions/css-language-features/package.json | 30 +++++++++---------- extensions/emmet/package.json | 18 +++++------ extensions/git/package.json | 4 +-- extensions/npm/package.json | 4 +-- .../typescript-language-features/package.json | 10 +++---- .../common/config/commonEditorConfig.ts | 24 +++++++-------- .../electron-browser/main.contribution.ts | 18 +++++------ .../electron-browser/debug.contribution.ts | 2 +- .../electron-browser/files.contribution.ts | 14 ++++----- .../electron-browser/search.contribution.ts | 4 +-- .../electron-browser/terminal.contribution.ts | 22 +++++++------- .../electron-browser/keybindingService.ts | 2 +- 12 files changed, 76 insertions(+), 76 deletions(-) diff --git a/extensions/css-language-features/package.json b/extensions/css-language-features/package.json index 76da6212d8f..41b83b02164 100644 --- a/extensions/css-language-features/package.json +++ b/extensions/css-language-features/package.json @@ -110,7 +110,7 @@ "error" ], "default": "ignore", - "description": "%css.lint.boxModel.desc%" + "markdownDescription": "%css.lint.boxModel.desc%" }, "css.lint.universalSelector": { "type": "string", @@ -121,7 +121,7 @@ "error" ], "default": "ignore", - "description": "%css.lint.universalSelector.desc%" + "markdownDescription": "%css.lint.universalSelector.desc%" }, "css.lint.zeroUnits": { "type": "string", @@ -209,7 +209,7 @@ "error" ], "default": "warning", - "description": "%css.lint.propertyIgnoredDueToDisplay.desc%" + "markdownDescription": "%css.lint.propertyIgnoredDueToDisplay.desc%" }, "css.lint.important": { "type": "string", @@ -231,7 +231,7 @@ "error" ], "default": "ignore", - "description": "%css.lint.float.desc%" + "markdownDescription": "%css.lint.float.desc%" }, "css.lint.idSelector": { "type": "string", @@ -350,7 +350,7 @@ "error" ], "default": "ignore", - "description": "%scss.lint.boxModel.desc%" + "markdownDescription": "%scss.lint.boxModel.desc%" }, "scss.lint.universalSelector": { "type": "string", @@ -361,7 +361,7 @@ "error" ], "default": "ignore", - "description": "%scss.lint.universalSelector.desc%" + "markdownDescription": "%scss.lint.universalSelector.desc%" }, "scss.lint.zeroUnits": { "type": "string", @@ -383,7 +383,7 @@ "error" ], "default": "warning", - "description": "%scss.lint.fontFaceProperties.desc%" + "markdownDescription": "%scss.lint.fontFaceProperties.desc%" }, "scss.lint.hexColorLength": { "type": "string", @@ -449,7 +449,7 @@ "error" ], "default": "warning", - "description": "%scss.lint.propertyIgnoredDueToDisplay.desc%" + "markdownDescription": "%scss.lint.propertyIgnoredDueToDisplay.desc%" }, "scss.lint.important": { "type": "string", @@ -460,7 +460,7 @@ "error" ], "default": "ignore", - "description": "%scss.lint.important.desc%" + "markdownDescription": "%scss.lint.important.desc%" }, "scss.lint.float": { "type": "string", @@ -471,7 +471,7 @@ "error" ], "default": "ignore", - "description": "%scss.lint.float.desc%" + "markdownDescription": "%scss.lint.float.desc%" }, "scss.lint.idSelector": { "type": "string", @@ -569,7 +569,7 @@ "error" ], "default": "ignore", - "description": "%less.lint.boxModel.desc%" + "markdownDescription": "%less.lint.boxModel.desc%" }, "less.lint.universalSelector": { "type": "string", @@ -580,7 +580,7 @@ "error" ], "default": "ignore", - "description": "%less.lint.universalSelector.desc%" + "markdownDescription": "%less.lint.universalSelector.desc%" }, "less.lint.zeroUnits": { "type": "string", @@ -602,7 +602,7 @@ "error" ], "default": "warning", - "description": "%less.lint.fontFaceProperties.desc%" + "markdownDescription": "%less.lint.fontFaceProperties.desc%" }, "less.lint.hexColorLength": { "type": "string", @@ -668,7 +668,7 @@ "error" ], "default": "warning", - "description": "%less.lint.propertyIgnoredDueToDisplay.desc%" + "markdownDescription": "%less.lint.propertyIgnoredDueToDisplay.desc%" }, "less.lint.important": { "type": "string", @@ -690,7 +690,7 @@ "error" ], "default": "ignore", - "description": "%less.lint.float.desc%" + "markdownDescription": "%less.lint.float.desc%" }, "less.lint.idSelector": { "type": "string", diff --git a/extensions/emmet/package.json b/extensions/emmet/package.json index 4197d1c45c6..d9be62f74d1 100644 --- a/extensions/emmet/package.json +++ b/extensions/emmet/package.json @@ -39,17 +39,17 @@ "inMarkupAndStylesheetFilesOnly" ], "default": "always", - "description": "%emmetShowExpandedAbbreviation%" + "markdownDescription": "%emmetShowExpandedAbbreviation%" }, "emmet.showAbbreviationSuggestions": { "type": "boolean", "default": true, - "description": "%emmetShowAbbreviationSuggestions%" + "markdownDescription": "%emmetShowAbbreviationSuggestions%" }, "emmet.includeLanguages": { "type": "object", "default": {}, - "description": "%emmetIncludeLanguages%" + "markdownDescription": "%emmetIncludeLanguages%" }, "emmet.variables": { "type": "object", @@ -183,22 +183,22 @@ "css.webkitProperties": { "type": "string", "default": null, - "description": "%emmetPreferencesCssWebkitProperties%" + "markdownDescription": "%emmetPreferencesCssWebkitProperties%" }, "css.mozProperties": { "type": "string", "default": null, - "description": "%emmetPreferencesCssMozProperties%" + "markdownDescription": "%emmetPreferencesCssMozProperties%" }, "css.oProperties": { "type": "string", "default": null, - "description": "%emmetPreferencesCssOProperties%" + "markdownDescription": "%emmetPreferencesCssOProperties%" }, "css.msProperties": { "type": "string", "default": null, - "description": "%emmetPreferencesCssMsProperties%" + "markdownDescription": "%emmetPreferencesCssMsProperties%" }, "css.fuzzySearchMinScore": { "type": "number", @@ -210,12 +210,12 @@ "emmet.showSuggestionsAsSnippets": { "type": "boolean", "default": false, - "description": "%emmetShowSuggestionsAsSnippets%" + "markdownDescription": "%emmetShowSuggestionsAsSnippets%" }, "emmet.optimizeStylesheetParsing": { "type": "boolean", "default": true, - "description": "%emmetOptimizeStylesheetParsing%" + "markdownDescription": "%emmetOptimizeStylesheetParsing%" } } }, diff --git a/extensions/git/package.json b/extensions/git/package.json index 33a565f0914..0eba9ba5c94 100644 --- a/extensions/git/package.json +++ b/extensions/git/package.json @@ -885,7 +885,7 @@ "string", "null" ], - "description": "%config.path%", + "markdownDescription": "%config.path%", "default": null, "scope": "application" }, @@ -956,7 +956,7 @@ "%config.checkoutType.tags%", "%config.checkoutType.remote%" ], - "description": "%config.checkoutType%", + "markdownDescription": "%config.checkoutType%", "default": "all" }, "git.ignoreLegacyWarning": { diff --git a/extensions/npm/package.json b/extensions/npm/package.json index b0017b08b49..dc6a25a9dca 100644 --- a/extensions/npm/package.json +++ b/extensions/npm/package.json @@ -191,7 +191,7 @@ "type": "boolean", "default": false, "scope": "resource", - "description": "%config.npm.runSilent%" + "markdownDescription": "%config.npm.runSilent%" }, "npm.packageManager": { "scope": "resource", @@ -226,7 +226,7 @@ "open", "run" ], - "description": "%config.npm.scriptExplorerAction%", + "markdownDescription": "%config.npm.scriptExplorerAction%", "scope": "window", "default": "open" }, diff --git a/extensions/typescript-language-features/package.json b/extensions/typescript-language-features/package.json index 41c826ea71b..cf13bdf97cd 100644 --- a/extensions/typescript-language-features/package.json +++ b/extensions/typescript-language-features/package.json @@ -367,7 +367,7 @@ "javascript.implicitProjectConfig.experimentalDecorators": { "type": "boolean", "default": false, - "description": "%javascript.implicitProjectConfig.experimentalDecorators%", + "markdownDescription": "%javascript.implicitProjectConfig.experimentalDecorators%", "scope": "window" }, "javascript.nameSuggestions": { @@ -425,7 +425,7 @@ null ], "default": null, - "description": "%typescript.locale%", + "markdownDescription": "%typescript.locale%", "scope": "window" }, "javascript.suggestionActions.enabled": { @@ -448,7 +448,7 @@ "double" ], "default": "auto", - "description": "%typescript.preferences.quoteStyle%", + "markdownDescription": "%typescript.preferences.quoteStyle%", "scope": "resource" }, "typescript.preferences.quoteStyle": { @@ -459,7 +459,7 @@ "double" ], "default": "auto", - "description": "%typescript.preferences.quoteStyle%", + "markdownDescription": "%typescript.preferences.quoteStyle%", "scope": "resource" }, "javascript.preferences.importModuleSpecifier": { @@ -469,7 +469,7 @@ "relative", "non-relative" ], - "enumDescriptions": [ + "markdownEnumDescriptions": [ "%typescript.preferences.importModuleSpecifier.auto%", "%typescript.preferences.importModuleSpecifier.relative%", "%typescript.preferences.importModuleSpecifier.nonRelative%" diff --git a/src/vs/editor/common/config/commonEditorConfig.ts b/src/vs/editor/common/config/commonEditorConfig.ts index b6c7a9941da..07380bbb371 100644 --- a/src/vs/editor/common/config/commonEditorConfig.ts +++ b/src/vs/editor/common/config/commonEditorConfig.ts @@ -289,13 +289,13 @@ const editorConfiguration: IConfigurationNode = { 'editor.insertSpaces': { 'type': 'boolean', 'default': EDITOR_MODEL_DEFAULTS.insertSpaces, - 'description': nls.localize('insertSpaces', "Insert spaces when pressing `Tab`. This setting is overridden based on the file contents when `#editor.detectIndentation#` is on."), + 'markdownDescription': nls.localize('insertSpaces', "Insert spaces when pressing `Tab`. This setting is overridden based on the file contents when `#editor.detectIndentation#` is on."), 'errorMessage': nls.localize('insertSpaces.errorMessage', "Expected 'boolean'. Note that the value \"auto\" has been replaced by the `editor.detectIndentation` setting.") }, 'editor.detectIndentation': { 'type': 'boolean', 'default': EDITOR_MODEL_DEFAULTS.detectIndentation, - 'description': nls.localize('detectIndentation', "Controls whether `#editor.tabSize#` and `#editor.insertSpaces#` will be automatically detected when a file is opened based on the file contents.") + 'markdownDescription': nls.localize('detectIndentation', "Controls whether `#editor.tabSize#` and `#editor.insertSpaces#` will be automatically detected when a file is opened based on the file contents.") }, 'editor.roundedSelection': { 'type': 'boolean', @@ -378,7 +378,7 @@ const editorConfiguration: IConfigurationNode = { 'editor.wordWrap': { 'type': 'string', 'enum': ['off', 'on', 'wordWrapColumn', 'bounded'], - 'enumDescriptions': [ + 'markdownEnumDescriptions': [ nls.localize('wordWrap.off', "Lines will never wrap."), nls.localize('wordWrap.on', "Lines will wrap at the viewport width."), nls.localize({ @@ -408,7 +408,7 @@ const editorConfiguration: IConfigurationNode = { 'type': 'integer', 'default': EDITOR_DEFAULTS.wordWrapColumn, 'minimum': 1, - 'description': nls.localize({ + 'markdownDescription': nls.localize({ key: 'wordWrapColumn', comment: [ '- `editor.wordWrap` refers to a different setting and should not be localized.', @@ -431,7 +431,7 @@ const editorConfiguration: IConfigurationNode = { 'editor.mouseWheelScrollSensitivity': { 'type': 'number', 'default': EDITOR_DEFAULTS.viewInfo.scrollbar.mouseWheelScrollSensitivity, - 'description': nls.localize('mouseWheelScrollSensitivity', "A multiplier to be used on the `deltaX` and `deltaY` of mouse wheel scroll events.") + 'markdownDescription': nls.localize('mouseWheelScrollSensitivity', "A multiplier to be used on the `deltaX` and `deltaY` of mouse wheel scroll events.") }, 'editor.multiCursorModifier': { 'type': 'string', @@ -441,7 +441,7 @@ const editorConfiguration: IConfigurationNode = { nls.localize('multiCursorModifier.alt', "Maps to `Alt` on Windows and Linux and to `Option` on macOS.") ], 'default': 'alt', - 'description': nls.localize({ + 'markdownDescription': nls.localize({ key: 'multiCursorModifier', comment: [ '- `ctrlCmd` refers to a value the setting can take and should not be localized.', @@ -533,12 +533,12 @@ const editorConfiguration: IConfigurationNode = { nls.localize('acceptSuggestionOnEnterSmart', "Only accept a suggestion with `Enter` when it makes a textual change."), '' ], - 'description': nls.localize('acceptSuggestionOnEnter', "Controls whether suggestions should be accepted on `Enter`, in addition to `Tab`. Helps to avoid ambiguity between inserting new lines or accepting suggestions.") + 'markdownDescription': nls.localize('acceptSuggestionOnEnter', "Controls whether suggestions should be accepted on `Enter`, in addition to `Tab`. Helps to avoid ambiguity between inserting new lines or accepting suggestions.") }, 'editor.acceptSuggestionOnCommitCharacter': { 'type': 'boolean', 'default': EDITOR_DEFAULTS.contribInfo.acceptSuggestionOnCommitCharacter, - 'description': nls.localize('acceptSuggestionOnCommitCharacter', "Controls whether suggestions should be accepted on commit characters. For example, in JavaScript, the semi-colon (`;`) can be a commit character that accepts a suggestion and types that character.") + 'markdownDescription': nls.localize('acceptSuggestionOnCommitCharacter', "Controls whether suggestions should be accepted on commit characters. For example, in JavaScript, the semi-colon (`;`) can be a commit character that accepts a suggestion and types that character.") }, 'editor.snippetSuggestions': { 'type': 'string', @@ -624,7 +624,7 @@ const editorConfiguration: IConfigurationNode = { 'editor.mouseWheelZoom': { 'type': 'boolean', 'default': EDITOR_DEFAULTS.viewInfo.mouseWheelZoom, - 'description': nls.localize('mouseWheelZoom', "Zoom the font of the editor when using mouse wheel and holding `Ctrl`.") + 'markdownDescription': nls.localize('mouseWheelZoom', "Zoom the font of the editor when using mouse wheel and holding `Ctrl`.") }, 'editor.cursorStyle': { 'type': 'string', @@ -635,7 +635,7 @@ const editorConfiguration: IConfigurationNode = { 'editor.cursorWidth': { 'type': 'integer', 'default': EDITOR_DEFAULTS.viewInfo.cursorWidth, - 'description': nls.localize('cursorWidth', "Controls the width of the cursor when `#editor.cursorStyle#` is set to `line`.") + 'markdownDescription': nls.localize('cursorWidth', "Controls the width of the cursor when `#editor.cursorStyle#` is set to `line`.") }, 'editor.fontLigatures': { 'type': 'boolean', @@ -699,7 +699,7 @@ const editorConfiguration: IConfigurationNode = { 'type': 'string', 'enum': ['auto', 'indentation'], 'default': EDITOR_DEFAULTS.contribInfo.foldingStrategy, - 'description': nls.localize('foldingStrategy', "Controls the strategy for computing folding ranges. `auto` uses a language specific folding strategy, if available. `indentation` uses the indentation based folding strategy.") + 'markdownDescription': nls.localize('foldingStrategy', "Controls the strategy for computing folding ranges. `auto` uses a language specific folding strategy, if available. `indentation` uses the indentation based folding strategy.") }, 'editor.showFoldingControls': { 'type': 'string', @@ -730,7 +730,7 @@ const editorConfiguration: IConfigurationNode = { 'editor.stablePeek': { 'type': 'boolean', 'default': false, - 'description': nls.localize('stablePeek', "Keep peek editors open even when double clicking their content or when hitting `Escape`.") + 'markdownDescription': nls.localize('stablePeek', "Keep peek editors open even when double clicking their content or when hitting `Escape`.") }, 'editor.dragAndDrop': { 'type': 'boolean', diff --git a/src/vs/workbench/electron-browser/main.contribution.ts b/src/vs/workbench/electron-browser/main.contribution.ts index a302df9185c..2ab51f8a1de 100644 --- a/src/vs/workbench/electron-browser/main.contribution.ts +++ b/src/vs/workbench/electron-browser/main.contribution.ts @@ -411,13 +411,13 @@ configurationRegistry.registerConfiguration({ 'type': 'string', 'enum': ['left', 'right', 'first', 'last'], 'default': 'right', - 'description': nls.localize({ comment: ['This is the description for a setting. Values surrounded by single quotes are not to be translated.'], key: 'editorOpenPositioning' }, "Controls where editors open. Select `left` or `right` to open editors to the left or right of the currently active one. Select `first` or `last` to open editors independently from the currently active one.") + 'markdownDescription': nls.localize({ comment: ['This is the description for a setting. Values surrounded by single quotes are not to be translated.'], key: 'editorOpenPositioning' }, "Controls where editors open. Select `left` or `right` to open editors to the left or right of the currently active one. Select `first` or `last` to open editors independently from the currently active one.") }, 'workbench.editor.openSideBySideDirection': { 'type': 'string', 'enum': ['right', 'down'], 'default': 'right', - 'description': nls.localize('sideBySideDirection', "Controls the default direction of editors that are opened side by side (e.g. from the explorer). By default, editors will open on the right hand side of the currently active one. If changed to `down`, the editors will open below the currently active one.") + 'markdownDescription': nls.localize('sideBySideDirection', "Controls the default direction of editors that are opened side by side (e.g. from the explorer). By default, editors will open on the right hand side of the currently active one. If changed to `down`, the editors will open below the currently active one.") }, 'workbench.editor.closeEmptyGroups': { 'type': 'boolean', @@ -550,10 +550,10 @@ configurationRegistry.registerConfiguration({ ], 'default': 'off', 'scope': ConfigurationScope.APPLICATION, - 'description': + 'markdownDescription': isMacintosh ? - 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).") + 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', @@ -565,7 +565,7 @@ configurationRegistry.registerConfiguration({ ], 'default': 'default', 'scope': ConfigurationScope.APPLICATION, - 'description': 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).") + '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', @@ -576,7 +576,7 @@ configurationRegistry.registerConfiguration({ ], 'default': isMacintosh ? 'off' : 'on', 'scope': ConfigurationScope.APPLICATION, - 'description': nls.localize('openWithoutArgumentsInNewWindow', "Controls whether a new empty window should open when starting a second instance without arguments or if the last running instance should get focus.\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).") + 'description': nls.localize('openWithoutArgumentsInNewWindow', "Controls whether a new empty window should open when starting a second instance without arguments or if the last running instance should get focus.\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.restoreWindows': { 'type': 'string', @@ -605,7 +605,7 @@ configurationRegistry.registerConfiguration({ 'window.title': { 'type': 'string', 'default': isMacintosh ? '${activeEditorShort}${separator}${rootName}' : '${dirty}${activeEditorShort}${separator}${rootName}${separator}${appName}', - 'description': nls.localize({ comment: ['This is the description for a setting. Values surrounded by parenthesis are not to be translated.'], key: 'title' }, + 'markdownDescription': nls.localize({ comment: ['This is the description for a setting. Values surrounded by parenthesis are not to be translated.'], key: 'title' }, "Controls the window title based on the active editor. Variables are substituted based on the context:\n- `\${activeEditorShort}`: the file name (e.g. myFile.txt).\n- `\${activeEditorMedium}`: the path of the file relative to the workspace folder (e.g. myFolder/myFile.txt).\n- `\${activeEditorLong}`: the full path of the file (e.g. /Users/Development/myProject/myFolder/myFile.txt).\n- `\${folderName}`: name of the workspace folder the file is contained in (e.g. myFolder).\n- `\${folderPath}`: file path of the workspace folder the file is contained in (e.g. /Users/Development/myFolder).\n- `\${rootName}`: name of the workspace (e.g. myFolder or myWorkspace).\n- `\${rootPath}`: file path of the workspace (e.g. /Users/Development/myWorkspace).\n- `\${appName}`: e.g. VS Code.\n- `\${dirty}`: a dirty indicator if the active editor is dirty.\n- `\${separator}`: a conditional separator (\" - \") that only shows when surrounded by variables with values or static text.") }, 'window.newWindowDimensions': { @@ -671,7 +671,7 @@ configurationRegistry.registerConfiguration({ 'type': 'boolean', 'default': false, 'scope': ConfigurationScope.APPLICATION, - 'description': nls.localize('window.smoothScrollingWorkaround', "Enable this workaround if scrolling is no longer smooth after restoring a minimized VS Code window. This is a workaround for an issue (https://github.com/Microsoft/vscode/issues/13612) where scrolling starts to lag on devices with precision trackpads like the Surface devices from Microsoft. Enabling this workaround can result in a little bit of layout flickering after restoring the window from minimized state but is otherwise harmless. Note: in order for this workaround to function, make sure to also set `#window.titleBarStyle#` to `native`."), + 'markdownDescription': nls.localize('window.smoothScrollingWorkaround', "Enable this workaround if scrolling is no longer smooth after restoring a minimized VS Code window. This is a workaround for an issue (https://github.com/Microsoft/vscode/issues/13612) where scrolling starts to lag on devices with precision trackpads like the Surface devices from Microsoft. Enabling this workaround can result in a little bit of layout flickering after restoring the window from minimized state but is otherwise harmless. Note: in order for this workaround to function, make sure to also set `#window.titleBarStyle#` to `native`."), 'included': isWindows }, 'window.clickThroughInactive': { diff --git a/src/vs/workbench/parts/debug/electron-browser/debug.contribution.ts b/src/vs/workbench/parts/debug/electron-browser/debug.contribution.ts index 35bad718d0b..c8faf5c0e38 100644 --- a/src/vs/workbench/parts/debug/electron-browser/debug.contribution.ts +++ b/src/vs/workbench/parts/debug/electron-browser/debug.contribution.ts @@ -193,7 +193,7 @@ configurationRegistry.registerConfiguration({ }, 'debug.toolBarLocation': { enum: ['floating', 'docked', 'hidden'], - description: nls.localize({ comment: ['This is the description for a setting'], key: 'toolBarLocation' }, "Controls the location of the debug toolbar. Either `floating` in all views, `docked` in the debug view, or `hidden`"), + markdownDescription: nls.localize({ comment: ['This is the description for a setting'], key: 'toolBarLocation' }, "Controls the location of the debug toolbar. Either `floating` in all views, `docked` in the debug view, or `hidden`"), default: 'floating' }, 'debug.showInStatusBar': { diff --git a/src/vs/workbench/parts/files/electron-browser/files.contribution.ts b/src/vs/workbench/parts/files/electron-browser/files.contribution.ts index f6b90bd8536..a34d3ded080 100644 --- a/src/vs/workbench/parts/files/electron-browser/files.contribution.ts +++ b/src/vs/workbench/parts/files/electron-browser/files.contribution.ts @@ -186,7 +186,7 @@ configurationRegistry.registerConfiguration({ 'properties': { 'files.exclude': { 'type': 'object', - 'description': nls.localize('exclude', "Configure glob patterns for excluding files and folders. For example, the files explorer decides which files and folders to show or hide based on this setting. Read more about glob patterns [here](https://code.visualstudio.com/docs/editor/codebasics#_advanced-search-options)."), + 'markdownDescription': nls.localize('exclude', "Configure glob patterns for excluding files and folders. For example, the files explorer decides which files and folders to show or hide based on this setting. Read more about glob patterns [here](https://code.visualstudio.com/docs/editor/codebasics#_advanced-search-options)."), 'default': { '**/.git': true, '**/.svn': true, '**/.hg': true, '**/CVS': true, '**/.DS_Store': true }, 'scope': ConfigurationScope.RESOURCE, 'additionalProperties': { @@ -211,7 +211,7 @@ configurationRegistry.registerConfiguration({ }, 'files.associations': { 'type': 'object', - 'description': nls.localize('associations', "Configure file associations to languages (e.g. `\"*.extension\": \"html\"`). These have precedence over the default associations of the languages installed."), + 'markdownDescription': nls.localize('associations', "Configure file associations to languages (e.g. `\"*.extension\": \"html\"`). These have precedence over the default associations of the languages installed."), }, 'files.encoding': { 'type': 'string', @@ -267,19 +267,19 @@ configurationRegistry.registerConfiguration({ 'files.autoSave': { 'type': 'string', 'enum': [AutoSaveConfiguration.OFF, AutoSaveConfiguration.AFTER_DELAY, AutoSaveConfiguration.ON_FOCUS_CHANGE, AutoSaveConfiguration.ON_WINDOW_CHANGE], - 'enumDescriptions': [ + 'markdownEnumDescriptions': [ nls.localize({ comment: ['This is the description for a setting. Values surrounded by single quotes are not to be translated.'], key: 'files.autoSave.off' }, "A dirty file is never automatically saved."), nls.localize({ comment: ['This is the description for a setting. Values surrounded by single quotes are not to be translated.'], key: 'files.autoSave.afterDelay' }, "A dirty file is automatically saved after the configured `#files.autoSaveDelay#`."), nls.localize({ comment: ['This is the description for a setting. Values surrounded by single quotes are not to be translated.'], key: 'files.autoSave.onFocusChange' }, "A dirty file is automatically saved when the editor loses focus."), nls.localize({ comment: ['This is the description for a setting. Values surrounded by single quotes are not to be translated.'], key: 'files.autoSave.onWindowChange' }, "A dirty file is automatically saved when the window loses focus.") ], 'default': AutoSaveConfiguration.OFF, - 'description': nls.localize({ comment: ['This is the description for a setting. Values surrounded by single quotes are not to be translated.'], key: 'autoSave' }, "Controls auto save of dirty files. Read more about autosave [here](https://code.visualstudio.com/docs/editor/codebasics#_save-auto-save).", AutoSaveConfiguration.OFF, AutoSaveConfiguration.AFTER_DELAY, AutoSaveConfiguration.ON_FOCUS_CHANGE, AutoSaveConfiguration.ON_WINDOW_CHANGE, AutoSaveConfiguration.AFTER_DELAY) + 'markdownDescription': nls.localize({ comment: ['This is the description for a setting. Values surrounded by single quotes are not to be translated.'], key: 'autoSave' }, "Controls auto save of dirty files. Read more about autosave [here](https://code.visualstudio.com/docs/editor/codebasics#_save-auto-save).", AutoSaveConfiguration.OFF, AutoSaveConfiguration.AFTER_DELAY, AutoSaveConfiguration.ON_FOCUS_CHANGE, AutoSaveConfiguration.ON_WINDOW_CHANGE, AutoSaveConfiguration.AFTER_DELAY) }, 'files.autoSaveDelay': { 'type': 'number', 'default': 1000, - 'description': nls.localize({ comment: ['This is the description for a setting. Values surrounded by single quotes are not to be translated.'], key: 'autoSaveDelay' }, "Controls the delay in ms after which a dirty file is saved automatically. Only applies when `#files.autoSave#` is set to `{0}`.", AutoSaveConfiguration.AFTER_DELAY) + 'markdownDescription': nls.localize({ comment: ['This is the description for a setting. Values surrounded by single quotes are not to be translated.'], key: 'autoSaveDelay' }, "Controls the delay in ms after which a dirty file is saved automatically. Only applies when `#files.autoSave#` is set to `{0}`.", AutoSaveConfiguration.AFTER_DELAY) }, 'files.watcherExclude': { 'type': 'object', @@ -291,7 +291,7 @@ configurationRegistry.registerConfiguration({ 'type': 'string', 'enum': [HotExitConfiguration.OFF, HotExitConfiguration.ON_EXIT, HotExitConfiguration.ON_EXIT_AND_WINDOW_CLOSE], 'default': HotExitConfiguration.ON_EXIT, - 'enumDescriptions': [ + '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.'), nls.localize('hotExit.onExitAndWindowClose', '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), and also for any window with a folder opened regardless of whether it\'s the last window. All windows without folders opened will be restored upon next launch. To restore folder windows as they were before shutdown set `#window.restoreWindows#` to `all`.') @@ -310,7 +310,7 @@ configurationRegistry.registerConfiguration({ 'files.maxMemoryForLargeFilesMB': { 'type': 'number', 'default': 4096, - 'description': nls.localize('maxMemoryForLargeFilesMB', "Controls the memory available to VS Code after restart when trying to open large files. Same effect as specifying `--max-memory=NEWSIZE` on the command line.") + 'markdownDescription': nls.localize('maxMemoryForLargeFilesMB', "Controls the memory available to VS Code after restart when trying to open large files. Same effect as specifying `--max-memory=NEWSIZE` on the command line.") } } }); diff --git a/src/vs/workbench/parts/search/electron-browser/search.contribution.ts b/src/vs/workbench/parts/search/electron-browser/search.contribution.ts index f3dfe629672..fd4ddfd6534 100644 --- a/src/vs/workbench/parts/search/electron-browser/search.contribution.ts +++ b/src/vs/workbench/parts/search/electron-browser/search.contribution.ts @@ -560,7 +560,7 @@ configurationRegistry.registerConfiguration({ properties: { 'search.exclude': { type: 'object', - description: nls.localize('exclude', "Configure glob patterns for excluding files and folders in searches. Inherits all glob patterns from the `#files.exclude#` setting. Read more about glob patterns [here](https://code.visualstudio.com/docs/editor/codebasics#_advanced-search-options)."), + markdownDescription: nls.localize('exclude', "Configure glob patterns for excluding files and folders in searches. Inherits all glob patterns from the `#files.exclude#` setting. Read more about glob patterns [here](https://code.visualstudio.com/docs/editor/codebasics#_advanced-search-options)."), default: { '**/node_modules': true, '**/bower_components': true }, additionalProperties: { anyOf: [ @@ -590,7 +590,7 @@ configurationRegistry.registerConfiguration({ }, 'search.useIgnoreFiles': { type: 'boolean', - description: nls.localize('useIgnoreFiles', "Controls whether to use `.gitignore` and `.ignore` files when searching for files."), + markdownDescription: nls.localize('useIgnoreFiles', "Controls whether to use `.gitignore` and `.ignore` files when searching for files."), default: true, scope: ConfigurationScope.RESOURCE }, diff --git a/src/vs/workbench/parts/terminal/electron-browser/terminal.contribution.ts b/src/vs/workbench/parts/terminal/electron-browser/terminal.contribution.ts index fa2894cbcae..9ef058f2994 100644 --- a/src/vs/workbench/parts/terminal/electron-browser/terminal.contribution.ts +++ b/src/vs/workbench/parts/terminal/electron-browser/terminal.contribution.ts @@ -75,12 +75,12 @@ configurationRegistry.registerConfiguration({ type: 'object', properties: { 'terminal.integrated.shell.linux': { - description: nls.localize('terminal.integrated.shell.linux', "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)."), + markdownDescription: nls.localize('terminal.integrated.shell.linux', "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', default: getTerminalDefaultShellUnixLike() }, 'terminal.integrated.shellArgs.linux': { - description: nls.localize('terminal.integrated.shellArgs.linux', "The command line arguments to use when on the Linux terminal. [Read more about configuring the shell](https://code.visualstudio.com/docs/editor/integrated-terminal#_configuration)."), + markdownDescription: nls.localize('terminal.integrated.shellArgs.linux', "The command line arguments to use when on the Linux terminal. [Read more about configuring the shell](https://code.visualstudio.com/docs/editor/integrated-terminal#_configuration)."), type: 'array', items: { type: 'string' @@ -88,12 +88,12 @@ configurationRegistry.registerConfiguration({ default: [] }, 'terminal.integrated.shell.osx': { - description: nls.localize('terminal.integrated.shell.osx', "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)."), + markdownDescription: nls.localize('terminal.integrated.shell.osx', "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', default: getTerminalDefaultShellUnixLike() }, 'terminal.integrated.shellArgs.osx': { - description: nls.localize('terminal.integrated.shellArgs.osx', "The command line arguments to use when on the macOS terminal. [Read more about configuring the shell](https://code.visualstudio.com/docs/editor/integrated-terminal#_configuration)."), + markdownDescription: nls.localize('terminal.integrated.shellArgs.osx', "The command line arguments to use when on the macOS terminal. [Read more about configuring the shell](https://code.visualstudio.com/docs/editor/integrated-terminal#_configuration)."), type: 'array', items: { type: 'string' @@ -104,12 +104,12 @@ configurationRegistry.registerConfiguration({ default: ['-l'] }, 'terminal.integrated.shell.windows': { - description: nls.localize('terminal.integrated.shell.windows', "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)."), + markdownDescription: nls.localize('terminal.integrated.shell.windows', "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', default: getTerminalDefaultShellWindows() }, 'terminal.integrated.shellArgs.windows': { - description: nls.localize('terminal.integrated.shellArgs.windows', "The command line arguments to use when on the Windows terminal. [Read more about configuring the shell](https://code.visualstudio.com/docs/editor/integrated-terminal#_configuration)."), + markdownDescription: nls.localize('terminal.integrated.shellArgs.windows', "The command line arguments to use when on the Windows terminal. [Read more about configuring the shell](https://code.visualstudio.com/docs/editor/integrated-terminal#_configuration)."), type: 'array', items: { type: 'string' @@ -137,7 +137,7 @@ configurationRegistry.registerConfiguration({ default: true }, 'terminal.integrated.fontFamily': { - description: nls.localize('terminal.integrated.fontFamily', "Controls the font family of the terminal, this defaults to `#editor.fontFamily#`'s value."), + markdownDescription: nls.localize('terminal.integrated.fontFamily', "Controls the font family of the terminal, this defaults to `#editor.fontFamily#`'s value."), type: 'string' }, // TODO: Support font ligatures @@ -189,7 +189,7 @@ configurationRegistry.registerConfiguration({ default: 1000 }, 'terminal.integrated.setLocaleVariables': { - description: nls.localize('terminal.integrated.setLocaleVariables', "Controls whether locale variables are set at startup of the terminal, this defaults to `true` on macOS, `false` on other platforms."), + markdownDescription: nls.localize('terminal.integrated.setLocaleVariables', "Controls whether locale variables are set at startup of the terminal, this defaults to `true` on macOS, `false` on other platforms."), type: 'boolean', default: platform.isMacintosh }, @@ -329,7 +329,7 @@ configurationRegistry.registerConfiguration({ ].sort() }, 'terminal.integrated.env.osx': { - description: nls.localize('terminal.integrated.env.osx', "Object with environment variables that will be added to the VS Code process to be used by the terminal on macOS. Set to `null` to delete the environment variable."), + markdownDescription: nls.localize('terminal.integrated.env.osx', "Object with environment variables that will be added to the VS Code process to be used by the terminal on macOS. Set to `null` to delete the environment variable."), type: 'object', additionalProperties: { type: ['string', 'null'] @@ -337,7 +337,7 @@ configurationRegistry.registerConfiguration({ default: {} }, 'terminal.integrated.env.linux': { - description: nls.localize('terminal.integrated.env.linux', "Object with environment variables that will be added to the VS Code process to be used by the terminal on Linux. Set to `null` to delete the environment variable."), + markdownDescription: nls.localize('terminal.integrated.env.linux', "Object with environment variables that will be added to the VS Code process to be used by the terminal on Linux. Set to `null` to delete the environment variable."), type: 'object', additionalProperties: { type: ['string', 'null'] @@ -345,7 +345,7 @@ configurationRegistry.registerConfiguration({ default: {} }, 'terminal.integrated.env.windows': { - description: nls.localize('terminal.integrated.env.windows', "Object with environment variables that will be added to the VS Code process to be used by the terminal on Windows. Set to `null` to delete the environment variable."), + markdownDescription: nls.localize('terminal.integrated.env.windows', "Object with environment variables that will be added to the VS Code process to be used by the terminal on Windows. Set to `null` to delete the environment variable."), type: 'object', additionalProperties: { type: ['string', 'null'] diff --git a/src/vs/workbench/services/keybinding/electron-browser/keybindingService.ts b/src/vs/workbench/services/keybinding/electron-browser/keybindingService.ts index 775b74e6e76..77a0eb4cd9e 100644 --- a/src/vs/workbench/services/keybinding/electron-browser/keybindingService.ts +++ b/src/vs/workbench/services/keybinding/electron-browser/keybindingService.ts @@ -606,7 +606,7 @@ const keyboardConfiguration: IConfigurationNode = { 'type': 'string', 'enum': ['code', 'keyCode'], 'default': 'code', - 'description': nls.localize('dispatch', "Controls the dispatching logic for key presses to use either `code` (recommended) or `keyCode`."), + 'markdownDescription': nls.localize('dispatch', "Controls the dispatching logic for key presses to use either `code` (recommended) or `keyCode`."), 'included': OS === OperatingSystem.Macintosh || OS === OperatingSystem.Linux }, 'keyboard.touchbar.enabled': { From 157ceab9f6625d78812be9e22ec8e0b1bdda0071 Mon Sep 17 00:00:00 2001 From: Rob Lourens Date: Wed, 8 Aug 2018 10:59:28 -0700 Subject: [PATCH 0607/1276] Start #54039 - tabbing around the list without selecting things works --- src/vs/base/parts/tree/browser/treeImpl.ts | 3 + src/vs/base/parts/tree/browser/treeView.ts | 5 + .../browser/media/settingsEditor2.css | 5 + .../preferences/browser/settingsEditor2.ts | 101 +++++++----------- .../parts/preferences/browser/settingsTree.ts | 88 +++++++++------ .../parts/preferences/common/preferences.ts | 3 - .../preferences.contribution.ts | 36 +------ 7 files changed, 109 insertions(+), 132 deletions(-) diff --git a/src/vs/base/parts/tree/browser/treeImpl.ts b/src/vs/base/parts/tree/browser/treeImpl.ts index 10b350737ec..dc008d1eede 100644 --- a/src/vs/base/parts/tree/browser/treeImpl.ts +++ b/src/vs/base/parts/tree/browser/treeImpl.ts @@ -211,7 +211,10 @@ export class Tree implements _.ITree { public getFirstVisibleElement(): any { return this.view.getFirstVisibleElement(); + } + public getLastVisibleElement(): any { + return this.view.getLastVisibleElement(); } public getScrollPosition(): number { diff --git a/src/vs/base/parts/tree/browser/treeView.ts b/src/vs/base/parts/tree/browser/treeView.ts index 5d56011feac..bb125f1c905 100644 --- a/src/vs/base/parts/tree/browser/treeView.ts +++ b/src/vs/base/parts/tree/browser/treeView.ts @@ -658,6 +658,11 @@ export class TreeView extends HeightMap { return item && item.model.getElement(); } + public getLastVisibleElement(): any { + const item = this.itemAtIndex(this.indexAt(this.lastRenderTop + this.lastRenderHeight)); + return item && item.model.getElement(); + } + private render(scrollTop: number, viewHeight: number, scrollLeft: number, viewWidth: number, scrollWidth: number): void { var i: number; var stop: number; diff --git a/src/vs/workbench/parts/preferences/browser/media/settingsEditor2.css b/src/vs/workbench/parts/preferences/browser/media/settingsEditor2.css index 19651c22713..fa5d1ab6f8f 100644 --- a/src/vs/workbench/parts/preferences/browser/media/settingsEditor2.css +++ b/src/vs/workbench/parts/preferences/browser/media/settingsEditor2.css @@ -295,6 +295,11 @@ margin: 0px; } +.settings-editor > .settings-body > .settings-tree-container .setting-item .setting-item-description-markdown a:focus { + outline: 1px solid -webkit-focus-ring-color; + outline-offset: -1px; +} + .settings-editor > .settings-body > .settings-tree-container .setting-item .setting-item-description-markdown code { line-height: 15px; /** For some reason, this is needed, otherwise will take up 20px height */ font-family: Menlo, Monaco, Consolas, "Droid Sans Mono", "Courier New", monospace, "Droid Sans Fallback"; diff --git a/src/vs/workbench/parts/preferences/browser/settingsEditor2.ts b/src/vs/workbench/parts/preferences/browser/settingsEditor2.ts index 27c14ebd24a..aa5ffbe2e98 100644 --- a/src/vs/workbench/parts/preferences/browser/settingsEditor2.ts +++ b/src/vs/workbench/parts/preferences/browser/settingsEditor2.ts @@ -35,7 +35,7 @@ import { SearchWidget, SettingsTarget, SettingsTargetsWidget } from 'vs/workbenc import { commonlyUsedData, tocData } from 'vs/workbench/parts/preferences/browser/settingsLayout'; import { ISettingsEditorViewState, MODIFIED_SETTING_TAG, ONLINE_SERVICES_SETTING_TAG, resolveExtensionsSettings, resolveSettingsTree, SearchResultIdx, SearchResultModel, SettingsRenderer, SettingsTree, SettingsTreeElement, SettingsTreeGroupElement, SettingsTreeModel, SettingsTreeSettingElement } from 'vs/workbench/parts/preferences/browser/settingsTree'; import { TOCRenderer, TOCTree, TOCTreeModel } from 'vs/workbench/parts/preferences/browser/tocTree'; -import { CONTEXT_SETTINGS_EDITOR, CONTEXT_SETTINGS_FIRST_ROW_FOCUS, CONTEXT_SETTINGS_ROW_FOCUS, CONTEXT_SETTINGS_SEARCH_FOCUS, CONTEXT_TOC_ROW_FOCUS, IPreferencesSearchService, ISearchProvider } from 'vs/workbench/parts/preferences/common/preferences'; +import { CONTEXT_SETTINGS_EDITOR, CONTEXT_SETTINGS_SEARCH_FOCUS, CONTEXT_TOC_ROW_FOCUS, IPreferencesSearchService, ISearchProvider } from 'vs/workbench/parts/preferences/common/preferences'; import { IPreferencesService, ISearchResult, ISettingsEditorModel } from 'vs/workbench/services/preferences/common/preferences'; import { SettingsEditor2Input } from 'vs/workbench/services/preferences/common/preferencesEditorInput'; import { DefaultSettingsEditorModel } from 'vs/workbench/services/preferences/common/preferencesModels'; @@ -70,13 +70,9 @@ export class SettingsEditor2 extends BaseEditor { private settingUpdateDelayer: Delayer; private pendingSettingUpdate: { key: string, value: any }; - private selectedElement: SettingsTreeElement; - private viewState: ISettingsEditorViewState; private searchResultModel: SearchResultModel; - private firstRowFocused: IContextKey; - private rowFocused: IContextKey; private tocRowFocused: IContextKey; private inSettingsEditorContextKey: IContextKey; private searchFocusContextKey: IContextKey; @@ -108,8 +104,6 @@ export class SettingsEditor2 extends BaseEditor { this.inSettingsEditorContextKey = CONTEXT_SETTINGS_EDITOR.bindTo(contextKeyService); this.searchFocusContextKey = CONTEXT_SETTINGS_SEARCH_FOCUS.bindTo(contextKeyService); - this.firstRowFocused = CONTEXT_SETTINGS_FIRST_ROW_FOCUS.bindTo(contextKeyService); - this.rowFocused = CONTEXT_SETTINGS_ROW_FOCUS.bindTo(contextKeyService); this.tocRowFocused = CONTEXT_TOC_ROW_FOCUS.bindTo(contextKeyService); this._register(configurationService.onDidChangeConfiguration(e => { @@ -154,14 +148,10 @@ export class SettingsEditor2 extends BaseEditor { } focusSettings(): void { - const selection = this.settingsTree.getSelection(); - if (selection && selection[0]) { - this.settingsTree.setFocus(selection[0]); - } else { - this.settingsTree.focusFirst(); + const firstFocusable = this.settingsTree.getHTMLElement().querySelector('a, input, [tabindex="0"]'); + if (firstFocusable) { + (firstFocusable).focus(); } - - this.settingsTree.domFocus(); } focusSearch(): void { @@ -254,13 +244,19 @@ export class SettingsEditor2 extends BaseEditor { private revealSetting(settingName: string): void { const element = this.settingsTreeModel.getElementByName(settingName); if (element) { - this.settingsTree.setSelection([element]); - this.settingsTree.setFocus(element); this.settingsTree.reveal(element, 0); - this.settingsTree.domFocus(); } } + private revealSettingElement(element: SettingsTreeElement): void { + const top = this.settingsTree.getRelativeTop(element); + const clampedTop = Math.max( + Math.min(top, .9), + .1); + + this.settingsTree.reveal(element, clampedTop); + } + private openSettingsFile(): TPromise { const currentSettingsTarget = this.settingsTargetsWidget.settingsTarget; @@ -276,7 +272,16 @@ export class SettingsEditor2 extends BaseEditor { private createBody(parent: HTMLElement): void { const bodyContainer = DOM.append(parent, $('.settings-body')); + this.createFocusSink(bodyContainer, () => { + const firstElement = this.settingsTree.getFirstVisibleElement(); + this.settingsTree.reveal(firstElement, 0.1); + }); this.createSettingsTree(bodyContainer); + this.createFocusSink(bodyContainer, () => { + const lastElement = this.settingsTree.getLastVisibleElement(); + this.settingsTree.reveal(lastElement, 0.9); + }); + this.createTOC(bodyContainer); if (this.environmentService.appQuality !== 'stable') { @@ -284,6 +289,19 @@ export class SettingsEditor2 extends BaseEditor { } } + private createFocusSink(container: HTMLElement, callback: () => void): HTMLElement { + const listFocusSink = DOM.append(container, $('.settings-tree-focus-sink')); + listFocusSink.tabIndex = 0; + this._register(DOM.addDisposableListener(listFocusSink, 'focus', e => { + if (e.relatedTarget && DOM.findParentWithClass(e.relatedTarget, 'monaco-tree')) { + callback(); + e.relatedTarget.focus(); + } + })); + + return listFocusSink; + } + private createTOC(parent: HTMLElement): void { this.tocTreeModel = new TOCTreeModel(); this.tocTreeContainer = DOM.append(parent, $('.settings-toc-container')); @@ -304,13 +322,6 @@ export class SettingsEditor2 extends BaseEditor { if (this.searchResultModel) { this.viewState.filterToCategory = element; this.refreshTreeAndMaintainFocus(); - } else if (this.settingsTreeModel) { - if (element && !e.payload.fromScroll) { - const payload = { fromTOC: true }; - this.settingsTree.reveal(element, 0); - this.settingsTree.setSelection([element], payload); - this.settingsTree.setFocus(element, payload); - } } }); })); @@ -344,6 +355,7 @@ export class SettingsEditor2 extends BaseEditor { }); })); this._register(renderer.onDidClickSettingLink(settingName => this.revealSetting(settingName))); + this._register(renderer.onDidFocusSetting(element => this.revealSettingElement(element))); this.settingsTree = this._register(this.instantiationService.createInstance(SettingsTree, this.settingsTreeContainer, @@ -351,46 +363,7 @@ export class SettingsEditor2 extends BaseEditor { { renderer })); - - this._register(this.settingsTree.onDidChangeFocus(e => { - this.settingsTree.setSelection([e.focus], e.payload); - if (this.selectedElement) { - this.settingsTree.refresh(this.selectedElement); - } - - if (e.focus) { - this.settingsTree.refresh(e.focus); - } - - this.selectedElement = e.focus; - })); - - this._register(this.settingsTree.onDidBlur(() => { - this.rowFocused.set(false); - this.firstRowFocused.set(false); - })); - - this._register(this.settingsTree.onDidChangeSelection(e => { - if (!e.payload || !e.payload.fromTOC) { - this.updateTreeScrollSync(); - } - - let firstRowFocused = false; - let rowFocused = false; - const selection: SettingsTreeElement = e.selection[0]; - if (selection) { - rowFocused = true; - if (this.searchResultModel) { - firstRowFocused = selection.id === this.searchResultModel.getChildren()[0].id; - } else { - const firstRowId = this.settingsTreeModel.root.children[0] && this.settingsTreeModel.root.children[0].id; - firstRowFocused = selection.id === firstRowId; - } - } - - this.rowFocused.set(rowFocused); - this.firstRowFocused.set(firstRowFocused); - })); + this.settingsTree.getHTMLElement().tabIndex = -1; this._register(this.settingsTree.onDidScroll(() => { this.updateTreeScrollSync(); diff --git a/src/vs/workbench/parts/preferences/browser/settingsTree.ts b/src/vs/workbench/parts/preferences/browser/settingsTree.ts index 58853e72e65..cede589c319 100644 --- a/src/vs/workbench/parts/preferences/browser/settingsTree.ts +++ b/src/vs/workbench/parts/preferences/browser/settingsTree.ts @@ -469,6 +469,7 @@ interface IDisposableTemplate { interface ISettingItemTemplate extends IDisposableTemplate { onChange?: (value: T) => void; + context?: SettingsTreeSettingElement; containerElement: HTMLElement; categoryElement: HTMLElement; labelElement: HTMLElement; @@ -499,7 +500,6 @@ interface ISettingComplexItemTemplate extends ISettingItemTemplate { interface ISettingExcludeItemTemplate extends ISettingItemTemplate { excludeWidget: ExcludeSettingWidget; - context?: SettingsTreeSettingElement; } interface ISettingNewExtensionsTemplate extends IDisposableTemplate { @@ -550,7 +550,11 @@ export class SettingsRenderer implements ITreeRenderer { private readonly _onDidClickSettingLink: Emitter = new Emitter(); public readonly onDidClickSettingLink: Event = this._onDidClickSettingLink.event; + private readonly _onDidFocusSetting: Emitter = new Emitter(); + public readonly onDidFocusSetting: Event = this._onDidFocusSetting.event; + private measureContainer: HTMLElement; + private measureTemplatesPool = new Map(); constructor( _measureContainer: HTMLElement, @@ -607,7 +611,7 @@ export class SettingsRenderer implements ITreeRenderer { const measureHelper = DOM.append(this.measureContainer, $('.setting-measure-helper')); const templateId = this.getTemplateId(tree, element); - const template = this.renderTemplate(tree, templateId, measureHelper); + const template = this.measureTemplatesPool.get(templateId) || this.renderTemplate(tree, templateId, measureHelper); this.renderElement(tree, element, templateId, template); const height = this.measureContainer.offsetHeight; @@ -703,7 +707,6 @@ export class SettingsRenderer implements ITreeRenderer { private renderCommonTemplate(tree: ITree, container: HTMLElement, typeClass: string): ISettingItemTemplate { DOM.addClass(container, 'setting-item'); DOM.addClass(container, 'setting-item-' + typeClass); - const titleElement = DOM.append(container, $('.setting-item-title')); const categoryElement = DOM.append(titleElement, $('span.setting-item-category')); const labelElement = DOM.append(titleElement, $('span.setting-item-label')); @@ -740,6 +743,14 @@ export class SettingsRenderer implements ITreeRenderer { return template; } + private addSettingElementFocusHandler(template: ISettingItemTemplate): void { + template.toDispose.push(DOM.addDisposableListener(template.containerElement, 'focus', e => { + if (template.context) { + this._onDidFocusSetting.fire(template.context); + } + }, true)); + } + private renderSettingTextTemplate(tree: ITree, container: HTMLElement, type = 'text'): ISettingTextItemTemplate { const common = this.renderCommonTemplate(tree, container, 'text'); @@ -763,6 +774,8 @@ export class SettingsRenderer implements ITreeRenderer { inputBox }; + this.addSettingElementFocusHandler(template); + return template; } @@ -789,6 +802,8 @@ export class SettingsRenderer implements ITreeRenderer { inputBox }; + this.addSettingElementFocusHandler(template); + return template; } @@ -829,6 +844,8 @@ export class SettingsRenderer implements ITreeRenderer { otherOverridesElement }; + this.addSettingElementFocusHandler(template); + // Prevent clicks from being handled by list toDispose.push(DOM.addDisposableListener(controlElement, 'mousedown', (e: IMouseEvent) => e.stopPropagation())); @@ -869,6 +886,8 @@ export class SettingsRenderer implements ITreeRenderer { enumDescriptionElement }; + this.addSettingElementFocusHandler(template); + return template; } @@ -883,6 +902,8 @@ export class SettingsRenderer implements ITreeRenderer { excludeWidget }; + this.addSettingElementFocusHandler(template); + common.toDispose.push(excludeWidget.onDidChangeExclude(e => { if (template.context) { const newValue = { @@ -942,6 +963,8 @@ export class SettingsRenderer implements ITreeRenderer { button: openSettingsButton }; + this.addSettingElementFocusHandler(template); + return template; } @@ -966,6 +989,8 @@ export class SettingsRenderer implements ITreeRenderer { toDispose }; + // this.addSettingElementFocusHandler(template); + return template; } @@ -993,9 +1018,10 @@ export class SettingsRenderer implements ITreeRenderer { } private elementIsSelected(tree: ITree, element: SettingsTreeElement): boolean { - const selection = tree.getSelection(); - const selectedElement: SettingsTreeElement = selection && selection[0]; - return selectedElement && selectedElement.id === element.id; + // const selection = tree.getSelection(); + // const selectedElement: SettingsTreeElement = selection && selection[0]; + // return selectedElement && selectedElement.id === element.id; + return true; } private renderNewExtensionsElement(element: SettingsTreeNewExtensionsElement, template: ISettingNewExtensionsTemplate): void { @@ -1003,6 +1029,8 @@ export class SettingsRenderer implements ITreeRenderer { } private renderSettingElement(tree: ITree, element: SettingsTreeSettingElement, templateId: string, template: ISettingItemTemplate | ISettingBoolItemTemplate): void { + template.context = element; + const isSelected = !!this.elementIsSelected(tree, element); const setting = element.setting; @@ -1023,9 +1051,9 @@ export class SettingsRenderer implements ITreeRenderer { if (element.setting.descriptionIsMarkdown) { const renderedDescription = this.renderDescriptionMarkdown(element.description, template.toDispose); template.descriptionElement.appendChild(renderedDescription); - (renderedDescription.querySelectorAll('a')).forEach(aElement => { - aElement.tabIndex = isSelected ? 0 : -1; - }); + // (renderedDescription.querySelectorAll('a')).forEach(aElement => { + // aElement.tabIndex = isSelected ? 0 : -1; + // }); const firstLineOverflows = renderedDescription.firstElementChild && renderedDescription.firstElementChild.clientHeight > 18; const hasExtraLines = renderedDescription.childElementCount > 1; @@ -1096,7 +1124,7 @@ export class SettingsRenderer implements ITreeRenderer { template.checkbox.checked = dataElement.value; template.onChange = onChange; - template.checkbox.domNode.tabIndex = isSelected ? 0 : -1; + // template.checkbox.domNode.tabIndex = isSelected ? 0 : -1; // Setup and add ARIA attributes // Create id and label for control/input element - parent is wrapper div @@ -1131,30 +1159,30 @@ export class SettingsRenderer implements ITreeRenderer { template.onChange = idx => onChange(dataElement.setting.enum[idx]); if (template.controlElement.firstElementChild) { - template.controlElement.firstElementChild.setAttribute('tabindex', isSelected ? '0' : '-1'); + // template.controlElement.firstElementChild.setAttribute('tabindex', isSelected ? '0' : '-1'); // SelectBox needs to be treeitem to read correctly within tree template.controlElement.firstElementChild.setAttribute('role', 'treeitem'); } template.enumDescriptionElement.innerHTML = ''; - if (dataElement.setting.enumDescriptions && dataElement.setting.enum && dataElement.setting.enum.length < SettingsRenderer.MAX_ENUM_DESCRIPTIONS) { - if (isSelected) { - let enumDescriptionText = '\n' + dataElement.setting.enumDescriptions - .map((desc, i) => { - const displayEnum = escapeInvisibleChars(dataElement.setting.enum[i]); - return desc ? - ` - \`${displayEnum}\`: ${desc}` : - ` - \`${dataElement.setting.enum[i]}\``; - }) - .filter(desc => !!desc) - .join('\n'); + // if (dataElement.setting.enumDescriptions && dataElement.setting.enum && dataElement.setting.enum.length < SettingsRenderer.MAX_ENUM_DESCRIPTIONS) { + // if (isSelected) { + // let enumDescriptionText = '\n' + dataElement.setting.enumDescriptions + // .map((desc, i) => { + // const displayEnum = escapeInvisibleChars(dataElement.setting.enum[i]); + // return desc ? + // ` - \`${displayEnum}\`: ${desc}` : + // ` - \`${dataElement.setting.enum[i]}\``; + // }) + // .filter(desc => !!desc) + // .join('\n'); - const renderedMarkdown = this.renderDescriptionMarkdown(fixSettingLinks(enumDescriptionText), template.toDispose); - template.enumDescriptionElement.appendChild(renderedMarkdown); - } + // const renderedMarkdown = this.renderDescriptionMarkdown(fixSettingLinks(enumDescriptionText), template.toDispose); + // template.enumDescriptionElement.appendChild(renderedMarkdown); + // } - return { overflows: true }; - } + // return { overflows: true }; + // } return { overflows: false }; } @@ -1163,7 +1191,7 @@ export class SettingsRenderer implements ITreeRenderer { template.onChange = null; template.inputBox.value = dataElement.value; template.onChange = value => onChange(value); - template.inputBox.inputElement.tabIndex = isSelected ? 0 : -1; + // template.inputBox.inputElement.tabIndex = isSelected ? 0 : -1; // Setup and add ARIA attributes // Create id and label for control/input element - parent is wrapper div @@ -1189,7 +1217,7 @@ export class SettingsRenderer implements ITreeRenderer { template.onChange = null; template.inputBox.value = dataElement.value; template.onChange = value => onChange(parseFn(value)); - template.inputBox.inputElement.tabIndex = isSelected ? 0 : -1; + // template.inputBox.inputElement.tabIndex = isSelected ? 0 : -1; const parseFn = dataElement.valueType === 'integer' ? parseInt : parseFloat; @@ -1219,7 +1247,7 @@ export class SettingsRenderer implements ITreeRenderer { } private renderComplexSetting(dataElement: SettingsTreeSettingElement, isSelected: boolean, template: ISettingComplexItemTemplate): void { - template.button.element.tabIndex = isSelected ? 0 : -1; + // template.button.element.tabIndex = isSelected ? 0 : -1; template.onChange = () => this._onDidOpenSettings.fire(dataElement.setting.key); } diff --git a/src/vs/workbench/parts/preferences/common/preferences.ts b/src/vs/workbench/parts/preferences/common/preferences.ts index efbbd723b00..f77fc18a455 100644 --- a/src/vs/workbench/parts/preferences/common/preferences.ts +++ b/src/vs/workbench/parts/preferences/common/preferences.ts @@ -61,8 +61,6 @@ export interface IKeybindingsEditor extends IEditor { export const CONTEXT_SETTINGS_EDITOR = new RawContextKey('inSettingsEditor', false); export const CONTEXT_SETTINGS_SEARCH_FOCUS = new RawContextKey('inSettingsSearch', false); -export const CONTEXT_SETTINGS_FIRST_ROW_FOCUS = new RawContextKey('firstSettingRowFocused', false); -export const CONTEXT_SETTINGS_ROW_FOCUS = new RawContextKey('settingRowFocused', false); export const CONTEXT_TOC_ROW_FOCUS = new RawContextKey('settingsTocRowFocus', false); export const CONTEXT_KEYBINDINGS_EDITOR = new RawContextKey('inKeybindings', false); export const CONTEXT_KEYBINDINGS_SEARCH_FOCUS = new RawContextKey('inKeybindingsSearch', false); @@ -74,7 +72,6 @@ export const SETTINGS_EDITOR_COMMAND_FOCUS_NEXT_SETTING = 'settings.action.focus export const SETTINGS_EDITOR_COMMAND_FOCUS_PREVIOUS_SETTING = 'settings.action.focusPreviousSetting'; export const SETTINGS_EDITOR_COMMAND_FOCUS_FILE = 'settings.action.focusSettingsFile'; export const SETTINGS_EDITOR_COMMAND_EDIT_FOCUSED_SETTING = 'settings.action.editFocusedSetting'; -export const SETTINGS_EDITOR_COMMAND_FOCUS_SEARCH_FROM_SETTINGS = 'settings.action.focusSearchFromSettings'; export const SETTINGS_EDITOR_COMMAND_FOCUS_SETTINGS_FROM_SEARCH = 'settings.action.focusSettingsFromSearch'; export const SETTINGS_EDITOR_COMMAND_FOCUS_SETTINGS_LIST = 'settings.action.focusSettingsList'; diff --git a/src/vs/workbench/parts/preferences/electron-browser/preferences.contribution.ts b/src/vs/workbench/parts/preferences/electron-browser/preferences.contribution.ts index 00ee94dd845..12f455b6224 100644 --- a/src/vs/workbench/parts/preferences/electron-browser/preferences.contribution.ts +++ b/src/vs/workbench/parts/preferences/electron-browser/preferences.contribution.ts @@ -22,7 +22,7 @@ import { KeybindingsEditor } from 'vs/workbench/parts/preferences/browser/keybin import { OpenDefaultKeybindingsFileAction, OpenRawDefaultSettingsAction, OpenSettingsAction, OpenGlobalSettingsAction, OpenGlobalKeybindingsFileAction, OpenWorkspaceSettingsAction, OpenFolderSettingsAction, ConfigureLanguageBasedSettingsAction, OPEN_FOLDER_SETTINGS_COMMAND, OpenGlobalKeybindingsAction, OpenSettings2Action } from 'vs/workbench/parts/preferences/browser/preferencesActions'; import { IKeybindingsEditor, IPreferencesSearchService, CONTEXT_KEYBINDING_FOCUS, CONTEXT_KEYBINDINGS_EDITOR, CONTEXT_KEYBINDINGS_SEARCH_FOCUS, KEYBINDINGS_EDITOR_COMMAND_DEFINE, KEYBINDINGS_EDITOR_COMMAND_REMOVE, KEYBINDINGS_EDITOR_COMMAND_SEARCH, - KEYBINDINGS_EDITOR_COMMAND_COPY, KEYBINDINGS_EDITOR_COMMAND_RESET, KEYBINDINGS_EDITOR_COMMAND_COPY_COMMAND, KEYBINDINGS_EDITOR_COMMAND_SHOW_SIMILAR, KEYBINDINGS_EDITOR_COMMAND_FOCUS_KEYBINDINGS, KEYBINDINGS_EDITOR_COMMAND_CLEAR_SEARCH_RESULTS, SETTINGS_EDITOR_COMMAND_SEARCH, CONTEXT_SETTINGS_EDITOR, SETTINGS_EDITOR_COMMAND_FOCUS_FILE, CONTEXT_SETTINGS_SEARCH_FOCUS, SETTINGS_EDITOR_COMMAND_CLEAR_SEARCH_RESULTS, SETTINGS_EDITOR_COMMAND_FOCUS_NEXT_SETTING, SETTINGS_EDITOR_COMMAND_FOCUS_PREVIOUS_SETTING, SETTINGS_EDITOR_COMMAND_EDIT_FOCUSED_SETTING, SETTINGS_EDITOR_COMMAND_FOCUS_SEARCH_FROM_SETTINGS, SETTINGS_EDITOR_COMMAND_FOCUS_SETTINGS_FROM_SEARCH, CONTEXT_SETTINGS_FIRST_ROW_FOCUS, CONTEXT_SETTINGS_ROW_FOCUS, CONTEXT_TOC_ROW_FOCUS, SETTINGS_EDITOR_COMMAND_FOCUS_SETTINGS_LIST + KEYBINDINGS_EDITOR_COMMAND_COPY, KEYBINDINGS_EDITOR_COMMAND_RESET, KEYBINDINGS_EDITOR_COMMAND_COPY_COMMAND, KEYBINDINGS_EDITOR_COMMAND_SHOW_SIMILAR, KEYBINDINGS_EDITOR_COMMAND_FOCUS_KEYBINDINGS, KEYBINDINGS_EDITOR_COMMAND_CLEAR_SEARCH_RESULTS, SETTINGS_EDITOR_COMMAND_SEARCH, CONTEXT_SETTINGS_EDITOR, SETTINGS_EDITOR_COMMAND_FOCUS_FILE, CONTEXT_SETTINGS_SEARCH_FOCUS, SETTINGS_EDITOR_COMMAND_CLEAR_SEARCH_RESULTS, SETTINGS_EDITOR_COMMAND_FOCUS_NEXT_SETTING, SETTINGS_EDITOR_COMMAND_FOCUS_PREVIOUS_SETTING, SETTINGS_EDITOR_COMMAND_EDIT_FOCUSED_SETTING, SETTINGS_EDITOR_COMMAND_FOCUS_SETTINGS_FROM_SEARCH, CONTEXT_TOC_ROW_FOCUS, SETTINGS_EDITOR_COMMAND_FOCUS_SETTINGS_LIST } from 'vs/workbench/parts/preferences/common/preferences'; import { IInstantiationService, ServicesAccessor } from 'vs/platform/instantiation/common/instantiation'; import { IWorkbenchContributionsRegistry, Extensions as WorkbenchExtensions } from 'vs/workbench/common/contributions'; @@ -355,23 +355,6 @@ const startSearchCommand = new StartSearchDefaultSettingsCommand({ }); startSearchCommand.register(); -class FocusSearchFromSettingsCommand extends SettingsCommand { - - public runCommand(accessor: ServicesAccessor, args: any): void { - const preferencesEditor = this.getPreferencesEditor(accessor); - if (preferencesEditor) { - preferencesEditor.focusSearch(); - } - } -} -const focusSearchFromSettingsCommand = new FocusSearchFromSettingsCommand({ - id: SETTINGS_EDITOR_COMMAND_FOCUS_SEARCH_FROM_SETTINGS, - precondition: ContextKeyExpr.and(CONTEXT_SETTINGS_EDITOR, CONTEXT_SETTINGS_FIRST_ROW_FOCUS), - kbOpts: { primary: KeyCode.UpArrow, weight: KeybindingWeight.WorkbenchContrib } -}); -focusSearchFromSettingsCommand.register(); - - class ClearSearchResultsCommand extends SettingsCommand { public runCommand(accessor: ServicesAccessor, args: any): void { @@ -461,23 +444,6 @@ const editFocusedSettingCommand = new EditFocusedSettingCommand({ }); editFocusedSettingCommand.register(); -class EditFocusedSettingCommand2 extends SettingsCommand { - - public runCommand(accessor: ServicesAccessor, args: any): void { - const preferencesEditor = this.getPreferencesEditor(accessor); - if (preferencesEditor instanceof SettingsEditor2) { - preferencesEditor.editSelectedSetting(); - } - } -} - -const editFocusedSettingCommand2 = new EditFocusedSettingCommand2({ - id: SETTINGS_EDITOR_COMMAND_EDIT_FOCUSED_SETTING, - precondition: ContextKeyExpr.and(CONTEXT_SETTINGS_EDITOR, CONTEXT_SETTINGS_ROW_FOCUS), - kbOpts: { primary: KeyCode.Enter, weight: KeybindingWeight.WorkbenchContrib } -}); -editFocusedSettingCommand2.register(); - class FocusSettingsListCommand extends SettingsCommand { public runCommand(accessor: ServicesAccessor, args: any): void { From d1c0cc09edbf1cc9d827a927c4348c51771255cf Mon Sep 17 00:00:00 2001 From: Rob Lourens Date: Wed, 8 Aug 2018 17:26:26 -0700 Subject: [PATCH 0608/1276] #54039 pool templates for faster measuring --- .../workbench/parts/preferences/browser/settingsTree.ts | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/vs/workbench/parts/preferences/browser/settingsTree.ts b/src/vs/workbench/parts/preferences/browser/settingsTree.ts index cede589c319..0b0d00fc622 100644 --- a/src/vs/workbench/parts/preferences/browser/settingsTree.ts +++ b/src/vs/workbench/parts/preferences/browser/settingsTree.ts @@ -608,14 +608,14 @@ export class SettingsRenderer implements ITreeRenderer { } private measureSettingElementHeight(tree: ITree, element: SettingsTreeSettingElement): number { - const measureHelper = DOM.append(this.measureContainer, $('.setting-measure-helper')); - const templateId = this.getTemplateId(tree, element); - const template = this.measureTemplatesPool.get(templateId) || this.renderTemplate(tree, templateId, measureHelper); + const template: ISettingItemTemplate = this.measureTemplatesPool.get(templateId) || this.renderTemplate(tree, templateId, $('.setting-measure-helper')) as ISettingItemTemplate; this.renderElement(tree, element, templateId, template); - const height = this.measureContainer.offsetHeight; + this.measureContainer.appendChild(template.containerElement); this.measureContainer.removeChild(this.measureContainer.firstChild); + const height = this.measureContainer.offsetHeight; + return Math.max(height, this._getUnexpandedSettingHeight(element)); } From 2a8c623ff0bf846104d129b7f610c3abddda2e79 Mon Sep 17 00:00:00 2001 From: Rob Lourens Date: Wed, 8 Aug 2018 19:09:58 -0700 Subject: [PATCH 0609/1276] #54039 - focus and refresh fixes --- .../preferences/browser/settingsEditor2.ts | 72 ++++++++++----- .../parts/preferences/browser/settingsTree.ts | 92 +++++-------------- .../preferences/browser/settingsWidgets.ts | 1 - 3 files changed, 72 insertions(+), 93 deletions(-) diff --git a/src/vs/workbench/parts/preferences/browser/settingsEditor2.ts b/src/vs/workbench/parts/preferences/browser/settingsEditor2.ts index aa5ffbe2e98..efcaf7544ef 100644 --- a/src/vs/workbench/parts/preferences/browser/settingsEditor2.ts +++ b/src/vs/workbench/parts/preferences/browser/settingsEditor2.ts @@ -15,6 +15,7 @@ import * as collections from 'vs/base/common/collections'; import { getErrorMessage, isPromiseCanceledError } from 'vs/base/common/errors'; import URI from 'vs/base/common/uri'; import { TPromise } from 'vs/base/common/winjs.base'; +import { Tree } from 'vs/base/parts/tree/browser/treeImpl'; import { collapseAll, expandAll } from 'vs/base/parts/tree/browser/treeUtils'; import 'vs/css!./media/settingsEditor2'; import { localize } from 'vs/nls'; @@ -55,7 +56,7 @@ export class SettingsEditor2 extends BaseEditor { private toolbar: ToolBar; private settingsTreeContainer: HTMLElement; - private settingsTree: WorkbenchTree; + private settingsTree: Tree; private tocTreeModel: TOCTreeModel; private settingsTreeModel: SettingsTreeModel; @@ -126,9 +127,10 @@ export class SettingsEditor2 extends BaseEditor { setInput(input: SettingsEditor2Input, options: EditorOptions, token: CancellationToken): Thenable { this.inSettingsEditorContextKey.set(true); return super.setInput(input, options, token) + .then(() => new Promise(process.nextTick)) // Force setInput to be async .then(() => { return this.render(token); - }).then(() => new Promise(process.nextTick)); // Force setInput to be async + }); } clearInput(): void { @@ -272,15 +274,32 @@ export class SettingsEditor2 extends BaseEditor { private createBody(parent: HTMLElement): void { const bodyContainer = DOM.append(parent, $('.settings-body')); - this.createFocusSink(bodyContainer, () => { - const firstElement = this.settingsTree.getFirstVisibleElement(); - this.settingsTree.reveal(firstElement, 0.1); - }); + this.createFocusSink( + bodyContainer, + () => { + if (this.settingsTree.getScrollPosition() > 0) { + const firstElement = this.settingsTree.getFirstVisibleElement(); + this.settingsTree.reveal(firstElement, 0.1); + return true; + } + return false; + }, + 'settings list focus helper'); + this.createSettingsTree(bodyContainer); - this.createFocusSink(bodyContainer, () => { - const lastElement = this.settingsTree.getLastVisibleElement(); - this.settingsTree.reveal(lastElement, 0.9); - }); + + this.createFocusSink( + bodyContainer, + () => { + if (this.settingsTree.getScrollPosition() < 1) { + const lastElement = this.settingsTree.getLastVisibleElement(); + this.settingsTree.reveal(lastElement, 0.9); + return true; + } + return false; + }, + 'settings list focus helper' + ); this.createTOC(bodyContainer); @@ -289,13 +308,15 @@ export class SettingsEditor2 extends BaseEditor { } } - private createFocusSink(container: HTMLElement, callback: () => void): HTMLElement { + private createFocusSink(container: HTMLElement, callback: () => boolean, label: string): HTMLElement { const listFocusSink = DOM.append(container, $('.settings-tree-focus-sink')); + listFocusSink.setAttribute('aria-label', label); listFocusSink.tabIndex = 0; this._register(DOM.addDisposableListener(listFocusSink, 'focus', e => { - if (e.relatedTarget && DOM.findParentWithClass(e.relatedTarget, 'monaco-tree')) { - callback(); - e.relatedTarget.focus(); + if (e.relatedTarget && DOM.findParentWithClass(e.relatedTarget, 'settings-editor-tree')) { + if (callback()) { + e.relatedTarget.focus(); + } } })); @@ -315,15 +336,15 @@ export class SettingsEditor2 extends BaseEditor { })); this._register(this.tocTree.onDidChangeFocus(e => { - // Let the caller finish before trying to sync with settings tree. - // e.g. clicking this twistie, which will toggle the row's expansion state _after_ this event is fired. - process.nextTick(() => { - const element = e.focus; - if (this.searchResultModel) { - this.viewState.filterToCategory = element; - this.refreshTreeAndMaintainFocus(); - } - }); + const element = e.focus; + if (this.searchResultModel) { + this.viewState.filterToCategory = element; + this.refreshTreeAndMaintainFocus(); + } + + if (element && (!e.payload || !e.payload.fromScroll)) { + this.settingsTree.reveal(element, 0); + } })); this._register(this.tocTree.onDidFocus(() => { @@ -363,7 +384,7 @@ export class SettingsEditor2 extends BaseEditor { { renderer })); - this.settingsTree.getHTMLElement().tabIndex = -1; + this.settingsTree.getHTMLElement().attributes.removeNamedItem('tabindex'); this._register(this.settingsTree.onDidScroll(() => { this.updateTreeScrollSync(); @@ -568,6 +589,7 @@ export class SettingsEditor2 extends BaseEditor { if (this.settingsTreeModel) { this.settingsTreeModel.update(resolvedSettingsRoot); + return this.refreshTreeAndMaintainFocus(); } else { this.settingsTreeModel = this.instantiationService.createInstance(SettingsTreeModel, this.viewState, resolvedSettingsRoot); this.settingsTree.setInput(this.settingsTreeModel.root); @@ -580,7 +602,7 @@ export class SettingsEditor2 extends BaseEditor { } } - return this.refreshTreeAndMaintainFocus(); + return TPromise.wrap(null); } private refreshTreeAndMaintainFocus(): TPromise { diff --git a/src/vs/workbench/parts/preferences/browser/settingsTree.ts b/src/vs/workbench/parts/preferences/browser/settingsTree.ts index 0b0d00fc622..aac4fd444f4 100644 --- a/src/vs/workbench/parts/preferences/browser/settingsTree.ts +++ b/src/vs/workbench/parts/preferences/browser/settingsTree.ts @@ -23,20 +23,21 @@ import URI from 'vs/base/common/uri'; import { TPromise } from 'vs/base/common/winjs.base'; import { IAccessibilityProvider, IDataSource, IFilter, IRenderer as ITreeRenderer, ITree, ITreeConfiguration } from 'vs/base/parts/tree/browser/tree'; import { DefaultTreestyler } from 'vs/base/parts/tree/browser/treeDefaults'; +import { Tree } from 'vs/base/parts/tree/browser/treeImpl'; import { localize } from 'vs/nls'; import { ICommandService } from 'vs/platform/commands/common/commands'; import { ConfigurationTarget, IConfigurationService } from 'vs/platform/configuration/common/configuration'; import { IContextKeyService } from 'vs/platform/contextkey/common/contextkey'; import { IContextViewService } from 'vs/platform/contextview/browser/contextView'; import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; -import { IListService, WorkbenchTree, WorkbenchTreeController } from 'vs/platform/list/browser/listService'; +import { IListService, WorkbenchTreeController } from 'vs/platform/list/browser/listService'; import { IOpenerService } from 'vs/platform/opener/common/opener'; import { editorBackground, focusBorder, foreground } from 'vs/platform/theme/common/colorRegistry'; import { attachButtonStyler, attachInputBoxStyler, attachSelectBoxStyler, attachStyler } from 'vs/platform/theme/common/styler'; import { ICssStyleCollector, ITheme, IThemeService, registerThemingParticipant } from 'vs/platform/theme/common/themeService'; import { SettingsTarget } from 'vs/workbench/parts/preferences/browser/preferencesWidgets'; import { ITOCEntry } from 'vs/workbench/parts/preferences/browser/settingsLayout'; -import { ExcludeSettingWidget, IExcludeDataItem, settingItemInactiveSelectionBorder, settingsHeaderForeground, settingsNumberInputBackground, settingsNumberInputBorder, settingsNumberInputForeground, settingsSelectBackground, settingsSelectBorder, settingsSelectForeground, settingsTextInputBackground, settingsTextInputBorder, settingsTextInputForeground } from 'vs/workbench/parts/preferences/browser/settingsWidgets'; +import { ExcludeSettingWidget, IExcludeDataItem, settingsHeaderForeground, settingsNumberInputBackground, settingsNumberInputBorder, settingsNumberInputForeground, settingsSelectBackground, settingsSelectBorder, settingsSelectForeground, settingsTextInputBackground, settingsTextInputBorder, settingsTextInputForeground } from 'vs/workbench/parts/preferences/browser/settingsWidgets'; import { IExtensionSetting, ISearchResult, ISetting, ISettingsGroup } from 'vs/workbench/services/preferences/common/preferences'; const $ = DOM.$; @@ -578,10 +579,10 @@ export class SettingsRenderer implements ITreeRenderer { if (element instanceof SettingsTreeSettingElement) { const isSelected = this.elementIsSelected(tree, element); - if (isSelected) { - return this.measureSettingElementHeight(tree, element); - } else if (isExcludeSetting(element.setting)) { + if (isExcludeSetting(element.setting)) { return this._getExcludeSettingHeight(element); + } else if (isSelected) { + return this.measureSettingElementHeight(tree, element); } else { return this._getUnexpandedSettingHeight(element); } @@ -613,9 +614,8 @@ export class SettingsRenderer implements ITreeRenderer { this.renderElement(tree, element, templateId, template); this.measureContainer.appendChild(template.containerElement); - this.measureContainer.removeChild(this.measureContainer.firstChild); const height = this.measureContainer.offsetHeight; - + this.measureContainer.removeChild(this.measureContainer.firstChild); return Math.max(height, this._getUnexpandedSettingHeight(element)); } @@ -1476,7 +1476,7 @@ export class SearchResultModel { } } -class NonExpandableTree extends WorkbenchTree { +class NonExpandableOrSelectableTree extends Tree { expand(): TPromise { return TPromise.wrap(null); } @@ -1484,9 +1484,23 @@ class NonExpandableTree extends WorkbenchTree { collapse(): TPromise { return TPromise.wrap(null); } + + public setFocus(element?: any, eventPayload?: any): void { + return; + } + + public focusNext(count?: number, eventPayload?: any): void { + return; + } + + public focusPrevious(count?: number, eventPayload?: any): void { + return; + } } -export class SettingsTree extends NonExpandableTree { +export class SettingsTree extends NonExpandableOrSelectableTree { + protected disposables: IDisposable[]; + constructor( container: HTMLElement, viewState: ISettingsEditorViewState, @@ -1519,29 +1533,18 @@ export class SettingsTree extends NonExpandableTree { super(container, fullConfiguration, - options, - contextKeyService, - listService, - themeService, - instantiationService, - configurationService); + options); + this.disposables = []; this.disposables.push(controller); this.disposables.push(registerThemingParticipant((theme: ITheme, collector: ICssStyleCollector) => { const activeBorderColor = theme.getColor(focusBorder); if (activeBorderColor) { - collector.addRule(`.settings-editor > .settings-body > .settings-tree-container .monaco-tree:focus .monaco-tree-row.focused {outline: solid 1px ${activeBorderColor}; outline-offset: -1px; }`); - // TODO@rob - why isn't this applied when added to the stylesheet from tocTree.ts? Seems like a chromium glitch. collector.addRule(`.settings-editor > .settings-body > .settings-toc-container .monaco-tree:focus .monaco-tree-row.focused {outline: solid 1px ${activeBorderColor}; outline-offset: -1px; }`); } - const inactiveBorderColor = theme.getColor(settingItemInactiveSelectionBorder); - if (inactiveBorderColor) { - collector.addRule(`.settings-editor > .settings-body > .settings-tree-container .monaco-tree .monaco-tree-row.focused {outline: solid 1px ${inactiveBorderColor}; outline-offset: -1px; }`); - } - const foregroundColor = theme.getColor(foreground); if (foregroundColor) { // Links appear inside other elements in markdown. CSS opacity acts like a mask. So we have to dynamically compute the description color to avoid @@ -1573,49 +1576,4 @@ export class SettingsTree extends NonExpandableTree { this.style(colors); })); } - - public setFocus(element?: any, eventPayload?: any): void { - if (element instanceof SettingsTreeGroupElement) { - const nav = this.getNavigator(element, false); - do { - element = nav.next(); - } while (element instanceof SettingsTreeGroupElement); - } - - super.setFocus(element, eventPayload); - } - - public focusNext(count?: number, eventPayload?: any): void { - const focus = this.getFocus(); - if (!focus) { - return super.focusFirst(); - } - - const nav = this.getNavigator(focus, false); - let current; - do { - current = nav.next(); - } while (current instanceof SettingsTreeGroupElement); - - if (current) { - this.setFocus(current, eventPayload); - } - } - - public focusPrevious(count?: number, eventPayload?: any): void { - const focus = this.getFocus(); - if (!focus) { - return super.focusFirst(); - } - - const nav = this.getNavigator(focus, false); - let current; - do { - current = nav.previous(); - } while (current instanceof SettingsTreeGroupElement); - - if (current) { - this.setFocus(current, eventPayload); - } - } } diff --git a/src/vs/workbench/parts/preferences/browser/settingsWidgets.ts b/src/vs/workbench/parts/preferences/browser/settingsWidgets.ts index 16c7dc7ad40..775caefe5d3 100644 --- a/src/vs/workbench/parts/preferences/browser/settingsWidgets.ts +++ b/src/vs/workbench/parts/preferences/browser/settingsWidgets.ts @@ -22,7 +22,6 @@ import { ICssStyleCollector, ITheme, IThemeService, registerThemingParticipant } const $ = DOM.$; export const settingsHeaderForeground = registerColor('settings.headerForeground', { light: '#444444', dark: '#e7e7e7', hc: '#ffffff' }, localize('headerForeground', "(For settings editor preview) The foreground color for a section header or active title.")); export const modifiedItemForeground = registerColor('settings.modifiedItemForeground', { light: '#018101', dark: '#73C991', hc: '#73C991' }, localize('modifiedItemForeground', "(For settings editor preview) The foreground color for a the modified setting indicator.")); -export const settingItemInactiveSelectionBorder = registerColor('settings.inactiveSelectedItemBorder', { dark: '#3F3F46', light: '#CCCEDB', hc: null }, localize('settingItemInactiveSelectionBorder', "(For settings editor preview) The color of the selected setting row border, when the settings list does not have focus.")); // Enum control colors export const settingsSelectBackground = registerColor('settings.dropdownBackground', { dark: selectBackground, light: selectBackground, hc: selectBackground }, localize('settingsDropdownBackground', "(For settings editor preview) Settings editor dropdown background.")); From c958a500f9462fc41db4c14fa555f7cc4c91229d Mon Sep 17 00:00:00 2001 From: Rob Lourens Date: Wed, 8 Aug 2018 19:28:04 -0700 Subject: [PATCH 0610/1276] #54039 - cache row widths for faster rendering --- .../preferences/browser/settingsEditor2.ts | 19 ++++++++++++------ .../parts/preferences/browser/settingsTree.ts | 20 +++++++++++++++++++ 2 files changed, 33 insertions(+), 6 deletions(-) diff --git a/src/vs/workbench/parts/preferences/browser/settingsEditor2.ts b/src/vs/workbench/parts/preferences/browser/settingsEditor2.ts index efcaf7544ef..4420b3ec434 100644 --- a/src/vs/workbench/parts/preferences/browser/settingsEditor2.ts +++ b/src/vs/workbench/parts/preferences/browser/settingsEditor2.ts @@ -57,6 +57,7 @@ export class SettingsEditor2 extends BaseEditor { private settingsTreeContainer: HTMLElement; private settingsTree: Tree; + private settingsTreeRenderer: SettingsRenderer; private tocTreeModel: TOCTreeModel; private settingsTreeModel: SettingsTreeModel; @@ -67,6 +68,7 @@ export class SettingsEditor2 extends BaseEditor { private localSearchDelayer: Delayer; private remoteSearchThrottle: ThrottledDelayer; private searchInProgress: TPromise; + private delayRefreshOnLayout: Delayer; private settingUpdateDelayer: Delayer; private pendingSettingUpdate: { key: string, value: any }; @@ -100,6 +102,7 @@ export class SettingsEditor2 extends BaseEditor { this.localSearchDelayer = new Delayer(100); this.remoteSearchThrottle = new ThrottledDelayer(200); this.viewState = { settingsTarget: ConfigurationTarget.USER }; + this.delayRefreshOnLayout = new Delayer(100); this.settingUpdateDelayer = new Delayer(500); @@ -143,6 +146,8 @@ export class SettingsEditor2 extends BaseEditor { this.layoutTrees(dimension); DOM.toggleClass(this.rootElement, 'narrow', dimension.width < 600); + + this.delayRefreshOnLayout.trigger(() => this.refreshTreeAndMaintainFocus()); } focus(): void { @@ -366,23 +371,23 @@ export class SettingsEditor2 extends BaseEditor { private createSettingsTree(parent: HTMLElement): void { this.settingsTreeContainer = DOM.append(parent, $('.settings-tree-container')); - const renderer = this.instantiationService.createInstance(SettingsRenderer, this.settingsTreeContainer); - this._register(renderer.onDidChangeSetting(e => this.onDidChangeSetting(e.key, e.value))); - this._register(renderer.onDidOpenSettings(settingKey => { + this.settingsTreeRenderer = this.instantiationService.createInstance(SettingsRenderer, this.settingsTreeContainer); + this._register(this.settingsTreeRenderer.onDidChangeSetting(e => this.onDidChangeSetting(e.key, e.value))); + this._register(this.settingsTreeRenderer.onDidOpenSettings(settingKey => { this.openSettingsFile().then(editor => { if (editor instanceof PreferencesEditor && settingKey) { editor.focusSearch(settingKey); } }); })); - this._register(renderer.onDidClickSettingLink(settingName => this.revealSetting(settingName))); - this._register(renderer.onDidFocusSetting(element => this.revealSettingElement(element))); + this._register(this.settingsTreeRenderer.onDidClickSettingLink(settingName => this.revealSetting(settingName))); + this._register(this.settingsTreeRenderer.onDidFocusSetting(element => this.revealSettingElement(element))); this.settingsTree = this._register(this.instantiationService.createInstance(SettingsTree, this.settingsTreeContainer, this.viewState, { - renderer + renderer: this.settingsTreeRenderer })); this.settingsTree.getHTMLElement().attributes.removeNamedItem('tabindex'); @@ -801,6 +806,8 @@ export class SettingsEditor2 extends BaseEditor { const tocTreeHeight = listHeight - 16; this.tocTreeContainer.style.height = `${tocTreeHeight}px`; this.tocTree.layout(tocTreeHeight, 175); + + this.settingsTreeRenderer.updateWidth(dimension.width); } } diff --git a/src/vs/workbench/parts/preferences/browser/settingsTree.ts b/src/vs/workbench/parts/preferences/browser/settingsTree.ts index aac4fd444f4..db4b008c3ba 100644 --- a/src/vs/workbench/parts/preferences/browser/settingsTree.ts +++ b/src/vs/workbench/parts/preferences/browser/settingsTree.ts @@ -556,6 +556,8 @@ export class SettingsRenderer implements ITreeRenderer { private measureContainer: HTMLElement; private measureTemplatesPool = new Map(); + private rowHeightCache = new Map(); + private lastRenderedWidth: number; constructor( _measureContainer: HTMLElement, @@ -568,7 +570,25 @@ export class SettingsRenderer implements ITreeRenderer { this.measureContainer = DOM.append(_measureContainer, $('.setting-measure-container.monaco-tree-row')); } + updateWidth(width: number): void { + if (this.lastRenderedWidth !== width) { + this.rowHeightCache = new Map(); + } + + this.lastRenderedWidth = width; + } + getHeight(tree: ITree, element: SettingsTreeElement): number { + if (this.rowHeightCache.has(element.id)) { + return this.rowHeightCache.get(element.id); + } + + const h = this._getHeight(tree, element); + this.rowHeightCache.set(element.id, h); + return h; + } + + _getHeight(tree: ITree, element: SettingsTreeElement): number { if (element instanceof SettingsTreeGroupElement) { if (element.isFirstGroup) { return 31; From 0b0e476fa6eef2c00d402124c149c6a7d637942d Mon Sep 17 00:00:00 2001 From: Rob Lourens Date: Wed, 8 Aug 2018 20:12:47 -0700 Subject: [PATCH 0611/1276] #54039 - don't leave focus on focus sinks --- .../preferences/browser/settingsEditor2.ts | 51 ++++++++++++------- .../parts/preferences/browser/settingsTree.ts | 14 +++-- .../preferences/browser/settingsWidgets.ts | 4 ++ 3 files changed, 48 insertions(+), 21 deletions(-) diff --git a/src/vs/workbench/parts/preferences/browser/settingsEditor2.ts b/src/vs/workbench/parts/preferences/browser/settingsEditor2.ts index 4420b3ec434..c8b81ea5955 100644 --- a/src/vs/workbench/parts/preferences/browser/settingsEditor2.ts +++ b/src/vs/workbench/parts/preferences/browser/settingsEditor2.ts @@ -155,7 +155,7 @@ export class SettingsEditor2 extends BaseEditor { } focusSettings(): void { - const firstFocusable = this.settingsTree.getHTMLElement().querySelector('a, input, [tabindex="0"]'); + const firstFocusable = this.settingsTree.getHTMLElement().querySelector(SettingsRenderer.CONTROL_SELECTOR); if (firstFocusable) { (firstFocusable).focus(); } @@ -251,7 +251,7 @@ export class SettingsEditor2 extends BaseEditor { private revealSetting(settingName: string): void { const element = this.settingsTreeModel.getElementByName(settingName); if (element) { - this.settingsTree.reveal(element, 0); + this.settingsTree.reveal(element, .1); } } @@ -281,12 +281,20 @@ export class SettingsEditor2 extends BaseEditor { this.createFocusSink( bodyContainer, - () => { - if (this.settingsTree.getScrollPosition() > 0) { - const firstElement = this.settingsTree.getFirstVisibleElement(); - this.settingsTree.reveal(firstElement, 0.1); - return true; + e => { + if (DOM.findParentWithClass(e.relatedTarget, 'settings-editor-tree')) { + if (this.settingsTree.getScrollPosition() > 0) { + const firstElement = this.settingsTree.getFirstVisibleElement(); + this.settingsTree.reveal(firstElement, 0.1); + return true; + } + } else { + const firstControl = this.settingsTree.getHTMLElement().querySelector(SettingsRenderer.CONTROL_SELECTOR); + if (firstControl) { + (firstControl).focus(); + } } + return false; }, 'settings list focus helper'); @@ -295,12 +303,21 @@ export class SettingsEditor2 extends BaseEditor { this.createFocusSink( bodyContainer, - () => { - if (this.settingsTree.getScrollPosition() < 1) { - const lastElement = this.settingsTree.getLastVisibleElement(); - this.settingsTree.reveal(lastElement, 0.9); - return true; + e => { + if (DOM.findParentWithClass(e.relatedTarget, 'settings-editor-tree')) { + if (this.settingsTree.getScrollPosition() < 1) { + const lastElement = this.settingsTree.getLastVisibleElement(); + this.settingsTree.reveal(lastElement, 0.9); + return true; + } + } else { + const controls = this.settingsTree.getHTMLElement().querySelectorAll(SettingsRenderer.CONTROL_SELECTOR); + const lastControl = controls && controls[controls.length]; + if (lastControl) { + (lastControl).focus(); + } } + return false; }, 'settings list focus helper' @@ -313,15 +330,13 @@ export class SettingsEditor2 extends BaseEditor { } } - private createFocusSink(container: HTMLElement, callback: () => boolean, label: string): HTMLElement { + private createFocusSink(container: HTMLElement, callback: (e: any) => boolean, label: string): HTMLElement { const listFocusSink = DOM.append(container, $('.settings-tree-focus-sink')); listFocusSink.setAttribute('aria-label', label); listFocusSink.tabIndex = 0; - this._register(DOM.addDisposableListener(listFocusSink, 'focus', e => { - if (e.relatedTarget && DOM.findParentWithClass(e.relatedTarget, 'settings-editor-tree')) { - if (callback()) { - e.relatedTarget.focus(); - } + this._register(DOM.addDisposableListener(listFocusSink, 'focus', (e: any) => { + if (e.relatedTarget && callback(e)) { + e.relatedTarget.focus(); } })); diff --git a/src/vs/workbench/parts/preferences/browser/settingsTree.ts b/src/vs/workbench/parts/preferences/browser/settingsTree.ts index db4b008c3ba..77cf3f29255 100644 --- a/src/vs/workbench/parts/preferences/browser/settingsTree.ts +++ b/src/vs/workbench/parts/preferences/browser/settingsTree.ts @@ -542,6 +542,9 @@ export class SettingsRenderer implements ITreeRenderer { private static readonly SETTING_BOOL_ROW_HEIGHT = 73; public static readonly MAX_ENUM_DESCRIPTIONS = 10; + private static readonly CONTROL_CLASS = 'setting-control-focus-target'; + public static readonly CONTROL_SELECTOR = '.' + SettingsRenderer.CONTROL_CLASS; + private readonly _onDidChangeSetting: Emitter = new Emitter(); public readonly onDidChangeSetting: Event = this._onDidChangeSetting.event; @@ -788,6 +791,7 @@ export class SettingsRenderer implements ITreeRenderer { } })); common.toDispose.push(inputBox); + inputBox.inputElement.classList.add(SettingsRenderer.CONTROL_CLASS); const template: ISettingTextItemTemplate = { ...common, @@ -816,6 +820,7 @@ export class SettingsRenderer implements ITreeRenderer { } })); common.toDispose.push(inputBox); + inputBox.inputElement.classList.add(SettingsRenderer.CONTROL_CLASS); const template: ISettingNumberItemTemplate = { ...common, @@ -850,6 +855,7 @@ export class SettingsRenderer implements ITreeRenderer { template.onChange(checkbox.checked); } })); + checkbox.domNode.classList.add(SettingsRenderer.CONTROL_CLASS); const template: ISettingBoolItemTemplate = { toDispose, @@ -890,6 +896,10 @@ export class SettingsRenderer implements ITreeRenderer { selectBorder: settingsSelectBorder })); selectBox.render(common.controlElement); + const selectElement = common.controlElement.querySelector('select'); + if (selectElement) { + selectElement.classList.add(SettingsRenderer.CONTROL_CLASS); + } common.toDispose.push( selectBox.onDidSelect(e => { @@ -915,6 +925,7 @@ export class SettingsRenderer implements ITreeRenderer { const common = this.renderCommonTemplate(tree, container, 'exclude'); const excludeWidget = this.instantiationService.createInstance(ExcludeSettingWidget, common.controlElement); + excludeWidget.domNode.classList.add(SettingsRenderer.CONTROL_CLASS); common.toDispose.push(excludeWidget); const template: ISettingExcludeItemTemplate = { @@ -1211,7 +1222,6 @@ export class SettingsRenderer implements ITreeRenderer { template.onChange = null; template.inputBox.value = dataElement.value; template.onChange = value => onChange(value); - // template.inputBox.inputElement.tabIndex = isSelected ? 0 : -1; // Setup and add ARIA attributes // Create id and label for control/input element - parent is wrapper div @@ -1237,7 +1247,6 @@ export class SettingsRenderer implements ITreeRenderer { template.onChange = null; template.inputBox.value = dataElement.value; template.onChange = value => onChange(parseFn(value)); - // template.inputBox.inputElement.tabIndex = isSelected ? 0 : -1; const parseFn = dataElement.valueType === 'integer' ? parseInt : parseFloat; @@ -1267,7 +1276,6 @@ export class SettingsRenderer implements ITreeRenderer { } private renderComplexSetting(dataElement: SettingsTreeSettingElement, isSelected: boolean, template: ISettingComplexItemTemplate): void { - // template.button.element.tabIndex = isSelected ? 0 : -1; template.onChange = () => this._onDidOpenSettings.fire(dataElement.setting.key); } diff --git a/src/vs/workbench/parts/preferences/browser/settingsWidgets.ts b/src/vs/workbench/parts/preferences/browser/settingsWidgets.ts index 775caefe5d3..862ec4dde3b 100644 --- a/src/vs/workbench/parts/preferences/browser/settingsWidgets.ts +++ b/src/vs/workbench/parts/preferences/browser/settingsWidgets.ts @@ -187,6 +187,10 @@ export class ExcludeSettingWidget extends Disposable { private readonly _onDidChangeExclude: Emitter = new Emitter(); public readonly onDidChangeExclude: Event = this._onDidChangeExclude.event; + get domNode(): HTMLElement { + return this.listElement; + } + constructor( private container: HTMLElement, @IThemeService private themeService: IThemeService, From b7677de2a04f5fd547b597e9a0a917b816524a73 Mon Sep 17 00:00:00 2001 From: Rob Lourens Date: Wed, 8 Aug 2018 20:20:55 -0700 Subject: [PATCH 0612/1276] #54039 - remove dead code --- .../browser/media/settingsEditor2.css | 18 ----- .../preferences/browser/settingsEditor2.ts | 23 +----- .../parts/preferences/browser/settingsTree.ts | 76 +++++-------------- 3 files changed, 18 insertions(+), 99 deletions(-) diff --git a/src/vs/workbench/parts/preferences/browser/media/settingsEditor2.css b/src/vs/workbench/parts/preferences/browser/media/settingsEditor2.css index fa5d1ab6f8f..30a6e934f54 100644 --- a/src/vs/workbench/parts/preferences/browser/media/settingsEditor2.css +++ b/src/vs/workbench/parts/preferences/browser/media/settingsEditor2.css @@ -273,24 +273,6 @@ transform: translate3d(0px, 0px, 0px); } -.settings-editor > .settings-body > .settings-tree-container .setting-item .setting-item-description.setting-item-description-artificial-overflow { - display: block; -} - -.settings-editor > .settings-body > .settings-tree-container .setting-item .setting-item-description-artificial-overflow .setting-item-description-markdown { - display: inline-block; - margin-right: 3px; -} - -.settings-editor > .settings-body > .settings-tree-container .setting-item .setting-item-description-artificial-overflow::after { - display: inline-block; - content: '…'; - width: 16px; - height: 16px; - position: absolute; - transform: translate3d(0px, 0px, 0px); -} - .settings-editor > .settings-body > .settings-tree-container .setting-item .setting-item-description-markdown * { margin: 0px; } diff --git a/src/vs/workbench/parts/preferences/browser/settingsEditor2.ts b/src/vs/workbench/parts/preferences/browser/settingsEditor2.ts index c8b81ea5955..4f94c79cb9e 100644 --- a/src/vs/workbench/parts/preferences/browser/settingsEditor2.ts +++ b/src/vs/workbench/parts/preferences/browser/settingsEditor2.ts @@ -165,14 +165,6 @@ export class SettingsEditor2 extends BaseEditor { this.searchWidget.focus(); } - editSelectedSetting(): void { - const focus = this.settingsTree.getFocus(); - if (focus instanceof SettingsTreeSettingElement) { - const itemId = focus.id.replace(/\./g, '_'); - this.focusEditControlForRow(itemId); - } - } - clearSearchResults(): void { this.searchWidget.clear(); } @@ -441,15 +433,7 @@ export class SettingsEditor2 extends BaseEditor { return; } - let elementToSync = this.settingsTree.getFirstVisibleElement(); - const selection = this.settingsTree.getSelection()[0]; - if (selection) { - const selectionPos = this.settingsTree.getRelativeTop(selection); - if (selectionPos >= 0 && selectionPos <= 1) { - elementToSync = selection; - } - } - + const elementToSync = this.settingsTree.getFirstVisibleElement(); const element = elementToSync instanceof SettingsTreeSettingElement ? elementToSync.parent : elementToSync instanceof SettingsTreeGroupElement ? elementToSync : null; @@ -813,11 +797,6 @@ export class SettingsEditor2 extends BaseEditor { this.settingsTreeContainer.style.height = `${settingsTreeHeight}px`; this.settingsTree.layout(settingsTreeHeight, 800); - const selectedSetting = this.settingsTree.getSelection()[0]; - if (selectedSetting) { - this.settingsTree.refresh(selectedSetting); - } - const tocTreeHeight = listHeight - 16; this.tocTreeContainer.style.height = `${tocTreeHeight}px`; this.tocTree.layout(tocTreeHeight, 175); diff --git a/src/vs/workbench/parts/preferences/browser/settingsTree.ts b/src/vs/workbench/parts/preferences/browser/settingsTree.ts index 77cf3f29255..59737f81ccb 100644 --- a/src/vs/workbench/parts/preferences/browser/settingsTree.ts +++ b/src/vs/workbench/parts/preferences/browser/settingsTree.ts @@ -518,10 +518,6 @@ interface IGroupTitleTemplate extends IDisposableTemplate { parent: HTMLElement; } -interface IValueRenderResult { - overflows?: boolean; -} - const SETTINGS_TEXT_TEMPLATE_ID = 'settings.text.template'; const SETTINGS_NUMBER_TEMPLATE_ID = 'settings.number.template'; const SETTINGS_ENUM_TEMPLATE_ID = 'settings.enum.template'; @@ -538,8 +534,6 @@ export interface ISettingChangeEvent { export class SettingsRenderer implements ITreeRenderer { - private static readonly SETTING_ROW_HEIGHT = 104; - private static readonly SETTING_BOOL_ROW_HEIGHT = 73; public static readonly MAX_ENUM_DESCRIPTIONS = 10; private static readonly CONTROL_CLASS = 'setting-control-focus-target'; @@ -601,13 +595,10 @@ export class SettingsRenderer implements ITreeRenderer { } if (element instanceof SettingsTreeSettingElement) { - const isSelected = this.elementIsSelected(tree, element); if (isExcludeSetting(element.setting)) { return this._getExcludeSettingHeight(element); - } else if (isSelected) { - return this.measureSettingElementHeight(tree, element); } else { - return this._getUnexpandedSettingHeight(element); + return this.measureSettingElementHeight(tree, element); } } @@ -623,14 +614,6 @@ export class SettingsRenderer implements ITreeRenderer { return (displayValue.length + 1) * 22 + 80; } - _getUnexpandedSettingHeight(element: SettingsTreeSettingElement): number { - if (element.valueType === 'boolean') { - return SettingsRenderer.SETTING_BOOL_ROW_HEIGHT; - } else { - return SettingsRenderer.SETTING_ROW_HEIGHT; - } - } - private measureSettingElementHeight(tree: ITree, element: SettingsTreeSettingElement): number { const templateId = this.getTemplateId(tree, element); const template: ISettingItemTemplate = this.measureTemplatesPool.get(templateId) || this.renderTemplate(tree, templateId, $('.setting-measure-helper')) as ISettingItemTemplate; @@ -639,7 +622,7 @@ export class SettingsRenderer implements ITreeRenderer { this.measureContainer.appendChild(template.containerElement); const height = this.measureContainer.offsetHeight; this.measureContainer.removeChild(this.measureContainer.firstChild); - return Math.max(height, this._getUnexpandedSettingHeight(element)); + return height; } getTemplateId(tree: ITree, element: SettingsTreeElement): string { @@ -1048,13 +1031,6 @@ export class SettingsRenderer implements ITreeRenderer { } } - private elementIsSelected(tree: ITree, element: SettingsTreeElement): boolean { - // const selection = tree.getSelection(); - // const selectedElement: SettingsTreeElement = selection && selection[0]; - // return selectedElement && selectedElement.id === element.id; - return true; - } - private renderNewExtensionsElement(element: SettingsTreeNewExtensionsElement, template: ISettingNewExtensionsTemplate): void { template.context = element; } @@ -1062,11 +1038,10 @@ export class SettingsRenderer implements ITreeRenderer { private renderSettingElement(tree: ITree, element: SettingsTreeSettingElement, templateId: string, template: ISettingItemTemplate | ISettingBoolItemTemplate): void { template.context = element; - const isSelected = !!this.elementIsSelected(tree, element); const setting = element.setting; DOM.toggleClass(template.containerElement, 'is-configured', element.isConfigured); - DOM.toggleClass(template.containerElement, 'is-expanded', isSelected); + DOM.toggleClass(template.containerElement, 'is-expanded', true); template.containerElement.id = element.id.replace(/\./g, '_'); const titleTooltip = setting.key; @@ -1076,25 +1051,15 @@ export class SettingsRenderer implements ITreeRenderer { template.labelElement.textContent = element.displayLabel; template.labelElement.title = titleTooltip; - const result = this.renderValue(element, isSelected, templateId, template); + this.renderValue(element, templateId, template); template.descriptionElement.innerHTML = ''; - let needsManualOverflowIndicator = false; if (element.setting.descriptionIsMarkdown) { const renderedDescription = this.renderDescriptionMarkdown(element.description, template.toDispose); template.descriptionElement.appendChild(renderedDescription); - // (renderedDescription.querySelectorAll('a')).forEach(aElement => { - // aElement.tabIndex = isSelected ? 0 : -1; - // }); - - const firstLineOverflows = renderedDescription.firstElementChild && renderedDescription.firstElementChild.clientHeight > 18; - const hasExtraLines = renderedDescription.childElementCount > 1; - needsManualOverflowIndicator = (hasExtraLines || result.overflows) && !firstLineOverflows && !isSelected; } else { template.descriptionElement.innerText = element.description; } - DOM.toggleClass(template.descriptionElement, 'setting-item-description-artificial-overflow', needsManualOverflowIndicator); - template.isConfiguredElement.textContent = element.isConfigured ? localize('configured', "Modified") : ''; if (element.overriddenScopeList.length) { @@ -1130,33 +1095,29 @@ export class SettingsRenderer implements ITreeRenderer { return renderedMarkdown; } - private renderValue(element: SettingsTreeSettingElement, isSelected: boolean, templateId: string, template: ISettingItemTemplate | ISettingBoolItemTemplate): IValueRenderResult { + private renderValue(element: SettingsTreeSettingElement, templateId: string, template: ISettingItemTemplate | ISettingBoolItemTemplate): void { const onChange = value => this._onDidChangeSetting.fire({ key: element.setting.key, value }); if (templateId === SETTINGS_ENUM_TEMPLATE_ID) { - return this.renderEnum(element, isSelected, template, onChange); + this.renderEnum(element, template, onChange); } else if (templateId === SETTINGS_TEXT_TEMPLATE_ID) { - this.renderText(element, isSelected, template, onChange); + this.renderText(element, template, onChange); } else if (templateId === SETTINGS_NUMBER_TEMPLATE_ID) { - this.renderNumber(element, isSelected, template, onChange); + this.renderNumber(element, template, onChange); } else if (templateId === SETTINGS_BOOL_TEMPLATE_ID) { - this.renderBool(element, isSelected, template, onChange); + this.renderBool(element, template, onChange); } else if (templateId === SETTINGS_EXCLUDE_TEMPLATE_ID) { - this.renderExcludeSetting(element, isSelected, template); + this.renderExcludeSetting(element, template); } else if (templateId === SETTINGS_COMPLEX_TEMPLATE_ID) { - this.renderComplexSetting(element, isSelected, template); + this.renderComplexSetting(element, template); } - - return { overflows: false }; } - private renderBool(dataElement: SettingsTreeSettingElement, isSelected: boolean, template: ISettingBoolItemTemplate, onChange: (value: boolean) => void): void { + private renderBool(dataElement: SettingsTreeSettingElement, template: ISettingBoolItemTemplate, onChange: (value: boolean) => void): void { template.onChange = null; template.checkbox.checked = dataElement.value; template.onChange = onChange; - // template.checkbox.domNode.tabIndex = isSelected ? 0 : -1; - // Setup and add ARIA attributes // Create id and label for control/input element - parent is wrapper div const id = (dataElement.displayCategory + '_' + dataElement.displayLabel).replace(/ /g, '_'); @@ -1176,7 +1137,7 @@ export class SettingsRenderer implements ITreeRenderer { } - private renderEnum(dataElement: SettingsTreeSettingElement, isSelected: boolean, template: ISettingEnumItemTemplate, onChange: (value: string) => void): IValueRenderResult { + private renderEnum(dataElement: SettingsTreeSettingElement, template: ISettingEnumItemTemplate, onChange: (value: string) => void): void { const displayOptions = getDisplayEnumOptions(dataElement.setting); template.selectBox.setOptions(displayOptions); @@ -1190,7 +1151,6 @@ export class SettingsRenderer implements ITreeRenderer { template.onChange = idx => onChange(dataElement.setting.enum[idx]); if (template.controlElement.firstElementChild) { - // template.controlElement.firstElementChild.setAttribute('tabindex', isSelected ? '0' : '-1'); // SelectBox needs to be treeitem to read correctly within tree template.controlElement.firstElementChild.setAttribute('role', 'treeitem'); } @@ -1214,11 +1174,9 @@ export class SettingsRenderer implements ITreeRenderer { // return { overflows: true }; // } - - return { overflows: false }; } - private renderText(dataElement: SettingsTreeSettingElement, isSelected: boolean, template: ISettingTextItemTemplate, onChange: (value: string) => void): void { + private renderText(dataElement: SettingsTreeSettingElement, template: ISettingTextItemTemplate, onChange: (value: string) => void): void { template.onChange = null; template.inputBox.value = dataElement.value; template.onChange = value => onChange(value); @@ -1243,7 +1201,7 @@ export class SettingsRenderer implements ITreeRenderer { } - private renderNumber(dataElement: SettingsTreeSettingElement, isSelected: boolean, template: ISettingTextItemTemplate, onChange: (value: number) => void): void { + private renderNumber(dataElement: SettingsTreeSettingElement, template: ISettingTextItemTemplate, onChange: (value: number) => void): void { template.onChange = null; template.inputBox.value = dataElement.value; template.onChange = value => onChange(parseFn(value)); @@ -1269,13 +1227,13 @@ export class SettingsRenderer implements ITreeRenderer { } - private renderExcludeSetting(dataElement: SettingsTreeSettingElement, isSelected: boolean, template: ISettingExcludeItemTemplate): void { + private renderExcludeSetting(dataElement: SettingsTreeSettingElement, template: ISettingExcludeItemTemplate): void { const value = getExcludeDisplayValue(dataElement); template.excludeWidget.setValue(value); template.context = dataElement; } - private renderComplexSetting(dataElement: SettingsTreeSettingElement, isSelected: boolean, template: ISettingComplexItemTemplate): void { + private renderComplexSetting(dataElement: SettingsTreeSettingElement, template: ISettingComplexItemTemplate): void { template.onChange = () => this._onDidOpenSettings.fire(dataElement.setting.key); } From 1678a450efd0f2b890118173973a18fac9dca2a5 Mon Sep 17 00:00:00 2001 From: Benjamin Pasero Date: Thu, 9 Aug 2018 08:04:47 +0200 Subject: [PATCH 0613/1276] change info => trace for "no grammar found for scope..." --- src/vs/workbench/services/textMate/electron-browser/TMSyntax.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vs/workbench/services/textMate/electron-browser/TMSyntax.ts b/src/vs/workbench/services/textMate/electron-browser/TMSyntax.ts index ab2e62d53f6..5a8a60d7238 100644 --- a/src/vs/workbench/services/textMate/electron-browser/TMSyntax.ts +++ b/src/vs/workbench/services/textMate/electron-browser/TMSyntax.ts @@ -216,7 +216,7 @@ export class TextMateService implements ITextMateService { loadGrammar: (scopeName: string) => { const location = this._scopeRegistry.getGrammarLocation(scopeName); if (!location) { - this._logService.info(`No grammar found for scope ${scopeName}`); + this._logService.trace(`No grammar found for scope ${scopeName}`); return null; } return this._fileService.resolveContent(location, { encoding: 'utf8' }).then(content => { From 861e040ea9b5dfd6fb920bded921fcaf6acb8e23 Mon Sep 17 00:00:00 2001 From: Benjamin Pasero Date: Thu, 9 Aug 2018 08:11:18 +0200 Subject: [PATCH 0614/1276] debt - do not check for canHandleResource right on startup (for #48275) --- src/vs/workbench/electron-browser/workbench.ts | 2 +- .../services/history/electron-browser/history.ts | 9 ++++++++- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/src/vs/workbench/electron-browser/workbench.ts b/src/vs/workbench/electron-browser/workbench.ts index dae70324dbf..bfed9637ad6 100644 --- a/src/vs/workbench/electron-browser/workbench.ts +++ b/src/vs/workbench/electron-browser/workbench.ts @@ -1118,7 +1118,7 @@ export class Workbench extends Disposable implements IPartService { get onEditorLayout(): Event { return this.editorPart.onDidLayout; } isCreated(): boolean { - return this.workbenchCreated && this.workbenchStarted; + return !!(this.workbenchCreated && this.workbenchStarted); } hasFocus(part: Parts): boolean { diff --git a/src/vs/workbench/services/history/electron-browser/history.ts b/src/vs/workbench/services/history/electron-browser/history.ts index 0cb907bc631..bdf9ae0eee3 100644 --- a/src/vs/workbench/services/history/electron-browser/history.ts +++ b/src/vs/workbench/services/history/electron-browser/history.ts @@ -32,6 +32,7 @@ import { IInstantiationService } from 'vs/platform/instantiation/common/instanti import { ResourceGlobMatcher } from 'vs/workbench/electron-browser/resources'; import { Schemas } from 'vs/base/common/network'; import { EditorServiceImpl } from 'vs/workbench/browser/parts/editor/editor'; +import { IPartService } from 'vs/workbench/services/part/common/partService'; /** * Stores the selection & view state of an editor and allows to compare it to other selection states. @@ -132,6 +133,7 @@ export class HistoryService extends Disposable implements IHistoryService { @IFileService private fileService: IFileService, @IWindowsService private windowService: IWindowsService, @IInstantiationService private instantiationService: IInstantiationService, + @IPartService private partService: IPartService ) { super(); @@ -658,7 +660,12 @@ export class HistoryService extends Disposable implements IHistoryService { if (arg2 instanceof EditorInput) { const inputResource = arg2.getResource(); - return inputResource && this.fileService.canHandleResource(inputResource) && inputResource.toString() === resource.toString(); + let isSupportedFile = true; + if (this.partService.isCreated() && !this.fileService.canHandleResource(inputResource)) { + isSupportedFile = false; // make sure to only check this when workbench has started (for https://github.com/Microsoft/vscode/issues/48275) + } + + return inputResource && isSupportedFile && inputResource.toString() === resource.toString(); } const resourceInput = arg2 as IResourceInput; From 3186ac39f6c4b2274872423cad79438fe65285a6 Mon Sep 17 00:00:00 2001 From: Christof Marti Date: Thu, 9 Aug 2018 08:22:17 +0200 Subject: [PATCH 0615/1276] Fix smoke tests (#29096) --- test/smoke/src/areas/quickinput/quickinput.ts | 9 +++++++++ test/smoke/src/areas/statusbar/statusbar.test.ts | 12 ++++++------ 2 files changed, 15 insertions(+), 6 deletions(-) diff --git a/test/smoke/src/areas/quickinput/quickinput.ts b/test/smoke/src/areas/quickinput/quickinput.ts index c13b308c0d9..aab4253c970 100644 --- a/test/smoke/src/areas/quickinput/quickinput.ts +++ b/test/smoke/src/areas/quickinput/quickinput.ts @@ -25,4 +25,13 @@ export class QuickInput { private async waitForQuickInputClosed(): Promise { await this.code.waitForElement(QuickInput.QUICK_INPUT, r => !!r && r.attributes.style.indexOf('display: none;') !== -1); } + + async selectQuickInputElement(index: number): Promise { + await this.waitForQuickInputOpened(); + for (let from = 0; from < index; from++) { + await this.code.dispatchKeybinding('down'); + } + await this.code.dispatchKeybinding('enter'); + await this.waitForQuickInputClosed(); + } } diff --git a/test/smoke/src/areas/statusbar/statusbar.test.ts b/test/smoke/src/areas/statusbar/statusbar.test.ts index dfb1d7550d3..c9ba22c290a 100644 --- a/test/smoke/src/areas/statusbar/statusbar.test.ts +++ b/test/smoke/src/areas/statusbar/statusbar.test.ts @@ -38,11 +38,11 @@ export function setup() { await app.workbench.quickopen.waitForQuickOpenOpened(); await app.workbench.quickopen.closeQuickOpen(); await app.workbench.statusbar.clickOn(StatusBarElement.ENCODING_STATUS); - await app.workbench.quickopen.waitForQuickOpenOpened(); - await app.workbench.quickopen.closeQuickOpen(); + await app.workbench.quickinput.waitForQuickInputOpened(); + await app.workbench.quickinput.closeQuickInput(); await app.workbench.statusbar.clickOn(StatusBarElement.EOL_STATUS); - await app.workbench.quickopen.waitForQuickOpenOpened(); - await app.workbench.quickopen.closeQuickOpen(); + await app.workbench.quickinput.waitForQuickInputOpened(); + await app.workbench.quickinput.closeQuickInput(); await app.workbench.statusbar.clickOn(StatusBarElement.LANGUAGE_STATUS); await app.workbench.quickopen.waitForQuickOpenOpened(); await app.workbench.quickopen.closeQuickOpen(); @@ -84,8 +84,8 @@ export function setup() { await app.workbench.quickopen.openFile('app.js'); await app.workbench.statusbar.clickOn(StatusBarElement.EOL_STATUS); - await app.workbench.quickopen.waitForQuickOpenOpened(); - await app.workbench.quickopen.selectQuickOpenElement(1); + await app.workbench.quickinput.waitForQuickInputOpened(); + await app.workbench.quickinput.selectQuickInputElement(1); await app.workbench.statusbar.waitForEOL('CRLF'); }); From 86caa11a612a0baac31e5ee7aa8d36ae7a62a092 Mon Sep 17 00:00:00 2001 From: SteVen Batten <6561887+sbatten@users.noreply.github.com> Date: Thu, 9 Aug 2018 01:10:12 -0700 Subject: [PATCH 0616/1276] demote menubar from part (#56031) --- .../parts/menubar/media/menubarpart.css | 50 ----------------- .../parts/titlebar/media/titlebarpart.css | 48 +++++++++++++++++ .../menubarControl.ts} | 54 +++++++++---------- .../titlebar.contribution.ts} | 0 .../browser/parts/titlebar/titlebarPart.ts | 10 ++-- 5 files changed, 80 insertions(+), 82 deletions(-) delete mode 100644 src/vs/workbench/browser/parts/menubar/media/menubarpart.css rename src/vs/workbench/browser/parts/{menubar/menubarPart.ts => titlebar/menubarControl.ts} (95%) rename src/vs/workbench/browser/parts/{menubar/menubar.contribution.ts => titlebar/titlebar.contribution.ts} (100%) diff --git a/src/vs/workbench/browser/parts/menubar/media/menubarpart.css b/src/vs/workbench/browser/parts/menubar/media/menubarpart.css deleted file mode 100644 index d117e3f9fc1..00000000000 --- a/src/vs/workbench/browser/parts/menubar/media/menubarpart.css +++ /dev/null @@ -1,50 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the MIT License. See License.txt in the project root for license information. - *--------------------------------------------------------------------------------------------*/ - -.monaco-workbench .part.menubar { - display: flex; - flex-shrink: 1; - box-sizing: border-box; - height: 30px; - -webkit-app-region: no-drag; - overflow: hidden; - flex-wrap: wrap; -} - -.monaco-workbench.fullscreen .part.menubar { - margin: 0px; - padding: 0px 5px; -} - -.monaco-workbench .part.menubar > .menubar-menu-button { - align-items: center; - box-sizing: border-box; - padding: 0px 8px; - cursor: default; - -webkit-app-region: no-drag; - zoom: 1; - white-space: nowrap; -} - -.monaco-workbench .part.menubar .menubar-menu-items-holder { - position: absolute; - left: 0px; - opacity: 1; - z-index: 2000; -} - -.monaco-workbench .part.menubar .menubar-menu-items-holder.monaco-menu-container { - font-family: "Segoe WPC", "Segoe UI", ".SFNSDisplay-Light", "SFUIText-Light", "HelveticaNeue-Light", sans-serif, "Droid Sans Fallback"; - outline: 0; - border: none; -} - -.monaco-workbench .part.menubar .menubar-menu-items-holder.monaco-menu-container :focus { - outline: 0; -} - -.hc-black .monaco-workbench .part.menubar .menubar-menu-items-holder.monaco-menu-container { - border: 2px solid #6FC3DF; -} \ No newline at end of file diff --git a/src/vs/workbench/browser/parts/titlebar/media/titlebarpart.css b/src/vs/workbench/browser/parts/titlebar/media/titlebarpart.css index d46c6e868cc..42965aae65c 100644 --- a/src/vs/workbench/browser/parts/titlebar/media/titlebarpart.css +++ b/src/vs/workbench/browser/parts/titlebar/media/titlebarpart.css @@ -150,4 +150,52 @@ .monaco-workbench > .part.titlebar > .window-controls-container .window-icon.window-close:hover { background-color: white; +} + +/* Menubar styles */ + +.monaco-workbench .menubar { + display: flex; + flex-shrink: 1; + box-sizing: border-box; + height: 30px; + -webkit-app-region: no-drag; + overflow: hidden; + flex-wrap: wrap; +} + +.monaco-workbench.fullscreen .menubar { + margin: 0px; + padding: 0px 5px; +} + +.monaco-workbench .menubar > .menubar-menu-button { + align-items: center; + box-sizing: border-box; + padding: 0px 8px; + cursor: default; + -webkit-app-region: no-drag; + zoom: 1; + white-space: nowrap; +} + +.monaco-workbench .menubar .menubar-menu-items-holder { + position: absolute; + left: 0px; + opacity: 1; + z-index: 2000; +} + +.monaco-workbench .menubar .menubar-menu-items-holder.monaco-menu-container { + font-family: "Segoe WPC", "Segoe UI", ".SFNSDisplay-Light", "SFUIText-Light", "HelveticaNeue-Light", sans-serif, "Droid Sans Fallback"; + outline: 0; + border: none; +} + +.monaco-workbench .menubar .menubar-menu-items-holder.monaco-menu-container :focus { + outline: 0; +} + +.hc-black .monaco-workbench .menubar .menubar-menu-items-holder.monaco-menu-container { + border: 2px solid #6FC3DF; } \ No newline at end of file diff --git a/src/vs/workbench/browser/parts/menubar/menubarPart.ts b/src/vs/workbench/browser/parts/titlebar/menubarControl.ts similarity index 95% rename from src/vs/workbench/browser/parts/menubar/menubarPart.ts rename to src/vs/workbench/browser/parts/titlebar/menubarControl.ts index a8c386c9e9a..98d87bac832 100644 --- a/src/vs/workbench/browser/parts/menubar/menubarPart.ts +++ b/src/vs/workbench/browser/parts/titlebar/menubarControl.ts @@ -5,11 +5,9 @@ 'use strict'; -import 'vs/workbench/browser/parts/menubar/menubar.contribution'; -import 'vs/css!./media/menubarpart'; +import 'vs/workbench/browser/parts/titlebar/titlebar.contribution'; import * as nls from 'vs/nls'; import * as browser from 'vs/base/browser/browser'; -import { Part } from 'vs/workbench/browser/part'; import { IMenubarMenu, IMenubarMenuItemAction, IMenubarMenuItemSubmenu, IMenubarKeybinding } from 'vs/platform/menubar/common/menubar'; import { IMenuService, MenuId, IMenu, SubmenuItemAction } from 'vs/platform/actions/common/actions'; import { IThemeService, registerThemingParticipant, ITheme, ICssStyleCollector } from 'vs/platform/theme/common/themeService'; @@ -26,7 +24,7 @@ import { KeyCode } from 'vs/base/common/keyCodes'; import { StandardKeyboardEvent } from 'vs/base/browser/keyboardEvent'; import { IConfigurationService, IConfigurationChangeEvent } from 'vs/platform/configuration/common/configuration'; import { Event, Emitter } from 'vs/base/common/event'; -import { IDisposable, dispose } from 'vs/base/common/lifecycle'; +import { IDisposable, Disposable, dispose } from 'vs/base/common/lifecycle'; import { domEvent } from 'vs/base/browser/event'; import { IRecentlyOpened } from 'vs/platform/history/common/history'; import { IWorkspaceIdentifier, getWorkspaceLabel, ISingleFolderWorkspaceIdentifier, isSingleFolderWorkspaceIdentifier, isWorkspaceIdentifier } from 'vs/platform/workspaces/common/workspaces'; @@ -52,7 +50,7 @@ enum MenubarState { OPEN } -export class MenubarPart extends Part { +export class MenubarControl extends Disposable { private keys = [ 'files.autoSave', @@ -126,7 +124,8 @@ export class MenubarPart extends Part { @IUriDisplayService private uriDisplayService: IUriDisplayService, @IUpdateService private updateService: IUpdateService ) { - super(id, { hasTitle: false }, themeService); + + super(); this.topLevelMenus = { 'File': this._register(this.menuService.createMenu(MenuId.MenubarFileMenu, this.contextKeyService)), @@ -315,7 +314,6 @@ export class MenubarPart extends Part { private onDidChangeFullscreen(): void { this.setUnfocusedState(); - this.updateStyles(); } private onDidChangeWindowFocus(hasFocus: boolean): void { @@ -525,7 +523,7 @@ export class MenubarPart extends Part { const result: IAction[] = []; if (workspaces.length > 0) { - for (let i = 0; i < MenubarPart.MAX_MENU_RECENT_ENTRIES && i < workspaces.length; i++) { + for (let i = 0; i < MenubarControl.MAX_MENU_RECENT_ENTRIES && i < workspaces.length; i++) { result.push(this.createOpenRecentMenuAction(workspaces[i], 'openRecentWorkspace', false)); } @@ -533,7 +531,7 @@ export class MenubarPart extends Part { } if (files.length > 0) { - for (let i = 0; i < MenubarPart.MAX_MENU_RECENT_ENTRIES && i < files.length; i++) { + for (let i = 0; i < MenubarControl.MAX_MENU_RECENT_ENTRIES && i < files.length; i++) { result.push(this.createOpenRecentMenuAction(files[i], 'openRecentFile', false)); } @@ -991,14 +989,16 @@ export class MenubarPart extends Part { return this._onVisibilityChange.event; } - public layout(dimension: Dimension): Dimension[] { + public layout(dimension: Dimension) { + if (this.container) { + this.container.style({ height: `${dimension.height}px` }); + } + if (!this.isVisible) { this.hideMenubar(); } else { this.showMenubar(); } - - return super.layout(dimension); } public getMenubarItemsDimensions(): Dimension { @@ -1011,7 +1011,7 @@ export class MenubarPart extends Part { return new Dimension(0, 0); } - public createContentArea(parent: HTMLElement): HTMLElement { + public create(parent: HTMLElement): HTMLElement { this.container = $(parent); // Build the menubar @@ -1031,7 +1031,7 @@ registerThemingParticipant((theme: ITheme, collector: ICssStyleCollector) => { const menubarActiveWindowFgColor = theme.getColor(TITLE_BAR_ACTIVE_FOREGROUND); if (menubarActiveWindowFgColor) { collector.addRule(` - .monaco-workbench .part.menubar > .menubar-menu-button { + .monaco-workbench .menubar > .menubar-menu-button { color: ${menubarActiveWindowFgColor}; } `); @@ -1040,7 +1040,7 @@ registerThemingParticipant((theme: ITheme, collector: ICssStyleCollector) => { const menubarInactiveWindowFgColor = theme.getColor(TITLE_BAR_INACTIVE_FOREGROUND); if (menubarInactiveWindowFgColor) { collector.addRule(` - .monaco-workbench .part.menubar.inactive > .menubar-menu-button { + .monaco-workbench .menubar.inactive > .menubar-menu-button { color: ${menubarInactiveWindowFgColor}; } `); @@ -1050,9 +1050,9 @@ registerThemingParticipant((theme: ITheme, collector: ICssStyleCollector) => { const menubarSelectedFgColor = theme.getColor(MENUBAR_SELECTION_FOREGROUND); if (menubarSelectedFgColor) { collector.addRule(` - .monaco-workbench .part.menubar > .menubar-menu-button.open, - .monaco-workbench .part.menubar > .menubar-menu-button:focus, - .monaco-workbench .part.menubar > .menubar-menu-button:hover { + .monaco-workbench .menubar > .menubar-menu-button.open, + .monaco-workbench .menubar > .menubar-menu-button:focus, + .monaco-workbench .menubar > .menubar-menu-button:hover { color: ${menubarSelectedFgColor}; } `); @@ -1061,9 +1061,9 @@ registerThemingParticipant((theme: ITheme, collector: ICssStyleCollector) => { const menubarSelectedBgColor = theme.getColor(MENUBAR_SELECTION_BACKGROUND); if (menubarSelectedBgColor) { collector.addRule(` - .monaco-workbench .part.menubar > .menubar-menu-button.open, - .monaco-workbench .part.menubar > .menubar-menu-button:focus, - .monaco-workbench .part.menubar > .menubar-menu-button:hover { + .monaco-workbench .menubar > .menubar-menu-button.open, + .monaco-workbench .menubar > .menubar-menu-button:focus, + .monaco-workbench .menubar > .menubar-menu-button:hover { background-color: ${menubarSelectedBgColor}; } `); @@ -1072,18 +1072,18 @@ registerThemingParticipant((theme: ITheme, collector: ICssStyleCollector) => { const menubarSelectedBorderColor = theme.getColor(MENUBAR_SELECTION_BORDER); if (menubarSelectedBorderColor) { collector.addRule(` - .monaco-workbench .part.menubar > .menubar-menu-button:hover { + .monaco-workbench .menubar > .menubar-menu-button:hover { outline: dashed 1px; } - .monaco-workbench .part.menubar > .menubar-menu-button.open, - .monaco-workbench .part.menubar > .menubar-menu-button:focus { + .monaco-workbench .menubar > .menubar-menu-button.open, + .monaco-workbench .menubar > .menubar-menu-button:focus { outline: solid 1px; } - .monaco-workbench .part.menubar > .menubar-menu-button.open, - .monaco-workbench .part.menubar > .menubar-menu-button:focus, - .monaco-workbench .part.menubar > .menubar-menu-button:hover { + .monaco-workbench .menubar > .menubar-menu-button.open, + .monaco-workbench .menubar > .menubar-menu-button:focus, + .monaco-workbench .menubar > .menubar-menu-button:hover { outline-offset: -1px; outline-color: ${menubarSelectedBorderColor}; } diff --git a/src/vs/workbench/browser/parts/menubar/menubar.contribution.ts b/src/vs/workbench/browser/parts/titlebar/titlebar.contribution.ts similarity index 100% rename from src/vs/workbench/browser/parts/menubar/menubar.contribution.ts rename to src/vs/workbench/browser/parts/titlebar/titlebar.contribution.ts diff --git a/src/vs/workbench/browser/parts/titlebar/titlebarPart.ts b/src/vs/workbench/browser/parts/titlebar/titlebarPart.ts index 6b2d003499b..fe01f90cbe0 100644 --- a/src/vs/workbench/browser/parts/titlebar/titlebarPart.ts +++ b/src/vs/workbench/browser/parts/titlebar/titlebarPart.ts @@ -31,7 +31,7 @@ import URI from 'vs/base/common/uri'; import { Color } from 'vs/base/common/color'; import { trim } from 'vs/base/common/strings'; import { addDisposableListener, EventType, EventHelper, Dimension } from 'vs/base/browser/dom'; -import { MenubarPart } from 'vs/workbench/browser/parts/menubar/menubarPart'; +import { MenubarControl } from 'vs/workbench/browser/parts/titlebar/menubarControl'; import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; import { template, getBaseLabel } from 'vs/base/common/labels'; import { IUriDisplayService } from 'vs/platform/uriDisplay/common/uriDisplay'; @@ -52,7 +52,7 @@ export class TitlebarPart extends Part implements ITitleService { private windowControls: Builder; private maxRestoreControl: Builder; private appIcon: Builder; - private menubarPart: MenubarPart; + private menubarPart: MenubarControl; private menubar: Builder; private resizer: Builder; @@ -273,10 +273,10 @@ export class TitlebarPart extends Part implements ITitleService { } // Menubar: the menubar part which is responsible for populating both the custom and native menubars - this.menubarPart = this.instantiationService.createInstance(MenubarPart, 'workbench.parts.menubar'); + this.menubarPart = this.instantiationService.createInstance(MenubarControl, 'workbench.parts.titlebar.menubar'); this.menubar = $(this.titleContainer).div({ - 'class': ['part', 'menubar'], - id: 'workbench.parts.menubar', + 'class': ['menubar'], + id: 'workbench.parts.titlebar.menubar', role: 'menubar' }); From eeb4873e8c7cebb54938cd76148a9b28c05314c6 Mon Sep 17 00:00:00 2001 From: Benjamin Pasero Date: Thu, 9 Aug 2018 10:25:38 +0200 Subject: [PATCH 0617/1276] debt - compositePar is not really part in workbench --- .../workbench/browser/parts/activitybar/activitybarActions.ts | 2 +- src/vs/workbench/browser/parts/activitybar/activitybarPart.ts | 4 ++-- .../browser/parts/{compositebar => }/compositeBar.ts | 2 +- .../browser/parts/{compositebar => }/compositeBarActions.ts | 0 src/vs/workbench/browser/parts/panel/panelActions.ts | 2 +- src/vs/workbench/browser/parts/panel/panelPart.ts | 4 ++-- 6 files changed, 7 insertions(+), 7 deletions(-) rename src/vs/workbench/browser/parts/{compositebar => }/compositeBar.ts (99%) rename src/vs/workbench/browser/parts/{compositebar => }/compositeBarActions.ts (100%) diff --git a/src/vs/workbench/browser/parts/activitybar/activitybarActions.ts b/src/vs/workbench/browser/parts/activitybar/activitybarActions.ts index 6d1fa885470..773bbe0d763 100644 --- a/src/vs/workbench/browser/parts/activitybar/activitybarActions.ts +++ b/src/vs/workbench/browser/parts/activitybar/activitybarActions.ts @@ -21,7 +21,7 @@ import { activeContrastBorder, focusBorder } from 'vs/platform/theme/common/colo import { StandardMouseEvent } from 'vs/base/browser/mouseEvent'; import { KeyCode } from 'vs/base/common/keyCodes'; import { StandardKeyboardEvent } from 'vs/base/browser/keyboardEvent'; -import { ActivityAction, ActivityActionItem, ICompositeBarColors, ToggleCompositePinnedAction, ICompositeBar } from 'vs/workbench/browser/parts/compositebar/compositeBarActions'; +import { ActivityAction, ActivityActionItem, ICompositeBarColors, ToggleCompositePinnedAction, ICompositeBar } from 'vs/workbench/browser/parts/compositeBarActions'; import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry'; import URI from 'vs/base/common/uri'; diff --git a/src/vs/workbench/browser/parts/activitybar/activitybarPart.ts b/src/vs/workbench/browser/parts/activitybar/activitybarPart.ts index 8577c13caaa..52d0ff4ccf3 100644 --- a/src/vs/workbench/browser/parts/activitybar/activitybarPart.ts +++ b/src/vs/workbench/browser/parts/activitybar/activitybarPart.ts @@ -22,7 +22,7 @@ import { ToggleActivityBarVisibilityAction } from 'vs/workbench/browser/actions/ import { IThemeService, registerThemingParticipant } from 'vs/platform/theme/common/themeService'; import { ACTIVITY_BAR_BACKGROUND, ACTIVITY_BAR_BORDER, ACTIVITY_BAR_FOREGROUND, ACTIVITY_BAR_BADGE_BACKGROUND, ACTIVITY_BAR_BADGE_FOREGROUND, ACTIVITY_BAR_DRAG_AND_DROP_BACKGROUND } from 'vs/workbench/common/theme'; import { contrastBorder } from 'vs/platform/theme/common/colorRegistry'; -import { CompositeBar } from 'vs/workbench/browser/parts/compositebar/compositeBar'; +import { CompositeBar } from 'vs/workbench/browser/parts/compositeBar'; import { isMacintosh } from 'vs/base/common/platform'; import { ILifecycleService, LifecyclePhase } from 'vs/platform/lifecycle/common/lifecycle'; import { scheduleAtNextAnimationFrame, Dimension, addClass } from 'vs/base/browser/dom'; @@ -30,7 +30,7 @@ import { Color } from 'vs/base/common/color'; import { IStorageService, StorageScope } from 'vs/platform/storage/common/storage'; import { IExtensionService } from 'vs/workbench/services/extensions/common/extensions'; import URI from 'vs/base/common/uri'; -import { ToggleCompositePinnedAction } from 'vs/workbench/browser/parts/compositebar/compositeBarActions'; +import { ToggleCompositePinnedAction } from 'vs/workbench/browser/parts/compositeBarActions'; import { ViewletDescriptor } from 'vs/workbench/browser/viewlet'; interface IPlaceholderComposite { diff --git a/src/vs/workbench/browser/parts/compositebar/compositeBar.ts b/src/vs/workbench/browser/parts/compositeBar.ts similarity index 99% rename from src/vs/workbench/browser/parts/compositebar/compositeBar.ts rename to src/vs/workbench/browser/parts/compositeBar.ts index 54f2748037a..8731222e1fe 100644 --- a/src/vs/workbench/browser/parts/compositebar/compositeBar.ts +++ b/src/vs/workbench/browser/parts/compositeBar.ts @@ -14,7 +14,7 @@ import { IBadge } from 'vs/workbench/services/activity/common/activity'; import { IStorageService, StorageScope } from 'vs/platform/storage/common/storage'; import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; import { ActionBar, ActionsOrientation, Separator } from 'vs/base/browser/ui/actionbar/actionbar'; -import { CompositeActionItem, CompositeOverflowActivityAction, ICompositeActivity, CompositeOverflowActivityActionItem, ActivityAction, ICompositeBar, ICompositeBarColors } from 'vs/workbench/browser/parts/compositebar/compositeBarActions'; +import { CompositeActionItem, CompositeOverflowActivityAction, ICompositeActivity, CompositeOverflowActivityActionItem, ActivityAction, ICompositeBar, ICompositeBarColors } from 'vs/workbench/browser/parts/compositeBarActions'; import { TPromise } from 'vs/base/common/winjs.base'; import { Dimension, $, addDisposableListener, EventType, EventHelper } from 'vs/base/browser/dom'; import { StandardMouseEvent } from 'vs/base/browser/mouseEvent'; diff --git a/src/vs/workbench/browser/parts/compositebar/compositeBarActions.ts b/src/vs/workbench/browser/parts/compositeBarActions.ts similarity index 100% rename from src/vs/workbench/browser/parts/compositebar/compositeBarActions.ts rename to src/vs/workbench/browser/parts/compositeBarActions.ts diff --git a/src/vs/workbench/browser/parts/panel/panelActions.ts b/src/vs/workbench/browser/parts/panel/panelActions.ts index d3933cb7b9c..54d4f61d040 100644 --- a/src/vs/workbench/browser/parts/panel/panelActions.ts +++ b/src/vs/workbench/browser/parts/panel/panelActions.ts @@ -14,7 +14,7 @@ import { SyncActionDescriptor, MenuId, MenuRegistry } from 'vs/platform/actions/ import { IWorkbenchActionRegistry, Extensions as WorkbenchExtensions } from 'vs/workbench/common/actions'; import { IPanelService } from 'vs/workbench/services/panel/common/panelService'; import { IPartService, Parts, Position } from 'vs/workbench/services/part/common/partService'; -import { ActivityAction } from 'vs/workbench/browser/parts/compositebar/compositeBarActions'; +import { ActivityAction } from 'vs/workbench/browser/parts/compositeBarActions'; import { IActivity } from 'vs/workbench/common/activity'; export class ClosePanelAction extends Action { diff --git a/src/vs/workbench/browser/parts/panel/panelPart.ts b/src/vs/workbench/browser/parts/panel/panelPart.ts index 094b9b2aa89..13df252c82f 100644 --- a/src/vs/workbench/browser/parts/panel/panelPart.ts +++ b/src/vs/workbench/browser/parts/panel/panelPart.ts @@ -23,8 +23,8 @@ import { ClosePanelAction, TogglePanelPositionAction, PanelActivityAction, Toggl import { IThemeService, registerThemingParticipant, ITheme, ICssStyleCollector } from 'vs/platform/theme/common/themeService'; import { PANEL_BACKGROUND, PANEL_BORDER, PANEL_ACTIVE_TITLE_FOREGROUND, PANEL_INACTIVE_TITLE_FOREGROUND, PANEL_ACTIVE_TITLE_BORDER, PANEL_DRAG_AND_DROP_BACKGROUND } from 'vs/workbench/common/theme'; import { activeContrastBorder, focusBorder, contrastBorder, editorBackground, badgeBackground, badgeForeground } from 'vs/platform/theme/common/colorRegistry'; -import { CompositeBar } from 'vs/workbench/browser/parts/compositebar/compositeBar'; -import { ToggleCompositePinnedAction } from 'vs/workbench/browser/parts/compositebar/compositeBarActions'; +import { CompositeBar } from 'vs/workbench/browser/parts/compositeBar'; +import { ToggleCompositePinnedAction } from 'vs/workbench/browser/parts/compositeBarActions'; import { IBadge } from 'vs/workbench/services/activity/common/activity'; import { INotificationService } from 'vs/platform/notification/common/notification'; import { Dimension } from 'vs/base/browser/dom'; From 7ae5c179d0876e5a394e0c7b6707a2b548dd4dbb Mon Sep 17 00:00:00 2001 From: Martin Aeschlimann Date: Thu, 9 Aug 2018 10:49:37 +0200 Subject: [PATCH 0618/1276] resources: fix tests, normalize/join: use fspath --- src/vs/base/common/paths.ts | 2 +- src/vs/base/common/resources.ts | 18 ++++++++++++------ 2 files changed, 13 insertions(+), 7 deletions(-) diff --git a/src/vs/base/common/paths.ts b/src/vs/base/common/paths.ts index e114052fba7..e5ed22fb7b9 100644 --- a/src/vs/base/common/paths.ts +++ b/src/vs/base/common/paths.ts @@ -34,7 +34,7 @@ export function dirname(path: string, separator = nativeSep): string { return dirname(path.substring(0, path.length - 1)); } else { let res = path.substring(0, ~idx); - if (isWindows && res.length === 2 && res[res.length - 1] === ':') { + if (isWindows && res[res.length - 1] === ':') { res += separator; // make sure drive letters end with backslash } return res; diff --git a/src/vs/base/common/resources.ts b/src/vs/base/common/resources.ts index f12b995f032..df50dfeb419 100644 --- a/src/vs/base/common/resources.ts +++ b/src/vs/base/common/resources.ts @@ -27,10 +27,6 @@ export function basenameOrAuthority(resource: URI): string { export function isEqualOrParent(resource: URI, candidate: URI, ignoreCase?: boolean): boolean { if (resource.scheme === candidate.scheme && resource.authority === candidate.authority) { - if (resource.scheme === Schemas.file) { - return paths.isEqualOrParent(resource.path, candidate.path, ignoreCase); - } - return paths.isEqualOrParent(resource.path, candidate.path, ignoreCase, '/'); } @@ -82,7 +78,12 @@ export function dirname(resource: URI): URI { * @returns The resulting URI. */ export function joinPath(resource: URI, pathFragment: string): URI { - const joinedPath = paths.join(resource.path || '/', pathFragment); + let joinedPath: string; + if (resource.scheme === Schemas.file) { + joinedPath = URI.file(paths.join(resource.fsPath, pathFragment)).path; + } else { + joinedPath = paths.join(resource.path, pathFragment); + } return resource.with({ path: joinedPath }); @@ -95,7 +96,12 @@ export function joinPath(resource: URI, pathFragment: string): URI { * @returns The URI with the normalized path. */ export function normalizePath(resource: URI): URI { - const normalizedPath = paths.normalize(resource.path, false); + let normalizedPath: string; + if (resource.scheme === Schemas.file) { + normalizedPath = URI.file(paths.normalize(resource.fsPath)).path; + } else { + normalizedPath = paths.normalize(resource.path); + } return resource.with({ path: normalizedPath }); From e89a78391e7f17d998d0ad7a9705e4ee7c2b3723 Mon Sep 17 00:00:00 2001 From: Christof Marti Date: Thu, 9 Aug 2018 10:54:53 +0200 Subject: [PATCH 0619/1276] Use QuickInput (#29096) --- .../terminal/electron-browser/terminalService.ts | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/vs/workbench/parts/terminal/electron-browser/terminalService.ts b/src/vs/workbench/parts/terminal/electron-browser/terminalService.ts index 5b865bd3a86..fb61123763f 100644 --- a/src/vs/workbench/parts/terminal/electron-browser/terminalService.ts +++ b/src/vs/workbench/parts/terminal/electron-browser/terminalService.ts @@ -13,7 +13,6 @@ import { ILifecycleService } from 'vs/platform/lifecycle/common/lifecycle'; import { IPanelService } from 'vs/workbench/services/panel/common/panelService'; import { IPartService } from 'vs/workbench/services/part/common/partService'; import { IConfigurationService, ConfigurationTarget } from 'vs/platform/configuration/common/configuration'; -import { IQuickOpenService, IPickOpenEntry, IPickOptions } from 'vs/platform/quickOpen/common/quickOpen'; import { ITerminalInstance, ITerminalService, IShellLaunchConfig, ITerminalConfigHelper, NEVER_SUGGEST_SELECT_WINDOWS_SHELL_STORAGE_KEY, TERMINAL_PANEL_ID, ITerminalProcessExtHostProxy } from 'vs/workbench/parts/terminal/common/terminal'; import { TerminalService as AbstractTerminalService } from 'vs/workbench/parts/terminal/common/terminalService'; import { TerminalConfigHelper } from 'vs/workbench/parts/terminal/electron-browser/terminalConfigHelper'; @@ -29,6 +28,7 @@ import { ipcRenderer as ipc } from 'electron'; import { IOpenFileRequest } from 'vs/platform/windows/common/windows'; import { TerminalInstance } from 'vs/workbench/parts/terminal/electron-browser/terminalInstance'; import { IExtensionService } from 'vs/workbench/services/extensions/common/extensions'; +import { IQuickInputService, IQuickPickItem, IPickOptions } from 'vs/platform/quickinput/common/quickInput'; export class TerminalService extends AbstractTerminalService implements ITerminalService { private _configHelper: TerminalConfigHelper; @@ -47,7 +47,7 @@ export class TerminalService extends AbstractTerminalService implements ITermina @ILifecycleService lifecycleService: ILifecycleService, @IConfigurationService private readonly _configurationService: IConfigurationService, @IInstantiationService private readonly _instantiationService: IInstantiationService, - @IQuickOpenService private readonly _quickOpenService: IQuickOpenService, + @IQuickInputService private readonly _quickInputService: IQuickInputService, @INotificationService private readonly _notificationService: INotificationService, @IDialogService private readonly _dialogService: IDialogService, @IExtensionService private readonly _extensionService: IExtensionService @@ -184,10 +184,10 @@ export class TerminalService extends AbstractTerminalService implements ITermina public selectDefaultWindowsShell(): TPromise { return this._detectWindowsShells().then(shells => { - const options: IPickOptions = { + const options: IPickOptions = { placeHolder: nls.localize('terminal.integrated.chooseWindowsShell', "Select your preferred terminal shell, you can change this later in your settings") }; - return this._quickOpenService.pick(shells, options).then(value => { + return this._quickInputService.pick(shells, options).then(value => { if (!value) { return null; } @@ -197,7 +197,7 @@ export class TerminalService extends AbstractTerminalService implements ITermina }); } - private _detectWindowsShells(): TPromise { + private _detectWindowsShells(): TPromise { // 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 @@ -231,7 +231,7 @@ export class TerminalService extends AbstractTerminalService implements ITermina Object.keys(expectedLocations).forEach(key => promises.push(this._validateShellPaths(key, expectedLocations[key]))); return TPromise.join(promises).then(results => { return results.filter(result => !!result).map(result => { - return { + return { label: result[0], description: result[1] }; From 06fa9c4d91fc561192506e6a5126ad16fca408ad Mon Sep 17 00:00:00 2001 From: Benjamin Pasero Date: Thu, 9 Aug 2018 10:58:52 +0200 Subject: [PATCH 0620/1276] move help contributions to origins (for #54510) --- .../parts/titlebar/titlebar.contribution.ts | 156 ------------------ .../electron-browser/main.contribution.ts | 125 ++++++++++++++ .../welcomePage.contribution.ts | 11 +- .../walkThrough.contribution.ts | 11 +- 4 files changed, 145 insertions(+), 158 deletions(-) diff --git a/src/vs/workbench/browser/parts/titlebar/titlebar.contribution.ts b/src/vs/workbench/browser/parts/titlebar/titlebar.contribution.ts index 04235f1557d..030bc4391ae 100644 --- a/src/vs/workbench/browser/parts/titlebar/titlebar.contribution.ts +++ b/src/vs/workbench/browser/parts/titlebar/titlebar.contribution.ts @@ -5,16 +5,9 @@ import * as nls from 'vs/nls'; import { MenuRegistry, MenuId } from 'vs/platform/actions/common/actions'; -import { isMacintosh } from 'vs/base/common/platform'; goMenuRegistration(); -if (isMacintosh) { - windowMenuRegistration(); -} - -helpMenuRegistration(); - // Menu registration function goMenuRegistration() { // Forward/Back @@ -251,152 +244,3 @@ function goMenuRegistration() { order: 7 }); } - -function windowMenuRegistration() { - -} - -function helpMenuRegistration() { - // Welcome - MenuRegistry.appendMenuItem(MenuId.MenubarHelpMenu, { - group: '1_welcome', - command: { - id: 'workbench.action.showWelcomePage', - title: nls.localize({ key: 'miWelcome', comment: ['&& denotes a mnemonic'] }, "&&Welcome") - }, - order: 1 - }); - - MenuRegistry.appendMenuItem(MenuId.MenubarHelpMenu, { - group: '1_welcome', - command: { - id: 'workbench.action.showInteractivePlayground', - title: nls.localize({ key: 'miInteractivePlayground', comment: ['&& denotes a mnemonic'] }, "&&Interactive Playground") - }, - order: 2 - }); - - MenuRegistry.appendMenuItem(MenuId.MenubarHelpMenu, { - group: '1_welcome', - command: { - id: 'workbench.action.openDocumentationUrl', - title: nls.localize({ key: 'miDocumentation', comment: ['&& denotes a mnemonic'] }, "&&Documentation") - }, - order: 3 - }); - - MenuRegistry.appendMenuItem(MenuId.MenubarHelpMenu, { - group: '1_welcome', - command: { - id: 'update.showCurrentReleaseNotes', - title: nls.localize({ key: 'miReleaseNotes', comment: ['&& denotes a mnemonic'] }, "&&Release Notes") - }, - order: 4 - }); - - // Reference - MenuRegistry.appendMenuItem(MenuId.MenubarHelpMenu, { - group: '2_reference', - command: { - id: 'workbench.action.keybindingsReference', - title: nls.localize({ key: 'miKeyboardShortcuts', comment: ['&& denotes a mnemonic'] }, "&&Keyboard Shortcuts Reference") - }, - order: 1 - }); - - MenuRegistry.appendMenuItem(MenuId.MenubarHelpMenu, { - group: '2_reference', - command: { - id: 'workbench.action.openIntroductoryVideosUrl', - title: nls.localize({ key: 'miIntroductoryVideos', comment: ['&& denotes a mnemonic'] }, "Introductory &&Videos") - }, - order: 2 - }); - - MenuRegistry.appendMenuItem(MenuId.MenubarHelpMenu, { - group: '2_reference', - command: { - id: 'workbench.action.openTipsAndTricksUrl', - title: nls.localize({ key: 'miTipsAndTricks', comment: ['&& denotes a mnemonic'] }, "&&Tips and Tricks") - }, - order: 3 - }); - - // Feedback - MenuRegistry.appendMenuItem(MenuId.MenubarHelpMenu, { - group: '3_feedback', - command: { - id: 'workbench.action.openTwitterUrl', - title: nls.localize({ key: 'miTwitter', comment: ['&& denotes a mnemonic'] }, "&&Join us on Twitter") - }, - order: 1 - }); - - MenuRegistry.appendMenuItem(MenuId.MenubarHelpMenu, { - group: '3_feedback', - command: { - id: 'workbench.action.openRequestFeatureUrl', - title: nls.localize({ key: 'miUserVoice', comment: ['&& denotes a mnemonic'] }, "&&Search Feature Requests") - }, - order: 2 - }); - - MenuRegistry.appendMenuItem(MenuId.MenubarHelpMenu, { - group: '3_feedback', - command: { - id: 'workbench.action.openIssueReporter', - title: nls.localize({ key: 'miReportIssue', comment: ['&& denotes a mnemonic', 'Translate this to "Report Issue in English" in all languages please!'] }, "Report &&Issue") - }, - order: 3 - }); - - // Legal - MenuRegistry.appendMenuItem(MenuId.MenubarHelpMenu, { - group: '4_legal', - command: { - id: 'workbench.action.openLicenseUrl', - title: nls.localize({ key: 'miLicense', comment: ['&& denotes a mnemonic'] }, "View &&License") - }, - order: 1 - }); - - MenuRegistry.appendMenuItem(MenuId.MenubarHelpMenu, { - group: '4_legal', - command: { - id: 'workbench.action.openPrivacyStatementUrl', - title: nls.localize({ key: 'miPrivacyStatement', comment: ['&& denotes a mnemonic'] }, "&&Privacy Statement") - }, - order: 2 - }); - - // Tools - MenuRegistry.appendMenuItem(MenuId.MenubarHelpMenu, { - group: '5_tools', - command: { - id: 'workbench.action.toggleDevTools', - title: nls.localize({ key: 'miToggleDevTools', comment: ['&& denotes a mnemonic'] }, "&&Toggle Developer Tools") - }, - order: 1 - }); - - MenuRegistry.appendMenuItem(MenuId.MenubarHelpMenu, { - group: '5_tools', - command: { - id: 'workbench.action.openProcessExplorer', - title: nls.localize({ key: 'miOpenProcessExplorerer', comment: ['&& denotes a mnemonic'] }, "Open &&Process Explorer") - }, - order: 2 - }); - - if (!isMacintosh) { - // About - MenuRegistry.appendMenuItem(MenuId.MenubarHelpMenu, { - group: 'z_about', - command: { - id: 'workbench.action.showAboutDialog', - title: nls.localize({ key: 'miAbout', comment: ['&& denotes a mnemonic'] }, "&&About") - }, - order: 1 - }); - } -} diff --git a/src/vs/workbench/electron-browser/main.contribution.ts b/src/vs/workbench/electron-browser/main.contribution.ts index 2ab51f8a1de..c8a4525a481 100644 --- a/src/vs/workbench/electron-browser/main.contribution.ts +++ b/src/vs/workbench/electron-browser/main.contribution.ts @@ -341,6 +341,131 @@ MenuRegistry.appendMenuItem(MenuId.MenubarAppearanceMenu, { order: 3 }); +// Help + +MenuRegistry.appendMenuItem(MenuId.MenubarHelpMenu, { + group: '1_welcome', + command: { + id: 'workbench.action.openDocumentationUrl', + title: nls.localize({ key: 'miDocumentation', comment: ['&& denotes a mnemonic'] }, "&&Documentation") + }, + order: 3 +}); + +MenuRegistry.appendMenuItem(MenuId.MenubarHelpMenu, { + group: '1_welcome', + command: { + id: 'update.showCurrentReleaseNotes', + title: nls.localize({ key: 'miReleaseNotes', comment: ['&& denotes a mnemonic'] }, "&&Release Notes") + }, + order: 4 +}); + +// Reference +MenuRegistry.appendMenuItem(MenuId.MenubarHelpMenu, { + group: '2_reference', + command: { + id: 'workbench.action.keybindingsReference', + title: nls.localize({ key: 'miKeyboardShortcuts', comment: ['&& denotes a mnemonic'] }, "&&Keyboard Shortcuts Reference") + }, + order: 1 +}); + +MenuRegistry.appendMenuItem(MenuId.MenubarHelpMenu, { + group: '2_reference', + command: { + id: 'workbench.action.openIntroductoryVideosUrl', + title: nls.localize({ key: 'miIntroductoryVideos', comment: ['&& denotes a mnemonic'] }, "Introductory &&Videos") + }, + order: 2 +}); + +MenuRegistry.appendMenuItem(MenuId.MenubarHelpMenu, { + group: '2_reference', + command: { + id: 'workbench.action.openTipsAndTricksUrl', + title: nls.localize({ key: 'miTipsAndTricks', comment: ['&& denotes a mnemonic'] }, "&&Tips and Tricks") + }, + order: 3 +}); + +// Feedback +MenuRegistry.appendMenuItem(MenuId.MenubarHelpMenu, { + group: '3_feedback', + command: { + id: 'workbench.action.openTwitterUrl', + title: nls.localize({ key: 'miTwitter', comment: ['&& denotes a mnemonic'] }, "&&Join us on Twitter") + }, + order: 1 +}); + +MenuRegistry.appendMenuItem(MenuId.MenubarHelpMenu, { + group: '3_feedback', + command: { + id: 'workbench.action.openRequestFeatureUrl', + title: nls.localize({ key: 'miUserVoice', comment: ['&& denotes a mnemonic'] }, "&&Search Feature Requests") + }, + order: 2 +}); + +MenuRegistry.appendMenuItem(MenuId.MenubarHelpMenu, { + group: '3_feedback', + command: { + id: 'workbench.action.openIssueReporter', + title: nls.localize({ key: 'miReportIssue', comment: ['&& denotes a mnemonic', 'Translate this to "Report Issue in English" in all languages please!'] }, "Report &&Issue") + }, + order: 3 +}); + +// Legal +MenuRegistry.appendMenuItem(MenuId.MenubarHelpMenu, { + group: '4_legal', + command: { + id: 'workbench.action.openLicenseUrl', + title: nls.localize({ key: 'miLicense', comment: ['&& denotes a mnemonic'] }, "View &&License") + }, + order: 1 +}); + +MenuRegistry.appendMenuItem(MenuId.MenubarHelpMenu, { + group: '4_legal', + command: { + id: 'workbench.action.openPrivacyStatementUrl', + title: nls.localize({ key: 'miPrivacyStatement', comment: ['&& denotes a mnemonic'] }, "&&Privacy Statement") + }, + order: 2 +}); + +// Tools +MenuRegistry.appendMenuItem(MenuId.MenubarHelpMenu, { + group: '5_tools', + command: { + id: 'workbench.action.toggleDevTools', + title: nls.localize({ key: 'miToggleDevTools', comment: ['&& denotes a mnemonic'] }, "&&Toggle Developer Tools") + }, + order: 1 +}); + +MenuRegistry.appendMenuItem(MenuId.MenubarHelpMenu, { + group: '5_tools', + command: { + id: 'workbench.action.openProcessExplorer', + title: nls.localize({ key: 'miOpenProcessExplorerer', comment: ['&& denotes a mnemonic'] }, "Open &&Process Explorer") + }, + order: 2 +}); + +// About +if (!isMacintosh) { + MenuRegistry.appendMenuItem(MenuId.MenubarHelpMenu, { + group: 'z_about', + command: { + id: 'workbench.action.showAboutDialog', + title: nls.localize({ key: 'miAbout', comment: ['&& denotes a mnemonic'] }, "&&About") + }, + order: 1 + }); +} // Configuration: Workbench const configurationRegistry = Registry.as(ConfigurationExtensions.Configuration); diff --git a/src/vs/workbench/parts/welcome/page/electron-browser/welcomePage.contribution.ts b/src/vs/workbench/parts/welcome/page/electron-browser/welcomePage.contribution.ts index 38cf82f6c69..99341e7cabe 100644 --- a/src/vs/workbench/parts/welcome/page/electron-browser/welcomePage.contribution.ts +++ b/src/vs/workbench/parts/welcome/page/electron-browser/welcomePage.contribution.ts @@ -9,7 +9,7 @@ import { IWorkbenchContributionsRegistry, Extensions as WorkbenchExtensions } fr import { Registry } from 'vs/platform/registry/common/platform'; import { WelcomePageContribution, WelcomePageAction, WelcomeInputFactory } from 'vs/workbench/parts/welcome/page/electron-browser/welcomePage'; import { IWorkbenchActionRegistry, Extensions as ActionExtensions } from 'vs/workbench/common/actions'; -import { SyncActionDescriptor } from 'vs/platform/actions/common/actions'; +import { SyncActionDescriptor, MenuRegistry, MenuId } from 'vs/platform/actions/common/actions'; import { IConfigurationRegistry, Extensions as ConfigurationExtensions } from 'vs/platform/configuration/common/configurationRegistry'; import { IEditorInputFactoryRegistry, Extensions as EditorExtensions } from 'vs/workbench/common/editor'; import { LifecyclePhase } from 'vs/platform/lifecycle/common/lifecycle'; @@ -41,3 +41,12 @@ Registry.as(ActionExtensions.WorkbenchActions) .registerWorkbenchAction(new SyncActionDescriptor(WelcomePageAction, WelcomePageAction.ID, WelcomePageAction.LABEL), 'Help: Welcome', localize('help', "Help")); Registry.as(EditorExtensions.EditorInputFactories).registerEditorInputFactory(WelcomeInputFactory.ID, WelcomeInputFactory); + +MenuRegistry.appendMenuItem(MenuId.MenubarHelpMenu, { + group: '1_welcome', + command: { + id: 'workbench.action.showWelcomePage', + title: localize({ key: 'miWelcome', comment: ['&& denotes a mnemonic'] }, "&&Welcome") + }, + order: 1 +}); diff --git a/src/vs/workbench/parts/welcome/walkThrough/electron-browser/walkThrough.contribution.ts b/src/vs/workbench/parts/welcome/walkThrough/electron-browser/walkThrough.contribution.ts index 335ba65618e..f0397cfb446 100644 --- a/src/vs/workbench/parts/welcome/walkThrough/electron-browser/walkThrough.contribution.ts +++ b/src/vs/workbench/parts/welcome/walkThrough/electron-browser/walkThrough.contribution.ts @@ -14,7 +14,7 @@ import { Registry } from 'vs/platform/registry/common/platform'; import { Extensions as EditorInputExtensions, IEditorInputFactoryRegistry } from 'vs/workbench/common/editor'; import { SyncDescriptor } from 'vs/platform/instantiation/common/descriptors'; import { IWorkbenchActionRegistry, Extensions } from 'vs/workbench/common/actions'; -import { SyncActionDescriptor } from 'vs/platform/actions/common/actions'; +import { SyncActionDescriptor, MenuRegistry, MenuId } from 'vs/platform/actions/common/actions'; import { IWorkbenchContributionsRegistry, Extensions as WorkbenchExtensions } from 'vs/workbench/common/contributions'; import { IEditorRegistry, Extensions as EditorExtensions, EditorDescriptor } from 'vs/workbench/browser/editor'; import { LifecyclePhase } from 'vs/platform/lifecycle/common/lifecycle'; @@ -48,3 +48,12 @@ KeybindingsRegistry.registerCommandAndKeybindingRule(WalkThroughArrowDown); KeybindingsRegistry.registerCommandAndKeybindingRule(WalkThroughPageUp); KeybindingsRegistry.registerCommandAndKeybindingRule(WalkThroughPageDown); + +MenuRegistry.appendMenuItem(MenuId.MenubarHelpMenu, { + group: '1_welcome', + command: { + id: 'workbench.action.showInteractivePlayground', + title: localize({ key: 'miInteractivePlayground', comment: ['&& denotes a mnemonic'] }, "&&Interactive Playground") + }, + order: 2 +}); \ No newline at end of file From e1be460bb92712d1838129a18c9db23d4d317e99 Mon Sep 17 00:00:00 2001 From: Benjamin Pasero Date: Thu, 9 Aug 2018 11:43:14 +0200 Subject: [PATCH 0621/1276] Migrate menubar action registrations out of menubar.contribution.ts (fixes #54510) --- .../goToDefinition/goToDefinitionCommands.ts | 29 +++ .../parts/editor/editor.contribution.ts | 174 +++++++++++++ .../browser/parts/titlebar/menubarControl.ts | 1 - .../parts/titlebar/titlebar.contribution.ts | 246 ------------------ .../fileActions.contribution.ts | 11 + .../browser/quickopen.contribution.ts | 20 ++ .../electron-browser/search.contribution.ts | 11 + .../history/electron-browser/history.ts | 24 +- 8 files changed, 268 insertions(+), 248 deletions(-) delete mode 100644 src/vs/workbench/browser/parts/titlebar/titlebar.contribution.ts diff --git a/src/vs/editor/contrib/goToDefinition/goToDefinitionCommands.ts b/src/vs/editor/contrib/goToDefinition/goToDefinitionCommands.ts index 667e77dbf2d..6ca73451d74 100644 --- a/src/vs/editor/contrib/goToDefinition/goToDefinitionCommands.ts +++ b/src/vs/editor/contrib/goToDefinition/goToDefinitionCommands.ts @@ -26,6 +26,7 @@ import { ITextModel, IWordAtPosition } from 'vs/editor/common/model'; import { INotificationService } from 'vs/platform/notification/common/notification'; import { createCancelablePromise } from 'vs/base/common/async'; import { KeybindingWeight } from 'vs/platform/keybinding/common/keybindingsRegistry'; +import { MenuRegistry, MenuId } from 'vs/platform/actions/common/actions'; export class DefinitionActionConfig { @@ -375,3 +376,31 @@ registerEditorAction(GoToImplementationAction); registerEditorAction(PeekImplementationAction); registerEditorAction(GoToTypeDefinitionAction); registerEditorAction(PeekTypeDefinitionAction); + +// Go to menu +MenuRegistry.appendMenuItem(MenuId.MenubarGoMenu, { + group: 'z_go_to', + command: { + id: 'editor.action.goToDeclaration', + title: nls.localize({ key: 'miGotoDefinition', comment: ['&& denotes a mnemonic'] }, "Go to &&Definition") + }, + order: 4 +}); + +MenuRegistry.appendMenuItem(MenuId.MenubarGoMenu, { + group: 'z_go_to', + command: { + id: 'editor.action.goToTypeDefinition', + title: nls.localize({ key: 'miGotoTypeDefinition', comment: ['&& denotes a mnemonic'] }, "Go to &&Type Definition") + }, + order: 5 +}); + +MenuRegistry.appendMenuItem(MenuId.MenubarGoMenu, { + group: 'z_go_to', + command: { + id: 'editor.action.goToImplementation', + title: nls.localize({ key: 'miGotoImplementation', comment: ['&& denotes a mnemonic'] }, "Go to &&Implementation") + }, + order: 6 +}); \ No newline at end of file diff --git a/src/vs/workbench/browser/parts/editor/editor.contribution.ts b/src/vs/workbench/browser/parts/editor/editor.contribution.ts index f7865c8bb40..c5dd8e397d1 100644 --- a/src/vs/workbench/browser/parts/editor/editor.contribution.ts +++ b/src/vs/workbench/browser/parts/editor/editor.contribution.ts @@ -671,3 +671,177 @@ MenuRegistry.appendMenuItem(MenuId.MenubarLayoutMenu, { }, order: 9 }); + +// Main Menu Bar Contributions: + +// Forward/Back +MenuRegistry.appendMenuItem(MenuId.MenubarGoMenu, { + group: '1_fwd_back', + command: { + id: 'workbench.action.navigateBack', + title: nls.localize({ key: 'miBack', comment: ['&& denotes a mnemonic'] }, "&&Back"), + precondition: ContextKeyExpr.has('canNavigateBack') + }, + order: 1 +}); + +MenuRegistry.appendMenuItem(MenuId.MenubarGoMenu, { + group: '1_fwd_back', + command: { + id: 'workbench.action.navigateForward', + title: nls.localize({ key: 'miForward', comment: ['&& denotes a mnemonic'] }, "&&Forward"), + precondition: ContextKeyExpr.has('canNavigateForward') + }, + order: 2 +}); + +// Switch Editor +MenuRegistry.appendMenuItem(MenuId.MenubarSwitchEditorMenu, { + group: '1_any', + command: { + id: 'workbench.action.nextEditor', + title: nls.localize({ key: 'miNextEditor', comment: ['&& denotes a mnemonic'] }, "&&Next Editor") + }, + order: 1 +}); + +MenuRegistry.appendMenuItem(MenuId.MenubarSwitchEditorMenu, { + group: '1_any', + command: { + id: 'workbench.action.previousEditor', + title: nls.localize({ key: 'miPreviousEditor', comment: ['&& denotes a mnemonic'] }, "&&Previous Editor") + }, + order: 2 +}); + +MenuRegistry.appendMenuItem(MenuId.MenubarSwitchEditorMenu, { + group: '2_used', + command: { + id: 'workbench.action.openNextRecentlyUsedEditorInGroup', + title: nls.localize({ key: 'miNextEditorInGroup', comment: ['&& denotes a mnemonic'] }, "&&Next Used Editor in Group") + }, + order: 1 +}); + +MenuRegistry.appendMenuItem(MenuId.MenubarSwitchEditorMenu, { + group: '2_used', + command: { + id: 'workbench.action.openPreviousRecentlyUsedEditorInGroup', + title: nls.localize({ key: 'miPreviousEditorInGroup', comment: ['&& denotes a mnemonic'] }, "&&Previous Used Editor in Group") + }, + order: 2 +}); + +MenuRegistry.appendMenuItem(MenuId.MenubarGoMenu, { + group: '2_switch', + title: nls.localize({ key: 'miSwitchEditor', comment: ['&& denotes a mnemonic'] }, "Switch &&Editor"), + submenu: MenuId.MenubarSwitchEditorMenu, + order: 1 +}); + +// Switch Group +MenuRegistry.appendMenuItem(MenuId.MenubarSwitchGroupMenu, { + group: '1_focus_index', + command: { + id: 'workbench.action.focusFirstEditorGroup', + title: nls.localize({ key: 'miFocusFirstGroup', comment: ['&& denotes a mnemonic'] }, "Group &&1") + }, + order: 1 +}); + +MenuRegistry.appendMenuItem(MenuId.MenubarSwitchGroupMenu, { + group: '1_focus_index', + command: { + id: 'workbench.action.focusSecondEditorGroup', + title: nls.localize({ key: 'miFocusSecondGroup', comment: ['&& denotes a mnemonic'] }, "Group &&2") + }, + order: 2 +}); + +MenuRegistry.appendMenuItem(MenuId.MenubarSwitchGroupMenu, { + group: '1_focus_index', + command: { + id: 'workbench.action.focusThirdEditorGroup', + title: nls.localize({ key: 'miFocusThirdGroup', comment: ['&& denotes a mnemonic'] }, "Group &&3") + }, + order: 3 +}); + +MenuRegistry.appendMenuItem(MenuId.MenubarSwitchGroupMenu, { + group: '1_focus_index', + command: { + id: 'workbench.action.focusFourthEditorGroup', + title: nls.localize({ key: 'miFocusFourthGroup', comment: ['&& denotes a mnemonic'] }, "Group &&4") + }, + order: 4 +}); + +MenuRegistry.appendMenuItem(MenuId.MenubarSwitchGroupMenu, { + group: '1_focus_index', + command: { + id: 'workbench.action.focusFifthEditorGroup', + title: nls.localize({ key: 'miFocusFifthGroup', comment: ['&& denotes a mnemonic'] }, "Group &&5") + }, + order: 5 +}); + +MenuRegistry.appendMenuItem(MenuId.MenubarSwitchGroupMenu, { + group: '2_next_prev', + command: { + id: 'workbench.action.focusNextGroup', + title: nls.localize({ key: 'miNextGroup', comment: ['&& denotes a mnemonic'] }, "&&Next Group") + }, + order: 1 +}); + +MenuRegistry.appendMenuItem(MenuId.MenubarSwitchGroupMenu, { + group: '2_next_prev', + command: { + id: 'workbench.action.focusPreviousGroup', + title: nls.localize({ key: 'miPreviousGroup', comment: ['&& denotes a mnemonic'] }, "&&Previous Group") + }, + order: 2 +}); + +MenuRegistry.appendMenuItem(MenuId.MenubarSwitchGroupMenu, { + group: '3_directional', + command: { + id: 'workbench.action.focusLeftGroup', + title: nls.localize({ key: 'miFocusLeftGroup', comment: ['&& denotes a mnemonic'] }, "Group &&Left") + }, + order: 1 +}); + +MenuRegistry.appendMenuItem(MenuId.MenubarSwitchGroupMenu, { + group: '3_directional', + command: { + id: 'workbench.action.focusRightGroup', + title: nls.localize({ key: 'miFocusRightGroup', comment: ['&& denotes a mnemonic'] }, "Group &&Right") + }, + order: 2 +}); + +MenuRegistry.appendMenuItem(MenuId.MenubarSwitchGroupMenu, { + group: '3_directional', + command: { + id: 'workbench.action.focusAboveGroup', + title: nls.localize({ key: 'miFocusAboveGroup', comment: ['&& denotes a mnemonic'] }, "Group &&Above") + }, + order: 3 +}); + +MenuRegistry.appendMenuItem(MenuId.MenubarSwitchGroupMenu, { + group: '3_directional', + command: { + id: 'workbench.action.focusBelowGroup', + title: nls.localize({ key: 'miFocusBelowGroup', comment: ['&& denotes a mnemonic'] }, "Group &&Below") + }, + order: 4 +}); + +MenuRegistry.appendMenuItem(MenuId.MenubarGoMenu, { + group: '2_switch', + title: nls.localize({ key: 'miSwitchGroup', comment: ['&& denotes a mnemonic'] }, "Switch &&Group"), + submenu: MenuId.MenubarSwitchGroupMenu, + order: 2 +}); \ No newline at end of file diff --git a/src/vs/workbench/browser/parts/titlebar/menubarControl.ts b/src/vs/workbench/browser/parts/titlebar/menubarControl.ts index 98d87bac832..8bf59473f91 100644 --- a/src/vs/workbench/browser/parts/titlebar/menubarControl.ts +++ b/src/vs/workbench/browser/parts/titlebar/menubarControl.ts @@ -5,7 +5,6 @@ 'use strict'; -import 'vs/workbench/browser/parts/titlebar/titlebar.contribution'; import * as nls from 'vs/nls'; import * as browser from 'vs/base/browser/browser'; import { IMenubarMenu, IMenubarMenuItemAction, IMenubarMenuItemSubmenu, IMenubarKeybinding } from 'vs/platform/menubar/common/menubar'; diff --git a/src/vs/workbench/browser/parts/titlebar/titlebar.contribution.ts b/src/vs/workbench/browser/parts/titlebar/titlebar.contribution.ts deleted file mode 100644 index 030bc4391ae..00000000000 --- a/src/vs/workbench/browser/parts/titlebar/titlebar.contribution.ts +++ /dev/null @@ -1,246 +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 { MenuRegistry, MenuId } from 'vs/platform/actions/common/actions'; - -goMenuRegistration(); - -// Menu registration -function goMenuRegistration() { - // Forward/Back - MenuRegistry.appendMenuItem(MenuId.MenubarGoMenu, { - group: '1_fwd_back', - command: { - id: 'workbench.action.navigateBack', - title: nls.localize({ key: 'miBack', comment: ['&& denotes a mnemonic'] }, "&&Back") - }, - order: 1 - }); - - MenuRegistry.appendMenuItem(MenuId.MenubarGoMenu, { - group: '1_fwd_back', - command: { - id: 'workbench.action.navigateForward', - title: nls.localize({ key: 'miForward', comment: ['&& denotes a mnemonic'] }, "&&Forward") - }, - order: 2 - }); - - // Switch Editor - MenuRegistry.appendMenuItem(MenuId.MenubarSwitchEditorMenu, { - group: '1_any', - command: { - id: 'workbench.action.nextEditor', - title: nls.localize({ key: 'miNextEditor', comment: ['&& denotes a mnemonic'] }, "&&Next Editor") - }, - order: 1 - }); - - MenuRegistry.appendMenuItem(MenuId.MenubarSwitchEditorMenu, { - group: '1_any', - command: { - id: 'workbench.action.previousEditor', - title: nls.localize({ key: 'miPreviousEditor', comment: ['&& denotes a mnemonic'] }, "&&Previous Editor") - }, - order: 2 - }); - - MenuRegistry.appendMenuItem(MenuId.MenubarSwitchEditorMenu, { - group: '2_used', - command: { - id: 'workbench.action.openNextRecentlyUsedEditorInGroup', - title: nls.localize({ key: 'miNextEditorInGroup', comment: ['&& denotes a mnemonic'] }, "&&Next Used Editor in Group") - }, - order: 1 - }); - - MenuRegistry.appendMenuItem(MenuId.MenubarSwitchEditorMenu, { - group: '2_used', - command: { - id: 'workbench.action.openPreviousRecentlyUsedEditorInGroup', - title: nls.localize({ key: 'miPreviousEditorInGroup', comment: ['&& denotes a mnemonic'] }, "&&Previous Used Editor in Group") - }, - order: 2 - }); - - MenuRegistry.appendMenuItem(MenuId.MenubarGoMenu, { - group: '2_switch', - title: nls.localize({ key: 'miSwitchEditor', comment: ['&& denotes a mnemonic'] }, "Switch &&Editor"), - submenu: MenuId.MenubarSwitchEditorMenu, - order: 1 - }); - - // Switch Group - MenuRegistry.appendMenuItem(MenuId.MenubarSwitchGroupMenu, { - group: '1_focus_index', - command: { - id: 'workbench.action.focusFirstEditorGroup', - title: nls.localize({ key: 'miFocusFirstGroup', comment: ['&& denotes a mnemonic'] }, "Group &&1") - }, - order: 1 - }); - - MenuRegistry.appendMenuItem(MenuId.MenubarSwitchGroupMenu, { - group: '1_focus_index', - command: { - id: 'workbench.action.focusSecondEditorGroup', - title: nls.localize({ key: 'miFocusSecondGroup', comment: ['&& denotes a mnemonic'] }, "Group &&2") - }, - order: 2 - }); - - MenuRegistry.appendMenuItem(MenuId.MenubarSwitchGroupMenu, { - group: '1_focus_index', - command: { - id: 'workbench.action.focusThirdEditorGroup', - title: nls.localize({ key: 'miFocusThirdGroup', comment: ['&& denotes a mnemonic'] }, "Group &&3") - }, - order: 3 - }); - - MenuRegistry.appendMenuItem(MenuId.MenubarSwitchGroupMenu, { - group: '1_focus_index', - command: { - id: 'workbench.action.focusFourthEditorGroup', - title: nls.localize({ key: 'miFocusFourthGroup', comment: ['&& denotes a mnemonic'] }, "Group &&4") - }, - order: 4 - }); - - MenuRegistry.appendMenuItem(MenuId.MenubarSwitchGroupMenu, { - group: '1_focus_index', - command: { - id: 'workbench.action.focusFifthEditorGroup', - title: nls.localize({ key: 'miFocusFifthGroup', comment: ['&& denotes a mnemonic'] }, "Group &&5") - }, - order: 5 - }); - - MenuRegistry.appendMenuItem(MenuId.MenubarSwitchGroupMenu, { - group: '2_next_prev', - command: { - id: 'workbench.action.focusNextGroup', - title: nls.localize({ key: 'miNextGroup', comment: ['&& denotes a mnemonic'] }, "&&Next Group") - }, - order: 1 - }); - - MenuRegistry.appendMenuItem(MenuId.MenubarSwitchGroupMenu, { - group: '2_next_prev', - command: { - id: 'workbench.action.focusPreviousGroup', - title: nls.localize({ key: 'miPreviousGroup', comment: ['&& denotes a mnemonic'] }, "&&Previous Group") - }, - order: 2 - }); - - MenuRegistry.appendMenuItem(MenuId.MenubarSwitchGroupMenu, { - group: '3_directional', - command: { - id: 'workbench.action.focusLeftGroup', - title: nls.localize({ key: 'miFocusLeftGroup', comment: ['&& denotes a mnemonic'] }, "Group &&Left") - }, - order: 1 - }); - - MenuRegistry.appendMenuItem(MenuId.MenubarSwitchGroupMenu, { - group: '3_directional', - command: { - id: 'workbench.action.focusRightGroup', - title: nls.localize({ key: 'miFocusRightGroup', comment: ['&& denotes a mnemonic'] }, "Group &&Right") - }, - order: 2 - }); - - MenuRegistry.appendMenuItem(MenuId.MenubarSwitchGroupMenu, { - group: '3_directional', - command: { - id: 'workbench.action.focusAboveGroup', - title: nls.localize({ key: 'miFocusAboveGroup', comment: ['&& denotes a mnemonic'] }, "Group &&Above") - }, - order: 3 - }); - - MenuRegistry.appendMenuItem(MenuId.MenubarSwitchGroupMenu, { - group: '3_directional', - command: { - id: 'workbench.action.focusBelowGroup', - title: nls.localize({ key: 'miFocusBelowGroup', comment: ['&& denotes a mnemonic'] }, "Group &&Below") - }, - order: 4 - }); - - MenuRegistry.appendMenuItem(MenuId.MenubarGoMenu, { - group: '2_switch', - title: nls.localize({ key: 'miSwitchGroup', comment: ['&& denotes a mnemonic'] }, "Switch &&Group"), - submenu: MenuId.MenubarSwitchGroupMenu, - order: 2 - }); - - // Go to - MenuRegistry.appendMenuItem(MenuId.MenubarGoMenu, { - group: 'z_go_to', - command: { - id: 'workbench.action.quickOpen', - title: nls.localize({ key: 'miGotoFile', comment: ['&& denotes a mnemonic'] }, "Go to &&File...") - }, - order: 1 - }); - - MenuRegistry.appendMenuItem(MenuId.MenubarGoMenu, { - group: 'z_go_to', - command: { - id: 'workbench.action.gotoSymbol', - title: nls.localize({ key: 'miGotoSymbolInFile', comment: ['&& denotes a mnemonic'] }, "Go to &&Symbol in File...") - }, - order: 2 - }); - - MenuRegistry.appendMenuItem(MenuId.MenubarGoMenu, { - group: 'z_go_to', - command: { - id: 'workbench.action.showAllSymbols', - title: nls.localize({ key: 'miGotoSymbolInWorkspace', comment: ['&& denotes a mnemonic'] }, "Go to Symbol in &&Workspace...") - }, - order: 3 - }); - - MenuRegistry.appendMenuItem(MenuId.MenubarGoMenu, { - group: 'z_go_to', - command: { - id: 'editor.action.goToDeclaration', - title: nls.localize({ key: 'miGotoDefinition', comment: ['&& denotes a mnemonic'] }, "Go to &&Definition") - }, - order: 4 - }); - - MenuRegistry.appendMenuItem(MenuId.MenubarGoMenu, { - group: 'z_go_to', - command: { - id: 'editor.action.goToTypeDefinition', - title: nls.localize({ key: 'miGotoTypeDefinition', comment: ['&& denotes a mnemonic'] }, "Go to &&Type Definition") - }, - order: 5 - }); - - MenuRegistry.appendMenuItem(MenuId.MenubarGoMenu, { - group: 'z_go_to', - command: { - id: 'editor.action.goToImplementation', - title: nls.localize({ key: 'miGotoImplementation', comment: ['&& denotes a mnemonic'] }, "Go to &&Implementation") - }, - order: 6 - }); - - MenuRegistry.appendMenuItem(MenuId.MenubarGoMenu, { - group: 'z_go_to', - command: { - id: 'workbench.action.gotoLine', - title: nls.localize({ key: 'miGotoLine', comment: ['&& denotes a mnemonic'] }, "Go to &&Line...") - }, - order: 7 - }); -} diff --git a/src/vs/workbench/parts/files/electron-browser/fileActions.contribution.ts b/src/vs/workbench/parts/files/electron-browser/fileActions.contribution.ts index aea7d036304..1fd97d3e912 100644 --- a/src/vs/workbench/parts/files/electron-browser/fileActions.contribution.ts +++ b/src/vs/workbench/parts/files/electron-browser/fileActions.contribution.ts @@ -544,3 +544,14 @@ MenuRegistry.appendMenuItem(MenuId.MenubarFileMenu, { }, order: 2 }); + +// Go to menu + +MenuRegistry.appendMenuItem(MenuId.MenubarGoMenu, { + group: 'z_go_to', + command: { + id: 'workbench.action.quickOpen', + title: nls.localize({ key: 'miGotoFile', comment: ['&& denotes a mnemonic'] }, "Go to &&File...") + }, + order: 1 +}); \ No newline at end of file diff --git a/src/vs/workbench/parts/quickopen/browser/quickopen.contribution.ts b/src/vs/workbench/parts/quickopen/browser/quickopen.contribution.ts index 1ce6dc74391..638f3f36c58 100644 --- a/src/vs/workbench/parts/quickopen/browser/quickopen.contribution.ts +++ b/src/vs/workbench/parts/quickopen/browser/quickopen.contribution.ts @@ -165,3 +165,23 @@ MenuRegistry.appendMenuItem(MenuId.MenubarViewMenu, { }, order: 2 }); + +// Go to menu + +MenuRegistry.appendMenuItem(MenuId.MenubarGoMenu, { + group: 'z_go_to', + command: { + id: 'workbench.action.gotoSymbol', + title: nls.localize({ key: 'miGotoSymbolInFile', comment: ['&& denotes a mnemonic'] }, "Go to &&Symbol in File...") + }, + order: 2 +}); + +MenuRegistry.appendMenuItem(MenuId.MenubarGoMenu, { + group: 'z_go_to', + command: { + id: 'workbench.action.gotoLine', + title: nls.localize({ key: 'miGotoLine', comment: ['&& denotes a mnemonic'] }, "Go to &&Line...") + }, + order: 7 +}); \ No newline at end of file diff --git a/src/vs/workbench/parts/search/electron-browser/search.contribution.ts b/src/vs/workbench/parts/search/electron-browser/search.contribution.ts index fd4ddfd6534..407f714fbf4 100644 --- a/src/vs/workbench/parts/search/electron-browser/search.contribution.ts +++ b/src/vs/workbench/parts/search/electron-browser/search.contribution.ts @@ -642,3 +642,14 @@ MenuRegistry.appendMenuItem(MenuId.MenubarViewMenu, { }, order: 2 }); + +// Go to menu + +MenuRegistry.appendMenuItem(MenuId.MenubarGoMenu, { + group: 'z_go_to', + command: { + id: 'workbench.action.showAllSymbols', + title: nls.localize({ key: 'miGotoSymbolInWorkspace', comment: ['&& denotes a mnemonic'] }, "Go to Symbol in &&Workspace...") + }, + order: 3 +}); \ No newline at end of file diff --git a/src/vs/workbench/services/history/electron-browser/history.ts b/src/vs/workbench/services/history/electron-browser/history.ts index bdf9ae0eee3..5cee94d49fb 100644 --- a/src/vs/workbench/services/history/electron-browser/history.ts +++ b/src/vs/workbench/services/history/electron-browser/history.ts @@ -33,6 +33,7 @@ import { ResourceGlobMatcher } from 'vs/workbench/electron-browser/resources'; import { Schemas } from 'vs/base/common/network'; import { EditorServiceImpl } from 'vs/workbench/browser/parts/editor/editor'; import { IPartService } from 'vs/workbench/services/part/common/partService'; +import { IContextKeyService, RawContextKey, IContextKey } from 'vs/platform/contextkey/common/contextkey'; /** * Stores the selection & view state of an editor and allows to compare it to other selection states. @@ -123,6 +124,9 @@ export class HistoryService extends Disposable implements IHistoryService { private fileInputFactory: IFileInputFactory; + private canNavigateBackContextKey: IContextKey; + private canNavigateForwardContextKey: IContextKey; + constructor( @IEditorService private editorService: EditorServiceImpl, @IEditorGroupsService private editorGroupService: IEditorGroupsService, @@ -133,12 +137,16 @@ export class HistoryService extends Disposable implements IHistoryService { @IFileService private fileService: IFileService, @IWindowsService private windowService: IWindowsService, @IInstantiationService private instantiationService: IInstantiationService, - @IPartService private partService: IPartService + @IPartService private partService: IPartService, + @IContextKeyService private contextKeyService: IContextKeyService ) { super(); this.activeEditorListeners = []; + this.canNavigateBackContextKey = (new RawContextKey('canNavigateBack', false)).bindTo(this.contextKeyService); + this.canNavigateForwardContextKey = (new RawContextKey('canNavigateForward', false)).bindTo(this.contextKeyService); + this.fileInputFactory = Registry.as(EditorInputExtensions.EditorInputFactories).getFileInputFactory(); this.index = -1; @@ -268,6 +276,8 @@ export class HistoryService extends Disposable implements IHistoryService { private setIndex(value: number): void { this.lastIndex = this.index; this.index = value; + + this.updateContextKeys(); } private doForwardAcrossEditors(): void { @@ -338,6 +348,13 @@ export class HistoryService extends Disposable implements IHistoryService { this.stack.splice(0); this.history = []; this.recentlyClosedFiles = []; + + this.updateContextKeys(); + } + + private updateContextKeys(): void { + this.canNavigateBackContextKey.set(this.stack.length > 0 && this.index > 0); + this.canNavigateForwardContextKey.set(this.stack.length > 0 && this.index < this.stack.length - 1); } private navigate(acrossEditors?: boolean): void { @@ -569,6 +586,9 @@ export class HistoryService extends Disposable implements IHistoryService { if (stackInput instanceof EditorInput) { once(stackInput.onDispose)(() => this.removeFromStack(input)); } + + // Context + this.updateContextKeys(); } private preferResourceInput(input: IEditorInput): IEditorInput | IResourceInput { @@ -595,6 +615,8 @@ export class HistoryService extends Disposable implements IHistoryService { this.stack = this.stack.filter(e => !this.matches(arg1, e.input)); this.index = this.stack.length - 1; // reset index this.lastIndex = -1; + + this.updateContextKeys(); } private removeFromRecentlyClosedFiles(arg1: IEditorInput | IResourceInput | FileChangesEvent): void { From a4b28b833e76602410b4e14ca72a65cf5906e71d Mon Sep 17 00:00:00 2001 From: Benjamin Pasero Date: Thu, 9 Aug 2018 11:49:22 +0200 Subject: [PATCH 0622/1276] fix history check --- .../services/history/electron-browser/history.ts | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/src/vs/workbench/services/history/electron-browser/history.ts b/src/vs/workbench/services/history/electron-browser/history.ts index 5cee94d49fb..13c20d4a51e 100644 --- a/src/vs/workbench/services/history/electron-browser/history.ts +++ b/src/vs/workbench/services/history/electron-browser/history.ts @@ -681,13 +681,15 @@ export class HistoryService extends Disposable implements IHistoryService { if (arg2 instanceof EditorInput) { const inputResource = arg2.getResource(); - - let isSupportedFile = true; - if (this.partService.isCreated() && !this.fileService.canHandleResource(inputResource)) { - isSupportedFile = false; // make sure to only check this when workbench has started (for https://github.com/Microsoft/vscode/issues/48275) + if (!inputResource) { + return false; } - return inputResource && isSupportedFile && inputResource.toString() === resource.toString(); + if (this.partService.isCreated() && !this.fileService.canHandleResource(inputResource)) { + return false; // make sure to only check this when workbench has started (for https://github.com/Microsoft/vscode/issues/48275) + } + + return inputResource.toString() === resource.toString(); } const resourceInput = arg2 as IResourceInput; From acf0d09f043b195e37bfbc1b580f0a81ec6d67c9 Mon Sep 17 00:00:00 2001 From: Martin Aeschlimann Date: Thu, 9 Aug 2018 12:03:23 +0200 Subject: [PATCH 0623/1276] isMalformedFileUri fix and tests --- src/vs/base/common/resources.ts | 10 +++++++++- src/vs/base/test/common/resources.test.ts | 22 +++++++++++++++++++++- src/vs/workbench/api/node/apiCommands.ts | 9 ++++++--- 3 files changed, 36 insertions(+), 5 deletions(-) diff --git a/src/vs/base/common/resources.ts b/src/vs/base/common/resources.ts index df50dfeb419..8a20f1b859e 100644 --- a/src/vs/base/common/resources.ts +++ b/src/vs/base/common/resources.ts @@ -8,7 +8,7 @@ import * as paths from 'vs/base/common/paths'; import URI from 'vs/base/common/uri'; import { equalsIgnoreCase } from 'vs/base/common/strings'; import { Schemas } from 'vs/base/common/network'; -import { isLinux } from 'vs/base/common/platform'; +import { isLinux, isWindows } from 'vs/base/common/platform'; import { CharCode } from 'vs/base/common/charCode'; export function getComparisonKey(resource: URI): string { @@ -133,3 +133,11 @@ export function distinctParents(items: T[], resourceAccessor: (item: T) => UR return distinctParents; } + +export function isMalformedFileUri(candidate: URI): URI | undefined { + if (!candidate.scheme || isWindows && candidate.scheme.match(/^[a-zA-Z]$/)) { + return URI.file((candidate.scheme ? candidate.scheme + ':' : '') + candidate.path); + } + return void 0; +} + diff --git a/src/vs/base/test/common/resources.test.ts b/src/vs/base/test/common/resources.test.ts index ac6c9db534d..e35a9bb438d 100644 --- a/src/vs/base/test/common/resources.test.ts +++ b/src/vs/base/test/common/resources.test.ts @@ -5,7 +5,7 @@ 'use strict'; import * as assert from 'assert'; -import { dirname, basename, distinctParents, joinPath, isEqual, isEqualOrParent, hasToIgnoreCase, normalizePath, isAbsolutePath } from 'vs/base/common/resources'; +import { dirname, basename, distinctParents, joinPath, isEqual, isEqualOrParent, hasToIgnoreCase, normalizePath, isAbsolutePath, isMalformedFileUri } from 'vs/base/common/resources'; import URI from 'vs/base/common/uri'; import { isWindows } from 'vs/base/common/platform'; @@ -204,4 +204,24 @@ suite('Resources', () => { assert.equal(isEqualOrParent(fileURI3, fileURI, true), false, '15'); assert.equal(isEqualOrParent(fileURI5, fileURI5, true), true, '16'); }); + + function assertMalformedFileUri(path: string, expected: string) { + const newURI = isMalformedFileUri(URI.parse(path)); + assert.equal(newURI && newURI.toString(), expected); + } + + test('isMalformedFileUri', () => { + if (isWindows) { + assertMalformedFileUri('c:/foo/bar', 'file:///c%3A/foo/bar'); + assertMalformedFileUri('c:\\foo\\bar', 'file:///c%3A/foo/bar'); + assertMalformedFileUri('\\\\localhost\\c$\\devel\\test', 'file://localhost/c%24/devel/test'); + } + assertMalformedFileUri('/foo/bar', 'file:///foo/bar'); + + assertMalformedFileUri('file:///foo/bar', void 0); + assertMalformedFileUri('file:///c%3A/foo/bar', void 0); + assertMalformedFileUri('file://localhost/c$/devel/test', void 0); + assertMalformedFileUri('foo://dadie/foo/bar', void 0); + assertMalformedFileUri('foo:///dadie/foo/bar', void 0); + }); }); \ No newline at end of file diff --git a/src/vs/workbench/api/node/apiCommands.ts b/src/vs/workbench/api/node/apiCommands.ts index 6be39d21aaa..d04d6b2334c 100644 --- a/src/vs/workbench/api/node/apiCommands.ts +++ b/src/vs/workbench/api/node/apiCommands.ts @@ -5,6 +5,7 @@ 'use strict'; import URI from 'vs/base/common/uri'; +import { isMalformedFileUri } from 'vs/base/common/resources'; import * as vscode from 'vscode'; import * as typeConverters from 'vs/workbench/api/node/extHostTypeConverters'; import { CommandsRegistry, ICommandService, ICommandHandler } from 'vs/platform/commands/common/commands'; @@ -48,9 +49,11 @@ export class OpenFolderAPICommand { if (!uri) { return executor.executeCommand('_files.pickFolderAndOpen', forceNewWindow); } - if (!uri.scheme) { - console.warn(`'vscode.openFolder' command invoked with an invalid URI (scheme missing): '${uri}'. Converted to a 'file://' URI.`); - uri = URI.file(uri.toString()); + let correctedUri = isMalformedFileUri(uri); + if (correctedUri) { + // workaround for #55916 and #55891, will be removed in 1.28 + console.warn(`'vscode.openFolder' command invoked with an invalid URI (file:// scheme missing): '${uri}'. Converted to a 'file://' URI: ${correctedUri}`); + uri = correctedUri; } return executor.executeCommand('_files.windowOpen', [uri], forceNewWindow); From 4bdf15ba9e861928a81ffa3862a971da40a4d12c Mon Sep 17 00:00:00 2001 From: Johannes Rieken Date: Thu, 9 Aug 2018 12:07:01 +0200 Subject: [PATCH 0624/1276] pack emmet --- extensions/emmet/extension.webpack.config.js | 30 ++++++++++++++++++++ extensions/git/extension.webpack.config.js | 3 ++ 2 files changed, 33 insertions(+) create mode 100644 extensions/emmet/extension.webpack.config.js diff --git a/extensions/emmet/extension.webpack.config.js b/extensions/emmet/extension.webpack.config.js new file mode 100644 index 00000000000..7f7e41df2e5 --- /dev/null +++ b/extensions/emmet/extension.webpack.config.js @@ -0,0 +1,30 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +'use strict'; + +const path = require('path'); + +module.exports = { + // mode: 'none', + mode: 'production', + target: 'node', + context: __dirname, + entry: { + main: './out/extension.js', + }, + output: { + filename: '[name].bundle.js', + path: path.join(__dirname, 'out'), + libraryTarget: "commonjs", + }, + externals: { + 'vscode': 'commonjs vscode', + }, + resolve: { + mainFields: ['main'] + }, + stats: 'errors-only' +}; diff --git a/extensions/git/extension.webpack.config.js b/extensions/git/extension.webpack.config.js index d4f5bf626b4..480e64fc558 100644 --- a/extensions/git/extension.webpack.config.js +++ b/extensions/git/extension.webpack.config.js @@ -24,5 +24,8 @@ module.exports = { externals: { 'vscode': 'commonjs vscode', }, + resolve: { + mainFields: ['main'] + }, stats: 'errors-only' }; From 6a34d351067b34a083e387ea2f3cc2fb4066a3e4 Mon Sep 17 00:00:00 2001 From: Martin Aeschlimann Date: Thu, 9 Aug 2018 12:13:09 +0200 Subject: [PATCH 0625/1276] isEqualOrParent: use fspath for file URIs --- src/vs/base/common/resources.ts | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/vs/base/common/resources.ts b/src/vs/base/common/resources.ts index 8a20f1b859e..95d05f973df 100644 --- a/src/vs/base/common/resources.ts +++ b/src/vs/base/common/resources.ts @@ -27,6 +27,9 @@ export function basenameOrAuthority(resource: URI): string { export function isEqualOrParent(resource: URI, candidate: URI, ignoreCase?: boolean): boolean { if (resource.scheme === candidate.scheme && resource.authority === candidate.authority) { + if (resource.scheme === Schemas.file) { + return paths.isEqualOrParent(resource.fsPath, candidate.fsPath, ignoreCase); + } return paths.isEqualOrParent(resource.path, candidate.path, ignoreCase, '/'); } From 297712dce9b03daf8b628716a62407a0514d98e3 Mon Sep 17 00:00:00 2001 From: Benjamin Pasero Date: Thu, 9 Aug 2018 12:18:07 +0200 Subject: [PATCH 0626/1276] Revert "Don't include non-resource entries in history quick pick" This reverts commit 37209a838e9f7e9abe6dc53ed73cdf1e03b72060. --- .../parts/quickopen/quickOpenController.ts | 23 ++++++++++--------- 1 file changed, 12 insertions(+), 11 deletions(-) diff --git a/src/vs/workbench/browser/parts/quickopen/quickOpenController.ts b/src/vs/workbench/browser/parts/quickopen/quickOpenController.ts index a63062b1035..e35dd586dd8 100644 --- a/src/vs/workbench/browser/parts/quickopen/quickOpenController.ts +++ b/src/vs/workbench/browser/parts/quickopen/quickOpenController.ts @@ -1074,7 +1074,17 @@ class EditorHistoryHandler { // Massage search for scoring const query = prepareQuery(searchValue); - const history = this.historyService.getHistory() + // Just return all if we are not searching + const history = this.historyService.getHistory(); + if (!query.value) { + return history.map(input => this.instantiationService.createInstance(EditorHistoryEntry, input)); + } + + // Otherwise filter by search value and sort by score. Include matches on description + // in case the user is explicitly including path separators. + const accessor = query.containsPathSeparator ? MatchOnDescription : DoNotMatchOnDescription; + return history + // For now, only support to match on inputs that provide resource information .filter(input => { let resource: URI; @@ -1088,17 +1098,8 @@ class EditorHistoryHandler { }) // Conver to quick open entries - .map(input => this.instantiationService.createInstance(EditorHistoryEntry, input)); + .map(input => this.instantiationService.createInstance(EditorHistoryEntry, input)) - // Just return all if we are not searching - if (!query.value) { - return history; - } - - // Otherwise filter by search value and sort by score. Include matches on description - // in case the user is explicitly including path separators. - const accessor = query.containsPathSeparator ? MatchOnDescription : DoNotMatchOnDescription; - return history // Make sure the search value is matching .filter(e => { const itemScore = scoreItem(e, query, false, accessor, this.scorerCache); From 69a95b6907e8cb5938319c8c1a9b61f84e09abeb Mon Sep 17 00:00:00 2001 From: Martin Aeschlimann Date: Thu, 9 Aug 2018 12:54:52 +0200 Subject: [PATCH 0627/1276] fix explorerModelTest on linux --- .../files/test/electron-browser/explorerModel.test.ts | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/vs/workbench/parts/files/test/electron-browser/explorerModel.test.ts b/src/vs/workbench/parts/files/test/electron-browser/explorerModel.test.ts index 210ff1bdb78..e88d9dadf02 100644 --- a/src/vs/workbench/parts/files/test/electron-browser/explorerModel.test.ts +++ b/src/vs/workbench/parts/files/test/electron-browser/explorerModel.test.ts @@ -18,7 +18,12 @@ function createStat(path: string, name: string, isFolder: boolean, hasChildren: } function toResource(path) { - return URI.file(join('C:\\', path)); + if (isWindows) { + return URI.file(join('C:\\', path)); + } else { + return URI.file(join('/home/john', path)); + } + } suite('Files - View Model', () => { From 2ede90086d1c8f128584d5f82e6dbaec660a9e9b Mon Sep 17 00:00:00 2001 From: Benjamin Pasero Date: Thu, 9 Aug 2018 13:08:54 +0200 Subject: [PATCH 0628/1276] Diff editor: horizontal scrollbar height is smaller (fixes #56062) --- .../workbench/browser/parts/editor/media/notabstitlecontrol.css | 1 + 1 file changed, 1 insertion(+) diff --git a/src/vs/workbench/browser/parts/editor/media/notabstitlecontrol.css b/src/vs/workbench/browser/parts/editor/media/notabstitlecontrol.css index 5c323a06753..efd03a02391 100644 --- a/src/vs/workbench/browser/parts/editor/media/notabstitlecontrol.css +++ b/src/vs/workbench/browser/parts/editor/media/notabstitlecontrol.css @@ -79,6 +79,7 @@ display: flex; flex: initial; opacity: 0.5; + height: 35px; } .monaco-workbench > .part.editor > .content .editor-group-container.active > .title .title-actions { From f48b0cb4466111895fc05a70f5ed869a4008e267 Mon Sep 17 00:00:00 2001 From: Nil Date: Thu, 9 Aug 2018 20:28:50 +0800 Subject: [PATCH 0629/1276] update smoke ts version --- test/smoke/package.json | 2 +- test/smoke/yarn.lock | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/test/smoke/package.json b/test/smoke/package.json index c3d79b62111..34cb60f37ee 100644 --- a/test/smoke/package.json +++ b/test/smoke/package.json @@ -33,7 +33,7 @@ "rimraf": "^2.6.1", "strip-json-comments": "^2.0.1", "tmp": "0.0.33", - "typescript": "2.5.2", + "typescript": "2.9.2", "watch": "^1.0.2" } } diff --git a/test/smoke/yarn.lock b/test/smoke/yarn.lock index 55ab35aceea..57ac002dedb 100644 --- a/test/smoke/yarn.lock +++ b/test/smoke/yarn.lock @@ -1825,9 +1825,9 @@ typedarray@^0.0.6: version "0.0.6" resolved "https://registry.yarnpkg.com/typedarray/-/typedarray-0.0.6.tgz#867ac74e3864187b1d3d47d996a78ec5c8830777" -typescript@2.5.2: - version "2.5.2" - resolved "https://registry.yarnpkg.com/typescript/-/typescript-2.5.2.tgz#038a95f7d9bbb420b1bf35ba31d4c5c1dd3ffe34" +typescript@2.9.2: + version "2.9.2" + resolved "https://registry.yarnpkg.com/typescript/-/typescript-2.9.2.tgz#1cbf61d05d6b96269244eb6a3bce4bd914e0f00c" uid-number@^0.0.6: version "0.0.6" From 3479e3b4e1d99c5b59b0bd5f28dc47c6c25c3afc Mon Sep 17 00:00:00 2001 From: Martin Aeschlimann Date: Thu, 9 Aug 2018 15:10:18 +0200 Subject: [PATCH 0630/1276] explorer: use isEqualOrParent --- src/vs/workbench/parts/files/common/explorerModel.ts | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/vs/workbench/parts/files/common/explorerModel.ts b/src/vs/workbench/parts/files/common/explorerModel.ts index 249e572bc0d..49d64d0a561 100644 --- a/src/vs/workbench/parts/files/common/explorerModel.ts +++ b/src/vs/workbench/parts/files/common/explorerModel.ts @@ -15,7 +15,7 @@ import { IWorkspaceContextService } from 'vs/platform/workspace/common/workspace import { toResource, IEditorIdentifier, IEditorInput } from 'vs/workbench/common/editor'; import { IDisposable, dispose } from 'vs/base/common/lifecycle'; import { Schemas } from 'vs/base/common/network'; -import { startsWith, startsWithIgnoreCase, rtrim } from 'vs/base/common/strings'; +import { rtrim } from 'vs/base/common/strings'; import { IEditorGroup } from 'vs/workbench/services/group/common/editorGroupsService'; export class Model { @@ -342,9 +342,7 @@ export class ExplorerItem { */ public find(resource: URI): ExplorerItem { // Return if path found - if (resource && this.resource.scheme === resource.scheme && this.resource.authority === resource.authority && - (isLinux ? startsWith(resource.path, this.resource.path) : startsWithIgnoreCase(resource.path, this.resource.path)) - ) { + if (resource && resources.isEqualOrParent(resource, this.resource)) { return this.findByPath(rtrim(resource.path, paths.sep), this.resource.path.length); } From b1f3ae287e81d0aedea535af476454c0a4fa8ae5 Mon Sep 17 00:00:00 2001 From: Martin Aeschlimann Date: Thu, 9 Aug 2018 15:20:51 +0200 Subject: [PATCH 0631/1276] storage.json: don't change existing format for recent files --- .../electron-main/historyMainService.ts | 27 +++++++++---------- 1 file changed, 13 insertions(+), 14 deletions(-) diff --git a/src/vs/platform/history/electron-main/historyMainService.ts b/src/vs/platform/history/electron-main/historyMainService.ts index 1bd96969e12..0d0ac885608 100644 --- a/src/vs/platform/history/electron-main/historyMainService.ts +++ b/src/vs/platform/history/electron-main/historyMainService.ts @@ -27,11 +27,12 @@ import { IUriDisplayService } from 'vs/platform/uriDisplay/common/uriDisplay'; interface ISerializedRecentlyOpened { workspaces2: (IWorkspaceIdentifier | string)[]; // IWorkspaceIdentifier or URI.toString() - files: string[]; + files2: string[]; // files as URI.toString() } interface ILegacySerializedRecentlyOpened { workspaces: (IWorkspaceIdentifier | string | UriComponents)[]; // legacy (UriComponents was also supported for a few insider builds) + files: string[]; // files as paths } export class HistoryMainService implements IHistoryMainService { @@ -284,27 +285,25 @@ export class HistoryMainService implements IHistoryMainService { } } } - if (Array.isArray(storedRecents.files)) { - for (const file of storedRecents.files) { + if (Array.isArray(storedRecents.files2)) { + for (const file of storedRecents.files2) { if (typeof file === 'string') { - result.files.push(file); + result.files.push(URI.parse(file)); + } + } + } else if (Array.isArray(storedRecents.files)) { + for (const file of storedRecents.files) { + if (typeof file === 'string') { + result.files.push(URI.file(file)); } } - } - } - for (const file of storedRecents.files) { - if (typeof file === 'string') { - // file paths were strings <= 1.25 - result.workspaces.push(URI.file(file)); - } else { - result.workspaces.push(URI.revive(file)); } } return result; } private saveRecentlyOpened(recent: IRecentlyOpened): void { - const serialized: ISerializedRecentlyOpened = { workspaces2: [], files: [] }; + const serialized: ISerializedRecentlyOpened = { workspaces2: [], files2: [] }; for (const workspace of recent.workspaces) { if (isSingleFolderWorkspaceIdentifier(workspace)) { serialized.workspaces2.push(workspace.toString()); @@ -313,7 +312,7 @@ export class HistoryMainService implements IHistoryMainService { } } for (const file of recent.files) { - serialized.files.push(file.toString()); + serialized.files2.push(file.toString()); } this.stateService.setItem(HistoryMainService.recentlyOpenedStorageKey, serialized); } From 776e491ba4ea5245da9aa75a9d4b5683c2e2221e Mon Sep 17 00:00:00 2001 From: Johannes Rieken Date: Thu, 9 Aug 2018 15:31:31 +0200 Subject: [PATCH 0632/1276] bundle into dist folder, copy ask-pass shell scripts into dist, some :lipstick: --- .gitignore | 3 +- build/lib/extensions.js | 7 ++- build/lib/extensions.ts | 8 ++- extensions/emmet/.vscodeignore | 4 +- extensions/emmet/extension.webpack.config.js | 19 ++++--- extensions/git/.gitignore | 1 - extensions/git/extension.webpack.config.js | 24 +++++---- package.json | 1 + yarn.lock | 53 +++++++++++++++++++- 9 files changed, 94 insertions(+), 26 deletions(-) delete mode 100644 extensions/git/.gitignore diff --git a/.gitignore b/.gitignore index 08adb4af663..6a9804cd237 100644 --- a/.gitignore +++ b/.gitignore @@ -3,6 +3,7 @@ npm-debug.log Thumbs.db node_modules/ .build/ +extensions/**/dist/ out/ out-build/ out-editor/ @@ -17,4 +18,4 @@ build/node_modules coverage/ test_data/ test-results/ -yarn-error.log \ No newline at end of file +yarn-error.log diff --git a/build/lib/extensions.js b/build/lib/extensions.js index 11c5e0c0b03..af06cde2b94 100644 --- a/build/lib/extensions.js +++ b/build/lib/extensions.js @@ -40,11 +40,16 @@ function fromLocal(extensionPath) { var patchFilesStream = filesStream .pipe(packageJsonFilter) .pipe(buffer()) - .pipe(json({ main: './out/main.bundle' })) // hardcoded entry point! + .pipe(json(function (data) { + // hardcoded entry point directory! + data.main = data.main.replace('/out/', /dist/); + return data; + })) .pipe(packageJsonFilter.restore); var webpackConfig = require(path.join(extensionPath, 'extension.webpack.config.js')); var webpackStream = webpackGulp(webpackConfig, webpack) .pipe(es.through(function (data) { + data.stat = data.stat || {}; data.base = extensionPath; this.emit('data', data); })); diff --git a/build/lib/extensions.ts b/build/lib/extensions.ts index 90dd5502981..2191710f232 100644 --- a/build/lib/extensions.ts +++ b/build/lib/extensions.ts @@ -20,7 +20,6 @@ import * as fs from 'fs'; import * as path from 'path'; import * as vsce from 'vsce'; import * as File from 'vinyl'; -import { rebase } from './util'; export function fromLocal(extensionPath: string): Stream { let result = es.through(); @@ -46,12 +45,17 @@ export function fromLocal(extensionPath: string): Stream { const patchFilesStream = filesStream .pipe(packageJsonFilter) .pipe(buffer()) - .pipe(json({ main: './out/main.bundle' })) // hardcoded entry point! + .pipe(json(data => { + // hardcoded entry point directory! + data.main = data.main.replace('/out/', /dist/); + return data; + })) .pipe(packageJsonFilter.restore); const webpackConfig = require(path.join(extensionPath, 'extension.webpack.config.js')); const webpackStream = webpackGulp(webpackConfig, webpack) .pipe(es.through(function (data) { + data.stat = data.stat || {}; data.base = extensionPath; this.emit('data', data); })); diff --git a/extensions/emmet/.vscodeignore b/extensions/emmet/.vscodeignore index ebab1d50b9b..d278b9bf417 100644 --- a/extensions/emmet/.vscodeignore +++ b/extensions/emmet/.vscodeignore @@ -1,3 +1,5 @@ test/** src/** -tsconfig.json \ No newline at end of file +out/** +node_modules/** +tsconfig.json diff --git a/extensions/emmet/extension.webpack.config.js b/extensions/emmet/extension.webpack.config.js index 7f7e41df2e5..5534ef2030b 100644 --- a/extensions/emmet/extension.webpack.config.js +++ b/extensions/emmet/extension.webpack.config.js @@ -8,23 +8,22 @@ const path = require('path'); module.exports = { - // mode: 'none', - mode: 'production', - target: 'node', + stats: 'errors-only', + // mode: 'none', // default is production context: __dirname, + target: 'node', + resolve: { + mainFields: ['main'] + }, entry: { - main: './out/extension.js', + extension: './out/extension.js', }, output: { - filename: '[name].bundle.js', - path: path.join(__dirname, 'out'), + filename: '[name].js', + path: path.join(__dirname, 'dist'), libraryTarget: "commonjs", }, externals: { 'vscode': 'commonjs vscode', }, - resolve: { - mainFields: ['main'] - }, - stats: 'errors-only' }; diff --git a/extensions/git/.gitignore b/extensions/git/.gitignore deleted file mode 100644 index 1521c8b7652..00000000000 --- a/extensions/git/.gitignore +++ /dev/null @@ -1 +0,0 @@ -dist diff --git a/extensions/git/extension.webpack.config.js b/extensions/git/extension.webpack.config.js index 480e64fc558..d2c8a4eee95 100644 --- a/extensions/git/extension.webpack.config.js +++ b/extensions/git/extension.webpack.config.js @@ -6,26 +6,32 @@ 'use strict'; const path = require('path'); +const CopyWebpackPlugin = require('copy-webpack-plugin'); module.exports = { - // mode: 'none', - mode: 'production', - target: 'node', + stats: 'errors-only', + // mode: 'none', // default is production context: __dirname, + target: 'node', + node: { + __dirname: false + }, + resolve: { + mainFields: ['main'] + }, entry: { main: './out/main.js', ['askpass-main']: './out/askpass-main.js' }, output: { - filename: '[name].bundle.js', - path: path.join(__dirname, 'out'), + filename: '[name].js', + path: path.join(__dirname, 'dist'), libraryTarget: "commonjs" }, externals: { 'vscode': 'commonjs vscode', }, - resolve: { - mainFields: ['main'] - }, - stats: 'errors-only' + plugins: [ + new CopyWebpackPlugin([{ from: './out/*.sh', to: '[name].sh' }]) + ] }; diff --git a/package.json b/package.json index ca9122ea56d..38d58c1f361 100644 --- a/package.json +++ b/package.json @@ -63,6 +63,7 @@ "asar": "^0.14.0", "chromium-pickle-js": "^0.2.0", "clean-css": "3.4.6", + "copy-webpack-plugin": "^4.5.2", "coveralls": "^2.11.11", "cson-parser": "^1.3.3", "debounce": "^1.0.0", diff --git a/yarn.lock b/yarn.lock index 19cb0c010e5..8b5ee32b9da 100644 --- a/yarn.lock +++ b/yarn.lock @@ -471,7 +471,7 @@ array-unique@^0.3.2: version "0.3.2" resolved "https://registry.yarnpkg.com/array-unique/-/array-unique-0.3.2.tgz#a894b75d4bc4f6cd679ef3244a9fd8f46ae2d428" -arrify@^1.0.0: +arrify@^1.0.0, arrify@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/arrify/-/arrify-1.0.1.tgz#898508da2226f380df904728456849c1501a4b0d" @@ -1375,6 +1375,19 @@ copy-descriptor@^0.1.0: version "0.1.1" resolved "https://registry.yarnpkg.com/copy-descriptor/-/copy-descriptor-0.1.1.tgz#676f6eb3c39997c2ee1ac3a924fd6124748f578d" +copy-webpack-plugin@^4.5.2: + version "4.5.2" + resolved "https://registry.yarnpkg.com/copy-webpack-plugin/-/copy-webpack-plugin-4.5.2.tgz#d53444a8fea2912d806e78937390ddd7e632ee5c" + dependencies: + cacache "^10.0.4" + find-cache-dir "^1.0.0" + globby "^7.1.1" + is-glob "^4.0.0" + loader-utils "^1.1.0" + minimatch "^3.0.4" + p-limit "^1.0.0" + serialize-javascript "^1.4.0" + core-util-is@1.0.2, core-util-is@~1.0.0: version "1.0.2" resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7" @@ -1793,6 +1806,13 @@ diffie-hellman@^5.0.0: miller-rabin "^4.0.0" randombytes "^2.0.0" +dir-glob@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/dir-glob/-/dir-glob-2.0.0.tgz#0b205d2b6aef98238ca286598a8204d29d0a0034" + dependencies: + 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" @@ -2943,6 +2963,17 @@ globby@^5.0.0: pify "^2.0.0" pinkie-promise "^2.0.0" +globby@^7.1.1: + version "7.1.1" + resolved "https://registry.yarnpkg.com/globby/-/globby-7.1.1.tgz#fb2ccff9401f8600945dfada97440cca972b8680" + dependencies: + array-union "^1.0.1" + dir-glob "^2.0.0" + glob "^7.1.2" + ignore "^3.3.5" + pify "^3.0.0" + slash "^1.0.0" + globule@~0.1.0: version "0.1.0" resolved "https://registry.yarnpkg.com/globule/-/globule-0.1.0.tgz#d9c8edde1da79d125a151b79533b978676346ae5" @@ -3582,6 +3613,10 @@ ignore@^3.2.0: version "3.3.7" resolved "https://registry.yarnpkg.com/ignore/-/ignore-3.3.7.tgz#612289bfb3c220e186a58118618d5be8c1bab021" +ignore@^3.3.5: + version "3.3.10" + resolved "https://registry.yarnpkg.com/ignore/-/ignore-3.3.10.tgz#0a97fb876986e8081c631160f8f9f389157f0043" + import-local@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/import-local/-/import-local-1.0.0.tgz#5e4ffdc03f4fe6c009c6729beb29631c2f8227bc" @@ -5402,6 +5437,12 @@ p-finally@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/p-finally/-/p-finally-1.0.0.tgz#3fbcfb15b899a44123b34b6dcc18b724336a2cae" +p-limit@^1.0.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-1.3.0.tgz#b86bd5f0c25690911c7590fcbfc2010d54b3ccb8" + dependencies: + p-try "^1.0.0" + p-limit@^1.1.0: version "1.2.0" resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-1.2.0.tgz#0e92b6bedcb59f022c13d0f1949dc82d15909f1c" @@ -5567,6 +5608,12 @@ path-type@^1.0.0: pify "^2.0.0" pinkie-promise "^2.0.0" +path-type@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/path-type/-/path-type-3.0.0.tgz#cef31dc8e0a1a3bb0d105c0cd97cf3bf47f4e36f" + dependencies: + pify "^3.0.0" + pause-stream@0.0.11: version "0.0.11" resolved "https://registry.yarnpkg.com/pause-stream/-/pause-stream-0.0.11.tgz#fe5a34b0cbce12b5aa6a2b403ee2e73b602f1445" @@ -6737,6 +6784,10 @@ sinon@^1.17.2: samsam "1.1.2" util ">=0.10.3 <1" +slash@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/slash/-/slash-1.0.0.tgz#c41f2f6c39fc16d1cd17ad4b5d896114ae470d55" + slice-ansi@0.0.4: version "0.0.4" resolved "https://registry.yarnpkg.com/slice-ansi/-/slice-ansi-0.0.4.tgz#edbf8903f66f7ce2f8eafd6ceed65e264c831b35" From 57ab236587b0745512395f67c6ad7d287a7d7c31 Mon Sep 17 00:00:00 2001 From: Benjamin Pasero Date: Thu, 9 Aug 2018 16:04:59 +0200 Subject: [PATCH 0633/1276] pinch zoom is now disabled by default --- src/vs/workbench/electron-browser/bootstrap/index.js | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/vs/workbench/electron-browser/bootstrap/index.js b/src/vs/workbench/electron-browser/bootstrap/index.js index 8311ab796ae..3be37da8695 100644 --- a/src/vs/workbench/electron-browser/bootstrap/index.js +++ b/src/vs/workbench/electron-browser/bootstrap/index.js @@ -252,9 +252,8 @@ function main() { const enableDeveloperTools = (process.env['VSCODE_DEV'] || !!configuration.extensionDevelopmentPath) && !configuration.extensionTestsPath; const unbind = registerListeners(enableDeveloperTools); - // disable pinch zoom & apply zoom level early to avoid glitches + // Apply zoom level early to avoid glitches const zoomLevel = configuration.zoomLevel; - webFrame.setVisualZoomLevelLimits(1, 1); if (typeof zoomLevel === 'number' && zoomLevel !== 0) { webFrame.setZoomLevel(zoomLevel); } From 16aa4bd4c161f234413a0cd153bf396dfabbd407 Mon Sep 17 00:00:00 2001 From: Benjamin Pasero Date: Thu, 9 Aug 2018 16:06:39 +0200 Subject: [PATCH 0634/1276] Revert "pinch zoom is now disabled by default" This reverts commit 57ab236587b0745512395f67c6ad7d287a7d7c31. --- src/vs/workbench/electron-browser/bootstrap/index.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/vs/workbench/electron-browser/bootstrap/index.js b/src/vs/workbench/electron-browser/bootstrap/index.js index 3be37da8695..8311ab796ae 100644 --- a/src/vs/workbench/electron-browser/bootstrap/index.js +++ b/src/vs/workbench/electron-browser/bootstrap/index.js @@ -252,8 +252,9 @@ function main() { const enableDeveloperTools = (process.env['VSCODE_DEV'] || !!configuration.extensionDevelopmentPath) && !configuration.extensionTestsPath; const unbind = registerListeners(enableDeveloperTools); - // Apply zoom level early to avoid glitches + // disable pinch zoom & apply zoom level early to avoid glitches const zoomLevel = configuration.zoomLevel; + webFrame.setVisualZoomLevelLimits(1, 1); if (typeof zoomLevel === 'number' && zoomLevel !== 0) { webFrame.setZoomLevel(zoomLevel); } From 8b8feed4ad6f4b7058a35ffbcf934444e7dac43a Mon Sep 17 00:00:00 2001 From: Martin Aeschlimann Date: Thu, 9 Aug 2018 17:54:54 +0200 Subject: [PATCH 0635/1276] polish cli args parsing --- src/vs/code/electron-main/app.ts | 13 ++-- src/vs/code/electron-main/launch.ts | 4 +- src/vs/code/electron-main/windows.ts | 100 +++++++++++++++++---------- src/vs/code/node/args.ts | 15 +++- src/vs/code/node/windowsFinder.ts | 53 +++++++------- 5 files changed, 112 insertions(+), 73 deletions(-) diff --git a/src/vs/code/electron-main/app.ts b/src/vs/code/electron-main/app.ts index e6c6f9fb91d..6919e7bafb1 100644 --- a/src/vs/code/electron-main/app.ts +++ b/src/vs/code/electron-main/app.ts @@ -65,6 +65,7 @@ import { MenubarService } from 'vs/platform/menubar/electron-main/menubarService import { MenubarChannel } from 'vs/platform/menubar/common/menubarIpc'; import { IUriDisplayService } from 'vs/platform/uriDisplay/common/uriDisplay'; import { CodeMenu } from 'vs/code/electron-main/menus'; +import { hasArgs } from 'vs/code/node/args'; export class CodeApplication { @@ -467,16 +468,16 @@ export class CodeApplication { // Open our first window const macOpenFiles = (global).macOpenFiles as string[]; const context = !!process.env['VSCODE_CLI'] ? OpenContext.CLI : OpenContext.DESKTOP; - const cliArgs = args._ || []; - const folderURIs = asArray(args['folder-uri']); - const fileURIs = asArray(args['file-uri']); + const hasCliArgs = hasArgs(args._); + const hasFolderURIs = hasArgs(args['folder-uri']); + const hasFileURIs = hasArgs(args['file-uri']); - if (args['new-window'] && !cliArgs.length && !folderURIs.length && !fileURIs.length) { + if (args['new-window'] && !hasCliArgs && !hasFolderURIs && !hasFileURIs) { this.windowsMainService.open({ context, cli: args, forceNewWindow: true, forceEmpty: true, initialStartup: true }); // new window if "-n" was used without paths - } else if (macOpenFiles && macOpenFiles.length && !cliArgs.length && !folderURIs.length && !fileURIs.length) { + } else if (macOpenFiles && macOpenFiles.length && !hasCliArgs && !hasFolderURIs && !hasFileURIs) { this.windowsMainService.open({ context: OpenContext.DOCK, cli: args, urisToOpen: macOpenFiles.map(file => URI.file(file)), initialStartup: true }); // mac: open-file event received on startup } else { - this.windowsMainService.open({ context, cli: args, forceNewWindow: args['new-window'] || (!cliArgs.length && args['unity-launch']), diffMode: args.diff, initialStartup: true }); // default: read paths from cli + this.windowsMainService.open({ context, cli: args, forceNewWindow: args['new-window'] || (!hasCliArgs && args['unity-launch']), diffMode: args.diff, initialStartup: true }); // default: read paths from cli } } diff --git a/src/vs/code/electron-main/launch.ts b/src/vs/code/electron-main/launch.ts index bf3c3d45c2a..b3bf915f9a9 100644 --- a/src/vs/code/electron-main/launch.ts +++ b/src/vs/code/electron-main/launch.ts @@ -20,7 +20,7 @@ import { IConfigurationService } from 'vs/platform/configuration/common/configur import URI, { UriComponents } from 'vs/base/common/uri'; import { BrowserWindow } from 'electron'; import { Event } from 'vs/base/common/event'; -import { asArray } from 'vs/code/node/args'; +import { hasArgs } from 'vs/code/node/args'; export const ID = 'launchService'; export const ILaunchService = createDecorator(ID); @@ -179,7 +179,7 @@ export class LaunchService implements ILaunchService { } // Start without file/folder arguments - else if (args._.length === 0 && !asArray(args['folder-uri'].length && !asArray(args['file-uri'].length))) { + else if (!hasArgs(args._) && !hasArgs(args['folder-uri']) && !hasArgs(args['file-uri'])) { let openNewWindow = false; // Force new window diff --git a/src/vs/code/electron-main/windows.ts b/src/vs/code/electron-main/windows.ts index fea7ce16394..7a450e46ca6 100644 --- a/src/vs/code/electron-main/windows.ts +++ b/src/vs/code/electron-main/windows.ts @@ -14,7 +14,7 @@ import { IBackupMainService } from 'vs/platform/backup/common/backup'; import { IEnvironmentService, ParsedArgs } from 'vs/platform/environment/common/environment'; import { IStateService } from 'vs/platform/state/common/state'; import { CodeWindow, defaultWindowState } from 'vs/code/electron-main/window'; -import { asArray } from 'vs/code/node/args'; +import { asArray, hasArgs } from 'vs/code/node/args'; import { ipcMain as ipc, screen, BrowserWindow, dialog, systemPreferences, app } from 'electron'; import { IPathWithLineAndColumn, parseLineAndColumnAware } from 'vs/code/node/paths'; import { ILifecycleService, UnloadReason, IWindowUnloadEvent } from 'vs/platform/lifecycle/electron-main/lifecycleMain'; @@ -423,7 +423,7 @@ export class WindowsManager implements IWindowsMainService { // Make sure to pass focus to the most relevant of the windows if we open multiple if (usedWindows.length > 1) { - let focusLastActive = this.windowsState.lastActiveWindow && !openConfig.forceEmpty && !openConfig.cli._.length && !asArray(openConfig.cli['file-uri']).length && !asArray(openConfig.cli['folder-uri']).length && !asArray(openConfig.urisToOpen).length; + let focusLastActive = this.windowsState.lastActiveWindow && !openConfig.forceEmpty && !hasArgs(openConfig.cli._) && !hasArgs(openConfig.cli['file-uri']) && !hasArgs(openConfig.cli['folder-uri']) && !hasArgs(openConfig.urisToOpen); let focusLastOpened = true; let focusLastWindow = true; @@ -795,7 +795,7 @@ export class WindowsManager implements IWindowsMainService { } // Extract paths: from CLI - else if (openConfig.cli._.length > 0 || asArray(openConfig.cli['folder-uri']).length > 0 || asArray(openConfig.cli['file-uri']).length > 0) { + else if (hasArgs(openConfig.cli._) || hasArgs(openConfig.cli['folder-uri']) || hasArgs(openConfig.cli['file-uri'])) { windowsToOpen = this.doExtractPathsFromCLI(openConfig.cli); isCommandLineOrAPICall = true; } @@ -824,53 +824,74 @@ export class WindowsManager implements IWindowsMainService { } private doExtractPathsFromAPI(openConfig: IOpenConfiguration): IPath[] { - let pathsToOpen = openConfig.urisToOpen.map(pathToOpen => { - const path = this.parseUri(pathToOpen, openConfig.forceOpenWorkspaceAsFile, { gotoLineMode: openConfig.cli && openConfig.cli.goto, forceOpenWorkspaceAsFile: openConfig.forceOpenWorkspaceAsFile }); + let pathsToOpen = []; + let parseOptions = { gotoLineMode: openConfig.cli && openConfig.cli.goto, forceOpenWorkspaceAsFile: openConfig.forceOpenWorkspaceAsFile }; + for (const pathToOpen of openConfig.urisToOpen) { + if (!pathToOpen) { + continue; + } - // Warn if the requested path to open does not exist - if (!path) { + const path = this.parseUri(pathToOpen, openConfig.forceOpenWorkspaceAsFile, parseOptions); + if (path) { + pathsToOpen.push(path); + } else { + // Warn about the invalid URI or path + + let message, detail; + if (pathToOpen.scheme === Schemas.file) { + message = localize('pathNotExistTitle', "Path does not exist"); + detail = localize('pathNotExistDetail', "The path '{0}' does not seem to exist anymore on disk.", pathToOpen.fsPath); + } else { + message = localize('uriInvalidTitle', "URI can not be opened"); + detail = localize('uriInvalidDetail', "The URI '{0}' is not valid and can not be opened.", pathToOpen.toString()); + } const options: Electron.MessageBoxOptions = { title: product.nameLong, type: 'info', buttons: [localize('ok', "OK")], - message: localize('pathNotExistTitle', "Path does not exist"), - detail: localize('pathNotExistDetail', "The path '{0}' does not seem to exist anymore on disk.", pathToOpen.scheme === Schemas.file ? pathToOpen.fsPath : pathToOpen.path), + message, + detail, noLink: true }; this.dialogs.showMessageBox(options, this.getFocusedWindow()); } - - return path; - }); - - // get rid of nulls - pathsToOpen = arrays.coalesce(pathsToOpen); - + } return pathsToOpen; } private doExtractPathsFromCLI(cli: ParsedArgs): IPath[] { const pathsToOpen = []; + const parseOptions = { ignoreFileNotFound: true, gotoLineMode: cli.goto }; // folder uris const folderUris = asArray(cli['folder-uri']); - if (folderUris.length) { - pathsToOpen.push(...arrays.coalesce(folderUris.map(candidate => this.parseUri(this.parseUriArg(candidate), false, { ignoreFileNotFound: true, gotoLineMode: cli.goto })))); + for (let folderUri of folderUris) { + const path = this.parseUri(this.argToUri(folderUri), false, parseOptions); + if (path) { + pathsToOpen.push(path); + } } // file uris const fileUris = asArray(cli['file-uri']); - if (fileUris.length) { - pathsToOpen.push(...arrays.coalesce(fileUris.map(candidate => this.parseUri(this.parseUriArg(candidate), true, { ignoreFileNotFound: true, gotoLineMode: cli.goto })))); + for (let fileUri of fileUris) { + const path = this.parseUri(this.argToUri(fileUri), true, parseOptions); + if (path) { + pathsToOpen.push(path); + } } // folder or file paths - if (cli._ && cli._.length) { - pathsToOpen.push(...arrays.coalesce(cli._.map(candidate => this.parsePath(candidate, { ignoreFileNotFound: true, gotoLineMode: cli.goto })))); + const cliArgs = asArray(cli._); + for (let cliArg of cliArgs) { + const path = this.parsePath(cliArg, parseOptions); + if (path) { + pathsToOpen.push(path); + } } - if (pathsToOpen.length > 0) { + if (pathsToOpen.length) { return pathsToOpen; } @@ -974,29 +995,34 @@ export class WindowsManager implements IWindowsMainService { return restoreWindows; } - private parseUriArg(arg: string): URI { - // Do not support if user has passed folder path on Windows - if (isWindows && /^([a-z])\:(.*)$/i.test(arg)) { - return null; + private argToUri(arg: string): URI { + try { + let uri = URI.parse(arg); + if (!uri.scheme) { + console.log(`Invalid URI string, scheme missing: ${arg}`); + return null; + } + return uri; + } catch (e) { + console.log(`Invalid URI string, scheme missing: ${e.message}`); } - return URI.parse(arg); + return null; } - private parseUri(anyUri: URI, isFile: boolean, options?: { ignoreFileNotFound?: boolean, gotoLineMode?: boolean, forceOpenWorkspaceAsFile?: boolean; }): IPathToOpen { - if (!anyUri || !anyUri.scheme) { + private parseUri(uri: URI, isFile: boolean, options?: { ignoreFileNotFound?: boolean, gotoLineMode?: boolean, forceOpenWorkspaceAsFile?: boolean; }): IPathToOpen { + if (!uri || !uri.scheme) { return null; } - - if (anyUri.scheme === Schemas.file) { - return this.parsePath(anyUri.fsPath, options); + if (uri.scheme === Schemas.file) { + return this.parsePath(uri.fsPath, options); } if (isFile) { return { - fileUri: anyUri + fileUri: uri }; } return { - folderUri: anyUri + folderUri: uri }; } @@ -1135,11 +1161,11 @@ export class WindowsManager implements IWindowsMainService { cliArgs = []; } - if (folderUris.length && folderUris.some(uri => !!findWindowOnWorkspaceOrFolderUri(WindowsManager.WINDOWS, this.parseUriArg(uri)))) { + if (folderUris.length && folderUris.some(uri => !!findWindowOnWorkspaceOrFolderUri(WindowsManager.WINDOWS, this.argToUri(uri)))) { folderUris = []; } - if (fileUris.length && fileUris.some(uri => !!findWindowOnWorkspaceOrFolderUri(WindowsManager.WINDOWS, this.parseUriArg(uri)))) { + if (fileUris.length && fileUris.some(uri => !!findWindowOnWorkspaceOrFolderUri(WindowsManager.WINDOWS, this.argToUri(uri)))) { fileUris = []; } diff --git a/src/vs/code/node/args.ts b/src/vs/code/node/args.ts index 8f1a5a9fc9c..feff5c5b405 100644 --- a/src/vs/code/node/args.ts +++ b/src/vs/code/node/args.ts @@ -6,7 +6,7 @@ 'use strict'; /** - * Converts an arument into to an array + * Converts an argument into an array * @param arg a argument value. Can be undefined, en entry or an array */ export function asArray(arg: T | T[] | undefined): T[] { @@ -17,4 +17,17 @@ export function asArray(arg: T | T[] | undefined): T[] { return [arg]; } return []; +} + +/** + * Returns whether an argument is present. + */ +export function hasArgs(arg: T | T[] | undefined): boolean { + if (arg) { + if (Array.isArray(arg)) { + return !!arg.length; + } + return true; + } + return false; } \ No newline at end of file diff --git a/src/vs/code/node/windowsFinder.ts b/src/vs/code/node/windowsFinder.ts index c4cc2e87c44..fa5fba59882 100644 --- a/src/vs/code/node/windowsFinder.ts +++ b/src/vs/code/node/windowsFinder.ts @@ -8,7 +8,7 @@ import * as platform from 'vs/base/common/platform'; import * as paths from 'vs/base/common/paths'; import { OpenContext } from 'vs/platform/windows/common/windows'; -import { IWorkspaceIdentifier, IResolvedWorkspace, ISingleFolderWorkspaceIdentifier, isSingleFolderWorkspaceIdentifier } from 'vs/platform/workspaces/common/workspaces'; +import { IWorkspaceIdentifier, IResolvedWorkspace, ISingleFolderWorkspaceIdentifier, isSingleFolderWorkspaceIdentifier, isWorkspaceIdentifier } from 'vs/platform/workspaces/common/workspaces'; import URI from 'vs/base/common/uri'; import { hasToIgnoreCase, isEqual, isEqualOrParent } from 'vs/base/common/resources'; @@ -70,51 +70,50 @@ export function getLastActiveWindow(windows: W[]): W { } export function findWindowOnWorkspace(windows: W[], workspace: (IWorkspaceIdentifier | ISingleFolderWorkspaceIdentifier)): W { - return windows.filter(window => { - - // match on folder - if (isSingleFolderWorkspaceIdentifier(workspace)) { - if (window.openedFolderUri && isEqual(window.openedFolderUri, workspace, hasToIgnoreCase(window.openedFolderUri))) { - return true; + if (isSingleFolderWorkspaceIdentifier(workspace)) { + for (const window of windows) { + // match on folder + if (isSingleFolderWorkspaceIdentifier(workspace)) { + if (window.openedFolderUri && isEqual(window.openedFolderUri, workspace, hasToIgnoreCase(window.openedFolderUri))) { + return window; + } } } - - // match on workspace - else { + } else if (isWorkspaceIdentifier(workspace)) { + for (const window of windows) { + // match on workspace if (window.openedWorkspace && window.openedWorkspace.id === workspace.id) { - return true; + return window; } } - - return false; - })[0]; + } + return null; } export function findWindowOnExtensionDevelopmentPath(windows: W[], extensionDevelopmentPath: string): W { - return windows.filter(window => { - + for (const window of windows) { // match on extension development path if (paths.isEqual(window.extensionDevelopmentPath, extensionDevelopmentPath, !platform.isLinux /* ignorecase */)) { - return true; + return window; } - - return false; - })[0]; + } + return null; } export function findWindowOnWorkspaceOrFolderUri(windows: W[], uri: URI): W { - return windows.filter(window => { - + if (!uri) { + return null; + } + for (const window of windows) { // check for workspace config path if (window.openedWorkspace && isEqual(URI.file(window.openedWorkspace.configPath), uri, !platform.isLinux /* ignorecase */)) { - return true; + return window; } // check for folder path if (window.openedFolderUri && isEqual(window.openedFolderUri, uri, hasToIgnoreCase(uri))) { - return true; + return window; } - - return false; - })[0]; + } + return null; } From ad6f6a66253002d7af138a8c4d34ba3affc8a5a3 Mon Sep 17 00:00:00 2001 From: Martin Aeschlimann Date: Thu, 9 Aug 2018 18:16:09 +0200 Subject: [PATCH 0636/1276] use regex to parse jumplist argument --- .../history/electron-main/historyMainService.ts | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/src/vs/platform/history/electron-main/historyMainService.ts b/src/vs/platform/history/electron-main/historyMainService.ts index 0d0ac885608..2ae5cf2041a 100644 --- a/src/vs/platform/history/electron-main/historyMainService.ts +++ b/src/vs/platform/history/electron-main/historyMainService.ts @@ -7,7 +7,6 @@ import * as nls from 'vs/nls'; import * as arrays from 'vs/base/common/arrays'; -import { trim, startsWith } from 'vs/base/common/strings'; import { IStateService } from 'vs/platform/state/common/state'; import { app } from 'electron'; import { ILogService } from 'vs/platform/log/common/log'; @@ -351,11 +350,14 @@ export class HistoryMainService implements IHistoryMainService { for (let item of app.getJumpListSettings().removedItems) { const args = item.args; if (args) { - if (startsWith(args, '--folderUri')) { - toRemove.push(URI.parse(args.substring(13, args.length - 1))); - } else { - let configPath = trim(args, '"'); - toRemove.push({ id: this.workspacesMainService.getWorkspaceId(configPath), configPath }); + const match = /^--folderUri\s+"([^"]+)"$/.exec(args); + if (match) { + if (args[0] === '-') { + toRemove.push(URI.parse(match[1])); + } else { + let configPath = match[1]; + toRemove.push({ id: this.workspacesMainService.getWorkspaceId(configPath), configPath }); + } } } } From afec727ae3d4af78437abe9219c2f1b6e15e732f Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Thu, 9 Aug 2018 09:24:27 -0700 Subject: [PATCH 0637/1276] Fix typos Fixes #56058 --- .../vscode-api-tests/src/singlefolder-tests/window.test.ts | 2 +- .../parts/terminal/electron-browser/terminalInstance.ts | 2 +- 2 files changed, 2 insertions(+), 2 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 27877a8608a..ab90746f65a 100644 --- a/extensions/vscode-api-tests/src/singlefolder-tests/window.test.ts +++ b/extensions/vscode-api-tests/src/singlefolder-tests/window.test.ts @@ -688,7 +688,7 @@ suite('window namespace tests', () => { const renderer = window.createTerminalRenderer('foo'); }); - test('Terminal.sendText should fire Termnial.onInput', (done) => { + test('Terminal.sendText should fire Terminal.onInput', (done) => { const reg1 = window.onDidOpenTerminal(terminal => { reg1.dispose(); const reg2 = renderer.onDidAcceptInput(data => { diff --git a/src/vs/workbench/parts/terminal/electron-browser/terminalInstance.ts b/src/vs/workbench/parts/terminal/electron-browser/terminalInstance.ts index 0b7ed17b6dc..04d9dcba251 100644 --- a/src/vs/workbench/parts/terminal/electron-browser/terminalInstance.ts +++ b/src/vs/workbench/parts/terminal/electron-browser/terminalInstance.ts @@ -482,7 +482,7 @@ export class TerminalInstance implements ITerminalInstance { label: nls.localize('yes', "Yes"), run: () => { this._configurationService.updateValue('terminal.integrated.rendererType', 'dom', ConfigurationTarget.USER).then(() => { - this._notificationService.info(nls.localize('terminal.rendererInAllNewTerminals', "The termnial is now using the fallback renderer.")); + this._notificationService.info(nls.localize('terminal.rendererInAllNewTerminals', "The terminal is now using the fallback renderer.")); }); } } as IPromptChoice, From 74de533cacc5d3f7981a20c2a7ba51a2045b1bcd Mon Sep 17 00:00:00 2001 From: Johannes Rieken Date: Thu, 9 Aug 2018 18:29:05 +0200 Subject: [PATCH 0638/1276] enable source map generation --- extensions/emmet/extension.webpack.config.js | 13 ++++++++-- extensions/git/extension.webpack.config.js | 15 ++++++++--- package.json | 1 + yarn.lock | 27 ++++++++++++++++++++ 4 files changed, 51 insertions(+), 5 deletions(-) diff --git a/extensions/emmet/extension.webpack.config.js b/extensions/emmet/extension.webpack.config.js index 5534ef2030b..752505a4108 100644 --- a/extensions/emmet/extension.webpack.config.js +++ b/extensions/emmet/extension.webpack.config.js @@ -8,8 +8,8 @@ const path = require('path'); module.exports = { - stats: 'errors-only', - // mode: 'none', // default is production + mode: 'production', + // mode: 'none', context: __dirname, target: 'node', resolve: { @@ -26,4 +26,13 @@ module.exports = { externals: { 'vscode': 'commonjs vscode', }, + stats: 'errors-only', + devtool: 'source-map', + module: { + rules: [{ + test: /\.js$/, + use: ["source-map-loader"], + enforce: "pre" + }] + } }; diff --git a/extensions/git/extension.webpack.config.js b/extensions/git/extension.webpack.config.js index d2c8a4eee95..2562c12140b 100644 --- a/extensions/git/extension.webpack.config.js +++ b/extensions/git/extension.webpack.config.js @@ -9,8 +9,8 @@ const path = require('path'); const CopyWebpackPlugin = require('copy-webpack-plugin'); module.exports = { - stats: 'errors-only', - // mode: 'none', // default is production + mode: 'production', + // mode: 'none', context: __dirname, target: 'node', node: { @@ -33,5 +33,14 @@ module.exports = { }, plugins: [ new CopyWebpackPlugin([{ from: './out/*.sh', to: '[name].sh' }]) - ] + ], + stats: 'errors-only', + devtool: 'source-map', + module: { + rules: [{ + test: /\.js$/, + use: ["source-map-loader"], + enforce: "pre" + }] + } }; diff --git a/package.json b/package.json index 38d58c1f361..8c84cfd3086 100644 --- a/package.json +++ b/package.json @@ -117,6 +117,7 @@ "rimraf": "^2.2.8", "sinon": "^1.17.2", "source-map": "^0.4.4", + "source-map-loader": "^0.2.3", "tslint": "^5.9.1", "typescript": "2.9.2", "typescript-formatter": "7.1.0", diff --git a/yarn.lock b/yarn.lock index 8b5ee32b9da..ed7f6ddf678 100644 --- a/yarn.lock +++ b/yarn.lock @@ -540,6 +540,12 @@ async@^2.0.1: dependencies: lodash "^4.14.0" +async@^2.5.0: + version "2.6.1" + resolved "https://registry.yarnpkg.com/async/-/async-2.6.1.tgz#b245a23ca71930044ec53fa46aa00a3e87c6a610" + dependencies: + lodash "^4.17.10" + async@~0.2.8: version "0.2.10" resolved "https://registry.yarnpkg.com/async/-/async-0.2.10.tgz#b6bbe0b0674b9d719708ca38de8c237cb526c3d1" @@ -4314,6 +4320,15 @@ loader-utils@^1.1.0: emojis-list "^2.0.0" json5 "^0.5.0" +loader-utils@~0.2.2: + version "0.2.17" + resolved "https://registry.yarnpkg.com/loader-utils/-/loader-utils-0.2.17.tgz#f86e6374d43205a6e6c60e9196f17c0299bfb348" + dependencies: + big.js "^3.1.3" + emojis-list "^2.0.0" + json5 "^0.5.0" + object-assign "^4.0.1" + locate-path@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-2.0.0.tgz#2b568b265eec944c6d9c0de9c3dbbbca0354cd8e" @@ -4556,6 +4571,10 @@ lodash@^4.0.0, lodash@^4.13.1, lodash@^4.14.0, lodash@^4.15.0, lodash@^4.3.0: version "4.17.4" resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.4.tgz#78203a4d1c328ae1d86dca6460e369b57f4055ae" +lodash@^4.17.10: + version "4.17.10" + resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.10.tgz#1b7793cf7259ea38fb3661d4d38b3260af8ae4e7" + lodash@~1.0.1: version "1.0.2" resolved "https://registry.yarnpkg.com/lodash/-/lodash-1.0.2.tgz#8f57560c83b59fc270bd3d561b690043430e2551" @@ -6841,6 +6860,14 @@ source-list-map@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/source-list-map/-/source-list-map-2.0.0.tgz#aaa47403f7b245a92fbc97ea08f250d6087ed085" +source-map-loader@^0.2.3: + version "0.2.3" + resolved "https://registry.yarnpkg.com/source-map-loader/-/source-map-loader-0.2.3.tgz#d4b0c8cd47d54edce3e6bfa0f523f452b5b0e521" + dependencies: + async "^2.5.0" + loader-utils "~0.2.2" + source-map "~0.6.1" + source-map-resolve@^0.3.0: version "0.3.1" resolved "https://registry.yarnpkg.com/source-map-resolve/-/source-map-resolve-0.3.1.tgz#610f6122a445b8dd51535a2a71b783dfc1248761" From 168d211810f7359e25286f5f69da552442b6dee3 Mon Sep 17 00:00:00 2001 From: Rob Lourens Date: Thu, 9 Aug 2018 10:12:33 -0700 Subject: [PATCH 0639/1276] Start removing TPromise.cancel from search - #55883 --- .../services/search/node/rawSearchService.ts | 31 +++++++++++-------- 1 file changed, 18 insertions(+), 13 deletions(-) diff --git a/src/vs/workbench/services/search/node/rawSearchService.ts b/src/vs/workbench/services/search/node/rawSearchService.ts index f2281f3d5c7..29e07c58247 100644 --- a/src/vs/workbench/services/search/node/rawSearchService.ts +++ b/src/vs/workbench/services/search/node/rawSearchService.ts @@ -21,6 +21,8 @@ import { Engine as TextSearchEngine } from 'vs/workbench/services/search/node/te import { TextSearchWorkerProvider } from 'vs/workbench/services/search/node/textSearchWorkerProvider'; import { IFileSearchProgressItem, IRawFileMatch, IRawSearch, IRawSearchService, ISearchEngine, ISerializedFileMatch, ISerializedSearchComplete, ISerializedSearchProgressItem, ITelemetryEvent, ISerializedSearchSuccess } from './search'; import { Event, Emitter } from 'vs/base/common/event'; +import { createCancelablePromise, CancelablePromise } from 'vs/base/common/async'; +import { CancellationToken } from 'vs/base/common/cancellation'; gracefulFs.gracefulify(fs); @@ -55,12 +57,14 @@ export class SearchService implements IRawSearchService { } public textSearch(config: IRawSearch): Event { - let promise: TPromise; + let promise: CancelablePromise; const emitter = new Emitter({ onFirstListenerDidAdd: () => { - promise = (config.useRipgrep ? this.ripgrepTextSearch(config, p => emitter.fire(p)) : this.legacyTextSearch(config, p => emitter.fire(p))) - .then(c => emitter.fire(c), err => emitter.fire({ type: 'error', error: { message: err.message, stack: err.stack } })); + promise = createCancelablePromise(token => { + return (config.useRipgrep ? this.ripgrepTextSearch(config, p => emitter.fire(p), token) : this.legacyTextSearch(config, p => emitter.fire(p), token)) + .then(c => emitter.fire(c), err => emitter.fire({ type: 'error', error: { message: err.message, stack: err.stack } })); + }); }, onLastListenerRemove: () => { promise.cancel(); @@ -70,11 +74,13 @@ export class SearchService implements IRawSearchService { return emitter.event; } - private ripgrepTextSearch(config: IRawSearch, progressCallback: IProgressCallback): TPromise { + private ripgrepTextSearch(config: IRawSearch, progressCallback: IProgressCallback, token: CancellationToken): Promise { config.maxFilesize = MAX_FILE_SIZE; let engine = new RipgrepEngine(config); - return new TPromise((c, e) => { + token.onCancellationRequested(() => engine.cancel()); + + return new Promise((c, e) => { // Use BatchedCollector to get new results to the frontend every 2s at least, until 50 results have been returned const collector = new BatchedCollector(SearchService.BATCH_SIZE, progressCallback); engine.search((match) => { @@ -90,12 +96,10 @@ export class SearchService implements IRawSearchService { c(stats); } }); - }, () => { - engine.cancel(); }); } - private legacyTextSearch(config: IRawSearch, progressCallback: IProgressCallback): TPromise { + private legacyTextSearch(config: IRawSearch, progressCallback: IProgressCallback, token: CancellationToken): Promise { if (!this.textSearchWorkerProvider) { this.textSearchWorkerProvider = new TextSearchWorkerProvider(); } @@ -113,7 +117,7 @@ export class SearchService implements IRawSearchService { }), this.textSearchWorkerProvider); - return this.doTextSearch(engine, progressCallback, SearchService.BATCH_SIZE); + return this.doTextSearch(engine, progressCallback, SearchService.BATCH_SIZE, token); } doFileSearch(EngineClass: { new(config: IRawSearch): ISearchEngine; }, config: IRawSearch, progressCallback: IProgressCallback, batchSize?: number): TPromise { @@ -241,6 +245,7 @@ export class SearchService implements IRawSearchService { const cached = this.getResultsFromCache(cache, config.filePattern, progressCallback); if (cached) { let chained: TPromise; + return new TPromise<[ISerializedSearchSuccess, IRawFileMatch[]]>((c, e) => { chained = cached.then(([result, results, cacheStats]) => { const cacheLookupResultTime = Date.now(); @@ -361,8 +366,10 @@ export class SearchService implements IRawSearchService { }); } - private doTextSearch(engine: TextSearchEngine, progressCallback: IProgressCallback, batchSize: number): TPromise { - return new TPromise((c, e) => { + private doTextSearch(engine: TextSearchEngine, progressCallback: IProgressCallback, batchSize: number, token: CancellationToken): Promise { + token.onCancellationRequested(() => engine.cancel()); + + return new Promise((c, e) => { // Use BatchedCollector to get new results to the frontend every 2s at least, until 50 results have been returned const collector = new BatchedCollector(batchSize, progressCallback); engine.search((matches) => { @@ -379,8 +386,6 @@ export class SearchService implements IRawSearchService { c(stats); } }); - }, () => { - engine.cancel(); }); } From f9b09ec42ae51bf9fa82c24d51dd75818615243a Mon Sep 17 00:00:00 2001 From: Jackson Kearl Date: Thu, 9 Aug 2018 11:51:55 -0700 Subject: [PATCH 0640/1276] Add validation to string and number settings --- src/vs/base/browser/ui/inputbox/inputBox.ts | 4 + .../parts/preferences/browser/settingsTree.ts | 11 +- .../preferences/common/preferences.ts | 1 + .../preferences/common/preferencesModels.ts | 106 ++++++++++++++++++ 4 files changed, 121 insertions(+), 1 deletion(-) diff --git a/src/vs/base/browser/ui/inputbox/inputBox.ts b/src/vs/base/browser/ui/inputbox/inputBox.ts index 1691821da48..80c6806e564 100644 --- a/src/vs/base/browser/ui/inputbox/inputBox.ts +++ b/src/vs/base/browser/ui/inputbox/inputBox.ts @@ -326,6 +326,10 @@ export class InputBox extends Widget { this.applyStyles(); } + public attachValidator(validator: IInputValidator) { + this.validation = validator; + } + public isInputValid(): boolean { return !!this.validation && !this.validation(this.value); } diff --git a/src/vs/workbench/parts/preferences/browser/settingsTree.ts b/src/vs/workbench/parts/preferences/browser/settingsTree.ts index eaa91fd368b..d524a735c61 100644 --- a/src/vs/workbench/parts/preferences/browser/settingsTree.ts +++ b/src/vs/workbench/parts/preferences/browser/settingsTree.ts @@ -9,7 +9,7 @@ import { StandardKeyboardEvent } from 'vs/base/browser/keyboardEvent'; import { IMouseEvent } from 'vs/base/browser/mouseEvent'; import { Button } from 'vs/base/browser/ui/button/button'; import { Checkbox } from 'vs/base/browser/ui/checkbox/checkbox'; -import { InputBox } from 'vs/base/browser/ui/inputbox/inputBox'; +import { InputBox, MessageType, IInputValidator } from 'vs/base/browser/ui/inputbox/inputBox'; import { SelectBox } from 'vs/base/browser/ui/selectBox/selectBox'; import * as arrays from 'vs/base/common/arrays'; import { Color, RGBA } from 'vs/base/common/color'; @@ -1157,6 +1157,7 @@ export class SettingsRenderer implements ITreeRenderer { private renderText(dataElement: SettingsTreeSettingElement, isSelected: boolean, template: ISettingTextItemTemplate, onChange: (value: string) => void): void { template.onChange = null; template.inputBox.value = dataElement.value; + template.inputBox.attachValidator(makeValidator(dataElement)); template.onChange = value => onChange(value); template.inputBox.inputElement.tabIndex = isSelected ? 0 : -1; @@ -1183,6 +1184,7 @@ export class SettingsRenderer implements ITreeRenderer { private renderNumber(dataElement: SettingsTreeSettingElement, isSelected: boolean, template: ISettingTextItemTemplate, onChange: (value: number) => void): void { template.onChange = null; template.inputBox.value = dataElement.value; + template.inputBox.attachValidator(makeValidator(dataElement)); template.onChange = value => onChange(parseFn(value)); template.inputBox.inputElement.tabIndex = isSelected ? 0 : -1; @@ -1223,6 +1225,13 @@ export class SettingsRenderer implements ITreeRenderer { } } +function makeValidator(dataElement: SettingsTreeSettingElement): IInputValidator | null { + return value => { + let message = dataElement.setting.validator(value).join(' '); + return message ? { content: dataElement.setting.validator(value).join(' '), type: MessageType.ERROR } : null; + }; +} + function cleanRenderedMarkdown(element: Node): void { for (let i = 0; i < element.childNodes.length; i++) { const child = element.childNodes.item(i); diff --git a/src/vs/workbench/services/preferences/common/preferences.ts b/src/vs/workbench/services/preferences/common/preferences.ts index 9718d8eaf1b..442538034bf 100644 --- a/src/vs/workbench/services/preferences/common/preferences.ts +++ b/src/vs/workbench/services/preferences/common/preferences.ts @@ -51,6 +51,7 @@ export interface ISetting { enum?: string[]; enumDescriptions?: string[]; tags?: string[]; + validator?: (value: string) => string[]; } export interface IExtensionSetting extends ISetting { diff --git a/src/vs/workbench/services/preferences/common/preferencesModels.ts b/src/vs/workbench/services/preferences/common/preferencesModels.ts index ac27d3ccf50..0a9aff78199 100644 --- a/src/vs/workbench/services/preferences/common/preferencesModels.ts +++ b/src/vs/workbench/services/preferences/common/preferencesModels.ts @@ -575,6 +575,7 @@ export class DefaultSettings extends Disposable { enumDescriptions: prop.enumDescriptions, tags: prop.tags, deprecationMessage: prop.deprecationMessage, + validator: createValidator(prop) }); } } @@ -950,6 +951,111 @@ class SettingsContentBuilder { } } +function createValidator(prop: IConfigurationPropertySchema): (value: string) => string[] { + let exclusiveMax: number | undefined; + let exclusiveMin: number | undefined; + + if (typeof prop.exclusiveMaximum === 'boolean') { + exclusiveMax = prop.exclusiveMaximum ? prop.maximum : undefined; + } else { + exclusiveMax = prop.exclusiveMaximum; + } + + if (typeof prop.exclusiveMinimum === 'boolean') { + exclusiveMin = prop.exclusiveMinimum ? prop.minimum : undefined; + } else { + exclusiveMin = prop.exclusiveMinimum; + } + + let patternRegex: RegExp | undefined; + if (typeof prop.pattern === 'string') { + patternRegex = new RegExp(prop.pattern); + } + + type Validator = { enabled: boolean, isValid: (value: T) => boolean; message: string }; + + let generalValidations: Validator[] = [ + { + enabled: prop.deprecationMessage !== undefined, + isValid: (value => false), + message: prop.deprecationMessage + } + ].filter(validation => validation.enabled); + + let numericValidations: Validator[] = [ + { + enabled: exclusiveMax !== undefined, + isValid: (value => value < exclusiveMax), + message: nls.localize('validations.exclusiveMax', "Value must be strictly less than {0}.", exclusiveMax) + }, + { + enabled: exclusiveMin !== undefined, + isValid: (value => value > exclusiveMin), + message: nls.localize('validations.exclusiveMin', "Value must be strictly greater than {0}.", exclusiveMin) + }, + + { + enabled: prop.maximum !== undefined && exclusiveMax === undefined, + isValid: (value => value <= prop.maximum), + message: nls.localize('validations.max', "Value must be less than or equal to {0}.", prop.maximum) + }, + { + enabled: prop.minimum !== undefined && exclusiveMin === undefined, + isValid: (value => value >= prop.minimum), + message: nls.localize('validations.min', "Value must be greater than or equal to {0}.", prop.minimum) + }, + + { + enabled: prop.multipleOf !== undefined, + isValid: (value => value % prop.multipleOf === 0), + message: nls.localize('validations.multipleOf', "Value must be a multiple of {0}.", prop.multipleOf) + }, + { + enabled: prop.type === 'integer', + isValid: (value => value % 1 === 0), + message: nls.localize('validations.expectedInteger', "Value must be an integer.") + }, + ].filter(validation => validation.enabled); + + let stringValidations: Validator[] = [ + { + enabled: prop.maxLength !== undefined, + isValid: (value => value.length <= prop.maxLength), + message: nls.localize('validations.maxLength', "Value must be fewer than {0} characters long.", prop.maxLength) + }, + { + enabled: prop.minLength !== undefined, + isValid: (value => value.length >= prop.minLength), + message: nls.localize('validations.minLength', "Value must be more than {0} characters long.", prop.minLength) + }, + { + enabled: patternRegex !== undefined, + isValid: (value => patternRegex.test(value)), + message: prop.patternErrorMessage || nls.localize('validations.regex', "Value must match regex `{0}`.", prop.pattern) + }, + ].filter(validation => validation.enabled); + + return value => { + let errors = []; + + errors.push(...generalValidations.filter(validator => !validator.isValid(value)).map(validator => validator.message)); + + if (prop.type === 'number' || prop.type === 'integer') { + if (value === '' || isNaN(+value)) { + errors.push(nls.localize('validations.expectedNumeric', "Value must be a number.")); + } else { + errors.push(...numericValidations.filter(validator => !validator.isValid(+value)).map(validator => validator.message)); + } + } + + if (prop.type === 'string') { + errors.push(...stringValidations.filter(validator => !validator.isValid(value)).map(validator => validator.message)); + } + + return errors; + }; +} + function escapeInvisibleChars(enumValue: string): string { return enumValue && enumValue .replace(/\n/g, '\\n') From e3e972589db57a16da6426828706ced9c2d52848 Mon Sep 17 00:00:00 2001 From: rebornix Date: Thu, 9 Aug 2018 15:43:56 -0700 Subject: [PATCH 0641/1276] Fix microsoft/vscode-pull-request-github#149. Ctrl+Enter to submit the comment. --- .../comments/electron-browser/commentThreadWidget.ts | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/vs/workbench/parts/comments/electron-browser/commentThreadWidget.ts b/src/vs/workbench/parts/comments/electron-browser/commentThreadWidget.ts index 80acb6b6adc..e859e123b94 100644 --- a/src/vs/workbench/parts/comments/electron-browser/commentThreadWidget.ts +++ b/src/vs/workbench/parts/comments/electron-browser/commentThreadWidget.ts @@ -366,6 +366,11 @@ export class ReviewZoneWidget extends ZoneWidget { this.dispose(); } } + + if (this._commentEditor.getModel().getValueLength() !== 0 && ev.keyCode === KeyCode.Enter && ev.ctrlKey) { + let lineNumber = this._commentGlyph.getPosition().position.lineNumber; + this.createComment(lineNumber); + } })); this._error = $('.validation-error.hidden').appendTo(this._commentForm).getHTMLElement(); @@ -386,6 +391,7 @@ export class ReviewZoneWidget extends ZoneWidget { })); button.onDidClick(async () => { + let lineNumber = this._commentGlyph.getPosition().position.lineNumber; this.createComment(lineNumber); }); @@ -501,7 +507,7 @@ export class ReviewZoneWidget extends ZoneWidget { if (model) { let valueLength = model.getValueLength(); const hasExistingComments = this._commentThread.comments.length > 0; - let placeholder = valueLength > 0 ? '' : (hasExistingComments ? 'Reply...' : 'Type a new comment'); + let placeholder = valueLength > 0 ? '' : (hasExistingComments ? 'Reply... (press Ctrl+Enter to submit)' : 'Type a new comment (press Ctrl+Enter to submit)'); const decorations = [{ range: { startLineNumber: 0, From 9a30e3e68b1fff49f612d0aac90859b97795aba0 Mon Sep 17 00:00:00 2001 From: Rob Lourens Date: Thu, 9 Aug 2018 17:34:00 -0700 Subject: [PATCH 0642/1276] Fix #55616 - render 'filters' the same as search. And clean up and fix lots of filter + search + TOC filter issues --- .../electron-browser/main.contribution.ts | 6 ++- .../preferences/browser/settingsEditor2.ts | 46 +++++++++++++++---- .../parts/preferences/browser/settingsTree.ts | 44 ++++++++++++------ .../parts/preferences/browser/tocTree.ts | 23 +++------- 4 files changed, 77 insertions(+), 42 deletions(-) diff --git a/src/vs/workbench/electron-browser/main.contribution.ts b/src/vs/workbench/electron-browser/main.contribution.ts index c8a4525a481..5977d01baa4 100644 --- a/src/vs/workbench/electron-browser/main.contribution.ts +++ b/src/vs/workbench/electron-browser/main.contribution.ts @@ -635,7 +635,11 @@ configurationRegistry.registerConfiguration({ }, 'workbench.settings.settingsSearchTocBehavior': { 'type': 'string', - 'enum': ['hide', 'filter', 'show'], + 'enum': ['hide', 'filter'], + 'enumDescriptions': [ + nls.localize('settingsSearchTocBehavior.hide', "Hide the Table of Contents while searching."), + nls.localize('settingsSearchTocBehavior.filter', "Filter the Table of Contents to just categories that have matching settings. Clicking a category will filter the results to that category."), + ], 'description': nls.localize('settingsSearchTocBehavior', "Controls the behavior of the settings editor Table of Contents while searching."), 'default': 'filter', 'scope': ConfigurationScope.WINDOW diff --git a/src/vs/workbench/parts/preferences/browser/settingsEditor2.ts b/src/vs/workbench/parts/preferences/browser/settingsEditor2.ts index 4f94c79cb9e..d4f1f3f0ff6 100644 --- a/src/vs/workbench/parts/preferences/browser/settingsEditor2.ts +++ b/src/vs/workbench/parts/preferences/browser/settingsEditor2.ts @@ -302,12 +302,6 @@ export class SettingsEditor2 extends BaseEditor { this.settingsTree.reveal(lastElement, 0.9); return true; } - } else { - const controls = this.settingsTree.getHTMLElement().querySelectorAll(SettingsRenderer.CONTROL_SELECTOR); - const lastControl = controls && controls[controls.length]; - if (lastControl) { - (lastControl).focus(); - } } return false; @@ -336,7 +330,7 @@ export class SettingsEditor2 extends BaseEditor { } private createTOC(parent: HTMLElement): void { - this.tocTreeModel = new TOCTreeModel(); + this.tocTreeModel = new TOCTreeModel(this.viewState); this.tocTreeContainer = DOM.append(parent, $('.settings-toc-container')); const tocRenderer = this.instantiationService.createInstance(TOCRenderer); @@ -673,22 +667,54 @@ export class SettingsEditor2 extends BaseEditor { this.searchInProgress = null; }); } else { + if (this.viewState.tagFilters && this.viewState.tagFilters.size) { + this.searchResultModel = this.createFilterModel(); + } else { + this.searchResultModel = null; + } + this.localSearchDelayer.cancel(); this.remoteSearchThrottle.cancel(); if (this.searchInProgress && this.searchInProgress.cancel) { this.searchInProgress.cancel(); } - this.searchResultModel = null; - this.tocTreeModel.currentSearchModel = null; this.viewState.filterToCategory = null; + this.tocTreeModel.currentSearchModel = this.searchResultModel; this.tocTree.refresh(); this.toggleSearchMode(); collapseAll(this.tocTree); - return this.settingsTree.setInput(this.settingsTreeModel.root); + + if (this.searchResultModel) { + return this.settingsTree.setInput(this.searchResultModel); + } else { + return this.settingsTree.setInput(this.settingsTreeModel.root); + } } } + /** + * Return a fake SearchResultModel which can hold a flat list of all settings, to be filtered (@modified etc) + */ + private createFilterModel(): SearchResultModel { + const filterModel = this.instantiationService.createInstance(SearchResultModel, this.viewState); + + const fullResult: ISearchResult = { + filterMatches: [] + }; + for (let g of this.defaultSettingsEditorModel.settingsGroups.slice(1)) { + for (let sect of g.sections) { + for (let setting of sect.settings) { + fullResult.filterMatches.push({ setting, matches: [], score: 0 }); + } + } + } + + filterModel.setResult(0, fullResult); + + return filterModel; + } + private reportFilteringUsed(query: string, results: ISearchResult[]): void { const nlpResult = results[SearchResultIdx.Remote]; const nlpMetadata = nlpResult && nlpResult.metadata; diff --git a/src/vs/workbench/parts/preferences/browser/settingsTree.ts b/src/vs/workbench/parts/preferences/browser/settingsTree.ts index 59737f81ccb..e80e6151dc8 100644 --- a/src/vs/workbench/parts/preferences/browser/settingsTree.ts +++ b/src/vs/workbench/parts/preferences/browser/settingsTree.ts @@ -52,6 +52,7 @@ export abstract class SettingsTreeElement { export class SettingsTreeGroupElement extends SettingsTreeElement { children: (SettingsTreeGroupElement | SettingsTreeSettingElement)[]; + count?: number; label: string; level: number; isFirstGroup: boolean; @@ -91,6 +92,22 @@ export class SettingsTreeSettingElement extends SettingsTreeElement { overriddenScopeList: string[]; description: string; valueType: 'enum' | 'string' | 'integer' | 'number' | 'boolean' | 'exclude' | 'complex'; + + matchesAllTags(tagFilters?: Set): boolean { + if (!tagFilters || !tagFilters.size) { + return true; + } + + if (this.tags) { + let hasFilteredTag = true; + tagFilters.forEach(tag => { + hasFilteredTag = hasFilteredTag && this.tags.has(tag); + }); + return hasFilteredTag; + } else { + return false; + } + } } export interface ITOCEntry { @@ -174,7 +191,7 @@ function sanitizeId(id: string): string { return id.replace(/[\.\/]/, '_'); } -function createSettingsTreeSettingElement(setting: ISetting, parent: any, settingsTarget: SettingsTarget, configurationService: IConfigurationService): SettingsTreeSettingElement { +function createSettingsTreeSettingElement(setting: ISetting, parent: SearchResultModel | SettingsTreeGroupElement, settingsTarget: SettingsTarget, configurationService: IConfigurationService): SettingsTreeSettingElement { const element = new SettingsTreeSettingElement(); element.id = sanitizeId(parent.id + '_' + setting.key); element.parent = parent; @@ -1287,25 +1304,22 @@ export class SettingsTreeFilter implements IFilter { ) { } isVisible(tree: ITree, element: SettingsTreeElement): boolean { + // Filter during search if (this.viewState.filterToCategory && element instanceof SettingsTreeSettingElement) { if (!this.settingContainedInGroup(element.setting, this.viewState.filterToCategory)) { return false; } } - if (element instanceof SettingsTreeSettingElement && this.viewState.tagFilters && this.viewState.tagFilters.size) { - if (element.tags) { - let hasFilteredTag = true; - this.viewState.tagFilters.forEach(tag => { - hasFilteredTag = hasFilteredTag && element.tags.has(tag); - }); - return hasFilteredTag; - } else { - return false; - } + if (element instanceof SettingsTreeSettingElement && this.viewState.tagFilters) { + return element.matchesAllTags(this.viewState.tagFilters); } - if (element instanceof SettingsTreeGroupElement && this.viewState.tagFilters && this.viewState.tagFilters.size) { + if (element instanceof SettingsTreeGroupElement) { + if (typeof element.count === 'number') { + return element.count > 0; + } + return element.children.some(child => this.isVisible(tree, child)); } @@ -1419,15 +1433,15 @@ export class SearchResultModel { return this.rawSearchResults; } - setResult(type: SearchResultIdx, result: ISearchResult): void { + setResult(order: SearchResultIdx, result: ISearchResult): void { this.cachedUniqueSearchResults = null; this.rawSearchResults = this.rawSearchResults || []; if (!result) { - delete this.rawSearchResults[type]; + delete this.rawSearchResults[order]; return; } - this.rawSearchResults[type] = result; + this.rawSearchResults[order] = result; this.updateChildren(); } diff --git a/src/vs/workbench/parts/preferences/browser/tocTree.ts b/src/vs/workbench/parts/preferences/browser/tocTree.ts index 1b71bcdb72b..f70ad30dc4a 100644 --- a/src/vs/workbench/parts/preferences/browser/tocTree.ts +++ b/src/vs/workbench/parts/preferences/browser/tocTree.ts @@ -25,6 +25,10 @@ export class TOCTreeModel { private _currentSearchModel: SearchResultModel; private _settingsTreeRoot: SettingsTreeGroupElement; + constructor(private viewState: ISettingsEditorViewState) { + + } + public set settingsTreeRoot(value: SettingsTreeGroupElement) { this._settingsTreeRoot = value; this.update(); @@ -44,7 +48,7 @@ export class TOCTreeModel { } private updateGroupCount(group: SettingsTreeGroupElement): void { - (group).count = this._currentSearchModel ? + group.count = this._currentSearchModel ? this.getSearchResultChildrenCount(group) : undefined; @@ -64,7 +68,7 @@ export class TOCTreeModel { private groupContainsSetting(group: SettingsTreeGroupElement, setting: ISetting): boolean { return group.children.some(child => { if (child instanceof SettingsTreeSettingElement) { - return child.setting.key === setting.key; + return child.setting.key === setting.key && child.matchesAllTags(this.viewState.tagFilters); } else if (child instanceof SettingsTreeGroupElement) { return this.groupContainsSetting(child, setting); } else { @@ -77,11 +81,6 @@ export class TOCTreeModel { export type TOCTreeElement = SettingsTreeGroupElement | TOCTreeModel; export class TOCDataSource implements IDataSource { - constructor( - @IConfigurationService private configService: IConfigurationService - ) { - } - getId(tree: ITree, element: SettingsTreeGroupElement): string { return element.id; } @@ -96,14 +95,6 @@ export class TOCDataSource implements IDataSource { } private _getChildren(element: TOCTreeElement): SettingsTreeElement[] { - // TODO@roblou hack. Clean up or remove this option - if (this.configService.getValue('workbench.settings.settingsSearchTocBehavior') === 'filter') { - const children = element.children as SettingsTreeElement[]; // TS???? - return children.filter(group => { - return (group).count !== 0; - }); - } - return element.children; } @@ -136,7 +127,7 @@ export class TOCRenderer implements IRenderer { } renderElement(tree: ITree, element: SettingsTreeGroupElement, templateId: string, template: ITOCEntryTemplate): void { - const count = (element).count; + const count = element.count; const label = element.label; DOM.toggleClass(template.labelElement, 'no-results', count === 0); From 86a8c6fe02798b7ee1146bdd92e9d3b91b3e9b82 Mon Sep 17 00:00:00 2001 From: Jackson Kearl Date: Thu, 9 Aug 2018 17:35:42 -0700 Subject: [PATCH 0643/1276] Add deprecation warnings below item. Initial messageBox implementation --- .../browser/media/settingsEditor2.css | 3 +++ .../parts/preferences/browser/settingsTree.ts | 20 ++++++++++++++++--- .../preferences/common/preferences.ts | 2 +- .../preferences/common/preferencesModels.ts | 20 ++++++------------- 4 files changed, 27 insertions(+), 18 deletions(-) diff --git a/src/vs/workbench/parts/preferences/browser/media/settingsEditor2.css b/src/vs/workbench/parts/preferences/browser/media/settingsEditor2.css index 19651c22713..1eef4797e27 100644 --- a/src/vs/workbench/parts/preferences/browser/media/settingsEditor2.css +++ b/src/vs/workbench/parts/preferences/browser/media/settingsEditor2.css @@ -262,6 +262,7 @@ opacity: 0.9; } +.settings-editor > .settings-body > .settings-tree-container .setting-item .setting-item-validation-message, .settings-editor > .settings-body > .settings-tree-container .setting-item .setting-item-description { margin-top: 3px; overflow: hidden; @@ -306,6 +307,8 @@ } .settings-editor > .settings-body > .settings-tree-container .setting-item.is-expanded .setting-item-description, +.settings-editor > .settings-body > .settings-tree-container .setting-item.is-expanded .setting-item-validation-message, +.settings-editor > .settings-body > .settings-tree-container .setting-item.setting-measure-helper .setting-item-validation-message, .settings-editor > .settings-body > .settings-tree-container .setting-item.setting-measure-helper .setting-item-description { height: initial; -webkit-line-clamp: initial; diff --git a/src/vs/workbench/parts/preferences/browser/settingsTree.ts b/src/vs/workbench/parts/preferences/browser/settingsTree.ts index d524a735c61..f411653b829 100644 --- a/src/vs/workbench/parts/preferences/browser/settingsTree.ts +++ b/src/vs/workbench/parts/preferences/browser/settingsTree.ts @@ -31,7 +31,7 @@ import { IContextViewService } from 'vs/platform/contextview/browser/contextView import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; import { IListService, WorkbenchTree, WorkbenchTreeController } from 'vs/platform/list/browser/listService'; import { IOpenerService } from 'vs/platform/opener/common/opener'; -import { editorBackground, focusBorder, foreground } from 'vs/platform/theme/common/colorRegistry'; +import { editorBackground, focusBorder, foreground, errorForeground } from 'vs/platform/theme/common/colorRegistry'; import { attachButtonStyler, attachInputBoxStyler, attachSelectBoxStyler, attachStyler } from 'vs/platform/theme/common/styler'; import { ICssStyleCollector, ITheme, IThemeService, registerThemingParticipant } from 'vs/platform/theme/common/themeService'; import { SettingsTarget } from 'vs/workbench/parts/preferences/browser/preferencesWidgets'; @@ -474,6 +474,7 @@ interface ISettingItemTemplate extends IDisposableTemplate { labelElement: HTMLElement; descriptionElement: HTMLElement; controlElement: HTMLElement; + deprecationWarningElement: HTMLElement; isConfiguredElement: HTMLElement; otherOverridesElement: HTMLElement; } @@ -714,6 +715,8 @@ export class SettingsRenderer implements ITreeRenderer { const valueElement = DOM.append(container, $('.setting-item-value')); const controlElement = DOM.append(valueElement, $('div.setting-item-control')); + const deprecationWarningElement = DOM.append(container, $('.setting-item-validation-message')); + const toDispose = []; const template: ISettingItemTemplate = { toDispose, @@ -723,6 +726,7 @@ export class SettingsRenderer implements ITreeRenderer { labelElement, descriptionElement, controlElement, + deprecationWarningElement, isConfiguredElement, otherOverridesElement }; @@ -806,6 +810,8 @@ export class SettingsRenderer implements ITreeRenderer { const controlElement = DOM.append(descriptionAndValueElement, $('.setting-item-bool-control')); const descriptionElement = DOM.append(descriptionAndValueElement, $('.setting-item-description')); + const deprecationWarningElement = DOM.append(container, $('.setting-item-validation-message')); + const toDispose = []; const checkbox = new Checkbox({ actionClassName: 'setting-value-checkbox', isChecked: true, title: '', inputActiveOptionBorder: null }); controlElement.appendChild(checkbox.domNode); @@ -825,6 +831,7 @@ export class SettingsRenderer implements ITreeRenderer { controlElement, checkbox, descriptionElement, + deprecationWarningElement, isConfiguredElement, otherOverridesElement }; @@ -1068,6 +1075,7 @@ export class SettingsRenderer implements ITreeRenderer { private renderValue(element: SettingsTreeSettingElement, isSelected: boolean, templateId: string, template: ISettingItemTemplate | ISettingBoolItemTemplate): IValueRenderResult { const onChange = value => this._onDidChangeSetting.fire({ key: element.setting.key, value }); + template.deprecationWarningElement.innerText = element.setting.deprecationMessage || ''; if (templateId === SETTINGS_ENUM_TEMPLATE_ID) { return this.renderEnum(element, isSelected, template, onChange); @@ -1158,6 +1166,7 @@ export class SettingsRenderer implements ITreeRenderer { template.onChange = null; template.inputBox.value = dataElement.value; template.inputBox.attachValidator(makeValidator(dataElement)); + template.inputBox.validate(); // for some reason this is needed on text but not number. TODO: figure out why template.onChange = value => onChange(value); template.inputBox.inputElement.tabIndex = isSelected ? 0 : -1; @@ -1227,8 +1236,8 @@ export class SettingsRenderer implements ITreeRenderer { function makeValidator(dataElement: SettingsTreeSettingElement): IInputValidator | null { return value => { - let message = dataElement.setting.validator(value).join(' '); - return message ? { content: dataElement.setting.validator(value).join(' '), type: MessageType.ERROR } : null; + let message = dataElement.setting.validator(value); + return message ? { content: message, type: MessageType.ERROR } : null; }; } @@ -1526,6 +1535,11 @@ export class SettingsTree extends NonExpandableTree { collector.addRule(`.settings-editor > .settings-body > .settings-tree-container .setting-item .setting-item-description { color: ${fgWithOpacity}; }`); } + const errorColor = theme.getColor(errorForeground); + if (errorColor) { + collector.addRule(`.settings-editor > .settings-body > .settings-tree-container .setting-item .setting-item-validation-message { color: ${errorColor}; }`); + } + const headerForegroundColor = theme.getColor(settingsHeaderForeground); if (headerForegroundColor) { collector.addRule(`.settings-editor > .settings-body > .settings-tree-container .settings-group-title-label { color: ${headerForegroundColor} };`); diff --git a/src/vs/workbench/services/preferences/common/preferences.ts b/src/vs/workbench/services/preferences/common/preferences.ts index 442538034bf..081c5c193a9 100644 --- a/src/vs/workbench/services/preferences/common/preferences.ts +++ b/src/vs/workbench/services/preferences/common/preferences.ts @@ -51,7 +51,7 @@ export interface ISetting { enum?: string[]; enumDescriptions?: string[]; tags?: string[]; - validator?: (value: string) => string[]; + validator?: (value: any) => string; } export interface IExtensionSetting extends ISetting { diff --git a/src/vs/workbench/services/preferences/common/preferencesModels.ts b/src/vs/workbench/services/preferences/common/preferencesModels.ts index 0a9aff78199..5edc9e93b07 100644 --- a/src/vs/workbench/services/preferences/common/preferencesModels.ts +++ b/src/vs/workbench/services/preferences/common/preferencesModels.ts @@ -951,7 +951,7 @@ class SettingsContentBuilder { } } -function createValidator(prop: IConfigurationPropertySchema): (value: string) => string[] { +function createValidator(prop: IConfigurationPropertySchema): (value: any) => string { let exclusiveMax: number | undefined; let exclusiveMin: number | undefined; @@ -974,14 +974,6 @@ function createValidator(prop: IConfigurationPropertySchema): (value: string) => type Validator = { enabled: boolean, isValid: (value: T) => boolean; message: string }; - let generalValidations: Validator[] = [ - { - enabled: prop.deprecationMessage !== undefined, - isValid: (value => false), - message: prop.deprecationMessage - } - ].filter(validation => validation.enabled); - let numericValidations: Validator[] = [ { enabled: exclusiveMax !== undefined, @@ -1038,8 +1030,6 @@ function createValidator(prop: IConfigurationPropertySchema): (value: string) => return value => { let errors = []; - errors.push(...generalValidations.filter(validator => !validator.isValid(value)).map(validator => validator.message)); - if (prop.type === 'number' || prop.type === 'integer') { if (value === '' || isNaN(+value)) { errors.push(nls.localize('validations.expectedNumeric', "Value must be a number.")); @@ -1049,10 +1039,12 @@ function createValidator(prop: IConfigurationPropertySchema): (value: string) => } if (prop.type === 'string') { - errors.push(...stringValidations.filter(validator => !validator.isValid(value)).map(validator => validator.message)); + errors.push(...stringValidations.filter(validator => !validator.isValid('' + value)).map(validator => validator.message)); } - - return errors; + if (errors.length) { + return errors.join(' '); + } + return ''; }; } From 36f8b1f39b2fdcf4013c3f0bd0a33be0862fe5ed Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Thu, 9 Aug 2018 17:51:05 -0700 Subject: [PATCH 0644/1276] vscode-xterm@3.7.0-beta4 Fixes #56105 --- package.json | 2 +- yarn.lock | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/package.json b/package.json index 11eeb0c2ecd..dc4802d58e3 100644 --- a/package.json +++ b/package.json @@ -50,7 +50,7 @@ "vscode-nsfw": "1.0.17", "vscode-ripgrep": "^1.0.1", "vscode-textmate": "^4.0.1", - "vscode-xterm": "3.7.0-beta3", + "vscode-xterm": "3.7.0-beta4", "winreg": "^1.2.4", "yauzl": "^2.9.1" }, diff --git a/yarn.lock b/yarn.lock index 9cb248b5d3f..a3d62b2ae38 100644 --- a/yarn.lock +++ b/yarn.lock @@ -6125,9 +6125,9 @@ vscode-textmate@^4.0.1: dependencies: oniguruma "^7.0.0" -vscode-xterm@3.7.0-beta3: - version "3.7.0-beta3" - resolved "https://registry.yarnpkg.com/vscode-xterm/-/vscode-xterm-3.7.0-beta3.tgz#2306f9650ee2f55637ba1804d10c5ffb9ef944f6" +vscode-xterm@3.7.0-beta4: + version "3.7.0-beta4" + resolved "https://registry.yarnpkg.com/vscode-xterm/-/vscode-xterm-3.7.0-beta4.tgz#f980d66f94f09ae80e100715dae60715dcae1ac6" vso-node-api@^6.1.2-preview: version "6.1.2-preview" From ffcfd5797a2cedb10eec296c375e12f643c17c92 Mon Sep 17 00:00:00 2001 From: kieferrm Date: Thu, 9 Aug 2018 18:09:00 -0700 Subject: [PATCH 0645/1276] change distro --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index dc4802d58e3..71487dd58a3 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "code-oss-dev", "version": "1.27.0", - "distro": "73cb7173636931afba8d741be343ceafb11a177e", + "distro": "a4155d9780fbbc94ead6cb3017dd0fc3806c57b8", "author": { "name": "Microsoft Corporation" }, From b53fa1635cb3f5b196cc42a996acda5d7527ee84 Mon Sep 17 00:00:00 2001 From: Rob Lourens Date: Thu, 9 Aug 2018 18:20:56 -0700 Subject: [PATCH 0646/1276] FIx #56118 - setting highlights in high contrast mode --- .../browser/media/settingsEditor2.css | 11 +--- .../preferences/browser/settingsLayout.ts | 2 +- .../parts/preferences/browser/settingsTree.ts | 50 +++++++++++++++++++ 3 files changed, 53 insertions(+), 10 deletions(-) diff --git a/src/vs/workbench/parts/preferences/browser/media/settingsEditor2.css b/src/vs/workbench/parts/preferences/browser/media/settingsEditor2.css index 30a6e934f54..081112d78cd 100644 --- a/src/vs/workbench/parts/preferences/browser/media/settingsEditor2.css +++ b/src/vs/workbench/parts/preferences/browser/media/settingsEditor2.css @@ -109,14 +109,6 @@ background-size: 16px; } -.vs .settings-editor > .settings-header > .settings-header-controls .settings-header-controls-right .toolbar-toggle-more { - background-image: url('ellipsis.svg'); -} - -.vs-dark .settings-editor > .settings-header > .settings-header-controls .settings-header-controls-right .toolbar-toggle-more { - background-image: url('ellipsis-inverse.svg'); -} - .settings-editor > .settings-header > .settings-header-controls .settings-tabs-widget > .monaco-action-bar .action-item { padding: 0px; /* padding must be on action-label because it has the bottom-border, because that's where the .checked class is */ } @@ -327,7 +319,8 @@ background: url('check.svg') center center no-repeat; } -.vs-dark .settings-editor > .settings-body > .settings-tree-container .setting-item-bool .setting-value-checkbox.checked { +.vs-dark .settings-editor > .settings-body > .settings-tree-container .setting-item-bool .setting-value-checkbox.checked, +.hc-black .settings-editor > .settings-body > .settings-tree-container .setting-item-bool .setting-value-checkbox.checked { background: url('check-inverse.svg') center center no-repeat; } diff --git a/src/vs/workbench/parts/preferences/browser/settingsLayout.ts b/src/vs/workbench/parts/preferences/browser/settingsLayout.ts index ef3cccf1611..475293ecc85 100644 --- a/src/vs/workbench/parts/preferences/browser/settingsLayout.ts +++ b/src/vs/workbench/parts/preferences/browser/settingsLayout.ts @@ -45,7 +45,7 @@ export const tocData: ITOCEntry = { }, { id: 'editor/format', - label: localize('format', "Format"), + label: localize('formatting', "Formatting"), settings: ['editor.format*'] }, { diff --git a/src/vs/workbench/parts/preferences/browser/settingsTree.ts b/src/vs/workbench/parts/preferences/browser/settingsTree.ts index e80e6151dc8..81668c95167 100644 --- a/src/vs/workbench/parts/preferences/browser/settingsTree.ts +++ b/src/vs/workbench/parts/preferences/browser/settingsTree.ts @@ -1496,6 +1496,54 @@ class NonExpandableOrSelectableTree extends Tree { public focusPrevious(count?: number, eventPayload?: any): void { return; } + + public focusParent(eventPayload?: any): void { + return; + } + + public focusFirstChild(eventPayload?: any): void { + return; + } + + public focusFirst(eventPayload?: any, from?: any): void { + return; + } + + public focusNth(index: number, eventPayload?: any): void { + return; + } + + public focusLast(eventPayload?: any, from?: any): void { + return; + } + + public focusNextPage(eventPayload?: any): void { + return; + } + + public focusPreviousPage(eventPayload?: any): void { + return; + } + + public select(element: any, eventPayload?: any): void { + return; + } + + public selectRange(fromElement: any, toElement: any, eventPayload?: any): void { + return; + } + + public selectAll(elements: any[], eventPayload?: any): void { + return; + } + + public setSelection(elements: any[], eventPayload?: any): void { + return; + } + + public toggleSelection(element: any, eventPayload?: any): void { + return; + } } export class SettingsTree extends NonExpandableOrSelectableTree { @@ -1570,6 +1618,8 @@ export class SettingsTree extends NonExpandableOrSelectableTree { listFocusForeground: foreground, listHoverForeground: foreground, listHoverBackground: editorBackground, + listHoverOutline: editorBackground, + listFocusOutline: editorBackground, listInactiveSelectionBackground: editorBackground, listInactiveSelectionForeground: foreground }, colors => { From a52bdd956e332a8d0a8c3c9d6ed6e702f7ef3f28 Mon Sep 17 00:00:00 2001 From: SteVen Batten Date: Thu, 9 Aug 2018 18:34:48 -0700 Subject: [PATCH 0647/1276] fixes #56116 repair ipc for native menubar keybindings --- src/vs/workbench/electron-browser/window.ts | 43 +++++++++++++++++++++ 1 file changed, 43 insertions(+) diff --git a/src/vs/workbench/electron-browser/window.ts b/src/vs/workbench/electron-browser/window.ts index b6b6953d245..f46b093c862 100644 --- a/src/vs/workbench/electron-browser/window.ts +++ b/src/vs/workbench/electron-browser/window.ts @@ -9,6 +9,7 @@ import * as nls from 'vs/nls'; import URI from 'vs/base/common/uri'; import * as errors from 'vs/base/common/errors'; import { TPromise } from 'vs/base/common/winjs.base'; +import * as arrays from 'vs/base/common/arrays'; import * as objects from 'vs/base/common/objects'; import * as DOM from 'vs/base/browser/dom'; import { Separator } from 'vs/base/browser/ui/actionbar/actionbar'; @@ -41,6 +42,8 @@ import { AccessibilitySupport, isRootUser, isWindows, isMacintosh } from 'vs/bas import product from 'vs/platform/node/product'; import { INotificationService } from 'vs/platform/notification/common/notification'; import { EditorServiceImpl } from 'vs/workbench/browser/parts/editor/editor'; +import { IExtensionService } from 'vs/workbench/services/extensions/common/extensions'; +import { IKeybindingService } from 'vs/platform/keybinding/common/keybinding'; const TextInputActions: IAction[] = [ new Action('undo', nls.localize('undo', "Undo"), null, true, () => document.execCommand('undo') && TPromise.as(true)), @@ -74,7 +77,9 @@ export class ElectronWindow extends Themable { @IWorkbenchThemeService protected themeService: IWorkbenchThemeService, @INotificationService private notificationService: INotificationService, @ICommandService private commandService: ICommandService, + @IExtensionService private extensionService: IExtensionService, @IContextMenuService private contextMenuService: IContextMenuService, + @IKeybindingService private keybindingService: IKeybindingService, @ITelemetryService private telemetryService: ITelemetryService, @IWorkspaceEditingService private workspaceEditingService: IWorkspaceEditingService, @IFileService private fileService: IFileService, @@ -136,6 +141,22 @@ export class ElectronWindow extends Themable { }); }); + // Support resolve keybindings event + ipc.on('vscode:resolveKeybindings', (event: any, rawActionIds: string) => { + let actionIds: string[] = []; + try { + actionIds = JSON.parse(rawActionIds); + } catch (error) { + // should not happen + } + // Resolve keys using the keybinding service and send back to browser process + this.resolveKeybindings(actionIds).done(keybindings => { + if (keybindings.length) { + ipc.send('vscode:keybindingsResolved', JSON.stringify(keybindings)); + } + }, () => errors.onUnexpectedError); + }); + ipc.on('vscode:reportError', (event: any, error: string) => { if (error) { const errorParsed = JSON.parse(error); @@ -354,6 +375,28 @@ export class ElectronWindow extends Themable { } } + private resolveKeybindings(actionIds: string[]): TPromise<{ id: string; label: string, isNative: boolean; }[]> { + return TPromise.join([this.lifecycleService.when(LifecyclePhase.Running), this.extensionService.whenInstalledExtensionsRegistered()]).then(() => { + return arrays.coalesce(actionIds.map(id => { + const binding = this.keybindingService.lookupKeybinding(id); + if (!binding) { + return null; + } + // first try to resolve a native accelerator + const electronAccelerator = binding.getElectronAccelerator(); + if (electronAccelerator) { + return { id, label: electronAccelerator, isNative: true }; + } + // we need this fallback to support keybindings that cannot show in electron menus (e.g. chords) + const acceleratorLabel = binding.getLabel(); + if (acceleratorLabel) { + return { id, label: acceleratorLabel, isNative: false }; + } + return null; + })); + }); + } + private onAddFoldersRequest(request: IAddFoldersRequest): void { // Buffer all pending requests From cc9e8e1a03f0b3d5fa7e2b8a1157a48c8c272184 Mon Sep 17 00:00:00 2001 From: Martin Aeschlimann Date: Fri, 10 Aug 2018 09:05:58 +0200 Subject: [PATCH 0648/1276] [seti] fileAssociationFile uses single and double quotes --- extensions/theme-seti/build/update-icon-theme.js | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/extensions/theme-seti/build/update-icon-theme.js b/extensions/theme-seti/build/update-icon-theme.js index 31d7bffe3a7..24b5d342694 100644 --- a/extensions/theme-seti/build/update-icon-theme.js +++ b/extensions/theme-seti/build/update-icon-theme.js @@ -172,13 +172,13 @@ exports.copyFont = function() { //let mappings = 'https://raw.githubusercontent.com/jesseweed/seti-ui/master/styles/components/icons/mapping.less'; //let colors = 'https://raw.githubusercontent.com/jesseweed/seti-ui/master/styles/ui-variables.less'; -let fontMappings = '../../../seti-ui/styles/_fonts/seti.less'; -let mappings = '../../../seti-ui/styles/components/icons/mapping.less'; -let colors = '../../../seti-ui/styles/ui-variables.less'; +let fontMappingsFile = '../../../seti-ui/styles/_fonts/seti.less'; +let fileAssociationFile = '../../../seti-ui/styles/components/icons/mapping.less'; +let colorsFile = '../../../seti-ui/styles/ui-variables.less'; exports.update = function () { - console.log('Reading from ' + fontMappings); + console.log('Reading from ' + fontMappingsFile); let def2Content = {}; let ext2Def = {}; let fileName2Def = {}; @@ -256,15 +256,15 @@ exports.update = function () { let match; - return download(fontMappings).then(function (content) { + return download(fontMappingsFile).then(function (content) { let regex = /@([\w-]+):\s*'(\\E[0-9A-F]+)';/g; let contents = {}; while ((match = regex.exec(content)) !== null) { contents[match[1]] = match[2]; } - return download(mappings).then(function (content) { - let regex2 = /\.icon-(?:set|partial)\('([\w-\.]+)',\s*'([\w-]+)',\s*(@[\w-]+)\)/g; + return download(fileAssociationFile).then(function (content) { + let regex2 = /\.icon-(?:set|partial)\(['"]([\w-\.]+)['"],\s*['"]([\w-]+)['"],\s*(@[\w-]+)\)/g; while ((match = regex2.exec(content)) !== null) { let pattern = match[1]; let def = '_' + match[2]; @@ -320,7 +320,7 @@ exports.update = function () { } - return download(colors).then(function (content) { + return download(colorsFile).then(function (content) { let regex3 = /(@[\w-]+):\s*(#[0-9a-z]+)/g; while ((match = regex3.exec(content)) !== null) { colorId2Value[match[1]] = match[2]; From 5d8c78294bd0d7d7f9318b565acb981dbb1525d4 Mon Sep 17 00:00:00 2001 From: Christof Marti Date: Fri, 10 Aug 2018 10:04:51 +0200 Subject: [PATCH 0649/1276] Separator (#29096) --- .../platform/quickinput/common/quickInput.ts | 25 +++++- .../browser/parts/quickinput/quickInput.css | 25 +++++- .../browser/parts/quickinput/quickInput.ts | 53 ++++++++++-- .../parts/quickinput/quickInputList.ts | 85 ++++++++++++++----- 4 files changed, 156 insertions(+), 32 deletions(-) diff --git a/src/vs/platform/quickinput/common/quickInput.ts b/src/vs/platform/quickinput/common/quickInput.ts index 8b88046261d..a65975541cf 100644 --- a/src/vs/platform/quickinput/common/quickInput.ts +++ b/src/vs/platform/quickinput/common/quickInput.ts @@ -12,6 +12,7 @@ import URI from 'vs/base/common/uri'; import { Event } from 'vs/base/common/event'; export interface IQuickPickItem { + type?: 'item'; id?: string; label: string; description?: string; @@ -21,6 +22,17 @@ export interface IQuickPickItem { picked?: boolean; } +export interface IQuickPickSeparator { + type: 'separator'; + border?: boolean; + label?: string; +} + +export interface IKeyMods { + readonly ctrlCmd: boolean; + readonly alt: boolean; +} + export interface IQuickNavigateConfiguration { keybindings: ResolvedKeybinding[]; } @@ -67,6 +79,7 @@ export interface IPickOptions { */ activeItem?: TPromise | T; + onKeyMods?: (keyMods: IKeyMods) => void; onDidFocus?: (entry: T) => void; onDidTriggerItemButton?: (context: IQuickPickItemButtonContext) => void; } @@ -147,7 +160,7 @@ export interface IQuickPick extends IQuickInput { readonly onDidTriggerItemButton: Event>; - items: ReadonlyArray; + items: ReadonlyArray; canSelectMany: boolean; @@ -164,6 +177,8 @@ export interface IQuickPick extends IQuickInput { selectedItems: ReadonlyArray; readonly onDidChangeSelection: Event; + + readonly keyMods: IKeyMods; } export interface IInputBox extends IQuickInput { @@ -208,6 +223,8 @@ export const IQuickInputService = createDecorator('quickInpu export type Omit = Pick>; +export type QuickPickInput = TPromise<(T | IQuickPickSeparator)[]> | (T | IQuickPickSeparator)[]; + export interface IQuickInputService { _serviceBrand: any; @@ -215,9 +232,9 @@ export interface IQuickInputService { /** * Opens the quick input box for selecting items and returns a promise with the user selected item(s) if any. */ - pick(picks: TPromise | T[], options?: IPickOptions & { canPickMany: true }, token?: CancellationToken): TPromise; - pick(picks: TPromise | T[], options?: IPickOptions & { canPickMany: false }, token?: CancellationToken): TPromise; - pick(picks: TPromise | T[], options?: Omit, 'canPickMany'>, token?: CancellationToken): TPromise; + pick(picks: QuickPickInput, options?: IPickOptions & { canPickMany: true }, token?: CancellationToken): TPromise; + pick(picks: QuickPickInput, options?: IPickOptions & { canPickMany: false }, token?: CancellationToken): TPromise; + pick(picks: QuickPickInput, options?: Omit, 'canPickMany'>, token?: CancellationToken): TPromise; /** * Opens the quick input box for text input and returns a promise with the user typed value if any. diff --git a/src/vs/workbench/browser/parts/quickinput/quickInput.css b/src/vs/workbench/browser/parts/quickinput/quickInput.css index 35094940935..514dc145b72 100644 --- a/src/vs/workbench/browser/parts/quickinput/quickInput.css +++ b/src/vs/workbench/browser/parts/quickinput/quickInput.css @@ -170,6 +170,21 @@ font-weight: bold; } +.quick-input-list .quick-input-list-separator { + margin-right: 18px; +} + +.quick-input-list .quick-input-list-entry.has-actions:hover .quick-input-list-separator, +.quick-input-list .monaco-list-row.focused .quick-input-list-entry.has-actions .quick-input-list-separator { + margin-right: 0; +} + +.quick-input-list .quick-input-list-separator-border { + border-top-width: 1px; + border-top-style: solid; + box-sizing: border-box; +} + .quick-input-list .quick-input-list-entry-action-bar { display: none; flex: 0; @@ -184,8 +199,16 @@ background-repeat: no-repeat; } +.quick-input-list .quick-input-list-entry-action-bar { + margin-top: 1px; +} + +.quick-input-list .quick-input-list-entry-action-bar ul:first-child .action-label.icon { + margin-left: 2px; +} + .quick-input-list .quick-input-list-entry-action-bar ul:last-child .action-label.icon { - margin-right: 3px; + margin-right: 8px; } .quick-input-list .quick-input-list-entry:hover .quick-input-list-entry-action-bar, diff --git a/src/vs/workbench/browser/parts/quickinput/quickInput.ts b/src/vs/workbench/browser/parts/quickinput/quickInput.ts index 0746e309b9e..2e68c465dba 100644 --- a/src/vs/workbench/browser/parts/quickinput/quickInput.ts +++ b/src/vs/workbench/browser/parts/quickinput/quickInput.ts @@ -7,7 +7,7 @@ import 'vs/css!./quickInput'; import { Component } from 'vs/workbench/common/component'; -import { IQuickInputService, IQuickPickItem, IPickOptions, IInputOptions, IQuickNavigateConfiguration, IQuickPick, IQuickInput, IQuickInputButton, IInputBox, IQuickPickItemButtonEvent } from 'vs/platform/quickinput/common/quickInput'; +import { IQuickInputService, IQuickPickItem, IPickOptions, IInputOptions, IQuickNavigateConfiguration, IQuickPick, IQuickInput, IQuickInputButton, IInputBox, IQuickPickItemButtonEvent, QuickPickInput, IQuickPickSeparator, IKeyMods } from 'vs/platform/quickinput/common/quickInput'; import { IPartService } from 'vs/workbench/services/part/common/partService'; import * as dom from 'vs/base/browser/dom'; import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; @@ -46,6 +46,8 @@ import { getIconClass } from 'vs/workbench/browser/parts/quickinput/quickInputUt const $ = dom.$; +type Writeable = { -readonly [P in keyof T]: T[P] }; + const backButton = { iconPath: { dark: URI.parse(require.toUrl('vs/workbench/browser/parts/quickinput/media/dark/arrow-left.svg')), @@ -70,6 +72,7 @@ interface QuickInputUI { onDidAccept: Event; onDidTriggerButton: Event; ignoreFocusOut: boolean; + keyMods: Writeable; show(controller: QuickInput): void; setVisibilities(visibilities: Visibilities): void; setEnabled(enabled: boolean): void; @@ -298,7 +301,7 @@ class QuickPick extends QuickInput implements IQuickPi private _placeholder; private onDidChangeValueEmitter = new Emitter(); private onDidAcceptEmitter = new Emitter(); - private _items: T[] = []; + private _items: (T | IQuickPickSeparator)[] = []; private itemsUpdated = false; private _canSelectMany = false; private _matchOnDescription = false; @@ -352,7 +355,7 @@ class QuickPick extends QuickInput implements IQuickPi return this._items; } - set items(items: T[]) { + set items(items: (T | IQuickPickSeparator)[]) { this._items = items; this.itemsUpdated = true; this.update(); @@ -407,6 +410,10 @@ class QuickPick extends QuickInput implements IQuickPi this.update(); } + get keyMods() { + return this.ui.keyMods; + } + onDidChangeSelection = this.onDidChangeSelectionEmitter.event; onDidTriggerItemButton = this.onDidTriggerItemButtonEmitter.event; @@ -950,6 +957,30 @@ export class QuickInputService extends Component implements IQuickInputService { break; } })); + this._register(dom.addDisposableListener(container, dom.EventType.KEY_DOWN, (e: KeyboardEvent) => { + const event = new StandardKeyboardEvent(e); + switch (event.keyCode) { + case KeyCode.Ctrl: + case KeyCode.Meta: + this.ui.keyMods.ctrlCmd = true; + break; + case KeyCode.Alt: + this.ui.keyMods.alt = true; + break; + } + })); + this._register(dom.addDisposableListener(container, dom.EventType.KEY_UP, (e: KeyboardEvent) => { + const event = new StandardKeyboardEvent(e); + switch (event.keyCode) { + case KeyCode.Ctrl: + case KeyCode.Meta: + this.ui.keyMods.ctrlCmd = false; + break; + case KeyCode.Alt: + this.ui.keyMods.alt = false; + break; + } + })); this._register(this.quickOpenService.onShow(() => this.hide(true))); @@ -968,6 +999,7 @@ export class QuickInputService extends Component implements IQuickInputService { onDidAccept: this.onDidAcceptEmitter.event, onDidTriggerButton: this.onDidTriggerButtonEmitter.event, ignoreFocusOut: false, + keyMods: { ctrlCmd: false, alt: false }, show: controller => this.show(controller), hide: () => this.hide(), setVisibilities: visibilities => this.setVisibilities(visibilities), @@ -977,8 +1009,15 @@ export class QuickInputService extends Component implements IQuickInputService { this.updateStyles(); } - pick>(picks: TPromise | T[], options: O = {}, token: CancellationToken = CancellationToken.None): TPromise { - return new TPromise((resolve, reject) => { + pick>(picks: QuickPickInput, options: O = {}, token: CancellationToken = CancellationToken.None): TPromise { + return new TPromise((doResolve, reject) => { + let resolve = (result: any) => { + resolve = doResolve; + if (options.onKeyMods) { + options.onKeyMods(input.keyMods); + } + doResolve(result); + }; if (token.isCancellationRequested) { resolve(undefined); return; @@ -1045,7 +1084,7 @@ export class QuickInputService extends Component implements IQuickInputService { input.busy = false; input.items = items; if (input.canSelectMany) { - input.selectedItems = items.filter(item => item.picked); + input.selectedItems = items.filter(item => item.type !== 'separator' && item.picked) as T[]; } if (activeItem) { input.activeItems = [activeItem]; @@ -1154,6 +1193,8 @@ export class QuickInputService extends Component implements IQuickInputService { this.ui.list.matchOnDescription = false; this.ui.list.matchOnDetail = false; this.ui.ignoreFocusOut = false; + this.ui.keyMods.ctrlCmd = false; + this.ui.keyMods.alt = false; const keybinding = this.keybindingService.lookupKeybinding(BackAction.ID); backButton.tooltip = keybinding ? localize('quickInput.backWithKeybinding', "Back ({0})", keybinding.getLabel()) : localize('quickInput.back', "Back"); diff --git a/src/vs/workbench/browser/parts/quickinput/quickInputList.ts b/src/vs/workbench/browser/parts/quickinput/quickInputList.ts index ff832f65ebe..104cb9ae3d1 100644 --- a/src/vs/workbench/browser/parts/quickinput/quickInputList.ts +++ b/src/vs/workbench/browser/parts/quickinput/quickInputList.ts @@ -11,7 +11,7 @@ import * as dom from 'vs/base/browser/dom'; import { dispose, IDisposable } from 'vs/base/common/lifecycle'; import { WorkbenchList } from 'vs/platform/list/browser/listService'; import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; -import { IQuickPickItem, IQuickPickItemButtonEvent } from 'vs/platform/quickinput/common/quickInput'; +import { IQuickPickItem, IQuickPickItemButtonEvent, IQuickPickSeparator } from 'vs/platform/quickinput/common/quickInput'; import { IMatch } from 'vs/base/common/filters'; import { matchesFuzzyOcticonAware, parseOcticons } from 'vs/base/common/octicon'; import { compareAnything } from 'vs/base/common/comparers'; @@ -24,7 +24,7 @@ import { HighlightedLabel } from 'vs/base/browser/ui/highlightedlabel/highlighte import { memoize } from 'vs/base/common/decorators'; import { range } from 'vs/base/common/arrays'; import * as platform from 'vs/base/common/platform'; -import { listFocusBackground } from 'vs/platform/theme/common/colorRegistry'; +import { listFocusBackground, pickerGroupBorder, pickerGroupForeground } from 'vs/platform/theme/common/colorRegistry'; import { registerThemingParticipant } from 'vs/platform/theme/common/themeService'; import { ActionBar } from 'vs/base/browser/ui/actionbar/actionbar'; import { Action } from 'vs/base/common/actions'; @@ -36,6 +36,7 @@ interface IListElement { index: number; item: IQuickPickItem; checked: boolean; + separator: IQuickPickSeparator; fireButtonTriggered: (event: IQuickPickItemButtonEvent) => void; } @@ -56,6 +57,7 @@ class ListElement implements IListElement { this._onChecked.fire(value); } } + separator: IQuickPickSeparator; labelHighlights?: IMatch[]; descriptionHighlights?: IMatch[]; detailHighlights?: IMatch[]; @@ -67,9 +69,11 @@ class ListElement implements IListElement { } interface IListElementTemplateData { + entry: HTMLDivElement; checkbox: HTMLInputElement; label: IconLabel; detail: HighlightedLabel; + separator: HTMLDivElement; actionBar: ActionBar; element: ListElement; toDisposeElement: IDisposable[]; @@ -89,10 +93,10 @@ class ListElementRenderer implements IRendererdom.append(label, $('input.quick-input-list-checkbox')); data.checkbox.type = 'checkbox'; data.toDisposeTemplate.push(dom.addStandardDisposableListener(data.checkbox, dom.EventType.CHANGE, e => { @@ -111,8 +115,11 @@ class ListElementRenderer implements IRenderer { + const buttons = element.item.buttons; + if (buttons && buttons.length) { + data.actionBar.push(buttons.map((button, index) => { const action = new Action(`id-${index}`, '', button.iconClass || getIconClass(button.iconPath), true, () => { element.fireButtonTriggered({ button, @@ -152,6 +173,9 @@ class ListElementRenderer implements IRenderer; + private inputElements: (IQuickPickItem | IQuickPickSeparator)[]; private elements: ListElement[] = []; private elementsToIndexes = new Map(); matchOnDescription = false; @@ -314,15 +339,23 @@ export class QuickInputList { } } - setElements(elements: IQuickPickItem[]): void { + setElements(inputElements: (IQuickPickItem | IQuickPickSeparator)[]): void { this.elementDisposables = dispose(this.elementDisposables); const fireButtonTriggered = (event: IQuickPickItemButtonEvent) => this.fireButtonTriggered(event); - this.elements = elements.map((item, index) => new ListElement({ - index, - item, - checked: false, - fireButtonTriggered - })); + this.inputElements = inputElements; + this.elements = inputElements.reduce((result, item, index) => { + if (item.type !== 'separator') { + const previous = index && inputElements[index - 1]; + result.push(new ListElement({ + index, + item, + checked: false, + separator: previous && previous.type === 'separator' ? previous : undefined, + fireButtonTriggered + })); + } + return result; + }, [] as ListElement[]); this.elementDisposables.push(...this.elements.map(element => element.onChecked(() => this.fireCheckedEvents()))); this.elementsToIndexes = this.elements.reduce((map, element, index) => { @@ -419,6 +452,8 @@ export class QuickInputList { element.descriptionHighlights = undefined; element.detailHighlights = undefined; element.hidden = false; + const previous = element.index && this.inputElements[element.index - 1]; + element.separator = previous && previous.type === 'separator' ? previous : undefined; }); } @@ -440,19 +475,19 @@ export class QuickInputList { element.detailHighlights = undefined; element.hidden = true; } + element.separator = undefined; }); } const shownElements = this.elements.filter(element => !element.hidden); // Sort by value - const normalizedSearchValue = query.toLowerCase(); - shownElements.sort((a, b) => { - if (!query) { - return a.index - b.index; // restore natural order - } - return compareEntries(a, b, normalizedSearchValue); - }); + if (query) { + const normalizedSearchValue = query.toLowerCase(); + shownElements.sort((a, b) => { + return compareEntries(a, b, normalizedSearchValue); + }); + } this.elementsToIndexes = shownElements.reduce((map, element, index) => { map.set(element.item, index); @@ -528,4 +563,12 @@ registerThemingParticipant((theme, collector) => { collector.addRule(`.quick-input-list .monaco-list .monaco-list-row.focused { background-color: ${listInactiveFocusBackground}; }`); collector.addRule(`.quick-input-list .monaco-list .monaco-list-row.focused:hover { background-color: ${listInactiveFocusBackground}; }`); } + const pickerGroupBorderColor = theme.getColor(pickerGroupBorder); + if (pickerGroupBorderColor) { + collector.addRule(`.quick-input-list .quick-input-list-entry { border-top-color: ${pickerGroupBorderColor}; }`); + } + const pickerGroupForegroundColor = theme.getColor(pickerGroupForeground); + if (pickerGroupForegroundColor) { + collector.addRule(`.quick-input-list .quick-input-list-separator { color: ${pickerGroupForegroundColor}; }`); + } }); From 7180bb922e46bbe1eb1509c28e774d0f06877783 Mon Sep 17 00:00:00 2001 From: Christof Marti Date: Fri, 10 Aug 2018 10:05:57 +0200 Subject: [PATCH 0650/1276] Use QuickInput (#29096) --- src/vs/workbench/electron-browser/actions.ts | 116 +++++++++---------- 1 file changed, 55 insertions(+), 61 deletions(-) diff --git a/src/vs/workbench/electron-browser/actions.ts b/src/vs/workbench/electron-browser/actions.ts index c8e4a2288f6..4a4790b2c7c 100644 --- a/src/vs/workbench/electron-browser/actions.ts +++ b/src/vs/workbench/electron-browser/actions.ts @@ -9,7 +9,7 @@ import 'vs/css!./media/actions'; import URI from 'vs/base/common/uri'; import { TPromise } from 'vs/base/common/winjs.base'; -import { Action, IAction } from 'vs/base/common/actions'; +import { Action } from 'vs/base/common/actions'; import { IWindowService, IWindowsService, MenuBarVisibility } from 'vs/platform/windows/common/windows'; import * as nls from 'vs/nls'; import product from 'vs/platform/node/product'; @@ -20,10 +20,8 @@ import { IEnvironmentService } from 'vs/platform/environment/common/environment' import { IConfigurationService, ConfigurationTarget } from 'vs/platform/configuration/common/configuration'; import { IWorkspaceConfigurationService } from 'vs/workbench/services/configuration/common/configuration'; import { isMacintosh, isLinux, language } from 'vs/base/common/platform'; -import { IQuickOpenService, IFilePickOpenEntry, ISeparator, IPickOpenAction, IPickOpenItem } from 'vs/platform/quickOpen/common/quickOpen'; import * as browser from 'vs/base/browser/browser'; import { IIntegrityService } from 'vs/platform/integrity/common/integrity'; -import { IEntryRunContext } from 'vs/base/parts/quickopen/common/quickOpen'; import { ITimerService, IStartupMetrics } from 'vs/workbench/services/timer/common/timerService'; import { IEditorGroupsService, GroupDirection, GroupLocation, IFindGroupScope } from 'vs/workbench/services/group/common/editorGroupsService'; import { IPanelService } from 'vs/workbench/services/panel/common/panelService'; @@ -37,7 +35,6 @@ import { IViewlet } from 'vs/workbench/common/viewlet'; import { IPanel } from 'vs/workbench/common/panel'; import { IWorkspaceIdentifier, getWorkspaceLabel, ISingleFolderWorkspaceIdentifier, isSingleFolderWorkspaceIdentifier, isWorkspaceIdentifier } from 'vs/platform/workspaces/common/workspaces'; import { FileKind } from 'vs/platform/files/common/files'; -import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; import { IExtensionService, ActivationTimes } from 'vs/workbench/services/extensions/common/extensions'; import { getEntries } from 'vs/base/common/performance'; import { IssueType } from 'vs/platform/issue/common/issue'; @@ -53,7 +50,7 @@ import { IUriDisplayService } from 'vs/platform/uriDisplay/common/uriDisplay'; import { dirname } from 'vs/base/common/resources'; import { IModelService } from 'vs/editor/common/services/modelService'; import { IModeService } from 'vs/editor/common/services/modeService'; -import { IQuickInputService, IQuickPickItem, IQuickInputButton } from 'vs/platform/quickinput/common/quickInput'; +import { IQuickInputService, IQuickPickItem, IQuickInputButton, IQuickPickSeparator, IKeyMods } from 'vs/platform/quickinput/common/quickInput'; import { getIconClasses } from 'vs/workbench/browser/labels'; // --- actions @@ -654,7 +651,6 @@ export class SwitchWindow extends BaseSwitchWindow { @IKeybindingService keybindingService: IKeybindingService, @IModelService modelService: IModelService, @IModeService modeService: IModeService, - @IInstantiationService instantiationService: IInstantiationService ) { super(id, label, windowsService, windowService, quickInputService, keybindingService, modelService, modeService); } @@ -678,7 +674,6 @@ export class QuickSwitchWindow extends BaseSwitchWindow { @IKeybindingService keybindingService: IKeybindingService, @IModelService modelService: IModelService, @IModeService modeService: IModeService, - @IInstantiationService instantiationService: IInstantiationService ) { super(id, label, windowsService, windowService, quickInputService, keybindingService, modelService, modeService); } @@ -692,16 +687,23 @@ export const inRecentFilesPickerContextKey = 'inRecentFilesPicker'; export abstract class BaseOpenRecentAction extends Action { + private removeFromRecentlyOpened: IQuickInputButton = { + iconClass: 'action-remove-from-recently-opened', + tooltip: nls.localize('remove', "Remove from Recently Opened") + }; + constructor( id: string, label: string, private windowService: IWindowService, - private quickOpenService: IQuickOpenService, + private windowsService: IWindowsService, + private quickInputService: IQuickInputService, private contextService: IWorkspaceContextService, private environmentService: IEnvironmentService, private uriDisplayService: IUriDisplayService, private keybindingService: IKeybindingService, - private instantiationService: IInstantiationService + private modelService: IModelService, + private modeService: IModeService, ) { super(id, label); } @@ -715,7 +717,7 @@ export abstract class BaseOpenRecentAction extends Action { private openRecent(recentWorkspaces: (IWorkspaceIdentifier | ISingleFolderWorkspaceIdentifier)[], recentFiles: string[]): void { - function toPick(workspace: IWorkspaceIdentifier | ISingleFolderWorkspaceIdentifier | string, separator: ISeparator, fileKind: FileKind, environmentService: IEnvironmentService, uriDisplayService: IUriDisplayService, action: IAction): IFilePickOpenEntry { + const toPick = (workspace: IWorkspaceIdentifier | ISingleFolderWorkspaceIdentifier | string, fileKind: FileKind, environmentService: IEnvironmentService, uriDisplayService: IUriDisplayService, buttons: IQuickInputButton[]) => { let resource: URI; let label: string; let description: string; @@ -734,63 +736,51 @@ export abstract class BaseOpenRecentAction extends Action { } return { - resource, - fileKind, + iconClasses: getIconClasses(this.modelService, this.modeService, resource, fileKind), label, description, - separator, - run: context => { - setTimeout(() => { - // Bug: somehow when not running this code in a timeout, it is not possible to use this picker - // with quick navigate keys (not able to trigger quick navigate once running it once). - runPick(resource, fileKind === FileKind.FILE, context); - }); - }, - action + buttons, + workspace, + resource, + fileKind, }; - } - - const runPick = (resource: URI, isFile: boolean, context: IEntryRunContext) => { - const forceNewWindow = context.keymods.ctrlCmd; - this.windowService.openWindow([resource], { forceNewWindow, forceOpenWorkspaceAsFile: isFile }); }; - const workspacePicks: IFilePickOpenEntry[] = recentWorkspaces.map((workspace, index) => toPick(workspace, index === 0 ? { label: nls.localize('workspaces', "workspaces") } : void 0, isSingleFolderWorkspaceIdentifier(workspace) ? FileKind.FOLDER : FileKind.ROOT_FOLDER, this.environmentService, this.uriDisplayService, !this.isQuickNavigate() ? this.instantiationService.createInstance(RemoveFromRecentlyOpened, workspace) : void 0)); - const filePicks: IFilePickOpenEntry[] = recentFiles.map((p, index) => toPick(p, index === 0 ? { label: nls.localize('files', "files"), border: true } : void 0, FileKind.FILE, this.environmentService, this.uriDisplayService, !this.isQuickNavigate() ? this.instantiationService.createInstance(RemoveFromRecentlyOpened, p) : void 0)); + const runPick = (resource: URI, isFile: boolean, keyMods: IKeyMods) => { + const forceNewWindow = keyMods.ctrlCmd; + return this.windowService.openWindow([resource], { forceNewWindow, forceOpenWorkspaceAsFile: isFile }); + }; + + const workspacePicks = recentWorkspaces.map(workspace => toPick(workspace, isSingleFolderWorkspaceIdentifier(workspace) ? FileKind.FOLDER : FileKind.ROOT_FOLDER, this.environmentService, this.uriDisplayService, !this.isQuickNavigate() ? [this.removeFromRecentlyOpened] : void 0)); + const filePicks = recentFiles.map(p => toPick(p, FileKind.FILE, this.environmentService, this.uriDisplayService, !this.isQuickNavigate() ? [this.removeFromRecentlyOpened] : void 0)); // focus second entry if the first recent workspace is the current workspace let autoFocusSecondEntry: boolean = recentWorkspaces[0] && this.contextService.isCurrentWorkspace(recentWorkspaces[0]); - this.quickOpenService.pick([...workspacePicks, ...filePicks], { + let keyMods: IKeyMods; + const workspaceSeparator: IQuickPickSeparator = { type: 'separator', label: nls.localize('workspaces', "workspaces") }; + const fileSeparator: IQuickPickSeparator = { type: 'separator', label: nls.localize('files', "files"), border: true }; + const picks = [workspaceSeparator, ...workspacePicks, fileSeparator, ...filePicks]; + this.quickInputService.pick(picks, { contextKey: inRecentFilesPickerContextKey, - autoFocus: { autoFocusFirstEntry: !autoFocusSecondEntry, autoFocusSecondEntry: autoFocusSecondEntry }, + activeItem: [...workspacePicks, ...filePicks][autoFocusSecondEntry ? 1 : 0], placeHolder: isMacintosh ? nls.localize('openRecentPlaceHolderMac', "Select to open (hold Cmd-key to open in new window)") : nls.localize('openRecentPlaceHolder', "Select to open (hold Ctrl-key to open in new window)"), matchOnDescription: true, - quickNavigateConfiguration: this.isQuickNavigate() ? { keybindings: this.keybindingService.lookupKeybindings(this.id) } : void 0 - }).done(null, errors.onUnexpectedError); - } -} - -class RemoveFromRecentlyOpened extends Action implements IPickOpenAction { - - static readonly ID = 'workbench.action.removeFromRecentlyOpened'; - static readonly LABEL = nls.localize('remove', "Remove from Recently Opened"); - - constructor( - private path: (IWorkspaceIdentifier | ISingleFolderWorkspaceIdentifier | string), - @IWindowsService private windowsService: IWindowsService - ) { - super(RemoveFromRecentlyOpened.ID, RemoveFromRecentlyOpened.LABEL); - - this.class = 'action-remove-from-recently-opened'; - } - - run(item: IPickOpenItem): TPromise { - return this.windowsService.removeFromRecentlyOpened([this.path]).then(() => { - item.remove(); - - return true; - }); + onKeyMods: mods => keyMods = mods, + quickNavigate: this.isQuickNavigate() ? { keybindings: this.keybindingService.lookupKeybindings(this.id) } : void 0, + onDidTriggerItemButton: context => { + this.windowsService.removeFromRecentlyOpened([context.item.workspace]).then(() => { + context.removeItem(); + }).then(null, errors.onUnexpectedError); + } + }) + .then(pick => { + if (pick) { + return runPick(pick.resource, pick.fileKind === FileKind.FILE, keyMods); + } + return null; + }) + .done(null, errors.onUnexpectedError); } } @@ -803,14 +793,16 @@ export class OpenRecentAction extends BaseOpenRecentAction { id: string, label: string, @IWindowService windowService: IWindowService, - @IQuickOpenService quickOpenService: IQuickOpenService, + @IWindowsService windowsService: IWindowsService, + @IQuickInputService quickInputService: IQuickInputService, @IWorkspaceContextService contextService: IWorkspaceContextService, @IEnvironmentService environmentService: IEnvironmentService, @IKeybindingService keybindingService: IKeybindingService, - @IInstantiationService instantiationService: IInstantiationService, + @IModelService modelService: IModelService, + @IModeService modeService: IModeService, @IUriDisplayService uriDisplayService: IUriDisplayService ) { - super(id, label, windowService, quickOpenService, contextService, environmentService, uriDisplayService, keybindingService, instantiationService); + super(id, label, windowService, windowsService, quickInputService, contextService, environmentService, uriDisplayService, keybindingService, modelService, modeService); } protected isQuickNavigate(): boolean { @@ -827,14 +819,16 @@ export class QuickOpenRecentAction extends BaseOpenRecentAction { id: string, label: string, @IWindowService windowService: IWindowService, - @IQuickOpenService quickOpenService: IQuickOpenService, + @IWindowsService windowsService: IWindowsService, + @IQuickInputService quickInputService: IQuickInputService, @IWorkspaceContextService contextService: IWorkspaceContextService, @IEnvironmentService environmentService: IEnvironmentService, @IKeybindingService keybindingService: IKeybindingService, - @IInstantiationService instantiationService: IInstantiationService, + @IModelService modelService: IModelService, + @IModeService modeService: IModeService, @IUriDisplayService uriDisplayService: IUriDisplayService ) { - super(id, label, windowService, quickOpenService, contextService, environmentService, uriDisplayService, keybindingService, instantiationService); + super(id, label, windowService, windowsService, quickInputService, contextService, environmentService, uriDisplayService, keybindingService, modelService, modeService); } protected isQuickNavigate(): boolean { From c65b69177a2fa977368a54b4fff98e69006c097d Mon Sep 17 00:00:00 2001 From: Martin Aeschlimann Date: Fri, 10 Aug 2018 10:37:31 +0200 Subject: [PATCH 0651/1276] [icon themes] seti theme should associate also to non build-in language modes (elm, caml, nunjucks..) Fixes #47432 --- .../theme-seti/build/update-icon-theme.js | 69 +++++++++++++------ 1 file changed, 49 insertions(+), 20 deletions(-) diff --git a/extensions/theme-seti/build/update-icon-theme.js b/extensions/theme-seti/build/update-icon-theme.js index 24b5d342694..b82a53ecc88 100644 --- a/extensions/theme-seti/build/update-icon-theme.js +++ b/extensions/theme-seti/build/update-icon-theme.js @@ -10,6 +10,30 @@ let fs = require('fs'); let https = require('https'); let url = require('url'); +// list of languagesIs not shipped with VSCode. The information is used to associate an icon with a langauge association +let nonBuiltInLanguages = { // { fileNames, extensions } + "r": { extensions: ['r', 'rhistory', 'rprofile', 'rt'] }, + "argdown": { extensions: ['ad', 'adown', 'argdown', 'argdn'] }, + "elm": { extensions: ['elm'] }, + "ocaml": { extensions: ['ml', 'mli'] }, + "nunjucks": { extensions: ['nunjucks', 'nunjs', 'nunj', 'nj', 'njk', 'tmpl', 'tpl'] }, + "mustache": { extensions: ['mustache', 'mst', 'mu', 'stache'] }, + "erb": { extensions: ['erb', 'rhtml', 'html.erb'] }, + "terraform": { extensions: ['tf', 'tfvars', 'hcl'] }, + "vue": { extensions: ['vue'] }, + "sass": { extensions: ['sass'] }, + "puppet": { extensions: ['puppet'] }, + "kotlin": { extensions: ['kt'] }, + "jinja": { extensions: ['jinja'] }, + "haxe": { extensions: ['hx'] }, + "haskell": { extensions: ['hs'] }, + "gradle": { extensions: ['gradle'] }, + "elixir": { extensions: ['ex'] }, + "haml": { extensions: ['haml'] }, + "stylus": { extensions: ['styl'] }, + "vala": { extensions: ['vala'] } +} + function getCommitSha(repoId, repoPath) { let commitInfo = 'https://api.github.com/repos/' + repoId + '/commits?path=' + repoPath; return download(commitInfo).then(function (content) { @@ -34,7 +58,7 @@ function download(source) { } return new Promise((c, e) => { let _url = url.parse(source); - let options = { host: _url.host, port: _url.port, path: _url.path, headers: { 'User-Agent': 'NodeJS' }}; + let options = { host: _url.host, port: _url.port, path: _url.path, headers: { 'User-Agent': 'NodeJS' } }; let content = ''; https.get(options, function (response) { response.on('data', function (data) { @@ -50,7 +74,7 @@ function download(source) { function readFile(fileName) { return new Promise((c, e) => { - fs.readFile(fileName, function(err, data) { + fs.readFile(fileName, function (err, data) { if (err) { e(err); } else { @@ -67,12 +91,12 @@ function downloadBinary(source, dest) { return new Promise((c, e) => { https.get(source, function (response) { - switch(response.statusCode) { + switch (response.statusCode) { case 200: let file = fs.createWriteStream(dest); - response.on('data', function(chunk){ + response.on('data', function (chunk) { file.write(chunk); - }).on('end', function(){ + }).on('end', function () { file.end(); c(null); }).on('error', function (err) { @@ -107,7 +131,7 @@ function copyFile(fileName, dest) { rd.on("error", handleError); let wr = fs.createWriteStream(dest); wr.on("error", handleError); - wr.on("close", function() { + wr.on("close", function () { if (!cbCalled) { c(); cbCalled = true; @@ -119,7 +143,7 @@ function copyFile(fileName, dest) { function darkenColor(color) { let res = '#'; - for (let i = 1; i < 7; i+=2) { + for (let i = 1; i < 7; i += 2) { let newVal = Math.round(parseInt('0x' + color.substr(i, 2), 16) * 0.9); let hex = newVal.toString(16); if (hex.length == 1) { @@ -133,7 +157,7 @@ function darkenColor(color) { function getLanguageMappings() { let langMappings = {}; let allExtensions = fs.readdirSync('..'); - for (let i= 0; i < allExtensions.length; i++) { + for (let i = 0; i < allExtensions.length; i++) { let dirPath = path.join('..', allExtensions[i], 'package.json'); if (fs.existsSync(dirPath)) { let content = fs.readFileSync(dirPath).toString(); @@ -158,13 +182,16 @@ function getLanguageMappings() { } } } + for (let languageId in nonBuiltInLanguages) { + langMappings[languageId] = nonBuiltInLanguages[languageId]; + } return langMappings; } //let font = 'https://raw.githubusercontent.com/jesseweed/seti-ui/master/styles/_fonts/seti/seti.woff'; let font = '../../../seti-ui/styles/_fonts/seti/seti.woff'; -exports.copyFont = function() { +exports.copyFont = function () { return downloadBinary(font, './icons/seti.woff'); }; @@ -234,7 +261,7 @@ exports.update = function () { size: "150%" }], iconDefinitions: iconDefinitions, - // folder: "_folder", + // folder: "_folder", file: "_default", fileExtensions: ext2Def, fileNames: fileName2Def, @@ -304,16 +331,18 @@ exports.update = function () { } if (preferredDef) { lang2Def[lang] = preferredDef; - for (let i2 = 0; i2 < exts.length; i2++) { - // remove the extension association, unless it is different from the preferred - if (ext2Def[exts[i2]] === preferredDef) { - delete ext2Def[exts[i2]]; + if (!nonBuiltInLanguages[lang]) { + for (let i2 = 0; i2 < exts.length; i2++) { + // remove the extension association, unless it is different from the preferred + if (ext2Def[exts[i2]] === preferredDef) { + delete ext2Def[exts[i2]]; + } } - } - for (let i2 = 0; i2 < fileNames.length; i2++) { - // remove the fileName association, unless it is different from the preferred - if (fileName2Def[fileNames[i2]] === preferredDef) { - delete fileName2Def[fileNames[i2]]; + for (let i2 = 0; i2 < fileNames.length; i2++) { + // remove the fileName association, unless it is different from the preferred + if (fileName2Def[fileNames[i2]] === preferredDef) { + delete fileName2Def[fileNames[i2]]; + } } } } @@ -323,7 +352,7 @@ exports.update = function () { return download(colorsFile).then(function (content) { let regex3 = /(@[\w-]+):\s*(#[0-9a-z]+)/g; while ((match = regex3.exec(content)) !== null) { - colorId2Value[match[1]] = match[2]; + colorId2Value[match[1]] = match[2]; } return getCommitSha('jesseweed/seti-ui', 'styles/_fonts/seti.less').then(function (info) { try { From 44d764b28afd3c6c666abc9c03b2dca28b90f478 Mon Sep 17 00:00:00 2001 From: Johannes Rieken Date: Fri, 10 Aug 2018 10:34:07 +0200 Subject: [PATCH 0652/1276] debt - replace WinJS.Promise#timeout usages with async#timeout or with setTimeout --- src/vs/editor/contrib/parameterHints/parameterHintsWidget.ts | 3 +-- src/vs/editor/standalone/browser/colorizer.ts | 3 ++- src/vs/workbench/node/extensionHostMain.ts | 3 ++- .../workbench/parts/outline/electron-browser/outlinePanel.ts | 4 ++-- .../parts/performance/electron-browser/startupProfiler.ts | 3 ++- .../services/extensions/electron-browser/extensionHost.ts | 3 ++- 6 files changed, 11 insertions(+), 8 deletions(-) diff --git a/src/vs/editor/contrib/parameterHints/parameterHintsWidget.ts b/src/vs/editor/contrib/parameterHints/parameterHintsWidget.ts index 80c27ea30e5..ec1fe98b373 100644 --- a/src/vs/editor/contrib/parameterHints/parameterHintsWidget.ts +++ b/src/vs/editor/contrib/parameterHints/parameterHintsWidget.ts @@ -8,7 +8,6 @@ import 'vs/css!./parameterHints'; import * as nls from 'vs/nls'; import { IDisposable, dispose, Disposable } from 'vs/base/common/lifecycle'; -import { TPromise } from 'vs/base/common/winjs.base'; import * as dom from 'vs/base/browser/dom'; import * as aria from 'vs/base/browser/ui/aria/aria'; import { SignatureHelp, SignatureInformation, SignatureHelpProviderRegistry } from 'vs/editor/common/modes'; @@ -294,7 +293,7 @@ export class ParameterHintsWidget implements IContentWidget, IDisposable { this.keyVisible.set(true); this.visible = true; - TPromise.timeout(100).done(() => dom.addClass(this.element, 'visible')); + setTimeout(() => dom.addClass(this.element, 'visible'), 100); this.editor.layoutContentWidget(this); } diff --git a/src/vs/editor/standalone/browser/colorizer.ts b/src/vs/editor/standalone/browser/colorizer.ts index 1f5595800c8..39afc2b54ba 100644 --- a/src/vs/editor/standalone/browser/colorizer.ts +++ b/src/vs/editor/standalone/browser/colorizer.ts @@ -14,6 +14,7 @@ import { LineTokens, IViewLineTokens } from 'vs/editor/common/core/lineTokens'; import * as strings from 'vs/base/common/strings'; import { IStandaloneThemeService } from 'vs/editor/standalone/common/standaloneThemeService'; import { ViewLineRenderingData } from 'vs/editor/common/viewModel/viewModel'; +import { timeout } from 'vs/base/common/async'; export interface IColorizerOptions { tabSize?: number; @@ -85,7 +86,7 @@ export class Colorizer { } // wait 500ms for mode to load, then give up - return TPromise.any([this._tokenizationSupportChangedPromise(language), TPromise.timeout(500)]).then(_ => { + return TPromise.any([this._tokenizationSupportChangedPromise(language), timeout(500)]).then(_ => { let tokenizationSupport = TokenizationRegistry.get(language); if (tokenizationSupport) { return _colorize(lines, options.tabSize, tokenizationSupport); diff --git a/src/vs/workbench/node/extensionHostMain.ts b/src/vs/workbench/node/extensionHostMain.ts index 6bf7a628602..b848a88609d 100644 --- a/src/vs/workbench/node/extensionHostMain.ts +++ b/src/vs/workbench/node/extensionHostMain.ts @@ -24,6 +24,7 @@ import { IMessagePassingProtocol } from 'vs/base/parts/ipc/common/ipc'; import { RPCProtocol } from 'vs/workbench/services/extensions/node/rpcProtocol'; import URI from 'vs/base/common/uri'; import { ExtHostLogService } from 'vs/workbench/api/node/extHostLogService'; +import { timeout } from 'vs/base/common/async'; const nativeExit = process.exit.bind(process); function patchProcess(allowExit: boolean) { @@ -179,7 +180,7 @@ export class ExtensionHostMain { // Give extensions 1 second to wrap up any async dispose, then exit setTimeout(() => { - TPromise.any([TPromise.timeout(4000), extensionsDeactivated]).then(() => exit(), () => exit()); + TPromise.any([timeout(4000), extensionsDeactivated]).then(() => exit(), () => exit()); }, 1000); } diff --git a/src/vs/workbench/parts/outline/electron-browser/outlinePanel.ts b/src/vs/workbench/parts/outline/electron-browser/outlinePanel.ts index 4123498f29d..4c9c93b5db4 100644 --- a/src/vs/workbench/parts/outline/electron-browser/outlinePanel.ts +++ b/src/vs/workbench/parts/outline/electron-browser/outlinePanel.ts @@ -13,7 +13,7 @@ import { InputBox } from 'vs/base/browser/ui/inputbox/inputBox'; import { ProgressBar } from 'vs/base/browser/ui/progressbar/progressbar'; import { Action, IAction, RadioGroup } from 'vs/base/common/actions'; import { firstIndex } from 'vs/base/common/arrays'; -import { asDisposablePromise, setDisposableTimeout, createCancelablePromise } from 'vs/base/common/async'; +import { asDisposablePromise, setDisposableTimeout, createCancelablePromise, timeout } from 'vs/base/common/async'; import { onUnexpectedError, isPromiseCanceledError } from 'vs/base/common/errors'; import { Emitter } from 'vs/base/common/event'; import { defaultGenerator } from 'vs/base/common/idGenerator'; @@ -496,7 +496,7 @@ export class OutlinePanel extends ViewletPanel { let oldRatio = oldSize / oldLength; if (newRatio <= oldRatio * 0.5 || newRatio >= oldRatio * 1.5) { if (!await asDisposablePromise( - TPromise.timeout(2000).then(_ => true), + timeout(2000).then(_ => true), false, this._editorDisposables).promise ) { diff --git a/src/vs/workbench/parts/performance/electron-browser/startupProfiler.ts b/src/vs/workbench/parts/performance/electron-browser/startupProfiler.ts index 1b8c90733cd..75df0ee2fa3 100644 --- a/src/vs/workbench/parts/performance/electron-browser/startupProfiler.ts +++ b/src/vs/workbench/parts/performance/electron-browser/startupProfiler.ts @@ -19,6 +19,7 @@ import { localize } from 'vs/nls'; import { readdir, del, readFile } from 'vs/base/node/pfs'; import { basename } from 'vs/base/common/paths'; import { IDialogService } from 'vs/platform/dialogs/common/dialogs'; +import { timeout } from 'vs/base/common/async'; class StartupProfiler implements IWorkbenchContribution { @@ -52,7 +53,7 @@ class StartupProfiler implements IWorkbenchContribution { const removeArgs: string[] = ['--prof-startup']; const markerFile = readFile(profileFilenamePrefix).then(value => removeArgs.push(...value.toString().split('|'))) .then(() => del(profileFilenamePrefix)) - .then(() => TPromise.timeout(1000)); + .then(() => timeout(1000)); markerFile.then(() => { return readdir(dir).then(files => files.filter(value => value.indexOf(prefix) === 0)); diff --git a/src/vs/workbench/services/extensions/electron-browser/extensionHost.ts b/src/vs/workbench/services/extensions/electron-browser/extensionHost.ts index 16a25f5dbea..f6f88704386 100644 --- a/src/vs/workbench/services/extensions/electron-browser/extensionHost.ts +++ b/src/vs/workbench/services/extensions/electron-browser/extensionHost.ts @@ -36,6 +36,7 @@ import { getScopes } from 'vs/platform/configuration/common/configurationRegistr import { ILogService } from 'vs/platform/log/common/log'; import { INotificationService, Severity } from 'vs/platform/notification/common/notification'; import { getPathFromAmdModule } from 'vs/base/common/amd'; +import { timeout } from 'vs/base/common/async'; export class ExtensionHostProcessWorker { @@ -505,7 +506,7 @@ export class ExtensionHostProcessWorker { } }); - event.veto(TPromise.timeout(100 /* wait a bit for IPC to get delivered */).then(() => false)); + event.veto(TPromise.wrap(timeout(100 /* wait a bit for IPC to get delivered */)).then(() => false)); } } } From f6a6db18c4138ae6bd43f80dfa212500f7395772 Mon Sep 17 00:00:00 2001 From: Johannes Rieken Date: Fri, 10 Aug 2018 10:39:44 +0200 Subject: [PATCH 0653/1276] debt - accept a Thenable instead of a WinJS.Promise --- src/vs/platform/lifecycle/common/lifecycle.ts | 9 +++++---- .../lifecycle/electron-browser/lifecycleService.ts | 2 +- .../extensions/electron-browser/extensionHost.ts | 2 +- 3 files changed, 7 insertions(+), 6 deletions(-) diff --git a/src/vs/platform/lifecycle/common/lifecycle.ts b/src/vs/platform/lifecycle/common/lifecycle.ts index 3a92380ea5f..3dda9ff7a05 100644 --- a/src/vs/platform/lifecycle/common/lifecycle.ts +++ b/src/vs/platform/lifecycle/common/lifecycle.ts @@ -7,6 +7,7 @@ import { TPromise } from 'vs/base/common/winjs.base'; import { Event } from 'vs/base/common/event'; import { createDecorator } from 'vs/platform/instantiation/common/instantiation'; +import { isThenable } from 'vs/base/common/async'; export const ILifecycleService = createDecorator('lifecycleService'); @@ -23,7 +24,7 @@ export interface ShutdownEvent { /** * Allows to veto the shutdown. The veto can be a long running operation. */ - veto(value: boolean | TPromise): void; + veto(value: boolean | Thenable): void; /** * The reason why Code is shutting down. @@ -108,12 +109,12 @@ export const NullLifecycleService: ILifecycleService = { }; // Shared veto handling across main and renderer -export function handleVetos(vetos: (boolean | TPromise)[], onError: (error: Error) => void): TPromise { +export function handleVetos(vetos: (boolean | Thenable)[], onError: (error: Error) => void): TPromise { if (vetos.length === 0) { return TPromise.as(false); } - const promises: TPromise[] = []; + const promises: Thenable[] = []; let lazyValue = false; for (let valueOrPromise of vetos) { @@ -123,7 +124,7 @@ export function handleVetos(vetos: (boolean | TPromise)[], onError: (er return TPromise.as(true); } - if (TPromise.is(valueOrPromise)) { + if (isThenable(valueOrPromise)) { promises.push(valueOrPromise.then(value => { if (value) { lazyValue = true; // veto, done diff --git a/src/vs/platform/lifecycle/electron-browser/lifecycleService.ts b/src/vs/platform/lifecycle/electron-browser/lifecycleService.ts index 34c1b8e99a9..08e31b2ad05 100644 --- a/src/vs/platform/lifecycle/electron-browser/lifecycleService.ts +++ b/src/vs/platform/lifecycle/electron-browser/lifecycleService.ts @@ -83,7 +83,7 @@ export class LifecycleService implements ILifecycleService { } private onBeforeUnload(reason: ShutdownReason): TPromise { - const vetos: (boolean | TPromise)[] = []; + const vetos: (boolean | Thenable)[] = []; this._onWillShutdown.fire({ veto(value) { diff --git a/src/vs/workbench/services/extensions/electron-browser/extensionHost.ts b/src/vs/workbench/services/extensions/electron-browser/extensionHost.ts index f6f88704386..e72d4340789 100644 --- a/src/vs/workbench/services/extensions/electron-browser/extensionHost.ts +++ b/src/vs/workbench/services/extensions/electron-browser/extensionHost.ts @@ -506,7 +506,7 @@ export class ExtensionHostProcessWorker { } }); - event.veto(TPromise.wrap(timeout(100 /* wait a bit for IPC to get delivered */)).then(() => false)); + event.veto(timeout(100 /* wait a bit for IPC to get delivered */).then(() => false)); } } } From d4a4d9588bb109ac2edc01b16c35fd50df7b8b64 Mon Sep 17 00:00:00 2001 From: Johannes Rieken Date: Fri, 10 Aug 2018 10:51:06 +0200 Subject: [PATCH 0654/1276] debt - remove WinJS.Promise#is and replace usages with async#isThenable or async#isWinJSPromise --- src/vs/base/common/actions.ts | 3 ++- src/vs/base/common/async.ts | 8 ++++++-- src/vs/base/common/glob.ts | 5 +++-- src/vs/base/common/winjs.base.d.ts | 2 -- src/vs/base/common/winjs.polyfill.promise.ts | 3 ++- src/vs/editor/common/services/modelServiceImpl.ts | 5 +++-- src/vs/monaco.d.ts | 2 -- .../browser/parts/quickopen/quickOpenController.ts | 3 ++- .../test/electron-browser/api/testRPCProtocol.ts | 3 ++- 9 files changed, 20 insertions(+), 14 deletions(-) diff --git a/src/vs/base/common/actions.ts b/src/vs/base/common/actions.ts index a6d78296e69..d2cca21d5ed 100644 --- a/src/vs/base/common/actions.ts +++ b/src/vs/base/common/actions.ts @@ -7,6 +7,7 @@ import { TPromise } from 'vs/base/common/winjs.base'; import { IDisposable, combinedDisposable } from 'vs/base/common/lifecycle'; import { Event, Emitter } from 'vs/base/common/event'; +import { isThenable } from 'vs/base/common/async'; export interface ITelemetryData { from?: string; @@ -225,7 +226,7 @@ export class ActionRunner implements IActionRunner { protected runAction(action: IAction, context?: any): TPromise { const res = context ? action.run(context) : action.run(); - if (TPromise.is(res)) { + if (isThenable(res)) { return res; } diff --git a/src/vs/base/common/async.ts b/src/vs/base/common/async.ts index 9b4a65a1bcb..f1a9a5c4919 100644 --- a/src/vs/base/common/async.ts +++ b/src/vs/base/common/async.ts @@ -408,8 +408,12 @@ export function timeout(n: number): CancelablePromise { }); } -function isWinJSPromise(candidate: any): candidate is TPromise { - return TPromise.is(candidate) && typeof (candidate).done === 'function'; +/** + * + * @returns `true` if candidate is a `WinJS.Promise` + */ +export function isWinJSPromise(candidate: any): candidate is TPromise { + return isThenable(candidate) && typeof (candidate).done === 'function'; } /** diff --git a/src/vs/base/common/glob.ts b/src/vs/base/common/glob.ts index 93365a9fb6a..6ec8e429211 100644 --- a/src/vs/base/common/glob.ts +++ b/src/vs/base/common/glob.ts @@ -10,6 +10,7 @@ import * as paths from 'vs/base/common/paths'; import { LRUCache } from 'vs/base/common/map'; import { CharCode } from 'vs/base/common/charCode'; import { TPromise } from 'vs/base/common/winjs.base'; +import { isThenable } from 'vs/base/common/async'; export interface IExpression { [pattern: string]: boolean | SiblingClause | any; @@ -646,7 +647,7 @@ function parseExpressionPattern(pattern: string, value: any, options: IGlobOptio const clausePattern = when.replace('$(basename)', name); const matched = hasSibling(clausePattern); - return TPromise.is(matched) ? + return isThenable(matched) ? matched.then(m => m ? pattern : null) : matched ? pattern : null; }; @@ -699,4 +700,4 @@ function aggregateBasenameMatches(parsedPatterns: (ParsedStringPattern | ParsedE const aggregatedPatterns = parsedPatterns.filter(parsedPattern => !(parsedPattern).basenames); aggregatedPatterns.push(aggregate); return aggregatedPatterns; -} \ No newline at end of file +} diff --git a/src/vs/base/common/winjs.base.d.ts b/src/vs/base/common/winjs.base.d.ts index c568d4d7b05..7cf7a842c11 100644 --- a/src/vs/base/common/winjs.base.d.ts +++ b/src/vs/base/common/winjs.base.d.ts @@ -29,8 +29,6 @@ export class Promise { public static as>(value: SomePromise): SomePromise; public static as(value: T): Promise; - public static is(value: any): value is PromiseLike; - public static timeout(delay: number): Promise; public static join(promises: [T1 | PromiseLike, T2 | PromiseLike]): Promise<[T1, T2]>; diff --git a/src/vs/base/common/winjs.polyfill.promise.ts b/src/vs/base/common/winjs.polyfill.promise.ts index 6ebd06ea511..e1e094d6521 100644 --- a/src/vs/base/common/winjs.polyfill.promise.ts +++ b/src/vs/base/common/winjs.polyfill.promise.ts @@ -5,6 +5,7 @@ import { Promise as WinJSPromise } from './winjs.base'; import * as platform from 'vs/base/common/platform'; +import { isWinJSPromise } from 'vs/base/common/async'; /** * A polyfill for the native promises. The implementation is based on @@ -45,7 +46,7 @@ export class PolyfillPromise implements Promise { constructor(callback: (resolve: (value?: T) => void, reject: (err?: any) => void) => any); constructor(initOrPromise: WinJSPromise | ((resolve: (value?: T) => void, reject: (err?: any) => void) => any)) { - if (WinJSPromise.is(initOrPromise)) { + if (isWinJSPromise(initOrPromise)) { this._winjsPromise = initOrPromise; } else { this._winjsPromise = new WinJSPromise((resolve, reject) => { diff --git a/src/vs/editor/common/services/modelServiceImpl.ts b/src/vs/editor/common/services/modelServiceImpl.ts index 560ed428507..1a1202dde3c 100644 --- a/src/vs/editor/common/services/modelServiceImpl.ts +++ b/src/vs/editor/common/services/modelServiceImpl.ts @@ -28,6 +28,7 @@ import { overviewRulerWarning, overviewRulerError, overviewRulerInfo } from 'vs/ import { ITextModel, IModelDeltaDecoration, IModelDecorationOptions, TrackedRangeStickiness, OverviewRulerLane, DefaultEndOfLine, ITextModelCreationOptions, EndOfLineSequence, IIdentifiedSingleEditOperation, ITextBufferFactory, ITextBuffer, EndOfLinePreference } from 'vs/editor/common/model'; import { isFalsyOrEmpty } from 'vs/base/common/arrays'; import { basename } from 'vs/base/common/paths'; +import { isThenable } from 'vs/base/common/async'; function MODEL_ID(resource: URI): string { return resource.toString(); @@ -500,7 +501,7 @@ export class ModelServiceImpl implements IModelService { public createModel(value: string | ITextBufferFactory, modeOrPromise: TPromise | IMode, resource: URI, isForSimpleWidget: boolean = false): ITextModel { let modelData: ModelData; - if (!modeOrPromise || TPromise.is(modeOrPromise)) { + if (!modeOrPromise || isThenable(modeOrPromise)) { modelData = this._createModelData(value, PLAINTEXT_LANGUAGE_IDENTIFIER, resource, isForSimpleWidget); this.setMode(modelData.model, modeOrPromise); } else { @@ -521,7 +522,7 @@ export class ModelServiceImpl implements IModelService { if (!modeOrPromise) { return; } - if (TPromise.is(modeOrPromise)) { + if (isThenable(modeOrPromise)) { modeOrPromise.then((mode) => { if (!model.isDisposed()) { model.setMode(mode.getLanguageIdentifier()); diff --git a/src/vs/monaco.d.ts b/src/vs/monaco.d.ts index 0642820ecfc..96a56b9807e 100644 --- a/src/vs/monaco.d.ts +++ b/src/vs/monaco.d.ts @@ -72,8 +72,6 @@ declare namespace monaco { public static as>(value: SomePromise): SomePromise; public static as(value: T): Promise; - public static is(value: any): value is PromiseLike; - public static timeout(delay: number): Promise; public static join(promises: [T1 | PromiseLike, T2 | PromiseLike]): Promise<[T1, T2]>; diff --git a/src/vs/workbench/browser/parts/quickopen/quickOpenController.ts b/src/vs/workbench/browser/parts/quickopen/quickOpenController.ts index e35dd586dd8..5d64bc0a385 100644 --- a/src/vs/workbench/browser/parts/quickopen/quickOpenController.ts +++ b/src/vs/workbench/browser/parts/quickopen/quickOpenController.ts @@ -56,6 +56,7 @@ import { Dimension, addClass } from 'vs/base/browser/dom'; import { IEditorService, ACTIVE_GROUP, SIDE_GROUP } from 'vs/workbench/services/editor/common/editorService'; import { IEditorGroupsService } from 'vs/workbench/services/group/common/editorGroupsService'; import { IUriDisplayService } from 'vs/platform/uriDisplay/common/uriDisplay'; +import { isThenable } from 'vs/base/common/async'; const HELP_PREFIX = '?'; @@ -157,7 +158,7 @@ export class QuickOpenController extends Component implements IQuickOpenService let arrayPromise: TPromise; if (Array.isArray(arg1)) { arrayPromise = TPromise.as(arg1); - } else if (TPromise.is(arg1)) { + } else if (isThenable(arg1)) { arrayPromise = arg1; } else { throw new Error('illegal input'); diff --git a/src/vs/workbench/test/electron-browser/api/testRPCProtocol.ts b/src/vs/workbench/test/electron-browser/api/testRPCProtocol.ts index 4d9a092e6be..b62caa2691b 100644 --- a/src/vs/workbench/test/electron-browser/api/testRPCProtocol.ts +++ b/src/vs/workbench/test/electron-browser/api/testRPCProtocol.ts @@ -9,6 +9,7 @@ import { TPromise } from 'vs/base/common/winjs.base'; import { ProxyIdentifier } from 'vs/workbench/services/extensions/node/proxyIdentifier'; import { CharCode } from 'vs/base/common/charCode'; import { IExtHostContext } from 'vs/workbench/api/node/extHost.protocol'; +import { isThenable } from 'vs/base/common/async'; export function SingleProxyRPCProtocol(thing: any): IExtHostContext { return { @@ -106,7 +107,7 @@ export class TestRPCProtocol implements IExtHostContext { let p: Thenable; try { let result = (instance[path]).apply(instance, wireArgs); - p = TPromise.is(result) ? result : TPromise.as(result); + p = isThenable(result) ? result : TPromise.as(result); } catch (err) { p = TPromise.wrapError(err); } From 8157bdc4d39beb24722b5a4f57149a787a24dc91 Mon Sep 17 00:00:00 2001 From: Martin Aeschlimann Date: Fri, 10 Aug 2018 10:52:45 +0200 Subject: [PATCH 0655/1276] Update the Seti icon theme. Fixes #55956 --- extensions/theme-seti/icons/seti.woff | Bin 33560 -> 33988 bytes .../theme-seti/icons/vs-seti-icon-theme.json | 738 +++++++++++------- 2 files changed, 448 insertions(+), 290 deletions(-) diff --git a/extensions/theme-seti/icons/seti.woff b/extensions/theme-seti/icons/seti.woff index 476c5a9946b3376e78964051db5294494b22ef43..ea92f2627db5652f044ca2fb6fd8e8ae918bf868 100644 GIT binary patch delta 33752 zcmV)OK(@b_h62Qi0u*;oMn(Vu00000gv0;~00000${>*xKYu%8ZDDW#00D#m00RI3 z00~g_nLC7MYW_xyE&FaFbiy<_>MN)4^Ttai0e~q?1QH<_S-W zzwa5(dBICw@tQYu@s@7h@tzNS&yGeqVy zMdq_a=CeiSb42EIMdtHF=JQ473qet3jjbY$Z6b~B zB8?p)jh!NmT_TO$B8@#FjlC-G*(cK5FVZ_8(mN>9JEZdd!y@e?BJHCh?PDVC<09=7 zBJGnR?NcJ{(<1FNBJHyx?QWB zk@iiI_AQb2ZISjJk#?I%yIrK+A=17p(!M9szAw^#Akuy)((V*#KN4v_7HK~bX+ITd zKND#`7iqr`X}=U{zY=M`7HPi`X?Lmo|M^zroNkeG-ie&^UgVq)BIkS*Ip>qeIiE$& z=@B{Si^w@&Ma~)dCUVYqk#l~CobyxUoL?g6^opLpe4wVdlW+twe~}Sx3`iir#>gX( z4Hkxl6*Jg?Fdl3eWcV462Cbz58;s3@jbXqBgTaG;_+myi`+br1y2UQu{cYE)s;oTX z{Eq*3M07zbz&|e8Hw)#$TH#FLxrIWv(_bU~-e|f_rju6EAW0lbmq@`nQb-XdaS{&) z)5&x)>i7D+AWrgEe<0V%8eJyEtk|BPf(M0q^|NS*PfRCccu3NFUiWjie{^#&*!<}2 zKS%hTcYJhXINbQ?9e1`~|MHg{y7baRFM0Xv-+ar9_HA$Pd(kb=wXM_*Y{B34FL$_J zU>W9p^>0uE2# z+3L{$xY$2@^gTx|?JqW4mmK*oM=ohKXRgK!Y1&es{R{a@ocMh9*Yt~&=~htgEZ(}O zQwbe||NW~7<OT@kjWq)Dwn_`brQxA{>nBI7VQpRHXh|;r(QACT*|zVd)zhy z+o^fd3yjo(563qGFA%XG7=kgO?^{g$rdf&|A$-HBB?l|IrB|v(&tL}A>uy;iZ;8XI zZtK3ssML%w@^sf>z+%T1zQ-Q&`mvP#ePMW#5dmaf1YoA@WJ2s@VpPJ^luBb!gk>XML!*A z?m7i(8IO=O#?uLqKvWE6CcC>d(Aj0k>7?JAP6mo*BIsQ|+`T%Q^wrfd-i9T_68Uyb zJp|*iO=28`m^`WJ;_QI2dwlNLcZ>Usl4LexWJS};VMB9)5IQBSWI=5+K|tW>xPe}2d)9!`OU=7WY@2qOR@Y%Y5yJvcR)_JLQo zY0{t6D{rG?F;U$M6;%OfCgZ`|8c4QP9?Q8H@G$P8=$ zv07BOc=dT+?A9X7Ga@%M%YsYI)tdX4PVY3c>H>4Rl+>Vax~bVo)2~8-jlr{*e~Ui1 zp49!v+#<- zFBX2Q@Oa@*NkD3(52K+vv`#ub2^7&_(_v0OJEVu*USnf*gA!dyP8t&=vAGDsK}+H( zo@(NdjHe?gU_3!$MM|0uK!Q!Ce?z=wa*)6!&>A2C*BEeJ9Bt#UH^~OlYQ78_vx&*b36n&@|_LTuG0uTDZH)&3)wpg5SDK(FbWH<#VI`2u zP+n=x74-;aupCqSSA&#Ln0`WajcXF5D_?dxm9k(`qXLAa?(3Q@EhlnK*Jo#Jjjb+# zq-Gwg#ePkAAZ0kAW(`iAe~mk>^>*t&q`?-4>O(^^joShAh=x@V#(c1FWbbB$rDoui zJh{+HqaZXKVawC)RcJ=*%HQ(>64t{&qZac)^qWu)(Kxjop%KSq)ZmozMm05;D?)ey z&w`!Zrp$7Dda@Xgksc~)?1n!^&6p#n~e+7On6)Pr#LG>7D z8m%ZmpD-FHrT9jJa9a?~K#pgW9ZsqqXq?1u`cMRsHt3zu^bNgeRSYVIRi6^A3bF}q z7KSY(v=EP_rI}|tYwh+%>(j!7vDK+&Q->KQ)dSni)+yi9+9DbOwMZGX5`2Dgx{a#?*j{YZg<#<2<+@Kn?ugR06HC=WhDLQjTkAi7-= zHppNy1*)VD*?IDx0_*Rk2OUako*PiwtUrE1|k$0rVPFk*&+dXIK?2`8eZIhNNt-E?3WDD4Go_H_|xhF{8#rvPbVE^ofR=mvrk zvc=f-%w&2^O2C?Hdazk=sxuemq9X43?@a!gad46j!yAAHCl*ui< zl8H}Tpm(;Ptrc4EW19?7r{;K63JMwx##>DYSOue)yo+-BOZU3f$Szx+u=agxU$7EA zRY; zDITy|4<;S8zf$i5Y)1pm_Im=v7yN*^&wAV?kx*k459W{)zSamZ1!`JEs~M-zA1!E;2YpY1Ouw z_k1JvQ?q1xx*66RzCj5Wgf5i)70_QnuN?G@O3iNey!BC7xyqK(ju0KdTIY5*kccgKkrGP2Ha0elQFDTyfj=>0r$LKO=`; z^qLoM6MA^E_t5sOjn=;cY}uPKkb4H@!;Y6p&*2tx@@LwUW6b4GDeNh=fUwMK-_ver zZ1#?U3mO7dY;c!gJ6v zfZ?eVv=G(MfWD5Cd|>jy3VMA|q-#W(+R9=?qHYl7=nz?tb%ay`6G<8l(3F(wB0Qi5 zm3+@EYb>eyO~bZ~>*}3OT{A_oWJ1UMlKVv0=`L+vwNdnHX1v_)f0o#(*IsdS`@rI! z1>?S>uk2;ZQCzgCAl+>9>h*EDzf}hUCgh5p!{j@`Mnjey04rgu@;mV*CwAgu?6wvX zn2+Uz17on##?>3Wg?5#dYkQs26|cR#-JBYNJbKAA=AeF{2~hWC`)bJ^>6rYA*LHim z^6`uG_dyRga|t0pfA&j+#_Mys0g;5rPxfV>evzO*S^t>>85k)l-$wnWf6N-N63EqD4|Q`r%z}=U zti1UA9mjfsi~_$|w$KYfq-O9k_Z+D;5A&284A3MA2HBoUEe#_PT4A}qe9cWsxt0dq zO2q=?&f_vrUIri@>b9%P&s=*3*Pgw;6?mwFbt^K9ATS6chI2fIGeDKL^cOwu7F)fw z{wNryOSO*ae+0a-+LB<`S#GH&O_*wW(YI6vd-j3Cdr@bt6R>MWFdEySCf0~YI^!N5 zpcymCb+sCZjdp2X4Ay|zUjZA2ke`KDf!C)G;)9~#Q7&qKn1Qw?r z+^}Ox?lF+Yn$M+Y!)0!pAY^}9A)wEp5a|O~{j@>^7&^9=7Xm++^^dF9ML}mpeUiuj zjVBzmuki^}aKrk))hjp{bR3?9dhJH-|D{@02;6Dv!u^RtI#M+rsVi^1Q`x)QDEPdH z&t`z}f42%pV3z-XVf-kIhS6|59B0$<#UB7S53Xig3fdP9D|F%@0%-3q0;W?tPBS5_sQ}8{o?~v+kf_8==TuHGbRixn*fv#ONLdtvK^K@x9yeP=E{BJ zm94E6w!J+*e0aP|rw7?>U>O0}0;((WZn4kSe@R=CAN}tSkrU*^LqERuT5|oh?6zk; zYj)44K1F{1S+l3T{q1j`_dkEuDFjb>x<5^162K@-`xgrN`fvaC((7J#*cG`Bw&u2=2klN&U0@Xk#deWH@zZ%V zKkfUgbTC_d&wIZ5)Bc$G#=Gyu#l;JK`a!`gl%P)`X!j!MAb^b{bu^)0 zd)KeM`=h^fs@FaL-kr&{*N`8-`gP<-e}@}49(dpE<5yk84q&hsx}XW4k;~lt1%h%i zcgicpcEJz;1(1N8$dq8sF5HdyE}l*j zAD^T{rdiYwRP$cUbWyZLYa20zJQ_Bryo$tR|tn9e>j zy@k8Y3ex(B6lR>rv_Q}oEA zJL=zY{5Ul~B0YHTq<&lqf82^RK>RQN)2m*=fr4bYzr6L9L;FU9#n@OhJ)j_;&8nv7 z#Gdz7E2`N^)8@7;S)&)wuWp;$&i0$;Z~QkF+M4IfpwW*!6A*+`Od9T_m1(qD9j$E? zb*2G$v&-*v6URy1qku9r-HI)PgUyg##6^eb|0r}&>jN7q1iyydf0!t4%e~mp@iBg~ z<><1S=DYEVQyT7dY%Pf++t&EzWMlv2>7rY&>GWBVS?7`I8@H2ezIyM^Sk}2`gZxC9CF=&EXu^dhG8XLW* z_ea@^?*^sC-ZQ%Z4URAQ36mf3$MoT9z1UhPwHn<$r$@_iiP_%5>WNFvoIHK}gHJwLrQ320d~Tjxc*Zmm(RU3z7Ep|QHKwd()Mh3?#>d;eBv+RLkLa%9q62yGdAX)Ov) zI#OJ^)n4(PXiwGiX1}=G)!ZmtU<=S=UeM>978eQzY4?+HmlR2{jhLMz?S66ECO?{e zgKod{HM38{fA_Oz|M2R!zV)rMKfZ^wUVr!O$K;!{Z`}6_|EoosPkx3RBJO+Mdf!{g z#_L}{`^McD^~Wmx9%$-fAu1H6IT(zTIO{RM9z{SQkJR^FpWK+7-&r4}fAWUy?H{i{ z^A{KHUto`&J9YIkBR4+s$n4wO+ZW0^2>OUayNf7+e_7BDcz--iqHdG`+0hTo-u>=( zlXLgaKK|&VkIp`R_uY3hXZCFj27c?duibUm*B*J`)Tsxq+MVzBu{!jA6-q+kFjfXk zZVzJ{fsxi2%H`a0!}t)+Ke^{N_Oks^{jRiP>6z>WM)lVKyxW87mP@%vS5kZI5PFBv zGp;3He?5G($$Be~FD=LJUU$2unf~j*h}UagrW4At?PhR1AoP9k$l6ow^}3oJPN{qYjJ$H_DXWzf~UK$Yd4fnj^4a7e8shi;N-Z$KPQ68+agNQr;uFIq^ zr~N7U(YY_btM{4D^d9_kcHq(G17E)R<}W|cf85n=^hfM^;A8ZG*3jndW1ukN0m{Vy zRXYwuz=Ca(&?CnVcVtP<{`s?iZWP(kzvhl*S^S%y{p>TSBk8q=Uw?&Vec_+Tt2(A| zW-omc15=c;H;`A&UQhQp%)aP%{aF?i-d^}n;Xf6gDEz7NvdL`Hmtaq$B<`tjQ9k&& zfBQ9wp&h#cx@9uXZEZQt5k-HfK!x&%DN7vnKof(Q+vw3nizg3YO)*yFk>M0f$Ek8> z_2VWT_MZ|dpY(f3t2<=Og#s_2i<5XV4|*y1GQk)Z7B6I8__C6_aQocni%pxb+cj!Z zbDNrFrq_$iOwHP=1E!uGku=$shN}T`e+Ko*q_2TW#UPKSNt;%D-LZ;#k+FvBShOiA z)eO_}Yuu@^l4I)auFDzWsn^h=wOG^FvW{mHUDJqg4mO?}Tf#EiC8N2v>e#xaaiB{9 zDqC_*o4rO01IpIgP(8=6P_wSBfT-Y^LQ;R+*>ol|v<*BWIa>ebCC6GwfB8PA0ORy8Qu1sVEPcV*vnEdpFqh$Dl(`ML$uIJ^?zn zTR2|09G=YP*sMta6e{>ORE|yfg&4O#UZ;`|CevVuZV`1JeH9}`=9yGLe+3bLKa=$S zTWqEgKv3?vKv?cA>;S!3 zxz{D@=e!LUzDmIS)*mEviv!@cz-G2B0E@Aq18Qdj3L3wcaM~;iF=ouIIA%A1SuQ%Y z+V|`A?*MTE7PEO!bAF3TgZ#kI1wj0F5xQ670MsbwZx%wYR7-xfe`3O~w+t|}8brKR z@*~Q|OhB1T#ar|c3jIN?_O}L;1a1u~-fwZ;o{z(b?J3-~OmIsx z(J-=P8ZdG41avVle>~6T)G)yA;vh5ZwT0Ao1gpel->-R`Fp(N&t6cLPqt`v&Se#GQ0t*VvAj<4k8@f?#h*-4y z=(|W6F}Wz$G!R){J%k}VASHE^!I7ia9DC)}u9v2_pT6RXe^a-o+;mTc9;oR^>6ib` zt^ur(7W#$F!c~QHh1(0SEBq_bNleD%7Z~&z?U2D3<^CiYC~s?)$1vb8Li9fd zIgb%UBy5Rke^cnk-DYvbvc5`u*->*kLO&W1?mRPSGKL4IDqx}FF;k@s@LM^=qZoKO zjFSOou_=TI4a$(ecN4R6aM@d@c{{;YMu(defeM?9a_rt9czT|K0yicd^u{IVpNm91 zn3D|BVh1R(myAbiOhoWt7*C;zeUM}>mC6}}4pHoAe{S+jN1bp8kL2dhAeIBThNfkl zU;-Z$Jit7OY1kPJqZl}N1ZSWh^gt!!TIeoEK}3_tJY;#6C3Wj1wUQ@wXAyvgQLQuE zwc+n(+X2E9B~F1(b?Ul~h&TWvstJvmw&R#o2c^fQW>D7Q28eIK38tW=2G$iP+~MT? zLKBQrf2$}vCWwZ>mWJV?Q&4~vZ(2aZ>t&6XE2qzFG<7rRm7Iv#VEKAJnC;vEYZW66 zR5Kf#`-bLfx^RThG`_ZTVn1WROuF`6Uj#9WvNbow!NEdH*W|Wg+ktHxO^|nt zv69I(rh%LiB?lC{l$ypm!Z0bwO)ed1^gwVO*wnEpfmWFy`!#Bp7-l^XI;%3yx#L<| ze|^)9?6h<|ur;{H1XZ%roGjZKlc}9XHs_&Ubwx$zrqgY~)jiYWJ&jRc!z#I8%qT@x z$FC;iOhd_RK$jeWqBrGLW@wyI>M~gk!j@}!A@uY%zFLc7${VG=QhOP(TTYE~;%YYU`$E z!B8KD@nDwFD3!`pp8MqJ-?2f#EL1^*uNPibxVLbB;RA(_77E=-Je()Laphe_Zk>Bl zyU4gvnDr*Sb5J481_^p7jMhkQDqhHlih#>O@T+9H-Mpv>Id%%{Imem6iqlaKf3uoK zD9yIPHb9sC03Q+wia_-PBp|xgRWmS)DNj+1C({_)1W=uvGg8T-SZ73#f>zWFn0U&7 z)eMK5vp=w46iY589|L29Sst~$#44K0x8Jeiq@GnW7==4Ekm>e=VAX?`wo*+S$9@e-;(+H0TwBC!u3=J(Uept9Zby zcIB(Y1^sLRuQ=4Ap!6BHaCZMmfR!L@C+*qrZ3-_XR|E!7aJQB$n36KHWJ-Z4Kz8Hc zMtQO20WOxA-cG6^1yTd($0`+QePeB5Vmi79231&d%b^>ZGI}@LQ)#bee~l~-C@n?Z zMz+=}F9F{`J3J2J0UF}?+^23txohv*tZW15qF&g8UZ-S;J~q(u1aJ%H|3&jOW+07z z=#tJF`rtwNkVigx!}F}`4 zr{8h%uFgU{`|x`|_r5dBf3G`v?a5<%mXFFS)Amy|ii*~NlG+VzMPg35%6Xw4>GTH^l|-MC33b(zrPCn%`&WWI3OqC=wBT8l_D~ zmq8$PFj{&p_YV<$e;$K?nJ&Dq@DPk_?iifAc>tyL$Gy3Gdz5X?jXoSk6;4w*+At4z z4moiOpe_T9C!#!nj)61<{Un@M3S7n7m7`Y$%Mb=&LL+89syRX*`XI`^y19pPH+2YZ zL1ZxACUQtW&17UcCQv!oTt958Q~?`Iaf5kDm{cM^&@32#e`Hu82~TWS!>}ZSF-tgF zVj`8baV-_80A<5$&37pU_3HpHO4Ih!6y$_oq&4n(3ry6uWVu>yhNfpxgNzzR)3HGE zGsl4kK?nZ$m&kVr1B0qk7MfR0k`7el3eb=s1&TOTju~N&H)za&Go4u>2ze&}i_*|p zkitZwpE}|`e{oZk2w}i@nkS89%2GnvOh(J{>c znlV;PGxDMmsDG!JTD5U0`rqdKL;pQ{EuhYkieCVotGs53@lKq%9%g*^$8mru^x@o% z0BBD|PSHRa$Nk9=b4qtpp!&*}kPGu+GH4R@4821*e}-?ZSs5`&&odd-oL77Z#w>1i zwk|tpp_>?Ri7DCd{;n;rqk>~%uCVNN+tj6DyZYGFT<1aPaC+v7%daFYGd0c?!4zZ6 zF-(!Jr&efdZStY$`uJOQ4w%0L>d*3(2(rZcud&>FTcmJho+ zoDQUvfBFT#3;hneyxM zxNASaZ}J277*bZ}4PXe;$AQH=Z(LyVF~XJzee^jmWdHflGuY*i3icSKk1^7D)02-; z@;JQPZ|tl;_9!I=yq`b&AR+L5_=bx<*e6)2e{f^r7xElrG&nIV4-$#?(X*W??TX&1 z+3elX3rQ572(8)kva|m-*VXhc$mu;YOhS?UHuCZ$lHwS6Zt+wM5KwP^B zf5ML$Ak8{q1%V60e8;8*+zX)SXj79nX=T7GkrPk=NrCWf&xM`@=KVzABGV=*h|XilH^>u`(iV&ZaI1M#mrfA zqRg-DKLAke(e)plU;iNeLiNSfr`>%ii?5H-R|8*+E!?-D-m@dDSa%;}cizlOf5%GA zVU;akdjtLZ4p^gN) z3uX_I>r>-@X#2amB?&V+rqd3dy#LwfF7O#(9H#u}g|70VOLRLW^uF0+e-A!LwjTW3 zE3f>GE3f<;keKf5AKrxjcKP!M^uH7YNROw+d-~(#$B(?_Esu~Nee$hu{Ui+@zUut> zs~%<#pE-a2%)@gUi|H3(Y!(Z93ujQ@j!{VpWsJ{tV$#XO#>mAxn7u!liew6)Tgco} z&l7!f6)VAlS9!Ne7w1{~fAk5VRs9`iOnzqkoFkw@%Jra&8B~E`YP{$hW3jh8*g`@7G7L~sy{UK3STgjQ-py7-NnYt{wh{PFfAm6Q*Wc~Z9{{DS z7cMEBEZl&;#$p>2l(0ji-ZJTU6vZrbHAeyHfle@uR`D5_$+-mVPf9r)+{K9pIFCOL zHYsC=&pLtU7`77tKoN8+1rfG6r-M5Ehk{Nw%DW;yQUsFc@W8Z%jJ#6fl(pgrqyf4u zgYX#lcU#L=`D*)_d)xKF4VPaR3v+pT_1?9?%b#{Az;z(A$BrL7aP-*0ofF4inJv&0 z2ettbD|CD=e{C9OPp96?Q9tR67waxp2G<~wQ+=9QS#M(gqq=k*bLF6#ynVhF1sy@%x zP!g5#hN;AfkSa?ND98oGa^fBEN*k(I#cY-n41 zkH7LLdBgmvea8-FbD6Zp_JW=BTAVXnaW!9zhc6J9xidA&oviZf5PV&&&zGL7=au>cwB-6G8Y+akf)~g(fFB1b?_8hH8{|-5JYIw6kM7CKs&(7 zhGrIJ;(8U|3H^!a+GqfnbU6(60+Q7$JLAVXN@A!sCViN%oMJlZVJ3k;lms7A-`^BYV}~K;-q=% ze=rO_6}=0~1eA*u7258Su}ObKE*Ldn>U31bp-6BMm|7+KzXk%z=_H?3Ncam(W6mla8s?_ji0zliRg+o7x0GIM|Rz zYR8z}T{88W)O6o`SlCg~4h;iWe+DxLsxdWYM~SewZZXreqL6-~yX z*>4A!$^@`ox|Za+CWHfQI}o;OfN2b7>R!sw$*PG(Sra_AQgH_Q1lk`RykNO$9lz_O zVDnmvw?Hid`nH|gR#x&29vd--a(FoVHagTO1rTlnYC9G6c&xEH+)JY#e{?Tiu6uqI zIM7atNn1-)YdV2#fH7`zy~K#FNfFp#Wa>mS?XX^UXMcXz5810MOLrZ6vkt{My^`Cns zS~|>v!?++4t}&^W?g@-df1d`JiS9p`SBzO}F7_NWo2}Vk;7d#uXNU-1!h~z-o-RwK zZMkL%F1u|3&G)3`29Y!ZPuS85ov0ERfnc*HMkxhB#}TH5aj;^r-1WSd}RE5d%e@e59srO-&RF{Dr>rBkv3!25mv=?|e zjwiTbmn>)n(J)@ak(ntW=ANXu-SmpC0n(Zh2P_++F`jrh zs8wu_mQ1Y*w_m0~zd?L@5~R89wlEVK)B(j>Xw|io&(~rJ=m3|kfT5cNu1~400l5LM zehXg|_$sF;@AYNSCCG*67H zPtj`j9Zjvs)=)7Qle#cUKhQvgvr@LujiFIEgKrQP40{vWvJaZ4Rb4pyF)|efTnD3e z`vx#qkzS~_Mu{mjO|N=(k&u5OxX|8?e@dme)MzD9u`xV&U?}JLkeAc16#k^}XN7MT z{;u%f3qLA6iR&tMMU`6m8|~&`V-#)@yEGSdAeiJjnS!9pc^1V;s6y~6Ob9Y%I_wYS za6AR`aXL>AMSMKZERc!J##4O5A%<^akhKG;!UMS<5^CrVBYY<@dO|UZKSl?^e;C9n zJf)IGKq-y;xE>E|zRh`h+QkHNl#Uaat8p?6qY#r$G88paXvhvppsm?>KZ&3pJrr&T z4^IIz?m6?48`jFbrdCr>)Ym(+8}h8N@~=#_7rvt*BEL zi+oUR5VdOo;4$C=gSXoetN#YCf26&oBHRqc0E-i%D>24sk5?zW%zcw8O9uD?*BIBAf}&r-b=%AZ@#d8sz&u6Wvq7egS2vbXmU+Y| zflTp2I{|d6JE7}xiwT|4Yo*~xpkNT!6nDj;5_!{;9EPqn`%OYGg$Ggx*DO;xzMts; z*cycV>1CJFBM*2sC$6ipe~Z5K8Iy%6W-SFO(X2O8NChT4%hTd7WTfOFDG{sHxav9v zx<*;I6Jh8&3YW_BLVdTtfx=jG%LNoDLklsdqzPm&KrGmK@=4l-d5Z4Rt-TyodvGt~{Gig}K#+G3s)!uLNBb=3DYKX$%H( zU+sI9i{)vL9@kDx)>$!pMkCc~j%goSt%v1O9O*{gOs!(f03S$~Yt>-A3@ja(4liwk zX6KTF$;LyBe?)qm85$}}i<>qGCbUum#}sY|wk3?bVVcZ{O-x}D)CD7jfaM3qZ{aE+ z7zVY0m*z-LpkF4KNruVcS@X)1Lx4>t863ZAz;x~%@E&HGyYU4Pg3+eEx8{S=y{;hU z>kL*4f2Rv~7v5F)aN$#hAF6d|5$;qbvfPD&n*rd$r||@n(?FakXpS%)my(Y2#pgo+ z(s`;vIGpC9Ciguh{dm{fz@$qg-RU+}LTc`cQfYY@_`49okAq%@D|{8L#>&kyo{m&i z2`;`;cSZAMtGFfrb2jHfkR*|Ex_G2B-;NFFe-)tn!Bo<- zvM%++46hEI29OB=J4EcDbToS})%12)k+DFHR@HQfktv3G|)d?purlynmOT>CYWTj0D&+4k#a>t7u)S zGf-qY)7wTfIK6H|!F+YI;lNqba8gj#+#S2cuV7d zh>Mw+?KCvaghp%uLf5%WYl~r*JOlNHe~~oyqTe2uZZ9>a5r48Do3$#mnbeV3@G2KUZ=n;B?o~BQy*VAXv8|bs>v+48b^XUueZS-aI zPWtooJbg9&1+d9pOYfy`q`yqxO5aW&pbye_(f87SPd`LIOdqBnqrXdkk3K?wpMHvd zn*L|{D1DqhLH{d7|7!{ zVKQv*UcD#r)2C3W{8CU|ZzN^n5&87L8;Pg2K?hvc}A9qdg(G9(j}S11%zfgnNn5N^Q@ z8llIX(U?S|UNY==pj`uxe_(l{Ba@7bqd1g#TZggi!?no69e3mieZ}|*_QYr$jr(CV zmebKdPC}_Z`(bA)r}&Xbya5kAGKJf+ekbE(8f}d6k&R(Cl=C0zcmN-&NOgqI9wZw- zaSjWKWQL*ru}APsek=!@*>H!1n-XfqH8|5vc#k*WQnW)hB>aLef4q9(3-0nTf-vmQ zPxOWQrs3u|nr^BaF5FGYkEn8OD9gYIBvr9QLOLKYGN$QL8k)*&YA|NNl@&^yz>udv zY>AfvL-yXU@ki(Gk@<_#?=r9;X5U3Q0aAQ%!R(@= zpry%i5G&dN2}<9_f2}Gl;0~xb^(pCqos41=n(> zO5RAxonYwR2X}C=fDS`dpXM60Z*8kRJACRW7|{IaaYi1de~t5ZU~PmPW-9Wszz5^q@WbNhLKg=B5C&cb!V=Er>;JY z2GiyE_z4X?!N=g|CENJ>mtTWE*nABWAwPp3T=|Nl66zW?S@VlT-8X@Q4R}wqLH-!Z z@e2hI?KGWze@|KSD(P2z+Mx15xCO4?c^&JBb*k<%r3VjcO}x=ASuoTwN5S8#X>$si z`^d1*F*>yk1-f{Xb>KYTj|&~>F~*LgvwoYahLA^L08&7$ze42fDk>dI6XbcAP%P!_ zPf{DFCxFQ!ryl_I#=gR5F6!p}T;(cjhdH?wr}h0v3%I+F_J1fm0k;~T7EF8wr}+W# zPSm$D#^KOXG?~ZH!P$Ey)-!u`3kXgJ_zVv4``fcUq zsEHcG6u(EQwxc{WKY|+Hd6a5bQ36&xS(>e!26BMHn~dqj9mbXzvjgw@@N|TZe;*%G zPoj&E;Z7u=wtsR0*bq1uKL301m&A27DtzzAY!#q?b7n>FG+UXHv0$b!hg7We1eb@T-IBRF4vAfC4TM| z%9uOU?c_NDd1TNfLB7gl)EnaR3Cu(Z1$q3$`4cC%4_$Hmu597N`F?w2?a0RZ`Sv

`;Vu}mI4mZ^DSY-N*}3`d z+b+ND?kk%=#+-C!lgV9o&Hjk|D1CHpJI+`|?Lbf*3W>Yls_nKWQ+n^6H-2pPuagl% z8Gn1egI%dsz3#?EG5KaaH~c33alQlBJQNDX7cNi(+mHO%4m(az^mW^_(rtOXa>3tmpIFIKQsWICFXx*YJ&!42$u0U^yD+vU+iz zB=E^XpFs5~OKhyo`Q?zQ%w?5xqtokWiYCT zM>+2vKl_Y*oF5&gM$p~q^>$9~bh|rV*KlmJi))h>b<5Hh;Q(aPDu~njnK-Knu^yLR z_T*oJxu9{!D$z>SWDnkP$7}^R9Xm5xd-~MrUB1~FopA-(>RxhUXMyx~PHZpSX%&qX zY1nef@~kBZMvkuuk6jq67k|=w3lg|B0jbgldQp4sw8uQd4S2@GM197xo&Q$9coq%M zf9WA|$CF=QTsrg6=dU^Q5QxRz;?m0EH9wwxbZLp+`{R|RC;#M?uYBmCmCp@sdnNpP zXyvNH|D(>h&{6)apI#^bx2ycZHD}(>Naz2%#$2BK1^t5Bk5j6Q1Aig=ED8FPe5+|0 zfL!W1Vf$&F$X&VdWj8JvQMy(RjP)CDqi5~q_Gr@DW6!>tk)GXYEiE-OZ}yeWML*p> zCJVn(_(Sv_bc>_iY#@OAVW!f#!gx2~LG3uEb{Eb!8W>LFrlC#tkC zOtHYVyDHfP?VmWDyMIRWrJBkUFhHkPvdh%N!FY{~yHnh@HDB_n9H1gmyBVsK;|aPI zvf(%yfqdi_zR1Zq#reF=HJU@Qrhl(xHB33?vbs-{&9wKQ%P*%@xM?&~^0 zLS5%-_w>+GR=m)`%D1J1%iE0Dlf}q49V_HuMzd1Ikan>MpnnN~6WHWjau@K4WcASi z@Dca%c}z&QHPbT!GpaaI30TQ-jgoC>vyKM0)Z0y87SR(SNy)RgS98%zhT9inqQJYL z9*vqc+c7{}2L^`iaHncYMe0;rj;*_9NrDV{lDt24(g?6Lz&U48+V@F<;FMF%;qXsT zT<#|ru2i>#uYZG>vx>k`2EZmSt>r5V5XhL=ABP&eWFojQXdSQ?RAvW06R{!7Cd1gI z0)XgF!A-EG&TnAVA_l26lNdCB=I%Esrg>QmePco;5a1?3jM~~58ZB+nDocXNBFz9s zomfndb-Wd~!jl|q0cLom`Fb+uFiYWwI`CZ|bl7@fSbvyeo@WOQ${1}{ux)!J&)WNo78({|%zkg>%z9iVk26=pS_e-^hk} zs6XFFDget8ea@qNEls{_&sTwfD;*9f zG#S@~WIkJHH(Kxo)7dLI1BC2xvs^D0Q&ZSQB!5vJYp2Z8E2;}ZFpFuD6?tv;DMG3h zjFp?Z=0x`c_%v`49l~RvN>X!d3ANaPMo;yuWs5D>J4<223|TUKC#{z{8QU|&*eqxo zTf`PemoNfd%Z!<$wt4WFwzyO;TflH7``h-w39Rw~pkabEh`BZVCMObsV4#-mDmht8 z1AkoFuXEcsG3`Rnfh}Fnc9p?PV@iW@ADCY=DLU4D%0c{C z>lSlF!h?fVVBwMjy56=yT)w$wmb<|tT0n)Xhwf+8hN8UvyuAxt2$)>lPgx5p$x69s zc%n8cFP0mg;U`{Ya-d$?8rm-ot9~c77f)Z_)lK=<`?CE(;(~xF8J47xFy?-i9 zsLQSU8%OleLnk=bR-UQXHm=-ref!i>VK?6xF}y5P3n$f%$>Vkr8NG`vgPN*1+69AZ zJEp$M@1F0NnD2w8yxz$m#+{owD#U@|mADHRqZqG^@{I1x5VMb!I>{E*+Romzw?gUS z6TFWb@d@UXOC_Ibi7bgqLRqu2xPJs<%V;`)`k*tO;hMZR`(JicNz;blMMmr=KPQau za7J%4IavZhsI4z7?mfQb#i^tzN=D7JiY`cHyHkmp5`(B6kiR^Z_}_YH)O{Ds-3uvo zJgbw;_4OY5mBQN!A1M4zz5}IlyeGR`n9aq4^30>K+1+k-4uF$*cLxM~aDSZd%8v`J z;@k`wp>uGqA)^rQTB9AMcyVQyP&vQ=AQ2^O|6hH53%F!eb!P3o&)NID|f>QvoZ z_tvedTc_^(QO|C=`(9{hXy~R}pcNE_;0J2(G2(NgAps>CiHHe`(X`{|BR(dYQ4#_G*|H=~rKsPU^ z8bF|p!=o-TIZTBw?yMm6e+;+olo<4g-DS>HVre_X5*$f1h$)%EJ+4UIU~#xT2eY5PhCUryZv>IjVc9eiB&CilwjuotIa=LWK3;>n8k}kj5r5Soib!55mlzYL zGL&N#TWh3ZlSotZ3kElX@J*5v3o-@vqsY9sjgoIUHn*k2ZdT;U6ahpF6y zOc9Cc?WVMqy9w_BTenBqI1eqr((e@UJr63_VOeL;2RGGQlsR5Xdd@~Px3&4F@r2=F zqAJ?EI2i`4v40PRhFJjzWZuhTNili$6kWXG37xE$?kf{p2idtFgCi^{54V!xi2v~k z*DA(E+i5InPb6oqy}dZ^7&>aL{WqpvZ`F!(!i+W?=F%uyOhrL8;&YQaT|QT=wd#TA zhdiu?kz|%-aF^Q~>@63ActopNJb98^aHfbhY$$%DLVpS6F>8g?O3v4pd^f2juD`U7 zfI68etkz=R)X>OClaDf1FV$*`Gc#Y#N;5NywOXC=Pd#kJ{IJAzY*eYpn z#J;`T?ArCUIFw4dmS4(m{?{($ zMt`??z{wi5o#ib{L~tluYTLeWeCfNk>%Y9YC_e9mQ7Pczx4O-P_K#mmf-NxhrME1c zyOg@i*LLYs{CgVP;b7q;&F&ki=U!iU3rVN<75;tUvw4K+kAOkXv1YDDiyyHNOx=24&2#d z$&pO>BqfyeXP=oJnIT*3sVA@@*{~dI?imdaxeXeY{BBgkwm2qQMRqc-V0GS!5_IU@wZ=sbf)g$yoJ9wdGbo5<%!45bAk8Ara5IwF=- zxp&Q`Roj_wt@|_O(Z+E1Ks{;~=h9lQ*Qq^oHL}Wd6PtX^YQkFVG4mcz%DSY|YoCQn zsi0}eMTuQSwTTh^tdeiowkVMX8Grk1!H7({l&bO&)ij0~;0gOH3hQpnMYrXIV~g=6horMdSM_qK}|k$-df@8Dmp za)|8)&%Fz~fOVDARC!P#Wq*n`ukYxLbl}o>A7`qPn($uGs#H$N^eA)BQzu{V&?W6H zflMQw^Mzlm$kCU$tw~O|PE|T&t#!sk%42;rH*$s-KTxzcD<%ZZm-r3EP#f5ES%<(>_1RaRb!;X0_4qkn2d`2LCGvL;pZ zYQrj8a7OJMFed+--qbhgxG$^hPGKH7vcyf-sfMcNxnz=LJI6fVt0mhB(WWPkRXQ`o zNF%q*m61h>ZFUN~pN#vxy5aG;ZAVat%=oSw)XEW7E~~wYcf6Pu zyHU|q_ttwt^cvC+?SJA*6qf9csW_`;iBq)fxE|NS1(Rl8qgYQO;+~ORm6gnP{#v?q zKP{&vGFI%es%7$6u~byyc4a0ajZ!GnmY(CXp;fn3)&F6EKHYd-1@+=k9X{%mpMTW$ z=lXufCv{}%JNPKsG{=Bc+{uZ2>X((TzhycLM6Rdwrcw1n9e;zT5lE&yl~^%r_H?kp zxx{Fg9z#f~1e^Q(zB4pMsbQ&81j3(h7fC~{`Uc5l(pr4r)gf@hg>$kbCe}=6R=wCK z>)JCJ2^OLNG5Lz}+vS>9PMYQJtUUajZ`k2l^wh^plLyuL%TCXcQfw(~CsDm-n#Iud z@l;{sK`xC|QGZD}C+qdbZnTitow%edWtxbytnJKYVc90bZ&r#E-ehO#%Emb#z6qb? zks&&iO=Em$=ZOF~1$n#~kS6kFZ|zYz`jLE$eC;->+F_aoE-;$x;?ZL3&KBv|#Hi-F za11Bz7MIfb)z$4GvD=9VN5p7r^t$&KFSZey0}ItKT7R>|k|Smbf9TD5+Y2l68}$X> z(7HGAx1m^L&tvarf5!ffeILnlc$v@f4E`c%e}^OHl|&h70SXJD3F!v?c>$T2lp(e9 zhzx}Lm+5Ss?FWotS0f*Fju1C$Jh3rSDr7Rx5lqr;E7^zhsK&h`T|@)km>oqq!)=*8spJRRFO9P|$9baxy1a>{hw z1`9Fh1wC_EyOqZu4mKD9kEf0}NJmFn83IBoIi5Q1$97YH(4lgaUXg1ElZ(lCX$ zMh}h9=%kgY9@vs>4>Yf{x2qZFM_>$3W1RVi$EzvLrlP z2Y+WdMooBhp;q>c@FTN-w3 z>OFtMY+P( zy^n;fCrnFwWY9no3+5I=FyJUCDp(7VB!I9OZnC;#&^XXfGU=!@Y9zFL8>st6ts>++ zNCNto4fL^mB+k|5$Hu{+VbC-t$bbGLP8CTiOAij*DLkF-M+fu~LFh0(l8|&${pl1z zl|bt%i2g)<82l$hjVgt0gIGh4fh@Fl0sT@p2&V*S_s~J`2|P-Q0)t948;WJpaL~$f zBNDL{x+?({N&_iNnVNiESg9;IBvqG~*dcc85rwH`Xs94R;?&ELVcUOOqJRF>x!f3! z8XeB>S%tSH5m_ko2zir#!l&!Z(wj@e`5xsuk^3>63f-x^`40a`;f6dv9q|IJ+4shp z-;|O0HBSvZU7X*O!Fh~vTk{ree71`MqR=zCLj^=g~63Nuvf$;oTnx^NIlp^Xi z`)y3C51K`38kpW><0bHZ@yN9IOF>dYhTk|MmO#@*k$tZmD=>p_)(X&%hE3MLO{%1i zRawS8d#>H%Vyde=F4DqJ6<(U>A<9<}!BzLuvF@@By%)U?o|YrCs(*cK_vym;6nksW zD%9KhB+>LefO{WKkLC~I{ZeOK3feENrhf7Pl;Gaen>GGdF9tPs&@(J4E)f=Wi|%8NPXCzG(6&Y$pK9 z`;wcsme&?nO+y)_m4BvFR+eW2$Adew^R+Nqt1PbUwyH?a9FDT{7pf&?RDGfGFPp9v z7SEe)C&Z10Gflr1FZwm7r?D$%EC5`JE7JL58U(^xD8R(L%4E6Y&0v$^ny_;)=fUSaXC%ct(~8F|H(^V5JWRGuYWpy!7seLrAl8aCZ!^R z*FL^R7aR%#_SGO&%Tei)E8|Avb*Hbm{KQMk#p=m}M$#-+(<~|(#{Rkr{}Ab~ z*|A-^)ZE+q0k%o6unRAL_+AYE$w^jMbr?cmrA zqlKAj|0*&#oJ2=#-Akp_w2z~DySV6@xHh_GOP*OjeckEJ4SL()3$>Z*;F&$L*)F_( zyc}cM$&DM5c^kOtdGvN_FaHhycEKxD3JZD_>w?0m!ZkX( z8sL3&{(n4J8WuVrQCk6du>@cy&d%Vsjpvp(KF z?m0_Kj>qehFSDNGd2g=mpPF3aImp|Bv$)2a{F%OQK-{{+tS{3E@2RhO&fRy@72j^n z?94Qq^wzo}cDx;r{yVYl-Kr1ilULABecYxCZhvjnc5(e~t#xSEw`1F{&}-K}w# zrhgL7d^wrCT>lbRIOS$c3cw@ScW;$8-+sx-zmTy!JhRHy^c_pZk_ftiHF-HRSgR5m z^h>a7z1nJ-ESk=0`M^pkcFWh4o9FM(?azr5y3QBs)y-@V7+Xhb&+o5T08~r67y-a0 z9ckp6w$AdV4;|7z*K~+IakOZOpa~n=SbuE|Ztia`+oXz>n-&TGu(o!>vAG-F4KUxh zw0z1|+zHDAIlIM&UnrY`~FLZ=>+;aT@I-%{vG<|Q8wjDW8 z3T(dD_pz8I9(Ag4b)H3J>g}~JcycMz+uuaRHdMa8GZj6XY`T4}IT(B!r~3`&o`0^+ zADeeWJGg3fv)6mwdmZ!0;h%ZQ^|7?DbIQ}?x@s#~D*?tLUh3DDn>!bJUJcpGjLzwF zq1-KByi}cIfjeI%bNcxgTsrxr?MEfw<=?sD(8-Hla#@oG&-mUpM^2<@z-8{TDea5TKlz-f*?;v9b{ru5nhT}FyS3DZGe&K#|I1PAg%xdn=JP)h zHuaFL{Ue%%l|sL8SmP97N2i+&cbOWGhMO$i!>CSv;tLspWEu+A?I1VzIA-INJ$&NC zhfZ^Ldh!fwrV_mDNC}azVWQ>8cSa~`A+up{NeRckAKb1uHCcE zXJ^(wWYOiG_bNO8$bYdLpYiPL{K*U0z3ctc*IXaaw|A~@7S8eEHkUqGdzt32MPMLJcJkcw9MEp|8iO1cod7p)L zDX>F>Y$3Z+i?Z$7ng=Kj&VN;Ta(}d9323hLkBlplCP{r|Q1VMfk2GfyI6e)GuL3n% zI@B!H=blwG9n#(m)!06AQRAxZt_J?#aa^1{G#6l5SOGr8 z2+Y=b-j#!^wnAkq7pnCd5uv1qU-r|lFe`2;Qtn=V#bSx(#S5`NK7XCuN5Y z6^UII-Kpan(c1u((!1vY9)61w!EHY4VA?i`vW0NjADBzD8c z&0>?i@Z)Rk?wQLsX3|R=N7*ftyZIfBOVgS46K9s%8#hkwK7XgftrUQ#KgfpD<-5vW zUV>>Nf}sYyp!4YJd67=T*K`o5cFD9tGxD&${(jKB z-nr0A*cz@VkMI=T0b7Ia=Wm&2 zP%m3`OQ*b-H8(c-+hO&^rYmjB_qa_)q)FOb&30P0SgkC0%ZN=^mX!6NVVM=GmnTR? zWM=ogl@%E~i4&D*^rY829?plO4N)g!$rGCgoJ#1x2Y+pqtY54mSY)Wm$c&8MwE`gN z4t(FZXU@>jyS0+6OQ&W;rmXv2_2y#%F^iUH0ZjA7y{^=%Y^^ zdGygIAAOWR`qO`MGhXZ@y?vBk=X8wc^81Oh>_V$>yzolM*?y<1Quv0F+60d?Y&G}0 zZPm}G+kYVz=LhE)orbK{ao~DEtUFD{Hg3a@ZJg>Sv}k-a&w}Qa^od>LKAjJp_#D=< zSaj?zc6N2sJ2vsw?p!9}Ya1Q;gxwK_>DV>@yTg*Nc$RUp3VUf{2;Q+DYc#&@Ev4@X zH#Y5;hk@iLdV(gD7u^tvY}vUb3QTdq0ow_q8-Lk*myR71twL08**>RzSx!f^^y|p!F-f+gTJNvp6e0!2Y zR=6x*=LLXgS%Y>pbJw16F)8PcePm<8(XW!H=O&`xw=;-q$*HL^#T8>ue7bW$iOmjK z*ngAvZ64alD(pJj7p^<`fai!4g80R%OYC`hw+X}yWg8-DG&-@j;2kG1Ec}hO^e1Pt zgQhrdo!zi>Ku!Mk)3I-}>paKt4xA!ZWmJf?8k-e3W(gN*LX!2>eznBoo0YKr!lPR6 zx=+lL))^LNNH5(5 zdjtCw_7V0O_6YkL`#Sr3uJ|^;fZw2F7~js{!QaDwi{Hn;$p4&wjenhglYfstMG~MY z=0r<$#Yh|$N5ye*Qd}i|R@^1tA%0by74H`x5g!-7E$$P4ApTN(U3^nKY0MifV}IGW z#JJq}DdT0vt;X%fn~b}RPZ*yve#iKn@dw6Z#$OrVGF@}SJY}9SuQ7kwe2@7F^Hb&* z%`cl@HNRng%lt=4CYoH3i*i|BA}^QEmeoa@WF z7Fe^&*S|;QO494o<=fd9MJEbayQnZt(@eqoNvF^2wt#)2a3ktQlQN^D2v0~8xaPG- zU8Hy&sjWdD9iz0fc%?h4DVb@1YbW|9K)X`1C}l<9kh)83;d@_&9smf=zfSF@yx zh}0nIF!pc&}yHt@c`;jQc;MzCoTkk^OlZ%odROPB@uK|R&4~bb{$4kULH}8uw%M^>j)if%WRa6(rug~ zs|FdM0hpr_U~P{FW2!#ADi}2)U@T$CG(kQbs@C?nUsfP)ojHkaO4|VF9&hmO7$9uj z?W9dL8D>b%tEeWU1{r~=M0U90s9Vw18w|%uoBB5?CkPgz-+%a?!o#@-;tSvk(8@a- z3njUQM)!~VNcch3>!+ClWQZRP}M6+SuJLtKp#CPiR1?Vk1m2l-u1R zDKMsa*`}Vum{JS%xWe@xnR-T9Kj~A;RTl|^FipzTRb<oB&erLU4Nuox;>!r!fuovjYQv=w7VECO*vzo!lz540Y$kFy3&r;87MMMKu2Bb zhOr(Zy0xnSL#CT~nDwcQl)Ao~47z%t(8uta#9k9k^Wi{e_M%qhT}-4fPPV(4;eagz z3{h{Kv}6|@LptABjw)ma5jRSv!!*jqc?Jroib?~uc7L<&u1;DGM57Thq@;RTTE}US zT`-4{16g3fT01{)&lbQe&YFq4r~1?k>tTy-3uCetzS$;a~?Q=>BKV;;c8S?bj0 znQUjnl%zGvrJFHV+XvZBj$OBjC%1_3x+zGcfiR`Cj7_^y-u&_QUVav00mI4;%MiRx zLx_>1r+)@48@1>85$J7NO`?t(fO~^=fl4qK*fJjudNeUnOiEQ!de4|t@9x&F9^Z@} zpX%|!?9pz5#JKl%8g*l+6KOJI%4`D;zq>`9OKt6vqE1Izn!=M@6;DU{siUYG~Cs0)v%3XQ4W=Z0y}r+?>{Q?LLU0*DYi5Ov8(Wt%3z01^g} zvD-AhA;+j?x{tT13s3=I`w|l#V+=GbAyt07O@$8W(KKp3Vnq^@MW3AVYob&lh#}nR zsG&MVH>sT?)!JJ;Y40KS9bwyKdzV{d5<5ge33YVZDnnF(DS#Rxt>B~qb6e2()_yJh2uUkhOw-SF!E!qUbeeLnwUX~o>vCp zq;0@H^dMh}S5O)4QAJX>3_z(QakOm7yMKk42MutFu_hi{Mqd(p0IX#LGA>K|5QSq! z6C?qME!YH^f7H-14Mn-1ssW8T@EE{vQ_W(jbYd-KT$qi!6>37O4XBCH5EBo)22g1F zfx`hcKUHmF^3+-|fpG>#r=gwoM>i$;OG-+wFT23QML_^Z>J5p$Al}-*kbtDw9)A&y z$j#h^k)}bLgeeUe5r|$6N8Uv|gBp`*eI`|?Csnge#6CVmCJFDOv(i3T28L7<4b92~ zX%2|0%V|r~YJW>7FhuS`s20eT)(7jPQuQ3}_KEn2Pi#|{Zfg@7%|UV|5CJfcskZQq z7!qj!&4}n0gq_H4uaEkWRtL}K?SGzz-%>+!hHCbGgI1ay26VPn~!`j$m?n4v47imiqOX_ z?)Y?~&NY}LmCFo-)+2r(;H*d``G^UpOAMC-a!}-uGaUKWG@>g!%jre{H(0P?gu#(d z96)rOCwd=RhlT^7)=Vub$1>O)Lf16}9d-&0ME&Qe0syN_c%Eg>glEEybSo!~(Exs< zi>e#;W!PL~Qd>-Rp4LO4JAW!V0*FpIIjBOH@p6tWfB>KKa2fq@=|Oma(5Mws1Y0^X zo|%R|iY;}S*9}i`9HIBq^D88}PfSmWDLw<9qrD%v{%LUbyZU}ppEh(|-pklo_S+gM z7lo+3D0*Q;jNM6>8c|7E-a+k}ssHO|J;;{1csG504x#{P7r9Oy?(c4E@2VJf)1@vutVM~wm6lnmRBOc=U zDV9TXe1!~2b}#2kc*+ucCmnlW+EKr!>rAgZ0JNNwi0%X-0{S?L(!QiIj5WkZjz9Qm z-Af$QD_Gvoa1X#RA%BifqM&;iyDM)ts7OCkQ$9887=1ay_0F@Yt1nFPF3$G`Pve6M zT^zkpEk4Ug1JxmiOb0*e4|6)67+z`-`%}8}E7Q_A`y+G*239$A0AZbMlks0;>|Odi z%G5nZwUKOEIe?Pth%#i#0^ZoPN|x>uc#AopfP9NtcLe-#On=}qVwM^`w!oN!9eH6+ zd!H)pATy1T#{*Ec;kJ(nPbK_?Y12jW4?u*vQd|Qte~__H0-BTILZ%_pW|f|?R!ZM( z$$tYKj!J)-eVZ7Sj`v*Bl#Ou%jeZs_R2toZ-=`Z#M-A%Aw;=Tk+H6=x-Ui%+!QE!; zQIHTl_ZR7Bb$>cv3~H3_agebFPccl%e;dzJwjN)G^ugvkrcYz6&e-kXc$!91a6(Nb za8!^@p2L<*Ckj*iHN?#I)Zz{n*=;mNfCaEeSq_}RrZ6@1_8;Mff_Om_w8{RRDZ&Bqypu%z#2tfVUq zxX&*LX*dGus%dZ@1F>o5r`W3YqG9Yq`(Pg8CMGP9!`skUu6_X-Ga+28$i^s1V!g@~ ze~9{0e}Bb{T}$%8#CX3VM-GwPWv^zY`AfQoGpZ_IWF)+(T5a|YD#W%)3fb7JP*nj$ zT|+3_fR7l_yR9LEy_lp5Ab!n6@K&3-M2DVo?DxW%=a;A@hT@KGm?@HGD)E4xr=0m7 zrWm#99vgzE1nIXV?EzG8Z(EjXn+%{7JmqjZrMU5QFnTlxeaN?{Q!Nf47H2# zG8Hz{s4K;)fUK5gLZ{#;-4aNY2hS`bN*A-*G(8NBV~RNz(O3onNfw13Ohn8h6l~}r z1eNm`AvX}Hb&Y{eY9*Jpkhaq7H59pHl)*y5RE~)c!VXCC8?#joq*Y!93Tx;Sqi0Sf z@_&dJs88%HrV1I21t6qGl?0E=z=D9Aj4Y!`3L>D!+jB*`6jG&VM)#MAL^UNy&x_08 zy>8;!k)Df&%^iA%p*ex##W}Tr8SIzcKzNu5jmj2Kwg zn68Q|k9#8Y6|$fb5fc@GkcF-L#s#OR?tk^D|Lrm(Y7F3QXJYa)mh(>V2OA_W*b))D zQ4i80*qg9jv`@ziSPFsVD$)W?hlc|SA9>U*nmra=4mEkfU&ln(3VjkO#$3m!$OR(Z9Ap~8nRJg&lUX4#j1?8AC5eox07R}4Avqxu7Vv;bPGE*98xW$GWF5NG zgFhT^Y3@chhv6k8It)GkC8?V&89LNJi^dl&dere%`bq3Wf>edhXJ!CJ1F>ADqctsf zRx*Dcu$p1u%(pNM9!3aSo8f>N5r1b_L_{IS?xf)=k2os0302yGkEd{~gd2gS0%FYc zR7e^NlG1>GpytFuSxjY7C}=KnATYt76e#49R9H*bSqmgn5<4)dBe~ASV!417He93) z1qc|;6Xi`dx%w8n@3mP7Z#-7zGAER4WIu4BPxs8`|uu)jp(GE5v$ zlHn6!dai};^BoOoKus#^W?6iZN-%9W4Y`<9HWF$=Z#6vRH!X=!0YPb}J#Y zC7;Lz_yWQs)@~Xh0Dr2@+1Vmdjj2rwMJkBF?A(Y8F{_dPnCceM#h6lH)(Wx)i3SA? zrw33uMsoummI%jik=+HeT@Iv3mujiK=L7k7o@AV#n0*G(o9!fF8w> z8Neg0(3jebf$t1ML%@r;wh}n(B6x=DOp4kjG|_{mX6r020e?oM_f+LihtA3ky*#*Ab$6unhFPsj&xOJ1OX!rsIJ! zs}`f?YsW~_aEL`10aREZ6X0H{wI&T$hcPp?S2?Iqn}KoX z{BP>Ju*iR_V8Kt3wTtv`*i6zv*4<0pg)kVzptiMNLw}C;kta==dVq}k+SQ>q9`h`P<%L_LY zURihx_J7~@!3#n*b=b*6!sj^xPPAuAZ{JI8KP<4H=Xs(NdofYy0PUJR#l6lqlyx%T z+!cAa!*r5J96{O?4V68GPe}O8QWnmV5Ft|WWN9h2qB&mxO_HnG_6&ETQnLu~9PY1X zo1N_SE5S^*db;LCrDgL-Crcu==$1<5Buq@XR(~-pRa6c!ZKnfJlv|06&5}E7iX@0^ z?`mn1e2Qy<8w8eC`uR1s@~cVexYAMKOlZOfj?~nm6;$kU?0dF{Y(Qq<4Z2Ok3^s4u zymEetDs=6MR_qwnwQVnULNXbH_{93WZ7AiGvPRn>32Yw^ExKLUl~yGz`^EG|#|zM` z)qmJ6Nzw&;(!gwI&o3qvK_M>81Ep`zNl^Es_WTyb{w~`>{>TA);^Z5$E@vlqkDfYt zdne=U^4$ymgLq1ak6yzcyZnL+Po4O=#SEX9{rqCa9+~|5$HXlMxUpBxuL&>Dk;&q= z>b9FMYm=&c&HK)rIB|yE@X$lIvkU3p_kURV4R4ryl0D<8ukg(u!341j)xttyG56+d z>m-(FstJ)+iccN-)a7*1Dh+(roHkECzz&n zOuOB5^2kf*@BY`#?6mH`e{=KRi}(E%cK9a?UZG4S7g$%d_sRoiY9Fb?y7b0Aynnm1 zd+O-g&hF0I(bLSi_43Q3=S8PKQ*Bh)!6%<&uYHXECU0S{oxJ6F&pZ3px9<7yF|qy= z*bKE#17S9vv4WR($^R6DSW)}aN(~DPr@H>>Qc7{-_^$)-C$}8;{d;=JUv?Oi)6Oi z8nj3O0VM6`7!4q)EN$)ikpp3Vha<`iXuf)fA=$?j>sN>Zb+%|zgSRBPZ+{iuN7HPj z(h z0O#!QNu$`PbbxNEA|qwvIydhWCIXU#@q$W#>0D)ft_WjpG`m%`U`Sw1ip`51ve=4^Iw`)ksDIY1x%TYk+w<1# zGbiG(Zm0!Pb(!UcZl*RCk|5RwfqZf5lS~gCI#}0nPt>F!RSmXMOhcERZnndjpMqrN zayYYI)Eb)NKHF_qE4>BSi?*eVKop~ZN_{xF^;F_gkyTXSe3A#%r}>4NrKz8d88XHtkBC@yCJSB-rGmb*v7N`eMsiqsR+n zM8^VsO(NML4S#k=z-j`}y=Wj+uFVmF$apP+dUy0Y_k9``!DsIK9cW1OJ^%gb{P%r~ ze~T#cjw_t-K#mwi3cQ?z8a&?tV*OBS!M0#87HhBbYKZ62T9>orcs*bE;yMv&gx?#7 zX2lfc<*gbC*7#Hm-SnDG;rG%_Xwvdl#wLdjP}}A>tADounnh1psOwnAdZvGG5*_Yg z>8y*n!dBsU;cnuO?<)LS;eCY<0yP#P0IMv);3_W=zEm>B(=x(N)zW8S+;??h-(SKK8edf$}C%?=N-5}F#ifCzVtj98T|UopZlKXW`j33 zn}7U%e%|=Ln~uKhxoM?7`DpLpQI`b6sokqCPMZtWYO}c?*Zu?kkA+v0c9r`aLobG+-guVztv5-g-LJBu}kZ$-(DTz;o~;9X6MHMD|BIJK|L8=DuOMLfjj% z*IN08mzqhXPXkvpJuBs8{KZj)#-OONAAbzME~>^RnWKS&+(|ZK4ar8Vj$zpw2~Bx2 zw5;~5RdT}6c6>WpzWOj(Xv#8O$2z=F@=Jyp3hN2tv(hut$dpcr47PA#J0&f)RhzFS zJ}Jb>oaK->QrtBc5R31S)#jFciwtAw-*~m~EmE3$^>&M-u3Iu(*wm({0@K=!41X-s z>FjTkG~cJ?Wx7VxNq?HlV+U5*s5Ay7X(iV-kb+w0%Bk>*<=e&qqTJ3Z9IjQ#H$#hO zhqpP;j;^x1IBB2Gg(NOi@1~1Zu72mtveB%~WyX9V(ewX0k{M6e)Xrg29wN)^!onqm z6NS@-s|r_Z?2|%g>e7m&4e)Yh{eNOR{uf!mxtI9=oGVUWX$DiKl_%WQfveqiYlA3z zd)%YOic^!avMj~^r?jof_seDT$dCOEcYfmU4z2*AKb#|zmb$!>98D@Gcvxa_$itYG zK5t8Ym9%a7)F-6PUop9Z-IQq04|=8AV}fn#FX{9!JC;oDE5Eh0SQ8HYiGSK+DJU{l zT=i2dji&zp1IFqtBY2!+U}Rum0OG^%cy`3|+k9o@76?6drAHM;U0C=2ZU|?Wi4%!b8 z4>%8A52_E$59AOY5o8g55%3ap6BHF*7HSr-7hV`p7}^;q8R8m78h?fw+#2{B6dRTt z7#vC*#vLXd=pb+)#3N!P&LvzWoF%v=)+Y`qW-K@?W-OpAx-8l)CM|p|`Ywq(90)BtVEk z6hVAK6hf{-&_l9A)`ony!8 zz4vU2(|hmT>2-r(Bq1TdfVMaRJp;o0y(i8;9oBpPEqvb$BY|e-&3l^cO?GQG`Tune zdtk_rqdgg;gop769>rsL98cg$JcXz644%bvcpfj{MZAQU z@d{qWYj_=R;7z=RxA6|%#d~-kAK)}T#7FoTpWst`hR^W@zQkAf8sA`nZ^2PPK!Q-C zK?{WrJv0UwSU8-4M?l1gC01BtgR}S!-{S}Th@bE?e!;K!4S&Dm5B!P0@HhU!Is7}p z>6|;KspP(qc4Zh3L(WI3Y+mt-bY9sNc~%8oig{?ccMzH2Jx#Z6;aYc6v?ThhqB(mEo;71Da*80o+=)w+y=E>7j^2Ld{$c%S)*c+tR1Vp z#0wPps%-m_wY1LKm=0BA ztS5P(v>rqBJmJaH+#1T1scoJBE0J|vQgTZ^+qxaBvLn+g6Y@@(j%Qu4ChtbAc;0hA z@S?Xdfi1NXWC9ghof(y!X|<%?_t};)rbj*<63eyHlmg#x1(FYZNrny5PKVSKPgGA0 zt>)WH%zwDyAlc%m@u?Y2H;O*wRwS^wl{|9hWSu$kdf&A++R$3Zl8k0 zjznZ`Yzj9zN3n35*d`FWX?o%!7T%_@xXh2$Cb102|ji#**ieGIshBAy*x?&k9rt6B3r|%B z786g=N}I)%YG!fcE=+HkYUWEN$+G20*(&{0Y{g@_qRJ)q*{VsgGHIM4TUjsJS_ifs YbhhE%u+5;^S>+~^{{Smja)AH<0AtHZSpWb4 delta 33334 zcmV)LK)Jufi2|600u*;oMn(Vu00000gBSn{00000$C!~6KYur4ZDDW#00D#m00QX% z00|0dDf^peYl<(IwvV6Z&`@!$;I& zHLRtLb*yIt8);_~n~S|$*vdAx)4>jQ(#bA%7uP-PWnXdK&jAi{h{GJ=D91R?2~Ki~ z)12Wf=Qz&=E^>*>T;VF$xXynKZgPt*ZgYojdg!H(yWHbG4|vEU9`l5!JmY!sx4qyc zuXxQH-tvz3^z(s_eBv`-7$`oN2L69F<ic2qu1bs}rM@>JHU%JWqlraZB= z29dQj@(Bi6Zk! zBJ;^2^C=?psUq`fBJ=4Y^BE%ZnIiL9BJqPdg7umN#WZy=S zeeELqHi_)pEV6Hl$i9EABKx+9?AtD~uS4bMyhEh1Q>4);(%2=^*e%l7BhuI_(%2`` z*e}vJAksLf@}5H?y~85CBO<+{D(^Wa(mpQIJ|WURDbhYA(mpNHJ|ogTE7CqE(mpTJ zz97=RDAK+p(!MOxz9Q1TD$>3t(!MUzz9G`SDbl_r((V#z-xhyq-w|ndi?n-0+Pxy} zK9Tlak@h{2_I;7|1CjPak@h2z_G6Lu6Or~)k@ho@_H&W;3z7Cqk@hQ*_G^*$80_Is88C;LUt`57dhvL$T>en&iN&B z&To-(2F1W%x{n2to&W#4ib!7zh=j1Oj1v)>n4uUqWm-QRY-s>;eE&hPktM?@F20{r8WeXCF|tQF1_ zo?9q%JN-4%?~SJ0WIAaj4U)v6bcqzKBZU-U5-0I+Fr7>%qkga73*sbye+6=#tkGps z%!=*#DR@w*S3iq}_{4NFhKD4*=MAsC{o|X1!RE(rew7=MFU2^0< z9l4~{oVgk^q-jfi_Rr*NapLpY-_S2prdvU|vv}*CP9<~<{$F2BD3`VuExMAxa8VpH zM%YH-y25RR0ud2*5l3j5bk=DvgK_eR=w}@qpZql*^$wEJG#}Lce`L@k@eoFFhfD_f zP`Lyisgp2{@K?5xuxNMivhgS%JN1g8=2GT`+~c+x*iOxpUSOmSd^o-lc!7xhzz~cH zecxj0H_cM)2;mz}Ejd`xExl4TdImF?UU$nHd0QM-bzAp6Mx|zik*B*3BR31Nu@<__ zVL})}(}WO`7=|C%f7ONFV(RgL*KE@cdY76~LS4cz1=EDp7QK=zJ2AAaUH4o9C)Sk;1kK63aSK!#AA_ z2T7#H7AUYu8YBu~aI(&HJWQs;C>zVHAAS1j<*QecYvb0Tf7Yuus-Xv?XGB3W^3rrq zud^pD*%r)gso!wjblClkeS^_pX^;)c-QW7w!Gq6u=I``;otwHXOkMW_KWum&;+rjvo1{|I{54|lJQCVh2vjJIJ4u|ytRQxCy-Y?BxVAtq01x;Q&v z>>i&x_TAz>qa>Nl7+KM@a@f#ZAYV>QvTg*|*|v;~o>$f=IWyKg+tf6TWQKbX<_}0H zsIlu>TCv2XFErcbnj31aML8)5?W!e8ypP+Cc3u*be;Ko5Mb3T{7<;z{9T+do;ZWz{ zQ@{MuqGg&Jd$x9BO2paIk{jHC$tLSN=gv4n*BP(24sJO1_KLyHqEYTur)BuoWYp8^ zFnBng^siW{a25QJQ9PUiJIn_SISNJq#L--iOnPu?GVKH3ZPTPdFWv=2p?GdO0ruME z8~W8le}o=lAR|f(n@PW7Z&j8@K&;-lx2GD=_F$uA)R>VO*8XF)sBZD<^Ss!tMV4no zZfKSTmzt|J_b;8^X=c?0=5#5kLEm&!vy-M@g#sIcXD=6hZpW3yWTDb@W8gU^Qc>OG z8G3guc;iq9E`dQOwv$$qdMVS7AK5rMh|8vne_hvedSYhb6@_0c{8r)d!k?0W)JPvj zLv?7Kbb1mfqQR!aoPKsl54*j_#_9$ohLW5#CP-p)ae{-E#8W)g#330^M^M0cg2alH zG#!96noNgy%j6(|OP~QjnyoS5x;Wa#VQ-QRq{-oYkbzVqczCQvSBd!1M52HjVs!~> ze-J79P%+535FYSI*6R=AP;`1DXv;7e#L(7$7U%PoxzI)60+gcAlTmLRs|M#yQm-L& zDj6a{^atCd*AZddhb|^qX1~XL26AlAnPn{m4)7_X8jWi`8;CoV$$@I!WxinHW+{!6 zbK8wN)ApG)yV!#Y31gfCZQ2?S0;+M{e-N%TLFVh42K2&8AY-At(wZyk5zJsYruMG} zDWNd^gz6gCBuGlW>~tz+!K6k72t3`_HCtLvz=eJXVYSn(#o%a6-)* zoH`qKTI=oBze|HH4%LT-WE!^v=n)O8AXxce;mF?23QNtvDS2|Cl}15mIKq~vf7`3j zjMkOE=LICJhk-^d=7ShFp&X)dYCA$Bj>)LODdml7YA#oV@B*L@9G`L1(lq8?(Y;~g z+;wi%Hkm^W=oRIz&rMU~+%O2-K?x`m5BdxITq;&f27~G`&>C7%fNo$kPD=5O2I00K znt>e8C_9`~JIv=7~ z_WE)PDzP`oRjKSiXQEhSLdg)&!wRq>T19~f!#vjqaFO0`CeiC=w|$rR?*bV0ML&$2 zjb7LK$8qOnU!?3;e}Fa}5vSFO)OZcZvgad90dzBLK)b_JkW) zrgR1X&p5~Ianw~%RlvxA=x(4`PZTaEKkkkydphZ|6IiAfE?#n(e&y0jpW~FnG&UoX zO7_5MDYnnf#K5Z97t441k47qyt?Fv zR>FyBX^!Q!e@-_Y7zRpv0h|4`2sFblWye#1r!ki|Ute?sK?&Jn?0RN0y(T4K#=-^6 zy@%~7M1@=*wsCTcXq_Z&r3{NB28gf?y1xjjf7k{hEV5p5+3coRT;hUcNsf{C^FTXn z9IGa?U#nyqX}KY}vE0$ob zhNx3>JSqhRjRxbbCIk@vC?@Zroc_|iZZ)#YmM5%z-`*FjM32?$R$vBc@CuFG#pECV zVW7D((4DID^x1DeJ>}73wVGQpg5XY`vxEBZ=pPrBfE(V07KaC{)`Lk$?XT4P0Nc@k zv;Cd`fAIxBVD7UXcS$7F7{!A*)9ZJzCZtH}==xT$>=xsN+E6mk2bD5(v$oaK}xR6jrXXrL-eN2k^LU33+iYUFH_Xh0D;|Cc}Js;1vS< z!ieIaq8)(vi>MiZ*QAHAY>tEm6V{;HR9#cICwK{nZairqZQvi8o5Kl|I40lj={0?8 zy%#MR*g0=!+(_y*fb2^m;RkQ%___rQe+*aLc6~Y+bN|oCp%=aG#oL4)p6oreeQTrj zF92KirVQksLHV%bWzuuF#hm<^_T(6I`BMseN-ZEP^V;{c8ycH^bLZ9_a_F|hSSTfz zOt$tjL+hf*%MX)_dOKvY;1$}1Lxr1>`f+^f1WiOWHlVQMeeyO~bZ~ z>*}3OT{A_oWJ2HklKVv0=`L+vwNdnHX1v_)me{G+UvYH%z~Y_->SfDOT(qem z-E8yf^>MntRR;0I;`QC$u8jOL{e95I&0IWlL5ML^HbLhHBRQwCUWg$#2+0T3RC7A%F_ zNI}O)PhH8I1g3KK6dO;yU=Bu#(zj8^Dbofl1#&glL)}~tv!G)oD=$8O$FW`@qrh*L zE%Yi7sTsV?Jx6NI!#w2%e*;8GfQ3Rhld26>7LD4W(Zc}MI#fMC7GvbFqnqzG<>@R1`f9tfz7E0H|&^_dkiG9=5y)U zaGBdC2-=@j2!P5uqCUyv|H=~%+SvGnDY#+% z-|7_{j5-caLcMmQ_Wx3?Dg^E{b>aS0Aswk2kJObn-l^=}Z4`W7#Aq|X`CEk}Fw6hH zaDJ3U!)Q1jj!dBokN@|F$O&@dp`ToPExG<$cH6U_HM{3CpCPY#*6eBT zeCIpo{m-9ue+t1K=I`3WQ6aW0- z(}(VYe}_&VK7aoFXRf>wY>QkETXTERgLWsXF0c%Pe`34Hq4?>%nxFOkbvl?WzVCfs z|5<;`eDY7}%I!-_OXJ=5;^N|kKK-y@7D~{k5Hx%d)DS?&kvf{tZ@lN%-uv-iI@Rl* zfB(+p+H1&9Ui${}XXG+Be}SN!%$@8?w_Pv>KmjBm zCo&~if3pjBBgTuTlSKJZ)iouE@(Vzypr6O1e~xs{r2eiK!%uV?*P6`Y)HH8}^IX4x z4SMv;7v``)+F;b9GZ?;$@Fs6156*7>+rPz6GMIgVd|~pb>8GZ%k4-OPG5Ti;i`|5_ z)f|3B=&_PYZFc&bqYE&2vg=YD<~}whW4j%=S-IKJS2YH^YmV8_jRm7QMVo7x2nCmT zf2;+JJ@+~5NxyY7V=*sr+X(bx-AxC*&<{eRxm2x`I>lOQyR*Nqr2sJ#=0rY#k+cIy zYN1)HHj3=8|7!iJ-ZGdRI|daLWLFS?k^(b}g4tCrf-H9Hk_k((-<&;#!w!>FlGZIfG(7>ky5wf2}QXwiDpkD8q|ApZ>+q;E|^R?Y#ies}fl1 z-TxWiU3~X4R4>XBhrxvb?Z5!fG4F8KoXAJF$9G+XQaLQ++?gqQK&(njeuK zymwMRE(LBy8X*3c|MAtY;6OpL++W^$+o64!f23)1 zTb8WR3+UIk&24A zB<@i_8JcdzmchYp$S&fdL-cZGQP4nG&#VHN< zI<}U?k!@>ybF#62@^sOy*L3=P{ruTH4es9iRf zF*Ew5f+)BcQ;B2}^|>4aVUCmUJ@&u@kJ0e4cfIQ|8h`5gyYIgKQw+Y?-8X)67pu@O zuq$DP7t!mo8^x13r0dVU>ey(QOQys}zd>jn#-Ism#d0*!Yi#tM-XCQvf4&=(7JJX^ z0yH?jiKKVIvh`8^2`+aXGe;aRnW(^wzq$>{>)!oxPO5?cJ9>G z%Z%Lk$Ro4wY;RvE?;z+S4(%?Y1ZF`y;QjG5iMmk&WJf;*>k*8tDkgX)$`xky)1 zd+ZQ;htV^xC0}p1k2YCvuGC*~Ye7Cut=4}~WRf2zE1GMn@znAs?u zdn$~SPeJaMO=4)rZs2a2jB^uQPIHveA1a`sJY~v2e@ETW#Ng&OdV0|c$^%Mx^&&GF(qF!XI z;W`#=e@aRmt50kuhYVSvb8o;&oNxotm}FZ3-@M9Zn-yJu8m&zs%8CCMB`?}4Nd35 zwCs}UekP!vO?nAxKlLrN`t#)v*7||e;am{hjiMwy6ub#vK{M^5S4mo)cM2_Q$; zDf2Z;cLgi2Mpe#T*YmyFa=c;@Ruy1QbHIAO&nZAV{mYa*8wN{XaQ3XplLAa=_$S;I ze^Z)VUgKB&s8}vv0mv&(dhDLr?W^tCt?UuH!u(!)^?&{~J=s0c=WEu?7Rie(L|6-)bJd+B% zpcT;1B)$I@n`s14m3uA_mU|0(fos{ue=pgNEs3bDEYE&DYFcjz-ewoMUVWnG7(hhK z|E0hTM0)=F2gDZna1DKx9MGF#2x+yx`@^;+@DL!&_~x7MUulwSW}j@d4d3?#+-OSM z><$tOh|0hJzWXkWOUNpP>p>2w9?@hFp{7KpK{LPwt%yNW6*GX|MoH8Fwt=4#e|^B? z2_B4hW9HE5+!K@abKZsvUngLa>kksT#Q}s{U`N{)0La+T0m-ug1r*RrIBgb%7&GQp z9J3q1EEkU9Ilo1vL4IiH0$~4p2;Hl30B@A@w+f+GswKZ#G2z$S z1{iV;BHk+b5oKd0piHLXFnS1ufBvvm`#Xb40=EVg@3**a&&OfJ_7rYazWF(OWBSMh zpm>)1tFxZ!a(@mj5oLC( z4c(|VL@e5U^k<}um|T==8i*{f9>NeFkdnH|;K|RvoX5x_61K$DD0J^`vp8Z|UnRuss5u>>Zw&}{o-s5Tf5U@Q706I=nyFF- z_^lk}Q4G8s#>oIP)f8%k24%?KyUABM;Owo_yq#b_qZ3YwK!sCAIi7D2JUvfMfg6(! zdgv1L*+n8A%t;1mu>+LYOU9!$CL(w+jHl4VK1ec`O64FzCnDhe_;N^H0+FqQ4AbBf-}$$dZ3bVEp(ToAficR9!P2)r7`O+i^^)gVN(tGbrnD1H?Dr1XEB_ z1B;6j?r`!!p$W#RRg@hQL_=Up!*J12D8RBeEui7`vc}7mf753+nz|YEN>0RVu!cP! zOnGjA1&a{~s+kSWeM56KT{uE$8eiKvv7a$uCSCiUFM^mw*_s<_JbQ~*uNtyfUMT9) zD;;nI$ZROWp{8rQ9!O-z(lIN;)f@tBiA~ly#&U%XJVy-YnNGp2n!J zVU=7kW|ShU<5!b$rlDjupi7QG(VOxrGc?X9b(yRNVav6=5PEtWU#&$k<&9F`anAyX z0nHAmMK>`F4nHG92my-dj8F5%8m`VI47BaQ55y53rlLqewL8^FISg|QsHp}hpaeu0 z)wUS5e|1x{V5kqncrZ(7luG43&;4}t@7bVW7OJ4Z*9)&M+*`Q6@S(!T3x)0^9?p~E zxbnCnx6Zw*U1Z!S%z6{vIjE3kg9JSkMr$NDA1`D|MZo1C_*IhKZoX8696JT}oa0Pj z#p$Sr*-j&rX4_yJpc{XH4~Yatp!xw45MAx6e;JtFl&3DnlWB}?0;o>T8L4DZtTQ4= zK`UwoOgv@4YKFtj*&kRiiY1qlPk^z(ERWh=VinEh+wWL$QqL+GjKZB7awmo!O$Kuv z180^rUB3KTmL;5y4=g~0P(e7u2K4{$lK#@c7EQtrG{Q3N>|O3Ziwbxe^oqfg(6PCm zf69ibRXku;yYhA7f_}DuR~%|lQ2LBpIJ^HSz)BFdllE-*HiegxD*^*3xLZpWOi7tp zGNr)OAiHsJqrBMi02j+lZzt7|0;vJ?W0eZDzOlA2F&*6lgDR}K<y2C-9AuLs&Ky!f} zQX#a7DjReq`L@B#rUWjRz|oxFkaUY7C0~epPutX(rI#f4JRXBUBCpXvu%v?)70i&L z*r|C200l-JAEYFsM;AdtUG-$?e>4dH{*@q)0uN0IZFvs}5SvSG`_n2R8fh^Du&5C< zqegX@l{?Me${;(Em523CvH&v=6bNKi)GSV?uHG+}?AWy!NP9Q%f}mUk3!`#O10l!{ zWtjGrMrqU0We`XmjFz6u{X;~b$0cB<3m+&v1S6X}3+JvMKxzGPZ|?FQe`T95{{ObNM&tYOGPR`f7viw^Ib|o{W`#l(zN|F1v%jtX^p$y0u!|@S+16wq3K!F zAftxSbS#kk%yHmB(1AbsCGuUuz@Vy>h2~Y0qyrVX0yHE@fg(>fb4*R&890{0Ushne90 zaU5Wpd^mR_0NPX0R5Vb=aep$zT+`jusJ`+gw(SVoLVAziZ3usNk5eD=d56Hg##(u0A$3*Le^+oSwPj@+(Qp zOpS9zFvS>i3{#}*sTJB5Od< zw1(}A<-@KHrvoXae!=fTzsoK!IE5P6u1hd71>k;*`|JxYlI@8{1xObC1*zTu)@_6b%h+*tU9JU1B)P7Kw9M52B4 zc4tbvqIW7ce;C1pKG~NNzS*sAusaU$rngX2+`n~ z6~HDMp=F{;jotbH5DOzE$#l@7)HDHgLhI?L{eNl`(fmZ&(jC;{x(~*p&@H!~xaSN* zf|e6P>IBuCuG?$Wh>zAvrY0@RFIu{|u-4#9g+^gq*jG3V$goFv;(XU|yzO5ShaW=mWpWBY-9+*Dt?>x%*)l;e)-Td@f1OmAfxC z1M8NPM_P!ishG zL3ZcOtaPl@99G%#wKvfJdYnB%$Z+&;83^T;~Mq9$}A8ty=Y zhvRiJ<^4n^vYYgoxxLNa#m=9Hj|)dPJ^a1d=>y+?_~Gx9-`W2?a_3K9RYz}oc>njl zxBsz+4}Aao2X=KeeFXGLt1v7~pzbxA_2$cLvf^;EL+A0+s5mT+`k*o*6+<0P2IFm& ze?SUog8nM6^x}S_Q>-WK9CNC5_vnI`8IEz5b#E5c3XtE;6ot4R$k}b@&e37m3UDcn zFdm;hin-O1KzG6HA##0c{10t^SGOc#M#ps8!ISqt``iUS1B}CzZ@th}o^^?Cr-a@& zd+fmn$<~8^cjcA8apjeN3lh_v{li=Ef8Q>D{*eBsf&l69)EH2Ioc!dGx4rEV^5ajx z{q3Ko!NXUbKY!K3?BO%#&!2gCPGd3sGK|e)VQ=9K>f13YNuiAKxlT+vc_3wqdR#qYJgE`PP&#e)0?_z%I->2u)uuIOAXBy0Xwz-t{YwYK?l^Nxx*ro zEWg0?M7`{%%nMAb=xOHbnv2KUr%%1pt3-wYN~$;Y&KXOFUemkTiYUn|UClNE--%vm z?E1T1`a__U^};2ElZ6}5*H~<0f6@|mXw+LK9gm`zg|6l(06owNrq?Py19Mzm#CW_q z8~1bT9j${=2jPd1@qRJ@>BgKVzd#2+Xo6G$6~eW{ptS>yb^!5$!7gfG4ua_n>H-=| z$#t3?0~Dh*P^gjVIg#)F9v~>&By5=z%IOcE{K5TT?XFwsA36%cgoVA8e=s?hfc;4+ zhl9H~@c`%X$H69L?C@D9@EpT-0stt2Zlxf?Hs^Fur~gpU3w9v@tz01J(?S1D7gHnJ z#lGxI7?okMP2Zig+w1N2?DxqxW?SUrw;g@!?PM@Ja)7*!e6a-=)?2?dJ5TP8W*>ds zRrlXVK0JGv)OP){8*C5If7+mMqHwj+BPhw1FXZ=K3=pGC>y1fgo))H3CeZ;m?O^h0 ze+%uim>hc=^)~1-L$B_So@*2aX;) zxO3vztFi@p;=nc_Vug;+rA@;OYLDEUG+HZ-7WGdY+dSkN#@31Fe>a1{bqB6$h1@)I z=th{9jx=Up>t=V|cURV>#||9C?{ff=$m3vvrM7urkfu+zmRs=ml=vISpR}-1IEWmk zJd^V*Mb+o|I!U6k;4sBF5mF^D0tLCCzg>#ipKAcX%=6 zjI0DkXG7cCd;C>L$(!a+?K^fbo6Dp%wioQ2*W;YwO04-JJ$!+<%$=!G?qr=`fYW(= z2o*PoT7};b+wBI46h6oJUT(9+2;>05H0NMdoHZ-#+6W6QwPUu%`u(92-tCxhKd5pEHm8KT+UZvAmX;w04K&>Uq z1`KJm+nt?ie{4tq#WKAmwae0V0Tom+zXdJ(h300k3_1WR)qLBz?o_~a(?$cptZPoG zu|Pdtqh?yS51ZTr<3TblgnnJf%Lv)43tNSE6do`9PqK%+oIFJSh&)c7ApezL?6*tXOied1n=v`Popj@P=&~}%SP5L8p!KeXKf2X6e5JiHE!_@MDAxbTDi460b zaBBMFL9!XoYd}qbiHj)zaC(7Z={l~7l;N18a}`&xWy1zd)auu%GI4VWI+;ehq<~2x zD*YKqBnUGBnD>H_oUcY!!Nj?DAHjd`LIw%T)1UJepg_UUKbEf6fnX=F3#tRqDYOuw zu1!#Ae^{wdkM)!n7>RS5=Ti+cg#a#$#qKZ+CIeN_V8X-BG|#lZPz6?y43)j9q7EIE z-b$K1)JAWyaj3z(6{Z>wz86M@Ysksl*7Z>chI3mDS&VrP}`}f$77Av;a(c` zpnLIh-SeZsfp$_%6Lu17MF^PDcC8cW?%`^ly=Q8hJMKe^&f-L3>Yzf@|2F5vgowNl?Y5jt5oF6 z5E#%BuI&a}(b8cS9L5EaaE(c|q)%XM`ZT~ybpOG;V$51|vFD)KY|RD(Ut;<=e?vs@ z5++2I*u?^jDrnh5Q$Ji zQws>B@i0Y7GVv-#Ix$bm#}$GmgGQnsoZ%l{-jBuf8>`|&DSin4|@xi5u`P@_`XuPT5dFI*)3OGItIEdSy5cA`}X2sy|;9- z-bzFIu^(QMwKzXwc%?l9Q|eJKu@^2M>;y-lyCUjXh96A&gJ!045Zs=Uf7?gd3&5J6 z6pj|2Ubw07(!yVnz2rE#iM*1$nLI!~Mjk`yy?-tn<^m1{XrBBu7qTeVFz$pYPSf#7 ziB{S{_<)`$5Ord%AxF7SEKE9eT+;~8P62~s5_w)40Q)#tBUmb&rYcO9SDIZ+#}A_< z_lfN$geCL%a5VRz!{2nEf4+ygSe{HbG1VM~8&^~$gH4c(n{jTBc2&5pzmZpvd-7DF zoAFR(#rH5J4qZFb`Rey3$#KHuV*c0e5F6ccpTsbqOvq}HAvuCD&)3Gg}IQwE_6M@)7^*8C@s{ZM?FGX*Re;$v?d_q{hfFIKd z!dwaNP%vHTYY70r76AaSCq;_f3ooq*wjTxJkVOM93)O*pmvt|WMcEa$;UFsa>ztOP zuHkr6ugZmHTOoZN^-{@X9C$V^m=#pXB4AnmCQ**0@Avc|v?bxbM_6U)5;Lx>tk{V` z0XBdf0gRODKJc9he*jlrrZG>`Z50?Z4i-xqjR{{_O28HXmXj`~j#BEEDAi?P$2t?U z_k(6JG3^Cjj^hb#*d+^EK{SllaAammh`A>zZa2N6Yk;(-!~x5OXpASGRcyyWQgTC( zQAUL6lbdGIzSlrcv967=FS@mYtB27E!gT`|Qd7?KsNOJKe^6hB&RMjPVcd)8l<3YT z+(jK2WDb_L39``kK;(5_LZ~CkdIRbqH1?#+aPgRP6%?jPE@1>T&-UGg)HGW3EDbU5 zLPk|hN@zc4yc9VWchT;WM1xu#PGcQ}tRQTsf7Z7aQlkj{)P1`KAli>K94e+I zw;E|s1kDrUs#LU^eMeI(wKY`C#iTBb(hoHd;jEM`bYo}~&fuGb1;gHiw(NuEX;l}_ zeu7Me0oTE(-M#_LRiqcHtx;kMP1CEMT_oh62`<35qf#j@HCjnjYzz+`7|MB$iq z3KN1%nGX9yIUG;He4NfxMiC#+GYe!Qv+)$)aERfX7-a20s_;PWhlCpX!wBC=jGj=8 z;*ZfmFb1&-PpPC4P)g%IuG0gXZ*!iWb}^|Of2HFD=4zY_!zje0lMF@86dJNa5@>5S z-cKUvM-PP?!oyR*jC;Q3mo++sp!^jc{+5-1qNHN~B8s6^iMB!{7E&3=>6OW}dk z!L`g(j_+qW0Ja7pe|p)a^vDCA&57%3?4mDy#$;iNSxbRRH0zBNQh~|N@>KZ?e;Fxx zNJ_+Nm9Dyufv!>3?L-*5j>2U!MyP`uXsE@Hxs^9Y@PpZHYQ2~$X864pCIHZ_Vd`Ma zl~CVpG*D#V=*Ld_0y(Dsn6X;{%m+-{y~@JKP6t~+2Oxr5)c35&$bz6KH`ey2sjxj= zI3=?OCv-pTS|!K!ES{$O&vv@mf4W#VG9&1m9j60FZ|dF9*JUy2nI%W~8)deCZ9`p; zEbpSPgwX#E7H?YU!RUl4i*2+W}ZVw+?T$)d%TaJih-ar(e?EJ!;{B zI&QVLzTd`Ab=QS_L;6LgVSX=(g5ek}IyRnS)Py%&7UpJC4|+*|m3;VbB4##8{6fD{4J$m6>g_G$q+H6HZ=TOgpw6WcM~IA0@x zw}H8gD}3|65zgWqmjQNB5Emn4`DFw)+ghFx1-5k$;fu1cgHgWb3~ojXcdQ5`&j?hZ zYPA`Ry4>q4VHJh>b~{ZPe}j?RSNl`tqIKG%$F&oabyf_Y(MYwLW7>yS>tVSRN4ilr zQ>z#=(DBmcS~XZN16u~B!%N$sow?*-cJUCSi5_Q$h6>N(rVYXcEzQ6&g&Tr>2#VM+ zO=iRW)fhLc=6e|yvh+2Fb%41?NeOLHVA&@U5A9mC}Cta;_hAwVCK431wlU^@2> zcn>qp-T0CS!SK@FU-Ln6URMzF^#iMg(}lYW?G68Ugs2dcAX78n%-VQ4=7N}L6NSe0r z(JKPCz{htSe*+hh+FpVyg2Av~-l!}D9+Q^zg#(bN)}&ehMsB^kSgC=M`$YtahLM)4 zfRBKB;iqN$tC-5>0Rb?hR5VyBOWet=_sn3y@zQz|_tU`&4QPavnsjOc{U5lq7UKZX z-=k;xbB7Tl0k(_-QU~}cT9@h!l#$N#w$ThuuiH>Ce_!2fIB?c9oD>u;cgJq=criW` zGaKyoq7CY}1ieoyqNTCw`dS19;vywxI}J@Up%GhvvUM)g+G5xx&p_F4B#phO{BYQ8 z)+m+7UIp}ouE$LbrlR>SSmfgFI|i_$m_7S2+APXl!D0g{Z^mZ)P%~X`5oTi`7C2O< zV%tCLe^qa-0;!(8-~;~-0V)NFbs2dYSim=vSCcoAUnL(Tzezq!{yq6L`F-+-Sc?PyPY$;giY+0pw3z8UQLyXql$8L7Q}ec4?0;(+xVN`{)imLQl}s^y&0^ z`V4vleHMK-eI9*2eIdP#zKq^UUqjE+*V11Af4l1S^j`XA`pfj~^quqp`XGG|eLwxT z^dt16^kMo5`n&Y^=p*#^>1XI?>3^h;(#Po&^gmPdu|@;6sC_sY?;~S49vmd2{RG1h z!+k0i4i@GRZURO+h)LC8%X$PzH&daCY%;)n6x`n|%%2LyGVQ^Mp$g)6!U(Ry-ySkQ ze*pV_hvZ=nk+qRK;CCB;w>usQlVN-J8t#LWVFapoAriG8Dg?wZ=@-?;ba7NvsB>pnTDkyniz*x@qH!-TG=Xztbq;RH zCV9npKN#;&OstBL*@aH@G8T)d7-mp8e?FKksk;X;!E=LAf&+@rK#2ffk~(fGB*%U1 zU~dYNA(^1OLZP4v1PQ{2a0_mv2tDqM#v~f`l3~9C?HYg)59NuDOfoW#;!x&o9mcW` z*CG#h(~%?e_u?nm1fy{@?uXG>PDcYd38nh%hn=aM;zuI!20Zl06mHAdApP|km-;{klABGnN-dys7W)Hy69k{O2Q#~#5m`LP^qX2Ts4Zc3;b*U?Nj;XU4f zOVJM5knjt>@alyxxXZ&Rz_33*(HH8QhMVJPx~Xosa5p7Crpi5`(7h2zs^Wo!bUqTJ8XBLE`ldkT98hNcl-0||8lKIEWr`lBC#f9a{sejv14 zs4DOt`1J>53yYuq9~%8V@iMR^PRSc7xf6`l````^R?K0j>a$#f_N{HTXNON61tXXr zJxqAa+NPl$=h&LVrU&H4#-|i42A+x)#z&b z6O^LYFtUo&CTo6?sQV^xumSIhHpm}CIewu4qMfF*?<Pd9-G2CGU)K*Ra8v^Izm2h+|`u)G%ntk;;oS19Q zT&0MBoI0*1OML=ff??Z!43GaqKE>+uz4$1-NCy`w;HPQfg+d)_bALj>iT!C>n8$gC z^q&i!T4z{n7l&vtP_>{a8{w`jYX}VMgbin>PEfviVsUiY2_jY-)h;d1{*q+JZL@!{ zE{v7#S|Z^kNWXMy5S zNCJhn|_!09W11SG7y!4M=|Ikv(L}P8(H!{QX?Z_|< zT)p80Q5Q6laIK)xu4ZTUj+@+PJ}>2`O#uHo2b7uOdp>XxN1!U4#nRS>85GjUcEVm&Us?8(0bb3x;dRic%u z$sWApj@b%sD0XJF_VlUKyL_`VI^znm)xG4z&I0M}oY-Et(<&M((y--{2J^3fEdeuV@t$bl{+pFN;Ln~Jm{vUP5g^u!3 z{p>pVzh32+t~v8TMmqoBHRkfOgL6~?bYIs266!ivyPSuXvf_mf zR=zDAT%u;go-9Vb=~y8LGn$nuhJUn+MF33zoWLgMlDmLUB&&}GfRDJ3&tp=tt(l$? zm{G-vO2A5vYm{t5n{_m}rQUA(vWT7tNlKo@y_$<>fRFgZ=M;dNgX*Y{vj?9T*sT z!(FH;6{%BgIkxVaB?&U*N%FzeNh8400Oy=VY2POaf>Ta4hr>TXamk)wxPRK*621;% z&ME>&833ESw3e?9KpcDq>(0^g;g<)Zextbj`C}Xr)!M5#@JohpbxO-G|@gvD_$E}NR z`q|m7?bX#bxxc+iS7z^MZvcW=zy7gDnfm+lN9X^Tx!RuHrtZA2y*evx9@^YIyz#_% zd>Z}+gKv-HaSHE?@&WfQJX?5P;f}&RxOZo;o9?7sZYr@cS4m*#=6_LSwP{n7Z`yrf zBd1(4}sCl;v$BbB|Z{?~?17tT%dNH~Bspnuc>d?Op?;re`kr~oWW^f{06 z^)UHvJYNR_u5^reg=$@&d%UFST#En`S(<69v<+b-Yd`>ssmMyki?<|E8Gi1r|owQ!+WNgn6k#zsYhmsR-7L>BTPNe)MJDJ>@2frf)l#iIKLZ5Q?vCZV(y)P1y-X!gVE6`<06N-t z^WD^W5kZM4okl%H7m6rG(~J8e;yD0@A6SQm7cooKN=k-n4C{&C6M@+=0m*2UO6XbC zHVO5^g|OA`uYbnEi=|&{2DWrP+f@cHjVTSrePDjgr07`pDF^Xmty|0y2@eidfrU#B z=z7}*arxGkS?&gpXaN51rs# zTY08l+qiPi_3cwjh25NC#PG6EEu2)lA&=WdWb`hw3~H+4Xcr8sZI=2fM|-{#V!pqb z@_HwO7LgoKYdd?>-U_9QPw+l&uqT*PE|q+$ zC9)(c34dkH%Hk4;Eu-lG>VwXBhHLWP?0?x&B~2TG7a6gi{DLsP%Nf1Rb@=D!L$*?M@|XN(_W{K>qSr;(x!PQTIJCcQ2&W@vKfV*VlXK*9z|_ ze5mj{`OcEc@t*8%O*R(`$}^9`W_K&uIRH-L-G5yS@WFAu<328yigPn$gwDaahKxeI zYmIi4;>FcjLgn!SfJBtAop1J!*gQK?U(=6z&ZK90l1YY4GLwl(1``Mb!!H31!V(Z%LEI!nkSGKV z55dXu;~|d~TtHC*F~KZo{NWOD#Z}lvk+8-etLtiZdHquC_dmC~C!%i8RCU*_`#9%( z-}xTreBb{IBBfKSi4vrxjxBef{R}x?-+x;@RY%Af0%HsjHK2+}Un!Ra6Q^e=$11ls z$iyaMQ z9K(=&JWu9r2lny}R_j(nm@kD}Ac;nbPOzxks2H7Sr2J zS-S}J-3P7ijPps69)P9a8Jc^M7_i6k?r;EUs<$W$%#-Ybk7({__fJCwBY#Rnr8+`5 z83n9)0C9#{fgobuFY-Y#dG-xmyx|Vryq_Hy6Wd4Fg%87HEUAvRlhK&};c3?@$7S1T zF6(F_XQ8vRyyzG@^Q`k%rrl`Q%L~GcHXY^?6)mQspce6kX@gE*DA(JK!1F^M*1||K z%QCpj?M?QEXMlM`yH!4OhJRZKh=?|A7=C0z3FR?sjm%2U53TraQcqle^>$XKINuP@KdeIc*R%`MmK4aPtAIn$TYH-p`F$0yTK(f^7cNA2A=7b=SEN_1bOJKnTz+*h-umok5r36S5{;W7R+S8+ zyftnbEL@R1B@;Vz)w{%>V!b;l*7x*YKld5_-xcCGVNWnQ+Y5ZD{Ipos0?n zdk*VY++vJf@L5XY-cm)cWR&7TlOZS~4>_PhM?H z@VRU0N4)8wTffVU=YK!^-51>Tg7;rHb+6smF-%ycLu5_fTKYH0=GOZOI-p!<8xQ)& zbe@XdSeYES5gI^bAOECBGEVPH47FXS1G+oy1!BzEUe7@eYd%3x>Uf5alJ&>ziQ}!F z-Pnjj8Aj`$ASuCKq|8P$Iy#)IxFj-`Tj?D^H3}U!xP7lUm46Jj;#7Xyzji7&dac7w z-mLGfZd)QkP}oYx_J!k1-?d%;rLAT0X(x;-0S~{?YaOwF@KjQ4fvHcued)rfG+e&+ zOP}K3*7yuZN@r+x-$Enz>e3rXJH4y)A4;DrvPAz0$nyeg6=qaX-3n-2qY2XDX$DR( z9ec&!G%}-vMt?iWs)LLb z=*!R$Mr?9NZPE9rLK6z-oDfKb^9-U2Ib5bZLh>FykUYntvD>%qsbsZHo$7kg?B}jL4)@sVR?8OJleJp0K~j;803BBHkflNlhgqP+kM$ zJ%X)bT?W_&rhp=KF;=;i(ke<9ITBkUDxE65sPu13_mu7@>HoRXmrGwOJyH5!rGG4a zyYzjma3yJVe|BhA+2oV`2!kR>p+Fp(McvL8j(>H0l$PEzJlh`fJTBC!LyWX4ptGC2 zh!E@nu2s%T+QEdBgBg&#zM?zU$w!j|tf(|I5xt;Ise+T~R_1=BPO;vhpR~UOGRs;n z7JjiJM}Nc}&2qYTD(#ZD)}0V5PxR58e^f4J*?e_512$yX*j`{VkL&d+Pa`s-vE|N` zT7PfU>y?a*mVRTYnav9_D;onhPSe<{SC&3ux}oxIVnq=y8Sbb-uDS}ywXp-wAsa@< zZ;kE7;bxjf^^o1+#YE58^Xjc&u3pZQ>4*9aGVv=*bw5q!mQ0P~a6~9>8);Clg>x!u z+GnSaG6dL4qgksaUS?I6q*(r0zn)e5Hh&^cS#>Q&_@7dasuSb;r%%bcRM9I8t85{l zw0qc?{%?9yU#H`~tg(B9dF?FjSo;aCy=SYx7Zj~z| zj}qJLHTzE0S9aaDri<+UiR*j-a`R?icsY}s)mu7^t|&Aev0kwhdtBfBQk+;;v_x(z?8W)*T) z?5e8g@?^PER^d)M7m-CNlxa)PaoNafSgPiKzeK;?_>c-3<&ipi!l^$0gzYa3{H{;t z$SnTvG4g3n0)e<&F!?Mlt5|=_b$^A2!cOVWGUG=&k4~eA%w#HwV%F;Ggnv51A$pYKvE1y+B5>rLdhu?V4+qLx0!DU4@Ms zxkRh7l5#;d8qMR;Qet=Gin5exB3H7$w~&Wbn;gG+DNcLSy_IX57vk`yd|G68=yWuV z)1iYW0$>dkIb%SJD3-l-ROI-d)J^0YcTm%g(ll^^vt*Y~l-u{T$;Ku@wa`OwH%Yg+ zk}a;U?~F*?PDMB-L0hNS+kbxU88*^u;Gr5ud!9sc#4O>DyajJ(X>D<{vE&=t_9po@ z5*zHf?A`27*x#`4pfC=v@&%qFUL+grapbL%DkCdEVIedj+hDLLpc9iSv{sQ-ft39! zecNCMNgvqND5%bnrbeA7F-As(Ocps3LV6t~2M7Sw*mY!!XwbSM!hfWrlQE0G+d5vl z(;n$m+YrMw%16B+v|dp+gj6U;h%wnu?PE;mY;=YlofB68TpxhjjOZ}Z>qe+qI2a>5 z3vS{bpA4`NOAj6IB4QCJY*^17kR?ANiwN=9b)*GOImGI-wCp z)0rLEmTVvRuDidh85c+34A1hE`TNPyk9G2~kPQc76-z8JNqH&1AmBVjn584>MANLNFhd&Hkhi5_$EM!%H_SE` zn@JePf-DU3pnpB3bHrQ|J~dYRNJdca^d_|rXgQSAVICsfkP;TSri-{dIxRNU^jH5b zwikoYc0w8&3EWV6m}QXlq1Us3MB}i~BrTylfAfThJu@;J!i#r$lHL4VN02vVx)ty6 zVfaj+mNcpGY*)pALyqU+VfnhD&xIDOpdL zmX63ELXrsP7SbpXC@4~_g-B9BSPVB=!!d{s^pRXT8jLzAE#C&3zEMwwTm(zN{<47} zR#4(XYkz)#4hE4y^Ozw2k0ezj=~=B2lRamHCKYxu5pm@UlIN9jn2>qz zsegJ@SH9^vG{VY`+@P^y`ilH)3oBoiX-5mk6H>`E+=1}?SemBila?axH3uC`tM{5^ zX&RW`vp2NaP`#9C-+oSF3)+@Nq%-6 zXje?A3F)UlI6_ziW?<6FR zMsqE{9xwZKr?2rR=PZC!ifgjPaux)_TB^j+1sw2E34to4SX#*D7_@?-!j~Q<8bgF~ zLT$9tWOl+h6NgMby=65^*lW5!^?&X&SG*vI=H`Cl>Pvq1rEOLDd^xF)0H8KZGhy%|Z zS?U+IfwN@4G%wyqK_N8?7E$6mtHy`BQsk+nfG6X@&Sy-0Ig>TO=ARn)=yt>tt}vidzx>YlR4O zGC5uUTHzU{GL=I@MZN#E(nbAHq7^;;wFp&qDw0&n>t72e+*F38VIy9P#bn2J=~Q!n z?+5rK{nBxuDkJs@^M8?NMSoS54v=VdIt}m%ib>xC-~riElc(pSJZJ|eZyqnr)dts* z!{H=4>*{Uvw7QOQRBslS-4NHuH*CvuhpxWq>a9(B+vH32x!UlVee&5Zecog>-tHj; z?QKYN^ktpYxVra{DTB*z*_6!N#6{1gx3l|oZTJ%v@WH*^Und zj>j9*FR;Gjd9SY@d^Nq?b5M^3-{Kr^`X~CjAxY~lv%WxIcu#%VbMC#D&Um6dw>Q^n z(OdhP*zxu}`tQWH_kS9FNPl?^ebmQoI^i|#`f;3pyx!hD?%T2Lr}R4RU)Ym1g(NPA z#U7v%kFNKVsf5Ns7c-&Xf6NEd?(QzTZThyyA7@+BFA9m8KBu<&TPvqmPpw{9e=O5H zSuE|qH;Kzw9?&t_dh4%T#3`UAB_v{8Y_I_N2m7#CLjb5_XMa5Tif|XZ?9HTYSL>z{ z&SEv0zEpn_*ErQyOa{QC*mrMNw%&aCnLm@UJUX||HuM!M<%$S;fi-<8Ggvzf4f-V5 zjb44dN*+yjy?S`961&wKs;!F;=Juz=Y2D^a_3CE64{oiqtrrhgEC7t9LyQ1IlZ`d{ zOh;F5(}#9-%zrf@rE%abr;_2k);rB>EG(GMLV9=BXSfK6ySF-_mwrENzJi~^hQ zk9{oWNk*M5U0+lOnMHdYD4s&g^ba;su?VC&OcJ!xy{CTmouye|@EPS6h3RdR`q>$c*mQ*;2Jv zea1>{fd%ejjoj(yUvkCtqqZMae3yUon%y&({rHtFBA)TdSKfHZwMp=dh#ShxjE~-Q zwi-E+B7cI*B4ktA&$#%^v!hneKhkx8(rYeNjvlXPK7ujo8-rhrVlPacgM31gTdyZw zf?A2~3wzAT{u0$lYUuKP=eVzPeMqPeb1fh=0va^V)9UeoNrp69Glaei;=eb{$#C~8 z6(^qbwikUC+Lgc#4e}lAv>xR<^$id36P&B+^nbx<%@VNm=pQ*FBz=>{+OXnR${tyo zB5-`_h_3=QUOBdexEAh-yQL&2W%ufHFYGV5KIfiQHXX8d4AtB@c3Jbfot_4};Bj1@ zKC%#C8C3x?#0bpxMc%c;>$XE>D;K8d1`$ot&9D5imzk+siIlrPUa?pqK6)YclV_7b z$$zJVP-!Ei7zeU+1Yip_5bzA$Xf$ItWGrbk@&Zp3@)PTmgEnF(2Z-C#u;)NXX*BX? z{?k8kX)kqMyVKq1ES@}k{>0*+mlLnPJ+x)T5S^Xaj$~BHjl`+g5$T=Q-dM!gPf04( zl>9f#nh%_GUO0}ZA*h%ef$cb4g}Z~b)_+{EeKg-|x5#n7VltkuS&5y!>F8;j^CiRV z3N}w(LZxgu9+RXuqxN!AHSM-g&; z|3wz%x1F{v*3%_#75Ui8lClvr zEiI!7V#T;;&JpR|dPO#*Q#T@0Hhi-A4&pI>NSt|E{k1IVbyYIK?@oh>kNweYc(F6|_Cb1G(8E+N%gKke{h@~Vm z0})!-njQ2yYEVqKT^1Jy7k?Oi4c(-3pY;M#Z&s9S(m~wUB-3|j6MePJf~ArSLe|4| zx;8k;IjsG#=;RyO`SmUD(*K;R|?u;UbpLRT_cFXFctJls~UwrapyUUH2oDxcyt6gK%-`HU0&F37u zdtiGY7A7g>r7MedQGixfHBeQn2!)xHlWGwNM?M(>pcYiZa*-f@DTzC2&&k?5u$%}QD#PjO$7EmITZHTDZ?8e@bcZ$@O z@HacspPtW;nBt;C?BA#e|S^5WNvNjvD zOW6;z=d+iyyVx(W53o(I^&JTM~sgdzh!*N_&wt*#$OoUFkN%gJZqjaZ!mw+ ze5d&l^JC^`%`cc=GQVbi!~AFE3DU8cU$kU-edim^>OPV>+{whS$}GM)q33e8|&|^Z(HBDP202Q zNF*J$_v|a}YwTy+x7shVZ?|7*-(kPbzQ?}LzTf_^{hr7G- z9y#4H3jqv^;0#qAq!V4-O6l6_6CjU&4@0n)C;B`c6K0bDZ4h7;-*R$@ZlqjroY+HT&5eL`0D7TJ~^y_7W`0at24 zn?AskA~B>98js;W23x-)JaT(yf-M`|k?xjFhA@YcR3T5Dq!8k>+d5Zt1_Ff;KJZCZ zb&&XtYsQmaKT(~*1m-@ydf5C&b@XAL4S(~2svC*Mv$LMHB z=HqOf?cgi&0#FGVATcTdzVu``q2|*o1=Waw;quEYK@Avc*3M*5RbXyiEr>44Ism1f zZ1Ua&z+=6gq(dzk7MQkiGN<$z0uT2^o2=B7qi!#Gtp&hdPEHv$^-C~4ouF$ zky!#h>d`PvG>Pcao&xli?&eW8pl4(>^u1)*(}cnpBgznaGc?UdLtV{^dQ}WDvBD(T z>0yQgsteFN{Ylc6Jq!%ld=oiN$qyoFl+4I9&L>6H1(=FTgOm31ot`e<4Sy7$F{*-O zdKp*eHIQGh0Lpg*WLJmW=ceP@gc9QAh-3&xx)&?@hDm1en~DMUJVFjt7_r z2nm+D#CI+``6wf8jpx$En5&&5Y_Gs;+rpjO#CW|7EYd_;Pgcby*SP5ZWM{u735kGF zy2o-PI}-^(Il61W@^NR8AAf`0rp+W8s3D{`L>IUO#K0EwXxOKTiN|ErB&GLQ$@K1R zAJ_EF>GqkX4`z=Jt0Td^zcZ&hLxV_@8B=Bl5b(Wi8eHmYj|_D>($*ZF6sCAK)^|l4 za}+j2sL-gNP6mb4YbV(d?1g!NlX{3CN{Oa=Ul^{zfbL(-AOeU4P=6t~A=*-~$_`C{ zAv6qNQg?{HAqUlRJ;pmU1ZV*8Y)J@DKm!fMM~$EC&_hRbYoc18M3KZ~(O=HwHE}92 z#0cSM)KOikn#|6zYVR*LboNo|ji{O95B*BAf}YVCr;>(c2u>x9qjgI$EF?ULz!_*wGJm#;u_W;TD90vrT%HY} z3MYytNCMzihzWB4sG}1iMRky=A<-Q81(3Iy7P0hn5-nAnm`{2sb)nq>G{bm=i3eE& z_%D6K(U7{IsSXKw>Mex8B!{5WaK`#qFC+a+MoNDmd%%Fjg8&HB9}#~+y>)=O08O(q zCLWPnMaUmbgMSVwQz95Kh+aNMtwG#_I+JUACR1o9HM2v^KG`Lggby%S*#IH~B-Knq zvoZm+KXG+6YinK|Z0n+ZsMiP60`={r0GwZH zEn*2q#2P^VA-)A;C$iTcpgm;OArg3}uOX+@h~LS$<$o?!0$*V5#}6z+nx-LFgp48< zMFzJefIHHcZzr&6|-w{iDp_rfu22 z5nvOOS#+6;Em&^ZQs+?H5^2;1!fMHFGO(t?e8gijQ`#Lm!;6s1jv6SaWoZ?;&bW)v z$1Lvn^nXQzYXC!fE;Epdj(Gckvobx&M-DZeVz?YId!m47;ixgDQA`nuO&0>_z=97W z434_m0AJ%g(fhVKl^UR|W@gcIEQ2i|)my`^VQ0-imVA+g4}ivm7nRja?Bw4w*n*Zt+i(}h5qkf*I74Fi#OzBk!!y8rbhH519}UiaTVHSLuMORn`x!gW zep92v;vs53>s%NSWB1UhMpRLjcSMIW>i_y)53^M+-a&sp8&UH_d7YdtOqaR~2!t_X zX@8l%&>gIzX@>C}#y-Q?I~b?ybZCSwNQTbPQy)gd==yWLf)IigYIMOjekYA!A1I>n)9h!C+Ux4T<_GHy7|HsZ|8iU zcp4K^=*Q6;wc?YEEKr@I$8@rw{$LafUwG;14x5pTa5n- zV{g~rhwP{8M!HObOrg6Jv-98he@>VZJ~iU}-2%u=JzmVX#? zu!Akk+2~WF9aLj6iuieIHp1L7;pqu~X4-U;{5>$CZWPy`!|!G6qkyAiIFV_Hv3aFu ztd-H)}eSeNV)@Jj?pib!#2Y(xDuo1(Q{5NqwWo!B}l*~2XGP@gN4aV+-#M3;I zK@w^%!N$I9@dD;!Hc^=3uOwlvrxtgx$Zn%E0wRDt#tNVbHiLDcxBrB&4dmCE;7#`L z9Vc^q55)B3?4CkP6tP6){n6RY0%p^~PqB3!b;8*D4!|$OtxQ;8hc}_KT>UJnL_)b(kqs(I z61~b4zmN9Pc*Ts}NczD9y?Kui_!yRBhzy_mELU~SDr@OFo}#D|`8?E4Y?^7GUaLvhD8%nXGhm3TgIrCL-n$ z9&Bh5g3Eb~6cs4chQ|FSvyw|&NLy*~8j2#2$Y7yhs=$EhA8I;A;R^9-wCcjbqH z5d+^D(^YZhaZiN4Lgi0lV&Wn&vat2oxRCTTydI6eU1h|L0e_;?OiW(J3fT$yV1wla zTOnpQ8bMZucoVjZ{^|I7OCb?kMOvZhbZWrAqjtDOv&TY+o<>bKAz`>76{HyR0PKs_ zuyPhOQ1Y8-;8g4`4G~}5u!5cg=w{mqZ5aj96u@dVEacSMwqsi0AsY{nEHhw)X?5q4 zePIU5lr;fHB!64V_o7y0m04tUb1Ni)v8DpGB2h&YAi#BEBqsz&KM#oI1ZJ4BiQ~-6 z^DbTKA%2XvwREG4!|-xa9fqF&lFZGv3?1sAMf62T8x4GoK9V?*U{#@Oco{&QK<<<2 zXiE!`h|FIE3}qNNi*1m>1BGC<84iRINp?j{6mslN8h@_xNTNcTP@^5hL<+}BxDi+? zAi+#`g{HBfDGkKaX-OPZ#Y`84g61LzViDpmfxIorgtc^=wL&r_i35`clI!{-mJ29d z!$qk~fM(G=QLdD(fhJVAtgOmUflw~N}9yD`&VqHc@03@!oD$|0aN@GWY#MJr=@B^kQG$Iibm3m2L zXpnQQ#WZCk_MSaYOO?W^29+(2z*>PI&@w(rAgD=ZYhqZK{uT;Ls6ZBe1gfPn2v`FZ z6MvStvS>89MskMb41+_5%3=%Mg&MH5b|;AoxJ$YbNhr2dwcIihxT*~TOeI^PsuavX z?Rt=@sa#Xr^E7cxQM6av&R{+b|3<@M$coOP#e>0cQaTpNQ5#+pW;x0jTN+p0f!=o0 z5Z01U?1FrJ;gM)JjS!&B=KOq_xW?43g?}Ow#9(&e#D$pEsQF86i|AxbDF|x?U4!C! zg2?FsgpJYMKtv+a7hF^{!7P`0UegSu(F&ABTtVVq!Dyl;nmR&QgJ;+=bv#S(R60Pn z;y}aq$SU-uc4H80!q5@OBCfpz4!;PI)Vg}0_6bdlpsB?=iz|SgwMbiA8o7Y@lYgEW zgd|lkqR^BuaDmuQ5%Jhk3+8Q2{ zW!*A|VLVNM?ZMe?vL(2v7EE$p*newFtt+#^Nlnxb&ph)EIddsAJZ!U`sPS@1%qiYaP5R@{loXoXB#G`MmN(= z?+^aWVi%VAZNcIoeEMTWdp?_ZFNYK!cDgA?}u7fnXK~dX?zSz$p!T{({<{3_Ov7xLB z;1;2~qdlezBjN~3g=lE$8Qeg^=T`D?o|Fi&iYF^8nH4Sg0_cle&3ERw6IEJefX#4! zJ>Tl)uU-r0^7X6hUQ}5%k9G4TQp;|oQcc3dlpCpGsj_lNXgghih=06>*x0PN^QK6G z$o8(6Ch4cR9=JhZX``RtU@O0tWR5Ex70!hwV#df!En7iqS7YC^JygIk18>-C8D_9` z$JVurE7YJHPq$;osBP?cu@jQZ7{sR!E!u`sP9<-49MZt{snDX!g`Kw3uEE|m^{%_7A7wxE)PEQGR%stQhlxY~Ebkw6 zIMry9l~rP9qn;{fiRdQk5F3d&#!z$YtJ#upY59ZwWqG$K%HU01BK6K-I=ym(Kb2m~mihQXn z#U8a_t8@i%^na^M_mw_e`dsNROW#H8+ARER9~x=^e%@qi1`&W5prU+M5w~NuI~ov2 z0bL>+6#4%c{yb~%$0!56e2*i82}rSeH9k4OtQw?5EnQ96)W9G~5r>5L@vNHVEQ7R{ zOC6@90}1hTtfA^OJuM?ry)C2DM6>N9sJ^ktXJu{og?~&@atAR}=`K3}%NlF&Z1%UL zeK*rCkTX?eWNgyl<~_nhvWqZYkOo+KaIA*WM&;R&Vfbg`r~!+GEDguC8fL3r@p;WA zgGD5j33%<2$e%Ni3olx<&ts^-J zmCBCiB&PMu(5W8F_j)zhW3oTLxjeflA;yLS5P>^eqo{7ap0vH5RxzQod<>3`)*(?8$(&V~5n zL!wvODg8|8Aw(|%&KP0Xor8LO>#V$Jg1t4mpDtX7%*b-qH;Wnq9TMgU0-oi`VY3mr zgUDGywK|)<*%Qav5PzE(ZP~5vjLI5FYaeV{2W*XJ$jx-@U-?Qm zY0?*m0{0v1sCl;GuE!holTA-}{W{7-G`H-u!T94q2oh}i!3I`SNZs2q)+pryRkN|6 zU6&|`M+EN*co_gv7fqB?wK+1}7_Ub#hfaL+fsez2{=@^n1&f0IECTemP2Bp zv|Tz?x|d|++e^PvdROVaKqW#C58j3u2>c{E5+T6#o(V~0u{ zGMw=5&D3zWYW+GoEmKJ&I)BKkRV=GhcDJ%EU;LvJ@!Ge}>7VPbKX>k1(|_M)+}(1Q zx+0P!#aKNinl|9nN#EIWlGqV3-ATlNm4hc^1wI^vrbQB^b93>-KR3Oe?89ge0>Bmp z@nDz!Azh5c6Y>i{Qoiex*vUsR{Y&Z9-KBBAA(eY4bh*9J2HC2YVGAO;NyIB1GzHke zsTmu1q@aJ9ioOiain!L5u;t%qR zCJ)?t;w8_?(#G_I{Uaw_QVwU2U-yixwN$IMS_gU4-{XH@dIeb{MSqMgEIC-PG@0qw zSl1$&1;iItpAOQ(TVJO#6y?{_0^Cdmya3nHX<0=C;b5#Q=*={55ldAVko__HNvqf( zQgfN~iEw4pvocQ3QXHj3gR;gJFaYbPnp@<)1rF-#*vMrgpQ<*2Cu}4%<;gLzI`dY= z2}9fQ?P&G-qvX*j%YSqo>*!L&uNY=1tS3p-O3%n5Q#uuLaKfdXjI6$PeX*AKWI!eh zmP0B@ao1czuD3&8j$8FDawMgH%k{#y$jIzBI&IRtZpCongPNWSOzU`LU|CC72$N(f zKCO1o4WdCd)It$!zs|;$2_P@i!s0-gVqJ?R<*DV{#$n>z?teN0lvTwyLyPA}cR0^a ztg|Eca+Ee&cK2^9?-d56Au2=3@o>BmsX?XP4YI4BR=Y-QGENoZfrSrZ~Miy;rB#3q?W_C5og;YKzm0 z^Si_Kp1+0f5r6~|>4t9O4A7z)76Kl{k&7a5b*M zwYUz~;|AP_n{YF3!L7Irx8n}niMwz&?!mpd5BK8%Jcx(zFcyD!1drk|JdQJX0#D*8 zJdJ1YES|&jcmXfsCA^HYcm=QGHN1{D@Fw2E+js}>;yt{N5AY#A!pHaopW+-o!{_({ zU*ao#jc@QRzQgzU0YBmhKY^o$fCQmIiw+7s255{huy8mJkAR2?ORTWQ1{d%%e!;K! z4Zq_L{E5HtH~xRYMf^L%xtu$viSaPze3HuMHLpqMwOx^Cb*q zv|1~FV&{&6@XAF-dd$fIp8;V0d+Q4dTA5f;?8wtJmdy@s+3=-GRjNjLs(GMt8#H!Z zG--D7Sz}FPt%^mu-BjaycuAg$BG znu^rf4ioEWopmvPB~@#zCwZW>o()2qTJ#i5WZxbIb^HaS^Cd7H*nnIJrrY!KZ zBB73X5M1*j5ci_10>!9I8}dtSvZVA_gaj;Zir{?86d`UB$7Pu6lp_|FZ5~#tiTg2a z2T!#}7LzPL(Mp@em1^g4<1TZyOr7$jl4RL(qH;yGOB%CP8_Sh4iMx=kte0%916z+e W+i-8#X4LG0a Date: Fri, 10 Aug 2018 10:55:22 +0200 Subject: [PATCH 0656/1276] Use QuickInput (#29096) --- .../platform/quickinput/common/quickInput.ts | 8 ++-- .../browser/parts/editor/editorStatus.ts | 41 +++++++++---------- .../browser/parts/quickinput/quickInput.ts | 2 +- 3 files changed, 25 insertions(+), 26 deletions(-) diff --git a/src/vs/platform/quickinput/common/quickInput.ts b/src/vs/platform/quickinput/common/quickInput.ts index a65975541cf..1588078e763 100644 --- a/src/vs/platform/quickinput/common/quickInput.ts +++ b/src/vs/platform/quickinput/common/quickInput.ts @@ -223,7 +223,7 @@ export const IQuickInputService = createDecorator('quickInpu export type Omit = Pick>; -export type QuickPickInput = TPromise<(T | IQuickPickSeparator)[]> | (T | IQuickPickSeparator)[]; +export type QuickPickInput = T | IQuickPickSeparator; export interface IQuickInputService { @@ -232,9 +232,9 @@ export interface IQuickInputService { /** * Opens the quick input box for selecting items and returns a promise with the user selected item(s) if any. */ - pick(picks: QuickPickInput, options?: IPickOptions & { canPickMany: true }, token?: CancellationToken): TPromise; - pick(picks: QuickPickInput, options?: IPickOptions & { canPickMany: false }, token?: CancellationToken): TPromise; - pick(picks: QuickPickInput, options?: Omit, 'canPickMany'>, token?: CancellationToken): TPromise; + pick(picks: TPromise[]> | QuickPickInput[], options?: IPickOptions & { canPickMany: true }, token?: CancellationToken): TPromise; + pick(picks: TPromise[]> | QuickPickInput[], options?: IPickOptions & { canPickMany: false }, token?: CancellationToken): TPromise; + pick(picks: TPromise[]> | QuickPickInput[], options?: Omit, 'canPickMany'>, token?: CancellationToken): TPromise; /** * Opens the quick input box for text input and returns a promise with the user typed value if any. diff --git a/src/vs/workbench/browser/parts/editor/editorStatus.ts b/src/vs/workbench/browser/parts/editor/editorStatus.ts index 20a1bc2d68d..a4db8633e97 100644 --- a/src/vs/workbench/browser/parts/editor/editorStatus.ts +++ b/src/vs/workbench/browser/parts/editor/editorStatus.ts @@ -31,7 +31,7 @@ import { IndentUsingSpaces, IndentUsingTabs, DetectIndentation, IndentationToSpa import { BaseBinaryResourceEditor } from 'vs/workbench/browser/parts/editor/binaryEditor'; import { BinaryResourceDiffEditor } from 'vs/workbench/browser/parts/editor/binaryDiffEditor'; import { IEditorService } from 'vs/workbench/services/editor/common/editorService'; -import { IQuickOpenService, IPickOpenEntry, IFilePickOpenEntry } from 'vs/platform/quickOpen/common/quickOpen'; +import { IQuickOpenService } from 'vs/platform/quickOpen/common/quickOpen'; import { IWorkspaceConfigurationService } from 'vs/workbench/services/configuration/common/configuration'; import { SUPPORTED_ENCODINGS, IFileService, FILES_ASSOCIATIONS_CONFIG } from 'vs/platform/files/common/files'; import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; @@ -58,7 +58,8 @@ import { Schemas } from 'vs/base/common/network'; import { IAnchor } from 'vs/base/browser/ui/contextview/contextview'; import { Themable } from 'vs/workbench/common/theme'; import { IPreferencesService } from 'vs/workbench/services/preferences/common/preferences'; -import { IQuickInputService, IQuickPickItem } from 'vs/platform/quickinput/common/quickInput'; +import { IQuickInputService, IQuickPickItem, QuickPickInput } from 'vs/platform/quickinput/common/quickInput'; +import { getIconClasses } from 'vs/workbench/browser/labels'; class SideBySideEditorEncodingSupport implements IEncodingSupport { constructor(private master: IEncodingSupport, private details: IEncodingSupport) { } @@ -834,7 +835,6 @@ export class ChangeModeAction extends Action { @IModelService private modelService: IModelService, @IEditorService private editorService: IEditorService, @IWorkspaceConfigurationService private configurationService: IWorkspaceConfigurationService, - @IQuickOpenService private quickOpenService: IQuickOpenService, @IQuickInputService private quickInputService: IQuickInputService, @IPreferencesService private preferencesService: IPreferencesService, @IInstantiationService private instantiationService: IInstantiationService, @@ -867,7 +867,7 @@ export class ChangeModeAction extends Action { // All languages are valid picks const languages = this.modeService.getRegisteredLanguageNames(); - const picks: IPickOpenEntry[] = languages.sort().map((lang, index) => { + const picks: QuickPickInput[] = languages.sort().map((lang, index) => { let description: string; if (currentModeId === lang) { description = nls.localize('languageDescription', "({0}) - Configured Language", this.modeService.getModeIdForLanguageName(lang.toLowerCase())); @@ -887,20 +887,20 @@ export class ChangeModeAction extends Action { } } - return { + return { label: lang, - resource: fakeResource, + iconClasses: getIconClasses(this.modelService, this.modeService, fakeResource), description }; }); if (hasLanguageSupport) { - picks[0].separator = { border: true, label: nls.localize('languagesPicks', "languages (identifier)") }; + picks.unshift({ type: 'separator', border: true, label: nls.localize('languagesPicks', "languages (identifier)") }); } // Offer action to configure via settings - let configureModeAssociations: IPickOpenEntry; - let configureModeSettings: IPickOpenEntry; + let configureModeAssociations: IQuickPickItem; + let configureModeSettings: IQuickPickItem; let galleryAction: Action; if (hasLanguageSupport) { const ext = paths.extname(resource.fsPath) || paths.basename(resource.fsPath); @@ -917,7 +917,7 @@ export class ChangeModeAction extends Action { } // Offer to "Auto Detect" - const autoDetectMode: IPickOpenEntry = { + const autoDetectMode: IQuickPickItem = { label: nls.localize('autoDetect', "Auto Detect") }; @@ -925,7 +925,7 @@ export class ChangeModeAction extends Action { picks.unshift(autoDetectMode); } - return this.quickOpenService.pick(picks, { placeHolder: nls.localize('pickLanguage', "Select Language Mode"), matchOnDescription: true }).then(pick => { + return this.quickInputService.pick(picks, { placeHolder: nls.localize('pickLanguage', "Select Language Mode"), matchOnDescription: true }).then(pick => { if (!pick) { return; } @@ -1045,7 +1045,6 @@ class ChangeIndentationAction extends Action { actionId: string, actionLabel: string, @IEditorService private editorService: IEditorService, - @IQuickOpenService private quickOpenService: IQuickOpenService, @IQuickInputService private quickInputService: IQuickInputService ) { super(actionId, actionLabel); @@ -1061,7 +1060,7 @@ class ChangeIndentationAction extends Action { return this.quickInputService.pick([{ label: nls.localize('noWritableCodeEditor', "The active code editor is read-only.") }]); } - const picks = [ + const picks: QuickPickInput[] = [ activeTextEditorWidget.getAction(IndentUsingSpaces.ID), activeTextEditorWidget.getAction(IndentUsingTabs.ID), activeTextEditorWidget.getAction(DetectIndentation.ID), @@ -1080,10 +1079,10 @@ class ChangeIndentationAction extends Action { }; }); - (picks[0]).separator = { label: nls.localize('indentView', "change view") }; - (picks[3]).separator = { label: nls.localize('indentConvert', "convert file"), border: true }; + picks.splice(3, 0, { type: 'separator', label: nls.localize('indentConvert', "convert file"), border: true }); + picks.unshift({ type: 'separator', label: nls.localize('indentView', "change view") }); - return this.quickOpenService.pick(picks, { placeHolder: nls.localize('pickAction', "Select Action"), matchOnDetail: true }).then(action => action && action.run()); + return this.quickInputService.pick(picks, { placeHolder: nls.localize('pickAction', "Select Action"), matchOnDetail: true }).then(action => action && action.run()); } } @@ -1141,7 +1140,6 @@ export class ChangeEncodingAction extends Action { actionId: string, actionLabel: string, @IEditorService private editorService: IEditorService, - @IQuickOpenService private quickOpenService: IQuickOpenService, @IQuickInputService private quickInputService: IQuickInputService, @ITextResourceConfigurationService private textResourceConfigurationService: ITextResourceConfigurationService, @IFileService private fileService: IFileService @@ -1204,7 +1202,7 @@ export class ChangeEncodingAction extends Action { let aliasMatchIndex: number; // All encodings are valid picks - const picks: IPickOpenEntry[] = Object.keys(SUPPORTED_ENCODINGS) + const picks: QuickPickInput[] = Object.keys(SUPPORTED_ENCODINGS) .sort((k1, k2) => { if (k1 === configuredEncoding) { return -1; @@ -1233,13 +1231,14 @@ export class ChangeEncodingAction extends Action { // If we have a guessed encoding, show it first unless it matches the configured encoding if (guessedEncoding && configuredEncoding !== guessedEncoding && SUPPORTED_ENCODINGS[guessedEncoding]) { - picks[0].separator = { border: true }; + picks.unshift({ type: 'separator', border: true }); picks.unshift({ id: guessedEncoding, label: SUPPORTED_ENCODINGS[guessedEncoding].labelLong, description: nls.localize('guessedEncoding', "Guessed from content") }); } - return this.quickOpenService.pick(picks, { + const items = picks.filter(p => p.type !== 'separator') as IQuickPickItem[]; + return this.quickInputService.pick(picks, { placeHolder: isReopenWithEncoding ? nls.localize('pickEncodingForReopen', "Select File Encoding to Reopen File") : nls.localize('pickEncodingForSave', "Select File Encoding to Save with"), - autoFocus: { autoFocusIndex: typeof directMatchIndex === 'number' ? directMatchIndex : typeof aliasMatchIndex === 'number' ? aliasMatchIndex : void 0 } + activeItem: items[typeof directMatchIndex === 'number' ? directMatchIndex : typeof aliasMatchIndex === 'number' ? aliasMatchIndex : -1] }).then(encoding => { if (encoding) { activeControl = this.editorService.activeControl; diff --git a/src/vs/workbench/browser/parts/quickinput/quickInput.ts b/src/vs/workbench/browser/parts/quickinput/quickInput.ts index 2e68c465dba..1f34e401506 100644 --- a/src/vs/workbench/browser/parts/quickinput/quickInput.ts +++ b/src/vs/workbench/browser/parts/quickinput/quickInput.ts @@ -1009,7 +1009,7 @@ export class QuickInputService extends Component implements IQuickInputService { this.updateStyles(); } - pick>(picks: QuickPickInput, options: O = {}, token: CancellationToken = CancellationToken.None): TPromise { + pick>(picks: TPromise[]> | QuickPickInput[], options: O = {}, token: CancellationToken = CancellationToken.None): TPromise { return new TPromise((doResolve, reject) => { let resolve = (result: any) => { resolve = doResolve; From 15b5eb48d14109107c745867c8c1d45c7317e76f Mon Sep 17 00:00:00 2001 From: Johannes Rieken Date: Fri, 10 Aug 2018 11:25:41 +0200 Subject: [PATCH 0657/1276] more jsdoc for the URI class, #56108 --- src/vs/base/common/uri.ts | 63 +++++++++++++++++++++++++++++++++++---- src/vs/monaco.d.ts | 63 +++++++++++++++++++++++++++++++++++---- 2 files changed, 114 insertions(+), 12 deletions(-) diff --git a/src/vs/base/common/uri.ts b/src/vs/base/common/uri.ts index 7ead50439d3..5fe794d4581 100644 --- a/src/vs/base/common/uri.ts +++ b/src/vs/base/common/uri.ts @@ -69,7 +69,7 @@ const _regexp = /^(([^:/?#]+?):)?(\/\/([^/?#]*))?([^?#]*)(\?([^#]*))?(#(.*))?/; /** * Uniform Resource Identifier (URI) http://tools.ietf.org/html/rfc3986. - * This class is a simple parser which creates the basic component paths + * This class is a simple parser which creates the basic component parts * (http://tools.ietf.org/html/rfc3986#section-3) with minimal validation * and encoding. * @@ -80,8 +80,6 @@ const _regexp = /^(([^:/?#]+?):)?(\/\/([^/?#]*))?([^?#]*)(\?([^#]*))?(#(.*))?/; * | _____________________|__ * / \ / \ * urn:example:animal:ferret:nose - * - * */ export default class URI implements UriComponents { @@ -165,9 +163,27 @@ export default class URI implements UriComponents { /** * Returns a string representing the corresponding file system path of this URI. - * Will handle UNC paths and normalize windows drive letters to lower-case. Also - * uses the platform specific path separator. Will *not* validate the path for - * invalid characters and semantics. Will *not* look at the scheme of this URI. + * Will handle UNC paths, normalizes windows drive letters to lower-case, and uses the + * platform specific path separator. + * + * * Will *not* validate the path for invalid characters and semantics. + * * Will *not* look at the scheme of this URI. + * * The result shall *not* be used for display purposes but for accessing a file on disk. + * + * + * The *difference* to `URI#path` is the use of the platform specific separator and the handling + * of UNC paths. See the below sample of a file-uri with an authority (UNC path). + * + * ```ts + const u = URI.parse('file://server/c$/folder/file.txt') + u.authority === 'server' + u.path === '/shares/c$/file.txt' + u.fsPath === '\\server\c$\folder\file.txt' + ``` + * + * Using `URI#path` to read a file (using fs-apis) would not be enough because parts of the path, + * namely the server name, would be missing. Therefore `URI#fsPath` exists - it's sugar to ease working + * with URIs that represent files on disk (`file` scheme). */ get fsPath(): string { return _makeFsPath(this); @@ -222,6 +238,12 @@ export default class URI implements UriComponents { // ---- parse & validate ------------------------ + /** + * Creates a new URI from a string, e.g. `http://www.msft.com/some/path`, + * `file:///usr/home`, or `scheme:with/path`. + * + * @param value A string which represents an URI (see `URI#toString`). + */ public static parse(value: string): URI { const match = _regexp.exec(value); if (!match) { @@ -236,6 +258,28 @@ export default class URI implements UriComponents { ); } + /** + * Creates a new URI from a file system path, e.g. `c:\my\files`, + * `/usr/home`, or `\\server\share\some\path`. + * + * The *difference* between `URI#parse` and `URI#file` is that the latter treats the argument + * as path, not as stringified-uri. E.g. `URI.file(path)` is **not the same as** + * `URI.parse('file://' + path)` because the path might contain characters that are + * interpreted (# and ?). See the following sample: + * ```ts + const good = URI.file('/coding/c#/project1'); + good.scheme === 'file'; + good.path === '/coding/c#/project1'; + good.fragment === ''; + + const bad = URI.parse('file://' + '/coding/c#/project1'); + bad.scheme === 'file'; + bad.path === '/coding/c'; // path is now broken + bad.fragment === '/project1'; + ``` + * + * @param path A file system path (see `URI#fsPath`) + */ public static file(path: string): URI { let authority = _empty; @@ -276,6 +320,13 @@ export default class URI implements UriComponents { // ---- printing/externalize --------------------------- /** + * Creates a string presentation for this URI. It's guardeed that calling + * `URI.parse` with the result of this function creates an URI which is equal + * to this URI. + * + * * The result shall *not* be used for display purposes but for externalization or transport. + * * The result will be encoded using the percentage encoding and encoding happens mostly + * ignore the scheme-specific encoding rules. * * @param skipEncoding Do not encode the result, default is `false` */ diff --git a/src/vs/monaco.d.ts b/src/vs/monaco.d.ts index 96a56b9807e..18baa911399 100644 --- a/src/vs/monaco.d.ts +++ b/src/vs/monaco.d.ts @@ -100,7 +100,7 @@ declare namespace monaco { } /** * Uniform Resource Identifier (Uri) http://tools.ietf.org/html/rfc3986. - * This class is a simple parser which creates the basic component paths + * This class is a simple parser which creates the basic component parts * (http://tools.ietf.org/html/rfc3986#section-3) with minimal validation * and encoding. * @@ -111,8 +111,6 @@ declare namespace monaco { * | _____________________|__ * / \ / \ * urn:example:animal:ferret:nose - * - * */ export class Uri implements UriComponents { static isUri(thing: any): thing is Uri; @@ -140,9 +138,27 @@ declare namespace monaco { readonly fragment: string; /** * Returns a string representing the corresponding file system path of this Uri. - * Will handle UNC paths and normalize windows drive letters to lower-case. Also - * uses the platform specific path separator. Will *not* validate the path for - * invalid characters and semantics. Will *not* look at the scheme of this Uri. + * Will handle UNC paths, normalizes windows drive letters to lower-case, and uses the + * platform specific path separator. + * + * * Will *not* validate the path for invalid characters and semantics. + * * Will *not* look at the scheme of this Uri. + * * The result shall *not* be used for display purposes but for accessing a file on disk. + * + * + * The *difference* to `Uri#path` is the use of the platform specific separator and the handling + * of UNC paths. See the below sample of a file-uri with an authority (UNC path). + * + * ```ts + const u = Uri.parse('file://server/c$/folder/file.txt') + u.authority === 'server' + u.path === '/shares/c$/file.txt' + u.fsPath === '\\server\c$\folder\file.txt' + ``` + * + * Using `Uri#path` to read a file (using fs-apis) would not be enough because parts of the path, + * namely the server name, would be missing. Therefore `Uri#fsPath` exists - it's sugar to ease working + * with URIs that represent files on disk (`file` scheme). */ readonly fsPath: string; with(change: { @@ -152,7 +168,35 @@ declare namespace monaco { query?: string; fragment?: string; }): Uri; + /** + * Creates a new Uri from a string, e.g. `http://www.msft.com/some/path`, + * `file:///usr/home`, or `scheme:with/path`. + * + * @param value A string which represents an Uri (see `Uri#toString`). + */ static parse(value: string): Uri; + /** + * Creates a new Uri from a file system path, e.g. `c:\my\files`, + * `/usr/home`, or `\\server\share\some\path`. + * + * The *difference* between `Uri#parse` and `Uri#file` is that the latter treats the argument + * as path, not as stringified-uri. E.g. `Uri.file(path)` is **not the same as** + * `Uri.parse('file://' + path)` because the path might contain characters that are + * interpreted (# and ?). See the following sample: + * ```ts + const good = Uri.file('/coding/c#/project1'); + good.scheme === 'file'; + good.path === '/coding/c#/project1'; + good.fragment === ''; + + const bad = Uri.parse('file://' + '/coding/c#/project1'); + bad.scheme === 'file'; + bad.path === '/coding/c'; // path is now broken + bad.fragment === '/project1'; + ``` + * + * @param path A file system path (see `Uri#fsPath`) + */ static file(path: string): Uri; static from(components: { scheme?: string; @@ -162,6 +206,13 @@ declare namespace monaco { fragment?: string; }): Uri; /** + * Creates a string presentation for this Uri. It's guardeed that calling + * `Uri.parse` with the result of this function creates an Uri which is equal + * to this Uri. + * + * * The result shall *not* be used for display purposes but for externalization or transport. + * * The result will be encoded using the percentage encoding and encoding happens mostly + * ignore the scheme-specific encoding rules. * * @param skipEncoding Do not encode the result, default is `false` */ From 4fa87ebca6b4550bd05e22b66fcdb223a1ed9b2b Mon Sep 17 00:00:00 2001 From: Christof Marti Date: Fri, 10 Aug 2018 11:33:47 +0200 Subject: [PATCH 0658/1276] Use QuickInput (#29096) --- .../debugConfigurationManager.ts | 11 ++++++----- .../electron-browser/configureSnippets.ts | 19 ++++++++++--------- .../electron-browser/insertSnippet.ts | 14 +++++++------- 3 files changed, 23 insertions(+), 21 deletions(-) diff --git a/src/vs/workbench/parts/debug/electron-browser/debugConfigurationManager.ts b/src/vs/workbench/parts/debug/electron-browser/debugConfigurationManager.ts index f847d1a6830..01a6f1ca36d 100644 --- a/src/vs/workbench/parts/debug/electron-browser/debugConfigurationManager.ts +++ b/src/vs/workbench/parts/debug/electron-browser/debugConfigurationManager.ts @@ -25,7 +25,6 @@ import { ICommandService } from 'vs/platform/commands/common/commands'; import { IDebugConfigurationProvider, ICompound, IDebugConfiguration, IConfig, IGlobalConfig, IConfigurationManager, ILaunch, IAdapterExecutable, IDebugAdapterProvider, IDebugAdapter, ITerminalSettings, ITerminalLauncher } from 'vs/workbench/parts/debug/common/debug'; import { Debugger } from 'vs/workbench/parts/debug/node/debugger'; import { IEditorService, ACTIVE_GROUP, SIDE_GROUP } from 'vs/workbench/services/editor/common/editorService'; -import { IQuickOpenService } from 'vs/platform/quickOpen/common/quickOpen'; import { isCodeEditor } from 'vs/editor/browser/editorBrowser'; import { launchSchemaId } from 'vs/workbench/services/configuration/common/configuration'; import { IPreferencesService } from 'vs/workbench/services/preferences/common/preferences'; @@ -33,6 +32,7 @@ import { TerminalLauncher } from 'vs/workbench/parts/debug/electron-browser/term import { Registry } from 'vs/platform/registry/common/platform'; import { IJSONContributionRegistry, Extensions as JSONExtensions } from 'vs/platform/jsonschemas/common/jsonContributionRegistry'; import { launchSchema, debuggersExtPoint, breakpointsExtPoint } from 'vs/workbench/parts/debug/common/debugSchemas'; +import { IQuickInputService } from 'vs/platform/quickinput/common/quickInput'; const jsonRegistry = Registry.as(JSONExtensions.JSONContribution); jsonRegistry.registerSchema(launchSchemaId, launchSchema); @@ -57,7 +57,7 @@ export class ConfigurationManager implements IConfigurationManager { @IWorkspaceContextService private contextService: IWorkspaceContextService, @IEditorService private editorService: IEditorService, @IConfigurationService private configurationService: IConfigurationService, - @IQuickOpenService private quickOpenService: IQuickOpenService, + @IQuickInputService private quickInputService: IQuickInputService, @IInstantiationService private instantiationService: IInstantiationService, @ICommandService private commandService: ICommandService, @IStorageService private storageService: IStorageService, @@ -347,10 +347,11 @@ export class ConfigurationManager implements IConfigurationManager { } candidates = candidates.sort((first, second) => first.label.localeCompare(second.label)); - return this.quickOpenService.pick([...candidates, { label: 'More...', separator: { border: true } }], { placeHolder: nls.localize('selectDebug', "Select Environment") }) + const picks = candidates.map(c => ({ label: c.label, debugger: c })); + return this.quickInputService.pick<(typeof picks)[0]>([...picks, { type: 'separator', border: true }, { label: 'More...', debugger: undefined }], { placeHolder: nls.localize('selectDebug', "Select Environment") }) .then(picked => { - if (picked instanceof Debugger) { - return picked; + if (picked.debugger) { + return picked.debugger; } if (picked) { this.commandService.executeCommand('debug.installAdditionalDebuggers'); diff --git a/src/vs/workbench/parts/snippets/electron-browser/configureSnippets.ts b/src/vs/workbench/parts/snippets/electron-browser/configureSnippets.ts index c7398954035..a9bf6177165 100644 --- a/src/vs/workbench/parts/snippets/electron-browser/configureSnippets.ts +++ b/src/vs/workbench/parts/snippets/electron-browser/configureSnippets.ts @@ -9,7 +9,6 @@ import { CommandsRegistry } from 'vs/platform/commands/common/commands'; import { writeFile, exists } from 'vs/base/node/pfs'; import { IEnvironmentService } from 'vs/platform/environment/common/environment'; import { IModeService } from 'vs/editor/common/services/modeService'; -import { IQuickOpenService, IPickOpenEntry } from 'vs/platform/quickOpen/common/quickOpen'; import { IWindowService } from 'vs/platform/windows/common/windows'; import { join, basename, dirname, extname } from 'path'; import { MenuRegistry, MenuId } from 'vs/platform/actions/common/actions'; @@ -18,6 +17,7 @@ import { IOpenerService } from 'vs/platform/opener/common/opener'; import URI from 'vs/base/common/uri'; import { ISnippetsService } from 'vs/workbench/parts/snippets/electron-browser/snippets.contribution'; import { values } from 'vs/base/common/map'; +import { IQuickPickItem, IQuickInputService, QuickPickInput } from 'vs/platform/quickinput/common/quickInput'; const id = 'workbench.action.openSnippets'; @@ -27,7 +27,7 @@ namespace ISnippetPick { } } -interface ISnippetPick extends IPickOpenEntry { +interface ISnippetPick extends IQuickPickItem { filepath: string; hint?: true; } @@ -179,22 +179,23 @@ async function createLanguageSnippetFile(pick: ISnippetPick) { CommandsRegistry.registerCommand(id, async accessor => { const snippetService = accessor.get(ISnippetsService); - const quickOpenService = accessor.get(IQuickOpenService); + const quickInputService = accessor.get(IQuickInputService); const opener = accessor.get(IOpenerService); const windowService = accessor.get(IWindowService); const modeService = accessor.get(IModeService); const envService = accessor.get(IEnvironmentService); - const { existing, future } = await computePicks(snippetService, envService, modeService); - const newGlobalPick = { label: nls.localize('new.global', "New Global Snippets file...") }; + const picks = await computePicks(snippetService, envService, modeService); + const existing: QuickPickInput[] = picks.existing; + const newGlobalPick = { label: nls.localize('new.global', "New Global Snippets file...") }; if (existing.length > 0) { - existing[0].separator = { label: nls.localize('group.global', "Existing Snippets") }; - newGlobalPick.separator = { border: true, label: nls.localize('new.global.sep', "New Snippets") }; + existing.unshift({ type: 'separator', label: nls.localize('group.global', "Existing Snippets") }); + existing.push({ type: 'separator', border: true, label: nls.localize('new.global.sep', "New Snippets") }); } else { - newGlobalPick.separator = { label: nls.localize('new.global.sep', "New Snippets") }; + existing.push({ type: 'separator', label: nls.localize('new.global.sep', "New Snippets") }); } - const pick = await quickOpenService.pick(<(IPickOpenEntry | ISnippetPick)[]>[].concat(existing, newGlobalPick, future), { + const pick = await quickInputService.pick(<(IQuickPickItem | ISnippetPick)[]>[].concat(existing, newGlobalPick, picks.future), { placeHolder: nls.localize('openSnippet.pickLanguage', "Select Snippets File or Create Snippets"), matchOnDescription: true }); diff --git a/src/vs/workbench/parts/snippets/electron-browser/insertSnippet.ts b/src/vs/workbench/parts/snippets/electron-browser/insertSnippet.ts index 581e4854c2f..062036e19b4 100644 --- a/src/vs/workbench/parts/snippets/electron-browser/insertSnippet.ts +++ b/src/vs/workbench/parts/snippets/electron-browser/insertSnippet.ts @@ -7,7 +7,6 @@ import * as nls from 'vs/nls'; import { TPromise } from 'vs/base/common/winjs.base'; import { registerEditorAction, ServicesAccessor, EditorAction } from 'vs/editor/browser/editorExtensions'; -import { IQuickOpenService, IPickOpenEntry } from 'vs/platform/quickOpen/common/quickOpen'; import { IModeService } from 'vs/editor/common/services/modeService'; import { LanguageId } from 'vs/editor/common/modes'; import { ICommandService, CommandsRegistry } from 'vs/platform/commands/common/commands'; @@ -16,8 +15,9 @@ import { SnippetController2 } from 'vs/editor/contrib/snippet/snippetController2 import { EditorContextKeys } from 'vs/editor/common/editorContextKeys'; import { ICodeEditor } from 'vs/editor/browser/editorBrowser'; import { Snippet } from 'vs/workbench/parts/snippets/electron-browser/snippetsFile'; +import { IQuickPickItem, IQuickInputService, QuickPickInput } from 'vs/platform/quickinput/common/quickInput'; -interface ISnippetPick extends IPickOpenEntry { +interface ISnippetPick extends IQuickPickItem { snippet: Snippet; } @@ -71,7 +71,7 @@ class InsertSnippetAction extends EditorAction { return undefined; } - const quickOpenService = accessor.get(IQuickOpenService); + const quickInputService = accessor.get(IQuickInputService); const { lineNumber, column } = editor.getPosition(); let { snippet, name, langId } = Args.fromUser(arg); @@ -116,7 +116,7 @@ class InsertSnippetAction extends EditorAction { } else { // let user pick a snippet const snippets = (await snippetService.getSnippets(languageId)).sort(Snippet.compare); - const picks: ISnippetPick[] = []; + const picks: QuickPickInput[] = []; let prevSnippet: Snippet; for (const snippet of snippets) { const pick: ISnippetPick = { @@ -125,14 +125,14 @@ class InsertSnippetAction extends EditorAction { snippet }; if (!snippet.isFromExtension && !prevSnippet) { - pick.separator = { label: nls.localize('sep.userSnippet', "User Snippets") }; + picks.push({ type: 'separator', label: nls.localize('sep.userSnippet', "User Snippets") }); } else if (snippet.isFromExtension && (!prevSnippet || !prevSnippet.isFromExtension)) { - pick.separator = { label: nls.localize('sep.extSnippet', "Extension Snippets") }; + picks.push({ type: 'separator', label: nls.localize('sep.extSnippet', "Extension Snippets") }); } picks.push(pick); prevSnippet = snippet; } - return quickOpenService.pick(picks, { matchOnDetail: true }).then(pick => resolve(pick && pick.snippet), reject); + return quickInputService.pick(picks, { matchOnDetail: true }).then(pick => resolve(pick && pick.snippet), reject); } }).then(snippet => { if (snippet) { From 48e118bb84133850253096137c2f33c1647b34e0 Mon Sep 17 00:00:00 2001 From: Johannes Rieken Date: Fri, 10 Aug 2018 11:50:41 +0200 Subject: [PATCH 0659/1276] make URI#from more strict and URI#with more clear wrt schme-enforcement, #56108 --- src/vs/base/common/uri.ts | 4 ++-- src/vs/monaco.d.ts | 10 +++++----- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/vs/base/common/uri.ts b/src/vs/base/common/uri.ts index 5fe794d4581..4a6f69ea626 100644 --- a/src/vs/base/common/uri.ts +++ b/src/vs/base/common/uri.ts @@ -191,7 +191,7 @@ export default class URI implements UriComponents { // ---- modify to new ------------------------- - public with(change: { scheme?: string; authority?: string; path?: string; query?: string; fragment?: string }): URI { + public with(change: { scheme?: string; authority?: string | null; path?: string | null; query?: string | null; fragment?: string | null }): URI { if (!change) { return this; @@ -307,7 +307,7 @@ export default class URI implements UriComponents { return new _URI('file', authority, path, _empty, _empty); } - public static from(components: { scheme?: string; authority?: string; path?: string; query?: string; fragment?: string }): URI { + public static from(components: { scheme: string; authority?: string; path?: string; query?: string; fragment?: string }): URI { return new _URI( components.scheme, components.authority, diff --git a/src/vs/monaco.d.ts b/src/vs/monaco.d.ts index 18baa911399..b8394da57dc 100644 --- a/src/vs/monaco.d.ts +++ b/src/vs/monaco.d.ts @@ -163,10 +163,10 @@ declare namespace monaco { readonly fsPath: string; with(change: { scheme?: string; - authority?: string; - path?: string; - query?: string; - fragment?: string; + authority?: string | null; + path?: string | null; + query?: string | null; + fragment?: string | null; }): Uri; /** * Creates a new Uri from a string, e.g. `http://www.msft.com/some/path`, @@ -199,7 +199,7 @@ declare namespace monaco { */ static file(path: string): Uri; static from(components: { - scheme?: string; + scheme: string; authority?: string; path?: string; query?: string; From 9215e7701c5664ba8fdd0fce33b3a2e366f75a8d Mon Sep 17 00:00:00 2001 From: Benjamin Pasero Date: Fri, 10 Aug 2018 11:59:05 +0200 Subject: [PATCH 0660/1276] debt - remove some WinJS.timeout() calls --- .../browser/ui/progressbar/progressbar.ts | 21 +----- .../quickopen/browser/quickOpenWidget.ts | 10 +-- src/vs/code/electron-main/app.ts | 5 +- .../browser/quickOpen/quickCommand.ts | 4 +- .../browser/parts/editor/editorStatus.ts | 6 +- .../parts/quickopen/quickOpenController.ts | 19 +++-- .../browser/editors/fileEditorTracker.ts | 11 ++- .../quickopen/browser/commandsHandler.ts | 4 +- .../electron-browser/contextmenuService.ts | 70 +++++++++---------- .../textfile/common/textFileEditorModel.ts | 10 +-- 10 files changed, 74 insertions(+), 86 deletions(-) diff --git a/src/vs/base/browser/ui/progressbar/progressbar.ts b/src/vs/base/browser/ui/progressbar/progressbar.ts index 7d294d601f5..602b7d93dd9 100644 --- a/src/vs/base/browser/ui/progressbar/progressbar.ts +++ b/src/vs/base/browser/ui/progressbar/progressbar.ts @@ -6,10 +6,8 @@ 'use strict'; import 'vs/css!./progressbar'; -import { TPromise, ValueCallback } from 'vs/base/common/winjs.base'; import * as assert from 'vs/base/common/assert'; import { Builder, $ } from 'vs/base/browser/builder'; -import * as DOM from 'vs/base/browser/dom'; import { Disposable } from 'vs/base/common/lifecycle'; import { Color } from 'vs/base/common/color'; import { mixin } from 'vs/base/common/objects'; @@ -41,7 +39,6 @@ export class ProgressBar extends Disposable { private element: Builder; private bit: HTMLElement; private totalWork: number; - private animationStopToken: ValueCallback; private progressBarBackground: Color; constructor(container: HTMLElement, options?: IProgressBarOptions) { @@ -60,19 +57,7 @@ export class ProgressBar extends Disposable { private create(container: HTMLElement): void { $(container).div({ 'class': css_progress_container }, builder => { this.element = builder.clone(); - - builder.div({ 'class': css_progress_bit }).on([DOM.EventType.ANIMATION_START, DOM.EventType.ANIMATION_END, DOM.EventType.ANIMATION_ITERATION], (e: Event) => { - switch (e.type) { - case DOM.EventType.ANIMATION_ITERATION: - if (this.animationStopToken) { - this.animationStopToken(null); - } - break; - } - - }, this.toDispose); - - this.bit = builder.getHTMLElement(); + this.bit = builder.div({ 'class': css_progress_bit }).getHTMLElement(); }); this.applyStyles(); @@ -111,7 +96,7 @@ export class ProgressBar extends Disposable { this.bit.style.width = 'inherit'; if (delayed) { - TPromise.timeout(200).then(() => this.off()); + setTimeout(200, () => this.off()); } else { this.off(); } @@ -121,7 +106,7 @@ export class ProgressBar extends Disposable { else { this.bit.style.opacity = '0'; if (delayed) { - TPromise.timeout(200).then(() => this.off()); + setTimeout(200, () => this.off()); } else { this.off(); } diff --git a/src/vs/base/parts/quickopen/browser/quickOpenWidget.ts b/src/vs/base/parts/quickopen/browser/quickOpenWidget.ts index ca63a6398d1..0b73a959113 100644 --- a/src/vs/base/parts/quickopen/browser/quickOpenWidget.ts +++ b/src/vs/base/parts/quickopen/browser/quickOpenWidget.ts @@ -6,7 +6,6 @@ import 'vs/css!./quickopen'; import * as nls from 'vs/nls'; -import { TPromise } from 'vs/base/common/winjs.base'; import * as platform from 'vs/base/common/platform'; import * as types from 'vs/base/common/types'; import * as errors from 'vs/base/common/errors'; @@ -980,11 +979,8 @@ export class QuickOpenWidget extends Disposable implements IModelProvider { } this.isLoosingFocus = true; - TPromise.timeout(0).then(() => { - if (!this.isLoosingFocus) { - return; - } - if (this.isDisposed) { + setTimeout(() => { + if (!this.isLoosingFocus || this.isDisposed) { return; } @@ -992,7 +988,7 @@ export class QuickOpenWidget extends Disposable implements IModelProvider { if (!veto) { this.hide(HideReason.FOCUS_LOST); } - }); + }, 0); } dispose(): void { diff --git a/src/vs/code/electron-main/app.ts b/src/vs/code/electron-main/app.ts index a52ce64b90d..e0ff559f804 100644 --- a/src/vs/code/electron-main/app.ts +++ b/src/vs/code/electron-main/app.ts @@ -65,6 +65,7 @@ import { MenubarService } from 'vs/platform/menubar/electron-main/menubarService import { MenubarChannel } from 'vs/platform/menubar/common/menubarIpc'; import { IUriDisplayService } from 'vs/platform/uriDisplay/common/uriDisplay'; import { CodeMenu } from 'vs/code/electron-main/menus'; +import { RunOnceScheduler } from 'vs/base/common/async'; export class CodeApplication { @@ -529,7 +530,9 @@ export class CodeApplication { this.historyMainService.onRecentlyOpenedChange(() => this.historyMainService.updateWindowsJumpList()); // Start shared process after a while - TPromise.timeout(3000).then(() => this.sharedProcess.spawn()); + const sharedProcess = new RunOnceScheduler(() => this.sharedProcess.spawn(), 3000); + sharedProcess.schedule(); + this.toDispose.push(sharedProcess); } private dispose(): void { diff --git a/src/vs/editor/standalone/browser/quickOpen/quickCommand.ts b/src/vs/editor/standalone/browser/quickOpen/quickCommand.ts index 7fe59dd0453..7a0168883c7 100644 --- a/src/vs/editor/standalone/browser/quickOpen/quickCommand.ts +++ b/src/vs/editor/standalone/browser/quickOpen/quickCommand.ts @@ -50,7 +50,7 @@ export class EditorActionCommandEntry extends QuickOpenEntryGroup { if (mode === Mode.OPEN) { // Use a timeout to give the quick open widget a chance to close itself first - TPromise.timeout(50).done(() => { + setTimeout(() => { // Some actions are enabled only when editor has focus this.editor.focus(); @@ -61,7 +61,7 @@ export class EditorActionCommandEntry extends QuickOpenEntryGroup { } catch (error) { onUnexpectedError(error); } - }, onUnexpectedError); + }, 50); return true; } diff --git a/src/vs/workbench/browser/parts/editor/editorStatus.ts b/src/vs/workbench/browser/parts/editor/editorStatus.ts index a4db8633e97..d7156eec4e6 100644 --- a/src/vs/workbench/browser/parts/editor/editorStatus.ts +++ b/src/vs/workbench/browser/parts/editor/editorStatus.ts @@ -999,7 +999,7 @@ export class ChangeModeAction extends Action { }; }); - TPromise.timeout(50 /* quick open is sensitive to being opened so soon after another */).done(() => { + setTimeout(() => { this.quickInputService.pick(picks, { placeHolder: nls.localize('pickLanguageToConfigure', "Select Language Mode to Associate with '{0}'", extension || basename) }).done(language => { if (language) { const fileAssociationsConfig = this.configurationService.inspect(FILES_ASSOCIATIONS_CONFIG); @@ -1027,8 +1027,8 @@ export class ChangeModeAction extends Action { this.configurationService.updateValue(FILES_ASSOCIATIONS_CONFIG, currentAssociations, target); } - }); - }); + }, error => errors.onUnexpectedError(error)); + }, 50 /* quick open is sensitive to being opened so soon after another */); } } diff --git a/src/vs/workbench/browser/parts/quickopen/quickOpenController.ts b/src/vs/workbench/browser/parts/quickopen/quickOpenController.ts index 5d64bc0a385..5ae172239da 100644 --- a/src/vs/workbench/browser/parts/quickopen/quickOpenController.ts +++ b/src/vs/workbench/browser/parts/quickopen/quickOpenController.ts @@ -56,7 +56,7 @@ import { Dimension, addClass } from 'vs/base/browser/dom'; import { IEditorService, ACTIVE_GROUP, SIDE_GROUP } from 'vs/workbench/services/editor/common/editorService'; import { IEditorGroupsService } from 'vs/workbench/services/group/common/editorGroupsService'; import { IUriDisplayService } from 'vs/platform/uriDisplay/common/uriDisplay'; -import { isThenable } from 'vs/base/common/async'; +import { isThenable, timeout } from 'vs/base/common/async'; const HELP_PREFIX = '?'; @@ -394,11 +394,11 @@ export class QuickOpenController extends Component implements IQuickOpenService }); // Progress if task takes a long time - TPromise.timeout(800).then(() => { + setTimeout(() => { if (!picksPromiseDone && this.currentPickerToken === currentPickerToken) { this.pickOpenWidget.getProgressBar().infinite().show(); } - }); + }, 800); // Show picker empty if resolving takes a while if (!picksPromiseDone) { @@ -670,11 +670,11 @@ export class QuickOpenController extends Component implements IQuickOpenService this.previousActiveHandlerDescriptor = handlerDescriptor; // Progress if task takes a long time - TPromise.timeout(instantProgress ? 0 : 800).then(() => { + setTimeout(() => { if (!resultPromiseDone && currentResultToken === this.currentResultToken) { this.quickOpenWidget.getProgressBar().infinite().show(); } - }); + }, instantProgress ? 0 : 800); // Promise done handling resultPromise.done(() => { @@ -709,7 +709,14 @@ export class QuickOpenController extends Component implements IQuickOpenService const previousInput = this.quickOpenWidget.getInput(); const wasShowingHistory = previousInput && previousInput.entries && previousInput.entries.some(e => e instanceof EditorHistoryEntry || e instanceof EditorHistoryEntryGroup); if (wasShowingHistory || matchingHistoryEntries.length > 0) { - (resolvedHandler.hasShortResponseTime() ? TPromise.timeout(QuickOpenController.MAX_SHORT_RESPONSE_TIME) : TPromise.as(undefined)).then(() => { + let responseDelay: Thenable; + if (resolvedHandler.hasShortResponseTime()) { + responseDelay = timeout(QuickOpenController.MAX_SHORT_RESPONSE_TIME); + } else { + responseDelay = Promise.resolve(void 0); + } + + responseDelay.then(() => { if (this.currentResultToken === currentResultToken && !inputSet) { this.quickOpenWidget.setInput(quickOpenModel, { autoFocusFirstEntry: true }); inputSet = true; diff --git a/src/vs/workbench/parts/files/browser/editors/fileEditorTracker.ts b/src/vs/workbench/parts/files/browser/editors/fileEditorTracker.ts index 9f6bd55fff9..3ca77a2a912 100644 --- a/src/vs/workbench/parts/files/browser/editors/fileEditorTracker.ts +++ b/src/vs/workbench/parts/files/browser/editors/fileEditorTracker.ts @@ -4,7 +4,6 @@ *--------------------------------------------------------------------------------------------*/ 'use strict'; -import { TPromise } from 'vs/base/common/winjs.base'; import { IWorkbenchContribution } from 'vs/workbench/common/contributions'; import URI from 'vs/base/common/uri'; import * as resources from 'vs/base/common/resources'; @@ -27,7 +26,7 @@ import { IWindowService } from 'vs/platform/windows/common/windows'; import { BINARY_FILE_EDITOR_ID } from 'vs/workbench/parts/files/common/files'; import { IEditorService } from 'vs/workbench/services/editor/common/editorService'; import { IEditorGroupsService, IEditorGroup } from 'vs/workbench/services/group/common/editorGroupsService'; -import { ResourceQueue } from 'vs/base/common/async'; +import { ResourceQueue, timeout } from 'vs/base/common/async'; import { onUnexpectedError } from 'vs/base/common/errors'; export class FileEditorTracker extends Disposable implements IWorkbenchContribution { @@ -170,14 +169,14 @@ export class FileEditorTracker extends Disposable implements IWorkbenchContribut // file is really gone and not just a faulty file event. // This only applies to external file events, so we need to check for the isExternal // flag. - let checkExists: TPromise; + let checkExists: Thenable; if (isExternal) { - checkExists = TPromise.timeout(100).then(() => this.fileService.existsFile(resource)); + checkExists = timeout(100).then(() => this.fileService.existsFile(resource)); } else { - checkExists = TPromise.as(false); + checkExists = Promise.resolve(false); } - checkExists.done(exists => { + checkExists.then(exists => { if (!exists && !editor.isDisposed()) { editor.dispose(); } else if (this.environmentService.verbose) { diff --git a/src/vs/workbench/parts/quickopen/browser/commandsHandler.ts b/src/vs/workbench/parts/quickopen/browser/commandsHandler.ts index e76351076f2..1454998d2d9 100644 --- a/src/vs/workbench/parts/quickopen/browser/commandsHandler.ts +++ b/src/vs/workbench/parts/quickopen/browser/commandsHandler.ts @@ -293,7 +293,7 @@ abstract class BaseCommandEntry extends QuickOpenEntryGroup { this.onBeforeRun(this.commandId); // Use a timeout to give the quick open widget a chance to close itself first - TPromise.timeout(50).done(() => { + setTimeout(() => { if (action && (!(action instanceof Action) || action.enabled)) { try { /* __GDPR__ @@ -314,7 +314,7 @@ abstract class BaseCommandEntry extends QuickOpenEntryGroup { } else { this.notificationService.info(nls.localize('actionNotEnabled', "Command '{0}' is not enabled in the current context.", this.getLabel())); } - }, err => this.onError(err)); + }, 50); } private onError(error?: Error): void { diff --git a/src/vs/workbench/services/contextview/electron-browser/contextmenuService.ts b/src/vs/workbench/services/contextview/electron-browser/contextmenuService.ts index c4fdf722b72..22429b85715 100644 --- a/src/vs/workbench/services/contextview/electron-browser/contextmenuService.ts +++ b/src/vs/workbench/services/contextview/electron-browser/contextmenuService.ts @@ -37,46 +37,44 @@ export class ContextMenuService extends Disposable implements IContextMenuServic showContextMenu(delegate: IContextMenuDelegate): void { delegate.getActions().then(actions => { - if (!actions.length) { - return TPromise.as(null); - } + if (actions.length) { + setTimeout(() => { + const onHide = once(() => { + if (delegate.onHide) { + delegate.onHide(undefined); + } - return TPromise.timeout(0).then(() => { // https://github.com/Microsoft/vscode/issues/3638 - const onHide = once(() => { - if (delegate.onHide) { - delegate.onHide(undefined); + this._onDidContextMenu.fire(); + }); + + const menu = this.createMenu(delegate, actions, onHide); + const anchor = delegate.getAnchor(); + let x: number, y: number; + + if (dom.isHTMLElement(anchor)) { + let elementPosition = dom.getDomNodePagePosition(anchor); + + x = elementPosition.left; + y = elementPosition.top + elementPosition.height; + } else { + const pos = <{ x: number; y: number; }>anchor; + x = pos.x + 1; /* prevent first item from being selected automatically under mouse */ + y = pos.y; } - this._onDidContextMenu.fire(); - }); + let zoom = webFrame.getZoomFactor(); + x *= zoom; + y *= zoom; - const menu = this.createMenu(delegate, actions, onHide); - const anchor = delegate.getAnchor(); - let x: number, y: number; - - if (dom.isHTMLElement(anchor)) { - let elementPosition = dom.getDomNodePagePosition(anchor); - - x = elementPosition.left; - y = elementPosition.top + elementPosition.height; - } else { - const pos = <{ x: number; y: number; }>anchor; - x = pos.x + 1; /* prevent first item from being selected automatically under mouse */ - y = pos.y; - } - - let zoom = webFrame.getZoomFactor(); - x *= zoom; - y *= zoom; - - menu.popup({ - window: remote.getCurrentWindow(), - x: Math.floor(x), - y: Math.floor(y), - positioningItem: delegate.autoSelectFirstItem ? 0 : void 0, - callback: () => onHide() - }); - }); + menu.popup({ + window: remote.getCurrentWindow(), + x: Math.floor(x), + y: Math.floor(y), + positioningItem: delegate.autoSelectFirstItem ? 0 : void 0, + callback: () => onHide() + }); + }, 0); // https://github.com/Microsoft/vscode/issues/3638 + } }); } diff --git a/src/vs/workbench/services/textfile/common/textFileEditorModel.ts b/src/vs/workbench/services/textfile/common/textFileEditorModel.ts index 0c3642145b3..6faef447dc3 100644 --- a/src/vs/workbench/services/textfile/common/textFileEditorModel.ts +++ b/src/vs/workbench/services/textfile/common/textFileEditorModel.ts @@ -25,7 +25,7 @@ import { IInstantiationService } from 'vs/platform/instantiation/common/instanti import { IModeService } from 'vs/editor/common/services/modeService'; import { IModelService } from 'vs/editor/common/services/modelService'; import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry'; -import { RunOnceScheduler } from 'vs/base/common/async'; +import { RunOnceScheduler, timeout } from 'vs/base/common/async'; import { ITextBufferFactory } from 'vs/editor/common/model'; import { IHashService } from 'vs/workbench/services/hash/common/hashService'; import { createTextBufferFactory } from 'vs/editor/common/model/textModel'; @@ -153,13 +153,13 @@ export class TextFileEditorModel extends BaseTextEditorModel implements ITextFil } if (fileEventImpactsModel && this.inOrphanMode !== newInOrphanModeGuess) { - let checkOrphanedPromise: TPromise; + let checkOrphanedPromise: Thenable; if (newInOrphanModeGuess) { // We have received reports of users seeing delete events even though the file still // exists (network shares issue: https://github.com/Microsoft/vscode/issues/13665). // Since we do not want to mark the model as orphaned, we have to check if the // file is really gone and not just a faulty file event. - checkOrphanedPromise = TPromise.timeout(100).then(() => { + checkOrphanedPromise = timeout(100).then(() => { if (this.disposed) { return true; } @@ -167,10 +167,10 @@ export class TextFileEditorModel extends BaseTextEditorModel implements ITextFil return this.fileService.existsFile(this.resource).then(exists => !exists); }); } else { - checkOrphanedPromise = TPromise.as(false); + checkOrphanedPromise = Promise.resolve(false); } - checkOrphanedPromise.done(newInOrphanModeValidated => { + checkOrphanedPromise.then(newInOrphanModeValidated => { if (this.inOrphanMode !== newInOrphanModeValidated && !this.disposed) { this.setOrphaned(newInOrphanModeValidated); } From c8ac8ec30096bdabf1041fd0bdf271d02e3ed4ab Mon Sep 17 00:00:00 2001 From: Johannes Rieken Date: Fri, 10 Aug 2018 12:10:23 +0200 Subject: [PATCH 0661/1276] debt - towards scheme-enforcement, #56108 --- .../src/test/documentLinkProvider.test.ts | 2 +- .../src/test/documentSymbolProvider.test.ts | 2 +- .../src/test/foldingProvider.test.ts | 2 +- .../src/test/tableOfContentsProvider.test.ts | 2 +- .../src/test/workspaceSymbolProvider.test.ts | 12 ++++++------ src/vs/workbench/browser/parts/views/customView.ts | 2 +- 6 files changed, 11 insertions(+), 11 deletions(-) diff --git a/extensions/markdown-language-features/src/test/documentLinkProvider.test.ts b/extensions/markdown-language-features/src/test/documentLinkProvider.test.ts index 910ed3c9bdf..5a1d0c87880 100644 --- a/extensions/markdown-language-features/src/test/documentLinkProvider.test.ts +++ b/extensions/markdown-language-features/src/test/documentLinkProvider.test.ts @@ -10,7 +10,7 @@ import LinkProvider from '../features/documentLinkProvider'; import { InMemoryDocument } from './inMemoryDocument'; -const testFileName = vscode.Uri.parse('test.md'); +const testFileName = vscode.Uri.file('test.md'); const noopToken = new class implements vscode.CancellationToken { private _onCancellationRequestedEmitter = new vscode.EventEmitter(); diff --git a/extensions/markdown-language-features/src/test/documentSymbolProvider.test.ts b/extensions/markdown-language-features/src/test/documentSymbolProvider.test.ts index b87b5cf2ea4..9533f807cf9 100644 --- a/extensions/markdown-language-features/src/test/documentSymbolProvider.test.ts +++ b/extensions/markdown-language-features/src/test/documentSymbolProvider.test.ts @@ -11,7 +11,7 @@ import { InMemoryDocument } from './inMemoryDocument'; import { createNewMarkdownEngine } from './engine'; -const testFileName = vscode.Uri.parse('test.md'); +const testFileName = vscode.Uri.file('test.md'); function getSymbolsForFile(fileContents: string) { diff --git a/extensions/markdown-language-features/src/test/foldingProvider.test.ts b/extensions/markdown-language-features/src/test/foldingProvider.test.ts index cd3b82d599e..6489694db46 100644 --- a/extensions/markdown-language-features/src/test/foldingProvider.test.ts +++ b/extensions/markdown-language-features/src/test/foldingProvider.test.ts @@ -11,7 +11,7 @@ import MarkdownFoldingProvider from '../features/foldingProvider'; import { InMemoryDocument } from './inMemoryDocument'; import { createNewMarkdownEngine } from './engine'; -const testFileName = vscode.Uri.parse('test.md'); +const testFileName = vscode.Uri.file('test.md'); suite('markdown.FoldingProvider', () => { test('Should not return anything for empty document', async () => { diff --git a/extensions/markdown-language-features/src/test/tableOfContentsProvider.test.ts b/extensions/markdown-language-features/src/test/tableOfContentsProvider.test.ts index 6d6f382ae7e..ee103b294ca 100644 --- a/extensions/markdown-language-features/src/test/tableOfContentsProvider.test.ts +++ b/extensions/markdown-language-features/src/test/tableOfContentsProvider.test.ts @@ -11,7 +11,7 @@ import { TableOfContentsProvider } from '../tableOfContentsProvider'; import { InMemoryDocument } from './inMemoryDocument'; import { createNewMarkdownEngine } from './engine'; -const testFileName = vscode.Uri.parse('test.md'); +const testFileName = vscode.Uri.file('test.md'); suite('markdown.TableOfContentsProvider', () => { test('Lookup should not return anything for empty document', async () => { diff --git a/extensions/markdown-language-features/src/test/workspaceSymbolProvider.test.ts b/extensions/markdown-language-features/src/test/workspaceSymbolProvider.test.ts index 2ee12a7979c..f5b3eb0ea4a 100644 --- a/extensions/markdown-language-features/src/test/workspaceSymbolProvider.test.ts +++ b/extensions/markdown-language-features/src/test/workspaceSymbolProvider.test.ts @@ -22,7 +22,7 @@ suite('markdown.WorkspaceSymbolProvider', () => { }); test('Should return symbols from workspace with one markdown file', async () => { - const testFileName = vscode.Uri.parse('test.md'); + const testFileName = vscode.Uri.file('test.md'); const provider = new MarkdownWorkspaceSymbolProvider(symbolProvider, new InMemoryWorkspaceMarkdownDocumentProvider([ new InMemoryDocument(testFileName, `# header1\nabc\n## header2`) @@ -49,7 +49,7 @@ suite('markdown.WorkspaceSymbolProvider', () => { }); test('Should update results when markdown file changes symbols', async () => { - const testFileName = vscode.Uri.parse('test.md'); + const testFileName = vscode.Uri.file('test.md'); const workspaceFileProvider = new InMemoryWorkspaceMarkdownDocumentProvider([ new InMemoryDocument(testFileName, `# header1`) @@ -68,7 +68,7 @@ suite('markdown.WorkspaceSymbolProvider', () => { }); test('Should remove results when file is deleted', async () => { - const testFileName = vscode.Uri.parse('test.md'); + const testFileName = vscode.Uri.file('test.md'); const workspaceFileProvider = new InMemoryWorkspaceMarkdownDocumentProvider([ new InMemoryDocument(testFileName, `# header1`) @@ -84,7 +84,7 @@ suite('markdown.WorkspaceSymbolProvider', () => { }); test('Should update results when markdown file is created', async () => { - const testFileName = vscode.Uri.parse('test.md'); + const testFileName = vscode.Uri.file('test.md'); const workspaceFileProvider = new InMemoryWorkspaceMarkdownDocumentProvider([ new InMemoryDocument(testFileName, `# header1`) @@ -94,7 +94,7 @@ suite('markdown.WorkspaceSymbolProvider', () => { assert.strictEqual((await provider.provideWorkspaceSymbols('')).length, 1); // Creat file - workspaceFileProvider.createDocument(new InMemoryDocument(vscode.Uri.parse('test2.md'), `# new header\nabc\n## header2`)); + workspaceFileProvider.createDocument(new InMemoryDocument(vscode.Uri.file('test2.md'), `# new header\nabc\n## header2`)); const newSymbols = await provider.provideWorkspaceSymbols(''); assert.strictEqual(newSymbols.length, 3); }); @@ -105,7 +105,7 @@ class InMemoryWorkspaceMarkdownDocumentProvider implements WorkspaceMarkdownDocu private readonly _documents = new Map(); constructor(documents: vscode.TextDocument[]) { - for( const doc of documents) { + for (const doc of documents) { this._documents.set(doc.fileName, doc); } } diff --git a/src/vs/workbench/browser/parts/views/customView.ts b/src/vs/workbench/browser/parts/views/customView.ts index bf04ef7a0c0..b79fd81f196 100644 --- a/src/vs/workbench/browser/parts/views/customView.ts +++ b/src/vs/workbench/browser/parts/views/customView.ts @@ -504,7 +504,7 @@ class TreeRenderer implements IRenderer { if ((resource || node.themeIcon) && !icon) { const fileDecorations = this.configurationService.getValue<{ colors: boolean, badges: boolean }>('explorer.decorations'); - templateData.resourceLabel.setLabel({ name: label, resource: resource ? resource : URI.parse('_icon_resource') }, { fileKind: this.getFileKind(node), title, fileDecorations: fileDecorations, extraClasses: ['custom-view-tree-node-item-resourceLabel'] }); + templateData.resourceLabel.setLabel({ name: label, resource: resource ? resource : URI.parse('missing:_icon_resource') }, { fileKind: this.getFileKind(node), title, fileDecorations: fileDecorations, extraClasses: ['custom-view-tree-node-item-resourceLabel'] }); } else { templateData.resourceLabel.setLabel({ name: label }, { title, hideIcon: true, extraClasses: ['custom-view-tree-node-item-resourceLabel'] }); } From 65f46a1da2ade16547a5d4a97efc903b60ad9c2a Mon Sep 17 00:00:00 2001 From: Christof Marti Date: Fri, 10 Aug 2018 12:11:14 +0200 Subject: [PATCH 0662/1276] Use QuickInput (#29096) --- .../electron-browser/task.contribution.ts | 79 +++++++++---------- 1 file changed, 36 insertions(+), 43 deletions(-) diff --git a/src/vs/workbench/parts/tasks/electron-browser/task.contribution.ts b/src/vs/workbench/parts/tasks/electron-browser/task.contribution.ts index 9f8b91f0d45..fee6ca9b812 100644 --- a/src/vs/workbench/parts/tasks/electron-browser/task.contribution.ts +++ b/src/vs/workbench/parts/tasks/electron-browser/task.contribution.ts @@ -57,7 +57,6 @@ import { IJSONSchema } from 'vs/base/common/jsonSchema'; import { IStatusbarItem, IStatusbarRegistry, Extensions as StatusbarExtensions, StatusbarItemDescriptor, StatusbarAlignment } from 'vs/workbench/browser/parts/statusbar/statusbar'; import { IQuickOpenRegistry, Extensions as QuickOpenExtensions, QuickOpenHandlerDescriptor } from 'vs/workbench/browser/quickopen'; -import { IQuickOpenService, IPickOpenEntry, IPickOpenAction, IPickOpenItem } from 'vs/platform/quickOpen/common/quickOpen'; import { IPanelService } from 'vs/workbench/services/panel/common/panelService'; import Constants from 'vs/workbench/parts/markers/electron-browser/constants'; import { IPartService } from 'vs/workbench/services/part/common/partService'; @@ -90,7 +89,7 @@ import { QuickOpenActionContributor } from '../browser/quickOpen'; import { Themable, STATUS_BAR_FOREGROUND, STATUS_BAR_NO_FOLDER_FOREGROUND } from 'vs/workbench/common/theme'; import { IThemeService } from 'vs/platform/theme/common/themeService'; -import { IQuickInputService } from 'vs/platform/quickinput/common/quickInput'; +import { IQuickInputService, IQuickPickItem, QuickPickInput } from 'vs/platform/quickinput/common/quickInput'; let tasksCategory = nls.localize('tasksCategory', "Tasks"); @@ -425,7 +424,7 @@ class TaskMap { } } -interface TaskQuickPickEntry extends IPickOpenEntry { +interface TaskQuickPickEntry extends IQuickPickItem { task: Task; } @@ -475,7 +474,6 @@ class TaskService implements ITaskService { @ILifecycleService lifecycleService: ILifecycleService, @IModelService private modelService: IModelService, @IExtensionService private extensionService: IExtensionService, - @IQuickOpenService private quickOpenService: IQuickOpenService, @IQuickInputService private quickInputService: IQuickInputService, @IConfigurationResolverService private configurationResolverService: IConfigurationResolverService, @ITerminalService private terminalService: ITerminalService, @@ -873,12 +871,12 @@ class TaskService implements ITaskService { } private attachProblemMatcher(task: ContributedTask | CustomTask): TPromise { - interface ProblemMatcherPickEntry extends IPickOpenEntry { + interface ProblemMatcherPickEntry extends IQuickPickItem { matcher: NamedProblemMatcher; never?: boolean; learnMore?: boolean; } - let entries: ProblemMatcherPickEntry[] = []; + let entries: QuickPickInput[] = []; for (let key of ProblemMatcherRegistry.keys()) { let matcher = ProblemMatcherRegistry.get(key); if (matcher.deprecated) { @@ -896,15 +894,14 @@ class TaskService implements ITaskService { } if (entries.length > 0) { entries = entries.sort((a, b) => a.label.localeCompare(b.label)); - entries[0].separator = { border: true, label: nls.localize('TaskService.associate', 'associate') }; + entries.unshift({ type: 'separator', border: true, label: nls.localize('TaskService.associate', 'associate') }); entries.unshift( { label: nls.localize('TaskService.attachProblemMatcher.continueWithout', 'Continue without scanning the task output'), matcher: undefined }, { label: nls.localize('TaskService.attachProblemMatcher.never', 'Never scan the task output'), matcher: undefined, never: true }, { label: nls.localize('TaskService.attachProblemMatcher.learnMoreAbout', 'Learn more about scanning the task output'), matcher: undefined, learnMore: true } ); - return this.quickOpenService.pick(entries, { + return this.quickInputService.pick(entries, { placeHolder: nls.localize('selectProblemMatcher', 'Select for which kind of errors and warnings to scan the task output'), - autoFocus: { autoFocusFirstEntry: true } }).then((selected) => { if (selected) { if (selected.learnMore) { @@ -1807,32 +1804,13 @@ class TaskService implements ITaskService { } return { label: task._label, description, task }; }; - let taskService = this; - let action = new class extends Action implements IPickOpenAction { - constructor() { - super('configureAction', 'Configure Task', 'quick-open-task-configure', true); + function fillEntries(entries: QuickPickInput[], tasks: Task[], groupLabel: string, withBorder: boolean = false): void { + if (tasks.length) { + entries.push({ type: 'separator', label: groupLabel, border: withBorder }); } - public run(item: IPickOpenItem): TPromise { - let task: Task = item.getPayload(); - taskService.quickOpenService.close(); - if (ContributedTask.is(task)) { - taskService.customize(task, undefined, true); - } else if (CustomTask.is(task)) { - taskService.openConfig(task); - } - return TPromise.as(false); - } - }; - function fillEntries(entries: TaskQuickPickEntry[], tasks: Task[], groupLabel: string, withBorder: boolean = false): void { - let first = true; for (let task of tasks) { let entry: TaskQuickPickEntry = TaskQuickPickEntry(task); - if (first) { - first = false; - entry.separator = { label: groupLabel, border: withBorder }; - } - entry.action = action; - entry.payload = task; + entry.buttons = [{ iconClass: 'quick-open-task-configure', tooltip: nls.localize('configureTask', "Configure Task") }]; entries.push(entry); } } @@ -1896,12 +1874,24 @@ class TaskService implements ITaskService { return tasks.then((tasks) => this.createTaskQuickPickEntries(tasks, group, sort)); } }; - return this.quickOpenService.pick(_createEntries().then((entries) => { + return this.quickInputService.pick(_createEntries().then((entries) => { if (entries.length === 0 && defaultEntry) { entries.push(defaultEntry); } return entries; - }), { placeHolder, autoFocus: { autoFocusFirstEntry: true }, matchOnDescription: true }).then(entry => entry ? entry.task : undefined); + }), { + placeHolder, + matchOnDescription: true, + onDidTriggerItemButton: context => { + let task = context.item.task; + this.quickInputService.cancel(); + if (ContributedTask.is(task)) { + this.customize(task, undefined, true); + } else if (CustomTask.is(task)) { + this.openConfig(task); + } + } + }).then(entry => entry ? entry.task : undefined); } private showIgnoredFoldersMessage(): TPromise { @@ -2254,8 +2244,8 @@ class TaskService implements ITaskService { } }; - function isTaskEntry(value: IPickOpenEntry): value is IPickOpenEntry & { task: Task } { - let candidate: IPickOpenEntry & { task: Task } = value as any; + function isTaskEntry(value: IQuickPickItem): value is IQuickPickItem & { task: Task } { + let candidate: IQuickPickItem & { task: Task } = value as any; return candidate && !!candidate.task; } @@ -2267,8 +2257,8 @@ class TaskService implements ITaskService { let openLabel = nls.localize('TaskService.openJsonFile', 'Open tasks.json file'); let entries = TPromise.join(stats).then((stats) => { return taskPromise.then((taskMap) => { - type EntryType = (IPickOpenEntry & { task: Task; }) | (IPickOpenEntry & { folder: IWorkspaceFolder; }); - let entries: EntryType[] = []; + type EntryType = (IQuickPickItem & { task: Task; }) | (IQuickPickItem & { folder: IWorkspaceFolder; }); + let entries: QuickPickInput[] = []; if (this.contextService.getWorkbenchState() === WorkbenchState.FOLDER) { let tasks = taskMap.all(); let needsCreateOrOpen: boolean = true; @@ -2283,7 +2273,10 @@ class TaskService implements ITaskService { } if (needsCreateOrOpen) { let label = stats[0] !== void 0 ? openLabel : createLabel; - entries.push({ label, folder: this.contextService.getWorkspace().folders[0], separator: entries.length > 0 ? { border: true } : undefined }); + if (entries.length) { + entries.push({ type: 'separator', border: true }); + } + entries.push({ label, folder: this.contextService.getWorkspace().folders[0] }); } } else { let folders = this.contextService.getWorkspace().folders; @@ -2295,14 +2288,14 @@ class TaskService implements ITaskService { for (let i = 0; i < tasks.length; i++) { let entry: EntryType = { label: tasks[i]._label, task: tasks[i], description: folder.name }; if (i === 0) { - entry.separator = { label: folder.name, border: index > 0 }; + entries.push({ type: 'separator', label: folder.name, border: index > 0 }); } entries.push(entry); } } else { let label = stats[index] !== void 0 ? openLabel : createLabel; let entry: EntryType = { label, folder: folder }; - entry.separator = { label: folder.name, border: index > 0 }; + entries.push({ type: 'separator', label: folder.name, border: index > 0 }); entries.push(entry); } index++; @@ -2312,8 +2305,8 @@ class TaskService implements ITaskService { }); }); - this.quickOpenService.pick(entries, - { placeHolder: nls.localize('TaskService.pickTask', 'Select a task to configure'), autoFocus: { autoFocusFirstEntry: true } }). + this.quickInputService.pick(entries, + { placeHolder: nls.localize('TaskService.pickTask', 'Select a task to configure') }). then((selection) => { if (!selection) { return; From e8706e2223bef51aef259e6430ce9b0de0d04075 Mon Sep 17 00:00:00 2001 From: Christof Marti Date: Fri, 10 Aug 2018 12:44:17 +0200 Subject: [PATCH 0663/1276] Update smoke test (#29096) --- test/smoke/src/areas/statusbar/statusbar.test.ts | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/test/smoke/src/areas/statusbar/statusbar.test.ts b/test/smoke/src/areas/statusbar/statusbar.test.ts index c9ba22c290a..b2212a92797 100644 --- a/test/smoke/src/areas/statusbar/statusbar.test.ts +++ b/test/smoke/src/areas/statusbar/statusbar.test.ts @@ -35,8 +35,8 @@ export function setup() { await app.workbench.quickopen.openFile('app.js'); await app.workbench.statusbar.clickOn(StatusBarElement.INDENTATION_STATUS); - await app.workbench.quickopen.waitForQuickOpenOpened(); - await app.workbench.quickopen.closeQuickOpen(); + await app.workbench.quickinput.waitForQuickInputOpened(); + await app.workbench.quickinput.closeQuickInput(); await app.workbench.statusbar.clickOn(StatusBarElement.ENCODING_STATUS); await app.workbench.quickinput.waitForQuickInputOpened(); await app.workbench.quickinput.closeQuickInput(); @@ -44,8 +44,8 @@ export function setup() { await app.workbench.quickinput.waitForQuickInputOpened(); await app.workbench.quickinput.closeQuickInput(); await app.workbench.statusbar.clickOn(StatusBarElement.LANGUAGE_STATUS); - await app.workbench.quickopen.waitForQuickOpenOpened(); - await app.workbench.quickopen.closeQuickOpen(); + await app.workbench.quickinput.waitForQuickInputOpened(); + await app.workbench.quickinput.closeQuickInput(); }); it(`verifies that 'Problems View' appears when clicking on 'Problems' status element`, async function () { From bc6fd20790dd0c36f6f93d584266122bcea049c2 Mon Sep 17 00:00:00 2001 From: Martin Aeschlimann Date: Fri, 10 Aug 2018 09:05:58 +0200 Subject: [PATCH 0664/1276] [seti] fileAssociationFile uses single and double quotes --- extensions/theme-seti/build/update-icon-theme.js | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/extensions/theme-seti/build/update-icon-theme.js b/extensions/theme-seti/build/update-icon-theme.js index 31d7bffe3a7..24b5d342694 100644 --- a/extensions/theme-seti/build/update-icon-theme.js +++ b/extensions/theme-seti/build/update-icon-theme.js @@ -172,13 +172,13 @@ exports.copyFont = function() { //let mappings = 'https://raw.githubusercontent.com/jesseweed/seti-ui/master/styles/components/icons/mapping.less'; //let colors = 'https://raw.githubusercontent.com/jesseweed/seti-ui/master/styles/ui-variables.less'; -let fontMappings = '../../../seti-ui/styles/_fonts/seti.less'; -let mappings = '../../../seti-ui/styles/components/icons/mapping.less'; -let colors = '../../../seti-ui/styles/ui-variables.less'; +let fontMappingsFile = '../../../seti-ui/styles/_fonts/seti.less'; +let fileAssociationFile = '../../../seti-ui/styles/components/icons/mapping.less'; +let colorsFile = '../../../seti-ui/styles/ui-variables.less'; exports.update = function () { - console.log('Reading from ' + fontMappings); + console.log('Reading from ' + fontMappingsFile); let def2Content = {}; let ext2Def = {}; let fileName2Def = {}; @@ -256,15 +256,15 @@ exports.update = function () { let match; - return download(fontMappings).then(function (content) { + return download(fontMappingsFile).then(function (content) { let regex = /@([\w-]+):\s*'(\\E[0-9A-F]+)';/g; let contents = {}; while ((match = regex.exec(content)) !== null) { contents[match[1]] = match[2]; } - return download(mappings).then(function (content) { - let regex2 = /\.icon-(?:set|partial)\('([\w-\.]+)',\s*'([\w-]+)',\s*(@[\w-]+)\)/g; + return download(fileAssociationFile).then(function (content) { + let regex2 = /\.icon-(?:set|partial)\(['"]([\w-\.]+)['"],\s*['"]([\w-]+)['"],\s*(@[\w-]+)\)/g; while ((match = regex2.exec(content)) !== null) { let pattern = match[1]; let def = '_' + match[2]; @@ -320,7 +320,7 @@ exports.update = function () { } - return download(colors).then(function (content) { + return download(colorsFile).then(function (content) { let regex3 = /(@[\w-]+):\s*(#[0-9a-z]+)/g; while ((match = regex3.exec(content)) !== null) { colorId2Value[match[1]] = match[2]; From 1a078cd5cf5a5658838c913800778fa5e2f90379 Mon Sep 17 00:00:00 2001 From: Martin Aeschlimann Date: Fri, 10 Aug 2018 10:37:31 +0200 Subject: [PATCH 0665/1276] [icon themes] seti theme should associate also to non build-in language modes (elm, caml, nunjucks..) Fixes #47432 --- .../theme-seti/build/update-icon-theme.js | 69 +++++++++++++------ 1 file changed, 49 insertions(+), 20 deletions(-) diff --git a/extensions/theme-seti/build/update-icon-theme.js b/extensions/theme-seti/build/update-icon-theme.js index 24b5d342694..b82a53ecc88 100644 --- a/extensions/theme-seti/build/update-icon-theme.js +++ b/extensions/theme-seti/build/update-icon-theme.js @@ -10,6 +10,30 @@ let fs = require('fs'); let https = require('https'); let url = require('url'); +// list of languagesIs not shipped with VSCode. The information is used to associate an icon with a langauge association +let nonBuiltInLanguages = { // { fileNames, extensions } + "r": { extensions: ['r', 'rhistory', 'rprofile', 'rt'] }, + "argdown": { extensions: ['ad', 'adown', 'argdown', 'argdn'] }, + "elm": { extensions: ['elm'] }, + "ocaml": { extensions: ['ml', 'mli'] }, + "nunjucks": { extensions: ['nunjucks', 'nunjs', 'nunj', 'nj', 'njk', 'tmpl', 'tpl'] }, + "mustache": { extensions: ['mustache', 'mst', 'mu', 'stache'] }, + "erb": { extensions: ['erb', 'rhtml', 'html.erb'] }, + "terraform": { extensions: ['tf', 'tfvars', 'hcl'] }, + "vue": { extensions: ['vue'] }, + "sass": { extensions: ['sass'] }, + "puppet": { extensions: ['puppet'] }, + "kotlin": { extensions: ['kt'] }, + "jinja": { extensions: ['jinja'] }, + "haxe": { extensions: ['hx'] }, + "haskell": { extensions: ['hs'] }, + "gradle": { extensions: ['gradle'] }, + "elixir": { extensions: ['ex'] }, + "haml": { extensions: ['haml'] }, + "stylus": { extensions: ['styl'] }, + "vala": { extensions: ['vala'] } +} + function getCommitSha(repoId, repoPath) { let commitInfo = 'https://api.github.com/repos/' + repoId + '/commits?path=' + repoPath; return download(commitInfo).then(function (content) { @@ -34,7 +58,7 @@ function download(source) { } return new Promise((c, e) => { let _url = url.parse(source); - let options = { host: _url.host, port: _url.port, path: _url.path, headers: { 'User-Agent': 'NodeJS' }}; + let options = { host: _url.host, port: _url.port, path: _url.path, headers: { 'User-Agent': 'NodeJS' } }; let content = ''; https.get(options, function (response) { response.on('data', function (data) { @@ -50,7 +74,7 @@ function download(source) { function readFile(fileName) { return new Promise((c, e) => { - fs.readFile(fileName, function(err, data) { + fs.readFile(fileName, function (err, data) { if (err) { e(err); } else { @@ -67,12 +91,12 @@ function downloadBinary(source, dest) { return new Promise((c, e) => { https.get(source, function (response) { - switch(response.statusCode) { + switch (response.statusCode) { case 200: let file = fs.createWriteStream(dest); - response.on('data', function(chunk){ + response.on('data', function (chunk) { file.write(chunk); - }).on('end', function(){ + }).on('end', function () { file.end(); c(null); }).on('error', function (err) { @@ -107,7 +131,7 @@ function copyFile(fileName, dest) { rd.on("error", handleError); let wr = fs.createWriteStream(dest); wr.on("error", handleError); - wr.on("close", function() { + wr.on("close", function () { if (!cbCalled) { c(); cbCalled = true; @@ -119,7 +143,7 @@ function copyFile(fileName, dest) { function darkenColor(color) { let res = '#'; - for (let i = 1; i < 7; i+=2) { + for (let i = 1; i < 7; i += 2) { let newVal = Math.round(parseInt('0x' + color.substr(i, 2), 16) * 0.9); let hex = newVal.toString(16); if (hex.length == 1) { @@ -133,7 +157,7 @@ function darkenColor(color) { function getLanguageMappings() { let langMappings = {}; let allExtensions = fs.readdirSync('..'); - for (let i= 0; i < allExtensions.length; i++) { + for (let i = 0; i < allExtensions.length; i++) { let dirPath = path.join('..', allExtensions[i], 'package.json'); if (fs.existsSync(dirPath)) { let content = fs.readFileSync(dirPath).toString(); @@ -158,13 +182,16 @@ function getLanguageMappings() { } } } + for (let languageId in nonBuiltInLanguages) { + langMappings[languageId] = nonBuiltInLanguages[languageId]; + } return langMappings; } //let font = 'https://raw.githubusercontent.com/jesseweed/seti-ui/master/styles/_fonts/seti/seti.woff'; let font = '../../../seti-ui/styles/_fonts/seti/seti.woff'; -exports.copyFont = function() { +exports.copyFont = function () { return downloadBinary(font, './icons/seti.woff'); }; @@ -234,7 +261,7 @@ exports.update = function () { size: "150%" }], iconDefinitions: iconDefinitions, - // folder: "_folder", + // folder: "_folder", file: "_default", fileExtensions: ext2Def, fileNames: fileName2Def, @@ -304,16 +331,18 @@ exports.update = function () { } if (preferredDef) { lang2Def[lang] = preferredDef; - for (let i2 = 0; i2 < exts.length; i2++) { - // remove the extension association, unless it is different from the preferred - if (ext2Def[exts[i2]] === preferredDef) { - delete ext2Def[exts[i2]]; + if (!nonBuiltInLanguages[lang]) { + for (let i2 = 0; i2 < exts.length; i2++) { + // remove the extension association, unless it is different from the preferred + if (ext2Def[exts[i2]] === preferredDef) { + delete ext2Def[exts[i2]]; + } } - } - for (let i2 = 0; i2 < fileNames.length; i2++) { - // remove the fileName association, unless it is different from the preferred - if (fileName2Def[fileNames[i2]] === preferredDef) { - delete fileName2Def[fileNames[i2]]; + for (let i2 = 0; i2 < fileNames.length; i2++) { + // remove the fileName association, unless it is different from the preferred + if (fileName2Def[fileNames[i2]] === preferredDef) { + delete fileName2Def[fileNames[i2]]; + } } } } @@ -323,7 +352,7 @@ exports.update = function () { return download(colorsFile).then(function (content) { let regex3 = /(@[\w-]+):\s*(#[0-9a-z]+)/g; while ((match = regex3.exec(content)) !== null) { - colorId2Value[match[1]] = match[2]; + colorId2Value[match[1]] = match[2]; } return getCommitSha('jesseweed/seti-ui', 'styles/_fonts/seti.less').then(function (info) { try { From eb68f9deefec7e34810866ab129842c641b41b0c Mon Sep 17 00:00:00 2001 From: Benjamin Pasero Date: Fri, 10 Aug 2018 14:12:41 +0200 Subject: [PATCH 0666/1276] disable tests for now in prod --- build/tfs/darwin/product-build-darwin.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build/tfs/darwin/product-build-darwin.yml b/build/tfs/darwin/product-build-darwin.yml index 0dd31503586..6e48af628e0 100644 --- a/build/tfs/darwin/product-build-darwin.yml +++ b/build/tfs/darwin/product-build-darwin.yml @@ -26,7 +26,7 @@ steps: - script: | set -e - ./scripts/test.sh --build --tfs "Unit Tests" + # ./scripts/test.sh --build --tfs "Unit Tests" APP_NAME="`ls $(agent.builddirectory)/VSCode-darwin | head -n 1`" # yarn smoketest -- --build "$(agent.builddirectory)/VSCode-darwin/$APP_NAME" name: test From cf0a1f899f572e8065947582162ec62c2d8341c2 Mon Sep 17 00:00:00 2001 From: Benjamin Pasero Date: Fri, 10 Aug 2018 14:13:17 +0200 Subject: [PATCH 0667/1276] Revert "disable tests for now in prod" This reverts commit eb68f9deefec7e34810866ab129842c641b41b0c. --- build/tfs/darwin/product-build-darwin.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build/tfs/darwin/product-build-darwin.yml b/build/tfs/darwin/product-build-darwin.yml index 6e48af628e0..0dd31503586 100644 --- a/build/tfs/darwin/product-build-darwin.yml +++ b/build/tfs/darwin/product-build-darwin.yml @@ -26,7 +26,7 @@ steps: - script: | set -e - # ./scripts/test.sh --build --tfs "Unit Tests" + ./scripts/test.sh --build --tfs "Unit Tests" APP_NAME="`ls $(agent.builddirectory)/VSCode-darwin | head -n 1`" # yarn smoketest -- --build "$(agent.builddirectory)/VSCode-darwin/$APP_NAME" name: test From f1cb0820d82d006f0ee4c3e7e3565b5a42de05fe Mon Sep 17 00:00:00 2001 From: Joao Moreno Date: Fri, 10 Aug 2018 12:29:25 +0200 Subject: [PATCH 0668/1276] simplify PagedModel --- src/vs/base/common/paging.ts | 25 ++++++++++++++++--- src/vs/base/test/common/paging.test.ts | 2 +- .../electron-browser/extensionsViews.ts | 4 +-- 3 files changed, 25 insertions(+), 6 deletions(-) diff --git a/src/vs/base/common/paging.ts b/src/vs/base/common/paging.ts index 286fa69d08f..c88d4a0e4b2 100644 --- a/src/vs/base/common/paging.ts +++ b/src/vs/base/common/paging.ts @@ -51,7 +51,7 @@ export class PagedModel implements IPagedModel { get length(): number { return this.pager.total; } - constructor(arg: IPager | T[], private pageTimeout: number = 500) { + constructor(arg: IPager | T[]) { this.pager = isArray(arg) ? singlePagePager(arg) : arg; this.pages = [{ isResolved: true, promise: null, promiseIndexes: new Set(), elements: this.pager.firstPage.slice() }]; @@ -87,8 +87,7 @@ export class PagedModel implements IPagedModel { } if (!page.promise) { - page.promise = TPromise.timeout(this.pageTimeout) - .then(() => this.pager.getPage(pageIndex)) + page.promise = this.pager.getPage(pageIndex) .then(elements => { page.elements = elements; page.isResolved = true; @@ -117,6 +116,26 @@ export class PagedModel implements IPagedModel { } } +export class DelayedPagedModel implements IPagedModel { + + get length(): number { return this.model.length; } + + constructor(private model: IPagedModel, private timeout: number = 500) { } + + isResolved(index: number): boolean { + return this.model.isResolved(index); + } + + get(index: number): T { + return this.model.get(index); + } + + resolve(index: number): TPromise { + return TPromise.timeout(this.timeout) + .then(() => this.model.resolve(index)); + } +} + /** * Similar to array.map, `mapPager` lets you map the elements of an * abstract paged collection to another type. diff --git a/src/vs/base/test/common/paging.test.ts b/src/vs/base/test/common/paging.test.ts index 04aed69dda4..3460264ae83 100644 --- a/src/vs/base/test/common/paging.test.ts +++ b/src/vs/base/test/common/paging.test.ts @@ -21,7 +21,7 @@ suite('PagedModel', () => { getPage: pageIndex => TPromise.as([0, 1, 2, 3, 4].map(i => i + (pageIndex * 5))) }; - model = new PagedModel(pager, 0); + model = new PagedModel(pager); }); test('isResolved', () => { diff --git a/src/vs/workbench/parts/extensions/electron-browser/extensionsViews.ts b/src/vs/workbench/parts/extensions/electron-browser/extensionsViews.ts index 70edc1d5fab..9857be0c0cb 100644 --- a/src/vs/workbench/parts/extensions/electron-browser/extensionsViews.ts +++ b/src/vs/workbench/parts/extensions/electron-browser/extensionsViews.ts @@ -12,7 +12,7 @@ import { dispose } from 'vs/base/common/lifecycle'; import { assign } from 'vs/base/common/objects'; import { chain } from 'vs/base/common/event'; import { isPromiseCanceledError, create as createError } from 'vs/base/common/errors'; -import { PagedModel, IPagedModel, IPager } from 'vs/base/common/paging'; +import { PagedModel, IPagedModel, IPager, DelayedPagedModel } from 'vs/base/common/paging'; import { SortBy, SortOrder, IQueryOptions, LocalExtensionType, IExtensionTipsService, EnablementState, IExtensionRecommendation, IExtensionManagementServerService, ExtensionRecommendationSource, IExtensionManagementServer } from 'vs/platform/extensionManagement/common/extensionManagement'; import { areSameExtensions } from 'vs/platform/extensionManagement/common/extensionManagementUtil'; import { IKeybindingService } from 'vs/platform/keybinding/common/keybinding'; @@ -563,7 +563,7 @@ export class ExtensionsListView extends ViewletPanel { private setModel(model: IPagedModel) { if (this.list) { - this.list.model = model; + this.list.model = new DelayedPagedModel(model); this.list.scrollTop = 0; const count = this.count(); From 1ed580c82ad54d2f8c286033e9a8c9cfcfcfeb7a Mon Sep 17 00:00:00 2001 From: Joao Moreno Date: Fri, 10 Aug 2018 14:18:12 +0200 Subject: [PATCH 0669/1276] remove promise.cancel from list paging related to #56137 --- src/vs/base/browser/ui/list/listPaging.ts | 8 +- src/vs/base/common/paging.ts | 84 ++++++++--- src/vs/base/test/common/paging.test.ts | 134 +++++++++++++++--- .../node/extensionGalleryService.ts | 16 ++- .../electron-browser/extensionsActions.ts | 3 +- 5 files changed, 199 insertions(+), 46 deletions(-) diff --git a/src/vs/base/browser/ui/list/listPaging.ts b/src/vs/base/browser/ui/list/listPaging.ts index 10094f4e5a6..73f8ec7f4ca 100644 --- a/src/vs/base/browser/ui/list/listPaging.ts +++ b/src/vs/base/browser/ui/list/listPaging.ts @@ -10,6 +10,7 @@ import { IVirtualDelegate, IRenderer, IListEvent, IListOpenEvent } from './list' import { List, IListStyles, IListOptions } from './listWidget'; import { IPagedModel } from 'vs/base/common/paging'; import { Event, mapEvent } from 'vs/base/common/event'; +import { CancellationTokenSource } from 'vs/base/common/cancellation'; export interface IPagedRenderer extends IRenderer { renderPlaceholder(index: number, templateData: TTemplateData): void; @@ -43,11 +44,12 @@ class PagedRenderer implements IRenderer promise.cancel() }; + const cts = new CancellationTokenSource(); + const promise = model.resolve(index, cts.token); + data.disposable = { dispose: () => cts.cancel() }; this.renderer.renderPlaceholder(index, data.data); - promise.done(entry => this.renderer.renderElement(entry, index, data.data)); + promise.then(entry => this.renderer.renderElement(entry, index, data.data)); } disposeElement(): void { diff --git a/src/vs/base/common/paging.ts b/src/vs/base/common/paging.ts index c88d4a0e4b2..93e1e4dfa52 100644 --- a/src/vs/base/common/paging.ts +++ b/src/vs/base/common/paging.ts @@ -7,6 +7,9 @@ import { TPromise } from 'vs/base/common/winjs.base'; import { isArray } from 'vs/base/common/types'; +import { CancellationToken, CancellationTokenSource } from 'vs/base/common/cancellation'; +import { canceled } from 'vs/base/common/errors'; +import { range } from 'vs/base/common/arrays'; /** * A Pager is a stateless abstraction over a paged collection. @@ -15,16 +18,27 @@ export interface IPager { firstPage: T[]; total: number; pageSize: number; - getPage(pageIndex: number): TPromise; + getPage(pageIndex: number, cancellationToken: CancellationToken): Thenable; } interface IPage { isResolved: boolean; - promise: TPromise; + promise: Thenable; + cts: CancellationTokenSource; promiseIndexes: Set; elements: T[]; } +function createPage(elements?: T[]): IPage { + return { + isResolved: !!elements, + promise: null, + cts: null, + promiseIndexes: new Set(), + elements: elements || [] + }; +} + /** * A PagedModel is a stateful model over an abstracted paged collection. */ @@ -32,7 +46,7 @@ export interface IPagedModel { length: number; isResolved(index: number): boolean; get(index: number): T; - resolve(index: number): TPromise; + resolve(index: number, cancellationToken: CancellationToken): Thenable; } export function singlePagePager(elements: T[]): IPager { @@ -54,18 +68,18 @@ export class PagedModel implements IPagedModel { constructor(arg: IPager | T[]) { this.pager = isArray(arg) ? singlePagePager(arg) : arg; - this.pages = [{ isResolved: true, promise: null, promiseIndexes: new Set(), elements: this.pager.firstPage.slice() }]; - const totalPages = Math.ceil(this.pager.total / this.pager.pageSize); - for (let i = 0, len = totalPages - 1; i < len; i++) { - this.pages.push({ isResolved: false, promise: null, promiseIndexes: new Set(), elements: [] }); - } + this.pages = [ + createPage(this.pager.firstPage.slice()), + ...range(totalPages - 1).map(() => createPage()) + ]; } isResolved(index: number): boolean { const pageIndex = Math.floor(index / this.pager.pageSize); const page = this.pages[pageIndex]; + return !!page.isResolved; } @@ -77,7 +91,11 @@ export class PagedModel implements IPagedModel { return page.elements[indexInPage]; } - resolve(index: number): TPromise { + resolve(index: number, cancellationToken: CancellationToken): Thenable { + if (cancellationToken.isCancellationRequested) { + return TPromise.wrapError(canceled()); + } + const pageIndex = Math.floor(index / this.pager.pageSize); const indexInPage = index % this.pager.pageSize; const page = this.pages[pageIndex]; @@ -87,32 +105,36 @@ export class PagedModel implements IPagedModel { } if (!page.promise) { - page.promise = this.pager.getPage(pageIndex) + page.cts = new CancellationTokenSource(); + page.promise = this.pager.getPage(pageIndex, page.cts.token) .then(elements => { page.elements = elements; page.isResolved = true; page.promise = null; + page.cts = null; }, err => { page.isResolved = false; page.promise = null; + page.cts = null; return TPromise.wrapError(err); }); } - return new TPromise((c, e) => { - page.promiseIndexes.add(index); - page.promise.done(() => c(page.elements[indexInPage])); - }, () => { - if (!page.promise) { + cancellationToken.onCancellationRequested(() => { + if (!page.cts) { return; } page.promiseIndexes.delete(index); if (page.promiseIndexes.size === 0) { - page.promise.cancel(); + page.cts.cancel(); } }); + + page.promiseIndexes.add(index); + + return page.promise.then(() => page.elements[indexInPage]); } } @@ -130,9 +152,27 @@ export class DelayedPagedModel implements IPagedModel { return this.model.get(index); } - resolve(index: number): TPromise { - return TPromise.timeout(this.timeout) - .then(() => this.model.resolve(index)); + resolve(index: number, cancellationToken: CancellationToken): Thenable { + return new TPromise((c, e) => { + if (cancellationToken.isCancellationRequested) { + return e(canceled()); + } + + const timer = setTimeout(() => { + if (cancellationToken.isCancellationRequested) { + return e(canceled()); + } + + timeoutCancellation.dispose(); + this.model.resolve(index, cancellationToken).then(c, e); + }, this.timeout); + + const timeoutCancellation = cancellationToken.onCancellationRequested(() => { + clearTimeout(timer); + timeoutCancellation.dispose(); + e(canceled()); + }); + }); } } @@ -145,7 +185,7 @@ export function mapPager(pager: IPager, fn: (t: T) => R): IPager { firstPage: pager.firstPage.map(fn), total: pager.total, pageSize: pager.pageSize, - getPage: pageIndex => pager.getPage(pageIndex).then(r => r.map(fn)) + getPage: (pageIndex, token) => pager.getPage(pageIndex, token).then(r => r.map(fn)) }; } @@ -157,8 +197,8 @@ export function mergePagers(one: IPager, other: IPager): IPager { firstPage: [...one.firstPage, ...other.firstPage], total: one.total + other.total, pageSize: one.pageSize + other.pageSize, - getPage(pageIndex: number): TPromise { - return TPromise.join([one.getPage(pageIndex), other.getPage(pageIndex)]) + getPage(pageIndex: number, token): Thenable { + return TPromise.join([one.getPage(pageIndex, token), other.getPage(pageIndex, token)]) .then(([onePage, otherPage]) => [...onePage, ...otherPage]); } }; diff --git a/src/vs/base/test/common/paging.test.ts b/src/vs/base/test/common/paging.test.ts index 3460264ae83..b7a4cd076a6 100644 --- a/src/vs/base/test/common/paging.test.ts +++ b/src/vs/base/test/common/paging.test.ts @@ -8,23 +8,35 @@ import * as assert from 'assert'; import { IPager, PagedModel } from 'vs/base/common/paging'; import { TPromise } from 'vs/base/common/winjs.base'; +import { CancellationToken, CancellationTokenSource } from 'vs/base/common/cancellation'; +import { isPromiseCanceledError, canceled } from 'vs/base/common/errors'; + +function getPage(pageIndex: number, cancellationToken: CancellationToken): Thenable { + if (cancellationToken.isCancellationRequested) { + return TPromise.wrapError(canceled()); + } + + return TPromise.as([0, 1, 2, 3, 4].map(i => i + (pageIndex * 5))); +} + +class TestPager implements IPager { + + readonly firstPage = [0, 1, 2, 3, 4]; + readonly pageSize = 5; + readonly total = 100; + readonly getPage: (pageIndex: number, cancellationToken: CancellationToken) => Thenable; + + constructor(getPageFn?: (pageIndex: number, cancellationToken: CancellationToken) => Thenable) { + this.getPage = getPageFn || getPage; + } +} suite('PagedModel', () => { - let model: PagedModel; - - setup(() => { - const pager: IPager = { - firstPage: [0, 1, 2, 3, 4], - pageSize: 5, - total: 100, - getPage: pageIndex => TPromise.as([0, 1, 2, 3, 4].map(i => i + (pageIndex * 5))) - }; - - model = new PagedModel(pager); - }); - test('isResolved', () => { + const pager = new TestPager(); + const model = new PagedModel(pager); + assert(model.isResolved(0)); assert(model.isResolved(1)); assert(model.isResolved(2)); @@ -40,14 +52,20 @@ suite('PagedModel', () => { }); test('resolve single', () => { + const pager = new TestPager(); + const model = new PagedModel(pager); + assert(!model.isResolved(5)); - return model.resolve(5).then(() => { + return model.resolve(5, CancellationToken.None).then(() => { assert(model.isResolved(5)); }); }); test('resolve page', () => { + const pager = new TestPager(); + const model = new PagedModel(pager); + assert(!model.isResolved(5)); assert(!model.isResolved(6)); assert(!model.isResolved(7)); @@ -55,7 +73,7 @@ suite('PagedModel', () => { assert(!model.isResolved(9)); assert(!model.isResolved(10)); - return model.resolve(5).then(() => { + return model.resolve(5, CancellationToken.None).then(() => { assert(model.isResolved(5)); assert(model.isResolved(6)); assert(model.isResolved(7)); @@ -66,6 +84,9 @@ suite('PagedModel', () => { }); test('resolve page 2', () => { + const pager = new TestPager(); + const model = new PagedModel(pager); + assert(!model.isResolved(5)); assert(!model.isResolved(6)); assert(!model.isResolved(7)); @@ -73,7 +94,7 @@ suite('PagedModel', () => { assert(!model.isResolved(9)); assert(!model.isResolved(10)); - return model.resolve(10).then(() => { + return model.resolve(10, CancellationToken.None).then(() => { assert(!model.isResolved(5)); assert(!model.isResolved(6)); assert(!model.isResolved(7)); @@ -82,4 +103,85 @@ suite('PagedModel', () => { assert(model.isResolved(10)); }); }); + + test('preemptive cancellation works', function () { + const pager = new TestPager(() => { + assert(false); + return TPromise.wrap([]); + }); + + const model = new PagedModel(pager); + + return model.resolve(5, CancellationToken.Cancelled).then( + () => assert(false), + err => assert(isPromiseCanceledError(err)) + ); + }); + + test('cancellation works', function () { + const pager = new TestPager((_, token) => new TPromise((_, e) => { + token.onCancellationRequested(() => e(canceled())); + })); + + const model = new PagedModel(pager); + const tokenSource = new CancellationTokenSource(); + + const promise = model.resolve(5, tokenSource.token).then( + () => assert(false), + err => assert(isPromiseCanceledError(err)) + ); + + setTimeout(() => tokenSource.cancel(), 10); + + return promise; + }); + + test('same page cancellation works', function () { + let state = 'idle'; + + const pager = new TestPager((pageIndex, token) => { + state = 'resolving'; + + return new TPromise((_, e) => { + token.onCancellationRequested(() => { + state = 'idle'; + e(canceled()); + }); + }); + }); + + const model = new PagedModel(pager); + + assert.equal(state, 'idle'); + + const tokenSource1 = new CancellationTokenSource(); + const promise1 = model.resolve(5, tokenSource1.token).then( + () => assert(false), + err => assert(isPromiseCanceledError(err)) + ); + + assert.equal(state, 'resolving'); + + const tokenSource2 = new CancellationTokenSource(); + const promise2 = model.resolve(6, tokenSource2.token).then( + () => assert(false), + err => assert(isPromiseCanceledError(err)) + ); + + assert.equal(state, 'resolving'); + + setTimeout(() => { + assert.equal(state, 'resolving'); + tokenSource1.cancel(); + assert.equal(state, 'resolving'); + + setTimeout(() => { + assert.equal(state, 'resolving'); + tokenSource2.cancel(); + assert.equal(state, 'idle'); + }, 10); + }, 10); + + return TPromise.join([promise1, promise2]); + }); }); \ No newline at end of file diff --git a/src/vs/platform/extensionManagement/node/extensionGalleryService.ts b/src/vs/platform/extensionManagement/node/extensionGalleryService.ts index 16af4dbf97a..18b43c9c0ef 100644 --- a/src/vs/platform/extensionManagement/node/extensionGalleryService.ts +++ b/src/vs/platform/extensionManagement/node/extensionGalleryService.ts @@ -8,7 +8,7 @@ import { tmpdir } from 'os'; import * as path from 'path'; import { TPromise } from 'vs/base/common/winjs.base'; import { distinct } from 'vs/base/common/arrays'; -import { getErrorMessage, isPromiseCanceledError } from 'vs/base/common/errors'; +import { getErrorMessage, isPromiseCanceledError, canceled } from 'vs/base/common/errors'; import { StatisticType, IGalleryExtension, IExtensionGalleryService, IGalleryExtensionAsset, IQueryOptions, SortBy, SortOrder, IExtensionManifest, IExtensionIdentifier, IReportedExtension, InstallOperation, ITranslation } from 'vs/platform/extensionManagement/common/extensionManagement'; import { getGalleryExtensionId, getGalleryExtensionTelemetryData, adoptToGalleryExtensionId } from 'vs/platform/extensionManagement/common/extensionManagementUtil'; import { assign, getOrDefault } from 'vs/base/common/objects'; @@ -24,6 +24,8 @@ import { readFile } from 'vs/base/node/pfs'; import { writeFileAndFlushSync } from 'vs/base/node/extfs'; import { generateUuid, isUUID } from 'vs/base/common/uuid'; import { values } from 'vs/base/common/map'; +import { CancellationToken } from 'vs/base/common/cancellation'; +import { wireCancellationToken } from 'vs/base/common/async'; interface IRawGalleryExtensionFile { assetType: string; @@ -425,13 +427,19 @@ export class ExtensionGalleryService implements IExtensionGalleryService { return this.queryGallery(query).then(({ galleryExtensions, total }) => { const extensions = galleryExtensions.map((e, index) => toExtension(e, this.extensionsGalleryUrl, index, query, options.source)); const pageSize = query.pageSize; - const getPage = (pageIndex: number) => { + const getPage = (pageIndex: number, ct: CancellationToken) => { + if (ct.isCancellationRequested) { + return TPromise.wrapError(canceled()); + } + const nextPageQuery = query.withPage(pageIndex + 1); - return this.queryGallery(nextPageQuery) + const promise = this.queryGallery(nextPageQuery) .then(({ galleryExtensions }) => galleryExtensions.map((e, index) => toExtension(e, this.extensionsGalleryUrl, index, nextPageQuery, options.source))); + + return wireCancellationToken(ct, promise); }; - return { firstPage: extensions, total, pageSize, getPage }; + return { firstPage: extensions, total, pageSize, getPage } as IPager; }); } diff --git a/src/vs/workbench/parts/extensions/electron-browser/extensionsActions.ts b/src/vs/workbench/parts/extensions/electron-browser/extensionsActions.ts index 0d74ff218bd..9900d0d5a7a 100644 --- a/src/vs/workbench/parts/extensions/electron-browser/extensionsActions.ts +++ b/src/vs/workbench/parts/extensions/electron-browser/extensionsActions.ts @@ -52,6 +52,7 @@ import { ExtensionsInput } from 'vs/workbench/parts/extensions/common/extensions import product from 'vs/platform/node/product'; import { ContextSubMenu } from 'vs/base/browser/contextmenu'; import { IQuickPickItem, IQuickInputService } from 'vs/platform/quickinput/common/quickInput'; +import { CancellationToken } from 'vs/base/common/cancellation'; const promptDownloadManually = (extension: IGalleryExtension, message: string, instantiationService: IInstantiationService, notificationService: INotificationService, openerService: IOpenerService) => { const downloadUrl = `${product.extensionsGallery.serviceUrl}/publishers/${extension.publisher}/vsextensions/${extension.name}/${extension.version}/vspackage`; @@ -1633,7 +1634,7 @@ export class InstallWorkspaceRecommendedExtensionsAction extends Action { let installPromises = []; let model = new PagedModel(pager); for (let i = 0; i < pager.total; i++) { - installPromises.push(model.resolve(i).then(e => { + installPromises.push(model.resolve(i, CancellationToken.None).then(e => { return this.install(e); })); } From b9d1534d79b2d6a9cf5780686712ecbfa6f94244 Mon Sep 17 00:00:00 2001 From: Christof Marti Date: Fri, 10 Aug 2018 13:12:31 +0200 Subject: [PATCH 0670/1276] Update smoke test (#29096) --- .../platform/quickinput/common/quickInput.ts | 1 + .../parts/quickinput/quickInputList.ts | 2 +- .../electron-browser/themes.contribution.ts | 66 +++++++++++-------- 3 files changed, 42 insertions(+), 27 deletions(-) diff --git a/src/vs/platform/quickinput/common/quickInput.ts b/src/vs/platform/quickinput/common/quickInput.ts index 1588078e763..d1427331cce 100644 --- a/src/vs/platform/quickinput/common/quickInput.ts +++ b/src/vs/platform/quickinput/common/quickInput.ts @@ -20,6 +20,7 @@ export interface IQuickPickItem { iconClasses?: string[]; buttons?: IQuickInputButton[]; picked?: boolean; + alwaysShow?: boolean; } export interface IQuickPickSeparator { diff --git a/src/vs/workbench/browser/parts/quickinput/quickInputList.ts b/src/vs/workbench/browser/parts/quickinput/quickInputList.ts index 104cb9ae3d1..ef9e7899182 100644 --- a/src/vs/workbench/browser/parts/quickinput/quickInputList.ts +++ b/src/vs/workbench/browser/parts/quickinput/quickInputList.ts @@ -473,7 +473,7 @@ export class QuickInputList { element.labelHighlights = undefined; element.descriptionHighlights = undefined; element.detailHighlights = undefined; - element.hidden = true; + element.hidden = !element.item.alwaysShow; } element.separator = undefined; }); diff --git a/src/vs/workbench/parts/themes/electron-browser/themes.contribution.ts b/src/vs/workbench/parts/themes/electron-browser/themes.contribution.ts index dfa15ae450f..15d021df4fc 100644 --- a/src/vs/workbench/parts/themes/electron-browser/themes.contribution.ts +++ b/src/vs/workbench/parts/themes/electron-browser/themes.contribution.ts @@ -13,7 +13,6 @@ import { KeyMod, KeyChord, KeyCode } from 'vs/base/common/keyCodes'; import { SyncActionDescriptor, MenuRegistry, MenuId } from 'vs/platform/actions/common/actions'; import { Registry } from 'vs/platform/registry/common/platform'; import { IWorkbenchActionRegistry, Extensions } from 'vs/workbench/common/actions'; -import { IQuickOpenService, IPickOpenEntry } from 'vs/platform/quickOpen/common/quickOpen'; import { IWorkbenchThemeService, COLOR_THEME_SETTING, ICON_THEME_SETTING, IColorTheme, IFileIconTheme } from 'vs/workbench/services/themes/common/workbenchThemeService'; import { VIEWLET_ID, IExtensionsViewlet } from 'vs/workbench/parts/extensions/common/extensions'; import { IExtensionGalleryService } from 'vs/platform/extensionManagement/common/extensionManagement'; @@ -27,6 +26,7 @@ import { ConfigurationTarget } from 'vs/platform/configuration/common/configurat import { LIGHT, DARK, HIGH_CONTRAST } from 'vs/platform/theme/common/themeService'; import { schemaId } from 'vs/workbench/services/themes/common/colorThemeSchema'; import { onUnexpectedError } from 'vs/base/common/errors'; +import { IQuickInputService, IQuickPickItem, QuickPickInput } from 'vs/platform/quickinput/common/quickInput'; export class SelectColorThemeAction extends Action { @@ -36,7 +36,7 @@ export class SelectColorThemeAction extends Action { constructor( id: string, label: string, - @IQuickOpenService private quickOpenService: IQuickOpenService, + @IQuickInputService private quickInputService: IQuickInputService, @IWorkbenchThemeService private themeService: IWorkbenchThemeService, @IExtensionGalleryService private extensionGalleryService: IExtensionGalleryService, @IViewletService private viewletService: IViewletService, @@ -49,15 +49,18 @@ export class SelectColorThemeAction extends Action { return this.themeService.getColorThemes().then(themes => { const currentTheme = this.themeService.getColorTheme(); - const picks: IPickOpenEntry[] = [].concat( + const picks: QuickPickInput[] = [].concat( toEntries(themes.filter(t => t.type === LIGHT), localize('themes.category.light', "light themes")), toEntries(themes.filter(t => t.type === DARK), localize('themes.category.dark', "dark themes"), true), toEntries(themes.filter(t => t.type === HIGH_CONTRAST), localize('themes.category.hc', "high contrast themes"), true), - configurationEntries(this.extensionGalleryService, this.viewletService, 'category:themes', localize('installColorThemes', "Install Additional Color Themes...")) + configurationEntries(this.extensionGalleryService, localize('installColorThemes', "Install Additional Color Themes...")) ); const selectTheme = (theme, applyTheme: boolean) => { if (typeof theme.id === 'undefined') { // 'pick in marketplace' entry + if (applyTheme) { + openExtensionViewlet(this.viewletService, 'category:themes'); + } theme = currentTheme; } let target = null; @@ -75,12 +78,12 @@ export class SelectColorThemeAction extends Action { }; const placeHolder = localize('themes.selectTheme', "Select Color Theme (Up/Down Keys to Preview)"); - const autoFocusIndex = firstIndex(picks, p => p.id === currentTheme.id); + const autoFocusIndex = firstIndex(picks, p => p.type !== 'separator' && p.id === currentTheme.id); const delayer = new Delayer(100); const chooseTheme = theme => delayer.trigger(() => selectTheme(theme || currentTheme, true), 0); const tryTheme = theme => delayer.trigger(() => selectTheme(theme, false)); - return this.quickOpenService.pick(picks, { placeHolder, autoFocus: { autoFocusIndex }, onDidFocus: tryTheme }) + return this.quickInputService.pick(picks, { placeHolder, activeItem: picks[autoFocusIndex], onDidFocus: tryTheme }) .then(chooseTheme); }); } @@ -94,7 +97,7 @@ class SelectIconThemeAction extends Action { constructor( id: string, label: string, - @IQuickOpenService private quickOpenService: IQuickOpenService, + @IQuickInputService private quickInputService: IQuickInputService, @IWorkbenchThemeService private themeService: IWorkbenchThemeService, @IExtensionGalleryService private extensionGalleryService: IExtensionGalleryService, @IViewletService private viewletService: IViewletService, @@ -108,14 +111,17 @@ class SelectIconThemeAction extends Action { return this.themeService.getFileIconThemes().then(themes => { const currentTheme = this.themeService.getFileIconTheme(); - let picks: IPickOpenEntry[] = [{ id: '', label: localize('noIconThemeLabel', 'None'), description: localize('noIconThemeDesc', 'Disable file icons') }]; + let picks: QuickPickInput[] = [{ id: '', label: localize('noIconThemeLabel', 'None'), description: localize('noIconThemeDesc', 'Disable file icons') }]; picks = picks.concat( toEntries(themes), - configurationEntries(this.extensionGalleryService, this.viewletService, 'tag:icon-theme', localize('installIconThemes', "Install Additional File Icon Themes...")) + configurationEntries(this.extensionGalleryService, localize('installIconThemes', "Install Additional File Icon Themes...")) ); const selectTheme = (theme, applyTheme: boolean) => { if (typeof theme.id === 'undefined') { // 'pick in marketplace' entry + if (applyTheme) { + openExtensionViewlet(this.viewletService, 'tag:icon-theme'); + } theme = currentTheme; } let target = null; @@ -132,39 +138,47 @@ class SelectIconThemeAction extends Action { }; const placeHolder = localize('themes.selectIconTheme', "Select File Icon Theme"); - const autoFocusIndex = firstIndex(picks, p => p.id === currentTheme.id); + const autoFocusIndex = firstIndex(picks, p => p.type !== 'separator' && p.id === currentTheme.id); const delayer = new Delayer(100); const chooseTheme = theme => delayer.trigger(() => selectTheme(theme || currentTheme, true), 0); const tryTheme = theme => delayer.trigger(() => selectTheme(theme, false)); - return this.quickOpenService.pick(picks, { placeHolder, autoFocus: { autoFocusIndex }, onDidFocus: tryTheme }) + return this.quickInputService.pick(picks, { placeHolder, activeItem: picks[autoFocusIndex], onDidFocus: tryTheme }) .then(chooseTheme); }); } } -function configurationEntries(extensionGalleryService: IExtensionGalleryService, viewletService: IViewletService, query: string, label: string): IPickOpenEntry[] { +function configurationEntries(extensionGalleryService: IExtensionGalleryService, label: string): QuickPickInput[] { if (extensionGalleryService.isEnabled()) { - return [{ - id: void 0, - label: label, - separator: { border: true }, - alwaysShow: true, - run: () => viewletService.openViewlet(VIEWLET_ID, true).then(viewlet => { - (viewlet).search(query); - viewlet.focus(); - }) - }]; + return [ + { + type: 'separator', + border: true + }, + { + id: void 0, + label: label, + alwaysShow: true, + } + ]; } return []; } +function openExtensionViewlet(viewletService: IViewletService, query: string) { + return viewletService.openViewlet(VIEWLET_ID, true).then(viewlet => { + (viewlet).search(query); + viewlet.focus(); + }); +} + function toEntries(themes: (IColorTheme | IFileIconTheme)[], label?: string, border = false) { - const toEntry = theme => { id: theme.id, label: theme.label, description: theme.description }; - const sorter = (t1: IColorTheme, t2: IColorTheme) => t1.label.localeCompare(t2.label); - let entries = themes.map(toEntry).sort(sorter); + const toEntry = theme => { id: theme.id, label: theme.label, description: theme.description }; + const sorter = (t1: IQuickPickItem, t2: IQuickPickItem) => t1.label.localeCompare(t2.label); + let entries: QuickPickInput[] = themes.map(toEntry).sort(sorter); if (entries.length > 0 && (label || border)) { - entries[0].separator = { label, border }; + entries.unshift({ type: 'separator', label, border }); } return entries; } From 26a756c5c6b2bec786fa34d3ec1e7fe7c39f63d1 Mon Sep 17 00:00:00 2001 From: Christof Marti Date: Fri, 10 Aug 2018 14:24:10 +0200 Subject: [PATCH 0671/1276] Restore active item when filter is cleared (#29096) --- src/vs/workbench/browser/parts/quickinput/quickInput.ts | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/vs/workbench/browser/parts/quickinput/quickInput.ts b/src/vs/workbench/browser/parts/quickinput/quickInput.ts index 1f34e401506..d834bd59460 100644 --- a/src/vs/workbench/browser/parts/quickinput/quickInput.ts +++ b/src/vs/workbench/browser/parts/quickinput/quickInput.ts @@ -1023,6 +1023,7 @@ export class QuickInputService extends Component implements IQuickInputService { return; } const input = this.createQuickPick(); + let activeItem: T; const disposables = [ input, input.onDidAccept(() => { @@ -1063,6 +1064,11 @@ export class QuickInputService extends Component implements IQuickInputService { } } })), + input.onDidChangeValue(value => { + if (activeItem && !value && (input.activeItems.length !== 1 || input.activeItems[0] !== activeItem)) { + input.activeItems = [activeItem]; + } + }), token.onCancellationRequested(() => { input.hide(); }), @@ -1080,7 +1086,8 @@ export class QuickInputService extends Component implements IQuickInputService { input.contextKey = options.contextKey; input.busy = true; TPromise.join([picks, options.activeItem]) - .then(([items, activeItem]) => { + .then(([items, _activeItem]) => { + activeItem = _activeItem; input.busy = false; input.items = items; if (input.canSelectMany) { From 87f890a9ebcef49dac93a0ef4038c4661780c8f2 Mon Sep 17 00:00:00 2001 From: Christof Marti Date: Fri, 10 Aug 2018 14:54:16 +0200 Subject: [PATCH 0672/1276] Automate border choice (#29096) --- .../platform/quickinput/common/quickInput.ts | 1 - .../browser/parts/editor/editorStatus.ts | 6 +++--- .../browser/parts/quickinput/quickInput.css | 16 ++++++++++------ .../browser/parts/quickinput/quickInputList.ts | 2 +- src/vs/workbench/electron-browser/actions.ts | 2 +- .../debugConfigurationManager.ts | 2 +- .../electron-browser/configureSnippets.ts | 2 +- .../electron-browser/task.contribution.ts | 18 ++++++++---------- .../electron-browser/themes.contribution.ts | 13 ++++++------- 9 files changed, 31 insertions(+), 31 deletions(-) diff --git a/src/vs/platform/quickinput/common/quickInput.ts b/src/vs/platform/quickinput/common/quickInput.ts index d1427331cce..b384addd509 100644 --- a/src/vs/platform/quickinput/common/quickInput.ts +++ b/src/vs/platform/quickinput/common/quickInput.ts @@ -25,7 +25,6 @@ export interface IQuickPickItem { export interface IQuickPickSeparator { type: 'separator'; - border?: boolean; label?: string; } diff --git a/src/vs/workbench/browser/parts/editor/editorStatus.ts b/src/vs/workbench/browser/parts/editor/editorStatus.ts index d7156eec4e6..9a47132500a 100644 --- a/src/vs/workbench/browser/parts/editor/editorStatus.ts +++ b/src/vs/workbench/browser/parts/editor/editorStatus.ts @@ -895,7 +895,7 @@ export class ChangeModeAction extends Action { }); if (hasLanguageSupport) { - picks.unshift({ type: 'separator', border: true, label: nls.localize('languagesPicks', "languages (identifier)") }); + picks.unshift({ type: 'separator', label: nls.localize('languagesPicks', "languages (identifier)") }); } // Offer action to configure via settings @@ -1079,7 +1079,7 @@ class ChangeIndentationAction extends Action { }; }); - picks.splice(3, 0, { type: 'separator', label: nls.localize('indentConvert', "convert file"), border: true }); + picks.splice(3, 0, { type: 'separator', label: nls.localize('indentConvert', "convert file") }); picks.unshift({ type: 'separator', label: nls.localize('indentView', "change view") }); return this.quickInputService.pick(picks, { placeHolder: nls.localize('pickAction', "Select Action"), matchOnDetail: true }).then(action => action && action.run()); @@ -1231,7 +1231,7 @@ export class ChangeEncodingAction extends Action { // If we have a guessed encoding, show it first unless it matches the configured encoding if (guessedEncoding && configuredEncoding !== guessedEncoding && SUPPORTED_ENCODINGS[guessedEncoding]) { - picks.unshift({ type: 'separator', border: true }); + picks.unshift({ type: 'separator' }); picks.unshift({ id: guessedEncoding, label: SUPPORTED_ENCODINGS[guessedEncoding].labelLong, description: nls.localize('guessedEncoding', "Guessed from content") }); } diff --git a/src/vs/workbench/browser/parts/quickinput/quickInput.css b/src/vs/workbench/browser/parts/quickinput/quickInput.css index 514dc145b72..690286ea033 100644 --- a/src/vs/workbench/browser/parts/quickinput/quickInput.css +++ b/src/vs/workbench/browser/parts/quickinput/quickInput.css @@ -113,12 +113,22 @@ } .quick-input-list .quick-input-list-entry { + box-sizing: border-box; overflow: hidden; display: flex; height: 100%; padding: 0 6px; } +.quick-input-list .quick-input-list-entry.quick-input-list-separator-border { + border-top-width: 1px; + border-top-style: solid; +} + +.quick-input-list .monaco-list-row:first-child .quick-input-list-entry.quick-input-list-separator-border { + border-top-style: none; +} + .quick-input-list .quick-input-list-label { overflow: hidden; display: flex; @@ -179,12 +189,6 @@ margin-right: 0; } -.quick-input-list .quick-input-list-separator-border { - border-top-width: 1px; - border-top-style: solid; - box-sizing: border-box; -} - .quick-input-list .quick-input-list-entry-action-bar { display: none; flex: 0; diff --git a/src/vs/workbench/browser/parts/quickinput/quickInputList.ts b/src/vs/workbench/browser/parts/quickinput/quickInputList.ts index ef9e7899182..0b2ecb2d265 100644 --- a/src/vs/workbench/browser/parts/quickinput/quickInputList.ts +++ b/src/vs/workbench/browser/parts/quickinput/quickInputList.ts @@ -152,7 +152,7 @@ class ListElementRenderer implements IRenderer first.label.localeCompare(second.label)); const picks = candidates.map(c => ({ label: c.label, debugger: c })); - return this.quickInputService.pick<(typeof picks)[0]>([...picks, { type: 'separator', border: true }, { label: 'More...', debugger: undefined }], { placeHolder: nls.localize('selectDebug', "Select Environment") }) + return this.quickInputService.pick<(typeof picks)[0]>([...picks, { type: 'separator' }, { label: 'More...', debugger: undefined }], { placeHolder: nls.localize('selectDebug', "Select Environment") }) .then(picked => { if (picked.debugger) { return picked.debugger; diff --git a/src/vs/workbench/parts/snippets/electron-browser/configureSnippets.ts b/src/vs/workbench/parts/snippets/electron-browser/configureSnippets.ts index a9bf6177165..24ad084aa27 100644 --- a/src/vs/workbench/parts/snippets/electron-browser/configureSnippets.ts +++ b/src/vs/workbench/parts/snippets/electron-browser/configureSnippets.ts @@ -190,7 +190,7 @@ CommandsRegistry.registerCommand(id, async accessor => { const newGlobalPick = { label: nls.localize('new.global', "New Global Snippets file...") }; if (existing.length > 0) { existing.unshift({ type: 'separator', label: nls.localize('group.global', "Existing Snippets") }); - existing.push({ type: 'separator', border: true, label: nls.localize('new.global.sep', "New Snippets") }); + existing.push({ type: 'separator', label: nls.localize('new.global.sep', "New Snippets") }); } else { existing.push({ type: 'separator', label: nls.localize('new.global.sep', "New Snippets") }); } diff --git a/src/vs/workbench/parts/tasks/electron-browser/task.contribution.ts b/src/vs/workbench/parts/tasks/electron-browser/task.contribution.ts index fee6ca9b812..f6c79e586a7 100644 --- a/src/vs/workbench/parts/tasks/electron-browser/task.contribution.ts +++ b/src/vs/workbench/parts/tasks/electron-browser/task.contribution.ts @@ -894,7 +894,7 @@ class TaskService implements ITaskService { } if (entries.length > 0) { entries = entries.sort((a, b) => a.label.localeCompare(b.label)); - entries.unshift({ type: 'separator', border: true, label: nls.localize('TaskService.associate', 'associate') }); + entries.unshift({ type: 'separator', label: nls.localize('TaskService.associate', 'associate') }); entries.unshift( { label: nls.localize('TaskService.attachProblemMatcher.continueWithout', 'Continue without scanning the task output'), matcher: undefined }, { label: nls.localize('TaskService.attachProblemMatcher.never', 'Never scan the task output'), matcher: undefined, never: true }, @@ -1804,9 +1804,9 @@ class TaskService implements ITaskService { } return { label: task._label, description, task }; }; - function fillEntries(entries: QuickPickInput[], tasks: Task[], groupLabel: string, withBorder: boolean = false): void { + function fillEntries(entries: QuickPickInput[], tasks: Task[], groupLabel: string): void { if (tasks.length) { - entries.push({ type: 'separator', label: groupLabel, border: withBorder }); + entries.push({ type: 'separator', label: groupLabel }); } for (let task of tasks) { let entry: TaskQuickPickEntry = TaskQuickPickEntry(task); @@ -1848,13 +1848,11 @@ class TaskService implements ITaskService { } } const sorter = this.createSorter(); - let hasRecentlyUsed: boolean = recent.length > 0; fillEntries(entries, recent, nls.localize('recentlyUsed', 'recently used tasks')); configured = configured.sort((a, b) => sorter.compare(a, b)); - let hasConfigured = configured.length > 0; - fillEntries(entries, configured, nls.localize('configured', 'configured tasks'), hasRecentlyUsed); + fillEntries(entries, configured, nls.localize('configured', 'configured tasks')); detected = detected.sort((a, b) => sorter.compare(a, b)); - fillEntries(entries, detected, nls.localize('detected', 'detected tasks'), hasRecentlyUsed || hasConfigured); + fillEntries(entries, detected, nls.localize('detected', 'detected tasks')); } } else { if (sort) { @@ -2274,7 +2272,7 @@ class TaskService implements ITaskService { if (needsCreateOrOpen) { let label = stats[0] !== void 0 ? openLabel : createLabel; if (entries.length) { - entries.push({ type: 'separator', border: true }); + entries.push({ type: 'separator' }); } entries.push({ label, folder: this.contextService.getWorkspace().folders[0] }); } @@ -2288,14 +2286,14 @@ class TaskService implements ITaskService { for (let i = 0; i < tasks.length; i++) { let entry: EntryType = { label: tasks[i]._label, task: tasks[i], description: folder.name }; if (i === 0) { - entries.push({ type: 'separator', label: folder.name, border: index > 0 }); + entries.push({ type: 'separator', label: folder.name }); } entries.push(entry); } } else { let label = stats[index] !== void 0 ? openLabel : createLabel; let entry: EntryType = { label, folder: folder }; - entries.push({ type: 'separator', label: folder.name, border: index > 0 }); + entries.push({ type: 'separator', label: folder.name }); entries.push(entry); } index++; diff --git a/src/vs/workbench/parts/themes/electron-browser/themes.contribution.ts b/src/vs/workbench/parts/themes/electron-browser/themes.contribution.ts index 15d021df4fc..524a0915457 100644 --- a/src/vs/workbench/parts/themes/electron-browser/themes.contribution.ts +++ b/src/vs/workbench/parts/themes/electron-browser/themes.contribution.ts @@ -51,8 +51,8 @@ export class SelectColorThemeAction extends Action { const picks: QuickPickInput[] = [].concat( toEntries(themes.filter(t => t.type === LIGHT), localize('themes.category.light', "light themes")), - toEntries(themes.filter(t => t.type === DARK), localize('themes.category.dark', "dark themes"), true), - toEntries(themes.filter(t => t.type === HIGH_CONTRAST), localize('themes.category.hc', "high contrast themes"), true), + toEntries(themes.filter(t => t.type === DARK), localize('themes.category.dark', "dark themes")), + toEntries(themes.filter(t => t.type === HIGH_CONTRAST), localize('themes.category.hc', "high contrast themes")), configurationEntries(this.extensionGalleryService, localize('installColorThemes', "Install Additional Color Themes...")) ); @@ -153,8 +153,7 @@ function configurationEntries(extensionGalleryService: IExtensionGalleryService, if (extensionGalleryService.isEnabled()) { return [ { - type: 'separator', - border: true + type: 'separator' }, { id: void 0, @@ -173,12 +172,12 @@ function openExtensionViewlet(viewletService: IViewletService, query: string) { }); } -function toEntries(themes: (IColorTheme | IFileIconTheme)[], label?: string, border = false) { +function toEntries(themes: (IColorTheme | IFileIconTheme)[], label?: string) { const toEntry = theme => { id: theme.id, label: theme.label, description: theme.description }; const sorter = (t1: IQuickPickItem, t2: IQuickPickItem) => t1.label.localeCompare(t2.label); let entries: QuickPickInput[] = themes.map(toEntry).sort(sorter); - if (entries.length > 0 && (label || border)) { - entries.unshift({ type: 'separator', label, border }); + if (entries.length > 0 && label) { + entries.unshift({ type: 'separator', label }); } return entries; } From cd1f0f27582c84d80a7943dc4d3cf576dcea644d Mon Sep 17 00:00:00 2001 From: Benjamin Pasero Date: Fri, 10 Aug 2018 14:58:42 +0200 Subject: [PATCH 0673/1276] debt - remove nsfw from build dependencies --- build/lib/watch/index.js | 10 ---- build/lib/watch/package.json | 3 +- build/lib/watch/watch-nsfw.js | 94 ----------------------------------- build/lib/watch/yarn.lock | 62 ++--------------------- 4 files changed, 4 insertions(+), 165 deletions(-) delete mode 100644 build/lib/watch/watch-nsfw.js diff --git a/build/lib/watch/index.js b/build/lib/watch/index.js index e1138b07f90..94f73cdd4a0 100644 --- a/build/lib/watch/index.js +++ b/build/lib/watch/index.js @@ -19,16 +19,6 @@ function handleDeletions() { let watch = void 0; -// Disabled due to https://github.com/Microsoft/vscode/issues/36214 -// if (!process.env['VSCODE_USE_LEGACY_WATCH']) { -// try { -// watch = require('./watch-nsfw'); -// } catch (err) { -// console.warn('Could not load our cross platform file watcher: ' + err.toString()); -// console.warn('Falling back to our platform specific watcher...'); -// } -// } - if (!watch) { watch = process.platform === 'win32' ? require('./watch-win32') : require('gulp-watch'); } diff --git a/build/lib/watch/package.json b/build/lib/watch/package.json index b10e8ed2727..0d031340153 100644 --- a/build/lib/watch/package.json +++ b/build/lib/watch/package.json @@ -5,7 +5,6 @@ "author": "Microsoft ", "private": true, "devDependencies": { - "gulp-watch": "^4.3.9", - "nsfw": "^1.0.15" + "gulp-watch": "^4.3.9" } } diff --git a/build/lib/watch/watch-nsfw.js b/build/lib/watch/watch-nsfw.js deleted file mode 100644 index fb2b2758d02..00000000000 --- a/build/lib/watch/watch-nsfw.js +++ /dev/null @@ -1,94 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the MIT License. See License.txt in the project root for license information. - *--------------------------------------------------------------------------------------------*/ - -var nsfw = require('nsfw'); -var path = require('path'); -var fs = require('fs'); -var File = require('vinyl'); -var es = require('event-stream'); -var filter = require('gulp-filter'); - -function toChangeType(type) { - switch (type) { - case 0: return 'add'; - case 1: return 'unlink'; - case 2: return 'change'; - } -} - -function watch(root) { - var result = es.through(); - - function handleEvent(path, type) { - if (/[/\\].git[/\\]/.test(path) || /[/\\]out[/\\]/.test(path)) { - return; // filter as early as possible - } - - var file = new File({ - path: path, - base: root - }); - //@ts-ignore - file.event = type; - result.emit('data', file); - } - - nsfw(root, function (events) { - for (var i = 0; i < events.length; i++) { - var e = events[i]; - var changeType = e.action; - - if (changeType === 3 /* RENAMED */) { - handleEvent(path.join(e.directory, e.oldFile), 'unlink'); - handleEvent(path.join(e.directory, e.newFile), 'add'); - } else { - handleEvent(path.join(e.directory, e.file), toChangeType(changeType)); - } - } - }).then(function (watcher) { - watcher.start(); - }); - - return result; -} - -var cache = Object.create(null); - -module.exports = function (pattern, options) { - options = options || {}; - - var cwd = path.normalize(options.cwd || process.cwd()); - var watcher = cache[cwd]; - - if (!watcher) { - watcher = cache[cwd] = watch(cwd); - } - - var rebase = !options.base ? es.through() : es.mapSync(function (f) { - f.base = options.base; - return f; - }); - - return watcher - .pipe(filter(['**', '!.git{,/**}'])) // ignore all things git - .pipe(filter(pattern)) - .pipe(es.map(function (file, cb) { - fs.stat(file.path, function (err, stat) { - if (err && err.code === 'ENOENT') { return cb(null, file); } - if (err) { return cb(); } - if (!stat.isFile()) { return cb(); } - - fs.readFile(file.path, function (err, contents) { - if (err && err.code === 'ENOENT') { return cb(null, file); } - if (err) { return cb(); } - - file.contents = contents; - file.stat = stat; - cb(null, file); - }); - }); - })) - .pipe(rebase); -}; \ No newline at end of file diff --git a/build/lib/watch/yarn.lock b/build/lib/watch/yarn.lock index 0b4d3f70bb7..4fb4b56c0f6 100644 --- a/build/lib/watch/yarn.lock +++ b/build/lib/watch/yarn.lock @@ -61,10 +61,6 @@ array-unique@^0.2.1: version "0.2.1" resolved "https://registry.yarnpkg.com/array-unique/-/array-unique-0.2.1.tgz#a1d97ccafcbc2625cc70fadceb36a50c58b01a53" -asap@~2.0.3: - version "2.0.6" - resolved "https://registry.yarnpkg.com/asap/-/asap-2.0.6.tgz#e50347611d7e690943208bbdafebcbc2fb866d46" - asn1@~0.2.3: version "0.2.3" resolved "https://registry.yarnpkg.com/asn1/-/asn1-0.2.3.tgz#dac8787713c9966849fc8180777ebe9c1ddf3b86" @@ -330,16 +326,6 @@ form-data@~2.1.1: combined-stream "^1.0.5" mime-types "^2.1.12" -fs-extra@^0.26.5: - version "0.26.7" - resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-0.26.7.tgz#9ae1fdd94897798edab76d0918cf42d0c3184fa9" - dependencies: - graceful-fs "^4.1.2" - jsonfile "^2.1.0" - klaw "^1.0.0" - path-is-absolute "^1.0.0" - rimraf "^2.2.8" - fs.realpath@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" @@ -424,7 +410,7 @@ glogg@^1.0.0: dependencies: sparkles "^1.0.0" -graceful-fs@^4.1.2, graceful-fs@^4.1.6, graceful-fs@^4.1.9: +graceful-fs@^4.1.2: version "4.1.11" resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.1.11.tgz#0e8bdfe4d1ddb8854d64e04ea7c00e2a026e5658" @@ -649,12 +635,6 @@ json-stringify-safe@~5.0.1: version "5.0.1" resolved "https://registry.yarnpkg.com/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz#1296a2d58fd45f19a0f6ce01d65701e2c735b6eb" -jsonfile@^2.1.0: - version "2.4.0" - resolved "https://registry.yarnpkg.com/jsonfile/-/jsonfile-2.4.0.tgz#3736a2b428b87bbda0cc83b53fa3d633a35c2ae8" - optionalDependencies: - graceful-fs "^4.1.6" - jsonify@~0.0.0: version "0.0.0" resolved "https://registry.yarnpkg.com/jsonify/-/jsonify-0.0.0.tgz#2c74b6ee41d93ca51b7b5aaee8f503631d252a73" @@ -680,12 +660,6 @@ kind-of@^4.0.0: dependencies: is-buffer "^1.1.5" -klaw@^1.0.0: - version "1.3.1" - resolved "https://registry.yarnpkg.com/klaw/-/klaw-1.3.1.tgz#4088433b46b3b1ba259d78785d8e96f73ba02439" - optionalDependencies: - graceful-fs "^4.1.9" - lodash._basecopy@^3.0.0: version "3.0.1" resolved "https://registry.yarnpkg.com/lodash._basecopy/-/lodash._basecopy-3.0.1.tgz#8da0e6a876cf344c0ad8a54882111dd3c5c7ca36" @@ -736,14 +710,6 @@ lodash.isarray@^3.0.0: version "3.0.4" resolved "https://registry.yarnpkg.com/lodash.isarray/-/lodash.isarray-3.0.4.tgz#79e4eb88c36a8122af86f844aa9bcd851b5fbb55" -lodash.isinteger@^4.0.4: - version "4.0.4" - resolved "https://registry.yarnpkg.com/lodash.isinteger/-/lodash.isinteger-4.0.4.tgz#619c0af3d03f8b04c31f5882840b77b11cd68343" - -lodash.isundefined@^3.0.1: - version "3.0.1" - resolved "https://registry.yarnpkg.com/lodash.isundefined/-/lodash.isundefined-3.0.1.tgz#23ef3d9535565203a66cefd5b830f848911afb48" - lodash.keys@^3.0.0: version "3.1.2" resolved "https://registry.yarnpkg.com/lodash.keys/-/lodash.keys-3.1.2.tgz#4dbc0472b156be50a0b286855d1bd0b0c656098a" @@ -835,7 +801,7 @@ multipipe@^0.1.2: dependencies: duplexer2 "0.0.2" -nan@^2.0.0, nan@^2.3.0: +nan@^2.3.0: version "2.7.0" resolved "https://registry.yarnpkg.com/nan/-/nan-2.7.0.tgz#d95bf721ec877e08db276ed3fc6eb78f9083ad46" @@ -855,12 +821,6 @@ node-pre-gyp@^0.6.39: tar "^2.2.1" tar-pack "^3.4.0" -nodegit-promise@~4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/nodegit-promise/-/nodegit-promise-4.0.0.tgz#5722b184f2df7327161064a791d2e842c9167b34" - dependencies: - asap "~2.0.3" - nopt@^4.0.1: version "4.0.1" resolved "https://registry.yarnpkg.com/nopt/-/nopt-4.0.1.tgz#d0d4685afd5415193c8c7505602d0d17cd64474d" @@ -883,16 +843,6 @@ npmlog@^4.0.2: gauge "~2.7.3" set-blocking "~2.0.0" -nsfw@^1.0.15: - version "1.0.16" - resolved "https://registry.yarnpkg.com/nsfw/-/nsfw-1.0.16.tgz#78ba3e7f513b53d160c221b9018e0baf108614cc" - dependencies: - fs-extra "^0.26.5" - lodash.isinteger "^4.0.4" - lodash.isundefined "^3.0.1" - nan "^2.0.0" - promisify-node "^0.3.0" - number-is-nan@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/number-is-nan/-/number-is-nan-1.0.1.tgz#097b602b53422a522c1afb8790318336941a011d" @@ -980,12 +930,6 @@ process-nextick-args@~1.0.6: version "1.0.7" resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-1.0.7.tgz#150e20b756590ad3f91093f25a4f2ad8bff30ba3" -promisify-node@^0.3.0: - version "0.3.0" - resolved "https://registry.yarnpkg.com/promisify-node/-/promisify-node-0.3.0.tgz#b4b55acf90faa7d2b8b90ca396899086c03060cf" - dependencies: - nodegit-promise "~4.0.0" - punycode@^1.4.1: version "1.4.1" resolved "https://registry.yarnpkg.com/punycode/-/punycode-1.4.1.tgz#c0d5a63b2718800ad8e1eb0fa5269c84dd41845e" @@ -1089,7 +1033,7 @@ request@2.81.0: tunnel-agent "^0.6.0" uuid "^3.0.0" -rimraf@2, rimraf@^2.2.8, rimraf@^2.5.1, rimraf@^2.6.1: +rimraf@2, rimraf@^2.5.1, rimraf@^2.6.1: version "2.6.2" resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.6.2.tgz#2ed8150d24a16ea8651e6d6ef0f47c4158ce7a36" dependencies: From 8daf1f2366f400d5d3906b461f4ee9e8736c1047 Mon Sep 17 00:00:00 2001 From: Christof Marti Date: Fri, 10 Aug 2018 15:04:27 +0200 Subject: [PATCH 0674/1276] Use QuickInput (#29096) --- .../browser/parts/quickopen/quickOpenController.ts | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/src/vs/workbench/browser/parts/quickopen/quickOpenController.ts b/src/vs/workbench/browser/parts/quickopen/quickOpenController.ts index 5ae172239da..8bd9614ba75 100644 --- a/src/vs/workbench/browser/parts/quickopen/quickOpenController.ts +++ b/src/vs/workbench/browser/parts/quickopen/quickOpenController.ts @@ -57,6 +57,7 @@ import { IEditorService, ACTIVE_GROUP, SIDE_GROUP } from 'vs/workbench/services/ import { IEditorGroupsService } from 'vs/workbench/services/group/common/editorGroupsService'; import { IUriDisplayService } from 'vs/platform/uriDisplay/common/uriDisplay'; import { isThenable, timeout } from 'vs/base/common/async'; +import { IQuickInputService, IQuickPickItem } from 'vs/platform/quickinput/common/quickInput'; const HELP_PREFIX = '?'; @@ -1251,7 +1252,9 @@ export class RemoveFromEditorHistoryAction extends Action { constructor( id: string, label: string, - @IQuickOpenService private quickOpenService: IQuickOpenService, + @IQuickInputService private quickInputService: IQuickInputService, + @IModelService private modelService: IModelService, + @IModeService private modeService: IModeService, @IInstantiationService private instantiationService: IInstantiationService, @IHistoryService private historyService: IHistoryService ) { @@ -1259,7 +1262,7 @@ export class RemoveFromEditorHistoryAction extends Action { } run(): TPromise { - interface IHistoryPickEntry extends IFilePickOpenEntry { + interface IHistoryPickEntry extends IQuickPickItem { input: IEditorInput | IResourceInput; } @@ -1269,13 +1272,13 @@ export class RemoveFromEditorHistoryAction extends Action { return { input: h, - resource: entry.getResource(), + iconClasses: getIconClasses(this.modelService, this.modeService, entry.getResource()), label: entry.getLabel(), description: entry.getDescription() }; }); - return this.quickOpenService.pick(picks, { placeHolder: nls.localize('pickHistory', "Select an editor entry to remove from history"), autoFocus: { autoFocusFirstEntry: true }, matchOnDescription: true }).then(pick => { + return this.quickInputService.pick(picks, { placeHolder: nls.localize('pickHistory', "Select an editor entry to remove from history"), matchOnDescription: true }).then(pick => { if (pick) { this.historyService.remove(pick.input); } From e34098dee3cbf4b8acdae47e798c331924d184c8 Mon Sep 17 00:00:00 2001 From: Joao Moreno Date: Fri, 10 Aug 2018 14:24:23 +0200 Subject: [PATCH 0675/1276] remove promise.cancel from treeView related to #56137 --- src/vs/base/parts/tree/browser/treeView.ts | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/vs/base/parts/tree/browser/treeView.ts b/src/vs/base/parts/tree/browser/treeView.ts index bb125f1c905..d9e1f612471 100644 --- a/src/vs/base/parts/tree/browser/treeView.ts +++ b/src/vs/base/parts/tree/browser/treeView.ts @@ -25,7 +25,7 @@ import { KeyCode } from 'vs/base/common/keyCodes'; import { Event, Emitter } from 'vs/base/common/event'; import { DataTransfers } from 'vs/base/browser/dnd'; import { DefaultTreestyler } from './treeDefaults'; -import { Delayer } from 'vs/base/common/async'; +import { Delayer, CancelablePromise, createCancelablePromise, wireCancellationToken } from 'vs/base/common/async'; export interface IRow { element: HTMLElement; @@ -429,7 +429,7 @@ export class TreeView extends HeightMap { private currentDropTarget: ViewItem; private shouldInvalidateDropReaction: boolean; private currentDropTargets: ViewItem[]; - private currentDropPromise: WinJS.Promise; + private currentDropPromise: CancelablePromise; private dragAndDropScrollInterval: number; private dragAndDropScrollTimeout: number; private dragAndDropMouseY: number; @@ -1530,9 +1530,11 @@ export class TreeView extends HeightMap { } if (reaction.autoExpand) { - this.currentDropPromise = WinJS.TPromise.timeout(500) + const promise = WinJS.TPromise.timeout(500) .then(() => this.context.tree.expand(this.currentDropElement)) .then(() => this.shouldInvalidateDropReaction = true); + + this.currentDropPromise = createCancelablePromise(token => wireCancellationToken(token, promise)); } } } From b3ae767998afa508caf48a55ccb637a5e5047f3e Mon Sep 17 00:00:00 2001 From: Joao Moreno Date: Fri, 10 Aug 2018 15:10:54 +0200 Subject: [PATCH 0676/1276] remove cancel calls from cache, extension editor related to #56137 --- src/vs/base/common/cache.ts | 30 ++++--- src/vs/base/test/common/cache.test.ts | 26 +++--- .../electron-browser/extensionEditor.ts | 84 +++++++++---------- 3 files changed, 75 insertions(+), 65 deletions(-) diff --git a/src/vs/base/common/cache.ts b/src/vs/base/common/cache.ts index 65c468842ce..68dbbfe3845 100644 --- a/src/vs/base/common/cache.ts +++ b/src/vs/base/common/cache.ts @@ -5,25 +5,33 @@ 'use strict'; -import { TPromise } from 'vs/base/common/winjs.base'; +import { CancelablePromise } from 'vs/base/common/async'; + +export interface CacheResult { + promise: Thenable; + dispose(): void; +} export default class Cache { - private promise: TPromise = null; - constructor(private task: () => TPromise) { } + private result: CacheResult = null; + constructor(private task: () => CancelablePromise) { } - get(): TPromise { - if (this.promise) { - return this.promise; + get(): CacheResult { + if (this.result) { + return this.result; } const promise = this.task(); - this.promise = new TPromise((c, e) => promise.done(c, e), () => { - this.promise = null; - promise.cancel(); - }); + this.result = { + promise, + dispose: () => { + this.result = null; + promise.cancel(); + } + }; - return this.promise; + return this.result; } } diff --git a/src/vs/base/test/common/cache.test.ts b/src/vs/base/test/common/cache.test.ts index c7bab09abd0..f27a4253a0e 100644 --- a/src/vs/base/test/common/cache.test.ts +++ b/src/vs/base/test/common/cache.test.ts @@ -8,26 +8,27 @@ import * as assert from 'assert'; import Cache from 'vs/base/common/cache'; import { TPromise } from 'vs/base/common/winjs.base'; +import { createCancelablePromise, wireCancellationToken } from 'vs/base/common/async'; suite('Cache', () => { test('simple value', () => { let counter = 0; - const cache = new Cache(() => TPromise.as(counter++)); + const cache = new Cache(() => createCancelablePromise(_ => TPromise.as(counter++))); - return cache.get() + return cache.get().promise .then(c => assert.equal(c, 0), () => assert.fail('Unexpected assertion error')) - .then(() => cache.get()) + .then(() => cache.get().promise) .then(c => assert.equal(c, 0), () => assert.fail('Unexpected assertion error')); }); test('simple error', () => { let counter = 0; - const cache = new Cache(() => TPromise.wrapError(new Error(String(counter++)))); + const cache = new Cache(() => createCancelablePromise(_ => TPromise.wrapError(new Error(String(counter++))))); - return cache.get() + return cache.get().promise .then(() => assert.fail('Unexpected assertion error'), err => assert.equal(err.message, 0)) - .then(() => cache.get()) + .then(() => cache.get().promise) .then(() => assert.fail('Unexpected assertion error'), err => assert.equal(err.message, 0)); }); @@ -36,28 +37,29 @@ suite('Cache', () => { const cache = new Cache(() => { counter1++; - return TPromise.timeout(1).then(() => counter2++); + return createCancelablePromise(token => wireCancellationToken(token, TPromise.timeout(1).then(() => counter2++))); }); assert.equal(counter1, 0); assert.equal(counter2, 0); - let promise = cache.get(); + let result = cache.get(); assert.equal(counter1, 1); assert.equal(counter2, 0); - promise.cancel(); + result.promise.then(null, () => assert(true)); + result.dispose(); assert.equal(counter1, 1); assert.equal(counter2, 0); - promise = cache.get(); + result = cache.get(); assert.equal(counter1, 2); assert.equal(counter2, 0); - return promise + return result.promise .then(c => { assert.equal(counter1, 2); assert.equal(counter2, 1); }) - .then(() => cache.get()) + .then(() => cache.get().promise) .then(c => { assert.equal(counter1, 2); assert.equal(counter2, 1); diff --git a/src/vs/workbench/parts/extensions/electron-browser/extensionEditor.ts b/src/vs/workbench/parts/extensions/electron-browser/extensionEditor.ts index 4f850fe16ea..4b0c0b54bba 100644 --- a/src/vs/workbench/parts/extensions/electron-browser/extensionEditor.ts +++ b/src/vs/workbench/parts/extensions/electron-browser/extensionEditor.ts @@ -9,11 +9,11 @@ import 'vs/css!./media/extensionEditor'; import { localize } from 'vs/nls'; import { TPromise, Promise } from 'vs/base/common/winjs.base'; import { marked } from 'vs/base/common/marked/marked'; -import { always } from 'vs/base/common/async'; +import { createCancelablePromise, wireCancellationToken } from 'vs/base/common/async'; import * as arrays from 'vs/base/common/arrays'; import { OS } from 'vs/base/common/platform'; import { Event, Emitter, once, chain } from 'vs/base/common/event'; -import Cache from 'vs/base/common/cache'; +import Cache, { CacheResult } from 'vs/base/common/cache'; import { Action } from 'vs/base/common/actions'; import { isPromiseCanceledError } from 'vs/base/common/errors'; import { IDisposable, dispose, toDisposable } from 'vs/base/common/lifecycle'; @@ -290,10 +290,10 @@ export class ExtensionEditor extends BaseEditor { this.transientDisposables = dispose(this.transientDisposables); - this.extensionReadme = new Cache(() => extension.getReadme()); - this.extensionChangelog = new Cache(() => extension.getChangelog()); - this.extensionManifest = new Cache(() => extension.getManifest()); - this.extensionDependencies = new Cache(() => this.extensionsWorkbenchService.loadDependencies(extension)); + this.extensionReadme = new Cache(() => createCancelablePromise(token => wireCancellationToken(token, extension.getReadme()))); + this.extensionChangelog = new Cache(() => createCancelablePromise(token => wireCancellationToken(token, extension.getChangelog()))); + this.extensionManifest = new Cache(() => createCancelablePromise(token => wireCancellationToken(token, extension.getManifest()))); + this.extensionDependencies = new Cache(() => createCancelablePromise(token => wireCancellationToken(token, this.extensionsWorkbenchService.loadDependencies(extension)))); const onError = once(domEvent(this.icon, 'error')); onError(() => this.icon.src = extension.iconUrlFallback, null, this.transientDisposables); @@ -429,6 +429,7 @@ export class ExtensionEditor extends BaseEditor { this.navbar.push(NavbarSection.Readme, localize('details', "Details"), localize('detailstooltip', "Extension details, rendered from the extension's 'README.md' file")); } this.extensionManifest.get() + .promise .then(manifest => { if (extension.extensionPack.length) { this.navbar.push(NavbarSection.ExtensionPack, localize('extensionPack', "Extension Pack"), localize('extensionsPack', "Set of extensions that can be installed together")); @@ -479,8 +480,8 @@ export class ExtensionEditor extends BaseEditor { } } - private openMarkdown(content: TPromise, noContentCopy: string) { - return this.loadContents(() => content + private openMarkdown(cacheResult: CacheResult, noContentCopy: string): void { + this.loadContents(() => cacheResult) .then(marked.parse) .then(renderBody) .then(removeEmbeddedSVGs) @@ -507,19 +508,19 @@ export class ExtensionEditor extends BaseEditor { .then(null, () => { const p = append(this.content, $('p.nocontent')); p.textContent = noContentCopy; - })); + }); } - private openReadme() { - return this.openMarkdown(this.extensionReadme.get(), localize('noReadme', "No README available.")); + private openReadme(): void { + this.openMarkdown(this.extensionReadme.get(), localize('noReadme', "No README available.")); } - private openChangelog() { - return this.openMarkdown(this.extensionChangelog.get(), localize('noChangelog', "No Changelog available.")); + private openChangelog(): void { + this.openMarkdown(this.extensionChangelog.get(), localize('noChangelog', "No Changelog available.")); } - private openContributions() { - return this.loadContents(() => this.extensionManifest.get() + private openContributions(): void { + this.loadContents(() => this.extensionManifest.get()) .then(manifest => { const content = $('div', { class: 'subcontent' }); const scrollableContent = new DomScrollableElement(content, {}); @@ -554,17 +555,17 @@ export class ExtensionEditor extends BaseEditor { } }, () => { append(this.content, $('p.nocontent')).textContent = localize('noContributions', "No Contributions"); - })); + }); } - private openDependencies(extension: IExtension) { + private openDependencies(extension: IExtension): void { if (extension.dependencies.length === 0) { append(this.content, $('p.nocontent')).textContent = localize('noDependencies', "No Dependencies"); return; } - return this.loadContents(() => { - return this.extensionDependencies.get().then(extensionDependencies => { + this.loadContents(() => this.extensionDependencies.get()) + .then(extensionDependencies => { const content = $('div', { class: 'subcontent' }); const scrollableContent = new DomScrollableElement(content, {}); append(this.content, scrollableContent.getDomNode()); @@ -585,7 +586,6 @@ export class ExtensionEditor extends BaseEditor { append(this.content, $('p.nocontent')).textContent = error; this.notificationService.error(error); }); - }); } private renderDependencies(container: HTMLElement, extensionDependencies: IExtensionDependencies): Tree { @@ -617,26 +617,23 @@ export class ExtensionEditor extends BaseEditor { return this.instantiationService.createInstance(ExtensionsTree, new ExtensionData(extensionDependencies), container); } - private openExtensionPack(extension: IExtension) { - return this.loadContents(() => { - const content = $('div', { class: 'subcontent' }); - const scrollableContent = new DomScrollableElement(content, {}); - append(this.content, scrollableContent.getDomNode()); - this.contentDisposables.push(scrollableContent); + private openExtensionPack(extension: IExtension): void { + const content = $('div', { class: 'subcontent' }); + const scrollableContent = new DomScrollableElement(content, {}); + append(this.content, scrollableContent.getDomNode()); + this.contentDisposables.push(scrollableContent); - const dependenciesTree = this.renderExtensionPack(content, extension); - const layout = () => { - scrollableContent.scanDomNode(); - const scrollDimensions = scrollableContent.getScrollDimensions(); - dependenciesTree.layout(scrollDimensions.height); - }; - const removeLayoutParticipant = arrays.insert(this.layoutParticipants, { layout }); - this.contentDisposables.push(toDisposable(removeLayoutParticipant)); - - this.contentDisposables.push(dependenciesTree); + const dependenciesTree = this.renderExtensionPack(content, extension); + const layout = () => { scrollableContent.scanDomNode(); - return TPromise.as(null); - }); + const scrollDimensions = scrollableContent.getScrollDimensions(); + dependenciesTree.layout(scrollDimensions.height); + }; + const removeLayoutParticipant = arrays.insert(this.layoutParticipants, { layout }); + this.contentDisposables.push(toDisposable(removeLayoutParticipant)); + + this.contentDisposables.push(dependenciesTree); + scrollableContent.scanDomNode(); } private renderExtensionPack(container: HTMLElement, extension: IExtension): Tree { @@ -1073,13 +1070,16 @@ export class ExtensionEditor extends BaseEditor { return this.keybindingService.resolveKeybinding(keyBinding)[0]; } - private loadContents(loadingTask: () => TPromise): void { + private loadContents(loadingTask: () => CacheResult): Thenable { addClass(this.content, 'loading'); - let promise = loadingTask(); - promise = always(promise, () => removeClass(this.content, 'loading')); + const result = loadingTask(); + const onDone = () => removeClass(this.content, 'loading'); + result.promise.then(onDone, onDone); - this.contentDisposables.push(toDisposable(() => promise.cancel())); + this.contentDisposables.push(toDisposable(() => result.dispose())); + + return result.promise; } layout(): void { From 4c71656f5d89929ebb3d5174d568e7a9c28af21a Mon Sep 17 00:00:00 2001 From: Christof Marti Date: Fri, 10 Aug 2018 15:28:46 +0200 Subject: [PATCH 0677/1276] Remove dead code (#29096) --- src/vs/platform/quickOpen/common/quickOpen.ts | 99 +--- .../parts/quickopen/quickOpenController.ts | 541 ++---------------- .../workbench/test/browser/quickopen.test.ts | 4 - 3 files changed, 34 insertions(+), 610 deletions(-) diff --git a/src/vs/platform/quickOpen/common/quickOpen.ts b/src/vs/platform/quickOpen/common/quickOpen.ts index 6a9b847fc09..b0b91b9e1b4 100644 --- a/src/vs/platform/quickOpen/common/quickOpen.ts +++ b/src/vs/platform/quickOpen/common/quickOpen.ts @@ -5,94 +5,9 @@ 'use strict'; import { TPromise } from 'vs/base/common/winjs.base'; -import uri from 'vs/base/common/uri'; import { Event } from 'vs/base/common/event'; -import { CancellationToken } from 'vs/base/common/cancellation'; -import { IQuickNavigateConfiguration, IAutoFocus, IEntryRunContext } from 'vs/base/parts/quickopen/common/quickOpen'; +import { IQuickNavigateConfiguration, IAutoFocus } from 'vs/base/parts/quickopen/common/quickOpen'; import { createDecorator } from 'vs/platform/instantiation/common/instantiation'; -import { IAction } from 'vs/base/common/actions'; -import { FileKind } from 'vs/platform/files/common/files'; - -export interface IFilePickOpenEntry extends IPickOpenEntry { - resource: uri; - fileKind?: FileKind; -} - -export interface IPickOpenAction extends IAction { - run(item: IPickOpenItem): TPromise; -} - -export interface IPickOpenEntry { - id?: string; - label: string; - description?: string; - detail?: string; - tooltip?: string; - separator?: ISeparator; - alwaysShow?: boolean; - run?: (context: IEntryRunContext) => void; - action?: IAction; - payload?: any; -} - -export interface IPickOpenItem { - index: number; - remove: () => void; - getId: () => string; - getResource: () => uri; - getPayload: () => any; -} - -export interface ISeparator { - border?: boolean; - label?: string; -} - -export interface IPickOptions { - - /** - * an optional string to show as place holder in the input box to guide the user what she picks on - */ - placeHolder?: string; - - /** - * optional auto focus settings - */ - autoFocus?: IAutoFocus; - - /** - * an optional flag to include the description when filtering the picks - */ - matchOnDescription?: boolean; - - /** - * an optional flag to include the detail when filtering the picks - */ - matchOnDetail?: boolean; - - /** - * an optional flag to not close the picker on focus lost - */ - ignoreFocusLost?: boolean; - - /** - * enables quick navigate in the picker to open an element without typing - */ - quickNavigateConfiguration?: IQuickNavigateConfiguration; - - /** - * a context key to set when this picker is active - */ - contextKey?: string; -} - -export interface IStringPickOptions extends IPickOptions { - onDidFocus?: (item: string) => void; -} - -export interface ITypedPickOptions extends IPickOptions { - onDidFocus?: (entry: T) => void; -} export interface IShowOptions { quickNavigateConfiguration?: IQuickNavigateConfiguration; @@ -115,18 +30,6 @@ export interface IQuickOpenService { */ show(prefix?: string, options?: IShowOptions): TPromise; - /** - * A convenient way to bring up quick open as a picker with custom elements. This bypasses the quick open handler - * registry and just leverages the quick open widget to select any kind of entries. - * - * Passing in a promise will allow you to resolve the elements in the background while quick open will show a - * progress bar spinning. - */ - pick(picks: TPromise, options?: IStringPickOptions, token?: CancellationToken): TPromise; - pick(picks: TPromise, options?: ITypedPickOptions, token?: CancellationToken): TPromise; - pick(picks: string[], options?: IStringPickOptions, token?: CancellationToken): TPromise; - pick(picks: T[], options?: ITypedPickOptions, token?: CancellationToken): TPromise; - /** * Allows to navigate from the outside in an opened picker. */ diff --git a/src/vs/workbench/browser/parts/quickopen/quickOpenController.ts b/src/vs/workbench/browser/parts/quickopen/quickOpenController.ts index 8bd9614ba75..7a0183bffff 100644 --- a/src/vs/workbench/browser/parts/quickopen/quickOpenController.ts +++ b/src/vs/workbench/browser/parts/quickopen/quickOpenController.ts @@ -14,11 +14,10 @@ import URI from 'vs/base/common/uri'; import * as resources from 'vs/base/common/resources'; import { defaultGenerator } from 'vs/base/common/idGenerator'; import * as types from 'vs/base/common/types'; -import { Action, IAction } from 'vs/base/common/actions'; +import { Action } from 'vs/base/common/actions'; import { IIconLabelValueOptions } from 'vs/base/browser/ui/iconLabel/iconLabel'; -import { CancellationToken } from 'vs/base/common/cancellation'; import { Mode, IEntryRunContext, IAutoFocus, IQuickNavigateConfiguration, IModel } from 'vs/base/parts/quickopen/common/quickOpen'; -import { QuickOpenEntry, QuickOpenModel, QuickOpenEntryGroup, compareEntries, QuickOpenItemAccessorClass } from 'vs/base/parts/quickopen/browser/quickOpenModel'; +import { QuickOpenEntry, QuickOpenModel, QuickOpenEntryGroup, QuickOpenItemAccessorClass } from 'vs/base/parts/quickopen/browser/quickOpenModel'; import { QuickOpenWidget, HideReason } from 'vs/base/parts/quickopen/browser/quickOpenWidget'; import { ContributableActionProvider } from 'vs/workbench/browser/actions'; import { ITextFileService, AutoSaveMode } from 'vs/workbench/services/textfile/common/textfiles'; @@ -33,7 +32,7 @@ import { Event, Emitter } from 'vs/base/common/event'; import { IPartService } from 'vs/workbench/services/part/common/partService'; import { QuickOpenHandler, QuickOpenHandlerDescriptor, IQuickOpenRegistry, Extensions, EditorQuickOpenEntry, CLOSE_ON_FOCUS_LOST_CONFIG } from 'vs/workbench/browser/quickopen'; import * as errors from 'vs/base/common/errors'; -import { IPickOpenEntry, IFilePickOpenEntry, IQuickOpenService, IShowOptions, IPickOpenItem, IStringPickOptions, ITypedPickOptions } from 'vs/platform/quickOpen/common/quickOpen'; +import { IQuickOpenService, IShowOptions } from 'vs/platform/quickOpen/common/quickOpen'; import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; import { IContextKeyService, RawContextKey, IContextKey } from 'vs/platform/contextkey/common/contextkey'; @@ -42,41 +41,20 @@ import { IThemeService } from 'vs/platform/theme/common/themeService'; import { SIDE_BAR_BACKGROUND, SIDE_BAR_FOREGROUND } from 'vs/workbench/common/theme'; import { attachQuickOpenStyler } from 'vs/platform/theme/common/styler'; import { IEnvironmentService } from 'vs/platform/environment/common/environment'; -import { ITree, IActionProvider } from 'vs/base/parts/tree/browser/tree'; -import { BaseActionItem } from 'vs/base/browser/ui/actionbar/actionbar'; -import { FileKind, IFileService } from 'vs/platform/files/common/files'; +import { IFileService } from 'vs/platform/files/common/files'; import { scoreItem, ScorerCache, compareItemsByScore, prepareQuery } from 'vs/base/parts/quickopen/common/quickOpenScorer'; import { WorkbenchTree } from 'vs/platform/list/browser/listService'; -import { matchesFuzzyOcticonAware, parseOcticons, IParsedOcticons } from 'vs/base/common/octicon'; -import { IMatch } from 'vs/base/common/filters'; import { Schemas } from 'vs/base/common/network'; -import Severity from 'vs/base/common/severity'; import { INotificationService } from 'vs/platform/notification/common/notification'; import { Dimension, addClass } from 'vs/base/browser/dom'; import { IEditorService, ACTIVE_GROUP, SIDE_GROUP } from 'vs/workbench/services/editor/common/editorService'; import { IEditorGroupsService } from 'vs/workbench/services/group/common/editorGroupsService'; import { IUriDisplayService } from 'vs/platform/uriDisplay/common/uriDisplay'; -import { isThenable, timeout } from 'vs/base/common/async'; +import { timeout } from 'vs/base/common/async'; import { IQuickInputService, IQuickPickItem } from 'vs/platform/quickinput/common/quickInput'; const HELP_PREFIX = '?'; -interface IInternalPickOptions { - contextKey?: string; - value?: string; - valueSelection?: [number, number]; - placeHolder?: string; - inputDecoration?: Severity; - password?: boolean; - autoFocus?: IAutoFocus; - matchOnDescription?: boolean; - matchOnDetail?: boolean; - ignoreFocusLost?: boolean; - quickNavigateConfiguration?: IQuickNavigateConfiguration; - onDidType?: (value: string) => any; - onDidFocus?: (item: any) => void; -} - export class QuickOpenController extends Component implements IQuickOpenService { private static readonly MAX_SHORT_RESPONSE_TIME = 500; @@ -91,13 +69,11 @@ export class QuickOpenController extends Component implements IQuickOpenService get onHide(): Event { return this._onHide.event; } private quickOpenWidget: QuickOpenWidget; - private pickOpenWidget: QuickOpenWidget; private layoutDimensions: Dimension; private mapResolvedHandlersToPrefix: { [prefix: string]: TPromise; } = Object.create(null); private mapContextKeyToContext: { [id: string]: IContextKey; } = Object.create(null); private handlerOnOpenCalled: { [prefix: string]: boolean; } = Object.create(null); private currentResultToken: string; - private currentPickerToken: string; private promisesToCompleteOnHide: ValueCallback[] = []; private previousActiveHandlerDescriptor: QuickOpenHandlerDescriptor; private actionProvider = new ContributableActionProvider(); @@ -124,7 +100,7 @@ export class QuickOpenController extends Component implements IQuickOpenService } private registerListeners(): void { - this._register(this.configurationService.onDidChangeConfiguration(e => this.updateConfiguration())); + this._register(this.configurationService.onDidChangeConfiguration(() => this.updateConfiguration())); this._register(this.partService.onTitleBarVisibilityChange(() => this.positionQuickOpenWidget())); this._register(browser.onDidChangeZoomLevel(() => this.positionQuickOpenWidget())); } @@ -141,295 +117,24 @@ export class QuickOpenController extends Component implements IQuickOpenService if (this.quickOpenWidget) { this.quickOpenWidget.navigate(next, quickNavigate); } - - if (this.pickOpenWidget) { - this.pickOpenWidget.navigate(next, quickNavigate); - } - } - - pick(picks: TPromise, options?: IStringPickOptions, token?: CancellationToken): TPromise; - pick(picks: TPromise, options?: ITypedPickOptions, token?: CancellationToken): TPromise; - pick(picks: string[], options?: IStringPickOptions, token?: CancellationToken): TPromise; - pick(picks: T[], options?: ITypedPickOptions, token?: CancellationToken): TPromise; - pick(arg1: string[] | TPromise | IPickOpenEntry[] | TPromise, options?: IStringPickOptions | ITypedPickOptions, token?: CancellationToken): TPromise { - if (!options) { - options = Object.create(null); - } - - let arrayPromise: TPromise; - if (Array.isArray(arg1)) { - arrayPromise = TPromise.as(arg1); - } else if (isThenable(arg1)) { - arrayPromise = arg1; - } else { - throw new Error('illegal input'); - } - - let isAboutStrings = false; - const entryPromise = arrayPromise.then(elements => { - return (>elements).map(element => { - if (typeof element === 'string') { - isAboutStrings = true; - - return { label: element }; - } else { - return element; - } - }); - }); - - if (this.pickOpenWidget && this.pickOpenWidget.isVisible()) { - this.pickOpenWidget.hide(HideReason.CANCELED); - } - - return new TPromise((resolve, reject) => { - - function onItem(item: IPickOpenEntry): string | IPickOpenEntry { - return item && isAboutStrings ? item.label : item; - } - - this.doPick(entryPromise, options, token).then(item => resolve(onItem(item)), err => reject(err)); - }); - } - - private doPick(picksPromise: TPromise, options: IInternalPickOptions, token: CancellationToken = CancellationToken.None): TPromise { - const autoFocus = options.autoFocus; - - // Use a generated token to avoid race conditions from long running promises - const currentPickerToken = defaultGenerator.nextId(); - this.currentPickerToken = currentPickerToken; - - // Update context - this.setQuickOpenContextKey(options.contextKey); - - // Create upon first open - if (!this.pickOpenWidget) { - this.pickOpenWidget = this._register(new QuickOpenWidget( - document.getElementById(this.partService.getWorkbenchElementId()), - { - onOk: () => { /* ignore, handle later */ }, - onCancel: () => { /* ignore, handle later */ }, - onType: (value: string) => { /* ignore, handle later */ }, - onShow: () => this.handleOnShow(true), - onHide: (reason) => this.handleOnHide(true, reason) - }, { - inputPlaceHolder: options.placeHolder || '', - keyboardSupport: false, - treeCreator: (container, config, opts) => this.instantiationService.createInstance(WorkbenchTree, container, config, opts) - } - )); - this._register(attachQuickOpenStyler(this.pickOpenWidget, this.themeService, { background: SIDE_BAR_BACKGROUND, foreground: SIDE_BAR_FOREGROUND })); - - const pickOpenContainer = this.pickOpenWidget.create(); - addClass(pickOpenContainer, 'show-file-icons'); - this.positionQuickOpenWidget(); - } - - // Update otherwise - else { - this.pickOpenWidget.setPlaceHolder(options.placeHolder || ''); - } - - // Respect input value - if (options.value) { - this.pickOpenWidget.setValue(options.value, options.valueSelection); - } - - // Respect password - this.pickOpenWidget.setPassword(options.password); - - // Input decoration - if (!types.isUndefinedOrNull(options.inputDecoration)) { - this.pickOpenWidget.showInputDecoration(options.inputDecoration); - } else { - this.pickOpenWidget.clearInputDecoration(); - } - - // Layout - if (this.layoutDimensions) { - this.pickOpenWidget.layout(this.layoutDimensions); - } - - return new TPromise((complete, error) => { - - // Detect cancellation while pick promise is loading - this.pickOpenWidget.setCallbacks({ - onCancel: () => { complete(void 0); }, - onOk: () => { /* ignore, handle later */ }, - onType: (value: string) => { /* ignore, handle later */ }, - }); - - // hide widget when being cancelled - token.onCancellationRequested(e => { - if (this.currentPickerToken === currentPickerToken) { - this.pickOpenWidget.hide(HideReason.CANCELED); - } - }); - - let picksPromiseDone = false; - - // Resolve picks - picksPromise.then(picks => { - if (this.currentPickerToken !== currentPickerToken) { - return complete(void 0); // Return as canceled if another request came after or user canceled - } - - picksPromiseDone = true; - - // Reset Progress - this.pickOpenWidget.getProgressBar().stop().hide(); - - // Model - const model = new QuickOpenModel([], new PickOpenActionProvider()); - const entries = picks.map((e, index) => { - const onPreview = () => { - if (options.onDidFocus) { - options.onDidFocus(e); - } - }; - return this.instantiationService.createInstance(PickOpenEntry, e, index, onPreview, () => this.pickOpenWidget.refresh()); - }); - if (picks.length === 0) { - entries.push(this.instantiationService.createInstance(PickOpenEntry, { label: nls.localize('emptyPicks', "There are no entries to pick from") }, 0, null, null)); - } - - model.setEntries(entries); - - // Handlers - const callbacks = { - onOk: () => { - if (picks.length === 0) { - return complete(null); - } - - let index = -1; - let context: IEntryRunContext; - entries.forEach(entry => { - if (entry.shouldRunWithContext) { - index = entry.index; - context = entry.shouldRunWithContext; - } - }); - - const selectedPick = picks[index]; - - if (selectedPick && typeof selectedPick.run === 'function') { - selectedPick.run(context); - } - - complete(selectedPick || null); - }, - onCancel: () => complete(void 0), - onFocusLost: () => !this.closeOnFocusLost || options.ignoreFocusLost, - onType: (value: string) => { - - // the caller takes care of all input - if (options.onDidType) { - options.onDidType(value); - return; - } - - if (picks.length === 0) { - return; - } - - value = value ? strings.trim(value) : value; - - // Reset filtering - if (!value) { - entries.forEach(e => { - e.setHighlights(null); - e.setHidden(false); - }); - } - - // Filter by value (since we support octicons, use octicon aware fuzzy matching) - else { - entries.forEach(entry => { - const { labelHighlights, descriptionHighlights, detailHighlights } = entry.matchesFuzzy(value, options); - - if (entry.shouldAlwaysShow() || labelHighlights || descriptionHighlights || detailHighlights) { - entry.setHighlights(labelHighlights, descriptionHighlights, detailHighlights); - entry.setHidden(false); - } else { - entry.setHighlights(null, null, null); - entry.setHidden(true); - } - }); - } - - // Sort by value - const normalizedSearchValue = value ? strings.stripWildcards(value.toLowerCase()) : value; - model.entries.sort((pickA: PickOpenEntry, pickB: PickOpenEntry) => { - if (!value) { - return pickA.index - pickB.index; // restore natural order - } - - return compareEntries(pickA, pickB, normalizedSearchValue); - }); - - this.pickOpenWidget.refresh(model, value ? { autoFocusFirstEntry: true } : autoFocus); - }, - onShow: () => this.handleOnShow(true), - onHide: (reason: HideReason) => this.handleOnHide(true, reason) - }; - this.pickOpenWidget.setCallbacks(callbacks); - - // Set input - if (!this.pickOpenWidget.isVisible()) { - this.pickOpenWidget.show(model, { autoFocus, quickNavigateConfiguration: options.quickNavigateConfiguration }); - } else { - this.pickOpenWidget.setInput(model, autoFocus); - } - - // The user might have typed something (or options.value was set) so we need to play back - // the input box value through our callbacks to filter the result accordingly. - const inputValue = this.pickOpenWidget.getInputBox().value; - if (inputValue) { - callbacks.onType(inputValue); - } - }, (err) => { - this.pickOpenWidget.hide(); - - error(err); - }); - - // Progress if task takes a long time - setTimeout(() => { - if (!picksPromiseDone && this.currentPickerToken === currentPickerToken) { - this.pickOpenWidget.getProgressBar().infinite().show(); - } - }, 800); - - // Show picker empty if resolving takes a while - if (!picksPromiseDone) { - this.pickOpenWidget.show(new QuickOpenModel()); - } - }); } accept(): void { - [this.quickOpenWidget, this.pickOpenWidget].forEach(w => { - if (w && w.isVisible()) { - w.accept(); - } - }); + if (this.quickOpenWidget.isVisible()) { + this.quickOpenWidget.accept(); + } } focus(): void { - [this.quickOpenWidget, this.pickOpenWidget].forEach(w => { - if (w && w.isVisible()) { - w.focus(); - } - }); + if (this.quickOpenWidget.isVisible()) { + this.quickOpenWidget.focus(); + } } close(): void { - [this.quickOpenWidget, this.pickOpenWidget].forEach(w => { - if (w && w.isVisible()) { - w.hide(HideReason.CANCELED); - } - }); + if (this.quickOpenWidget.isVisible()) { + this.quickOpenWidget.hide(HideReason.CANCELED); + } } private emitQuickOpenVisibilityChange(isVisible: boolean): void { @@ -464,8 +169,8 @@ export class QuickOpenController extends Component implements IQuickOpenService onOk: () => { /* ignore */ }, onCancel: () => { /* ignore */ }, onType: (value: string) => this.onType(value || ''), - onShow: () => this.handleOnShow(false), - onHide: (reason) => this.handleOnHide(false, reason), + onShow: () => this.handleOnShow(), + onHide: (reason) => this.handleOnHide(reason), onFocusLost: () => !this.closeOnFocusLost }, { inputPlaceHolder: this.hasHandler(HELP_PREFIX) ? nls.localize('quickOpenInput', "Type '?' to get help on the actions you can take from here") : '', @@ -527,42 +232,29 @@ export class QuickOpenController extends Component implements IQuickOpenService if (this.quickOpenWidget) { this.quickOpenWidget.getElement().style.top = `${titlebarOffset}px`; } - - if (this.pickOpenWidget) { - this.pickOpenWidget.getElement().style.top = `${titlebarOffset}px`; - } } - private handleOnShow(isPicker: boolean): void { - if (isPicker && this.quickOpenWidget) { - this.quickOpenWidget.hide(HideReason.FOCUS_LOST); - } else if (!isPicker && this.pickOpenWidget) { - this.pickOpenWidget.hide(HideReason.FOCUS_LOST); - } - + private handleOnShow(): void { this.emitQuickOpenVisibilityChange(true); } - private handleOnHide(isPicker: boolean, reason: HideReason): void { - if (!isPicker) { + private handleOnHide(reason: HideReason): void { + // Clear state + this.previousActiveHandlerDescriptor = null; - // Clear state - this.previousActiveHandlerDescriptor = null; + // Pass to handlers + for (let prefix in this.mapResolvedHandlersToPrefix) { + const promise = this.mapResolvedHandlersToPrefix[prefix]; + promise.then(handler => { + this.handlerOnOpenCalled[prefix] = false; - // Pass to handlers - for (let prefix in this.mapResolvedHandlersToPrefix) { - const promise = this.mapResolvedHandlersToPrefix[prefix]; - promise.then(handler => { - this.handlerOnOpenCalled[prefix] = false; + handler.onClose(reason === HideReason.CANCELED); // Don't check if onOpen was called to preserve old behaviour for now + }); + } - handler.onClose(reason === HideReason.CANCELED); // Don't check if onOpen was called to preserve old behaviour for now - }); - } - - // Complete promises that are waiting - while (this.promisesToCompleteOnHide.length) { - this.promisesToCompleteOnHide.pop()(true); - } + // Complete promises that are waiting + while (this.promisesToCompleteOnHide.length) { + this.promisesToCompleteOnHide.pop()(true); } if (reason !== HideReason.FOCUS_LOST) { @@ -883,10 +575,6 @@ export class QuickOpenController extends Component implements IQuickOpenService if (this.quickOpenWidget) { this.quickOpenWidget.layout(this.layoutDimensions); } - - if (this.pickOpenWidget) { - this.pickOpenWidget.layout(this.layoutDimensions); - } } } @@ -904,169 +592,6 @@ class PlaceholderQuickOpenEntry extends QuickOpenEntryGroup { } } -class PickOpenEntry extends PlaceholderQuickOpenEntry implements IPickOpenItem { - private _shouldRunWithContext: IEntryRunContext; - private description: string; - private detail: string; - private tooltip: string; - private descriptionTooltip: string; - private hasSeparator: boolean; - private separatorLabel: string; - private alwaysShow: boolean; - private resource: URI; - private fileKind: FileKind; - private _action: IAction; - private removed: boolean; - private payload: any; - private labelOcticons: IParsedOcticons; - private descriptionOcticons: IParsedOcticons; - private detailOcticons: IParsedOcticons; - - constructor( - item: IPickOpenEntry, - private _index: number, - private onPreview: () => void, - private onRemove: () => void, - @IModeService private modeService: IModeService, - @IModelService private modelService: IModelService - ) { - super(item.label); - - this.description = item.description; - this.detail = item.detail; - this.tooltip = item.tooltip; - this.descriptionOcticons = item.description ? parseOcticons(item.description) : void 0; - this.descriptionTooltip = this.descriptionOcticons ? this.descriptionOcticons.text : void 0; - this.hasSeparator = item.separator && item.separator.border; - this.separatorLabel = item.separator && item.separator.label; - this.alwaysShow = item.alwaysShow; - this._action = item.action; - this.payload = item.payload; - - const fileItem = item; - this.resource = fileItem.resource; - this.fileKind = fileItem.fileKind; - } - - matchesFuzzy(query: string, options: IInternalPickOptions): { labelHighlights: IMatch[], descriptionHighlights: IMatch[], detailHighlights: IMatch[] } { - if (!this.labelOcticons) { - this.labelOcticons = parseOcticons(this.getLabel()); // parse on demand - } - - const detail = this.getDetail(); - if (detail && options.matchOnDetail && !this.detailOcticons) { - this.detailOcticons = parseOcticons(detail); // parse on demand - } - - return { - labelHighlights: matchesFuzzyOcticonAware(query, this.labelOcticons), - descriptionHighlights: options.matchOnDescription && this.descriptionOcticons ? matchesFuzzyOcticonAware(query, this.descriptionOcticons) : void 0, - detailHighlights: options.matchOnDetail && this.detailOcticons ? matchesFuzzyOcticonAware(query, this.detailOcticons) : void 0 - }; - } - - getPayload(): any { - return this.payload; - } - - remove(): void { - super.setHidden(true); - this.removed = true; - - this.onRemove(); - } - - isHidden(): boolean { - return this.removed || super.isHidden(); - } - - get action(): IAction { - return this._action; - } - - get index(): number { - return this._index; - } - - getLabelOptions(): IIconLabelValueOptions { - return { - extraClasses: this.resource ? getIconClasses(this.modelService, this.modeService, this.resource, this.fileKind) : [] - }; - } - - get shouldRunWithContext(): IEntryRunContext { - return this._shouldRunWithContext; - } - - getDescription(): string { - return this.description; - } - - getDetail(): string { - return this.detail; - } - - getTooltip(): string { - return this.tooltip; - } - - getDescriptionTooltip(): string { - return this.descriptionTooltip; - } - - showBorder(): boolean { - return this.hasSeparator; - } - - getGroupLabel(): string { - return this.separatorLabel; - } - - shouldAlwaysShow(): boolean { - return this.alwaysShow; - } - - getResource(): URI { - return this.resource; - } - - run(mode: Mode, context: IEntryRunContext): boolean { - if (mode === Mode.OPEN) { - this._shouldRunWithContext = context; - - return true; - } - - if (mode === Mode.PREVIEW && this.onPreview) { - this.onPreview(); - } - - return false; - } -} - -class PickOpenActionProvider implements IActionProvider { - hasActions(tree: ITree, element: PickOpenEntry): boolean { - return !!element.action; - } - - getActions(tree: ITree, element: PickOpenEntry): TPromise { - return TPromise.as(element.action ? [element.action] : []); - } - - hasSecondaryActions(tree: ITree, element: PickOpenEntry): boolean { - return false; - } - - getSecondaryActions(tree: ITree, element: PickOpenEntry): TPromise { - return TPromise.as([]); - } - - getActionItem(tree: ITree, element: PickOpenEntry, action: Action): BaseActionItem { - return null; - } -} - class EditorHistoryHandler { private scorerCache: ScorerCache; @@ -1123,7 +648,7 @@ class EditorHistoryHandler { // Sort by score and provide a fallback sorter that keeps the // recency of items in case the score for items is the same - .sort((e1, e2) => compareItemsByScore(e1, e2, query, false, accessor, this.scorerCache, (e1, e2, query, accessor) => -1)); + .sort((e1, e2) => compareItemsByScore(e1, e2, query, false, accessor, this.scorerCache, () => -1)); } } diff --git a/src/vs/workbench/test/browser/quickopen.test.ts b/src/vs/workbench/test/browser/quickopen.test.ts index fd71405603a..d17bd4fdc81 100644 --- a/src/vs/workbench/test/browser/quickopen.test.ts +++ b/src/vs/workbench/test/browser/quickopen.test.ts @@ -22,10 +22,6 @@ export class TestQuickOpenService implements IQuickOpenService { this.callback = callback; } - pick(arg: any, options?: any, token?: any): Promise { - return TPromise.as(null); - } - accept(): void { } From 6f55622a0625c60516632b1e5c61c62409641b0b Mon Sep 17 00:00:00 2001 From: Johannes Rieken Date: Fri, 10 Aug 2018 15:36:44 +0200 Subject: [PATCH 0678/1276] make sure to massage sourcemaps-url, make sure to upload sourcemaps from dist/folders --- build/gulpfile.vscode.js | 13 +++++++------ build/lib/extensions.js | 14 ++++++++++++-- build/lib/extensions.ts | 14 ++++++++++++-- 3 files changed, 31 insertions(+), 10 deletions(-) diff --git a/build/gulpfile.vscode.js b/build/gulpfile.vscode.js index 090db00ffeb..32288f63d35 100644 --- a/build/gulpfile.vscode.js +++ b/build/gulpfile.vscode.js @@ -113,9 +113,9 @@ gulp.task('optimize-index-js', ['optimize-vscode'], () => { fs.writeFileSync(fullpath, newContents); }); -const baseUrl = `https://ticino.blob.core.windows.net/sourcemaps/${commit}/core`; +const sourceMappingURLBase = `https://ticino.blob.core.windows.net/sourcemaps/${commit}`; gulp.task('clean-minified-vscode', util.rimraf('out-vscode-min')); -gulp.task('minify-vscode', ['clean-minified-vscode', 'optimize-index-js'], common.minifyTask('out-vscode', baseUrl)); +gulp.task('minify-vscode', ['clean-minified-vscode', 'optimize-index-js'], common.minifyTask('out-vscode', `${sourceMappingURLBase}/core`)); // Package @@ -241,7 +241,7 @@ function packageTask(platform, arch, opts) { .filter(({ name }) => builtInExtensions.every(b => b.name !== name)); const localExtensions = es.merge(...localExtensionDescriptions.map(extension => { - return ext.fromLocal(extension.path) + return ext.fromLocal(extension.path, sourceMappingURLBase) .pipe(rename(p => p.dirname = `extensions/${extension.name}/${p.dirname}`)); })); @@ -459,9 +459,10 @@ gulp.task('upload-vscode-sourcemaps', ['minify-vscode'], () => { return f; })); - const extensions = gulp.src('extensions/**/out/**/*.map', { base: '.' }); + const extensionsOut = gulp.src('extensions/**/out/**/*.map', { base: '.' }); + const extensionsDist = gulp.src('extensions/**/dist/**/*.map', { base: '.' }); - return es.merge(vs, extensions) + return es.merge(vs, extensionsOut, extensionsDist) .pipe(azure.upload({ account: process.env.AZURE_STORAGE_ACCOUNT, key: process.env.AZURE_STORAGE_ACCESS_KEY, @@ -506,7 +507,7 @@ function getSettingsSearchBuildId(packageJson) { const branch = process.env.BUILD_SOURCEBRANCH; const branchId = branch.indexOf('/release/') >= 0 ? 0 : /\/master$/.test(branch) ? 1 : - 2; // Some unexpected branch + 2; // Some unexpected branch const out = cp.execSync(`git rev-list HEAD --count`); const count = parseInt(out.toString()); diff --git a/build/lib/extensions.js b/build/lib/extensions.js index af06cde2b94..9bb5da1e39c 100644 --- a/build/lib/extensions.js +++ b/build/lib/extensions.js @@ -16,11 +16,13 @@ var buffer = require('gulp-buffer'); var json = require('gulp-json-editor'); var webpack = require('webpack'); var webpackGulp = require('webpack-stream'); +var sourcemaps = require("gulp-sourcemaps"); var fs = require("fs"); var path = require("path"); var vsce = require("vsce"); var File = require("vinyl"); -function fromLocal(extensionPath) { +var util_1 = require("./util"); +function fromLocal(extensionPath, sourceMappingURLBase) { var result = es.through(); vsce.listFiles({ cwd: extensionPath, packageManager: vsce.PackageManager.Yarn }).then(function (fileNames) { var files = fileNames @@ -52,11 +54,19 @@ function fromLocal(extensionPath) { data.stat = data.stat || {}; data.base = extensionPath; this.emit('data', data); + })) + .pipe(sourcemaps.init()) + .pipe(Boolean(sourceMappingURLBase) ? util_1.stripSourceMappingURL() : es.through()) + .pipe(sourcemaps.write('.', { + sourceMappingURLPrefix: sourceMappingURLBase && sourceMappingURLBase + "/dist", + addComment: !!sourceMappingURLBase, + includeContent: !!sourceMappingURLBase, + sourceRoot: '../src', })); es.merge(webpackStream, patchFilesStream) // .pipe(es.through(function (data) { // // debug - // console.log('out', data.path, data.base, data.contents.length); + // console.log('out', data.path, data.contents.length); // this.emit('data', data); // })) .pipe(result); diff --git a/build/lib/extensions.ts b/build/lib/extensions.ts index 2191710f232..16a8f9b567f 100644 --- a/build/lib/extensions.ts +++ b/build/lib/extensions.ts @@ -16,12 +16,14 @@ const buffer = require('gulp-buffer'); const json = require('gulp-json-editor'); const webpack = require('webpack'); const webpackGulp = require('webpack-stream'); +import * as sourcemaps from 'gulp-sourcemaps'; import * as fs from 'fs'; import * as path from 'path'; import * as vsce from 'vsce'; import * as File from 'vinyl'; +import { stripSourceMappingURL } from './util'; -export function fromLocal(extensionPath: string): Stream { +export function fromLocal(extensionPath: string, sourceMappingURLBase?: string): Stream { let result = es.through(); vsce.listFiles({ cwd: extensionPath, packageManager: vsce.PackageManager.Yarn }).then(fileNames => { @@ -58,12 +60,20 @@ export function fromLocal(extensionPath: string): Stream { data.stat = data.stat || {}; data.base = extensionPath; this.emit('data', data); + })) + .pipe(sourcemaps.init()) + .pipe(Boolean(sourceMappingURLBase) ? stripSourceMappingURL() : es.through()) + .pipe(sourcemaps.write('.', { + sourceMappingURLPrefix: sourceMappingURLBase && `${sourceMappingURLBase}/dist`, + addComment: !!sourceMappingURLBase, + includeContent: !!sourceMappingURLBase, + sourceRoot: '../src', })); es.merge(webpackStream, patchFilesStream) // .pipe(es.through(function (data) { // // debug - // console.log('out', data.path, data.base, data.contents.length); + // console.log('out', data.path, data.contents.length); // this.emit('data', data); // })) .pipe(result); From 839a40edb3d256986e44fbcbf6e46b5948bd9663 Mon Sep 17 00:00:00 2001 From: Christof Marti Date: Fri, 10 Aug 2018 15:54:22 +0200 Subject: [PATCH 0679/1276] Avoid Uri.parse('') --- extensions/extension-editing/src/extensionLinter.ts | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/extensions/extension-editing/src/extensionLinter.ts b/extensions/extension-editing/src/extensionLinter.ts index 2724038bdf7..cfcb7ca04d4 100644 --- a/extensions/extension-editing/src/extensionLinter.ts +++ b/extensions/extension-editing/src/extensionLinter.ts @@ -249,9 +249,10 @@ export class ExtensionLinter { private readPackageJsonInfo(folder: Uri, tree: JsonNode) { const engine = tree && findNodeAtLocation(tree, ['engines', 'vscode']); const repo = tree && findNodeAtLocation(tree, ['repository', 'url']); + const uri = parseUri(repo.value); const info: PackageJsonInfo = { isExtension: !!(engine && engine.type === 'string'), - hasHttpsRepository: !!(repo && repo.type === 'string' && repo.value && parseUri(repo.value).scheme.toLowerCase() === 'https') + hasHttpsRepository: !!(repo && repo.type === 'string' && repo.value && uri && uri.scheme.toLowerCase() === 'https') }; const str = folder.toString(); const oldInfo = this.folderToPackageJsonInfo[str]; @@ -288,6 +289,9 @@ export class ExtensionLinter { private addDiagnostics(diagnostics: Diagnostic[], document: TextDocument, begin: number, end: number, src: string, context: Context, info: PackageJsonInfo) { const uri = parseUri(src); + if (!uri) { + return; + } const scheme = uri.scheme.toLowerCase(); if (scheme && scheme !== 'https' && scheme !== 'data') { @@ -347,7 +351,7 @@ function parseUri(src: string) { try { return Uri.parse(encodeURI(src)); } catch (err) { - return Uri.parse(''); + return null; } } } \ No newline at end of file From b2c8ca553cf06d782edc4ca9d2a78d5f4ff36976 Mon Sep 17 00:00:00 2001 From: Johannes Rieken Date: Fri, 10 Aug 2018 16:15:34 +0200 Subject: [PATCH 0680/1276] tweak source mapping url --- build/lib/extensions.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build/lib/extensions.ts b/build/lib/extensions.ts index 16a8f9b567f..4e8045ac336 100644 --- a/build/lib/extensions.ts +++ b/build/lib/extensions.ts @@ -64,7 +64,7 @@ export function fromLocal(extensionPath: string, sourceMappingURLBase?: string): .pipe(sourcemaps.init()) .pipe(Boolean(sourceMappingURLBase) ? stripSourceMappingURL() : es.through()) .pipe(sourcemaps.write('.', { - sourceMappingURLPrefix: sourceMappingURLBase && `${sourceMappingURLBase}/dist`, + sourceMappingURLPrefix: sourceMappingURLBase && `${sourceMappingURLBase}/extensions/${path.basename(extensionPath)}/out`, addComment: !!sourceMappingURLBase, includeContent: !!sourceMappingURLBase, sourceRoot: '../src', From efea735f9d4d82187bcec19b89c149bbd0c1dc3a Mon Sep 17 00:00:00 2001 From: Christof Marti Date: Fri, 10 Aug 2018 16:46:43 +0200 Subject: [PATCH 0681/1276] Compile it (#29096) --- .../parts/terminal/electron-browser/terminalActions.ts | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/vs/workbench/parts/terminal/electron-browser/terminalActions.ts b/src/vs/workbench/parts/terminal/electron-browser/terminalActions.ts index 25b65e9eafc..d1cafbd699d 100644 --- a/src/vs/workbench/parts/terminal/electron-browser/terminalActions.ts +++ b/src/vs/workbench/parts/terminal/electron-browser/terminalActions.ts @@ -16,8 +16,8 @@ import { IPartService } from 'vs/workbench/services/part/common/partService'; import { IPanelService } from 'vs/workbench/services/panel/common/panelService'; import { attachSelectBoxStyler } from 'vs/platform/theme/common/styler'; import { IThemeService } from 'vs/platform/theme/common/themeService'; -import { IQuickOpenService, IPickOptions } from 'vs/platform/quickOpen/common/quickOpen'; -import { IQuickInputService } from 'vs/platform/quickinput/common/quickInput'; +import { IQuickOpenService } from 'vs/platform/quickOpen/common/quickOpen'; +import { IQuickInputService, IPickOptions, IQuickPickItem } from 'vs/platform/quickinput/common/quickInput'; import { ActionBarContributor } from 'vs/workbench/browser/actions'; import { TerminalEntry } from 'vs/workbench/parts/terminal/browser/terminalQuickOpen'; import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; @@ -258,7 +258,7 @@ export class CreateNewTerminalAction extends Action { // single root instancePromise = TPromise.as(this.terminalService.createTerminal(undefined, true)); } else { - const options: IPickOptions = { + const options: IPickOptions = { placeHolder: nls.localize('workbench.action.terminal.newWorkspacePlaceholder', "Select current working directory for new terminal") }; instancePromise = this.commandService.executeCommand(PICK_WORKSPACE_FOLDER_COMMAND_ID, [options]).then(workspace => { @@ -327,7 +327,7 @@ export class SplitTerminalAction extends Action { let pathPromise: TPromise = TPromise.as({}); if (folders.length > 1) { // Only choose a path when there's more than 1 folder - const options: IPickOptions = { + const options: IPickOptions = { placeHolder: nls.localize('workbench.action.terminal.newWorkspacePlaceholder', "Select current working directory for new terminal") }; pathPromise = this.commandService.executeCommand(PICK_WORKSPACE_FOLDER_COMMAND_ID, [options]).then(workspace => { From 35788350ba0fcbf2acb9801df86dd6523f066fc9 Mon Sep 17 00:00:00 2001 From: Joao Moreno Date: Fri, 10 Aug 2018 15:44:18 +0200 Subject: [PATCH 0682/1276] tree: reveal when focusing --- src/vs/base/browser/ui/tree/tree.ts | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/vs/base/browser/ui/tree/tree.ts b/src/vs/base/browser/ui/tree/tree.ts index 18a45d2c74c..a90726815f7 100644 --- a/src/vs/base/browser/ui/tree/tree.ts +++ b/src/vs/base/browser/ui/tree/tree.ts @@ -200,6 +200,8 @@ export class Tree implements IDisposable { const [parentLocation] = tail2(location); const parentListIndex = this.model.getListIndex(parentLocation); + + this.view.reveal(parentListIndex); this.view.setFocus([parentListIndex]); } } @@ -224,7 +226,10 @@ export class Tree implements IDisposable { } const [focusedIndex] = this.view.getFocus(); - this.view.setFocus([focusedIndex + 1]); + const firstChildIndex = focusedIndex + 1; + + this.view.reveal(firstChildIndex); + this.view.setFocus([firstChildIndex]); } } From 3e4685d87da03c1bff4de1a25a1deae755867ee8 Mon Sep 17 00:00:00 2001 From: Martin Aeschlimann Date: Fri, 10 Aug 2018 16:56:05 +0200 Subject: [PATCH 0683/1276] move initial back-/foreground to rapid render code (fixes #55677) --- src/vs/code/electron-main/app.ts | 2 +- src/vs/code/electron-main/window.ts | 4 -- .../electron-browser/bootstrap/index.html | 1 - .../electron-browser/bootstrap/index.js | 20 +++++++++- .../electron-browser/bootstrap/preload.js | 39 ------------------- .../partsSplash.contribution.ts | 25 ++++++++++-- .../electron-browser/workbenchThemeService.ts | 9 ----- 7 files changed, 42 insertions(+), 58 deletions(-) delete mode 100644 src/vs/workbench/electron-browser/bootstrap/preload.js diff --git a/src/vs/code/electron-main/app.ts b/src/vs/code/electron-main/app.ts index e0ff559f804..1227becb99f 100644 --- a/src/vs/code/electron-main/app.ts +++ b/src/vs/code/electron-main/app.ts @@ -263,7 +263,7 @@ export class CodeApplication { if (event === 'vscode:changeColorTheme' && typeof payload === 'string') { let data = JSON.parse(payload); - this.stateService.setItem(CodeWindow.themeStorageKey, data.id); + this.stateService.setItem(CodeWindow.themeStorageKey, data.baseTheme); this.stateService.setItem(CodeWindow.themeBackgroundStorageKey, data.background); } } diff --git a/src/vs/code/electron-main/window.ts b/src/vs/code/electron-main/window.ts index d0151137c0b..3bc811d9c7b 100644 --- a/src/vs/code/electron-main/window.ts +++ b/src/vs/code/electron-main/window.ts @@ -617,10 +617,6 @@ export class CodeWindow implements ICodeWindow { windowConfiguration.highContrast = isWindows && autoDetectHighContrast && systemPreferences.isInvertedColorScheme(); windowConfiguration.accessibilitySupport = app.isAccessibilitySupportEnabled(); - // Theme - windowConfiguration.baseTheme = this.getBaseTheme(); - windowConfiguration.backgroundColor = this.getBackgroundColor(); - // Title style related windowConfiguration.maximized = this._win.isMaximized(); windowConfiguration.frameless = this.hasHiddenTitleBarStyle() && !isMacintosh; diff --git a/src/vs/workbench/electron-browser/bootstrap/index.html b/src/vs/workbench/electron-browser/bootstrap/index.html index c14ebbe8653..31e970da6c4 100644 --- a/src/vs/workbench/electron-browser/bootstrap/index.html +++ b/src/vs/workbench/electron-browser/bootstrap/index.html @@ -6,7 +6,6 @@ - diff --git a/src/vs/workbench/electron-browser/bootstrap/index.js b/src/vs/workbench/electron-browser/bootstrap/index.js index 8311ab796ae..5d0965c6de9 100644 --- a/src/vs/workbench/electron-browser/bootstrap/index.js +++ b/src/vs/workbench/electron-browser/bootstrap/index.js @@ -97,10 +97,24 @@ function showPartsSplash(configuration) { // ignore } + // high contrast mode has been turned on, ignore stored colors and layouts + if (data && configuration.highContrast && data.baseTheme !== 'hc-black') { + data = void 0; + } + + const style = document.createElement('style'); + document.head.appendChild(style); + if (data) { + const { layoutInfo, colorInfo, baseTheme } = data; + + // set the theme base id used by images and some styles + document.body.className = `monaco-shell ${baseTheme}`; + // stylesheet that defines foreground and background color + style.innerHTML = `.monaco-shell { background-color: ${colorInfo.editorBackground}; color: ${colorInfo.foreground}; }`; + const splash = document.createElement('div'); splash.id = data.id; - const { layoutInfo, colorInfo } = data; // ensure there is enough space layoutInfo.sideBarWidth = Math.min(layoutInfo.sideBarWidth, window.innerWidth - (layoutInfo.activityBarWidth + layoutInfo.editorPartMinWidth)); @@ -122,7 +136,11 @@ function showPartsSplash(configuration) { `; } document.body.appendChild(splash); + } else { + document.body.className = `monaco-shell ${configuration.highContrast ? 'hc-black' : 'vs-dark'}`; + style.innerHTML = `.monaco-shell { background-color: ${configuration.highContrast ? '#000000' : '#1E1E1E'}; color: ${configuration.highContrast ? '#FFFFFF' : '#CCCCCC'}; }`; } + perf.mark('didShowPartsSplash'); } diff --git a/src/vs/workbench/electron-browser/bootstrap/preload.js b/src/vs/workbench/electron-browser/bootstrap/preload.js deleted file mode 100644 index d451c2d5fb7..00000000000 --- a/src/vs/workbench/electron-browser/bootstrap/preload.js +++ /dev/null @@ -1,39 +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'; - -(function() { - function getConfig() { - const queryParams = window.location.search.substring(1).split('&'); - for (var i = 0; i < queryParams.length; i++) { - var kv = queryParams[i].split('='); - if (kv[0] === 'config' && kv[1]) { - return JSON.parse(decodeURIComponent(kv[1])); - } - } - return {}; - } - try { - const config = getConfig(); - const document = window.document; - - // sets the base theme class ('vs', 'vs-dark', 'hc-black') - const baseTheme = config.baseTheme || 'vs'; - document.body.className = 'monaco-shell ' + baseTheme; - - // adds a stylesheet with the backgrdound color - var backgroundColor = config.backgroundColor; - if (!backgroundColor) { - backgroundColor = baseTheme === 'hc-black' ? '#000000' : (baseTheme === 'vs' ? '#FFFFFF' : '#1E1E1E'); - } - const foregroundColor = baseTheme === 'hc-black' ? '#FFFFFF' : (baseTheme === 'vs' ? '#6C6C6C' : '#CCCCCC'); - const style = document.createElement('style'); - style.innerHTML = '.monaco-shell { background-color:' + backgroundColor + '; color:' + foregroundColor + '; }'; - document.head.appendChild(style); - - } catch (error) { - console.error(error); - } -})(); \ No newline at end of file diff --git a/src/vs/workbench/parts/splash/electron-browser/partsSplash.contribution.ts b/src/vs/workbench/parts/splash/electron-browser/partsSplash.contribution.ts index 4632aaf6efb..5f76b802ea5 100644 --- a/src/vs/workbench/parts/splash/electron-browser/partsSplash.contribution.ts +++ b/src/vs/workbench/parts/splash/electron-browser/partsSplash.contribution.ts @@ -9,14 +9,16 @@ import { getTotalHeight, getTotalWidth } from 'vs/base/browser/dom'; import { ILifecycleService, LifecyclePhase } from 'vs/platform/lifecycle/common/lifecycle'; import { Registry } from 'vs/platform/registry/common/platform'; import { IStorageService, StorageScope } from 'vs/platform/storage/common/storage'; -import { IThemeService } from 'vs/platform/theme/common/themeService'; +import { IThemeService, getThemeTypeSelector } from 'vs/platform/theme/common/themeService'; +import { IBroadcastService } from 'vs/platform/broadcast/electron-browser/broadcastService'; import { Extensions, IWorkbenchContributionsRegistry } from 'vs/workbench/common/contributions'; import * as themes from 'vs/workbench/common/theme'; import { IPartService, Parts, Position } from 'vs/workbench/services/part/common/partService'; import { IDisposable, dispose } from 'vs/base/common/lifecycle'; import { debounceEvent } from 'vs/base/common/event'; import { DEFAULT_EDITOR_MIN_DIMENSIONS } from 'vs/workbench/browser/parts/editor/editor'; -import { ColorIdentifier } from 'vs/platform/theme/common/colorRegistry'; +import { ColorIdentifier, editorBackground, foreground } from 'vs/platform/theme/common/colorRegistry'; +import { Color } from 'vs/base/common/color'; class PartsSplash { @@ -24,11 +26,15 @@ class PartsSplash { private readonly _disposables: IDisposable[] = []; + private lastBaseTheme: string; + private lastBackground: string; + constructor( @IThemeService private readonly _themeService: IThemeService, @IPartService private readonly _partService: IPartService, @IStorageService private readonly _storageService: IStorageService, @ILifecycleService lifecycleService: ILifecycleService, + @IBroadcastService private broadcastService: IBroadcastService ) { lifecycleService.when(LifecyclePhase.Running).then(_ => this._removePartsSplash()); debounceEvent(_partService.onEditorLayout, () => { }, 50)(this._savePartsSplash, this, this._disposables); @@ -39,7 +45,10 @@ class PartsSplash { } private _savePartsSplash() { + const baseTheme = getThemeTypeSelector(this._themeService.getTheme().type); const colorInfo = { + foreground: this._getThemeColor(foreground), + editorBackground: this._getThemeColor(editorBackground), titleBarBackground: this._getThemeColor(themes.TITLE_BAR_ACTIVE_BACKGROUND), activityBarBackground: this._getThemeColor(themes.ACTIVITY_BAR_BACKGROUND), sideBarBackground: this._getThemeColor(themes.SIDE_BAR_BACKGROUND), @@ -54,7 +63,17 @@ class PartsSplash { sideBarWidth: getTotalWidth(this._partService.getContainer(Parts.SIDEBAR_PART)), statusBarHeight: getTotalHeight(this._partService.getContainer(Parts.STATUSBAR_PART)), }; - this._storageService.store('parts-splash-data', JSON.stringify({ id: PartsSplash._splashElementId, colorInfo, layoutInfo }), StorageScope.GLOBAL); + this._storageService.store('parts-splash-data', JSON.stringify({ id: PartsSplash._splashElementId, colorInfo, layoutInfo, baseTheme }), StorageScope.GLOBAL); + + if (baseTheme !== this.lastBaseTheme || colorInfo.editorBackground !== this.lastBackground) { + // notify the main window on background color changes: the main window sets the background color to new windows + this.lastBaseTheme = baseTheme; + this.lastBackground = colorInfo.editorBackground; + + // the color needs to be in hex + const backgroundColor = this._themeService.getTheme().getColor(editorBackground) || themes.WORKBENCH_BACKGROUND(this._themeService.getTheme()); + this.broadcastService.broadcast({ channel: 'vscode:changeColorTheme', payload: JSON.stringify({ baseTheme, background: Color.Format.CSS.formatHex(backgroundColor) }) }); + } } private _getThemeColor(id: ColorIdentifier): string { diff --git a/src/vs/workbench/services/themes/electron-browser/workbenchThemeService.ts b/src/vs/workbench/services/themes/electron-browser/workbenchThemeService.ts index 8dcbaf381f8..91c55890363 100644 --- a/src/vs/workbench/services/themes/electron-browser/workbenchThemeService.ts +++ b/src/vs/workbench/services/themes/electron-browser/workbenchThemeService.ts @@ -18,13 +18,10 @@ import { IConfigurationRegistry, Extensions as ConfigurationExtensions, IConfigu import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; import { ColorThemeData } from './colorThemeData'; import { ITheme, Extensions as ThemingExtensions, IThemingRegistry } from 'vs/platform/theme/common/themeService'; -import { editorBackground } from 'vs/platform/theme/common/colorRegistry'; -import { Color } from 'vs/base/common/color'; import { Event, Emitter } from 'vs/base/common/event'; import * as colorThemeSchema from 'vs/workbench/services/themes/common/colorThemeSchema'; import * as fileIconThemeSchema from 'vs/workbench/services/themes/common/fileIconThemeSchema'; import { IDisposable } from 'vs/base/common/lifecycle'; -import { IBroadcastService } from 'vs/platform/broadcast/electron-browser/broadcastService'; import { ColorThemeStore } from 'vs/workbench/services/themes/electron-browser/colorThemeStore'; import { FileIconThemeStore } from 'vs/workbench/services/themes/electron-browser/fileIconThemeStore'; import { FileIconThemeData } from 'vs/workbench/services/themes/electron-browser/fileIconThemeData'; @@ -97,7 +94,6 @@ export class WorkbenchThemeService implements IWorkbenchThemeService { container: HTMLElement, @IExtensionService extensionService: IExtensionService, @IStorageService private storageService: IStorageService, - @IBroadcastService private broadcastService: IBroadcastService, @IConfigurationService private configurationService: IConfigurationService, @ITelemetryService private telemetryService: ITelemetryService, @IWindowService private windowService: IWindowService, @@ -342,11 +338,6 @@ export class WorkbenchThemeService implements IWorkbenchThemeService { this.onColorThemeChange.fire(this.currentColorTheme); - if (settingsTarget !== ConfigurationTarget.WORKSPACE) { - let background = Color.Format.CSS.formatHex(newTheme.getColor(editorBackground)); // only take RGB, its what is used in the initial CSS - let data = { id: newTheme.id, background: background }; - this.broadcastService.broadcast({ channel: 'vscode:changeColorTheme', payload: JSON.stringify(data) }); - } // remember theme data for a quick restore this.storageService.store(PERSISTED_THEME_STORAGE_KEY, newTheme.toStorageData()); From 97ed4762336c94b4f326699131badfd961fc0642 Mon Sep 17 00:00:00 2001 From: Christof Marti Date: Fri, 10 Aug 2018 18:08:56 +0200 Subject: [PATCH 0684/1276] Missing checks (#29096) --- .../browser/parts/quickopen/quickOpenController.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/vs/workbench/browser/parts/quickopen/quickOpenController.ts b/src/vs/workbench/browser/parts/quickopen/quickOpenController.ts index 7a0183bffff..9b5dd21bd15 100644 --- a/src/vs/workbench/browser/parts/quickopen/quickOpenController.ts +++ b/src/vs/workbench/browser/parts/quickopen/quickOpenController.ts @@ -120,19 +120,19 @@ export class QuickOpenController extends Component implements IQuickOpenService } accept(): void { - if (this.quickOpenWidget.isVisible()) { + if (this.quickOpenWidget && this.quickOpenWidget.isVisible()) { this.quickOpenWidget.accept(); } } focus(): void { - if (this.quickOpenWidget.isVisible()) { + if (this.quickOpenWidget && this.quickOpenWidget.isVisible()) { this.quickOpenWidget.focus(); } } close(): void { - if (this.quickOpenWidget.isVisible()) { + if (this.quickOpenWidget && this.quickOpenWidget.isVisible()) { this.quickOpenWidget.hide(HideReason.CANCELED); } } From 9a7e4ed8b696463efd6589965acbd50f91923cc7 Mon Sep 17 00:00:00 2001 From: Rob Lourens Date: Fri, 10 Aug 2018 07:39:14 -0700 Subject: [PATCH 0685/1276] Remove 'workbench.settings.tocVisible' setting --- .../workbench/electron-browser/main.contribution.ts | 6 ------ .../preferences/browser/media/settingsEditor2.css | 4 ---- .../parts/preferences/browser/settingsEditor2.ts | 11 ----------- 3 files changed, 21 deletions(-) diff --git a/src/vs/workbench/electron-browser/main.contribution.ts b/src/vs/workbench/electron-browser/main.contribution.ts index 5977d01baa4..9ad1d55109f 100644 --- a/src/vs/workbench/electron-browser/main.contribution.ts +++ b/src/vs/workbench/electron-browser/main.contribution.ts @@ -644,12 +644,6 @@ configurationRegistry.registerConfiguration({ 'default': 'filter', 'scope': ConfigurationScope.WINDOW }, - 'workbench.settings.tocVisible': { - 'type': 'boolean', - 'description': nls.localize('settingsTocVisible', "Controls whether the settings editor Table of Contents is visible."), - 'default': true, - 'scope': ConfigurationScope.WINDOW - }, 'workbench.enableExperiments': { 'type': 'boolean', 'description': nls.localize('workbench.enableExperiments', "Fetches experiments to run from a Microsoft online service."), diff --git a/src/vs/workbench/parts/preferences/browser/media/settingsEditor2.css b/src/vs/workbench/parts/preferences/browser/media/settingsEditor2.css index 081112d78cd..58f332fb562 100644 --- a/src/vs/workbench/parts/preferences/browser/media/settingsEditor2.css +++ b/src/vs/workbench/parts/preferences/browser/media/settingsEditor2.css @@ -155,10 +155,6 @@ padding-left: 5px; } -.settings-editor > .settings-body .settings-toc-container.hidden { - display: none; -} - .settings-editor.search-mode .settings-toc-container { display: none; } diff --git a/src/vs/workbench/parts/preferences/browser/settingsEditor2.ts b/src/vs/workbench/parts/preferences/browser/settingsEditor2.ts index d4f1f3f0ff6..baa97db5544 100644 --- a/src/vs/workbench/parts/preferences/browser/settingsEditor2.ts +++ b/src/vs/workbench/parts/preferences/browser/settingsEditor2.ts @@ -112,10 +112,6 @@ export class SettingsEditor2 extends BaseEditor { this._register(configurationService.onDidChangeConfiguration(e => { this.onConfigUpdate(); - - if (e.affectsConfiguration('workbench.settings.tocVisible')) { - this.updateTOCVisible(); - } })); } @@ -360,13 +356,6 @@ export class SettingsEditor2 extends BaseEditor { this._register(this.tocTree.onDidBlur(() => { this.tocRowFocused.set(false); })); - - this.updateTOCVisible(); - } - - private updateTOCVisible(): void { - const visible = !!this.configurationService.getValue('workbench.settings.tocVisible'); - DOM.toggleClass(this.tocTreeContainer, 'hidden', !visible); } private createSettingsTree(parent: HTMLElement): void { From 271a56a051908db4d91bacbfaf726e1b86305e5c Mon Sep 17 00:00:00 2001 From: Rob Lourens Date: Fri, 10 Aug 2018 10:44:27 -0700 Subject: [PATCH 0686/1276] Bump node2 --- build/builtInExtensions.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build/builtInExtensions.json b/build/builtInExtensions.json index e927280e32f..112d0157ca6 100644 --- a/build/builtInExtensions.json +++ b/build/builtInExtensions.json @@ -6,7 +6,7 @@ }, { "name": "ms-vscode.node-debug2", - "version": "1.26.8", + "version": "1.27.0", "repo": "https://github.com/Microsoft/vscode-node-debug2" } ] From a220dfe9f2e609fa7872b5aaea1f5c52ac2e05da Mon Sep 17 00:00:00 2001 From: Ramya Rao Date: Fri, 10 Aug 2018 11:06:37 -0700 Subject: [PATCH 0687/1276] Move sticky to suggestController (#56123) * Move sticky to suggestController * Style check --- src/vs/editor/contrib/suggest/suggestController.ts | 7 +++++++ src/vs/editor/contrib/suggest/suggestModel.ts | 3 --- src/vs/editor/contrib/suggest/suggestWidget.ts | 14 -------------- 3 files changed, 7 insertions(+), 17 deletions(-) diff --git a/src/vs/editor/contrib/suggest/suggestController.ts b/src/vs/editor/contrib/suggest/suggestController.ts index e281a671244..edb083518f5 100644 --- a/src/vs/editor/contrib/suggest/suggestController.ts +++ b/src/vs/editor/contrib/suggest/suggestController.ts @@ -88,6 +88,8 @@ export class SuggestController implements IEditorContribution { private _memory: SuggestMemories; private _toDispose: IDisposable[] = []; + private readonly _sticky = false; // for development purposes only + constructor( private _editor: ICodeEditor, @ICommandService private readonly _commandService: ICommandService, @@ -112,6 +114,11 @@ export class SuggestController implements IEditorContribution { this._widget.hideWidget(); } })); + this._toDispose.push(this._editor.onDidBlurEditorText(() => { + if (!this._sticky) { + this._model.cancel(); + } + })); // Manage the acceptSuggestionsOnEnter context key let acceptSuggestionsOnEnter = SuggestContext.AcceptSuggestionsOnEnter.bindTo(_contextKeyService); diff --git a/src/vs/editor/contrib/suggest/suggestModel.ts b/src/vs/editor/contrib/suggest/suggestModel.ts index d3b11c702fb..4a427b85dfe 100644 --- a/src/vs/editor/contrib/suggest/suggestModel.ts +++ b/src/vs/editor/contrib/suggest/suggestModel.ts @@ -123,9 +123,6 @@ export class SuggestModel implements IDisposable { this._updateTriggerCharacters(); this.cancel(); })); - this._toDispose.push(this._editor.onDidBlurEditorText(() => { - this.cancel(); - })); this._toDispose.push(this._editor.onDidChangeConfiguration(() => { this._updateTriggerCharacters(); this._updateQuickSuggest(); diff --git a/src/vs/editor/contrib/suggest/suggestWidget.ts b/src/vs/editor/contrib/suggest/suggestWidget.ts index 3360b6fbda0..a221be2731d 100644 --- a/src/vs/editor/contrib/suggest/suggestWidget.ts +++ b/src/vs/editor/contrib/suggest/suggestWidget.ts @@ -35,7 +35,6 @@ import { IOpenerService } from 'vs/platform/opener/common/opener'; import { TimeoutTimer, CancelablePromise, createCancelablePromise } from 'vs/base/common/async'; import { CancellationToken } from 'vs/base/common/cancellation'; -const sticky = false; // for development purposes const expandSuggestionDocsByDefault = false; const maxSuggestionsToShow = 12; @@ -456,7 +455,6 @@ export class SuggestWidget implements IContentWidget, IVirtualDelegate this.onThemeChange(t)), - editor.onDidBlurEditorText(() => this.onEditorBlur()), editor.onDidLayoutChange(() => this.onEditorLayoutChange()), this.list.onSelectionChange(e => this.onListSelection(e)), this.list.onFocusChange(e => this.onListFocus(e)), @@ -481,18 +479,6 @@ export class SuggestWidget implements IContentWidget, IVirtualDelegate { - if (!this.editor.hasTextFocus()) { - this.setState(State.Hidden); - } - }, 150); - } - private onEditorLayoutChange(): void { if ((this.state === State.Open || this.state === State.Details) && this.expandDocsSettingFromStorage()) { this.expandSideOrBelow(); From 753c832fdd68c21496ab90d3aaa7d0d43e26827e Mon Sep 17 00:00:00 2001 From: Peng Lyu Date: Fri, 10 Aug 2018 12:45:18 -0700 Subject: [PATCH 0688/1276] Re Microsoft/vscode-pull-request-github#171. --- .../electron-browser/commentsEditorContribution.ts | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/vs/workbench/parts/comments/electron-browser/commentsEditorContribution.ts b/src/vs/workbench/parts/comments/electron-browser/commentsEditorContribution.ts index 175e36282e3..aa5e8402ac2 100644 --- a/src/vs/workbench/parts/comments/electron-browser/commentsEditorContribution.ts +++ b/src/vs/workbench/parts/comments/electron-browser/commentsEditorContribution.ts @@ -34,6 +34,7 @@ import { ModelDecorationOptions } from 'vs/editor/common/model/textModel'; import { IModelDecorationOptions } from 'vs/editor/common/model'; import { Color, RGBA } from 'vs/base/common/color'; import { IMarginData } from 'vs/editor/browser/controller/mouseTarget'; +import { INotificationService } from 'vs/platform/notification/common/notification'; export const ctxReviewPanelVisible = new RawContextKey('reviewPanelVisible', false); @@ -173,6 +174,7 @@ export class ReviewController implements IEditorContribution { @IContextKeyService contextKeyService: IContextKeyService, @IThemeService private themeService: IThemeService, @ICommentService private commentService: ICommentService, + @INotificationService private notificationService: INotificationService, @IInstantiationService private instantiationService: IInstantiationService, @IModeService private modeService: IModeService, @IModelService private modelService: IModelService, @@ -373,6 +375,11 @@ export class ReviewController implements IEditorContribution { } private addComment(lineNumber: number) { + if (this._newCommentWidget !== null) { + this.notificationService.warn(`Please submit the comment at line ${this._newCommentWidget.position.lineNumber} before creating a new one.`); + return; + } + let newCommentInfo = this._commentingRangeDecorator.getMatchedCommentAction(lineNumber); if (!newCommentInfo) { return; From 5e37f92880ce27159003c2eb7f3c0e3cf5b40308 Mon Sep 17 00:00:00 2001 From: Jackson Kearl Date: Fri, 10 Aug 2018 12:47:51 -0700 Subject: [PATCH 0689/1276] Extract autosuggest editor to own class; bring into settings (#55924) * Extract autosuggest editor to own class; bring into settings * Remove unused css. Fix clipping issue. * Autosuggest -> suggest * Remove rounded selections from suggest inputs --- .../browser/media/suggestEnabledInput.css | 27 ++ .../menuPreventer.ts | 0 .../codeEditor/browser/simpleEditorOptions.ts | 31 +++ .../codeEditor/browser/suggestEnabledInput.ts | 232 ++++++++++++++++++ .../codeEditor/codeEditor.contribution.ts | 2 +- .../electron-browser/simpleEditorOptions.ts | 30 +-- .../electron-browser/simpleCommentEditor.ts | 2 +- .../electron-browser/breakpointWidget.ts | 3 +- .../parts/debug/electron-browser/repl.ts | 3 +- .../parts/extensions/common/extensionQuery.ts | 2 +- .../electron-browser/extensionsViewlet.ts | 163 +++--------- .../media/extensionsViewlet.css | 26 -- .../test/common/extensionQuery.test.ts | 8 +- .../browser/media/settingsEditor2.css | 18 -- .../preferences/browser/settingsEditor2.ts | 49 +++- .../preferences.contribution.ts | 5 +- 16 files changed, 376 insertions(+), 225 deletions(-) create mode 100644 src/vs/workbench/parts/codeEditor/browser/media/suggestEnabledInput.css rename src/vs/workbench/parts/codeEditor/{electron-browser => browser}/menuPreventer.ts (100%) create mode 100644 src/vs/workbench/parts/codeEditor/browser/simpleEditorOptions.ts create mode 100644 src/vs/workbench/parts/codeEditor/browser/suggestEnabledInput.ts diff --git a/src/vs/workbench/parts/codeEditor/browser/media/suggestEnabledInput.css b/src/vs/workbench/parts/codeEditor/browser/media/suggestEnabledInput.css new file mode 100644 index 00000000000..4cce699dee8 --- /dev/null +++ b/src/vs/workbench/parts/codeEditor/browser/media/suggestEnabledInput.css @@ -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. + *--------------------------------------------------------------------------------------------*/ + +.suggest-input-container { + padding: 3px 4px 5px; +} + +.suggest-input-container .monaco-editor-background, +.suggest-input-container .monaco-editor, +.suggest-input-container .mtk1 { + /* allow the embedded monaco to be styled from the outer context */ + background-color: inherit; + color: inherit; +} + +.suggest-input-container .suggest-input-placeholder { + position: absolute; + z-index: 1; + overflow: hidden; + white-space: nowrap; + text-overflow: ellipsis; + pointer-events: none; + margin-top: 2px; + margin-left: 1px; +} \ No newline at end of file diff --git a/src/vs/workbench/parts/codeEditor/electron-browser/menuPreventer.ts b/src/vs/workbench/parts/codeEditor/browser/menuPreventer.ts similarity index 100% rename from src/vs/workbench/parts/codeEditor/electron-browser/menuPreventer.ts rename to src/vs/workbench/parts/codeEditor/browser/menuPreventer.ts diff --git a/src/vs/workbench/parts/codeEditor/browser/simpleEditorOptions.ts b/src/vs/workbench/parts/codeEditor/browser/simpleEditorOptions.ts new file mode 100644 index 00000000000..a18c1f0479d --- /dev/null +++ b/src/vs/workbench/parts/codeEditor/browser/simpleEditorOptions.ts @@ -0,0 +1,31 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import { IEditorOptions } from 'vs/editor/common/config/editorOptions'; + +export function getSimpleEditorOptions(): IEditorOptions { + return { + wordWrap: 'on', + overviewRulerLanes: 0, + glyphMargin: false, + lineNumbers: 'off', + folding: false, + selectOnLineNumbers: false, + hideCursorInOverviewRuler: true, + selectionHighlight: false, + scrollbar: { + horizontal: 'hidden' + }, + lineDecorationsWidth: 0, + overviewRulerBorder: false, + scrollBeyondLastLine: false, + renderLineHighlight: 'none', + fixedOverflowWidgets: true, + acceptSuggestionOnEnter: 'smart', + minimap: { + enabled: false + } + }; +} diff --git a/src/vs/workbench/parts/codeEditor/browser/suggestEnabledInput.ts b/src/vs/workbench/parts/codeEditor/browser/suggestEnabledInput.ts new file mode 100644 index 00000000000..d85455c40dc --- /dev/null +++ b/src/vs/workbench/parts/codeEditor/browser/suggestEnabledInput.ts @@ -0,0 +1,232 @@ +/*--------------------------------------------------------------------------------------------- + * 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 'vs/css!./media/suggestEnabledInput'; +import { $, addClass, append, removeClass, Dimension } from 'vs/base/browser/dom'; +import { chain, Emitter, Event } from 'vs/base/common/event'; +import { KeyCode } from 'vs/base/common/keyCodes'; +import { IDisposable, dispose } from 'vs/base/common/lifecycle'; +import { isMacintosh } from 'vs/base/common/platform'; +import uri from 'vs/base/common/uri'; +import { CodeEditorWidget } from 'vs/editor/browser/widget/codeEditorWidget'; +import { IEditorOptions } from 'vs/editor/common/config/editorOptions'; +import * as modes from 'vs/editor/common/modes'; +import { IModelService } from 'vs/editor/common/services/modelService'; +import { ContextMenuController } from 'vs/editor/contrib/contextmenu/contextmenu'; +import { SnippetController2 } from 'vs/editor/contrib/snippet/snippetController2'; +import { SuggestController } from 'vs/editor/contrib/suggest/suggestController'; +import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; +import { inputBackground, inputBorder, inputForeground, inputPlaceholderForeground } from 'vs/platform/theme/common/colorRegistry'; +import { IThemeService } from 'vs/platform/theme/common/themeService'; +import { Component } from 'vs/workbench/common/component'; +import { MenuPreventer } from 'vs/workbench/parts/codeEditor/browser/menuPreventer'; +import { getSimpleEditorOptions } from 'vs/workbench/parts/codeEditor/browser/simpleEditorOptions'; +import { Position } from 'vs/editor/common/core/position'; +import { Range } from 'vs/editor/common/core/range'; +import { ITextModel } from 'vs/editor/common/model'; +import { IContextKey } from 'vs/platform/contextkey/common/contextkey'; + +interface SuggestResultsProvider { + /** + * Provider function for suggestion results. + * + * @param query the full text of the input. + */ + provideResults: (query: string) => string[]; + + /** + * Trigger characters for this input. Suggestions will appear when one of these is typed, + * or upon `ctrl+space` triggering at a word boundary. + * + * Defaults to the empty array. + */ + triggerCharacters?: string[]; + + /** + * Defines the sorting function used when showing results. + * + * Defaults to the identity function. + */ + sortKey?: (result: string) => string; +} + +interface SuggestEnabledInputOptions { + /** + * The text to show when no input is present. + * + * Defaults to the empty string. + */ + placeholderText?: string; + + /** + * Context key tracking the focus state of this element + */ + focusContextKey?: IContextKey; +} + +export class SuggestEnabledInput extends Component { + + private _onShouldFocusResults = new Emitter(); + readonly onShouldFocusResults: Event = this._onShouldFocusResults.event; + + private _onEnter = new Emitter(); + readonly onEnter: Event = this._onEnter.event; + + private _onInputDidChange = new Emitter(); + readonly onInputDidChange: Event = this._onInputDidChange.event; + + private disposables: IDisposable[] = []; + private inputWidget: CodeEditorWidget; + private stylingContainer: HTMLDivElement; + private placeholderText: HTMLDivElement; + + constructor( + id: string, + parent: HTMLElement, + suggestionProvider: SuggestResultsProvider, + ariaLabel: string, + resourceHandle: string, + options: SuggestEnabledInputOptions, + @IThemeService themeService: IThemeService, + @IInstantiationService instantiationService: IInstantiationService, + @IModelService modelService: IModelService, + ) { + super(id, themeService); + + this.stylingContainer = append(parent, $('.suggest-input-container')); + this.placeholderText = append(this.stylingContainer, $('.suggest-input-placeholder', null, options.placeholderText || '')); + + this.inputWidget = instantiationService.createInstance(CodeEditorWidget, this.stylingContainer, + mixinHTMLInputStyleOptions(getSimpleEditorOptions(), ariaLabel), + { + contributions: [SuggestController, SnippetController2, ContextMenuController, MenuPreventer], + isSimpleWidget: true, + }); + + let scopeHandle = uri.parse(resourceHandle); + this.inputWidget.setModel(modelService.createModel('', null, scopeHandle, true)); + + this.disposables.push(this.inputWidget.onDidPaste(() => this.setValue(this.getValue()))); // setter cleanses + + this.disposables.push((this.inputWidget.onDidFocusEditorText(() => { + if (options.focusContextKey) { options.focusContextKey.set(true); } + addClass(this.stylingContainer, 'synthetic-focus'); + }))); + this.disposables.push((this.inputWidget.onDidBlurEditorText(() => { + if (options.focusContextKey) { options.focusContextKey.set(false); } + removeClass(this.stylingContainer, 'synthetic-focus'); + }))); + + const onKeyDownMonaco = chain(this.inputWidget.onKeyDown); + onKeyDownMonaco.filter(e => e.keyCode === KeyCode.Enter).on(e => { e.preventDefault(); this._onEnter.fire(); }, this, this.disposables); + onKeyDownMonaco.filter(e => e.keyCode === KeyCode.DownArrow && (isMacintosh ? e.metaKey : e.ctrlKey)).on(() => this._onShouldFocusResults.fire(), this, this.disposables); + + let preexistingContent = this.getValue(); + this.disposables.push(this.inputWidget.getModel().onDidChangeContent(() => { + let content = this.getValue(); + this.placeholderText.style.visibility = content ? 'hidden' : 'visible'; + if (preexistingContent.trim() === content.trim()) { return; } + this._onInputDidChange.fire(); + preexistingContent = content; + })); + + let validatedSuggestProvider = { + provideResults: suggestionProvider.provideResults, + sortKey: suggestionProvider.sortKey || (a => a), + triggerCharacters: suggestionProvider.triggerCharacters || [] + }; + + this.disposables.push(modes.SuggestRegistry.register({ scheme: scopeHandle.scheme, pattern: '**/' + scopeHandle.path, hasAccessToAllModels: true }, { + triggerCharacters: validatedSuggestProvider.triggerCharacters, + provideCompletionItems: (model: ITextModel, position: Position, _context: modes.SuggestContext) => { + let query = model.getValue(); + + let wordStart = query.lastIndexOf(' ', position.column - 1) + 1; + let alreadyTypedCount = position.column - wordStart - 1; + + // dont show suggestions if the user has typed something, but hasn't used the trigger character + if (alreadyTypedCount > 0 && (validatedSuggestProvider.triggerCharacters).indexOf(query[wordStart]) === -1) { return { suggestions: [] }; } + + return { + suggestions: suggestionProvider.provideResults(query).map(result => { + return { + label: result, + insertText: result, + overwriteBefore: alreadyTypedCount, + sortText: validatedSuggestProvider.sortKey(result), + type: 'keyword' + }; + }) + }; + } + })); + } + + public setValue(val: string) { + val = val.replace(/\s/g, ' '); + this.inputWidget.setValue(val); + this.inputWidget.setScrollTop(0); + this.inputWidget.setPosition(new Position(1, val.length + 1)); + } + + public getValue(): string { + return this.inputWidget.getValue(); + } + + + public updateStyles(): void { + super.updateStyles(); + + this.stylingContainer.style.backgroundColor = this.getColor(inputBackground); + this.stylingContainer.style.color = this.getColor(inputForeground); + this.placeholderText.style.color = this.getColor(inputPlaceholderForeground); + + const inputBorderColor = this.getColor(inputBorder); + this.stylingContainer.style.borderWidth = inputBorderColor ? '1px' : null; + this.stylingContainer.style.borderStyle = inputBorderColor ? 'solid' : null; + this.stylingContainer.style.borderColor = inputBorderColor; + + let cursor = this.stylingContainer.getElementsByClassName('cursor')[0] as HTMLDivElement; + if (cursor) { + cursor.style.backgroundColor = this.getColor(inputForeground); + } + } + + public focus(): void { + this.inputWidget.focus(); + } + + public layout(dimension: Dimension): void { + this.inputWidget.layout(dimension); + this.placeholderText.style.width = `${dimension.width}px`; + } + + public selectAll(): void { + this.inputWidget.setSelection(new Range(1, 1, 1, this.getValue().length + 1)); + } + + dispose(): void { + this.disposables = dispose(this.disposables); + super.dispose(); + } +} + + +function mixinHTMLInputStyleOptions(config: IEditorOptions, ariaLabel?: string): IEditorOptions { + config.fontSize = 13; + config.lineHeight = 22; + config.wordWrap = 'off'; + config.scrollbar.vertical = 'hidden'; + config.roundedSelection = false; + config.ariaLabel = ariaLabel || ''; + config.renderIndentGuides = false; + config.cursorWidth = 1; + config.snippetSuggestions = 'none'; + config.suggest = { filterGraceful: false }; + config.fontFamily = ' -apple-system, BlinkMacSystemFont, "Segoe WPC", "Segoe UI", "HelveticaNeue-Light", "Ubuntu", "Droid Sans", sans-serif'; + return config; +} diff --git a/src/vs/workbench/parts/codeEditor/codeEditor.contribution.ts b/src/vs/workbench/parts/codeEditor/codeEditor.contribution.ts index cc4c07f981a..d66877173a1 100644 --- a/src/vs/workbench/parts/codeEditor/codeEditor.contribution.ts +++ b/src/vs/workbench/parts/codeEditor/codeEditor.contribution.ts @@ -6,7 +6,7 @@ import './electron-browser/accessibility'; import './electron-browser/inspectKeybindings'; import './electron-browser/largeFileOptimizations'; -import './electron-browser/menuPreventer'; +import './browser/menuPreventer'; import './electron-browser/selectionClipboard'; import './electron-browser/textMate/inspectTMScopes'; import './electron-browser/toggleMinimap'; diff --git a/src/vs/workbench/parts/codeEditor/electron-browser/simpleEditorOptions.ts b/src/vs/workbench/parts/codeEditor/electron-browser/simpleEditorOptions.ts index 809dbd0584d..4e3a0f1a14c 100644 --- a/src/vs/workbench/parts/codeEditor/electron-browser/simpleEditorOptions.ts +++ b/src/vs/workbench/parts/codeEditor/electron-browser/simpleEditorOptions.ts @@ -3,9 +3,8 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -import { IEditorOptions } from 'vs/editor/common/config/editorOptions'; import { ICodeEditorWidgetOptions } from 'vs/editor/browser/widget/codeEditorWidget'; -import { MenuPreventer } from 'vs/workbench/parts/codeEditor/electron-browser/menuPreventer'; +import { MenuPreventer } from 'vs/workbench/parts/codeEditor/browser/menuPreventer'; import { SelectionClipboard } from 'vs/workbench/parts/codeEditor/electron-browser/selectionClipboard'; import { ContextMenuController } from 'vs/editor/contrib/contextmenu/contextmenu'; import { SuggestController } from 'vs/editor/contrib/suggest/suggestController'; @@ -24,29 +23,4 @@ export function getSimpleCodeEditorWidgetOptions(): ICodeEditorWidgetOptions { TabCompletionController, ] }; -} - -export function getSimpleEditorOptions(): IEditorOptions { - return { - wordWrap: 'on', - overviewRulerLanes: 0, - glyphMargin: false, - lineNumbers: 'off', - folding: false, - selectOnLineNumbers: false, - hideCursorInOverviewRuler: true, - selectionHighlight: false, - scrollbar: { - horizontal: 'hidden' - }, - lineDecorationsWidth: 0, - overviewRulerBorder: false, - scrollBeyondLastLine: false, - renderLineHighlight: 'none', - fixedOverflowWidgets: true, - acceptSuggestionOnEnter: 'smart', - minimap: { - enabled: false - } - }; -} +} \ No newline at end of file diff --git a/src/vs/workbench/parts/comments/electron-browser/simpleCommentEditor.ts b/src/vs/workbench/parts/comments/electron-browser/simpleCommentEditor.ts index 3bbb410d3f5..a103105c641 100644 --- a/src/vs/workbench/parts/comments/electron-browser/simpleCommentEditor.ts +++ b/src/vs/workbench/parts/comments/electron-browser/simpleCommentEditor.ts @@ -12,7 +12,7 @@ import { IInstantiationService } from 'vs/platform/instantiation/common/instanti import { ICommandService } from 'vs/platform/commands/common/commands'; // Allowed Editor Contributions: -import { MenuPreventer } from 'vs/workbench/parts/codeEditor/electron-browser/menuPreventer'; +import { MenuPreventer } from 'vs/workbench/parts/codeEditor/browser/menuPreventer'; import { SelectionClipboard } from 'vs/workbench/parts/codeEditor/electron-browser/selectionClipboard'; import { ContextMenuController } from 'vs/editor/contrib/contextmenu/contextmenu'; import { SuggestController } from 'vs/editor/contrib/suggest/suggestController'; diff --git a/src/vs/workbench/parts/debug/electron-browser/breakpointWidget.ts b/src/vs/workbench/parts/debug/electron-browser/breakpointWidget.ts index d9bc400ab10..fe86cf067fd 100644 --- a/src/vs/workbench/parts/debug/electron-browser/breakpointWidget.ts +++ b/src/vs/workbench/parts/debug/electron-browser/breakpointWidget.ts @@ -33,7 +33,8 @@ import { ServiceCollection } from 'vs/platform/instantiation/common/serviceColle import { IDecorationOptions } from 'vs/editor/common/editorCommon'; import { CodeEditorWidget } from 'vs/editor/browser/widget/codeEditorWidget'; import { KeybindingWeight } from 'vs/platform/keybinding/common/keybindingsRegistry'; -import { getSimpleEditorOptions, getSimpleCodeEditorWidgetOptions } from 'vs/workbench/parts/codeEditor/electron-browser/simpleEditorOptions'; +import { getSimpleCodeEditorWidgetOptions } from 'vs/workbench/parts/codeEditor/electron-browser/simpleEditorOptions'; +import { getSimpleEditorOptions } from 'vs/workbench/parts/codeEditor/browser/simpleEditorOptions'; const $ = dom.$; const IPrivateBreakpointWidgetService = createDecorator('privateBreakopintWidgetService'); diff --git a/src/vs/workbench/parts/debug/electron-browser/repl.ts b/src/vs/workbench/parts/debug/electron-browser/repl.ts index 453e622d41e..68d06e337a4 100644 --- a/src/vs/workbench/parts/debug/electron-browser/repl.ts +++ b/src/vs/workbench/parts/debug/electron-browser/repl.ts @@ -47,7 +47,8 @@ import { HistoryNavigator } from 'vs/base/common/history'; import { IHistoryNavigationWidget } from 'vs/base/browser/history'; import { createAndBindHistoryNavigationWidgetScopedContextKeyService } from 'vs/platform/widget/browser/contextScopedHistoryWidget'; import { KeybindingWeight } from 'vs/platform/keybinding/common/keybindingsRegistry'; -import { getSimpleEditorOptions, getSimpleCodeEditorWidgetOptions } from 'vs/workbench/parts/codeEditor/electron-browser/simpleEditorOptions'; +import { getSimpleCodeEditorWidgetOptions } from 'vs/workbench/parts/codeEditor/electron-browser/simpleEditorOptions'; +import { getSimpleEditorOptions } from 'vs/workbench/parts/codeEditor/browser/simpleEditorOptions'; const $ = dom.$; diff --git a/src/vs/workbench/parts/extensions/common/extensionQuery.ts b/src/vs/workbench/parts/extensions/common/extensionQuery.ts index b966d438028..5f85a0ee0e0 100644 --- a/src/vs/workbench/parts/extensions/common/extensionQuery.ts +++ b/src/vs/workbench/parts/extensions/common/extensionQuery.ts @@ -12,7 +12,7 @@ export class Query { this.value = value.trim(); } - static autocompletions(query: string): string[] { + static suggestions(query: string): string[] { const commands = ['installed', 'outdated', 'enabled', 'disabled', 'builtin', 'recommended', 'sort', 'category', 'tag', 'ext']; const subcommands = { 'sort': ['installs', 'rating', 'name'], diff --git a/src/vs/workbench/parts/extensions/electron-browser/extensionsViewlet.ts b/src/vs/workbench/parts/extensions/electron-browser/extensionsViewlet.ts index 334c02d10d7..307fae07cc0 100644 --- a/src/vs/workbench/parts/extensions/electron-browser/extensionsViewlet.ts +++ b/src/vs/workbench/parts/extensions/electron-browser/extensionsViewlet.ts @@ -6,21 +6,18 @@ 'use strict'; import 'vs/css!./media/extensionsViewlet'; -import uri from 'vs/base/common/uri'; -import * as modes from 'vs/editor/common/modes'; import { localize } from 'vs/nls'; import { ThrottledDelayer, always } from 'vs/base/common/async'; import { TPromise } from 'vs/base/common/winjs.base'; import { isPromiseCanceledError, onUnexpectedError, create as createError } from 'vs/base/common/errors'; import { IWorkbenchContribution } from 'vs/workbench/common/contributions'; import { IDisposable, dispose } from 'vs/base/common/lifecycle'; -import { Event as EventOf, Emitter, chain } from 'vs/base/common/event'; +import { Event as EventOf, Emitter } from 'vs/base/common/event'; import { IAction } from 'vs/base/common/actions'; import { Separator } from 'vs/base/browser/ui/actionbar/actionbar'; -import { KeyCode } from 'vs/base/common/keyCodes'; import { IViewlet } from 'vs/workbench/common/viewlet'; import { IViewletService } from 'vs/workbench/services/viewlet/browser/viewlet'; -import { append, $, addClass, removeClass, toggleClass, Dimension } from 'vs/base/browser/dom'; +import { append, $, addClass, toggleClass, Dimension } from 'vs/base/browser/dom'; import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry'; import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; import { IExtensionService } from 'vs/workbench/services/extensions/common/extensions'; @@ -39,7 +36,6 @@ import { IEditorGroupsService } from 'vs/workbench/services/group/common/editorG import Severity from 'vs/base/common/severity'; import { IActivityService, ProgressBadge, NumberBadge } from 'vs/workbench/services/activity/common/activity'; import { IThemeService } from 'vs/platform/theme/common/themeService'; -import { inputForeground, inputBackground, inputBorder, inputPlaceholderForeground } from 'vs/platform/theme/common/colorRegistry'; import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; import { ViewsRegistry, IViewDescriptor } from 'vs/workbench/common/views'; import { ViewContainerViewlet, IViewletViewOptions } from 'vs/workbench/browser/parts/views/viewsViewlet'; @@ -59,18 +55,7 @@ import { ExtensionsWorkbenchService } from 'vs/workbench/parts/extensions/node/e import { SyncDescriptor } from 'vs/platform/instantiation/common/descriptors'; import { SingleServerExtensionManagementServerService } from 'vs/workbench/services/extensions/node/extensionManagementServerService'; import { Query } from 'vs/workbench/parts/extensions/common/extensionQuery'; -import { CodeEditorWidget } from 'vs/editor/browser/widget/codeEditorWidget'; -import { IModelService } from 'vs/editor/common/services/modelService'; -import { Range } from 'vs/editor/common/core/range'; -import { Position } from 'vs/editor/common/core/position'; -import { ITextModel } from 'vs/editor/common/model'; -import { IEditorOptions } from 'vs/editor/common/config/editorOptions'; -import { getSimpleEditorOptions } from 'vs/workbench/parts/codeEditor/electron-browser/simpleEditorOptions'; -import { SuggestController } from 'vs/editor/contrib/suggest/suggestController'; -import { ContextMenuController } from 'vs/editor/contrib/contextmenu/contextmenu'; -import { MenuPreventer } from 'vs/workbench/parts/codeEditor/electron-browser/menuPreventer'; -import { SnippetController2 } from 'vs/editor/contrib/snippet/snippetController2'; -import { isMacintosh } from 'vs/base/common/platform'; +import { SuggestEnabledInput } from 'vs/workbench/parts/codeEditor/browser/suggestEnabledInput'; interface SearchInputEvent extends Event { target: HTMLInputElement; @@ -265,14 +250,12 @@ export class ExtensionsViewlet extends ViewContainerViewlet implements IExtensio private searchDelayer: ThrottledDelayer; private root: HTMLElement; - private searchBox: CodeEditorWidget; + private searchBox: SuggestEnabledInput; private extensionsBox: HTMLElement; private primaryActions: IAction[]; private secondaryActions: IAction[]; private groupByServerAction: IAction; private disposables: IDisposable[] = []; - private monacoStyleContainer: HTMLDivElement; - private placeholderText: HTMLDivElement; constructor( @IPartService partService: IPartService, @@ -290,8 +273,7 @@ export class ExtensionsViewlet extends ViewContainerViewlet implements IExtensio @IContextKeyService contextKeyService: IContextKeyService, @IContextMenuService contextMenuService: IContextMenuService, @IExtensionService extensionService: IExtensionService, - @IExtensionManagementServerService private extensionManagementServerService: IExtensionManagementServerService, - @IModelService private modelService: IModelService, + @IExtensionManagementServerService private extensionManagementServerService: IExtensionManagementServerService ) { super(VIEWLET_ID, `${VIEWLET_ID}.state`, true, partService, telemetryService, storageService, instantiationService, themeService, contextMenuService, extensionService, contextService); @@ -315,28 +297,6 @@ export class ExtensionsViewlet extends ViewContainerViewlet implements IExtensio this.defaultRecommendedExtensionsContextKey.set(!this.configurationService.getValue(ShowRecommendationsOnlyOnDemandKey)); } }, this, this.disposables); - - modes.SuggestRegistry.register({ scheme: 'extensions', pattern: '**/searchinput', hasAccessToAllModels: true }, { - triggerCharacters: ['@'], - provideCompletionItems: (model: ITextModel, position: Position, _context: modes.SuggestContext) => { - const sortKey = (item: string) => { - if (item.indexOf(':') === -1) { return 'a'; } - else if (/ext:/.test(item) || /tag:/.test(item)) { return 'b'; } - else if (/sort:/.test(item)) { return 'c'; } - else { return 'd'; } - }; - return { - suggestions: this.autoComplete(model.getValue(), position.column).map(item => ( - { - label: item.fullText, - insertText: item.fullText, - overwriteBefore: item.overwrite, - sortText: sortKey(item.fullText), - type: 'keyword' - })) - }; - } - }); } create(parent: HTMLElement): TPromise { @@ -344,51 +304,32 @@ export class ExtensionsViewlet extends ViewContainerViewlet implements IExtensio this.root = parent; const header = append(this.root, $('.header')); - this.monacoStyleContainer = append(header, $('.monaco-container')); - this.searchBox = this.instantiationService.createInstance(CodeEditorWidget, this.monacoStyleContainer, - mixinHTMLInputStyleOptions(getSimpleEditorOptions(), localize('searchExtensions', "Search Extensions in Marketplace")), - { - isSimpleWidget: true, contributions: [ - SuggestController, - SnippetController2, - ContextMenuController, - MenuPreventer - ] - }); - this.placeholderText = append(this.monacoStyleContainer, $('.search-placeholder', null, localize('searchExtensions', "Search Extensions in Marketplace"))); + const placeholder = localize('searchExtensions', "Search Extensions in Marketplace"); + + this.searchBox = this.instantiationService.createInstance(SuggestEnabledInput, `${VIEWLET_ID}.searchbox`, header, { + triggerCharacters: ['@'], + sortKey: item => { + if (item.indexOf(':') === -1) { return 'a'; } + else if (/ext:/.test(item) || /tag:/.test(item)) { return 'b'; } + else if (/sort:/.test(item)) { return 'c'; } + else { return 'd'; } + }, + provideResults: (query) => Query.suggestions(query) + }, placeholder, 'extensions:searchinput', { placeholderText: placeholder }); + + this.disposables.push(this.searchBox); + + const _searchChange = new Emitter(); + this.onSearchChange = _searchChange.event; + this.searchBox.onInputDidChange(() => { + this.triggerSearch(); + _searchChange.fire(this.searchBox.getValue()); + }, this, this.disposables); + + this.searchBox.onShouldFocusResults(() => this.focusListView(), this, this.disposables); this.extensionsBox = append(this.root, $('.extensions')); - - this.searchBox.setModel(this.modelService.createModel('', null, uri.parse('extensions:searchinput'), true)); - - this.disposables.push(this.searchBox.onDidPaste(() => { - let trimmed = this.searchBox.getValue().replace(/\s+/g, ' '); - this.searchBox.setValue(trimmed); - this.searchBox.setScrollTop(0); - this.searchBox.setPosition(new Position(1, trimmed.length + 1)); - })); - - this.disposables.push(this.searchBox.onDidFocusEditorText(() => addClass(this.monacoStyleContainer, 'synthetic-focus'))); - this.disposables.push(this.searchBox.onDidBlurEditorText(() => removeClass(this.monacoStyleContainer, 'synthetic-focus'))); - - const onKeyDownMonaco = chain(this.searchBox.onKeyDown); - onKeyDownMonaco.filter(e => e.keyCode === KeyCode.Enter).on(e => e.preventDefault(), this, this.disposables); - onKeyDownMonaco.filter(e => e.keyCode === KeyCode.DownArrow && (isMacintosh ? e.metaKey : e.ctrlKey)).on(() => this.focusListView(), this, this.disposables); - - const searchChangeEvent = new Emitter(); - this.onSearchChange = searchChangeEvent.event; - - let existingContent = this.searchBox.getValue().trim(); - this.disposables.push(this.searchBox.getModel().onDidChangeContent(() => { - this.placeholderText.style.visibility = this.searchBox.getValue() ? 'hidden' : 'visible'; - let content = this.searchBox.getValue().trim(); - if (existingContent === content) { return; } - this.triggerSearch(); - searchChangeEvent.fire(content); - existingContent = content; - })); - return super.create(this.extensionsBox) .then(() => this.extensionManagementService.getInstalled(LocalExtensionType.User)) .then(installed => { @@ -401,20 +342,7 @@ export class ExtensionsViewlet extends ViewContainerViewlet implements IExtensio public updateStyles(): void { super.updateStyles(); - - this.monacoStyleContainer.style.backgroundColor = this.getColor(inputBackground); - this.monacoStyleContainer.style.color = this.getColor(inputForeground); - this.placeholderText.style.color = this.getColor(inputPlaceholderForeground); - - const inputBorderColor = this.getColor(inputBorder); - this.monacoStyleContainer.style.borderWidth = inputBorderColor ? '1px' : null; - this.monacoStyleContainer.style.borderStyle = inputBorderColor ? 'solid' : null; - this.monacoStyleContainer.style.borderColor = inputBorderColor; - - let cursor = this.monacoStyleContainer.getElementsByClassName('cursor')[0] as HTMLDivElement; - if (cursor) { - cursor.style.backgroundColor = this.getColor(inputForeground); - } + this.searchBox.updateStyles(); } setVisible(visible: boolean): TPromise { @@ -423,7 +351,7 @@ export class ExtensionsViewlet extends ViewContainerViewlet implements IExtensio if (isVisibilityChanged) { if (visible) { this.searchBox.focus(); - this.searchBox.setSelection(new Range(1, 1, 1, this.searchBox.getValue().length + 1)); + this.searchBox.selectAll(); } } }); @@ -436,8 +364,6 @@ export class ExtensionsViewlet extends ViewContainerViewlet implements IExtensio layout(dimension: Dimension): void { toggleClass(this.root, 'narrow', dimension.width <= 300); this.searchBox.layout({ height: 20, width: dimension.width - 34 }); - this.placeholderText.style.width = '' + (dimension.width - 30) + 'px'; - super.layout(new Dimension(dimension.width, dimension.height - 38)); } @@ -493,7 +419,6 @@ export class ExtensionsViewlet extends ViewContainerViewlet implements IExtensio event.immediate = true; this.searchBox.setValue(value); - this.searchBox.setPosition(new Position(1, value.length + 1)); } private triggerSearch(immediate = false): void { @@ -501,7 +426,7 @@ export class ExtensionsViewlet extends ViewContainerViewlet implements IExtensio } private normalizedQuery(): string { - return (this.searchBox.getValue() || '').replace(/@category/g, 'category').replace(/@tag:/g, 'tag:').replace(/@ext:/g, 'ext:'); + return this.searchBox.getValue().replace(/@category/g, 'category').replace(/@tag:/g, 'tag:').replace(/@ext:/g, 'ext:'); } private doSearch(): TPromise { @@ -539,16 +464,6 @@ export class ExtensionsViewlet extends ViewContainerViewlet implements IExtensio return this.instantiationService.createInstance(viewDescriptor.ctor, options) as ViewletPanel; } - private autoComplete(query: string, position: number): { fullText: string, overwrite: number }[] { - let wordStart = query.lastIndexOf(' ', position - 1) + 1; - let alreadyTypedCount = position - wordStart - 1; - - // dont show autosuggestions if the user has typed something, but hasn't used the trigger character - if (alreadyTypedCount > 0 && query[wordStart] !== '@') { return []; } - - return Query.autocompletions(query).map(replacement => ({ fullText: replacement, overwrite: alreadyTypedCount })); - } - private count(): number { return this.panels.reduce((count, view) => (view).count() + count, 0); } @@ -690,18 +605,4 @@ export class MaliciousExtensionChecker implements IWorkbenchContribution { dispose(): void { this.disposables = dispose(this.disposables); } -} - -function mixinHTMLInputStyleOptions(config: IEditorOptions, ariaLabel?: string): IEditorOptions { - config.fontSize = 13; - config.lineHeight = 22; - config.wordWrap = 'off'; - config.scrollbar.vertical = 'hidden'; - config.ariaLabel = ariaLabel || ''; - config.renderIndentGuides = false; - config.cursorWidth = 1; - config.snippetSuggestions = 'none'; - config.suggest = { filterGraceful: false }; - config.fontFamily = ' -apple-system, BlinkMacSystemFont, "Segoe WPC", "Segoe UI", "HelveticaNeue-Light", "Ubuntu", "Droid Sans", sans-serif'; - return config; -} +} \ No newline at end of file diff --git a/src/vs/workbench/parts/extensions/electron-browser/media/extensionsViewlet.css b/src/vs/workbench/parts/extensions/electron-browser/media/extensionsViewlet.css index 98e419e22e2..e8e11338689 100644 --- a/src/vs/workbench/parts/extensions/electron-browser/media/extensionsViewlet.css +++ b/src/vs/workbench/parts/extensions/electron-browser/media/extensionsViewlet.css @@ -202,32 +202,6 @@ opacity: 0.9; } -.extensions-viewlet .header .monaco-container { - padding: 3px 4px 5px; -} - -.extensions-viewlet .header .monaco-container .suggest-widget { - width: 275px; -} - -.extensions-viewlet .header .monaco-container .monaco-editor-background, -.extensions-viewlet .header .monaco-container .monaco-editor, -.extensions-viewlet .header .monaco-container .mtk1 { - /* allow the embedded monaco to be styled from the outer context */ - background-color: inherit; - color: inherit; -} - -.extensions-viewlet .header .search-placeholder { - position: absolute; - z-index: 1; - overflow: hidden; - white-space: nowrap; - text-overflow: ellipsis; - pointer-events: none; - margin-top: 2px; -} - .vs .extensions-viewlet > .extensions .monaco-list-row.disabled > .bookmark, .vs-dark .extensions-viewlet > .extensions .monaco-list-row.disabled > .bookmark, .vs .extensions-viewlet > .extensions .monaco-list-row.disabled > .extension > .icon, diff --git a/src/vs/workbench/parts/extensions/test/common/extensionQuery.test.ts b/src/vs/workbench/parts/extensions/test/common/extensionQuery.test.ts index a3ba946041f..f107018c53d 100644 --- a/src/vs/workbench/parts/extensions/test/common/extensionQuery.test.ts +++ b/src/vs/workbench/parts/extensions/test/common/extensionQuery.test.ts @@ -142,10 +142,10 @@ suite('Extension query', () => { }); test('autocomplete', () => { - Query.autocompletions('@sort:in').some(x => x === '@sort:installs '); - Query.autocompletions('@sort:installs').every(x => x !== '@sort:rating '); + Query.suggestions('@sort:in').some(x => x === '@sort:installs '); + Query.suggestions('@sort:installs').every(x => x !== '@sort:rating '); - Query.autocompletions('@category:blah').some(x => x === '@category:"extension packs" '); - Query.autocompletions('@category:"extension packs"').every(x => x !== '@category:formatters '); + Query.suggestions('@category:blah').some(x => x === '@category:"extension packs" '); + Query.suggestions('@category:"extension packs"').every(x => x !== '@category:formatters '); }); }); \ No newline at end of file diff --git a/src/vs/workbench/parts/preferences/browser/media/settingsEditor2.css b/src/vs/workbench/parts/preferences/browser/media/settingsEditor2.css index 58f332fb562..1d3aff5f07d 100644 --- a/src/vs/workbench/parts/preferences/browser/media/settingsEditor2.css +++ b/src/vs/workbench/parts/preferences/browser/media/settingsEditor2.css @@ -39,24 +39,6 @@ margin-right: 7px; } -.settings-editor > .settings-header > .search-container { - position: relative; -} - -.settings-editor > .settings-header .search-container > .settings-search-input { - vertical-align: middle; -} - -.settings-editor > .settings-header .search-container > .settings-search-input > .monaco-inputbox { - height: 30px; - width: 100%; -} - -.settings-editor > .settings-header .search-container .settings-search-input > .monaco-inputbox .input { - font-size: 14px; - padding-left: 7px; -} - .settings-editor > .settings-header > .settings-header-controls { height: 32px; display: flex; diff --git a/src/vs/workbench/parts/preferences/browser/settingsEditor2.ts b/src/vs/workbench/parts/preferences/browser/settingsEditor2.ts index baa97db5544..2b8114c77af 100644 --- a/src/vs/workbench/parts/preferences/browser/settingsEditor2.ts +++ b/src/vs/workbench/parts/preferences/browser/settingsEditor2.ts @@ -32,7 +32,7 @@ import { IThemeService } from 'vs/platform/theme/common/themeService'; import { BaseEditor } from 'vs/workbench/browser/parts/editor/baseEditor'; import { EditorOptions, IEditor } from 'vs/workbench/common/editor'; import { PreferencesEditor } from 'vs/workbench/parts/preferences/browser/preferencesEditor'; -import { SearchWidget, SettingsTarget, SettingsTargetsWidget } from 'vs/workbench/parts/preferences/browser/preferencesWidgets'; +import { SettingsTarget, SettingsTargetsWidget } from 'vs/workbench/parts/preferences/browser/preferencesWidgets'; import { commonlyUsedData, tocData } from 'vs/workbench/parts/preferences/browser/settingsLayout'; import { ISettingsEditorViewState, MODIFIED_SETTING_TAG, ONLINE_SERVICES_SETTING_TAG, resolveExtensionsSettings, resolveSettingsTree, SearchResultIdx, SearchResultModel, SettingsRenderer, SettingsTree, SettingsTreeElement, SettingsTreeGroupElement, SettingsTreeModel, SettingsTreeSettingElement } from 'vs/workbench/parts/preferences/browser/settingsTree'; import { TOCRenderer, TOCTree, TOCTreeModel } from 'vs/workbench/parts/preferences/browser/tocTree'; @@ -40,6 +40,8 @@ import { CONTEXT_SETTINGS_EDITOR, CONTEXT_SETTINGS_SEARCH_FOCUS, CONTEXT_TOC_ROW import { IPreferencesService, ISearchResult, ISettingsEditorModel } from 'vs/workbench/services/preferences/common/preferences'; import { SettingsEditor2Input } from 'vs/workbench/services/preferences/common/preferencesEditorInput'; import { DefaultSettingsEditorModel } from 'vs/workbench/services/preferences/common/preferencesModels'; +import { SuggestEnabledInput } from 'vs/workbench/parts/codeEditor/browser/suggestEnabledInput'; +import { IEditorGroup } from 'vs/workbench/services/group/common/editorGroupsService'; const $ = DOM.$; @@ -51,7 +53,7 @@ export class SettingsEditor2 extends BaseEditor { private rootElement: HTMLElement; private headerContainer: HTMLElement; - private searchWidget: SearchWidget; + private searchWidget: SuggestEnabledInput; private settingsTargetsWidget: SettingsTargetsWidget; private toolbar: ToolBar; @@ -121,6 +123,7 @@ export class SettingsEditor2 extends BaseEditor { this.createHeader(this.rootElement); this.createBody(this.rootElement); + this.updateStyles(); } setInput(input: SettingsEditor2Input, options: EditorOptions, token: CancellationToken): Thenable { @@ -138,9 +141,12 @@ export class SettingsEditor2 extends BaseEditor { } layout(dimension: DOM.Dimension): void { - this.searchWidget.layout(dimension); this.layoutTrees(dimension); + let innerWidth = dimension.width - 24 * 2; // 24px padding on left and right + let monacoWidth = (innerWidth > 1000 ? 1000 : innerWidth - 10); + this.searchWidget.layout({ height: 20, width: monacoWidth }); + DOM.toggleClass(this.rootElement, 'narrow', dimension.width < 600); this.delayRefreshOnLayout.trigger(() => this.refreshTreeAndMaintainFocus()); @@ -162,7 +168,7 @@ export class SettingsEditor2 extends BaseEditor { } clearSearchResults(): void { - this.searchWidget.clear(); + this.searchWidget.setValue(''); } search(text: string): void { @@ -184,13 +190,20 @@ export class SettingsEditor2 extends BaseEditor { previewTextLabel.textContent = localize('previewLabel', "This is a preview of our new settings editor"); const searchContainer = DOM.append(this.headerContainer, $('.search-container')); - this.searchWidget = this._register(this.instantiationService.createInstance(SearchWidget, searchContainer, { - ariaLabel: localize('SearchSettings.AriaLabel', "Search settings"), - placeholder: localize('SearchSettings.Placeholder', "Search settings"), - focusKey: this.searchFocusContextKey, - ariaLive: 'assertive' - })); - this._register(this.searchWidget.onDidChange(() => this.onSearchInputChanged())); + + let searchBoxLabel = localize('SearchSettings.AriaLabel', "Search settings"); + this.searchWidget = this._register(this.instantiationService.createInstance(SuggestEnabledInput, `${SettingsEditor2.ID}.searchbox`, searchContainer, { + triggerCharacters: ['@'], + provideResults: (query: string) => { + return ['@modified', '@tag:usesOnlineServices'].filter(tag => query.indexOf(tag) === -1).map(tag => tag + ' '); + } + }, searchBoxLabel, 'settingseditor:searchinput', { + placeholderText: searchBoxLabel, + focusContextKey: this.searchFocusContextKey, + // TODO: Aria-live + })); + + this._register(this.searchWidget.onInputDidChange(() => this.onSearchInputChanged())); const headerControlsContainer = DOM.append(this.headerContainer, $('.settings-header-controls')); const targetWidgetContainer = DOM.append(headerControlsContainer, $('.settings-target-container')); @@ -818,6 +831,20 @@ export class SettingsEditor2 extends BaseEditor { this.settingsTreeRenderer.updateWidth(dimension.width); } + + public updateStyles(): void { + super.updateStyles(); + this.searchWidget.updateStyles(); + } + + setVisible(visible: boolean, group?: IEditorGroup): TPromise { + if (visible) { + this.searchWidget.focus(); + this.searchWidget.selectAll(); + } + + return TPromise.as(super.setVisible(visible, group)); + } } interface ISettingsToolbarContext { diff --git a/src/vs/workbench/parts/preferences/electron-browser/preferences.contribution.ts b/src/vs/workbench/parts/preferences/electron-browser/preferences.contribution.ts index 12f455b6224..fcc7e381afe 100644 --- a/src/vs/workbench/parts/preferences/electron-browser/preferences.contribution.ts +++ b/src/vs/workbench/parts/preferences/electron-browser/preferences.contribution.ts @@ -35,6 +35,7 @@ import { LifecyclePhase } from 'vs/platform/lifecycle/common/lifecycle'; import { PreferencesSearchService } from 'vs/workbench/parts/preferences/electron-browser/preferencesSearch'; import { IPreferencesService } from 'vs/workbench/services/preferences/common/preferences'; import { Command } from 'vs/editor/browser/editorExtensions'; +import { Context as SuggestContext } from 'vs/editor/contrib/suggest/suggest'; registerSingleton(IPreferencesSearchService, PreferencesSearchService); @@ -384,14 +385,14 @@ class FocusSettingsFileEditorCommand extends SettingsCommand { } const focusSettingsFileEditorCommand = new FocusSettingsFileEditorCommand({ id: SETTINGS_EDITOR_COMMAND_FOCUS_FILE, - precondition: CONTEXT_SETTINGS_SEARCH_FOCUS, + precondition: ContextKeyExpr.and(CONTEXT_SETTINGS_SEARCH_FOCUS, SuggestContext.Visible.toNegated()), kbOpts: { primary: KeyCode.DownArrow, weight: KeybindingWeight.EditorContrib } }); focusSettingsFileEditorCommand.register(); const focusSettingsFromSearchCommand = new FocusSettingsFileEditorCommand({ id: SETTINGS_EDITOR_COMMAND_FOCUS_SETTINGS_FROM_SEARCH, - precondition: CONTEXT_SETTINGS_SEARCH_FOCUS, + precondition: ContextKeyExpr.and(CONTEXT_SETTINGS_SEARCH_FOCUS, SuggestContext.Visible.toNegated()), kbOpts: { primary: KeyCode.DownArrow, weight: KeybindingWeight.WorkbenchContrib } }); focusSettingsFromSearchCommand.register(); From 37755faeb67675f7924353c06d0be30a05e2fdfa Mon Sep 17 00:00:00 2001 From: Joao Moreno Date: Fri, 10 Aug 2018 23:15:27 +0200 Subject: [PATCH 0690/1276] tree: fix expand/collapse --- src/vs/base/browser/ui/tree/tree.ts | 6 ++- src/vs/base/browser/ui/tree/treeModel.ts | 55 +++++++++++++----------- test/tree/public/index.html | 4 ++ test/tree/server.js | 2 +- 4 files changed, 41 insertions(+), 26 deletions(-) diff --git a/src/vs/base/browser/ui/tree/tree.ts b/src/vs/base/browser/ui/tree/tree.ts index a90726815f7..1b020fee6e7 100644 --- a/src/vs/base/browser/ui/tree/tree.ts +++ b/src/vs/base/browser/ui/tree/tree.ts @@ -60,6 +60,7 @@ class TreeDelegate implements IVirtualDelegate> { interface ITreeListTemplateData { twistie: HTMLElement; + count: HTMLElement; templateData: T; } @@ -89,9 +90,10 @@ class TreeRenderer implements IRenderer, ITreeLis const el = append(container, $('.monaco-tl-row')); const twistie = append(el, $('.tl-twistie')); const contents = append(el, $('.tl-contents')); + const count = append(el, $('.tl-count')); const templateData = this.renderer.renderTemplate(contents); - return { twistie, templateData }; + return { twistie, count, templateData }; } renderElement(node: ITreeNode, index: number, templateData: ITreeListTemplateData): void { @@ -99,6 +101,7 @@ class TreeRenderer implements IRenderer, ITreeLis templateData.twistie.style.width = `${10 + node.depth * 10}px`; renderTwistie(node, templateData.twistie); + templateData.count.textContent = `${node.visibleCount}`; this.renderer.renderElement(node.element, index, templateData.templateData); } @@ -119,6 +122,7 @@ class TreeRenderer implements IRenderer, ITreeLis } renderTwistie(node, templateData.twistie); + templateData.count.textContent = `${node.visibleCount}`; } dispose(): void { diff --git a/src/vs/base/browser/ui/tree/treeModel.ts b/src/vs/base/browser/ui/tree/treeModel.ts index 1a30ff92292..7d8e2b70c98 100644 --- a/src/vs/base/browser/ui/tree/treeModel.ts +++ b/src/vs/base/browser/ui/tree/treeModel.ts @@ -39,13 +39,35 @@ function getVisibleCount(nodes: IMutableTreeNode[]): number { return nodes.reduce(visibleCountReducer, 0); } -function getVisibleNodes(nodes: IMutableTreeNode[], result: ITreeNode[] = []): ITreeNode[] { - for (const node of nodes) { +/** + * Recursively updates the visibleCount of a subtree, while collecting + * all the visible nodes in an array. + */ +function updateVisibleCount(node: IMutableTreeNode): ITreeNode[] { + const previousVisibleCount = node.visibleCount; + const result: ITreeNode[] = []; + + function _updateVisibleCount(node: IMutableTreeNode): number { result.push(node); + node.visibleCount = 1; if (!node.collapsed) { - getVisibleNodes(node.children, result); + for (const child of node.children) { + node.visibleCount += _updateVisibleCount(child); + } } + + return node.visibleCount; + } + + _updateVisibleCount(node); + + const visibleCountDiff = result.length - previousVisibleCount; + node = node.parent; + + while (node) { + node.visibleCount += visibleCountDiff; + node = node.parent; } return result; @@ -108,6 +130,7 @@ export class TreeModel { visibleCount: 1 }; + // TODO@joao can't we do without this? private _onDidChangeCollapseState = new Emitter>(); readonly onDidChangeCollapseState: Event> = this._onDidChangeCollapseState.event; @@ -165,30 +188,14 @@ export class TreeModel { node.collapsed = collapsed; if (visible) { - this._onDidChangeCollapseState.fire(node); + const previousVisibleCount = node.visibleCount; + const toInsert = updateVisibleCount(node); - let visibleCountDiff: number; - - if (collapsed) { - const deleteCount = getVisibleCount(node.children); - - this.list.splice(listIndex + 1, deleteCount, []); - visibleCountDiff = -deleteCount; - } else { - const toInsert = getVisibleNodes(node.children); - - this.list.splice(listIndex + 1, 0, toInsert); - visibleCountDiff = toInsert.length; - } - - let mutableNode = node; - - while (mutableNode) { - mutableNode.visibleCount += visibleCountDiff; - mutableNode = mutableNode.parent; - } + this.list.splice(listIndex + 1, previousVisibleCount - 1, toInsert.slice(1)); } + this._onDidChangeCollapseState.fire(node); + return true; } diff --git a/test/tree/public/index.html b/test/tree/public/index.html index f676b7a8753..3716374c0de 100644 --- a/test/tree/public/index.html +++ b/test/tree/public/index.html @@ -13,6 +13,10 @@ .monaco-scrollable-element>.scrollbar>.slider { background: rgba(100, 100, 100, .4); } + + .tl-contents { + flex: 1; + } diff --git a/test/tree/server.js b/test/tree/server.js index b1105bfb741..11ac8e1ac9b 100644 --- a/test/tree/server.js +++ b/test/tree/server.js @@ -17,7 +17,7 @@ async function getTree(fsPath, level) { const element = path.basename(fsPath); const stat = await fs.stat(fsPath); - if (!stat.isDirectory() || element === '.git' || element === '.build' || level >= 3) { + if (!stat.isDirectory() || element === '.git' || element === '.build' || level >= 4) { return { element }; } From da1b0b3830208130b7aace4ee1cae73dc085df31 Mon Sep 17 00:00:00 2001 From: Martin Aeschlimann Date: Fri, 10 Aug 2018 23:29:07 +0200 Subject: [PATCH 0691/1276] [theme] only restore colors if base theme matches --- .../themes/electron-browser/colorThemeData.ts | 7 +++++-- .../electron-browser/workbenchThemeService.ts | 18 +++++++++++++++--- 2 files changed, 20 insertions(+), 5 deletions(-) diff --git a/src/vs/workbench/services/themes/electron-browser/colorThemeData.ts b/src/vs/workbench/services/themes/electron-browser/colorThemeData.ts index d9b1331feda..f49ab6eea33 100644 --- a/src/vs/workbench/services/themes/electron-browser/colorThemeData.ts +++ b/src/vs/workbench/services/themes/electron-browser/colorThemeData.ts @@ -189,9 +189,12 @@ export class ColorThemeData implements IColorTheme { return objects.equals(this.colorMap, other.colorMap) && objects.equals(this.tokenColors, other.tokenColors); } + get baseTheme(): string { + return this.id.split(' ')[0]; + } + get type(): ThemeType { - let baseTheme = this.id.split(' ')[0]; - switch (baseTheme) { + switch (this.baseTheme) { case VS_LIGHT_THEME: return 'light'; case VS_HC_THEME: return 'hc'; default: return 'dark'; diff --git a/src/vs/workbench/services/themes/electron-browser/workbenchThemeService.ts b/src/vs/workbench/services/themes/electron-browser/workbenchThemeService.ts index 91c55890363..7246d69e9cc 100644 --- a/src/vs/workbench/services/themes/electron-browser/workbenchThemeService.ts +++ b/src/vs/workbench/services/themes/electron-browser/workbenchThemeService.ts @@ -126,9 +126,9 @@ export class WorkbenchThemeService implements IWorkbenchThemeService { if (persistedThemeData) { themeData = ColorThemeData.fromStorageData(persistedThemeData); } - if (!themeData) { - let isLightTheme = (Array.prototype.indexOf.call(document.body.classList, 'vs') >= 0); - themeData = ColorThemeData.createUnloadedTheme(isLightTheme ? VS_LIGHT_THEME : VS_DARK_THEME); + let containerBaseTheme = this.getBaseThemeFromContainer(); + if (!themeData || themeData && themeData.baseTheme !== containerBaseTheme) { + themeData = ColorThemeData.createUnloadedTheme(containerBaseTheme); } themeData.setCustomColors(this.colorCustomizations); themeData.setCustomTokenColors(this.tokenColorCustomizations); @@ -440,6 +440,18 @@ export class WorkbenchThemeService implements IWorkbenchThemeService { } return this._configurationWriter; } + + private getBaseThemeFromContainer() { + if (this.container) { + for (let i = this.container.classList.length - 1; i >= 0; i--) { + const item = document.body.classList.item(i); + if (item === VS_LIGHT_THEME || item === VS_DARK_THEME || item === VS_HC_THEME) { + return item; + } + } + } + return VS_DARK_THEME; + } } function _applyIconTheme(data: FileIconThemeData, onApply: (theme: FileIconThemeData) => TPromise): TPromise { From f6f4d3f5d78e2bbb3fbc27d074da348e231aa875 Mon Sep 17 00:00:00 2001 From: Martin Aeschlimann Date: Fri, 10 Aug 2018 23:40:57 +0200 Subject: [PATCH 0692/1276] [themes] When exiting High Contrast, restore previous color theme. Fixes #46862 --- src/vs/workbench/electron-browser/window.ts | 4 ++-- .../services/themes/common/workbenchThemeService.ts | 1 + .../themes/electron-browser/workbenchThemeService.ts | 11 +++++++++++ 3 files changed, 14 insertions(+), 2 deletions(-) diff --git a/src/vs/workbench/electron-browser/window.ts b/src/vs/workbench/electron-browser/window.ts index f46b093c862..2bcb79cc83d 100644 --- a/src/vs/workbench/electron-browser/window.ts +++ b/src/vs/workbench/electron-browser/window.ts @@ -22,7 +22,7 @@ import { IWorkspaceConfigurationService } from 'vs/workbench/services/configurat import { IWindowsService, IWindowService, IWindowSettings, IPath, IOpenFileRequest, IWindowsConfiguration, IAddFoldersRequest, IRunActionInWindowRequest } from 'vs/platform/windows/common/windows'; import { IContextMenuService } from 'vs/platform/contextview/browser/contextView'; import { ITitleService } from 'vs/workbench/services/title/common/titleService'; -import { IWorkbenchThemeService, VS_HC_THEME, VS_DARK_THEME } from 'vs/workbench/services/themes/common/workbenchThemeService'; +import { IWorkbenchThemeService, VS_HC_THEME } from 'vs/workbench/services/themes/common/workbenchThemeService'; import * as browser from 'vs/base/browser/browser'; import { ICommandService } from 'vs/platform/commands/common/commands'; import { IResourceInput } from 'vs/platform/editor/common/editor'; @@ -203,7 +203,7 @@ export class ElectronWindow extends Themable { const windowConfig = this.configurationService.getValue('window'); if (windowConfig && windowConfig.autoDetectHighContrast) { this.lifecycleService.when(LifecyclePhase.Running).then(() => { - this.themeService.setColorTheme(VS_DARK_THEME, null); + this.themeService.restoreColorTheme(); }); } }); diff --git a/src/vs/workbench/services/themes/common/workbenchThemeService.ts b/src/vs/workbench/services/themes/common/workbenchThemeService.ts index 8d8a6df7b78..fb288d66132 100644 --- a/src/vs/workbench/services/themes/common/workbenchThemeService.ts +++ b/src/vs/workbench/services/themes/common/workbenchThemeService.ts @@ -59,6 +59,7 @@ export interface IWorkbenchThemeService extends IThemeService { getColorTheme(): IColorTheme; getColorThemes(): TPromise; onDidColorThemeChange: Event; + restoreColorTheme(); setFileIconTheme(iconThemeId: string, settingsTarget: ConfigurationTarget): TPromise; getFileIconTheme(): IFileIconTheme; diff --git a/src/vs/workbench/services/themes/electron-browser/workbenchThemeService.ts b/src/vs/workbench/services/themes/electron-browser/workbenchThemeService.ts index 7246d69e9cc..91a9a231ffa 100644 --- a/src/vs/workbench/services/themes/electron-browser/workbenchThemeService.ts +++ b/src/vs/workbench/services/themes/electron-browser/workbenchThemeService.ts @@ -301,6 +301,17 @@ export class WorkbenchThemeService implements IWorkbenchThemeService { }); } + public restoreColorTheme() { + let colorThemeSetting = this.configurationService.getValue(COLOR_THEME_SETTING); + if (colorThemeSetting !== this.currentColorTheme.settingsId) { + this.colorThemeStore.findThemeDataBySettingsId(colorThemeSetting, null).then(theme => { + if (theme) { + this.setColorTheme(theme.id, null); + } + }); + } + } + private updateDynamicCSSRules(themeData: ITheme) { let cssRules: string[] = []; let hasRule: { [rule: string]: boolean } = {}; From a19b523e5a04bcd91d339a9fc41236e464f9a66b Mon Sep 17 00:00:00 2001 From: Jackson Kearl Date: Fri, 10 Aug 2018 16:03:18 -0700 Subject: [PATCH 0693/1276] Add MessageBox-styled validation --- .../browser/media/settingsEditor2.css | 33 +++++++++- .../parts/preferences/browser/settingsTree.ts | 60 ++++++++++++------- .../preferences/common/preferencesModels.ts | 23 +++---- 3 files changed, 82 insertions(+), 34 deletions(-) diff --git a/src/vs/workbench/parts/preferences/browser/media/settingsEditor2.css b/src/vs/workbench/parts/preferences/browser/media/settingsEditor2.css index 259f9a10bab..01b21cac434 100644 --- a/src/vs/workbench/parts/preferences/browser/media/settingsEditor2.css +++ b/src/vs/workbench/parts/preferences/browser/media/settingsEditor2.css @@ -223,6 +223,10 @@ position: relative; } +.settings-editor > .settings-body > .settings-tree-container .monaco-tree-row { + overflow: visible; /* so validation messages dont get clipped */ +} + .settings-editor > .settings-body > .settings-tree-container .setting-item { padding-top: 12px; padding-bottom: 18px; @@ -262,7 +266,7 @@ opacity: 0.9; } -.settings-editor > .settings-body > .settings-tree-container .setting-item .setting-item-validation-message, +.settings-editor > .settings-body > .settings-tree-container .setting-item .setting-item-deprecation-message, .settings-editor > .settings-body > .settings-tree-container .setting-item .setting-item-description { margin-top: 3px; overflow: hidden; @@ -274,6 +278,31 @@ transform: translate3d(0px, 0px, 0px); } +.settings-editor > .settings-body > .settings-tree-container .setting-item .setting-item-deprecation-message { + position: absolute; +} + +.settings-editor > .settings-body > .settings-tree-container .setting-item .setting-item-validation-message { + display: none; +} + +.settings-editor > .settings-body > .settings-tree-container .setting-item.invalid-input .setting-item-validation-message { + display: block; + position: absolute; + padding: 5px; + box-sizing: border-box; + margin-top: -1px; + z-index: 1; +} + +.settings-editor > .settings-body > .settings-tree-container .setting-item.setting-item-text .setting-item-validation-message { + width: 500px; +} + +.settings-editor > .settings-body > .settings-tree-container .setting-item.setting-item-number .setting-item-validation-message { + width: 200px; +} + .settings-editor > .settings-body > .settings-tree-container .setting-item .setting-item-description-markdown * { margin: 0px; } @@ -294,8 +323,6 @@ } .settings-editor > .settings-body > .settings-tree-container .setting-item.is-expanded .setting-item-description, -.settings-editor > .settings-body > .settings-tree-container .setting-item.is-expanded .setting-item-validation-message, -.settings-editor > .settings-body > .settings-tree-container .setting-item.setting-measure-helper .setting-item-validation-message, .settings-editor > .settings-body > .settings-tree-container .setting-item.setting-measure-helper .setting-item-description { height: initial; -webkit-line-clamp: initial; diff --git a/src/vs/workbench/parts/preferences/browser/settingsTree.ts b/src/vs/workbench/parts/preferences/browser/settingsTree.ts index e0c88c9d6d9..42c928f3dd8 100644 --- a/src/vs/workbench/parts/preferences/browser/settingsTree.ts +++ b/src/vs/workbench/parts/preferences/browser/settingsTree.ts @@ -9,7 +9,7 @@ import { StandardKeyboardEvent } from 'vs/base/browser/keyboardEvent'; import { IMouseEvent } from 'vs/base/browser/mouseEvent'; import { Button } from 'vs/base/browser/ui/button/button'; import { Checkbox } from 'vs/base/browser/ui/checkbox/checkbox'; -import { InputBox, MessageType, IInputValidator } from 'vs/base/browser/ui/inputbox/inputBox'; +import { InputBox } from 'vs/base/browser/ui/inputbox/inputBox'; import { SelectBox } from 'vs/base/browser/ui/selectBox/selectBox'; import * as arrays from 'vs/base/common/arrays'; import { Color, RGBA } from 'vs/base/common/color'; @@ -32,7 +32,7 @@ import { IContextViewService } from 'vs/platform/contextview/browser/contextView import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; import { IListService, WorkbenchTreeController } from 'vs/platform/list/browser/listService'; import { IOpenerService } from 'vs/platform/opener/common/opener'; -import { editorBackground, focusBorder, foreground, errorForeground } from 'vs/platform/theme/common/colorRegistry'; +import { editorBackground, focusBorder, foreground, errorForeground, inputValidationErrorBackground, inputValidationErrorBorder } from 'vs/platform/theme/common/colorRegistry'; import { attachButtonStyler, attachInputBoxStyler, attachSelectBoxStyler, attachStyler } from 'vs/platform/theme/common/styler'; import { ICssStyleCollector, ITheme, IThemeService, registerThemingParticipant } from 'vs/platform/theme/common/themeService'; import { SettingsTarget } from 'vs/workbench/parts/preferences/browser/preferencesWidgets'; @@ -504,6 +504,7 @@ interface ISettingBoolItemTemplate extends ISettingItemTemplate { interface ISettingTextItemTemplate extends ISettingItemTemplate { inputBox: InputBox; + validationErrorMessageElement: HTMLElement; } type ISettingNumberItemTemplate = ISettingTextItemTemplate; @@ -741,7 +742,7 @@ export class SettingsRenderer implements ITreeRenderer { const valueElement = DOM.append(container, $('.setting-item-value')); const controlElement = DOM.append(valueElement, $('div.setting-item-control')); - const deprecationWarningElement = DOM.append(container, $('.setting-item-validation-message')); + const deprecationWarningElement = DOM.append(container, $('.setting-item-deprecation-message')); const toDispose = []; const template: ISettingItemTemplate = { @@ -780,6 +781,7 @@ export class SettingsRenderer implements ITreeRenderer { private renderSettingTextTemplate(tree: ITree, container: HTMLElement, type = 'text'): ISettingTextItemTemplate { const common = this.renderCommonTemplate(tree, container, 'text'); + const validationErrorMessageElement = DOM.append(container, $('.setting-item-validation-message')); const inputBox = new InputBox(common.controlElement, this.contextViewService); common.toDispose.push(inputBox); @@ -799,7 +801,8 @@ export class SettingsRenderer implements ITreeRenderer { const template: ISettingTextItemTemplate = { ...common, - inputBox + inputBox, + validationErrorMessageElement }; this.addSettingElementFocusHandler(template); @@ -809,6 +812,7 @@ export class SettingsRenderer implements ITreeRenderer { private renderSettingNumberTemplate(tree: ITree, container: HTMLElement): ISettingNumberItemTemplate { const common = this.renderCommonTemplate(tree, container, 'number'); + const validationErrorMessageElement = DOM.append(container, $('.setting-item-validation-message')); const inputBox = new InputBox(common.controlElement, this.contextViewService); common.toDispose.push(inputBox); @@ -828,7 +832,8 @@ export class SettingsRenderer implements ITreeRenderer { const template: ISettingNumberItemTemplate = { ...common, - inputBox + inputBox, + validationErrorMessageElement }; this.addSettingElementFocusHandler(template); @@ -850,7 +855,7 @@ export class SettingsRenderer implements ITreeRenderer { const controlElement = DOM.append(descriptionAndValueElement, $('.setting-item-bool-control')); const descriptionElement = DOM.append(descriptionAndValueElement, $('.setting-item-description')); - const deprecationWarningElement = DOM.append(container, $('.setting-item-validation-message')); + const deprecationWarningElement = DOM.append(container, $('.setting-item-deprecation-message')); const toDispose = []; const checkbox = new Checkbox({ actionClassName: 'setting-value-checkbox', isChecked: true, title: '', inputActiveOptionBorder: null }); @@ -1204,10 +1209,9 @@ export class SettingsRenderer implements ITreeRenderer { private renderText(dataElement: SettingsTreeSettingElement, template: ISettingTextItemTemplate, onChange: (value: string) => void): void { template.onChange = null; template.inputBox.value = dataElement.value; - template.inputBox.attachValidator(makeValidator(dataElement)); - template.inputBox.validate(); // for some reason this is needed on text but not number. TODO: figure out why - template.onChange = value => onChange(value); + template.onChange = value => { renderValidations(dataElement, template); onChange(value); }; + renderValidations(dataElement, template); // Setup and add ARIA attributes // Create id and label for control/input element - parent is wrapper div const id = (dataElement.displayCategory + '_' + dataElement.displayLabel).replace(/ /g, '_'); @@ -1229,13 +1233,13 @@ export class SettingsRenderer implements ITreeRenderer { private renderNumber(dataElement: SettingsTreeSettingElement, template: ISettingTextItemTemplate, onChange: (value: number) => void): void { - template.onChange = null; - template.inputBox.value = dataElement.value; - template.inputBox.attachValidator(makeValidator(dataElement)); - template.onChange = value => onChange(parseFn(value)); - const parseFn = dataElement.valueType === 'integer' ? parseInt : parseFloat; + template.onChange = null; + template.inputBox.value = dataElement.value; + template.onChange = value => { renderValidations(dataElement, template); onChange(parseFn(value)); }; + + renderValidations(dataElement, template); // Setup and add ARIA attributes // Create id and label for control/input element - parent is wrapper div const id = (dataElement.displayCategory + '_' + dataElement.displayLabel).replace(/ /g, '_'); @@ -1270,11 +1274,16 @@ export class SettingsRenderer implements ITreeRenderer { } } -function makeValidator(dataElement: SettingsTreeSettingElement): IInputValidator | null { - return value => { - let message = dataElement.setting.validator(value); - return message ? { content: message, type: MessageType.ERROR } : null; - }; +function renderValidations(dataElement: SettingsTreeSettingElement, template: ISettingTextItemTemplate) { + if (dataElement.setting.validator) { + let errMsg = dataElement.setting.validator(template.inputBox.value); + if (errMsg) { + DOM.addClass(template.containerElement, 'invalid-input'); + template.validationErrorMessageElement.innerText = errMsg; + return; + } + } + DOM.removeClass(template.containerElement, 'invalid-input'); } function cleanRenderedMarkdown(element: Node): void { @@ -1573,7 +1582,18 @@ export class SettingsTree extends NonExpandableOrSelectableTree { const errorColor = theme.getColor(errorForeground); if (errorColor) { - collector.addRule(`.settings-editor > .settings-body > .settings-tree-container .setting-item .setting-item-validation-message { color: ${errorColor}; }`); + collector.addRule(`.settings-editor > .settings-body > .settings-tree-container .setting-item .setting-item-deprecation-message { color: ${errorColor}; }`); + } + + const invalidInputBackground = theme.getColor(inputValidationErrorBackground); + if (invalidInputBackground) { + collector.addRule(`.settings-editor > .settings-body > .settings-tree-container .setting-item .setting-item-validation-message { background-color: ${invalidInputBackground}; }`); + } + + const invalidInputBorder = theme.getColor(inputValidationErrorBorder); + if (invalidInputBorder) { + collector.addRule(`.settings-editor > .settings-body > .settings-tree-container .setting-item .setting-item-validation-message { border-style:solid; border-width: 1px; border-color: ${invalidInputBorder}; }`); + collector.addRule(`.settings-editor > .settings-body > .settings-tree-container .setting-item.invalid-input .setting-item-control .monaco-inputbox.idle { outline-width: 0; border-style:solid; border-width: 1px; border-color: ${invalidInputBorder}; }`); } const headerForegroundColor = theme.getColor(settingsHeaderForeground); diff --git a/src/vs/workbench/services/preferences/common/preferencesModels.ts b/src/vs/workbench/services/preferences/common/preferencesModels.ts index 78da97898e5..fbc31b4875f 100644 --- a/src/vs/workbench/services/preferences/common/preferencesModels.ts +++ b/src/vs/workbench/services/preferences/common/preferencesModels.ts @@ -555,12 +555,6 @@ export class DefaultSettings extends Disposable { if (this.matchesScope(prop)) { const value = prop.default; const description = (prop.description || prop.markdownDescription || '').split('\n'); - if (prop.deprecationMessage) { - description.push( - '', - prop.deprecationMessage, - nls.localize('deprecatedSetting.unstable', "This setting should not be used, and will be removed in a future release.")); - } const overrides = OVERRIDE_PROPERTY_PATTERN.test(key) ? this.parseOverrideSettings(prop.default) : []; result.push({ key, @@ -773,7 +767,7 @@ export class DefaultSettingsEditorModel extends AbstractSettingsModel implements } private copySetting(setting: ISetting): ISetting { - return { + return { description: setting.description, type: setting.type, enum: setting.enum, @@ -783,7 +777,12 @@ export class DefaultSettingsEditorModel extends AbstractSettingsModel implements range: setting.range, overrides: [], overrideOf: setting.overrideOf, - tags: setting.tags + tags: setting.tags, + deprecationMessage: setting.deprecationMessage, + keyRange: undefined, + valueRange: undefined, + descriptionIsMarkdown: undefined, + descriptionRanges: undefined }; } @@ -910,8 +909,7 @@ class SettingsContentBuilder { setting.descriptionRanges = []; const descriptionPreValue = indent + '// '; - for (let line of setting.description) { - // Remove setting link tag + for (let line of (setting.deprecationMessage ? [setting.deprecationMessage] : setting.description)) { line = fixSettingLink(line); this._contentByLines.push(descriptionPreValue + line); @@ -964,7 +962,7 @@ class SettingsContentBuilder { } } -function createValidator(prop: IConfigurationPropertySchema): (value: any) => string { +function createValidator(prop: IConfigurationPropertySchema): ((value: any) => string) | null { let exclusiveMax: number | undefined; let exclusiveMin: number | undefined; @@ -1040,6 +1038,9 @@ function createValidator(prop: IConfigurationPropertySchema): (value: any) => st }, ].filter(validation => validation.enabled); + if ((prop.type === 'number' || prop.type === 'integer') && numericValidations.length === 0) { return null; } + if (prop.type === 'string' && stringValidations.length === 0) { return null; } + return value => { let errors = []; From f7de4dab374c3ea4e8f2593c887d9dd62cd197af Mon Sep 17 00:00:00 2001 From: Jackson Kearl Date: Fri, 10 Aug 2018 16:08:41 -0700 Subject: [PATCH 0694/1276] Remove unused --- src/vs/base/browser/ui/inputbox/inputBox.ts | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/vs/base/browser/ui/inputbox/inputBox.ts b/src/vs/base/browser/ui/inputbox/inputBox.ts index 80c6806e564..1691821da48 100644 --- a/src/vs/base/browser/ui/inputbox/inputBox.ts +++ b/src/vs/base/browser/ui/inputbox/inputBox.ts @@ -326,10 +326,6 @@ export class InputBox extends Widget { this.applyStyles(); } - public attachValidator(validator: IInputValidator) { - this.validation = validator; - } - public isInputValid(): boolean { return !!this.validation && !this.validation(this.value); } From c7d930900f614a65e62158a3b3a62ee461a5bc14 Mon Sep 17 00:00:00 2001 From: SteVen Batten Date: Fri, 10 Aug 2018 16:11:01 -0700 Subject: [PATCH 0695/1276] fixes #54058 --- .../browser/parts/titlebar/menubarControl.ts | 160 +++++++++--------- 1 file changed, 80 insertions(+), 80 deletions(-) diff --git a/src/vs/workbench/browser/parts/titlebar/menubarControl.ts b/src/vs/workbench/browser/parts/titlebar/menubarControl.ts index 8bf59473f91..d8816a7f7bb 100644 --- a/src/vs/workbench/browser/parts/titlebar/menubarControl.ts +++ b/src/vs/workbench/browser/parts/titlebar/menubarControl.ts @@ -13,9 +13,8 @@ import { IThemeService, registerThemingParticipant, ITheme, ICssStyleCollector } import { IWindowService, MenuBarVisibility, IWindowsService } from 'vs/platform/windows/common/windows'; import { IContextKeyService } from 'vs/platform/contextkey/common/contextkey'; import { ActionRunner, IActionRunner, IAction, Action } from 'vs/base/common/actions'; -import { Builder, $ } from 'vs/base/browser/builder'; import { Separator } from 'vs/base/browser/ui/actionbar/actionbar'; -import { EventType, Dimension } from 'vs/base/browser/dom'; +import * as DOM from 'vs/base/browser/dom'; import { IKeybindingService } from 'vs/platform/keybinding/common/keybinding'; import { isMacintosh } from 'vs/base/common/platform'; import { Menu, IMenuOptions, SubmenuAction } from 'vs/base/browser/ui/menu/menu'; @@ -35,10 +34,12 @@ import { IUriDisplayService } from 'vs/platform/uriDisplay/common/uriDisplay'; import { foreground } from 'vs/platform/theme/common/colorRegistry'; import { IUpdateService, StateType } from 'vs/platform/update/common/update'; +const $ = DOM.$; + interface CustomMenu { title: string; - buttonElement: Builder; - titleElement: Builder; + buttonElement: HTMLElement; + titleElement: HTMLElement; actions?: IAction[]; } @@ -90,7 +91,7 @@ export class MenubarControl extends Disposable { private focusedMenu: { index: number; - holder?: Builder; + holder?: HTMLElement; widget?: Menu; }; @@ -98,8 +99,8 @@ export class MenubarControl extends Disposable { private menuUpdater: RunOnceScheduler; private actionRunner: IActionRunner; - private focusToReturn: Builder; - private container: Builder; + private focusToReturn: HTMLElement; + private container: HTMLElement; private recentlyOpened: IRecentlyOpened; private updatePending: boolean; private _modifierKeyStatus: IModifierKeyStatus; @@ -242,7 +243,7 @@ export class MenubarControl extends Disposable { this.focusedMenu = null; if (this.focusToReturn) { - this.focusToReturn.domFocus(); + this.focusToReturn.focus(); this.focusToReturn = null; } } @@ -260,13 +261,13 @@ export class MenubarControl extends Disposable { if (this.isFocused) { if (this.focusedMenu) { - this.customMenus[this.focusedMenu.index].buttonElement.domBlur(); + this.customMenus[this.focusedMenu.index].buttonElement.blur(); } this.focusedMenu = null; if (this.focusToReturn) { - this.focusToReturn.domFocus(); + this.focusToReturn.focus(); this.focusToReturn = null; } } @@ -282,7 +283,7 @@ export class MenubarControl extends Disposable { } if (this.focusedMenu) { - this.customMenus[this.focusedMenu.index].buttonElement.domFocus(); + this.customMenus[this.focusedMenu.index].buttonElement.focus(); } break; case MenubarState.OPEN: @@ -318,9 +319,9 @@ export class MenubarControl extends Disposable { private onDidChangeWindowFocus(hasFocus: boolean): void { if (this.container) { if (hasFocus) { - this.container.removeClass('inactive'); + DOM.removeClass(this.container, 'inactive'); } else { - this.container.addClass('inactive'); + DOM.addClass(this.container, 'inactive'); this.setUnfocusedState(); } } @@ -341,12 +342,12 @@ export class MenubarControl extends Disposable { } private hideMenubar(): void { - this.container.style('display', 'none'); + this.container.style.display = 'none'; this._onVisibilityChange.fire(false); } private showMenubar(): void { - this.container.style('display', 'flex'); + this.container.style.display = 'flex'; this._onVisibilityChange.fire(true); } @@ -370,9 +371,11 @@ export class MenubarControl extends Disposable { if (this.currentEnableMenuBarMnemonics && this.customMenus) { this.customMenus.forEach(customMenu => { - let child = customMenu.titleElement.child(); - if (child) { - child.style('text-decoration', modifierKeyStatus.altKey ? 'underline' : null); + if (customMenu.titleElement.children.length) { + let child = customMenu.titleElement.children.item(0) as HTMLElement; + if (child) { + child.style.textDecoration = modifierKeyStatus.altKey ? 'underline' : null; + } } }); } @@ -604,7 +607,7 @@ export class MenubarControl extends Disposable { return; } - this.container.attr('role', 'menubar'); + this.container.attributes['role'] = 'menubar'; const firstTimeSetup = this.customMenus === undefined; if (firstTimeSetup) { @@ -619,10 +622,11 @@ export class MenubarControl extends Disposable { // Create the top level menu button element if (firstTimeSetup) { - const buttonElement = $(this.container).div({ class: 'menubar-menu-button' }).attr({ 'role': 'menu', 'tabindex': 0 }); - buttonElement.attr('aria-label', this.topLevelTitles[menuTitle].replace(/&&(.)/g, '$1')); + const buttonElement = $('div.menubar-menu-button', { 'role': 'menu', 'tabindex': 0, 'aria-label': this.topLevelTitles[menuTitle].replace(/&&(.)/g, '$1') }); + const titleElement = $('div.menubar-menu-title', { 'aria-hidden': true }); - const titleElement = $(buttonElement).div({ class: 'menubar-menu-title', 'aria-hidden': true }); + buttonElement.appendChild(titleElement); + this.container.appendChild(buttonElement); this.customMenus.push({ title: menuTitle, @@ -633,14 +637,14 @@ export class MenubarControl extends Disposable { // Update the button label to reflect mnemonics let displayTitle = this.topLevelTitles[menuTitle].replace(/&&(.)/g, this.currentEnableMenuBarMnemonics ? '$1' : '$1'); - $(this.customMenus[menuIndex].titleElement).innerHtml(displayTitle); + this.customMenus[menuIndex].titleElement.innerHTML = displayTitle; // Clear and register mnemonics due to updated settings - this.clearMnemonic(this.customMenus[menuIndex].buttonElement.getHTMLElement()); + this.clearMnemonic(this.customMenus[menuIndex].buttonElement); if (this.currentEnableMenuBarMnemonics) { let mnemonic = (/&&(.)/g).exec(this.topLevelTitles[menuTitle]); if (mnemonic && mnemonic[1]) { - this.registerMnemonic(this.customMenus[menuIndex].buttonElement.getHTMLElement(), mnemonic[1]); + this.registerMnemonic(this.customMenus[menuIndex].buttonElement, mnemonic[1]); } } @@ -679,7 +683,7 @@ export class MenubarControl extends Disposable { updateActions(menu, this.customMenus[menuIndex].actions); if (firstTimeSetup) { - this.customMenus[menuIndex].buttonElement.on(EventType.KEY_UP, (e) => { + this._register(DOM.addDisposableListener(this.customMenus[menuIndex].buttonElement, DOM.EventType.KEY_UP, (e) => { let event = new StandardKeyboardEvent(e as KeyboardEvent); let eventHandled = true; @@ -695,9 +699,9 @@ export class MenubarControl extends Disposable { event.preventDefault(); event.stopPropagation(); } - }); + })); - this.customMenus[menuIndex].buttonElement.on(EventType.CLICK, (e) => { + this._register(DOM.addDisposableListener(this.customMenus[menuIndex].buttonElement, DOM.EventType.CLICK, (e) => { // This should only happen for mnemonics and we shouldn't trigger them if (this.currentMenubarVisibility === 'hidden') { return; @@ -722,24 +726,23 @@ export class MenubarControl extends Disposable { e.preventDefault(); e.stopPropagation(); - }); + })); - this.customMenus[menuIndex].buttonElement.on(EventType.MOUSE_ENTER, () => { + this._register(DOM.addDisposableListener(this.customMenus[menuIndex].buttonElement, DOM.EventType.MOUSE_ENTER, () => { if (this.isOpen && !this.isCurrentMenu(menuIndex)) { - this.customMenus[menuIndex].buttonElement.domFocus(); + this.customMenus[menuIndex].buttonElement.focus(); this.cleanupCustomMenu(); this.showCustomMenu(menuIndex, false); } else if (this.isFocused && !this.isOpen) { this.focusedMenu = { index: menuIndex }; - this.customMenus[menuIndex].buttonElement.domFocus(); + this.customMenus[menuIndex].buttonElement.focus(); } - }); - + })); } } if (firstTimeSetup) { - this.container.on(EventType.KEY_DOWN, (e) => { + this._register(DOM.addDisposableListener(this.container, DOM.EventType.KEY_DOWN, (e) => { let event = new StandardKeyboardEvent(e as KeyboardEvent); let eventHandled = true; @@ -757,36 +760,36 @@ export class MenubarControl extends Disposable { event.preventDefault(); event.stopPropagation(); } - }); + })); - this._register($(window).on(EventType.CLICK, () => { + this._register(DOM.addDisposableListener(window, DOM.EventType.CLICK, () => { // This click is outside the menubar so it counts as a focus out if (this.isFocused) { this.setUnfocusedState(); } })); + + this._register(DOM.addDisposableListener(this.container, DOM.EventType.FOCUS_IN, (e) => { + let event = e as FocusEvent; + + if (event.relatedTarget) { + if (!this.container.contains(event.relatedTarget as HTMLElement)) { + this.focusToReturn = event.relatedTarget as HTMLElement; + } + } + })); + + this._register(DOM.addDisposableListener(this.container, DOM.EventType.FOCUS_OUT, (e) => { + let event = e as FocusEvent; + + if (event.relatedTarget) { + if (!this.container.contains(event.relatedTarget as HTMLElement)) { + this.focusToReturn = null; + this.setUnfocusedState(); + } + } + })); } - - this.container.on(EventType.FOCUS_IN, (e) => { - let event = e as FocusEvent; - - if (event.relatedTarget) { - if (!this.container.getHTMLElement().contains(event.relatedTarget as HTMLElement)) { - this.focusToReturn = $(event.relatedTarget as HTMLElement); - } - } - }); - - this.container.on(EventType.FOCUS_OUT, (e) => { - let event = e as FocusEvent; - - if (event.relatedTarget) { - if (!this.container.getHTMLElement().contains(event.relatedTarget as HTMLElement)) { - this.focusToReturn = null; - this.setUnfocusedState(); - } - } - }); } private focusPrevious(): void { @@ -806,7 +809,7 @@ export class MenubarControl extends Disposable { this.showCustomMenu(newFocusedIndex); } else if (this.isFocused) { this.focusedMenu.index = newFocusedIndex; - this.customMenus[newFocusedIndex].buttonElement.domFocus(); + this.customMenus[newFocusedIndex].buttonElement.focus(); } } @@ -826,7 +829,7 @@ export class MenubarControl extends Disposable { this.showCustomMenu(newFocusedIndex); } else if (this.isFocused) { this.focusedMenu.index = newFocusedIndex; - this.customMenus[newFocusedIndex].buttonElement.domFocus(); + this.customMenus[newFocusedIndex].buttonElement.focus(); } } @@ -933,8 +936,8 @@ export class MenubarControl extends Disposable { if (this.focusedMenu) { if (this.focusedMenu.holder) { - $(this.focusedMenu.holder.getHTMLElement().parentElement).removeClass('open'); - this.focusedMenu.holder.dispose(); + DOM.removeClass(this.focusedMenu.holder.parentElement, 'open'); + this.focusedMenu.holder.remove(); } if (this.focusedMenu.widget) { @@ -947,23 +950,20 @@ export class MenubarControl extends Disposable { private showCustomMenu(menuIndex: number, selectFirst = true): void { const customMenu = this.customMenus[menuIndex]; + const menuHolder = $('div.menubar-menu-items-holder'); - let menuHolder = $(customMenu.buttonElement).div({ class: 'menubar-menu-items-holder' }); + DOM.addClass(customMenu.buttonElement, 'open'); + menuHolder.style.top = `${this.container.clientHeight}px`; + menuHolder.style.left = `${customMenu.buttonElement.getBoundingClientRect().left}px`; - $(menuHolder.getHTMLElement().parentElement).addClass('open'); - menuHolder.style({ - 'top': `${this.container.getClientArea().height}px`, - 'left': `${customMenu.buttonElement.getHTMLElement().getBoundingClientRect().left}px` - }); + customMenu.buttonElement.appendChild(menuHolder); let menuOptions: IMenuOptions = { getKeyBinding: (action) => this.keybindingService.lookupKeybinding(action.id), actionRunner: this.actionRunner, - // ariaLabel: 'File' - // actionItemProvider: (action) => { return this._getActionItem(action); } }; - let menuWidget = this._register(new Menu(menuHolder.getHTMLElement(), customMenu.actions, menuOptions)); + let menuWidget = this._register(new Menu(menuHolder, customMenu.actions, menuOptions)); this._register(menuWidget.onDidCancel(() => { this.focusState = MenubarState.FOCUSED; @@ -988,9 +988,9 @@ export class MenubarControl extends Disposable { return this._onVisibilityChange.event; } - public layout(dimension: Dimension) { + public layout(dimension: DOM.Dimension) { if (this.container) { - this.container.style({ height: `${dimension.height}px` }); + this.container.style.height = `${dimension.height}px`; } if (!this.isVisible) { @@ -1000,18 +1000,18 @@ export class MenubarControl extends Disposable { } } - public getMenubarItemsDimensions(): Dimension { + public getMenubarItemsDimensions(): DOM.Dimension { if (this.customMenus) { - const left = this.customMenus[0].buttonElement.getHTMLElement().getBoundingClientRect().left; - const right = this.customMenus[this.customMenus.length - 1].buttonElement.getHTMLElement().getBoundingClientRect().right; - return new Dimension(right - left, this.container.getClientArea().height); + const left = this.customMenus[0].buttonElement.getBoundingClientRect().left; + const right = this.customMenus[this.customMenus.length - 1].buttonElement.getBoundingClientRect().right; + return new DOM.Dimension(right - left, this.container.clientHeight); } - return new Dimension(0, 0); + return new DOM.Dimension(0, 0); } public create(parent: HTMLElement): HTMLElement { - this.container = $(parent); + this.container = parent; // Build the menubar if (this.container) { @@ -1022,7 +1022,7 @@ export class MenubarControl extends Disposable { } } - return this.container.getHTMLElement(); + return this.container; } } From 74b501b91f890d3ce25bf005dd4663d603869a0f Mon Sep 17 00:00:00 2001 From: Jackson Kearl Date: Fri, 10 Aug 2018 16:22:56 -0700 Subject: [PATCH 0696/1276] Fix settings monaco clipping in 'wide' mode (#56177) --- src/vs/workbench/parts/preferences/browser/settingsEditor2.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vs/workbench/parts/preferences/browser/settingsEditor2.ts b/src/vs/workbench/parts/preferences/browser/settingsEditor2.ts index 2b8114c77af..398003c6595 100644 --- a/src/vs/workbench/parts/preferences/browser/settingsEditor2.ts +++ b/src/vs/workbench/parts/preferences/browser/settingsEditor2.ts @@ -144,7 +144,7 @@ export class SettingsEditor2 extends BaseEditor { this.layoutTrees(dimension); let innerWidth = dimension.width - 24 * 2; // 24px padding on left and right - let monacoWidth = (innerWidth > 1000 ? 1000 : innerWidth - 10); + let monacoWidth = (innerWidth > 1000 ? 1000 : innerWidth) - 10; this.searchWidget.layout({ height: 20, width: monacoWidth }); DOM.toggleClass(this.rootElement, 'narrow', dimension.width < 600); From aae9cd355edde26036243430d4b11bb4e1da08ee Mon Sep 17 00:00:00 2001 From: Ramya Achutha Rao Date: Fri, 10 Aug 2018 17:37:32 -0700 Subject: [PATCH 0697/1276] Extensions in Preferences menu #56042 --- src/vs/code/electron-main/menus.ts | 2 ++ .../electron-browser/extensions.contribution.ts | 9 +++++++++ src/vs/workbench/parts/update/electron-browser/update.ts | 2 +- 3 files changed, 12 insertions(+), 1 deletion(-) diff --git a/src/vs/code/electron-main/menus.ts b/src/vs/code/electron-main/menus.ts index f2cd26b67f1..0c9b269d1e1 100644 --- a/src/vs/code/electron-main/menus.ts +++ b/src/vs/code/electron-main/menus.ts @@ -439,6 +439,7 @@ export class CodeMenu { private getPreferencesMenu(): Electron.MenuItem { const settings = this.createMenuItem(nls.localize({ key: 'miOpenSettings', comment: ['&& denotes a mnemonic'] }, "&&Settings"), 'workbench.action.openSettings2'); + const extensions = this.createMenuItem(nls.localize({ key: 'miOpenExtensions', comment: ['&& denotes a mnemonic'] }, '&&Extensions'), 'workbench.view.extensions'); const kebindingSettings = this.createMenuItem(nls.localize({ key: 'miOpenKeymap', comment: ['&& denotes a mnemonic'] }, "&&Keyboard Shortcuts"), 'workbench.action.openGlobalKeybindings'); const keymapExtensions = this.createMenuItem(nls.localize({ key: 'miOpenKeymapExtensions', comment: ['&& denotes a mnemonic'] }, "&&Keymap Extensions"), 'workbench.extensions.action.showRecommendedKeymapExtensions'); const snippetsSettings = this.createMenuItem(nls.localize({ key: 'miOpenSnippets', comment: ['&& denotes a mnemonic'] }, "User &&Snippets"), 'workbench.action.openSnippets'); @@ -447,6 +448,7 @@ export class CodeMenu { const preferencesMenu = new Menu(); preferencesMenu.append(settings); + preferencesMenu.append(extensions); preferencesMenu.append(__separator__()); preferencesMenu.append(kebindingSettings); preferencesMenu.append(keymapExtensions); diff --git a/src/vs/workbench/parts/extensions/electron-browser/extensions.contribution.ts b/src/vs/workbench/parts/extensions/electron-browser/extensions.contribution.ts index d14b8666b9d..62cd74ec7c8 100644 --- a/src/vs/workbench/parts/extensions/electron-browser/extensions.contribution.ts +++ b/src/vs/workbench/parts/extensions/electron-browser/extensions.contribution.ts @@ -258,6 +258,15 @@ MenuRegistry.appendMenuItem(MenuId.MenubarPreferencesMenu, { order: 2 }); +MenuRegistry.appendMenuItem(MenuId.MenubarPreferencesMenu, { + group: '1_settings', + command: { + id: VIEWLET_ID, + title: localize({ key: 'miPreferencesExtensions', comment: ['&& denotes a mnemonic'] }, "&&Extensions") + }, + order: 2 +}); + // View menu MenuRegistry.appendMenuItem(MenuId.MenubarViewMenu, { diff --git a/src/vs/workbench/parts/update/electron-browser/update.ts b/src/vs/workbench/parts/update/electron-browser/update.ts index 04edd26fd77..70def20275d 100644 --- a/src/vs/workbench/parts/update/electron-browser/update.ts +++ b/src/vs/workbench/parts/update/electron-browser/update.ts @@ -570,8 +570,8 @@ export class UpdateContribution implements IGlobalActivity { new CommandAction(UpdateContribution.showCommandsId, nls.localize('commandPalette', "Command Palette..."), this.commandService), new Separator(), new CommandAction(UpdateContribution.openSettingsId, nls.localize('settings', "Settings"), this.commandService), + new CommandAction(UpdateContribution.showExtensionsId, nls.localize('showExtensions', "Extensions"), this.commandService), new CommandAction(UpdateContribution.openKeybindingsId, nls.localize('keyboardShortcuts', "Keyboard Shortcuts"), this.commandService), - new CommandAction(UpdateContribution.showExtensionsId, nls.localize('showExtensions', "Manage Extensions"), this.commandService), new Separator(), new CommandAction(UpdateContribution.openUserSnippets, nls.localize('userSnippets', "User Snippets"), this.commandService), new Separator(), From 8e6c09cdaea91bc9a415c8eafa78f97c33d61c10 Mon Sep 17 00:00:00 2001 From: Ramya Achutha Rao Date: Fri, 10 Aug 2018 17:41:04 -0700 Subject: [PATCH 0698/1276] The built in views are not used during search --- .../extensions/electron-browser/extensionsViewlet.ts | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/vs/workbench/parts/extensions/electron-browser/extensionsViewlet.ts b/src/vs/workbench/parts/extensions/electron-browser/extensionsViewlet.ts index 307fae07cc0..2ba10ccbf6e 100644 --- a/src/vs/workbench/parts/extensions/electron-browser/extensionsViewlet.ts +++ b/src/vs/workbench/parts/extensions/electron-browser/extensionsViewlet.ts @@ -84,9 +84,9 @@ export class ExtensionsViewletViewsContribution implements IWorkbenchContributio viewDescriptors.push(this.createEnabledExtensionsListViewDescriptor()); viewDescriptors.push(this.createDisabledExtensionsListViewDescriptor()); viewDescriptors.push(this.createSearchInstalledExtensionsListViewDescriptor()); - viewDescriptors.push(this.createSearchBuiltInExtensionsListViewDescriptor()); - viewDescriptors.push(this.createSearchBuiltInBasicsExtensionsListViewDescriptor()); - viewDescriptors.push(this.createSearchBuiltInThemesExtensionsListViewDescriptor()); + viewDescriptors.push(this.createBuiltInExtensionsListViewDescriptor()); + viewDescriptors.push(this.createBuiltInBasicsExtensionsListViewDescriptor()); + viewDescriptors.push(this.createBuiltInThemesExtensionsListViewDescriptor()); viewDescriptors.push(this.createDefaultRecommendedExtensionsListViewDescriptor()); viewDescriptors.push(this.createOtherRecommendedExtensionsListViewDescriptor()); viewDescriptors.push(this.createWorkspaceRecommendedExtensionsListViewDescriptor()); @@ -199,7 +199,7 @@ export class ExtensionsViewletViewsContribution implements IWorkbenchContributio }; } - private createSearchBuiltInExtensionsListViewDescriptor(): IViewDescriptor { + private createBuiltInExtensionsListViewDescriptor(): IViewDescriptor { return { id: 'extensions.builtInExtensionsList', name: localize('builtInExtensions', "Features"), @@ -211,7 +211,7 @@ export class ExtensionsViewletViewsContribution implements IWorkbenchContributio }; } - private createSearchBuiltInThemesExtensionsListViewDescriptor(): IViewDescriptor { + private createBuiltInThemesExtensionsListViewDescriptor(): IViewDescriptor { return { id: 'extensions.builtInThemesExtensionsList', name: localize('builtInThemesExtensions', "Themes"), @@ -223,7 +223,7 @@ export class ExtensionsViewletViewsContribution implements IWorkbenchContributio }; } - private createSearchBuiltInBasicsExtensionsListViewDescriptor(): IViewDescriptor { + private createBuiltInBasicsExtensionsListViewDescriptor(): IViewDescriptor { return { id: 'extensions.builtInBasicsExtensionsList', name: localize('builtInBasicsExtensions', "Programming Languages"), From 0ec983bd9eed92ead8e220877865c6be92a8bbc5 Mon Sep 17 00:00:00 2001 From: Jackson Kearl Date: Fri, 10 Aug 2018 19:11:14 -0700 Subject: [PATCH 0699/1276] Add nullable numbers and validation for nullable numbers --- .../parts/preferences/browser/settingsTree.ts | 13 ++++++++++--- .../preferences/common/preferencesModels.ts | 11 +++++++++-- 2 files changed, 19 insertions(+), 5 deletions(-) diff --git a/src/vs/workbench/parts/preferences/browser/settingsTree.ts b/src/vs/workbench/parts/preferences/browser/settingsTree.ts index c2ae2a98018..28549681adf 100644 --- a/src/vs/workbench/parts/preferences/browser/settingsTree.ts +++ b/src/vs/workbench/parts/preferences/browser/settingsTree.ts @@ -39,6 +39,7 @@ import { SettingsTarget } from 'vs/workbench/parts/preferences/browser/preferenc import { ITOCEntry } from 'vs/workbench/parts/preferences/browser/settingsLayout'; import { ExcludeSettingWidget, IExcludeDataItem, settingsHeaderForeground, settingsNumberInputBackground, settingsNumberInputBorder, settingsNumberInputForeground, settingsSelectBackground, settingsSelectBorder, settingsSelectForeground, settingsTextInputBackground, settingsTextInputBorder, settingsTextInputForeground } from 'vs/workbench/parts/preferences/browser/settingsWidgets'; import { IExtensionSetting, ISearchResult, ISetting, ISettingsGroup } from 'vs/workbench/services/preferences/common/preferences'; +import { isArray } from 'vs/base/common/types'; const $ = DOM.$; @@ -91,7 +92,7 @@ export class SettingsTreeSettingElement extends SettingsTreeElement { tags?: Set; overriddenScopeList: string[]; description: string; - valueType: 'enum' | 'string' | 'integer' | 'number' | 'boolean' | 'exclude' | 'complex'; + valueType: 'enum' | 'string' | 'integer' | 'number' | 'boolean' | 'exclude' | 'complex' | 'nullable-integer' | 'nullable-number'; matchesAllTags(tagFilters?: Set): boolean { if (!tagFilters || !tagFilters.size) { @@ -245,6 +246,12 @@ function createSettingsTreeSettingElement(setting: ISetting, parent: SearchResul element.valueType = 'number'; } else if (setting.type === 'boolean') { element.valueType = 'boolean'; + } else if (isArray(setting.type) && setting.type.indexOf('null') > -1 && setting.type.length === 2) { + if (setting.type.indexOf('number') > -1) { + element.valueType = 'nullable-integer'; + } else if (setting.type.indexOf('number') > -1) { + element.valueType = 'nullable-number'; + } } else { element.valueType = 'complex'; } @@ -655,7 +662,7 @@ export class SettingsRenderer implements ITreeRenderer { return SETTINGS_BOOL_TEMPLATE_ID; } - if (element.valueType === 'integer' || element.valueType === 'number') { + if (element.valueType === 'integer' || element.valueType === 'number' || element.valueType === 'nullable-integer' || element.valueType === 'nullable-number') { return SETTINGS_NUMBER_TEMPLATE_ID; } @@ -1233,7 +1240,7 @@ export class SettingsRenderer implements ITreeRenderer { private renderNumber(dataElement: SettingsTreeSettingElement, template: ISettingTextItemTemplate, onChange: (value: number) => void): void { - const parseFn = dataElement.valueType === 'integer' ? parseInt : parseFloat; + const parseFn = (dataElement.valueType === 'integer' || dataElement.valueType === 'nullable-integer') ? parseInt : parseFloat; template.onChange = null; template.inputBox.value = dataElement.value; diff --git a/src/vs/workbench/services/preferences/common/preferencesModels.ts b/src/vs/workbench/services/preferences/common/preferencesModels.ts index fbc31b4875f..b31f83b2a92 100644 --- a/src/vs/workbench/services/preferences/common/preferencesModels.ts +++ b/src/vs/workbench/services/preferences/common/preferencesModels.ts @@ -1038,13 +1038,20 @@ function createValidator(prop: IConfigurationPropertySchema): ((value: any) => s }, ].filter(validation => validation.enabled); - if ((prop.type === 'number' || prop.type === 'integer') && numericValidations.length === 0) { return null; } + const type = Array.isArray(prop.type) ? prop.type : [prop.type]; + const canBeType = (t: string) => type.indexOf(t) > -1; + + const isNullable = canBeType('null'); + const isNumeric = (canBeType('number') || canBeType('integer')) && (type.length === 1 || type.length === 2 && isNullable); + if (prop.type === 'string' && stringValidations.length === 0) { return null; } return value => { + if (isNullable && value === '') { return ''; } + let errors = []; - if (prop.type === 'number' || prop.type === 'integer') { + if (isNumeric) { if (value === '' || isNaN(+value)) { errors.push(nls.localize('validations.expectedNumeric', "Value must be a number.")); } else { From 3e591c006cd5b9e3442e35d1bfe3ef795d187f0f Mon Sep 17 00:00:00 2001 From: Jackson Kearl Date: Fri, 10 Aug 2018 19:27:05 -0700 Subject: [PATCH 0700/1276] Reset on null entry to null defualt valued entry --- .../parts/preferences/browser/settingsTree.ts | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/vs/workbench/parts/preferences/browser/settingsTree.ts b/src/vs/workbench/parts/preferences/browser/settingsTree.ts index 28549681adf..1c19b80ba0f 100644 --- a/src/vs/workbench/parts/preferences/browser/settingsTree.ts +++ b/src/vs/workbench/parts/preferences/browser/settingsTree.ts @@ -1240,11 +1240,17 @@ export class SettingsRenderer implements ITreeRenderer { private renderNumber(dataElement: SettingsTreeSettingElement, template: ISettingTextItemTemplate, onChange: (value: number) => void): void { - const parseFn = (dataElement.valueType === 'integer' || dataElement.valueType === 'nullable-integer') ? parseInt : parseFloat; + const numParseFn = (dataElement.valueType === 'integer' || dataElement.valueType === 'nullable-integer') + ? parseInt : parseFloat; + + const nullNumParseFn = (dataElement.valueType === 'nullable-integer' || dataElement.valueType === 'nullable-number') + ? (v => v === '' ? null : numParseFn(v)) : numParseFn; template.onChange = null; template.inputBox.value = dataElement.value; - template.onChange = value => { renderValidations(dataElement, template); onChange(parseFn(value)); }; + template.onChange = value => { + renderValidations(dataElement, template); onChange(nullNumParseFn(value)); + }; renderValidations(dataElement, template); // Setup and add ARIA attributes From 03cfde3d68b9c4a3139c7e3725755d35b4527437 Mon Sep 17 00:00:00 2001 From: Benjamin Pasero Date: Sat, 11 Aug 2018 10:56:09 +0200 Subject: [PATCH 0701/1276] fix build --- build/gulpfile.vscode.js | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/build/gulpfile.vscode.js b/build/gulpfile.vscode.js index 090db00ffeb..608c1a42915 100644 --- a/build/gulpfile.vscode.js +++ b/build/gulpfile.vscode.js @@ -223,8 +223,7 @@ function packageTask(platform, arch, opts) { 'vs/workbench/workbench.main.js', 'vs/workbench/workbench.main.css', 'vs/workbench/electron-browser/bootstrap/index.html', - 'vs/workbench/electron-browser/bootstrap/index.js', - 'vs/workbench/electron-browser/bootstrap/preload.js' + 'vs/workbench/electron-browser/bootstrap/index.js' ]); const src = gulp.src(out + '/**', { base: '.' }) From e7871ead4ec06e3b77f16ba72455b9b281d6e4ac Mon Sep 17 00:00:00 2001 From: Rob Lourens Date: Fri, 10 Aug 2018 15:13:48 -0700 Subject: [PATCH 0702/1276] #55803 - Don't refresh a setting currently being edited --- src/vs/base/browser/dom.ts | 2 +- .../preferences/browser/settingsEditor2.ts | 61 +++++++++---------- 2 files changed, 31 insertions(+), 32 deletions(-) diff --git a/src/vs/base/browser/dom.ts b/src/vs/base/browser/dom.ts index e8ed9bec491..a5ca4033c5c 100644 --- a/src/vs/base/browser/dom.ts +++ b/src/vs/base/browser/dom.ts @@ -920,7 +920,7 @@ class FocusTracker implements IFocusTracker { private disposables: IDisposable[] = []; constructor(element: HTMLElement | Window) { - let hasFocus = false; + let hasFocus = document.activeElement === element; let loosingFocus = false; let onFocus = () => { diff --git a/src/vs/workbench/parts/preferences/browser/settingsEditor2.ts b/src/vs/workbench/parts/preferences/browser/settingsEditor2.ts index 398003c6595..e981be264a1 100644 --- a/src/vs/workbench/parts/preferences/browser/settingsEditor2.ts +++ b/src/vs/workbench/parts/preferences/browser/settingsEditor2.ts @@ -82,6 +82,8 @@ export class SettingsEditor2 extends BaseEditor { private inSettingsEditorContextKey: IContextKey; private searchFocusContextKey: IContextKey; + private scheduledRefreshTracker: DOM.IFocusTracker; + private tagRegex = /(^|\s)@tag:("([^"]*)"|[^"]\S*)/g; /** Don't spam warnings */ @@ -149,7 +151,7 @@ export class SettingsEditor2 extends BaseEditor { DOM.toggleClass(this.rootElement, 'narrow', dimension.width < 600); - this.delayRefreshOnLayout.trigger(() => this.refreshTreeAndMaintainFocus()); + this.delayRefreshOnLayout.trigger(() => this.refreshTree()); } focus(): void { @@ -214,7 +216,7 @@ export class SettingsEditor2 extends BaseEditor { this.toolbar.context = { target: this.settingsTargetsWidget.settingsTarget }; this.settingsTreeModel.update(); - this.refreshTreeAndMaintainFocus(); + this.refreshTree(); }); this.createHeaderControls(headerControlsContainer); @@ -354,7 +356,7 @@ export class SettingsEditor2 extends BaseEditor { const element = e.focus; if (this.searchResultModel) { this.viewState.filterToCategory = element; - this.refreshTreeAndMaintainFocus(); + this.refreshTree(); } if (element && (!e.payload || !e.payload.fromScroll)) { @@ -464,7 +466,7 @@ export class SettingsEditor2 extends BaseEditor { } return this.configurationService.updateValue(key, value, overrides, configurationTarget) - .then(() => this.refreshTreeAndMaintainFocus()) + .then(() => this.refreshTree()) .then(() => { const reportModifiedProps = { key, @@ -561,6 +563,19 @@ export class SettingsEditor2 extends BaseEditor { } } + private scheduleRefresh(): void { + if (this.scheduledRefreshTracker) { + return; + } + + this.scheduledRefreshTracker = DOM.trackFocus(document.activeElement); + this.scheduledRefreshTracker.onDidBlur(() => { + this.scheduledRefreshTracker.dispose(); + this.scheduledRefreshTracker = null; + this.refreshTree(); + }); + } + private onConfigUpdate(): TPromise { const groups = this.defaultSettingsEditorModel.settingsGroups.slice(1); // Without commonlyUsed const dividedGroups = collections.groupBy(groups, g => g.contributedByExtension ? 'extension' : 'core'); @@ -589,7 +604,7 @@ export class SettingsEditor2 extends BaseEditor { if (this.settingsTreeModel) { this.settingsTreeModel.update(resolvedSettingsRoot); - return this.refreshTreeAndMaintainFocus(); + return this.refreshTree(); } else { this.settingsTreeModel = this.instantiationService.createInstance(SettingsTreeModel, this.viewState, resolvedSettingsRoot); this.settingsTree.setInput(this.settingsTreeModel.root); @@ -605,39 +620,23 @@ export class SettingsEditor2 extends BaseEditor { return TPromise.wrap(null); } - private refreshTreeAndMaintainFocus(): TPromise { - // Sort of a hack to maintain focus on the focused control across a refresh - const focusedRowItem = DOM.findParentWithClass(document.activeElement, 'setting-item'); - const focusedRowId = focusedRowItem && focusedRowItem.id; - const selection = focusedRowId && document.activeElement.tagName.toLowerCase() === 'input' ? - (document.activeElement).selectionStart : - null; + private refreshTree(element?: SettingsTreeElement): TPromise { + if (this.scheduledRefreshTracker) { + return TPromise.wrap(null); + } + + if (document.activeElement.classList.contains(SettingsRenderer.CONTROL_CLASS)) { + this.scheduleRefresh(); + return TPromise.wrap(null); + } return this.settingsTree.refresh() .then(() => { - if (focusedRowId) { - this.focusEditControlForRow(focusedRowId, selection); - } - }) - .then(() => { - // TODO@roblou - hack this.tocTreeModel.update(); - return this.tocTree.refresh(); }); } - private focusEditControlForRow(id: string, selection?: number): void { - const rowSelector = `.setting-item#${id}`; - const inputElementToFocus: HTMLElement = this.settingsTreeContainer.querySelector(`${rowSelector} input, ${rowSelector} select, ${rowSelector} .monaco-custom-checkbox`); - if (inputElementToFocus) { - inputElementToFocus.focus(); - if (typeof selection === 'number') { - (inputElementToFocus).setSelectionRange(selection, selection); - } - } - } - private onSearchInputChanged(): void { const query = this.searchWidget.getValue().trim(); this.delayedFilterLogging.cancel(); @@ -788,7 +787,7 @@ export class SettingsEditor2 extends BaseEditor { this.tocTreeModel.update(); expandAll(this.tocTree); - resolve(this.refreshTreeAndMaintainFocus()); + resolve(this.refreshTree()); }); }, () => { isCanceled = true; From 3833a3de6a0a6daa479a120c14f700a67994d4b9 Mon Sep 17 00:00:00 2001 From: Rob Lourens Date: Fri, 10 Aug 2018 15:43:45 -0700 Subject: [PATCH 0703/1276] Settings editor - don't run search on '@' --- src/vs/workbench/parts/preferences/browser/settingsEditor2.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/vs/workbench/parts/preferences/browser/settingsEditor2.ts b/src/vs/workbench/parts/preferences/browser/settingsEditor2.ts index e981be264a1..022059fa0c0 100644 --- a/src/vs/workbench/parts/preferences/browser/settingsEditor2.ts +++ b/src/vs/workbench/parts/preferences/browser/settingsEditor2.ts @@ -659,8 +659,9 @@ export class SettingsEditor2 extends BaseEditor { return ''; }); } + query = query.trim(); - if (query) { + if (query && query !== '@') { return this.searchInProgress = TPromise.join([ this.localSearchDelayer.trigger(() => this.localFilterPreferences(query)), this.remoteSearchThrottle.trigger(() => this.remoteSearchPreferences(query), 500) From 8dda8cb9dbef4f6cb233c2b17a3da8e768542c4b Mon Sep 17 00:00:00 2001 From: Rob Lourens Date: Fri, 10 Aug 2018 15:44:14 -0700 Subject: [PATCH 0704/1276] Settings editor - reduce SearchResultModel special-casing --- .../preferences/browser/settingsEditor2.ts | 7 ++- .../parts/preferences/browser/settingsTree.ts | 56 +++++++++---------- .../parts/preferences/browser/tocTree.ts | 2 +- 3 files changed, 31 insertions(+), 34 deletions(-) diff --git a/src/vs/workbench/parts/preferences/browser/settingsEditor2.ts b/src/vs/workbench/parts/preferences/browser/settingsEditor2.ts index 022059fa0c0..23ebc91444e 100644 --- a/src/vs/workbench/parts/preferences/browser/settingsEditor2.ts +++ b/src/vs/workbench/parts/preferences/browser/settingsEditor2.ts @@ -606,7 +606,8 @@ export class SettingsEditor2 extends BaseEditor { this.settingsTreeModel.update(resolvedSettingsRoot); return this.refreshTree(); } else { - this.settingsTreeModel = this.instantiationService.createInstance(SettingsTreeModel, this.viewState, resolvedSettingsRoot); + this.settingsTreeModel = this.instantiationService.createInstance(SettingsTreeModel, this.viewState); + this.settingsTreeModel.update(resolvedSettingsRoot); this.settingsTree.setInput(this.settingsTreeModel.root); this.tocTreeModel.settingsTreeRoot = this.settingsTreeModel.root as SettingsTreeGroupElement; @@ -688,7 +689,7 @@ export class SettingsEditor2 extends BaseEditor { collapseAll(this.tocTree); if (this.searchResultModel) { - return this.settingsTree.setInput(this.searchResultModel); + return this.settingsTree.setInput(this.searchResultModel.root); } else { return this.settingsTree.setInput(this.settingsTreeModel.root); } @@ -780,7 +781,7 @@ export class SettingsEditor2 extends BaseEditor { this.searchResultModel.setResult(type, result); this.tocTreeModel.currentSearchModel = this.searchResultModel; this.toggleSearchMode(); - this.settingsTree.setInput(this.searchResultModel); + this.settingsTree.setInput(this.searchResultModel.root); } else { this.searchResultModel.setResult(type, result); } diff --git a/src/vs/workbench/parts/preferences/browser/settingsTree.ts b/src/vs/workbench/parts/preferences/browser/settingsTree.ts index 81668c95167..e738c9f30f4 100644 --- a/src/vs/workbench/parts/preferences/browser/settingsTree.ts +++ b/src/vs/workbench/parts/preferences/browser/settingsTree.ts @@ -47,11 +47,11 @@ export const ONLINE_SERVICES_SETTING_TAG = 'usesOnlineServices'; export abstract class SettingsTreeElement { id: string; - parent: any; // SearchResultModel or group element... TODO search should be more similar to the normal case + parent: SettingsTreeGroupElement; } export class SettingsTreeGroupElement extends SettingsTreeElement { - children: (SettingsTreeGroupElement | SettingsTreeSettingElement)[]; + children: (SettingsTreeGroupElement | SettingsTreeSettingElement | SettingsTreeNewExtensionsElement)[]; count?: number; label: string; level: number; @@ -118,17 +118,15 @@ export interface ITOCEntry { } export class SettingsTreeModel { - private _root: SettingsTreeGroupElement; + protected _root: SettingsTreeGroupElement; private _treeElementsById = new Map(); private _treeElementsBySettingName = new Map(); + private _tocRoot: ITOCEntry; constructor( private _viewState: ISettingsEditorViewState, - private _tocRoot: ITOCEntry, @IConfigurationService private _configurationService: IConfigurationService - ) { - this.update(this._tocRoot); - } + ) { } get root(): SettingsTreeGroupElement { return this._root; @@ -136,7 +134,9 @@ export class SettingsTreeModel { update(newTocRoot = this._tocRoot): void { const newRoot = this.createSettingsTreeGroupElement(newTocRoot); - (newRoot.children[0]).isFirstGroup = true; + if (newRoot.children[0] instanceof SettingsTreeGroupElement) { + (newRoot.children[0]).isFirstGroup = true; // TODO + } if (this._root) { this._root.children = newRoot.children; @@ -165,6 +165,8 @@ export class SettingsTreeModel { } else if (tocEntry.settings) { element.children = tocEntry.settings.map(s => this.createSettingsTreeSettingElement(s, element)) .filter(el => el.setting.deprecationMessage ? el.isConfigured : true); + } else { + element.children = []; } this._treeElementsById.set(element.id, element); @@ -191,7 +193,7 @@ function sanitizeId(id: string): string { return id.replace(/[\.\/]/, '_'); } -function createSettingsTreeSettingElement(setting: ISetting, parent: SearchResultModel | SettingsTreeGroupElement, settingsTarget: SettingsTarget, configurationService: IConfigurationService): SettingsTreeSettingElement { +function createSettingsTreeSettingElement(setting: ISetting, parent: SettingsTreeGroupElement, settingsTarget: SettingsTarget, configurationService: IConfigurationService): SettingsTreeSettingElement { const element = new SettingsTreeSettingElement(); element.id = sanitizeId(parent.id + '_' + setting.key); element.parent = parent; @@ -385,10 +387,6 @@ export class SettingsDataSource implements IDataSource { } hasChildren(tree: ITree, element: SettingsTreeElement): boolean { - if (element instanceof SearchResultModel) { - return true; - } - if (element instanceof SettingsTreeGroupElement) { return true; } @@ -401,9 +399,7 @@ export class SettingsDataSource implements IDataSource { } private _getChildren(element: SettingsTreeElement): SettingsTreeElement[] { - if (element instanceof SearchResultModel) { - return element.getChildren(); - } else if (element instanceof SettingsTreeGroupElement) { + if (element instanceof SettingsTreeGroupElement) { return element.children; } else { // No children... @@ -553,7 +549,7 @@ export class SettingsRenderer implements ITreeRenderer { public static readonly MAX_ENUM_DESCRIPTIONS = 10; - private static readonly CONTROL_CLASS = 'setting-control-focus-target'; + public static readonly CONTROL_CLASS = 'setting-control-focus-target'; public static readonly CONTROL_SELECTOR = '.' + SettingsRenderer.CONTROL_CLASS; private readonly _onDidChangeSetting: Emitter = new Emitter(); @@ -1386,21 +1382,19 @@ export enum SearchResultIdx { NewExtensions = 2 } -export class SearchResultModel { +export class SearchResultModel extends SettingsTreeModel { private rawSearchResults: ISearchResult[]; private cachedUniqueSearchResults: ISearchResult[]; private newExtensionSearchResults: ISearchResult; - private children: (SettingsTreeSettingElement | SettingsTreeNewExtensionsElement)[]; readonly id = 'searchResultModel'; constructor( - private _viewState: ISettingsEditorViewState, - @IConfigurationService private _configurationService: IConfigurationService - ) { } - - getChildren(): (SettingsTreeSettingElement | SettingsTreeNewExtensionsElement)[] { - return this.children; + viewState: ISettingsEditorViewState, + @IConfigurationService configurationService: IConfigurationService + ) { + super(viewState, configurationService); + this.update({ id: 'searchResultModel', label: '' }); } getUniqueResults(): ISearchResult[] { @@ -1446,20 +1440,22 @@ export class SearchResultModel { } updateChildren(): void { - this.children = this.getFlatSettings() - .map(s => createSettingsTreeSettingElement(s, this, this._viewState.settingsTarget, this._configurationService)) - .filter(el => el.setting.deprecationMessage ? el.isConfigured : true); + this.update({ + id: 'searchResultModel', + label: 'searchResultModel', + settings: this.getFlatSettings() + }); if (this.newExtensionSearchResults) { const newExtElement = new SettingsTreeNewExtensionsElement(); - newExtElement.parent = this; + newExtElement.parent = this._root; newExtElement.id = 'newExtensions'; const resultExtensionIds = this.newExtensionSearchResults.filterMatches .map(result => (result.setting)) .filter(setting => setting.extensionName && setting.extensionPublisher) .map(setting => `${setting.extensionPublisher}.${setting.extensionName}`); newExtElement.extensionIds = arrays.distinct(resultExtensionIds); - this.children.push(newExtElement); + this._root.children.push(newExtElement); } } diff --git a/src/vs/workbench/parts/preferences/browser/tocTree.ts b/src/vs/workbench/parts/preferences/browser/tocTree.ts index f70ad30dc4a..e11d096c8a0 100644 --- a/src/vs/workbench/parts/preferences/browser/tocTree.ts +++ b/src/vs/workbench/parts/preferences/browser/tocTree.ts @@ -60,7 +60,7 @@ export class TOCTreeModel { } private getSearchResultChildrenCount(group: SettingsTreeGroupElement): number { - return this._currentSearchModel.getChildren().filter(child => { + return this._currentSearchModel.root.children.filter(child => { return child instanceof SettingsTreeSettingElement && this.groupContainsSetting(group, child.setting); }).length; } From 470515e919b9146023db310be68ddcfa683aad97 Mon Sep 17 00:00:00 2001 From: Rob Lourens Date: Fri, 10 Aug 2018 16:51:10 -0700 Subject: [PATCH 0705/1276] Settings editor - split out settingsTreeModels.ts --- .../preferences/browser/settingsEditor2.ts | 7 +- .../parts/preferences/browser/settingsTree.ts | 395 +---------------- .../preferences/browser/settingsTreeModels.ts | 396 ++++++++++++++++++ .../parts/preferences/browser/tocTree.ts | 3 +- .../test/browser/settingsTree.test.ts | 2 +- 5 files changed, 406 insertions(+), 397 deletions(-) create mode 100644 src/vs/workbench/parts/preferences/browser/settingsTreeModels.ts diff --git a/src/vs/workbench/parts/preferences/browser/settingsEditor2.ts b/src/vs/workbench/parts/preferences/browser/settingsEditor2.ts index 23ebc91444e..3796be5e51f 100644 --- a/src/vs/workbench/parts/preferences/browser/settingsEditor2.ts +++ b/src/vs/workbench/parts/preferences/browser/settingsEditor2.ts @@ -31,17 +31,18 @@ import { attachButtonStyler } from 'vs/platform/theme/common/styler'; import { IThemeService } from 'vs/platform/theme/common/themeService'; import { BaseEditor } from 'vs/workbench/browser/parts/editor/baseEditor'; import { EditorOptions, IEditor } from 'vs/workbench/common/editor'; +import { SuggestEnabledInput } from 'vs/workbench/parts/codeEditor/browser/suggestEnabledInput'; import { PreferencesEditor } from 'vs/workbench/parts/preferences/browser/preferencesEditor'; import { SettingsTarget, SettingsTargetsWidget } from 'vs/workbench/parts/preferences/browser/preferencesWidgets'; import { commonlyUsedData, tocData } from 'vs/workbench/parts/preferences/browser/settingsLayout'; -import { ISettingsEditorViewState, MODIFIED_SETTING_TAG, ONLINE_SERVICES_SETTING_TAG, resolveExtensionsSettings, resolveSettingsTree, SearchResultIdx, SearchResultModel, SettingsRenderer, SettingsTree, SettingsTreeElement, SettingsTreeGroupElement, SettingsTreeModel, SettingsTreeSettingElement } from 'vs/workbench/parts/preferences/browser/settingsTree'; +import { resolveExtensionsSettings, resolveSettingsTree, SettingsRenderer, SettingsTree } from 'vs/workbench/parts/preferences/browser/settingsTree'; +import { ISettingsEditorViewState, MODIFIED_SETTING_TAG, ONLINE_SERVICES_SETTING_TAG, SearchResultIdx, SearchResultModel, SettingsTreeElement, SettingsTreeGroupElement, SettingsTreeModel, SettingsTreeSettingElement } from 'vs/workbench/parts/preferences/browser/settingsTreeModels'; import { TOCRenderer, TOCTree, TOCTreeModel } from 'vs/workbench/parts/preferences/browser/tocTree'; import { CONTEXT_SETTINGS_EDITOR, CONTEXT_SETTINGS_SEARCH_FOCUS, CONTEXT_TOC_ROW_FOCUS, IPreferencesSearchService, ISearchProvider } from 'vs/workbench/parts/preferences/common/preferences'; +import { IEditorGroup } from 'vs/workbench/services/group/common/editorGroupsService'; import { IPreferencesService, ISearchResult, ISettingsEditorModel } from 'vs/workbench/services/preferences/common/preferences'; import { SettingsEditor2Input } from 'vs/workbench/services/preferences/common/preferencesEditorInput'; import { DefaultSettingsEditorModel } from 'vs/workbench/services/preferences/common/preferencesModels'; -import { SuggestEnabledInput } from 'vs/workbench/parts/codeEditor/browser/suggestEnabledInput'; -import { IEditorGroup } from 'vs/workbench/services/group/common/editorGroupsService'; const $ = DOM.$; diff --git a/src/vs/workbench/parts/preferences/browser/settingsTree.ts b/src/vs/workbench/parts/preferences/browser/settingsTree.ts index e738c9f30f4..241c6949e4d 100644 --- a/src/vs/workbench/parts/preferences/browser/settingsTree.ts +++ b/src/vs/workbench/parts/preferences/browser/settingsTree.ts @@ -26,7 +26,7 @@ import { DefaultTreestyler } from 'vs/base/parts/tree/browser/treeDefaults'; import { Tree } from 'vs/base/parts/tree/browser/treeImpl'; import { localize } from 'vs/nls'; import { ICommandService } from 'vs/platform/commands/common/commands'; -import { ConfigurationTarget, IConfigurationService } from 'vs/platform/configuration/common/configuration'; +import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; import { IContextKeyService } from 'vs/platform/contextkey/common/contextkey'; import { IContextViewService } from 'vs/platform/contextview/browser/contextView'; import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; @@ -35,224 +35,13 @@ import { IOpenerService } from 'vs/platform/opener/common/opener'; import { editorBackground, focusBorder, foreground } from 'vs/platform/theme/common/colorRegistry'; import { attachButtonStyler, attachInputBoxStyler, attachSelectBoxStyler, attachStyler } from 'vs/platform/theme/common/styler'; import { ICssStyleCollector, ITheme, IThemeService, registerThemingParticipant } from 'vs/platform/theme/common/themeService'; -import { SettingsTarget } from 'vs/workbench/parts/preferences/browser/preferencesWidgets'; import { ITOCEntry } from 'vs/workbench/parts/preferences/browser/settingsLayout'; +import { ISettingsEditorViewState, isExcludeSetting, SettingsTreeElement, SettingsTreeGroupElement, SettingsTreeNewExtensionsElement, SettingsTreeSettingElement } from 'vs/workbench/parts/preferences/browser/settingsTreeModels'; import { ExcludeSettingWidget, IExcludeDataItem, settingsHeaderForeground, settingsNumberInputBackground, settingsNumberInputBorder, settingsNumberInputForeground, settingsSelectBackground, settingsSelectBorder, settingsSelectForeground, settingsTextInputBackground, settingsTextInputBorder, settingsTextInputForeground } from 'vs/workbench/parts/preferences/browser/settingsWidgets'; -import { IExtensionSetting, ISearchResult, ISetting, ISettingsGroup } from 'vs/workbench/services/preferences/common/preferences'; +import { ISetting, ISettingsGroup } from 'vs/workbench/services/preferences/common/preferences'; const $ = DOM.$; -export const MODIFIED_SETTING_TAG = 'modified'; -export const ONLINE_SERVICES_SETTING_TAG = 'usesOnlineServices'; - -export abstract class SettingsTreeElement { - id: string; - parent: SettingsTreeGroupElement; -} - -export class SettingsTreeGroupElement extends SettingsTreeElement { - children: (SettingsTreeGroupElement | SettingsTreeSettingElement | SettingsTreeNewExtensionsElement)[]; - count?: number; - label: string; - level: number; - isFirstGroup: boolean; -} - -export class SettingsTreeNewExtensionsElement extends SettingsTreeElement { - extensionIds: string[]; -} - -export class SettingsTreeSettingElement extends SettingsTreeElement { - setting: ISetting; - - displayCategory: string; - displayLabel: string; - - /** - * scopeValue || defaultValue, for rendering convenience. - */ - value: any; - - /** - * The value in the current settings scope. - */ - scopeValue: any; - - /** - * The default value - */ - defaultValue?: any; - - /** - * Whether the setting is configured in the selected scope. - */ - isConfigured: boolean; - - tags?: Set; - overriddenScopeList: string[]; - description: string; - valueType: 'enum' | 'string' | 'integer' | 'number' | 'boolean' | 'exclude' | 'complex'; - - matchesAllTags(tagFilters?: Set): boolean { - if (!tagFilters || !tagFilters.size) { - return true; - } - - if (this.tags) { - let hasFilteredTag = true; - tagFilters.forEach(tag => { - hasFilteredTag = hasFilteredTag && this.tags.has(tag); - }); - return hasFilteredTag; - } else { - return false; - } - } -} - -export interface ITOCEntry { - id: string; - label: string; - children?: ITOCEntry[]; - settings?: (string | ISetting)[]; -} - -export class SettingsTreeModel { - protected _root: SettingsTreeGroupElement; - private _treeElementsById = new Map(); - private _treeElementsBySettingName = new Map(); - private _tocRoot: ITOCEntry; - - constructor( - private _viewState: ISettingsEditorViewState, - @IConfigurationService private _configurationService: IConfigurationService - ) { } - - get root(): SettingsTreeGroupElement { - return this._root; - } - - update(newTocRoot = this._tocRoot): void { - const newRoot = this.createSettingsTreeGroupElement(newTocRoot); - if (newRoot.children[0] instanceof SettingsTreeGroupElement) { - (newRoot.children[0]).isFirstGroup = true; // TODO - } - - if (this._root) { - this._root.children = newRoot.children; - } else { - this._root = newRoot; - } - } - - getElementById(id: string): SettingsTreeElement { - return this._treeElementsById.get(id); - } - - getElementByName(name: string): SettingsTreeElement { - return this._treeElementsBySettingName.get(name); - } - - private createSettingsTreeGroupElement(tocEntry: ITOCEntry, parent?: SettingsTreeGroupElement): SettingsTreeGroupElement { - const element = new SettingsTreeGroupElement(); - element.id = tocEntry.id; - element.label = tocEntry.label; - element.parent = parent; - element.level = this.getDepth(element); - - if (tocEntry.children) { - element.children = tocEntry.children.map(child => this.createSettingsTreeGroupElement(child, element)); - } else if (tocEntry.settings) { - element.children = tocEntry.settings.map(s => this.createSettingsTreeSettingElement(s, element)) - .filter(el => el.setting.deprecationMessage ? el.isConfigured : true); - } else { - element.children = []; - } - - this._treeElementsById.set(element.id, element); - return element; - } - - private getDepth(element: SettingsTreeElement): number { - if (element.parent) { - return 1 + this.getDepth(element.parent); - } else { - return 0; - } - } - - private createSettingsTreeSettingElement(setting: ISetting, parent: SettingsTreeGroupElement): SettingsTreeSettingElement { - const element = createSettingsTreeSettingElement(setting, parent, this._viewState.settingsTarget, this._configurationService); - this._treeElementsById.set(element.id, element); - this._treeElementsBySettingName.set(setting.key, element); - return element; - } -} - -function sanitizeId(id: string): string { - return id.replace(/[\.\/]/, '_'); -} - -function createSettingsTreeSettingElement(setting: ISetting, parent: SettingsTreeGroupElement, settingsTarget: SettingsTarget, configurationService: IConfigurationService): SettingsTreeSettingElement { - const element = new SettingsTreeSettingElement(); - element.id = sanitizeId(parent.id + '_' + setting.key); - element.parent = parent; - - const inspectResult = inspectSetting(setting.key, settingsTarget, configurationService); - const { isConfigured, inspected, targetSelector } = inspectResult; - - const displayValue = isConfigured ? inspected[targetSelector] : inspected.default; - const overriddenScopeList = []; - if (targetSelector === 'user' && typeof inspected.workspace !== 'undefined') { - overriddenScopeList.push(localize('workspace', "Workspace")); - } - - if (targetSelector === 'workspace' && typeof inspected.user !== 'undefined') { - overriddenScopeList.push(localize('user', "User")); - } - - const displayKeyFormat = settingKeyToDisplayFormat(setting.key, parent.id); - element.setting = setting; - element.displayLabel = displayKeyFormat.label; - element.displayCategory = displayKeyFormat.category; - - element.value = displayValue; - element.scopeValue = isConfigured && inspected[targetSelector]; - element.defaultValue = inspected.default; - - element.isConfigured = isConfigured; - if (isConfigured || setting.tags) { - element.tags = new Set(); - if (isConfigured) { - element.tags.add(MODIFIED_SETTING_TAG); - } - - if (setting.tags) { - setting.tags.forEach(tag => element.tags.add(tag)); - } - } - - element.overriddenScopeList = overriddenScopeList; - element.description = setting.description.join('\n'); - - if (setting.enum && (setting.type === 'string' || !setting.type)) { - element.valueType = 'enum'; - } else if (setting.type === 'string') { - element.valueType = 'string'; - } else if (isExcludeSetting(setting)) { - element.valueType = 'exclude'; - } else if (setting.type === 'integer') { - element.valueType = 'integer'; - } else if (setting.type === 'number') { - element.valueType = 'number'; - } else if (setting.type === 'boolean') { - element.valueType = 'boolean'; - } else { - element.valueType = 'complex'; - } - - return element; -} function getExcludeDisplayValue(element: SettingsTreeSettingElement): IExcludeDataItem[] { const data = element.isConfigured ? @@ -273,23 +62,6 @@ function getExcludeDisplayValue(element: SettingsTreeSettingElement): IExcludeDa }); } -interface IInspectResult { - isConfigured: boolean; - inspected: any; - targetSelector: string; -} - -function inspectSetting(key: string, target: SettingsTarget, configurationService: IConfigurationService): IInspectResult { - const inspectOverrides = URI.isUri(target) ? { resource: target } : undefined; - const inspected = configurationService.inspect(key, inspectOverrides); - const targetSelector = target === ConfigurationTarget.USER ? 'user' : - target === ConfigurationTarget.WORKSPACE ? 'workspace' : - 'workspaceFolder'; - const isConfigured = typeof inspected[targetSelector] !== 'undefined'; - - return { isConfigured, inspected, targetSelector }; -} - export function resolveSettingsTree(tocData: ITOCEntry, coreSettingsGroups: ISettingsGroup[]): { tree: ITOCEntry, leftoverSettings: Set } { const allSettings = getFlatSettings(coreSettingsGroups); return { @@ -416,66 +188,6 @@ export class SettingsDataSource implements IDataSource { } } -export function settingKeyToDisplayFormat(key: string, groupId = ''): { category: string, label: string } { - const lastDotIdx = key.lastIndexOf('.'); - let category = ''; - if (lastDotIdx >= 0) { - category = key.substr(0, lastDotIdx); - key = key.substr(lastDotIdx + 1); - } - - groupId = groupId.replace(/\//g, '.'); - category = trimCategoryForGroup(category, groupId); - category = wordifyKey(category); - - const label = wordifyKey(key); - return { category, label }; -} - -function wordifyKey(key: string): string { - return key - .replace(/\.([a-z])/g, (match, p1) => `.${p1.toUpperCase()}`) - .replace(/([a-z])([A-Z])/g, '$1 $2') // fooBar => foo Bar - .replace(/^[a-z]/g, match => match.toUpperCase()); // foo => Foo -} - -function trimCategoryForGroup(category: string, groupId: string): string { - const doTrim = forward => { - const parts = groupId.split('.'); - while (parts.length) { - const reg = new RegExp(`^${parts.join('\\.')}(\\.|$)`, 'i'); - if (reg.test(category)) { - return category.replace(reg, ''); - } - - if (forward) { - parts.pop(); - } else { - parts.shift(); - } - } - - return null; - }; - - let trimmed = doTrim(true); - if (trimmed === null) { - trimmed = doTrim(false); - } - - if (trimmed === null) { - trimmed = category; - } - - return trimmed; -} - -export interface ISettingsEditorViewState { - settingsTarget: SettingsTarget; - tagFilters?: Set; - filterToCategory?: SettingsTreeGroupElement; -} - interface IDisposableTemplate { toDispose: IDisposable[]; } @@ -521,11 +233,6 @@ interface ISettingNewExtensionsTemplate extends IDisposableTemplate { context?: SettingsTreeNewExtensionsElement; } -function isExcludeSetting(setting: ISetting): boolean { - return setting.key === 'files.exclude' || - setting.key === 'search.exclude'; -} - interface IGroupTitleTemplate extends IDisposableTemplate { context?: SettingsTreeGroupElement; parent: HTMLElement; @@ -1376,102 +1083,6 @@ export class SettingsAccessibilityProvider implements IAccessibilityProvider { } } -export enum SearchResultIdx { - Local = 0, - Remote = 1, - NewExtensions = 2 -} - -export class SearchResultModel extends SettingsTreeModel { - private rawSearchResults: ISearchResult[]; - private cachedUniqueSearchResults: ISearchResult[]; - private newExtensionSearchResults: ISearchResult; - - readonly id = 'searchResultModel'; - - constructor( - viewState: ISettingsEditorViewState, - @IConfigurationService configurationService: IConfigurationService - ) { - super(viewState, configurationService); - this.update({ id: 'searchResultModel', label: '' }); - } - - getUniqueResults(): ISearchResult[] { - if (this.cachedUniqueSearchResults) { - return this.cachedUniqueSearchResults; - } - - if (!this.rawSearchResults) { - return []; - } - - const localMatchKeys = new Set(); - const localResult = objects.deepClone(this.rawSearchResults[SearchResultIdx.Local]); - if (localResult) { - localResult.filterMatches.forEach(m => localMatchKeys.add(m.setting.key)); - } - - const remoteResult = objects.deepClone(this.rawSearchResults[SearchResultIdx.Remote]); - if (remoteResult) { - remoteResult.filterMatches = remoteResult.filterMatches.filter(m => !localMatchKeys.has(m.setting.key)); - } - - this.newExtensionSearchResults = objects.deepClone(this.rawSearchResults[SearchResultIdx.NewExtensions]); - - this.cachedUniqueSearchResults = [localResult, remoteResult]; - return this.cachedUniqueSearchResults; - } - - getRawResults(): ISearchResult[] { - return this.rawSearchResults; - } - - setResult(order: SearchResultIdx, result: ISearchResult): void { - this.cachedUniqueSearchResults = null; - this.rawSearchResults = this.rawSearchResults || []; - if (!result) { - delete this.rawSearchResults[order]; - return; - } - - this.rawSearchResults[order] = result; - this.updateChildren(); - } - - updateChildren(): void { - this.update({ - id: 'searchResultModel', - label: 'searchResultModel', - settings: this.getFlatSettings() - }); - - if (this.newExtensionSearchResults) { - const newExtElement = new SettingsTreeNewExtensionsElement(); - newExtElement.parent = this._root; - newExtElement.id = 'newExtensions'; - const resultExtensionIds = this.newExtensionSearchResults.filterMatches - .map(result => (result.setting)) - .filter(setting => setting.extensionName && setting.extensionPublisher) - .map(setting => `${setting.extensionPublisher}.${setting.extensionName}`); - newExtElement.extensionIds = arrays.distinct(resultExtensionIds); - this._root.children.push(newExtElement); - } - } - - private getFlatSettings(): ISetting[] { - const flatSettings: ISetting[] = []; - this.getUniqueResults() - .filter(r => !!r) - .forEach(r => { - flatSettings.push( - ...r.filterMatches.map(m => m.setting)); - }); - - return flatSettings; - } -} - class NonExpandableOrSelectableTree extends Tree { expand(): TPromise { return TPromise.wrap(null); diff --git a/src/vs/workbench/parts/preferences/browser/settingsTreeModels.ts b/src/vs/workbench/parts/preferences/browser/settingsTreeModels.ts new file mode 100644 index 00000000000..45a450dc787 --- /dev/null +++ b/src/vs/workbench/parts/preferences/browser/settingsTreeModels.ts @@ -0,0 +1,396 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import * as arrays from 'vs/base/common/arrays'; +import * as objects from 'vs/base/common/objects'; +import URI from 'vs/base/common/uri'; +import { localize } from 'vs/nls'; +import { ConfigurationTarget, IConfigurationService } from 'vs/platform/configuration/common/configuration'; +import { SettingsTarget } from 'vs/workbench/parts/preferences/browser/preferencesWidgets'; +import { ITOCEntry } from 'vs/workbench/parts/preferences/browser/settingsLayout'; +import { IExtensionSetting, ISearchResult, ISetting } from 'vs/workbench/services/preferences/common/preferences'; + +export const MODIFIED_SETTING_TAG = 'modified'; +export const ONLINE_SERVICES_SETTING_TAG = 'usesOnlineServices'; + +export interface ISettingsEditorViewState { + settingsTarget: SettingsTarget; + tagFilters?: Set; + filterToCategory?: SettingsTreeGroupElement; +} + +export abstract class SettingsTreeElement { + id: string; + parent: SettingsTreeGroupElement; +} + +export class SettingsTreeGroupElement extends SettingsTreeElement { + children: (SettingsTreeGroupElement | SettingsTreeSettingElement | SettingsTreeNewExtensionsElement)[]; + count?: number; + label: string; + level: number; + isFirstGroup: boolean; +} + +export class SettingsTreeNewExtensionsElement extends SettingsTreeElement { + extensionIds: string[]; +} + +export class SettingsTreeSettingElement extends SettingsTreeElement { + setting: ISetting; + + displayCategory: string; + displayLabel: string; + + /** + * scopeValue || defaultValue, for rendering convenience. + */ + value: any; + + /** + * The value in the current settings scope. + */ + scopeValue: any; + + /** + * The default value + */ + defaultValue?: any; + + /** + * Whether the setting is configured in the selected scope. + */ + isConfigured: boolean; + + tags?: Set; + overriddenScopeList: string[]; + description: string; + valueType: 'enum' | 'string' | 'integer' | 'number' | 'boolean' | 'exclude' | 'complex'; + + matchesAllTags(tagFilters?: Set): boolean { + if (!tagFilters || !tagFilters.size) { + return true; + } + + if (this.tags) { + let hasFilteredTag = true; + tagFilters.forEach(tag => { + hasFilteredTag = hasFilteredTag && this.tags.has(tag); + }); + return hasFilteredTag; + } else { + return false; + } + } +} + +export class SettingsTreeModel { + protected _root: SettingsTreeGroupElement; + private _treeElementsById = new Map(); + private _treeElementsBySettingName = new Map(); + private _tocRoot: ITOCEntry; + + constructor( + private _viewState: ISettingsEditorViewState, + @IConfigurationService private _configurationService: IConfigurationService + ) { } + + get root(): SettingsTreeGroupElement { + return this._root; + } + + update(newTocRoot = this._tocRoot): void { + const newRoot = this.createSettingsTreeGroupElement(newTocRoot); + if (newRoot.children[0] instanceof SettingsTreeGroupElement) { + (newRoot.children[0]).isFirstGroup = true; // TODO + } + + if (this._root) { + this._root.children = newRoot.children; + } else { + this._root = newRoot; + } + } + + getElementById(id: string): SettingsTreeElement { + return this._treeElementsById.get(id); + } + + getElementByName(name: string): SettingsTreeElement { + return this._treeElementsBySettingName.get(name); + } + + private createSettingsTreeGroupElement(tocEntry: ITOCEntry, parent?: SettingsTreeGroupElement): SettingsTreeGroupElement { + const element = new SettingsTreeGroupElement(); + element.id = tocEntry.id; + element.label = tocEntry.label; + element.parent = parent; + element.level = this.getDepth(element); + + if (tocEntry.children) { + element.children = tocEntry.children.map(child => this.createSettingsTreeGroupElement(child, element)); + } else if (tocEntry.settings) { + element.children = tocEntry.settings.map(s => this.createSettingsTreeSettingElement(s, element)) + .filter(el => el.setting.deprecationMessage ? el.isConfigured : true); + } else { + element.children = []; + } + + this._treeElementsById.set(element.id, element); + return element; + } + + private getDepth(element: SettingsTreeElement): number { + if (element.parent) { + return 1 + this.getDepth(element.parent); + } else { + return 0; + } + } + + private createSettingsTreeSettingElement(setting: ISetting, parent: SettingsTreeGroupElement): SettingsTreeSettingElement { + const element = createSettingsTreeSettingElement(setting, parent, this._viewState.settingsTarget, this._configurationService); + this._treeElementsById.set(element.id, element); + this._treeElementsBySettingName.set(setting.key, element); + return element; + } +} + +interface IInspectResult { + isConfigured: boolean; + inspected: any; + targetSelector: string; +} + +function inspectSetting(key: string, target: SettingsTarget, configurationService: IConfigurationService): IInspectResult { + const inspectOverrides = URI.isUri(target) ? { resource: target } : undefined; + const inspected = configurationService.inspect(key, inspectOverrides); + const targetSelector = target === ConfigurationTarget.USER ? 'user' : + target === ConfigurationTarget.WORKSPACE ? 'workspace' : + 'workspaceFolder'; + const isConfigured = typeof inspected[targetSelector] !== 'undefined'; + + return { isConfigured, inspected, targetSelector }; +} + +function sanitizeId(id: string): string { + return id.replace(/[\.\/]/, '_'); +} + +export function settingKeyToDisplayFormat(key: string, groupId = ''): { category: string, label: string } { + const lastDotIdx = key.lastIndexOf('.'); + let category = ''; + if (lastDotIdx >= 0) { + category = key.substr(0, lastDotIdx); + key = key.substr(lastDotIdx + 1); + } + + groupId = groupId.replace(/\//g, '.'); + category = trimCategoryForGroup(category, groupId); + category = wordifyKey(category); + + const label = wordifyKey(key); + return { category, label }; +} + +function wordifyKey(key: string): string { + return key + .replace(/\.([a-z])/g, (match, p1) => `.${p1.toUpperCase()}`) + .replace(/([a-z])([A-Z])/g, '$1 $2') // fooBar => foo Bar + .replace(/^[a-z]/g, match => match.toUpperCase()); // foo => Foo +} + +function trimCategoryForGroup(category: string, groupId: string): string { + const doTrim = forward => { + const parts = groupId.split('.'); + while (parts.length) { + const reg = new RegExp(`^${parts.join('\\.')}(\\.|$)`, 'i'); + if (reg.test(category)) { + return category.replace(reg, ''); + } + + if (forward) { + parts.pop(); + } else { + parts.shift(); + } + } + + return null; + }; + + let trimmed = doTrim(true); + if (trimmed === null) { + trimmed = doTrim(false); + } + + if (trimmed === null) { + trimmed = category; + } + + return trimmed; +} + +export function isExcludeSetting(setting: ISetting): boolean { + return setting.key === 'files.exclude' || + setting.key === 'search.exclude'; +} + +function createSettingsTreeSettingElement(setting: ISetting, parent: SettingsTreeGroupElement, settingsTarget: SettingsTarget, configurationService: IConfigurationService): SettingsTreeSettingElement { + const element = new SettingsTreeSettingElement(); + element.id = sanitizeId(parent.id + '_' + setting.key); + element.parent = parent; + + const inspectResult = inspectSetting(setting.key, settingsTarget, configurationService); + const { isConfigured, inspected, targetSelector } = inspectResult; + + const displayValue = isConfigured ? inspected[targetSelector] : inspected.default; + const overriddenScopeList = []; + if (targetSelector === 'user' && typeof inspected.workspace !== 'undefined') { + overriddenScopeList.push(localize('workspace', "Workspace")); + } + + if (targetSelector === 'workspace' && typeof inspected.user !== 'undefined') { + overriddenScopeList.push(localize('user', "User")); + } + + const displayKeyFormat = settingKeyToDisplayFormat(setting.key, parent.id); + element.setting = setting; + element.displayLabel = displayKeyFormat.label; + element.displayCategory = displayKeyFormat.category; + + element.value = displayValue; + element.scopeValue = isConfigured && inspected[targetSelector]; + element.defaultValue = inspected.default; + + element.isConfigured = isConfigured; + if (isConfigured || setting.tags) { + element.tags = new Set(); + if (isConfigured) { + element.tags.add(MODIFIED_SETTING_TAG); + } + + if (setting.tags) { + setting.tags.forEach(tag => element.tags.add(tag)); + } + } + + element.overriddenScopeList = overriddenScopeList; + element.description = setting.description.join('\n'); + + if (setting.enum && (setting.type === 'string' || !setting.type)) { + element.valueType = 'enum'; + } else if (setting.type === 'string') { + element.valueType = 'string'; + } else if (isExcludeSetting(setting)) { + element.valueType = 'exclude'; + } else if (setting.type === 'integer') { + element.valueType = 'integer'; + } else if (setting.type === 'number') { + element.valueType = 'number'; + } else if (setting.type === 'boolean') { + element.valueType = 'boolean'; + } else { + element.valueType = 'complex'; + } + + return element; +} + +export enum SearchResultIdx { + Local = 0, + Remote = 1, + NewExtensions = 2 +} + +export class SearchResultModel extends SettingsTreeModel { + private rawSearchResults: ISearchResult[]; + private cachedUniqueSearchResults: ISearchResult[]; + private newExtensionSearchResults: ISearchResult; + + readonly id = 'searchResultModel'; + + constructor( + viewState: ISettingsEditorViewState, + @IConfigurationService configurationService: IConfigurationService + ) { + super(viewState, configurationService); + this.update({ id: 'searchResultModel', label: '' }); + } + + getUniqueResults(): ISearchResult[] { + if (this.cachedUniqueSearchResults) { + return this.cachedUniqueSearchResults; + } + + if (!this.rawSearchResults) { + return []; + } + + const localMatchKeys = new Set(); + const localResult = objects.deepClone(this.rawSearchResults[SearchResultIdx.Local]); + if (localResult) { + localResult.filterMatches.forEach(m => localMatchKeys.add(m.setting.key)); + } + + const remoteResult = objects.deepClone(this.rawSearchResults[SearchResultIdx.Remote]); + if (remoteResult) { + remoteResult.filterMatches = remoteResult.filterMatches.filter(m => !localMatchKeys.has(m.setting.key)); + } + + this.newExtensionSearchResults = objects.deepClone(this.rawSearchResults[SearchResultIdx.NewExtensions]); + + this.cachedUniqueSearchResults = [localResult, remoteResult]; + return this.cachedUniqueSearchResults; + } + + getRawResults(): ISearchResult[] { + return this.rawSearchResults; + } + + setResult(order: SearchResultIdx, result: ISearchResult): void { + this.cachedUniqueSearchResults = null; + this.rawSearchResults = this.rawSearchResults || []; + if (!result) { + delete this.rawSearchResults[order]; + return; + } + + this.rawSearchResults[order] = result; + this.updateChildren(); + } + + updateChildren(): void { + this.update({ + id: 'searchResultModel', + label: 'searchResultModel', + settings: this.getFlatSettings() + }); + + if (this.newExtensionSearchResults) { + const newExtElement = new SettingsTreeNewExtensionsElement(); + newExtElement.parent = this._root; + newExtElement.id = 'newExtensions'; + const resultExtensionIds = this.newExtensionSearchResults.filterMatches + .map(result => (result.setting)) + .filter(setting => setting.extensionName && setting.extensionPublisher) + .map(setting => `${setting.extensionPublisher}.${setting.extensionName}`); + newExtElement.extensionIds = arrays.distinct(resultExtensionIds); + this._root.children.push(newExtElement); + } + } + + private getFlatSettings(): ISetting[] { + const flatSettings: ISetting[] = []; + this.getUniqueResults() + .filter(r => !!r) + .forEach(r => { + flatSettings.push( + ...r.filterMatches.map(m => m.setting)); + }); + + return flatSettings; + } +} \ No newline at end of file diff --git a/src/vs/workbench/parts/preferences/browser/tocTree.ts b/src/vs/workbench/parts/preferences/browser/tocTree.ts index e11d096c8a0..04b2710ebb3 100644 --- a/src/vs/workbench/parts/preferences/browser/tocTree.ts +++ b/src/vs/workbench/parts/preferences/browser/tocTree.ts @@ -14,7 +14,8 @@ import { IListService, WorkbenchTree, WorkbenchTreeController } from 'vs/platfor import { editorBackground, focusBorder } from 'vs/platform/theme/common/colorRegistry'; import { attachStyler } from 'vs/platform/theme/common/styler'; import { ICssStyleCollector, ITheme, IThemeService, registerThemingParticipant } from 'vs/platform/theme/common/themeService'; -import { ISettingsEditorViewState, SearchResultModel, SettingsAccessibilityProvider, SettingsTreeElement, SettingsTreeFilter, SettingsTreeGroupElement, SettingsTreeSettingElement } from 'vs/workbench/parts/preferences/browser/settingsTree'; +import { SettingsAccessibilityProvider, SettingsTreeFilter } from 'vs/workbench/parts/preferences/browser/settingsTree'; +import { ISettingsEditorViewState, SearchResultModel, SettingsTreeElement, SettingsTreeGroupElement, SettingsTreeSettingElement } from 'vs/workbench/parts/preferences/browser/settingsTreeModels'; import { settingsHeaderForeground } from 'vs/workbench/parts/preferences/browser/settingsWidgets'; import { ISetting } from 'vs/workbench/services/preferences/common/preferences'; diff --git a/src/vs/workbench/parts/preferences/test/browser/settingsTree.test.ts b/src/vs/workbench/parts/preferences/test/browser/settingsTree.test.ts index 06517a42795..9ddd279b6ab 100644 --- a/src/vs/workbench/parts/preferences/test/browser/settingsTree.test.ts +++ b/src/vs/workbench/parts/preferences/test/browser/settingsTree.test.ts @@ -6,7 +6,7 @@ 'use strict'; import * as assert from 'assert'; -import { settingKeyToDisplayFormat } from 'vs/workbench/parts/preferences/browser/settingsTree'; +import { settingKeyToDisplayFormat } from 'vs/workbench/parts/preferences/browser/settingsTreeModels'; suite('SettingsTree', () => { test('settingKeyToDisplayFormat', () => { From 9354a17a1960c4289f661f7a73f9f5e7ce3693b4 Mon Sep 17 00:00:00 2001 From: Rob Lourens Date: Sat, 11 Aug 2018 08:30:15 -0700 Subject: [PATCH 0706/1276] #55803 - get rid of focus maintaining hack, allow refreshing single setting rows --- .../preferences/browser/settingsEditor2.ts | 104 ++++++++---- .../parts/preferences/browser/settingsTree.ts | 21 ++- .../preferences/browser/settingsTreeModels.ts | 149 ++++++++++-------- 3 files changed, 175 insertions(+), 99 deletions(-) diff --git a/src/vs/workbench/parts/preferences/browser/settingsEditor2.ts b/src/vs/workbench/parts/preferences/browser/settingsEditor2.ts index 3796be5e51f..f3fa52ee562 100644 --- a/src/vs/workbench/parts/preferences/browser/settingsEditor2.ts +++ b/src/vs/workbench/parts/preferences/browser/settingsEditor2.ts @@ -71,7 +71,9 @@ export class SettingsEditor2 extends BaseEditor { private localSearchDelayer: Delayer; private remoteSearchThrottle: ThrottledDelayer; private searchInProgress: TPromise; + private delayRefreshOnLayout: Delayer; + private lastLayedoutWidth: number; private settingUpdateDelayer: Delayer; private pendingSettingUpdate: { key: string, value: any }; @@ -83,7 +85,7 @@ export class SettingsEditor2 extends BaseEditor { private inSettingsEditorContextKey: IContextKey; private searchFocusContextKey: IContextKey; - private scheduledRefreshTracker: DOM.IFocusTracker; + private scheduledRefreshes: Map; private tagRegex = /(^|\s)@tag:("([^"]*)"|[^"]\S*)/g; @@ -115,8 +117,10 @@ export class SettingsEditor2 extends BaseEditor { this.searchFocusContextKey = CONTEXT_SETTINGS_SEARCH_FOCUS.bindTo(contextKeyService); this.tocRowFocused = CONTEXT_TOC_ROW_FOCUS.bindTo(contextKeyService); + this.scheduledRefreshes = new Map(); + this._register(configurationService.onDidChangeConfiguration(e => { - this.onConfigUpdate(); + this.onConfigUpdate(e.affectedKeys); })); } @@ -152,7 +156,11 @@ export class SettingsEditor2 extends BaseEditor { DOM.toggleClass(this.rootElement, 'narrow', dimension.width < 600); - this.delayRefreshOnLayout.trigger(() => this.refreshTree()); + // #56185 + if (dimension.width !== this.lastLayedoutWidth) { + this.lastLayedoutWidth = dimension.width; + this.delayRefreshOnLayout.trigger(() => this.renderTree()); + } } focus(): void { @@ -217,7 +225,7 @@ export class SettingsEditor2 extends BaseEditor { this.toolbar.context = { target: this.settingsTargetsWidget.settingsTarget }; this.settingsTreeModel.update(); - this.refreshTree(); + this.renderTree(); }); this.createHeaderControls(headerControlsContainer); @@ -252,8 +260,12 @@ export class SettingsEditor2 extends BaseEditor { this.toolbar.context = { target: this.settingsTargetsWidget.settingsTarget }; } - private revealSetting(settingName: string): void { - const element = this.settingsTreeModel.getElementByName(settingName); + private getElementsByKey(settingKey: string): SettingsTreeSettingElement[] | null { + return (this.searchResultModel || this.settingsTreeModel).getElementByName(settingKey); + } + + private revealSetting(settingKey: string): void { + const element = this.getElementsByKey(settingKey); if (element) { this.settingsTree.reveal(element, .1); } @@ -357,7 +369,7 @@ export class SettingsEditor2 extends BaseEditor { const element = e.focus; if (this.searchResultModel) { this.viewState.filterToCategory = element; - this.refreshTree(); + this.renderTree(); } if (element && (!e.payload || !e.payload.fromScroll)) { @@ -467,7 +479,7 @@ export class SettingsEditor2 extends BaseEditor { } return this.configurationService.updateValue(key, value, overrides, configurationTarget) - .then(() => this.refreshTree()) + .then(() => this.renderTree(key)) // to draw "Modified" TODO .then(() => { const reportModifiedProps = { key, @@ -564,20 +576,30 @@ export class SettingsEditor2 extends BaseEditor { } } - private scheduleRefresh(): void { - if (this.scheduledRefreshTracker) { + private scheduleRefresh(element: HTMLElement, key = ''): void { + if (key && this.scheduledRefreshes.has(key)) { return; } - this.scheduledRefreshTracker = DOM.trackFocus(document.activeElement); - this.scheduledRefreshTracker.onDidBlur(() => { - this.scheduledRefreshTracker.dispose(); - this.scheduledRefreshTracker = null; - this.refreshTree(); + if (!key) { + this.scheduledRefreshes.forEach(r => r.dispose()); + this.scheduledRefreshes.clear(); + } + + const scheduledRefreshTracker = DOM.trackFocus(element); + this.scheduledRefreshes.set(key, scheduledRefreshTracker); + scheduledRefreshTracker.onDidBlur(() => { + scheduledRefreshTracker.dispose(); + this.scheduledRefreshes.delete(key); + this.onConfigUpdate([key]); }); } - private onConfigUpdate(): TPromise { + private onConfigUpdate(keys?: string[]): TPromise { + if (keys) { + return this.updateElementsByKey(keys); + } + const groups = this.defaultSettingsEditorModel.settingsGroups.slice(1); // Without commonlyUsed const dividedGroups = collections.groupBy(groups, g => g.contributedByExtension ? 'extension' : 'core'); const settingsResult = resolveSettingsTree(tocData, dividedGroups.core); @@ -605,7 +627,7 @@ export class SettingsEditor2 extends BaseEditor { if (this.settingsTreeModel) { this.settingsTreeModel.update(resolvedSettingsRoot); - return this.refreshTree(); + return this.renderTree(); } else { this.settingsTreeModel = this.instantiationService.createInstance(SettingsTreeModel, this.viewState); this.settingsTreeModel.update(resolvedSettingsRoot); @@ -622,21 +644,49 @@ export class SettingsEditor2 extends BaseEditor { return TPromise.wrap(null); } - private refreshTree(element?: SettingsTreeElement): TPromise { - if (this.scheduledRefreshTracker) { + private updateElementsByKey(keys: string[]): TPromise { + if (keys.length) { + keys.forEach(key => this.settingsTreeModel.updateElementsByName(key)); + return TPromise.join( + keys.map(key => this.renderTree(key))) + .then(() => { }); + } else { + return this.renderTree(); + } + } + + private renderTree(key?: string): TPromise { + if (key && this.scheduledRefreshes.has(key)) { return TPromise.wrap(null); } + // If a setting control is currently focused, schedule a refresh for later if (document.activeElement.classList.contains(SettingsRenderer.CONTROL_CLASS)) { - this.scheduleRefresh(); - return TPromise.wrap(null); + // If a single setting is being refreshed, it's ok to refresh now if that is not the focused setting + if (key) { + const focusedKey = this.settingsTreeRenderer.getSettingKeyForDOMElement(document.activeElement); + if (focusedKey === key) { + this.scheduleRefresh(document.activeElement, key); + return TPromise.wrap(null); + } + } else { + this.scheduleRefresh(document.activeElement); + return TPromise.wrap(null); + } } - return this.settingsTree.refresh() - .then(() => { - this.tocTreeModel.update(); - return this.tocTree.refresh(); - }); + let refreshP: TPromise; + const elements = key && this.getElementsByKey(key); + if (elements && elements.length) { + refreshP = TPromise.join(elements.map(e => this.settingsTree.refresh(e))); + } else { + refreshP = this.settingsTree.refresh(); + } + + return refreshP.then(() => { + this.tocTreeModel.update(); // ? + return this.tocTree.refresh(); + }).then(() => { }); } private onSearchInputChanged(): void { @@ -790,7 +840,7 @@ export class SettingsEditor2 extends BaseEditor { this.tocTreeModel.update(); expandAll(this.tocTree); - resolve(this.refreshTree()); + resolve(this.renderTree()); }); }, () => { isCanceled = true; diff --git a/src/vs/workbench/parts/preferences/browser/settingsTree.ts b/src/vs/workbench/parts/preferences/browser/settingsTree.ts index 241c6949e4d..eefdbd0c13f 100644 --- a/src/vs/workbench/parts/preferences/browser/settingsTree.ts +++ b/src/vs/workbench/parts/preferences/browser/settingsTree.ts @@ -27,10 +27,9 @@ import { Tree } from 'vs/base/parts/tree/browser/treeImpl'; import { localize } from 'vs/nls'; import { ICommandService } from 'vs/platform/commands/common/commands'; import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; -import { IContextKeyService } from 'vs/platform/contextkey/common/contextkey'; import { IContextViewService } from 'vs/platform/contextview/browser/contextView'; import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; -import { IListService, WorkbenchTreeController } from 'vs/platform/list/browser/listService'; +import { WorkbenchTreeController } from 'vs/platform/list/browser/listService'; import { IOpenerService } from 'vs/platform/opener/common/opener'; import { editorBackground, focusBorder, foreground } from 'vs/platform/theme/common/colorRegistry'; import { attachButtonStyler, attachInputBoxStyler, attachSelectBoxStyler, attachStyler } from 'vs/platform/theme/common/styler'; @@ -259,6 +258,8 @@ export class SettingsRenderer implements ITreeRenderer { public static readonly CONTROL_CLASS = 'setting-control-focus-target'; public static readonly CONTROL_SELECTOR = '.' + SettingsRenderer.CONTROL_CLASS; + private static readonly SETTING_KEY_ATTR = 'data-key'; + private readonly _onDidChangeSetting: Emitter = new Emitter(); public readonly onDidChangeSetting: Event = this._onDidChangeSetting.event; @@ -755,6 +756,15 @@ export class SettingsRenderer implements ITreeRenderer { template.context = element; } + public getSettingKeyForDOMElement(domElement: HTMLElement): string { + const parent = DOM.findParentWithClass(domElement, 'setting-item'); + if (parent) { + return parent.getAttribute(SettingsRenderer.SETTING_KEY_ATTR); + } + + return null; + } + private renderSettingElement(tree: ITree, element: SettingsTreeSettingElement, templateId: string, template: ISettingItemTemplate | ISettingBoolItemTemplate): void { template.context = element; @@ -762,7 +772,7 @@ export class SettingsRenderer implements ITreeRenderer { DOM.toggleClass(template.containerElement, 'is-configured', element.isConfigured); DOM.toggleClass(template.containerElement, 'is-expanded', true); - template.containerElement.id = element.id.replace(/\./g, '_'); + template.containerElement.setAttribute(SettingsRenderer.SETTING_KEY_ATTR, element.setting.key); const titleTooltip = setting.key; template.categoryElement.textContent = element.displayCategory && (element.displayCategory + ': '); @@ -1160,11 +1170,8 @@ export class SettingsTree extends NonExpandableOrSelectableTree { container: HTMLElement, viewState: ISettingsEditorViewState, configuration: Partial, - @IContextKeyService contextKeyService: IContextKeyService, - @IListService listService: IListService, @IThemeService themeService: IThemeService, - @IInstantiationService instantiationService: IInstantiationService, - @IConfigurationService configurationService: IConfigurationService + @IInstantiationService instantiationService: IInstantiationService ) { const treeClass = 'settings-editor-tree'; diff --git a/src/vs/workbench/parts/preferences/browser/settingsTreeModels.ts b/src/vs/workbench/parts/preferences/browser/settingsTreeModels.ts index 45a450dc787..4f2b1e428a8 100644 --- a/src/vs/workbench/parts/preferences/browser/settingsTreeModels.ts +++ b/src/vs/workbench/parts/preferences/browser/settingsTreeModels.ts @@ -69,6 +69,68 @@ export class SettingsTreeSettingElement extends SettingsTreeElement { description: string; valueType: 'enum' | 'string' | 'integer' | 'number' | 'boolean' | 'exclude' | 'complex'; + constructor(setting: ISetting, parent: SettingsTreeGroupElement, inspectResult: IInspectResult) { + super(); + this.setting = setting; + this.parent = parent; + this.id = sanitizeId(parent.id + '_' + setting.key); + + this.update(inspectResult); + } + + update(inspectResult: IInspectResult): void { + const { isConfigured, inspected, targetSelector } = inspectResult; + + const displayValue = isConfigured ? inspected[targetSelector] : inspected.default; + const overriddenScopeList = []; + if (targetSelector === 'user' && typeof inspected.workspace !== 'undefined') { + overriddenScopeList.push(localize('workspace', "Workspace")); + } + + if (targetSelector === 'workspace' && typeof inspected.user !== 'undefined') { + overriddenScopeList.push(localize('user', "User")); + } + + const displayKeyFormat = settingKeyToDisplayFormat(this.setting.key, this.parent.id); + this.displayLabel = displayKeyFormat.label; + this.displayCategory = displayKeyFormat.category; + + this.value = displayValue; + this.scopeValue = isConfigured && inspected[targetSelector]; + this.defaultValue = inspected.default; + + this.isConfigured = isConfigured; + if (isConfigured || this.setting.tags) { + this.tags = new Set(); + if (isConfigured) { + this.tags.add(MODIFIED_SETTING_TAG); + } + + if (this.setting.tags) { + this.setting.tags.forEach(tag => this.tags.add(tag)); + } + } + + this.overriddenScopeList = overriddenScopeList; + this.description = this.setting.description.join('\n'); + + if (this.setting.enum && (this.setting.type === 'string' || !this.setting.type)) { + this.valueType = 'enum'; + } else if (this.setting.type === 'string') { + this.valueType = 'string'; + } else if (isExcludeSetting(this.setting)) { + this.valueType = 'exclude'; + } else if (this.setting.type === 'integer') { + this.valueType = 'integer'; + } else if (this.setting.type === 'number') { + this.valueType = 'number'; + } else if (this.setting.type === 'boolean') { + this.valueType = 'boolean'; + } else { + this.valueType = 'complex'; + } + } + matchesAllTags(tagFilters?: Set): boolean { if (!tagFilters || !tagFilters.size) { return true; @@ -89,7 +151,7 @@ export class SettingsTreeSettingElement extends SettingsTreeElement { export class SettingsTreeModel { protected _root: SettingsTreeGroupElement; private _treeElementsById = new Map(); - private _treeElementsBySettingName = new Map(); + private _treeElementsBySettingName = new Map(); private _tocRoot: ITOCEntry; constructor( @@ -102,6 +164,9 @@ export class SettingsTreeModel { } update(newTocRoot = this._tocRoot): void { + this._treeElementsById.clear(); + this._treeElementsBySettingName.clear(); + const newRoot = this.createSettingsTreeGroupElement(newTocRoot); if (newRoot.children[0] instanceof SettingsTreeGroupElement) { (newRoot.children[0]).isFirstGroup = true; // TODO @@ -118,10 +183,21 @@ export class SettingsTreeModel { return this._treeElementsById.get(id); } - getElementByName(name: string): SettingsTreeElement { + getElementByName(name: string): SettingsTreeSettingElement[] { return this._treeElementsBySettingName.get(name); } + updateElementsByName(name: string): void { + if (!this._treeElementsBySettingName.has(name)) { + return; + } + + this._treeElementsBySettingName.get(name).forEach(element => { + const inspectResult = inspectSetting(element.setting.key, this._viewState.settingsTarget, this._configurationService); + element.update(inspectResult); + }); + } + private createSettingsTreeGroupElement(tocEntry: ITOCEntry, parent?: SettingsTreeGroupElement): SettingsTreeGroupElement { const element = new SettingsTreeGroupElement(); element.id = tocEntry.id; @@ -151,9 +227,13 @@ export class SettingsTreeModel { } private createSettingsTreeSettingElement(setting: ISetting, parent: SettingsTreeGroupElement): SettingsTreeSettingElement { - const element = createSettingsTreeSettingElement(setting, parent, this._viewState.settingsTarget, this._configurationService); + const inspectResult = inspectSetting(setting.key, this._viewState.settingsTarget, this._configurationService); + const element = new SettingsTreeSettingElement(setting, parent, inspectResult); this._treeElementsById.set(element.id, element); - this._treeElementsBySettingName.set(setting.key, element); + + const nameElements = this._treeElementsBySettingName.get(setting.key) || []; + nameElements.push(element); + this._treeElementsBySettingName.set(setting.key, nameElements); return element; } } @@ -238,67 +318,6 @@ export function isExcludeSetting(setting: ISetting): boolean { setting.key === 'search.exclude'; } -function createSettingsTreeSettingElement(setting: ISetting, parent: SettingsTreeGroupElement, settingsTarget: SettingsTarget, configurationService: IConfigurationService): SettingsTreeSettingElement { - const element = new SettingsTreeSettingElement(); - element.id = sanitizeId(parent.id + '_' + setting.key); - element.parent = parent; - - const inspectResult = inspectSetting(setting.key, settingsTarget, configurationService); - const { isConfigured, inspected, targetSelector } = inspectResult; - - const displayValue = isConfigured ? inspected[targetSelector] : inspected.default; - const overriddenScopeList = []; - if (targetSelector === 'user' && typeof inspected.workspace !== 'undefined') { - overriddenScopeList.push(localize('workspace', "Workspace")); - } - - if (targetSelector === 'workspace' && typeof inspected.user !== 'undefined') { - overriddenScopeList.push(localize('user', "User")); - } - - const displayKeyFormat = settingKeyToDisplayFormat(setting.key, parent.id); - element.setting = setting; - element.displayLabel = displayKeyFormat.label; - element.displayCategory = displayKeyFormat.category; - - element.value = displayValue; - element.scopeValue = isConfigured && inspected[targetSelector]; - element.defaultValue = inspected.default; - - element.isConfigured = isConfigured; - if (isConfigured || setting.tags) { - element.tags = new Set(); - if (isConfigured) { - element.tags.add(MODIFIED_SETTING_TAG); - } - - if (setting.tags) { - setting.tags.forEach(tag => element.tags.add(tag)); - } - } - - element.overriddenScopeList = overriddenScopeList; - element.description = setting.description.join('\n'); - - if (setting.enum && (setting.type === 'string' || !setting.type)) { - element.valueType = 'enum'; - } else if (setting.type === 'string') { - element.valueType = 'string'; - } else if (isExcludeSetting(setting)) { - element.valueType = 'exclude'; - } else if (setting.type === 'integer') { - element.valueType = 'integer'; - } else if (setting.type === 'number') { - element.valueType = 'number'; - } else if (setting.type === 'boolean') { - element.valueType = 'boolean'; - } else { - element.valueType = 'complex'; - } - - return element; -} - export enum SearchResultIdx { Local = 0, Remote = 1, From 67468c4756b2f7910c114f75460b59048ac2e645 Mon Sep 17 00:00:00 2001 From: Martin Aeschlimann Date: Sat, 11 Aug 2018 21:03:13 +0200 Subject: [PATCH 0707/1276] Seti file icon theme: support more "todo" files. Fixes #56143 --- extensions/theme-seti/build/update-icon-theme.js | 3 ++- extensions/theme-seti/icons/vs-seti-icon-theme.json | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/extensions/theme-seti/build/update-icon-theme.js b/extensions/theme-seti/build/update-icon-theme.js index b82a53ecc88..ed22a1fb3c4 100644 --- a/extensions/theme-seti/build/update-icon-theme.js +++ b/extensions/theme-seti/build/update-icon-theme.js @@ -31,7 +31,8 @@ let nonBuiltInLanguages = { // { fileNames, extensions } "elixir": { extensions: ['ex'] }, "haml": { extensions: ['haml'] }, "stylus": { extensions: ['styl'] }, - "vala": { extensions: ['vala'] } + "vala": { extensions: ['vala'] }, + "todo": { fileNames: ['todo'] } } function getCommitSha(repoId, repoPath) { diff --git a/extensions/theme-seti/icons/vs-seti-icon-theme.json b/extensions/theme-seti/icons/vs-seti-icon-theme.json index 3dd08149c79..ad4817d51f7 100644 --- a/extensions/theme-seti/icons/vs-seti-icon-theme.json +++ b/extensions/theme-seti/icons/vs-seti-icon-theme.json @@ -1529,7 +1529,8 @@ "elixir": "_elixir", "haml": "_haml", "stylus": "_stylus", - "vala": "_vala" + "vala": "_vala", + "todo": "_todo" }, "light": { "file": "_default_light", From 34ca4c78b2ffe560c807e69ee1f48834bcb4ddda Mon Sep 17 00:00:00 2001 From: Alex Dima Date: Thu, 9 Aug 2018 11:12:30 +0200 Subject: [PATCH 0708/1276] Handle Promise errors caused by cancellation --- .../contrib/codeAction/codeActionCommands.ts | 3 ++- .../contrib/colorPicker/colorDetector.ts | 16 ++++++++-------- src/vs/editor/contrib/folding/folding.ts | 7 ++++--- src/vs/editor/contrib/hover/hoverOperation.ts | 13 ++++++------- src/vs/editor/contrib/links/links.ts | 18 +++++------------- .../contrib/wordHighlighter/wordHighlighter.ts | 4 ++-- 6 files changed, 27 insertions(+), 34 deletions(-) diff --git a/src/vs/editor/contrib/codeAction/codeActionCommands.ts b/src/vs/editor/contrib/codeAction/codeActionCommands.ts index 1f229bfbfbc..5dd721207d4 100644 --- a/src/vs/editor/contrib/codeAction/codeActionCommands.ts +++ b/src/vs/editor/contrib/codeAction/codeActionCommands.ts @@ -27,6 +27,7 @@ import { CodeActionAutoApply, CodeActionFilter, CodeActionKind } from './codeAct import { CodeActionContextMenu } from './codeActionWidget'; import { LightBulbWidget } from './lightBulbWidget'; import { KeybindingWeight } from 'vs/platform/keybinding/common/keybindingsRegistry'; +import { onUnexpectedError } from 'vs/base/common/errors'; function contextKeyForSupportedActions(kind: CodeActionKind) { return ContextKeyExpr.regex( @@ -98,7 +99,7 @@ export class QuickFixController implements IEditorContribution { } else { this._codeActionContextMenu.show(e.actions, e.position); } - }); + }).catch(onUnexpectedError); return; } diff --git a/src/vs/editor/contrib/colorPicker/colorDetector.ts b/src/vs/editor/contrib/colorPicker/colorDetector.ts index b3836d6aa68..a676d0e8c36 100644 --- a/src/vs/editor/contrib/colorPicker/colorDetector.ts +++ b/src/vs/editor/contrib/colorPicker/colorDetector.ts @@ -17,6 +17,7 @@ import { getColors, IColorData } from 'vs/editor/contrib/colorPicker/color'; import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; import { ModelDecorationOptions } from 'vs/editor/common/model/textModel'; import { TimeoutTimer, CancelablePromise, createCancelablePromise } from 'vs/base/common/async'; +import { onUnexpectedError } from 'vs/base/common/errors'; const MAX_DECORATORS = 500; @@ -28,7 +29,7 @@ export class ColorDetector implements IEditorContribution { private _globalToDispose: IDisposable[] = []; private _localToDispose: IDisposable[] = []; - private _computePromise: CancelablePromise; + private _computePromise: CancelablePromise; private _timeoutTimer: TimeoutTimer; private _decorationsIds: string[] = []; @@ -127,13 +128,12 @@ export class ColorDetector implements IEditorContribution { } private beginCompute(): void { - this._computePromise = createCancelablePromise(token => { - return getColors(this._editor.getModel(), token).then(colorInfos => { - this.updateDecorations(colorInfos); - this.updateColorDecorators(colorInfos); - this._computePromise = null; - }); - }); + this._computePromise = createCancelablePromise(token => getColors(this._editor.getModel(), token)); + this._computePromise.then((colorInfos) => { + this.updateDecorations(colorInfos); + this.updateColorDecorators(colorInfos); + this._computePromise = null; + }, onUnexpectedError); } private stop(): void { diff --git a/src/vs/editor/contrib/folding/folding.ts b/src/vs/editor/contrib/folding/folding.ts index c972f6885a2..520ad0ac57d 100644 --- a/src/vs/editor/contrib/folding/folding.ts +++ b/src/vs/editor/contrib/folding/folding.ts @@ -33,6 +33,7 @@ import { SyntaxRangeProvider, ID_SYNTAX_PROVIDER } from './syntaxRangeProvider'; import { CancellationToken } from 'vs/base/common/cancellation'; import { InitializingRangeProvider, ID_INIT_PROVIDER } from 'vs/editor/contrib/folding/intializingRangeProvider'; import { KeybindingWeight } from 'vs/platform/keybinding/common/keybindingsRegistry'; +import { onUnexpectedError } from 'vs/base/common/errors'; export const ID = 'editor.contrib.folding'; @@ -166,7 +167,7 @@ export class FoldingController implements IEditorContribution { if (foldingModel) { foldingModel.applyMemento(state.collapsedRegions); } - }); + }).done(undefined, onUnexpectedError); } } @@ -312,7 +313,7 @@ export class FoldingController implements IEditorContribution { } } } - }); + }).done(undefined, onUnexpectedError); } @@ -407,7 +408,7 @@ export class FoldingController implements IEditorContribution { } } } - }); + }).done(undefined, onUnexpectedError); } public reveal(position: IPosition): void { diff --git a/src/vs/editor/contrib/hover/hoverOperation.ts b/src/vs/editor/contrib/hover/hoverOperation.ts index 16699608cd6..2b55f24057d 100644 --- a/src/vs/editor/contrib/hover/hoverOperation.ts +++ b/src/vs/editor/contrib/hover/hoverOperation.ts @@ -57,7 +57,7 @@ export class HoverOperation { private _firstWaitScheduler: RunOnceScheduler; private _secondWaitScheduler: RunOnceScheduler; private _loadingMessageScheduler: RunOnceScheduler; - private _asyncComputationPromise: CancelablePromise; + private _asyncComputationPromise: CancelablePromise; private _asyncComputationPromiseDone: boolean; private _completeCallback: (r: Result) => void; @@ -103,12 +103,11 @@ export class HoverOperation { if (this._computer.computeAsync) { this._asyncComputationPromiseDone = false; - this._asyncComputationPromise = createCancelablePromise(token => { - return this._computer.computeAsync(token).then((asyncResult: Result) => { - this._asyncComputationPromiseDone = true; - this._withAsyncResult(asyncResult); - }, (e) => this._onError(e)); - }); + this._asyncComputationPromise = createCancelablePromise(token => this._computer.computeAsync(token)); + this._asyncComputationPromise.then((asyncResult: Result) => { + this._asyncComputationPromiseDone = true; + this._withAsyncResult(asyncResult); + }, (e) => this._onError(e)); } else { this._asyncComputationPromiseDone = true; diff --git a/src/vs/editor/contrib/links/links.ts b/src/vs/editor/contrib/links/links.ts index 87fe09b073e..91adad411bd 100644 --- a/src/vs/editor/contrib/links/links.ts +++ b/src/vs/editor/contrib/links/links.ts @@ -149,7 +149,7 @@ class LinkDetector implements editorCommon.IEditorContribution { private editor: ICodeEditor; private enabled: boolean; private listenersToRemove: IDisposable[]; - private timeoutPromise: async.CancelablePromise; + private timeout: async.TimeoutTimer; private computePromise: async.CancelablePromise; private activeLinkDecorationId: string; private openerService: IOpenerService; @@ -201,7 +201,7 @@ class LinkDetector implements editorCommon.IEditorContribution { this.listenersToRemove.push(editor.onDidChangeModelLanguage((e) => this.onModelModeChanged())); this.listenersToRemove.push(LinkProviderRegistry.onDidChange((e) => this.onModelModeChanged())); - this.timeoutPromise = null; + this.timeout = new async.TimeoutTimer(); this.computePromise = null; this.currentOccurrences = {}; this.activeLinkDecorationId = null; @@ -225,13 +225,7 @@ class LinkDetector implements editorCommon.IEditorContribution { } private onChange(): void { - if (!this.timeoutPromise) { - this.timeoutPromise = async.timeout(LinkDetector.RECOMPUTE_TIME); - this.timeoutPromise.then(() => { - this.timeoutPromise = null; - this.beginCompute(); - }); - } + this.timeout.setIfNotSet(() => this.beginCompute(), LinkDetector.RECOMPUTE_TIME); } private async beginCompute(): Promise { @@ -374,10 +368,7 @@ class LinkDetector implements editorCommon.IEditorContribution { } private stop(): void { - if (this.timeoutPromise) { - this.timeoutPromise.cancel(); - this.timeoutPromise = null; - } + this.timeout.cancel(); if (this.computePromise) { this.computePromise.cancel(); this.computePromise = null; @@ -387,6 +378,7 @@ class LinkDetector implements editorCommon.IEditorContribution { public dispose(): void { this.listenersToRemove = dispose(this.listenersToRemove); this.stop(); + this.timeout.dispose(); } } diff --git a/src/vs/editor/contrib/wordHighlighter/wordHighlighter.ts b/src/vs/editor/contrib/wordHighlighter/wordHighlighter.ts index 8c852574b12..684fc6757e2 100644 --- a/src/vs/editor/contrib/wordHighlighter/wordHighlighter.ts +++ b/src/vs/editor/contrib/wordHighlighter/wordHighlighter.ts @@ -6,7 +6,7 @@ import * as nls from 'vs/nls'; import { first2, createCancelablePromise, CancelablePromise } from 'vs/base/common/async'; -import { onUnexpectedExternalError } from 'vs/base/common/errors'; +import { onUnexpectedExternalError, onUnexpectedError } from 'vs/base/common/errors'; import { Range } from 'vs/editor/common/core/range'; import * as editorCommon from 'vs/editor/common/editorCommon'; import { registerEditorContribution, EditorAction, IActionOptions, registerEditorAction, registerDefaultLanguageCommand } from 'vs/editor/browser/editorExtensions'; @@ -300,7 +300,7 @@ class WordHighlighter { this.workerRequestValue = data || []; this._beginRenderDecorations(); } - }); + }, onUnexpectedError); } this._lastWordRange = currentWordRange; From 089ac7df3b9a08795bbe872931f60b87e66ed91e Mon Sep 17 00:00:00 2001 From: Alex Dima Date: Thu, 9 Aug 2018 12:01:02 +0200 Subject: [PATCH 0709/1276] Fixes Microsoft/monaco-editor#973 --- src/vs/editor/common/editorCommon.ts | 4 ++-- src/vs/editor/standalone/browser/standaloneCodeEditor.ts | 2 +- src/vs/monaco.d.ts | 6 +++--- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/vs/editor/common/editorCommon.ts b/src/vs/editor/common/editorCommon.ts index 714b67fa3aa..8ab17ce6977 100644 --- a/src/vs/editor/common/editorCommon.ts +++ b/src/vs/editor/common/editorCommon.ts @@ -439,7 +439,7 @@ export interface IEditor { /** * Gets the current model attached to this editor. */ - getModel(): IEditorModel; + getModel(): IEditorModel | null; /** * Sets the current model attached to this editor. @@ -449,7 +449,7 @@ export interface IEditor { * will not be destroyed. * It is safe to call setModel(null) to simply detach the current model from the editor. */ - setModel(model: IEditorModel): void; + setModel(model: IEditorModel | null): void; /** * Change the decorations. All decorations added through this changeAccessor diff --git a/src/vs/editor/standalone/browser/standaloneCodeEditor.ts b/src/vs/editor/standalone/browser/standaloneCodeEditor.ts index 6018f9f47d5..890b51f49bd 100644 --- a/src/vs/editor/standalone/browser/standaloneCodeEditor.ts +++ b/src/vs/editor/standalone/browser/standaloneCodeEditor.ts @@ -84,7 +84,7 @@ export interface IEditorConstructionOptions extends IEditorOptions { /** * The initial model associated with this code editor. */ - model?: ITextModel; + model?: ITextModel | null; /** * The initial value of the auto created model in the editor. * To not create automatically a model, use `model: null`. diff --git a/src/vs/monaco.d.ts b/src/vs/monaco.d.ts index b8394da57dc..462664d6c60 100644 --- a/src/vs/monaco.d.ts +++ b/src/vs/monaco.d.ts @@ -1058,7 +1058,7 @@ declare namespace monaco.editor { /** * The initial model associated with this code editor. */ - model?: ITextModel; + model?: ITextModel | null; /** * The initial value of the auto created model in the editor. * To not create automatically a model, use `model: null`. @@ -2197,7 +2197,7 @@ declare namespace monaco.editor { /** * Gets the current model attached to this editor. */ - getModel(): IEditorModel; + getModel(): IEditorModel | null; /** * Sets the current model attached to this editor. * If the previous model was created by the editor via the value key in the options @@ -2206,7 +2206,7 @@ declare namespace monaco.editor { * will not be destroyed. * It is safe to call setModel(null) to simply detach the current model from the editor. */ - setModel(model: IEditorModel): void; + setModel(model: IEditorModel | null): void; } /** From 3c7b9a8c55a544bac8920a4d645e5eeb6bd7d01c Mon Sep 17 00:00:00 2001 From: Alex Dima Date: Fri, 10 Aug 2018 09:27:06 +0200 Subject: [PATCH 0710/1276] Create the ESM distribution from the tree shaken sources --- build/gulpfile.editor.js | 22 ++- build/lib/standalone.js | 294 ++++++++++++++------------------- build/lib/standalone.ts | 344 +++++++++++++++++---------------------- 3 files changed, 288 insertions(+), 372 deletions(-) diff --git a/build/gulpfile.editor.js b/build/gulpfile.editor.js index 562ee1dd754..0b54a765408 100644 --- a/build/gulpfile.editor.js +++ b/build/gulpfile.editor.js @@ -122,17 +122,21 @@ gulp.task('clean-minified-editor', util.rimraf('out-editor-min')); gulp.task('minify-editor', ['clean-minified-editor', 'optimize-editor'], common.minifyTask('out-editor')); gulp.task('clean-editor-esm', util.rimraf('out-editor-esm')); -gulp.task('extract-editor-esm', ['clean-editor-esm', 'clean-editor-distro'], function () { - standalone.createESMSourcesAndResources({ - entryPoints: [ - 'vs/editor/editor.main', - 'vs/editor/editor.worker' - ], +gulp.task('extract-editor-esm', ['clean-editor-esm', 'clean-editor-distro', 'extract-editor-src'], function () { + standalone.createESMSourcesAndResources2({ + srcFolder: './out-editor-src', outFolder: './out-editor-esm/src', outResourcesFolder: './out-monaco-editor-core/esm', - redirects: { - 'vs/base/browser/ui/octiconLabel/octiconLabel': 'vs/base/browser/ui/octiconLabel/octiconLabel.mock', - 'vs/nls': 'vs/nls.mock', + ignores: [ + 'inlineEntryPoint:0.ts', + 'inlineEntryPoint:1.ts', + 'vs/nls.ts', + 'vs/nls.d.ts', + 'vs/css.d.ts', + 'vs/base/worker/workerMain.ts', + ], + renames: { + 'vs/nls.mock.ts': 'vs/nls.ts' } }); }); diff --git a/build/lib/standalone.js b/build/lib/standalone.js index 885d3e789f5..3e2bacc25d5 100644 --- a/build/lib/standalone.js +++ b/build/lib/standalone.js @@ -10,7 +10,6 @@ var path = require("path"); var tss = require("./treeshaking"); var REPO_ROOT = path.join(__dirname, '../../'); var SRC_DIR = path.join(REPO_ROOT, 'src'); -var OUT_EDITOR = path.join(REPO_ROOT, 'out-editor'); var dirCache = {}; function writeFile(filePath, contents) { function ensureDirs(dirPath) { @@ -76,6 +75,8 @@ function extractEditor(options) { } var tsConfig = JSON.parse(fs.readFileSync(path.join(options.sourcesRoot, 'tsconfig.json')).toString()); tsConfig.compilerOptions.noUnusedLocals = false; + tsConfig.compilerOptions.preserveConstEnums = false; + tsConfig.compilerOptions.declaration = false; writeOutputFile('tsconfig.json', JSON.stringify(tsConfig, null, '\t')); [ 'vs/css.build.js', @@ -94,167 +95,148 @@ function extractEditor(options) { ].forEach(copyFile); } exports.extractEditor = extractEditor; -function createESMSourcesAndResources(options) { +function createESMSourcesAndResources2(options) { + var SRC_FOLDER = path.join(REPO_ROOT, options.srcFolder); var OUT_FOLDER = path.join(REPO_ROOT, options.outFolder); var OUT_RESOURCES_FOLDER = path.join(REPO_ROOT, options.outResourcesFolder); - var in_queue = Object.create(null); - var queue = []; - var enqueue = function (module) { - if (in_queue[module]) { - return; + var getDestAbsoluteFilePath = function (file) { + var dest = options.renames[file.replace(/\\/g, '/')] || file; + if (dest === 'tsconfig.json') { + return path.join(OUT_FOLDER, "../tsconfig.json"); } - in_queue[module] = true; - queue.push(module); + if (/\.ts$/.test(dest)) { + return path.join(OUT_FOLDER, dest); + } + return path.join(OUT_RESOURCES_FOLDER, dest); }; - var seenDir = {}; - var createDirectoryRecursive = function (dir) { - if (seenDir[dir]) { - return; + var allFiles = walkDirRecursive(SRC_FOLDER); + for (var i = 0; i < allFiles.length; i++) { + var file = allFiles[i]; + if (options.ignores.indexOf(file.replace(/\\/g, '/')) >= 0) { + continue; } - var lastSlash = dir.lastIndexOf('/'); - if (lastSlash === -1) { - lastSlash = dir.lastIndexOf('\\'); + if (file === 'tsconfig.json') { + var tsConfig = JSON.parse(fs.readFileSync(path.join(SRC_FOLDER, file)).toString()); + tsConfig.compilerOptions.moduleResolution = undefined; + tsConfig.compilerOptions.baseUrl = undefined; + tsConfig.compilerOptions.module = 'es6'; + tsConfig.compilerOptions.rootDir = 'src'; + tsConfig.compilerOptions.outDir = path.relative(path.dirname(OUT_FOLDER), OUT_RESOURCES_FOLDER); + write(getDestAbsoluteFilePath(file), JSON.stringify(tsConfig, null, '\t')); + continue; } - if (lastSlash !== -1) { - createDirectoryRecursive(dir.substring(0, lastSlash)); + if (/\.d\.ts$/.test(file) || /\.css$/.test(file) || /\.js$/.test(file)) { + // Transport the files directly + write(getDestAbsoluteFilePath(file), fs.readFileSync(path.join(SRC_FOLDER, file))); + continue; } - seenDir[dir] = true; - try { - fs.mkdirSync(dir); - } - catch (err) { } - }; - seenDir[REPO_ROOT] = true; - var toggleComments = function (fileContents) { - var lines = fileContents.split(/\r\n|\r|\n/); - var mode = 0; - for (var i = 0; i < lines.length; i++) { - var line = lines[i]; - if (mode === 0) { - if (/\/\/ ESM-comment-begin/.test(line)) { - mode = 1; - continue; + if (/\.ts$/.test(file)) { + // Transform the .ts file + var fileContents = fs.readFileSync(path.join(SRC_FOLDER, file)).toString(); + var info = ts.preProcessFile(fileContents); + for (var i_1 = info.importedFiles.length - 1; i_1 >= 0; i_1--) { + var importedFilename = info.importedFiles[i_1].fileName; + var pos = info.importedFiles[i_1].pos; + var end = info.importedFiles[i_1].end; + var importedFilepath = void 0; + if (/^vs\/css!/.test(importedFilename)) { + importedFilepath = importedFilename.substr('vs/css!'.length) + '.css'; } - if (/\/\/ ESM-uncomment-begin/.test(line)) { - mode = 2; - continue; + else { + importedFilepath = importedFilename; } - continue; + if (/(^\.\/)|(^\.\.\/)/.test(importedFilepath)) { + importedFilepath = path.join(path.dirname(file), importedFilepath); + } + var relativePath = void 0; + if (importedFilepath === path.dirname(file)) { + relativePath = '../' + path.basename(path.dirname(file)); + } + else if (importedFilepath === path.dirname(path.dirname(file))) { + relativePath = '../../' + path.basename(path.dirname(path.dirname(file))); + } + else { + relativePath = path.relative(path.dirname(file), importedFilepath); + } + if (!/(^\.\/)|(^\.\.\/)/.test(relativePath)) { + relativePath = './' + relativePath; + } + fileContents = (fileContents.substring(0, pos + 1) + + relativePath + + fileContents.substring(end + 1)); } - if (mode === 1) { - if (/\/\/ ESM-comment-end/.test(line)) { - mode = 0; - continue; - } - lines[i] = '// ' + line; - continue; + fileContents = fileContents.replace(/import ([a-zA-z0-9]+) = require\(('[^']+')\);/g, function (_, m1, m2) { + return "import * as " + m1 + " from " + m2 + ";"; + }); + write(getDestAbsoluteFilePath(file), fileContents); + continue; + } + console.log("UNKNOWN FILE: " + file); + } + function walkDirRecursive(dir) { + if (dir.charAt(dir.length - 1) !== '/' || dir.charAt(dir.length - 1) !== '\\') { + dir += '/'; + } + var result = []; + _walkDirRecursive(dir, result, dir.length); + return result; + } + function _walkDirRecursive(dir, result, trimPos) { + var files = fs.readdirSync(dir); + for (var i = 0; i < files.length; i++) { + var file = path.join(dir, files[i]); + if (fs.statSync(file).isDirectory()) { + _walkDirRecursive(file, result, trimPos); } - if (mode === 2) { - if (/\/\/ ESM-uncomment-end/.test(line)) { - mode = 0; - continue; - } - lines[i] = line.replace(/^(\s*)\/\/ ?/, function (_, indent) { - return indent; - }); + else { + result.push(file.substr(trimPos)); } } - return lines.join('\n'); - }; - var write = function (filePath, contents) { - var absoluteFilePath; - if (/\.ts$/.test(filePath)) { - absoluteFilePath = path.join(OUT_FOLDER, filePath); - } - else { - absoluteFilePath = path.join(OUT_RESOURCES_FOLDER, filePath); - } - createDirectoryRecursive(path.dirname(absoluteFilePath)); - if (/(\.ts$)|(\.js$)/.test(filePath)) { + } + function write(absoluteFilePath, contents) { + if (/(\.ts$)|(\.js$)/.test(absoluteFilePath)) { contents = toggleComments(contents.toString()); } - fs.writeFileSync(absoluteFilePath, contents); - }; - options.entryPoints.forEach(function (entryPoint) { return enqueue(entryPoint); }); - while (queue.length > 0) { - var module_1 = queue.shift(); - if (transportCSS(module_1, enqueue, write)) { - continue; + writeFile(absoluteFilePath, contents); + function toggleComments(fileContents) { + var lines = fileContents.split(/\r\n|\r|\n/); + var mode = 0; + for (var i = 0; i < lines.length; i++) { + var line = lines[i]; + if (mode === 0) { + if (/\/\/ ESM-comment-begin/.test(line)) { + mode = 1; + continue; + } + if (/\/\/ ESM-uncomment-begin/.test(line)) { + mode = 2; + continue; + } + continue; + } + if (mode === 1) { + if (/\/\/ ESM-comment-end/.test(line)) { + mode = 0; + continue; + } + lines[i] = '// ' + line; + continue; + } + if (mode === 2) { + if (/\/\/ ESM-uncomment-end/.test(line)) { + mode = 0; + continue; + } + lines[i] = line.replace(/^(\s*)\/\/ ?/, function (_, indent) { + return indent; + }); + } + } + return lines.join('\n'); } - if (transportResource(options, module_1, enqueue, write)) { - continue; - } - if (transportDTS(options, module_1, enqueue, write)) { - continue; - } - var filename = void 0; - if (options.redirects[module_1]) { - filename = path.join(SRC_DIR, options.redirects[module_1] + '.ts'); - } - else { - filename = path.join(SRC_DIR, module_1 + '.ts'); - } - var fileContents = fs.readFileSync(filename).toString(); - var info = ts.preProcessFile(fileContents); - for (var i = info.importedFiles.length - 1; i >= 0; i--) { - var importedFilename = info.importedFiles[i].fileName; - var pos = info.importedFiles[i].pos; - var end = info.importedFiles[i].end; - var importedFilepath = void 0; - if (/^vs\/css!/.test(importedFilename)) { - importedFilepath = importedFilename.substr('vs/css!'.length) + '.css'; - } - else { - importedFilepath = importedFilename; - } - if (/(^\.\/)|(^\.\.\/)/.test(importedFilepath)) { - importedFilepath = path.join(path.dirname(module_1), importedFilepath); - } - enqueue(importedFilepath); - var relativePath = void 0; - if (importedFilepath === path.dirname(module_1)) { - relativePath = '../' + path.basename(path.dirname(module_1)); - } - else if (importedFilepath === path.dirname(path.dirname(module_1))) { - relativePath = '../../' + path.basename(path.dirname(path.dirname(module_1))); - } - else { - relativePath = path.relative(path.dirname(module_1), importedFilepath); - } - if (!/(^\.\/)|(^\.\.\/)/.test(relativePath)) { - relativePath = './' + relativePath; - } - fileContents = (fileContents.substring(0, pos + 1) - + relativePath - + fileContents.substring(end + 1)); - } - fileContents = fileContents.replace(/import ([a-zA-z0-9]+) = require\(('[^']+')\);/g, function (_, m1, m2) { - return "import * as " + m1 + " from " + m2 + ";"; - }); - fileContents = fileContents.replace(/Thenable/g, 'PromiseLike'); - write(module_1 + '.ts', fileContents); } - var esm_opts = { - "compilerOptions": { - "outDir": path.relative(path.dirname(OUT_FOLDER), OUT_RESOURCES_FOLDER), - "rootDir": "src", - "module": "es6", - "target": "es5", - "experimentalDecorators": true, - "lib": [ - "dom", - "es5", - "es2015.collection", - "es2015.promise" - ], - "types": [] - } - }; - fs.writeFileSync(path.join(path.dirname(OUT_FOLDER), 'tsconfig.json'), JSON.stringify(esm_opts, null, '\t')); - var monacodts = fs.readFileSync(path.join(SRC_DIR, 'vs/monaco.d.ts')).toString(); - fs.writeFileSync(path.join(OUT_FOLDER, 'vs/monaco.d.ts'), monacodts); } -exports.createESMSourcesAndResources = createESMSourcesAndResources; +exports.createESMSourcesAndResources2 = createESMSourcesAndResources2; function transportCSS(module, enqueue, write) { if (!/\.css/.test(module)) { return false; @@ -323,27 +305,3 @@ function transportCSS(module, enqueue, write) { return haystack.length >= needle.length && haystack.substr(0, needle.length) === needle; } } -function transportResource(options, module, enqueue, write) { - if (!/\.svg/.test(module)) { - return false; - } - write(module, fs.readFileSync(path.join(SRC_DIR, module))); - return true; -} -function transportDTS(options, module, enqueue, write) { - if (options.redirects[module] && fs.existsSync(path.join(SRC_DIR, options.redirects[module] + '.ts'))) { - return false; - } - if (!fs.existsSync(path.join(SRC_DIR, module + '.d.ts'))) { - return false; - } - write(module + '.d.ts', fs.readFileSync(path.join(SRC_DIR, module + '.d.ts'))); - var filename; - if (options.redirects[module]) { - write(module + '.js', fs.readFileSync(path.join(SRC_DIR, options.redirects[module] + '.js'))); - } - else { - write(module + '.js', fs.readFileSync(path.join(SRC_DIR, module + '.js'))); - } - return true; -} diff --git a/build/lib/standalone.ts b/build/lib/standalone.ts index 7931737fadb..621b4aea6d4 100644 --- a/build/lib/standalone.ts +++ b/build/lib/standalone.ts @@ -10,7 +10,6 @@ import * as tss from './treeshaking'; const REPO_ROOT = path.join(__dirname, '../../'); const SRC_DIR = path.join(REPO_ROOT, 'src'); -const OUT_EDITOR = path.join(REPO_ROOT, 'out-editor'); let dirCache: { [dir: string]: boolean; } = {}; @@ -38,7 +37,7 @@ export function extractEditor(options: tss.ITreeShakingOptions & { destRoot: str writeFile(path.join(options.destRoot, fileName), result[fileName]); } } - let copied: { [fileName:string]: boolean; } = {}; + let copied: { [fileName: string]: boolean; } = {}; const copyFile = (fileName: string) => { if (copied[fileName]) { return; @@ -82,6 +81,8 @@ export function extractEditor(options: tss.ITreeShakingOptions & { destRoot: str const tsConfig = JSON.parse(fs.readFileSync(path.join(options.sourcesRoot, 'tsconfig.json')).toString()); tsConfig.compilerOptions.noUnusedLocals = false; + tsConfig.compilerOptions.preserveConstEnums = false; + tsConfig.compilerOptions.declaration = false; writeOutputFile('tsconfig.json', JSON.stringify(tsConfig, null, '\t')); [ @@ -101,191 +102,174 @@ export function extractEditor(options: tss.ITreeShakingOptions & { destRoot: str ].forEach(copyFile); } -export interface IOptions { - entryPoints: string[]; +export interface IOptions2 { + srcFolder: string; outFolder: string; outResourcesFolder: string; - redirects: { [module: string]: string; }; + ignores: string[]; + renames: { [filename: string]: string; }; } -export function createESMSourcesAndResources(options: IOptions): void { +export function createESMSourcesAndResources2(options: IOptions2): void { + const SRC_FOLDER = path.join(REPO_ROOT, options.srcFolder); const OUT_FOLDER = path.join(REPO_ROOT, options.outFolder); const OUT_RESOURCES_FOLDER = path.join(REPO_ROOT, options.outResourcesFolder); - let in_queue: { [module: string]: boolean; } = Object.create(null); - let queue: string[] = []; - - const enqueue = (module: string) => { - if (in_queue[module]) { - return; + const getDestAbsoluteFilePath = (file: string): string => { + let dest = options.renames[file.replace(/\\/g, '/')] || file; + if (dest === 'tsconfig.json') { + return path.join(OUT_FOLDER, `../tsconfig.json`); } - in_queue[module] = true; - queue.push(module); + if (/\.ts$/.test(dest)) { + return path.join(OUT_FOLDER, dest); + } + return path.join(OUT_RESOURCES_FOLDER, dest); }; - const seenDir: { [key: string]: boolean; } = {}; - const createDirectoryRecursive = (dir: string) => { - if (seenDir[dir]) { - return; - } + const allFiles = walkDirRecursive(SRC_FOLDER); + for (let i = 0; i < allFiles.length; i++) { + const file = allFiles[i]; - let lastSlash = dir.lastIndexOf('/'); - if (lastSlash === -1) { - lastSlash = dir.lastIndexOf('\\'); - } - if (lastSlash !== -1) { - createDirectoryRecursive(dir.substring(0, lastSlash)); - } - seenDir[dir] = true; - try { fs.mkdirSync(dir); } catch (err) { } - }; - - seenDir[REPO_ROOT] = true; - - const toggleComments = (fileContents: string) => { - let lines = fileContents.split(/\r\n|\r|\n/); - let mode = 0; - for (let i = 0; i < lines.length; i++) { - const line = lines[i]; - - if (mode === 0) { - if (/\/\/ ESM-comment-begin/.test(line)) { - mode = 1; - continue; - } - if (/\/\/ ESM-uncomment-begin/.test(line)) { - mode = 2; - continue; - } - continue; - } - - if (mode === 1) { - if (/\/\/ ESM-comment-end/.test(line)) { - mode = 0; - continue; - } - lines[i] = '// ' + line; - continue; - } - - if (mode === 2) { - if (/\/\/ ESM-uncomment-end/.test(line)) { - mode = 0; - continue; - } - lines[i] = line.replace(/^(\s*)\/\/ ?/, function (_, indent) { - return indent; - }); - } - } - - return lines.join('\n'); - }; - - const write = (filePath: string, contents: string | Buffer) => { - let absoluteFilePath: string; - if (/\.ts$/.test(filePath)) { - absoluteFilePath = path.join(OUT_FOLDER, filePath); - } else { - absoluteFilePath = path.join(OUT_RESOURCES_FOLDER, filePath); - } - createDirectoryRecursive(path.dirname(absoluteFilePath)); - if (/(\.ts$)|(\.js$)/.test(filePath)) { - contents = toggleComments(contents.toString()); - } - fs.writeFileSync(absoluteFilePath, contents); - }; - - options.entryPoints.forEach((entryPoint) => enqueue(entryPoint)); - - while (queue.length > 0) { - const module = queue.shift(); - if (transportCSS(module, enqueue, write)) { - continue; - } - if (transportResource(options, module, enqueue, write)) { - continue; - } - if (transportDTS(options, module, enqueue, write)) { + if (options.ignores.indexOf(file.replace(/\\/g, '/')) >= 0) { continue; } - let filename: string; - if (options.redirects[module]) { - filename = path.join(SRC_DIR, options.redirects[module] + '.ts'); - } else { - filename = path.join(SRC_DIR, module + '.ts'); - } - let fileContents = fs.readFileSync(filename).toString(); - - const info = ts.preProcessFile(fileContents); - - for (let i = info.importedFiles.length - 1; i >= 0; i--) { - const importedFilename = info.importedFiles[i].fileName; - const pos = info.importedFiles[i].pos; - const end = info.importedFiles[i].end; - - let importedFilepath: string; - if (/^vs\/css!/.test(importedFilename)) { - importedFilepath = importedFilename.substr('vs/css!'.length) + '.css'; - } else { - importedFilepath = importedFilename; - } - if (/(^\.\/)|(^\.\.\/)/.test(importedFilepath)) { - importedFilepath = path.join(path.dirname(module), importedFilepath); - } - - enqueue(importedFilepath); - - let relativePath: string; - if (importedFilepath === path.dirname(module)) { - relativePath = '../' + path.basename(path.dirname(module)); - } else if (importedFilepath === path.dirname(path.dirname(module))) { - relativePath = '../../' + path.basename(path.dirname(path.dirname(module))); - } else { - relativePath = path.relative(path.dirname(module), importedFilepath); - } - if (!/(^\.\/)|(^\.\.\/)/.test(relativePath)) { - relativePath = './' + relativePath; - } - fileContents = ( - fileContents.substring(0, pos + 1) - + relativePath - + fileContents.substring(end + 1) - ); + if (file === 'tsconfig.json') { + const tsConfig = JSON.parse(fs.readFileSync(path.join(SRC_FOLDER, file)).toString()); + tsConfig.compilerOptions.moduleResolution = undefined; + tsConfig.compilerOptions.baseUrl = undefined; + tsConfig.compilerOptions.module = 'es6'; + tsConfig.compilerOptions.rootDir = 'src'; + tsConfig.compilerOptions.outDir = path.relative(path.dirname(OUT_FOLDER), OUT_RESOURCES_FOLDER); + write(getDestAbsoluteFilePath(file), JSON.stringify(tsConfig, null, '\t')); + continue; } - fileContents = fileContents.replace(/import ([a-zA-z0-9]+) = require\(('[^']+')\);/g, function (_, m1, m2) { - return `import * as ${m1} from ${m2};`; - }); - fileContents = fileContents.replace(/Thenable/g, 'PromiseLike'); + if (/\.d\.ts$/.test(file) || /\.css$/.test(file) || /\.js$/.test(file)) { + // Transport the files directly + write(getDestAbsoluteFilePath(file), fs.readFileSync(path.join(SRC_FOLDER, file))); + continue; + } - write(module + '.ts', fileContents); + if (/\.ts$/.test(file)) { + // Transform the .ts file + let fileContents = fs.readFileSync(path.join(SRC_FOLDER, file)).toString(); + + const info = ts.preProcessFile(fileContents); + + for (let i = info.importedFiles.length - 1; i >= 0; i--) { + const importedFilename = info.importedFiles[i].fileName; + const pos = info.importedFiles[i].pos; + const end = info.importedFiles[i].end; + + let importedFilepath: string; + if (/^vs\/css!/.test(importedFilename)) { + importedFilepath = importedFilename.substr('vs/css!'.length) + '.css'; + } else { + importedFilepath = importedFilename; + } + if (/(^\.\/)|(^\.\.\/)/.test(importedFilepath)) { + importedFilepath = path.join(path.dirname(file), importedFilepath); + } + + let relativePath: string; + if (importedFilepath === path.dirname(file)) { + relativePath = '../' + path.basename(path.dirname(file)); + } else if (importedFilepath === path.dirname(path.dirname(file))) { + relativePath = '../../' + path.basename(path.dirname(path.dirname(file))); + } else { + relativePath = path.relative(path.dirname(file), importedFilepath); + } + if (!/(^\.\/)|(^\.\.\/)/.test(relativePath)) { + relativePath = './' + relativePath; + } + fileContents = ( + fileContents.substring(0, pos + 1) + + relativePath + + fileContents.substring(end + 1) + ); + } + + fileContents = fileContents.replace(/import ([a-zA-z0-9]+) = require\(('[^']+')\);/g, function (_, m1, m2) { + return `import * as ${m1} from ${m2};`; + }); + + write(getDestAbsoluteFilePath(file), fileContents); + continue; + } + + console.log(`UNKNOWN FILE: ${file}`); } - const esm_opts = { - "compilerOptions": { - "outDir": path.relative(path.dirname(OUT_FOLDER), OUT_RESOURCES_FOLDER), - "rootDir": "src", - "module": "es6", - "target": "es5", - "experimentalDecorators": true, - "lib": [ - "dom", - "es5", - "es2015.collection", - "es2015.promise" - ], - "types": [ - ] + + function walkDirRecursive(dir: string): string[] { + if (dir.charAt(dir.length - 1) !== '/' || dir.charAt(dir.length - 1) !== '\\') { + dir += '/'; } - }; - fs.writeFileSync(path.join(path.dirname(OUT_FOLDER), 'tsconfig.json'), JSON.stringify(esm_opts, null, '\t')); + let result: string[] = []; + _walkDirRecursive(dir, result, dir.length); + return result; + } - const monacodts = fs.readFileSync(path.join(SRC_DIR, 'vs/monaco.d.ts')).toString(); - fs.writeFileSync(path.join(OUT_FOLDER, 'vs/monaco.d.ts'), monacodts); + function _walkDirRecursive(dir: string, result: string[], trimPos: number): void { + const files = fs.readdirSync(dir); + for (let i = 0; i < files.length; i++) { + const file = path.join(dir, files[i]); + if (fs.statSync(file).isDirectory()) { + _walkDirRecursive(file, result, trimPos); + } else { + result.push(file.substr(trimPos)); + } + } + } + function write(absoluteFilePath: string, contents: string | Buffer): void { + if (/(\.ts$)|(\.js$)/.test(absoluteFilePath)) { + contents = toggleComments(contents.toString()); + } + writeFile(absoluteFilePath, contents); + + function toggleComments(fileContents: string): string { + let lines = fileContents.split(/\r\n|\r|\n/); + let mode = 0; + for (let i = 0; i < lines.length; i++) { + const line = lines[i]; + + if (mode === 0) { + if (/\/\/ ESM-comment-begin/.test(line)) { + mode = 1; + continue; + } + if (/\/\/ ESM-uncomment-begin/.test(line)) { + mode = 2; + continue; + } + continue; + } + + if (mode === 1) { + if (/\/\/ ESM-comment-end/.test(line)) { + mode = 0; + continue; + } + lines[i] = '// ' + line; + continue; + } + + if (mode === 2) { + if (/\/\/ ESM-uncomment-end/.test(line)) { + mode = 0; + continue; + } + lines[i] = line.replace(/^(\s*)\/\/ ?/, function (_, indent) { + return indent; + }); + } + } + + return lines.join('\n'); + } + } } function transportCSS(module: string, enqueue: (module: string) => void, write: (path: string, contents: string | Buffer) => void): boolean { @@ -363,33 +347,3 @@ function transportCSS(module: string, enqueue: (module: string) => void, write: return haystack.length >= needle.length && haystack.substr(0, needle.length) === needle; } } - -function transportResource(options: IOptions, module: string, enqueue: (module: string) => void, write: (path: string, contents: string | Buffer) => void): boolean { - - if (!/\.svg/.test(module)) { - return false; - } - - write(module, fs.readFileSync(path.join(SRC_DIR, module))); - return true; -} - -function transportDTS(options: IOptions, module: string, enqueue: (module: string) => void, write: (path: string, contents: string | Buffer) => void): boolean { - - if (options.redirects[module] && fs.existsSync(path.join(SRC_DIR, options.redirects[module] + '.ts'))) { - return false; - } - - if (!fs.existsSync(path.join(SRC_DIR, module + '.d.ts'))) { - return false; - } - - write(module + '.d.ts', fs.readFileSync(path.join(SRC_DIR, module + '.d.ts'))); - let filename: string; - if (options.redirects[module]) { - write(module + '.js', fs.readFileSync(path.join(SRC_DIR, options.redirects[module] + '.js'))); - } else { - write(module + '.js', fs.readFileSync(path.join(SRC_DIR, module + '.js'))); - } - return true; -} From 933c8d4b06ff9cc56fea855e0479027bf9d57214 Mon Sep 17 00:00:00 2001 From: Alex Dima Date: Fri, 10 Aug 2018 09:27:47 +0200 Subject: [PATCH 0711/1276] Bring back nls bundles for the editor --- build/lib/optimize.js | 5 +++++ build/lib/optimize.ts | 6 +++++- 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/build/lib/optimize.js b/build/lib/optimize.js index 4fafbd800a9..60169cf1892 100644 --- a/build/lib/optimize.js +++ b/build/lib/optimize.js @@ -20,6 +20,7 @@ var util = require("./util"); var gulpUtil = require("gulp-util"); var flatmap = require("gulp-flatmap"); var pump = require("pump"); +var i18n_1 = require("./i18n"); var REPO_ROOT_PATH = path.join(__dirname, '../..'); function log(prefix, message) { gulpUtil.log(gulpUtil.colors.cyan('[' + prefix + ']'), message); @@ -164,6 +165,10 @@ function optimizeTask(opts) { addComment: true, includeContent: true })) + .pipe(opts.languages && opts.languages.length ? i18n_1.processNlsFiles({ + fileHeader: bundledFileHeader, + languages: opts.languages + }) : es.through()) .pipe(gulp.dest(out)); }; } diff --git a/build/lib/optimize.ts b/build/lib/optimize.ts index 78328e3ce2c..038cf09dd21 100644 --- a/build/lib/optimize.ts +++ b/build/lib/optimize.ts @@ -22,7 +22,7 @@ import * as gulpUtil from 'gulp-util'; import * as flatmap from 'gulp-flatmap'; import * as pump from 'pump'; import * as sm from 'source-map'; -import { Language } from './i18n'; +import { processNlsFiles, Language } from './i18n'; const REPO_ROOT_PATH = path.join(__dirname, '../..'); @@ -239,6 +239,10 @@ export function optimizeTask(opts: IOptimizeTaskOpts): () => NodeJS.ReadWriteStr addComment: true, includeContent: true })) + .pipe(opts.languages && opts.languages.length ? processNlsFiles({ + fileHeader: bundledFileHeader, + languages: opts.languages + }) : es.through()) .pipe(gulp.dest(out)); }; } From 399a80f42ae75cb0efede8d828842f157b3178b3 Mon Sep 17 00:00:00 2001 From: Alex Dima Date: Fri, 10 Aug 2018 11:10:36 +0200 Subject: [PATCH 0712/1276] Remove unnecessary declarations --- build/monaco/monaco.d.ts.recipe | 7 --- build/monaco/package.json | 2 +- src/vs/editor/common/modes.ts | 26 ++++++++++- src/vs/monaco.d.ts | 77 --------------------------------- 4 files changed, 25 insertions(+), 87 deletions(-) diff --git a/build/monaco/monaco.d.ts.recipe b/build/monaco/monaco.d.ts.recipe index e39100bc3bc..bebfe723484 100644 --- a/build/monaco/monaco.d.ts.recipe +++ b/build/monaco/monaco.d.ts.recipe @@ -25,13 +25,6 @@ declare namespace monaco { dispose(): void; } - export enum Severity { - Ignore = 0, - Info = 1, - Warning = 2, - Error = 3, - } - export enum MarkerTag { Unnecessary = 1, } diff --git a/build/monaco/package.json b/build/monaco/package.json index 256ca1ff534..7db9617a5dc 100644 --- a/build/monaco/package.json +++ b/build/monaco/package.json @@ -1,7 +1,7 @@ { "name": "monaco-editor-core", "private": true, - "version": "0.12.0", + "version": "0.14.1", "description": "A browser based code editor", "author": "Microsoft Corporation", "license": "MIT", diff --git a/src/vs/editor/common/modes.ts b/src/vs/editor/common/modes.ts index 0f643685413..6a4abcffa36 100644 --- a/src/vs/editor/common/modes.ts +++ b/src/vs/editor/common/modes.ts @@ -938,6 +938,9 @@ export interface Command { arguments?: any[]; } +/** + * @internal + */ export interface CommentInfo { owner: number; threads: CommentThread[]; @@ -945,6 +948,9 @@ export interface CommentInfo { reply?: Command; } +/** + * @internal + */ export enum CommentThreadCollapsibleState { /** * Determines an item is collapsed @@ -956,6 +962,9 @@ export enum CommentThreadCollapsibleState { Expanded = 1 } +/** + * @internal + */ export interface CommentThread { threadId: string; resource: string; @@ -965,11 +974,17 @@ export interface CommentThread { reply?: Command; } +/** + * @internal + */ export interface NewCommentAction { ranges: IRange[]; actions: Command[]; } +/** + * @internal + */ export interface Comment { readonly commentId: string; readonly body: IMarkdownString; @@ -978,6 +993,9 @@ export interface Comment { readonly command?: Command; } +/** + * @internal + */ export interface CommentThreadChangedEvent { readonly owner: number; /** @@ -996,7 +1014,9 @@ export interface CommentThreadChangedEvent { readonly changed: CommentThread[]; } - +/** + * @internal + */ export interface DocumentCommentProvider { provideDocumentComments(resource: URI, token: CancellationToken): Promise; createNewCommentThread(resource: URI, range: Range, text: string, token: CancellationToken): Promise; @@ -1004,7 +1024,9 @@ export interface DocumentCommentProvider { onDidChangeCommentThreads(): Event; } - +/** + * @internal + */ export interface WorkspaceCommentProvider { provideWorkspaceComments(token: CancellationToken): Promise; createNewCommentThread(resource: URI, range: Range, text: string, token: CancellationToken): Promise; diff --git a/src/vs/monaco.d.ts b/src/vs/monaco.d.ts index 462664d6c60..64d6a8bd52a 100644 --- a/src/vs/monaco.d.ts +++ b/src/vs/monaco.d.ts @@ -25,13 +25,6 @@ declare namespace monaco { dispose(): void; } - export enum Severity { - Ignore = 0, - Info = 1, - Warning = 2, - Error = 3, - } - export enum MarkerTag { Unnecessary = 1, } @@ -5309,76 +5302,6 @@ declare namespace monaco.languages { arguments?: any[]; } - export interface CommentInfo { - owner: number; - threads: CommentThread[]; - commentingRanges?: IRange[]; - reply?: Command; - } - - export enum CommentThreadCollapsibleState { - /** - * Determines an item is collapsed - */ - Collapsed = 0, - /** - * Determines an item is expanded - */ - Expanded = 1 - } - - export interface CommentThread { - threadId: string; - resource: string; - range: IRange; - comments: Comment[]; - collapsibleState?: CommentThreadCollapsibleState; - reply?: Command; - } - - export interface NewCommentAction { - ranges: IRange[]; - actions: Command[]; - } - - export interface Comment { - readonly commentId: string; - readonly body: IMarkdownString; - readonly userName: string; - readonly gravatar: string; - readonly command?: Command; - } - - export interface CommentThreadChangedEvent { - readonly owner: number; - /** - * Added comment threads. - */ - readonly added: CommentThread[]; - /** - * Removed comment threads. - */ - readonly removed: CommentThread[]; - /** - * Changed comment threads. - */ - readonly changed: CommentThread[]; - } - - export interface DocumentCommentProvider { - provideDocumentComments(resource: Uri, token: CancellationToken): Promise; - createNewCommentThread(resource: Uri, range: Range, text: string, token: CancellationToken): Promise; - replyToCommentThread(resource: Uri, range: Range, thread: CommentThread, text: string, token: CancellationToken): Promise; - onDidChangeCommentThreads(): IEvent; - } - - export interface WorkspaceCommentProvider { - provideWorkspaceComments(token: CancellationToken): Promise; - createNewCommentThread(resource: Uri, range: Range, text: string, token: CancellationToken): Promise; - replyToCommentThread(resource: Uri, range: Range, thread: CommentThread, text: string, token: CancellationToken): Promise; - onDidChangeCommentThreads(): IEvent; - } - export interface ICodeLensSymbol { range: IRange; id?: string; From 12411187281f5f738d3ccc56c263ad51bfe300a1 Mon Sep 17 00:00:00 2001 From: Alex Dima Date: Fri, 10 Aug 2018 11:17:54 +0200 Subject: [PATCH 0713/1276] Fix compilation errors --- build/monaco/monaco.usage.recipe | 1 - src/vs/editor/common/standalone/standaloneBase.ts | 7 ------- src/vs/editor/editor.api.ts | 1 - .../editor/standalone/browser/standaloneLanguages.ts | 1 - .../test/common/standalone/standaloneBase.test.ts | 12 +----------- 5 files changed, 1 insertion(+), 21 deletions(-) diff --git a/build/monaco/monaco.usage.recipe b/build/monaco/monaco.usage.recipe index 05377a19ba0..beaad500aad 100644 --- a/build/monaco/monaco.usage.recipe +++ b/build/monaco/monaco.usage.recipe @@ -71,7 +71,6 @@ import * as editorAPI from 'vs/editor/editor.api'; a = editorAPI.Range; a = editorAPI.Selection; a = editorAPI.SelectionDirection; - a = editorAPI.Severity; a = editorAPI.MarkerSeverity; a = editorAPI.MarkerTag; a = editorAPI.Promise; diff --git a/src/vs/editor/common/standalone/standaloneBase.ts b/src/vs/editor/common/standalone/standaloneBase.ts index c4683e6d6ed..6c44f5f1fa5 100644 --- a/src/vs/editor/common/standalone/standaloneBase.ts +++ b/src/vs/editor/common/standalone/standaloneBase.ts @@ -18,12 +18,6 @@ import URI from 'vs/base/common/uri'; // This is repeated here so it can be exported // because TS inlines const enums // -------------------------------------------- -export enum Severity { - Ignore = 0, - Info = 1, - Warning = 2, - Error = 3, -} export enum MarkerTag { Unnecessary = 1, @@ -248,7 +242,6 @@ export function createMonacoBaseAPI(): typeof monaco { Range: Range, Selection: Selection, SelectionDirection: SelectionDirection, - Severity: Severity, MarkerSeverity: MarkerSeverity, MarkerTag: MarkerTag, Promise: TPromise, diff --git a/src/vs/editor/editor.api.ts b/src/vs/editor/editor.api.ts index 5594a22627c..7bd274aab60 100644 --- a/src/vs/editor/editor.api.ts +++ b/src/vs/editor/editor.api.ts @@ -35,7 +35,6 @@ export const Position = api.Position; export const Range = api.Range; export const Selection = api.Selection; export const SelectionDirection = api.SelectionDirection; -export const Severity = api.Severity; export const MarkerSeverity = api.MarkerSeverity; export const MarkerTag = api.MarkerTag; export const Promise = api.Promise; diff --git a/src/vs/editor/standalone/browser/standaloneLanguages.ts b/src/vs/editor/standalone/browser/standaloneLanguages.ts index 592e1705796..b0287953b31 100644 --- a/src/vs/editor/standalone/browser/standaloneLanguages.ts +++ b/src/vs/editor/standalone/browser/standaloneLanguages.ts @@ -880,7 +880,6 @@ export function createMonacoLanguagesAPI(): typeof monaco.languages { SymbolKind: modes.SymbolKind, IndentAction: IndentAction, SuggestTriggerKind: modes.SuggestTriggerKind, - CommentThreadCollapsibleState: modes.CommentThreadCollapsibleState, FoldingRangeKind: modes.FoldingRangeKind }; } diff --git a/src/vs/editor/test/common/standalone/standaloneBase.test.ts b/src/vs/editor/test/common/standalone/standaloneBase.test.ts index 64849eb80cb..4cec807f3c1 100644 --- a/src/vs/editor/test/common/standalone/standaloneBase.test.ts +++ b/src/vs/editor/test/common/standalone/standaloneBase.test.ts @@ -5,18 +5,8 @@ 'use strict'; import * as assert from 'assert'; -import { KeyCode as StandaloneKeyCode, Severity as StandaloneSeverity } from 'vs/editor/common/standalone/standaloneBase'; +import { KeyCode as StandaloneKeyCode } from 'vs/editor/common/standalone/standaloneBase'; import { KeyCode as RuntimeKeyCode } from 'vs/base/common/keyCodes'; -import RuntimeSeverity from 'vs/base/common/severity'; - -suite('StandaloneBase', () => { - test('exports enums correctly', () => { - assert.equal(StandaloneSeverity.Ignore, RuntimeSeverity.Ignore); - assert.equal(StandaloneSeverity.Info, RuntimeSeverity.Info); - assert.equal(StandaloneSeverity.Warning, RuntimeSeverity.Warning); - assert.equal(StandaloneSeverity.Error, RuntimeSeverity.Error); - }); -}); suite('KeyCode', () => { test('is exported correctly in standalone editor', () => { From dd2a752c09bd6c9f331413feb5865d4fe5f7d804 Mon Sep 17 00:00:00 2001 From: Alex Dima Date: Fri, 10 Aug 2018 13:57:35 +0200 Subject: [PATCH 0714/1276] Don't ship unnecessary files in /esm/ --- build/gulpfile.editor.js | 4 ++++ build/monaco/package.json | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/build/gulpfile.editor.js b/build/gulpfile.editor.js index 0b54a765408..52d1f0fcf32 100644 --- a/build/gulpfile.editor.js +++ b/build/gulpfile.editor.js @@ -130,8 +130,12 @@ gulp.task('extract-editor-esm', ['clean-editor-esm', 'clean-editor-distro', 'ext ignores: [ 'inlineEntryPoint:0.ts', 'inlineEntryPoint:1.ts', + 'vs/loader.js', 'vs/nls.ts', + 'vs/nls.build.js', 'vs/nls.d.ts', + 'vs/css.js', + 'vs/css.build.js', 'vs/css.d.ts', 'vs/base/worker/workerMain.ts', ], diff --git a/build/monaco/package.json b/build/monaco/package.json index 7db9617a5dc..085a26eb353 100644 --- a/build/monaco/package.json +++ b/build/monaco/package.json @@ -1,7 +1,7 @@ { "name": "monaco-editor-core", "private": true, - "version": "0.14.1", + "version": "0.14.2", "description": "A browser based code editor", "author": "Microsoft Corporation", "license": "MIT", From f6cf2af556ee0dd15a27e90960787a4e12dcc586 Mon Sep 17 00:00:00 2001 From: Alex Dima Date: Fri, 10 Aug 2018 17:07:51 +0200 Subject: [PATCH 0715/1276] Add workaround for #56151 --- build/monaco/package.json | 2 +- .../editor/standalone/browser/standalone-tokens.css | 13 ++----------- 2 files changed, 3 insertions(+), 12 deletions(-) diff --git a/build/monaco/package.json b/build/monaco/package.json index 085a26eb353..efd919085b2 100644 --- a/build/monaco/package.json +++ b/build/monaco/package.json @@ -1,7 +1,7 @@ { "name": "monaco-editor-core", "private": true, - "version": "0.14.2", + "version": "0.14.3", "description": "A browser based code editor", "author": "Microsoft Corporation", "license": "MIT", diff --git a/src/vs/editor/standalone/browser/standalone-tokens.css b/src/vs/editor/standalone/browser/standalone-tokens.css index c5860572a8e..9362b426b48 100644 --- a/src/vs/editor/standalone/browser/standalone-tokens.css +++ b/src/vs/editor/standalone/browser/standalone-tokens.css @@ -9,17 +9,8 @@ font-family: -apple-system, BlinkMacSystemFont, "Segoe WPC", "Segoe UI", "HelveticaNeue-Light", "Ubuntu", "Droid Sans", sans-serif; } -.monaco-menu .monaco-action-bar.vertical .action-item .action-label:focus { - color: #0059AC; - stroke-width: 1.2px; - text-shadow: 0px 0px 0.15px #0059AC; -} - -.monaco-editor.vs-dark .monaco-menu .monaco-action-bar.vertical .action-item .action-label:focus, -.monaco-editor.hc-black .monaco-menu .monaco-action-bar.vertical .action-item .action-label:focus { - color: #ACDDFF; - stroke-width: 1.2px; - text-shadow: 0px 0px 0.15px #ACDDFF; +.monaco-editor .monaco-menu .monaco-action-bar.vertical .action-menu-item { + height: 20px; } .monaco-editor-hover p { From f1cbb9d22c6ef6933770be9c21ea0b78806426ff Mon Sep 17 00:00:00 2001 From: Alex Dima Date: Fri, 10 Aug 2018 18:05:34 +0200 Subject: [PATCH 0716/1276] Fix NPE uncovered in theme sample --- src/vs/editor/standalone/browser/standaloneThemeServiceImpl.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vs/editor/standalone/browser/standaloneThemeServiceImpl.ts b/src/vs/editor/standalone/browser/standaloneThemeServiceImpl.ts index 61e358dc4a0..f72758ff75e 100644 --- a/src/vs/editor/standalone/browser/standaloneThemeServiceImpl.ts +++ b/src/vs/editor/standalone/browser/standaloneThemeServiceImpl.ts @@ -100,7 +100,7 @@ class StandaloneTheme implements IStandaloneTheme { } public defines(colorId: ColorIdentifier): boolean { - return this.getColors().hasOwnProperty(colorId); + return Object.prototype.hasOwnProperty.call(this.getColors(), colorId); } public get type() { From c16beede9d093d950986bb64760e54ba60e0eabd Mon Sep 17 00:00:00 2001 From: Alex Dima Date: Fri, 10 Aug 2018 20:57:17 +0200 Subject: [PATCH 0717/1276] Fixes #56160 --- .../standalone/browser/simpleServices.ts | 19 +++++++++++++++++++ .../standalone/browser/standaloneServices.ts | 5 ++++- 2 files changed, 23 insertions(+), 1 deletion(-) diff --git a/src/vs/editor/standalone/browser/simpleServices.ts b/src/vs/editor/standalone/browser/simpleServices.ts index d20f7346b83..b3d9dbf7f14 100644 --- a/src/vs/editor/standalone/browser/simpleServices.ts +++ b/src/vs/editor/standalone/browser/simpleServices.ts @@ -45,6 +45,7 @@ import { WorkspaceEdit, isResourceTextEdit, TextEdit } from 'vs/editor/common/mo import { IModelService } from 'vs/editor/common/services/modelService'; import { EditOperation } from 'vs/editor/common/core/editOperation'; import { localize } from 'vs/nls'; +import { IUriDisplayService, UriDisplayRules } from 'vs/platform/uriDisplay/common/uriDisplay'; export class SimpleModel implements ITextEditorModel { @@ -590,3 +591,21 @@ export class SimpleBulkEditService implements IBulkEditService { }); } } + +export class SimpleUriDisplayService implements IUriDisplayService { + _serviceBrand: any; + + private readonly _onDidRegisterFormater: Emitter<{ scheme: string, formater: UriDisplayRules }> = new Emitter<{ scheme: string, formater: UriDisplayRules }>(); + public readonly onDidRegisterFormater: Event<{ scheme: string, formater: UriDisplayRules }> = this._onDidRegisterFormater.event; + + public getLabel(resource: URI, relative?: boolean): string { + if (resource.scheme === 'file') { + return resource.fsPath; + } + return resource.path; + } + + public registerFormater(schema: string, formater: UriDisplayRules): IDisposable { + throw new Error('Not implemented'); + } +} diff --git a/src/vs/editor/standalone/browser/standaloneServices.ts b/src/vs/editor/standalone/browser/standaloneServices.ts index d3275d83f30..49375edbcff 100644 --- a/src/vs/editor/standalone/browser/standaloneServices.ts +++ b/src/vs/editor/standalone/browser/standaloneServices.ts @@ -33,7 +33,7 @@ import { StandaloneCodeEditorServiceImpl } from 'vs/editor/standalone/browser/st import { SimpleConfigurationService, SimpleResourceConfigurationService, SimpleMenuService, SimpleProgressService, StandaloneCommandService, StandaloneKeybindingService, SimpleNotificationService, - StandaloneTelemetryService, SimpleWorkspaceContextService, SimpleDialogService, SimpleBulkEditService + StandaloneTelemetryService, SimpleWorkspaceContextService, SimpleDialogService, SimpleBulkEditService, SimpleUriDisplayService } from 'vs/editor/standalone/browser/simpleServices'; import { ContextKeyService } from 'vs/platform/contextkey/browser/contextKeyService'; import { IMenuService } from 'vs/platform/actions/common/actions'; @@ -44,6 +44,7 @@ import { INotificationService } from 'vs/platform/notification/common/notificati import { IDialogService } from 'vs/platform/dialogs/common/dialogs'; import { IListService, ListService } from 'vs/platform/list/browser/listService'; import { IBulkEditService } from 'vs/editor/browser/services/bulkEditService'; +import { IUriDisplayService } from 'vs/platform/uriDisplay/common/uriDisplay'; export interface IEditorOverrideServices { [index: string]: any; @@ -121,6 +122,8 @@ export module StaticServices { export const contextService = define(IWorkspaceContextService, () => new SimpleWorkspaceContextService()); + export const uriDisplayService = define(IUriDisplayService, () => new SimpleUriDisplayService()); + export const telemetryService = define(ITelemetryService, () => new StandaloneTelemetryService()); export const dialogService = define(IDialogService, () => new SimpleDialogService()); From 6d81a2213507b31d496c61d6741cb2879193554a Mon Sep 17 00:00:00 2001 From: SteVen Batten Date: Fri, 10 Aug 2018 12:07:16 -0700 Subject: [PATCH 0718/1276] first fixes #56151 --- src/vs/base/browser/ui/menu/menu.css | 6 +++--- .../editor/standalone/browser/standalone-tokens.css | 13 +++++++++++-- src/vs/workbench/electron-browser/media/shell.css | 3 +++ 3 files changed, 17 insertions(+), 5 deletions(-) diff --git a/src/vs/base/browser/ui/menu/menu.css b/src/vs/base/browser/ui/menu/menu.css index 221640196a1..4f0c0152caa 100644 --- a/src/vs/base/browser/ui/menu/menu.css +++ b/src/vs/base/browser/ui/menu/menu.css @@ -40,7 +40,7 @@ flex: 1 1 auto; display: -ms-flexbox; display: flex; - height: 2.6em; + height: 2em; align-items: center; } @@ -50,7 +50,7 @@ text-decoration: none; padding: 0 1em; background: none; - font-size: inherit; + font-size: 12px; line-height: 1; } @@ -61,7 +61,7 @@ flex: 2 1 auto; padding: 0 1em; text-align: right; - font-size: inherit; + font-size: 12px; line-height: 1; } diff --git a/src/vs/editor/standalone/browser/standalone-tokens.css b/src/vs/editor/standalone/browser/standalone-tokens.css index 9362b426b48..53582cb8360 100644 --- a/src/vs/editor/standalone/browser/standalone-tokens.css +++ b/src/vs/editor/standalone/browser/standalone-tokens.css @@ -9,8 +9,17 @@ font-family: -apple-system, BlinkMacSystemFont, "Segoe WPC", "Segoe UI", "HelveticaNeue-Light", "Ubuntu", "Droid Sans", sans-serif; } -.monaco-editor .monaco-menu .monaco-action-bar.vertical .action-menu-item { - height: 20px; +.monaco-menu .monaco-action-bar.vertical .action-item .action-menu-item:focus .action-label { + color: #0059AC; + stroke-width: 1.2px; + text-shadow: 0px 0px 0.15px #0059AC; +} + +.monaco-editor.vs-dark .monaco-menu .monaco-action-bar.vertical .action-menu-item:focus .action-label, +.monaco-editor.hc-black .monaco-menu .monaco-action-bar.vertical .action-menu-item:focus .action-label { + color: #ACDDFF; + stroke-width: 1.2px; + text-shadow: 0px 0px 0.15px #ACDDFF; } .monaco-editor-hover p { diff --git a/src/vs/workbench/electron-browser/media/shell.css b/src/vs/workbench/electron-browser/media/shell.css index 7a2b1a8207e..05267d25b87 100644 --- a/src/vs/workbench/electron-browser/media/shell.css +++ b/src/vs/workbench/electron-browser/media/shell.css @@ -80,15 +80,18 @@ .monaco-shell .monaco-menu .monaco-action-bar.vertical .action-label:not(.separator), .monaco-shell .monaco-menu .monaco-action-bar.vertical .keybinding { + font-size: inherit; padding: 0 1.5em; } .monaco-shell .monaco-menu .monaco-action-bar.vertical .action-label.separator { + font-size: inherit; padding: 0.2em 0 0 0; margin-bottom: 0.2em; } .monaco-shell .monaco-menu .monaco-action-bar.vertical .submenu-indicator { + font-size: inherit; padding: 0 1em; } From 219e8b7d2368e92f959e9c2c63d2339c339f66c9 Mon Sep 17 00:00:00 2001 From: SteVen Batten Date: Fri, 10 Aug 2018 13:45:04 -0700 Subject: [PATCH 0719/1276] fix other menu action-item references --- src/vs/editor/standalone/browser/standalone-tokens.css | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/vs/editor/standalone/browser/standalone-tokens.css b/src/vs/editor/standalone/browser/standalone-tokens.css index 53582cb8360..1396ea01d0a 100644 --- a/src/vs/editor/standalone/browser/standalone-tokens.css +++ b/src/vs/editor/standalone/browser/standalone-tokens.css @@ -211,14 +211,14 @@ } /* contextmenu */ - .monaco-editor.vs .monaco-menu .monaco-action-bar.vertical .action-item .action-label:focus, - .monaco-editor.vs-dark .monaco-menu .monaco-action-bar.vertical .action-item .action-label:focus { + .monaco-editor.vs .monaco-menu .monaco-action-bar.vertical .action-menu-item:focus .action-label, + .monaco-editor.vs-dark .monaco-menu .monaco-action-bar.vertical .action-menu-item:focus .action-label { -ms-high-contrast-adjust: none; color: highlighttext !important; background-color: highlight !important; } - .monaco-editor.vs .monaco-menu .monaco-action-bar.vertical .action-item .action-label:hover, - .monaco-editor.vs-dark .monaco-menu .monaco-action-bar.vertical .action-item .action-label:hover { + .monaco-editor.vs .monaco-menu .monaco-action-bar.vertical .action-menu-item:hover .action-label, + .monaco-editor.vs-dark .monaco-menu .monaco-action-bar.vertical .action-menu-item:hover .action-label { -ms-high-contrast-adjust: none; background: transparent !important; border: 1px solid highlight; From f34300b82ea2cabc4713096aa72d78c743fe3e57 Mon Sep 17 00:00:00 2001 From: Alex Dima Date: Fri, 10 Aug 2018 23:51:00 +0200 Subject: [PATCH 0720/1276] Remove dynamic require call in the ESM case --- src/vs/editor/common/services/editorSimpleWorker.ts | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/vs/editor/common/services/editorSimpleWorker.ts b/src/vs/editor/common/services/editorSimpleWorker.ts index d478fef73c6..884fba7fa02 100644 --- a/src/vs/editor/common/services/editorSimpleWorker.ts +++ b/src/vs/editor/common/services/editorSimpleWorker.ts @@ -529,6 +529,7 @@ export abstract class BaseEditorSimpleWorker { } return TPromise.as(methods); } + // ESM-comment-begin return new TPromise((c, e) => { require([moduleId], (foreignModule: { create: IForeignModuleFactory }) => { this._foreignModule = foreignModule.create(ctx, createData); @@ -544,6 +545,11 @@ export abstract class BaseEditorSimpleWorker { }, e); }); + // ESM-comment-end + + // ESM-uncomment-begin + // return TPromise.wrapError(new Error(`Unexpected usage`)); + // ESM-uncomment-end } // foreign method request From 413e644a1df8516900ba81fbee7f68d8c035da80 Mon Sep 17 00:00:00 2001 From: Joao Moreno Date: Mon, 13 Aug 2018 08:31:01 +0200 Subject: [PATCH 0721/1276] comment out test --- .../test/browser/ui/tree/treeModel.test.ts | 72 +++++++++---------- 1 file changed, 36 insertions(+), 36 deletions(-) diff --git a/src/vs/base/test/browser/ui/tree/treeModel.test.ts b/src/vs/base/test/browser/ui/tree/treeModel.test.ts index f348b38a9d9..71d44e275e2 100644 --- a/src/vs/base/test/browser/ui/tree/treeModel.test.ts +++ b/src/vs/base/test/browser/ui/tree/treeModel.test.ts @@ -259,45 +259,45 @@ suite('TreeModel2', function () { assert.deepEqual(list[2].depth, 1); }); - test('expand', function () { - const list = [] as ITreeNode[]; - const model = new TreeModel(toSpliceable(list)); + // test('expand', function () { + // const list = [] as ITreeNode[]; + // const model = new TreeModel(toSpliceable(list)); - model.splice([0], 0, Iterator.iterate([ - { - element: 0, collapsed: true, children: Iterator.iterate([ - { element: 10 }, - { element: 11 }, - { element: 12 }, - ]) - }, - { element: 1 }, - { element: 2 } - ])); + // model.splice([0], 0, Iterator.iterate([ + // { + // element: 0, collapsed: true, children: Iterator.iterate([ + // { element: 10 }, + // { element: 11 }, + // { element: 12 }, + // ]) + // }, + // { element: 1 }, + // { element: 2 } + // ])); - assert.deepEqual(list.length, 3); + // assert.deepEqual(list.length, 3); - model.setCollapsed([0], false); - assert.deepEqual(list.length, 6); - assert.deepEqual(list[0].element, 0); - assert.deepEqual(list[0].collapsed, false); - assert.deepEqual(list[0].depth, 1); - assert.deepEqual(list[1].element, 10); - assert.deepEqual(list[1].collapsed, false); - assert.deepEqual(list[1].depth, 2); - assert.deepEqual(list[2].element, 11); - assert.deepEqual(list[2].collapsed, false); - assert.deepEqual(list[2].depth, 2); - assert.deepEqual(list[3].element, 12); - assert.deepEqual(list[3].collapsed, false); - assert.deepEqual(list[3].depth, 2); - assert.deepEqual(list[4].element, 1); - assert.deepEqual(list[4].collapsed, false); - assert.deepEqual(list[4].depth, 1); - assert.deepEqual(list[5].element, 2); - assert.deepEqual(list[5].collapsed, false); - assert.deepEqual(list[5].depth, 1); - }); + // model.setCollapsed([0], false); + // assert.deepEqual(list.length, 6); + // assert.deepEqual(list[0].element, 0); + // assert.deepEqual(list[0].collapsed, false); + // assert.deepEqual(list[0].depth, 1); + // assert.deepEqual(list[1].element, 10); + // assert.deepEqual(list[1].collapsed, false); + // assert.deepEqual(list[1].depth, 2); + // assert.deepEqual(list[2].element, 11); + // assert.deepEqual(list[2].collapsed, false); + // assert.deepEqual(list[2].depth, 2); + // assert.deepEqual(list[3].element, 12); + // assert.deepEqual(list[3].collapsed, false); + // assert.deepEqual(list[3].depth, 2); + // assert.deepEqual(list[4].element, 1); + // assert.deepEqual(list[4].collapsed, false); + // assert.deepEqual(list[4].depth, 1); + // assert.deepEqual(list[5].element, 2); + // assert.deepEqual(list[5].collapsed, false); + // assert.deepEqual(list[5].depth, 1); + // }); test('collapse should recursively adjust visible count', function () { const list = [] as ITreeNode[]; From 456031a537d4af250e8bc89fbf0ea97f6423cd52 Mon Sep 17 00:00:00 2001 From: Benjamin Pasero Date: Mon, 13 Aug 2018 08:32:23 +0200 Subject: [PATCH 0722/1276] :lipstick: --- src/vs/base/common/marked/marked.js | 2 +- src/vs/editor/common/model/pieceTreeTextBuffer/pieceTreeBase.ts | 2 +- src/vs/platform/history/electron-main/historyMainService.ts | 2 +- .../comments/electron-browser/commentsEditorContribution.ts | 2 +- .../parts/feedback/electron-browser/media/feedback.css | 1 - src/vs/workbench/parts/files/electron-browser/fileCommands.ts | 1 - .../textmodelResolver/common/textModelResolverService.ts | 1 - 7 files changed, 4 insertions(+), 7 deletions(-) diff --git a/src/vs/base/common/marked/marked.js b/src/vs/base/common/marked/marked.js index 64cc685b4c2..92e7aaa8b53 100644 --- a/src/vs/base/common/marked/marked.js +++ b/src/vs/base/common/marked/marked.js @@ -1242,7 +1242,7 @@ Parser.prototype.tok = function() { return this.renderer.listitem(body); } case 'html': { - // TODO parse inline content if parameter markdown=1 + // TODO@matt parse inline content if parameter markdown=1 return this.renderer.html(this.token.text); } case 'paragraph': { diff --git a/src/vs/editor/common/model/pieceTreeTextBuffer/pieceTreeBase.ts b/src/vs/editor/common/model/pieceTreeTextBuffer/pieceTreeBase.ts index 491f5a38134..4d4b03519d1 100644 --- a/src/vs/editor/common/model/pieceTreeTextBuffer/pieceTreeBase.ts +++ b/src/vs/editor/common/model/pieceTreeTextBuffer/pieceTreeBase.ts @@ -1100,7 +1100,7 @@ export class PieceTreeBase { let endColumn = endOffset - this._buffers[0].lineStarts[endIndex]; let endPos = { line: endIndex, column: endColumn }; let newPiece = new Piece( - 0, /** todo */ + 0, /** todo@peng */ start, endPos, this.getLineFeedCnt(0, start, endPos), diff --git a/src/vs/platform/history/electron-main/historyMainService.ts b/src/vs/platform/history/electron-main/historyMainService.ts index e98b36915e1..fc24300eaa2 100644 --- a/src/vs/platform/history/electron-main/historyMainService.ts +++ b/src/vs/platform/history/electron-main/historyMainService.ts @@ -262,7 +262,7 @@ export class HistoryMainService implements IHistoryMainService { } } } else if (Array.isArray(storedRecents.workspaces)) { - // TODO legacy support can be removed at some point (6 month?) + // TODO@martin legacy support can be removed at some point (6 month?) // format of 1.25 and before for (const workspace of storedRecents.workspaces) { if (typeof workspace === 'string') { diff --git a/src/vs/workbench/parts/comments/electron-browser/commentsEditorContribution.ts b/src/vs/workbench/parts/comments/electron-browser/commentsEditorContribution.ts index aa5e8402ac2..65590c32c85 100644 --- a/src/vs/workbench/parts/comments/electron-browser/commentsEditorContribution.ts +++ b/src/vs/workbench/parts/comments/electron-browser/commentsEditorContribution.ts @@ -326,7 +326,7 @@ export class ReviewController implements IEditorContribution { public onModelChanged(): void { this.localToDispose = dispose(this.localToDispose); if (this._newCommentWidget) { - // todo store view state. + // todo@peng store view state. this._newCommentWidget.dispose(); this._newCommentWidget = null; } diff --git a/src/vs/workbench/parts/feedback/electron-browser/media/feedback.css b/src/vs/workbench/parts/feedback/electron-browser/media/feedback.css index 3a390da8f70..3c69f00d995 100644 --- a/src/vs/workbench/parts/feedback/electron-browser/media/feedback.css +++ b/src/vs/workbench/parts/feedback/electron-browser/media/feedback.css @@ -48,7 +48,6 @@ padding-left: 3px; } -/* TODO @C5 review link color */ .monaco-shell .feedback-form .content .channels a { padding: 2px 0; } diff --git a/src/vs/workbench/parts/files/electron-browser/fileCommands.ts b/src/vs/workbench/parts/files/electron-browser/fileCommands.ts index 5be4ed15f03..39bcd8cc6cf 100644 --- a/src/vs/workbench/parts/files/electron-browser/fileCommands.ts +++ b/src/vs/workbench/parts/files/electron-browser/fileCommands.ts @@ -79,7 +79,6 @@ export const ResourceSelectedForCompareContext = new RawContextKey('res export const REMOVE_ROOT_FOLDER_COMMAND_ID = 'removeRootFolder'; export const REMOVE_ROOT_FOLDER_LABEL = nls.localize('removeFolderFromWorkspace', "Remove Folder from Workspace"); -//TODO #54483 support string paths for backward compatibility. check with @bpasero and remove if not necessary export const openWindowCommand = (accessor: ServicesAccessor, paths: (string | URI)[], forceNewWindow: boolean) => { const windowService = accessor.get(IWindowService); windowService.openWindow(paths.map(p => typeof p === 'string' ? URI.file(p) : p), { forceNewWindow }); diff --git a/src/vs/workbench/services/textmodelResolver/common/textModelResolverService.ts b/src/vs/workbench/services/textmodelResolver/common/textModelResolverService.ts index c7e655da6e1..76cd245f08a 100644 --- a/src/vs/workbench/services/textmodelResolver/common/textModelResolverService.ts +++ b/src/vs/workbench/services/textmodelResolver/common/textModelResolverService.ts @@ -86,7 +86,6 @@ class ResourceModelCollection extends ReferenceCollection { if (!model) { - console.error(`Unable to open '${resource}' resource is not available.`); // TODO PII return TPromise.wrapError(new Error('resource is not available')); } From 2f07ddae8bf56e969e3f4ba1447258ebc999672f Mon Sep 17 00:00:00 2001 From: isidor Date: Mon, 13 Aug 2018 09:21:25 +0200 Subject: [PATCH 0723/1276] debug issues to isidorn --- .github/classifier.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/classifier.yml b/.github/classifier.yml index c1c067e5c53..a7bcb40c96f 100644 --- a/.github/classifier.yml +++ b/.github/classifier.yml @@ -15,7 +15,7 @@ css-less-scss: [ aeschli ], debug-console: [], debug: { - assignees: [ weinand ], + assignees: [ isidorn ], assignLabel: false }, diff-editor: [], From ba6a26f8cc4d8ac55b3c273943be0eeaa8bb60df Mon Sep 17 00:00:00 2001 From: isidor Date: Mon, 13 Aug 2018 10:27:40 +0200 Subject: [PATCH 0724/1276] explorer: middle click to open file pinned fixes #55733 --- .../parts/files/electron-browser/views/explorerViewer.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vs/workbench/parts/files/electron-browser/views/explorerViewer.ts b/src/vs/workbench/parts/files/electron-browser/views/explorerViewer.ts index af257952938..e0204febe1f 100644 --- a/src/vs/workbench/parts/files/electron-browser/views/explorerViewer.ts +++ b/src/vs/workbench/parts/files/electron-browser/views/explorerViewer.ts @@ -502,7 +502,7 @@ export class FileController extends WorkbenchTreeController implements IDisposab sideBySide = tree.useAltAsMultipleSelectionModifier ? (event.ctrlKey || event.metaKey) : event.altKey; } - this.openEditor(stat, { preserveFocus, sideBySide, pinned: isDoubleClick }); + this.openEditor(stat, { preserveFocus, sideBySide, pinned: isDoubleClick || (event && event.middleButton) }); } } From f3cc0677974128effaa987e8969fa8510a421038 Mon Sep 17 00:00:00 2001 From: Christof Marti Date: Mon, 13 Aug 2018 10:36:31 +0200 Subject: [PATCH 0725/1276] Missing check (#56170) --- extensions/extension-editing/src/extensionLinter.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/extensions/extension-editing/src/extensionLinter.ts b/extensions/extension-editing/src/extensionLinter.ts index cfcb7ca04d4..54af327ae07 100644 --- a/extensions/extension-editing/src/extensionLinter.ts +++ b/extensions/extension-editing/src/extensionLinter.ts @@ -249,7 +249,7 @@ export class ExtensionLinter { private readPackageJsonInfo(folder: Uri, tree: JsonNode) { const engine = tree && findNodeAtLocation(tree, ['engines', 'vscode']); const repo = tree && findNodeAtLocation(tree, ['repository', 'url']); - const uri = parseUri(repo.value); + const uri = repo && parseUri(repo.value); const info: PackageJsonInfo = { isExtension: !!(engine && engine.type === 'string'), hasHttpsRepository: !!(repo && repo.type === 'string' && repo.value && uri && uri.scheme.toLowerCase() === 'https') From 850fc8d1fc8afa38fc71756f96bde823293f4160 Mon Sep 17 00:00:00 2001 From: isidor Date: Mon, 13 Aug 2018 10:59:48 +0200 Subject: [PATCH 0726/1276] Change the default for "openDebug" to open on session start fixes #56032 --- .../parts/debug/electron-browser/debug.contribution.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vs/workbench/parts/debug/electron-browser/debug.contribution.ts b/src/vs/workbench/parts/debug/electron-browser/debug.contribution.ts index c8faf5c0e38..d34c404a4ca 100644 --- a/src/vs/workbench/parts/debug/electron-browser/debug.contribution.ts +++ b/src/vs/workbench/parts/debug/electron-browser/debug.contribution.ts @@ -205,7 +205,7 @@ configurationRegistry.registerConfiguration({ 'debug.internalConsoleOptions': INTERNAL_CONSOLE_OPTIONS_SCHEMA, 'debug.openDebug': { enum: ['neverOpen', 'openOnSessionStart', 'openOnFirstSessionStart', 'openOnDebugBreak'], - default: 'openOnFirstSessionStart', + default: 'openOnSessionStart', description: nls.localize('openDebug', "Controls when the debug view should open.") }, 'debug.enableAllHovers': { From efe424dfe76a492eab032343e2fa4cfe639939f0 Mon Sep 17 00:00:00 2001 From: Alex Dima Date: Mon, 13 Aug 2018 11:00:55 +0200 Subject: [PATCH 0727/1276] Tweaks --- .../api/electron-browser/mainThreadFileSystem.ts | 8 +++++++- src/vs/workbench/api/electron-browser/mainThreadTask.ts | 2 +- src/vs/workbench/api/node/extHost.protocol.ts | 2 ++ src/vs/workbench/api/node/extHostFileSystem.ts | 5 +++++ src/vs/workbench/api/shared/tasks.ts | 3 +-- .../extensions/electron-browser/extensionHost.ts | 9 ++++++++- .../extensions/electron-browser/extensionService.ts | 6 +++--- 7 files changed, 27 insertions(+), 8 deletions(-) diff --git a/src/vs/workbench/api/electron-browser/mainThreadFileSystem.ts b/src/vs/workbench/api/electron-browser/mainThreadFileSystem.ts index 334c62d7251..691841b18de 100644 --- a/src/vs/workbench/api/electron-browser/mainThreadFileSystem.ts +++ b/src/vs/workbench/api/electron-browser/mainThreadFileSystem.ts @@ -11,6 +11,7 @@ import { TPromise } from 'vs/base/common/winjs.base'; import { FileWriteOptions, FileSystemProviderCapabilities, IFileChange, IFileService, IFileSystemProvider, IStat, IWatchOptions, FileType, FileOverwriteOptions, FileDeleteOptions } from 'vs/platform/files/common/files'; import { extHostNamedCustomer } from 'vs/workbench/api/electron-browser/extHostCustomers'; import { ExtHostContext, ExtHostFileSystemShape, IExtHostContext, IFileChangeDto, MainContext, MainThreadFileSystemShape } from '../node/extHost.protocol'; +import { UriDisplayRules, IUriDisplayService } from 'vs/platform/uriDisplay/common/uriDisplay'; @extHostNamedCustomer(MainContext.MainThreadFileSystem) export class MainThreadFileSystem implements MainThreadFileSystemShape { @@ -20,7 +21,8 @@ export class MainThreadFileSystem implements MainThreadFileSystemShape { constructor( extHostContext: IExtHostContext, - @IFileService private readonly _fileService: IFileService + @IFileService private readonly _fileService: IFileService, + @IUriDisplayService private readonly _uriDisplayService: IUriDisplayService ) { this._proxy = extHostContext.getProxy(ExtHostContext.ExtHostFileSystem); } @@ -39,6 +41,10 @@ export class MainThreadFileSystem implements MainThreadFileSystemShape { this._fileProvider.delete(handle); } + $setUriFormatter(scheme: string, formatter: UriDisplayRules): void { + this._uriDisplayService.registerFormater(scheme, formatter); + } + $onFileSystemChange(handle: number, changes: IFileChangeDto[]): void { this._fileProvider.get(handle).$onFileSystemChange(changes); } diff --git a/src/vs/workbench/api/electron-browser/mainThreadTask.ts b/src/vs/workbench/api/electron-browser/mainThreadTask.ts index cafb5b305b2..a1b5243fa6c 100644 --- a/src/vs/workbench/api/electron-browser/mainThreadTask.ts +++ b/src/vs/workbench/api/electron-browser/mainThreadTask.ts @@ -504,7 +504,7 @@ export class MainThreadTask implements MainThreadTaskShape { this._taskService.registerTaskSystem(key, { platform: platform, uriProvider: (path: string): URI => { - return URI.parse(`${info.scheme}://${info.host}:${info.port}${path}`); + return URI.parse(`${info.scheme}://${info.authority}${path}`); }, context: this._extHostContext, resolveVariables: (workspaceFolder: IWorkspaceFolder, variables: Set): TPromise> => { diff --git a/src/vs/workbench/api/node/extHost.protocol.ts b/src/vs/workbench/api/node/extHost.protocol.ts index 0afcb94f377..575bb71cb4b 100644 --- a/src/vs/workbench/api/node/extHost.protocol.ts +++ b/src/vs/workbench/api/node/extHost.protocol.ts @@ -40,6 +40,7 @@ import { IExtensionDescription } from 'vs/workbench/services/extensions/common/e import { createExtHostContextProxyIdentifier as createExtId, createMainContextProxyIdentifier as createMainId, IRPCProtocol, ProxyIdentifier } from 'vs/workbench/services/extensions/node/proxyIdentifier'; import { IProgressOptions, IProgressStep } from 'vs/workbench/services/progress/common/progress'; import { SaveReason } from 'vs/workbench/services/textfile/common/textfiles'; +import { UriDisplayRules } from 'vs/platform/uriDisplay/common/uriDisplay'; import * as vscode from 'vscode'; export interface IEnvironment { @@ -482,6 +483,7 @@ export interface IFileChangeDto { export interface MainThreadFileSystemShape extends IDisposable { $registerFileSystemProvider(handle: number, scheme: string, capabilities: FileSystemProviderCapabilities): void; $unregisterProvider(handle: number): void; + $setUriFormatter(scheme: string, formatter: UriDisplayRules): void; $onFileSystemChange(handle: number, resource: IFileChangeDto[]): void; } diff --git a/src/vs/workbench/api/node/extHostFileSystem.ts b/src/vs/workbench/api/node/extHostFileSystem.ts index 4c29149c845..c39ffb2a3f9 100644 --- a/src/vs/workbench/api/node/extHostFileSystem.ts +++ b/src/vs/workbench/api/node/extHostFileSystem.ts @@ -15,6 +15,7 @@ import { values } from 'vs/base/common/map'; import { Range, FileChangeType } from 'vs/workbench/api/node/extHostTypes'; import { ExtHostLanguageFeatures } from 'vs/workbench/api/node/extHostLanguageFeatures'; import { Schemas } from 'vs/base/common/network'; +import { UriDisplayRules } from 'vs/platform/uriDisplay/common/uriDisplay'; class FsLinkProvider implements vscode.DocumentLinkProvider { @@ -141,6 +142,10 @@ export class ExtHostFileSystem implements ExtHostFileSystemShape { }); } + setUriFormatter(scheme: string, formatter: UriDisplayRules): void { + this._proxy.$setUriFormatter(scheme, formatter); + } + private static _asIStat(stat: vscode.FileStat): files.IStat { const { type, ctime, mtime, size } = stat; return { type, ctime, mtime, size }; diff --git a/src/vs/workbench/api/shared/tasks.ts b/src/vs/workbench/api/shared/tasks.ts index ee98ba6cccd..c03895bfb41 100644 --- a/src/vs/workbench/api/shared/tasks.ts +++ b/src/vs/workbench/api/shared/tasks.ts @@ -107,7 +107,6 @@ export interface TaskFilterDTO { export interface TaskSystemInfoDTO { scheme: string; - host: string; - port: number; + authority: string; platform: string; } \ No newline at end of file diff --git a/src/vs/workbench/services/extensions/electron-browser/extensionHost.ts b/src/vs/workbench/services/extensions/electron-browser/extensionHost.ts index e72d4340789..e30e323957d 100644 --- a/src/vs/workbench/services/extensions/electron-browser/extensionHost.ts +++ b/src/vs/workbench/services/extensions/electron-browser/extensionHost.ts @@ -38,7 +38,14 @@ import { INotificationService, Severity } from 'vs/platform/notification/common/ import { getPathFromAmdModule } from 'vs/base/common/amd'; import { timeout } from 'vs/base/common/async'; -export class ExtensionHostProcessWorker { +export interface IExtensionHostStarter { + readonly onCrashed: Event<[number, string]>; + start(): TPromise; + getInspectPort(): number; + dispose(): void; +} + +export class ExtensionHostProcessWorker implements IExtensionHostStarter { private readonly _onCrashed: Emitter<[number, string]> = new Emitter<[number, string]>(); public readonly onCrashed: Event<[number, string]> = this._onCrashed.event; diff --git a/src/vs/workbench/services/extensions/electron-browser/extensionService.ts b/src/vs/workbench/services/extensions/electron-browser/extensionService.ts index a46a116e22e..6e8576b4e4d 100644 --- a/src/vs/workbench/services/extensions/electron-browser/extensionService.ts +++ b/src/vs/workbench/services/extensions/electron-browser/extensionService.ts @@ -27,7 +27,7 @@ import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry'; import { IEnvironmentService } from 'vs/platform/environment/common/environment'; import { IStorageService } from 'vs/platform/storage/common/storage'; import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; -import { ExtensionHostProcessWorker } from 'vs/workbench/services/extensions/electron-browser/extensionHost'; +import { ExtensionHostProcessWorker, IExtensionHostStarter } from 'vs/workbench/services/extensions/electron-browser/extensionHost'; import { IMessagePassingProtocol } from 'vs/base/parts/ipc/common/ipc'; import { ExtHostCustomersRegistry } from 'vs/workbench/api/electron-browser/extHostCustomers'; import { IWindowService } from 'vs/platform/windows/common/windows'; @@ -119,14 +119,14 @@ export class ExtensionHostProcessManager extends Disposable { private readonly _extensionHostProcessFinishedActivateEvents: { [activationEvent: string]: boolean; }; private _extensionHostProcessRPCProtocol: RPCProtocol; private readonly _extensionHostProcessCustomers: IDisposable[]; - private readonly _extensionHostProcessWorker: ExtensionHostProcessWorker; + private readonly _extensionHostProcessWorker: IExtensionHostStarter; /** * winjs believes a proxy is a promise because it has a `then` method, so wrap the result in an object. */ private _extensionHostProcessProxy: TPromise<{ value: ExtHostExtensionServiceShape; }>; constructor( - extensionHostProcessWorker: ExtensionHostProcessWorker, + extensionHostProcessWorker: IExtensionHostStarter, initialActivationEvents: string[], @IInstantiationService private readonly _instantiationService: IInstantiationService, @IEnvironmentService private readonly _environmentService: IEnvironmentService, From 474e7539dd41d67bd1ff4581a49ee139fdd849bf Mon Sep 17 00:00:00 2001 From: Sandeep Somavarapu Date: Mon, 13 Aug 2018 11:55:38 +0200 Subject: [PATCH 0728/1276] Compute total weight from weights of all view descriptors --- src/vs/workbench/browser/parts/views/viewsViewlet.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/vs/workbench/browser/parts/views/viewsViewlet.ts b/src/vs/workbench/browser/parts/views/viewsViewlet.ts index 36268d9a636..7fbaeee1186 100644 --- a/src/vs/workbench/browser/parts/views/viewsViewlet.ts +++ b/src/vs/workbench/browser/parts/views/viewsViewlet.ts @@ -377,8 +377,9 @@ export abstract class ViewContainerViewlet extends PanelViewlet implements IView private computeInitialSizes(): { [id: string]: number } { let sizes = {}; if (this.dimension) { + const totalWeight = this.viewsModel.visibleViewDescriptors.reduce((totalWeight, { weight }) => totalWeight + (weight || 20), 0); for (const viewDescriptor of this.viewsModel.visibleViewDescriptors) { - sizes[viewDescriptor.id] = this.dimension.height * (viewDescriptor.weight || 20) / 100; + sizes[viewDescriptor.id] = this.dimension.height * (viewDescriptor.weight || 20) / totalWeight; } } return sizes; From 8d9331a57c26242bac2ea009eb43c58ad99cac2e Mon Sep 17 00:00:00 2001 From: Martin Aeschlimann Date: Mon, 13 Aug 2018 12:09:34 +0200 Subject: [PATCH 0729/1276] incorperate review comments --- src/vs/code/electron-main/app.ts | 2 +- src/vs/code/electron-main/launch.ts | 2 +- src/vs/code/electron-main/windows.ts | 8 ++--- src/vs/code/node/args.ts | 33 ------------------- src/vs/platform/environment/node/argv.ts | 27 +++++++++++++++ .../electron-main/historyMainService.ts | 4 +-- src/vs/platform/windows/common/windows.ts | 19 ++++------- src/vs/platform/windows/common/windowsIpc.ts | 10 +++--- src/vs/workbench/electron-browser/main.ts | 31 ++++++----------- 9 files changed, 56 insertions(+), 80 deletions(-) delete mode 100644 src/vs/code/node/args.ts diff --git a/src/vs/code/electron-main/app.ts b/src/vs/code/electron-main/app.ts index a26e6c79c39..be65769bfce 100644 --- a/src/vs/code/electron-main/app.ts +++ b/src/vs/code/electron-main/app.ts @@ -65,7 +65,7 @@ import { MenubarService } from 'vs/platform/menubar/electron-main/menubarService import { MenubarChannel } from 'vs/platform/menubar/common/menubarIpc'; import { IUriDisplayService } from 'vs/platform/uriDisplay/common/uriDisplay'; import { CodeMenu } from 'vs/code/electron-main/menus'; -import { hasArgs } from 'vs/code/node/args'; +import { hasArgs } from 'vs/platform/environment/node/argv'; import { RunOnceScheduler } from 'vs/base/common/async'; export class CodeApplication { diff --git a/src/vs/code/electron-main/launch.ts b/src/vs/code/electron-main/launch.ts index b3bf915f9a9..a3affdb0597 100644 --- a/src/vs/code/electron-main/launch.ts +++ b/src/vs/code/electron-main/launch.ts @@ -20,7 +20,7 @@ import { IConfigurationService } from 'vs/platform/configuration/common/configur import URI, { UriComponents } from 'vs/base/common/uri'; import { BrowserWindow } from 'electron'; import { Event } from 'vs/base/common/event'; -import { hasArgs } from 'vs/code/node/args'; +import { hasArgs } from 'vs/platform/environment/node/argv'; export const ID = 'launchService'; export const ILaunchService = createDecorator(ID); diff --git a/src/vs/code/electron-main/windows.ts b/src/vs/code/electron-main/windows.ts index 7a450e46ca6..4c2cbfdf499 100644 --- a/src/vs/code/electron-main/windows.ts +++ b/src/vs/code/electron-main/windows.ts @@ -14,7 +14,7 @@ import { IBackupMainService } from 'vs/platform/backup/common/backup'; import { IEnvironmentService, ParsedArgs } from 'vs/platform/environment/common/environment'; import { IStateService } from 'vs/platform/state/common/state'; import { CodeWindow, defaultWindowState } from 'vs/code/electron-main/window'; -import { asArray, hasArgs } from 'vs/code/node/args'; +import { hasArgs, asArray } from 'vs/platform/environment/node/argv'; import { ipcMain as ipc, screen, BrowserWindow, dialog, systemPreferences, app } from 'electron'; import { IPathWithLineAndColumn, parseLineAndColumnAware } from 'vs/code/node/paths'; import { ILifecycleService, UnloadReason, IWindowUnloadEvent } from 'vs/platform/lifecycle/electron-main/lifecycleMain'; @@ -423,7 +423,7 @@ export class WindowsManager implements IWindowsMainService { // Make sure to pass focus to the most relevant of the windows if we open multiple if (usedWindows.length > 1) { - let focusLastActive = this.windowsState.lastActiveWindow && !openConfig.forceEmpty && !hasArgs(openConfig.cli._) && !hasArgs(openConfig.cli['file-uri']) && !hasArgs(openConfig.cli['folder-uri']) && !hasArgs(openConfig.urisToOpen); + let focusLastActive = this.windowsState.lastActiveWindow && !openConfig.forceEmpty && !hasArgs(openConfig.cli._) && !hasArgs(openConfig.cli['file-uri']) && !hasArgs(openConfig.cli['folder-uri']) && !(openConfig.urisToOpen && openConfig.urisToOpen.length); let focusLastOpened = true; let focusLastWindow = true; @@ -999,12 +999,12 @@ export class WindowsManager implements IWindowsMainService { try { let uri = URI.parse(arg); if (!uri.scheme) { - console.log(`Invalid URI string, scheme missing: ${arg}`); + this.logService.error(`Invalid URI input string, scheme missing: ${arg}`); return null; } return uri; } catch (e) { - console.log(`Invalid URI string, scheme missing: ${e.message}`); + this.logService.error(`Invalid URI input string: ${arg}, ${e.message}`); } return null; } diff --git a/src/vs/code/node/args.ts b/src/vs/code/node/args.ts deleted file mode 100644 index feff5c5b405..00000000000 --- a/src/vs/code/node/args.ts +++ /dev/null @@ -1,33 +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'; - -/** - * Converts an argument into an array - * @param arg a argument value. Can be undefined, en entry or an array - */ -export function asArray(arg: T | T[] | undefined): T[] { - if (arg) { - if (Array.isArray(arg)) { - return arg; - } - return [arg]; - } - return []; -} - -/** - * Returns whether an argument is present. - */ -export function hasArgs(arg: T | T[] | undefined): boolean { - if (arg) { - if (Array.isArray(arg)) { - return !!arg.length; - } - return true; - } - return false; -} \ No newline at end of file diff --git a/src/vs/platform/environment/node/argv.ts b/src/vs/platform/environment/node/argv.ts index 386b12f597c..2d834829c24 100644 --- a/src/vs/platform/environment/node/argv.ts +++ b/src/vs/platform/environment/node/argv.ts @@ -236,3 +236,30 @@ ${formatOptions(extensionsHelp, columns)} ${ localize('troubleshooting', "Troubleshooting")}: ${formatOptions(troubleshootingHelp, columns)}`; } + +/** + * Converts an argument into an array + * @param arg a argument value. Can be undefined, an entry or an array + */ +export function asArray(arg: string | string[] | undefined): string[] { + if (arg) { + if (Array.isArray(arg)) { + return arg; + } + return [arg]; + } + return []; +} + +/** + * Returns whether an argument is present. + */ +export function hasArgs(arg: string | string[] | undefined): boolean { + if (arg) { + if (Array.isArray(arg)) { + return !!arg.length; + } + return true; + } + return false; +} \ No newline at end of file diff --git a/src/vs/platform/history/electron-main/historyMainService.ts b/src/vs/platform/history/electron-main/historyMainService.ts index 2ae5cf2041a..47f31f09499 100644 --- a/src/vs/platform/history/electron-main/historyMainService.ts +++ b/src/vs/platform/history/electron-main/historyMainService.ts @@ -350,7 +350,7 @@ export class HistoryMainService implements IHistoryMainService { for (let item of app.getJumpListSettings().removedItems) { const args = item.args; if (args) { - const match = /^--folderUri\s+"([^"]+)"$/.exec(args); + const match = /^--folder-uri\s+"([^"]+)"$/.exec(args); if (match) { if (args[0] === '-') { toRemove.push(URI.parse(match[1])); @@ -373,7 +373,7 @@ export class HistoryMainService implements IHistoryMainService { let args; if (isSingleFolderWorkspaceIdentifier(workspace)) { description = nls.localize('folderDesc', "{0} {1}", getBaseLabel(workspace), this.uriDisplayService.getLabel(dirname(workspace))); - args = `--folderUri "${workspace.toString()}"`; + args = `--folder-uri "${workspace.toString()}"`; } else { description = nls.localize('codeWorkspace', "Code Workspace"); args = `"${workspace.configPath}"`; diff --git a/src/vs/platform/windows/common/windows.ts b/src/vs/platform/windows/common/windows.ts index f00a214d5c5..8daee9d9578 100644 --- a/src/vs/platform/windows/common/windows.ts +++ b/src/vs/platform/windows/common/windows.ts @@ -292,20 +292,18 @@ export enum ReadyState { READY } -export interface IPath { +export interface IPath extends IPathData { // the file path to open within a Code instance fileUri?: URI; - - // the line number in the file path to open - lineNumber?: number; - - // the column number in the file path to open - columnNumber?: number; } -export interface IPathsToWaitFor { +export interface IPathsToWaitFor extends IPathsToWaitForData { paths: IPath[]; +} + +export interface IPathsToWaitForData { + paths: IPathData[]; waitMarkerFilePath: string; } @@ -321,11 +319,6 @@ export interface IPathData { columnNumber?: number; } -export interface IPathsToWaitForData { - paths: IPathData[]; - waitMarkerFilePath: string; -} - export interface IOpenFileRequest { filesToOpen?: IPathData[]; filesToCreate?: IPathData[]; diff --git a/src/vs/platform/windows/common/windowsIpc.ts b/src/vs/platform/windows/common/windowsIpc.ts index c884a48217c..a23fd06d07a 100644 --- a/src/vs/platform/windows/common/windowsIpc.ts +++ b/src/vs/platform/windows/common/windowsIpc.ts @@ -12,7 +12,7 @@ import { IWindowsService, INativeOpenDialogOptions, IEnterWorkspaceResult, Crash import { IWorkspaceIdentifier, IWorkspaceFolderCreationData, ISingleFolderWorkspaceIdentifier, isWorkspaceIdentifier } from 'vs/platform/workspaces/common/workspaces'; import { IRecentlyOpened } from 'vs/platform/history/common/history'; import { ISerializableCommandAction } from 'vs/platform/actions/common/actions'; -import URI from 'vs/base/common/uri'; +import URI, { UriComponents } from 'vs/base/common/uri'; import { ParsedArgs } from 'vs/platform/environment/common/environment'; export interface IWindowsChannel extends IChannel { @@ -40,8 +40,8 @@ export interface IWindowsChannel extends IChannel { call(command: 'saveAndEnterWorkspace', arg: [number, string]): TPromise; call(command: 'toggleFullScreen', arg: number): TPromise; call(command: 'setRepresentedFilename', arg: [number, string]): TPromise; - call(command: 'addRecentlyOpened', arg: URI[]): TPromise; - call(command: 'removeFromRecentlyOpened', arg: (IWorkspaceIdentifier | ISingleFolderWorkspaceIdentifier | URI)[]): TPromise; + call(command: 'addRecentlyOpened', arg: UriComponents[]): TPromise; + call(command: 'removeFromRecentlyOpened', arg: (IWorkspaceIdentifier | UriComponents | string)[]): TPromise; call(command: 'clearRecentlyOpened'): TPromise; call(command: 'getRecentlyOpened', arg: number): TPromise; call(command: 'newWindowTab'): TPromise; @@ -139,9 +139,9 @@ export class WindowsChannel implements IWindowsChannel { case 'saveAndEnterWorkspace': return this.service.saveAndEnterWorkspace(arg[0], arg[1]); case 'toggleFullScreen': return this.service.toggleFullScreen(arg); case 'setRepresentedFilename': return this.service.setRepresentedFilename(arg[0], arg[1]); - case 'addRecentlyOpened': return this.service.addRecentlyOpened(arg); + case 'addRecentlyOpened': return this.service.addRecentlyOpened(arg.map(URI.revive)); case 'removeFromRecentlyOpened': { - let paths: (IWorkspaceIdentifier | ISingleFolderWorkspaceIdentifier | URI)[] = arg; + let paths: (IWorkspaceIdentifier | ISingleFolderWorkspaceIdentifier | URI | string)[] = arg; if (Array.isArray(paths)) { paths = paths.map(path => isWorkspaceIdentifier(path) ? path : URI.revive(path)); } diff --git a/src/vs/workbench/electron-browser/main.ts b/src/vs/workbench/electron-browser/main.ts index fb2f9584086..f2b0cf0d3a5 100644 --- a/src/vs/workbench/electron-browser/main.ts +++ b/src/vs/workbench/electron-browser/main.ts @@ -15,7 +15,7 @@ import * as errors from 'vs/base/common/errors'; import * as comparer from 'vs/base/common/comparers'; import * as platform from 'vs/base/common/platform'; import * as paths from 'vs/base/common/paths'; -import uri, { UriComponents } from 'vs/base/common/uri'; +import uri from 'vs/base/common/uri'; import * as strings from 'vs/base/common/strings'; import { IWorkspaceContextService, Workspace, WorkbenchState } from 'vs/platform/workspace/common/workspace'; import { WorkspaceService } from 'vs/workbench/services/configuration/node/configurationService'; @@ -81,27 +81,16 @@ function revive(workbench: IWindowConfiguration) { if (workbench.folderUri) { workbench.folderUri = uri.revive(workbench.folderUri); } - function reviveFileUri(path: { fileUri?: UriComponents }) { - if (path.fileUri) { - path.fileUri = uri.revive(path.fileUri); + const filesToWaitPaths = workbench.filesToWait && workbench.filesToWait.paths; + [filesToWaitPaths, workbench.filesToOpen, workbench.filesToCreate, workbench.filesToDiff].forEach(paths => { + if (Array.isArray(paths)) { + paths.forEach(path => { + if (path.fileUri) { + path.fileUri = uri.revive(path.fileUri); + } + }); } - } - const filesToOpen = workbench.filesToOpen; - if (Array.isArray(filesToOpen)) { - filesToOpen.forEach(reviveFileUri); - } - const filesToCreate = workbench.filesToCreate; - if (Array.isArray(filesToCreate)) { - filesToCreate.forEach(reviveFileUri); - } - const filesToDiff = workbench.filesToDiff; - if (Array.isArray(filesToDiff)) { - filesToDiff.forEach(reviveFileUri); - } - const filesToWait = workbench.filesToWait; - if (filesToWait && Array.isArray(filesToWait.paths)) { - filesToWait.paths.forEach(reviveFileUri); - } + }); } function openWorkbench(configuration: IWindowConfiguration): TPromise { From 30dba777fb068e6ec7442b0e898e28d0da97642b Mon Sep 17 00:00:00 2001 From: Sandeep Somavarapu Date: Mon, 13 Aug 2018 12:12:11 +0200 Subject: [PATCH 0730/1276] Fix #52452 typo --- src/vs/workbench/parts/preferences/browser/keybindingsEditor.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vs/workbench/parts/preferences/browser/keybindingsEditor.ts b/src/vs/workbench/parts/preferences/browser/keybindingsEditor.ts index c071be384ec..0f25d0a34a6 100644 --- a/src/vs/workbench/parts/preferences/browser/keybindingsEditor.ts +++ b/src/vs/workbench/parts/preferences/browser/keybindingsEditor.ts @@ -439,7 +439,7 @@ export class KeybindingsEditor extends BaseEditor implements IKeybindingsEditor private getAriaLabel(keybindingsEntries: IKeybindingItemEntry[]): string { if (this.sortByPrecedence.checked) { - return localize('show sorted keybindings', "Showing {0} Keybindings in precendence order", keybindingsEntries.length); + return localize('show sorted keybindings', "Showing {0} Keybindings in precedence order", keybindingsEntries.length); } else { return localize('show keybindings', "Showing {0} Keybindings in alphabetical order", keybindingsEntries.length); } From f42844bf07d48e30756d25f63c4d9196853edcaf Mon Sep 17 00:00:00 2001 From: Andre Weinand Date: Mon, 13 Aug 2018 12:22:10 +0200 Subject: [PATCH 0731/1276] protect against short running debug sessions; fixes #56252 --- .../workbench/parts/debug/browser/loadedScriptsView.ts | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/vs/workbench/parts/debug/browser/loadedScriptsView.ts b/src/vs/workbench/parts/debug/browser/loadedScriptsView.ts index d5f424be629..10a11ba765b 100644 --- a/src/vs/workbench/parts/debug/browser/loadedScriptsView.ts +++ b/src/vs/workbench/parts/debug/browser/loadedScriptsView.ts @@ -364,13 +364,18 @@ export class LoadedScriptsView extends TreeViewsViewletPanel { clearTimeout(timeout); timeout = setTimeout(() => { - this.tree.refresh(root, true); + if (this.tree) { + this.tree.refresh(root, true); + } }, 300); })); this.disposables.push(this.debugService.onDidEndSession(session => { + clearTimeout(timeout); root.remove(session.getId()); - this.tree.refresh(root, false); + if (this.tree) { + this.tree.refresh(root, false); + } })); } From b5cd6d8261698444ca09c0176298fc6a34d51c41 Mon Sep 17 00:00:00 2001 From: Martin Aeschlimann Date: Mon, 13 Aug 2018 12:29:12 +0200 Subject: [PATCH 0732/1276] 'backgroundColor' and 'baseTheme' no longer needed in IWindowConfiguration (for #55677) --- src/vs/platform/windows/common/windows.ts | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/vs/platform/windows/common/windows.ts b/src/vs/platform/windows/common/windows.ts index 0a289de0b97..1903391cb6e 100644 --- a/src/vs/platform/windows/common/windows.ts +++ b/src/vs/platform/windows/common/windows.ts @@ -342,8 +342,6 @@ export interface IWindowConfiguration extends ParsedArgs, IOpenFileRequest { fullscreen?: boolean; maximized?: boolean; highContrast?: boolean; - baseTheme?: string; - backgroundColor?: string; frameless?: boolean; accessibilitySupport?: boolean; From 44dcb084e03c82a903af0f573a9e0e952baa4cf5 Mon Sep 17 00:00:00 2001 From: Andre Weinand Date: Mon, 13 Aug 2018 12:49:14 +0200 Subject: [PATCH 0733/1276] detect PowerShell when using pwsh executable; fixes #55852 --- src/vs/workbench/parts/debug/node/terminals.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vs/workbench/parts/debug/node/terminals.ts b/src/vs/workbench/parts/debug/node/terminals.ts index 00ff6960cb4..221a8bd7bc2 100644 --- a/src/vs/workbench/parts/debug/node/terminals.ts +++ b/src/vs/workbench/parts/debug/node/terminals.ts @@ -312,7 +312,7 @@ export function prepareCommand(args: DebugProtocol.RunInTerminalRequestArguments // try to determine the shell type shell = shell.trim().toLowerCase(); - if (shell.indexOf('powershell') >= 0) { + if (shell.indexOf('powershell') >= 0 || shell.indexOf('pwsh') >= 0) { shellType = ShellType.powershell; } else if (shell.indexOf('cmd.exe') >= 0) { shellType = ShellType.cmd; From 9ea3c9068180bcc998c5b1406cf32d8c8977ac12 Mon Sep 17 00:00:00 2001 From: Martin Aeschlimann Date: Mon, 13 Aug 2018 13:00:10 +0200 Subject: [PATCH 0734/1276] isEqualOrParent: compare authority according to case-sensitivity --- src/vs/base/common/resources.ts | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/vs/base/common/resources.ts b/src/vs/base/common/resources.ts index 95d05f973df..a9a53243001 100644 --- a/src/vs/base/common/resources.ts +++ b/src/vs/base/common/resources.ts @@ -26,16 +26,23 @@ export function basenameOrAuthority(resource: URI): string { } export function isEqualOrParent(resource: URI, candidate: URI, ignoreCase?: boolean): boolean { - if (resource.scheme === candidate.scheme && resource.authority === candidate.authority) { + if (resource.scheme === candidate.scheme) { if (resource.scheme === Schemas.file) { return paths.isEqualOrParent(resource.fsPath, candidate.fsPath, ignoreCase); } + if (!isEqualAuthority(resource.authority, candidate.authority, ignoreCase)) { + return false; + } return paths.isEqualOrParent(resource.path, candidate.path, ignoreCase, '/'); } return false; } +function isEqualAuthority(a1: string, a2: string, ignoreCase?: boolean) { + return a1 === a2 || ignoreCase && a1 && a2 && equalsIgnoreCase(a1, a2); +} + export function isEqual(first: URI, second: URI, ignoreCase?: boolean): boolean { const identityEquals = (first === second); if (identityEquals) { From 5831346dd1921df8e4b466a00e7587cd8bf76ac4 Mon Sep 17 00:00:00 2001 From: Johannes Rieken Date: Mon, 13 Aug 2018 11:02:58 +0200 Subject: [PATCH 0735/1276] add jsdoc form timer service metrics, #56253 --- .../services/timer/common/timerService.ts | 154 ++++++++++++++++-- .../services/timer/node/timerService.ts | 4 +- 2 files changed, 142 insertions(+), 16 deletions(-) diff --git a/src/vs/workbench/services/timer/common/timerService.ts b/src/vs/workbench/services/timer/common/timerService.ts index 84842c4eb00..040a0f34b36 100644 --- a/src/vs/workbench/services/timer/common/timerService.ts +++ b/src/vs/workbench/services/timer/common/timerService.ts @@ -55,21 +55,151 @@ export interface IMemoryInfo { } */ export interface IStartupMetrics { - version: number; + + /** + * The version of these metrics. + */ + version: 1; + + /** + * The time it took to create the workbench. + * + * * Happens in the main-process *and* the renderer-process + * * Measured with the *start* and `didStartWorkbench`-performance mark. The *start* is either the start of the + * main process or the start of the renderer. + * * This should be looked at carefully because times vary depending on + * * This being the first window, the only window, or a reloaded window + * * Cached data being present and used or not + * * The numbers and types of editors being restored + * * The numbers of windows being restored (when starting 'fresh') + * * The viewlet being restored (esp. when it's a contributed viewlet) + */ ellapsed: number; + + /** + * If this started the main process and renderer or just a renderer (new or reloaded). + */ + initialStartup: boolean; + + /** + * No folder, no file, no workspace has been opened + */ + emptyWorkbench: boolean; + timers: { + /** + * The time it took to receieve the [`ready`](https://electronjs.org/docs/api/app#event-ready)-event. Measured from the first line + * of JavaScript code till receiving that event. + * + * * Happens in the main-process + * * Measured with the `main:started` and `main:appReady` performance marks. + * * This can be compared between insider and stable builds. + * * This should be looked at per OS version and per electron version. + * * This is often affected by AV software (and can change with AV software updates outside of our release-cycle). + * * It is not our code running here and we can only observe what's happening. + */ ellapsedAppReady?: number; - ellapsedWindowLoad?: number; - ellapsedWindowLoadToRequire: number; - ellapsedExtensions: number; - ellapsedExtensionsReady: number; - ellapsedRequire: number; - ellapsedViewletRestore: number; - ellapsedEditorRestore: number; - ellapsedWorkbench: number; - ellapsedTimersToTimersComputed: number; + + /** + * The time it took to generate NLS data. + * + * * Happens in the main-process + * * Measured with the `nlsGeneration:start` and `nlsGeneration:end` performance marks. + * * This only happens when a non-english locale is being used. + * * It is our code running here and we should monitor this carefully for regressions. + */ ellapsedNlsGeneration: number; + + /** + * The time it took to tell electron to open/restore a renderer (browser window). + * + * * Happens in the main-process + * * Measured with the `main:appReady` and `main:loadWindow` performance marks. + * * This can be compared between insider and stable builds. + * * It is our code running here and we should monitor this carefully for regressions. + */ + ellapsedWindowLoad?: number; + + /** + * The time it took to create a new renderer (browser window) and to initialize that to the point + * of load the main-bundle (`workbench.main.js`). + * + * * Happens in the main-process *and* the renderer-process + * * Measured with the `main:loadWindow` and `willLoadWorkbenchMain` performance marks. + * * This can be compared between insider and stable builds. + * * It is mostly not our code running here and we can only observe what's happening. + */ + ellapsedWindowLoadToRequire: number; + + /** + * The time it took to load the main-bundle of the workbench, e.g `workbench.main.js`. + * + * * Happens in the renderer-process + * * Measured with the `willLoadWorkbenchMain` and `didLoadWorkbenchMain` performance marks. + * * This varies *a lot* when V8 cached data could be used or not + * * This should be looked at with and without V8 cached data usage + * * This is affected by the size of our code bundle (which usually grows about 5%) + */ + ellapsedRequire: number; + + /** + * The time it took to read extensions' package.json-files *and* interpret them (invoking + * the contribution points). + * + * * Happens in the renderer-process + * * Measured with the `willLoadExtensions` and `didLoadExtensions` performance marks. + * * Reading of package.json-files is avoided by caching them all in a single file (after the read, + * until another extension is installed) + * * Happens in parallel to other things, depends on async timing + * + * todo@joh/ramya this measures an artifical dealy we have added, see https://github.com/Microsoft/vscode/blob/2f07ddae8bf56e969e3f4ba1447258ebc999672f/src/vs/workbench/services/extensions/electron-browser/extensionService.ts#L311-L326 + */ + ellapsedExtensions: number; + + // the time from start till `didLoadExtensions` + // remove? + ellapsedExtensionsReady: number; + + /** + * The time it took to restore the viewlet. + * + * * Happens in the renderer-process + * * Measured with the `willRestoreViewlet` and `didRestoreViewlet` performance marks. + * * This should be looked at per viewlet-type/id. + * * Happens in parallel to other things, depends on async timing + */ + ellapsedViewletRestore: number; + + /** + * The time it took to restore editors - that is text editor and complex editor likes the settings UI + * or webviews (markdown preview). + * + * * Happens in the renderer-process + * * Measured with the `willRestoreEditors` and `didRestoreEditors` performance marks. + * * This should be looked at per editor and per editor type. + * * Happens in parallel to other things, depends on async timing + * + * todo@joh/ramya We should probably measures each editor individually? + */ + ellapsedEditorRestore: number; + + /** + * The time it took to create the workbench. + * + * * Happens in the renderer-process + * * Measured with the `willStartWorkbench` and `didStartWorkbench` performance marks. + * + * todo@joh/ramya Not sure if this is useful because this includes too much + */ + ellapsedWorkbench: number; + + // the time it took to generate this object. + // remove? + ellapsedTimersToTimersComputed: number; }; + + hasAccessibilitySupport: boolean; + isVMLikelyhood: number; platform: string; release: string; arch: string; @@ -77,10 +207,6 @@ export interface IStartupMetrics { freemem: number; meminfo: IMemoryInfo; cpus: { count: number; speed: number; model: string; }; - initialStartup: boolean; - hasAccessibilitySupport: boolean; - isVMLikelyhood: number; - emptyWorkbench: boolean; loadavg: number[]; } diff --git a/src/vs/workbench/services/timer/node/timerService.ts b/src/vs/workbench/services/timer/node/timerService.ts index 1de3ba8f6cc..4c085bfd43c 100644 --- a/src/vs/workbench/services/timer/node/timerService.ts +++ b/src/vs/workbench/services/timer/node/timerService.ts @@ -83,7 +83,7 @@ export class TimerService implements ITimerService { ellapsedEditorRestore: perf.getDuration('willRestoreEditors', 'didRestoreEditors'), ellapsedViewletRestore: perf.getDuration('willRestoreViewlet', 'didRestoreViewlet'), ellapsedWorkbench: perf.getDuration('willStartWorkbench', 'didStartWorkbench'), - ellapsedWindowLoadToRequire: perf.getEntry('mark', 'willLoadWorkbenchMain').startTime - this.windowLoad, + ellapsedWindowLoadToRequire: perf.getDuration('main:loadWindow', 'willLoadWorkbenchMain'), ellapsedTimersToTimersComputed: Date.now() - now, ellapsedNlsGeneration: nlsTime }, @@ -103,7 +103,7 @@ export class TimerService implements ITimerService { if (initialStartup) { this._startupMetrics.timers.ellapsedAppReady = perf.getDuration('main:started', 'main:appReady'); - this._startupMetrics.timers.ellapsedWindowLoad = this.windowLoad - perf.getEntry('mark', 'main:appReady').startTime; + this._startupMetrics.timers.ellapsedWindowLoad = perf.getDuration('main:appReady', 'main:loadWindow'); } } } From 199d541af1ad938c8ac0ac13d84b9165794fd97c Mon Sep 17 00:00:00 2001 From: Johannes Rieken Date: Mon, 13 Aug 2018 11:13:49 +0200 Subject: [PATCH 0736/1276] debt - simplify timer service --- src/vs/base/common/performance.js | 19 ++++--- src/vs/workbench/electron-browser/main.ts | 3 +- .../services/timer/common/timerService.ts | 9 +--- .../services/timer/node/timerService.ts | 52 ++++++++----------- 4 files changed, 34 insertions(+), 49 deletions(-) diff --git a/src/vs/base/common/performance.js b/src/vs/base/common/performance.js index c89ace71f2c..5590211c6d5 100644 --- a/src/vs/base/common/performance.js +++ b/src/vs/base/common/performance.js @@ -76,17 +76,16 @@ define([], function () { function getDuration(from, to) { const entries = global._performanceEntries; - let name = from; - let startTime = 0; - for (let i = 0; i < entries.length; i += 5) { - if (entries[i + 1] === name) { - if (name === from) { - // found `from` (start of interval) - name = to; - startTime = entries[i + 2]; + let target = to; + let endTime = 0; + for (let i = entries.length - 1; i >= 0; i -= 5) { + if (entries[i - 3] === target) { + if (target === to) { + // found `to` (end of interval) + endTime = entries[i - 2]; + target = from; } else { - // from `to` (end of interval) - return entries[i + 2] - startTime; + return endTime - entries[i - 2]; } } } diff --git a/src/vs/workbench/electron-browser/main.ts b/src/vs/workbench/electron-browser/main.ts index 05c7a8a054e..e03f30a664f 100644 --- a/src/vs/workbench/electron-browser/main.ts +++ b/src/vs/workbench/electron-browser/main.ts @@ -24,8 +24,7 @@ import { ServiceCollection } from 'vs/platform/instantiation/common/serviceColle import { realpath } from 'vs/base/node/pfs'; import { EnvironmentService } from 'vs/platform/environment/node/environmentService'; import * as gracefulFs from 'graceful-fs'; -import { IInitData } from 'vs/workbench/services/timer/common/timerService'; -import { TimerService } from 'vs/workbench/services/timer/node/timerService'; +import { TimerService, IInitData } from 'vs/workbench/services/timer/node/timerService'; import { KeyboardMapperFactory } from 'vs/workbench/services/keybinding/electron-browser/keybindingService'; import { IWindowConfiguration, IWindowsService } from 'vs/platform/windows/common/windows'; import { WindowsChannelClient } from 'vs/platform/windows/common/windowsIpc'; diff --git a/src/vs/workbench/services/timer/common/timerService.ts b/src/vs/workbench/services/timer/common/timerService.ts index 040a0f34b36..a04f4023cf9 100644 --- a/src/vs/workbench/services/timer/common/timerService.ts +++ b/src/vs/workbench/services/timer/common/timerService.ts @@ -210,14 +210,7 @@ export interface IStartupMetrics { loadavg: number[]; } -export interface IInitData { - start: number; - windowLoad: number; - isInitialStartup: boolean; - hasAccessibilitySupport: boolean; -} - -export interface ITimerService extends IInitData { +export interface ITimerService { _serviceBrand: any; readonly startupMetrics: IStartupMetrics; diff --git a/src/vs/workbench/services/timer/node/timerService.ts b/src/vs/workbench/services/timer/node/timerService.ts index 4c085bfd43c..fd34449c961 100644 --- a/src/vs/workbench/services/timer/node/timerService.ts +++ b/src/vs/workbench/services/timer/node/timerService.ts @@ -4,29 +4,29 @@ *--------------------------------------------------------------------------------------------*/ 'use strict'; -import { ITimerService, IStartupMetrics, IInitData, IMemoryInfo } from 'vs/workbench/services/timer/common/timerService'; +import { ITimerService, IStartupMetrics, IMemoryInfo } from 'vs/workbench/services/timer/common/timerService'; import { virtualMachineHint } from 'vs/base/node/id'; import * as perf from 'vs/base/common/performance'; import * as os from 'os'; +export interface IInitData { + start: number; + windowLoad: number; + isInitialStartup: boolean; + hasAccessibilitySupport: boolean; +} + export class TimerService implements ITimerService { public _serviceBrand: any; - public readonly start: number; - public readonly windowLoad: number; - - public readonly isInitialStartup: boolean; - public readonly hasAccessibilitySupport: boolean; - private _startupMetrics: IStartupMetrics; - constructor(initData: IInitData, private isEmptyWorkbench: boolean) { - this.start = initData.start; - this.windowLoad = initData.windowLoad; - - this.isInitialStartup = initData.isInitialStartup; - this.hasAccessibilitySupport = initData.hasAccessibilitySupport; + constructor( + private readonly _initData: IInitData, + private readonly _isEmptyWorkbench: boolean + ) { + // } get startupMetrics(): IStartupMetrics { @@ -38,8 +38,8 @@ export class TimerService implements ITimerService { public _computeStartupMetrics(): void { const now = Date.now(); - const initialStartup = !!this.isInitialStartup; - const start = initialStartup ? this.start : this.windowLoad; + const initialStartup = !!this._initData.isInitialStartup; + const start = initialStartup ? this._initData.start : this._initData.windowLoad; let totalmem: number; let freemem: number; @@ -70,22 +70,21 @@ export class TimerService implements ITimerService { // ignore, be on the safe side with these hardware method calls } - let nlsStart = perf.getEntry('mark', 'nlsGeneration:start'); - let nlsEnd = perf.getEntry('mark', 'nlsGeneration:end'); - let nlsTime = nlsStart && nlsEnd ? nlsEnd.startTime - nlsStart.startTime : 0; this._startupMetrics = { version: 1, ellapsed: perf.getEntry('mark', 'didStartWorkbench').startTime - start, timers: { - ellapsedExtensions: perf.getDuration('willLoadExtensions', 'didLoadExtensions'), - ellapsedExtensionsReady: perf.getEntry('mark', 'didLoadExtensions').startTime - start, + ellapsedAppReady: initialStartup ? perf.getDuration('main:started', 'main:appReady') : undefined, + ellapsedNlsGeneration: perf.getDuration('nlsGeneration:start', 'nlsGeneration:end'), + ellapsedWindowLoad: initialStartup ? perf.getDuration('main:appReady', 'main:loadWindow') : undefined, + ellapsedWindowLoadToRequire: perf.getDuration('main:loadWindow', 'willLoadWorkbenchMain'), ellapsedRequire: perf.getDuration('willLoadWorkbenchMain', 'didLoadWorkbenchMain'), + ellapsedExtensions: perf.getDuration('willLoadExtensions', 'didLoadExtensions'), ellapsedEditorRestore: perf.getDuration('willRestoreEditors', 'didRestoreEditors'), ellapsedViewletRestore: perf.getDuration('willRestoreViewlet', 'didRestoreViewlet'), ellapsedWorkbench: perf.getDuration('willStartWorkbench', 'didStartWorkbench'), - ellapsedWindowLoadToRequire: perf.getDuration('main:loadWindow', 'willLoadWorkbenchMain'), + ellapsedExtensionsReady: perf.getEntry('mark', 'didLoadExtensions').startTime - start, ellapsedTimersToTimersComputed: Date.now() - now, - ellapsedNlsGeneration: nlsTime }, platform, release, @@ -97,13 +96,8 @@ export class TimerService implements ITimerService { loadavg, initialStartup, isVMLikelyhood, - hasAccessibilitySupport: !!this.hasAccessibilitySupport, - emptyWorkbench: this.isEmptyWorkbench + hasAccessibilitySupport: !!this._initData.hasAccessibilitySupport, + emptyWorkbench: this._isEmptyWorkbench }; - - if (initialStartup) { - this._startupMetrics.timers.ellapsedAppReady = perf.getDuration('main:started', 'main:appReady'); - this._startupMetrics.timers.ellapsedWindowLoad = perf.getDuration('main:appReady', 'main:loadWindow'); - } } } From aaf573bb7fc6ff4396aded19c866134f605ca5e5 Mon Sep 17 00:00:00 2001 From: Johannes Rieken Date: Mon, 13 Aug 2018 12:02:45 +0200 Subject: [PATCH 0737/1276] wip - send startup reflections as telemetry event, #56253 --- src/vs/workbench/common/editor.ts | 5 + .../electron-browser/startupTimings.ts | 94 ++++++++++++++++++- 2 files changed, 98 insertions(+), 1 deletion(-) diff --git a/src/vs/workbench/common/editor.ts b/src/vs/workbench/common/editor.ts index 8162f48a02e..0d5e2e30903 100644 --- a/src/vs/workbench/common/editor.ts +++ b/src/vs/workbench/common/editor.ts @@ -279,6 +279,11 @@ export interface IEditorInput extends IDisposable { */ getResource(): URI; + /** + * Unique type identifier for this inpput. + */ + getTypeId(): string; + /** * Returns the display name of this input. */ diff --git a/src/vs/workbench/parts/performance/electron-browser/startupTimings.ts b/src/vs/workbench/parts/performance/electron-browser/startupTimings.ts index 047c038d75b..25ae117b18e 100644 --- a/src/vs/workbench/parts/performance/electron-browser/startupTimings.ts +++ b/src/vs/workbench/parts/performance/electron-browser/startupTimings.ts @@ -23,6 +23,55 @@ import { ILogService } from 'vs/platform/log/common/log'; import { IPanelService } from 'vs/workbench/services/panel/common/panelService'; import { IUpdateService } from 'vs/platform/update/common/update'; +/* __GDPR__FRAGMENT__ + "IStartupReflections" : { + "isLatestVersion": { "classification": "SystemMetaData", "purpose": "PerformanceAndHealth" }, + "didUseCachedData": { "classification": "SystemMetaData", "purpose": "PerformanceAndHealth" }, + "windowKind": { "classification": "SystemMetaData", "purpose": "PerformanceAndHealth" }, + "windowCount": { "classification": "SystemMetaData", "purpose": "PerformanceAndHealth" }, + "viewletId": { "classification": "SystemMetaData", "purpose": "PerformanceAndHealth" }, + "panelId": { "classification": "SystemMetaData", "purpose": "PerformanceAndHealth" }, + "editorIds": { "classification": "SystemMetaData", "purpose": "PerformanceAndHealth" } + } +*/ +interface IStartupReflections { + /** + * This is the latest (stable/insider) version. Iff not we should ignore this + * measurement. + */ + isLatestVersion: boolean; + + /** + * Whether we asked for and V8 accepted cached data. + */ + didUseCachedData: boolean; + + /** + * How/why the window was created. See https://github.com/Microsoft/vscode/blob/d1f57d871722f4d6ba63e4ef6f06287121ceb045/src/vs/platform/lifecycle/common/lifecycle.ts#L50 + */ + windowKind: number; + + /** + * The total number of windows that have been restored/created + */ + windowCount: number; + + /** + * The active viewlet id or `undedined` + */ + viewletId: string; + + /** + * The active panel id or `undefined` + */ + panelId: string; + + /** + * The editor input types or `[]` + */ + editorIds: string[]; +} + class StartupTimings implements IWorkbenchContribution { constructor( @@ -40,6 +89,7 @@ class StartupTimings implements IWorkbenchContribution { this._reportVariedStartupTimes().then(undefined, onUnexpectedError); this._reportStandardStartupTimes().then(undefined, onUnexpectedError); + this._reportStartupReflections().then(undefined, onUnexpectedError); } private async _reportVariedStartupTimes(): Promise { @@ -110,6 +160,48 @@ class StartupTimings implements IWorkbenchContribution { this._logService.info('standard startup', this._timerService.startupMetrics); } + private async _reportStartupReflections(): Promise { + await Promise.all([ + this._extensionService.whenInstalledExtensionsRegistered(), + this._lifecycleService.when(LifecyclePhase.Eventually) + ]); + + //todo@joh/ramya decide how to send this data, as single event merged with the timing or + // separate. + + /* __GDPR__ + "startupReflections" : { + "${include}": [ + "${IStartupReflections}" + ] + } + */ + this._telemetryService.publicLog('startupReflections', await this._createStartupReflections()); + } + + private async _createStartupReflections(): Promise { + + const isLatestVersion = Boolean(await this._updateService.isLatestVersion()); + const didUseCachedData = this._didUseCachedData(); + + const windowKind = this._lifecycleService.startupKind; + const windowCount = await this._windowsService.getWindowCount(); + + const viewletId = this._viewletService.getActiveViewlet() ? this._viewletService.getActiveViewlet().getId() : undefined; + const editorIds = this._editorService.visibleEditors.map(input => input.getTypeId()); + const panelId = this._panelService.getActivePanel() ? this._panelService.getActivePanel().getId() : undefined; + + return { + isLatestVersion, + didUseCachedData, + windowKind, + windowCount, + viewletId, + panelId, + editorIds + }; + } + private _didUseCachedData(): boolean { // We surely don't use cached data when we don't tell the loader to do so if (!Boolean((global).require.getConfig().nodeCachedDataDir)) { @@ -117,7 +209,7 @@ class StartupTimings implements IWorkbenchContribution { } // whenever cached data is produced or rejected a onNodeCachedData-callback is invoked. That callback // stores data in the `MonacoEnvironment.onNodeCachedData` global. See: - // https://github.com/Microsoft/vscode/blob/master/src/vs/workbench/electron-browser/bootstrap/index.js#L219 + // https://github.com/Microsoft/vscode/blob/efe424dfe76a492eab032343e2fa4cfe639939f0/src/vs/workbench/electron-browser/bootstrap/index.js#L299 if (!isFalsyOrEmpty(MonacoEnvironment.onNodeCachedData)) { return false; } From 8f46064995904717aa526854097dfdb8eba09491 Mon Sep 17 00:00:00 2001 From: Johannes Rieken Date: Mon, 13 Aug 2018 12:16:58 +0200 Subject: [PATCH 0738/1276] perf - add markers for workbench contributions --- src/vs/workbench/common/contributions.ts | 8 ++++++-- src/vs/workbench/electron-browser/actions.ts | 2 +- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/src/vs/workbench/common/contributions.ts b/src/vs/workbench/common/contributions.ts index 0b86ba6a484..beaec28f4c4 100644 --- a/src/vs/workbench/common/contributions.ts +++ b/src/vs/workbench/common/contributions.ts @@ -7,6 +7,7 @@ import { Registry } from 'vs/platform/registry/common/platform'; import { IInstantiationService, IConstructorSignature0 } from 'vs/platform/instantiation/common/instantiation'; import { ILifecycleService, LifecyclePhase } from 'vs/platform/lifecycle/common/lifecycle'; +import { mark } from 'vs/base/common/performance'; // --- Workbench Contribution Registry @@ -89,13 +90,16 @@ export class WorkbenchContributionsRegistry implements IWorkbenchContributionsRe } private doInstantiateByPhase(instantiationService: IInstantiationService, phase: LifecyclePhase): void { + mark(`LifecyclePhase/${LifecyclePhase[phase]}/createContrib:start`); const toBeInstantiated = this.toBeInstantiated.get(phase); if (toBeInstantiated) { while (toBeInstantiated.length > 0) { - instantiationService.createInstance(toBeInstantiated.shift()); + const ctor = toBeInstantiated.shift(); + instantiationService.createInstance(ctor); } } + mark(`LifecyclePhase/${LifecyclePhase[phase]}/createContrib:end`); } } -Registry.add(Extensions.Workbench, new WorkbenchContributionsRegistry()); \ No newline at end of file +Registry.add(Extensions.Workbench, new WorkbenchContributionsRegistry()); diff --git a/src/vs/workbench/electron-browser/actions.ts b/src/vs/workbench/electron-browser/actions.ts index 9a8710bd04a..ffb8afa6d7a 100644 --- a/src/vs/workbench/electron-browser/actions.ts +++ b/src/vs/workbench/electron-browser/actions.ts @@ -355,7 +355,7 @@ export class ShowStartupPerformance extends Action { (console).group('Raw Startup Timers (CSV)'); let value = `Name\tStart\n`; - let entries = getEntries('mark').slice(0).sort((a, b) => a.startTime - b.startTime); + let entries = getEntries('mark'); for (const entry of entries) { value += `${entry.name}\t${entry.startTime}\n`; } From 1b5c9925d764e7ead69957a7b175f68f377df2b5 Mon Sep 17 00:00:00 2001 From: Johannes Rieken Date: Mon, 13 Aug 2018 12:25:06 +0200 Subject: [PATCH 0739/1276] more tweaks #56253 --- src/vs/workbench/services/timer/common/timerService.ts | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/vs/workbench/services/timer/common/timerService.ts b/src/vs/workbench/services/timer/common/timerService.ts index a04f4023cf9..8605a39e58f 100644 --- a/src/vs/workbench/services/timer/common/timerService.ts +++ b/src/vs/workbench/services/timer/common/timerService.ts @@ -128,6 +128,7 @@ export interface IStartupMetrics { * * Measured with the `main:loadWindow` and `willLoadWorkbenchMain` performance marks. * * This can be compared between insider and stable builds. * * It is mostly not our code running here and we can only observe what's happening. + * */ ellapsedWindowLoadToRequire: number; @@ -137,8 +138,8 @@ export interface IStartupMetrics { * * Happens in the renderer-process * * Measured with the `willLoadWorkbenchMain` and `didLoadWorkbenchMain` performance marks. * * This varies *a lot* when V8 cached data could be used or not - * * This should be looked at with and without V8 cached data usage - * * This is affected by the size of our code bundle (which usually grows about 5%) + * * This should be looked at with and without V8 cached data usage and per electron/v8 version + * * This is affected by the size of our code bundle (which grows about 3-5% per release) */ ellapsedRequire: number; From 4944cc28475f482b60db8095699e53314c967ea9 Mon Sep 17 00:00:00 2001 From: Johannes Rieken Date: Mon, 13 Aug 2018 12:58:22 +0200 Subject: [PATCH 0740/1276] debt - remove last usages of globals and any-casts when it comes to perf marks --- src/main.js | 3 --- src/vs/code/electron-main/window.ts | 10 ++++----- src/vs/platform/windows/common/windows.ts | 5 +---- .../electron-browser/bootstrap/index.js | 8 ------- src/vs/workbench/electron-browser/main.ts | 4 ++-- .../timerService.ts | 22 ++++++++----------- 6 files changed, 16 insertions(+), 36 deletions(-) rename src/vs/workbench/services/timer/{node => electron-browser}/timerService.ts (82%) diff --git a/src/main.js b/src/main.js index ca00474ba1e..fe52e5c1621 100644 --- a/src/main.js +++ b/src/main.js @@ -7,9 +7,6 @@ const perf = require('./vs/base/common/performance'); perf.mark('main:started'); -// Perf measurements -global.perfStartTime = Date.now(); - Error.stackTraceLimit = 100; // increase number of stack frames (from 10, https://github.com/v8/v8/wiki/Stack-Trace-API) const fs = require('fs'); diff --git a/src/vs/code/electron-main/window.ts b/src/vs/code/electron-main/window.ts index 3bc811d9c7b..9f7403ac236 100644 --- a/src/vs/code/electron-main/window.ts +++ b/src/vs/code/electron-main/window.ts @@ -24,7 +24,7 @@ import { ICodeWindow, IWindowState, WindowMode } from 'vs/platform/windows/elect import { IWorkspaceIdentifier, IWorkspacesMainService } from 'vs/platform/workspaces/common/workspaces'; import { IBackupMainService } from 'vs/platform/backup/common/backup'; import { ISerializableCommandAction } from 'vs/platform/actions/common/actions'; -import { mark, exportEntries } from 'vs/base/common/performance'; +import * as perf from 'vs/base/common/performance'; import { resolveMarketplaceHeaders } from 'vs/platform/extensionManagement/node/extensionGalleryService'; export interface IWindowCreationOptions { @@ -547,7 +547,7 @@ export class CodeWindow implements ICodeWindow { } // Load URL - mark('main:loadWindow'); + perf.mark('main:loadWindow'); this._win.loadURL(this.getUrl(configuration)); // Make window visible if it did not open in N seconds because this indicates an error @@ -621,10 +621,8 @@ export class CodeWindow implements ICodeWindow { windowConfiguration.maximized = this._win.isMaximized(); windowConfiguration.frameless = this.hasHiddenTitleBarStyle() && !isMacintosh; - // Perf Counters - windowConfiguration.perfEntries = exportEntries(); - windowConfiguration.perfStartTime = (global).perfStartTime; - windowConfiguration.perfWindowLoadTime = Date.now(); + // Dump Perf Counters + windowConfiguration.perfEntries = perf.exportEntries(); // Config (combination of process.argv and window configuration) const environment = parseArgs(process.argv); diff --git a/src/vs/platform/windows/common/windows.ts b/src/vs/platform/windows/common/windows.ts index 1903391cb6e..b5c178db9ca 100644 --- a/src/vs/platform/windows/common/windows.ts +++ b/src/vs/platform/windows/common/windows.ts @@ -346,9 +346,6 @@ export interface IWindowConfiguration extends ParsedArgs, IOpenFileRequest { accessibilitySupport?: boolean; perfEntries: PerformanceEntry[]; - perfStartTime?: number; - perfAppReady?: number; - perfWindowLoadTime?: number; } export interface IRunActionInWindowRequest { @@ -389,4 +386,4 @@ export class ActiveWindowManager implements IDisposable { dispose() { this.disposables = dispose(this.disposables); } -} \ No newline at end of file +} diff --git a/src/vs/workbench/electron-browser/bootstrap/index.js b/src/vs/workbench/electron-browser/bootstrap/index.js index 5d0965c6de9..c0e0e59d31e 100644 --- a/src/vs/workbench/electron-browser/bootstrap/index.js +++ b/src/vs/workbench/electron-browser/bootstrap/index.js @@ -306,14 +306,6 @@ function main() { }); } - // Perf Counters - window.MonacoEnvironment.timers = { - isInitialStartup: !!configuration.isInitialStartup, - hasAccessibilitySupport: !!configuration.accessibilitySupport, - start: configuration.perfStartTime, - windowLoad: configuration.perfWindowLoadTime - }; - perf.mark('willLoadWorkbenchMain'); require([ 'vs/workbench/workbench.main', diff --git a/src/vs/workbench/electron-browser/main.ts b/src/vs/workbench/electron-browser/main.ts index e03f30a664f..4a9ef9247b7 100644 --- a/src/vs/workbench/electron-browser/main.ts +++ b/src/vs/workbench/electron-browser/main.ts @@ -24,7 +24,7 @@ import { ServiceCollection } from 'vs/platform/instantiation/common/serviceColle import { realpath } from 'vs/base/node/pfs'; import { EnvironmentService } from 'vs/platform/environment/node/environmentService'; import * as gracefulFs from 'graceful-fs'; -import { TimerService, IInitData } from 'vs/workbench/services/timer/node/timerService'; +import { TimerService } from 'vs/workbench/services/timer/electron-browser/timerService'; import { KeyboardMapperFactory } from 'vs/workbench/services/keybinding/electron-browser/keybindingService'; import { IWindowConfiguration, IWindowsService } from 'vs/platform/windows/common/windows'; import { WindowsChannelClient } from 'vs/platform/windows/common/windowsIpc'; @@ -85,7 +85,7 @@ function openWorkbench(configuration: IWindowConfiguration): TPromise { // Since the configuration service is one of the core services that is used in so many places, we initialize it // right before startup of the workbench shell to have its data ready for consumers return createAndInitializeWorkspaceService(configuration, environmentService).then(workspaceService => { - const timerService = new TimerService((window).MonacoEnvironment.timers as IInitData, workspaceService.getWorkbenchState() === WorkbenchState.EMPTY); + const timerService = new TimerService(configuration, workspaceService.getWorkbenchState() === WorkbenchState.EMPTY); const storageService = createStorageService(workspaceService, environmentService); return domContentLoaded().then(() => { diff --git a/src/vs/workbench/services/timer/node/timerService.ts b/src/vs/workbench/services/timer/electron-browser/timerService.ts similarity index 82% rename from src/vs/workbench/services/timer/node/timerService.ts rename to src/vs/workbench/services/timer/electron-browser/timerService.ts index fd34449c961..a1f75b791ce 100644 --- a/src/vs/workbench/services/timer/node/timerService.ts +++ b/src/vs/workbench/services/timer/electron-browser/timerService.ts @@ -8,13 +8,9 @@ import { ITimerService, IStartupMetrics, IMemoryInfo } from 'vs/workbench/servic import { virtualMachineHint } from 'vs/base/node/id'; import * as perf from 'vs/base/common/performance'; import * as os from 'os'; - -export interface IInitData { - start: number; - windowLoad: number; - isInitialStartup: boolean; - hasAccessibilitySupport: boolean; -} +import { getAccessibilitySupport } from 'vs/base/browser/browser'; +import { AccessibilitySupport } from 'vs/base/common/platform'; +import { IWindowConfiguration } from 'vs/platform/windows/common/windows'; export class TimerService implements ITimerService { @@ -23,7 +19,7 @@ export class TimerService implements ITimerService { private _startupMetrics: IStartupMetrics; constructor( - private readonly _initData: IInitData, + private readonly _configuration: IWindowConfiguration, private readonly _isEmptyWorkbench: boolean ) { // @@ -38,8 +34,8 @@ export class TimerService implements ITimerService { public _computeStartupMetrics(): void { const now = Date.now(); - const initialStartup = !!this._initData.isInitialStartup; - const start = initialStartup ? this._initData.start : this._initData.windowLoad; + const initialStartup = !!this._configuration.isInitialStartup; + const startMark = initialStartup ? 'main:started' : 'main:loadWindow'; let totalmem: number; let freemem: number; @@ -72,7 +68,7 @@ export class TimerService implements ITimerService { this._startupMetrics = { version: 1, - ellapsed: perf.getEntry('mark', 'didStartWorkbench').startTime - start, + ellapsed: perf.getDuration(startMark, 'didStartWorkbench'), timers: { ellapsedAppReady: initialStartup ? perf.getDuration('main:started', 'main:appReady') : undefined, ellapsedNlsGeneration: perf.getDuration('nlsGeneration:start', 'nlsGeneration:end'), @@ -83,7 +79,7 @@ export class TimerService implements ITimerService { ellapsedEditorRestore: perf.getDuration('willRestoreEditors', 'didRestoreEditors'), ellapsedViewletRestore: perf.getDuration('willRestoreViewlet', 'didRestoreViewlet'), ellapsedWorkbench: perf.getDuration('willStartWorkbench', 'didStartWorkbench'), - ellapsedExtensionsReady: perf.getEntry('mark', 'didLoadExtensions').startTime - start, + ellapsedExtensionsReady: perf.getDuration(startMark, 'didLoadExtensions'), ellapsedTimersToTimersComputed: Date.now() - now, }, platform, @@ -96,7 +92,7 @@ export class TimerService implements ITimerService { loadavg, initialStartup, isVMLikelyhood, - hasAccessibilitySupport: !!this._initData.hasAccessibilitySupport, + hasAccessibilitySupport: getAccessibilitySupport() === AccessibilitySupport.Enabled, emptyWorkbench: this._isEmptyWorkbench }; } From b1eb4b73c5589ff0c28ed012d80bf60cd32e300b Mon Sep 17 00:00:00 2001 From: Johannes Rieken Date: Mon, 13 Aug 2018 13:03:19 +0200 Subject: [PATCH 0741/1276] debt - move importing of entries to TS-world --- src/vs/platform/windows/common/windows.ts | 4 ++-- src/vs/workbench/electron-browser/bootstrap/index.js | 1 - src/vs/workbench/electron-browser/main.ts | 2 ++ 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/src/vs/platform/windows/common/windows.ts b/src/vs/platform/windows/common/windows.ts index b5c178db9ca..5e15c8e9fb5 100644 --- a/src/vs/platform/windows/common/windows.ts +++ b/src/vs/platform/windows/common/windows.ts @@ -14,7 +14,7 @@ import { ParsedArgs } from 'vs/platform/environment/common/environment'; import { IWorkspaceIdentifier, IWorkspaceFolderCreationData, ISingleFolderWorkspaceIdentifier } from 'vs/platform/workspaces/common/workspaces'; import { IRecentlyOpened } from 'vs/platform/history/common/history'; import { ISerializableCommandAction } from 'vs/platform/actions/common/actions'; -import { PerformanceEntry } from 'vs/base/common/performance'; +import { ExportData } from 'vs/base/common/performance'; import { LogLevel } from 'vs/platform/log/common/log'; import { IDisposable, dispose } from 'vs/base/common/lifecycle'; import URI, { UriComponents } from 'vs/base/common/uri'; @@ -345,7 +345,7 @@ export interface IWindowConfiguration extends ParsedArgs, IOpenFileRequest { frameless?: boolean; accessibilitySupport?: boolean; - perfEntries: PerformanceEntry[]; + perfEntries: ExportData; } export interface IRunActionInWindowRequest { diff --git a/src/vs/workbench/electron-browser/bootstrap/index.js b/src/vs/workbench/electron-browser/bootstrap/index.js index c0e0e59d31e..b16c9e2e461 100644 --- a/src/vs/workbench/electron-browser/bootstrap/index.js +++ b/src/vs/workbench/electron-browser/bootstrap/index.js @@ -220,7 +220,6 @@ function main() { // Correctly inherit the parent's environment assign(process.env, configuration.userEnv); - perf.importEntries(configuration.perfEntries); showPartsSplash(configuration); diff --git a/src/vs/workbench/electron-browser/main.ts b/src/vs/workbench/electron-browser/main.ts index 4a9ef9247b7..9ba1620c297 100644 --- a/src/vs/workbench/electron-browser/main.ts +++ b/src/vs/workbench/electron-browser/main.ts @@ -54,6 +54,8 @@ gracefulFs.gracefulify(fs); // enable gracefulFs export function startup(configuration: IWindowConfiguration): TPromise { + perf.importEntries(configuration.perfEntries); + // Ensure others can listen to zoom level changes browser.setZoomFactor(webFrame.getZoomFactor()); From 7ce26a4a24076262efbb321105819579df9f277f Mon Sep 17 00:00:00 2001 From: Benjamin Pasero Date: Mon, 13 Aug 2018 13:31:52 +0200 Subject: [PATCH 0742/1276] Electron 2.0.7 (#56256) * update to Electron 2.0.7 * disable ColorCorrectRendering (for #51791) --- .yarnrc | 2 +- OSSREADME.json | 2 +- src/main.js | 5 ++--- 3 files changed, 4 insertions(+), 5 deletions(-) diff --git a/.yarnrc b/.yarnrc index f1749b387ef..58d37cc88fb 100644 --- a/.yarnrc +++ b/.yarnrc @@ -1,3 +1,3 @@ disturl "https://atom.io/download/electron" -target "2.0.5" +target "2.0.7" runtime "electron" diff --git a/OSSREADME.json b/OSSREADME.json index ddfe2a1fa05..e15cccabcad 100644 --- a/OSSREADME.json +++ b/OSSREADME.json @@ -51,7 +51,7 @@ }, { "name": "electron", - "version": "2.0.5", + "version": "2.0.7", "license": "MIT", "repositoryURL": "https://github.com/electron/electron", "isProd": true diff --git a/src/main.js b/src/main.js index fe52e5c1621..1c13edd6c05 100644 --- a/src/main.js +++ b/src/main.js @@ -81,9 +81,8 @@ const app = require('electron').app; // TODO@Ben Electron 2.0.x: prevent localStorage migration from SQLite to LevelDB due to issues app.commandLine.appendSwitch('disable-mojo-local-storage'); -// TODO@Ben Electron 2.0.x: force srgb color profile (for https://github.com/Microsoft/vscode/issues/51791) -// This also seems to fix: https://github.com/Microsoft/vscode/issues/48043 -app.commandLine.appendSwitch('force-color-profile', 'srgb'); +// Force pre-Chrome-60 color profile handling (for https://github.com/Microsoft/vscode/issues/51791) +app.commandLine.appendSwitch('disable-features', 'ColorCorrectRendering'); const minimist = require('minimist'); const paths = require('./paths'); From bf67df5c2fb9297180f62c369978a491b83c7e24 Mon Sep 17 00:00:00 2001 From: Andre Weinand Date: Mon, 13 Aug 2018 14:36:54 +0200 Subject: [PATCH 0743/1276] move loaded scripts view to bottom; fixes #55463 --- .../parts/debug/electron-browser/debug.contribution.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vs/workbench/parts/debug/electron-browser/debug.contribution.ts b/src/vs/workbench/parts/debug/electron-browser/debug.contribution.ts index d34c404a4ca..7b3dfae36f1 100644 --- a/src/vs/workbench/parts/debug/electron-browser/debug.contribution.ts +++ b/src/vs/workbench/parts/debug/electron-browser/debug.contribution.ts @@ -113,8 +113,8 @@ Registry.as(PanelExtensions.Panels).setDefaultPanelId(REPL_ID); ViewsRegistry.registerViews([{ id: VARIABLES_VIEW_ID, name: nls.localize('variables', "Variables"), ctor: VariablesView, order: 10, weight: 40, container: VIEW_CONTAINER, canToggleVisibility: true }]); ViewsRegistry.registerViews([{ id: WATCH_VIEW_ID, name: nls.localize('watch', "Watch"), ctor: WatchExpressionsView, order: 20, weight: 10, container: VIEW_CONTAINER, canToggleVisibility: true }]); ViewsRegistry.registerViews([{ id: CALLSTACK_VIEW_ID, name: nls.localize('callStack', "Call Stack"), ctor: CallStackView, order: 30, weight: 30, container: VIEW_CONTAINER, canToggleVisibility: true }]); -ViewsRegistry.registerViews([{ id: LOADED_SCRIPTS_VIEW_ID, name: nls.localize('loadedScripts', "Loaded Scripts"), ctor: LoadedScriptsView, order: 35, weight: 10, container: VIEW_CONTAINER, canToggleVisibility: true, when: CONTEXT_LOADED_SCRIPTS_SUPPORTED }]); ViewsRegistry.registerViews([{ id: BREAKPOINTS_VIEW_ID, name: nls.localize('breakpoints', "Breakpoints"), ctor: BreakpointsView, order: 40, weight: 20, container: VIEW_CONTAINER, canToggleVisibility: true }]); +ViewsRegistry.registerViews([{ id: LOADED_SCRIPTS_VIEW_ID, name: nls.localize('loadedScripts', "Loaded Scripts"), ctor: LoadedScriptsView, order: 50, weight: 5, container: VIEW_CONTAINER, canToggleVisibility: true, collapsed: true, when: CONTEXT_LOADED_SCRIPTS_SUPPORTED }]); // register action to open viewlet const registry = Registry.as(WorkbenchActionRegistryExtensions.WorkbenchActions); From a295e8b615fe680718654ead1e09ead3763443a4 Mon Sep 17 00:00:00 2001 From: isidor Date: Mon, 13 Aug 2018 15:22:46 +0200 Subject: [PATCH 0744/1276] breakpoints: some promise error hanlders --- src/vs/workbench/parts/debug/browser/breakpointsView.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/vs/workbench/parts/debug/browser/breakpointsView.ts b/src/vs/workbench/parts/debug/browser/breakpointsView.ts index 33605695d12..be6268a4aa8 100644 --- a/src/vs/workbench/parts/debug/browser/breakpointsView.ts +++ b/src/vs/workbench/parts/debug/browser/breakpointsView.ts @@ -107,9 +107,9 @@ export class BreakpointsView extends ViewletPanel { if (isMiddleClick) { if (element instanceof Breakpoint) { - this.debugService.removeBreakpoints(element.getId()); + this.debugService.removeBreakpoints(element.getId()).done(undefined, onUnexpectedError); } else if (element instanceof FunctionBreakpoint) { - this.debugService.removeFunctionBreakpoints(element.getId()); + this.debugService.removeFunctionBreakpoints(element.getId()).done(undefined, onUnexpectedError); } return; } From 15b0f599b824ed4f5cbacbde9486dba598b26642 Mon Sep 17 00:00:00 2001 From: Martin Aeschlimann Date: Mon, 13 Aug 2018 15:23:53 +0200 Subject: [PATCH 0745/1276] --file-uri /--folder--uri are advanced: remove from help --- src/vs/platform/environment/node/argv.ts | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/vs/platform/environment/node/argv.ts b/src/vs/platform/environment/node/argv.ts index 2d834829c24..7183c2471eb 100644 --- a/src/vs/platform/environment/node/argv.ts +++ b/src/vs/platform/environment/node/argv.ts @@ -154,9 +154,7 @@ const optionsHelp: { [name: string]: string; } = { '--locale ': localize('locale', "The locale to use (e.g. en-US or zh-TW)."), '--user-data-dir

': localize('userDataDir', "Specifies the directory that user data is kept in. Can be used to open multiple distinct instances of Code."), '-v, --version': localize('version', "Print version."), - '-h, --help': localize('help', "Print usage."), - '--folder-uri ': localize('folder uri', "Opens a window with given folder uri(s)"), - '--file-uri ': localize('file uri', "Opens a window with given file uri(s)") + '-h, --help': localize('help', "Print usage.") }; const extensionsHelp: { [name: string]: string; } = { From 56220afb7d15ebdbfa1903f6e24024d79e256ba3 Mon Sep 17 00:00:00 2001 From: Dirk Baeumer Date: Mon, 13 Aug 2018 14:57:10 +0200 Subject: [PATCH 0746/1276] Fixes #54819: Support English locales like en-gb, en-au --- src/main.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main.js b/src/main.js index 1c13edd6c05..711217d64e2 100644 --- a/src/main.js +++ b/src/main.js @@ -260,9 +260,9 @@ function getNLSConfiguration(locale) { // We have a built version so we have extracted nls file. Try to find // the right file to use. - // Check if we have an English locale. If so fall to default since that is our + // Check if we have an English or English US locale. If so fall to default since that is our // English translation (we don't ship *.nls.en.json files) - if (locale && (locale == 'en' || locale.startsWith('en-'))) { + if (locale && (locale === 'en' || locale === 'en-us')) { return Promise.resolve({ locale: locale, availableLanguages: {} }); } From 4bed3a88cf4a67cd8d198725f92751080f234767 Mon Sep 17 00:00:00 2001 From: Johannes Rieken Date: Mon, 13 Aug 2018 15:35:51 +0200 Subject: [PATCH 0747/1276] fix #56150 --- src/vs/editor/browser/editorBrowser.ts | 8 ++++++++ .../editor/browser/widget/codeEditorWidget.ts | 13 +++++++++++++ src/vs/editor/contrib/suggest/suggestModel.ts | 17 ++++++++++++++++- src/vs/monaco.d.ts | 8 ++++++++ 4 files changed, 45 insertions(+), 1 deletion(-) diff --git a/src/vs/editor/browser/editorBrowser.ts b/src/vs/editor/browser/editorBrowser.ts index 28ecaca15e1..d2b256b0ac9 100644 --- a/src/vs/editor/browser/editorBrowser.ts +++ b/src/vs/editor/browser/editorBrowser.ts @@ -396,6 +396,14 @@ export interface ICodeEditor extends editorCommon.IEditor { * @internal */ onDidType(listener: (text: string) => void): IDisposable; + /** + * An event emitted after composition has started. + */ + onCompositionStart(listener: () => void): IDisposable; + /** + * An event emitted after composition has ended. + */ + onCompositionEnd(listener: () => void): IDisposable; /** * An event emitted when editing failed because the editor is read-only. * @event diff --git a/src/vs/editor/browser/widget/codeEditorWidget.ts b/src/vs/editor/browser/widget/codeEditorWidget.ts index 3f20b8b4a2d..6f588e16445 100644 --- a/src/vs/editor/browser/widget/codeEditorWidget.ts +++ b/src/vs/editor/browser/widget/codeEditorWidget.ts @@ -127,6 +127,12 @@ export class CodeEditorWidget extends Disposable implements editorBrowser.ICodeE private readonly _onDidType: Emitter = this._register(new Emitter()); public readonly onDidType = this._onDidType.event; + private readonly _onCompositionStart: Emitter = this._register(new Emitter()); + public readonly onCompositionStart = this._onCompositionStart.event; + + private readonly _onCompositionEnd: Emitter = this._register(new Emitter()); + public readonly onCompositionEnd = this._onCompositionEnd.event; + private readonly _onDidPaste: Emitter = this._register(new Emitter()); public readonly onDidPaste = this._onDidPaste.event; @@ -894,6 +900,13 @@ export class CodeEditorWidget extends Disposable implements editorBrowser.ICodeE return; } + if (handlerId === editorCommon.Handler.CompositionStart) { + this._onCompositionStart.fire(); + } + if (handlerId === editorCommon.Handler.CompositionEnd) { + this._onCompositionEnd.fire(); + } + const action = this.getAction(handlerId); if (action) { TPromise.as(action.run()).then(null, onUnexpectedError); diff --git a/src/vs/editor/contrib/suggest/suggestModel.ts b/src/vs/editor/contrib/suggest/suggestModel.ts index 4a427b85dfe..cceda3b6cfd 100644 --- a/src/vs/editor/contrib/suggest/suggestModel.ts +++ b/src/vs/editor/contrib/suggest/suggestModel.ts @@ -134,9 +134,24 @@ export class SuggestModel implements IDisposable { this._toDispose.push(this._editor.onDidChangeCursorSelection(e => { this._onCursorChange(e); })); - this._toDispose.push(this._editor.onDidChangeModelContent(e => { + + let editorIsComposing = false; + this._toDispose.push(this._editor.onCompositionStart(() => { + editorIsComposing = true; + })); + this._toDispose.push(this._editor.onCompositionEnd(() => { + // refilter when composition ends + editorIsComposing = false; this._refilterCompletionItems(); })); + this._toDispose.push(this._editor.onDidChangeModelContent(() => { + // only filter completions when the editor isn't + // composing a character, e.g. ¨ + u makes ü but just + // ¨ cannot be used for filtering + if (!editorIsComposing) { + this._refilterCompletionItems(); + } + })); this._updateTriggerCharacters(); this._updateQuickSuggest(); diff --git a/src/vs/monaco.d.ts b/src/vs/monaco.d.ts index 64d6a8bd52a..7a7340a5649 100644 --- a/src/vs/monaco.d.ts +++ b/src/vs/monaco.d.ts @@ -3794,6 +3794,14 @@ declare namespace monaco.editor { * @event */ onDidBlurEditorWidget(listener: () => void): IDisposable; + /** + * An event emitted after composition has started. + */ + onCompositionStart(listener: () => void): IDisposable; + /** + * An event emitted after composition has ended. + */ + onCompositionEnd(listener: () => void): IDisposable; /** * An event emitted on a "mouseup". * @event From 47affc12421f22d902dbe436f1d10e13070ed1ac Mon Sep 17 00:00:00 2001 From: Johannes Rieken Date: Mon, 13 Aug 2018 15:49:27 +0200 Subject: [PATCH 0748/1276] remove unused dependencies --- extensions/git/package.json | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/extensions/git/package.json b/extensions/git/package.json index 24d3660dca6..a3ceecff75f 100644 --- a/extensions/git/package.json +++ b/extensions/git/package.json @@ -1207,8 +1207,6 @@ "@types/mocha": "2.2.43", "@types/node": "7.0.43", "@types/which": "^1.0.28", - "mocha": "^3.2.0", - "webpack": "^4.16.5", - "webpack-cli": "^3.1.0" + "mocha": "^3.2.0" } } From cee43d735067d34b0b2892c1b0796066f7d33cb0 Mon Sep 17 00:00:00 2001 From: Martin Aeschlimann Date: Mon, 13 Aug 2018 15:52:19 +0200 Subject: [PATCH 0749/1276] support goto for file uris arguments --- src/vs/code/electron-main/windows.ts | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/vs/code/electron-main/windows.ts b/src/vs/code/electron-main/windows.ts index 4c2cbfdf499..66448d3c472 100644 --- a/src/vs/code/electron-main/windows.ts +++ b/src/vs/code/electron-main/windows.ts @@ -1017,6 +1017,14 @@ export class WindowsManager implements IWindowsMainService { return this.parsePath(uri.fsPath, options); } if (isFile) { + if (options && options.gotoLineMode) { + const parsedPath = parseLineAndColumnAware(uri.path); + return { + fileUri: uri.with({ path: parsedPath.path }), + lineNumber: parsedPath.line, + columnNumber: parsedPath.column + }; + } return { fileUri: uri }; From 29c72c0124c2299a56faa69490440076f1f75976 Mon Sep 17 00:00:00 2001 From: Andre Weinand Date: Mon, 13 Aug 2018 15:49:27 +0200 Subject: [PATCH 0750/1276] aria labels for loaded scripts view; fixes #55447 --- .../parts/debug/browser/loadedScriptsView.ts | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/src/vs/workbench/parts/debug/browser/loadedScriptsView.ts b/src/vs/workbench/parts/debug/browser/loadedScriptsView.ts index 10a11ba765b..6151ef068a4 100644 --- a/src/vs/workbench/parts/debug/browser/loadedScriptsView.ts +++ b/src/vs/workbench/parts/debug/browser/loadedScriptsView.ts @@ -491,6 +491,22 @@ class LoadedScriptsRenderer implements IRenderer { class LoadedSciptsAccessibilityProvider implements IAccessibilityProvider { public getAriaLabel(tree: ITree, element: any): string { - return nls.localize('implement me', "implement me"); + + if (element instanceof RootFolderTreeItem) { + return nls.localize('loadedScriptsRootFolderAriaLabel', "Workspace folder {0}, loaded script, debug", element.getLabel()); + } + + if (element instanceof SessionTreeItem) { + return nls.localize('loadedScriptsSessionAriaLabel', "Session {0}, loaded script, debug", element.getLabel()); + } + + if (element instanceof BaseTreeItem) { + if (element.hasChildren()) { + return nls.localize('loadedScriptsFolderAriaLabel', "Folder {0}, loaded script, debug", element.getLabel()); + } else { + return nls.localize('loadedScriptsSourceAriaLabel', "{0}, loaded script, debug", element.getLabel()); + } + } + return null; } } From 8a7a56e7c511ebae17a5afc31b76897543b259f3 Mon Sep 17 00:00:00 2001 From: isidor Date: Mon, 13 Aug 2018 16:15:50 +0200 Subject: [PATCH 0751/1276] fixes #56140 --- src/vs/workbench/parts/files/electron-browser/fileActions.ts | 2 +- src/vs/workbench/parts/files/electron-browser/fileCommands.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/vs/workbench/parts/files/electron-browser/fileActions.ts b/src/vs/workbench/parts/files/electron-browser/fileActions.ts index 4fa6d796f55..2b34716fc38 100644 --- a/src/vs/workbench/parts/files/electron-browser/fileActions.ts +++ b/src/vs/workbench/parts/files/electron-browser/fileActions.ts @@ -1551,7 +1551,7 @@ export class CompareWithClipboardAction extends Action { this.registrationDisposal = dispose(this.registrationDisposal); }; - return always(this.editorService.openEditor({ leftResource: URI.from({ scheme: CompareWithClipboardAction.SCHEME, path: resource.fsPath }), rightResource: resource, label: editorLabel }), cleanUp); + return always(this.editorService.openEditor({ leftResource: resource.with({ scheme: CompareWithClipboardAction.SCHEME }), rightResource: resource, label: editorLabel }), cleanUp); } return TPromise.as(true); diff --git a/src/vs/workbench/parts/files/electron-browser/fileCommands.ts b/src/vs/workbench/parts/files/electron-browser/fileCommands.ts index 39bcd8cc6cf..38cb4a1c6b9 100644 --- a/src/vs/workbench/parts/files/electron-browser/fileCommands.ts +++ b/src/vs/workbench/parts/files/electron-browser/fileCommands.ts @@ -288,7 +288,7 @@ KeybindingsRegistry.registerCommandAndKeybindingRule({ const name = paths.basename(uri.fsPath); const editorLabel = nls.localize('modifiedLabel', "{0} (on disk) ↔ {1}", name, name); - return editorService.openEditor({ leftResource: URI.from({ scheme: COMPARE_WITH_SAVED_SCHEMA, path: uri.fsPath }), rightResource: uri, label: editorLabel }).then(() => void 0); + return editorService.openEditor({ leftResource: uri.with({ scheme: COMPARE_WITH_SAVED_SCHEMA }), rightResource: uri, label: editorLabel }).then(() => void 0); } return TPromise.as(true); From ebf3859c7d2425fb7b4266acecd5ae9e7233e3d6 Mon Sep 17 00:00:00 2001 From: Johannes Rieken Date: Mon, 13 Aug 2018 16:23:11 +0200 Subject: [PATCH 0752/1276] fix extensions actions test --- .../extensions/test/electron-browser/extensionsActions.test.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/vs/workbench/parts/extensions/test/electron-browser/extensionsActions.test.ts b/src/vs/workbench/parts/extensions/test/electron-browser/extensionsActions.test.ts index 1c34aeeffa7..efdd2be342e 100644 --- a/src/vs/workbench/parts/extensions/test/electron-browser/extensionsActions.test.ts +++ b/src/vs/workbench/parts/extensions/test/electron-browser/extensionsActions.test.ts @@ -37,6 +37,7 @@ import { URLService } from 'vs/platform/url/common/urlService'; import URI from 'vs/base/common/uri'; import { SingleServerExtensionManagementServerService } from 'vs/workbench/services/extensions/node/extensionManagementServerService'; import { Schemas } from 'vs/base/common/network'; +import { TestConfigurationService } from 'vs/platform/configuration/test/common/testConfigurationService'; suite('ExtensionsActions Test', () => { @@ -60,7 +61,7 @@ suite('ExtensionsActions Test', () => { instantiationService.stub(IWindowService, TestWindowService); instantiationService.stub(IWorkspaceContextService, new TestContextService()); - instantiationService.stub(IConfigurationService, { onDidUpdateConfiguration: () => { }, onDidChangeConfiguration: () => { }, getConfiguration: () => ({}) }); + instantiationService.stub(IConfigurationService, new TestConfigurationService()); instantiationService.stub(IExtensionGalleryService, ExtensionGalleryService); From ce15d8c355a2591bd6c2a850fca4df14cf0b05ab Mon Sep 17 00:00:00 2001 From: Johannes Rieken Date: Mon, 13 Aug 2018 16:31:41 +0200 Subject: [PATCH 0753/1276] uri - print a warning when an URI lacks a scheme, #56108 --- src/vs/base/common/uri.ts | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/vs/base/common/uri.ts b/src/vs/base/common/uri.ts index 4a6f69ea626..00d663cd507 100644 --- a/src/vs/base/common/uri.ts +++ b/src/vs/base/common/uri.ts @@ -13,10 +13,11 @@ const _doubleSlashStart = /^\/\//; function _validateUri(ret: URI): void { - // // scheme, must be set - // if (!ret.scheme) { - // throw new Error('[UriError]: Scheme is missing.'); - // } + // scheme, must be set + if (!ret.scheme) { + // throw new Error(`[UriError]: Scheme is missing: {scheme: "", authority: "${ret.authority}", path: "${ret.path}", query: "${ret.query}", fragment: "${ret.fragment}"}`); + console.warn(`[UriError]: Scheme is missing: {scheme: "", authority: "${ret.authority}", path: "${ret.path}", query: "${ret.query}", fragment: "${ret.fragment}"}`); + } // scheme, https://tools.ietf.org/html/rfc3986#section-3.1 // ALPHA *( ALPHA / DIGIT / "+" / "-" / "." ) From 4c094254ac207c899ad3a368d2fb800f0eaf7aea Mon Sep 17 00:00:00 2001 From: Johannes Rieken Date: Mon, 13 Aug 2018 16:42:05 +0200 Subject: [PATCH 0754/1276] try different source map config --- extensions/emmet/extension.webpack.config.js | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/extensions/emmet/extension.webpack.config.js b/extensions/emmet/extension.webpack.config.js index 752505a4108..8e5d4d98f18 100644 --- a/extensions/emmet/extension.webpack.config.js +++ b/extensions/emmet/extension.webpack.config.js @@ -27,12 +27,5 @@ module.exports = { 'vscode': 'commonjs vscode', }, stats: 'errors-only', - devtool: 'source-map', - module: { - rules: [{ - test: /\.js$/, - use: ["source-map-loader"], - enforce: "pre" - }] - } + devtool: 'source-map' }; From dd31f42c0cdf04db38a392050503874e49518279 Mon Sep 17 00:00:00 2001 From: Martin Aeschlimann Date: Mon, 13 Aug 2018 16:48:26 +0200 Subject: [PATCH 0755/1276] Normalize uri-paths before attempting to open them? Fixes #54990 --- src/vs/code/electron-main/windows.ts | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/vs/code/electron-main/windows.ts b/src/vs/code/electron-main/windows.ts index 66448d3c472..ba5c9f64885 100644 --- a/src/vs/code/electron-main/windows.ts +++ b/src/vs/code/electron-main/windows.ts @@ -37,7 +37,8 @@ import { normalizeNFC } from 'vs/base/common/normalization'; import URI from 'vs/base/common/uri'; import { Queue } from 'vs/base/common/async'; import { exists } from 'vs/base/node/pfs'; -import { getComparisonKey, isEqual, hasToIgnoreCase } from 'vs/base/common/resources'; +import { getComparisonKey, isEqual, hasToIgnoreCase, normalizePath } from 'vs/base/common/resources'; +import { endsWith } from 'vs/base/common/strings'; enum WindowError { UNRESPONSIVE, @@ -1016,6 +1017,11 @@ export class WindowsManager implements IWindowsMainService { if (uri.scheme === Schemas.file) { return this.parsePath(uri.fsPath, options); } + // normalize URI + uri = normalizePath(uri); + if (endsWith(uri.path, '/')) { + uri = uri.with({ path: uri.path.substr(0, uri.path.length - 1) }); + } if (isFile) { if (options && options.gotoLineMode) { const parsedPath = parseLineAndColumnAware(uri.path); From 7f2ca9a8b047042496b2ea33fb6342939041995b Mon Sep 17 00:00:00 2001 From: Johannes Rieken Date: Mon, 13 Aug 2018 17:00:00 +0200 Subject: [PATCH 0756/1276] Revert "try different source map config" This reverts commit 4c094254ac207c899ad3a368d2fb800f0eaf7aea. --- extensions/emmet/extension.webpack.config.js | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/extensions/emmet/extension.webpack.config.js b/extensions/emmet/extension.webpack.config.js index 8e5d4d98f18..752505a4108 100644 --- a/extensions/emmet/extension.webpack.config.js +++ b/extensions/emmet/extension.webpack.config.js @@ -27,5 +27,12 @@ module.exports = { 'vscode': 'commonjs vscode', }, stats: 'errors-only', - devtool: 'source-map' + devtool: 'source-map', + module: { + rules: [{ + test: /\.js$/, + use: ["source-map-loader"], + enforce: "pre" + }] + } }; From bbd54cb673382d74dbc252c2ffb85e5eadcc4bd8 Mon Sep 17 00:00:00 2001 From: Benjamin Pasero Date: Mon, 13 Aug 2018 17:39:43 +0200 Subject: [PATCH 0757/1276] fix #56251 --- src/vs/code/electron-main/windows.ts | 15 --------------- 1 file changed, 15 deletions(-) diff --git a/src/vs/code/electron-main/windows.ts b/src/vs/code/electron-main/windows.ts index ba5c9f64885..ee30f9a282b 100644 --- a/src/vs/code/electron-main/windows.ts +++ b/src/vs/code/electron-main/windows.ts @@ -546,14 +546,6 @@ export class WindowsManager implements IWindowsMainService { workspaceResolver: workspace => this.workspacesMainService.resolveWorkspaceSync(workspace.configPath) }); - // Special case: we started with --wait and we got back a folder to open. In this case - // we actually prefer to not open the folder but operate purely on the file. - if (typeof bestWindowOrFolder === 'string' && filesToWait) { - //TODO@Ben: #54483 This should not happen - console.error(`This should not happen`, bestWindowOrFolder, WindowsManager.WINDOWS); - bestWindowOrFolder = !openFilesInNewWindow ? this.getLastActiveWindow() : null; - } - // We found a window to open the files in if (bestWindowOrFolder instanceof CodeWindow) { @@ -581,13 +573,6 @@ export class WindowsManager implements IWindowsMainService { } } - // We found a suitable folder to open: add it to foldersToOpen - else if (typeof bestWindowOrFolder === 'string') { - //TODO@Ben: #54483 Ben This should not happen - // foldersToOpen.push(bestWindowOrFolder); - console.error(`This should not happen`, bestWindowOrFolder, WindowsManager.WINDOWS); - } - // Finally, if no window or folder is found, just open the files in an empty window else { usedWindows.push(this.openInBrowserWindow({ From d4430204886446e7f16f101753ac13ed2e3cea90 Mon Sep 17 00:00:00 2001 From: Sandeep Somavarapu Date: Mon, 13 Aug 2018 18:21:43 +0200 Subject: [PATCH 0758/1276] Fix #55699 --- .../markers/electron-browser/markersPanel.ts | 20 +++++++++++++++++-- .../electron-browser/media/markers.css | 1 + 2 files changed, 19 insertions(+), 2 deletions(-) diff --git a/src/vs/workbench/parts/markers/electron-browser/markersPanel.ts b/src/vs/workbench/parts/markers/electron-browser/markersPanel.ts index c89d699c248..76d693bd41f 100644 --- a/src/vs/workbench/parts/markers/electron-browser/markersPanel.ts +++ b/src/vs/workbench/parts/markers/electron-browser/markersPanel.ts @@ -32,6 +32,8 @@ import { SimpleFileResourceDragAndDrop } from 'vs/workbench/browser/dnd'; import { IStorageService } from 'vs/platform/storage/common/storage'; import { Scope } from 'vs/workbench/common/memento'; import { localize } from 'vs/nls'; +import { IKeyboardEvent } from 'vs/base/browser/keyboardEvent'; +import { KeyCode } from 'vs/base/common/keyCodes'; export class MarkersPanel extends Panel { @@ -307,6 +309,7 @@ export class MarkersPanel extends Panel { dom.clearNode(this.messageBoxContainer); const markersModel = this.markersWorkbenchService.markersModel; if (markersModel.hasFilteredResources()) { + this.messageBoxContainer.style.display = 'none'; const { total, filtered } = markersModel.stats(); if (filtered === total) { this.ariaLabelElement.setAttribute('aria-label', localize('No problems filtered', "Showing {0} problems", total)); @@ -315,6 +318,7 @@ export class MarkersPanel extends Panel { } this.messageBoxContainer.removeAttribute('tabIndex'); } else { + this.messageBoxContainer.style.display = 'block'; this.messageBoxContainer.setAttribute('tabIndex', '0'); if (markersModel.hasResources()) { if (markersModel.filterOptions.filter) { @@ -334,7 +338,13 @@ export class MarkersPanel extends Panel { const link = dom.append(container, dom.$('a.messageAction')); link.textContent = localize('disableFilesExclude', "Disable Files Exclude Filter."); link.setAttribute('tabIndex', '0'); - dom.addDisposableListener(link, dom.EventType.CLICK, () => this.filterInputActionItem.useFilesExclude = false); + dom.addStandardDisposableListener(link, dom.EventType.CLICK, () => this.filterInputActionItem.useFilesExclude = false); + dom.addStandardDisposableListener(link, dom.EventType.KEY_DOWN, (e: IKeyboardEvent) => { + if (e.equals(KeyCode.Enter) || e.equals(KeyCode.Space)) { + this.filterInputActionItem.useFilesExclude = false; + e.stopPropagation(); + } + }); this.ariaLabelElement.setAttribute('aria-label', Messages.MARKERS_PANEL_NO_PROBLEMS_FILE_EXCLUSIONS_FILTER); } @@ -344,7 +354,13 @@ export class MarkersPanel extends Panel { const link = dom.append(container, dom.$('a.messageAction')); link.textContent = localize('clearFilter', "Clear Filter."); link.setAttribute('tabIndex', '0'); - dom.addDisposableListener(link, dom.EventType.CLICK, () => this.filterInputActionItem.clear()); + dom.addStandardDisposableListener(link, dom.EventType.CLICK, () => this.filterInputActionItem.clear()); + dom.addStandardDisposableListener(link, dom.EventType.KEY_DOWN, (e: IKeyboardEvent) => { + if (e.equals(KeyCode.Enter) || e.equals(KeyCode.Space)) { + this.filterInputActionItem.clear(); + e.stopPropagation(); + } + }); this.ariaLabelElement.setAttribute('aria-label', Messages.MARKERS_PANEL_NO_PROBLEMS_FILTERS); } diff --git a/src/vs/workbench/parts/markers/electron-browser/media/markers.css b/src/vs/workbench/parts/markers/electron-browser/media/markers.css index 373b5718b2e..635af71f10c 100644 --- a/src/vs/workbench/parts/markers/electron-browser/media/markers.css +++ b/src/vs/workbench/parts/markers/electron-browser/media/markers.css @@ -72,6 +72,7 @@ .markers-panel .markers-panel-container .message-box-container { line-height: 22px; padding-left: 20px; + height: 100%; } .markers-panel .markers-panel-container .message-box-container .messageAction { From 0425b36c5da331e2114151fd58557d0705b1800f Mon Sep 17 00:00:00 2001 From: Johannes Rieken Date: Mon, 13 Aug 2018 18:23:46 +0200 Subject: [PATCH 0759/1276] patch and save source maps so that they get uploaded --- build/lib/extensions.js | 24 +++++++++++++++--------- build/lib/extensions.ts | 29 +++++++++++++++++++---------- 2 files changed, 34 insertions(+), 19 deletions(-) diff --git a/build/lib/extensions.js b/build/lib/extensions.js index 9bb5da1e39c..75a10259d55 100644 --- a/build/lib/extensions.js +++ b/build/lib/extensions.js @@ -16,12 +16,10 @@ var buffer = require('gulp-buffer'); var json = require('gulp-json-editor'); var webpack = require('webpack'); var webpackGulp = require('webpack-stream'); -var sourcemaps = require("gulp-sourcemaps"); var fs = require("fs"); var path = require("path"); var vsce = require("vsce"); var File = require("vinyl"); -var util_1 = require("./util"); function fromLocal(extensionPath, sourceMappingURLBase) { var result = es.through(); vsce.listFiles({ cwd: extensionPath, packageManager: vsce.PackageManager.Yarn }).then(function (fileNames) { @@ -55,13 +53,21 @@ function fromLocal(extensionPath, sourceMappingURLBase) { data.base = extensionPath; this.emit('data', data); })) - .pipe(sourcemaps.init()) - .pipe(Boolean(sourceMappingURLBase) ? util_1.stripSourceMappingURL() : es.through()) - .pipe(sourcemaps.write('.', { - sourceMappingURLPrefix: sourceMappingURLBase && sourceMappingURLBase + "/dist", - addComment: !!sourceMappingURLBase, - includeContent: !!sourceMappingURLBase, - sourceRoot: '../src', + .pipe(es.through(function (data) { + // source map handling: + // * rewrite sourceMappingURL + // * save to disk so that upload-task picks this up + if (sourceMappingURLBase && /\.js\.map$/.test(data.path)) { + var contents = data.contents.toString('utf8'); + data.contents = Buffer.from(contents.replace(/\n\/\/# sourceMappingURL=(.*)$/gm, function (_m, g1) { + return sourceMappingURLBase + "/extensions/" + path.basename(extensionPath) + "/out/" + g1; + }), 'utf8'); + if (!fs.existsSync(path.dirname(data.path))) { + fs.mkdirSync(path.dirname(data.path)); + } + fs.writeFileSync(data.path, data.contents); + } + this.emit('data', data); })); es.merge(webpackStream, patchFilesStream) // .pipe(es.through(function (data) { diff --git a/build/lib/extensions.ts b/build/lib/extensions.ts index 4e8045ac336..ecd725f1561 100644 --- a/build/lib/extensions.ts +++ b/build/lib/extensions.ts @@ -16,12 +16,10 @@ const buffer = require('gulp-buffer'); const json = require('gulp-json-editor'); const webpack = require('webpack'); const webpackGulp = require('webpack-stream'); -import * as sourcemaps from 'gulp-sourcemaps'; import * as fs from 'fs'; import * as path from 'path'; import * as vsce from 'vsce'; import * as File from 'vinyl'; -import { stripSourceMappingURL } from './util'; export function fromLocal(extensionPath: string, sourceMappingURLBase?: string): Stream { let result = es.through(); @@ -61,14 +59,25 @@ export function fromLocal(extensionPath: string, sourceMappingURLBase?: string): data.base = extensionPath; this.emit('data', data); })) - .pipe(sourcemaps.init()) - .pipe(Boolean(sourceMappingURLBase) ? stripSourceMappingURL() : es.through()) - .pipe(sourcemaps.write('.', { - sourceMappingURLPrefix: sourceMappingURLBase && `${sourceMappingURLBase}/extensions/${path.basename(extensionPath)}/out`, - addComment: !!sourceMappingURLBase, - includeContent: !!sourceMappingURLBase, - sourceRoot: '../src', - })); + .pipe(es.through(function (data: File) { + // source map handling: + // * rewrite sourceMappingURL + // * save to disk so that upload-task picks this up + if (sourceMappingURLBase && /\.js\.map$/.test(data.path)) { + const contents = (data.contents).toString('utf8'); + data.contents = Buffer.from(contents.replace(/\n\/\/# sourceMappingURL=(.*)$/gm, function (_m, g1) { + return `${sourceMappingURLBase}/extensions/${path.basename(extensionPath)}/out/${g1}`; + }), 'utf8'); + + if (!fs.existsSync(path.dirname(data.path))) { + fs.mkdirSync(path.dirname(data.path)); + } + fs.writeFileSync(data.path, data.contents); + + } + this.emit('data', data); + })) + ; es.merge(webpackStream, patchFilesStream) // .pipe(es.through(function (data) { From bb07163524976f766d76d158b1c1835cd92f5799 Mon Sep 17 00:00:00 2001 From: Johannes Rieken Date: Mon, 13 Aug 2018 18:52:12 +0200 Subject: [PATCH 0760/1276] more tweaks --- build/lib/extensions.js | 12 +++++++----- build/lib/extensions.ts | 12 +++++++----- 2 files changed, 14 insertions(+), 10 deletions(-) diff --git a/build/lib/extensions.js b/build/lib/extensions.js index 75a10259d55..0d373845b19 100644 --- a/build/lib/extensions.js +++ b/build/lib/extensions.js @@ -57,15 +57,17 @@ function fromLocal(extensionPath, sourceMappingURLBase) { // source map handling: // * rewrite sourceMappingURL // * save to disk so that upload-task picks this up - if (sourceMappingURLBase && /\.js\.map$/.test(data.path)) { + if (sourceMappingURLBase) { var contents = data.contents.toString('utf8'); data.contents = Buffer.from(contents.replace(/\n\/\/# sourceMappingURL=(.*)$/gm, function (_m, g1) { - return sourceMappingURLBase + "/extensions/" + path.basename(extensionPath) + "/out/" + g1; + return "\n//# sourceMappingURL=" + sourceMappingURLBase + "/extensions/" + path.basename(extensionPath) + "/out/" + g1; }), 'utf8'); - if (!fs.existsSync(path.dirname(data.path))) { - fs.mkdirSync(path.dirname(data.path)); + if (/\.js\.map$/.test(data.path)) { + if (!fs.existsSync(path.dirname(data.path))) { + fs.mkdirSync(path.dirname(data.path)); + } + fs.writeFileSync(data.path, data.contents); } - fs.writeFileSync(data.path, data.contents); } this.emit('data', data); })); diff --git a/build/lib/extensions.ts b/build/lib/extensions.ts index ecd725f1561..91de1774e4c 100644 --- a/build/lib/extensions.ts +++ b/build/lib/extensions.ts @@ -63,16 +63,18 @@ export function fromLocal(extensionPath: string, sourceMappingURLBase?: string): // source map handling: // * rewrite sourceMappingURL // * save to disk so that upload-task picks this up - if (sourceMappingURLBase && /\.js\.map$/.test(data.path)) { + if (sourceMappingURLBase) { const contents = (data.contents).toString('utf8'); data.contents = Buffer.from(contents.replace(/\n\/\/# sourceMappingURL=(.*)$/gm, function (_m, g1) { - return `${sourceMappingURLBase}/extensions/${path.basename(extensionPath)}/out/${g1}`; + return `\n//# sourceMappingURL=${sourceMappingURLBase}/extensions/${path.basename(extensionPath)}/out/${g1}`; }), 'utf8'); - if (!fs.existsSync(path.dirname(data.path))) { - fs.mkdirSync(path.dirname(data.path)); + if (/\.js\.map$/.test(data.path)) { + if (!fs.existsSync(path.dirname(data.path))) { + fs.mkdirSync(path.dirname(data.path)); + } + fs.writeFileSync(data.path, data.contents); } - fs.writeFileSync(data.path, data.contents); } this.emit('data', data); From 5e5f6fc6ec785a602f1444500264f18d136b5e87 Mon Sep 17 00:00:00 2001 From: Ramya Rao Date: Mon, 13 Aug 2018 10:04:40 -0700 Subject: [PATCH 0761/1276] Show recommended with popular when no extensions installed (#56186) * Show recommended with popular when no extensions installed * Ensure empty value results in popular extensions --- .../electron-browser/extensionsViewlet.ts | 45 ++++++++-------- .../electron-browser/extensionsViews.ts | 52 ++++++------------- 2 files changed, 37 insertions(+), 60 deletions(-) diff --git a/src/vs/workbench/parts/extensions/electron-browser/extensionsViewlet.ts b/src/vs/workbench/parts/extensions/electron-browser/extensionsViewlet.ts index 2ba10ccbf6e..76efff9131a 100644 --- a/src/vs/workbench/parts/extensions/electron-browser/extensionsViewlet.ts +++ b/src/vs/workbench/parts/extensions/electron-browser/extensionsViewlet.ts @@ -29,7 +29,7 @@ import { } from 'vs/workbench/parts/extensions/electron-browser/extensionsActions'; import { LocalExtensionType, IExtensionManagementService, IExtensionManagementServerService, IExtensionManagementServer } from 'vs/platform/extensionManagement/common/extensionManagement'; import { ExtensionsInput } from 'vs/workbench/parts/extensions/common/extensionsInput'; -import { ExtensionsListView, InstalledExtensionsView, EnabledExtensionsView, DisabledExtensionsView, RecommendedExtensionsView, WorkspaceRecommendedExtensionsView, BuiltInExtensionsView, BuiltInThemesExtensionsView, BuiltInBasicsExtensionsView, GroupByServerExtensionsView, DefaultRecommendedExtensionsView } from './extensionsViews'; +import { ExtensionsListView, EnabledExtensionsView, DisabledExtensionsView, RecommendedExtensionsView, WorkspaceRecommendedExtensionsView, BuiltInExtensionsView, BuiltInThemesExtensionsView, BuiltInBasicsExtensionsView, GroupByServerExtensionsView, DefaultRecommendedExtensionsView } from './extensionsViews'; import { OpenGlobalSettingsAction } from 'vs/workbench/parts/preferences/browser/preferencesActions'; import { IProgressService } from 'vs/platform/progress/common/progress'; import { IEditorGroupsService } from 'vs/workbench/services/group/common/editorGroupsService'; @@ -64,7 +64,7 @@ interface SearchInputEvent extends Event { const NonEmptyWorkspaceContext = new RawContextKey('nonEmptyWorkspace', false); const SearchExtensionsContext = new RawContextKey('searchExtensions', false); -const SearchInstalledExtensionsContext = new RawContextKey('searchInstalledExtensions', false); +const HasInstalledExtensionsContext = new RawContextKey('hasInstalledExtensions', true); const SearchBuiltInExtensionsContext = new RawContextKey('searchBuiltInExtensions', false); const RecommendedExtensionsContext = new RawContextKey('recommendedExtensions', false); const DefaultRecommendedExtensionsContext = new RawContextKey('defaultRecommendedExtensions', false); @@ -83,7 +83,7 @@ export class ExtensionsViewletViewsContribution implements IWorkbenchContributio viewDescriptors.push(this.createMarketPlaceExtensionsListViewDescriptor()); viewDescriptors.push(this.createEnabledExtensionsListViewDescriptor()); viewDescriptors.push(this.createDisabledExtensionsListViewDescriptor()); - viewDescriptors.push(this.createSearchInstalledExtensionsListViewDescriptor()); + viewDescriptors.push(this.createPopularExtensionsListViewDescriptor()); viewDescriptors.push(this.createBuiltInExtensionsListViewDescriptor()); viewDescriptors.push(this.createBuiltInBasicsExtensionsListViewDescriptor()); viewDescriptors.push(this.createBuiltInThemesExtensionsListViewDescriptor()); @@ -117,7 +117,7 @@ export class ExtensionsViewletViewsContribution implements IWorkbenchContributio name: localize('enabledExtensions', "Enabled"), container: VIEW_CONTAINER, ctor: EnabledExtensionsView, - when: ContextKeyExpr.not('searchExtensions'), + when: ContextKeyExpr.and(ContextKeyExpr.not('searchExtensions'), ContextKeyExpr.has('hasInstalledExtensions')), weight: 40, canToggleVisibility: true, order: 1 @@ -130,7 +130,7 @@ export class ExtensionsViewletViewsContribution implements IWorkbenchContributio name: localize('disabledExtensions', "Disabled"), container: VIEW_CONTAINER, ctor: DisabledExtensionsView, - when: ContextKeyExpr.not('searchExtensions'), + when: ContextKeyExpr.and(ContextKeyExpr.not('searchExtensions'), ContextKeyExpr.has('hasInstalledExtensions')), weight: 10, canToggleVisibility: true, order: 3, @@ -138,14 +138,15 @@ export class ExtensionsViewletViewsContribution implements IWorkbenchContributio }; } - private createSearchInstalledExtensionsListViewDescriptor(): IViewDescriptor { + private createPopularExtensionsListViewDescriptor(): IViewDescriptor { return { - id: 'extensions.searchInstalledList', - name: localize('searchInstalledExtensions', "Installed"), + id: 'extensions.popularExtensionsList', + name: localize('popularExtensions', "Popular"), container: VIEW_CONTAINER, - ctor: InstalledExtensionsView, - when: ContextKeyExpr.and(ContextKeyExpr.has('searchInstalledExtensions'), ContextKeyExpr.not('groupByServersContext')), - weight: 100 + ctor: ExtensionsListView, + when: ContextKeyExpr.and(ContextKeyExpr.not('searchExtensions'), ContextKeyExpr.not('hasInstalledExtensions')), + weight: 60, + order: 1 }; } @@ -167,7 +168,7 @@ export class ExtensionsViewletViewsContribution implements IWorkbenchContributio container: VIEW_CONTAINER, ctor: DefaultRecommendedExtensionsView, when: ContextKeyExpr.and(ContextKeyExpr.not('searchExtensions'), ContextKeyExpr.has('defaultRecommendedExtensions')), - weight: 60, + weight: 40, order: 2, canToggleVisibility: true }; @@ -241,7 +242,7 @@ export class ExtensionsViewlet extends ViewContainerViewlet implements IExtensio private onSearchChange: EventOf; private nonEmptyWorkspaceContextKey: IContextKey; private searchExtensionsContextKey: IContextKey; - private searchInstalledExtensionsContextKey: IContextKey; + private hasInstalledExtensionsContextKey: IContextKey; private searchBuiltInExtensionsContextKey: IContextKey; private groupByServersContextKey: IContextKey; private recommendedExtensionsContextKey: IContextKey; @@ -280,7 +281,7 @@ export class ExtensionsViewlet extends ViewContainerViewlet implements IExtensio this.searchDelayer = new ThrottledDelayer(500); this.nonEmptyWorkspaceContextKey = NonEmptyWorkspaceContext.bindTo(contextKeyService); this.searchExtensionsContextKey = SearchExtensionsContext.bindTo(contextKeyService); - this.searchInstalledExtensionsContextKey = SearchInstalledExtensionsContext.bindTo(contextKeyService); + this.hasInstalledExtensionsContextKey = HasInstalledExtensionsContext.bindTo(contextKeyService); this.searchBuiltInExtensionsContextKey = SearchBuiltInExtensionsContext.bindTo(contextKeyService); this.recommendedExtensionsContextKey = RecommendedExtensionsContext.bindTo(contextKeyService); this.groupByServersContextKey = GroupByServersContext.bindTo(contextKeyService); @@ -288,6 +289,10 @@ export class ExtensionsViewlet extends ViewContainerViewlet implements IExtensio this.defaultRecommendedExtensionsContextKey.set(!this.configurationService.getValue(ShowRecommendationsOnlyOnDemandKey)); this.disposables.push(this.viewletService.onDidViewletOpen(this.onViewletOpen, this, this.disposables)); + this.extensionManagementService.getInstalled(LocalExtensionType.User).then(result => { + this.hasInstalledExtensionsContextKey.set(result.length > 0); + }); + this.configurationService.onDidChangeConfiguration(e => { if (e.affectsConfiguration(AutoUpdateConfigurationKey)) { this.secondaryActions = null; @@ -330,14 +335,7 @@ export class ExtensionsViewlet extends ViewContainerViewlet implements IExtensio this.searchBox.onShouldFocusResults(() => this.focusListView(), this, this.disposables); this.extensionsBox = append(this.root, $('.extensions')); - return super.create(this.extensionsBox) - .then(() => this.extensionManagementService.getInstalled(LocalExtensionType.User)) - .then(installed => { - if (installed.length === 0) { - this.searchBox.setValue('@sort:installs'); - this.searchExtensionsContextKey.set(true); - } - }); + return super.create(this.extensionsBox); } public updateStyles(): void { @@ -385,7 +383,7 @@ export class ExtensionsViewlet extends ViewContainerViewlet implements IExtensio if (!this.groupByServerAction) { this.groupByServerAction = this.instantiationService.createInstance(ChangeGroupAction, 'extensions.group.servers', localize('group by servers', "Group By: Server"), this.onSearchChange, 'server'); this.disposables.push(this.onSearchChange(value => { - this.groupByServerAction.enabled = !value || InstalledExtensionsView.isInstalledExtensionsQuery(value) || ExtensionsListView.isBuiltInExtensionsQuery(value); + this.groupByServerAction.enabled = !value || ExtensionsListView.isInstalledExtensionsQuery(value) || ExtensionsListView.isBuiltInExtensionsQuery(value); })); } this.secondaryActions = [ @@ -432,7 +430,6 @@ export class ExtensionsViewlet extends ViewContainerViewlet implements IExtensio private doSearch(): TPromise { const value = this.normalizedQuery(); this.searchExtensionsContextKey.set(!!value); - this.searchInstalledExtensionsContextKey.set(InstalledExtensionsView.isInstalledExtensionsQuery(value)); this.searchBuiltInExtensionsContextKey.set(ExtensionsListView.isBuiltInExtensionsQuery(value)); this.groupByServersContextKey.set(ExtensionsListView.isGroupByServersExtensionsQuery(value)); this.recommendedExtensionsContextKey.set(ExtensionsListView.isRecommendedExtensionsQuery(value)); diff --git a/src/vs/workbench/parts/extensions/electron-browser/extensionsViews.ts b/src/vs/workbench/parts/extensions/electron-browser/extensionsViews.ts index 9857be0c0cb..ab3c66b7802 100644 --- a/src/vs/workbench/parts/extensions/electron-browser/extensionsViews.ts +++ b/src/vs/workbench/parts/extensions/electron-browser/extensionsViews.ts @@ -165,6 +165,9 @@ export class ExtensionsListView extends ViewletPanel { case 'rating': options = assign(options, { sortBy: SortBy.WeightedRating }); break; case 'name': options = assign(options, { sortBy: SortBy.Title }); break; } + if (!value || !value.trim()) { + options.sortBy = SortBy.InstallCount; + } if (/@builtin/i.test(value)) { const showThemesOnly = /@builtin:themes/i.test(value); @@ -218,9 +221,9 @@ export class ExtensionsListView extends ViewletPanel { return new PagedModel(this.sortExtensions(result, options)); } - if (!value || ExtensionsListView.isInstalledExtensionsQuery(value)) { + if (/@installed/i.test(value)) { // Show installed extensions - value = value ? value.replace(/@installed/g, '').replace(/@sort:(\w+)(-\w*)?/g, '').trim().toLowerCase() : ''; + value = value.replace(/@installed/g, '').replace(/@sort:(\w+)(-\w*)?/g, '').trim().toLowerCase(); let result = await this.extensionsWorkbenchService.queryLocal(); @@ -623,25 +626,13 @@ export class ExtensionsListView extends ViewletPanel { } static isInstalledExtensionsQuery(query: string): boolean { - return /@installed/i.test(query); + return /@installed|@outdated|@enabled|@disabled/i.test(query); } static isGroupByServersExtensionsQuery(query: string): boolean { return !!Query.parse(query).groupBy; } - static isOutdatedExtensionsQuery(query: string): boolean { - return /@outdated/i.test(query); - } - - static isDisabledExtensionsQuery(query: string): boolean { - return /@disabled/i.test(query); - } - - static isEnabledExtensionsQuery(query: string): boolean { - return /@enabled/i.test(query); - } - static isRecommendedExtensionsQuery(query: string): boolean { return /^@recommended$/i.test(query.trim()); } @@ -667,31 +658,12 @@ export class ExtensionsListView extends ViewletPanel { } } -export class InstalledExtensionsView extends ExtensionsListView { - - public static isInstalledExtensionsQuery(query: string): boolean { - return ExtensionsListView.isInstalledExtensionsQuery(query) - || ExtensionsListView.isOutdatedExtensionsQuery(query) - || ExtensionsListView.isDisabledExtensionsQuery(query) - || ExtensionsListView.isEnabledExtensionsQuery(query); - } - - async show(query: string): Promise> { - if (InstalledExtensionsView.isInstalledExtensionsQuery(query)) { - return super.show(query); - } - let searchInstalledQuery = '@installed'; - searchInstalledQuery = query ? searchInstalledQuery + ' ' + query : searchInstalledQuery; - return super.show(searchInstalledQuery); - } -} - export class GroupByServerExtensionsView extends ExtensionsListView { async show(query: string): Promise> { query = query.replace(/@group:server/g, '').trim(); query = query ? query : '@installed'; - if (!InstalledExtensionsView.isInstalledExtensionsQuery(query) && !ExtensionsListView.isBuiltInExtensionsQuery(query)) { + if (!ExtensionsListView.isInstalledExtensionsQuery(query) && !ExtensionsListView.isBuiltInExtensionsQuery(query)) { query = query += ' @installed'; } return super.show(query.trim()); @@ -744,7 +716,15 @@ export class DefaultRecommendedExtensionsView extends ExtensionsListView { } async show(query: string): Promise> { - return (query && query.trim() !== this.recommendedExtensionsQuery) ? this.showEmptyModel() : super.show(this.recommendedExtensionsQuery); + if (query && query.trim() !== this.recommendedExtensionsQuery) { + return this.showEmptyModel(); + } + const model = await super.show(this.recommendedExtensionsQuery); + if (!this.extensionsWorkbenchService.local.some(e => e.type === LocalExtensionType.User)) { + // This is part of popular extensions view. Collapse if no installed extensions. + this.setExpanded(model.length > 0); + } + return model; } } From 0269916bea49569488e37ca80d08e610a212cc57 Mon Sep 17 00:00:00 2001 From: Jackson Kearl Date: Mon, 13 Aug 2018 10:37:43 -0700 Subject: [PATCH 0762/1276] Fix missing or incorrect valueType on some nullables --- src/vs/workbench/parts/preferences/browser/settingsTree.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/vs/workbench/parts/preferences/browser/settingsTree.ts b/src/vs/workbench/parts/preferences/browser/settingsTree.ts index 1c19b80ba0f..67ee915b513 100644 --- a/src/vs/workbench/parts/preferences/browser/settingsTree.ts +++ b/src/vs/workbench/parts/preferences/browser/settingsTree.ts @@ -247,10 +247,12 @@ function createSettingsTreeSettingElement(setting: ISetting, parent: SearchResul } else if (setting.type === 'boolean') { element.valueType = 'boolean'; } else if (isArray(setting.type) && setting.type.indexOf('null') > -1 && setting.type.length === 2) { - if (setting.type.indexOf('number') > -1) { + if (setting.type.indexOf('integer') > -1) { element.valueType = 'nullable-integer'; } else if (setting.type.indexOf('number') > -1) { element.valueType = 'nullable-number'; + } else { + element.valueType = 'complex'; } } else { element.valueType = 'complex'; From 0ecd8daad2fed874b04697394435ad58590527bd Mon Sep 17 00:00:00 2001 From: Jackson Kearl Date: Mon, 13 Aug 2018 10:58:18 -0700 Subject: [PATCH 0763/1276] Render description after deprecation message. Also spelling --- .../preferences/common/preferencesModels.ts | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/vs/workbench/services/preferences/common/preferencesModels.ts b/src/vs/workbench/services/preferences/common/preferencesModels.ts index b31f83b2a92..8923e842a25 100644 --- a/src/vs/workbench/services/preferences/common/preferencesModels.ts +++ b/src/vs/workbench/services/preferences/common/preferencesModels.ts @@ -889,16 +889,16 @@ class SettingsContentBuilder { this.pushSettingDescription(setting, indent); - let preValueConent = indent; + let preValueContent = indent; const keyString = JSON.stringify(setting.key); - preValueConent += keyString; - setting.keyRange = { startLineNumber: this.lineCountWithOffset + 1, startColumn: preValueConent.indexOf(setting.key) + 1, endLineNumber: this.lineCountWithOffset + 1, endColumn: setting.key.length }; + preValueContent += keyString; + setting.keyRange = { startLineNumber: this.lineCountWithOffset + 1, startColumn: preValueContent.indexOf(setting.key) + 1, endLineNumber: this.lineCountWithOffset + 1, endColumn: setting.key.length }; - preValueConent += ': '; + preValueContent += ': '; const valueStart = this.lineCountWithOffset + 1; - this.pushValue(setting, preValueConent, indent); + this.pushValue(setting, preValueContent, indent); - setting.valueRange = { startLineNumber: valueStart, startColumn: preValueConent.length + 1, endLineNumber: this.lineCountWithOffset, endColumn: this.lastLine.length + 1 }; + setting.valueRange = { startLineNumber: valueStart, startColumn: preValueContent.length + 1, endLineNumber: this.lineCountWithOffset, endColumn: this.lastLine.length + 1 }; this._contentByLines[this._contentByLines.length - 1] += ','; this._contentByLines.push(''); setting.range = { startLineNumber: settingStart, startColumn: 1, endLineNumber: this.lineCountWithOffset, endColumn: this.lastLine.length }; @@ -909,7 +909,7 @@ class SettingsContentBuilder { setting.descriptionRanges = []; const descriptionPreValue = indent + '// '; - for (let line of (setting.deprecationMessage ? [setting.deprecationMessage] : setting.description)) { + for (let line of (setting.deprecationMessage ? [setting.deprecationMessage, ...setting.description] : setting.description)) { line = fixSettingLink(line); this._contentByLines.push(descriptionPreValue + line); From 01a50ac55fdd1c0016af6b7f48eca3a7a63dafba Mon Sep 17 00:00:00 2001 From: SteVen Batten Date: Mon, 13 Aug 2018 11:28:45 -0700 Subject: [PATCH 0764/1276] fixes #56185 --- src/vs/workbench/electron-browser/workbench.ts | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/vs/workbench/electron-browser/workbench.ts b/src/vs/workbench/electron-browser/workbench.ts index cb1958138b4..c8682932cd2 100644 --- a/src/vs/workbench/electron-browser/workbench.ts +++ b/src/vs/workbench/electron-browser/workbench.ts @@ -1435,10 +1435,12 @@ export class Workbench extends Disposable implements IPartService { } setMenubarVisibility(visibility: MenuBarVisibility, skipLayout: boolean): void { - this.menubarVisibility = visibility; + if (this.menubarVisibility !== visibility) { + this.menubarVisibility = visibility; - if (!skipLayout) { - this.workbenchLayout.layout(); + if (!skipLayout) { + this.workbenchLayout.layout(); + } } } From 0c97949dcd117c039211059e9d99fbf87cf91abe Mon Sep 17 00:00:00 2001 From: Peng Lyu Date: Mon, 13 Aug 2018 11:25:47 -0700 Subject: [PATCH 0765/1276] Fix Microsoft/vscode-pull-request-github#182. Remove all decorations when there is no comment avail. --- .../electron-browser/commentsEditorContribution.ts | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/vs/workbench/parts/comments/electron-browser/commentsEditorContribution.ts b/src/vs/workbench/parts/comments/electron-browser/commentsEditorContribution.ts index 65590c32c85..14deda0806e 100644 --- a/src/vs/workbench/parts/comments/electron-browser/commentsEditorContribution.ts +++ b/src/vs/workbench/parts/comments/electron-browser/commentsEditorContribution.ts @@ -64,6 +64,10 @@ export const overviewRulerCommentingRangeForeground = registerColor('editorGutte class CommentingRangeDecoration { private _decorationId: string; + get id(): string { + return this._decorationId; + } + constructor(private _editor: ICodeEditor, private _ownerId: number, private _range: IRange, private _reply: modes.Command, commentingOptions: ModelDecorationOptions) { const startLineNumber = _range.startLineNumber; const endLineNumber = _range.endLineNumber; @@ -133,6 +137,9 @@ class CommentingRangeDecorator { }); } + let oldDecorations = this.commentingRangeDecorations.map(decoration => decoration.id); + editor.deltaDecorations(oldDecorations, []); + this.commentingRangeDecorations = commentingRangeDecorations; } @@ -496,6 +503,8 @@ export class ReviewController implements IEditorContribution { zone.dispose(); }); + this._commentWidgets = []; + this._commentInfos.forEach(info => { info.threads.forEach(thread => { let zoneWidget = new ReviewZoneWidget(this.instantiationService, this.modeService, this.modelService, this.themeService, this.commentService, this.openerService, this.editor, info.owner, thread, {}); From 06139b43d4123b764166e1d619c7b3d4d2fbfad8 Mon Sep 17 00:00:00 2001 From: Johannes Rieken Date: Mon, 13 Aug 2018 20:40:22 +0200 Subject: [PATCH 0766/1276] leave upload path as /dist/ --- build/lib/extensions.js | 2 +- build/lib/extensions.ts | 3 +-- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/build/lib/extensions.js b/build/lib/extensions.js index 0d373845b19..51b5dd2a576 100644 --- a/build/lib/extensions.js +++ b/build/lib/extensions.js @@ -60,7 +60,7 @@ function fromLocal(extensionPath, sourceMappingURLBase) { if (sourceMappingURLBase) { var contents = data.contents.toString('utf8'); data.contents = Buffer.from(contents.replace(/\n\/\/# sourceMappingURL=(.*)$/gm, function (_m, g1) { - return "\n//# sourceMappingURL=" + sourceMappingURLBase + "/extensions/" + path.basename(extensionPath) + "/out/" + g1; + return "\n//# sourceMappingURL=" + sourceMappingURLBase + "/extensions/" + path.basename(extensionPath) + "/dist/" + g1; }), 'utf8'); if (/\.js\.map$/.test(data.path)) { if (!fs.existsSync(path.dirname(data.path))) { diff --git a/build/lib/extensions.ts b/build/lib/extensions.ts index 91de1774e4c..206572f23ff 100644 --- a/build/lib/extensions.ts +++ b/build/lib/extensions.ts @@ -66,7 +66,7 @@ export function fromLocal(extensionPath: string, sourceMappingURLBase?: string): if (sourceMappingURLBase) { const contents = (data.contents).toString('utf8'); data.contents = Buffer.from(contents.replace(/\n\/\/# sourceMappingURL=(.*)$/gm, function (_m, g1) { - return `\n//# sourceMappingURL=${sourceMappingURLBase}/extensions/${path.basename(extensionPath)}/out/${g1}`; + return `\n//# sourceMappingURL=${sourceMappingURLBase}/extensions/${path.basename(extensionPath)}/dist/${g1}`; }), 'utf8'); if (/\.js\.map$/.test(data.path)) { @@ -75,7 +75,6 @@ export function fromLocal(extensionPath: string, sourceMappingURLBase?: string): } fs.writeFileSync(data.path, data.contents); } - } this.emit('data', data); })) From 127700628a34daea02b92f4cb79476cc4e168434 Mon Sep 17 00:00:00 2001 From: Peng Lyu Date: Mon, 13 Aug 2018 12:00:46 -0700 Subject: [PATCH 0767/1276] Fix Microsoft/vscode-pull-request-github#180. Render whitespace for code blocks in comments --- .../parts/comments/electron-browser/media/review.css | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/vs/workbench/parts/comments/electron-browser/media/review.css b/src/vs/workbench/parts/comments/electron-browser/media/review.css index cb249b33a09..853f55ca531 100644 --- a/src/vs/workbench/parts/comments/electron-browser/media/review.css +++ b/src/vs/workbench/parts/comments/electron-browser/media/review.css @@ -117,6 +117,10 @@ padding: 0 0.4em; } +.monaco-editor .review-widget .body span { + white-space: pre; +} + .monaco-editor .review-widget .body .comment-body img { max-width: 100%; } From a4c0c434b6d3c8aecdeccdaae0aaede6b9650783 Mon Sep 17 00:00:00 2001 From: kieferrm Date: Mon, 13 Aug 2018 13:38:23 -0700 Subject: [PATCH 0768/1276] update calendar --- .github/calendar.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/calendar.yml b/.github/calendar.yml index 6d3e0f593d7..a37969648ad 100644 --- a/.github/calendar.yml +++ b/.github/calendar.yml @@ -25,5 +25,5 @@ '2018-06-25 18:00, US/Pacific': 'endgame', '2018-07-05 12:00, US/Pacific': 'development', # 1.25.0 released '2018-07-30 18:00, US/Pacific': 'endgame', - # '2018-08-08 12:00, US/Pacific': 'development', # 1.26.0 released + '2018-08-13 12:00, US/Pacific': 'development' # 1.26.0 released } From dbbbafc204c7e807bef9724e9dcf8e33b2ddcf98 Mon Sep 17 00:00:00 2001 From: SteVen Batten <6561887+sbatten@users.noreply.github.com> Date: Mon, 13 Aug 2018 14:43:51 -0700 Subject: [PATCH 0769/1276] Sbatten/check menu items (#56179) * fixes #52929 * add high contrast default * fix theming for selected item --- src/vs/base/browser/ui/menu/check.svg | 1 + src/vs/base/browser/ui/menu/menu.css | 18 ++++++++++++++++-- src/vs/base/browser/ui/menu/menu.ts | 6 ++++-- .../browser/parts/titlebar/menubarControl.ts | 8 ++++++++ .../workbench/electron-browser/media/shell.css | 7 ++++++- 5 files changed, 35 insertions(+), 5 deletions(-) create mode 100644 src/vs/base/browser/ui/menu/check.svg diff --git a/src/vs/base/browser/ui/menu/check.svg b/src/vs/base/browser/ui/menu/check.svg new file mode 100644 index 00000000000..3f365c4800e --- /dev/null +++ b/src/vs/base/browser/ui/menu/check.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/vs/base/browser/ui/menu/menu.css b/src/vs/base/browser/ui/menu/menu.css index 4f0c0152caa..bea8dd19777 100644 --- a/src/vs/base/browser/ui/menu/menu.css +++ b/src/vs/base/browser/ui/menu/menu.css @@ -97,8 +97,18 @@ color: inherit; } -.monaco-menu .monaco-action-bar.vertical .action-label.checked:after { - content: ' \2713'; +.monaco-menu .monaco-action-bar.vertical .menu-item-check { + position: absolute; + visibility: hidden; + background-color: #646465; + -webkit-mask: url('check.svg') no-repeat 50% 56%/15px 15px; + mask: url('check.svg') no-repeat 50% 56%/15px 15px; + width: 1em; + height: 100%; +} + +.monaco-menu .monaco-action-bar.vertical .action-menu-item.checked .menu-item-check { + visibility: visible; } /* Context Menu */ @@ -149,4 +159,8 @@ .hc-black .monaco-menu .monaco-action-bar.vertical .action-item.focused { background: none; border: 1px dotted #f38518; +} + +.hc-black .monaco-menu .monaco-action-bar.vertical .menu-item-check { + background-color: white; } \ No newline at end of file diff --git a/src/vs/base/browser/ui/menu/menu.ts b/src/vs/base/browser/ui/menu/menu.ts index 3a79019d4f1..4c94cfabb47 100644 --- a/src/vs/base/browser/ui/menu/menu.ts +++ b/src/vs/base/browser/ui/menu/menu.ts @@ -117,6 +117,7 @@ class MenuActionItem extends BaseActionItem { protected $e: Builder; protected $label: Builder; + protected $check: Builder; protected options: IActionItemOptions; private cssClass: string; @@ -141,6 +142,7 @@ class MenuActionItem extends BaseActionItem { this.$e.attr({ role: 'menuitem' }); } + this.$check = $('span.menu-item-check').appendTo(this.$e); this.$label = $('span.action-label').appendTo(this.$e); if (this.options.label && this.options.keybinding) { @@ -231,9 +233,9 @@ class MenuActionItem extends BaseActionItem { public _updateChecked(): void { if (this.getAction().checked) { - this.$label.addClass('checked'); + this.$e.addClass('checked'); } else { - this.$label.removeClass('checked'); + this.$e.removeClass('checked'); } } } diff --git a/src/vs/workbench/browser/parts/titlebar/menubarControl.ts b/src/vs/workbench/browser/parts/titlebar/menubarControl.ts index 304663e4a11..30c0ef9630a 100644 --- a/src/vs/workbench/browser/parts/titlebar/menubarControl.ts +++ b/src/vs/workbench/browser/parts/titlebar/menubarControl.ts @@ -1119,6 +1119,10 @@ registerThemingParticipant((theme: ITheme, collector: ICssStyleCollector) => { .monaco-shell .monaco-menu .monaco-action-bar.vertical .action-item { color: ${menuFgColor}; } + + .monaco-shell .monaco-menu .monaco-action-bar.vertical .action-item .action-menu-item .menu-item-check { + background-color: ${menuFgColor}; + } `); } @@ -1137,6 +1141,10 @@ registerThemingParticipant((theme: ITheme, collector: ICssStyleCollector) => { .monaco-shell .monaco-menu .monaco-action-bar.vertical .action-item.focused { color: ${selectedMenuItemFgColor}; } + + .monaco-shell .monaco-menu .monaco-action-bar.vertical .action-item.focused .action-menu-item .menu-item-check { + background-color: ${selectedMenuItemFgColor}; + } `); } diff --git a/src/vs/workbench/electron-browser/media/shell.css b/src/vs/workbench/electron-browser/media/shell.css index 05267d25b87..1ce2598e143 100644 --- a/src/vs/workbench/electron-browser/media/shell.css +++ b/src/vs/workbench/electron-browser/media/shell.css @@ -81,7 +81,12 @@ .monaco-shell .monaco-menu .monaco-action-bar.vertical .action-label:not(.separator), .monaco-shell .monaco-menu .monaco-action-bar.vertical .keybinding { font-size: inherit; - padding: 0 1.5em; + padding: 0 2em; +} + +.monaco-shell .monaco-menu .monaco-action-bar.vertical .menu-item-check { + font-size: inherit; + width: 2em; } .monaco-shell .monaco-menu .monaco-action-bar.vertical .action-label.separator { From 292fe45ae31666cc20b048a90123cf994d3c41d2 Mon Sep 17 00:00:00 2001 From: Rob Lourens Date: Mon, 13 Aug 2018 14:41:41 -0700 Subject: [PATCH 0770/1276] #55803 - update "modified" label without rendering the tree row --- .../preferences/browser/media/settingsEditor2.css | 5 +++++ .../parts/preferences/browser/settingsEditor2.ts | 15 +++++++++++++-- .../parts/preferences/browser/settingsTree.ts | 8 ++++++-- 3 files changed, 24 insertions(+), 4 deletions(-) diff --git a/src/vs/workbench/parts/preferences/browser/media/settingsEditor2.css b/src/vs/workbench/parts/preferences/browser/media/settingsEditor2.css index 1d3aff5f07d..f37498ef8cc 100644 --- a/src/vs/workbench/parts/preferences/browser/media/settingsEditor2.css +++ b/src/vs/workbench/parts/preferences/browser/media/settingsEditor2.css @@ -212,6 +212,11 @@ font-style: italic; opacity: 0.8; margin-right: 7px; + display: none; +} + +.settings-editor > .settings-body > .settings-tree-container .setting-item.is-configured .setting-item-title .setting-item-is-configured-label { + display: inline-block; } .settings-editor > .settings-body > .settings-tree-container .setting-item .setting-item-title .setting-item-overrides { diff --git a/src/vs/workbench/parts/preferences/browser/settingsEditor2.ts b/src/vs/workbench/parts/preferences/browser/settingsEditor2.ts index f3fa52ee562..64c5620fe37 100644 --- a/src/vs/workbench/parts/preferences/browser/settingsEditor2.ts +++ b/src/vs/workbench/parts/preferences/browser/settingsEditor2.ts @@ -111,7 +111,7 @@ export class SettingsEditor2 extends BaseEditor { this.viewState = { settingsTarget: ConfigurationTarget.USER }; this.delayRefreshOnLayout = new Delayer(100); - this.settingUpdateDelayer = new Delayer(500); + this.settingUpdateDelayer = new Delayer(200); this.inSettingsEditorContextKey = CONTEXT_SETTINGS_EDITOR.bindTo(contextKeyService); this.searchFocusContextKey = CONTEXT_SETTINGS_SEARCH_FOCUS.bindTo(contextKeyService); @@ -657,6 +657,7 @@ export class SettingsEditor2 extends BaseEditor { private renderTree(key?: string): TPromise { if (key && this.scheduledRefreshes.has(key)) { + this.updateModifiedLabelForKey(key); return TPromise.wrap(null); } @@ -666,6 +667,7 @@ export class SettingsEditor2 extends BaseEditor { if (key) { const focusedKey = this.settingsTreeRenderer.getSettingKeyForDOMElement(document.activeElement); if (focusedKey === key) { + this.updateModifiedLabelForKey(key); this.scheduleRefresh(document.activeElement, key); return TPromise.wrap(null); } @@ -684,11 +686,20 @@ export class SettingsEditor2 extends BaseEditor { } return refreshP.then(() => { - this.tocTreeModel.update(); // ? + this.tocTreeModel.update(); return this.tocTree.refresh(); }).then(() => { }); } + private updateModifiedLabelForKey(key: string): void { + const dataElements = this.getElementsByKey(key); + const isModified = dataElements && dataElements[0] && dataElements[0].isConfigured; // all elements are either configured or not + const elements = this.settingsTreeRenderer.getDOMElementsForSettingKey(this.settingsTree.getHTMLElement(), key); + if (elements && elements[0]) { + DOM.toggleClass(elements[0], 'is-configured', isModified); + } + } + private onSearchInputChanged(): void { const query = this.searchWidget.getValue().trim(); this.delayedFilterLogging.cancel(); diff --git a/src/vs/workbench/parts/preferences/browser/settingsTree.ts b/src/vs/workbench/parts/preferences/browser/settingsTree.ts index eefdbd0c13f..de9a6764f0e 100644 --- a/src/vs/workbench/parts/preferences/browser/settingsTree.ts +++ b/src/vs/workbench/parts/preferences/browser/settingsTree.ts @@ -438,6 +438,7 @@ export class SettingsRenderer implements ITreeRenderer { const categoryElement = DOM.append(titleElement, $('span.setting-item-category')); const labelElement = DOM.append(titleElement, $('span.setting-item-label')); const isConfiguredElement = DOM.append(titleElement, $('span.setting-item-is-configured-label')); + isConfiguredElement.textContent = localize('configured', "Modified"); const otherOverridesElement = DOM.append(titleElement, $('span.setting-item-overrides')); const descriptionElement = DOM.append(container, $('.setting-item-description')); @@ -544,6 +545,7 @@ export class SettingsRenderer implements ITreeRenderer { const categoryElement = DOM.append(titleElement, $('span.setting-item-category')); const labelElement = DOM.append(titleElement, $('span.setting-item-label')); const isConfiguredElement = DOM.append(titleElement, $('span.setting-item-is-configured-label')); + isConfiguredElement.textContent = localize('configured', "Modified"); const otherOverridesElement = DOM.append(titleElement, $('span.setting-item-overrides')); const descriptionAndValueElement = DOM.append(container, $('.setting-item-value-description')); @@ -765,6 +767,10 @@ export class SettingsRenderer implements ITreeRenderer { return null; } + public getDOMElementsForSettingKey(treeContainer: HTMLElement, key: string): NodeListOf { + return treeContainer.querySelectorAll(`[${SettingsRenderer.SETTING_KEY_ATTR}="${key}"]`); + } + private renderSettingElement(tree: ITree, element: SettingsTreeSettingElement, templateId: string, template: ISettingItemTemplate | ISettingBoolItemTemplate): void { template.context = element; @@ -790,8 +796,6 @@ export class SettingsRenderer implements ITreeRenderer { template.descriptionElement.innerText = element.description; } - template.isConfiguredElement.textContent = element.isConfigured ? localize('configured', "Modified") : ''; - if (element.overriddenScopeList.length) { let otherOverridesLabel = element.isConfigured ? localize('alsoConfiguredIn', "Also modified in") : From b5d75afdafc2dac78c156176ad969ac2b2f6c2bb Mon Sep 17 00:00:00 2001 From: Rob Lourens Date: Mon, 13 Aug 2018 15:00:42 -0700 Subject: [PATCH 0771/1276] #55803 - watch other focusable elements inside the setting row, (link) not just the control --- src/vs/base/browser/dom.ts | 2 +- .../parts/preferences/browser/settingsEditor2.ts | 9 +++++---- .../workbench/parts/preferences/browser/settingsTree.ts | 6 +++--- 3 files changed, 9 insertions(+), 8 deletions(-) diff --git a/src/vs/base/browser/dom.ts b/src/vs/base/browser/dom.ts index a5ca4033c5c..ef90d9e037e 100644 --- a/src/vs/base/browser/dom.ts +++ b/src/vs/base/browser/dom.ts @@ -920,7 +920,7 @@ class FocusTracker implements IFocusTracker { private disposables: IDisposable[] = []; constructor(element: HTMLElement | Window) { - let hasFocus = document.activeElement === element; + let hasFocus = isAncestor(document.activeElement, element); let loosingFocus = false; let onFocus = () => { diff --git a/src/vs/workbench/parts/preferences/browser/settingsEditor2.ts b/src/vs/workbench/parts/preferences/browser/settingsEditor2.ts index 64c5620fe37..4060c37f87c 100644 --- a/src/vs/workbench/parts/preferences/browser/settingsEditor2.ts +++ b/src/vs/workbench/parts/preferences/browser/settingsEditor2.ts @@ -662,17 +662,18 @@ export class SettingsEditor2 extends BaseEditor { } // If a setting control is currently focused, schedule a refresh for later - if (document.activeElement.classList.contains(SettingsRenderer.CONTROL_CLASS)) { + const focusedSetting = this.settingsTreeRenderer.getSettingDOMElementForDOMElement(document.activeElement); + if (focusedSetting) { // If a single setting is being refreshed, it's ok to refresh now if that is not the focused setting if (key) { - const focusedKey = this.settingsTreeRenderer.getSettingKeyForDOMElement(document.activeElement); + const focusedKey = focusedSetting.getAttribute(SettingsRenderer.SETTING_KEY_ATTR); if (focusedKey === key) { this.updateModifiedLabelForKey(key); - this.scheduleRefresh(document.activeElement, key); + this.scheduleRefresh(focusedSetting, key); return TPromise.wrap(null); } } else { - this.scheduleRefresh(document.activeElement); + this.scheduleRefresh(focusedSetting); return TPromise.wrap(null); } } diff --git a/src/vs/workbench/parts/preferences/browser/settingsTree.ts b/src/vs/workbench/parts/preferences/browser/settingsTree.ts index de9a6764f0e..f5816444c86 100644 --- a/src/vs/workbench/parts/preferences/browser/settingsTree.ts +++ b/src/vs/workbench/parts/preferences/browser/settingsTree.ts @@ -258,7 +258,7 @@ export class SettingsRenderer implements ITreeRenderer { public static readonly CONTROL_CLASS = 'setting-control-focus-target'; public static readonly CONTROL_SELECTOR = '.' + SettingsRenderer.CONTROL_CLASS; - private static readonly SETTING_KEY_ATTR = 'data-key'; + public static readonly SETTING_KEY_ATTR = 'data-key'; private readonly _onDidChangeSetting: Emitter = new Emitter(); public readonly onDidChangeSetting: Event = this._onDidChangeSetting.event; @@ -758,10 +758,10 @@ export class SettingsRenderer implements ITreeRenderer { template.context = element; } - public getSettingKeyForDOMElement(domElement: HTMLElement): string { + public getSettingDOMElementForDOMElement(domElement: HTMLElement): HTMLElement { const parent = DOM.findParentWithClass(domElement, 'setting-item'); if (parent) { - return parent.getAttribute(SettingsRenderer.SETTING_KEY_ATTR); + return parent; } return null; From 8d92a3494ec634296399cd31c80b79d73146f30b Mon Sep 17 00:00:00 2001 From: SteVen Batten Date: Mon, 13 Aug 2018 15:19:29 -0700 Subject: [PATCH 0772/1276] fixes #55921 --- src/vs/base/browser/ui/actionbar/actionbar.ts | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/vs/base/browser/ui/actionbar/actionbar.ts b/src/vs/base/browser/ui/actionbar/actionbar.ts index dd85d1c0645..6f480c13af0 100644 --- a/src/vs/base/browser/ui/actionbar/actionbar.ts +++ b/src/vs/base/browser/ui/actionbar/actionbar.ts @@ -154,11 +154,14 @@ export class BaseActionItem implements IActionItem { DOM.EventHelper.stop(event, true); let context: any; - if (types.isUndefinedOrNull(this._context) || !types.isObject(this._context)) { + if (types.isUndefinedOrNull(this._context)) { context = event; } else { context = this._context; - context.event = event; + + if (types.isObject(context)) { + context.event = event; + } } this._actionRunner.run(this._action, context); From 820d3dc15118a00805a94e268e038ec35c34955f Mon Sep 17 00:00:00 2001 From: Rob Lourens Date: Mon, 13 Aug 2018 15:58:34 -0700 Subject: [PATCH 0773/1276] Fix #55375 - add setting and commands to select preferred settings editor --- src/vs/code/electron-main/menus.ts | 2 +- .../electron-browser/main.contribution.ts | 11 ++++ .../preferences/browser/preferencesActions.ts | 56 +++++++++++++++---- .../preferences.contribution.ts | 5 +- 4 files changed, 60 insertions(+), 14 deletions(-) diff --git a/src/vs/code/electron-main/menus.ts b/src/vs/code/electron-main/menus.ts index 0c9b269d1e1..916bd309bcc 100644 --- a/src/vs/code/electron-main/menus.ts +++ b/src/vs/code/electron-main/menus.ts @@ -438,7 +438,7 @@ export class CodeMenu { } private getPreferencesMenu(): Electron.MenuItem { - const settings = this.createMenuItem(nls.localize({ key: 'miOpenSettings', comment: ['&& denotes a mnemonic'] }, "&&Settings"), 'workbench.action.openSettings2'); + const settings = this.createMenuItem(nls.localize({ key: 'miOpenSettings', comment: ['&& denotes a mnemonic'] }, "&&Settings"), 'workbench.action.openSettings'); const extensions = this.createMenuItem(nls.localize({ key: 'miOpenExtensions', comment: ['&& denotes a mnemonic'] }, '&&Extensions'), 'workbench.view.extensions'); const kebindingSettings = this.createMenuItem(nls.localize({ key: 'miOpenKeymap', comment: ['&& denotes a mnemonic'] }, "&&Keyboard Shortcuts"), 'workbench.action.openGlobalKeybindings'); const keymapExtensions = this.createMenuItem(nls.localize({ key: 'miOpenKeymapExtensions', comment: ['&& denotes a mnemonic'] }, "&&Keymap Extensions"), 'workbench.extensions.action.showRecommendedKeymapExtensions'); diff --git a/src/vs/workbench/electron-browser/main.contribution.ts b/src/vs/workbench/electron-browser/main.contribution.ts index 9ad1d55109f..150d1754371 100644 --- a/src/vs/workbench/electron-browser/main.contribution.ts +++ b/src/vs/workbench/electron-browser/main.contribution.ts @@ -644,6 +644,17 @@ configurationRegistry.registerConfiguration({ 'default': 'filter', 'scope': ConfigurationScope.WINDOW }, + 'workbench.settings.editor': { + 'type': 'string', + 'enum': ['ui', 'json'], + 'enumDescriptions': [ + nls.localize('settings.editor.json', "Use the JSON file editor."), + nls.localize('settings.editor.ui', "Use the settings UI editor."), + ], + 'description': nls.localize('settings.editor.desc', "Determines which settings editor to use by default."), + 'default': 'ui', + 'scope': ConfigurationScope.WINDOW + }, 'workbench.enableExperiments': { 'type': 'boolean', 'description': nls.localize('workbench.enableExperiments', "Fetches experiments to run from a Microsoft online service."), diff --git a/src/vs/workbench/parts/preferences/browser/preferencesActions.ts b/src/vs/workbench/parts/preferences/browser/preferencesActions.ts index 95acd99a978..60ec2e5e99d 100644 --- a/src/vs/workbench/parts/preferences/browser/preferencesActions.ts +++ b/src/vs/workbench/parts/preferences/browser/preferencesActions.ts @@ -17,6 +17,7 @@ import { PICK_WORKSPACE_FOLDER_COMMAND_ID } from 'vs/workbench/browser/actions/w import { IQuickInputService, IQuickPickItem } from 'vs/platform/quickinput/common/quickInput'; import { getIconClasses } from 'vs/workbench/browser/labels'; import { IModelService } from 'vs/editor/common/services/modelService'; +import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; export class OpenRawDefaultSettingsAction extends Action { @@ -39,7 +40,7 @@ export class OpenRawDefaultSettingsAction extends Action { export class OpenSettings2Action extends Action { public static readonly ID = 'workbench.action.openSettings2'; - public static readonly LABEL = nls.localize('openSettings2', "Open Settings (Preview)"); + public static readonly LABEL = nls.localize('openSettings2', "Open Settings (UI)"); constructor( id: string, @@ -60,6 +61,27 @@ export class OpenSettingsAction extends Action { public static readonly ID = 'workbench.action.openSettings'; public static readonly LABEL = nls.localize('openSettings', "Open Settings"); + constructor( + id: string, + label: string, + @IPreferencesService private preferencesService: IPreferencesService, + @IConfigurationService private configurationService: IConfigurationService, + ) { + super(id, label); + } + + public run(event?: any): TPromise { + return this.configurationService.getValue('workbench.settings.editor') === 'json' ? + this.preferencesService.openSettings() : + this.preferencesService.openSettings2(); + } +} + +export class OpenSettingsJsonAction extends Action { + + public static readonly ID = 'workbench.action.openSettingsJson'; + public static readonly LABEL = nls.localize('openSettingsJson', "Open Settings (JSON)"); + constructor( id: string, label: string, @@ -81,13 +103,16 @@ export class OpenGlobalSettingsAction extends Action { constructor( id: string, label: string, - @IPreferencesService private preferencesService: IPreferencesService + @IPreferencesService private preferencesService: IPreferencesService, + @IConfigurationService private configurationService: IConfigurationService ) { super(id, label); } public run(event?: any): TPromise { - return this.preferencesService.openGlobalSettings(); + return this.configurationService.getValue('workbench.settings.editor') === 'json' ? + this.preferencesService.openGlobalSettings() : + this.preferencesService.openSettings2(); } } @@ -156,6 +181,7 @@ export class OpenWorkspaceSettingsAction extends Action { id: string, label: string, @IPreferencesService private preferencesService: IPreferencesService, + @IConfigurationService private configurationService: IConfigurationService, @IWorkspaceContextService private workspaceContextService: IWorkspaceContextService ) { super(id, label); @@ -168,7 +194,9 @@ export class OpenWorkspaceSettingsAction extends Action { } public run(event?: any): TPromise { - return this.preferencesService.openWorkspaceSettings(); + return this.configurationService.getValue('workbench.settings.editor') === 'json' ? + this.preferencesService.openWorkspaceSettings() : + this.preferencesService.openSettings2(); } public dispose(): void { @@ -191,6 +219,8 @@ export class OpenFolderSettingsAction extends Action { id: string, label: string, @IWorkspaceContextService private workspaceContextService: IWorkspaceContextService, + @IConfigurationService private configurationService: IConfigurationService, + @IPreferencesService private preferencesService: IPreferencesService, @ICommandService private commandService: ICommandService ) { super(id, label); @@ -204,13 +234,17 @@ export class OpenFolderSettingsAction extends Action { } public run(): TPromise { - return this.commandService.executeCommand(PICK_WORKSPACE_FOLDER_COMMAND_ID) - .then(workspaceFolder => { - if (workspaceFolder) { - return this.commandService.executeCommand(OPEN_FOLDER_SETTINGS_COMMAND, workspaceFolder.uri); - } - return null; - }); + if (this.configurationService.getValue('workbench.settings.editor') === 'json') { + return this.commandService.executeCommand(PICK_WORKSPACE_FOLDER_COMMAND_ID) + .then(workspaceFolder => { + if (workspaceFolder) { + return this.commandService.executeCommand(OPEN_FOLDER_SETTINGS_COMMAND, workspaceFolder.uri); + } + return null; + }); + } else { + return this.preferencesService.openSettings2(); + } } public dispose(): void { diff --git a/src/vs/workbench/parts/preferences/electron-browser/preferences.contribution.ts b/src/vs/workbench/parts/preferences/electron-browser/preferences.contribution.ts index fcc7e381afe..37c60e73f60 100644 --- a/src/vs/workbench/parts/preferences/electron-browser/preferences.contribution.ts +++ b/src/vs/workbench/parts/preferences/electron-browser/preferences.contribution.ts @@ -19,7 +19,7 @@ import { PreferencesEditor } from 'vs/workbench/parts/preferences/browser/prefer import { SettingsEditor2 } from 'vs/workbench/parts/preferences/browser/settingsEditor2'; import { DefaultPreferencesEditorInput, PreferencesEditorInput, KeybindingsEditorInput, SettingsEditor2Input } from 'vs/workbench/services/preferences/common/preferencesEditorInput'; import { KeybindingsEditor } from 'vs/workbench/parts/preferences/browser/keybindingsEditor'; -import { OpenDefaultKeybindingsFileAction, OpenRawDefaultSettingsAction, OpenSettingsAction, OpenGlobalSettingsAction, OpenGlobalKeybindingsFileAction, OpenWorkspaceSettingsAction, OpenFolderSettingsAction, ConfigureLanguageBasedSettingsAction, OPEN_FOLDER_SETTINGS_COMMAND, OpenGlobalKeybindingsAction, OpenSettings2Action } from 'vs/workbench/parts/preferences/browser/preferencesActions'; +import { OpenDefaultKeybindingsFileAction, OpenRawDefaultSettingsAction, OpenSettingsAction, OpenGlobalSettingsAction, OpenGlobalKeybindingsFileAction, OpenWorkspaceSettingsAction, OpenFolderSettingsAction, ConfigureLanguageBasedSettingsAction, OPEN_FOLDER_SETTINGS_COMMAND, OpenGlobalKeybindingsAction, OpenSettings2Action, OpenSettingsJsonAction } from 'vs/workbench/parts/preferences/browser/preferencesActions'; import { IKeybindingsEditor, IPreferencesSearchService, CONTEXT_KEYBINDING_FOCUS, CONTEXT_KEYBINDINGS_EDITOR, CONTEXT_KEYBINDINGS_SEARCH_FOCUS, KEYBINDINGS_EDITOR_COMMAND_DEFINE, KEYBINDINGS_EDITOR_COMMAND_REMOVE, KEYBINDINGS_EDITOR_COMMAND_SEARCH, KEYBINDINGS_EDITOR_COMMAND_COPY, KEYBINDINGS_EDITOR_COMMAND_RESET, KEYBINDINGS_EDITOR_COMMAND_COPY_COMMAND, KEYBINDINGS_EDITOR_COMMAND_SHOW_SIMILAR, KEYBINDINGS_EDITOR_COMMAND_FOCUS_KEYBINDINGS, KEYBINDINGS_EDITOR_COMMAND_CLEAR_SEARCH_RESULTS, SETTINGS_EDITOR_COMMAND_SEARCH, CONTEXT_SETTINGS_EDITOR, SETTINGS_EDITOR_COMMAND_FOCUS_FILE, CONTEXT_SETTINGS_SEARCH_FOCUS, SETTINGS_EDITOR_COMMAND_CLEAR_SEARCH_RESULTS, SETTINGS_EDITOR_COMMAND_FOCUS_NEXT_SETTING, SETTINGS_EDITOR_COMMAND_FOCUS_PREVIOUS_SETTING, SETTINGS_EDITOR_COMMAND_EDIT_FOCUSED_SETTING, SETTINGS_EDITOR_COMMAND_FOCUS_SETTINGS_FROM_SEARCH, CONTEXT_TOC_ROW_FOCUS, SETTINGS_EDITOR_COMMAND_FOCUS_SETTINGS_LIST @@ -193,7 +193,8 @@ const category = nls.localize('preferences', "Preferences"); const registry = Registry.as(Extensions.WorkbenchActions); registry.registerWorkbenchAction(new SyncActionDescriptor(OpenRawDefaultSettingsAction, OpenRawDefaultSettingsAction.ID, OpenRawDefaultSettingsAction.LABEL), 'Preferences: Open Raw Default Settings', category); registry.registerWorkbenchAction(new SyncActionDescriptor(OpenSettingsAction, OpenSettingsAction.ID, OpenSettingsAction.LABEL, { primary: KeyMod.CtrlCmd | KeyCode.US_COMMA }), 'Preferences: Open Settings', category); -registry.registerWorkbenchAction(new SyncActionDescriptor(OpenSettings2Action, OpenSettings2Action.ID, OpenSettings2Action.LABEL), 'Preferences: Open Settings (Preview)', category); +registry.registerWorkbenchAction(new SyncActionDescriptor(OpenSettingsJsonAction, OpenSettingsJsonAction.ID, OpenSettingsJsonAction.LABEL, { primary: KeyMod.CtrlCmd | KeyCode.US_COMMA }), 'Preferences: Open Settings (JSON)', category); +registry.registerWorkbenchAction(new SyncActionDescriptor(OpenSettings2Action, OpenSettings2Action.ID, OpenSettings2Action.LABEL, { primary: KeyMod.CtrlCmd | KeyCode.US_COMMA }), 'Preferences: Open Settings (UI)', category); registry.registerWorkbenchAction(new SyncActionDescriptor(OpenGlobalSettingsAction, OpenGlobalSettingsAction.ID, OpenGlobalSettingsAction.LABEL), 'Preferences: Open User Settings', category); registry.registerWorkbenchAction(new SyncActionDescriptor(OpenGlobalKeybindingsAction, OpenGlobalKeybindingsAction.ID, OpenGlobalKeybindingsAction.LABEL, { primary: KeyChord(KeyMod.CtrlCmd | KeyCode.KEY_K, KeyMod.CtrlCmd | KeyCode.KEY_S) }), 'Preferences: Open Keyboard Shortcuts', category); registry.registerWorkbenchAction(new SyncActionDescriptor(OpenDefaultKeybindingsFileAction, OpenDefaultKeybindingsFileAction.ID, OpenDefaultKeybindingsFileAction.LABEL), 'Preferences: Open Default Keyboard Shortcuts File', category); From a15b4ed66dbb9eb560aeae7c771f16a45938f221 Mon Sep 17 00:00:00 2001 From: Jackson Kearl Date: Mon, 13 Aug 2018 16:11:42 -0700 Subject: [PATCH 0774/1276] Hopefully make install extensions smoke test less flakey (#56271) --- test/smoke/src/areas/extensions/extensions.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/smoke/src/areas/extensions/extensions.ts b/test/smoke/src/areas/extensions/extensions.ts index be72895ae26..b3ad16827c8 100644 --- a/test/smoke/src/areas/extensions/extensions.ts +++ b/test/smoke/src/areas/extensions/extensions.ts @@ -34,6 +34,6 @@ export class Extensions extends Viewlet { await this.searchForExtension(name); const ariaLabel = `${name}. Press enter for extension details.`; await this.code.waitAndClick(`div.extensions-viewlet[id="workbench.view.extensions"] .monaco-list-row[aria-label="${ariaLabel}"] .extension li[class='action-item'] .extension-action.install`); - await this.code.waitForElement(`div.extensions-viewlet[id="workbench.view.extensions"] .monaco-list-row[aria-label="${ariaLabel}"] .extension li[class='action-item'] .extension-action.reload`); + await this.code.waitForElement(`.extension-editor .monaco-action-bar .action-item:not(.disabled) .extension-action.reload`); } } \ No newline at end of file From f0a793389e244bba05a7a5536ace590e535f6cbd Mon Sep 17 00:00:00 2001 From: Rob Lourens Date: Mon, 13 Aug 2018 17:03:49 -0700 Subject: [PATCH 0775/1276] #55800 - Format category labels with >, use lighter color for label --- src/vs/workbench/parts/preferences/browser/settingsTree.ts | 3 ++- .../workbench/parts/preferences/browser/settingsTreeModels.ts | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/src/vs/workbench/parts/preferences/browser/settingsTree.ts b/src/vs/workbench/parts/preferences/browser/settingsTree.ts index f5816444c86..d14789d9908 100644 --- a/src/vs/workbench/parts/preferences/browser/settingsTree.ts +++ b/src/vs/workbench/parts/preferences/browser/settingsTree.ts @@ -1221,7 +1221,8 @@ export class SettingsTree extends NonExpandableOrSelectableTree { const headerForegroundColor = theme.getColor(settingsHeaderForeground); if (headerForegroundColor) { - collector.addRule(`.settings-editor > .settings-body > .settings-tree-container .settings-group-title-label { color: ${headerForegroundColor} };`); + collector.addRule(`.settings-editor > .settings-body > .settings-tree-container .settings-group-title-label { color: ${headerForegroundColor}; }`); + collector.addRule(`.settings-editor > .settings-body > .settings-tree-container .setting-item-label { color: ${headerForegroundColor}; }`); } })); diff --git a/src/vs/workbench/parts/preferences/browser/settingsTreeModels.ts b/src/vs/workbench/parts/preferences/browser/settingsTreeModels.ts index 4f2b1e428a8..6e37741a0be 100644 --- a/src/vs/workbench/parts/preferences/browser/settingsTreeModels.ts +++ b/src/vs/workbench/parts/preferences/browser/settingsTreeModels.ts @@ -277,7 +277,7 @@ export function settingKeyToDisplayFormat(key: string, groupId = ''): { category function wordifyKey(key: string): string { return key - .replace(/\.([a-z])/g, (match, p1) => `.${p1.toUpperCase()}`) + .replace(/\.([a-z])/g, (match, p1) => ` › ${p1.toUpperCase()}`) .replace(/([a-z])([A-Z])/g, '$1 $2') // fooBar => foo Bar .replace(/^[a-z]/g, match => match.toUpperCase()); // foo => Foo } From 2075a36029510ad1306511ae44a5db84e9eae862 Mon Sep 17 00:00:00 2001 From: Rob Lourens Date: Mon, 13 Aug 2018 17:37:06 -0700 Subject: [PATCH 0776/1276] Fix settingKeyToDisplayFormat unit test --- .../parts/preferences/test/browser/settingsTree.test.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vs/workbench/parts/preferences/test/browser/settingsTree.test.ts b/src/vs/workbench/parts/preferences/test/browser/settingsTree.test.ts index 9ddd279b6ab..44088dcbd61 100644 --- a/src/vs/workbench/parts/preferences/test/browser/settingsTree.test.ts +++ b/src/vs/workbench/parts/preferences/test/browser/settingsTree.test.ts @@ -20,7 +20,7 @@ suite('SettingsTree', () => { assert.deepEqual( settingKeyToDisplayFormat('foo.bar.etc'), { - category: 'Foo.Bar', + category: 'Foo › Bar', label: 'Etc' }); From 523565474257de0209a4b6eccdca63903c905068 Mon Sep 17 00:00:00 2001 From: Jackson Kearl Date: Mon, 13 Aug 2018 17:37:26 -0700 Subject: [PATCH 0777/1276] Add edits that didnt make it into the merge for some reason --- .../parts/preferences/browser/settingsTreeModels.ts | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/src/vs/workbench/parts/preferences/browser/settingsTreeModels.ts b/src/vs/workbench/parts/preferences/browser/settingsTreeModels.ts index 4f2b1e428a8..81083543ea0 100644 --- a/src/vs/workbench/parts/preferences/browser/settingsTreeModels.ts +++ b/src/vs/workbench/parts/preferences/browser/settingsTreeModels.ts @@ -11,6 +11,7 @@ import { ConfigurationTarget, IConfigurationService } from 'vs/platform/configur import { SettingsTarget } from 'vs/workbench/parts/preferences/browser/preferencesWidgets'; import { ITOCEntry } from 'vs/workbench/parts/preferences/browser/settingsLayout'; import { IExtensionSetting, ISearchResult, ISetting } from 'vs/workbench/services/preferences/common/preferences'; +import { isArray } from 'vs/base/common/types'; export const MODIFIED_SETTING_TAG = 'modified'; export const ONLINE_SERVICES_SETTING_TAG = 'usesOnlineServices'; @@ -67,7 +68,7 @@ export class SettingsTreeSettingElement extends SettingsTreeElement { tags?: Set; overriddenScopeList: string[]; description: string; - valueType: 'enum' | 'string' | 'integer' | 'number' | 'boolean' | 'exclude' | 'complex'; + valueType: 'enum' | 'string' | 'integer' | 'number' | 'boolean' | 'exclude' | 'complex' | 'nullable-integer' | 'nullable-number'; constructor(setting: ISetting, parent: SettingsTreeGroupElement, inspectResult: IInspectResult) { super(); @@ -126,6 +127,14 @@ export class SettingsTreeSettingElement extends SettingsTreeElement { this.valueType = 'number'; } else if (this.setting.type === 'boolean') { this.valueType = 'boolean'; + } else if (isArray(this.setting.type) && this.setting.type.indexOf('null') > -1 && this.setting.type.length === 2) { + if (this.setting.type.indexOf('integer') > -1) { + this.valueType = 'nullable-integer'; + } else if (this.setting.type.indexOf('number') > -1) { + this.valueType = 'nullable-number'; + } else { + this.valueType = 'complex'; + } } else { this.valueType = 'complex'; } From 658d9b7bafe805f3aecd86855df3fc62f7f0981b Mon Sep 17 00:00:00 2001 From: Rob Lourens Date: Mon, 13 Aug 2018 17:38:31 -0700 Subject: [PATCH 0778/1276] Rename settingsTreeModels.test.ts to match --- .../browser/{settingsTree.test.ts => settingsTreeModels.test.ts} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename src/vs/workbench/parts/preferences/test/browser/{settingsTree.test.ts => settingsTreeModels.test.ts} (100%) diff --git a/src/vs/workbench/parts/preferences/test/browser/settingsTree.test.ts b/src/vs/workbench/parts/preferences/test/browser/settingsTreeModels.test.ts similarity index 100% rename from src/vs/workbench/parts/preferences/test/browser/settingsTree.test.ts rename to src/vs/workbench/parts/preferences/test/browser/settingsTreeModels.test.ts From 9fdf186175985d84af8100a042805344b826f7ef Mon Sep 17 00:00:00 2001 From: Jackson Kearl Date: Mon, 13 Aug 2018 18:49:23 -0700 Subject: [PATCH 0779/1276] Begin writing tests for validator --- .../preferences/common/preferencesModels.ts | 2 +- .../test/common/preferencesModel.test.ts | 105 ++++++++++++++++++ 2 files changed, 106 insertions(+), 1 deletion(-) create mode 100644 src/vs/workbench/services/preferences/test/common/preferencesModel.test.ts diff --git a/src/vs/workbench/services/preferences/common/preferencesModels.ts b/src/vs/workbench/services/preferences/common/preferencesModels.ts index 8923e842a25..1a081bf8287 100644 --- a/src/vs/workbench/services/preferences/common/preferencesModels.ts +++ b/src/vs/workbench/services/preferences/common/preferencesModels.ts @@ -962,7 +962,7 @@ class SettingsContentBuilder { } } -function createValidator(prop: IConfigurationPropertySchema): ((value: any) => string) | null { +export function createValidator(prop: IConfigurationPropertySchema): ((value: any) => string) | null { let exclusiveMax: number | undefined; let exclusiveMin: number | undefined; diff --git a/src/vs/workbench/services/preferences/test/common/preferencesModel.test.ts b/src/vs/workbench/services/preferences/test/common/preferencesModel.test.ts new file mode 100644 index 00000000000..f02d5d7164f --- /dev/null +++ b/src/vs/workbench/services/preferences/test/common/preferencesModel.test.ts @@ -0,0 +1,105 @@ +/*--------------------------------------------------------------------------------------------- + * 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 { createValidator } from 'vs/workbench/services/preferences/common/preferencesModels'; +import { IConfigurationPropertySchema } from 'vs/platform/configuration/common/configurationRegistry'; + + +suite('Preferences Model test', () => { + + + class Tester { + private validator: (value: any) => string; + + constructor(settings: IConfigurationPropertySchema) { + this.validator = createValidator(settings); + } + + public accepts(input) { + assert(this.validator(input) === ''); + } + + public rejects(input) { + assert(this.validator(input) !== ''); + } + + public acceptsEmpty() { + this.accepts(''); + } + + public rejectsEmpty() { + this.rejects(''); + } + + public validatesNumeric() { + this.accepts('3'); + this.accepts('3.'); + this.accepts('.0'); + this.accepts('3.0'); + this.accepts(' 3.0'); + this.accepts(' 3.0 '); + this.rejects('3f'); + } + + public validatesNullableNumeric() { + this.validatesNumeric(); + this.acceptsEmpty(); + } + + public validatesNonNullableNumeric() { + this.validatesNumeric(); + this.rejectsEmpty(); + } + + public validatesString() { + this.accepts('3'); + this.accepts('3.'); + this.accepts('.0'); + this.accepts('3.0'); + this.accepts(' 3.0'); + this.accepts(' 3.0 '); + this.accepts(''); + this.accepts('3f'); + this.accepts('hello'); + } + } + + + test('exclusive max and max work together properly', () => { + { + const justMax = new Tester({ maximum: 5, type: 'number' }); + justMax.validatesNonNullableNumeric(); + justMax.rejects('5.1'); + justMax.accepts('5.0'); + } + { + const justEMax = new Tester({ exclusiveMaximum: 5, type: 'number' }); + justEMax.validatesNonNullableNumeric(); + justEMax.rejects('5.1'); + justEMax.rejects('5.0'); + justEMax.accepts('4.999'); + } + { + const bothNumeric = new Tester({ exclusiveMaximum: 5, maximum: 4, type: 'number' }); + bothNumeric.validatesNonNullableNumeric(); + bothNumeric.rejects('5.1'); + bothNumeric.rejects('5.0'); + bothNumeric.rejects('4.999'); + bothNumeric.accepts('4'); + } + { + const bothNumeric = new Tester({ exclusiveMaximum: 5, maximum: 6, type: 'number' }); + bothNumeric.validatesNonNullableNumeric(); + bothNumeric.rejects('5.1'); + bothNumeric.rejects('5.0'); + bothNumeric.accepts('4.999'); + } + }); + + test('exclusive min and min work together properly', () => { + + }); +}); \ No newline at end of file From 8727085fff33bf7d8f5e27483b10f72508d4167a Mon Sep 17 00:00:00 2001 From: Rob Lourens Date: Mon, 13 Aug 2018 21:43:31 -0700 Subject: [PATCH 0780/1276] Fix #56284 --- .../parts/preferences/browser/settingsEditor2.ts | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/vs/workbench/parts/preferences/browser/settingsEditor2.ts b/src/vs/workbench/parts/preferences/browser/settingsEditor2.ts index 4060c37f87c..69fa9d13e74 100644 --- a/src/vs/workbench/parts/preferences/browser/settingsEditor2.ts +++ b/src/vs/workbench/parts/preferences/browser/settingsEditor2.ts @@ -124,6 +124,10 @@ export class SettingsEditor2 extends BaseEditor { })); } + private get currentSettingsModel() { + return this.searchResultModel || this.settingsTreeModel; + } + createEditor(parent: HTMLElement): void { parent.setAttribute('tabindex', '-1'); this.rootElement = DOM.append(parent, $('.settings-editor')); @@ -261,7 +265,7 @@ export class SettingsEditor2 extends BaseEditor { } private getElementsByKey(settingKey: string): SettingsTreeSettingElement[] | null { - return (this.searchResultModel || this.settingsTreeModel).getElementByName(settingKey); + return this.currentSettingsModel.getElementByName(settingKey); } private revealSetting(settingKey: string): void { @@ -646,7 +650,7 @@ export class SettingsEditor2 extends BaseEditor { private updateElementsByKey(keys: string[]): TPromise { if (keys.length) { - keys.forEach(key => this.settingsTreeModel.updateElementsByName(key)); + keys.forEach(key => this.currentSettingsModel.updateElementsByName(key)); return TPromise.join( keys.map(key => this.renderTree(key))) .then(() => { }); From 206e1b0914427da8261a856c373daa35d207beec Mon Sep 17 00:00:00 2001 From: Rob Lourens Date: Mon, 13 Aug 2018 22:30:08 -0700 Subject: [PATCH 0781/1276] Fix settings smoketest --- test/smoke/src/areas/preferences/settings.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/smoke/src/areas/preferences/settings.ts b/test/smoke/src/areas/preferences/settings.ts index ecdef71c033..b20102e1dbb 100644 --- a/test/smoke/src/areas/preferences/settings.ts +++ b/test/smoke/src/areas/preferences/settings.ts @@ -42,6 +42,6 @@ export class SettingsEditor { } private async openSettings(): Promise { - await this.quickopen.runCommand('Preferences: Open User Settings'); + await this.quickopen.runCommand('Preferences: Open Settings (JSON)'); } } \ No newline at end of file From 8319bfbb65d97cc0b56445f3ae08b0c17820d717 Mon Sep 17 00:00:00 2001 From: Johannes Rieken Date: Tue, 14 Aug 2018 09:32:32 +0200 Subject: [PATCH 0782/1276] log what source maps we upload --- build/gulpfile.vscode.js | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/build/gulpfile.vscode.js b/build/gulpfile.vscode.js index 5da087404e1..54648e7f5ef 100644 --- a/build/gulpfile.vscode.js +++ b/build/gulpfile.vscode.js @@ -462,6 +462,11 @@ gulp.task('upload-vscode-sourcemaps', ['minify-vscode'], () => { const extensionsDist = gulp.src('extensions/**/dist/**/*.map', { base: '.' }); return es.merge(vs, extensionsOut, extensionsDist) + .pipe(es.through(function (data) { + // debug + console.log('Uploading Sourcemap', data.relative); + this.emit('data', data); + })) .pipe(azure.upload({ account: process.env.AZURE_STORAGE_ACCOUNT, key: process.env.AZURE_STORAGE_ACCESS_KEY, From 6a158f8fd24322654e60884b79c7513230288b2a Mon Sep 17 00:00:00 2001 From: Sandeep Somavarapu Date: Tue, 14 Aug 2018 09:41:55 +0200 Subject: [PATCH 0783/1276] Fix #55536 --- .../parts/extensions/node/extensionsWorkbenchService.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/vs/workbench/parts/extensions/node/extensionsWorkbenchService.ts b/src/vs/workbench/parts/extensions/node/extensionsWorkbenchService.ts index eaf82c0f793..15b8bcf0225 100644 --- a/src/vs/workbench/parts/extensions/node/extensionsWorkbenchService.ts +++ b/src/vs/workbench/parts/extensions/node/extensionsWorkbenchService.ts @@ -816,7 +816,8 @@ export class ExtensionsWorkbenchService implements IExtensionsWorkbenchService, if (i.enablementState === enablementState) { return false; } - return (options.dependencies || options.pack) + return i.type === LocalExtensionType.User + && (options.dependencies || options.pack) && extensions.some(extension => (options.dependencies && extension.dependencies.some(id => areSameExtensions({ id }, i))) || (options.pack && extension.extensionPack.some(id => areSameExtensions({ id }, i))) From 920defc6a68980cbe55ba06b9e609f716d606a84 Mon Sep 17 00:00:00 2001 From: Benjamin Pasero Date: Tue, 14 Aug 2018 10:44:56 +0200 Subject: [PATCH 0784/1276] debt - update extensions node dependency to 8.x --- extensions/configuration-editing/package.json | 4 ++-- extensions/configuration-editing/yarn.lock | 6 +++--- extensions/css-language-features/package.json | 2 +- extensions/css-language-features/server/package.json | 2 +- extensions/css-language-features/server/yarn.lock | 6 +++--- extensions/css-language-features/yarn.lock | 6 +++--- extensions/extension-editing/package.json | 4 ++-- extensions/extension-editing/yarn.lock | 6 +++++- extensions/git/package.json | 4 ++-- extensions/git/yarn.lock | 6 +++--- extensions/grunt/package.json | 8 +++++--- extensions/grunt/yarn.lock | 6 +++--- extensions/gulp/package.json | 8 +++++--- extensions/gulp/yarn.lock | 6 +++--- extensions/html-language-features/package.json | 2 +- extensions/html-language-features/server/package.json | 2 +- extensions/html-language-features/server/yarn.lock | 6 +++--- extensions/html-language-features/yarn.lock | 6 +++--- extensions/jake/package.json | 8 +++++--- extensions/jake/yarn.lock | 6 +++--- extensions/json-language-features/package.json | 2 +- extensions/json-language-features/server/package.json | 2 +- extensions/json-language-features/server/yarn.lock | 6 +++--- extensions/json-language-features/yarn.lock | 6 +++--- extensions/markdown-language-features/package.json | 2 +- extensions/markdown-language-features/yarn.lock | 6 +++--- extensions/npm/package.json | 8 +++++--- extensions/npm/yarn.lock | 6 +++--- extensions/php-language-features/package.json | 2 +- extensions/php-language-features/yarn.lock | 6 +++--- extensions/vscode-api-tests/package.json | 9 ++++----- extensions/vscode-api-tests/yarn.lock | 6 +++--- extensions/vscode-colorize-tests/package.json | 2 +- extensions/vscode-colorize-tests/yarn.lock | 6 +++--- 34 files changed, 92 insertions(+), 81 deletions(-) diff --git a/extensions/configuration-editing/package.json b/extensions/configuration-editing/package.json index f63d8c84087..125f2456f54 100644 --- a/extensions/configuration-editing/package.json +++ b/extensions/configuration-editing/package.json @@ -96,6 +96,6 @@ ] }, "devDependencies": { - "@types/node": "7.0.4" + "@types/node": "^8.10.25" } -} \ No newline at end of file +} diff --git a/extensions/configuration-editing/yarn.lock b/extensions/configuration-editing/yarn.lock index bcf4ddb12d8..c3f9631aeb0 100644 --- a/extensions/configuration-editing/yarn.lock +++ b/extensions/configuration-editing/yarn.lock @@ -2,9 +2,9 @@ # yarn lockfile v1 -"@types/node@7.0.4": - version "7.0.4" - resolved "https://registry.yarnpkg.com/@types/node/-/node-7.0.4.tgz#9aabc135979ded383325749f508894c662948c8b" +"@types/node@^8.10.25": + version "8.10.25" + resolved "https://registry.yarnpkg.com/@types/node/-/node-8.10.25.tgz#801fe4e39372cef18f268db880a5fbfcf71adc7e" jsonc-parser@^1.0.0: version "1.0.0" diff --git a/extensions/css-language-features/package.json b/extensions/css-language-features/package.json index 41b83b02164..cf0903f0a81 100644 --- a/extensions/css-language-features/package.json +++ b/extensions/css-language-features/package.json @@ -712,7 +712,7 @@ "vscode-nls": "^3.2.4" }, "devDependencies": { - "@types/node": "7.0.43", + "@types/node": "^8.10.25", "mocha": "^5.2.0" } } diff --git a/extensions/css-language-features/server/package.json b/extensions/css-language-features/server/package.json index 7b98111d447..98a8a370800 100644 --- a/extensions/css-language-features/server/package.json +++ b/extensions/css-language-features/server/package.json @@ -13,7 +13,7 @@ }, "devDependencies": { "@types/mocha": "2.2.33", - "@types/node": "7.0.43", + "@types/node": "^8.10.25", "glob": "^7.1.2", "mocha": "^5.2.0", "mocha-junit-reporter": "^1.17.0", diff --git a/extensions/css-language-features/server/yarn.lock b/extensions/css-language-features/server/yarn.lock index 6878038d8f8..61e83d9a85d 100644 --- a/extensions/css-language-features/server/yarn.lock +++ b/extensions/css-language-features/server/yarn.lock @@ -6,9 +6,9 @@ version "2.2.33" resolved "https://registry.yarnpkg.com/@types/mocha/-/mocha-2.2.33.tgz#d79a0061ec270379f4d9e225f4096fb436669def" -"@types/node@7.0.43": - version "7.0.43" - resolved "https://registry.yarnpkg.com/@types/node/-/node-7.0.43.tgz#a187e08495a075f200ca946079c914e1a5fe962c" +"@types/node@^8.10.25": + version "8.10.25" + resolved "https://registry.yarnpkg.com/@types/node/-/node-8.10.25.tgz#801fe4e39372cef18f268db880a5fbfcf71adc7e" ansi-regex@^3.0.0: version "3.0.0" diff --git a/extensions/css-language-features/yarn.lock b/extensions/css-language-features/yarn.lock index 6338d75b098..a51de5f43ac 100644 --- a/extensions/css-language-features/yarn.lock +++ b/extensions/css-language-features/yarn.lock @@ -2,9 +2,9 @@ # yarn lockfile v1 -"@types/node@7.0.43": - version "7.0.43" - resolved "https://registry.yarnpkg.com/@types/node/-/node-7.0.43.tgz#a187e08495a075f200ca946079c914e1a5fe962c" +"@types/node@^8.10.25": + version "8.10.25" + resolved "https://registry.yarnpkg.com/@types/node/-/node-8.10.25.tgz#801fe4e39372cef18f268db880a5fbfcf71adc7e" balanced-match@^1.0.0: version "1.0.0" diff --git a/extensions/extension-editing/package.json b/extensions/extension-editing/package.json index 88b339023b2..b386dc565f3 100644 --- a/extensions/extension-editing/package.json +++ b/extensions/extension-editing/package.json @@ -45,6 +45,6 @@ }, "devDependencies": { "@types/markdown-it": "0.0.2", - "@types/node": "6.0.78" + "@types/node": "^8.10.25" } -} \ No newline at end of file +} diff --git a/extensions/extension-editing/yarn.lock b/extensions/extension-editing/yarn.lock index cdc02d1e035..b28c81dbb27 100644 --- a/extensions/extension-editing/yarn.lock +++ b/extensions/extension-editing/yarn.lock @@ -6,10 +6,14 @@ version "0.0.2" resolved "https://registry.yarnpkg.com/@types/markdown-it/-/markdown-it-0.0.2.tgz#5d9ad19e6e6508cdd2f2596df86fd0aade598660" -"@types/node@6.0.78", "@types/node@^6.0.46": +"@types/node@^6.0.46": version "6.0.78" resolved "https://registry.yarnpkg.com/@types/node/-/node-6.0.78.tgz#5d4a3f579c1524e01ee21bf474e6fba09198f470" +"@types/node@^8.10.25": + version "8.10.25" + resolved "https://registry.yarnpkg.com/@types/node/-/node-8.10.25.tgz#801fe4e39372cef18f268db880a5fbfcf71adc7e" + argparse@^1.0.7: version "1.0.9" resolved "https://registry.yarnpkg.com/argparse/-/argparse-1.0.9.tgz#73d83bc263f86e97f8cc4f6bae1b0e90a7d22c86" diff --git a/extensions/git/package.json b/extensions/git/package.json index 0eba9ba5c94..712f071eb3a 100644 --- a/extensions/git/package.json +++ b/extensions/git/package.json @@ -1205,8 +1205,8 @@ "@types/byline": "4.2.31", "@types/file-type": "^5.2.1", "@types/mocha": "2.2.43", - "@types/node": "7.0.43", + "@types/node": "^8.10.25", "@types/which": "^1.0.28", "mocha": "^3.2.0" } -} \ No newline at end of file +} diff --git a/extensions/git/yarn.lock b/extensions/git/yarn.lock index 497e26b21d6..cf3f64be853 100644 --- a/extensions/git/yarn.lock +++ b/extensions/git/yarn.lock @@ -22,9 +22,9 @@ version "8.0.51" resolved "https://registry.yarnpkg.com/@types/node/-/node-8.0.51.tgz#b31d716fb8d58eeb95c068a039b9b6292817d5fb" -"@types/node@7.0.43": - version "7.0.43" - resolved "https://registry.yarnpkg.com/@types/node/-/node-7.0.43.tgz#a187e08495a075f200ca946079c914e1a5fe962c" +"@types/node@^8.10.25": + version "8.10.25" + resolved "https://registry.yarnpkg.com/@types/node/-/node-8.10.25.tgz#801fe4e39372cef18f268db880a5fbfcf71adc7e" "@types/which@^1.0.28": version "1.0.28" diff --git a/extensions/grunt/package.json b/extensions/grunt/package.json index 18c5c21e0cb..c1839be2cc9 100644 --- a/extensions/grunt/package.json +++ b/extensions/grunt/package.json @@ -19,7 +19,7 @@ "vscode-nls": "^3.2.4" }, "devDependencies": { - "@types/node": "7.0.43" + "@types/node": "^8.10.25" }, "main": "./out/main", "activationEvents": [ @@ -46,7 +46,9 @@ "taskDefinitions": [ { "type": "grunt", - "required": ["task"], + "required": [ + "task" + ], "properties": { "task": { "type": "string", @@ -60,4 +62,4 @@ } ] } -} \ No newline at end of file +} diff --git a/extensions/grunt/yarn.lock b/extensions/grunt/yarn.lock index 573098d7d26..fe244123db7 100644 --- a/extensions/grunt/yarn.lock +++ b/extensions/grunt/yarn.lock @@ -2,9 +2,9 @@ # yarn lockfile v1 -"@types/node@7.0.43": - version "7.0.43" - resolved "https://registry.yarnpkg.com/@types/node/-/node-7.0.43.tgz#a187e08495a075f200ca946079c914e1a5fe962c" +"@types/node@^8.10.25": + version "8.10.25" + resolved "https://registry.yarnpkg.com/@types/node/-/node-8.10.25.tgz#801fe4e39372cef18f268db880a5fbfcf71adc7e" vscode-nls@^3.2.4: version "3.2.4" diff --git a/extensions/gulp/package.json b/extensions/gulp/package.json index 65d9197a0d9..5c5656a126d 100644 --- a/extensions/gulp/package.json +++ b/extensions/gulp/package.json @@ -19,7 +19,7 @@ "vscode-nls": "^3.2.4" }, "devDependencies": { - "@types/node": "7.0.43" + "@types/node": "^8.10.25" }, "main": "./out/main", "activationEvents": [ @@ -46,7 +46,9 @@ "taskDefinitions": [ { "type": "gulp", - "required": ["task"], + "required": [ + "task" + ], "properties": { "task": { "type": "string", @@ -60,4 +62,4 @@ } ] } -} \ No newline at end of file +} diff --git a/extensions/gulp/yarn.lock b/extensions/gulp/yarn.lock index 573098d7d26..fe244123db7 100644 --- a/extensions/gulp/yarn.lock +++ b/extensions/gulp/yarn.lock @@ -2,9 +2,9 @@ # yarn lockfile v1 -"@types/node@7.0.43": - version "7.0.43" - resolved "https://registry.yarnpkg.com/@types/node/-/node-7.0.43.tgz#a187e08495a075f200ca946079c914e1a5fe962c" +"@types/node@^8.10.25": + version "8.10.25" + resolved "https://registry.yarnpkg.com/@types/node/-/node-8.10.25.tgz#801fe4e39372cef18f268db880a5fbfcf71adc7e" vscode-nls@^3.2.4: version "3.2.4" diff --git a/extensions/html-language-features/package.json b/extensions/html-language-features/package.json index 586b1684cda..e55530df063 100644 --- a/extensions/html-language-features/package.json +++ b/extensions/html-language-features/package.json @@ -178,6 +178,6 @@ "vscode-nls": "^3.2.4" }, "devDependencies": { - "@types/node": "7.0.43" + "@types/node": "^8.10.25" } } diff --git a/extensions/html-language-features/server/package.json b/extensions/html-language-features/server/package.json index 5db8caf8ea8..9d4b15d815b 100644 --- a/extensions/html-language-features/server/package.json +++ b/extensions/html-language-features/server/package.json @@ -17,7 +17,7 @@ }, "devDependencies": { "@types/mocha": "2.2.33", - "@types/node": "7.0.43", + "@types/node": "^8.10.25", "glob": "^7.1.2", "mocha": "^5.2.0", "mocha-junit-reporter": "^1.17.0", diff --git a/extensions/html-language-features/server/yarn.lock b/extensions/html-language-features/server/yarn.lock index 0fb9f113a5d..d642e6bb321 100644 --- a/extensions/html-language-features/server/yarn.lock +++ b/extensions/html-language-features/server/yarn.lock @@ -6,9 +6,9 @@ version "2.2.33" resolved "https://registry.yarnpkg.com/@types/mocha/-/mocha-2.2.33.tgz#d79a0061ec270379f4d9e225f4096fb436669def" -"@types/node@7.0.43": - version "7.0.43" - resolved "https://registry.yarnpkg.com/@types/node/-/node-7.0.43.tgz#a187e08495a075f200ca946079c914e1a5fe962c" +"@types/node@^8.10.25": + version "8.10.25" + resolved "https://registry.yarnpkg.com/@types/node/-/node-8.10.25.tgz#801fe4e39372cef18f268db880a5fbfcf71adc7e" ansi-regex@^3.0.0: version "3.0.0" diff --git a/extensions/html-language-features/yarn.lock b/extensions/html-language-features/yarn.lock index a33a4a08108..f6e965d98ea 100644 --- a/extensions/html-language-features/yarn.lock +++ b/extensions/html-language-features/yarn.lock @@ -2,9 +2,9 @@ # yarn lockfile v1 -"@types/node@7.0.43": - version "7.0.43" - resolved "https://registry.yarnpkg.com/@types/node/-/node-7.0.43.tgz#a187e08495a075f200ca946079c914e1a5fe962c" +"@types/node@^8.10.25": + version "8.10.25" + resolved "https://registry.yarnpkg.com/@types/node/-/node-8.10.25.tgz#801fe4e39372cef18f268db880a5fbfcf71adc7e" applicationinsights@1.0.1: version "1.0.1" diff --git a/extensions/jake/package.json b/extensions/jake/package.json index 6befa9fbd9e..34a149cf355 100644 --- a/extensions/jake/package.json +++ b/extensions/jake/package.json @@ -19,7 +19,7 @@ "vscode-nls": "^3.2.4" }, "devDependencies": { - "@types/node": "7.0.43" + "@types/node": "^8.10.25" }, "main": "./out/main", "activationEvents": [ @@ -46,7 +46,9 @@ "taskDefinitions": [ { "type": "jake", - "required": ["task"], + "required": [ + "task" + ], "properties": { "task": { "type": "string", @@ -60,4 +62,4 @@ } ] } -} \ No newline at end of file +} diff --git a/extensions/jake/yarn.lock b/extensions/jake/yarn.lock index 573098d7d26..fe244123db7 100644 --- a/extensions/jake/yarn.lock +++ b/extensions/jake/yarn.lock @@ -2,9 +2,9 @@ # yarn lockfile v1 -"@types/node@7.0.43": - version "7.0.43" - resolved "https://registry.yarnpkg.com/@types/node/-/node-7.0.43.tgz#a187e08495a075f200ca946079c914e1a5fe962c" +"@types/node@^8.10.25": + version "8.10.25" + resolved "https://registry.yarnpkg.com/@types/node/-/node-8.10.25.tgz#801fe4e39372cef18f268db880a5fbfcf71adc7e" vscode-nls@^3.2.4: version "3.2.4" diff --git a/extensions/json-language-features/package.json b/extensions/json-language-features/package.json index f814f5e747d..fab153b6000 100644 --- a/extensions/json-language-features/package.json +++ b/extensions/json-language-features/package.json @@ -105,6 +105,6 @@ "vscode-nls": "^3.2.4" }, "devDependencies": { - "@types/node": "7.0.43" + "@types/node": "^8.10.25" } } diff --git a/extensions/json-language-features/server/package.json b/extensions/json-language-features/server/package.json index e894d848722..605e1b18f8c 100644 --- a/extensions/json-language-features/server/package.json +++ b/extensions/json-language-features/server/package.json @@ -20,7 +20,7 @@ }, "devDependencies": { "@types/mocha": "2.2.33", - "@types/node": "7.0.43" + "@types/node": "^8.10.25" }, "scripts": { "prepublishOnly": "npm run clean && npm run test", diff --git a/extensions/json-language-features/server/yarn.lock b/extensions/json-language-features/server/yarn.lock index 8948926b0bd..31389ce0fc1 100644 --- a/extensions/json-language-features/server/yarn.lock +++ b/extensions/json-language-features/server/yarn.lock @@ -6,9 +6,9 @@ version "2.2.33" resolved "https://registry.yarnpkg.com/@types/mocha/-/mocha-2.2.33.tgz#d79a0061ec270379f4d9e225f4096fb436669def" -"@types/node@7.0.43": - version "7.0.43" - resolved "https://registry.yarnpkg.com/@types/node/-/node-7.0.43.tgz#a187e08495a075f200ca946079c914e1a5fe962c" +"@types/node@^8.10.25": + version "8.10.25" + resolved "https://registry.yarnpkg.com/@types/node/-/node-8.10.25.tgz#801fe4e39372cef18f268db880a5fbfcf71adc7e" agent-base@4, agent-base@^4.1.0: version "4.1.2" diff --git a/extensions/json-language-features/yarn.lock b/extensions/json-language-features/yarn.lock index a33a4a08108..f6e965d98ea 100644 --- a/extensions/json-language-features/yarn.lock +++ b/extensions/json-language-features/yarn.lock @@ -2,9 +2,9 @@ # yarn lockfile v1 -"@types/node@7.0.43": - version "7.0.43" - resolved "https://registry.yarnpkg.com/@types/node/-/node-7.0.43.tgz#a187e08495a075f200ca946079c914e1a5fe962c" +"@types/node@^8.10.25": + version "8.10.25" + resolved "https://registry.yarnpkg.com/@types/node/-/node-8.10.25.tgz#801fe4e39372cef18f268db880a5fbfcf71adc7e" applicationinsights@1.0.1: version "1.0.1" diff --git a/extensions/markdown-language-features/package.json b/extensions/markdown-language-features/package.json index b49638d9707..31171b5aef9 100644 --- a/extensions/markdown-language-features/package.json +++ b/extensions/markdown-language-features/package.json @@ -302,7 +302,7 @@ "@types/highlight.js": "9.1.10", "@types/lodash.throttle": "^4.1.3", "@types/markdown-it": "0.0.2", - "@types/node": "7.0.43", + "@types/node": "^8.10.25", "lodash.throttle": "^4.1.1", "mocha-junit-reporter": "^1.17.0", "mocha-multi-reporters": "^1.1.7", diff --git a/extensions/markdown-language-features/yarn.lock b/extensions/markdown-language-features/yarn.lock index a2e69ddb6b8..f75c44c634f 100644 --- a/extensions/markdown-language-features/yarn.lock +++ b/extensions/markdown-language-features/yarn.lock @@ -24,9 +24,9 @@ version "0.0.2" resolved "https://registry.yarnpkg.com/@types/markdown-it/-/markdown-it-0.0.2.tgz#5d9ad19e6e6508cdd2f2596df86fd0aade598660" -"@types/node@7.0.43": - version "7.0.43" - resolved "https://registry.yarnpkg.com/@types/node/-/node-7.0.43.tgz#a187e08495a075f200ca946079c914e1a5fe962c" +"@types/node@^8.10.25": + version "8.10.25" + resolved "https://registry.yarnpkg.com/@types/node/-/node-8.10.25.tgz#801fe4e39372cef18f268db880a5fbfcf71adc7e" abbrev@1: version "1.1.1" diff --git a/extensions/npm/package.json b/extensions/npm/package.json index dc6a25a9dca..2e478c09e5e 100644 --- a/extensions/npm/package.json +++ b/extensions/npm/package.json @@ -24,7 +24,7 @@ }, "devDependencies": { "@types/minimatch": "^3.0.3", - "@types/node": "7.0.43" + "@types/node": "^8.10.25" }, "main": "./out/main", "activationEvents": [ @@ -235,7 +235,9 @@ "description": "%config.npm.fetchOnlinePackageInfo%", "default": true, "scope": "window", - "tags": ["usesOnlineServices"] + "tags": [ + "usesOnlineServices" + ] } } }, @@ -268,4 +270,4 @@ } ] } -} \ No newline at end of file +} diff --git a/extensions/npm/yarn.lock b/extensions/npm/yarn.lock index 9822a92a784..395adb4e496 100644 --- a/extensions/npm/yarn.lock +++ b/extensions/npm/yarn.lock @@ -6,9 +6,9 @@ version "3.0.3" resolved "https://registry.yarnpkg.com/@types/minimatch/-/minimatch-3.0.3.tgz#3dca0e3f33b200fc7d1139c0cd96c1268cadfd9d" -"@types/node@7.0.43": - version "7.0.43" - resolved "https://registry.yarnpkg.com/@types/node/-/node-7.0.43.tgz#a187e08495a075f200ca946079c914e1a5fe962c" +"@types/node@^8.10.25": + version "8.10.25" + resolved "https://registry.yarnpkg.com/@types/node/-/node-8.10.25.tgz#801fe4e39372cef18f268db880a5fbfcf71adc7e" agent-base@4, agent-base@^4.1.0: version "4.2.0" diff --git a/extensions/php-language-features/package.json b/extensions/php-language-features/package.json index e39073271f3..29ebe03b9b1 100644 --- a/extensions/php-language-features/package.json +++ b/extensions/php-language-features/package.json @@ -80,6 +80,6 @@ "vscode-nls": "^3.2.4" }, "devDependencies": { - "@types/node": "7.0.43" + "@types/node": "^8.10.25" } } diff --git a/extensions/php-language-features/yarn.lock b/extensions/php-language-features/yarn.lock index 573098d7d26..fe244123db7 100644 --- a/extensions/php-language-features/yarn.lock +++ b/extensions/php-language-features/yarn.lock @@ -2,9 +2,9 @@ # yarn lockfile v1 -"@types/node@7.0.43": - version "7.0.43" - resolved "https://registry.yarnpkg.com/@types/node/-/node-7.0.43.tgz#a187e08495a075f200ca946079c914e1a5fe962c" +"@types/node@^8.10.25": + version "8.10.25" + resolved "https://registry.yarnpkg.com/@types/node/-/node-8.10.25.tgz#801fe4e39372cef18f268db880a5fbfcf71adc7e" vscode-nls@^3.2.4: version "3.2.4" diff --git a/extensions/vscode-api-tests/package.json b/extensions/vscode-api-tests/package.json index 72fa2b8dcd5..4c3f93d4fc2 100644 --- a/extensions/vscode-api-tests/package.json +++ b/extensions/vscode-api-tests/package.json @@ -4,10 +4,9 @@ "version": "0.0.1", "publisher": "vscode", "enableProposedApi": true, - "private": true, - "main": "horse", - "activationEvents": [ - ], + "private": true, + "main": "horse", + "activationEvents": [], "engines": { "vscode": "1.25.0" }, @@ -50,7 +49,7 @@ }, "devDependencies": { "@types/mocha": "2.2.43", - "@types/node": "7.0.43", + "@types/node": "^8.10.25", "mocha-junit-reporter": "^1.17.0", "mocha-multi-reporters": "^1.1.7", "typescript": "^1.6.2", diff --git a/extensions/vscode-api-tests/yarn.lock b/extensions/vscode-api-tests/yarn.lock index 8397cfb2eef..5fee636122b 100644 --- a/extensions/vscode-api-tests/yarn.lock +++ b/extensions/vscode-api-tests/yarn.lock @@ -6,9 +6,9 @@ version "2.2.43" resolved "https://registry.yarnpkg.com/@types/mocha/-/mocha-2.2.43.tgz#03c54589c43ad048cbcbfd63999b55d0424eec27" -"@types/node@7.0.43": - version "7.0.43" - resolved "https://registry.yarnpkg.com/@types/node/-/node-7.0.43.tgz#a187e08495a075f200ca946079c914e1a5fe962c" +"@types/node@^8.10.25": + version "8.10.25" + resolved "https://registry.yarnpkg.com/@types/node/-/node-8.10.25.tgz#801fe4e39372cef18f268db880a5fbfcf71adc7e" ajv@^5.1.0: version "5.3.0" diff --git a/extensions/vscode-colorize-tests/package.json b/extensions/vscode-colorize-tests/package.json index 756d09c8650..9b43cfa2a6c 100644 --- a/extensions/vscode-colorize-tests/package.json +++ b/extensions/vscode-colorize-tests/package.json @@ -12,7 +12,7 @@ "postinstall": "node ./node_modules/vscode/bin/install" }, "devDependencies": { - "@types/node": "7.0.43", + "@types/node": "^8.10.25", "mocha-junit-reporter": "^1.17.0", "mocha-multi-reporters": "^1.1.7", "vscode": "1.1.5" diff --git a/extensions/vscode-colorize-tests/yarn.lock b/extensions/vscode-colorize-tests/yarn.lock index 5aa4e04741c..b4e9355d74f 100644 --- a/extensions/vscode-colorize-tests/yarn.lock +++ b/extensions/vscode-colorize-tests/yarn.lock @@ -2,9 +2,9 @@ # yarn lockfile v1 -"@types/node@7.0.43": - version "7.0.43" - resolved "https://registry.yarnpkg.com/@types/node/-/node-7.0.43.tgz#a187e08495a075f200ca946079c914e1a5fe962c" +"@types/node@^8.10.25": + version "8.10.25" + resolved "https://registry.yarnpkg.com/@types/node/-/node-8.10.25.tgz#801fe4e39372cef18f268db880a5fbfcf71adc7e" ajv@^5.1.0: version "5.3.0" From c93fe0d58bf38d3a7ae0d742ee09782382de3b56 Mon Sep 17 00:00:00 2001 From: Johannes Rieken Date: Tue, 14 Aug 2018 10:53:59 +0200 Subject: [PATCH 0785/1276] ensure uploading source maps happens *after* they have been created --- build/gulpfile.vscode.js | 2 +- build/lib/extensions.js | 2 ++ build/lib/extensions.ts | 3 +++ 3 files changed, 6 insertions(+), 1 deletion(-) diff --git a/build/gulpfile.vscode.js b/build/gulpfile.vscode.js index 54648e7f5ef..54c55ef6bae 100644 --- a/build/gulpfile.vscode.js +++ b/build/gulpfile.vscode.js @@ -451,7 +451,7 @@ gulp.task('vscode-translations-import', function () { // Sourcemaps -gulp.task('upload-vscode-sourcemaps', ['minify-vscode'], () => { +gulp.task('upload-vscode-sourcemaps', ['vscode-darwin-min'/*here to ensure webpack has happened*/, 'minify-vscode'], () => { const vs = gulp.src('out-vscode-min/**/*.map', { base: 'out-vscode-min' }) .pipe(es.mapSync(f => { f.path = `${f.base}/core/${f.relative}`; diff --git a/build/lib/extensions.js b/build/lib/extensions.js index 51b5dd2a576..9afed560031 100644 --- a/build/lib/extensions.js +++ b/build/lib/extensions.js @@ -36,6 +36,7 @@ function fromLocal(extensionPath, sourceMappingURLBase) { // and merge its output with the files stream. also rewrite the package.json // file to a new entry point if (fs.existsSync(path.join(extensionPath, 'extension.webpack.config.js'))) { + console.log("Using Webpack for \"" + extensionPath + "\""); var packageJsonFilter = filter('package.json', { restore: true }); var patchFilesStream = filesStream .pipe(packageJsonFilter) @@ -67,6 +68,7 @@ function fromLocal(extensionPath, sourceMappingURLBase) { fs.mkdirSync(path.dirname(data.path)); } fs.writeFileSync(data.path, data.contents); + console.log("Webpack source maps saved as \"" + data.path + "\""); } } this.emit('data', data); diff --git a/build/lib/extensions.ts b/build/lib/extensions.ts index 206572f23ff..ebfca72e1d1 100644 --- a/build/lib/extensions.ts +++ b/build/lib/extensions.ts @@ -40,6 +40,8 @@ export function fromLocal(extensionPath: string, sourceMappingURLBase?: string): // and merge its output with the files stream. also rewrite the package.json // file to a new entry point if (fs.existsSync(path.join(extensionPath, 'extension.webpack.config.js'))) { + console.log(`Using Webpack for "${extensionPath}"`); + const packageJsonFilter = filter('package.json', { restore: true }); const patchFilesStream = filesStream @@ -74,6 +76,7 @@ export function fromLocal(extensionPath: string, sourceMappingURLBase?: string): fs.mkdirSync(path.dirname(data.path)); } fs.writeFileSync(data.path, data.contents); + console.log(`Webpack source maps saved as "${data.path}"`); } } this.emit('data', data); From c24122b3fc724b5acdf7e757f57639d0b5e2f85e Mon Sep 17 00:00:00 2001 From: Johannes Rieken Date: Tue, 14 Aug 2018 11:22:56 +0200 Subject: [PATCH 0786/1276] merge IStartupMetrics and IStartupReflections, #56253 --- .../electron-browser/startupTimings.ts | 90 ++++++++----------- 1 file changed, 39 insertions(+), 51 deletions(-) diff --git a/src/vs/workbench/parts/performance/electron-browser/startupTimings.ts b/src/vs/workbench/parts/performance/electron-browser/startupTimings.ts index 25ae117b18e..cbbe1712b66 100644 --- a/src/vs/workbench/parts/performance/electron-browser/startupTimings.ts +++ b/src/vs/workbench/parts/performance/electron-browser/startupTimings.ts @@ -10,9 +10,8 @@ import { ILifecycleService, LifecyclePhase, StartupKind } from 'vs/platform/life import { IWindowsService } from 'vs/platform/windows/common/windows'; import { IWorkbenchContributionsRegistry, IWorkbenchContribution, Extensions } from 'vs/workbench/common/contributions'; import { Registry } from 'vs/platform/registry/common/platform'; -import { TPromise } from 'vs/base/common/winjs.base'; import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry'; -import { ITimerService } from 'vs/workbench/services/timer/common/timerService'; +import { ITimerService, IStartupMetrics } from 'vs/workbench/services/timer/common/timerService'; import { onUnexpectedError } from 'vs/base/common/errors'; import { IViewletService } from 'vs/workbench/services/viewlet/browser/viewlet'; import * as files from 'vs/workbench/parts/files/common/files'; @@ -72,6 +71,8 @@ interface IStartupReflections { editorIds: string[]; } +type IStartupTimings = IStartupMetrics & IStartupReflections; + class StartupTimings implements IWorkbenchContribution { constructor( @@ -89,22 +90,18 @@ class StartupTimings implements IWorkbenchContribution { this._reportVariedStartupTimes().then(undefined, onUnexpectedError); this._reportStandardStartupTimes().then(undefined, onUnexpectedError); - this._reportStartupReflections().then(undefined, onUnexpectedError); } private async _reportVariedStartupTimes(): Promise { - await Promise.all([ - this._extensionService.whenInstalledExtensionsRegistered(), - this._lifecycleService.when(LifecyclePhase.Eventually) - ]); /* __GDPR__ "startupTimeVaried" : { "${include}": [ - "${IStartupMetrics}" + "${IStartupMetrics}", + "${IStartupReflections}" ] } */ - this._telemetryService.publicLog('startupTimeVaried', this._timerService.startupMetrics); + this._telemetryService.publicLog('startupTimeVaried', await this._getStartupTimings()); } private async _reportStandardStartupTimes(): Promise { @@ -135,7 +132,7 @@ class StartupTimings implements IWorkbenchContribution { this._logService.info('no standard startup: panel is active'); return; } - if (!this._didUseCachedData()) { + if (!_didUseCachedData()) { this._logService.info('no standard startup: not using cached data'); return; } @@ -143,46 +140,29 @@ class StartupTimings implements IWorkbenchContribution { this._logService.info('no standard startup: not running latest version'); return; } - // wait only know so that can check the restored state as soon as possible - await TPromise.join([ - this._extensionService.whenInstalledExtensionsRegistered(), - this._lifecycleService.when(LifecyclePhase.Eventually) - ]); /* __GDPR__ "startupTime" : { "${include}": [ - "${IStartupMetrics}" + "${IStartupMetrics}", + "${IStartupReflections}" ] } */ - this._telemetryService.publicLog('startupTime', this._timerService.startupMetrics); - this._logService.info('standard startup', this._timerService.startupMetrics); + const timings = await this._getStartupTimings(); + this._telemetryService.publicLog('startupTime', timings); + this._logService.info('standard startup', timings); } - private async _reportStartupReflections(): Promise { + private async _getStartupTimings(): Promise { + await Promise.all([ this._extensionService.whenInstalledExtensionsRegistered(), this._lifecycleService.when(LifecyclePhase.Eventually) ]); - //todo@joh/ramya decide how to send this data, as single event merged with the timing or - // separate. - - /* __GDPR__ - "startupReflections" : { - "${include}": [ - "${IStartupReflections}" - ] - } - */ - this._telemetryService.publicLog('startupReflections', await this._createStartupReflections()); - } - - private async _createStartupReflections(): Promise { - const isLatestVersion = Boolean(await this._updateService.isLatestVersion()); - const didUseCachedData = this._didUseCachedData(); + const didUseCachedData = _didUseCachedData(); const windowKind = this._lifecycleService.startupKind; const windowCount = await this._windowsService.getWindowCount(); @@ -191,7 +171,7 @@ class StartupTimings implements IWorkbenchContribution { const editorIds = this._editorService.visibleEditors.map(input => input.getTypeId()); const panelId = this._panelService.getActivePanel() ? this._panelService.getActivePanel().getId() : undefined; - return { + const reflections = { isLatestVersion, didUseCachedData, windowKind, @@ -200,25 +180,33 @@ class StartupTimings implements IWorkbenchContribution { panelId, editorIds }; - } - private _didUseCachedData(): boolean { - // We surely don't use cached data when we don't tell the loader to do so - if (!Boolean((global).require.getConfig().nodeCachedDataDir)) { - return false; - } - // whenever cached data is produced or rejected a onNodeCachedData-callback is invoked. That callback - // stores data in the `MonacoEnvironment.onNodeCachedData` global. See: - // https://github.com/Microsoft/vscode/blob/efe424dfe76a492eab032343e2fa4cfe639939f0/src/vs/workbench/electron-browser/bootstrap/index.js#L299 - if (!isFalsyOrEmpty(MonacoEnvironment.onNodeCachedData)) { - return false; - } - return true; + const metrics = this._timerService.startupMetrics; + return { ...reflections, ...metrics }; } } +const registry = Registry.as(Extensions.Workbench); +registry.registerWorkbenchContribution(StartupTimings, LifecyclePhase.Running); + + +//#region cached data logic + +function _didUseCachedData(): boolean { + // We surely don't use cached data when we don't tell the loader to do so + if (!Boolean((global).require.getConfig().nodeCachedDataDir)) { + return false; + } + // whenever cached data is produced or rejected a onNodeCachedData-callback is invoked. That callback + // stores data in the `MonacoEnvironment.onNodeCachedData` global. See: + // https://github.com/Microsoft/vscode/blob/efe424dfe76a492eab032343e2fa4cfe639939f0/src/vs/workbench/electron-browser/bootstrap/index.js#L299 + if (!isFalsyOrEmpty(MonacoEnvironment.onNodeCachedData)) { + return false; + } + return true; +} + declare type OnNodeCachedDataArgs = [{ errorCode: string, path: string, detail?: string }, { path: string, length: number }]; declare const MonacoEnvironment: { onNodeCachedData: OnNodeCachedDataArgs[] }; -const registry = Registry.as(Extensions.Workbench); -registry.registerWorkbenchContribution(StartupTimings, LifecyclePhase.Running); +//#endregion From 564dfac1d3e53d823cef27581ddd94a3eb597b04 Mon Sep 17 00:00:00 2001 From: Johannes Rieken Date: Tue, 14 Aug 2018 12:55:15 +0200 Subject: [PATCH 0787/1276] bla --- build/gulpfile.vscode.js | 2 +- build/tfs/darwin/product-build-darwin.yml | 5 +++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/build/gulpfile.vscode.js b/build/gulpfile.vscode.js index 54c55ef6bae..54648e7f5ef 100644 --- a/build/gulpfile.vscode.js +++ b/build/gulpfile.vscode.js @@ -451,7 +451,7 @@ gulp.task('vscode-translations-import', function () { // Sourcemaps -gulp.task('upload-vscode-sourcemaps', ['vscode-darwin-min'/*here to ensure webpack has happened*/, 'minify-vscode'], () => { +gulp.task('upload-vscode-sourcemaps', ['minify-vscode'], () => { const vs = gulp.src('out-vscode-min/**/*.map', { base: 'out-vscode-min' }) .pipe(es.mapSync(f => { f.path = `${f.base}/core/${f.relative}`; diff --git a/build/tfs/darwin/product-build-darwin.yml b/build/tfs/darwin/product-build-darwin.yml index 0dd31503586..77cd79f4512 100644 --- a/build/tfs/darwin/product-build-darwin.yml +++ b/build/tfs/darwin/product-build-darwin.yml @@ -21,7 +21,8 @@ steps: set -e VSCODE_MIXIN_PASSWORD="$(VSCODE_MIXIN_PASSWORD)" \ AZURE_STORAGE_ACCESS_KEY="$(AZURE_STORAGE_ACCESS_KEY)" \ - npm run gulp -- vscode-darwin-min upload-vscode-sourcemaps + npm run gulp -- vscode-darwin-min + npm run gulp -- upload-vscode-sourcemaps name: build - script: | @@ -60,4 +61,4 @@ steps: node build/tfs/darwin/enqueue.js "$(VSCODE_QUALITY)" AZURE_STORAGE_ACCESS_KEY="$(AZURE_STORAGE_ACCESS_KEY)" \ - npm run gulp -- upload-vscode-configuration \ No newline at end of file + npm run gulp -- upload-vscode-configuration From 7372be0a4fa1d24c2225e04eff7cd0580ac6fd29 Mon Sep 17 00:00:00 2001 From: Johannes Rieken Date: Tue, 14 Aug 2018 14:23:22 +0200 Subject: [PATCH 0788/1276] Revert "bla" This reverts commit 564dfac1d3e53d823cef27581ddd94a3eb597b04. --- build/gulpfile.vscode.js | 2 +- build/tfs/darwin/product-build-darwin.yml | 5 ++--- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/build/gulpfile.vscode.js b/build/gulpfile.vscode.js index 54648e7f5ef..54c55ef6bae 100644 --- a/build/gulpfile.vscode.js +++ b/build/gulpfile.vscode.js @@ -451,7 +451,7 @@ gulp.task('vscode-translations-import', function () { // Sourcemaps -gulp.task('upload-vscode-sourcemaps', ['minify-vscode'], () => { +gulp.task('upload-vscode-sourcemaps', ['vscode-darwin-min'/*here to ensure webpack has happened*/, 'minify-vscode'], () => { const vs = gulp.src('out-vscode-min/**/*.map', { base: 'out-vscode-min' }) .pipe(es.mapSync(f => { f.path = `${f.base}/core/${f.relative}`; diff --git a/build/tfs/darwin/product-build-darwin.yml b/build/tfs/darwin/product-build-darwin.yml index 77cd79f4512..0dd31503586 100644 --- a/build/tfs/darwin/product-build-darwin.yml +++ b/build/tfs/darwin/product-build-darwin.yml @@ -21,8 +21,7 @@ steps: set -e VSCODE_MIXIN_PASSWORD="$(VSCODE_MIXIN_PASSWORD)" \ AZURE_STORAGE_ACCESS_KEY="$(AZURE_STORAGE_ACCESS_KEY)" \ - npm run gulp -- vscode-darwin-min - npm run gulp -- upload-vscode-sourcemaps + npm run gulp -- vscode-darwin-min upload-vscode-sourcemaps name: build - script: | @@ -61,4 +60,4 @@ steps: node build/tfs/darwin/enqueue.js "$(VSCODE_QUALITY)" AZURE_STORAGE_ACCESS_KEY="$(AZURE_STORAGE_ACCESS_KEY)" \ - npm run gulp -- upload-vscode-configuration + npm run gulp -- upload-vscode-configuration \ No newline at end of file From 4962417ffc2351dcbf9dfa5df10afcbdcfaa8c44 Mon Sep 17 00:00:00 2001 From: Johannes Rieken Date: Tue, 14 Aug 2018 14:23:35 +0200 Subject: [PATCH 0789/1276] Revert "ensure uploading source maps happens *after* they have been created" This reverts commit c93fe0d58bf38d3a7ae0d742ee09782382de3b56. --- build/gulpfile.vscode.js | 2 +- build/lib/extensions.js | 2 -- build/lib/extensions.ts | 3 --- 3 files changed, 1 insertion(+), 6 deletions(-) diff --git a/build/gulpfile.vscode.js b/build/gulpfile.vscode.js index 54c55ef6bae..54648e7f5ef 100644 --- a/build/gulpfile.vscode.js +++ b/build/gulpfile.vscode.js @@ -451,7 +451,7 @@ gulp.task('vscode-translations-import', function () { // Sourcemaps -gulp.task('upload-vscode-sourcemaps', ['vscode-darwin-min'/*here to ensure webpack has happened*/, 'minify-vscode'], () => { +gulp.task('upload-vscode-sourcemaps', ['minify-vscode'], () => { const vs = gulp.src('out-vscode-min/**/*.map', { base: 'out-vscode-min' }) .pipe(es.mapSync(f => { f.path = `${f.base}/core/${f.relative}`; diff --git a/build/lib/extensions.js b/build/lib/extensions.js index 9afed560031..51b5dd2a576 100644 --- a/build/lib/extensions.js +++ b/build/lib/extensions.js @@ -36,7 +36,6 @@ function fromLocal(extensionPath, sourceMappingURLBase) { // and merge its output with the files stream. also rewrite the package.json // file to a new entry point if (fs.existsSync(path.join(extensionPath, 'extension.webpack.config.js'))) { - console.log("Using Webpack for \"" + extensionPath + "\""); var packageJsonFilter = filter('package.json', { restore: true }); var patchFilesStream = filesStream .pipe(packageJsonFilter) @@ -68,7 +67,6 @@ function fromLocal(extensionPath, sourceMappingURLBase) { fs.mkdirSync(path.dirname(data.path)); } fs.writeFileSync(data.path, data.contents); - console.log("Webpack source maps saved as \"" + data.path + "\""); } } this.emit('data', data); diff --git a/build/lib/extensions.ts b/build/lib/extensions.ts index ebfca72e1d1..206572f23ff 100644 --- a/build/lib/extensions.ts +++ b/build/lib/extensions.ts @@ -40,8 +40,6 @@ export function fromLocal(extensionPath: string, sourceMappingURLBase?: string): // and merge its output with the files stream. also rewrite the package.json // file to a new entry point if (fs.existsSync(path.join(extensionPath, 'extension.webpack.config.js'))) { - console.log(`Using Webpack for "${extensionPath}"`); - const packageJsonFilter = filter('package.json', { restore: true }); const patchFilesStream = filesStream @@ -76,7 +74,6 @@ export function fromLocal(extensionPath: string, sourceMappingURLBase?: string): fs.mkdirSync(path.dirname(data.path)); } fs.writeFileSync(data.path, data.contents); - console.log(`Webpack source maps saved as "${data.path}"`); } } this.emit('data', data); From 0b423d627aba95c2ea884f7b31f451df4ee473a1 Mon Sep 17 00:00:00 2001 From: Johannes Rieken Date: Tue, 14 Aug 2018 15:02:53 +0200 Subject: [PATCH 0790/1276] another try --- build/gulpfile.vscode.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build/gulpfile.vscode.js b/build/gulpfile.vscode.js index 54648e7f5ef..d79071e56bc 100644 --- a/build/gulpfile.vscode.js +++ b/build/gulpfile.vscode.js @@ -451,7 +451,7 @@ gulp.task('vscode-translations-import', function () { // Sourcemaps -gulp.task('upload-vscode-sourcemaps', ['minify-vscode'], () => { +gulp.task('upload-vscode-sourcemaps', ['vscode-darwin-min', 'minify-vscode'], () => { const vs = gulp.src('out-vscode-min/**/*.map', { base: 'out-vscode-min' }) .pipe(es.mapSync(f => { f.path = `${f.base}/core/${f.relative}`; From 5de43b5ab3566b66681b40f729ede033d573339c Mon Sep 17 00:00:00 2001 From: Andre Weinand Date: Tue, 14 Aug 2018 15:50:28 +0200 Subject: [PATCH 0791/1276] improve loaded scripts hover; fixes #55459 --- .../parts/debug/browser/loadedScriptsView.ts | 44 ++++++++++++++++--- 1 file changed, 37 insertions(+), 7 deletions(-) diff --git a/src/vs/workbench/parts/debug/browser/loadedScriptsView.ts b/src/vs/workbench/parts/debug/browser/loadedScriptsView.ts index 6151ef068a4..6c0ea42c896 100644 --- a/src/vs/workbench/parts/debug/browser/loadedScriptsView.ts +++ b/src/vs/workbench/parts/debug/browser/loadedScriptsView.ts @@ -38,24 +38,37 @@ const ROOT_FOLDER_TEMPLATE_ID = 'node'; class BaseTreeItem { + private static SEQUENCE = 1; + private _id: string; private _children: { [key: string]: BaseTreeItem; }; private _source: Source; constructor(private _parent: BaseTreeItem, private _label: string) { - this._id = this._parent ? `${this._parent._id}/${this._label}` : this._label; + this._id = `${BaseTreeItem.SEQUENCE++}`; this._children = {}; } - getLabel() { + getLabel(showRootFolder = true) { const child = this.oneChild(); if (child) { - const sep = this instanceof RootFolderTreeItem ? ' • ' : '/'; + const sep = (this instanceof RootFolderTreeItem && showRootFolder) ? ' • ' : '/'; return `${this._label}${sep}${child.getLabel()}`; } return this._label; } + getHoverLabel(): string { + let label = this.getLabel(false); + if (this._parent) { + const parentLabel = this._parent.getHoverLabel(); + if (parentLabel) { + return `${parentLabel}/${label}`; + } + } + return label; + } + getId(): string { return this._id; } @@ -64,6 +77,19 @@ class BaseTreeItem { return SOURCE_TEMPLATE_ID; } + /* + getParent(): BaseTreeItem { + if (this._parent) { + const child = this._parent.oneChild(); + if (child) { + return this._parent.getParent(); + } + return this._parent; + } + return undefined; + } + */ + getChildren(): TPromise { const child = this.oneChild(); if (child) { @@ -81,7 +107,7 @@ class BaseTreeItem { return Object.keys(this._children).length > 0; } - getSource() { + getSource(): Source { const child = this.oneChild(); if (child) { return child.getSource(); @@ -181,6 +207,10 @@ class SessionTreeItem extends BaseTreeItem { this._session = session; } + getHoverLabel(): string { + return undefined; + } + getTemplateId(): string { return SESSION_TEMPLATE_ID; } @@ -473,17 +503,17 @@ class LoadedScriptsRenderer implements IRenderer { } private renderSession(session: SessionTreeItem, data: ISessionTemplateData): void { - data.session.title = 'session'; + data.session.title = nls.localize('loadedScriptsSession', "Session"); data.session.textContent = session.getLabel(); } private renderSource(source: BaseTreeItem, data: ISourceTemplateData): void { - data.source.title = 'source'; + data.source.title = source.getHoverLabel(); data.source.textContent = source.getLabel(); } private renderNode(node: BaseTreeItem, data: INodeTemplateData): void { - data.node.title = 'node'; + data.node.title = node.getHoverLabel(); data.node.textContent = node.getLabel(); } } From 121bb10fd176fc29e790581449518554d53228b2 Mon Sep 17 00:00:00 2001 From: Sandeep Somavarapu Date: Tue, 14 Aug 2018 15:57:05 +0200 Subject: [PATCH 0792/1276] Simplify extension management: - Remove server options while managing extension --- .../common/extensionManagement.ts | 2 + .../common/multiExtensionManagement.ts | 8 +- .../parts/extensions/common/extensions.ts | 3 +- .../extensions/common/extensionsInput.ts | 3 - .../electron-browser/extensionEditor.ts | 11 +- .../electron-browser/extensionTipsService.ts | 15 +- .../extensions.contribution.ts | 2 +- .../electron-browser/extensionsActions.ts | 522 ++---------------- .../electron-browser/extensionsList.ts | 14 +- .../electron-browser/extensionsViews.ts | 38 +- .../node/extensionsWorkbenchService.ts | 33 +- .../extensionsActions.test.ts | 5 +- .../node/extensionManagementServerService.ts | 4 +- 13 files changed, 80 insertions(+), 580 deletions(-) diff --git a/src/vs/platform/extensionManagement/common/extensionManagement.ts b/src/vs/platform/extensionManagement/common/extensionManagement.ts index e30d7e8787e..99e4f12b96d 100644 --- a/src/vs/platform/extensionManagement/common/extensionManagement.ts +++ b/src/vs/platform/extensionManagement/common/extensionManagement.ts @@ -13,6 +13,7 @@ import { createDecorator } from 'vs/platform/instantiation/common/instantiation' import { ILocalization } from 'vs/platform/localizations/common/localizations'; import URI from 'vs/base/common/uri'; import { IWorkspaceFolder, IWorkspace } from 'vs/platform/workspace/common/workspace'; +import { Schemas } from 'vs/base/common/network'; export const EXTENSION_IDENTIFIER_PATTERN = '^([a-z0-9A-Z][a-z0-9\-A-Z]*)\\.([a-z0-9A-Z][a-z0-9\-A-Z]*)$'; export const EXTENSION_IDENTIFIER_REGEX = new RegExp(EXTENSION_IDENTIFIER_PATTERN); @@ -317,6 +318,7 @@ export interface IExtensionManagementService { } export const IExtensionManagementServerService = createDecorator('extensionManagementServerService'); +export const localExtensionManagementServerLocation: URI = URI.from({ scheme: Schemas.file }); export interface IExtensionManagementServer { extensionManagementService: IExtensionManagementService; diff --git a/src/vs/platform/extensionManagement/common/multiExtensionManagement.ts b/src/vs/platform/extensionManagement/common/multiExtensionManagement.ts index c9308a0d0f1..26530f18c45 100644 --- a/src/vs/platform/extensionManagement/common/multiExtensionManagement.ts +++ b/src/vs/platform/extensionManagement/common/multiExtensionManagement.ts @@ -7,7 +7,7 @@ import { TPromise } from 'vs/base/common/winjs.base'; import { Event, EventMultiplexer } from 'vs/base/common/event'; import { IExtensionManagementService, ILocalExtension, IGalleryExtension, LocalExtensionType, InstallExtensionEvent, DidInstallExtensionEvent, IExtensionIdentifier, DidUninstallExtensionEvent, IReportedExtension, IGalleryMetadata, - IExtensionManagementServerService, IExtensionManagementServer + IExtensionManagementServerService, IExtensionManagementServer, localExtensionManagementServerLocation } from 'vs/platform/extensionManagement/common/extensionManagement'; import { flatten } from 'vs/base/common/arrays'; @@ -50,15 +50,15 @@ export class MulitExtensionManagementService implements IExtensionManagementServ } install(zipPath: string): TPromise { - return this.servers[0].extensionManagementService.install(zipPath); + return this.extensionManagementServerService.getExtensionManagementServer(localExtensionManagementServerLocation).extensionManagementService.install(zipPath); } installFromGallery(extension: IGalleryExtension): TPromise { - return TPromise.join(this.servers.map(server => server.extensionManagementService.installFromGallery(extension))).then(() => null); + return TPromise.join(this.servers.map(({ extensionManagementService }) => extensionManagementService.installFromGallery(extension))).then(() => null); } getExtensionsReport(): TPromise { - return this.servers[0].extensionManagementService.getExtensionsReport(); + return this.extensionManagementServerService.getExtensionManagementServer(localExtensionManagementServerLocation).extensionManagementService.getExtensionsReport(); } private getServer(extension: ILocalExtension): IExtensionManagementServer { diff --git a/src/vs/workbench/parts/extensions/common/extensions.ts b/src/vs/workbench/parts/extensions/common/extensions.ts index 4a08d9122f7..f80eddc2997 100644 --- a/src/vs/workbench/parts/extensions/common/extensions.ts +++ b/src/vs/workbench/parts/extensions/common/extensions.ts @@ -8,7 +8,7 @@ import { createDecorator } from 'vs/platform/instantiation/common/instantiation' import { Event } from 'vs/base/common/event'; import { TPromise } from 'vs/base/common/winjs.base'; import { IPager } from 'vs/base/common/paging'; -import { IQueryOptions, IExtensionManifest, LocalExtensionType, EnablementState, ILocalExtension, IGalleryExtension, ExtensionRecommendationSource } from 'vs/platform/extensionManagement/common/extensionManagement'; +import { IQueryOptions, IExtensionManifest, LocalExtensionType, EnablementState, ILocalExtension, IGalleryExtension } from 'vs/platform/extensionManagement/common/extensionManagement'; import { IViewContainersRegistry, ViewContainer, Extensions as ViewContainerExtensions } from 'vs/workbench/common/views'; import { Registry } from 'vs/platform/registry/common/platform'; @@ -61,7 +61,6 @@ export interface IExtension { locals?: ILocalExtension[]; gallery?: IGalleryExtension; isMalicious: boolean; - recommendationSources: ExtensionRecommendationSource[]; } export interface IExtensionDependencies { diff --git a/src/vs/workbench/parts/extensions/common/extensionsInput.ts b/src/vs/workbench/parts/extensions/common/extensionsInput.ts index 3a7642cd39a..fab4abc019a 100644 --- a/src/vs/workbench/parts/extensions/common/extensionsInput.ts +++ b/src/vs/workbench/parts/extensions/common/extensionsInput.ts @@ -10,17 +10,14 @@ import { TPromise } from 'vs/base/common/winjs.base'; import { EditorInput } from 'vs/workbench/common/editor'; import { IExtension } from 'vs/workbench/parts/extensions/common/extensions'; import URI from 'vs/base/common/uri'; -import { IExtensionManagementServerService, IExtensionManagementServer } from 'vs/platform/extensionManagement/common/extensionManagement'; export class ExtensionsInput extends EditorInput { static readonly ID = 'workbench.extensions.input2'; get extension(): IExtension { return this._extension; } - get servers(): IExtensionManagementServer[] { return this.extensionManagementServerService.extensionManagementServers; } constructor( private _extension: IExtension, - @IExtensionManagementServerService private extensionManagementServerService: IExtensionManagementServerService ) { super(); } diff --git a/src/vs/workbench/parts/extensions/electron-browser/extensionEditor.ts b/src/vs/workbench/parts/extensions/electron-browser/extensionEditor.ts index 4b0c0b54bba..69bc1703280 100644 --- a/src/vs/workbench/parts/extensions/electron-browser/extensionEditor.ts +++ b/src/vs/workbench/parts/extensions/electron-browser/extensionEditor.ts @@ -30,7 +30,7 @@ import { IExtensionsWorkbenchService, IExtensionsViewlet, VIEWLET_ID, IExtension import { RatingsWidget, InstallCountWidget } from 'vs/workbench/parts/extensions/browser/extensionsWidgets'; import { EditorOptions } from 'vs/workbench/common/editor'; import { ActionBar } from 'vs/base/browser/ui/actionbar/actionbar'; -import { CombinedInstallAction, UpdateAction, EnableAction, DisableAction, ReloadAction, MaliciousStatusLabelAction, DisabledStatusLabelAction, MultiServerInstallAction, MultiServerUpdateAction, IgnoreExtensionRecommendationAction, UndoIgnoreExtensionRecommendationAction } from 'vs/workbench/parts/extensions/electron-browser/extensionsActions'; +import { CombinedInstallAction, UpdateAction, EnableAction, DisableAction, ReloadAction, MaliciousStatusLabelAction, DisabledStatusLabelAction, IgnoreExtensionRecommendationAction, UndoIgnoreExtensionRecommendationAction } from 'vs/workbench/parts/extensions/electron-browser/extensionsActions'; import { WebviewElement } from 'vs/workbench/parts/webview/electron-browser/webviewElement'; import { KeybindingIO } from 'vs/workbench/services/keybinding/common/keybindingIO'; import { IKeybindingService } from 'vs/platform/keybinding/common/keybinding'; @@ -250,12 +250,6 @@ export class ExtensionEditor extends BaseEditor { if (action.id === DisableAction.ID) { return (action).actionItem; } - if (action.id === MultiServerInstallAction.ID) { - return (action).actionItem; - } - if (action.id === MultiServerUpdateAction.ID) { - return (action).actionItem; - } return null; } }); @@ -286,7 +280,6 @@ export class ExtensionEditor extends BaseEditor { setInput(input: ExtensionsInput, options: EditorOptions, token: CancellationToken): Thenable { this.editorLoadComplete = false; const extension = input.extension; - const servers = input.servers; this.transientDisposables = dispose(this.transientDisposables); @@ -377,7 +370,7 @@ export class ExtensionEditor extends BaseEditor { const maliciousStatusAction = this.instantiationService.createInstance(MaliciousStatusLabelAction, true); const disabledStatusAction = this.instantiationService.createInstance(DisabledStatusLabelAction); const installAction = this.instantiationService.createInstance(CombinedInstallAction); - const updateAction = servers.length === 1 ? this.instantiationService.createInstance(UpdateAction) : this.instantiationService.createInstance(MultiServerUpdateAction); + const updateAction = this.instantiationService.createInstance(UpdateAction); const enableAction = this.instantiationService.createInstance(EnableAction); const disableAction = this.instantiationService.createInstance(DisableAction); const reloadAction = this.instantiationService.createInstance(ReloadAction); diff --git a/src/vs/workbench/parts/extensions/electron-browser/extensionTipsService.ts b/src/vs/workbench/parts/extensions/electron-browser/extensionTipsService.ts index 79af9338ba2..6f9d4a74f5f 100644 --- a/src/vs/workbench/parts/extensions/electron-browser/extensionTipsService.ts +++ b/src/vs/workbench/parts/extensions/electron-browser/extensionTipsService.ts @@ -12,7 +12,7 @@ import { match } from 'vs/base/common/glob'; import * as json from 'vs/base/common/json'; import { IExtensionManagementService, IExtensionGalleryService, IExtensionTipsService, ExtensionRecommendationReason, LocalExtensionType, EXTENSION_IDENTIFIER_PATTERN, - IExtensionsConfigContent, RecommendationChangeNotification, IExtensionRecommendation, ExtensionRecommendationSource, IExtensionManagementServerService, InstallOperation + IExtensionsConfigContent, RecommendationChangeNotification, IExtensionRecommendation, ExtensionRecommendationSource, InstallOperation } from 'vs/platform/extensionManagement/common/extensionManagement'; import { IModelService } from 'vs/editor/common/services/modelService'; import { ITextModel } from 'vs/editor/common/model'; @@ -23,7 +23,7 @@ import { ShowRecommendedExtensionsAction, InstallWorkspaceRecommendedExtensionsA import Severity from 'vs/base/common/severity'; import { IWorkspaceContextService, IWorkspaceFolder, IWorkspace, IWorkspaceFoldersChangeEvent, WorkbenchState } from 'vs/platform/workspace/common/workspace'; import { IFileService } from 'vs/platform/files/common/files'; -import { IExtensionsConfiguration, ConfigurationKey, ShowRecommendationsOnlyOnDemandKey, IExtensionsViewlet } from 'vs/workbench/parts/extensions/common/extensions'; +import { IExtensionsConfiguration, ConfigurationKey, ShowRecommendationsOnlyOnDemandKey, IExtensionsViewlet, IExtensionsWorkbenchService } from 'vs/workbench/parts/extensions/common/extensions'; import { IConfigurationService, ConfigurationTarget } from 'vs/platform/configuration/common/configuration'; import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry'; import * as pfs from 'vs/base/node/pfs'; @@ -104,7 +104,7 @@ export class ExtensionTipsService extends Disposable implements IExtensionTipsSe @IViewletService private viewletService: IViewletService, @INotificationService private notificationService: INotificationService, @IExtensionManagementService private extensionManagementService: IExtensionManagementService, - @IExtensionManagementServerService private extensionManagementServiceService: IExtensionManagementServerService, + @IExtensionsWorkbenchService private extensionWorkbenchService: IExtensionsWorkbenchService, @IExperimentService private experimentService: IExperimentService, ) { super(); @@ -545,9 +545,8 @@ export class ExtensionTipsService extends Disposable implements IExtensionTipsSe const importantRecommendationsIgnoreList = JSON.parse(this.storageService.get('extensionsAssistant/importantRecommendationsIgnore', StorageScope.GLOBAL, '[]')); recommendationsToSuggest = recommendationsToSuggest.filter(id => importantRecommendationsIgnoreList.indexOf(id) === -1 && this.isExtensionAllowedToBeRecommended(id)); - const server = this.extensionManagementServiceService.getExtensionManagementServer(model.uri); - const importantTipsPromise = recommendationsToSuggest.length === 0 ? TPromise.as(null) : server.extensionManagementService.getInstalled(LocalExtensionType.User).then(local => { - const localExtensions = local.map(e => `${e.manifest.publisher.toLowerCase()}.${e.manifest.name.toLowerCase()}`); + const importantTipsPromise = recommendationsToSuggest.length === 0 ? TPromise.as(null) : this.extensionWorkbenchService.queryLocal().then(local => { + const localExtensions = local.map(e => e.id); recommendationsToSuggest = recommendationsToSuggest.filter(id => localExtensions.every(local => local !== id.toLowerCase())); if (!recommendationsToSuggest.length) { return; @@ -575,9 +574,7 @@ export class ExtensionTipsService extends Disposable implements IExtensionTipsSe } */ this.telemetryService.publicLog('extensionRecommendations:popup', { userReaction: 'install', extensionId: name }); - - const installAction = this.instantiationService.createInstance(InstallRecommendedExtensionAction, id, server); - installAction.run().then(() => installAction.dispose()); + this.instantiationService.createInstance(InstallRecommendedExtensionAction, id).run(); } }, { label: localize('showRecommendations', "Show Recommendations"), diff --git a/src/vs/workbench/parts/extensions/electron-browser/extensions.contribution.ts b/src/vs/workbench/parts/extensions/electron-browser/extensions.contribution.ts index 62cd74ec7c8..5ce89339923 100644 --- a/src/vs/workbench/parts/extensions/electron-browser/extensions.contribution.ts +++ b/src/vs/workbench/parts/extensions/electron-browser/extensions.contribution.ts @@ -45,8 +45,8 @@ import { ExtensionHostProfileService } from 'vs/workbench/parts/extensions/elect // Singletons registerSingleton(IExtensionGalleryService, ExtensionGalleryService); -registerSingleton(IExtensionTipsService, ExtensionTipsService); registerSingleton(IExtensionsWorkbenchService, ExtensionsWorkbenchService); +registerSingleton(IExtensionTipsService, ExtensionTipsService); registerSingleton(IExtensionHostProfileService, ExtensionHostProfileService); const workbenchRegistry = Registry.as(WorkbenchExtensions.Workbench); diff --git a/src/vs/workbench/parts/extensions/electron-browser/extensionsActions.ts b/src/vs/workbench/parts/extensions/electron-browser/extensionsActions.ts index 9900d0d5a7a..77daf931345 100644 --- a/src/vs/workbench/parts/extensions/electron-browser/extensionsActions.ts +++ b/src/vs/workbench/parts/extensions/electron-browser/extensionsActions.ts @@ -5,7 +5,6 @@ import 'vs/css!./media/extensionActions'; import { localize } from 'vs/nls'; -import * as semver from 'semver'; import { TPromise } from 'vs/base/common/winjs.base'; import { IAction, Action } from 'vs/base/common/actions'; import { Throttler } from 'vs/base/common/async'; @@ -18,7 +17,7 @@ import { IContextMenuService } from 'vs/platform/contextview/browser/contextView import { IDisposable, dispose, Disposable } from 'vs/base/common/lifecycle'; import { IExtension, ExtensionState, IExtensionsWorkbenchService, VIEWLET_ID, IExtensionsViewlet, AutoUpdateConfigurationKey } from 'vs/workbench/parts/extensions/common/extensions'; import { ExtensionsConfigurationInitialContent } from 'vs/workbench/parts/extensions/common/extensionsFileTemplate'; -import { LocalExtensionType, IExtensionEnablementService, IExtensionTipsService, EnablementState, ExtensionsLabel, IExtensionManagementServer, IExtensionManagementServerService, IExtensionRecommendation, ExtensionRecommendationSource, IExtensionGalleryService, IGalleryExtension, ILocalExtension, IExtensionsConfigContent } from 'vs/platform/extensionManagement/common/extensionManagement'; +import { LocalExtensionType, IExtensionEnablementService, IExtensionTipsService, EnablementState, ExtensionsLabel, IExtensionRecommendation, IGalleryExtension, IExtensionsConfigContent } from 'vs/platform/extensionManagement/common/extensionManagement'; import { areSameExtensions } from 'vs/platform/extensionManagement/common/extensionManagementUtil'; import { IInstantiationService, ServicesAccessor } from 'vs/platform/instantiation/common/instantiation'; import { ToggleViewletAction } from 'vs/workbench/browser/viewlet'; @@ -50,7 +49,6 @@ import { IEditorService } from 'vs/workbench/services/editor/common/editorServic import { IEditorGroupsService } from 'vs/workbench/services/group/common/editorGroupsService'; import { ExtensionsInput } from 'vs/workbench/parts/extensions/common/extensionsInput'; import product from 'vs/platform/node/product'; -import { ContextSubMenu } from 'vs/base/browser/contextmenu'; import { IQuickPickItem, IQuickInputService } from 'vs/platform/quickinput/common/quickInput'; import { CancellationToken } from 'vs/base/common/cancellation'; @@ -75,21 +73,6 @@ const promptDownloadManually = (extension: IGalleryExtension, message: string, i }]); }; -const getExtensionManagementServerForRecommendationSource = (source: ExtensionRecommendationSource, extensionManagementServerService: IExtensionManagementServerService, contextService: IWorkspaceContextService): IExtensionManagementServer => { - if (source instanceof URI) { - return extensionManagementServerService.getExtensionManagementServer(source); - } - if (source === contextService.getWorkspace()) { - return extensionManagementServerService.getDefaultExtensionManagementServer(); - } - for (const workspaceFolder of contextService.getWorkspace().folders) { - if (source === workspaceFolder) { - return extensionManagementServerService.getExtensionManagementServer(workspaceFolder.uri); - } - } - return extensionManagementServerService.getDefaultExtensionManagementServer(); -}; - export interface IExtensionAction extends IAction { extension: IExtension; } @@ -233,8 +216,8 @@ export class UninstallAction extends Action { export class CombinedInstallAction extends Action { private static readonly NoExtensionClass = 'extension-action prominent install no-extension'; - private installAction: MultiServerInstallAction | InstallAction; - private uninstallAction: MultiServerUninstallAction | UninstallAction; + private installAction: InstallAction; + private uninstallAction: UninstallAction; private disposables: IDisposable[] = []; private _extension: IExtension; get extension(): IExtension { return this._extension; } @@ -245,13 +228,12 @@ export class CombinedInstallAction extends Action { } constructor( - @IInstantiationService instantiationService: IInstantiationService, - @IExtensionManagementServerService extensionManagementServerService: IExtensionManagementServerService + @IInstantiationService instantiationService: IInstantiationService ) { super('extensions.combinedInstall', '', '', false); - this.installAction = extensionManagementServerService.extensionManagementServers.length > 1 ? instantiationService.createInstance(MultiServerInstallAction, false) : instantiationService.createInstance(InstallAction); - this.uninstallAction = extensionManagementServerService.extensionManagementServers.length > 1 ? instantiationService.createInstance(MultiServerUninstallAction) : instantiationService.createInstance(UninstallAction); + this.installAction = instantiationService.createInstance(InstallAction); + this.uninstallAction = instantiationService.createInstance(UninstallAction); this.disposables.push(this.installAction, this.uninstallAction); this.installAction.onDidChange(this.update, this, this.disposables); @@ -377,383 +359,6 @@ export class UpdateAction extends Action { } } -export class InstallGalleryExtensionAction extends Action { - - private _server: IExtensionManagementServer; - private _extension: IGalleryExtension; - get extension(): IGalleryExtension { return this._extension; } - set extension(extension: IGalleryExtension) { this._extension = extension; this.enabled = !!this._extension; } - - constructor( - id: string, label: string, server: IExtensionManagementServer, - @INotificationService private notificationService: INotificationService, - @IInstantiationService private instantiationService: IInstantiationService, - @IOpenerService private openerService: IOpenerService - ) { - super(id, label, null, false); - this._server = server; - } - - run(): TPromise { - if (this.extension) { - return this._server.extensionManagementService.installFromGallery(this.extension) - .then(() => null, err => { - console.error(err); - promptDownloadManually(this.extension, localize('failedToInstall', "Failed to install \'{0}\'.", this.extension.identifier.id), this.instantiationService, this.notificationService, this.openerService); - }); - } - return TPromise.as(null); - } -} - -export class UninstallExtensionAction extends Action { - - private _server: IExtensionManagementServer; - private _extension: ILocalExtension; - get extension(): ILocalExtension { return this._extension; } - set extension(extension: ILocalExtension) { this._extension = extension; this.enabled = !!this._extension; } - - constructor( - id: string, label: string, server: IExtensionManagementServer, - ) { - super(id, label, null, false); - this._server = server; - } - - run(): TPromise { - if (this.extension) { - return this._server.extensionManagementService.uninstall(this.extension); - } - return TPromise.as(null); - } -} - -export class UpdateGalleryExtensionAction extends Action { - - private server: IExtensionManagementServer; - - private local: ILocalExtension; - private gallery: IGalleryExtension; - get extension(): { local: ILocalExtension, gallery: IGalleryExtension } { return { local: this.local, gallery: this.gallery }; } - set extension(extension: { local: ILocalExtension, gallery: IGalleryExtension }) { this.local = extension ? extension.local : null; this.gallery = extension ? extension.gallery : null; this.update(); } - - constructor( - id: string, label: string, server: IExtensionManagementServer, - @INotificationService private notificationService: INotificationService, - @IInstantiationService private instantiationService: IInstantiationService, - @IOpenerService private openerService: IOpenerService - ) { - super(id, label, null, false); - this.server = server; - } - - private update(): void { - this.enabled = this.local && this.gallery && this.local.type === LocalExtensionType.User && semver.gt(this.gallery.version, this.local.manifest.version); - this.label = this.enabled ? localize('updateToInServer', "Update to {0} ({1})", this.gallery.version, this.server.location.authority) : localize('updateLabelInServer', "Update ({0})", this.server.location.authority); - } - - run(): TPromise { - if (this.gallery) { - return this.server.extensionManagementService.installFromGallery(this.gallery) - .then(() => null, err => { - console.error(err); - promptDownloadManually(this.gallery, localize('failedToInstall', "Failed to install \'{0}\'.", this.gallery.identifier.id), this.instantiationService, this.notificationService, this.openerService); - }); - } - return TPromise.as(null); - } -} - -export class MultiServerInstallAction extends Action { - - static ID: string = 'extensions.multiserver.install'; - - private static readonly InstallLabel = localize('installAction', "Install"); - private static readonly InstallingLabel = localize('installing', "Installing"); - - private static readonly Class = 'extension-action multiserver prominent install'; - private static readonly InstallingClass = 'extension-action multiserver install installing'; - - private readonly disableWhenInstalled: boolean; - - readonly actions: InstallGalleryExtensionAction[] = []; - private _actionItem: DropDownMenuActionItem; - get actionItem(): IActionItem { return this._actionItem; } - - private _extension: IExtension; - get extension(): IExtension { return this._extension; } - set extension(extension: IExtension) { this._extension = extension; this.update(); } - - private disposables: IDisposable[] = []; - - constructor( - disableWhenInstalled: boolean, - @IExtensionManagementServerService private extensionManagementServerService: IExtensionManagementServerService, - @IInstantiationService private instantiationService: IInstantiationService, - @IExtensionsWorkbenchService private extensionsWorkbenchService: IExtensionsWorkbenchService, - @IWorkspaceContextService private contextService: IWorkspaceContextService - ) { - super(MultiServerInstallAction.ID, MultiServerInstallAction.InstallLabel, MultiServerInstallAction.Class, false); - this.disableWhenInstalled = disableWhenInstalled; - this.actions = this.extensionManagementServerService.extensionManagementServers.map(server => this.instantiationService.createInstance(InstallGalleryExtensionAction, `extensions.install.${server.location.authority}`, localize('installInServer', "{0}", server.location.authority), server)); - this._actionItem = this.instantiationService.createInstance(DropDownMenuActionItem, this, [this.actions]); - this.disposables.push(...[this._actionItem, ...this.actions]); - this.disposables.push(this.extensionsWorkbenchService.onChange(() => { - if (this.extension) { - this.extension = this.extensionsWorkbenchService.local.filter(l => areSameExtensions({ id: l.id }, { id: this.extension.id }))[0] || this.extension; - } - })); - this.update(); - } - - private update(): void { - if (!this.extension || this.extension.type === LocalExtensionType.System) { - this.enabled = false; - this.class = MultiServerInstallAction.Class; - this.label = MultiServerInstallAction.InstallLabel; - return; - } - - if (this.extension.state === ExtensionState.Installing) { - this.label = MultiServerInstallAction.InstallingLabel; - this.class = MultiServerInstallAction.InstallingClass; - this.tooltip = MultiServerInstallAction.InstallingLabel; - } else { - this.label = MultiServerInstallAction.InstallLabel; - this.class = MultiServerInstallAction.Class; - this.tooltip = MultiServerInstallAction.InstallLabel; - } - - const isInstalled = this.extension.locals.length > 0; - - if (isInstalled && this.disableWhenInstalled) { - this.enabled = false; - return; - } - - let isExtensionNotInstalledInRecommendedServer: boolean = false; - this.actions.forEach((installAction, index) => { - const server = this.extensionManagementServerService.extensionManagementServers[index]; - installAction.extension = this.extension.gallery; - installAction.label = localize('installInServer', "{0}", server.location.authority); - installAction.enabled = this.extension.gallery && !this.extension.locals.some(local => this.extensionManagementServerService.getExtensionManagementServer(local.location) === server); - if (this.extension.recommendationSources && this.extension.recommendationSources.length) { - if (this.extension.recommendationSources.some(recommendationSource => getExtensionManagementServerForRecommendationSource(recommendationSource, this.extensionManagementServerService, this.contextService) === server)) { - installAction.label = localize('installInRecommendedServer', "{0} (Recommended)", server.location.authority); - isExtensionNotInstalledInRecommendedServer = isExtensionNotInstalledInRecommendedServer || installAction.enabled; - } - } - }); - - this.enabled = this.extensionsWorkbenchService.canInstall(this.extension) && (isExtensionNotInstalledInRecommendedServer || this.extension.locals.length === 0); - } - - public run(): TPromise { - this._actionItem.showMenu(); - return TPromise.wrap(null); - } - - dispose(): void { - super.dispose(); - this.disposables = dispose(this.disposables); - } -} - -export class MultiServerInstallSubMenuAction extends ContextSubMenu { - - private readonly action: MultiServerInstallAction; - private disposables: IDisposable[] = []; - - private _extension: IExtension; - get extension(): IExtension { return this._extension; } - set extension(extension: IExtension) { this._extension = extension; this.action.extension = extension; } - - constructor( - @IInstantiationService instantiationService: IInstantiationService, - ) { - super('', []); - this.action = instantiationService.createInstance(MultiServerInstallAction, false); - this.disposables.push(this.action); - this.entries = this.action.actions; - this.disposables.push(this.onDidChange(() => this.update())); - this.update(); - } - - private update(): void { - this.label = this.action.label; - this.enabled = this.action.enabled; - } - - dispose(): void { - super.dispose(); - this.disposables = dispose(this.disposables); - } -} - -export class MultiServerUnInstallSubMenuAction extends ContextSubMenu { - - private readonly action: MultiServerUninstallAction; - private disposables: IDisposable[] = []; - - private _extension: IExtension; - get extension(): IExtension { return this._extension; } - set extension(extension: IExtension) { this._extension = extension; this.action.extension = extension; } - - constructor( - @IInstantiationService instantiationService: IInstantiationService, - ) { - super('', []); - this.action = instantiationService.createInstance(MultiServerUninstallAction); - this.disposables.push(this.action); - this.entries = this.action.actions; - this.disposables.push(this.onDidChange(() => this.update())); - this.update(); - } - - private update(): void { - this.label = this.action.label; - this.enabled = this.action.enabled; - } - - dispose(): void { - super.dispose(); - this.disposables = dispose(this.disposables); - } -} - -export class MultiServerUpdateAction extends Action { - - static ID: string = 'extensions.multiserver.update'; - - private static readonly Class = 'extension-action multiserver prominent update'; - - private _updateActions: UpdateGalleryExtensionAction[] = []; - private _actionItem: DropDownMenuActionItem; - get actionItem(): IActionItem { return this._actionItem; } - - private disposables: IDisposable[] = []; - private _extension: IExtension; - get extension(): IExtension { return this._extension; } - set extension(extension: IExtension) { this._extension = extension; this.update(); } - - constructor( - @IExtensionManagementServerService private extensionManagementServerService: IExtensionManagementServerService, - @IInstantiationService private instantiationService: IInstantiationService, - @IExtensionsWorkbenchService private extensionsWorkbenchService: IExtensionsWorkbenchService - ) { - super(MultiServerUpdateAction.ID, localize('update', "Update"), MultiServerUpdateAction.Class, false); - this._updateActions = this.extensionManagementServerService.extensionManagementServers.map(server => this.instantiationService.createInstance(UpdateGalleryExtensionAction, `extensions.update.${server.location.authority}`, localize('installInServer', "{0}", server.location.authority), server)); - this._actionItem = this.instantiationService.createInstance(DropDownMenuActionItem, this, [this._updateActions]); - this.disposables.push(this._actionItem); - this.disposables.push(...this._updateActions); - this.disposables.push(this.extensionsWorkbenchService.onChange(() => this.update())); - this.update(); - } - - private update(): void { - this._updateActions.forEach((updateAction, index) => { - updateAction.extension = null; - if (this.extension && this.extension.locals && this.extension.gallery) { - const server = this.extensionManagementServerService.extensionManagementServers[index]; - const local = this.extension.locals.filter(local => this.extensionManagementServerService.getExtensionManagementServer(local.location) === server)[0]; - updateAction.extension = { local, gallery: this.extension.gallery }; - } - }); - this.enabled = this._updateActions.some(action => action.enabled); - } - - public run(): TPromise { - this._actionItem.showMenu(); - return TPromise.wrap(null); - } - - dispose(): void { - super.dispose(); - this.disposables = dispose(this.disposables); - } -} - -export class MultiServerUninstallAction extends Action { - - static ID: string = 'extensions.multiserver.uninstall'; - - private static readonly UninstallLabel = localize('uninstallAction', "Uninstall"); - private static readonly UninstallingLabel = localize('Uninstalling', "Uninstalling"); - - private static readonly UninstallClass = 'extension-action uninstall'; - private static readonly UnInstallingClass = 'extension-action uninstall uninstalling'; - - readonly actions: UninstallExtensionAction[] = []; - private _actionItem: DropDownMenuActionItem; - get actionItem(): IActionItem { return this._actionItem; } - - private _extension: IExtension; - get extension(): IExtension { return this._extension; } - set extension(extension: IExtension) { this._extension = extension; this.update(); } - - private disposables: IDisposable[] = []; - - constructor( - @IExtensionManagementServerService private extensionManagementServerService: IExtensionManagementServerService, - @IInstantiationService private instantiationService: IInstantiationService, - @IExtensionsWorkbenchService private extensionsWorkbenchService: IExtensionsWorkbenchService, - ) { - super(MultiServerUninstallAction.ID, MultiServerUninstallAction.UninstallLabel, MultiServerUninstallAction.UninstallClass, false); - this.actions = this.extensionManagementServerService.extensionManagementServers.map(server => this.instantiationService.createInstance(UninstallExtensionAction, `extensions.uninstall.${server.location.authority}`, server.location.authority, server)); - this._actionItem = this.instantiationService.createInstance(DropDownMenuActionItem, this, [this.actions]); - this.disposables.push(...[this._actionItem, ...this.actions]); - this.disposables.push(this.extensionsWorkbenchService.onChange(() => this.extension = this.extension ? this.extensionsWorkbenchService.local.filter(l => areSameExtensions({ id: l.id }, { id: this.extension.id }))[0] : this.extension)); - this.update(); - } - - private update(): void { - if (!this.extension) { - this.enabled = false; - } else { - const state = this.extension.state; - - if (state === ExtensionState.Uninstalling) { - this.label = MultiServerUninstallAction.UninstallingLabel; - this.class = MultiServerUninstallAction.UnInstallingClass; - this.enabled = false; - return; - } - - this.label = MultiServerUninstallAction.UninstallLabel; - this.class = MultiServerUninstallAction.UninstallClass; - - const installedExtensions = this.extensionsWorkbenchService.local.filter(e => e.id === this.extension.id); - - if (!installedExtensions.length) { - this.enabled = false; - return; - } - - if (installedExtensions[0].type !== LocalExtensionType.User) { - this.enabled = false; - return; - } - - this.enabled = true; - - this.actions.forEach((installAction, index) => { - const server = this.extensionManagementServerService.extensionManagementServers[index]; - installAction.extension = this.extension.locals.filter(local => this.extensionManagementServerService.getExtensionManagementServer(local.location) === server)[0]; - }); - } - } - - public run(): TPromise { - this._actionItem.showMenu(); - return TPromise.wrap(null); - } - - dispose(): void { - super.dispose(); - this.disposables = dispose(this.disposables); - } -} - export class DropDownMenuActionItem extends ActionItem { private disposables: IDisposable[] = []; @@ -812,8 +417,7 @@ export class ManageExtensionAction extends Action { constructor( @IExtensionsWorkbenchService private extensionsWorkbenchService: IExtensionsWorkbenchService, - @IInstantiationService private instantiationService: IInstantiationService, - @IExtensionManagementServerService private extensionManagmentServerService: IExtensionManagementServerService + @IInstantiationService private instantiationService: IInstantiationService ) { super(ManageExtensionAction.ID); @@ -834,12 +438,7 @@ export class ManageExtensionAction extends Action { this.instantiationService.createInstance(DisableGloballyAction, DisableGloballyAction.LABEL), this.instantiationService.createInstance(DisableForWorkspaceAction, DisableForWorkspaceAction.LABEL) ]); - if (this.extensionManagmentServerService.extensionManagementServers.length > 1) { - groups.push([this.instantiationService.createInstance(MultiServerInstallSubMenuAction)]); - groups.push([this.instantiationService.createInstance(MultiServerUnInstallSubMenuAction)]); - } else { - groups.push([this.instantiationService.createInstance(UninstallAction)]); - } + groups.push([this.instantiationService.createInstance(UninstallAction)]); return groups; } @@ -1290,8 +889,7 @@ export class ReloadAction extends Action { @IExtensionsWorkbenchService private extensionsWorkbenchService: IExtensionsWorkbenchService, @IWindowService private windowService: IWindowService, @IExtensionService private extensionService: IExtensionService, - @IExtensionEnablementService private extensionEnablementService: IExtensionEnablementService, - @IExtensionManagementServerService private extensionManagementServerService: IExtensionManagementServerService + @IExtensionEnablementService private extensionEnablementService: IExtensionEnablementService ) { super('extensions.reload', localize('reloadAction', "Reload"), ReloadAction.DisabledClass, false); this.throttler = new Throttler(); @@ -1327,27 +925,21 @@ export class ReloadAction extends Action { if (installed && installed.local) { if (runningExtension) { - const runningExtensionServer = this.extensionManagementServerService.getExtensionManagementServer(runningExtension.extensionLocation); - const installedExtensionServer = this.extensionManagementServerService.getExtensionManagementServer(installed.local.location); - const isSameLocation = runningExtensionServer.location.toString() === installedExtensionServer.location.toString(); - if (isSameLocation) { - const isDifferentVersionRunning = this.extension.version !== runningExtension.version; - if (isDifferentVersionRunning && !isDisabled) { - // Requires reload to run the updated extension - this.enabled = true; - this.tooltip = localize('postUpdateTooltip', "Reload to update"); - this.reloadMessage = localize('postUpdateMessage', "Reload this window to activate the updated extension '{0}'?", this.extension.displayName); - return; - } - if (isDisabled) { - // Requires reload to disable the extension - this.enabled = true; - this.tooltip = localize('postDisableTooltip', "Reload to deactivate"); - this.reloadMessage = localize('postDisableMessage', "Reload this window to deactivate the extension '{0}'?", this.extension.displayName); - return; - } + const isDifferentVersionRunning = this.extension.version !== runningExtension.version; + if (isDifferentVersionRunning && !isDisabled) { + // Requires reload to run the updated extension + this.enabled = true; + this.tooltip = localize('postUpdateTooltip', "Reload to update"); + this.reloadMessage = localize('postUpdateMessage', "Reload this window to activate the updated extension '{0}'?", this.extension.displayName); + return; + } + if (isDisabled) { + // Requires reload to disable the extension + this.enabled = true; + this.tooltip = localize('postDisableTooltip', "Reload to deactivate"); + this.reloadMessage = localize('postDisableMessage', "Reload this window to deactivate the extension '{0}'?", this.extension.displayName); + return; } - return; } else { if (!isDisabled) { // Requires reload to enable the extension @@ -1596,8 +1188,6 @@ export class InstallWorkspaceRecommendedExtensionsAction extends Action { static readonly ID = 'workbench.extensions.action.installWorkspaceRecommendedExtensions'; static LABEL = localize('installWorkspaceRecommendedExtensions', "Install All Workspace Recommended Extensions"); - private disposables: IDisposable[] = []; - private _recommendations: IExtensionRecommendation[] = []; get recommendations(): IExtensionRecommendation[] { return this._recommendations; } set recommendations(recommendations: IExtensionRecommendation[]) { this._recommendations = recommendations; this.enabled = this._recommendations.length > 0; } @@ -1606,13 +1196,11 @@ export class InstallWorkspaceRecommendedExtensionsAction extends Action { id: string = InstallWorkspaceRecommendedExtensionsAction.ID, label: string = InstallWorkspaceRecommendedExtensionsAction.LABEL, recommendations: IExtensionRecommendation[], - @IWorkspaceContextService private contextService: IWorkspaceContextService, @IViewletService private viewletService: IViewletService, @INotificationService private notificationService: INotificationService, @IInstantiationService private instantiationService: IInstantiationService, @IOpenerService private openerService: IOpenerService, - @IExtensionManagementServerService private extensionManagementServerService: IExtensionManagementServerService, - @IExtensionGalleryService private extensionGalleryService: IExtensionGalleryService + @IExtensionsWorkbenchService private extensionWorkbenchService: IExtensionsWorkbenchService ) { super(id, label, 'extension-action'); this.recommendations = recommendations; @@ -1624,52 +1212,25 @@ export class InstallWorkspaceRecommendedExtensionsAction extends Action { .then(viewlet => { viewlet.search('@recommended '); viewlet.focus(); - if (this.recommendations.length === 0) { - this.notificationService.info(localize('extensionInstalled', "The recommended extension has already been installed")); - return TPromise.as(null); - } - const names = this.recommendations.map(({ extensionId }) => extensionId); - return this.extensionGalleryService.query({ names, source: 'install-all-workspace-recommendations' }).then(pager => { + return this.extensionWorkbenchService.queryGallery({ names, source: 'install-all-workspace-recommendations' }).then(pager => { let installPromises = []; let model = new PagedModel(pager); for (let i = 0; i < pager.total; i++) { installPromises.push(model.resolve(i, CancellationToken.None).then(e => { - return this.install(e); + return this.extensionWorkbenchService.install(e).then(null, err => { + console.error(err); + promptDownloadManually(e.gallery, localize('failedToInstall', "Failed to install \'{0}\'.", e.id), this.instantiationService, this.notificationService, this.openerService); + }); })); } return TPromise.join(installPromises); }); }); } - - private install(extension: IGalleryExtension): TPromise { - const servers: IExtensionManagementServer[] = []; - const recommendation = this.recommendations.filter(r => areSameExtensions({ id: r.extensionId }, extension.identifier))[0]; - if (recommendation) { - for (const source of recommendation.sources || []) { - const server = getExtensionManagementServerForRecommendationSource(source, this.extensionManagementServerService, this.contextService); - if (servers.indexOf(server) === -1) { - servers.push(server); - } - } - } - if (!servers.length) { - servers.push(this.extensionManagementServerService.getDefaultExtensionManagementServer()); - } - return TPromise.join(servers.map(server => server.extensionManagementService.installFromGallery(extension).then(null, err => { - console.error(err); - promptDownloadManually(extension, localize('failedToInstall', "Failed to install \'{0}\'.", extension.identifier.id), this.instantiationService, this.notificationService, this.openerService); - }))).then(() => null); - } - - dispose(): void { - this.disposables = dispose(this.disposables); - super.dispose(); - } } -export class InstallRecommendedExtensionAction extends InstallGalleryExtensionAction { +export class InstallRecommendedExtensionAction extends Action { static readonly ID = 'workbench.extensions.action.installRecommendedExtension'; static LABEL = localize('installRecommendedExtension', "Install Recommended Extension"); @@ -1677,14 +1238,14 @@ export class InstallRecommendedExtensionAction extends InstallGalleryExtensionAc private extensionId: string; constructor( - extensionId: string, server: IExtensionManagementServer, + extensionId: string, @IViewletService private viewletService: IViewletService, - @INotificationService notificationService: INotificationService, - @IInstantiationService instantiationService: IInstantiationService, - @IOpenerService openerService: IOpenerService, - @IExtensionGalleryService private extensionGalleryService: IExtensionGalleryService + @INotificationService private notificationService: INotificationService, + @IInstantiationService private instantiationService: IInstantiationService, + @IOpenerService private openerService: IOpenerService, + @IExtensionsWorkbenchService private extensionWorkbenchService: IExtensionsWorkbenchService ) { - super(InstallRecommendedExtensionAction.ID, InstallRecommendedExtensionAction.LABEL, server, notificationService, instantiationService, openerService); + super(InstallRecommendedExtensionAction.ID, InstallRecommendedExtensionAction.LABEL, null, false); this.extensionId = extensionId; } @@ -1694,12 +1255,17 @@ export class InstallRecommendedExtensionAction extends InstallGalleryExtensionAc .then(viewlet => { viewlet.search('@recommended '); viewlet.focus(); - return this.extensionGalleryService.query({ names: [this.extensionId], source: 'install-recommendation', pageSize: 1 }) + return this.extensionWorkbenchService.queryGallery({ names: [this.extensionId], source: 'install-recommendation', pageSize: 1 }) .then(pager => { if (pager && pager.firstPage && pager.firstPage.length) { - this.extension = pager.firstPage[0]; + const extension = pager.firstPage[0]; + return this.extensionWorkbenchService.install(extension) + .then(() => null, err => { + console.error(err); + promptDownloadManually(extension.gallery, localize('failedToInstall', "Failed to install \'{0}\'.", extension.id), this.instantiationService, this.notificationService, this.openerService); + }); } - return super.run(); + return null; }); }); } diff --git a/src/vs/workbench/parts/extensions/electron-browser/extensionsList.ts b/src/vs/workbench/parts/extensions/electron-browser/extensionsList.ts index 846d0185cd5..f048c242f61 100644 --- a/src/vs/workbench/parts/extensions/electron-browser/extensionsList.ts +++ b/src/vs/workbench/parts/extensions/electron-browser/extensionsList.ts @@ -16,7 +16,7 @@ import { IPagedRenderer } from 'vs/base/browser/ui/list/listPaging'; import { once } from 'vs/base/common/event'; import { domEvent } from 'vs/base/browser/event'; import { IExtension, IExtensionsWorkbenchService } from 'vs/workbench/parts/extensions/common/extensions'; -import { InstallAction, UpdateAction, ManageExtensionAction, ReloadAction, extensionButtonProminentBackground, extensionButtonProminentForeground, MaliciousStatusLabelAction, DisabledStatusLabelAction, MultiServerInstallAction, MultiServerUpdateAction } from 'vs/workbench/parts/extensions/electron-browser/extensionsActions'; +import { InstallAction, UpdateAction, ManageExtensionAction, ReloadAction, extensionButtonProminentBackground, extensionButtonProminentForeground, MaliciousStatusLabelAction, DisabledStatusLabelAction } from 'vs/workbench/parts/extensions/electron-browser/extensionsActions'; import { areSameExtensions } from 'vs/platform/extensionManagement/common/extensionManagementUtil'; import { Label, RatingsWidget, InstallCountWidget } from 'vs/workbench/parts/extensions/browser/extensionsWidgets'; import { IExtensionService } from 'vs/workbench/services/extensions/common/extensions'; @@ -89,12 +89,6 @@ export class Renderer implements IPagedRenderer { if (action.id === ManageExtensionAction.ID) { return (action).actionItem; } - if (action.id === MultiServerInstallAction.ID) { - return (action).actionItem; - } - if (action.id === MultiServerUpdateAction.ID) { - return (action).actionItem; - } return null; } }); @@ -106,10 +100,8 @@ export class Renderer implements IPagedRenderer { const maliciousStatusAction = this.instantiationService.createInstance(MaliciousStatusLabelAction, false); const disabledStatusAction = this.instantiationService.createInstance(DisabledStatusLabelAction); - const installAction = this.extensionManagementServerService.extensionManagementServers.length === 1 ? this.instantiationService.createInstance(InstallAction) - : this.instantiationService.createInstance(MultiServerInstallAction, true); - const updateAction = this.extensionManagementServerService.extensionManagementServers.length === 1 ? this.instantiationService.createInstance(UpdateAction) - : this.instantiationService.createInstance(MultiServerUpdateAction); + const installAction = this.instantiationService.createInstance(InstallAction); + const updateAction = this.instantiationService.createInstance(UpdateAction); const reloadAction = this.instantiationService.createInstance(ReloadAction); const manageAction = this.instantiationService.createInstance(ManageExtensionAction); diff --git a/src/vs/workbench/parts/extensions/electron-browser/extensionsViews.ts b/src/vs/workbench/parts/extensions/electron-browser/extensionsViews.ts index ab3c66b7802..3bfb6cffba9 100644 --- a/src/vs/workbench/parts/extensions/electron-browser/extensionsViews.ts +++ b/src/vs/workbench/parts/extensions/electron-browser/extensionsViews.ts @@ -13,7 +13,7 @@ import { assign } from 'vs/base/common/objects'; import { chain } from 'vs/base/common/event'; import { isPromiseCanceledError, create as createError } from 'vs/base/common/errors'; import { PagedModel, IPagedModel, IPager, DelayedPagedModel } from 'vs/base/common/paging'; -import { SortBy, SortOrder, IQueryOptions, LocalExtensionType, IExtensionTipsService, EnablementState, IExtensionRecommendation, IExtensionManagementServerService, ExtensionRecommendationSource, IExtensionManagementServer } from 'vs/platform/extensionManagement/common/extensionManagement'; +import { SortBy, SortOrder, IQueryOptions, LocalExtensionType, IExtensionTipsService, EnablementState, IExtensionRecommendation } from 'vs/platform/extensionManagement/common/extensionManagement'; import { areSameExtensions } from 'vs/platform/extensionManagement/common/extensionManagementUtil'; import { IKeybindingService } from 'vs/platform/keybinding/common/keybinding'; import { IContextMenuService } from 'vs/platform/contextview/browser/contextView'; @@ -39,7 +39,6 @@ import { INotificationService } from 'vs/platform/notification/common/notificati import { ViewletPanel, IViewletPanelOptions } from 'vs/workbench/browser/parts/views/panelViewlet'; import { IWorkspaceContextService } from 'vs/platform/workspace/common/workspace'; import { distinct } from 'vs/base/common/arrays'; -import URI from 'vs/base/common/uri'; import { IExperimentService } from 'vs/workbench/parts/experiments/node/experimentService'; export class ExtensionsListView extends ViewletPanel { @@ -65,7 +64,6 @@ export class ExtensionsListView extends ViewletPanel { @ITelemetryService private telemetryService: ITelemetryService, @IConfigurationService configurationService: IConfigurationService, @IWorkspaceContextService protected contextService: IWorkspaceContextService, - @IExtensionManagementServerService protected extensionManagementServerService: IExtensionManagementServerService, @IExperimentService private experimentService: IExperimentService ) { super({ ...(options as IViewletPanelOptions), ariaHeaderLabel: options.title }, keybindingService, contextMenuService, configurationService); @@ -487,39 +485,7 @@ export class ExtensionsListView extends ViewletPanel { } private isRecommendationInstalled(recommendation: IExtensionRecommendation, installed: IExtension[]): boolean { - const extension = installed.filter(i => areSameExtensions({ id: i.id }, { id: recommendation.extensionId }))[0]; - if (extension && extension.locals) { - const servers: IExtensionManagementServer[] = []; - for (const local of extension.locals) { - const server = this.extensionManagementServerService.getExtensionManagementServer(local.location); - if (servers.indexOf(server) === -1) { - servers.push(server); - } - } - for (const server of servers) { - if (extension.recommendationSources && extension.recommendationSources.length) { - if (extension.recommendationSources.some(recommendationSource => this.getExtensionManagementServerForRecommendationSource(recommendationSource) === server)) { - return true; - } - } - } - } - return false; - } - - private getExtensionManagementServerForRecommendationSource(source: ExtensionRecommendationSource): IExtensionManagementServer { - if (source instanceof URI) { - return this.extensionManagementServerService.getExtensionManagementServer(source); - } - if (source === this.contextService.getWorkspace()) { - return this.extensionManagementServerService.getDefaultExtensionManagementServer(); - } - for (const workspaceFolder of this.contextService.getWorkspace().folders) { - if (source === workspaceFolder) { - return this.extensionManagementServerService.getExtensionManagementServer(workspaceFolder.uri); - } - } - return this.extensionManagementServerService.getDefaultExtensionManagementServer(); + return installed.some(i => areSameExtensions({ id: i.id }, { id: recommendation.extensionId })); } private getWorkspaceRecommendationsModel(query: Query, options: IQueryOptions): TPromise> { diff --git a/src/vs/workbench/parts/extensions/node/extensionsWorkbenchService.ts b/src/vs/workbench/parts/extensions/node/extensionsWorkbenchService.ts index 15b8bcf0225..c68fc3e92e9 100644 --- a/src/vs/workbench/parts/extensions/node/extensionsWorkbenchService.ts +++ b/src/vs/workbench/parts/extensions/node/extensionsWorkbenchService.ts @@ -18,7 +18,7 @@ import { IPager, mapPager, singlePagePager } from 'vs/base/common/paging'; import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry'; import { IExtensionManagementService, IExtensionGalleryService, ILocalExtension, IGalleryExtension, IQueryOptions, IExtensionManifest, - InstallExtensionEvent, DidInstallExtensionEvent, LocalExtensionType, DidUninstallExtensionEvent, IExtensionEnablementService, IExtensionIdentifier, EnablementState, IExtensionTipsService, ExtensionRecommendationSource, IExtensionRecommendation, IExtensionManagementServerService + InstallExtensionEvent, DidInstallExtensionEvent, LocalExtensionType, DidUninstallExtensionEvent, IExtensionEnablementService, IExtensionIdentifier, EnablementState, IExtensionManagementServerService } from 'vs/platform/extensionManagement/common/extensionManagement'; import { getGalleryExtensionIdFromLocal, getGalleryExtensionTelemetryData, getLocalExtensionTelemetryData, areSameExtensions, getMaliciousExtensionsSet } from 'vs/platform/extensionManagement/common/extensionManagementUtil'; import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; @@ -48,7 +48,6 @@ class Extension implements IExtension { public get local(): ILocalExtension { return this.locals[0]; } public enablementState: EnablementState = EnablementState.Enabled; - public recommendationSources: ExtensionRecommendationSource[]; constructor( private galleryService: IExtensionGalleryService, @@ -393,7 +392,6 @@ export class ExtensionsWorkbenchService implements IExtensionsWorkbenchService, @ILogService private logService: ILogService, @IProgressService2 private progressService: IProgressService2, @IExtensionService private runtimeExtensionService: IExtensionService, - @IExtensionTipsService private extensionTipsService: IExtensionTipsService, @IExtensionManagementServerService private extensionManagementServerService: IExtensionManagementServerService ) { this.stateProvider = ext => this.getExtensionState(ext); @@ -434,8 +432,8 @@ export class ExtensionsWorkbenchService implements IExtensionsWorkbenchService, } queryLocal(): TPromise { - return TPromise.join([this.extensionService.getInstalled(), this.extensionTipsService.getAllRecommendations()]) - .then(([installed, allRecommendations]) => this.getDistinctInstalledExtensions(installed) + return this.extensionService.getInstalled() + .then(installed => this.getDistinctInstalledExtensions(installed) .then(distinctInstalled => { const installedById = index(this.installed, e => e.local.identifier.id); const groupById = groupBy(installed, i => getGalleryExtensionIdFromLocal(i)); @@ -446,10 +444,6 @@ export class ExtensionsWorkbenchService implements IExtensionsWorkbenchService, const extension = installedById[local.identifier.id] || new Extension(this.galleryService, this.stateProvider, locals, null, this.telemetryService); extension.locals = locals; extension.enablementState = this.extensionEnablementService.getEnablementState(local); - const recommendation = allRecommendations.filter(r => areSameExtensions({ id: r.extensionId }, { id: extension.id }))[0]; - if (recommendation) { - extension.recommendationSources = recommendation.sources || []; - } return extension; }); @@ -459,12 +453,12 @@ export class ExtensionsWorkbenchService implements IExtensionsWorkbenchService, } queryGallery(options: IQueryOptions = {}): TPromise> { - return TPromise.join([this.extensionTipsService.getAllRecommendations(), this.extensionService.getExtensionsReport()]) - .then(([allRecommendations, report]) => { + return this.extensionService.getExtensionsReport() + .then(report => { const maliciousSet = getMaliciousExtensionsSet(report); return this.galleryService.query(options) - .then(result => mapPager(result, gallery => this.fromGallery(gallery, maliciousSet, allRecommendations))) + .then(result => mapPager(result, gallery => this.fromGallery(gallery, maliciousSet))) .then(null, err => { if (/No extension gallery service configured/.test(err.message)) { return TPromise.as(singlePagePager([])); @@ -480,12 +474,12 @@ export class ExtensionsWorkbenchService implements IExtensionsWorkbenchService, return TPromise.wrap(null); } - return TPromise.join([this.extensionTipsService.getAllRecommendations(), this.extensionService.getExtensionsReport()]) - .then(([allRecommendations, report]) => { + return this.extensionService.getExtensionsReport() + .then(report => { const maliciousSet = getMaliciousExtensionsSet(report); return this.galleryService.loadAllDependencies((extension).dependencies.map(id => ({ id }))) - .then(galleryExtensions => galleryExtensions.map(galleryExtension => this.fromGallery(galleryExtension, maliciousSet, allRecommendations))) + .then(galleryExtensions => galleryExtensions.map(galleryExtension => this.fromGallery(galleryExtension, maliciousSet))) .then(extensions => [...this.local, ...extensions]) .then(extensions => { const map = new Map(); @@ -553,7 +547,7 @@ export class ExtensionsWorkbenchService implements IExtensionsWorkbenchService, return false; } - private fromGallery(gallery: IGalleryExtension, maliciousExtensionSet: Set, allRecommendations: IExtensionRecommendation[]): Extension { + private fromGallery(gallery: IGalleryExtension, maliciousExtensionSet: Set): Extension { let result = this.getInstalledExtensionMatchingGallery(gallery); if (result) { @@ -573,11 +567,6 @@ export class ExtensionsWorkbenchService implements IExtensionsWorkbenchService, result.isMalicious = true; } - const recommendation = allRecommendations.filter(r => areSameExtensions({ id: r.extensionId }, { id: result.id }))[0]; - if (recommendation) { - result.recommendationSources = recommendation.sources || []; - } - return result; } @@ -687,7 +676,7 @@ export class ExtensionsWorkbenchService implements IExtensionsWorkbenchService, } if (!(extension instanceof Extension)) { - return undefined; + return TPromise.as(undefined); } if (extension.isMalicious) { diff --git a/src/vs/workbench/parts/extensions/test/electron-browser/extensionsActions.test.ts b/src/vs/workbench/parts/extensions/test/electron-browser/extensionsActions.test.ts index efdd2be342e..453b07a6f0f 100644 --- a/src/vs/workbench/parts/extensions/test/electron-browser/extensionsActions.test.ts +++ b/src/vs/workbench/parts/extensions/test/electron-browser/extensionsActions.test.ts @@ -14,7 +14,7 @@ import * as ExtensionsActions from 'vs/workbench/parts/extensions/electron-brows import { ExtensionsWorkbenchService } from 'vs/workbench/parts/extensions/node/extensionsWorkbenchService'; import { IExtensionManagementService, IExtensionGalleryService, IExtensionEnablementService, IExtensionTipsService, ILocalExtension, LocalExtensionType, IGalleryExtension, - DidInstallExtensionEvent, DidUninstallExtensionEvent, InstallExtensionEvent, IExtensionIdentifier, EnablementState, InstallOperation, IExtensionManagementServerService, IExtensionManagementServer + DidInstallExtensionEvent, DidUninstallExtensionEvent, InstallExtensionEvent, IExtensionIdentifier, EnablementState, InstallOperation, IExtensionManagementServerService, IExtensionManagementServer, localExtensionManagementServerLocation } from 'vs/platform/extensionManagement/common/extensionManagement'; import { getGalleryExtensionId, getGalleryExtensionIdFromLocal } from 'vs/platform/extensionManagement/common/extensionManagementUtil'; import { ExtensionManagementService, getLocalExtensionIdFromGallery, getLocalExtensionIdFromManifest } from 'vs/platform/extensionManagement/node/extensionManagementService'; @@ -36,7 +36,6 @@ import { IWindowService } from 'vs/platform/windows/common/windows'; import { URLService } from 'vs/platform/url/common/urlService'; import URI from 'vs/base/common/uri'; import { SingleServerExtensionManagementServerService } from 'vs/workbench/services/extensions/node/extensionManagementServerService'; -import { Schemas } from 'vs/base/common/network'; import { TestConfigurationService } from 'vs/platform/configuration/test/common/testConfigurationService'; suite('ExtensionsActions Test', () => { @@ -72,7 +71,7 @@ suite('ExtensionsActions Test', () => { instantiationService.stub(IExtensionManagementService, 'onUninstallExtension', uninstallEvent.event); instantiationService.stub(IExtensionManagementService, 'onDidUninstallExtension', didUninstallEvent.event); - instantiationService.stub(IExtensionManagementServerService, instantiationService.createInstance(SingleServerExtensionManagementServerService, { location: URI.from({ scheme: Schemas.file }), extensionManagementService: instantiationService.get(IExtensionManagementService) })); + instantiationService.stub(IExtensionManagementServerService, instantiationService.createInstance(SingleServerExtensionManagementServerService, { location: localExtensionManagementServerLocation, extensionManagementService: instantiationService.get(IExtensionManagementService) })); instantiationService.stub(IExtensionEnablementService, new TestExtensionEnablementService(instantiationService)); diff --git a/src/vs/workbench/services/extensions/node/extensionManagementServerService.ts b/src/vs/workbench/services/extensions/node/extensionManagementServerService.ts index e26546753ff..ddfbdf748b0 100644 --- a/src/vs/workbench/services/extensions/node/extensionManagementServerService.ts +++ b/src/vs/workbench/services/extensions/node/extensionManagementServerService.ts @@ -3,7 +3,7 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -import { IExtensionManagementService, IExtensionManagementServerService, IExtensionManagementServer } from 'vs/platform/extensionManagement/common/extensionManagement'; +import { IExtensionManagementService, IExtensionManagementServerService, IExtensionManagementServer, localExtensionManagementServerLocation } from 'vs/platform/extensionManagement/common/extensionManagement'; import URI from 'vs/base/common/uri'; import { Schemas } from 'vs/base/common/network'; @@ -16,7 +16,7 @@ export class ExtensionManagementServerService implements IExtensionManagementSer constructor( localExtensionManagementService: IExtensionManagementService ) { - this.extensionManagementServers = [{ extensionManagementService: localExtensionManagementService, location: URI.from({ scheme: Schemas.file }) }]; + this.extensionManagementServers = [{ extensionManagementService: localExtensionManagementService, location: localExtensionManagementServerLocation }]; } getExtensionManagementServer(location: URI): IExtensionManagementServer { From a057e3218bfdfb4ab02c3559ed24d85390ff741f Mon Sep 17 00:00:00 2001 From: Benjamin Pasero Date: Tue, 14 Aug 2018 16:31:17 +0200 Subject: [PATCH 0793/1276] ext host - improve printing of circular objects --- src/bootstrap.js | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/src/bootstrap.js b/src/bootstrap.js index 707513f7235..c61fc326a8f 100644 --- a/src/bootstrap.js +++ b/src/bootstrap.js @@ -76,9 +76,9 @@ if (!!process.send && process.env.PIPE_LOGGING === 'true') { res = JSON.stringify(argsArray, function (key, value) { // Objects get special treatment to prevent circles - if (value && Object.prototype.toString.call(value) === '[object Object]') { + if (isObject(value) || Array.isArray(value)) { if (seen.indexOf(value) !== -1) { - return Object.create(null); // prevent circular references! + return '[Circular]'; } seen.push(value); @@ -105,6 +105,14 @@ if (!!process.send && process.env.PIPE_LOGGING === 'true') { } } + function isObject(obj) { + return typeof obj === 'object' + && obj !== null + && !Array.isArray(obj) + && !(obj instanceof RegExp) + && !(obj instanceof Date); + } + // Pass console logging to the outside so that we have it in the main side if told so if (process.env.VERBOSE_LOGGING === 'true') { console.log = function () { safeSend({ type: '__$console', severity: 'log', arguments: safeToArray(arguments) }); }; From 2d73551585022af95783680ac6a7f7d0e92684e6 Mon Sep 17 00:00:00 2001 From: Sandeep Somavarapu Date: Tue, 14 Aug 2018 16:52:27 +0200 Subject: [PATCH 0794/1276] Add authority and label to extension management server --- .../common/extensionManagement.ts | 7 +++---- .../common/multiExtensionManagement.ts | 6 +++--- .../extensions/electron-browser/extensionsList.ts | 2 +- .../electron-browser/extensionsViewlet.ts | 6 +++--- .../extensions/node/extensionsWorkbenchService.ts | 2 +- .../electron-browser/extensionsActions.test.ts | 4 ++-- .../node/extensionManagementServerService.ts | 15 +++++++++------ 7 files changed, 22 insertions(+), 20 deletions(-) diff --git a/src/vs/platform/extensionManagement/common/extensionManagement.ts b/src/vs/platform/extensionManagement/common/extensionManagement.ts index 99e4f12b96d..f7a4416631b 100644 --- a/src/vs/platform/extensionManagement/common/extensionManagement.ts +++ b/src/vs/platform/extensionManagement/common/extensionManagement.ts @@ -13,7 +13,6 @@ import { createDecorator } from 'vs/platform/instantiation/common/instantiation' import { ILocalization } from 'vs/platform/localizations/common/localizations'; import URI from 'vs/base/common/uri'; import { IWorkspaceFolder, IWorkspace } from 'vs/platform/workspace/common/workspace'; -import { Schemas } from 'vs/base/common/network'; export const EXTENSION_IDENTIFIER_PATTERN = '^([a-z0-9A-Z][a-z0-9\-A-Z]*)\\.([a-z0-9A-Z][a-z0-9\-A-Z]*)$'; export const EXTENSION_IDENTIFIER_REGEX = new RegExp(EXTENSION_IDENTIFIER_PATTERN); @@ -318,17 +317,17 @@ export interface IExtensionManagementService { } export const IExtensionManagementServerService = createDecorator('extensionManagementServerService'); -export const localExtensionManagementServerLocation: URI = URI.from({ scheme: Schemas.file }); export interface IExtensionManagementServer { extensionManagementService: IExtensionManagementService; - location: URI; + authority: string; + label: string; } export interface IExtensionManagementServerService { _serviceBrand: any; readonly extensionManagementServers: IExtensionManagementServer[]; - getDefaultExtensionManagementServer(): IExtensionManagementServer; + getLocalExtensionManagementServer(): IExtensionManagementServer; getExtensionManagementServer(location: URI): IExtensionManagementServer; } diff --git a/src/vs/platform/extensionManagement/common/multiExtensionManagement.ts b/src/vs/platform/extensionManagement/common/multiExtensionManagement.ts index 26530f18c45..dd1a5bfbd4c 100644 --- a/src/vs/platform/extensionManagement/common/multiExtensionManagement.ts +++ b/src/vs/platform/extensionManagement/common/multiExtensionManagement.ts @@ -7,7 +7,7 @@ import { TPromise } from 'vs/base/common/winjs.base'; import { Event, EventMultiplexer } from 'vs/base/common/event'; import { IExtensionManagementService, ILocalExtension, IGalleryExtension, LocalExtensionType, InstallExtensionEvent, DidInstallExtensionEvent, IExtensionIdentifier, DidUninstallExtensionEvent, IReportedExtension, IGalleryMetadata, - IExtensionManagementServerService, IExtensionManagementServer, localExtensionManagementServerLocation + IExtensionManagementServerService, IExtensionManagementServer } from 'vs/platform/extensionManagement/common/extensionManagement'; import { flatten } from 'vs/base/common/arrays'; @@ -50,7 +50,7 @@ export class MulitExtensionManagementService implements IExtensionManagementServ } install(zipPath: string): TPromise { - return this.extensionManagementServerService.getExtensionManagementServer(localExtensionManagementServerLocation).extensionManagementService.install(zipPath); + return this.extensionManagementServerService.getLocalExtensionManagementServer().extensionManagementService.install(zipPath); } installFromGallery(extension: IGalleryExtension): TPromise { @@ -58,7 +58,7 @@ export class MulitExtensionManagementService implements IExtensionManagementServ } getExtensionsReport(): TPromise { - return this.extensionManagementServerService.getExtensionManagementServer(localExtensionManagementServerLocation).extensionManagementService.getExtensionsReport(); + return this.extensionManagementServerService.getLocalExtensionManagementServer().extensionManagementService.getExtensionsReport(); } private getServer(extension: ILocalExtension): IExtensionManagementServer { diff --git a/src/vs/workbench/parts/extensions/electron-browser/extensionsList.ts b/src/vs/workbench/parts/extensions/electron-browser/extensionsList.ts index f048c242f61..f6663b8a9bc 100644 --- a/src/vs/workbench/parts/extensions/electron-browser/extensionsList.ts +++ b/src/vs/workbench/parts/extensions/electron-browser/extensionsList.ts @@ -148,7 +148,7 @@ export class Renderer implements IPagedRenderer { this.extensionService.getExtensions().then(runningExtensions => { if (installed && installed.local) { const installedExtensionServer = this.extensionManagementServerService.getExtensionManagementServer(installed.local.location); - const isSameExtensionRunning = runningExtensions.some(e => areSameExtensions(e, extension) && installedExtensionServer.location.toString() === this.extensionManagementServerService.getExtensionManagementServer(e.extensionLocation).location.toString()); + const isSameExtensionRunning = runningExtensions.some(e => areSameExtensions(e, extension) && installedExtensionServer.authority === this.extensionManagementServerService.getExtensionManagementServer(e.extensionLocation).authority); toggleClass(data.root, 'disabled', !isSameExtensionRunning); } else { removeClass(data.root, 'disabled'); diff --git a/src/vs/workbench/parts/extensions/electron-browser/extensionsViewlet.ts b/src/vs/workbench/parts/extensions/electron-browser/extensionsViewlet.ts index 76efff9131a..0deb9a35143 100644 --- a/src/vs/workbench/parts/extensions/electron-browser/extensionsViewlet.ts +++ b/src/vs/workbench/parts/extensions/electron-browser/extensionsViewlet.ts @@ -152,8 +152,8 @@ export class ExtensionsViewletViewsContribution implements IWorkbenchContributio private createExtensionsViewDescriptorsForServer(server: IExtensionManagementServer): IViewDescriptor[] { return [{ - id: `server.extensionsList.${server.location.toString()}`, - name: server.location.authority, + id: `server.extensionsList.${server.authority}`, + name: server.label, container: VIEW_CONTAINER, ctor: GroupByServerExtensionsView, when: ContextKeyExpr.has('groupByServersContext'), @@ -449,7 +449,7 @@ export class ExtensionsViewlet extends ViewContainerViewlet implements IExtensio protected createView(viewDescriptor: IViewDescriptor, options: IViewletViewOptions): ViewletPanel { for (const extensionManagementServer of this.extensionManagementServerService.extensionManagementServers) { - if (viewDescriptor.id === `server.extensionsList.${extensionManagementServer.location.toString()}`) { + if (viewDescriptor.id === `server.extensionsList.${extensionManagementServer.authority}`) { const servicesCollection: ServiceCollection = new ServiceCollection(); servicesCollection.set(IExtensionManagementServerService, new SingleServerExtensionManagementServerService(extensionManagementServer)); servicesCollection.set(IExtensionManagementService, extensionManagementServer.extensionManagementService); diff --git a/src/vs/workbench/parts/extensions/node/extensionsWorkbenchService.ts b/src/vs/workbench/parts/extensions/node/extensionsWorkbenchService.ts index c68fc3e92e9..dde370485c8 100644 --- a/src/vs/workbench/parts/extensions/node/extensionsWorkbenchService.ts +++ b/src/vs/workbench/parts/extensions/node/extensionsWorkbenchService.ts @@ -921,7 +921,7 @@ export class ExtensionsWorkbenchService implements IExtensionsWorkbenchService, const installed = this.installed.filter(e => e.id === extension.id)[0]; if (installed) { const server = this.extensionManagementServerService.getExtensionManagementServer(local.location); - const existingLocal = installed.locals.filter(l => this.extensionManagementServerService.getExtensionManagementServer(l.location).location.toString() === server.location.toString())[0]; + const existingLocal = installed.locals.filter(l => this.extensionManagementServerService.getExtensionManagementServer(l.location).authority === server.authority)[0]; if (existingLocal) { const locals = [...installed.locals]; locals.splice(installed.locals.indexOf(existingLocal), 1, local); diff --git a/src/vs/workbench/parts/extensions/test/electron-browser/extensionsActions.test.ts b/src/vs/workbench/parts/extensions/test/electron-browser/extensionsActions.test.ts index 453b07a6f0f..5b724133ed5 100644 --- a/src/vs/workbench/parts/extensions/test/electron-browser/extensionsActions.test.ts +++ b/src/vs/workbench/parts/extensions/test/electron-browser/extensionsActions.test.ts @@ -14,7 +14,7 @@ import * as ExtensionsActions from 'vs/workbench/parts/extensions/electron-brows import { ExtensionsWorkbenchService } from 'vs/workbench/parts/extensions/node/extensionsWorkbenchService'; import { IExtensionManagementService, IExtensionGalleryService, IExtensionEnablementService, IExtensionTipsService, ILocalExtension, LocalExtensionType, IGalleryExtension, - DidInstallExtensionEvent, DidUninstallExtensionEvent, InstallExtensionEvent, IExtensionIdentifier, EnablementState, InstallOperation, IExtensionManagementServerService, IExtensionManagementServer, localExtensionManagementServerLocation + DidInstallExtensionEvent, DidUninstallExtensionEvent, InstallExtensionEvent, IExtensionIdentifier, EnablementState, InstallOperation, IExtensionManagementServerService, IExtensionManagementServer } from 'vs/platform/extensionManagement/common/extensionManagement'; import { getGalleryExtensionId, getGalleryExtensionIdFromLocal } from 'vs/platform/extensionManagement/common/extensionManagementUtil'; import { ExtensionManagementService, getLocalExtensionIdFromGallery, getLocalExtensionIdFromManifest } from 'vs/platform/extensionManagement/node/extensionManagementService'; @@ -71,7 +71,7 @@ suite('ExtensionsActions Test', () => { instantiationService.stub(IExtensionManagementService, 'onUninstallExtension', uninstallEvent.event); instantiationService.stub(IExtensionManagementService, 'onDidUninstallExtension', didUninstallEvent.event); - instantiationService.stub(IExtensionManagementServerService, instantiationService.createInstance(SingleServerExtensionManagementServerService, { location: localExtensionManagementServerLocation, extensionManagementService: instantiationService.get(IExtensionManagementService) })); + instantiationService.stub(IExtensionManagementServerService, instantiationService.createInstance(SingleServerExtensionManagementServerService, { authority: 'vscode-local', extensionManagementService: instantiationService.get(IExtensionManagementService), label: 'local' })); instantiationService.stub(IExtensionEnablementService, new TestExtensionEnablementService(instantiationService)); diff --git a/src/vs/workbench/services/extensions/node/extensionManagementServerService.ts b/src/vs/workbench/services/extensions/node/extensionManagementServerService.ts index ddfbdf748b0..c0ae970d509 100644 --- a/src/vs/workbench/services/extensions/node/extensionManagementServerService.ts +++ b/src/vs/workbench/services/extensions/node/extensionManagementServerService.ts @@ -3,9 +3,12 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -import { IExtensionManagementService, IExtensionManagementServerService, IExtensionManagementServer, localExtensionManagementServerLocation } from 'vs/platform/extensionManagement/common/extensionManagement'; +import { IExtensionManagementService, IExtensionManagementServerService, IExtensionManagementServer } from 'vs/platform/extensionManagement/common/extensionManagement'; import URI from 'vs/base/common/uri'; import { Schemas } from 'vs/base/common/network'; +import { localize } from 'vs/nls'; + +const localExtensionManagementServerAuthority: string = 'vscode-local'; export class ExtensionManagementServerService implements IExtensionManagementServerService { @@ -16,14 +19,14 @@ export class ExtensionManagementServerService implements IExtensionManagementSer constructor( localExtensionManagementService: IExtensionManagementService ) { - this.extensionManagementServers = [{ extensionManagementService: localExtensionManagementService, location: localExtensionManagementServerLocation }]; + this.extensionManagementServers = [{ extensionManagementService: localExtensionManagementService, authority: localExtensionManagementServerAuthority, label: localize('local', "Local") }]; } getExtensionManagementServer(location: URI): IExtensionManagementServer { return this.extensionManagementServers[0]; } - getDefaultExtensionManagementServer(): IExtensionManagementServer { + getLocalExtensionManagementServer(): IExtensionManagementServer { return this.extensionManagementServers[0]; } } @@ -41,11 +44,11 @@ export class SingleServerExtensionManagementServerService implements IExtensionM } getExtensionManagementServer(location: URI): IExtensionManagementServer { - location = location.scheme === Schemas.file ? URI.from({ scheme: Schemas.file }) : location; - return this.extensionManagementServers.filter(server => location.authority === server.location.authority)[0]; + const authority = location.scheme === Schemas.file ? localExtensionManagementServerAuthority : location.authority; + return this.extensionManagementServers.filter(server => authority === server.authority)[0]; } - getDefaultExtensionManagementServer(): IExtensionManagementServer { + getLocalExtensionManagementServer(): IExtensionManagementServer { return this.extensionManagementServers[0]; } } \ No newline at end of file From d49a98caa68a227ff83ee8138acfa2ef5713a760 Mon Sep 17 00:00:00 2001 From: Ramya Rao Date: Tue, 14 Aug 2018 09:00:32 -0700 Subject: [PATCH 0795/1276] Remove prompt to install packs for core languages #50588 (#52827) --- .../localizations.contribution.ts | 39 +------------------ 1 file changed, 2 insertions(+), 37 deletions(-) diff --git a/src/vs/workbench/parts/localizations/electron-browser/localizations.contribution.ts b/src/vs/workbench/parts/localizations/electron-browser/localizations.contribution.ts index ef0e09b3c44..052de75c677 100644 --- a/src/vs/workbench/parts/localizations/electron-browser/localizations.contribution.ts +++ b/src/vs/workbench/parts/localizations/electron-browser/localizations.contribution.ts @@ -12,7 +12,7 @@ import { SyncActionDescriptor } from 'vs/platform/actions/common/actions'; import { Disposable } from 'vs/base/common/lifecycle'; import { ConfigureLocaleAction } from 'vs/workbench/parts/localizations/electron-browser/localizationsActions'; import { ExtensionsRegistry } from 'vs/workbench/services/extensions/common/extensionsRegistry'; -import { ILocalizationsService, LanguageType } from 'vs/platform/localizations/common/localizations'; +import { ILocalizationsService } from 'vs/platform/localizations/common/localizations'; import { LifecyclePhase } from 'vs/platform/lifecycle/common/lifecycle'; import * as platform from 'vs/base/common/platform'; import { IExtensionManagementService, DidInstallExtensionEvent, LocalExtensionType, IExtensionGalleryService, IGalleryExtension, InstallOperation } from 'vs/platform/extensionManagement/common/extensionManagement'; @@ -98,24 +98,6 @@ export class LocalizationWorkbenchContribution extends Disposable implements IWo } } - private migrateToMarketplaceLanguagePack(language: string): void { - this.isLanguageInstalled(language) - .then(installed => { - if (!installed) { - this.getLanguagePackExtension(language) - .then(extension => { - if (extension) { - this.notificationService.prompt(Severity.Warning, localize('install language pack', "In the near future, VS Code will only support language packs in the form of Marketplace extensions. Please install the '{0}' extension in order to continue to use the currently configured language. ", extension.displayName || extension.displayName), - [ - { label: localize('install', "Install"), run: () => this.installExtension(extension) }, - { label: localize('more information', "More Information..."), run: () => window.open('https://go.microsoft.com/fwlink/?linkid=872941') } - ]); - } - }); - } - }); - } - private checkAndInstall(): void { const language = platform.language; const locale = platform.locale; @@ -124,11 +106,7 @@ export class LocalizationWorkbenchContribution extends Disposable implements IWo if (!this.galleryService.isEnabled()) { return; } - if (language !== 'en' && language.indexOf('en-') !== -1) { - this.migrateToMarketplaceLanguagePack(language); - return; - } - if (locale === 'en' || locale.indexOf('en-') !== -1) { + if (language === 'en' || language.indexOf('en-') === 0) { return; } if (language === locale || languagePackSuggestionIgnoreList.indexOf(language) > -1) { @@ -232,19 +210,6 @@ export class LocalizationWorkbenchContribution extends Disposable implements IWo } - private getLanguagePackExtension(language: string): TPromise { - return this.localizationService.getLanguageIds(LanguageType.Core) - .then(coreLanguages => { - if (coreLanguages.some(c => c.toLowerCase() === language)) { - const extensionIdPrefix = language === 'zh-cn' ? 'zh-hans' : language === 'zh-tw' ? 'zh-hant' : language; - const extensionId = `MS-CEINTL.vscode-language-pack-${extensionIdPrefix}`; - return this.galleryService.query({ names: [extensionId], pageSize: 1 }) - .then(result => result.total === 1 ? result.firstPage[0] : null); - } - return null; - }); - } - private isLanguageInstalled(language: string): TPromise { return this.extensionManagementService.getInstalled(LocalExtensionType.User) .then(installed => installed.some(i => i.manifest && i.manifest.contributes && i.manifest.contributes.localizations && i.manifest.contributes.localizations.length && i.manifest.contributes.localizations.some(l => l.languageId.toLowerCase() === language))); From 8bf65af9fd6a4067433d8318dbfaebc989e6b7c7 Mon Sep 17 00:00:00 2001 From: Jackson Kearl Date: Tue, 14 Aug 2018 10:30:42 -0700 Subject: [PATCH 0796/1276] Add more tests --- .../preferences/common/preferencesModels.ts | 13 +- .../test/common/preferencesModel.test.ts | 172 ++++++++++++++++-- 2 files changed, 164 insertions(+), 21 deletions(-) diff --git a/src/vs/workbench/services/preferences/common/preferencesModels.ts b/src/vs/workbench/services/preferences/common/preferencesModels.ts index 1a081bf8287..f836ad5b233 100644 --- a/src/vs/workbench/services/preferences/common/preferencesModels.ts +++ b/src/vs/workbench/services/preferences/common/preferencesModels.ts @@ -987,27 +987,26 @@ export function createValidator(prop: IConfigurationPropertySchema): ((value: an let numericValidations: Validator[] = [ { - enabled: exclusiveMax !== undefined, + enabled: exclusiveMax !== undefined && (prop.maximum === undefined || exclusiveMax <= prop.maximum), isValid: (value => value < exclusiveMax), message: nls.localize('validations.exclusiveMax', "Value must be strictly less than {0}.", exclusiveMax) }, { - enabled: exclusiveMin !== undefined, + enabled: exclusiveMin !== undefined && (prop.minimum === undefined || exclusiveMin >= prop.minimum), isValid: (value => value > exclusiveMin), message: nls.localize('validations.exclusiveMin', "Value must be strictly greater than {0}.", exclusiveMin) }, { - enabled: prop.maximum !== undefined && exclusiveMax === undefined, + enabled: prop.maximum !== undefined && (exclusiveMax === undefined || exclusiveMax > prop.maximum), isValid: (value => value <= prop.maximum), message: nls.localize('validations.max', "Value must be less than or equal to {0}.", prop.maximum) }, { - enabled: prop.minimum !== undefined && exclusiveMin === undefined, + enabled: prop.minimum !== undefined && (exclusiveMin === undefined || exclusiveMin < prop.minimum), isValid: (value => value >= prop.minimum), message: nls.localize('validations.min', "Value must be greater than or equal to {0}.", prop.minimum) }, - { enabled: prop.multipleOf !== undefined, isValid: (value => value % prop.multipleOf === 0), @@ -1015,7 +1014,7 @@ export function createValidator(prop: IConfigurationPropertySchema): ((value: an }, { enabled: prop.type === 'integer', - isValid: (value => value % 1 === 0), + isValid: (value => value % 1 === 0 && value.indexOf('.') === -1), message: nls.localize('validations.expectedInteger', "Value must be an integer.") }, ].filter(validation => validation.enabled); @@ -1063,7 +1062,7 @@ export function createValidator(prop: IConfigurationPropertySchema): ((value: an errors.push(...stringValidations.filter(validator => !validator.isValid('' + value)).map(validator => validator.message)); } if (errors.length) { - return errors.join(' '); + return prop.errorMessage ? [prop.errorMessage, ...errors].join(' ') : errors.join(' '); } return ''; }; diff --git a/src/vs/workbench/services/preferences/test/common/preferencesModel.test.ts b/src/vs/workbench/services/preferences/test/common/preferencesModel.test.ts index f02d5d7164f..fd7fa58eb88 100644 --- a/src/vs/workbench/services/preferences/test/common/preferencesModel.test.ts +++ b/src/vs/workbench/services/preferences/test/common/preferencesModel.test.ts @@ -9,30 +9,26 @@ import { IConfigurationPropertySchema } from 'vs/platform/configuration/common/c suite('Preferences Model test', () => { - - class Tester { private validator: (value: any) => string; - constructor(settings: IConfigurationPropertySchema) { + constructor(private settings: IConfigurationPropertySchema) { this.validator = createValidator(settings); } public accepts(input) { - assert(this.validator(input) === ''); + assert(this.validator(input) === '', `Expected ${JSON.stringify(this.settings)} to accept ${input}. Got ${this.validator(input)}.`); } public rejects(input) { - assert(this.validator(input) !== ''); + assert(this.validator(input) !== '', `Expected ${JSON.stringify(this.settings)} to reject ${input}.`); + return { + withMessage: + (message) => assert(this.validator(input).indexOf(message) > -1, + `Expected error of ${JSON.stringify(this.settings)} on ${input} to contain ${message}. Got ${this.validator(input)}.`) + }; } - public acceptsEmpty() { - this.accepts(''); - } - - public rejectsEmpty() { - this.rejects(''); - } public validatesNumeric() { this.accepts('3'); @@ -46,12 +42,12 @@ suite('Preferences Model test', () => { public validatesNullableNumeric() { this.validatesNumeric(); - this.acceptsEmpty(); + this.accepts(''); } public validatesNonNullableNumeric() { this.validatesNumeric(); - this.rejectsEmpty(); + this.rejects(''); } public validatesString() { @@ -100,6 +96,154 @@ suite('Preferences Model test', () => { }); test('exclusive min and min work together properly', () => { + { + const justMin = new Tester({ minimum: -5, type: 'number' }); + justMin.validatesNonNullableNumeric(); + justMin.rejects('-5.1'); + justMin.accepts('-5.0'); + } + { + const justEMin = new Tester({ exclusiveMinimum: -5, type: 'number' }); + justEMin.validatesNonNullableNumeric(); + justEMin.rejects('-5.1'); + justEMin.rejects('-5.0'); + justEMin.accepts('-4.999'); + } + { + const bothNumeric = new Tester({ exclusiveMinimum: -5, minimum: -4, type: 'number' }); + bothNumeric.validatesNonNullableNumeric(); + bothNumeric.rejects('-5.1'); + bothNumeric.rejects('-5.0'); + bothNumeric.rejects('-4.999'); + bothNumeric.accepts('-4'); + } + { + const bothNumeric = new Tester({ exclusiveMinimum: -5, minimum: -6, type: 'number' }); + bothNumeric.validatesNonNullableNumeric(); + bothNumeric.rejects('-5.1'); + bothNumeric.rejects('-5.0'); + bothNumeric.accepts('-4.999'); + } + }); + test('multiple of works for both integers and fractions', () => { + { + const onlyEvens = new Tester({ multipleOf: 2, type: 'number' }); + onlyEvens.accepts('2.0'); + onlyEvens.accepts('2'); + onlyEvens.accepts('-4'); + onlyEvens.accepts('0'); + onlyEvens.accepts('100'); + onlyEvens.rejects('100.1'); + onlyEvens.rejects(''); + onlyEvens.rejects('we'); + } + { + const hackyIntegers = new Tester({ multipleOf: 1, type: 'number' }); + hackyIntegers.accepts('2.0'); + hackyIntegers.rejects('.5'); + } + { + const halfIntegers = new Tester({ multipleOf: 0.5, type: 'number' }); + halfIntegers.accepts('0.5'); + halfIntegers.accepts('1.5'); + halfIntegers.rejects('1.51'); + } + }); + + test('integer type correctly adds a validation', () => { + { + const integers = new Tester({ multipleOf: 1, type: 'integer' }); + integers.accepts('02'); + integers.accepts('2'); + integers.accepts('20'); + integers.rejects('.5'); + integers.rejects('2j'); + integers.rejects(''); + } + }); + + test('null is allowed only when expected', () => { + { + const nullableIntegers = new Tester({ multipleOf: 1, type: ['integer', 'null'] }); + nullableIntegers.accepts('2'); + nullableIntegers.rejects('.5'); + nullableIntegers.rejects('2.0'); + nullableIntegers.rejects('2j'); + nullableIntegers.accepts(''); + } + { + const nonnullableIntegers = new Tester({ multipleOf: 1, type: ['integer'] }); + nonnullableIntegers.accepts('2'); + nonnullableIntegers.rejects('.5'); + nonnullableIntegers.rejects('2.0'); + nonnullableIntegers.rejects('2j'); + nonnullableIntegers.rejects(''); + } + { + const nullableNumbers = new Tester({ multipleOf: 1, type: ['number', 'null'] }); + nullableNumbers.accepts('2'); + nullableNumbers.accepts('.5'); + nullableNumbers.accepts('2.0'); + nullableNumbers.rejects('2j'); + nullableNumbers.accepts(''); + } + { + const nonnullableNumbers = new Tester({ multipleOf: 1, type: ['number'] }); + nonnullableNumbers.accepts('2'); + nonnullableNumbers.accepts('.5'); + nonnullableNumbers.accepts('2.0'); + nonnullableNumbers.rejects('2j'); + nonnullableNumbers.rejects(''); + } + }); + + test('string max min length work', () => { + { + const min = new Tester({ minLength: 4, type: 'string' }); + min.rejects('123'); + min.accepts('1234'); + min.accepts('12345'); + } + { + const max = new Tester({ maxLength: 6, type: 'string' }); + max.accepts('12345'); + max.accepts('123456'); + max.rejects('1234567'); + } + { + const minMax = new Tester({ minLength: 4, maxLength: 6, type: 'string' }); + minMax.rejects('123'); + minMax.accepts('1234'); + minMax.accepts('12345'); + minMax.accepts('123456'); + minMax.rejects('1234567'); + } + }); + + test('patterns work', () => { + { + const urls = new Tester({ pattern: '^(hello)*$' }); + urls.accepts(''); + urls.rejects('hel'); + urls.accepts('hello'); + urls.rejects('hellohel'); + urls.accepts('hellohello'); + } + { + const urls = new Tester({ pattern: '^(hello)*$', patternErrorMessage: 'err: must be friendly' }); + urls.accepts(''); + urls.rejects('hel').withMessage('err: must be friendly'); + urls.accepts('hello'); + urls.rejects('hellohel').withMessage('err: must be friendly'); + urls.accepts('hellohello'); + } + }); + + test('custom error messages are shown', () => { + const withMessage = new Tester({ minLength: 1, maxLength: 0, errorMessage: 'always error!' }); + withMessage.rejects('').withMessage('always error!'); + withMessage.rejects(' ').withMessage('always error!'); + withMessage.rejects('1').withMessage('always error!'); }); }); \ No newline at end of file From 8229aed327630e8aa3c2f6ac84cdae0ee1fd1d2d Mon Sep 17 00:00:00 2001 From: Martin Aeschlimann Date: Tue, 14 Aug 2018 19:43:18 +0200 Subject: [PATCH 0797/1276] [json] update service. Fixes #53605 --- .../json-language-features/package.json | 2 +- .../server/package.json | 4 +-- .../server/src/jsonServerMain.ts | 8 ++++- .../json-language-features/server/yarn.lock | 36 +++++++++---------- extensions/json-language-features/yarn.lock | 22 ++++++------ 5 files changed, 37 insertions(+), 35 deletions(-) diff --git a/extensions/json-language-features/package.json b/extensions/json-language-features/package.json index fab153b6000..a1910651a22 100644 --- a/extensions/json-language-features/package.json +++ b/extensions/json-language-features/package.json @@ -101,7 +101,7 @@ }, "dependencies": { "vscode-extension-telemetry": "0.0.18", - "vscode-languageclient": "^4.4.0", + "vscode-languageclient": "^4.4.2", "vscode-nls": "^3.2.4" }, "devDependencies": { diff --git a/extensions/json-language-features/server/package.json b/extensions/json-language-features/server/package.json index 605e1b18f8c..76fc712381c 100644 --- a/extensions/json-language-features/server/package.json +++ b/extensions/json-language-features/server/package.json @@ -13,8 +13,8 @@ "dependencies": { "jsonc-parser": "^2.0.1", "request-light": "^0.2.3", - "vscode-json-languageservice": "^3.1.4", - "vscode-languageserver": "^4.4.0", + "vscode-json-languageservice": "^3.1.5", + "vscode-languageserver": "^4.4.2", "vscode-nls": "^3.2.4", "vscode-uri": "^1.0.5" }, diff --git a/extensions/json-language-features/server/src/jsonServerMain.ts b/extensions/json-language-features/server/src/jsonServerMain.ts index 8db215a72e9..c152a7ac137 100644 --- a/extensions/json-language-features/server/src/jsonServerMain.ts +++ b/extensions/json-language-features/server/src/jsonServerMain.ts @@ -59,6 +59,7 @@ documents.listen(connection); let clientSnippetSupport = false; let clientDynamicRegisterSupport = false; let foldingRangeLimit = Number.MAX_VALUE; +let hierarchicalDocumentSymbolSupport = false; // After the server has started the client sends an initialize request. The server receives // in the passed params the rootPath of the workspace plus the client capabilities. @@ -79,6 +80,7 @@ connection.onInitialize((params: InitializeParams): InitializeResult => { clientSnippetSupport = getClientCapability('textDocument.completion.completionItem.snippetSupport', false); clientDynamicRegisterSupport = getClientCapability('workspace.symbol.dynamicRegistration', false); foldingRangeLimit = getClientCapability('textDocument.foldingRange.rangeLimit', Number.MAX_VALUE); + hierarchicalDocumentSymbolSupport = getClientCapability('textDocument.documentSymbol.hierarchicalDocumentSymbolSupport', false); const capabilities: ServerCapabilities = { // Tell the client that the server works in FULL text document sync mode textDocumentSync: documents.syncKind, @@ -342,7 +344,11 @@ connection.onDocumentSymbol((documentSymbolParams, token) => { const document = documents.get(documentSymbolParams.textDocument.uri); if (document) { const jsonDocument = getJSONDocument(document); - return languageService.findDocumentSymbols(document, jsonDocument); + if (hierarchicalDocumentSymbolSupport) { + return languageService.findDocumentSymbols2(document, jsonDocument); + } else { + return languageService.findDocumentSymbols(document, jsonDocument); + } } return []; }, [], `Error while computing document symbols for ${documentSymbolParams.textDocument.uri}`, token); diff --git a/extensions/json-language-features/server/yarn.lock b/extensions/json-language-features/server/yarn.lock index 31389ce0fc1..b8eca3bc52b 100644 --- a/extensions/json-language-features/server/yarn.lock +++ b/extensions/json-language-features/server/yarn.lock @@ -62,12 +62,12 @@ request-light@^0.2.3: https-proxy-agent "^2.2.1" vscode-nls "^3.2.2" -vscode-json-languageservice@^3.1.4: - version "3.1.4" - resolved "https://registry.yarnpkg.com/vscode-json-languageservice/-/vscode-json-languageservice-3.1.4.tgz#72e84e2754ad117f9e8d36876c1a66fe16234235" +vscode-json-languageservice@^3.1.5: + version "3.1.5" + resolved "https://registry.yarnpkg.com/vscode-json-languageservice/-/vscode-json-languageservice-3.1.5.tgz#4ebac4cadcaedd55ea2d0716259b50a89955e00e" dependencies: jsonc-parser "^2.0.1" - vscode-languageserver-types "^3.10.0" + vscode-languageserver-types "^3.10.1" vscode-nls "^3.2.4" vscode-uri "^1.0.5" @@ -75,32 +75,28 @@ vscode-jsonrpc@^3.6.2: version "3.6.2" resolved "https://registry.yarnpkg.com/vscode-jsonrpc/-/vscode-jsonrpc-3.6.2.tgz#3b5eef691159a15556ecc500e9a8a0dd143470c8" -vscode-languageserver-protocol@^3.10.0: - version "3.10.0" - resolved "https://registry.yarnpkg.com/vscode-languageserver-protocol/-/vscode-languageserver-protocol-3.10.0.tgz#f8dcdf987687f64a26e7c32d498fc781a0e886dc" +vscode-languageserver-protocol@^3.10.3: + version "3.10.3" + resolved "https://registry.yarnpkg.com/vscode-languageserver-protocol/-/vscode-languageserver-protocol-3.10.3.tgz#59841c9602a6a6baab68613c2a47760994657196" dependencies: vscode-jsonrpc "^3.6.2" - vscode-languageserver-types "^3.10.0" + vscode-languageserver-types "^3.10.1" -vscode-languageserver-types@^3.10.0: - version "3.10.0" - resolved "https://registry.yarnpkg.com/vscode-languageserver-types/-/vscode-languageserver-types-3.10.0.tgz#944e5308f3b36a3f372c766f1a344e903ec9c389" +vscode-languageserver-types@^3.10.1: + version "3.10.1" + resolved "https://registry.yarnpkg.com/vscode-languageserver-types/-/vscode-languageserver-types-3.10.1.tgz#d5d5f44f688a3b2aa9857dc53cb9cacca73fe35a" -vscode-languageserver@^4.4.0: - version "4.4.0" - resolved "https://registry.yarnpkg.com/vscode-languageserver/-/vscode-languageserver-4.4.0.tgz#b6e8b37a739ccb629d92f3635f0099d191c856fa" +vscode-languageserver@^4.4.2: + version "4.4.2" + resolved "https://registry.yarnpkg.com/vscode-languageserver/-/vscode-languageserver-4.4.2.tgz#600ae9cc7a6ff1e84d93c7807840c2cb5b22821b" dependencies: - vscode-languageserver-protocol "^3.10.0" - vscode-uri "^1.0.3" + vscode-languageserver-protocol "^3.10.3" + vscode-uri "^1.0.5" vscode-nls@^3.2.2, vscode-nls@^3.2.4: version "3.2.4" resolved "https://registry.yarnpkg.com/vscode-nls/-/vscode-nls-3.2.4.tgz#2166b4183c8aea884d20727f5449e62be69fd398" -vscode-uri@^1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/vscode-uri/-/vscode-uri-1.0.3.tgz#631bdbf716dccab0e65291a8dc25c23232085a52" - vscode-uri@^1.0.5: version "1.0.5" resolved "https://registry.yarnpkg.com/vscode-uri/-/vscode-uri-1.0.5.tgz#3b899a8ef71c37f3054d79bdbdda31c7bf36f20d" diff --git a/extensions/json-language-features/yarn.lock b/extensions/json-language-features/yarn.lock index f6e965d98ea..cb126a6c120 100644 --- a/extensions/json-language-features/yarn.lock +++ b/extensions/json-language-features/yarn.lock @@ -38,22 +38,22 @@ vscode-jsonrpc@^3.6.2: version "3.6.2" resolved "https://registry.yarnpkg.com/vscode-jsonrpc/-/vscode-jsonrpc-3.6.2.tgz#3b5eef691159a15556ecc500e9a8a0dd143470c8" -vscode-languageclient@^4.4.0: - version "4.4.0" - resolved "https://registry.yarnpkg.com/vscode-languageclient/-/vscode-languageclient-4.4.0.tgz#b05868f6477b6f0c9910b24daae4f3e8c4b65902" +vscode-languageclient@^4.4.2: + version "4.4.2" + resolved "https://registry.yarnpkg.com/vscode-languageclient/-/vscode-languageclient-4.4.2.tgz#a341a7b4ac403e481f011ed4572854646e8968c4" dependencies: - vscode-languageserver-protocol "^3.10.0" + vscode-languageserver-protocol "^3.10.3" -vscode-languageserver-protocol@^3.10.0: - version "3.10.0" - resolved "https://registry.yarnpkg.com/vscode-languageserver-protocol/-/vscode-languageserver-protocol-3.10.0.tgz#f8dcdf987687f64a26e7c32d498fc781a0e886dc" +vscode-languageserver-protocol@^3.10.3: + version "3.10.3" + resolved "https://registry.yarnpkg.com/vscode-languageserver-protocol/-/vscode-languageserver-protocol-3.10.3.tgz#59841c9602a6a6baab68613c2a47760994657196" dependencies: vscode-jsonrpc "^3.6.2" - vscode-languageserver-types "^3.10.0" + vscode-languageserver-types "^3.10.1" -vscode-languageserver-types@^3.10.0: - version "3.10.0" - resolved "https://registry.yarnpkg.com/vscode-languageserver-types/-/vscode-languageserver-types-3.10.0.tgz#944e5308f3b36a3f372c766f1a344e903ec9c389" +vscode-languageserver-types@^3.10.1: + version "3.10.1" + resolved "https://registry.yarnpkg.com/vscode-languageserver-types/-/vscode-languageserver-types-3.10.1.tgz#d5d5f44f688a3b2aa9857dc53cb9cacca73fe35a" vscode-nls@^3.2.4: version "3.2.4" From ed79775cde89dd912ca3484f1f98016af2ceab10 Mon Sep 17 00:00:00 2001 From: Jackson Kearl Date: Tue, 14 Aug 2018 10:58:48 -0700 Subject: [PATCH 0798/1276] Fix tests --- .../preferences/common/preferencesModels.ts | 21 ++++++++-------- .../test/common/preferencesModel.test.ts | 24 +++++++++---------- 2 files changed, 23 insertions(+), 22 deletions(-) diff --git a/src/vs/workbench/services/preferences/common/preferencesModels.ts b/src/vs/workbench/services/preferences/common/preferencesModels.ts index f836ad5b233..4b3ffbb6b80 100644 --- a/src/vs/workbench/services/preferences/common/preferencesModels.ts +++ b/src/vs/workbench/services/preferences/common/preferencesModels.ts @@ -983,9 +983,16 @@ export function createValidator(prop: IConfigurationPropertySchema): ((value: an patternRegex = new RegExp(prop.pattern); } + const type = Array.isArray(prop.type) ? prop.type : [prop.type]; + const canBeType = (t: string) => type.indexOf(t) > -1; + + const isNullable = canBeType('null'); + const isNumeric = (canBeType('number') || canBeType('integer')) && (type.length === 1 || type.length === 2 && isNullable); + const isIntegral = (canBeType('integer')) && (type.length === 1 || type.length === 2 && isNullable); + type Validator = { enabled: boolean, isValid: (value: T) => boolean; message: string }; - let numericValidations: Validator[] = [ + let numericValidations: Validator[] = isNumeric ? [ { enabled: exclusiveMax !== undefined && (prop.maximum === undefined || exclusiveMax <= prop.maximum), isValid: (value => value < exclusiveMax), @@ -1013,11 +1020,11 @@ export function createValidator(prop: IConfigurationPropertySchema): ((value: an message: nls.localize('validations.multipleOf', "Value must be a multiple of {0}.", prop.multipleOf) }, { - enabled: prop.type === 'integer', - isValid: (value => value % 1 === 0 && value.indexOf('.') === -1), + enabled: isIntegral, + isValid: (value => value % 1 === 0), message: nls.localize('validations.expectedInteger', "Value must be an integer.") }, - ].filter(validation => validation.enabled); + ].filter(validation => validation.enabled) : []; let stringValidations: Validator[] = [ { @@ -1037,12 +1044,6 @@ export function createValidator(prop: IConfigurationPropertySchema): ((value: an }, ].filter(validation => validation.enabled); - const type = Array.isArray(prop.type) ? prop.type : [prop.type]; - const canBeType = (t: string) => type.indexOf(t) > -1; - - const isNullable = canBeType('null'); - const isNumeric = (canBeType('number') || canBeType('integer')) && (type.length === 1 || type.length === 2 && isNullable); - if (prop.type === 'string' && stringValidations.length === 0) { return null; } return value => { diff --git a/src/vs/workbench/services/preferences/test/common/preferencesModel.test.ts b/src/vs/workbench/services/preferences/test/common/preferencesModel.test.ts index fd7fa58eb88..8550a177cf4 100644 --- a/src/vs/workbench/services/preferences/test/common/preferencesModel.test.ts +++ b/src/vs/workbench/services/preferences/test/common/preferencesModel.test.ts @@ -17,15 +17,15 @@ suite('Preferences Model test', () => { } public accepts(input) { - assert(this.validator(input) === '', `Expected ${JSON.stringify(this.settings)} to accept ${input}. Got ${this.validator(input)}.`); + assert.equal(this.validator(input), '', `Expected ${JSON.stringify(this.settings)} to accept \`${input}\`. Got ${this.validator(input)}.`); } public rejects(input) { - assert(this.validator(input) !== '', `Expected ${JSON.stringify(this.settings)} to reject ${input}.`); + assert.notEqual(this.validator(input), '', `Expected ${JSON.stringify(this.settings)} to reject \`${input}\`.`); return { withMessage: (message) => assert(this.validator(input).indexOf(message) > -1, - `Expected error of ${JSON.stringify(this.settings)} on ${input} to contain ${message}. Got ${this.validator(input)}.`) + `Expected error of ${JSON.stringify(this.settings)} on \`${input}\` to contain ${message}. Got ${this.validator(input)}.`) }; } @@ -165,23 +165,23 @@ suite('Preferences Model test', () => { test('null is allowed only when expected', () => { { - const nullableIntegers = new Tester({ multipleOf: 1, type: ['integer', 'null'] }); + const nullableIntegers = new Tester({ type: ['integer', 'null'] }); nullableIntegers.accepts('2'); nullableIntegers.rejects('.5'); - nullableIntegers.rejects('2.0'); + nullableIntegers.accepts('2.0'); nullableIntegers.rejects('2j'); nullableIntegers.accepts(''); } { - const nonnullableIntegers = new Tester({ multipleOf: 1, type: ['integer'] }); + const nonnullableIntegers = new Tester({ type: ['integer'] }); nonnullableIntegers.accepts('2'); nonnullableIntegers.rejects('.5'); - nonnullableIntegers.rejects('2.0'); + nonnullableIntegers.accepts('2.0'); nonnullableIntegers.rejects('2j'); nonnullableIntegers.rejects(''); } { - const nullableNumbers = new Tester({ multipleOf: 1, type: ['number', 'null'] }); + const nullableNumbers = new Tester({ type: ['number', 'null'] }); nullableNumbers.accepts('2'); nullableNumbers.accepts('.5'); nullableNumbers.accepts('2.0'); @@ -189,7 +189,7 @@ suite('Preferences Model test', () => { nullableNumbers.accepts(''); } { - const nonnullableNumbers = new Tester({ multipleOf: 1, type: ['number'] }); + const nonnullableNumbers = new Tester({ type: ['number'] }); nonnullableNumbers.accepts('2'); nonnullableNumbers.accepts('.5'); nonnullableNumbers.accepts('2.0'); @@ -223,7 +223,7 @@ suite('Preferences Model test', () => { test('patterns work', () => { { - const urls = new Tester({ pattern: '^(hello)*$' }); + const urls = new Tester({ pattern: '^(hello)*$', type: 'string' }); urls.accepts(''); urls.rejects('hel'); urls.accepts('hello'); @@ -231,7 +231,7 @@ suite('Preferences Model test', () => { urls.accepts('hellohello'); } { - const urls = new Tester({ pattern: '^(hello)*$', patternErrorMessage: 'err: must be friendly' }); + const urls = new Tester({ pattern: '^(hello)*$', type: 'string', patternErrorMessage: 'err: must be friendly' }); urls.accepts(''); urls.rejects('hel').withMessage('err: must be friendly'); urls.accepts('hello'); @@ -241,7 +241,7 @@ suite('Preferences Model test', () => { }); test('custom error messages are shown', () => { - const withMessage = new Tester({ minLength: 1, maxLength: 0, errorMessage: 'always error!' }); + const withMessage = new Tester({ minLength: 1, maxLength: 0, type: 'string', errorMessage: 'always error!' }); withMessage.rejects('').withMessage('always error!'); withMessage.rejects(' ').withMessage('always error!'); withMessage.rejects('1').withMessage('always error!'); From de8c4172a43b567dc9cb42ed4f9e9992147b5e09 Mon Sep 17 00:00:00 2001 From: Jackson Kearl Date: Tue, 14 Aug 2018 11:56:27 -0700 Subject: [PATCH 0799/1276] Add aria alerts to validations (#56394) --- .../parts/preferences/browser/settingsTree.ts | 22 +++++++++++-------- 1 file changed, 13 insertions(+), 9 deletions(-) diff --git a/src/vs/workbench/parts/preferences/browser/settingsTree.ts b/src/vs/workbench/parts/preferences/browser/settingsTree.ts index a49c2269c8c..d02076645d9 100644 --- a/src/vs/workbench/parts/preferences/browser/settingsTree.ts +++ b/src/vs/workbench/parts/preferences/browser/settingsTree.ts @@ -38,6 +38,7 @@ import { ITOCEntry } from 'vs/workbench/parts/preferences/browser/settingsLayout import { ISettingsEditorViewState, isExcludeSetting, SettingsTreeElement, SettingsTreeGroupElement, SettingsTreeNewExtensionsElement, SettingsTreeSettingElement } from 'vs/workbench/parts/preferences/browser/settingsTreeModels'; import { ExcludeSettingWidget, IExcludeDataItem, settingsHeaderForeground, settingsNumberInputBackground, settingsNumberInputBorder, settingsNumberInputForeground, settingsSelectBackground, settingsSelectBorder, settingsSelectForeground, settingsTextInputBackground, settingsTextInputBorder, settingsTextInputForeground } from 'vs/workbench/parts/preferences/browser/settingsWidgets'; import { ISetting, ISettingsGroup } from 'vs/workbench/services/preferences/common/preferences'; +import { alert as ariaAlert } from 'vs/base/browser/ui/aria/aria'; const $ = DOM.$; @@ -923,15 +924,14 @@ export class SettingsRenderer implements ITreeRenderer { } private renderText(dataElement: SettingsTreeSettingElement, template: ISettingTextItemTemplate, onChange: (value: string) => void): void { + const label = ' ' + dataElement.displayCategory + ' ' + dataElement.displayLabel + ' ' + template.isConfiguredElement.textContent; template.onChange = null; template.inputBox.value = dataElement.value; - template.onChange = value => { renderValidations(dataElement, template); onChange(value); }; + template.onChange = value => { renderValidations(dataElement, template, false, label); onChange(value); }; - renderValidations(dataElement, template); // Setup and add ARIA attributes // Create id and label for control/input element - parent is wrapper div const id = (dataElement.displayCategory + '_' + dataElement.displayLabel).replace(/ /g, '_'); - const label = ' ' + dataElement.displayCategory + ' ' + dataElement.displayLabel + ' ' + template.isConfiguredElement.textContent; // We use the parent control div for the aria-labelledby target // Does not appear you can use the direct label on the element itself within a tree @@ -945,10 +945,12 @@ export class SettingsRenderer implements ITreeRenderer { template.inputBox.inputElement.setAttribute('role', 'treeitem'); template.inputBox.inputElement.setAttribute('aria-labelledby', id + 'item ' + id); + renderValidations(dataElement, template, true, label); } private renderNumber(dataElement: SettingsTreeSettingElement, template: ISettingTextItemTemplate, onChange: (value: number) => void): void { + const label = ' ' + dataElement.displayCategory + ' ' + dataElement.displayLabel + ' number ' + template.isConfiguredElement.textContent; const numParseFn = (dataElement.valueType === 'integer' || dataElement.valueType === 'nullable-integer') ? parseInt : parseFloat; @@ -957,15 +959,11 @@ export class SettingsRenderer implements ITreeRenderer { template.onChange = null; template.inputBox.value = dataElement.value; - template.onChange = value => { - renderValidations(dataElement, template); onChange(nullNumParseFn(value)); - }; + template.onChange = value => { renderValidations(dataElement, template, false, label); onChange(nullNumParseFn(value)); }; - renderValidations(dataElement, template); // Setup and add ARIA attributes // Create id and label for control/input element - parent is wrapper div const id = (dataElement.displayCategory + '_' + dataElement.displayLabel).replace(/ /g, '_'); - const label = ' ' + dataElement.displayCategory + ' ' + dataElement.displayLabel + ' number ' + template.isConfiguredElement.textContent; // We use the parent control div for the aria-labelledby target // Does not appear you can use the direct label on the element itself within a tree @@ -979,6 +977,7 @@ export class SettingsRenderer implements ITreeRenderer { template.inputBox.inputElement.setAttribute('role', 'treeitem'); template.inputBox.inputElement.setAttribute('aria-labelledby', id + 'item ' + id); + renderValidations(dataElement, template, true, label); } private renderExcludeSetting(dataElement: SettingsTreeSettingElement, template: ISettingExcludeItemTemplate): void { @@ -996,13 +995,18 @@ export class SettingsRenderer implements ITreeRenderer { } } -function renderValidations(dataElement: SettingsTreeSettingElement, template: ISettingTextItemTemplate) { +function renderValidations(dataElement: SettingsTreeSettingElement, template: ISettingTextItemTemplate, calledOnStartup: boolean, originalAriaLabel: string) { if (dataElement.setting.validator) { let errMsg = dataElement.setting.validator(template.inputBox.value); if (errMsg) { DOM.addClass(template.containerElement, 'invalid-input'); template.validationErrorMessageElement.innerText = errMsg; + let validationError = localize('validationError', "Validation Error."); + template.inputBox.inputElement.parentElement.setAttribute('aria-label', [originalAriaLabel, validationError, errMsg].join(' ')); + if (!calledOnStartup) { ariaAlert(validationError + ' ' + errMsg); } return; + } else { + template.inputBox.inputElement.parentElement.setAttribute('aria-label', originalAriaLabel); } } DOM.removeClass(template.containerElement, 'invalid-input'); From ae6ecd8f006aad43bfbcf5d3738c32150a6f3ade Mon Sep 17 00:00:00 2001 From: Andre Weinand Date: Tue, 14 Aug 2018 22:03:59 +0200 Subject: [PATCH 0800/1276] fix layout for reparenting in loaded scripts viewer; fixes #55448 --- .../parts/debug/browser/loadedScriptsView.ts | 174 ++++++++---------- 1 file changed, 80 insertions(+), 94 deletions(-) diff --git a/src/vs/workbench/parts/debug/browser/loadedScriptsView.ts b/src/vs/workbench/parts/debug/browser/loadedScriptsView.ts index 6c0ea42c896..9827ad28916 100644 --- a/src/vs/workbench/parts/debug/browser/loadedScriptsView.ts +++ b/src/vs/workbench/parts/debug/browser/loadedScriptsView.ts @@ -38,81 +38,13 @@ const ROOT_FOLDER_TEMPLATE_ID = 'node'; class BaseTreeItem { - private static SEQUENCE = 1; - - private _id: string; + private _showedMoreThanOne: boolean; private _children: { [key: string]: BaseTreeItem; }; private _source: Source; constructor(private _parent: BaseTreeItem, private _label: string) { - this._id = `${BaseTreeItem.SEQUENCE++}`; this._children = {}; - } - - getLabel(showRootFolder = true) { - const child = this.oneChild(); - if (child) { - const sep = (this instanceof RootFolderTreeItem && showRootFolder) ? ' • ' : '/'; - return `${this._label}${sep}${child.getLabel()}`; - } - return this._label; - } - - getHoverLabel(): string { - let label = this.getLabel(false); - if (this._parent) { - const parentLabel = this._parent.getHoverLabel(); - if (parentLabel) { - return `${parentLabel}/${label}`; - } - } - return label; - } - - getId(): string { - return this._id; - } - - getTemplateId(): string { - return SOURCE_TEMPLATE_ID; - } - - /* - getParent(): BaseTreeItem { - if (this._parent) { - const child = this._parent.oneChild(); - if (child) { - return this._parent.getParent(); - } - return this._parent; - } - return undefined; - } - */ - - getChildren(): TPromise { - const child = this.oneChild(); - if (child) { - return child.getChildren(); - } - const array = Object.keys(this._children).map(key => this._children[key]); - return TPromise.as(array.sort((a, b) => this.compare(a, b))); - } - - hasChildren(): boolean { - const child = this.oneChild(); - if (child) { - return child.hasChildren(); - } - return Object.keys(this._children).length > 0; - } - - getSource(): Source { - const child = this.oneChild(); - if (child) { - return child.getSource(); - } - return this._source; + this._showedMoreThanOne = false; } setSource(session: ISession, source: Source): void { @@ -132,6 +64,78 @@ class BaseTreeItem { delete this._children[key]; } + getTemplateId(): string { + return SOURCE_TEMPLATE_ID; + } + + // a dynamic ID based on the parent chain; required for reparenting (see #55448) + getId(): string { + const parent = this.getParent(); + return parent ? `${parent.getId()}/${this._label}` : this._label; + } + + // skips intermediate single-child nodes + getParent(): BaseTreeItem { + if (this._parent) { + const child = this._parent.oneChild(); + if (child) { + return this._parent.getParent(); + } + return this._parent; + } + return undefined; + } + + // skips intermediate single-child nodes + hasChildren(): boolean { + const child = this.oneChild(); + if (child) { + return child.hasChildren(); + } + return Object.keys(this._children).length > 0; + } + + // skips intermediate single-child nodes + getChildren(): TPromise { + const child = this.oneChild(); + if (child) { + return child.getChildren(); + } + const array = Object.keys(this._children).map(key => this._children[key]); + return TPromise.as(array.sort((a, b) => this.compare(a, b))); + } + + // skips intermediate single-child nodes + getLabel(separateRootFolder = true) { + const child = this.oneChild(); + if (child) { + const sep = (this instanceof RootFolderTreeItem && separateRootFolder) ? ' • ' : '/'; + return `${this._label}${sep}${child.getLabel()}`; + } + return this._label; + } + + // skips intermediate single-child nodes + getHoverLabel(): string { + let label = this.getLabel(false); + if (this._parent) { + const parentLabel = this._parent.getHoverLabel(); + if (parentLabel) { + return `${parentLabel}/${label}`; + } + } + return label; + } + + // skips intermediate single-child nodes + getSource(): Source { + const child = this.oneChild(); + if (child) { + return child.getSource(); + } + return this._source; + } + protected compare(a: BaseTreeItem, b: BaseTreeItem): number { if (a._label && b._label) { return a._label.localeCompare(b._label); @@ -140,11 +144,15 @@ class BaseTreeItem { } private oneChild(): BaseTreeItem { - if (SMART && !(this instanceof RootTreeItem)) { + if (SMART && !this._showedMoreThanOne) { const keys = Object.keys(this._children); if (keys.length === 1) { return this._children[keys[0]]; } + // if a node had more than one child once, it will never be skipped again + if (keys.length > 1) { + this._showedMoreThanOne = true; + } } return undefined; } @@ -163,32 +171,13 @@ class RootFolderTreeItem extends BaseTreeItem { class RootTreeItem extends BaseTreeItem { - private _showedMoreThanOne: boolean; - constructor(private _debugModel: IModel, private _environmentService: IEnvironmentService, private _contextService: IWorkspaceContextService) { super(undefined, 'Root'); - this._showedMoreThanOne = false; this._debugModel.getSessions().forEach(session => { this.add(session); }); } - hasChildren(): boolean { - return true; - } - - getChildren(): TPromise { - return super.getChildren().then(children => { - const size = children.length; - if (!this._showedMoreThanOne && size === 1) { - // skip session if there is only one - return children[0].getChildren(); - } - this._showedMoreThanOne = size > 1; - return children; - }); - } - add(session: ISession): SessionTreeItem { return this.createIfNeeded(session.getId(), () => new SessionTreeItem(this, session, this._environmentService, this._contextService)); } @@ -241,9 +230,6 @@ class SessionTreeItem extends BaseTreeItem { return super.compare(a, b); } - /** - * Return an ordinal number for folders - */ private category(item: BaseTreeItem): number { // workspace scripts come at the beginning in "folder" order @@ -439,7 +425,7 @@ class LoadedScriptsDataSource implements IDataSource { } getParent(tree: ITree, element: any): TPromise { - return TPromise.as(null); + return element.getParent(); } shouldAutoexpand?(tree: ITree, element: any): boolean { From 24d094ae74e603a20127e2132003c257bd6b771a Mon Sep 17 00:00:00 2001 From: Rob Lourens Date: Tue, 14 Aug 2018 15:24:44 -0700 Subject: [PATCH 0801/1276] #55883 - remove some TPromise.cancel from file search --- src/vs/base/common/arrays.ts | 9 +- .../services/search/node/rawSearchService.ts | 223 +++++++++--------- .../search/test/node/searchService.test.ts | 31 ++- 3 files changed, 132 insertions(+), 131 deletions(-) diff --git a/src/vs/base/common/arrays.ts b/src/vs/base/common/arrays.ts index 4719c7c834d..7ce398f38a8 100644 --- a/src/vs/base/common/arrays.ts +++ b/src/vs/base/common/arrays.ts @@ -6,6 +6,7 @@ import { TPromise } from 'vs/base/common/winjs.base'; import { ISplice } from 'vs/base/common/sequence'; +import { CancellationToken } from 'vs/base/common/cancellation'; /** * Returns the last element of an array. @@ -252,11 +253,11 @@ export function top(array: T[], compare: (a: T, b: T) => number, n: number): * @param batch The number of elements to examine before yielding to the event loop. * @return The first n elemnts from array when sorted with compare. */ -export function topAsync(array: T[], compare: (a: T, b: T) => number, n: number, batch: number): TPromise { +export function topAsync(array: T[], compare: (a: T, b: T) => number, n: number, batch: number, token?: CancellationToken): TPromise { if (n === 0) { return TPromise.as([]); } - let canceled = false; + return new TPromise((resolve, reject) => { (async () => { const o = array.length; @@ -265,7 +266,7 @@ export function topAsync(array: T[], compare: (a: T, b: T) => number, n: numb if (i > n) { await new Promise(resolve => setTimeout(resolve)); // nextTick() would starve I/O. } - if (canceled) { + if (token && token.isCancellationRequested) { throw new Error('canceled'); } topStep(array, compare, result, i, m); @@ -273,8 +274,6 @@ export function topAsync(array: T[], compare: (a: T, b: T) => number, n: numb return result; })() .then(resolve, reject); - }, () => { - canceled = true; }); } diff --git a/src/vs/workbench/services/search/node/rawSearchService.ts b/src/vs/workbench/services/search/node/rawSearchService.ts index 29e07c58247..b2617de2d7f 100644 --- a/src/vs/workbench/services/search/node/rawSearchService.ts +++ b/src/vs/workbench/services/search/node/rawSearchService.ts @@ -9,6 +9,10 @@ import * as fs from 'fs'; import * as gracefulFs from 'graceful-fs'; import { join, sep } from 'path'; import * as arrays from 'vs/base/common/arrays'; +import { CancelablePromise, createCancelablePromise, toWinJsPromise } from 'vs/base/common/async'; +import { CancellationToken } from 'vs/base/common/cancellation'; +import { canceled } from 'vs/base/common/errors'; +import { Emitter, Event } from 'vs/base/common/event'; import * as objects from 'vs/base/common/objects'; import * as strings from 'vs/base/common/strings'; import { TPromise } from 'vs/base/common/winjs.base'; @@ -19,10 +23,7 @@ import { Engine as FileSearchEngine, FileWalker } from 'vs/workbench/services/se import { RipgrepEngine } from 'vs/workbench/services/search/node/ripgrepTextSearch'; import { Engine as TextSearchEngine } from 'vs/workbench/services/search/node/textSearch'; import { TextSearchWorkerProvider } from 'vs/workbench/services/search/node/textSearchWorkerProvider'; -import { IFileSearchProgressItem, IRawFileMatch, IRawSearch, IRawSearchService, ISearchEngine, ISerializedFileMatch, ISerializedSearchComplete, ISerializedSearchProgressItem, ITelemetryEvent, ISerializedSearchSuccess } from './search'; -import { Event, Emitter } from 'vs/base/common/event'; -import { createCancelablePromise, CancelablePromise } from 'vs/base/common/async'; -import { CancellationToken } from 'vs/base/common/cancellation'; +import { IFileSearchProgressItem, IRawFileMatch, IRawSearch, IRawSearchService, ISearchEngine, ISerializedFileMatch, ISerializedSearchComplete, ISerializedSearchProgressItem, ISerializedSearchSuccess, ITelemetryEvent } from './search'; gracefulFs.gracefulify(fs); @@ -41,12 +42,14 @@ export class SearchService implements IRawSearchService { readonly onTelemetry: Event = this._onTelemetry.event; public fileSearch(config: IRawSearch, batchSize = SearchService.BATCH_SIZE): Event { - let promise: TPromise; + let promise: CancelablePromise; const emitter = new Emitter({ onFirstListenerDidAdd: () => { - promise = this.doFileSearch(FileSearchEngine, config, p => emitter.fire(p), batchSize) - .then(c => emitter.fire(c), err => emitter.fire({ type: 'error', error: { message: err.message, stack: err.stack } })); + promise = createCancelablePromise(token => { + return this.doFileSearch(FileSearchEngine, config, p => emitter.fire(p), token, batchSize) + .then(c => emitter.fire(c), err => emitter.fire({ type: 'error', error: { message: err.message, stack: err.stack } })); + }); }, onLastListenerRemove: () => { promise.cancel(); @@ -120,7 +123,7 @@ export class SearchService implements IRawSearchService { return this.doTextSearch(engine, progressCallback, SearchService.BATCH_SIZE, token); } - doFileSearch(EngineClass: { new(config: IRawSearch): ISearchEngine; }, config: IRawSearch, progressCallback: IProgressCallback, batchSize?: number): TPromise { + doFileSearch(EngineClass: { new(config: IRawSearch): ISearchEngine; }, config: IRawSearch, progressCallback: IProgressCallback, token?: CancellationToken, batchSize?: number): TPromise { const fileProgressCallback: IFileProgressCallback = progress => { if (Array.isArray(progress)) { progressCallback(progress.map(m => this.rawMatchToSearchItem(m))); @@ -132,11 +135,11 @@ export class SearchService implements IRawSearchService { }; if (config.sortByScore) { - let sortedSearch = this.trySortedSearchFromCache(config, fileProgressCallback); + let sortedSearch = this.trySortedSearchFromCache(config, fileProgressCallback, token); if (!sortedSearch) { const walkerConfig = config.maxResults ? objects.assign({}, config, { maxResults: null }) : config; const engine = new EngineClass(walkerConfig); - sortedSearch = this.doSortedSearch(engine, config, progressCallback, fileProgressCallback); + sortedSearch = this.doSortedSearch(engine, config, progressCallback, fileProgressCallback, token); } return new TPromise((c, e) => { @@ -147,25 +150,22 @@ export class SearchService implements IRawSearchService { c(result); }, e); }); - }, () => { - sortedSearch.cancel(); }); } const engine = new EngineClass(config); - return this.doSearch(engine, fileProgressCallback, batchSize); + return this.doSearch(engine, fileProgressCallback, batchSize, token); } private rawMatchToSearchItem(match: IRawFileMatch): ISerializedFileMatch { return { path: match.base ? join(match.base, match.relativePath) : match.relativePath }; } - private doSortedSearch(engine: ISearchEngine, config: IRawSearch, progressCallback: IProgressCallback, fileProgressCallback: IFileProgressCallback): TPromise<[ISerializedSearchSuccess, IRawFileMatch[]]> { - let searchPromise: TPromise; + private doSortedSearch(engine: ISearchEngine, config: IRawSearch, progressCallback: IProgressCallback, fileProgressCallback: IFileProgressCallback, token?: CancellationToken): TPromise<[ISerializedSearchSuccess, IRawFileMatch[]]> { const emitter = new Emitter(); - let allResultsPromise = new TPromise<[ISerializedSearchSuccess, IRawFileMatch[]]>((c, e) => { + let allResultsPromise = createCancelablePromise(token => { let results: IRawFileMatch[] = []; const innerProgressCallback: IFileProgressCallback = progress => { @@ -177,17 +177,16 @@ export class SearchService implements IRawSearchService { } }; - searchPromise = this.doSearch(engine, innerProgressCallback, -1) - .then(result => { - c([result, results]); + return this.doSearch(engine, innerProgressCallback, -1, token) + .then<[ISerializedSearchSuccess, IRawFileMatch[]]>(result => { // __GDPR__TODO__ classify event this._onTelemetry.fire({ eventName: 'fileSearch', data: result.stats }); - }, e); - }, () => { - searchPromise.cancel(); + + return [result, results]; + }); }); let cache: Cache; @@ -203,28 +202,25 @@ export class SearchService implements IRawSearchService { allResultsPromise = this.preventCancellation(allResultsPromise); } - let chained: TPromise; - return new TPromise<[ISerializedSearchSuccess, IRawFileMatch[]]>((c, e) => { - chained = allResultsPromise.then(([result, results]) => { + return toWinJsPromise<[ISerializedSearchSuccess, IRawFileMatch[]]>( + allResultsPromise.then(([result, results]) => { const scorerCache: ScorerCache = cache ? cache.scorerCache : Object.create(null); const unsortedResultTime = Date.now(); - return this.sortResults(config, results, scorerCache) - .then(sortedResults => { + return this.sortResults(config, results, scorerCache, token) + .then<[ISerializedSearchSuccess, IRawFileMatch[]]>(sortedResults => { const sortedResultTime = Date.now(); - c([{ + return [{ type: 'success', stats: objects.assign({}, result.stats, { unsortedResultTime, sortedResultTime }), limitHit: result.limitHit || typeof config.maxResults === 'number' && results.length > config.maxResults - } as ISerializedSearchSuccess, sortedResults]); + } as ISerializedSearchSuccess, sortedResults]; }); - }, e); - }, () => { - chained.cancel(); - }); + }) + ); } private getOrCreateCache(cacheKey: string): Cache { @@ -235,57 +231,51 @@ export class SearchService implements IRawSearchService { return this.caches[cacheKey] = new Cache(); } - private trySortedSearchFromCache(config: IRawSearch, progressCallback: IFileProgressCallback): TPromise<[ISerializedSearchSuccess, IRawFileMatch[]]> { + private trySortedSearchFromCache(config: IRawSearch, progressCallback: IFileProgressCallback, token?: CancellationToken): TPromise<[ISerializedSearchSuccess, IRawFileMatch[]]> { const cache = config.cacheKey && this.caches[config.cacheKey]; if (!cache) { return undefined; } const cacheLookupStartTime = Date.now(); - const cached = this.getResultsFromCache(cache, config.filePattern, progressCallback); + const cached = this.getResultsFromCache(cache, config.filePattern, progressCallback, token); if (cached) { - let chained: TPromise; + return cached.then(([result, results, cacheStats]) => { + const cacheLookupResultTime = Date.now(); + return this.sortResults(config, results, cache.scorerCache, token) + .then<[ISerializedSearchSuccess, IRawFileMatch[]]>(sortedResults => { + const sortedResultTime = Date.now(); - return new TPromise<[ISerializedSearchSuccess, IRawFileMatch[]]>((c, e) => { - chained = cached.then(([result, results, cacheStats]) => { - const cacheLookupResultTime = Date.now(); - return this.sortResults(config, results, cache.scorerCache) - .then(sortedResults => { - const sortedResultTime = Date.now(); - - const stats: ICachedSearchStats = { - fromCache: true, - cacheLookupStartTime: cacheLookupStartTime, - cacheFilterStartTime: cacheStats.cacheFilterStartTime, - cacheLookupResultTime: cacheLookupResultTime, - cacheEntryCount: cacheStats.cacheFilterResultCount, - resultCount: results.length - }; - if (config.sortByScore) { - stats.unsortedResultTime = cacheLookupResultTime; - stats.sortedResultTime = sortedResultTime; - } - if (!cacheStats.cacheWasResolved) { - stats.joined = result.stats; - } - c([ - { - type: 'success', - limitHit: result.limitHit || typeof config.maxResults === 'number' && results.length > config.maxResults, - stats: stats - } as ISerializedSearchSuccess, - sortedResults - ]); - }); - }, e); - }, () => { - chained.cancel(); + const stats: ICachedSearchStats = { + fromCache: true, + cacheLookupStartTime: cacheLookupStartTime, + cacheFilterStartTime: cacheStats.cacheFilterStartTime, + cacheLookupResultTime: cacheLookupResultTime, + cacheEntryCount: cacheStats.cacheFilterResultCount, + resultCount: results.length + }; + if (config.sortByScore) { + stats.unsortedResultTime = cacheLookupResultTime; + stats.sortedResultTime = sortedResultTime; + } + if (!cacheStats.cacheWasResolved) { + stats.joined = result.stats; + } + return [ + { + type: 'success', + limitHit: result.limitHit || typeof config.maxResults === 'number' && results.length > config.maxResults, + stats: stats + } as ISerializedSearchSuccess, + sortedResults + ]; + }); }); } return undefined; } - private sortResults(config: IRawSearch, results: IRawFileMatch[], scorerCache: ScorerCache): TPromise { + private sortResults(config: IRawSearch, results: IRawFileMatch[], scorerCache: ScorerCache, token?: CancellationToken): TPromise { // we use the same compare function that is used later when showing the results using fuzzy scoring // this is very important because we are also limiting the number of results by config.maxResults // and as such we want the top items to be included in this result set if the number of items @@ -293,7 +283,7 @@ export class SearchService implements IRawSearchService { const query = prepareQuery(config.filePattern); const compare = (matchA: IRawFileMatch, matchB: IRawFileMatch) => compareItemsByScore(matchA, matchB, query, true, FileMatchItemAccessor, scorerCache); - return arrays.topAsync(results, compare, config.maxResults, 10000); + return arrays.topAsync(results, compare, config.maxResults, 10000, token); } private sendProgress(results: ISerializedFileMatch[], progressCb: IProgressCallback, batchSize: number) { @@ -306,13 +296,12 @@ export class SearchService implements IRawSearchService { } } - private getResultsFromCache(cache: Cache, searchValue: string, progressCallback: IFileProgressCallback): TPromise<[ISerializedSearchSuccess, IRawFileMatch[], CacheStats]> { + private getResultsFromCache(cache: Cache, searchValue: string, progressCallback: IFileProgressCallback, token?: CancellationToken): TPromise<[ISerializedSearchSuccess, IRawFileMatch[], CacheStats]> { // Find cache entries by prefix of search value const hasPathSep = searchValue.indexOf(sep) >= 0; let cachedRow: CacheRow; let wasResolved: boolean; for (let previousSearch in cache.resultsToSearchCache) { - // If we narrow down, we might be able to reuse the cached results if (strings.startsWith(searchValue, previousSearch)) { if (hasPathSep && previousSearch.indexOf(sep) < 0) { @@ -335,35 +324,39 @@ export class SearchService implements IRawSearchService { } const listener = cachedRow.event(progressCallback); + if (token) { + token.onCancellationRequested(() => { + listener.dispose(); + }); + } - return new TPromise<[ISerializedSearchSuccess, IRawFileMatch[], CacheStats]>((c, e) => { - cachedRow.promise.then(([complete, cachedEntries]) => { - const cacheFilterStartTime = Date.now(); + return toWinJsPromise(cachedRow.promise.then<[ISerializedSearchSuccess, IRawFileMatch[], CacheStats]>(([complete, cachedEntries]) => { + if (token && token.isCancellationRequested) { + throw canceled(); + } - // Pattern match on results - let results: IRawFileMatch[] = []; - const normalizedSearchValueLowercase = strings.stripWildcards(searchValue).toLowerCase(); - for (let i = 0; i < cachedEntries.length; i++) { - let entry = cachedEntries[i]; + const cacheFilterStartTime = Date.now(); - // Check if this entry is a match for the search value - if (!strings.fuzzyContains(entry.relativePath, normalizedSearchValueLowercase)) { - continue; - } + // Pattern match on results + let results: IRawFileMatch[] = []; + const normalizedSearchValueLowercase = strings.stripWildcards(searchValue).toLowerCase(); + for (let i = 0; i < cachedEntries.length; i++) { + let entry = cachedEntries[i]; - results.push(entry); + // Check if this entry is a match for the search value + if (!strings.fuzzyContains(entry.relativePath, normalizedSearchValueLowercase)) { + continue; } - c([complete, results, { - cacheWasResolved: wasResolved, - cacheFilterStartTime: cacheFilterStartTime, - cacheFilterResultCount: cachedEntries.length - }]); - }, e); - }, () => { - cachedRow.promise.cancel(); - listener.dispose(); - }); + results.push(entry); + } + + return [complete, results, { + cacheWasResolved: wasResolved, + cacheFilterStartTime: cacheFilterStartTime, + cacheFilterResultCount: cachedEntries.length + }] as [ISerializedSearchSuccess, IRawFileMatch[], CacheStats]; // TS? + })); } private doTextSearch(engine: TextSearchEngine, progressCallback: IProgressCallback, batchSize: number, token: CancellationToken): Promise { @@ -389,9 +382,13 @@ export class SearchService implements IRawSearchService { }); } - private doSearch(engine: ISearchEngine, progressCallback: IFileProgressCallback, batchSize?: number): TPromise { + private doSearch(engine: ISearchEngine, progressCallback: IFileProgressCallback, batchSize: number, token?: CancellationToken): TPromise { return new TPromise((c, e) => { let batch: IRawFileMatch[] = []; + if (token) { + token.onCancellationRequested(() => engine.cancel()); + } + engine.search((match) => { if (match) { if (batchSize) { @@ -418,8 +415,6 @@ export class SearchService implements IRawSearchService { c(stats); } }); - }, () => { - engine.cancel(); }); } @@ -428,20 +423,28 @@ export class SearchService implements IRawSearchService { return TPromise.as(undefined); } - private preventCancellation(promise: TPromise): TPromise { - return new TPromise((c, e) => { - // Allow for piled up cancellations to come through first. - process.nextTick(() => { - promise.then(c, e); - }); - }, () => { - // Do not propagate. - }); + /** + * Return a CancelablePromise which is not actually cancelable + * TODO@rob - Is this really needed? + */ + private preventCancellation(promise: CancelablePromise): CancelablePromise { + return new class implements CancelablePromise { + cancel() { + // Do nothing + } + then(resolve, reject) { + return promise.then(resolve, reject); + } + catch(reject?) { + return this.then(undefined, reject); + } + }; } } interface CacheRow { - promise: TPromise<[ISerializedSearchSuccess, IRawFileMatch[]]>; + // TODO@roblou - never actually canceled + promise: CancelablePromise<[ISerializedSearchSuccess, IRawFileMatch[]]>; event: Event; } diff --git a/src/vs/workbench/services/search/test/node/searchService.test.ts b/src/vs/workbench/services/search/test/node/searchService.test.ts index 23a434569ea..f679c79dc82 100644 --- a/src/vs/workbench/services/search/test/node/searchService.test.ts +++ b/src/vs/workbench/services/search/test/node/searchService.test.ts @@ -7,14 +7,13 @@ import * as assert from 'assert'; import * as path from 'path'; - -import { IProgress, IUncachedSearchStats } from 'vs/platform/search/common/search'; -import { ISearchEngine, IRawSearch, IRawFileMatch, ISerializedFileMatch, IFolderSearch, ISerializedSearchSuccess, ISerializedSearchProgressItem, ISerializedSearchComplete } from 'vs/workbench/services/search/node/search'; -import { SearchService as RawSearchService } from 'vs/workbench/services/search/node/rawSearchService'; -import { DiskSearch } from 'vs/workbench/services/search/node/searchService'; -import { Emitter, Event } from 'vs/base/common/event'; -import { TPromise } from 'vs/base/common/winjs.base'; import { getPathFromAmdModule } from 'vs/base/common/amd'; +import { CancelablePromise, createCancelablePromise } from 'vs/base/common/async'; +import { Emitter, Event } from 'vs/base/common/event'; +import { IProgress, IUncachedSearchStats } from 'vs/platform/search/common/search'; +import { SearchService as RawSearchService } from 'vs/workbench/services/search/node/rawSearchService'; +import { IFolderSearch, IRawFileMatch, IRawSearch, ISearchEngine, ISerializedFileMatch, ISerializedSearchComplete, ISerializedSearchProgressItem, ISerializedSearchSuccess } from 'vs/workbench/services/search/node/search'; +import { DiskSearch } from 'vs/workbench/services/search/node/searchService'; const TEST_FOLDER_QUERIES = [ { folder: path.normalize('/some/where') } @@ -137,7 +136,7 @@ suite('SearchService', () => { } }; - return service.doFileSearch(Engine, rawSearch, cb, 10).then(() => { + return service.doFileSearch(Engine, rawSearch, cb, undefined, 10).then(() => { assert.deepStrictEqual(results, [10, 10, 5]); }); }); @@ -150,12 +149,12 @@ suite('SearchService', () => { const service = new RawSearchService(); function fileSearch(config: IRawSearch, batchSize: number): Event { - let promise: TPromise; + let promise: CancelablePromise; const emitter = new Emitter({ onFirstListenerAdd: () => { - promise = service.doFileSearch(Engine, config, p => emitter.fire(p), batchSize) - .then(c => emitter.fire(c), err => emitter.fire({ type: 'error', error: err })); + promise = createCancelablePromise(token => service.doFileSearch(Engine, config, p => emitter.fire(p), token, batchSize) + .then(c => emitter.fire(c), err => emitter.fire({ type: 'error', error: err }))); }, onLastListenerRemove: () => { promise.cancel(); @@ -243,7 +242,7 @@ suite('SearchService', () => { filePattern: 'bb', sortByScore: true, maxResults: 2 - }, cb, 1).then(() => { + }, cb, undefined, 1).then(() => { assert.notStrictEqual(typeof TestSearchEngine.last.config.maxResults, 'number'); assert.deepStrictEqual(results, [path.normalize('/some/where/bbc'), path.normalize('/some/where/bab')]); }); @@ -271,7 +270,7 @@ suite('SearchService', () => { filePattern: 'a', sortByScore: true, maxResults: 23 - }, cb, 10) + }, cb, undefined, 10) .then(() => { assert.deepStrictEqual(results, [10, 10, 3]); }); @@ -302,7 +301,7 @@ suite('SearchService', () => { filePattern: 'b', sortByScore: true, cacheKey: 'x' - }, cb, -1).then(complete => { + }, cb, undefined, -1).then(complete => { assert.strictEqual(complete.stats.fromCache, false); assert.deepStrictEqual(results, [path.normalize('/some/where/bcb'), path.normalize('/some/where/bbc'), path.normalize('/some/where/aab')]); }).then(() => { @@ -319,7 +318,7 @@ suite('SearchService', () => { filePattern: 'bc', sortByScore: true, cacheKey: 'x' - }, cb, -1).then(complete => { + }, cb, undefined, -1).then(complete => { assert.ok(complete.stats.fromCache); assert.deepStrictEqual(results, [path.normalize('/some/where/bcb'), path.normalize('/some/where/bbc')]); }, null); @@ -345,7 +344,7 @@ suite('SearchService', () => { filePattern: 'bc', sortByScore: true, cacheKey: 'x' - }, cb, -1).then(complete => { + }, cb, undefined, -1).then(complete => { assert.strictEqual(complete.stats.fromCache, false); assert.deepStrictEqual(results, [path.normalize('/some/where/bc')]); }); From f65db76106c3a5702860c3740fc76497677f35aa Mon Sep 17 00:00:00 2001 From: Jackson Kearl Date: Tue, 14 Aug 2018 15:56:11 -0700 Subject: [PATCH 0802/1276] Expand the set of types which we can render in enum pickers (#56412) --- .../parts/preferences/browser/settingsTreeModels.ts | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/vs/workbench/parts/preferences/browser/settingsTreeModels.ts b/src/vs/workbench/parts/preferences/browser/settingsTreeModels.ts index 9776dee8b99..6daedddb33e 100644 --- a/src/vs/workbench/parts/preferences/browser/settingsTreeModels.ts +++ b/src/vs/workbench/parts/preferences/browser/settingsTreeModels.ts @@ -115,7 +115,7 @@ export class SettingsTreeSettingElement extends SettingsTreeElement { this.overriddenScopeList = overriddenScopeList; this.description = this.setting.description.join('\n'); - if (this.setting.enum && (this.setting.type === 'string' || !this.setting.type)) { + if (this.setting.enum && (!this.setting.type || settingTypeEnumRenderable(this.setting.type))) { this.valueType = 'enum'; } else if (this.setting.type === 'string') { this.valueType = 'string'; @@ -327,6 +327,12 @@ export function isExcludeSetting(setting: ISetting): boolean { setting.key === 'search.exclude'; } +function settingTypeEnumRenderable(_type: string | string[]) { + const enumRenderableSettingTypes = ['string', 'boolean', 'null', 'integer', 'number']; + let type = isArray(_type) ? _type : [_type]; + return type.every(type => enumRenderableSettingTypes.indexOf(type) > -1); +} + export enum SearchResultIdx { Local = 0, Remote = 1, From efa2906bb12b8cdbdbe8845ec4a2cbea68a8b587 Mon Sep 17 00:00:00 2001 From: Rob Lourens Date: Tue, 14 Aug 2018 16:24:08 -0700 Subject: [PATCH 0803/1276] Fix #56415 - 'new' tag for settings --- src/vs/editor/common/config/commonEditorConfig.ts | 6 ++++-- src/vs/workbench/electron-browser/main.contribution.ts | 3 ++- .../workbench/parts/preferences/browser/settingsEditor2.ts | 4 ++++ 3 files changed, 10 insertions(+), 3 deletions(-) diff --git a/src/vs/editor/common/config/commonEditorConfig.ts b/src/vs/editor/common/config/commonEditorConfig.ts index 07380bbb371..35389354cef 100644 --- a/src/vs/editor/common/config/commonEditorConfig.ts +++ b/src/vs/editor/common/config/commonEditorConfig.ts @@ -492,12 +492,14 @@ const editorConfiguration: IConfigurationNode = { 'editor.parameterHints.enabled': { 'type': 'boolean', 'default': EDITOR_DEFAULTS.contribInfo.parameterHints.enabled, - 'description': nls.localize('parameterHints.enabled', "Enables a pop-up that shows parameter documentation and type information as you type.") + 'description': nls.localize('parameterHints.enabled', "Enables a pop-up that shows parameter documentation and type information as you type."), + 'tags': ['new'] }, 'editor.parameterHints.cycle': { 'type': 'boolean', 'default': EDITOR_DEFAULTS.contribInfo.parameterHints.cycle, - 'description': nls.localize('parameterHints.cycle', "Controls whether the parameter hints menu cycles or closes when reaching the end of the list.") + 'description': nls.localize('parameterHints.cycle', "Controls whether the parameter hints menu cycles or closes when reaching the end of the list."), + 'tags': ['new'] }, 'editor.autoClosingBrackets': { 'type': 'boolean', diff --git a/src/vs/workbench/electron-browser/main.contribution.ts b/src/vs/workbench/electron-browser/main.contribution.ts index 150d1754371..d1d7e6d8dbe 100644 --- a/src/vs/workbench/electron-browser/main.contribution.ts +++ b/src/vs/workbench/electron-browser/main.contribution.ts @@ -653,7 +653,8 @@ configurationRegistry.registerConfiguration({ ], 'description': nls.localize('settings.editor.desc', "Determines which settings editor to use by default."), 'default': 'ui', - 'scope': ConfigurationScope.WINDOW + 'scope': ConfigurationScope.WINDOW, + 'tags': ['new'] }, 'workbench.enableExperiments': { 'type': 'boolean', diff --git a/src/vs/workbench/parts/preferences/browser/settingsEditor2.ts b/src/vs/workbench/parts/preferences/browser/settingsEditor2.ts index 69fa9d13e74..d94b01b7d5b 100644 --- a/src/vs/workbench/parts/preferences/browser/settingsEditor2.ts +++ b/src/vs/workbench/parts/preferences/browser/settingsEditor2.ts @@ -247,6 +247,10 @@ export class SettingsEditor2 extends BaseEditor { this.instantiationService.createInstance(FilterByTagAction, localize('filterModifiedLabel', "Show modified settings"), MODIFIED_SETTING_TAG, + this), + this.instantiationService.createInstance(FilterByTagAction, + localize('filterNewLabel', "Show new settings"), + 'new', this) ]; if (this.environmentService.appQuality !== 'stable') { From 6f010b081e1fc4a99e5edd007f6c6ce8bdba0e84 Mon Sep 17 00:00:00 2001 From: Rob Lourens Date: Tue, 14 Aug 2018 16:44:51 -0700 Subject: [PATCH 0804/1276] Settings editor - fix setting links --- .../preferences/browser/settingsEditor2.ts | 23 ++++++------------- 1 file changed, 7 insertions(+), 16 deletions(-) diff --git a/src/vs/workbench/parts/preferences/browser/settingsEditor2.ts b/src/vs/workbench/parts/preferences/browser/settingsEditor2.ts index d94b01b7d5b..2a56a5f69c9 100644 --- a/src/vs/workbench/parts/preferences/browser/settingsEditor2.ts +++ b/src/vs/workbench/parts/preferences/browser/settingsEditor2.ts @@ -36,7 +36,7 @@ import { PreferencesEditor } from 'vs/workbench/parts/preferences/browser/prefer import { SettingsTarget, SettingsTargetsWidget } from 'vs/workbench/parts/preferences/browser/preferencesWidgets'; import { commonlyUsedData, tocData } from 'vs/workbench/parts/preferences/browser/settingsLayout'; import { resolveExtensionsSettings, resolveSettingsTree, SettingsRenderer, SettingsTree } from 'vs/workbench/parts/preferences/browser/settingsTree'; -import { ISettingsEditorViewState, MODIFIED_SETTING_TAG, ONLINE_SERVICES_SETTING_TAG, SearchResultIdx, SearchResultModel, SettingsTreeElement, SettingsTreeGroupElement, SettingsTreeModel, SettingsTreeSettingElement } from 'vs/workbench/parts/preferences/browser/settingsTreeModels'; +import { ISettingsEditorViewState, MODIFIED_SETTING_TAG, ONLINE_SERVICES_SETTING_TAG, SearchResultIdx, SearchResultModel, SettingsTreeGroupElement, SettingsTreeModel, SettingsTreeSettingElement } from 'vs/workbench/parts/preferences/browser/settingsTreeModels'; import { TOCRenderer, TOCTree, TOCTreeModel } from 'vs/workbench/parts/preferences/browser/tocTree'; import { CONTEXT_SETTINGS_EDITOR, CONTEXT_SETTINGS_SEARCH_FOCUS, CONTEXT_TOC_ROW_FOCUS, IPreferencesSearchService, ISearchProvider } from 'vs/workbench/parts/preferences/common/preferences'; import { IEditorGroup } from 'vs/workbench/services/group/common/editorGroupsService'; @@ -272,22 +272,13 @@ export class SettingsEditor2 extends BaseEditor { return this.currentSettingsModel.getElementByName(settingKey); } - private revealSetting(settingKey: string): void { - const element = this.getElementsByKey(settingKey); - if (element) { - this.settingsTree.reveal(element, .1); + private revealSettingByKey(settingKey: string): void { + const elements = this.getElementsByKey(settingKey); + if (elements && elements[0]) { + this.settingsTree.reveal(elements[0]); } } - private revealSettingElement(element: SettingsTreeElement): void { - const top = this.settingsTree.getRelativeTop(element); - const clampedTop = Math.max( - Math.min(top, .9), - .1); - - this.settingsTree.reveal(element, clampedTop); - } - private openSettingsFile(): TPromise { const currentSettingsTarget = this.settingsTargetsWidget.settingsTarget; @@ -406,8 +397,8 @@ export class SettingsEditor2 extends BaseEditor { } }); })); - this._register(this.settingsTreeRenderer.onDidClickSettingLink(settingName => this.revealSetting(settingName))); - this._register(this.settingsTreeRenderer.onDidFocusSetting(element => this.revealSettingElement(element))); + this._register(this.settingsTreeRenderer.onDidClickSettingLink(settingName => this.revealSettingByKey(settingName))); + this._register(this.settingsTreeRenderer.onDidFocusSetting(element => this.settingsTree.reveal(element))); this.settingsTree = this._register(this.instantiationService.createInstance(SettingsTree, this.settingsTreeContainer, From 36b7a89211d4316521646772f5f771c6e1eb1088 Mon Sep 17 00:00:00 2001 From: Rob Lourens Date: Tue, 14 Aug 2018 16:49:02 -0700 Subject: [PATCH 0805/1276] Settings editor - avoid rendering templates every time during measurement. Actually use measurement template cache --- src/vs/workbench/parts/preferences/browser/settingsTree.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/src/vs/workbench/parts/preferences/browser/settingsTree.ts b/src/vs/workbench/parts/preferences/browser/settingsTree.ts index d02076645d9..157578cf08d 100644 --- a/src/vs/workbench/parts/preferences/browser/settingsTree.ts +++ b/src/vs/workbench/parts/preferences/browser/settingsTree.ts @@ -340,6 +340,7 @@ export class SettingsRenderer implements ITreeRenderer { private measureSettingElementHeight(tree: ITree, element: SettingsTreeSettingElement): number { const templateId = this.getTemplateId(tree, element); const template: ISettingItemTemplate = this.measureTemplatesPool.get(templateId) || this.renderTemplate(tree, templateId, $('.setting-measure-helper')) as ISettingItemTemplate; + this.measureTemplatesPool.set(templateId, template); this.renderElement(tree, element, templateId, template); this.measureContainer.appendChild(template.containerElement); From 75be73cb4b282f6fc0b202151a8572d8572a991c Mon Sep 17 00:00:00 2001 From: Rob Lourens Date: Tue, 14 Aug 2018 18:46:23 -0700 Subject: [PATCH 0806/1276] Settings editor - also focus control when revealing setting via setting link --- .../parts/preferences/browser/settingsEditor2.ts | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/vs/workbench/parts/preferences/browser/settingsEditor2.ts b/src/vs/workbench/parts/preferences/browser/settingsEditor2.ts index 2a56a5f69c9..0a7bf0c4bf6 100644 --- a/src/vs/workbench/parts/preferences/browser/settingsEditor2.ts +++ b/src/vs/workbench/parts/preferences/browser/settingsEditor2.ts @@ -276,6 +276,14 @@ export class SettingsEditor2 extends BaseEditor { const elements = this.getElementsByKey(settingKey); if (elements && elements[0]) { this.settingsTree.reveal(elements[0]); + + const domElements = this.settingsTreeRenderer.getDOMElementsForSettingKey(this.settingsTree.getHTMLElement(), settingKey); + if (domElements && domElements[0]) { + const control = domElements[0].querySelector(SettingsRenderer.CONTROL_SELECTOR); + if (control) { + (control).focus(); + } + } } } From ffa660576d3a8da3f6cf9b94cbfb879632688ebd Mon Sep 17 00:00:00 2001 From: Rob Lourens Date: Tue, 14 Aug 2018 21:19:32 -0700 Subject: [PATCH 0807/1276] Settings editor - also show 'new' tag in suggestions --- .../workbench/parts/preferences/browser/settingsEditor2.ts | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/vs/workbench/parts/preferences/browser/settingsEditor2.ts b/src/vs/workbench/parts/preferences/browser/settingsEditor2.ts index 0a7bf0c4bf6..31e0b9e6e33 100644 --- a/src/vs/workbench/parts/preferences/browser/settingsEditor2.ts +++ b/src/vs/workbench/parts/preferences/browser/settingsEditor2.ts @@ -50,6 +50,10 @@ export class SettingsEditor2 extends BaseEditor { public static readonly ID: string = 'workbench.editor.settings2'; + private static readonly SUGGESTIONS: string[] = [ + '@modified', '@tag:usesOnlineServices', '@tag:new' + ]; + private defaultSettingsEditorModel: DefaultSettingsEditorModel; private rootElement: HTMLElement; @@ -210,7 +214,7 @@ export class SettingsEditor2 extends BaseEditor { this.searchWidget = this._register(this.instantiationService.createInstance(SuggestEnabledInput, `${SettingsEditor2.ID}.searchbox`, searchContainer, { triggerCharacters: ['@'], provideResults: (query: string) => { - return ['@modified', '@tag:usesOnlineServices'].filter(tag => query.indexOf(tag) === -1).map(tag => tag + ' '); + return SettingsEditor2.SUGGESTIONS.filter(tag => query.indexOf(tag) === -1).map(tag => tag + ' '); } }, searchBoxLabel, 'settingseditor:searchinput', { placeholderText: searchBoxLabel, From 43e23215406f0e8f821df89709e48de15da10ee3 Mon Sep 17 00:00:00 2001 From: SteVen Batten <6561887+sbatten@users.noreply.github.com> Date: Tue, 14 Aug 2018 23:22:48 -0700 Subject: [PATCH 0808/1276] fixes issues with menubar in fullscreen (#56414) --- .../browser/parts/titlebar/menubarControl.ts | 32 +++++++++++++------ .../browser/parts/titlebar/titlebarPart.ts | 5 +++ .../workbench/electron-browser/workbench.ts | 31 +++++++++++++++++- 3 files changed, 57 insertions(+), 11 deletions(-) diff --git a/src/vs/workbench/browser/parts/titlebar/menubarControl.ts b/src/vs/workbench/browser/parts/titlebar/menubarControl.ts index 30c0ef9630a..78a6928f254 100644 --- a/src/vs/workbench/browser/parts/titlebar/menubarControl.ts +++ b/src/vs/workbench/browser/parts/titlebar/menubarControl.ts @@ -229,17 +229,23 @@ export class MenubarControl extends Disposable { return; } + const isVisible = this.isVisible; + const isOpen = this.isOpen; + const isFocused = this.isFocused; + + this._focusState = value; + switch (value) { case MenubarState.HIDDEN: - if (this.isVisible) { + if (isVisible) { this.hideMenubar(); } - if (this.isOpen) { + if (isOpen) { this.cleanupCustomMenu(); } - if (this.isFocused) { + if (isFocused) { this.focusedMenu = null; if (this.focusToReturn) { @@ -251,15 +257,15 @@ export class MenubarControl extends Disposable { break; case MenubarState.VISIBLE: - if (!this.isVisible) { + if (!isVisible) { this.showMenubar(); } - if (this.isOpen) { + if (isOpen) { this.cleanupCustomMenu(); } - if (this.isFocused) { + if (isFocused) { if (this.focusedMenu) { this.customMenus[this.focusedMenu.index].buttonElement.blur(); } @@ -274,11 +280,11 @@ export class MenubarControl extends Disposable { break; case MenubarState.FOCUSED: - if (!this.isVisible) { + if (!isVisible) { this.showMenubar(); } - if (this.isOpen) { + if (isOpen) { this.cleanupCustomMenu(); } @@ -287,7 +293,7 @@ export class MenubarControl extends Disposable { } break; case MenubarState.OPEN: - if (!this.isVisible) { + if (!isVisible) { this.showMenubar(); } @@ -338,7 +344,13 @@ export class MenubarControl extends Disposable { } private setUnfocusedState(): void { - this.focusState = this.currentMenubarVisibility === 'toggle' || this.currentMenubarVisibility === 'hidden' ? MenubarState.HIDDEN : MenubarState.VISIBLE; + if (this.currentMenubarVisibility === 'toggle' || this.currentMenubarVisibility === 'hidden') { + this.focusState = MenubarState.HIDDEN; + } else if (this.currentMenubarVisibility === 'default' && browser.isFullscreen()) { + this.focusState = MenubarState.HIDDEN; + } else { + this.focusState = MenubarState.VISIBLE; + } } private hideMenubar(): void { diff --git a/src/vs/workbench/browser/parts/titlebar/titlebarPart.ts b/src/vs/workbench/browser/parts/titlebar/titlebarPart.ts index fe01f90cbe0..84702f9de77 100644 --- a/src/vs/workbench/browser/parts/titlebar/titlebarPart.ts +++ b/src/vs/workbench/browser/parts/titlebar/titlebarPart.ts @@ -35,6 +35,7 @@ import { MenubarControl } from 'vs/workbench/browser/parts/titlebar/menubarContr import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; import { template, getBaseLabel } from 'vs/base/common/labels'; import { IUriDisplayService } from 'vs/platform/uriDisplay/common/uriDisplay'; +import { Event } from 'vs/base/common/event'; export class TitlebarPart extends Part implements ITitleService { @@ -134,6 +135,10 @@ export class TitlebarPart extends Part implements ITitleService { } } + onMenubarVisibilityChange(): Event { + return this.menubarPart.onVisibilityChange; + } + private onActiveEditorChange(): void { // Dispose old listeners diff --git a/src/vs/workbench/electron-browser/workbench.ts b/src/vs/workbench/electron-browser/workbench.ts index c8682932cd2..61bbd350fa7 100644 --- a/src/vs/workbench/electron-browser/workbench.ts +++ b/src/vs/workbench/electron-browser/workbench.ts @@ -219,6 +219,7 @@ export class Workbench extends Disposable implements IPartService { private sideBarHidden: boolean; private statusBarHidden: boolean; private activityBarHidden: boolean; + private menubarToggled: boolean; private sideBarPosition: Position; private panelPosition: Position; private panelHidden: boolean; @@ -532,6 +533,16 @@ export class Workbench extends Disposable implements IPartService { } } + private onMenubarToggled(visible: boolean) { + if (visible !== this.menubarToggled) { + this.menubarToggled = visible; + + if (this.menubarVisibility === 'toggle' || (browser.isFullscreen() && this.menubarVisibility === 'default')) { + this.layout(); + } + } + } + private onEditorClosed(listenerDispose: IDisposable, resourcesToWaitFor: URI[], waitMarkerFile: URI): void { // In wait mode, listen to changes to the editors and wait until the files @@ -1004,6 +1015,12 @@ export class Workbench extends Disposable implements IPartService { // Notification Handlers this.createNotificationsHandlers(); + + // Menubar visibility changes + if ((isWindows || isLinux) && this.getCustomTitleBarStyle() === 'custom') { + this.titlebarPart.onMenubarVisibilityChange()(e => this.onMenubarToggled(e)); + } + // Add Workbench to DOM this.container.appendChild(this.workbench); } @@ -1160,7 +1177,19 @@ export class Workbench extends Disposable implements IPartService { isVisible(part: Parts): boolean { switch (part) { case Parts.TITLEBAR_PART: - return this.getCustomTitleBarStyle() === 'custom' && (!browser.isFullscreen() || this.menubarVisibility === 'visible' || this.menubarVisibility === 'toggle'); + if (this.getCustomTitleBarStyle() !== 'custom') { + return false; + } else if (!browser.isFullscreen()) { + return true; + } else if (isMacintosh) { + return false; + } else if (this.menubarVisibility === 'visible') { + return true; + } else if (this.menubarVisibility === 'toggle' || this.menubarVisibility === 'default') { + return this.menubarToggled; + } + + return false; case Parts.SIDEBAR_PART: return !this.sideBarHidden; case Parts.PANEL_PART: From 87d71aac01e4f8d161587d90ef37d3f583012fa2 Mon Sep 17 00:00:00 2001 From: Johannes Rieken Date: Wed, 15 Aug 2018 09:25:53 +0200 Subject: [PATCH 0809/1276] copy nls-json-files, don't inline vscode-nls --- extensions/git/.vscodeignore | 1 + extensions/git/extension.webpack.config.js | 6 +++++- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/extensions/git/.vscodeignore b/extensions/git/.vscodeignore index 1b352bc4ec1..57779dd2a63 100644 --- a/extensions/git/.vscodeignore +++ b/extensions/git/.vscodeignore @@ -4,3 +4,4 @@ out/** tsconfig.json build/** node_modules/** +!node_modules/vscode-nls/** diff --git a/extensions/git/extension.webpack.config.js b/extensions/git/extension.webpack.config.js index 2562c12140b..28aa93b4918 100644 --- a/extensions/git/extension.webpack.config.js +++ b/extensions/git/extension.webpack.config.js @@ -30,9 +30,13 @@ module.exports = { }, externals: { 'vscode': 'commonjs vscode', + 'vscode-nls': 'commonjs vscode-nls', }, plugins: [ - new CopyWebpackPlugin([{ from: './out/*.sh', to: '[name].sh' }]) + new CopyWebpackPlugin([ + { from: './out/*.sh', to: '[name].sh' }, + { from: './out/nls.*.json', to: '[name].json' } + ]) ], stats: 'errors-only', devtool: 'source-map', From fbeb7277dad98d05e27332a45538d07f0aa1bf10 Mon Sep 17 00:00:00 2001 From: Johannes Rieken Date: Wed, 15 Aug 2018 09:30:01 +0200 Subject: [PATCH 0810/1276] set `keepFilenames`-option --- build/gulpfile.extensions.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/build/gulpfile.extensions.js b/build/gulpfile.extensions.js index acc7d90bfb7..57d52b03b06 100644 --- a/build/gulpfile.extensions.js +++ b/build/gulpfile.extensions.js @@ -89,7 +89,7 @@ const tasks = compilations.map(function (tsconfigFile) { .pipe(tsFilter) .pipe(util.loadSourcemaps()) .pipe(compilation()) - .pipe(build ? nlsDev.rewriteLocalizeCalls() : es.through()) + .pipe(build ? nlsDev.rewriteLocalizeCalls({ keepFilenames: true }) : es.through()) .pipe(build ? util.stripSourceMappingURL() : es.through()) .pipe(sourcemaps.write('.', { sourceMappingURL: !build ? null : f => `${baseUrl}/${f.relative}.map`, @@ -167,4 +167,4 @@ gulp.task('watch-extensions', tasks.map(t => t.watch)); gulp.task('clean-extensions-build', tasks.map(t => t.cleanBuild)); gulp.task('compile-extensions-build', tasks.map(t => t.compileBuild)); -gulp.task('watch-extensions-build', tasks.map(t => t.watchBuild)); \ No newline at end of file +gulp.task('watch-extensions-build', tasks.map(t => t.watchBuild)); From d8dd5c392837442ed0f1bf10a65f63eba0216af7 Mon Sep 17 00:00:00 2001 From: Johannes Rieken Date: Wed, 15 Aug 2018 09:46:30 +0200 Subject: [PATCH 0811/1276] remove unused import --- src/vs/vscode.proposed.d.ts | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/vs/vscode.proposed.d.ts b/src/vs/vscode.proposed.d.ts index 03f3b993f60..ffb260b891f 100644 --- a/src/vs/vscode.proposed.d.ts +++ b/src/vs/vscode.proposed.d.ts @@ -3,9 +3,7 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -// This is the place for API experiments and proposal. - -import { QuickPickItem } from 'vscode'; +// This is the place for API experiments and proposals. declare module 'vscode' { From 5a25b69ee5a785d19d9a164284dbd01366c49a08 Mon Sep 17 00:00:00 2001 From: Johannes Rieken Date: Wed, 15 Aug 2018 10:38:26 +0200 Subject: [PATCH 0812/1276] :lipstick: #54938 --- src/vs/workbench/api/node/extHostDecorations.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/vs/workbench/api/node/extHostDecorations.ts b/src/vs/workbench/api/node/extHostDecorations.ts index 77d9b441fc8..763caf53ab9 100644 --- a/src/vs/workbench/api/node/extHostDecorations.ts +++ b/src/vs/workbench/api/node/extHostDecorations.ts @@ -22,10 +22,10 @@ export class ExtHostDecorations implements ExtHostDecorationsShape { this._proxy = mainContext.getProxy(MainContext.MainThreadDecorations); } - registerDecorationProvider(provider: vscode.DecorationProvider, label: string): vscode.Disposable { + registerDecorationProvider(provider: vscode.DecorationProvider, extensionId: string): vscode.Disposable { const handle = ExtHostDecorations._handlePool++; this._provider.set(handle, provider); - this._proxy.$registerDecorationProvider(handle, label); + this._proxy.$registerDecorationProvider(handle, extensionId); const listener = provider.onDidChangeDecorations(e => { this._proxy.$onDidChange(handle, !e ? null : Array.isArray(e) ? e : [e]); From 0ed7b0e701592f42374e825fb1a22cd41bf97305 Mon Sep 17 00:00:00 2001 From: Johannes Rieken Date: Wed, 15 Aug 2018 10:48:09 +0200 Subject: [PATCH 0813/1276] rename abbreviation to letter, #54938 --- extensions/git/src/decorationProvider.ts | 2 +- extensions/git/src/repository.ts | 4 ++-- src/vs/vscode.proposed.d.ts | 8 ++++---- .../workbench/api/node/extHostDecorations.ts | 18 +++++++++++++----- 4 files changed, 20 insertions(+), 12 deletions(-) diff --git a/extensions/git/src/decorationProvider.ts b/extensions/git/src/decorationProvider.ts index 48594918f5d..4d15bb814ac 100644 --- a/extensions/git/src/decorationProvider.ts +++ b/extensions/git/src/decorationProvider.ts @@ -93,7 +93,7 @@ class GitDecorationProvider implements DecorationProvider { private static SubmoduleDecorationData: DecorationData = { title: 'Submodule', - abbreviation: 'S', + letter: 'S', color: new ThemeColor('gitDecoration.submoduleResourceForeground') }; diff --git a/extensions/git/src/repository.ts b/extensions/git/src/repository.ts index b3af0698312..c2c9a2f344d 100644 --- a/extensions/git/src/repository.ts +++ b/extensions/git/src/repository.ts @@ -259,10 +259,10 @@ export class Resource implements SourceControlResourceState { get resourceDecoration(): DecorationData { const title = this.tooltip; - const abbreviation = this.letter; + const letter = this.letter; const color = this.color; const priority = this.priority; - return { bubble: true, source: 'git.resource', title, abbreviation, color, priority }; + return { bubble: true, source: 'git.resource', title, letter, color, priority }; } constructor( diff --git a/src/vs/vscode.proposed.d.ts b/src/vs/vscode.proposed.d.ts index ffb260b891f..e48ce71fb1a 100644 --- a/src/vs/vscode.proposed.d.ts +++ b/src/vs/vscode.proposed.d.ts @@ -357,11 +357,11 @@ declare module 'vscode' { //todo@joh -> make class export interface DecorationData { - priority?: number; - title?: string; - bubble?: boolean; - abbreviation?: string; // letter, not optional + letter: string; + title: string; color?: ThemeColor; + priority?: number; + bubble?: boolean; source?: string; // hacky... we should remove it and use equality under the hood } diff --git a/src/vs/workbench/api/node/extHostDecorations.ts b/src/vs/workbench/api/node/extHostDecorations.ts index 763caf53ab9..4ffee738596 100644 --- a/src/vs/workbench/api/node/extHostDecorations.ts +++ b/src/vs/workbench/api/node/extHostDecorations.ts @@ -11,11 +11,16 @@ import { TPromise } from 'vs/base/common/winjs.base'; import { Disposable } from 'vs/workbench/api/node/extHostTypes'; import { asWinJsPromise } from 'vs/base/common/async'; +interface ProviderData { + provider: vscode.DecorationProvider; + extensionId: string; +} + export class ExtHostDecorations implements ExtHostDecorationsShape { private static _handlePool = 0; - private readonly _provider = new Map(); + private readonly _provider = new Map(); private readonly _proxy: MainThreadDecorationsShape; constructor(mainContext: IMainContext) { @@ -24,7 +29,7 @@ export class ExtHostDecorations implements ExtHostDecorationsShape { registerDecorationProvider(provider: vscode.DecorationProvider, extensionId: string): vscode.Disposable { const handle = ExtHostDecorations._handlePool++; - this._provider.set(handle, provider); + this._provider.set(handle, { provider, extensionId }); this._proxy.$registerDecorationProvider(handle, extensionId); const listener = provider.onDidChangeDecorations(e => { @@ -42,13 +47,16 @@ export class ExtHostDecorations implements ExtHostDecorationsShape { const result: DecorationReply = Object.create(null); return TPromise.join(requests.map(request => { const { handle, uri, id } = request; - const provider = this._provider.get(handle); - if (!provider) { + if (!this._provider.has(handle)) { // might have been unregistered in the meantime return void 0; } + const { provider, extensionId } = this._provider.get(handle); return asWinJsPromise(token => provider.provideDecoration(URI.revive(uri), token)).then(data => { - result[id] = data && [data.priority, data.bubble, data.title, data.abbreviation, data.color, data.source]; + if (!data.letter || data.letter.length !== 1) { + console.warn(`INVALID decoration from extension '${extensionId}'. The 'letter' must be set and be one character`); + } + result[id] = data && [data.priority, data.bubble, data.title, data.letter, data.color, data.source]; }, err => { console.error(err); }); From 2a31304fa0216e86ee477ff245c6a8a3a764be35 Mon Sep 17 00:00:00 2001 From: Johannes Rieken Date: Wed, 15 Aug 2018 11:01:15 +0200 Subject: [PATCH 0814/1276] simplify update-function (maybe get rid of it...) #54938 --- .../decorations/browser/decorations.ts | 2 +- .../decorations/browser/decorationsService.ts | 25 +++++-------------- 2 files changed, 7 insertions(+), 20 deletions(-) diff --git a/src/vs/workbench/services/decorations/browser/decorations.ts b/src/vs/workbench/services/decorations/browser/decorations.ts index 6d1e6607375..16ba75cd049 100644 --- a/src/vs/workbench/services/decorations/browser/decorations.ts +++ b/src/vs/workbench/services/decorations/browser/decorations.ts @@ -26,7 +26,7 @@ export interface IDecoration { readonly tooltip: string; readonly labelClassName: string; readonly badgeClassName: string; - update(source?: string, data?: IDecorationData): IDecoration; + update(data: IDecorationData): IDecoration; } export interface IDecorationsProvider { diff --git a/src/vs/workbench/services/decorations/browser/decorationsService.ts b/src/vs/workbench/services/decorations/browser/decorationsService.ts index 101a0f69d96..d8b1f1cbe89 100644 --- a/src/vs/workbench/services/decorations/browser/decorationsService.ts +++ b/src/vs/workbench/services/decorations/browser/decorationsService.ts @@ -141,25 +141,12 @@ class DecorationStyles { labelClassName, badgeClassName, tooltip, - update: (source, insert) => { + update: (replace) => { let newData = data.slice(); - if (!source) { - // add -> just append - newData.push(insert); - - } else { - // remove/replace -> require a walk - for (let i = 0; i < newData.length; i++) { - if (newData[i].source === source) { - if (!insert) { - // remove - newData.splice(i, 1); - i--; - } else { - // replace - newData[i] = insert; - } - } + for (let i = 0; i < newData.length; i++) { + if (newData[i].source === replace.source) { + // replace + newData[i] = replace; } } return this.asDecoration(newData, onlyChildren); @@ -434,7 +421,7 @@ export class FileDecorationsService implements IDecorationsService { // result, maybe overwrite let result = this._decorationStyles.asDecoration(data, containsChildren); if (overwrite) { - return result.update(overwrite.source, overwrite); + return result.update(overwrite); } else { return result; } From 58f274541c56e9702610b19a2f17a5c5526eb182 Mon Sep 17 00:00:00 2001 From: Andre Weinand Date: Wed, 15 Aug 2018 11:08:12 +0200 Subject: [PATCH 0815/1276] avoid double slashes; fixes #56450 --- src/vs/workbench/parts/debug/browser/loadedScriptsView.ts | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/vs/workbench/parts/debug/browser/loadedScriptsView.ts b/src/vs/workbench/parts/debug/browser/loadedScriptsView.ts index 9827ad28916..780b5ebb659 100644 --- a/src/vs/workbench/parts/debug/browser/loadedScriptsView.ts +++ b/src/vs/workbench/parts/debug/browser/loadedScriptsView.ts @@ -286,9 +286,6 @@ class SessionTreeItem extends BaseTreeItem { let x: BaseTreeItem = this; path.split(/[\/\\]/).forEach((segment, i) => { - if (segment.length === 0) { // macOS or unix path - segment = '/'; - } if (i === 0 && folder) { x = x.createIfNeeded(folder.name, parent => new RootFolderTreeItem(parent, folder)); } else if (i === 0 && url) { From 6be2cc92ffa7867cae8f2424de2f7ab75475ed8c Mon Sep 17 00:00:00 2001 From: Johannes Rieken Date: Wed, 15 Aug 2018 11:18:10 +0200 Subject: [PATCH 0816/1276] make breadcrumbs picker wider, #56318 --- src/vs/workbench/browser/parts/editor/breadcrumbsControl.ts | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/vs/workbench/browser/parts/editor/breadcrumbsControl.ts b/src/vs/workbench/browser/parts/editor/breadcrumbsControl.ts index ad040a10a27..4d763cfcced 100644 --- a/src/vs/workbench/browser/parts/editor/breadcrumbsControl.ts +++ b/src/vs/workbench/browser/parts/editor/breadcrumbsControl.ts @@ -137,6 +137,7 @@ export class BreadcrumbsControl { readonly domNode: HTMLDivElement; private readonly _widget: BreadcrumbsWidget; + private _dimension: dom.Dimension; private _disposables = new Array(); private _breadcrumbsDisposables = new Array(); @@ -187,6 +188,7 @@ export class BreadcrumbsControl { } layout(dim: dom.Dimension): void { + this._dimension = dim; this._widget.layout(dim); } @@ -288,10 +290,10 @@ export class BreadcrumbsControl { return combinedDisposable([listener, picker]); }, - getAnchor() { + getAnchor: () => { let pickerHeight = 330; - let pickerWidth = Math.max(220, dom.getTotalWidth(event.node)); + let pickerWidth = Math.max(this._dimension.width * 0.38, dom.getTotalWidth(event.node)); let pickerArrowSize = 8; let pickerArrowOffset: number; From f186dd19fe26fca0242a27264bd429b7af2bdd5b Mon Sep 17 00:00:00 2001 From: Johannes Rieken Date: Wed, 15 Aug 2018 11:22:40 +0200 Subject: [PATCH 0817/1276] update vscode-nls-dev dependency --- extensions/git/yarn.lock | 2456 +------------------------------------- package.json | 2 +- yarn.lock | 6 +- 3 files changed, 10 insertions(+), 2454 deletions(-) diff --git a/extensions/git/yarn.lock b/extensions/git/yarn.lock index 0d0c3aff34b..497e26b21d6 100644 --- a/extensions/git/yarn.lock +++ b/extensions/git/yarn.lock @@ -30,194 +30,6 @@ version "1.0.28" resolved "https://registry.yarnpkg.com/@types/which/-/which-1.0.28.tgz#016e387629b8817bed653fe32eab5d11279c8df6" -"@webassemblyjs/ast@1.5.13": - version "1.5.13" - resolved "https://registry.yarnpkg.com/@webassemblyjs/ast/-/ast-1.5.13.tgz#81155a570bd5803a30ec31436bc2c9c0ede38f25" - dependencies: - "@webassemblyjs/helper-module-context" "1.5.13" - "@webassemblyjs/helper-wasm-bytecode" "1.5.13" - "@webassemblyjs/wast-parser" "1.5.13" - debug "^3.1.0" - mamacro "^0.0.3" - -"@webassemblyjs/floating-point-hex-parser@1.5.13": - version "1.5.13" - resolved "https://registry.yarnpkg.com/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.5.13.tgz#29ce0baa97411f70e8cce68ce9c0f9d819a4e298" - -"@webassemblyjs/helper-api-error@1.5.13": - version "1.5.13" - resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-api-error/-/helper-api-error-1.5.13.tgz#e49b051d67ee19a56e29b9aa8bd949b5b4442a59" - -"@webassemblyjs/helper-buffer@1.5.13": - version "1.5.13" - resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-buffer/-/helper-buffer-1.5.13.tgz#873bb0a1b46449231137c1262ddfd05695195a1e" - dependencies: - debug "^3.1.0" - -"@webassemblyjs/helper-code-frame@1.5.13": - version "1.5.13" - resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-code-frame/-/helper-code-frame-1.5.13.tgz#1bd2181b6a0be14e004f0fe9f5a660d265362b58" - dependencies: - "@webassemblyjs/wast-printer" "1.5.13" - -"@webassemblyjs/helper-fsm@1.5.13": - version "1.5.13" - resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-fsm/-/helper-fsm-1.5.13.tgz#cdf3d9d33005d543a5c5e5adaabf679ffa8db924" - -"@webassemblyjs/helper-module-context@1.5.13": - version "1.5.13" - resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-module-context/-/helper-module-context-1.5.13.tgz#dc29ddfb51ed657655286f94a5d72d8a489147c5" - dependencies: - debug "^3.1.0" - mamacro "^0.0.3" - -"@webassemblyjs/helper-wasm-bytecode@1.5.13": - version "1.5.13" - resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.5.13.tgz#03245817f0a762382e61733146f5773def15a747" - -"@webassemblyjs/helper-wasm-section@1.5.13": - version "1.5.13" - resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.5.13.tgz#efc76f44a10d3073b584b43c38a179df173d5c7d" - dependencies: - "@webassemblyjs/ast" "1.5.13" - "@webassemblyjs/helper-buffer" "1.5.13" - "@webassemblyjs/helper-wasm-bytecode" "1.5.13" - "@webassemblyjs/wasm-gen" "1.5.13" - debug "^3.1.0" - -"@webassemblyjs/ieee754@1.5.13": - version "1.5.13" - resolved "https://registry.yarnpkg.com/@webassemblyjs/ieee754/-/ieee754-1.5.13.tgz#573e97c8c12e4eebb316ca5fde0203ddd90b0364" - dependencies: - ieee754 "^1.1.11" - -"@webassemblyjs/leb128@1.5.13": - version "1.5.13" - resolved "https://registry.yarnpkg.com/@webassemblyjs/leb128/-/leb128-1.5.13.tgz#ab52ebab9cec283c1c1897ac1da833a04a3f4cee" - dependencies: - long "4.0.0" - -"@webassemblyjs/utf8@1.5.13": - version "1.5.13" - resolved "https://registry.yarnpkg.com/@webassemblyjs/utf8/-/utf8-1.5.13.tgz#6b53d2cd861cf94fa99c1f12779dde692fbc2469" - -"@webassemblyjs/wasm-edit@1.5.13": - version "1.5.13" - resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-edit/-/wasm-edit-1.5.13.tgz#c9cef5664c245cf11b3b3a73110c9155831724a8" - dependencies: - "@webassemblyjs/ast" "1.5.13" - "@webassemblyjs/helper-buffer" "1.5.13" - "@webassemblyjs/helper-wasm-bytecode" "1.5.13" - "@webassemblyjs/helper-wasm-section" "1.5.13" - "@webassemblyjs/wasm-gen" "1.5.13" - "@webassemblyjs/wasm-opt" "1.5.13" - "@webassemblyjs/wasm-parser" "1.5.13" - "@webassemblyjs/wast-printer" "1.5.13" - debug "^3.1.0" - -"@webassemblyjs/wasm-gen@1.5.13": - version "1.5.13" - resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-gen/-/wasm-gen-1.5.13.tgz#8e6ea113c4b432fa66540189e79b16d7a140700e" - dependencies: - "@webassemblyjs/ast" "1.5.13" - "@webassemblyjs/helper-wasm-bytecode" "1.5.13" - "@webassemblyjs/ieee754" "1.5.13" - "@webassemblyjs/leb128" "1.5.13" - "@webassemblyjs/utf8" "1.5.13" - -"@webassemblyjs/wasm-opt@1.5.13": - version "1.5.13" - resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-opt/-/wasm-opt-1.5.13.tgz#147aad7717a7ee4211c36b21a5f4c30dddf33138" - dependencies: - "@webassemblyjs/ast" "1.5.13" - "@webassemblyjs/helper-buffer" "1.5.13" - "@webassemblyjs/wasm-gen" "1.5.13" - "@webassemblyjs/wasm-parser" "1.5.13" - debug "^3.1.0" - -"@webassemblyjs/wasm-parser@1.5.13": - version "1.5.13" - resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-parser/-/wasm-parser-1.5.13.tgz#6f46516c5bb23904fbdf58009233c2dd8a54c72f" - dependencies: - "@webassemblyjs/ast" "1.5.13" - "@webassemblyjs/helper-api-error" "1.5.13" - "@webassemblyjs/helper-wasm-bytecode" "1.5.13" - "@webassemblyjs/ieee754" "1.5.13" - "@webassemblyjs/leb128" "1.5.13" - "@webassemblyjs/utf8" "1.5.13" - -"@webassemblyjs/wast-parser@1.5.13": - version "1.5.13" - resolved "https://registry.yarnpkg.com/@webassemblyjs/wast-parser/-/wast-parser-1.5.13.tgz#5727a705d397ae6a3ae99d7f5460acf2ec646eea" - dependencies: - "@webassemblyjs/ast" "1.5.13" - "@webassemblyjs/floating-point-hex-parser" "1.5.13" - "@webassemblyjs/helper-api-error" "1.5.13" - "@webassemblyjs/helper-code-frame" "1.5.13" - "@webassemblyjs/helper-fsm" "1.5.13" - long "^3.2.0" - mamacro "^0.0.3" - -"@webassemblyjs/wast-printer@1.5.13": - version "1.5.13" - resolved "https://registry.yarnpkg.com/@webassemblyjs/wast-printer/-/wast-printer-1.5.13.tgz#bb34d528c14b4f579e7ec11e793ec50ad7cd7c95" - dependencies: - "@webassemblyjs/ast" "1.5.13" - "@webassemblyjs/wast-parser" "1.5.13" - long "^3.2.0" - -abbrev@1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/abbrev/-/abbrev-1.1.1.tgz#f8f2c887ad10bf67f634f005b6987fed3179aac8" - -acorn-dynamic-import@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/acorn-dynamic-import/-/acorn-dynamic-import-3.0.0.tgz#901ceee4c7faaef7e07ad2a47e890675da50a278" - dependencies: - acorn "^5.0.0" - -acorn@^5.0.0, acorn@^5.6.2: - version "5.7.1" - resolved "https://registry.yarnpkg.com/acorn/-/acorn-5.7.1.tgz#f095829297706a7c9776958c0afc8930a9b9d9d8" - -ajv-keywords@^3.1.0: - version "3.2.0" - resolved "https://registry.yarnpkg.com/ajv-keywords/-/ajv-keywords-3.2.0.tgz#e86b819c602cf8821ad637413698f1dec021847a" - -ajv@^6.1.0: - version "6.5.2" - resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.5.2.tgz#678495f9b82f7cca6be248dd92f59bff5e1f4360" - dependencies: - fast-deep-equal "^2.0.1" - fast-json-stable-stringify "^2.0.0" - json-schema-traverse "^0.4.1" - uri-js "^4.2.1" - -ansi-escapes@^3.0.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/ansi-escapes/-/ansi-escapes-3.1.0.tgz#f73207bb81207d75fd6c83f125af26eea378ca30" - -ansi-regex@^2.0.0: - version "2.1.1" - resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-2.1.1.tgz#c3b33ab5ee360d86e0e628f0468ae7ef27d654df" - -ansi-regex@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-3.0.0.tgz#ed0317c322064f79466c02966bddb605ab37d998" - -ansi-styles@^3.2.1: - version "3.2.1" - resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-3.2.1.tgz#41fbb20243e50b12be0f04b8dedbf07520ce841d" - dependencies: - color-convert "^1.9.0" - -anymatch@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-2.0.0.tgz#bcb24b4f37934d9aa7ac17b4adaf89e7c76ef2eb" - dependencies: - micromatch "^3.1.4" - normalize-path "^2.1.1" - applicationinsights@1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/applicationinsights/-/applicationinsights-1.0.1.tgz#53446b830fe8d5d619eee2a278b31d3d25030927" @@ -226,95 +38,10 @@ applicationinsights@1.0.1: diagnostic-channel-publishers "0.2.1" zone.js "0.7.6" -aproba@^1.0.3, aproba@^1.1.1: - version "1.2.0" - resolved "https://registry.yarnpkg.com/aproba/-/aproba-1.2.0.tgz#6802e6264efd18c790a1b0d517f0f2627bf2c94a" - -are-we-there-yet@~1.1.2: - version "1.1.5" - resolved "https://registry.yarnpkg.com/are-we-there-yet/-/are-we-there-yet-1.1.5.tgz#4b35c2944f062a8bfcda66410760350fe9ddfc21" - dependencies: - delegates "^1.0.0" - readable-stream "^2.0.6" - -arr-diff@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/arr-diff/-/arr-diff-4.0.0.tgz#d6461074febfec71e7e15235761a329a5dc7c520" - -arr-flatten@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/arr-flatten/-/arr-flatten-1.1.0.tgz#36048bbff4e7b47e136644316c99669ea5ae91f1" - -arr-union@^3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/arr-union/-/arr-union-3.1.0.tgz#e39b09aea9def866a8f206e288af63919bae39c4" - -array-unique@^0.3.2: - version "0.3.2" - resolved "https://registry.yarnpkg.com/array-unique/-/array-unique-0.3.2.tgz#a894b75d4bc4f6cd679ef3244a9fd8f46ae2d428" - -asn1.js@^4.0.0: - version "4.10.1" - resolved "https://registry.yarnpkg.com/asn1.js/-/asn1.js-4.10.1.tgz#b9c2bf5805f1e64aadeed6df3a2bfafb5a73f5a0" - dependencies: - bn.js "^4.0.0" - inherits "^2.0.1" - minimalistic-assert "^1.0.0" - -assert@^1.1.1: - version "1.4.1" - resolved "https://registry.yarnpkg.com/assert/-/assert-1.4.1.tgz#99912d591836b5a6f5b345c0f07eefc08fc65d91" - dependencies: - util "0.10.3" - -assign-symbols@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/assign-symbols/-/assign-symbols-1.0.0.tgz#59667f41fadd4f20ccbc2bb96b8d4f7f78ec0367" - -async-each@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/async-each/-/async-each-1.0.1.tgz#19d386a1d9edc6e7c1c85d388aedbcc56d33602d" - -atob@^2.1.1: - version "2.1.1" - resolved "https://registry.yarnpkg.com/atob/-/atob-2.1.1.tgz#ae2d5a729477f289d60dd7f96a6314a22dd6c22a" - balanced-match@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.0.tgz#89b4d199ab2bee49de164ea02b89ce462d71b767" -base64-js@^1.0.2: - version "1.3.0" - resolved "https://registry.yarnpkg.com/base64-js/-/base64-js-1.3.0.tgz#cab1e6118f051095e58b5281aea8c1cd22bfc0e3" - -base@^0.11.1: - version "0.11.2" - resolved "https://registry.yarnpkg.com/base/-/base-0.11.2.tgz#7bde5ced145b6d551a90db87f83c558b4eb48a8f" - dependencies: - cache-base "^1.0.1" - class-utils "^0.3.5" - component-emitter "^1.2.1" - define-property "^1.0.0" - isobject "^3.0.1" - mixin-deep "^1.2.0" - pascalcase "^0.1.1" - -big.js@^3.1.3: - version "3.2.0" - resolved "https://registry.yarnpkg.com/big.js/-/big.js-3.2.0.tgz#a5fc298b81b9e0dca2e458824784b65c52ba588e" - -binary-extensions@^1.0.0: - version "1.11.0" - resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-1.11.0.tgz#46aa1751fb6a2f93ee5e689bb1087d4b14c6c205" - -bluebird@^3.5.1: - version "3.5.1" - resolved "https://registry.yarnpkg.com/bluebird/-/bluebird-3.5.1.tgz#d9551f9de98f1fcda1e683d17ee91a0602ee2eb9" - -bn.js@^4.0.0, bn.js@^4.1.0, bn.js@^4.1.1, bn.js@^4.4.0: - version "4.11.8" - resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-4.11.8.tgz#2cde09eb5ee341f484746bb0309b3253b1b1442f" - brace-expansion@^1.1.7: version "1.1.8" resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.8.tgz#c07b211c7c952ec1f8efd51a77ef0d1d3990a292" @@ -322,438 +49,30 @@ brace-expansion@^1.1.7: balanced-match "^1.0.0" concat-map "0.0.1" -braces@^2.3.0, braces@^2.3.1: - version "2.3.2" - resolved "https://registry.yarnpkg.com/braces/-/braces-2.3.2.tgz#5979fd3f14cd531565e5fa2df1abfff1dfaee729" - dependencies: - arr-flatten "^1.1.0" - array-unique "^0.3.2" - extend-shallow "^2.0.1" - fill-range "^4.0.0" - isobject "^3.0.1" - repeat-element "^1.1.2" - snapdragon "^0.8.1" - snapdragon-node "^2.0.1" - split-string "^3.0.2" - to-regex "^3.0.1" - -brorand@^1.0.1: - version "1.1.0" - resolved "https://registry.yarnpkg.com/brorand/-/brorand-1.1.0.tgz#12c25efe40a45e3c323eb8675a0a0ce57b22371f" - browser-stdout@1.3.0: version "1.3.0" resolved "https://registry.yarnpkg.com/browser-stdout/-/browser-stdout-1.3.0.tgz#f351d32969d32fa5d7a5567154263d928ae3bd1f" -browserify-aes@^1.0.0, browserify-aes@^1.0.4: - version "1.2.0" - resolved "https://registry.yarnpkg.com/browserify-aes/-/browserify-aes-1.2.0.tgz#326734642f403dabc3003209853bb70ad428ef48" - dependencies: - buffer-xor "^1.0.3" - cipher-base "^1.0.0" - create-hash "^1.1.0" - evp_bytestokey "^1.0.3" - inherits "^2.0.1" - safe-buffer "^5.0.1" - -browserify-cipher@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/browserify-cipher/-/browserify-cipher-1.0.1.tgz#8d6474c1b870bfdabcd3bcfcc1934a10e94f15f0" - dependencies: - browserify-aes "^1.0.4" - browserify-des "^1.0.0" - evp_bytestokey "^1.0.0" - -browserify-des@^1.0.0: - version "1.0.2" - resolved "https://registry.yarnpkg.com/browserify-des/-/browserify-des-1.0.2.tgz#3af4f1f59839403572f1c66204375f7a7f703e9c" - dependencies: - cipher-base "^1.0.1" - des.js "^1.0.0" - inherits "^2.0.1" - safe-buffer "^5.1.2" - -browserify-rsa@^4.0.0: - version "4.0.1" - resolved "https://registry.yarnpkg.com/browserify-rsa/-/browserify-rsa-4.0.1.tgz#21e0abfaf6f2029cf2fafb133567a701d4135524" - dependencies: - bn.js "^4.1.0" - randombytes "^2.0.1" - -browserify-sign@^4.0.0: - version "4.0.4" - resolved "https://registry.yarnpkg.com/browserify-sign/-/browserify-sign-4.0.4.tgz#aa4eb68e5d7b658baa6bf6a57e630cbd7a93d298" - dependencies: - bn.js "^4.1.1" - browserify-rsa "^4.0.0" - create-hash "^1.1.0" - create-hmac "^1.1.2" - elliptic "^6.0.0" - inherits "^2.0.1" - parse-asn1 "^5.0.0" - -browserify-zlib@^0.2.0: - version "0.2.0" - resolved "https://registry.yarnpkg.com/browserify-zlib/-/browserify-zlib-0.2.0.tgz#2869459d9aa3be245fe8fe2ca1f46e2e7f54d73f" - dependencies: - pako "~1.0.5" - -buffer-from@^1.0.0: - version "1.1.1" - resolved "https://registry.yarnpkg.com/buffer-from/-/buffer-from-1.1.1.tgz#32713bc028f75c02fdb710d7c7bcec1f2c6070ef" - -buffer-xor@^1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/buffer-xor/-/buffer-xor-1.0.3.tgz#26e61ed1422fb70dd42e6e36729ed51d855fe8d9" - -buffer@^4.3.0: - version "4.9.1" - resolved "https://registry.yarnpkg.com/buffer/-/buffer-4.9.1.tgz#6d1bb601b07a4efced97094132093027c95bc298" - dependencies: - base64-js "^1.0.2" - ieee754 "^1.1.4" - isarray "^1.0.0" - -builtin-status-codes@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/builtin-status-codes/-/builtin-status-codes-3.0.0.tgz#85982878e21b98e1c66425e03d0174788f569ee8" - byline@^5.0.0: version "5.0.0" resolved "https://registry.yarnpkg.com/byline/-/byline-5.0.0.tgz#741c5216468eadc457b03410118ad77de8c1ddb1" -cacache@^10.0.4: - version "10.0.4" - resolved "https://registry.yarnpkg.com/cacache/-/cacache-10.0.4.tgz#6452367999eff9d4188aefd9a14e9d7c6a263460" - dependencies: - bluebird "^3.5.1" - chownr "^1.0.1" - glob "^7.1.2" - graceful-fs "^4.1.11" - lru-cache "^4.1.1" - mississippi "^2.0.0" - mkdirp "^0.5.1" - move-concurrently "^1.0.1" - promise-inflight "^1.0.1" - rimraf "^2.6.2" - ssri "^5.2.4" - unique-filename "^1.1.0" - y18n "^4.0.0" - -cache-base@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/cache-base/-/cache-base-1.0.1.tgz#0a7f46416831c8b662ee36fe4e7c59d76f666ab2" - dependencies: - collection-visit "^1.0.0" - component-emitter "^1.2.1" - get-value "^2.0.6" - has-value "^1.0.0" - isobject "^3.0.1" - set-value "^2.0.0" - to-object-path "^0.3.0" - union-value "^1.0.0" - unset-value "^1.0.0" - -camelcase@^4.1.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-4.1.0.tgz#d545635be1e33c542649c69173e5de6acfae34dd" - -chalk@^2.0.0, chalk@^2.4.1: - version "2.4.1" - resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.1.tgz#18c49ab16a037b6eb0152cc83e3471338215b66e" - dependencies: - ansi-styles "^3.2.1" - escape-string-regexp "^1.0.5" - supports-color "^5.3.0" - -chardet@^0.5.0: - version "0.5.0" - resolved "https://registry.yarnpkg.com/chardet/-/chardet-0.5.0.tgz#fe3ac73c00c3d865ffcc02a0682e2c20b6a06029" - -chokidar@^2.0.2: - version "2.0.4" - resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-2.0.4.tgz#356ff4e2b0e8e43e322d18a372460bbcf3accd26" - dependencies: - anymatch "^2.0.0" - async-each "^1.0.0" - braces "^2.3.0" - glob-parent "^3.1.0" - inherits "^2.0.1" - is-binary-path "^1.0.0" - is-glob "^4.0.0" - lodash.debounce "^4.0.8" - normalize-path "^2.1.1" - path-is-absolute "^1.0.0" - readdirp "^2.0.0" - upath "^1.0.5" - optionalDependencies: - fsevents "^1.2.2" - -chownr@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/chownr/-/chownr-1.0.1.tgz#e2a75042a9551908bebd25b8523d5f9769d79181" - -chrome-trace-event@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/chrome-trace-event/-/chrome-trace-event-1.0.0.tgz#45a91bd2c20c9411f0963b5aaeb9a1b95e09cc48" - dependencies: - tslib "^1.9.0" - -cipher-base@^1.0.0, cipher-base@^1.0.1, cipher-base@^1.0.3: - version "1.0.4" - resolved "https://registry.yarnpkg.com/cipher-base/-/cipher-base-1.0.4.tgz#8760e4ecc272f4c363532f926d874aae2c1397de" - dependencies: - inherits "^2.0.1" - safe-buffer "^5.0.1" - -class-utils@^0.3.5: - version "0.3.6" - resolved "https://registry.yarnpkg.com/class-utils/-/class-utils-0.3.6.tgz#f93369ae8b9a7ce02fd41faad0ca83033190c463" - dependencies: - arr-union "^3.1.0" - define-property "^0.2.5" - isobject "^3.0.0" - static-extend "^0.1.1" - -cli-cursor@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/cli-cursor/-/cli-cursor-2.1.0.tgz#b35dac376479facc3e94747d41d0d0f5238ffcb5" - dependencies: - restore-cursor "^2.0.0" - -cli-width@^2.0.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/cli-width/-/cli-width-2.2.0.tgz#ff19ede8a9a5e579324147b0c11f0fbcbabed639" - -cliui@^4.0.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/cliui/-/cliui-4.1.0.tgz#348422dbe82d800b3022eef4f6ac10bf2e4d1b49" - dependencies: - string-width "^2.1.1" - strip-ansi "^4.0.0" - wrap-ansi "^2.0.0" - -code-point-at@^1.0.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/code-point-at/-/code-point-at-1.1.0.tgz#0d070b4d043a5bea33a2f1a40e2edb3d9a4ccf77" - -collection-visit@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/collection-visit/-/collection-visit-1.0.0.tgz#4bc0373c164bc3291b4d368c829cf1a80a59dca0" - dependencies: - map-visit "^1.0.0" - object-visit "^1.0.0" - -color-convert@^1.9.0: - version "1.9.2" - resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-1.9.2.tgz#49881b8fba67df12a96bdf3f56c0aab9e7913147" - dependencies: - color-name "1.1.1" - -color-name@1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.1.tgz#4b1415304cf50028ea81643643bd82ea05803689" - commander@2.9.0: version "2.9.0" resolved "https://registry.yarnpkg.com/commander/-/commander-2.9.0.tgz#9c99094176e12240cb22d6c5146098400fe0f7d4" dependencies: graceful-readlink ">= 1.0.0" -commander@~2.13.0: - version "2.13.0" - resolved "https://registry.yarnpkg.com/commander/-/commander-2.13.0.tgz#6964bca67685df7c1f1430c584f07d7597885b9c" - -commondir@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/commondir/-/commondir-1.0.1.tgz#ddd800da0c66127393cca5950ea968a3aaf1253b" - -component-emitter@^1.2.1: - version "1.2.1" - resolved "https://registry.yarnpkg.com/component-emitter/-/component-emitter-1.2.1.tgz#137918d6d78283f7df7a6b7c5a63e140e69425e6" - concat-map@0.0.1: version "0.0.1" resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" -concat-stream@^1.5.0: - version "1.6.2" - resolved "https://registry.yarnpkg.com/concat-stream/-/concat-stream-1.6.2.tgz#904bdf194cd3122fc675c77fc4ac3d4ff0fd1a34" - dependencies: - buffer-from "^1.0.0" - inherits "^2.0.3" - readable-stream "^2.2.2" - typedarray "^0.0.6" - -console-browserify@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/console-browserify/-/console-browserify-1.1.0.tgz#f0241c45730a9fc6323b206dbf38edc741d0bb10" - dependencies: - date-now "^0.1.4" - -console-control-strings@^1.0.0, console-control-strings@~1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/console-control-strings/-/console-control-strings-1.1.0.tgz#3d7cf4464db6446ea644bf4b39507f9851008e8e" - -constants-browserify@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/constants-browserify/-/constants-browserify-1.0.0.tgz#c20b96d8c617748aaf1c16021760cd27fcb8cb75" - -copy-concurrently@^1.0.0: - version "1.0.5" - resolved "https://registry.yarnpkg.com/copy-concurrently/-/copy-concurrently-1.0.5.tgz#92297398cae34937fcafd6ec8139c18051f0b5e0" - dependencies: - aproba "^1.1.1" - fs-write-stream-atomic "^1.0.8" - iferr "^0.1.5" - mkdirp "^0.5.1" - rimraf "^2.5.4" - run-queue "^1.0.0" - -copy-descriptor@^0.1.0: - version "0.1.1" - resolved "https://registry.yarnpkg.com/copy-descriptor/-/copy-descriptor-0.1.1.tgz#676f6eb3c39997c2ee1ac3a924fd6124748f578d" - -core-util-is@~1.0.0: - version "1.0.2" - resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7" - -create-ecdh@^4.0.0: - version "4.0.3" - resolved "https://registry.yarnpkg.com/create-ecdh/-/create-ecdh-4.0.3.tgz#c9111b6f33045c4697f144787f9254cdc77c45ff" - dependencies: - bn.js "^4.1.0" - elliptic "^6.0.0" - -create-hash@^1.1.0, create-hash@^1.1.2: - version "1.2.0" - resolved "https://registry.yarnpkg.com/create-hash/-/create-hash-1.2.0.tgz#889078af11a63756bcfb59bd221996be3a9ef196" - dependencies: - cipher-base "^1.0.1" - inherits "^2.0.1" - md5.js "^1.3.4" - ripemd160 "^2.0.1" - sha.js "^2.4.0" - -create-hmac@^1.1.0, create-hmac@^1.1.2, create-hmac@^1.1.4: - version "1.1.7" - resolved "https://registry.yarnpkg.com/create-hmac/-/create-hmac-1.1.7.tgz#69170c78b3ab957147b2b8b04572e47ead2243ff" - dependencies: - cipher-base "^1.0.3" - create-hash "^1.1.0" - inherits "^2.0.1" - ripemd160 "^2.0.0" - safe-buffer "^5.0.1" - sha.js "^2.4.8" - -cross-spawn@^5.0.1: - version "5.1.0" - resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-5.1.0.tgz#e8bd0efee58fcff6f8f94510a0a554bbfa235449" - dependencies: - lru-cache "^4.0.1" - shebang-command "^1.2.0" - which "^1.2.9" - -cross-spawn@^6.0.5: - version "6.0.5" - resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-6.0.5.tgz#4a5ec7c64dfae22c3a14124dbacdee846d80cbc4" - dependencies: - nice-try "^1.0.4" - path-key "^2.0.1" - semver "^5.5.0" - shebang-command "^1.2.0" - which "^1.2.9" - -crypto-browserify@^3.11.0: - version "3.12.0" - resolved "https://registry.yarnpkg.com/crypto-browserify/-/crypto-browserify-3.12.0.tgz#396cf9f3137f03e4b8e532c58f698254e00f80ec" - dependencies: - browserify-cipher "^1.0.0" - browserify-sign "^4.0.0" - create-ecdh "^4.0.0" - create-hash "^1.1.0" - create-hmac "^1.1.0" - diffie-hellman "^5.0.0" - inherits "^2.0.1" - pbkdf2 "^3.0.3" - public-encrypt "^4.0.0" - randombytes "^2.0.0" - randomfill "^1.0.3" - -cyclist@~0.2.2: - version "0.2.2" - resolved "https://registry.yarnpkg.com/cyclist/-/cyclist-0.2.2.tgz#1b33792e11e914a2fd6d6ed6447464444e5fa640" - -date-now@^0.1.4: - version "0.1.4" - resolved "https://registry.yarnpkg.com/date-now/-/date-now-0.1.4.tgz#eaf439fd4d4848ad74e5cc7dbef200672b9e345b" - debug@2.6.8: version "2.6.8" resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.8.tgz#e731531ca2ede27d188222427da17821d68ff4fc" dependencies: ms "2.0.0" -debug@^2.1.2, debug@^2.2.0, debug@^2.3.3: - version "2.6.9" - resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f" - dependencies: - ms "2.0.0" - -debug@^3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/debug/-/debug-3.1.0.tgz#5bb5a0672628b64149566ba16819e61518c67261" - dependencies: - ms "2.0.0" - -decamelize@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-2.0.0.tgz#656d7bbc8094c4c788ea53c5840908c9c7d063c7" - dependencies: - xregexp "4.0.0" - -decode-uri-component@^0.2.0: - version "0.2.0" - resolved "https://registry.yarnpkg.com/decode-uri-component/-/decode-uri-component-0.2.0.tgz#eb3913333458775cb84cd1a1fae062106bb87545" - -deep-extend@^0.6.0: - version "0.6.0" - resolved "https://registry.yarnpkg.com/deep-extend/-/deep-extend-0.6.0.tgz#c4fa7c95404a17a9c3e8ca7e1537312b736330ac" - -define-property@^0.2.5: - version "0.2.5" - resolved "https://registry.yarnpkg.com/define-property/-/define-property-0.2.5.tgz#c35b1ef918ec3c990f9a5bc57be04aacec5c8116" - dependencies: - is-descriptor "^0.1.0" - -define-property@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/define-property/-/define-property-1.0.0.tgz#769ebaaf3f4a63aad3af9e8d304c9bbe79bfb0e6" - dependencies: - is-descriptor "^1.0.0" - -define-property@^2.0.2: - version "2.0.2" - resolved "https://registry.yarnpkg.com/define-property/-/define-property-2.0.2.tgz#d459689e8d654ba77e02a817f8710d702cb16e9d" - dependencies: - is-descriptor "^1.0.2" - isobject "^3.0.1" - -delegates@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/delegates/-/delegates-1.0.0.tgz#84c6e159b81904fdca59a0ef44cd870d31250f9a" - -des.js@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/des.js/-/des.js-1.0.0.tgz#c074d2e2aa6a8a9a07dbd61f9a15c2cd83ec8ecc" - dependencies: - inherits "^2.0.1" - minimalistic-assert "^1.0.0" - -detect-libc@^1.0.2: - version "1.0.3" - resolved "https://registry.yarnpkg.com/detect-libc/-/detect-libc-1.0.3.tgz#fa137c4bd698edf55cd5cd02ac559f91a4c4ba9b" - diagnostic-channel-publishers@0.2.1: version "0.2.1" resolved "https://registry.yarnpkg.com/diagnostic-channel-publishers/-/diagnostic-channel-publishers-0.2.1.tgz#8e2d607a8b6d79fe880b548bc58cc6beb288c4f3" @@ -768,282 +87,18 @@ diff@3.2.0: version "3.2.0" resolved "https://registry.yarnpkg.com/diff/-/diff-3.2.0.tgz#c9ce393a4b7cbd0b058a725c93df299027868ff9" -diffie-hellman@^5.0.0: - version "5.0.3" - resolved "https://registry.yarnpkg.com/diffie-hellman/-/diffie-hellman-5.0.3.tgz#40e8ee98f55a2149607146921c63e1ae5f3d2875" - dependencies: - bn.js "^4.1.0" - miller-rabin "^4.0.0" - randombytes "^2.0.0" - -domain-browser@^1.1.1: - version "1.2.0" - resolved "https://registry.yarnpkg.com/domain-browser/-/domain-browser-1.2.0.tgz#3d31f50191a6749dd1375a7f522e823d42e54eda" - -duplexify@^3.4.2, duplexify@^3.6.0: - version "3.6.0" - resolved "https://registry.yarnpkg.com/duplexify/-/duplexify-3.6.0.tgz#592903f5d80b38d037220541264d69a198fb3410" - dependencies: - end-of-stream "^1.0.0" - inherits "^2.0.1" - readable-stream "^2.0.0" - stream-shift "^1.0.0" - -elliptic@^6.0.0: - version "6.4.0" - resolved "https://registry.yarnpkg.com/elliptic/-/elliptic-6.4.0.tgz#cac9af8762c85836187003c8dfe193e5e2eae5df" - dependencies: - bn.js "^4.4.0" - brorand "^1.0.1" - hash.js "^1.0.0" - hmac-drbg "^1.0.0" - inherits "^2.0.1" - minimalistic-assert "^1.0.0" - minimalistic-crypto-utils "^1.0.0" - -emojis-list@^2.0.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/emojis-list/-/emojis-list-2.1.0.tgz#4daa4d9db00f9819880c79fa457ae5b09a1fd389" - -end-of-stream@^1.0.0, end-of-stream@^1.1.0: - version "1.4.1" - resolved "https://registry.yarnpkg.com/end-of-stream/-/end-of-stream-1.4.1.tgz#ed29634d19baba463b6ce6b80a37213eab71ec43" - dependencies: - once "^1.4.0" - -enhanced-resolve@^4.0.0, enhanced-resolve@^4.1.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/enhanced-resolve/-/enhanced-resolve-4.1.0.tgz#41c7e0bfdfe74ac1ffe1e57ad6a5c6c9f3742a7f" - dependencies: - graceful-fs "^4.1.2" - memory-fs "^0.4.0" - tapable "^1.0.0" - -errno@^0.1.3, errno@~0.1.7: - version "0.1.7" - resolved "https://registry.yarnpkg.com/errno/-/errno-0.1.7.tgz#4684d71779ad39af177e3f007996f7c67c852618" - dependencies: - prr "~1.0.1" - -escape-string-regexp@1.0.5, escape-string-regexp@^1.0.5: +escape-string-regexp@1.0.5: version "1.0.5" resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4" -eslint-scope@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-4.0.0.tgz#50bf3071e9338bcdc43331794a0cb533f0136172" - dependencies: - esrecurse "^4.1.0" - estraverse "^4.1.1" - -esrecurse@^4.1.0: - version "4.2.1" - resolved "https://registry.yarnpkg.com/esrecurse/-/esrecurse-4.2.1.tgz#007a3b9fdbc2b3bb87e4879ea19c92fdbd3942cf" - dependencies: - estraverse "^4.1.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" - -events@^1.0.0: - version "1.1.1" - resolved "https://registry.yarnpkg.com/events/-/events-1.1.1.tgz#9ebdb7635ad099c70dcc4c2a1f5004288e8bd924" - -evp_bytestokey@^1.0.0, evp_bytestokey@^1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/evp_bytestokey/-/evp_bytestokey-1.0.3.tgz#7fcbdb198dc71959432efe13842684e0525acb02" - dependencies: - md5.js "^1.3.4" - safe-buffer "^5.1.1" - -execa@^0.7.0: - version "0.7.0" - resolved "https://registry.yarnpkg.com/execa/-/execa-0.7.0.tgz#944becd34cc41ee32a63a9faf27ad5a65fc59777" - dependencies: - cross-spawn "^5.0.1" - get-stream "^3.0.0" - is-stream "^1.1.0" - npm-run-path "^2.0.0" - p-finally "^1.0.0" - signal-exit "^3.0.0" - strip-eof "^1.0.0" - -expand-brackets@^2.1.4: - version "2.1.4" - resolved "https://registry.yarnpkg.com/expand-brackets/-/expand-brackets-2.1.4.tgz#b77735e315ce30f6b6eff0f83b04151a22449622" - dependencies: - debug "^2.3.3" - define-property "^0.2.5" - extend-shallow "^2.0.1" - posix-character-classes "^0.1.0" - regex-not "^1.0.0" - snapdragon "^0.8.1" - to-regex "^3.0.1" - -extend-shallow@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/extend-shallow/-/extend-shallow-2.0.1.tgz#51af7d614ad9a9f610ea1bafbb989d6b1c56890f" - dependencies: - is-extendable "^0.1.0" - -extend-shallow@^3.0.0, extend-shallow@^3.0.2: - version "3.0.2" - resolved "https://registry.yarnpkg.com/extend-shallow/-/extend-shallow-3.0.2.tgz#26a71aaf073b39fb2127172746131c2704028db8" - dependencies: - assign-symbols "^1.0.0" - is-extendable "^1.0.1" - -external-editor@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/external-editor/-/external-editor-3.0.0.tgz#dc35c48c6f98a30ca27a20e9687d7f3c77704bb6" - dependencies: - chardet "^0.5.0" - iconv-lite "^0.4.22" - tmp "^0.0.33" - -extglob@^2.0.4: - version "2.0.4" - resolved "https://registry.yarnpkg.com/extglob/-/extglob-2.0.4.tgz#ad00fe4dc612a9232e8718711dc5cb5ab0285543" - dependencies: - array-unique "^0.3.2" - define-property "^1.0.0" - expand-brackets "^2.1.4" - extend-shallow "^2.0.1" - fragment-cache "^0.2.1" - regex-not "^1.0.0" - snapdragon "^0.8.1" - to-regex "^3.0.1" - -fast-deep-equal@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-2.0.1.tgz#7b05218ddf9667bf7f370bf7fdb2cb15fdd0aa49" - -fast-json-stable-stringify@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz#d5142c0caee6b1189f87d3a76111064f86c8bbf2" - -figures@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/figures/-/figures-2.0.0.tgz#3ab1a2d2a62c8bfb431a0c94cb797a2fce27c962" - dependencies: - escape-string-regexp "^1.0.5" - file-type@^7.2.0: version "7.2.0" resolved "https://registry.yarnpkg.com/file-type/-/file-type-7.2.0.tgz#113cfed52e1d6959ab80248906e2f25a8cdccb74" -fill-range@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-4.0.0.tgz#d544811d428f98eb06a63dc402d2403c328c38f7" - dependencies: - extend-shallow "^2.0.1" - is-number "^3.0.0" - repeat-string "^1.6.1" - to-regex-range "^2.1.0" - -find-cache-dir@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/find-cache-dir/-/find-cache-dir-1.0.0.tgz#9288e3e9e3cc3748717d39eade17cf71fc30ee6f" - dependencies: - commondir "^1.0.1" - make-dir "^1.0.0" - pkg-dir "^2.0.0" - -find-up@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/find-up/-/find-up-2.1.0.tgz#45d1b7e506c717ddd482775a2b77920a3c0c57a7" - dependencies: - locate-path "^2.0.0" - -find-up@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/find-up/-/find-up-3.0.0.tgz#49169f1d7993430646da61ecc5ae355c21c97b73" - dependencies: - locate-path "^3.0.0" - -flush-write-stream@^1.0.0: - version "1.0.3" - resolved "https://registry.yarnpkg.com/flush-write-stream/-/flush-write-stream-1.0.3.tgz#c5d586ef38af6097650b49bc41b55fabb19f35bd" - dependencies: - inherits "^2.0.1" - readable-stream "^2.0.4" - -for-in@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/for-in/-/for-in-1.0.2.tgz#81068d295a8142ec0ac726c6e2200c30fb6d5e80" - -fragment-cache@^0.2.1: - version "0.2.1" - resolved "https://registry.yarnpkg.com/fragment-cache/-/fragment-cache-0.2.1.tgz#4290fad27f13e89be7f33799c6bc5a0abfff0d19" - dependencies: - map-cache "^0.2.2" - -from2@^2.1.0: - version "2.3.0" - resolved "https://registry.yarnpkg.com/from2/-/from2-2.3.0.tgz#8bfb5502bde4a4d36cfdeea007fcca21d7e382af" - dependencies: - inherits "^2.0.1" - readable-stream "^2.0.0" - -fs-minipass@^1.2.5: - version "1.2.5" - resolved "https://registry.yarnpkg.com/fs-minipass/-/fs-minipass-1.2.5.tgz#06c277218454ec288df77ada54a03b8702aacb9d" - dependencies: - minipass "^2.2.1" - -fs-write-stream-atomic@^1.0.8: - version "1.0.10" - resolved "https://registry.yarnpkg.com/fs-write-stream-atomic/-/fs-write-stream-atomic-1.0.10.tgz#b47df53493ef911df75731e70a9ded0189db40c9" - dependencies: - graceful-fs "^4.1.2" - iferr "^0.1.5" - imurmurhash "^0.1.4" - readable-stream "1 || 2" - fs.realpath@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" -fsevents@^1.2.2: - version "1.2.4" - resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-1.2.4.tgz#f41dcb1af2582af3692da36fc55cbd8e1041c426" - dependencies: - nan "^2.9.2" - node-pre-gyp "^0.10.0" - -gauge@~2.7.3: - version "2.7.4" - resolved "https://registry.yarnpkg.com/gauge/-/gauge-2.7.4.tgz#2c03405c7538c39d7eb37b317022e325fb018bf7" - dependencies: - aproba "^1.0.3" - console-control-strings "^1.0.0" - has-unicode "^2.0.0" - object-assign "^4.1.0" - signal-exit "^3.0.0" - string-width "^1.0.1" - strip-ansi "^3.0.1" - wide-align "^1.1.0" - -get-caller-file@^1.0.1: - version "1.0.3" - resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-1.0.3.tgz#f978fa4c90d1dfe7ff2d6beda2a515e713bdcf4a" - -get-stream@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-3.0.0.tgz#8e943d1358dc37555054ecbe2edb05aa174ede14" - -get-value@^2.0.3, get-value@^2.0.6: - version "2.0.6" - resolved "https://registry.yarnpkg.com/get-value/-/get-value-2.0.6.tgz#dc15ca1c672387ca76bd37ac0a395ba2042a2c28" - -glob-parent@^3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-3.1.0.tgz#9e6af6299d8d3bd2bd40430832bd113df906c5ae" - dependencies: - is-glob "^3.1.0" - path-dirname "^1.0.0" - glob@7.1.1: version "7.1.1" resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.1.tgz#805211df04faaf1c63a3600306cdf5ade50b2ec8" @@ -1055,25 +110,6 @@ glob@7.1.1: once "^1.3.0" path-is-absolute "^1.0.0" -glob@^7.0.5, glob@^7.1.2: - version "7.1.2" - resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.2.tgz#c19c9df9a028702d678612384a6552404c636d15" - dependencies: - fs.realpath "^1.0.0" - inflight "^1.0.4" - inherits "2" - minimatch "^3.0.4" - once "^1.3.0" - path-is-absolute "^1.0.0" - -global-modules-path@^2.1.0: - version "2.3.0" - resolved "https://registry.yarnpkg.com/global-modules-path/-/global-modules-path-2.3.0.tgz#b0e2bac6beac39745f7db5c59d26a36a0b94f7dc" - -graceful-fs@^4.1.11, graceful-fs@^4.1.2: - version "4.1.11" - resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.1.11.tgz#0e8bdfe4d1ddb8854d64e04ea7c00e2a026e5658" - "graceful-readlink@>= 1.0.0": version "1.0.1" resolved "https://registry.yarnpkg.com/graceful-readlink/-/graceful-readlink-1.0.1.tgz#4cafad76bc62f02fa039b2f94e9a3dd3a391a725" @@ -1086,110 +122,14 @@ has-flag@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-1.0.0.tgz#9d9e793165ce017a00f00418c43f942a7b1d11fa" -has-flag@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-3.0.0.tgz#b5d454dc2199ae225699f3467e5a07f3b955bafd" - -has-unicode@^2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/has-unicode/-/has-unicode-2.0.1.tgz#e0e6fe6a28cf51138855e086d1691e771de2a8b9" - -has-value@^0.3.1: - version "0.3.1" - resolved "https://registry.yarnpkg.com/has-value/-/has-value-0.3.1.tgz#7b1f58bada62ca827ec0a2078025654845995e1f" - dependencies: - get-value "^2.0.3" - has-values "^0.1.4" - isobject "^2.0.0" - -has-value@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/has-value/-/has-value-1.0.0.tgz#18b281da585b1c5c51def24c930ed29a0be6b177" - dependencies: - get-value "^2.0.6" - has-values "^1.0.0" - isobject "^3.0.0" - -has-values@^0.1.4: - version "0.1.4" - resolved "https://registry.yarnpkg.com/has-values/-/has-values-0.1.4.tgz#6d61de95d91dfca9b9a02089ad384bff8f62b771" - -has-values@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/has-values/-/has-values-1.0.0.tgz#95b0b63fec2146619a6fe57fe75628d5a39efe4f" - dependencies: - is-number "^3.0.0" - kind-of "^4.0.0" - -hash-base@^3.0.0: - version "3.0.4" - resolved "https://registry.yarnpkg.com/hash-base/-/hash-base-3.0.4.tgz#5fc8686847ecd73499403319a6b0a3f3f6ae4918" - dependencies: - inherits "^2.0.1" - safe-buffer "^5.0.1" - -hash.js@^1.0.0, hash.js@^1.0.3: - version "1.1.5" - resolved "https://registry.yarnpkg.com/hash.js/-/hash.js-1.1.5.tgz#e38ab4b85dfb1e0c40fe9265c0e9b54854c23812" - dependencies: - inherits "^2.0.3" - minimalistic-assert "^1.0.1" - he@1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/he/-/he-1.1.1.tgz#93410fd21b009735151f8868c2f271f3427e23fd" -hmac-drbg@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/hmac-drbg/-/hmac-drbg-1.0.1.tgz#d2745701025a6c775a6c545793ed502fc0c649a1" - dependencies: - hash.js "^1.0.3" - minimalistic-assert "^1.0.0" - minimalistic-crypto-utils "^1.0.1" - -https-browserify@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/https-browserify/-/https-browserify-1.0.0.tgz#ec06c10e0a34c0f2faf199f7fd7fc78fffd03c73" - iconv-lite@0.4.19: version "0.4.19" resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.19.tgz#f7468f60135f5e5dad3399c0a81be9a1603a082b" -iconv-lite@^0.4.22, iconv-lite@^0.4.4: - version "0.4.23" - resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.23.tgz#297871f63be507adcfbfca715d0cd0eed84e9a63" - dependencies: - safer-buffer ">= 2.1.2 < 3" - -ieee754@^1.1.11, ieee754@^1.1.4: - version "1.1.12" - resolved "https://registry.yarnpkg.com/ieee754/-/ieee754-1.1.12.tgz#50bf24e5b9c8bb98af4964c941cdb0918da7b60b" - -iferr@^0.1.5: - version "0.1.5" - resolved "https://registry.yarnpkg.com/iferr/-/iferr-0.1.5.tgz#c60eed69e6d8fdb6b3104a1fcbca1c192dc5b501" - -ignore-walk@^3.0.1: - version "3.0.1" - resolved "https://registry.yarnpkg.com/ignore-walk/-/ignore-walk-3.0.1.tgz#a83e62e7d272ac0e3b551aaa82831a19b69f82f8" - dependencies: - minimatch "^3.0.4" - -import-local@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/import-local/-/import-local-1.0.0.tgz#5e4ffdc03f4fe6c009c6729beb29631c2f8227bc" - dependencies: - pkg-dir "^2.0.0" - resolve-cwd "^2.0.0" - -imurmurhash@^0.1.4: - version "0.1.4" - resolved "https://registry.yarnpkg.com/imurmurhash/-/imurmurhash-0.1.4.tgz#9218b9b2b928a238b13dc4fb6b6d576f231453ea" - -indexof@0.0.1: - version "0.0.1" - resolved "https://registry.yarnpkg.com/indexof/-/indexof-0.0.1.tgz#82dc336d232b9062179d05ab3293a66059fd435d" - inflight@^1.0.4: version "1.0.6" resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9" @@ -1197,244 +137,22 @@ inflight@^1.0.4: once "^1.3.0" wrappy "1" -inherits@2, inherits@2.0.3, inherits@^2.0.1, inherits@^2.0.3, inherits@~2.0.1, inherits@~2.0.3: +inherits@2: version "2.0.3" resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.3.tgz#633c2c83e3da42a502f52466022480f4208261de" -inherits@2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.1.tgz#b17d08d326b4423e568eff719f91b0b1cbdf69f1" - -ini@~1.3.0: - version "1.3.5" - resolved "https://registry.yarnpkg.com/ini/-/ini-1.3.5.tgz#eee25f56db1c9ec6085e0c22778083f596abf927" - -inquirer@^6.0.0: - version "6.1.0" - resolved "https://registry.yarnpkg.com/inquirer/-/inquirer-6.1.0.tgz#8f65c7b31c498285f4ddf3b742ad8c487892040b" - dependencies: - ansi-escapes "^3.0.0" - chalk "^2.0.0" - cli-cursor "^2.1.0" - cli-width "^2.0.0" - external-editor "^3.0.0" - figures "^2.0.0" - lodash "^4.3.0" - mute-stream "0.0.7" - run-async "^2.2.0" - rxjs "^6.1.0" - string-width "^2.1.0" - strip-ansi "^4.0.0" - through "^2.3.6" - -interpret@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/interpret/-/interpret-1.1.0.tgz#7ed1b1410c6a0e0f78cf95d3b8440c63f78b8614" - -invert-kv@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/invert-kv/-/invert-kv-1.0.0.tgz#104a8e4aaca6d3d8cd157a8ef8bfab2d7a3ffdb6" - -is-accessor-descriptor@^0.1.6: - version "0.1.6" - resolved "https://registry.yarnpkg.com/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz#a9e12cb3ae8d876727eeef3843f8a0897b5c98d6" - dependencies: - kind-of "^3.0.2" - -is-accessor-descriptor@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz#169c2f6d3df1f992618072365c9b0ea1f6878656" - dependencies: - kind-of "^6.0.0" - -is-binary-path@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/is-binary-path/-/is-binary-path-1.0.1.tgz#75f16642b480f187a711c814161fd3a4a7655898" - dependencies: - binary-extensions "^1.0.0" - -is-buffer@^1.1.5: - version "1.1.6" - resolved "https://registry.yarnpkg.com/is-buffer/-/is-buffer-1.1.6.tgz#efaa2ea9daa0d7ab2ea13a97b2b8ad51fefbe8be" - -is-data-descriptor@^0.1.4: - version "0.1.4" - resolved "https://registry.yarnpkg.com/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz#0b5ee648388e2c860282e793f1856fec3f301b56" - dependencies: - kind-of "^3.0.2" - -is-data-descriptor@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz#d84876321d0e7add03990406abbbbd36ba9268c7" - dependencies: - kind-of "^6.0.0" - -is-descriptor@^0.1.0: - version "0.1.6" - resolved "https://registry.yarnpkg.com/is-descriptor/-/is-descriptor-0.1.6.tgz#366d8240dde487ca51823b1ab9f07a10a78251ca" - dependencies: - is-accessor-descriptor "^0.1.6" - is-data-descriptor "^0.1.4" - kind-of "^5.0.0" - -is-descriptor@^1.0.0, is-descriptor@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/is-descriptor/-/is-descriptor-1.0.2.tgz#3b159746a66604b04f8c81524ba365c5f14d86ec" - dependencies: - is-accessor-descriptor "^1.0.0" - is-data-descriptor "^1.0.0" - kind-of "^6.0.2" - -is-extendable@^0.1.0, is-extendable@^0.1.1: - version "0.1.1" - resolved "https://registry.yarnpkg.com/is-extendable/-/is-extendable-0.1.1.tgz#62b110e289a471418e3ec36a617d472e301dfc89" - -is-extendable@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/is-extendable/-/is-extendable-1.0.1.tgz#a7470f9e426733d81bd81e1155264e3a3507cab4" - dependencies: - is-plain-object "^2.0.4" - -is-extglob@^2.1.0, is-extglob@^2.1.1: - version "2.1.1" - resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-2.1.1.tgz#a88c02535791f02ed37c76a1b9ea9773c833f8c2" - -is-fullwidth-code-point@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz#ef9e31386f031a7f0d643af82fde50c457ef00cb" - dependencies: - number-is-nan "^1.0.0" - -is-fullwidth-code-point@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz#a3b30a5c4f199183167aaab93beefae3ddfb654f" - -is-glob@^3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-3.1.0.tgz#7ba5ae24217804ac70707b96922567486cc3e84a" - dependencies: - is-extglob "^2.1.0" - -is-glob@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-4.0.0.tgz#9521c76845cc2610a85203ddf080a958c2ffabc0" - dependencies: - is-extglob "^2.1.1" - -is-number@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/is-number/-/is-number-3.0.0.tgz#24fd6201a4782cf50561c810276afc7d12d71195" - dependencies: - kind-of "^3.0.2" - -is-plain-object@^2.0.1, is-plain-object@^2.0.3, is-plain-object@^2.0.4: - version "2.0.4" - resolved "https://registry.yarnpkg.com/is-plain-object/-/is-plain-object-2.0.4.tgz#2c163b3fafb1b606d9d17928f05c2a1c38e07677" - dependencies: - isobject "^3.0.1" - -is-promise@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/is-promise/-/is-promise-2.1.0.tgz#79a2a9ece7f096e80f36d2b2f3bc16c1ff4bf3fa" - -is-stream@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-1.1.0.tgz#12d4a3dd4e68e0b79ceb8dbc84173ae80d91ca44" - -is-windows@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/is-windows/-/is-windows-1.0.2.tgz#d1850eb9791ecd18e6182ce12a30f396634bb19d" - -isarray@1.0.0, isarray@^1.0.0, isarray@~1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/isarray/-/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11" - isexe@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10" -isobject@^2.0.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/isobject/-/isobject-2.1.0.tgz#f065561096a3f1da2ef46272f815c840d87e0c89" - dependencies: - isarray "1.0.0" - -isobject@^3.0.0, isobject@^3.0.1: - version "3.0.1" - resolved "https://registry.yarnpkg.com/isobject/-/isobject-3.0.1.tgz#4e431e92b11a9731636aa1f9c8d1ccbcfdab78df" - jschardet@^1.6.0: version "1.6.0" resolved "https://registry.yarnpkg.com/jschardet/-/jschardet-1.6.0.tgz#c7d1a71edcff2839db2f9ec30fc5d5ebd3c1a678" -json-parse-better-errors@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz#bb867cfb3450e69107c131d1c514bab3dc8bcaa9" - -json-schema-traverse@^0.4.1: - version "0.4.1" - resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz#69f6a87d9513ab8bb8fe63bdb0979c448e684660" - json3@3.3.2: version "3.3.2" resolved "https://registry.yarnpkg.com/json3/-/json3-3.3.2.tgz#3c0434743df93e2f5c42aee7b19bcb483575f4e1" -json5@^0.5.0: - version "0.5.1" - resolved "https://registry.yarnpkg.com/json5/-/json5-0.5.1.tgz#1eade7acc012034ad84e2396767ead9fa5495821" - -kind-of@^3.0.2, kind-of@^3.0.3, kind-of@^3.2.0: - version "3.2.2" - resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-3.2.2.tgz#31ea21a734bab9bbb0f32466d893aea51e4a3c64" - dependencies: - is-buffer "^1.1.5" - -kind-of@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-4.0.0.tgz#20813df3d712928b207378691a45066fae72dd57" - dependencies: - is-buffer "^1.1.5" - -kind-of@^5.0.0: - version "5.1.0" - resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-5.1.0.tgz#729c91e2d857b7a419a1f9aa65685c4c33f5845d" - -kind-of@^6.0.0, kind-of@^6.0.2: - version "6.0.2" - resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-6.0.2.tgz#01146b36a6218e64e58f3a8d66de5d7fc6f6d051" - -lcid@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/lcid/-/lcid-1.0.0.tgz#308accafa0bc483a3867b4b6f2b9506251d1b835" - dependencies: - invert-kv "^1.0.0" - -loader-runner@^2.3.0: - version "2.3.0" - resolved "https://registry.yarnpkg.com/loader-runner/-/loader-runner-2.3.0.tgz#f482aea82d543e07921700d5a46ef26fdac6b8a2" - -loader-utils@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/loader-utils/-/loader-utils-1.1.0.tgz#c98aef488bcceda2ffb5e2de646d6a754429f5cd" - dependencies: - big.js "^3.1.3" - emojis-list "^2.0.0" - json5 "^0.5.0" - -locate-path@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-2.0.0.tgz#2b568b265eec944c6d9c0de9c3dbbbca0354cd8e" - dependencies: - p-locate "^2.0.0" - path-exists "^3.0.0" - -locate-path@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-3.0.0.tgz#dbec3b3ab759758071b58fe59fc41871af21400e" - dependencies: - p-locate "^3.0.0" - path-exists "^3.0.0" - lodash._baseassign@^3.0.0: version "3.2.0" resolved "https://registry.yarnpkg.com/lodash._baseassign/-/lodash._baseassign-3.2.0.tgz#8c38a099500f215ad09e59f1722fd0c52bfe0a4e" @@ -1466,10 +184,6 @@ lodash.create@3.1.1: lodash._basecreate "^3.0.0" lodash._isiterateecall "^3.0.0" -lodash.debounce@^4.0.8: - version "4.0.8" - resolved "https://registry.yarnpkg.com/lodash.debounce/-/lodash.debounce-4.0.8.tgz#82d79bff30a67c4005ffd5e2515300ad9ca4d7af" - lodash.isarguments@^3.0.0: version "3.1.0" resolved "https://registry.yarnpkg.com/lodash.isarguments/-/lodash.isarguments-3.1.0.tgz#2f573d85c6a24289ff00663b491c1d338ff3458a" @@ -1486,103 +200,7 @@ lodash.keys@^3.0.0: lodash.isarguments "^3.0.0" lodash.isarray "^3.0.0" -lodash@^4.3.0: - version "4.17.10" - resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.10.tgz#1b7793cf7259ea38fb3661d4d38b3260af8ae4e7" - -long@4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/long/-/long-4.0.0.tgz#9a7b71cfb7d361a194ea555241c92f7468d5bf28" - -long@^3.2.0: - version "3.2.0" - resolved "https://registry.yarnpkg.com/long/-/long-3.2.0.tgz#d821b7138ca1cb581c172990ef14db200b5c474b" - -lru-cache@^4.0.1, lru-cache@^4.1.1: - version "4.1.3" - resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-4.1.3.tgz#a1175cf3496dfc8436c156c334b4955992bce69c" - dependencies: - pseudomap "^1.0.2" - yallist "^2.1.2" - -make-dir@^1.0.0: - version "1.3.0" - resolved "https://registry.yarnpkg.com/make-dir/-/make-dir-1.3.0.tgz#79c1033b80515bd6d24ec9933e860ca75ee27f0c" - dependencies: - pify "^3.0.0" - -mamacro@^0.0.3: - version "0.0.3" - resolved "https://registry.yarnpkg.com/mamacro/-/mamacro-0.0.3.tgz#ad2c9576197c9f1abf308d0787865bd975a3f3e4" - -map-cache@^0.2.2: - version "0.2.2" - resolved "https://registry.yarnpkg.com/map-cache/-/map-cache-0.2.2.tgz#c32abd0bd6525d9b051645bb4f26ac5dc98a0dbf" - -map-visit@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/map-visit/-/map-visit-1.0.0.tgz#ecdca8f13144e660f1b5bd41f12f3479d98dfb8f" - dependencies: - object-visit "^1.0.0" - -md5.js@^1.3.4: - version "1.3.4" - resolved "https://registry.yarnpkg.com/md5.js/-/md5.js-1.3.4.tgz#e9bdbde94a20a5ac18b04340fc5764d5b09d901d" - dependencies: - hash-base "^3.0.0" - inherits "^2.0.1" - -mem@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/mem/-/mem-1.1.0.tgz#5edd52b485ca1d900fe64895505399a0dfa45f76" - dependencies: - mimic-fn "^1.0.0" - -memory-fs@^0.4.0, memory-fs@~0.4.1: - version "0.4.1" - resolved "https://registry.yarnpkg.com/memory-fs/-/memory-fs-0.4.1.tgz#3a9a20b8462523e447cfbc7e8bb80ed667bfc552" - dependencies: - errno "^0.1.3" - readable-stream "^2.0.1" - -micromatch@^3.1.4, micromatch@^3.1.8: - version "3.1.10" - resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-3.1.10.tgz#70859bc95c9840952f359a068a3fc49f9ecfac23" - dependencies: - arr-diff "^4.0.0" - array-unique "^0.3.2" - braces "^2.3.1" - define-property "^2.0.2" - extend-shallow "^3.0.2" - extglob "^2.0.4" - fragment-cache "^0.2.1" - kind-of "^6.0.2" - nanomatch "^1.2.9" - object.pick "^1.3.0" - regex-not "^1.0.0" - snapdragon "^0.8.1" - to-regex "^3.0.2" - -miller-rabin@^4.0.0: - version "4.0.1" - resolved "https://registry.yarnpkg.com/miller-rabin/-/miller-rabin-4.0.1.tgz#f080351c865b0dc562a8462966daa53543c78a4d" - dependencies: - bn.js "^4.0.0" - brorand "^1.0.1" - -mimic-fn@^1.0.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-1.2.0.tgz#820c86a39334640e99516928bd03fca88057d022" - -minimalistic-assert@^1.0.0, minimalistic-assert@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz#2e194de044626d4a10e7f7fbc00ce73e83e4d5c7" - -minimalistic-crypto-utils@^1.0.0, minimalistic-crypto-utils@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz#f6c00c1c0b082246e5c4d99dfb8c7c083b2b582a" - -minimatch@^3.0.2, minimatch@^3.0.4: +minimatch@^3.0.2: version "3.0.4" resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.4.tgz#5166e286457f03306064be5497e8dbb0c3d32083" dependencies: @@ -1592,46 +210,7 @@ minimist@0.0.8: version "0.0.8" resolved "https://registry.yarnpkg.com/minimist/-/minimist-0.0.8.tgz#857fcabfc3397d2625b8228262e86aa7a011b05d" -minimist@^1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.0.tgz#a35008b20f41383eec1fb914f4cd5df79a264284" - -minipass@^2.2.1, minipass@^2.3.3: - version "2.3.3" - resolved "https://registry.yarnpkg.com/minipass/-/minipass-2.3.3.tgz#a7dcc8b7b833f5d368759cce544dccb55f50f233" - dependencies: - safe-buffer "^5.1.2" - yallist "^3.0.0" - -minizlib@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/minizlib/-/minizlib-1.1.0.tgz#11e13658ce46bc3a70a267aac58359d1e0c29ceb" - dependencies: - minipass "^2.2.1" - -mississippi@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/mississippi/-/mississippi-2.0.0.tgz#3442a508fafc28500486feea99409676e4ee5a6f" - dependencies: - concat-stream "^1.5.0" - duplexify "^3.4.2" - end-of-stream "^1.1.0" - flush-write-stream "^1.0.0" - from2 "^2.1.0" - parallel-transform "^1.1.0" - pump "^2.0.1" - pumpify "^1.3.3" - stream-each "^1.1.0" - through2 "^2.0.0" - -mixin-deep@^1.2.0: - version "1.3.1" - resolved "https://registry.yarnpkg.com/mixin-deep/-/mixin-deep-1.3.1.tgz#a49e7268dce1a0d9698e45326c5626df3543d0fe" - dependencies: - for-in "^1.0.2" - is-extendable "^1.0.1" - -mkdirp@0.5.1, mkdirp@^0.5.0, mkdirp@^0.5.1, mkdirp@~0.5.0: +mkdirp@0.5.1: version "0.5.1" resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.1.tgz#30057438eac6cf7f8c4767f38648d6697d75c903" dependencies: @@ -1654,920 +233,30 @@ mocha@^3.2.0: mkdirp "0.5.1" supports-color "3.1.2" -move-concurrently@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/move-concurrently/-/move-concurrently-1.0.1.tgz#be2c005fda32e0b29af1f05d7c4b33214c701f92" - dependencies: - aproba "^1.1.1" - copy-concurrently "^1.0.0" - fs-write-stream-atomic "^1.0.8" - mkdirp "^0.5.1" - rimraf "^2.5.4" - run-queue "^1.0.3" - ms@2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8" -mute-stream@0.0.7: - version "0.0.7" - resolved "https://registry.yarnpkg.com/mute-stream/-/mute-stream-0.0.7.tgz#3075ce93bc21b8fab43e1bc4da7e8115ed1e7bab" - -nan@^2.9.2: - version "2.10.0" - resolved "https://registry.yarnpkg.com/nan/-/nan-2.10.0.tgz#96d0cd610ebd58d4b4de9cc0c6828cda99c7548f" - -nanomatch@^1.2.9: - version "1.2.13" - resolved "https://registry.yarnpkg.com/nanomatch/-/nanomatch-1.2.13.tgz#b87a8aa4fc0de8fe6be88895b38983ff265bd119" - dependencies: - arr-diff "^4.0.0" - array-unique "^0.3.2" - define-property "^2.0.2" - extend-shallow "^3.0.2" - fragment-cache "^0.2.1" - is-windows "^1.0.2" - kind-of "^6.0.2" - object.pick "^1.3.0" - regex-not "^1.0.0" - snapdragon "^0.8.1" - to-regex "^3.0.1" - -needle@^2.2.1: - version "2.2.1" - resolved "https://registry.yarnpkg.com/needle/-/needle-2.2.1.tgz#b5e325bd3aae8c2678902fa296f729455d1d3a7d" - dependencies: - debug "^2.1.2" - iconv-lite "^0.4.4" - sax "^1.2.4" - -neo-async@^2.5.0: - version "2.5.1" - resolved "https://registry.yarnpkg.com/neo-async/-/neo-async-2.5.1.tgz#acb909e327b1e87ec9ef15f41b8a269512ad41ee" - -nice-try@^1.0.4: - version "1.0.4" - resolved "https://registry.yarnpkg.com/nice-try/-/nice-try-1.0.4.tgz#d93962f6c52f2c1558c0fbda6d512819f1efe1c4" - -node-libs-browser@^2.0.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/node-libs-browser/-/node-libs-browser-2.1.0.tgz#5f94263d404f6e44767d726901fff05478d600df" - dependencies: - assert "^1.1.1" - browserify-zlib "^0.2.0" - buffer "^4.3.0" - console-browserify "^1.1.0" - constants-browserify "^1.0.0" - crypto-browserify "^3.11.0" - domain-browser "^1.1.1" - events "^1.0.0" - https-browserify "^1.0.0" - os-browserify "^0.3.0" - path-browserify "0.0.0" - process "^0.11.10" - punycode "^1.2.4" - querystring-es3 "^0.2.0" - readable-stream "^2.3.3" - stream-browserify "^2.0.1" - stream-http "^2.7.2" - string_decoder "^1.0.0" - timers-browserify "^2.0.4" - tty-browserify "0.0.0" - url "^0.11.0" - util "^0.10.3" - vm-browserify "0.0.4" - -node-pre-gyp@^0.10.0: - version "0.10.3" - resolved "https://registry.yarnpkg.com/node-pre-gyp/-/node-pre-gyp-0.10.3.tgz#3070040716afdc778747b61b6887bf78880b80fc" - dependencies: - detect-libc "^1.0.2" - mkdirp "^0.5.1" - needle "^2.2.1" - nopt "^4.0.1" - npm-packlist "^1.1.6" - npmlog "^4.0.2" - rc "^1.2.7" - rimraf "^2.6.1" - semver "^5.3.0" - tar "^4" - -nopt@^4.0.1: - version "4.0.1" - resolved "https://registry.yarnpkg.com/nopt/-/nopt-4.0.1.tgz#d0d4685afd5415193c8c7505602d0d17cd64474d" - dependencies: - abbrev "1" - osenv "^0.1.4" - -normalize-path@^2.1.1: - version "2.1.1" - resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-2.1.1.tgz#1ab28b556e198363a8c1a6f7e6fa20137fe6aed9" - dependencies: - remove-trailing-separator "^1.0.1" - -npm-bundled@^1.0.1: - version "1.0.3" - resolved "https://registry.yarnpkg.com/npm-bundled/-/npm-bundled-1.0.3.tgz#7e71703d973af3370a9591bafe3a63aca0be2308" - -npm-packlist@^1.1.6: - version "1.1.11" - resolved "https://registry.yarnpkg.com/npm-packlist/-/npm-packlist-1.1.11.tgz#84e8c683cbe7867d34b1d357d893ce29e28a02de" - dependencies: - ignore-walk "^3.0.1" - npm-bundled "^1.0.1" - -npm-run-path@^2.0.0: - version "2.0.2" - resolved "https://registry.yarnpkg.com/npm-run-path/-/npm-run-path-2.0.2.tgz#35a9232dfa35d7067b4cb2ddf2357b1871536c5f" - dependencies: - path-key "^2.0.0" - -npmlog@^4.0.2: - version "4.1.2" - resolved "https://registry.yarnpkg.com/npmlog/-/npmlog-4.1.2.tgz#08a7f2a8bf734604779a9efa4ad5cc717abb954b" - dependencies: - are-we-there-yet "~1.1.2" - console-control-strings "~1.1.0" - gauge "~2.7.3" - set-blocking "~2.0.0" - -number-is-nan@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/number-is-nan/-/number-is-nan-1.0.1.tgz#097b602b53422a522c1afb8790318336941a011d" - -object-assign@^4.1.0: - version "4.1.1" - resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863" - -object-copy@^0.1.0: - version "0.1.0" - resolved "https://registry.yarnpkg.com/object-copy/-/object-copy-0.1.0.tgz#7e7d858b781bd7c991a41ba975ed3812754e998c" - dependencies: - copy-descriptor "^0.1.0" - define-property "^0.2.5" - kind-of "^3.0.3" - -object-visit@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/object-visit/-/object-visit-1.0.1.tgz#f79c4493af0c5377b59fe39d395e41042dd045bb" - dependencies: - isobject "^3.0.0" - -object.pick@^1.3.0: - version "1.3.0" - resolved "https://registry.yarnpkg.com/object.pick/-/object.pick-1.3.0.tgz#87a10ac4c1694bd2e1cbf53591a66141fb5dd747" - dependencies: - isobject "^3.0.1" - -once@^1.3.0, once@^1.3.1, once@^1.4.0: +once@^1.3.0: version "1.4.0" resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1" dependencies: wrappy "1" -onetime@^2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/onetime/-/onetime-2.0.1.tgz#067428230fd67443b2794b22bba528b6867962d4" - dependencies: - mimic-fn "^1.0.0" - -os-browserify@^0.3.0: - version "0.3.0" - resolved "https://registry.yarnpkg.com/os-browserify/-/os-browserify-0.3.0.tgz#854373c7f5c2315914fc9bfc6bd8238fdda1ec27" - -os-homedir@^1.0.0: - version "1.0.2" - resolved "https://registry.yarnpkg.com/os-homedir/-/os-homedir-1.0.2.tgz#ffbc4988336e0e833de0c168c7ef152121aa7fb3" - -os-locale@^2.0.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/os-locale/-/os-locale-2.1.0.tgz#42bc2900a6b5b8bd17376c8e882b65afccf24bf2" - dependencies: - execa "^0.7.0" - lcid "^1.0.0" - mem "^1.1.0" - -os-tmpdir@^1.0.0, os-tmpdir@~1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/os-tmpdir/-/os-tmpdir-1.0.2.tgz#bbe67406c79aa85c5cfec766fe5734555dfa1274" - -osenv@^0.1.4: - version "0.1.5" - resolved "https://registry.yarnpkg.com/osenv/-/osenv-0.1.5.tgz#85cdfafaeb28e8677f416e287592b5f3f49ea410" - dependencies: - os-homedir "^1.0.0" - os-tmpdir "^1.0.0" - -p-finally@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/p-finally/-/p-finally-1.0.0.tgz#3fbcfb15b899a44123b34b6dcc18b724336a2cae" - -p-limit@^1.1.0: - version "1.3.0" - resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-1.3.0.tgz#b86bd5f0c25690911c7590fcbfc2010d54b3ccb8" - dependencies: - p-try "^1.0.0" - -p-limit@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-2.0.0.tgz#e624ed54ee8c460a778b3c9f3670496ff8a57aec" - dependencies: - p-try "^2.0.0" - -p-locate@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-2.0.0.tgz#20a0103b222a70c8fd39cc2e580680f3dde5ec43" - dependencies: - p-limit "^1.1.0" - -p-locate@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-3.0.0.tgz#322d69a05c0264b25997d9f40cd8a891ab0064a4" - dependencies: - p-limit "^2.0.0" - -p-try@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/p-try/-/p-try-1.0.0.tgz#cbc79cdbaf8fd4228e13f621f2b1a237c1b207b3" - -p-try@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/p-try/-/p-try-2.0.0.tgz#85080bb87c64688fa47996fe8f7dfbe8211760b1" - -pako@~1.0.5: - version "1.0.6" - resolved "https://registry.yarnpkg.com/pako/-/pako-1.0.6.tgz#0101211baa70c4bca4a0f63f2206e97b7dfaf258" - -parallel-transform@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/parallel-transform/-/parallel-transform-1.1.0.tgz#d410f065b05da23081fcd10f28854c29bda33b06" - dependencies: - cyclist "~0.2.2" - inherits "^2.0.3" - readable-stream "^2.1.5" - -parse-asn1@^5.0.0: - version "5.1.1" - resolved "https://registry.yarnpkg.com/parse-asn1/-/parse-asn1-5.1.1.tgz#f6bf293818332bd0dab54efb16087724745e6ca8" - dependencies: - asn1.js "^4.0.0" - browserify-aes "^1.0.0" - create-hash "^1.1.0" - evp_bytestokey "^1.0.0" - pbkdf2 "^3.0.3" - -pascalcase@^0.1.1: - version "0.1.1" - resolved "https://registry.yarnpkg.com/pascalcase/-/pascalcase-0.1.1.tgz#b363e55e8006ca6fe21784d2db22bd15d7917f14" - -path-browserify@0.0.0: - version "0.0.0" - resolved "https://registry.yarnpkg.com/path-browserify/-/path-browserify-0.0.0.tgz#a0b870729aae214005b7d5032ec2cbbb0fb4451a" - -path-dirname@^1.0.0: - version "1.0.2" - resolved "https://registry.yarnpkg.com/path-dirname/-/path-dirname-1.0.2.tgz#cc33d24d525e099a5388c0336c6e32b9160609e0" - -path-exists@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-3.0.0.tgz#ce0ebeaa5f78cb18925ea7d810d7b59b010fd515" - path-is-absolute@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f" -path-key@^2.0.0, path-key@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/path-key/-/path-key-2.0.1.tgz#411cadb574c5a140d3a4b1910d40d80cc9f40b40" - -pbkdf2@^3.0.3: - version "3.0.16" - resolved "https://registry.yarnpkg.com/pbkdf2/-/pbkdf2-3.0.16.tgz#7404208ec6b01b62d85bf83853a8064f8d9c2a5c" - dependencies: - create-hash "^1.1.2" - create-hmac "^1.1.4" - ripemd160 "^2.0.1" - safe-buffer "^5.0.1" - sha.js "^2.4.8" - -pify@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/pify/-/pify-3.0.0.tgz#e5a4acd2c101fdf3d9a4d07f0dbc4db49dd28176" - -pkg-dir@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/pkg-dir/-/pkg-dir-2.0.0.tgz#f6d5d1109e19d63edf428e0bd57e12777615334b" - dependencies: - find-up "^2.1.0" - -posix-character-classes@^0.1.0: - version "0.1.1" - resolved "https://registry.yarnpkg.com/posix-character-classes/-/posix-character-classes-0.1.1.tgz#01eac0fe3b5af71a2a6c02feabb8c1fef7e00eab" - -process-nextick-args@~2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-2.0.0.tgz#a37d732f4271b4ab1ad070d35508e8290788ffaa" - -process@^0.11.10: - version "0.11.10" - resolved "https://registry.yarnpkg.com/process/-/process-0.11.10.tgz#7332300e840161bda3e69a1d1d91a7d4bc16f182" - -promise-inflight@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/promise-inflight/-/promise-inflight-1.0.1.tgz#98472870bf228132fcbdd868129bad12c3c029e3" - -prr@~1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/prr/-/prr-1.0.1.tgz#d3fc114ba06995a45ec6893f484ceb1d78f5f476" - -pseudomap@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/pseudomap/-/pseudomap-1.0.2.tgz#f052a28da70e618917ef0a8ac34c1ae5a68286b3" - -public-encrypt@^4.0.0: - version "4.0.2" - resolved "https://registry.yarnpkg.com/public-encrypt/-/public-encrypt-4.0.2.tgz#46eb9107206bf73489f8b85b69d91334c6610994" - dependencies: - bn.js "^4.1.0" - browserify-rsa "^4.0.0" - create-hash "^1.1.0" - parse-asn1 "^5.0.0" - randombytes "^2.0.1" - -pump@^2.0.0, pump@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/pump/-/pump-2.0.1.tgz#12399add6e4cf7526d973cbc8b5ce2e2908b3909" - dependencies: - end-of-stream "^1.1.0" - once "^1.3.1" - -pumpify@^1.3.3: - version "1.5.1" - resolved "https://registry.yarnpkg.com/pumpify/-/pumpify-1.5.1.tgz#36513be246ab27570b1a374a5ce278bfd74370ce" - dependencies: - duplexify "^3.6.0" - inherits "^2.0.3" - pump "^2.0.0" - -punycode@1.3.2: - version "1.3.2" - resolved "https://registry.yarnpkg.com/punycode/-/punycode-1.3.2.tgz#9653a036fb7c1ee42342f2325cceefea3926c48d" - -punycode@^1.2.4: - version "1.4.1" - resolved "https://registry.yarnpkg.com/punycode/-/punycode-1.4.1.tgz#c0d5a63b2718800ad8e1eb0fa5269c84dd41845e" - -punycode@^2.1.0: - version "2.1.1" - resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.1.1.tgz#b58b010ac40c22c5657616c8d2c2c02c7bf479ec" - -querystring-es3@^0.2.0: - version "0.2.1" - resolved "https://registry.yarnpkg.com/querystring-es3/-/querystring-es3-0.2.1.tgz#9ec61f79049875707d69414596fd907a4d711e73" - -querystring@0.2.0: - version "0.2.0" - resolved "https://registry.yarnpkg.com/querystring/-/querystring-0.2.0.tgz#b209849203bb25df820da756e747005878521620" - -randombytes@^2.0.0, randombytes@^2.0.1, randombytes@^2.0.5: - version "2.0.6" - resolved "https://registry.yarnpkg.com/randombytes/-/randombytes-2.0.6.tgz#d302c522948588848a8d300c932b44c24231da80" - dependencies: - safe-buffer "^5.1.0" - -randomfill@^1.0.3: - version "1.0.4" - resolved "https://registry.yarnpkg.com/randomfill/-/randomfill-1.0.4.tgz#c92196fc86ab42be983f1bf31778224931d61458" - dependencies: - randombytes "^2.0.5" - safe-buffer "^5.1.0" - -rc@^1.2.7: - version "1.2.8" - resolved "https://registry.yarnpkg.com/rc/-/rc-1.2.8.tgz#cd924bf5200a075b83c188cd6b9e211b7fc0d3ed" - dependencies: - deep-extend "^0.6.0" - ini "~1.3.0" - minimist "^1.2.0" - strip-json-comments "~2.0.1" - -"readable-stream@1 || 2", readable-stream@^2.0.0, readable-stream@^2.0.1, readable-stream@^2.0.2, readable-stream@^2.0.4, readable-stream@^2.0.6, readable-stream@^2.1.5, readable-stream@^2.2.2, readable-stream@^2.3.3, readable-stream@^2.3.6: - version "2.3.6" - resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.6.tgz#b11c27d88b8ff1fbe070643cf94b0c79ae1b0aaf" - dependencies: - core-util-is "~1.0.0" - inherits "~2.0.3" - isarray "~1.0.0" - process-nextick-args "~2.0.0" - safe-buffer "~5.1.1" - string_decoder "~1.1.1" - util-deprecate "~1.0.1" - -readdirp@^2.0.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-2.1.0.tgz#4ed0ad060df3073300c48440373f72d1cc642d78" - dependencies: - graceful-fs "^4.1.2" - minimatch "^3.0.2" - readable-stream "^2.0.2" - set-immediate-shim "^1.0.1" - -regex-not@^1.0.0, regex-not@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/regex-not/-/regex-not-1.0.2.tgz#1f4ece27e00b0b65e0247a6810e6a85d83a5752c" - dependencies: - extend-shallow "^3.0.2" - safe-regex "^1.1.0" - -remove-trailing-separator@^1.0.1: - version "1.1.0" - resolved "https://registry.yarnpkg.com/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz#c24bce2a283adad5bc3f58e0d48249b92379d8ef" - -repeat-element@^1.1.2: - version "1.1.2" - resolved "https://registry.yarnpkg.com/repeat-element/-/repeat-element-1.1.2.tgz#ef089a178d1483baae4d93eb98b4f9e4e11d990a" - -repeat-string@^1.6.1: - version "1.6.1" - resolved "https://registry.yarnpkg.com/repeat-string/-/repeat-string-1.6.1.tgz#8dcae470e1c88abc2d600fff4a776286da75e637" - -require-directory@^2.1.1: - version "2.1.1" - resolved "https://registry.yarnpkg.com/require-directory/-/require-directory-2.1.1.tgz#8c64ad5fd30dab1c976e2344ffe7f792a6a6df42" - -require-main-filename@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/require-main-filename/-/require-main-filename-1.0.1.tgz#97f717b69d48784f5f526a6c5aa8ffdda055a4d1" - -resolve-cwd@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/resolve-cwd/-/resolve-cwd-2.0.0.tgz#00a9f7387556e27038eae232caa372a6a59b665a" - dependencies: - resolve-from "^3.0.0" - -resolve-from@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-3.0.0.tgz#b22c7af7d9d6881bc8b6e653335eebcb0a188748" - -resolve-url@^0.2.1: - version "0.2.1" - resolved "https://registry.yarnpkg.com/resolve-url/-/resolve-url-0.2.1.tgz#2c637fe77c893afd2a663fe21aa9080068e2052a" - -restore-cursor@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/restore-cursor/-/restore-cursor-2.0.0.tgz#9f7ee287f82fd326d4fd162923d62129eee0dfaf" - dependencies: - onetime "^2.0.0" - signal-exit "^3.0.2" - -ret@~0.1.10: - version "0.1.15" - resolved "https://registry.yarnpkg.com/ret/-/ret-0.1.15.tgz#b8a4825d5bdb1fc3f6f53c2bc33f81388681c7bc" - -rimraf@^2.5.4, rimraf@^2.6.1, rimraf@^2.6.2: - version "2.6.2" - resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.6.2.tgz#2ed8150d24a16ea8651e6d6ef0f47c4158ce7a36" - dependencies: - glob "^7.0.5" - -ripemd160@^2.0.0, ripemd160@^2.0.1: - version "2.0.2" - resolved "https://registry.yarnpkg.com/ripemd160/-/ripemd160-2.0.2.tgz#a1c1a6f624751577ba5d07914cbc92850585890c" - dependencies: - hash-base "^3.0.0" - inherits "^2.0.1" - -run-async@^2.2.0: - version "2.3.0" - resolved "https://registry.yarnpkg.com/run-async/-/run-async-2.3.0.tgz#0371ab4ae0bdd720d4166d7dfda64ff7a445a6c0" - dependencies: - is-promise "^2.1.0" - -run-queue@^1.0.0, run-queue@^1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/run-queue/-/run-queue-1.0.3.tgz#e848396f057d223f24386924618e25694161ec47" - dependencies: - aproba "^1.1.1" - -rxjs@^6.1.0: - version "6.2.2" - resolved "https://registry.yarnpkg.com/rxjs/-/rxjs-6.2.2.tgz#eb75fa3c186ff5289907d06483a77884586e1cf9" - dependencies: - tslib "^1.9.0" - -safe-buffer@^5.0.1, safe-buffer@^5.1.0, safe-buffer@^5.1.1, safe-buffer@^5.1.2, safe-buffer@~5.1.0, safe-buffer@~5.1.1: - version "5.1.2" - resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.2.tgz#991ec69d296e0313747d59bdfd2b745c35f8828d" - -safe-regex@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/safe-regex/-/safe-regex-1.1.0.tgz#40a3669f3b077d1e943d44629e157dd48023bf2e" - dependencies: - ret "~0.1.10" - -"safer-buffer@>= 2.1.2 < 3": - version "2.1.2" - resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a" - -sax@^1.2.4: - version "1.2.4" - resolved "https://registry.yarnpkg.com/sax/-/sax-1.2.4.tgz#2816234e2378bddc4e5354fab5caa895df7100d9" - -schema-utils@^0.4.4, schema-utils@^0.4.5: - version "0.4.7" - resolved "https://registry.yarnpkg.com/schema-utils/-/schema-utils-0.4.7.tgz#ba74f597d2be2ea880131746ee17d0a093c68187" - dependencies: - ajv "^6.1.0" - ajv-keywords "^3.1.0" - -semver@^5.3.0, semver@^5.5.0: +semver@^5.3.0: version "5.5.0" resolved "https://registry.yarnpkg.com/semver/-/semver-5.5.0.tgz#dc4bbc7a6ca9d916dee5d43516f0092b58f7b8ab" -serialize-javascript@^1.4.0: - version "1.5.0" - resolved "https://registry.yarnpkg.com/serialize-javascript/-/serialize-javascript-1.5.0.tgz#1aa336162c88a890ddad5384baebc93a655161fe" - -set-blocking@^2.0.0, set-blocking@~2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/set-blocking/-/set-blocking-2.0.0.tgz#045f9782d011ae9a6803ddd382b24392b3d890f7" - -set-immediate-shim@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/set-immediate-shim/-/set-immediate-shim-1.0.1.tgz#4b2b1b27eb808a9f8dcc481a58e5e56f599f3f61" - -set-value@^0.4.3: - version "0.4.3" - resolved "https://registry.yarnpkg.com/set-value/-/set-value-0.4.3.tgz#7db08f9d3d22dc7f78e53af3c3bf4666ecdfccf1" - dependencies: - extend-shallow "^2.0.1" - is-extendable "^0.1.1" - is-plain-object "^2.0.1" - to-object-path "^0.3.0" - -set-value@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/set-value/-/set-value-2.0.0.tgz#71ae4a88f0feefbbf52d1ea604f3fb315ebb6274" - dependencies: - extend-shallow "^2.0.1" - is-extendable "^0.1.1" - is-plain-object "^2.0.3" - split-string "^3.0.1" - -setimmediate@^1.0.4: - version "1.0.5" - resolved "https://registry.yarnpkg.com/setimmediate/-/setimmediate-1.0.5.tgz#290cbb232e306942d7d7ea9b83732ab7856f8285" - -sha.js@^2.4.0, sha.js@^2.4.8: - version "2.4.11" - resolved "https://registry.yarnpkg.com/sha.js/-/sha.js-2.4.11.tgz#37a5cf0b81ecbc6943de109ba2960d1b26584ae7" - dependencies: - inherits "^2.0.1" - safe-buffer "^5.0.1" - -shebang-command@^1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/shebang-command/-/shebang-command-1.2.0.tgz#44aac65b695b03398968c39f363fee5deafdf1ea" - dependencies: - shebang-regex "^1.0.0" - -shebang-regex@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-1.0.0.tgz#da42f49740c0b42db2ca9728571cb190c98efea3" - -signal-exit@^3.0.0, signal-exit@^3.0.2: - version "3.0.2" - resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.2.tgz#b5fdc08f1287ea1178628e415e25132b73646c6d" - -snapdragon-node@^2.0.1: - version "2.1.1" - resolved "https://registry.yarnpkg.com/snapdragon-node/-/snapdragon-node-2.1.1.tgz#6c175f86ff14bdb0724563e8f3c1b021a286853b" - dependencies: - define-property "^1.0.0" - isobject "^3.0.0" - snapdragon-util "^3.0.1" - -snapdragon-util@^3.0.1: - version "3.0.1" - resolved "https://registry.yarnpkg.com/snapdragon-util/-/snapdragon-util-3.0.1.tgz#f956479486f2acd79700693f6f7b805e45ab56e2" - dependencies: - kind-of "^3.2.0" - -snapdragon@^0.8.1: - version "0.8.2" - resolved "https://registry.yarnpkg.com/snapdragon/-/snapdragon-0.8.2.tgz#64922e7c565b0e14204ba1aa7d6964278d25182d" - dependencies: - base "^0.11.1" - debug "^2.2.0" - define-property "^0.2.5" - extend-shallow "^2.0.1" - map-cache "^0.2.2" - source-map "^0.5.6" - source-map-resolve "^0.5.0" - use "^3.1.0" - -source-list-map@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/source-list-map/-/source-list-map-2.0.0.tgz#aaa47403f7b245a92fbc97ea08f250d6087ed085" - -source-map-resolve@^0.5.0: - version "0.5.2" - resolved "https://registry.yarnpkg.com/source-map-resolve/-/source-map-resolve-0.5.2.tgz#72e2cc34095543e43b2c62b2c4c10d4a9054f259" - dependencies: - atob "^2.1.1" - decode-uri-component "^0.2.0" - resolve-url "^0.2.1" - source-map-url "^0.4.0" - urix "^0.1.0" - -source-map-url@^0.4.0: - version "0.4.0" - resolved "https://registry.yarnpkg.com/source-map-url/-/source-map-url-0.4.0.tgz#3e935d7ddd73631b97659956d55128e87b5084a3" - -source-map@^0.5.6: - version "0.5.7" - resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.5.7.tgz#8a039d2d1021d22d1ea14c80d8ea468ba2ef3fcc" - -source-map@^0.6.1, source-map@~0.6.1: - version "0.6.1" - resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263" - -split-string@^3.0.1, split-string@^3.0.2: - version "3.1.0" - resolved "https://registry.yarnpkg.com/split-string/-/split-string-3.1.0.tgz#7cb09dda3a86585705c64b39a6466038682e8fe2" - dependencies: - extend-shallow "^3.0.0" - -ssri@^5.2.4: - version "5.3.0" - resolved "https://registry.yarnpkg.com/ssri/-/ssri-5.3.0.tgz#ba3872c9c6d33a0704a7d71ff045e5ec48999d06" - dependencies: - safe-buffer "^5.1.1" - -static-extend@^0.1.1: - version "0.1.2" - resolved "https://registry.yarnpkg.com/static-extend/-/static-extend-0.1.2.tgz#60809c39cbff55337226fd5e0b520f341f1fb5c6" - dependencies: - define-property "^0.2.5" - object-copy "^0.1.0" - -stream-browserify@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/stream-browserify/-/stream-browserify-2.0.1.tgz#66266ee5f9bdb9940a4e4514cafb43bb71e5c9db" - dependencies: - inherits "~2.0.1" - readable-stream "^2.0.2" - -stream-each@^1.1.0: - version "1.2.3" - resolved "https://registry.yarnpkg.com/stream-each/-/stream-each-1.2.3.tgz#ebe27a0c389b04fbcc233642952e10731afa9bae" - dependencies: - end-of-stream "^1.1.0" - stream-shift "^1.0.0" - -stream-http@^2.7.2: - version "2.8.3" - resolved "https://registry.yarnpkg.com/stream-http/-/stream-http-2.8.3.tgz#b2d242469288a5a27ec4fe8933acf623de6514fc" - dependencies: - builtin-status-codes "^3.0.0" - inherits "^2.0.1" - readable-stream "^2.3.6" - to-arraybuffer "^1.0.0" - xtend "^4.0.0" - -stream-shift@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/stream-shift/-/stream-shift-1.0.0.tgz#d5c752825e5367e786f78e18e445ea223a155952" - -string-width@^1.0.1: - version "1.0.2" - resolved "https://registry.yarnpkg.com/string-width/-/string-width-1.0.2.tgz#118bdf5b8cdc51a2a7e70d211e07e2b0b9b107d3" - dependencies: - code-point-at "^1.0.0" - is-fullwidth-code-point "^1.0.0" - strip-ansi "^3.0.0" - -"string-width@^1.0.2 || 2", string-width@^2.0.0, string-width@^2.1.0, string-width@^2.1.1: - version "2.1.1" - resolved "https://registry.yarnpkg.com/string-width/-/string-width-2.1.1.tgz#ab93f27a8dc13d28cac815c462143a6d9012ae9e" - dependencies: - is-fullwidth-code-point "^2.0.0" - strip-ansi "^4.0.0" - -string_decoder@^1.0.0, string_decoder@~1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.1.1.tgz#9cf1611ba62685d7030ae9e4ba34149c3af03fc8" - dependencies: - safe-buffer "~5.1.0" - -strip-ansi@^3.0.0, strip-ansi@^3.0.1: - version "3.0.1" - resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-3.0.1.tgz#6a385fb8853d952d5ff05d0e8aaf94278dc63dcf" - dependencies: - ansi-regex "^2.0.0" - -strip-ansi@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-4.0.0.tgz#a8479022eb1ac368a871389b635262c505ee368f" - dependencies: - ansi-regex "^3.0.0" - -strip-eof@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/strip-eof/-/strip-eof-1.0.0.tgz#bb43ff5598a6eb05d89b59fcd129c983313606bf" - -strip-json-comments@~2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-2.0.1.tgz#3c531942e908c2697c0ec344858c286c7ca0a60a" - supports-color@3.1.2: version "3.1.2" resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-3.1.2.tgz#72a262894d9d408b956ca05ff37b2ed8a6e2a2d5" dependencies: has-flag "^1.0.0" -supports-color@^5.3.0, supports-color@^5.4.0: - version "5.4.0" - resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-5.4.0.tgz#1c6b337402c2137605efe19f10fec390f6faab54" - dependencies: - has-flag "^3.0.0" - -tapable@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/tapable/-/tapable-1.0.0.tgz#cbb639d9002eed9c6b5975eb20598d7936f1f9f2" - -tar@^4: - version "4.4.6" - resolved "https://registry.yarnpkg.com/tar/-/tar-4.4.6.tgz#63110f09c00b4e60ac8bcfe1bf3c8660235fbc9b" - dependencies: - chownr "^1.0.1" - fs-minipass "^1.2.5" - minipass "^2.3.3" - minizlib "^1.1.0" - mkdirp "^0.5.0" - safe-buffer "^5.1.2" - yallist "^3.0.2" - -through2@^2.0.0: - version "2.0.3" - resolved "https://registry.yarnpkg.com/through2/-/through2-2.0.3.tgz#0004569b37c7c74ba39c43f3ced78d1ad94140be" - dependencies: - readable-stream "^2.1.5" - xtend "~4.0.1" - -through@^2.3.6: - version "2.3.8" - resolved "https://registry.yarnpkg.com/through/-/through-2.3.8.tgz#0dd4c9ffaabc357960b1b724115d7e0e86a2e1f5" - -timers-browserify@^2.0.4: - version "2.0.10" - resolved "https://registry.yarnpkg.com/timers-browserify/-/timers-browserify-2.0.10.tgz#1d28e3d2aadf1d5a5996c4e9f95601cd053480ae" - dependencies: - setimmediate "^1.0.4" - -tmp@^0.0.33: - version "0.0.33" - resolved "https://registry.yarnpkg.com/tmp/-/tmp-0.0.33.tgz#6d34335889768d21b2bcda0aa277ced3b1bfadf9" - dependencies: - os-tmpdir "~1.0.2" - -to-arraybuffer@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/to-arraybuffer/-/to-arraybuffer-1.0.1.tgz#7d229b1fcc637e466ca081180836a7aabff83f43" - -to-object-path@^0.3.0: - version "0.3.0" - resolved "https://registry.yarnpkg.com/to-object-path/-/to-object-path-0.3.0.tgz#297588b7b0e7e0ac08e04e672f85c1f4999e17af" - dependencies: - kind-of "^3.0.2" - -to-regex-range@^2.1.0: - version "2.1.1" - resolved "https://registry.yarnpkg.com/to-regex-range/-/to-regex-range-2.1.1.tgz#7c80c17b9dfebe599e27367e0d4dd5590141db38" - dependencies: - is-number "^3.0.0" - repeat-string "^1.6.1" - -to-regex@^3.0.1, to-regex@^3.0.2: - version "3.0.2" - resolved "https://registry.yarnpkg.com/to-regex/-/to-regex-3.0.2.tgz#13cfdd9b336552f30b51f33a8ae1b42a7a7599ce" - dependencies: - define-property "^2.0.2" - extend-shallow "^3.0.2" - regex-not "^1.0.2" - safe-regex "^1.1.0" - -tslib@^1.9.0: - version "1.9.3" - resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.9.3.tgz#d7e4dd79245d85428c4d7e4822a79917954ca286" - -tty-browserify@0.0.0: - version "0.0.0" - resolved "https://registry.yarnpkg.com/tty-browserify/-/tty-browserify-0.0.0.tgz#a157ba402da24e9bf957f9aa69d524eed42901a6" - -typedarray@^0.0.6: - version "0.0.6" - resolved "https://registry.yarnpkg.com/typedarray/-/typedarray-0.0.6.tgz#867ac74e3864187b1d3d47d996a78ec5c8830777" - -uglify-es@^3.3.4: - version "3.3.9" - resolved "https://registry.yarnpkg.com/uglify-es/-/uglify-es-3.3.9.tgz#0c1c4f0700bed8dbc124cdb304d2592ca203e677" - dependencies: - commander "~2.13.0" - source-map "~0.6.1" - -uglifyjs-webpack-plugin@^1.2.4: - version "1.2.7" - resolved "https://registry.yarnpkg.com/uglifyjs-webpack-plugin/-/uglifyjs-webpack-plugin-1.2.7.tgz#57638dd99c853a1ebfe9d97b42160a8a507f9d00" - dependencies: - cacache "^10.0.4" - find-cache-dir "^1.0.0" - schema-utils "^0.4.5" - serialize-javascript "^1.4.0" - source-map "^0.6.1" - uglify-es "^3.3.4" - webpack-sources "^1.1.0" - worker-farm "^1.5.2" - -union-value@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/union-value/-/union-value-1.0.0.tgz#5c71c34cb5bad5dcebe3ea0cd08207ba5aa1aea4" - dependencies: - arr-union "^3.1.0" - get-value "^2.0.6" - is-extendable "^0.1.1" - set-value "^0.4.3" - -unique-filename@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/unique-filename/-/unique-filename-1.1.0.tgz#d05f2fe4032560871f30e93cbe735eea201514f3" - dependencies: - unique-slug "^2.0.0" - -unique-slug@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/unique-slug/-/unique-slug-2.0.0.tgz#db6676e7c7cc0629878ff196097c78855ae9f4ab" - dependencies: - imurmurhash "^0.1.4" - -unset-value@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/unset-value/-/unset-value-1.0.0.tgz#8376873f7d2335179ffb1e6fc3a8ed0dfc8ab559" - dependencies: - has-value "^0.3.1" - isobject "^3.0.0" - -upath@^1.0.5: - version "1.1.0" - resolved "https://registry.yarnpkg.com/upath/-/upath-1.1.0.tgz#35256597e46a581db4793d0ce47fa9aebfc9fabd" - -uri-js@^4.2.1: - version "4.2.2" - resolved "https://registry.yarnpkg.com/uri-js/-/uri-js-4.2.2.tgz#94c540e1ff772956e2299507c010aea6c8838eb0" - dependencies: - punycode "^2.1.0" - -urix@^0.1.0: - version "0.1.0" - resolved "https://registry.yarnpkg.com/urix/-/urix-0.1.0.tgz#da937f7a62e21fec1fd18d49b35c2935067a6c72" - -url@^0.11.0: - version "0.11.0" - resolved "https://registry.yarnpkg.com/url/-/url-0.11.0.tgz#3838e97cfc60521eb73c525a8e55bfdd9e2e28f1" - dependencies: - punycode "1.3.2" - querystring "0.2.0" - -use@^3.1.0: - version "3.1.1" - resolved "https://registry.yarnpkg.com/use/-/use-3.1.1.tgz#d50c8cac79a19fbc20f2911f56eb973f4e10070f" - -util-deprecate@~1.0.1: - version "1.0.2" - resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf" - -util@0.10.3: - version "0.10.3" - resolved "https://registry.yarnpkg.com/util/-/util-0.10.3.tgz#7afb1afe50805246489e3db7fe0ed379336ac0f9" - dependencies: - inherits "2.0.1" - -util@^0.10.3: - version "0.10.4" - resolved "https://registry.yarnpkg.com/util/-/util-0.10.4.tgz#3aa0125bfe668a4672de58857d3ace27ecb76901" - dependencies: - inherits "2.0.3" - -v8-compile-cache@^2.0.0: - version "2.0.2" - resolved "https://registry.yarnpkg.com/v8-compile-cache/-/v8-compile-cache-2.0.2.tgz#a428b28bb26790734c4fc8bc9fa106fccebf6a6c" - -vm-browserify@0.0.4: - version "0.0.4" - resolved "https://registry.yarnpkg.com/vm-browserify/-/vm-browserify-0.0.4.tgz#5d7ea45bbef9e4a6ff65f95438e0a87c357d5a73" - dependencies: - indexof "0.0.1" - vscode-extension-telemetry@0.0.18: version "0.0.18" resolved "https://registry.yarnpkg.com/vscode-extension-telemetry/-/vscode-extension-telemetry-0.0.18.tgz#602ba20d8c71453aa34533a291e7638f6e5c0327" @@ -2578,149 +267,16 @@ vscode-nls@^3.2.4: version "3.2.4" resolved "https://registry.yarnpkg.com/vscode-nls/-/vscode-nls-3.2.4.tgz#2166b4183c8aea884d20727f5449e62be69fd398" -watchpack@^1.5.0: - version "1.6.0" - resolved "https://registry.yarnpkg.com/watchpack/-/watchpack-1.6.0.tgz#4bc12c2ebe8aa277a71f1d3f14d685c7b446cd00" - dependencies: - chokidar "^2.0.2" - graceful-fs "^4.1.2" - neo-async "^2.5.0" - -webpack-cli@^3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/webpack-cli/-/webpack-cli-3.1.0.tgz#d71a83687dcfeb758fdceeb0fe042f96bcf62994" - dependencies: - chalk "^2.4.1" - cross-spawn "^6.0.5" - enhanced-resolve "^4.0.0" - global-modules-path "^2.1.0" - import-local "^1.0.0" - inquirer "^6.0.0" - interpret "^1.1.0" - loader-utils "^1.1.0" - supports-color "^5.4.0" - v8-compile-cache "^2.0.0" - yargs "^12.0.1" - -webpack-sources@^1.0.1, webpack-sources@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/webpack-sources/-/webpack-sources-1.1.0.tgz#a101ebae59d6507354d71d8013950a3a8b7a5a54" - dependencies: - source-list-map "^2.0.0" - source-map "~0.6.1" - -webpack@^4.16.5: - version "4.16.5" - resolved "https://registry.yarnpkg.com/webpack/-/webpack-4.16.5.tgz#29fb39462823d7eb8aefcab8b45f7f241db0d092" - dependencies: - "@webassemblyjs/ast" "1.5.13" - "@webassemblyjs/helper-module-context" "1.5.13" - "@webassemblyjs/wasm-edit" "1.5.13" - "@webassemblyjs/wasm-opt" "1.5.13" - "@webassemblyjs/wasm-parser" "1.5.13" - acorn "^5.6.2" - acorn-dynamic-import "^3.0.0" - ajv "^6.1.0" - ajv-keywords "^3.1.0" - chrome-trace-event "^1.0.0" - enhanced-resolve "^4.1.0" - eslint-scope "^4.0.0" - json-parse-better-errors "^1.0.2" - loader-runner "^2.3.0" - loader-utils "^1.1.0" - memory-fs "~0.4.1" - micromatch "^3.1.8" - mkdirp "~0.5.0" - neo-async "^2.5.0" - node-libs-browser "^2.0.0" - schema-utils "^0.4.4" - tapable "^1.0.0" - uglifyjs-webpack-plugin "^1.2.4" - watchpack "^1.5.0" - webpack-sources "^1.0.1" - -which-module@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/which-module/-/which-module-2.0.0.tgz#d9ef07dce77b9902b8a3a8fa4b31c3e3f7e6e87a" - -which@^1.2.9: - version "1.3.1" - resolved "https://registry.yarnpkg.com/which/-/which-1.3.1.tgz#a45043d54f5805316da8d62f9f50918d3da70b0a" - dependencies: - isexe "^2.0.0" - which@^1.3.0: version "1.3.0" resolved "https://registry.yarnpkg.com/which/-/which-1.3.0.tgz#ff04bdfc010ee547d780bec38e1ac1c2777d253a" dependencies: isexe "^2.0.0" -wide-align@^1.1.0: - version "1.1.3" - resolved "https://registry.yarnpkg.com/wide-align/-/wide-align-1.1.3.tgz#ae074e6bdc0c14a431e804e624549c633b000457" - dependencies: - string-width "^1.0.2 || 2" - -worker-farm@^1.5.2: - version "1.6.0" - resolved "https://registry.yarnpkg.com/worker-farm/-/worker-farm-1.6.0.tgz#aecc405976fab5a95526180846f0dba288f3a4a0" - dependencies: - errno "~0.1.7" - -wrap-ansi@^2.0.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-2.1.0.tgz#d8fc3d284dd05794fe84973caecdd1cf824fdd85" - dependencies: - string-width "^1.0.1" - strip-ansi "^3.0.1" - wrappy@1: version "1.0.2" resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" -xregexp@4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/xregexp/-/xregexp-4.0.0.tgz#e698189de49dd2a18cc5687b05e17c8e43943020" - -xtend@^4.0.0, xtend@~4.0.1: - version "4.0.1" - resolved "https://registry.yarnpkg.com/xtend/-/xtend-4.0.1.tgz#a5c6d532be656e23db820efb943a1f04998d63af" - -"y18n@^3.2.1 || ^4.0.0", y18n@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/y18n/-/y18n-4.0.0.tgz#95ef94f85ecc81d007c264e190a120f0a3c8566b" - -yallist@^2.1.2: - version "2.1.2" - resolved "https://registry.yarnpkg.com/yallist/-/yallist-2.1.2.tgz#1c11f9218f076089a47dd512f93c6699a6a81d52" - -yallist@^3.0.0, yallist@^3.0.2: - version "3.0.2" - resolved "https://registry.yarnpkg.com/yallist/-/yallist-3.0.2.tgz#8452b4bb7e83c7c188d8041c1a837c773d6d8bb9" - -yargs-parser@^10.1.0: - version "10.1.0" - resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-10.1.0.tgz#7202265b89f7e9e9f2e5765e0fe735a905edbaa8" - dependencies: - camelcase "^4.1.0" - -yargs@^12.0.1: - version "12.0.1" - resolved "https://registry.yarnpkg.com/yargs/-/yargs-12.0.1.tgz#6432e56123bb4e7c3562115401e98374060261c2" - dependencies: - cliui "^4.0.0" - decamelize "^2.0.0" - find-up "^3.0.0" - get-caller-file "^1.0.1" - os-locale "^2.0.0" - require-directory "^2.1.1" - require-main-filename "^1.0.1" - set-blocking "^2.0.0" - string-width "^2.0.0" - which-module "^2.0.0" - y18n "^3.2.1 || ^4.0.0" - yargs-parser "^10.1.0" - zone.js@0.7.6: version "0.7.6" resolved "https://registry.yarnpkg.com/zone.js/-/zone.js-0.7.6.tgz#fbbc39d3e0261d0986f1ba06306eb3aeb0d22009" diff --git a/package.json b/package.json index 2d41efb2420..ef648c05ceb 100644 --- a/package.json +++ b/package.json @@ -126,7 +126,7 @@ "vinyl": "^0.4.5", "vinyl-fs": "^2.4.3", "vsce": "1.33.2", - "vscode-nls-dev": "3.0.7", + "vscode-nls-dev": "3.1.0", "webpack": "^4.16.5", "webpack-cli": "^3.1.0", "webpack-stream": "^5.1.1" diff --git a/yarn.lock b/yarn.lock index fbb07ff228e..54f936dd954 100644 --- a/yarn.lock +++ b/yarn.lock @@ -7897,9 +7897,9 @@ vscode-fsevents@0.3.8: dependencies: nan "^2.3.0" -vscode-nls-dev@3.0.7: - version "3.0.7" - resolved "https://registry.yarnpkg.com/vscode-nls-dev/-/vscode-nls-dev-3.0.7.tgz#8cfbb371cb3c8f47f247073d9f84a6af357bbfe0" +vscode-nls-dev@3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/vscode-nls-dev/-/vscode-nls-dev-3.1.0.tgz#afbd6c6291446a9f82cc19b781841ae307fa36c2" dependencies: clone "^2.1.1" event-stream "^3.3.4" From b22fd24420639888c724bf94183dec0fee10913e Mon Sep 17 00:00:00 2001 From: Hao Hu Date: Wed, 15 Aug 2018 02:38:26 -0700 Subject: [PATCH 0818/1276] Add openEditorAtIndex command (#56441) --- .../browser/parts/editor/editorCommands.ts | 36 +++++++++++-------- 1 file changed, 21 insertions(+), 15 deletions(-) diff --git a/src/vs/workbench/browser/parts/editor/editorCommands.ts b/src/vs/workbench/browser/parts/editor/editorCommands.ts index b6545f0bdc6..f8a7357eecc 100644 --- a/src/vs/workbench/browser/parts/editor/editorCommands.ts +++ b/src/vs/workbench/browser/parts/editor/editorCommands.ts @@ -22,7 +22,7 @@ import { distinct } from 'vs/base/common/arrays'; import { IEditorGroupsService, IEditorGroup, GroupDirection, GroupLocation, GroupsOrder, preferredSideBySideGroupDirection, EditorGroupLayout } from 'vs/workbench/services/group/common/editorGroupsService'; import { ContextKeyExpr } from 'vs/platform/contextkey/common/contextkey'; import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; -import { CommandsRegistry } from 'vs/platform/commands/common/commands'; +import { CommandsRegistry, ICommandHandler } from 'vs/platform/commands/common/commands'; import { MenuRegistry, MenuId } from 'vs/platform/actions/common/actions'; export const CLOSE_SAVED_EDITORS_COMMAND_ID = 'workbench.action.closeUnmodifiedEditors'; @@ -47,6 +47,8 @@ export const SPLIT_EDITOR_RIGHT = 'workbench.action.splitEditorRight'; export const NAVIGATE_ALL_EDITORS_GROUP_PREFIX = 'edt '; export const NAVIGATE_IN_ACTIVE_GROUP_PREFIX = 'edt active '; +export const OPEN_EDITOR_AT_INDEX_COMMAND_ID = 'workbench.action.openEditorAtIndex'; + export interface ActiveEditorMoveArguments { to?: 'first' | 'last' | 'left' | 'right' | 'up' | 'down' | 'center' | 'position' | 'previous' | 'next'; by?: 'tab' | 'group'; @@ -275,6 +277,22 @@ function registerDiffEditorCommands(): void { } function registerOpenEditorAtIndexCommands(): void { + const openEditorAtIndex: ICommandHandler = (accessor: ServicesAccessor, editorIndex: number): void => { + const editorService = accessor.get(IEditorService); + const activeControl = editorService.activeControl; + if (activeControl) { + const editor = activeControl.group.getEditor(editorIndex); + if (editor) { + editorService.openEditor(editor); + } + } + }; + + // This command takes in the editor index number to open as an argument + CommandsRegistry.registerCommand({ + id: OPEN_EDITOR_AT_INDEX_COMMAND_ID, + handler: openEditorAtIndex + }); // Keybindings to focus a specific index in the tab folder if tabs are enabled for (let i = 0; i < 9; i++) { @@ -282,24 +300,12 @@ function registerOpenEditorAtIndexCommands(): void { const visibleIndex = i + 1; KeybindingsRegistry.registerCommandAndKeybindingRule({ - id: 'workbench.action.openEditorAtIndex' + visibleIndex, + id: OPEN_EDITOR_AT_INDEX_COMMAND_ID + visibleIndex, weight: KeybindingWeight.WorkbenchContrib, when: void 0, primary: KeyMod.Alt | toKeyCode(visibleIndex), mac: { primary: KeyMod.WinCtrl | toKeyCode(visibleIndex) }, - handler: accessor => { - const editorService = accessor.get(IEditorService); - - const activeControl = editorService.activeControl; - if (activeControl) { - const editor = activeControl.group.getEditor(editorIndex); - if (editor) { - return editorService.openEditor(editor).then(() => void 0); - } - } - - return void 0; - } + handler: accessor => openEditorAtIndex(accessor, editorIndex) }); } From 3d6349afcb9a190a24c59420cf4b66caed6284ba Mon Sep 17 00:00:00 2001 From: Johannes Rieken Date: Wed, 15 Aug 2018 11:53:52 +0200 Subject: [PATCH 0819/1276] prepare for warning for questionable fsPath-usage, #56108 --- src/vs/base/common/uri.ts | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/vs/base/common/uri.ts b/src/vs/base/common/uri.ts index 00d663cd507..eec9ccb001a 100644 --- a/src/vs/base/common/uri.ts +++ b/src/vs/base/common/uri.ts @@ -187,6 +187,9 @@ export default class URI implements UriComponents { * with URIs that represent files on disk (`file` scheme). */ get fsPath(): string { + // if (this.scheme !== 'file') { + // console.warn(`[UriError] calling fsPath with scheme ${this.scheme}`); + // } return _makeFsPath(this); } From 7cdc647aa3a22b5b434fd8791f27d7ecdc9e105b Mon Sep 17 00:00:00 2001 From: Johannes Rieken Date: Wed, 15 Aug 2018 11:56:00 +0200 Subject: [PATCH 0820/1276] letter,title can be skipped, #54938 --- src/vs/vscode.proposed.d.ts | 4 ++-- src/vs/workbench/api/node/extHostDecorations.ts | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/vs/vscode.proposed.d.ts b/src/vs/vscode.proposed.d.ts index e48ce71fb1a..3de4a7af9dd 100644 --- a/src/vs/vscode.proposed.d.ts +++ b/src/vs/vscode.proposed.d.ts @@ -357,8 +357,8 @@ declare module 'vscode' { //todo@joh -> make class export interface DecorationData { - letter: string; - title: string; + letter?: string; + title?: string; color?: ThemeColor; priority?: number; bubble?: boolean; diff --git a/src/vs/workbench/api/node/extHostDecorations.ts b/src/vs/workbench/api/node/extHostDecorations.ts index 4ffee738596..1cc31088fe1 100644 --- a/src/vs/workbench/api/node/extHostDecorations.ts +++ b/src/vs/workbench/api/node/extHostDecorations.ts @@ -53,8 +53,8 @@ export class ExtHostDecorations implements ExtHostDecorationsShape { } const { provider, extensionId } = this._provider.get(handle); return asWinJsPromise(token => provider.provideDecoration(URI.revive(uri), token)).then(data => { - if (!data.letter || data.letter.length !== 1) { - console.warn(`INVALID decoration from extension '${extensionId}'. The 'letter' must be set and be one character`); + if (data.letter && data.letter.length !== 1) { + console.warn(`INVALID decoration from extension '${extensionId}'. The 'letter' must be set and be one character, not '${data.letter}'.`); } result[id] = data && [data.priority, data.bubble, data.title, data.letter, data.color, data.source]; }, err => { From 9d631901bdcb817de3387af3a23c3f78a35a279a Mon Sep 17 00:00:00 2001 From: Johannes Rieken Date: Wed, 15 Aug 2018 12:08:58 +0200 Subject: [PATCH 0821/1276] When checking snippet files, don't use indexOf but isEqualOrParent, #56403 --- src/vs/base/common/resources.ts | 17 +++++++++++------ .../electron-browser/snippetsService.ts | 2 +- 2 files changed, 12 insertions(+), 7 deletions(-) diff --git a/src/vs/base/common/resources.ts b/src/vs/base/common/resources.ts index a9a53243001..07774d24ee8 100644 --- a/src/vs/base/common/resources.ts +++ b/src/vs/base/common/resources.ts @@ -25,15 +25,20 @@ export function basenameOrAuthority(resource: URI): string { return basename(resource) || resource.authority; } -export function isEqualOrParent(resource: URI, candidate: URI, ignoreCase?: boolean): boolean { - if (resource.scheme === candidate.scheme) { - if (resource.scheme === Schemas.file) { - return paths.isEqualOrParent(resource.fsPath, candidate.fsPath, ignoreCase); +/** + * + * @param base A uri which is "longer" + * @param parentCandidate A uri which is "shorter" then `base` + */ +export function isEqualOrParent(base: URI, parentCandidate: URI, ignoreCase?: boolean): boolean { + if (base.scheme === parentCandidate.scheme) { + if (base.scheme === Schemas.file) { + return paths.isEqualOrParent(base.fsPath, parentCandidate.fsPath, ignoreCase); } - if (!isEqualAuthority(resource.authority, candidate.authority, ignoreCase)) { + if (!isEqualAuthority(base.authority, parentCandidate.authority, ignoreCase)) { return false; } - return paths.isEqualOrParent(resource.path, candidate.path, ignoreCase, '/'); + return paths.isEqualOrParent(base.path, parentCandidate.path, ignoreCase, '/'); } return false; diff --git a/src/vs/workbench/parts/snippets/electron-browser/snippetsService.ts b/src/vs/workbench/parts/snippets/electron-browser/snippetsService.ts index 69dc72ef055..6ec87c8ce50 100644 --- a/src/vs/workbench/parts/snippets/electron-browser/snippetsService.ts +++ b/src/vs/workbench/parts/snippets/electron-browser/snippetsService.ts @@ -76,7 +76,7 @@ namespace schema { const extensionLocation = extension.description.extensionLocation; const snippetLocation = resources.joinPath(extensionLocation, snippet.path); - if (snippetLocation.path.indexOf(extensionLocation.path) !== 0) { + if (!resources.isEqualOrParent(snippetLocation, extensionLocation)) { extension.collector.error(localize( 'invalid.path.1', "Expected `contributes.{0}.path` ({1}) to be included inside extension's folder ({2}). This might make the extension non-portable.", From fe747f81c0e649c9ed131b5fa2c43c0d6e925cd3 Mon Sep 17 00:00:00 2001 From: isidor Date: Wed, 15 Aug 2018 12:14:07 +0200 Subject: [PATCH 0822/1276] debug smoke: match ona a substring for a specific stack frame due to a potential sufix "readonly node content" fixes #56069 --- test/smoke/src/areas/debug/debug.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/smoke/src/areas/debug/debug.ts b/test/smoke/src/areas/debug/debug.ts index 86cd1ec88ab..529951db531 100644 --- a/test/smoke/src/areas/debug/debug.ts +++ b/test/smoke/src/areas/debug/debug.ts @@ -25,7 +25,7 @@ const DEBUG_STATUS_BAR = `.statusbar.debugging`; const NOT_DEBUG_STATUS_BAR = `.statusbar:not(debugging)`; const TOOLBAR_HIDDEN = `.debug-actions-widget.monaco-builder-hidden`; const STACK_FRAME = `${VIEWLET} .monaco-tree-row .stack-frame`; -const SPECIFIC_STACK_FRAME = filename => `${STACK_FRAME} .file[title$="${filename}"]`; +const SPECIFIC_STACK_FRAME = filename => `${STACK_FRAME} .file[title*="${filename}"]`; const VARIABLE = `${VIEWLET} .debug-variables .monaco-tree-row .expression`; const CONSOLE_OUTPUT = `.repl .output.expression .value`; const CONSOLE_INPUT_OUTPUT = `.repl .input-output-pair .output.expression .value`; From 34a667a828e22cabe88a589ebbca78fd5d3e37f4 Mon Sep 17 00:00:00 2001 From: Johannes Rieken Date: Wed, 15 Aug 2018 12:42:36 +0200 Subject: [PATCH 0823/1276] breadcrumbs - don't leak a listener --- src/vs/workbench/browser/parts/editor/titleControl.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/vs/workbench/browser/parts/editor/titleControl.ts b/src/vs/workbench/browser/parts/editor/titleControl.ts index 91d2e0b3e83..ff452e13d8e 100644 --- a/src/vs/workbench/browser/parts/editor/titleControl.ts +++ b/src/vs/workbench/browser/parts/editor/titleControl.ts @@ -97,7 +97,7 @@ export abstract class TitleControl extends Themable { protected createBreadcrumbsControl(container: HTMLElement, options: IBreadcrumbsControlOptions): void { const config = this._register(BreadcrumbsConfig.IsEnabled.bindTo(this.configurationService)); - config.onDidChange(value => { + this._register(config.onDidChange(value => { if (!value && this.breadcrumbsControl) { this.breadcrumbsControl.dispose(); this.breadcrumbsControl = undefined; @@ -107,7 +107,7 @@ export abstract class TitleControl extends Themable { this.breadcrumbsControl.update(); this.handleBreadcrumbsEnablementChange(); } - }); + })); if (config.value) { this.breadcrumbsControl = this.instantiationService.createInstance(BreadcrumbsControl, container, options, this.group); } From b72f45c06f848c51ced649cfb08b605d6c8ceeb6 Mon Sep 17 00:00:00 2001 From: Johannes Rieken Date: Wed, 15 Aug 2018 13:20:40 +0200 Subject: [PATCH 0824/1276] add breadcrumb.background, #55960 --- src/vs/base/browser/ui/breadcrumbs/breadcrumbsWidget.ts | 8 -------- src/vs/platform/theme/common/colorRegistry.ts | 1 + src/vs/platform/theme/common/styler.ts | 4 ++-- .../workbench/browser/parts/editor/breadcrumbsControl.ts | 4 +++- .../workbench/browser/parts/editor/noTabsTitleControl.ts | 3 ++- src/vs/workbench/browser/parts/editor/tabsTitleControl.ts | 4 ++-- 6 files changed, 10 insertions(+), 14 deletions(-) diff --git a/src/vs/base/browser/ui/breadcrumbs/breadcrumbsWidget.ts b/src/vs/base/browser/ui/breadcrumbs/breadcrumbsWidget.ts index faa5908492e..f5544a9cd9a 100644 --- a/src/vs/base/browser/ui/breadcrumbs/breadcrumbsWidget.ts +++ b/src/vs/base/browser/ui/breadcrumbs/breadcrumbsWidget.ts @@ -45,10 +45,8 @@ export class SimpleBreadcrumbsItem extends BreadcrumbsItem { export interface IBreadcrumbsWidgetStyles { breadcrumbsBackground?: Color; breadcrumbsForeground?: Color; - breadcrumbsHoverBackground?: Color; breadcrumbsHoverForeground?: Color; breadcrumbsFocusForeground?: Color; - breadcrumbsFocusAndSelectionBackground?: Color; breadcrumbsFocusAndSelectionForeground?: Color; } @@ -135,15 +133,9 @@ export class BreadcrumbsWidget { if (style.breadcrumbsFocusForeground) { content += `.monaco-breadcrumbs .monaco-breadcrumb-item.focused { color: ${style.breadcrumbsFocusForeground}}\n`; } - if (style.breadcrumbsFocusAndSelectionBackground) { - content += `.monaco-breadcrumbs .monaco-breadcrumb-item.focused.selected { background-color: ${style.breadcrumbsFocusAndSelectionBackground}}\n`; - } if (style.breadcrumbsFocusAndSelectionForeground) { content += `.monaco-breadcrumbs .monaco-breadcrumb-item.focused.selected { color: ${style.breadcrumbsFocusAndSelectionForeground}}\n`; } - if (style.breadcrumbsHoverBackground) { - content += `.monaco-breadcrumbs .monaco-breadcrumb-item:hover:not(.focused):not(.selected) { background-color: ${style.breadcrumbsHoverBackground}}\n`; - } if (style.breadcrumbsHoverForeground) { content += `.monaco-breadcrumbs .monaco-breadcrumb-item:hover:not(.focused):not(.selected) { color: ${style.breadcrumbsHoverForeground}}\n`; } diff --git a/src/vs/platform/theme/common/colorRegistry.ts b/src/vs/platform/theme/common/colorRegistry.ts index 8d984bd6f21..8b3e5c985d6 100644 --- a/src/vs/platform/theme/common/colorRegistry.ts +++ b/src/vs/platform/theme/common/colorRegistry.ts @@ -224,6 +224,7 @@ export const scrollbarSliderActiveBackground = registerColor('scrollbarSlider.ac export const progressBarBackground = registerColor('progressBar.background', { dark: Color.fromHex('#0E70C0'), light: Color.fromHex('#0E70C0'), hc: contrastBorder }, nls.localize('progressBarBackground', "Background color of the progress bar that can show for long running operations.")); export const breadcrumbsForeground = registerColor('breadcrumb.foreground', { light: Color.fromHex('#6C6C6C').transparent(.7), dark: Color.fromHex('#CCCCCC').transparent(.7), hc: Color.white.transparent(.7) }, nls.localize('breadcrumbsFocusForeground', "Color of focused breadcrumb items.")); +export const breadcrumbsBackground = registerColor('breadcrumb.brackground', { light: '#fffffe', dark: '#1E1E1E', hc: Color.black }, nls.localize('breadcrumbsBackground', "Background color of breadcrumb items.")); export const breadcrumbsFocusForeground = registerColor('breadcrumb.focusForeground', { light: '#6C6C6C', dark: '#CCCCCC', hc: Color.white }, nls.localize('breadcrumbsFocusForeground', "Color of focused breadcrumb items.")); export const breadcrumbsActiveSelectionForeground = registerColor('breadcrumb.activeSelectionForeground', { light: '#6C6C6C', dark: '#CCCCCC', hc: Color.white }, nls.localize('breadcrumbsSelectedForegound', "Color of selected breadcrumb items.")); export const breadcrumbsPickerBackground = registerColor('breadcrumbPicker.background', { light: '#ECECEC', dark: '#252526', hc: Color.black }, nls.localize('breadcrumbsSelectedBackground', "Background color of breadcrumb item picker.")); diff --git a/src/vs/platform/theme/common/styler.ts b/src/vs/platform/theme/common/styler.ts index ff6542c0a9a..67e889439b7 100644 --- a/src/vs/platform/theme/common/styler.ts +++ b/src/vs/platform/theme/common/styler.ts @@ -6,7 +6,7 @@ 'use strict'; 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 } 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 } 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'; @@ -272,7 +272,7 @@ export interface IBreadcrumbsWidgetStyleOverrides extends IStyleOverrides { } export const defaultBreadcrumbsStyles = { - breadcrumbsBackground: editorBackground, + breadcrumbsBackground: breadcrumbsBackground, breadcrumbsForeground: breadcrumbsForeground, breadcrumbsHoverForeground: breadcrumbsFocusForeground, breadcrumbsFocusForeground: breadcrumbsFocusForeground, diff --git a/src/vs/workbench/browser/parts/editor/breadcrumbsControl.ts b/src/vs/workbench/browser/parts/editor/breadcrumbsControl.ts index 4d763cfcced..fb56b0b1fe9 100644 --- a/src/vs/workbench/browser/parts/editor/breadcrumbsControl.ts +++ b/src/vs/workbench/browser/parts/editor/breadcrumbsControl.ts @@ -40,6 +40,7 @@ import { localize } from 'vs/nls'; import { CommandsRegistry } from 'vs/platform/commands/common/commands'; import { tail } from 'vs/base/common/arrays'; import { WorkbenchListFocusContextKey } from 'vs/platform/list/browser/listService'; +import { ColorIdentifier } from 'vs/platform/theme/common/colorRegistry'; class Item extends BreadcrumbsItem { @@ -117,6 +118,7 @@ export interface IBreadcrumbsControlOptions { showSymbolIcons: boolean; showDecorationColors: boolean; extraClasses: string[]; + breadcrumbsBackground: ColorIdentifier; } export class BreadcrumbsControl { @@ -167,7 +169,7 @@ export class BreadcrumbsControl { this._widget.onDidSelectItem(this._onSelectEvent, this, this._disposables); this._widget.onDidFocusItem(this._onFocusEvent, this, this._disposables); this._widget.onDidChangeFocus(this._updateCkBreadcrumbsActive, this, this._disposables); - this._disposables.push(attachBreadcrumbsStyler(this._widget, this._themeService)); + this._disposables.push(attachBreadcrumbsStyler(this._widget, this._themeService, { breadcrumbsBackground: _options.breadcrumbsBackground })); this._ckBreadcrumbsVisible = BreadcrumbsControl.CK_BreadcrumbsVisible.bindTo(this._contextKeyService); this._ckBreadcrumbsActive = BreadcrumbsControl.CK_BreadcrumbsActive.bindTo(this._contextKeyService); diff --git a/src/vs/workbench/browser/parts/editor/noTabsTitleControl.ts b/src/vs/workbench/browser/parts/editor/noTabsTitleControl.ts index a5a99f0c2bd..6b1cdc64ca1 100644 --- a/src/vs/workbench/browser/parts/editor/noTabsTitleControl.ts +++ b/src/vs/workbench/browser/parts/editor/noTabsTitleControl.ts @@ -15,6 +15,7 @@ import { addDisposableListener, EventType, addClass, EventHelper, removeClass, t import { IEditorPartOptions, EDITOR_TITLE_HEIGHT } from 'vs/workbench/browser/parts/editor/editor'; import { IAction } from 'vs/base/common/actions'; import { CLOSE_EDITOR_COMMAND_ID } from 'vs/workbench/browser/parts/editor/editorCommands'; +import { editorBackground } from 'vs/platform/theme/common/colorRegistry'; export class NoTabsTitleControl extends TitleControl { private titleContainer: HTMLElement; @@ -40,7 +41,7 @@ export class NoTabsTitleControl extends TitleControl { this._register(this.editorLabel.onClick(e => this.onTitleLabelClick(e))); // Breadcrumbs - this.createBreadcrumbsControl(labelContainer, { showFileIcons: false, showSymbolIcons: true, showDecorationColors: false, extraClasses: ['no-tabs-breadcrumbs'] }); + this.createBreadcrumbsControl(labelContainer, { showFileIcons: false, showSymbolIcons: true, showDecorationColors: false, extraClasses: ['no-tabs-breadcrumbs'], breadcrumbsBackground: editorBackground }); // Right Actions Container const actionsContainer = document.createElement('div'); diff --git a/src/vs/workbench/browser/parts/editor/tabsTitleControl.ts b/src/vs/workbench/browser/parts/editor/tabsTitleControl.ts index 2cf73b3bf5a..5a73b95db7c 100644 --- a/src/vs/workbench/browser/parts/editor/tabsTitleControl.ts +++ b/src/vs/workbench/browser/parts/editor/tabsTitleControl.ts @@ -28,7 +28,7 @@ import { ScrollbarVisibility } from 'vs/base/common/scrollable'; import { getOrSet } from 'vs/base/common/map'; import { IThemeService, registerThemingParticipant, ITheme, ICssStyleCollector } from 'vs/platform/theme/common/themeService'; import { TAB_INACTIVE_BACKGROUND, TAB_ACTIVE_BACKGROUND, TAB_ACTIVE_FOREGROUND, TAB_INACTIVE_FOREGROUND, TAB_BORDER, EDITOR_DRAG_AND_DROP_BACKGROUND, TAB_UNFOCUSED_ACTIVE_FOREGROUND, TAB_UNFOCUSED_INACTIVE_FOREGROUND, TAB_UNFOCUSED_ACTIVE_BORDER, TAB_ACTIVE_BORDER, TAB_HOVER_BACKGROUND, TAB_HOVER_BORDER, TAB_UNFOCUSED_HOVER_BACKGROUND, TAB_UNFOCUSED_HOVER_BORDER, EDITOR_GROUP_HEADER_TABS_BACKGROUND, WORKBENCH_BACKGROUND, TAB_ACTIVE_BORDER_TOP, TAB_UNFOCUSED_ACTIVE_BORDER_TOP } from 'vs/workbench/common/theme'; -import { activeContrastBorder, contrastBorder, editorBackground } from 'vs/platform/theme/common/colorRegistry'; +import { activeContrastBorder, contrastBorder, editorBackground, breadcrumbsBackground } from 'vs/platform/theme/common/colorRegistry'; import { ResourcesDropHandler, fillResourceDataTransfers, DraggedEditorIdentifier, DraggedEditorGroupIdentifier, DragAndDropObserver } from 'vs/workbench/browser/dnd'; import { Color } from 'vs/base/common/color'; import { INotificationService } from 'vs/platform/notification/common/notification'; @@ -116,7 +116,7 @@ export class TabsTitleControl extends TitleControl { const breadcrumbsContainer = document.createElement('div'); addClass(breadcrumbsContainer, 'tabs-breadcrumbs'); this.titleContainer.appendChild(breadcrumbsContainer); - this.createBreadcrumbsControl(breadcrumbsContainer, { showFileIcons: true, showSymbolIcons: true, showDecorationColors: false, extraClasses: [] }); + this.createBreadcrumbsControl(breadcrumbsContainer, { showFileIcons: true, showSymbolIcons: true, showDecorationColors: false, extraClasses: [], breadcrumbsBackground: breadcrumbsBackground }); } private createScrollbar(): void { From 2959c8517bb86283419ec59f79f07fe9d3824bbf Mon Sep 17 00:00:00 2001 From: Johannes Rieken Date: Wed, 15 Aug 2018 13:22:15 +0200 Subject: [PATCH 0825/1276] fix typo in color name #55960 --- src/vs/platform/theme/common/colorRegistry.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vs/platform/theme/common/colorRegistry.ts b/src/vs/platform/theme/common/colorRegistry.ts index 8b3e5c985d6..8571fd6d2c9 100644 --- a/src/vs/platform/theme/common/colorRegistry.ts +++ b/src/vs/platform/theme/common/colorRegistry.ts @@ -224,7 +224,7 @@ export const scrollbarSliderActiveBackground = registerColor('scrollbarSlider.ac export const progressBarBackground = registerColor('progressBar.background', { dark: Color.fromHex('#0E70C0'), light: Color.fromHex('#0E70C0'), hc: contrastBorder }, nls.localize('progressBarBackground', "Background color of the progress bar that can show for long running operations.")); export const breadcrumbsForeground = registerColor('breadcrumb.foreground', { light: Color.fromHex('#6C6C6C').transparent(.7), dark: Color.fromHex('#CCCCCC').transparent(.7), hc: Color.white.transparent(.7) }, nls.localize('breadcrumbsFocusForeground', "Color of focused breadcrumb items.")); -export const breadcrumbsBackground = registerColor('breadcrumb.brackground', { light: '#fffffe', dark: '#1E1E1E', hc: Color.black }, nls.localize('breadcrumbsBackground', "Background color of breadcrumb items.")); +export const breadcrumbsBackground = registerColor('breadcrumb.background', { light: '#fffffe', dark: '#1E1E1E', hc: Color.black }, nls.localize('breadcrumbsBackground', "Background color of breadcrumb items.")); export const breadcrumbsFocusForeground = registerColor('breadcrumb.focusForeground', { light: '#6C6C6C', dark: '#CCCCCC', hc: Color.white }, nls.localize('breadcrumbsFocusForeground', "Color of focused breadcrumb items.")); export const breadcrumbsActiveSelectionForeground = registerColor('breadcrumb.activeSelectionForeground', { light: '#6C6C6C', dark: '#CCCCCC', hc: Color.white }, nls.localize('breadcrumbsSelectedForegound', "Color of selected breadcrumb items.")); export const breadcrumbsPickerBackground = registerColor('breadcrumbPicker.background', { light: '#ECECEC', dark: '#252526', hc: Color.black }, nls.localize('breadcrumbsSelectedBackground', "Background color of breadcrumb item picker.")); From d2ac0ce6ec72ea34b11782225af1176ff41cf9ff Mon Sep 17 00:00:00 2001 From: Benjamin Pasero Date: Wed, 15 Aug 2018 16:01:58 +0200 Subject: [PATCH 0826/1276] Open Editors: revisit order of groups to be based on visual order (for #56084) (#56264) --- .../browser/parts/editor/editorPart.ts | 35 +++++++++++++------ .../browser/parts/editor/editorPicker.ts | 4 +-- .../electron-browser/views/openEditorsView.ts | 6 ++-- 3 files changed, 29 insertions(+), 16 deletions(-) diff --git a/src/vs/workbench/browser/parts/editor/editorPart.ts b/src/vs/workbench/browser/parts/editor/editorPart.ts index 553ff7e0c65..eac59365565 100644 --- a/src/vs/workbench/browser/parts/editor/editorPart.ts +++ b/src/vs/workbench/browser/parts/editor/editorPart.ts @@ -419,13 +419,16 @@ export class EditorPart extends Part implements EditorGroupsServiceImpl, IEditor // Mark preferred size as changed this.resetPreferredSize(); - // Events for groupd that got added + // Events for groups that got added this.getGroups(GroupsOrder.GRID_APPEARANCE).forEach(groupView => { if (currentGroupViews.indexOf(groupView) === -1) { this._onDidAddGroup.fire(groupView); } }); + // Update labels + this.updateGroupLabels(); + // Restore focus as needed if (gridHasFocus) { this._activeGroup.focus(); @@ -475,6 +478,9 @@ export class EditorPart extends Part implements EditorGroupsServiceImpl, IEditor // Event this._onDidAddGroup.fire(newGroupView); + // Update labels + this.updateGroupLabels(); + return newGroupView; } @@ -631,12 +637,8 @@ export class EditorPart extends Part implements EditorGroupsServiceImpl, IEditor this._activeGroup.focus(); } - // Update labels: since our labels are created using the index of the - // group, removing a group might produce gaps. So we iterate over all - // groups and reassign the label based on the index. - this.getGroups(GroupsOrder.CREATION_TIME).forEach((group, index) => { - group.setLabel(this.getGroupLabel(index + 1)); - }); + // Update labels + this.updateGroupLabels(); // Update container this.updateContainer(); @@ -648,10 +650,6 @@ export class EditorPart extends Part implements EditorGroupsServiceImpl, IEditor this._onDidRemoveGroup.fire(groupView); } - private getGroupLabel(index: number): string { - return localize('groupLabel', "Group {0}", index); - } - moveGroup(group: IEditorGroupView | GroupIdentifier, location: IEditorGroupView | GroupIdentifier, direction: GroupDirection): IEditorGroupView { const sourceView = this.assertGroupView(group); const targetView = this.assertGroupView(location); @@ -887,6 +885,21 @@ export class EditorPart extends Part implements EditorGroupsServiceImpl, IEditor toggleClass(this.container, 'empty', this.isEmpty()); } + private updateGroupLabels(): void { + + // Since our labels are created using the index of the + // group, adding/removing a group might produce gaps. + // So we iterate over all groups and reassign the label + // based on the index. + this.getGroups(GroupsOrder.GRID_APPEARANCE).forEach((group, index) => { + group.setLabel(this.getGroupLabel(index + 1)); + }); + } + + private getGroupLabel(index: number): string { + return localize('groupLabel', "Group {0}", index); + } + private isEmpty(): boolean { return this.groupViews.size === 1 && this._activeGroup.isEmpty(); } diff --git a/src/vs/workbench/browser/parts/editor/editorPicker.ts b/src/vs/workbench/browser/parts/editor/editorPicker.ts index edbf302a694..58db9249439 100644 --- a/src/vs/workbench/browser/parts/editor/editorPicker.ts +++ b/src/vs/workbench/browser/parts/editor/editorPicker.ts @@ -117,7 +117,7 @@ export abstract class BaseEditorPicker extends QuickOpenHandler { // Sorting if (query.value) { - const groups = this.editorGroupService.getGroups(GroupsOrder.CREATION_TIME); + const groups = this.editorGroupService.getGroups(GroupsOrder.GRID_APPEARANCE); entries.sort((e1, e2) => { if (e1.group !== e2.group) { return groups.indexOf(e1.group) - groups.indexOf(e2.group); // older groups first @@ -206,7 +206,7 @@ export class AllEditorsPicker extends BaseEditorPicker { protected getEditorEntries(): EditorPickerEntry[] { const entries: EditorPickerEntry[] = []; - this.editorGroupService.getGroups(GroupsOrder.CREATION_TIME).forEach(group => { + this.editorGroupService.getGroups(GroupsOrder.GRID_APPEARANCE).forEach(group => { group.editors.forEach(editor => { entries.push(this.instantiationService.createInstance(EditorPickerEntry, editor, group)); }); diff --git a/src/vs/workbench/parts/files/electron-browser/views/openEditorsView.ts b/src/vs/workbench/parts/files/electron-browser/views/openEditorsView.ts index 52205ce5b1d..a9eb1724a80 100644 --- a/src/vs/workbench/parts/files/electron-browser/views/openEditorsView.ts +++ b/src/vs/workbench/parts/files/electron-browser/views/openEditorsView.ts @@ -10,7 +10,7 @@ import { IAction, ActionRunner } from 'vs/base/common/actions'; import * as dom from 'vs/base/browser/dom'; import { IContextMenuService } from 'vs/platform/contextview/browser/contextView'; import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; -import { IEditorGroupsService, IEditorGroup, GroupChangeKind } from 'vs/workbench/services/group/common/editorGroupsService'; +import { IEditorGroupsService, IEditorGroup, GroupChangeKind, GroupsOrder } from 'vs/workbench/services/group/common/editorGroupsService'; import { IConfigurationService, IConfigurationChangeEvent } from 'vs/platform/configuration/common/configuration'; import { IKeybindingService } from 'vs/platform/keybinding/common/keybinding'; import { IEditorInput } from 'vs/workbench/common/editor'; @@ -326,7 +326,7 @@ export class OpenEditorsView extends ViewletPanel { private get elements(): (IEditorGroup | OpenEditor)[] { const result: (IEditorGroup | OpenEditor)[] = []; - this.editorGroupService.groups.forEach(g => { + this.editorGroupService.getGroups(GroupsOrder.GRID_APPEARANCE).forEach(g => { if (this.showGroups) { result.push(g); } @@ -342,7 +342,7 @@ export class OpenEditorsView extends ViewletPanel { return index; } - for (let g of this.editorGroupService.groups) { + for (let g of this.editorGroupService.getGroups(GroupsOrder.GRID_APPEARANCE)) { if (g.id === group.id) { return index + (!!editor ? 1 : 0); } else { From ee869a32085a28e91d5519bc7709fc8396f5050e Mon Sep 17 00:00:00 2001 From: Christof Marti Date: Wed, 15 Aug 2018 16:09:56 +0200 Subject: [PATCH 0827/1276] Update calendar --- .github/calendar.yml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/.github/calendar.yml b/.github/calendar.yml index a37969648ad..d7827edb02b 100644 --- a/.github/calendar.yml +++ b/.github/calendar.yml @@ -25,5 +25,7 @@ '2018-06-25 18:00, US/Pacific': 'endgame', '2018-07-05 12:00, US/Pacific': 'development', # 1.25.0 released '2018-07-30 18:00, US/Pacific': 'endgame', - '2018-08-13 12:00, US/Pacific': 'development' # 1.26.0 released + '2018-08-13 12:00, US/Pacific': 'development', # 1.26.0 released + '2018-08-27 18:00, US/Pacific': 'endgame', +# '2018-09-05 12:00, US/Pacific': 'development', # 1.27.0 released } From a3bc4d26957da1e4a3cbe2b0192720ab631385a6 Mon Sep 17 00:00:00 2001 From: isidor Date: Wed, 15 Aug 2018 16:47:26 +0200 Subject: [PATCH 0828/1276] uriDisplay: if no formatter is registered fall back to getPathlabel fixes #56104 --- src/vs/platform/uriDisplay/common/uriDisplay.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/vs/platform/uriDisplay/common/uriDisplay.ts b/src/vs/platform/uriDisplay/common/uriDisplay.ts index 486aeb0d77e..cd53cee444f 100644 --- a/src/vs/platform/uriDisplay/common/uriDisplay.ts +++ b/src/vs/platform/uriDisplay/common/uriDisplay.ts @@ -11,7 +11,7 @@ import { IWorkspaceContextService } from 'vs/platform/workspace/common/workspace import { createDecorator } from 'vs/platform/instantiation/common/instantiation'; import { isEqual, basenameOrAuthority } from 'vs/base/common/resources'; import { isLinux, isWindows } from 'vs/base/common/platform'; -import { tildify } from 'vs/base/common/labels'; +import { tildify, getPathLabel } from 'vs/base/common/labels'; import { ltrim } from 'vs/base/common/strings'; export interface IUriDisplayService { @@ -58,7 +58,7 @@ export class UriDisplayService implements IUriDisplayService { } const formater = this.formaters.get(resource.scheme); if (!formater) { - return resource.path; + return getPathLabel(resource.path, this.environmentService, relative ? this.contextService : undefined); } if (relative) { From 2d9093bcf215189f40eafb2e301db91d0d19a8d5 Mon Sep 17 00:00:00 2001 From: Martin Aeschlimann Date: Wed, 15 Aug 2018 17:18:57 +0200 Subject: [PATCH 0829/1276] resources.join & normalize must not change windows drive letter. Fixes #56403 --- src/vs/base/common/resources.ts | 40 ++++++++++++++++++----- src/vs/base/test/common/resources.test.ts | 17 ++++++---- 2 files changed, 42 insertions(+), 15 deletions(-) diff --git a/src/vs/base/common/resources.ts b/src/vs/base/common/resources.ts index 07774d24ee8..365c144c132 100644 --- a/src/vs/base/common/resources.ts +++ b/src/vs/base/common/resources.ts @@ -26,21 +26,19 @@ export function basenameOrAuthority(resource: URI): string { } /** - * + * Tests wheter a `candidate` URI is a parent or equal of a given `base` URI. * @param base A uri which is "longer" * @param parentCandidate A uri which is "shorter" then `base` */ export function isEqualOrParent(base: URI, parentCandidate: URI, ignoreCase?: boolean): boolean { if (base.scheme === parentCandidate.scheme) { if (base.scheme === Schemas.file) { - return paths.isEqualOrParent(base.fsPath, parentCandidate.fsPath, ignoreCase); + return paths.isEqualOrParent(fsPath(base), fsPath(parentCandidate), ignoreCase); } - if (!isEqualAuthority(base.authority, parentCandidate.authority, ignoreCase)) { - return false; + if (isEqualAuthority(base.authority, parentCandidate.authority, ignoreCase)) { + return paths.isEqualOrParent(base.path, parentCandidate.path, ignoreCase, '/'); } - return paths.isEqualOrParent(base.path, parentCandidate.path, ignoreCase, '/'); } - return false; } @@ -95,7 +93,7 @@ export function dirname(resource: URI): URI { export function joinPath(resource: URI, pathFragment: string): URI { let joinedPath: string; if (resource.scheme === Schemas.file) { - joinedPath = URI.file(paths.join(resource.fsPath, pathFragment)).path; + joinedPath = URI.file(paths.join(fsPath(resource), pathFragment)).path; } else { joinedPath = paths.join(resource.path, pathFragment); } @@ -113,7 +111,7 @@ export function joinPath(resource: URI, pathFragment: string): URI { export function normalizePath(resource: URI): URI { let normalizedPath: string; if (resource.scheme === Schemas.file) { - normalizedPath = URI.file(paths.normalize(resource.fsPath)).path; + normalizedPath = URI.file(paths.normalize(fsPath(resource))).path; } else { normalizedPath = paths.normalize(resource.path); } @@ -122,6 +120,25 @@ export function normalizePath(resource: URI): URI { }); } +/** + * Returns the fsPath of an URI where the drive letter is not normalized. + * See #56403. + */ +function fsPath(uri: URI): string { + let value: string; + if (uri.authority && uri.path.length > 1 && uri.scheme === 'file') { + // unc path: file://shares/c$/far/boo + value = `//${uri.authority}${uri.path}`; + } else { + // other path + value = uri.path; + } + if (isWindows) { + value = value.replace(/\//g, '\\'); + } + return value; +} + /** * Returns true if the URI path is absolute. */ @@ -149,6 +166,13 @@ export function distinctParents(items: T[], resourceAccessor: (item: T) => UR return distinctParents; } +/** + * Tests wheter the given URL is a file URI created by `URI.parse` instead of `URI.file`. + * Such URI have no scheme or scheme that consist of a single letter (windows drive letter) + * @param candidate The URI to test + * @returns A corrected, real file URI if the input seems to be malformed. + * Undefined is returned if the input URI looks fine. + */ export function isMalformedFileUri(candidate: URI): URI | undefined { if (!candidate.scheme || isWindows && candidate.scheme.match(/^[a-zA-Z]$/)) { return URI.file((candidate.scheme ? candidate.scheme + ':' : '') + candidate.path); diff --git a/src/vs/base/test/common/resources.test.ts b/src/vs/base/test/common/resources.test.ts index e35a9bb438d..0a065279901 100644 --- a/src/vs/base/test/common/resources.test.ts +++ b/src/vs/base/test/common/resources.test.ts @@ -48,6 +48,7 @@ suite('Resources', () => { assert.equal(dirname(URI.file('c:\\some\\file')).toString(), 'file:///c%3A/some'); assert.equal(dirname(URI.file('c:\\some\\file\\')).toString(), 'file:///c%3A/some'); assert.equal(dirname(URI.file('c:\\some')).toString(), 'file:///c%3A/'); + assert.equal(dirname(URI.file('C:\\some')).toString(), 'file:///C%3A/'); } else { assert.equal(dirname(URI.file('/some/file/test.txt')).toString(), 'file:///some/file'); assert.equal(dirname(URI.file('/some/file/')).toString(), 'file:///some'); @@ -67,6 +68,7 @@ suite('Resources', () => { assert.equal(basename(URI.file('c:\\some\\file\\test.txt')), 'test.txt'); assert.equal(basename(URI.file('c:\\some\\file')), 'file'); assert.equal(basename(URI.file('c:\\some\\file\\')), 'file'); + assert.equal(basename(URI.file('C:\\some\\file\\')), 'file'); } else { assert.equal(basename(URI.file('/some/file/test.txt')), 'test.txt'); assert.equal(basename(URI.file('/some/file/')), 'file'); @@ -90,8 +92,8 @@ suite('Resources', () => { assert.equal(joinPath(URI.file('c:\\'), 'bar/file.js').toString(), 'file:///c%3A/bar/file.js'); assert.equal(joinPath(URI.file('c:\\foo'), './file.js').toString(), 'file:///c%3A/foo/file.js'); assert.equal(joinPath(URI.file('c:\\foo'), '/./file.js').toString(), 'file:///c%3A/foo/file.js'); - assert.equal(joinPath(URI.file('c:\\foo'), '../file.js').toString(), 'file:///c%3A/file.js'); - assert.equal(joinPath(URI.file('c:\\foo\\.'), '../file.js').toString(), 'file:///c%3A/file.js'); + assert.equal(joinPath(URI.file('C:\\foo'), '../file.js').toString(), 'file:///c%3A/file.js'); + assert.equal(joinPath(URI.file('C:\\foo\\.'), '../file.js').toString(), 'file:///c%3A/file.js'); } else { assert.equal(joinPath(URI.file('/foo/bar'), '/file.js').toString(), 'file:///foo/bar/file.js'); assert.equal(joinPath(URI.file('/foo/bar'), 'file.js').toString(), 'file:///foo/bar/file.js'); @@ -123,8 +125,8 @@ suite('Resources', () => { assert.equal(normalizePath(URI.file('c:\\foo\\..\\bar')).toString(), 'file:///c%3A/bar'); assert.equal(normalizePath(URI.file('c:\\foo\\..\\..\\bar')).toString(), 'file:///c%3A/bar'); assert.equal(normalizePath(URI.file('c:\\foo\\foo\\..\\..\\bar')).toString(), 'file:///c%3A/bar'); - assert.equal(normalizePath(URI.file('c:\\foo\\foo\\.\\..\\..\\bar')).toString(), 'file:///c%3A/bar'); - assert.equal(normalizePath(URI.file('c:\\foo\\foo\\.\\..\\some\\..\\bar')).toString(), 'file:///c%3A/foo/bar'); + assert.equal(normalizePath(URI.file('C:\\foo\\foo\\.\\..\\..\\bar')).toString(), 'file:///c%3A/bar'); + assert.equal(normalizePath(URI.file('C:\\foo\\foo\\.\\..\\some\\..\\bar')).toString(), 'file:///c%3A/foo/bar'); } else { assert.equal(normalizePath(URI.file('/foo/./bar')).toString(), 'file:///foo/bar'); assert.equal(normalizePath(URI.file('/foo/.')).toString(), 'file:///foo'); @@ -150,6 +152,7 @@ suite('Resources', () => { test('isAbsolute', () => { if (isWindows) { assert.equal(isAbsolutePath(URI.file('c:\\foo\\')), true); + assert.equal(isAbsolutePath(URI.file('C:\\foo\\')), true); assert.equal(isAbsolutePath(URI.file('bar')), true); // URI normalizes all file URIs to be absolute } else { assert.equal(isAbsolutePath(URI.file('/foo/bar')), true); @@ -160,8 +163,8 @@ suite('Resources', () => { }); test('isEqual', () => { - let fileURI = URI.file('/foo/bar'); - let fileURI2 = URI.file('/foo/Bar'); + let fileURI = isWindows ? URI.file('c:\\foo\\bar') : URI.file('/foo/bar'); + let fileURI2 = isWindows ? URI.file('C:\\foo\\Bar') : URI.file('/foo/Bar'); assert.equal(isEqual(fileURI, fileURI, true), true); assert.equal(isEqual(fileURI, fileURI, false), true); assert.equal(isEqual(fileURI, fileURI, hasToIgnoreCase(fileURI)), true); @@ -176,7 +179,6 @@ suite('Resources', () => { assert.equal(isEqual(fileURI3, fileURI4, true), true); assert.equal(isEqual(fileURI3, fileURI4, false), false); - assert.equal(isEqual(fileURI, fileURI3, true), false); }); @@ -214,6 +216,7 @@ suite('Resources', () => { if (isWindows) { assertMalformedFileUri('c:/foo/bar', 'file:///c%3A/foo/bar'); assertMalformedFileUri('c:\\foo\\bar', 'file:///c%3A/foo/bar'); + assertMalformedFileUri('C:\\foo\\bar', 'file:///C%3A/foo/bar'); assertMalformedFileUri('\\\\localhost\\c$\\devel\\test', 'file://localhost/c%24/devel/test'); } assertMalformedFileUri('/foo/bar', 'file:///foo/bar'); From a2895be7e8ce948b27cfbed95fb46408e7e47520 Mon Sep 17 00:00:00 2001 From: Martin Aeschlimann Date: Wed, 15 Aug 2018 17:19:34 +0200 Subject: [PATCH 0830/1276] use resources.isEqualOrParent instead of path.indexOf --- .../workbench/parts/files/browser/editors/fileEditorTracker.ts | 2 +- .../parts/snippets/electron-browser/snippetsService.ts | 2 +- .../services/jsonschemas/common/jsonValidationExtensionPoint.ts | 2 +- src/vs/workbench/services/textMate/electron-browser/TMSyntax.ts | 2 +- .../services/themes/electron-browser/colorThemeStore.ts | 2 +- .../services/themes/electron-browser/fileIconThemeStore.ts | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/vs/workbench/parts/files/browser/editors/fileEditorTracker.ts b/src/vs/workbench/parts/files/browser/editors/fileEditorTracker.ts index 3ca77a2a912..e26679c5a69 100644 --- a/src/vs/workbench/parts/files/browser/editors/fileEditorTracker.ts +++ b/src/vs/workbench/parts/files/browser/editors/fileEditorTracker.ts @@ -148,7 +148,7 @@ export class FileEditorTracker extends Disposable implements IWorkbenchContribut // Do NOT close any opened editor that matches the resource path (either equal or being parent) of the // resource we move to (movedTo). Otherwise we would close a resource that has been renamed to the same // path but different casing. - if (movedTo && resources.isEqualOrParent(resource, movedTo, resources.hasToIgnoreCase(resource)) && resource.path.indexOf(movedTo.path) === 0) { + if (movedTo && resources.isEqualOrParent(resource, movedTo, resources.hasToIgnoreCase(resource))) { return; } diff --git a/src/vs/workbench/parts/snippets/electron-browser/snippetsService.ts b/src/vs/workbench/parts/snippets/electron-browser/snippetsService.ts index 6ec87c8ce50..abb914561cd 100644 --- a/src/vs/workbench/parts/snippets/electron-browser/snippetsService.ts +++ b/src/vs/workbench/parts/snippets/electron-browser/snippetsService.ts @@ -76,7 +76,7 @@ namespace schema { const extensionLocation = extension.description.extensionLocation; const snippetLocation = resources.joinPath(extensionLocation, snippet.path); - if (!resources.isEqualOrParent(snippetLocation, extensionLocation)) { + if (!resources.isEqualOrParent(snippetLocation, extensionLocation, resources.hasToIgnoreCase(snippetLocation))) { extension.collector.error(localize( 'invalid.path.1', "Expected `contributes.{0}.path` ({1}) to be included inside extension's folder ({2}). This might make the extension non-portable.", diff --git a/src/vs/workbench/services/jsonschemas/common/jsonValidationExtensionPoint.ts b/src/vs/workbench/services/jsonschemas/common/jsonValidationExtensionPoint.ts index d5ab87d54f7..150400ab5c0 100644 --- a/src/vs/workbench/services/jsonschemas/common/jsonValidationExtensionPoint.ts +++ b/src/vs/workbench/services/jsonschemas/common/jsonValidationExtensionPoint.ts @@ -60,7 +60,7 @@ export class JSONValidationExtensionPoint { if (strings.startsWith(uri, './')) { try { const colorThemeLocation = resources.joinPath(extensionLocation, uri); - if (colorThemeLocation.path.indexOf(extensionLocation.path) !== 0) { + if (!resources.isEqualOrParent(colorThemeLocation, extensionLocation, resources.hasToIgnoreCase(colorThemeLocation))) { collector.warn(nls.localize('invalid.path.1', "Expected `contributes.{0}.url` ({1}) to be included inside extension's folder ({2}). This might make the extension non-portable.", configurationExtPoint.name, location, extensionLocation.path)); } } catch (e) { diff --git a/src/vs/workbench/services/textMate/electron-browser/TMSyntax.ts b/src/vs/workbench/services/textMate/electron-browser/TMSyntax.ts index 5a8a60d7238..cb08ce01cea 100644 --- a/src/vs/workbench/services/textMate/electron-browser/TMSyntax.ts +++ b/src/vs/workbench/services/textMate/electron-browser/TMSyntax.ts @@ -313,7 +313,7 @@ export class TextMateService implements ITextMateService { } const grammarLocation = resources.joinPath(extensionLocation, syntax.path); - if (grammarLocation.path.indexOf(extensionLocation.path) !== 0) { + if (!resources.isEqualOrParent(grammarLocation, extensionLocation, resources.hasToIgnoreCase(grammarLocation))) { collector.warn(nls.localize('invalid.path.1', "Expected `contributes.{0}.path` ({1}) to be included inside extension's folder ({2}). This might make the extension non-portable.", grammarsExtPoint.name, grammarLocation.path, extensionLocation.path)); } diff --git a/src/vs/workbench/services/themes/electron-browser/colorThemeStore.ts b/src/vs/workbench/services/themes/electron-browser/colorThemeStore.ts index 7029c57018f..de23498235b 100644 --- a/src/vs/workbench/services/themes/electron-browser/colorThemeStore.ts +++ b/src/vs/workbench/services/themes/electron-browser/colorThemeStore.ts @@ -95,7 +95,7 @@ export class ColorThemeStore { } const colorThemeLocation = resources.joinPath(extensionLocation, theme.path); - if (colorThemeLocation.path.indexOf(extensionLocation.path) !== 0) { + if (!resources.isEqualOrParent(colorThemeLocation, extensionLocation, resources.hasToIgnoreCase(colorThemeLocation))) { collector.warn(nls.localize('invalid.path.1', "Expected `contributes.{0}.path` ({1}) to be included inside extension's folder ({2}). This might make the extension non-portable.", themesExtPoint.name, colorThemeLocation.path, extensionLocation.path)); } diff --git a/src/vs/workbench/services/themes/electron-browser/fileIconThemeStore.ts b/src/vs/workbench/services/themes/electron-browser/fileIconThemeStore.ts index 179ae3342b1..1cb58bb40f0 100644 --- a/src/vs/workbench/services/themes/electron-browser/fileIconThemeStore.ts +++ b/src/vs/workbench/services/themes/electron-browser/fileIconThemeStore.ts @@ -97,7 +97,7 @@ export class FileIconThemeStore { } const iconThemeLocation = resources.joinPath(extensionLocation, iconTheme.path); - if (iconThemeLocation.path.indexOf(extensionLocation.path) !== 0) { + if (!resources.isEqualOrParent(iconThemeLocation, extensionLocation, resources.hasToIgnoreCase(iconThemeLocation))) { collector.warn(nls.localize('invalid.path.1', "Expected `contributes.{0}.path` ({1}) to be included inside extension's folder ({2}). This might make the extension non-portable.", iconThemeExtPoint.name, iconThemeLocation.path, extensionLocation.path)); } From c818220dc575445bd87dc0bf3b04bb5430b763e7 Mon Sep 17 00:00:00 2001 From: Johannes Rieken Date: Wed, 15 Aug 2018 17:13:51 +0200 Subject: [PATCH 0831/1276] fix #56360 --- src/vs/base/browser/ui/breadcrumbs/breadcrumbsWidget.css | 1 + 1 file changed, 1 insertion(+) diff --git a/src/vs/base/browser/ui/breadcrumbs/breadcrumbsWidget.css b/src/vs/base/browser/ui/breadcrumbs/breadcrumbsWidget.css index da510856593..f546b7edc88 100644 --- a/src/vs/base/browser/ui/breadcrumbs/breadcrumbsWidget.css +++ b/src/vs/base/browser/ui/breadcrumbs/breadcrumbsWidget.css @@ -27,6 +27,7 @@ background-image: url(./collapsed.svg); opacity: .7; width: 16px; + min-width: 16px; height: 16px; display: inline-block; background-size: 16px; From acaa129821e1abe128b5398d3f8ae92933fb41ce Mon Sep 17 00:00:00 2001 From: Johannes Rieken Date: Wed, 15 Aug 2018 17:17:54 +0200 Subject: [PATCH 0832/1276] set item max-width to 80% to of breadcrumd with, #56318 --- .../workbench/browser/parts/editor/media/tabstitlecontrol.css | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vs/workbench/browser/parts/editor/media/tabstitlecontrol.css b/src/vs/workbench/browser/parts/editor/media/tabstitlecontrol.css index 74218a0d7a9..3ddf3029c20 100644 --- a/src/vs/workbench/browser/parts/editor/media/tabstitlecontrol.css +++ b/src/vs/workbench/browser/parts/editor/media/tabstitlecontrol.css @@ -268,7 +268,7 @@ } .monaco-workbench > .part.editor > .content .editor-group-container > .title .tabs-breadcrumbs .breadcrumbs-control .monaco-breadcrumb-item { - max-width: 260px; + max-width: 80%; } .monaco-workbench > .part.editor > .content .editor-group-container > .title .tabs-breadcrumbs .breadcrumbs-control .monaco-breadcrumb-item:last-child { From 595f105e2a5a4298ea8f81441c9194f3ef0af993 Mon Sep 17 00:00:00 2001 From: Johannes Rieken Date: Wed, 15 Aug 2018 17:26:41 +0200 Subject: [PATCH 0833/1276] better picker width #56318 --- 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 fb56b0b1fe9..5936369fb46 100644 --- a/src/vs/workbench/browser/parts/editor/breadcrumbsControl.ts +++ b/src/vs/workbench/browser/parts/editor/breadcrumbsControl.ts @@ -295,7 +295,7 @@ export class BreadcrumbsControl { getAnchor: () => { let pickerHeight = 330; - let pickerWidth = Math.max(this._dimension.width * 0.38, dom.getTotalWidth(event.node)); + let pickerWidth = Math.max(this._dimension.width / 2.59, dom.getTotalWidth(event.node)); let pickerArrowSize = 8; let pickerArrowOffset: number; From 4455946543b7b070066ca40eb5f9a387a2a8b0de Mon Sep 17 00:00:00 2001 From: isidor Date: Wed, 15 Aug 2018 17:31:51 +0200 Subject: [PATCH 0834/1276] debug: do not use promise.cancel #56137 --- .../debug/electron-browser/rawDebugSession.ts | 21 ++++++++++--------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/src/vs/workbench/parts/debug/electron-browser/rawDebugSession.ts b/src/vs/workbench/parts/debug/electron-browser/rawDebugSession.ts index 5e9785e36c8..93891ff0b4e 100644 --- a/src/vs/workbench/parts/debug/electron-browser/rawDebugSession.ts +++ b/src/vs/workbench/parts/debug/electron-browser/rawDebugSession.ts @@ -17,6 +17,7 @@ import { INotificationService } from 'vs/platform/notification/common/notificati import { formatPII } from 'vs/workbench/parts/debug/common/debugUtils'; import { SocketDebugAdapter } from 'vs/workbench/parts/debug/node/debugAdapter'; import { SessionState, DebugEvent, IRawSession, IDebugAdapter } from 'vs/workbench/parts/debug/common/debug'; +import { CancellationToken, CancellationTokenSource } from 'vs/base/common/cancellation'; export interface SessionExitedEvent extends DebugEvent { @@ -44,7 +45,7 @@ export class RawDebugSession implements IRawSession { private startTime: number; public disconnected: boolean; private terminated: boolean; - private sentPromises: TPromise[]; + private cancellationTokens: CancellationTokenSource[]; private _capabilities: DebugProtocol.Capabilities; private allThreadsContinued: boolean; private state: SessionState = SessionState.LAUNCH; @@ -75,7 +76,7 @@ export class RawDebugSession implements IRawSession { this.emittedStopped = false; this.readyForBreakpoints = false; this.allThreadsContinued = true; - this.sentPromises = []; + this.cancellationTokens = []; this._onDidInitialize = new Emitter(); this._onDidStop = new Emitter(); @@ -182,7 +183,8 @@ export class RawDebugSession implements IRawSession { private send(command: string, args: any, cancelOnDisconnect = true): TPromise { return this.initServer().then(() => { - const promise = this.internalSend(command, args).then(response => response, (errorResponse: DebugProtocol.ErrorResponse) => { + const cancellationSource = new CancellationTokenSource(); + const promise = this.internalSend(command, args, cancellationSource.token).then(response => response, (errorResponse: DebugProtocol.ErrorResponse) => { const error = errorResponse && errorResponse.body ? errorResponse.body.error : null; const errorMessage = errorResponse ? errorResponse.message : ''; const telemetryMessage = error ? formatPII(error.format, true, error.variables) : errorMessage; @@ -217,16 +219,15 @@ export class RawDebugSession implements IRawSession { }); if (cancelOnDisconnect) { - this.sentPromises.push(promise); + this.cancellationTokens.push(cancellationSource); } return promise; }); } - private internalSend(command: string, args: any): TPromise { - let errorCallback: (error: Error) => void; + private internalSend(command: string, args: any, cancelationToken: CancellationToken): TPromise { return new TPromise((completeDispatch, errorDispatch) => { - errorCallback = errorDispatch; + cancelationToken.onCancellationRequested(() => errorDispatch(errors.canceled())); this.debugAdapter.sendRequest(command, args, (result: R) => { if (result.success) { completeDispatch(result); @@ -234,7 +235,7 @@ export class RawDebugSession implements IRawSession { errorDispatch(result); } }); - }, () => errorCallback(errors.canceled())); + }); } private onDapEvent(event: DebugEvent): void { @@ -495,8 +496,8 @@ export class RawDebugSession implements IRawSession { // Cancel all sent promises on disconnect so debug trees are not left in a broken state #3666. // Give a 1s timeout to give a chance for some promises to complete. setTimeout(() => { - this.sentPromises.forEach(p => p && p.cancel()); - this.sentPromises = []; + this.cancellationTokens.forEach(token => token.cancel()); + this.cancellationTokens = []; }, 1000); if (this.debugAdapter && !this.disconnected) { From 9293ce9f643eb160614314ddb7d53fd7dfc3eaa4 Mon Sep 17 00:00:00 2001 From: Martin Aeschlimann Date: Wed, 15 Aug 2018 17:41:08 +0200 Subject: [PATCH 0835/1276] fix resources tests on windows (for #56403) --- src/vs/base/common/resources.ts | 7 +++++++ src/vs/base/test/common/resources.test.ts | 4 ++-- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/src/vs/base/common/resources.ts b/src/vs/base/common/resources.ts index 365c144c132..53357fe29f5 100644 --- a/src/vs/base/common/resources.ts +++ b/src/vs/base/common/resources.ts @@ -129,6 +129,13 @@ function fsPath(uri: URI): string { if (uri.authority && uri.path.length > 1 && uri.scheme === 'file') { // unc path: file://shares/c$/far/boo value = `//${uri.authority}${uri.path}`; + } else if ( + isWindows + && uri.path.charCodeAt(0) === CharCode.Slash + && (uri.path.charCodeAt(1) >= CharCode.A && uri.path.charCodeAt(1) <= CharCode.Z || uri.path.charCodeAt(1) >= CharCode.a && uri.path.charCodeAt(1) <= CharCode.z) + && uri.path.charCodeAt(2) === CharCode.Colon + ) { + value = uri.path.substr(1); } else { // other path value = uri.path; diff --git a/src/vs/base/test/common/resources.test.ts b/src/vs/base/test/common/resources.test.ts index 0a065279901..d8e29039546 100644 --- a/src/vs/base/test/common/resources.test.ts +++ b/src/vs/base/test/common/resources.test.ts @@ -48,7 +48,7 @@ suite('Resources', () => { assert.equal(dirname(URI.file('c:\\some\\file')).toString(), 'file:///c%3A/some'); assert.equal(dirname(URI.file('c:\\some\\file\\')).toString(), 'file:///c%3A/some'); assert.equal(dirname(URI.file('c:\\some')).toString(), 'file:///c%3A/'); - assert.equal(dirname(URI.file('C:\\some')).toString(), 'file:///C%3A/'); + assert.equal(dirname(URI.file('C:\\some')).toString(), 'file:///c%3A/'); } else { assert.equal(dirname(URI.file('/some/file/test.txt')).toString(), 'file:///some/file'); assert.equal(dirname(URI.file('/some/file/')).toString(), 'file:///some'); @@ -216,7 +216,7 @@ suite('Resources', () => { if (isWindows) { assertMalformedFileUri('c:/foo/bar', 'file:///c%3A/foo/bar'); assertMalformedFileUri('c:\\foo\\bar', 'file:///c%3A/foo/bar'); - assertMalformedFileUri('C:\\foo\\bar', 'file:///C%3A/foo/bar'); + assertMalformedFileUri('C:\\foo\\bar', 'file:///c%3A/foo/bar'); assertMalformedFileUri('\\\\localhost\\c$\\devel\\test', 'file://localhost/c%24/devel/test'); } assertMalformedFileUri('/foo/bar', 'file:///foo/bar'); From 6d3ac521b98bf3b8971a8545755d17c751dec581 Mon Sep 17 00:00:00 2001 From: isidor Date: Wed, 15 Aug 2018 17:48:54 +0200 Subject: [PATCH 0836/1276] IUriDisplayService -> IUriLabelService fixes #55886 --- src/vs/code/electron-main/app.ts | 8 ++--- src/vs/code/electron-main/main.ts | 6 ++-- src/vs/code/electron-main/menubar.ts | 10 +++---- src/vs/code/electron-main/menus.ts | 12 ++++---- .../referenceSearch/referencesWidget.ts | 14 ++++----- .../standalone/browser/simpleServices.ts | 10 +++---- .../standalone/browser/standaloneServices.ts | 6 ++-- .../electron-main/historyMainService.ts | 8 ++--- .../common/uriLabel.ts} | 24 +++++++-------- .../uriLabel.contribution.ts} | 12 ++++---- .../test/uriLabel.test.ts} | 20 ++++++------- .../platform/workspaces/common/workspaces.ts | 10 +++---- .../electron-browser/mainThreadFileSystem.ts | 8 ++--- src/vs/workbench/api/node/extHost.protocol.ts | 4 +-- .../workbench/api/node/extHostFileSystem.ts | 4 +-- .../browser/actions/workspaceCommands.ts | 6 ++-- src/vs/workbench/browser/labels.ts | 12 ++++---- .../parts/quickopen/quickOpenController.ts | 6 ++-- .../browser/parts/titlebar/menubarControl.ts | 10 +++---- .../browser/parts/titlebar/titlebarPart.ts | 8 ++--- .../common/editor/untitledEditorInput.ts | 14 ++++----- src/vs/workbench/electron-browser/actions.ts | 30 +++++++++---------- .../workbench/electron-browser/workbench.ts | 8 ++--- .../parts/debug/browser/breakpointsView.ts | 6 ++-- .../debug/electron-browser/callStackView.ts | 6 ++-- .../debug/electron-browser/replViewer.ts | 6 ++-- .../files/common/editors/fileEditorInput.ts | 14 ++++----- .../electron-browser/files.contribution.ts | 10 +++---- .../electron-browser/localizationsActions.ts | 6 ++-- .../electron-browser/markersTreeViewer.ts | 12 ++++---- .../parts/search/browser/openFileHandler.ts | 6 ++-- .../parts/search/browser/openSymbolHandler.ts | 6 ++-- .../parts/search/browser/searchResultsView.ts | 6 ++-- .../page/electron-browser/welcomePage.ts | 10 +++---- .../electron-browser/bulkEditService.ts | 10 +++---- .../node/configurationService.ts | 14 ++++----- .../services/editor/browser/editorService.ts | 10 +++---- .../preferences/browser/preferencesService.ts | 6 ++-- .../api/mainThreadEditors.test.ts | 4 +-- .../workbench/test/workbenchTestServices.ts | 4 +-- src/vs/workbench/workbench.main.ts | 2 +- 41 files changed, 194 insertions(+), 194 deletions(-) rename src/vs/platform/{uriDisplay/common/uriDisplay.ts => uriLabel/common/uriLabel.ts} (84%) rename src/vs/platform/{uriDisplay/electron-browser/uriDisplay.contribution.ts => uriLabel/electron-browser/uriLabel.contribution.ts} (67%) rename src/vs/platform/{uriDisplay/test/uriDisplay.test.ts => uriLabel/test/uriLabel.test.ts} (62%) diff --git a/src/vs/code/electron-main/app.ts b/src/vs/code/electron-main/app.ts index be65769bfce..c0185b039e9 100644 --- a/src/vs/code/electron-main/app.ts +++ b/src/vs/code/electron-main/app.ts @@ -63,7 +63,7 @@ import { serve as serveDriver } from 'vs/platform/driver/electron-main/driver'; import { IMenubarService } from 'vs/platform/menubar/common/menubar'; import { MenubarService } from 'vs/platform/menubar/electron-main/menubarService'; import { MenubarChannel } from 'vs/platform/menubar/common/menubarIpc'; -import { IUriDisplayService } from 'vs/platform/uriDisplay/common/uriDisplay'; +import { IUriLabelService } from 'vs/platform/uriLabel/common/uriLabel'; import { CodeMenu } from 'vs/code/electron-main/menus'; import { hasArgs } from 'vs/platform/environment/node/argv'; import { RunOnceScheduler } from 'vs/base/common/async'; @@ -90,7 +90,7 @@ export class CodeApplication { @IConfigurationService private configurationService: ConfigurationService, @IStateService private stateService: IStateService, @IHistoryMainService private historyMainService: IHistoryMainService, - @IUriDisplayService private uriDisplayService: IUriDisplayService + @IUriLabelService private uriLabelService: IUriLabelService ) { this.toDispose = [mainIpcServer, configurationService]; @@ -225,8 +225,8 @@ export class CodeApplication { } }); - ipc.on('vscode:uriDisplayRegisterFormater', (event: any, { scheme, formater }) => { - this.uriDisplayService.registerFormater(scheme, formater); + ipc.on('vscode:uriLabelRegisterFormater', (event: any, { scheme, formater }) => { + this.uriLabelService.registerFormater(scheme, formater); }); // Keyboard layout changes diff --git a/src/vs/code/electron-main/main.ts b/src/vs/code/electron-main/main.ts index 060c2459c5f..dbe95eb11e2 100644 --- a/src/vs/code/electron-main/main.ts +++ b/src/vs/code/electron-main/main.ts @@ -50,7 +50,7 @@ import { uploadLogs } from 'vs/code/electron-main/logUploader'; import { setUnexpectedErrorHandler } from 'vs/base/common/errors'; import { IDialogService } from 'vs/platform/dialogs/common/dialogs'; import { CommandLineDialogService } from 'vs/platform/dialogs/node/dialogService'; -import { IUriDisplayService, UriDisplayService } from 'vs/platform/uriDisplay/common/uriDisplay'; +import { IUriLabelService, UriLabelService } from 'vs/platform/uriLabel/common/uriLabel'; function createServices(args: ParsedArgs, bufferLogService: BufferLogService): IInstantiationService { const services = new ServiceCollection(); @@ -58,7 +58,7 @@ function createServices(args: ParsedArgs, bufferLogService: BufferLogService): I const environmentService = new EnvironmentService(args, process.execPath); const consoleLogService = new ConsoleLogMainService(getLogLevel(environmentService)); const logService = new MultiplexLogService([consoleLogService, bufferLogService]); - const uriDisplayService = new UriDisplayService(environmentService, undefined); + const uriLabelService = new UriLabelService(environmentService, undefined); process.once('exit', () => logService.dispose()); @@ -66,7 +66,7 @@ function createServices(args: ParsedArgs, bufferLogService: BufferLogService): I setTimeout(() => cleanupOlderLogs(environmentService).then(null, err => console.error(err)), 10000); services.set(IEnvironmentService, environmentService); - services.set(IUriDisplayService, uriDisplayService); + services.set(IUriLabelService, uriLabelService); services.set(ILogService, logService); services.set(IWorkspacesMainService, new SyncDescriptor(WorkspacesMainService)); services.set(IHistoryMainService, new SyncDescriptor(HistoryMainService)); diff --git a/src/vs/code/electron-main/menubar.ts b/src/vs/code/electron-main/menubar.ts index 7f2a3082e0c..1bbfd9834bb 100644 --- a/src/vs/code/electron-main/menubar.ts +++ b/src/vs/code/electron-main/menubar.ts @@ -22,7 +22,7 @@ import { IHistoryMainService } from 'vs/platform/history/common/history'; import { IWorkspaceIdentifier, getWorkspaceLabel, ISingleFolderWorkspaceIdentifier, isSingleFolderWorkspaceIdentifier, isWorkspaceIdentifier } from 'vs/platform/workspaces/common/workspaces'; import { IMenubarData, IMenubarKeybinding, MenubarMenuItem, isMenubarMenuItemSeparator, isMenubarMenuItemSubmenu, isMenubarMenuItemAction } from 'vs/platform/menubar/common/menubar'; import URI from 'vs/base/common/uri'; -import { IUriDisplayService } from 'vs/platform/uriDisplay/common/uriDisplay'; +import { IUriLabelService } from 'vs/platform/uriLabel/common/uriLabel'; const telemetryFrom = 'menu'; @@ -49,7 +49,7 @@ export class Menubar { @IEnvironmentService private environmentService: IEnvironmentService, @ITelemetryService private telemetryService: ITelemetryService, @IHistoryMainService private historyMainService: IHistoryMainService, - @IUriDisplayService private uriDisplayService: IUriDisplayService + @IUriLabelService private uriLabelService: IUriLabelService ) { this.menuUpdater = new RunOnceScheduler(() => this.doUpdateMenu(), 0); @@ -563,13 +563,13 @@ export class Menubar { let label: string; let uri: URI; if (isSingleFolderWorkspaceIdentifier(workspaceOrFile) && !isFile) { - label = unmnemonicLabel(getWorkspaceLabel(workspaceOrFile, this.environmentService, this.uriDisplayService, { verbose: true })); + label = unmnemonicLabel(getWorkspaceLabel(workspaceOrFile, this.environmentService, this.uriLabelService, { verbose: true })); uri = workspaceOrFile; } else if (isWorkspaceIdentifier(workspaceOrFile)) { - label = getWorkspaceLabel(workspaceOrFile, this.environmentService, this.uriDisplayService, { verbose: true }); + label = getWorkspaceLabel(workspaceOrFile, this.environmentService, this.uriLabelService, { verbose: true }); uri = URI.file(workspaceOrFile.configPath); } else { - label = unmnemonicLabel(this.uriDisplayService.getLabel(workspaceOrFile)); + label = unmnemonicLabel(this.uriLabelService.getLabel(workspaceOrFile)); uri = workspaceOrFile; } diff --git a/src/vs/code/electron-main/menus.ts b/src/vs/code/electron-main/menus.ts index 916bd309bcc..9d5657cff26 100644 --- a/src/vs/code/electron-main/menus.ts +++ b/src/vs/code/electron-main/menus.ts @@ -24,7 +24,7 @@ import { IWindowsMainService, IWindowsCountChangedEvent } from 'vs/platform/wind import { IHistoryMainService } from 'vs/platform/history/common/history'; import { IWorkspaceIdentifier, getWorkspaceLabel, ISingleFolderWorkspaceIdentifier, isSingleFolderWorkspaceIdentifier, isWorkspaceIdentifier } from 'vs/platform/workspaces/common/workspaces'; import URI from 'vs/base/common/uri'; -import { IUriDisplayService } from 'vs/platform/uriDisplay/common/uriDisplay'; +import { IUriLabelService } from 'vs/platform/uriLabel/common/uriLabel'; interface IMenuItemClickHandler { inDevTools: (contents: Electron.WebContents) => void; @@ -68,7 +68,7 @@ export class CodeMenu { @IEnvironmentService private environmentService: IEnvironmentService, @ITelemetryService private telemetryService: ITelemetryService, @IHistoryMainService private historyMainService: IHistoryMainService, - @IUriDisplayService private uriDisplayService: IUriDisplayService + @IUriLabelService private uriLabelService: IUriLabelService ) { this.nativeTabMenuItems = []; @@ -496,14 +496,14 @@ export class CodeMenu { let label: string; let uri: URI; if (isSingleFolderWorkspaceIdentifier(workspace)) { - label = unmnemonicLabel(getWorkspaceLabel(workspace, this.environmentService, this.uriDisplayService, { verbose: true })); + label = unmnemonicLabel(getWorkspaceLabel(workspace, this.environmentService, this.uriLabelService, { verbose: true })); uri = workspace; } else if (isWorkspaceIdentifier(workspace)) { - label = getWorkspaceLabel(workspace, this.environmentService, this.uriDisplayService, { verbose: true }); + label = getWorkspaceLabel(workspace, this.environmentService, this.uriLabelService, { verbose: true }); uri = URI.file(workspace.configPath); } else { uri = URI.file(workspace); - label = unmnemonicLabel(this.uriDisplayService.getLabel(uri)); + label = unmnemonicLabel(this.uriLabelService.getLabel(uri)); } return new MenuItem(this.likeAction(commandId, { @@ -1319,4 +1319,4 @@ export class CodeMenu { function __separator__(): Electron.MenuItem { return new MenuItem({ type: 'separator' }); -} \ No newline at end of file +} diff --git a/src/vs/editor/contrib/referenceSearch/referencesWidget.ts b/src/vs/editor/contrib/referenceSearch/referencesWidget.ts index 45fd356d9d9..da6bf29eb68 100644 --- a/src/vs/editor/contrib/referenceSearch/referencesWidget.ts +++ b/src/vs/editor/contrib/referenceSearch/referencesWidget.ts @@ -40,7 +40,7 @@ import { WorkbenchTree, WorkbenchTreeController } from 'vs/platform/list/browser import { RawContextKey } from 'vs/platform/contextkey/common/contextkey'; import { Location } from 'vs/editor/common/modes'; import { ClickBehavior } from 'vs/base/parts/tree/browser/treeDefaults'; -import { IUriDisplayService } from 'vs/platform/uriDisplay/common/uriDisplay'; +import { IUriLabelService } from 'vs/platform/uriLabel/common/uriLabel'; import { dirname, basenameOrAuthority } from 'vs/base/common/resources'; import { getBaseLabel } from 'vs/base/common/labels'; @@ -300,7 +300,7 @@ class FileReferencesTemplate { constructor( container: HTMLElement, - @IUriDisplayService private readonly _uriDisplay: IUriDisplayService, + @IUriLabelService private readonly _uriLabel: IUriLabelService, @IThemeService themeService: IThemeService, ) { const parent = document.createElement('div'); @@ -319,7 +319,7 @@ class FileReferencesTemplate { set(element: FileReferences) { let parent = dirname(element.uri); - this.file.setValue(getBaseLabel(element.uri), parent ? this._uriDisplay.getLabel(parent, true) : undefined, { title: this._uriDisplay.getLabel(element.uri) }); + this.file.setValue(getBaseLabel(element.uri), parent ? this._uriLabel.getLabel(parent, true) : undefined, { title: this._uriLabel.getLabel(element.uri) }); const len = element.children.length; this.badge.setCount(len); if (element.failure) { @@ -368,7 +368,7 @@ class Renderer implements tree.IRenderer { constructor( @IThemeService private readonly _themeService: IThemeService, - @IUriDisplayService private readonly _uriDisplay: IUriDisplayService, + @IUriLabelService private readonly _uriLabel: IUriLabelService, ) { // } @@ -388,7 +388,7 @@ class Renderer implements tree.IRenderer { renderTemplate(tree: tree.ITree, templateId: string, container: HTMLElement) { if (templateId === Renderer._ids.FileReferences) { - return new FileReferencesTemplate(container, this._uriDisplay, this._themeService); + return new FileReferencesTemplate(container, this._uriLabel, this._themeService); } else if (templateId === Renderer._ids.OneReference) { return new OneReferenceTemplate(container); } @@ -532,7 +532,7 @@ export class ReferenceWidget extends PeekViewWidget { @IThemeService themeService: IThemeService, @ITextModelService private _textModelResolverService: ITextModelService, @IInstantiationService private _instantiationService: IInstantiationService, - @IUriDisplayService private _uriDisplay: IUriDisplayService + @IUriLabelService private _uriLabel: IUriLabelService ) { super(editor, { showFrame: false, showArrow: true, isResizeable: true, isAccessible: true }); @@ -778,7 +778,7 @@ export class ReferenceWidget extends PeekViewWidget { // Update widget header if (reference.uri.scheme !== Schemas.inMemory) { - this.setTitle(basenameOrAuthority(reference.uri), this._uriDisplay.getLabel(dirname(reference.uri), false)); + this.setTitle(basenameOrAuthority(reference.uri), this._uriLabel.getLabel(dirname(reference.uri), false)); } else { this.setTitle(nls.localize('peekView.alternateTitle', "References")); } diff --git a/src/vs/editor/standalone/browser/simpleServices.ts b/src/vs/editor/standalone/browser/simpleServices.ts index b3d9dbf7f14..231c2e182c3 100644 --- a/src/vs/editor/standalone/browser/simpleServices.ts +++ b/src/vs/editor/standalone/browser/simpleServices.ts @@ -45,7 +45,7 @@ import { WorkspaceEdit, isResourceTextEdit, TextEdit } from 'vs/editor/common/mo import { IModelService } from 'vs/editor/common/services/modelService'; import { EditOperation } from 'vs/editor/common/core/editOperation'; import { localize } from 'vs/nls'; -import { IUriDisplayService, UriDisplayRules } from 'vs/platform/uriDisplay/common/uriDisplay'; +import { IUriLabelService, UriLabelRules } from 'vs/platform/uriLabel/common/uriLabel'; export class SimpleModel implements ITextEditorModel { @@ -592,11 +592,11 @@ export class SimpleBulkEditService implements IBulkEditService { } } -export class SimpleUriDisplayService implements IUriDisplayService { +export class SimpleUriLabelService implements IUriLabelService { _serviceBrand: any; - private readonly _onDidRegisterFormater: Emitter<{ scheme: string, formater: UriDisplayRules }> = new Emitter<{ scheme: string, formater: UriDisplayRules }>(); - public readonly onDidRegisterFormater: Event<{ scheme: string, formater: UriDisplayRules }> = this._onDidRegisterFormater.event; + private readonly _onDidRegisterFormater: Emitter<{ scheme: string, formater: UriLabelRules }> = new Emitter<{ scheme: string, formater: UriLabelRules }>(); + public readonly onDidRegisterFormater: Event<{ scheme: string, formater: UriLabelRules }> = this._onDidRegisterFormater.event; public getLabel(resource: URI, relative?: boolean): string { if (resource.scheme === 'file') { @@ -605,7 +605,7 @@ export class SimpleUriDisplayService implements IUriDisplayService { return resource.path; } - public registerFormater(schema: string, formater: UriDisplayRules): IDisposable { + public registerFormater(schema: string, formater: UriLabelRules): IDisposable { throw new Error('Not implemented'); } } diff --git a/src/vs/editor/standalone/browser/standaloneServices.ts b/src/vs/editor/standalone/browser/standaloneServices.ts index 49375edbcff..d20dc25b60e 100644 --- a/src/vs/editor/standalone/browser/standaloneServices.ts +++ b/src/vs/editor/standalone/browser/standaloneServices.ts @@ -33,7 +33,7 @@ import { StandaloneCodeEditorServiceImpl } from 'vs/editor/standalone/browser/st import { SimpleConfigurationService, SimpleResourceConfigurationService, SimpleMenuService, SimpleProgressService, StandaloneCommandService, StandaloneKeybindingService, SimpleNotificationService, - StandaloneTelemetryService, SimpleWorkspaceContextService, SimpleDialogService, SimpleBulkEditService, SimpleUriDisplayService + StandaloneTelemetryService, SimpleWorkspaceContextService, SimpleDialogService, SimpleBulkEditService, SimpleUriLabelService } from 'vs/editor/standalone/browser/simpleServices'; import { ContextKeyService } from 'vs/platform/contextkey/browser/contextKeyService'; import { IMenuService } from 'vs/platform/actions/common/actions'; @@ -44,7 +44,7 @@ import { INotificationService } from 'vs/platform/notification/common/notificati import { IDialogService } from 'vs/platform/dialogs/common/dialogs'; import { IListService, ListService } from 'vs/platform/list/browser/listService'; import { IBulkEditService } from 'vs/editor/browser/services/bulkEditService'; -import { IUriDisplayService } from 'vs/platform/uriDisplay/common/uriDisplay'; +import { IUriLabelService } from 'vs/platform/uriLabel/common/uriLabel'; export interface IEditorOverrideServices { [index: string]: any; @@ -122,7 +122,7 @@ export module StaticServices { export const contextService = define(IWorkspaceContextService, () => new SimpleWorkspaceContextService()); - export const uriDisplayService = define(IUriDisplayService, () => new SimpleUriDisplayService()); + export const uriLabelService = define(IUriLabelService, () => new SimpleUriLabelService()); export const telemetryService = define(ITelemetryService, () => new StandaloneTelemetryService()); diff --git a/src/vs/platform/history/electron-main/historyMainService.ts b/src/vs/platform/history/electron-main/historyMainService.ts index 0308dfe3063..3f2657d3851 100644 --- a/src/vs/platform/history/electron-main/historyMainService.ts +++ b/src/vs/platform/history/electron-main/historyMainService.ts @@ -22,7 +22,7 @@ import { RunOnceScheduler } from 'vs/base/common/async'; import { getComparisonKey, isEqual as areResourcesEqual, hasToIgnoreCase, dirname } from 'vs/base/common/resources'; import URI, { UriComponents } from 'vs/base/common/uri'; import { Schemas } from 'vs/base/common/network'; -import { IUriDisplayService } from 'vs/platform/uriDisplay/common/uriDisplay'; +import { IUriLabelService } from 'vs/platform/uriLabel/common/uriLabel'; interface ISerializedRecentlyOpened { workspaces2: (IWorkspaceIdentifier | string)[]; // IWorkspaceIdentifier or URI.toString() @@ -53,7 +53,7 @@ export class HistoryMainService implements IHistoryMainService { @ILogService private logService: ILogService, @IWorkspacesMainService private workspacesMainService: IWorkspacesMainService, @IEnvironmentService private environmentService: IEnvironmentService, - @IUriDisplayService private uriDisplayService: IUriDisplayService + @IUriLabelService private uriLabelService: IUriLabelService ) { this.macOSRecentDocumentsUpdater = new RunOnceScheduler(() => this.updateMacOSRecentDocuments(), 800); @@ -368,11 +368,11 @@ export class HistoryMainService implements IHistoryMainService { type: 'custom', name: nls.localize('recentFolders', "Recent Workspaces"), items: this.getRecentlyOpened().workspaces.slice(0, 7 /* limit number of entries here */).map(workspace => { - const title = getWorkspaceLabel(workspace, this.environmentService, this.uriDisplayService); + const title = getWorkspaceLabel(workspace, this.environmentService, this.uriLabelService); let description; let args; if (isSingleFolderWorkspaceIdentifier(workspace)) { - description = nls.localize('folderDesc', "{0} {1}", getBaseLabel(workspace), this.uriDisplayService.getLabel(dirname(workspace))); + description = nls.localize('folderDesc', "{0} {1}", getBaseLabel(workspace), this.uriLabelService.getLabel(dirname(workspace))); args = `--folder-uri "${workspace.toString()}"`; } else { description = nls.localize('codeWorkspace', "Code Workspace"); diff --git a/src/vs/platform/uriDisplay/common/uriDisplay.ts b/src/vs/platform/uriLabel/common/uriLabel.ts similarity index 84% rename from src/vs/platform/uriDisplay/common/uriDisplay.ts rename to src/vs/platform/uriLabel/common/uriLabel.ts index cd53cee444f..f8c3a424a67 100644 --- a/src/vs/platform/uriDisplay/common/uriDisplay.ts +++ b/src/vs/platform/uriLabel/common/uriLabel.ts @@ -14,21 +14,21 @@ import { isLinux, isWindows } from 'vs/base/common/platform'; import { tildify, getPathLabel } from 'vs/base/common/labels'; import { ltrim } from 'vs/base/common/strings'; -export interface IUriDisplayService { +export interface IUriLabelService { _serviceBrand: any; getLabel(resource: URI, relative?: boolean): string; - registerFormater(schema: string, formater: UriDisplayRules): IDisposable; - onDidRegisterFormater: Event<{ scheme: string, formater: UriDisplayRules }>; + registerFormater(schema: string, formater: UriLabelRules): IDisposable; + onDidRegisterFormater: Event<{ scheme: string, formater: UriLabelRules }>; } -export interface UriDisplayRules { +export interface UriLabelRules { label: string; // myLabel:/${path} separator: '/' | '\\' | ''; tildify?: boolean; normalizeDriveLetter?: boolean; } -const URI_DISPLAY_SERVICE_ID = 'uriDisplay'; +const URI_LABEL_SERVICE_ID = 'uriLabel'; const sepRegexp = /\//g; const labelMatchingRegexp = /\$\{scheme\}|\$\{authority\}|\$\{path\}/g; @@ -36,11 +36,11 @@ function hasDriveLetter(path: string): boolean { return isWindows && path && path[2] === ':'; } -export class UriDisplayService implements IUriDisplayService { +export class UriLabelService implements IUriLabelService { _serviceBrand: any; - private readonly formaters = new Map(); - private readonly _onDidRegisterFormater = new Emitter<{ scheme: string, formater: UriDisplayRules }>(); + private readonly formaters = new Map(); + private readonly _onDidRegisterFormater = new Emitter<{ scheme: string, formater: UriLabelRules }>(); constructor( @IEnvironmentService private environmentService: IEnvironmentService, @@ -48,7 +48,7 @@ export class UriDisplayService implements IUriDisplayService { ) { } - get onDidRegisterFormater(): Event<{ scheme: string, formater: UriDisplayRules }> { + get onDidRegisterFormater(): Event<{ scheme: string, formater: UriLabelRules }> { return this._onDidRegisterFormater.event; } @@ -85,7 +85,7 @@ export class UriDisplayService implements IUriDisplayService { return this.formatUri(resource, formater); } - registerFormater(scheme: string, formater: UriDisplayRules): IDisposable { + registerFormater(scheme: string, formater: UriLabelRules): IDisposable { this.formaters.set(scheme, formater); this._onDidRegisterFormater.fire({ scheme, formater }); @@ -94,7 +94,7 @@ export class UriDisplayService implements IUriDisplayService { }; } - private formatUri(resource: URI, formater: UriDisplayRules): string { + private formatUri(resource: URI, formater: UriLabelRules): string { let label = formater.label.replace(labelMatchingRegexp, match => { switch (match) { case '${scheme}': return resource.scheme; @@ -117,4 +117,4 @@ export class UriDisplayService implements IUriDisplayService { } } -export const IUriDisplayService = createDecorator(URI_DISPLAY_SERVICE_ID); +export const IUriLabelService = createDecorator(URI_LABEL_SERVICE_ID); diff --git a/src/vs/platform/uriDisplay/electron-browser/uriDisplay.contribution.ts b/src/vs/platform/uriLabel/electron-browser/uriLabel.contribution.ts similarity index 67% rename from src/vs/platform/uriDisplay/electron-browser/uriDisplay.contribution.ts rename to src/vs/platform/uriLabel/electron-browser/uriLabel.contribution.ts index 9637712a2ec..bbd24220002 100644 --- a/src/vs/platform/uriDisplay/electron-browser/uriDisplay.contribution.ts +++ b/src/vs/platform/uriLabel/electron-browser/uriLabel.contribution.ts @@ -4,7 +4,7 @@ *--------------------------------------------------------------------------------------------*/ import { IWorkbenchContribution, IWorkbenchContributionsRegistry, Extensions as WorkbenchExtensions } from 'vs/workbench/common/contributions'; -import { IUriDisplayService } from 'vs/platform/uriDisplay/common/uriDisplay'; +import { IUriLabelService } from 'vs/platform/uriLabel/common/uriLabel'; import { ipcRenderer as ipc } from 'electron'; import { Registry } from 'vs/platform/registry/common/platform'; import { LifecyclePhase } from 'vs/platform/lifecycle/common/lifecycle'; @@ -13,13 +13,13 @@ import { LifecyclePhase } from 'vs/platform/lifecycle/common/lifecycle'; * Uri display registration needs to be shared from renderer to main. * Since there will be another instance of the uri display service running on main. */ -class UriDisplayRegistrationContribution implements IWorkbenchContribution { +class UriLabelRegistrationContribution implements IWorkbenchContribution { - constructor(@IUriDisplayService uriDisplayService: IUriDisplayService) { - uriDisplayService.onDidRegisterFormater(data => { - ipc.send('vscode:uriDisplayRegisterFormater', data); + constructor(@IUriLabelService uriLabelService: IUriLabelService) { + uriLabelService.onDidRegisterFormater(data => { + ipc.send('vscode:uriLabelRegisterFormater', data); }); } } -Registry.as(WorkbenchExtensions.Workbench).registerWorkbenchContribution(UriDisplayRegistrationContribution, LifecyclePhase.Starting); +Registry.as(WorkbenchExtensions.Workbench).registerWorkbenchContribution(UriLabelRegistrationContribution, LifecyclePhase.Starting); diff --git a/src/vs/platform/uriDisplay/test/uriDisplay.test.ts b/src/vs/platform/uriLabel/test/uriLabel.test.ts similarity index 62% rename from src/vs/platform/uriDisplay/test/uriDisplay.test.ts rename to src/vs/platform/uriLabel/test/uriLabel.test.ts index a54cc2318b4..8b36579e453 100644 --- a/src/vs/platform/uriDisplay/test/uriDisplay.test.ts +++ b/src/vs/platform/uriLabel/test/uriLabel.test.ts @@ -4,7 +4,7 @@ *--------------------------------------------------------------------------------------------*/ import * as assert from 'assert'; -import { IUriDisplayService, UriDisplayService } from 'vs/platform/uriDisplay/common/uriDisplay'; +import { IUriLabelService, UriLabelService } from 'vs/platform/uriLabel/common/uriLabel'; import { TestEnvironmentService, TestContextService } from 'vs/workbench/test/workbenchTestServices'; import { Schemas } from 'vs/base/common/network'; import { TestWorkspace } from 'vs/platform/workspace/test/common/testWorkspace'; @@ -12,16 +12,16 @@ import URI from 'vs/base/common/uri'; import { nativeSep } from 'vs/base/common/paths'; import { isWindows } from 'vs/base/common/platform'; -suite('URI Display', () => { +suite('URI Label', () => { - let uriDisplayService: IUriDisplayService; + let uriLabelService: IUriLabelService; setup(() => { - uriDisplayService = new UriDisplayService(TestEnvironmentService, new TestContextService()); + uriLabelService = new UriLabelService(TestEnvironmentService, new TestContextService()); }); test('file scheme', function () { - uriDisplayService.registerFormater(Schemas.file, { + uriLabelService.registerFormater(Schemas.file, { label: '${path}', separator: nativeSep, tildify: !isWindows, @@ -29,15 +29,15 @@ suite('URI Display', () => { }); const uri1 = TestWorkspace.folders[0].uri.with({ path: TestWorkspace.folders[0].uri.path.concat('/a/b/c/d') }); - assert.equal(uriDisplayService.getLabel(uri1, true), isWindows ? 'a\\b\\c\\d' : 'a/b/c/d'); - assert.equal(uriDisplayService.getLabel(uri1, false), isWindows ? 'C:\\testWorkspace\\a\\b\\c\\d' : '/testWorkspace/a/b/c/d'); + assert.equal(uriLabelService.getLabel(uri1, true), isWindows ? 'a\\b\\c\\d' : 'a/b/c/d'); + assert.equal(uriLabelService.getLabel(uri1, false), isWindows ? 'C:\\testWorkspace\\a\\b\\c\\d' : '/testWorkspace/a/b/c/d'); const uri2 = URI.file('c:\\1/2/3'); - assert.equal(uriDisplayService.getLabel(uri2, false), isWindows ? 'C:\\1\\2\\3' : '/c:\\1/2/3'); + assert.equal(uriLabelService.getLabel(uri2, false), isWindows ? 'C:\\1\\2\\3' : '/c:\\1/2/3'); }); test('custom scheme', function () { - uriDisplayService.registerFormater(Schemas.vscode, { + uriLabelService.registerFormater(Schemas.vscode, { label: 'LABEL/${path}/${authority}/END', separator: '/', tildify: true, @@ -45,6 +45,6 @@ suite('URI Display', () => { }); const uri1 = URI.parse('vscode://microsoft.com/1/2/3/4/5'); - assert.equal(uriDisplayService.getLabel(uri1, false), 'LABEL//1/2/3/4/5/microsoft.com/END'); + assert.equal(uriLabelService.getLabel(uri1, false), 'LABEL//1/2/3/4/5/microsoft.com/END'); }); }); diff --git a/src/vs/platform/workspaces/common/workspaces.ts b/src/vs/platform/workspaces/common/workspaces.ts index 3c3f6fe8c40..5c8c389fc85 100644 --- a/src/vs/platform/workspaces/common/workspaces.ts +++ b/src/vs/platform/workspaces/common/workspaces.ts @@ -17,7 +17,7 @@ import { getBaseLabel } from 'vs/base/common/labels'; import { IWorkspaceFolder } from 'vs/platform/workspace/common/workspace'; import URI from 'vs/base/common/uri'; import { Schemas } from 'vs/base/common/network'; -import { IUriDisplayService } from 'vs/platform/uriDisplay/common/uriDisplay'; +import { IUriLabelService } from 'vs/platform/uriLabel/common/uriLabel'; export const IWorkspacesMainService = createDecorator('workspacesMainService'); export const IWorkspacesService = createDecorator('workspacesService'); @@ -113,17 +113,17 @@ export interface IWorkspacesService { createWorkspace(folders?: IWorkspaceFolderCreationData[]): TPromise; } -export function getWorkspaceLabel(workspace: (IWorkspaceIdentifier | ISingleFolderWorkspaceIdentifier), environmentService: IEnvironmentService, uriDisplayService: IUriDisplayService, options?: { verbose: boolean }): string { +export function getWorkspaceLabel(workspace: (IWorkspaceIdentifier | ISingleFolderWorkspaceIdentifier), environmentService: IEnvironmentService, uriLabelService: IUriLabelService, options?: { verbose: boolean }): string { // Workspace: Single Folder if (isSingleFolderWorkspaceIdentifier(workspace)) { // Folder on disk if (workspace.scheme === Schemas.file) { - return options && options.verbose ? uriDisplayService.getLabel(workspace) : getBaseLabel(workspace); + return options && options.verbose ? uriLabelService.getLabel(workspace) : getBaseLabel(workspace); } // Remote folder - return options && options.verbose ? uriDisplayService.getLabel(workspace) : `${getBaseLabel(workspace)} (${workspace.scheme})`; + return options && options.verbose ? uriLabelService.getLabel(workspace) : `${getBaseLabel(workspace)} (${workspace.scheme})`; } // Workspace: Untitled @@ -135,7 +135,7 @@ export function getWorkspaceLabel(workspace: (IWorkspaceIdentifier | ISingleFold const filename = basename(workspace.configPath); const workspaceName = filename.substr(0, filename.length - WORKSPACE_EXTENSION.length - 1); if (options && options.verbose) { - return localize('workspaceNameVerbose', "{0} (Workspace)", uriDisplayService.getLabel(URI.file(join(dirname(workspace.configPath), workspaceName)))); + return localize('workspaceNameVerbose', "{0} (Workspace)", uriLabelService.getLabel(URI.file(join(dirname(workspace.configPath), workspaceName)))); } return localize('workspaceName', "{0} (Workspace)", workspaceName); diff --git a/src/vs/workbench/api/electron-browser/mainThreadFileSystem.ts b/src/vs/workbench/api/electron-browser/mainThreadFileSystem.ts index 691841b18de..164d458a3ed 100644 --- a/src/vs/workbench/api/electron-browser/mainThreadFileSystem.ts +++ b/src/vs/workbench/api/electron-browser/mainThreadFileSystem.ts @@ -11,7 +11,7 @@ import { TPromise } from 'vs/base/common/winjs.base'; import { FileWriteOptions, FileSystemProviderCapabilities, IFileChange, IFileService, IFileSystemProvider, IStat, IWatchOptions, FileType, FileOverwriteOptions, FileDeleteOptions } from 'vs/platform/files/common/files'; import { extHostNamedCustomer } from 'vs/workbench/api/electron-browser/extHostCustomers'; import { ExtHostContext, ExtHostFileSystemShape, IExtHostContext, IFileChangeDto, MainContext, MainThreadFileSystemShape } from '../node/extHost.protocol'; -import { UriDisplayRules, IUriDisplayService } from 'vs/platform/uriDisplay/common/uriDisplay'; +import { UriLabelRules, IUriLabelService } from 'vs/platform/uriLabel/common/uriLabel'; @extHostNamedCustomer(MainContext.MainThreadFileSystem) export class MainThreadFileSystem implements MainThreadFileSystemShape { @@ -22,7 +22,7 @@ export class MainThreadFileSystem implements MainThreadFileSystemShape { constructor( extHostContext: IExtHostContext, @IFileService private readonly _fileService: IFileService, - @IUriDisplayService private readonly _uriDisplayService: IUriDisplayService + @IUriLabelService private readonly _uriLabelService: IUriLabelService ) { this._proxy = extHostContext.getProxy(ExtHostContext.ExtHostFileSystem); } @@ -41,8 +41,8 @@ export class MainThreadFileSystem implements MainThreadFileSystemShape { this._fileProvider.delete(handle); } - $setUriFormatter(scheme: string, formatter: UriDisplayRules): void { - this._uriDisplayService.registerFormater(scheme, formatter); + $setUriFormatter(scheme: string, formatter: UriLabelRules): void { + this._uriLabelService.registerFormater(scheme, formatter); } $onFileSystemChange(handle: number, changes: IFileChangeDto[]): void { diff --git a/src/vs/workbench/api/node/extHost.protocol.ts b/src/vs/workbench/api/node/extHost.protocol.ts index 575bb71cb4b..edb764542ad 100644 --- a/src/vs/workbench/api/node/extHost.protocol.ts +++ b/src/vs/workbench/api/node/extHost.protocol.ts @@ -40,7 +40,7 @@ import { IExtensionDescription } from 'vs/workbench/services/extensions/common/e import { createExtHostContextProxyIdentifier as createExtId, createMainContextProxyIdentifier as createMainId, IRPCProtocol, ProxyIdentifier } from 'vs/workbench/services/extensions/node/proxyIdentifier'; import { IProgressOptions, IProgressStep } from 'vs/workbench/services/progress/common/progress'; import { SaveReason } from 'vs/workbench/services/textfile/common/textfiles'; -import { UriDisplayRules } from 'vs/platform/uriDisplay/common/uriDisplay'; +import { UriLabelRules } from 'vs/platform/uriLabel/common/uriLabel'; import * as vscode from 'vscode'; export interface IEnvironment { @@ -483,7 +483,7 @@ export interface IFileChangeDto { export interface MainThreadFileSystemShape extends IDisposable { $registerFileSystemProvider(handle: number, scheme: string, capabilities: FileSystemProviderCapabilities): void; $unregisterProvider(handle: number): void; - $setUriFormatter(scheme: string, formatter: UriDisplayRules): void; + $setUriFormatter(scheme: string, formatter: UriLabelRules): void; $onFileSystemChange(handle: number, resource: IFileChangeDto[]): void; } diff --git a/src/vs/workbench/api/node/extHostFileSystem.ts b/src/vs/workbench/api/node/extHostFileSystem.ts index c39ffb2a3f9..732d21cd761 100644 --- a/src/vs/workbench/api/node/extHostFileSystem.ts +++ b/src/vs/workbench/api/node/extHostFileSystem.ts @@ -15,7 +15,7 @@ import { values } from 'vs/base/common/map'; import { Range, FileChangeType } from 'vs/workbench/api/node/extHostTypes'; import { ExtHostLanguageFeatures } from 'vs/workbench/api/node/extHostLanguageFeatures'; import { Schemas } from 'vs/base/common/network'; -import { UriDisplayRules } from 'vs/platform/uriDisplay/common/uriDisplay'; +import { UriLabelRules } from 'vs/platform/uriLabel/common/uriLabel'; class FsLinkProvider implements vscode.DocumentLinkProvider { @@ -142,7 +142,7 @@ export class ExtHostFileSystem implements ExtHostFileSystemShape { }); } - setUriFormatter(scheme: string, formatter: UriDisplayRules): void { + setUriFormatter(scheme: string, formatter: UriLabelRules): void { this._proxy.$setUriFormatter(scheme, formatter); } diff --git a/src/vs/workbench/browser/actions/workspaceCommands.ts b/src/vs/workbench/browser/actions/workspaceCommands.ts index 955717730e0..055f30bd49d 100644 --- a/src/vs/workbench/browser/actions/workspaceCommands.ts +++ b/src/vs/workbench/browser/actions/workspaceCommands.ts @@ -22,7 +22,7 @@ import { FileKind, isParent } from 'vs/platform/files/common/files'; import { IEnvironmentService } from 'vs/platform/environment/common/environment'; import { ServicesAccessor } from 'vs/platform/instantiation/common/instantiation'; import { isLinux } from 'vs/base/common/platform'; -import { IUriDisplayService } from 'vs/platform/uriDisplay/common/uriDisplay'; +import { IUriLabelService } from 'vs/platform/uriLabel/common/uriLabel'; import { IQuickInputService, IPickOptions, IQuickPickItem } from 'vs/platform/quickinput/common/quickInput'; import { getIconClasses } from 'vs/workbench/browser/labels'; import { IModelService } from 'vs/editor/common/services/modelService'; @@ -163,7 +163,7 @@ CommandsRegistry.registerCommand({ CommandsRegistry.registerCommand(PICK_WORKSPACE_FOLDER_COMMAND_ID, function (accessor, args?: [IPickOptions, CancellationToken]) { const quickInputService = accessor.get(IQuickInputService); - const uriDisplayService = accessor.get(IUriDisplayService); + const uriLabelService = accessor.get(IUriLabelService); const contextService = accessor.get(IWorkspaceContextService); const modelService = accessor.get(IModelService); const modeService = accessor.get(IModeService); @@ -176,7 +176,7 @@ CommandsRegistry.registerCommand(PICK_WORKSPACE_FOLDER_COMMAND_ID, function (acc const folderPicks = folders.map(folder => { return { label: folder.name, - description: uriDisplayService.getLabel(resources.dirname(folder.uri), true), + description: uriLabelService.getLabel(resources.dirname(folder.uri), true), folder, iconClasses: getIconClasses(modelService, modeService, folder.uri, FileKind.ROOT_FOLDER) } as IQuickPickItem; diff --git a/src/vs/workbench/browser/labels.ts b/src/vs/workbench/browser/labels.ts index bf04e217fa7..7a1b6e0aedc 100644 --- a/src/vs/workbench/browser/labels.ts +++ b/src/vs/workbench/browser/labels.ts @@ -23,7 +23,7 @@ import { ITextModel } from 'vs/editor/common/model'; import { IThemeService } from 'vs/platform/theme/common/themeService'; import { Event, Emitter } from 'vs/base/common/event'; import { DataUri } from 'vs/workbench/common/resources'; -import { IUriDisplayService } from 'vs/platform/uriDisplay/common/uriDisplay'; +import { IUriLabelService } from 'vs/platform/uriLabel/common/uriLabel'; export interface IResourceLabel { name: string; @@ -56,7 +56,7 @@ export class ResourceLabel extends IconLabel { @IModelService private modelService: IModelService, @IDecorationsService protected decorationsService: IDecorationsService, @IThemeService private themeService: IThemeService, - @IUriDisplayService protected uriDisplayService: IUriDisplayService + @IUriLabelService protected uriLabelService: IUriLabelService ) { super(container, options); @@ -191,7 +191,7 @@ export class ResourceLabel extends IconLabel { iconLabelOptions.title = this.options.title; } else if (resource && resource.scheme !== Schemas.data /* do not accidentally inline Data URIs */) { if (!this.computedPathLabel) { - this.computedPathLabel = this.uriDisplayService.getLabel(resource); + this.computedPathLabel = this.uriLabelService.getLabel(resource); } iconLabelOptions.title = this.computedPathLabel; @@ -274,9 +274,9 @@ export class FileLabel extends ResourceLabel { @IDecorationsService decorationsService: IDecorationsService, @IThemeService themeService: IThemeService, @IUntitledEditorService private untitledEditorService: IUntitledEditorService, - @IUriDisplayService uriDisplayService: IUriDisplayService + @IUriLabelService uriLabelService: IUriLabelService ) { - super(container, options, extensionService, configurationService, modeService, modelService, decorationsService, themeService, uriDisplayService); + super(container, options, extensionService, configurationService, modeService, modelService, decorationsService, themeService, uriLabelService); } setFile(resource: uri, options?: IFileLabelOptions): void { @@ -298,7 +298,7 @@ export class FileLabel extends ResourceLabel { let description: string; const hidePath = (options && options.hidePath) || (resource.scheme === Schemas.untitled && !this.untitledEditorService.hasAssociatedFilePath(resource)); if (!hidePath) { - description = this.uriDisplayService.getLabel(resources.dirname(resource), true); + description = this.uriLabelService.getLabel(resources.dirname(resource), true); } this.setLabel({ resource, name, description }, options); diff --git a/src/vs/workbench/browser/parts/quickopen/quickOpenController.ts b/src/vs/workbench/browser/parts/quickopen/quickOpenController.ts index 9b5dd21bd15..428a391e24b 100644 --- a/src/vs/workbench/browser/parts/quickopen/quickOpenController.ts +++ b/src/vs/workbench/browser/parts/quickopen/quickOpenController.ts @@ -49,7 +49,7 @@ import { INotificationService } from 'vs/platform/notification/common/notificati import { Dimension, addClass } from 'vs/base/browser/dom'; import { IEditorService, ACTIVE_GROUP, SIDE_GROUP } from 'vs/workbench/services/editor/common/editorService'; import { IEditorGroupsService } from 'vs/workbench/services/group/common/editorGroupsService'; -import { IUriDisplayService } from 'vs/platform/uriDisplay/common/uriDisplay'; +import { IUriLabelService } from 'vs/platform/uriLabel/common/uriLabel'; import { timeout } from 'vs/base/common/async'; import { IQuickInputService, IQuickPickItem } from 'vs/platform/quickinput/common/quickInput'; @@ -684,7 +684,7 @@ export class EditorHistoryEntry extends EditorQuickOpenEntry { @IModelService private modelService: IModelService, @ITextFileService private textFileService: ITextFileService, @IConfigurationService private configurationService: IConfigurationService, - @IUriDisplayService uriDisplayService: IUriDisplayService, + @IUriLabelService uriLabelService: IUriLabelService, @IFileService fileService: IFileService ) { super(editorService); @@ -700,7 +700,7 @@ export class EditorHistoryEntry extends EditorQuickOpenEntry { const resourceInput = input as IResourceInput; this.resource = resourceInput.resource; this.label = resources.basenameOrAuthority(resourceInput.resource); - this.description = uriDisplayService.getLabel(resources.dirname(this.resource), true); + this.description = uriLabelService.getLabel(resources.dirname(this.resource), true); this.dirty = this.resource && this.textFileService.isDirty(this.resource); if (this.dirty && this.textFileService.getAutoSaveMode() === AutoSaveMode.AFTER_SHORT_DELAY) { diff --git a/src/vs/workbench/browser/parts/titlebar/menubarControl.ts b/src/vs/workbench/browser/parts/titlebar/menubarControl.ts index 78a6928f254..d383476fbd5 100644 --- a/src/vs/workbench/browser/parts/titlebar/menubarControl.ts +++ b/src/vs/workbench/browser/parts/titlebar/menubarControl.ts @@ -30,7 +30,7 @@ import { IEnvironmentService } from 'vs/platform/environment/common/environment' import { RunOnceScheduler } from 'vs/base/common/async'; import { MENUBAR_SELECTION_FOREGROUND, MENUBAR_SELECTION_BACKGROUND, MENUBAR_SELECTION_BORDER, TITLE_BAR_ACTIVE_FOREGROUND, TITLE_BAR_INACTIVE_FOREGROUND, MENU_BACKGROUND, MENU_FOREGROUND, MENU_SELECTION_BACKGROUND, MENU_SELECTION_FOREGROUND, MENU_SELECTION_BORDER } from 'vs/workbench/common/theme'; import URI from 'vs/base/common/uri'; -import { IUriDisplayService } from 'vs/platform/uriDisplay/common/uriDisplay'; +import { IUriLabelService } from 'vs/platform/uriLabel/common/uriLabel'; import { foreground } from 'vs/platform/theme/common/colorRegistry'; import { IUpdateService, StateType } from 'vs/platform/update/common/update'; @@ -121,7 +121,7 @@ export class MenubarControl extends Disposable { @IKeybindingService private keybindingService: IKeybindingService, @IConfigurationService private configurationService: IConfigurationService, @IEnvironmentService private environmentService: IEnvironmentService, - @IUriDisplayService private uriDisplayService: IUriDisplayService, + @IUriLabelService private uriLabelService: IUriLabelService, @IUpdateService private updateService: IUpdateService ) { @@ -507,14 +507,14 @@ export class MenubarControl extends Disposable { let uri: URI; if (isSingleFolderWorkspaceIdentifier(workspace) && !isFile) { - label = getWorkspaceLabel(workspace, this.environmentService, this.uriDisplayService, { verbose: true }); + label = getWorkspaceLabel(workspace, this.environmentService, this.uriLabelService, { verbose: true }); uri = workspace; } else if (isWorkspaceIdentifier(workspace)) { - label = getWorkspaceLabel(workspace, this.environmentService, this.uriDisplayService, { verbose: true }); + label = getWorkspaceLabel(workspace, this.environmentService, this.uriLabelService, { verbose: true }); uri = URI.file(workspace.configPath); } else { uri = workspace; - label = this.uriDisplayService.getLabel(uri); + label = this.uriLabelService.getLabel(uri); } return new Action(commandId, label, undefined, undefined, (event) => { diff --git a/src/vs/workbench/browser/parts/titlebar/titlebarPart.ts b/src/vs/workbench/browser/parts/titlebar/titlebarPart.ts index 84702f9de77..9a4bc78f8bf 100644 --- a/src/vs/workbench/browser/parts/titlebar/titlebarPart.ts +++ b/src/vs/workbench/browser/parts/titlebar/titlebarPart.ts @@ -34,7 +34,7 @@ import { addDisposableListener, EventType, EventHelper, Dimension } from 'vs/bas import { MenubarControl } from 'vs/workbench/browser/parts/titlebar/menubarControl'; import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; import { template, getBaseLabel } from 'vs/base/common/labels'; -import { IUriDisplayService } from 'vs/platform/uriDisplay/common/uriDisplay'; +import { IUriLabelService } from 'vs/platform/uriLabel/common/uriLabel'; import { Event } from 'vs/base/common/event'; export class TitlebarPart extends Part implements ITitleService { @@ -84,7 +84,7 @@ export class TitlebarPart extends Part implements ITitleService { @IWorkspaceContextService private contextService: IWorkspaceContextService, @IInstantiationService private instantiationService: IInstantiationService, @IThemeService themeService: IThemeService, - @IUriDisplayService private uriDisplayService: IUriDisplayService + @IUriLabelService private uriLabelService: IUriLabelService ) { super(id, { hasTitle: false }, themeService); @@ -244,9 +244,9 @@ export class TitlebarPart extends Part implements ITitleService { const activeEditorMedium = editor ? editor.getTitle(Verbosity.MEDIUM) : activeEditorShort; const activeEditorLong = editor ? editor.getTitle(Verbosity.LONG) : activeEditorMedium; const rootName = workspace.name; - const rootPath = root ? this.uriDisplayService.getLabel(root) : ''; + const rootPath = root ? this.uriLabelService.getLabel(root) : ''; const folderName = folder ? folder.name : ''; - const folderPath = folder ? this.uriDisplayService.getLabel(folder.uri) : ''; + const folderPath = folder ? this.uriLabelService.getLabel(folder.uri) : ''; const dirty = editor && editor.isDirty() ? TitlebarPart.TITLE_DIRTY : ''; const appName = this.environmentService.appNameLong; const separator = TitlebarPart.TITLE_SEPARATOR; diff --git a/src/vs/workbench/common/editor/untitledEditorInput.ts b/src/vs/workbench/common/editor/untitledEditorInput.ts index 27d9f0d2cdd..93d3f05fdec 100644 --- a/src/vs/workbench/common/editor/untitledEditorInput.ts +++ b/src/vs/workbench/common/editor/untitledEditorInput.ts @@ -18,7 +18,7 @@ import { Event, Emitter } from 'vs/base/common/event'; import { ITextFileService } from 'vs/workbench/services/textfile/common/textfiles'; import { telemetryURIDescriptor } from 'vs/platform/telemetry/common/telemetryUtils'; import { IHashService } from 'vs/workbench/services/hash/common/hashService'; -import { IUriDisplayService } from 'vs/platform/uriDisplay/common/uriDisplay'; +import { IUriLabelService } from 'vs/platform/uriLabel/common/uriLabel'; /** * An editor input to be used for untitled text buffers. @@ -46,7 +46,7 @@ export class UntitledEditorInput extends EditorInput implements IEncodingSupport @IInstantiationService private instantiationService: IInstantiationService, @ITextFileService private textFileService: ITextFileService, @IHashService private hashService: IHashService, - @IUriDisplayService private uriDisplayService: IUriDisplayService + @IUriLabelService private uriLabelService: IUriLabelService ) { super(); @@ -79,17 +79,17 @@ export class UntitledEditorInput extends EditorInput implements IEncodingSupport @memoize private get shortDescription(): string { - return paths.basename(this.uriDisplayService.getLabel(resources.dirname(this.resource))); + return paths.basename(this.uriLabelService.getLabel(resources.dirname(this.resource))); } @memoize private get mediumDescription(): string { - return this.uriDisplayService.getLabel(resources.dirname(this.resource), true); + return this.uriLabelService.getLabel(resources.dirname(this.resource), true); } @memoize private get longDescription(): string { - return this.uriDisplayService.getLabel(resources.dirname(this.resource)); + return this.uriLabelService.getLabel(resources.dirname(this.resource)); } getDescription(verbosity: Verbosity = Verbosity.MEDIUM): string { @@ -121,12 +121,12 @@ export class UntitledEditorInput extends EditorInput implements IEncodingSupport @memoize private get mediumTitle(): string { - return this.uriDisplayService.getLabel(this.resource, true); + return this.uriLabelService.getLabel(this.resource, true); } @memoize private get longTitle(): string { - return this.uriDisplayService.getLabel(this.resource); + return this.uriLabelService.getLabel(this.resource); } getTitle(verbosity: Verbosity): string { diff --git a/src/vs/workbench/electron-browser/actions.ts b/src/vs/workbench/electron-browser/actions.ts index 91c474950c1..5c5efee9c6c 100644 --- a/src/vs/workbench/electron-browser/actions.ts +++ b/src/vs/workbench/electron-browser/actions.ts @@ -46,7 +46,7 @@ import { IContextKeyService } from 'vs/platform/contextkey/common/contextkey'; import { Context } from 'vs/platform/contextkey/browser/contextKeyService'; import { IWorkbenchIssueService } from 'vs/workbench/services/issue/common/issue'; import { INotificationService } from 'vs/platform/notification/common/notification'; -import { IUriDisplayService } from 'vs/platform/uriDisplay/common/uriDisplay'; +import { IUriLabelService } from 'vs/platform/uriLabel/common/uriLabel'; import { dirname } from 'vs/base/common/resources'; import { IModelService } from 'vs/editor/common/services/modelService'; import { IModeService } from 'vs/editor/common/services/modeService'; @@ -700,7 +700,7 @@ export abstract class BaseOpenRecentAction extends Action { private quickInputService: IQuickInputService, private contextService: IWorkspaceContextService, private environmentService: IEnvironmentService, - private uriDisplayService: IUriDisplayService, + private uriLabelService: IUriLabelService, private keybindingService: IKeybindingService, private modelService: IModelService, private modeService: IModeService, @@ -717,22 +717,22 @@ export abstract class BaseOpenRecentAction extends Action { private openRecent(recentWorkspaces: (IWorkspaceIdentifier | ISingleFolderWorkspaceIdentifier)[], recentFiles: URI[]): void { - const toPick = (workspace: IWorkspaceIdentifier | ISingleFolderWorkspaceIdentifier | URI, fileKind: FileKind, environmentService: IEnvironmentService, uriDisplayService: IUriDisplayService, buttons: IQuickInputButton[]) => { + const toPick = (workspace: IWorkspaceIdentifier | ISingleFolderWorkspaceIdentifier | URI, fileKind: FileKind, environmentService: IEnvironmentService, uriLabelService: IUriLabelService, buttons: IQuickInputButton[]) => { let resource: URI; let label: string; let description: string; if (isSingleFolderWorkspaceIdentifier(workspace) && fileKind !== FileKind.FILE) { resource = workspace; - label = getWorkspaceLabel(workspace, environmentService, uriDisplayService); - description = uriDisplayService.getLabel(dirname(resource)); + label = getWorkspaceLabel(workspace, environmentService, uriLabelService); + description = uriLabelService.getLabel(dirname(resource)); } else if (isWorkspaceIdentifier(workspace)) { resource = URI.file(workspace.configPath); - label = getWorkspaceLabel(workspace, environmentService, uriDisplayService); - description = uriDisplayService.getLabel(dirname(resource)); + label = getWorkspaceLabel(workspace, environmentService, uriLabelService); + description = uriLabelService.getLabel(dirname(resource)); } else { resource = workspace; label = getBaseLabel(workspace); - description = uriDisplayService.getLabel(dirname(resource)); + description = uriLabelService.getLabel(dirname(resource)); } return { @@ -751,8 +751,8 @@ export abstract class BaseOpenRecentAction extends Action { return this.windowService.openWindow([resource], { forceNewWindow, forceOpenWorkspaceAsFile: isFile }); }; - const workspacePicks = recentWorkspaces.map(workspace => toPick(workspace, isSingleFolderWorkspaceIdentifier(workspace) ? FileKind.FOLDER : FileKind.ROOT_FOLDER, this.environmentService, this.uriDisplayService, !this.isQuickNavigate() ? [this.removeFromRecentlyOpened] : void 0)); - const filePicks = recentFiles.map(p => toPick(p, FileKind.FILE, this.environmentService, this.uriDisplayService, !this.isQuickNavigate() ? [this.removeFromRecentlyOpened] : void 0)); + const workspacePicks = recentWorkspaces.map(workspace => toPick(workspace, isSingleFolderWorkspaceIdentifier(workspace) ? FileKind.FOLDER : FileKind.ROOT_FOLDER, this.environmentService, this.uriLabelService, !this.isQuickNavigate() ? [this.removeFromRecentlyOpened] : void 0)); + const filePicks = recentFiles.map(p => toPick(p, FileKind.FILE, this.environmentService, this.uriLabelService, !this.isQuickNavigate() ? [this.removeFromRecentlyOpened] : void 0)); // focus second entry if the first recent workspace is the current workspace let autoFocusSecondEntry: boolean = recentWorkspaces[0] && this.contextService.isCurrentWorkspace(recentWorkspaces[0]); @@ -800,9 +800,9 @@ export class OpenRecentAction extends BaseOpenRecentAction { @IKeybindingService keybindingService: IKeybindingService, @IModelService modelService: IModelService, @IModeService modeService: IModeService, - @IUriDisplayService uriDisplayService: IUriDisplayService + @IUriLabelService uriLabelService: IUriLabelService ) { - super(id, label, windowService, windowsService, quickInputService, contextService, environmentService, uriDisplayService, keybindingService, modelService, modeService); + super(id, label, windowService, windowsService, quickInputService, contextService, environmentService, uriLabelService, keybindingService, modelService, modeService); } protected isQuickNavigate(): boolean { @@ -826,9 +826,9 @@ export class QuickOpenRecentAction extends BaseOpenRecentAction { @IKeybindingService keybindingService: IKeybindingService, @IModelService modelService: IModelService, @IModeService modeService: IModeService, - @IUriDisplayService uriDisplayService: IUriDisplayService + @IUriLabelService uriLabelService: IUriLabelService ) { - super(id, label, windowService, windowsService, quickInputService, contextService, environmentService, uriDisplayService, keybindingService, modelService, modeService); + super(id, label, windowService, windowsService, quickInputService, contextService, environmentService, uriLabelService, keybindingService, modelService, modeService); } protected isQuickNavigate(): boolean { @@ -1721,4 +1721,4 @@ export class InspectContextKeysAction extends Action { return TPromise.as(null); } -} \ No newline at end of file +} diff --git a/src/vs/workbench/electron-browser/workbench.ts b/src/vs/workbench/electron-browser/workbench.ts index 61bbd350fa7..443d3f56d8f 100644 --- a/src/vs/workbench/electron-browser/workbench.ts +++ b/src/vs/workbench/electron-browser/workbench.ts @@ -116,7 +116,7 @@ import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry'; import { TelemetryService } from 'vs/platform/telemetry/common/telemetryService'; import { WorkbenchThemeService } from 'vs/workbench/services/themes/electron-browser/workbenchThemeService'; import { IWorkbenchThemeService } from 'vs/workbench/services/themes/common/workbenchThemeService'; -import { IUriDisplayService, UriDisplayService } from 'vs/platform/uriDisplay/common/uriDisplay'; +import { IUriLabelService, UriLabelService } from 'vs/platform/uriLabel/common/uriLabel'; interface WorkbenchParams { configuration: IWindowConfiguration; @@ -337,9 +337,9 @@ export class Workbench extends Disposable implements IPartService { serviceCollection.set(IClipboardService, new ClipboardService()); // Uri Display - const uriDisplayService = new UriDisplayService(this.environmentService, this.contextService); - serviceCollection.set(IUriDisplayService, uriDisplayService); - this.configurationService.acquireUriDisplayService(uriDisplayService); + const uriLabelService = new UriLabelService(this.environmentService, this.contextService); + serviceCollection.set(IUriLabelService, uriLabelService); + this.configurationService.acquireUriLabelService(uriLabelService); // Status bar this.statusbarPart = this.instantiationService.createInstance(StatusbarPart, Identifiers.STATUSBAR_PART); diff --git a/src/vs/workbench/parts/debug/browser/breakpointsView.ts b/src/vs/workbench/parts/debug/browser/breakpointsView.ts index be6268a4aa8..3784a56063b 100644 --- a/src/vs/workbench/parts/debug/browser/breakpointsView.ts +++ b/src/vs/workbench/parts/debug/browser/breakpointsView.ts @@ -32,7 +32,7 @@ import { IConfigurationService } from 'vs/platform/configuration/common/configur import { ITextFileService } from 'vs/workbench/services/textfile/common/textfiles'; import { IEditorService, SIDE_GROUP, ACTIVE_GROUP } from 'vs/workbench/services/editor/common/editorService'; import { ViewletPanel, IViewletPanelOptions } from 'vs/workbench/browser/parts/views/panelViewlet'; -import { IUriDisplayService } from 'vs/platform/uriDisplay/common/uriDisplay'; +import { IUriLabelService } from 'vs/platform/uriLabel/common/uriLabel'; const $ = dom.$; @@ -296,7 +296,7 @@ class BreakpointsRenderer implements IRenderer element.sourceData; } diff --git a/src/vs/workbench/parts/files/common/editors/fileEditorInput.ts b/src/vs/workbench/parts/files/common/editors/fileEditorInput.ts index 5eea47892d2..6f171a925b3 100644 --- a/src/vs/workbench/parts/files/common/editors/fileEditorInput.ts +++ b/src/vs/workbench/parts/files/common/editors/fileEditorInput.ts @@ -21,7 +21,7 @@ import { telemetryURIDescriptor } from 'vs/platform/telemetry/common/telemetryUt import { ITextModelService } from 'vs/editor/common/services/resolverService'; import { IHashService } from 'vs/workbench/services/hash/common/hashService'; import { FILE_EDITOR_INPUT_ID, TEXT_FILE_EDITOR_ID, BINARY_FILE_EDITOR_ID } from 'vs/workbench/parts/files/common/files'; -import { IUriDisplayService } from 'vs/platform/uriDisplay/common/uriDisplay'; +import { IUriLabelService } from 'vs/platform/uriLabel/common/uriLabel'; /** * A file editor input is the input type for the file editor of file system resources. @@ -43,7 +43,7 @@ export class FileEditorInput extends EditorInput implements IFileEditorInput { @ITextFileService private textFileService: ITextFileService, @ITextModelService private textModelResolverService: ITextModelService, @IHashService private hashService: IHashService, - @IUriDisplayService private uriDisplayService: IUriDisplayService + @IUriLabelService private uriLabelService: IUriLabelService ) { super(); @@ -132,17 +132,17 @@ export class FileEditorInput extends EditorInput implements IFileEditorInput { @memoize private get shortDescription(): string { - return paths.basename(this.uriDisplayService.getLabel(resources.dirname(this.resource))); + return paths.basename(this.uriLabelService.getLabel(resources.dirname(this.resource))); } @memoize private get mediumDescription(): string { - return this.uriDisplayService.getLabel(resources.dirname(this.resource), true); + return this.uriLabelService.getLabel(resources.dirname(this.resource), true); } @memoize private get longDescription(): string { - return this.uriDisplayService.getLabel(resources.dirname(this.resource), true); + return this.uriLabelService.getLabel(resources.dirname(this.resource), true); } getDescription(verbosity: Verbosity = Verbosity.MEDIUM): string { @@ -170,12 +170,12 @@ export class FileEditorInput extends EditorInput implements IFileEditorInput { @memoize private get mediumTitle(): string { - return this.uriDisplayService.getLabel(this.resource, true); + return this.uriLabelService.getLabel(this.resource, true); } @memoize private get longTitle(): string { - return this.uriDisplayService.getLabel(this.resource, true); + return this.uriLabelService.getLabel(this.resource, true); } getTitle(verbosity: Verbosity): string { diff --git a/src/vs/workbench/parts/files/electron-browser/files.contribution.ts b/src/vs/workbench/parts/files/electron-browser/files.contribution.ts index a34d3ded080..39594b253a5 100644 --- a/src/vs/workbench/parts/files/electron-browser/files.contribution.ts +++ b/src/vs/workbench/parts/files/electron-browser/files.contribution.ts @@ -34,7 +34,7 @@ import { DataUriEditorInput } from 'vs/workbench/common/editor/dataUriEditorInpu import { LifecyclePhase } from 'vs/platform/lifecycle/common/lifecycle'; import { IEditorService } from 'vs/workbench/services/editor/common/editorService'; import { IEditorGroupsService } from 'vs/workbench/services/group/common/editorGroupsService'; -import { IUriDisplayService } from 'vs/platform/uriDisplay/common/uriDisplay'; +import { IUriLabelService } from 'vs/platform/uriLabel/common/uriLabel'; import { Schemas } from 'vs/base/common/network'; import { nativeSep } from 'vs/base/common/paths'; @@ -53,10 +53,10 @@ export class OpenExplorerViewletAction extends ToggleViewletAction { } } -class FileUriDisplayContribution implements IWorkbenchContribution { +class FileUriLabelContribution implements IWorkbenchContribution { - constructor(@IUriDisplayService uriDisplayService: IUriDisplayService) { - uriDisplayService.registerFormater(Schemas.file, { + constructor(@IUriLabelService uriLabelService: IUriLabelService) { + uriLabelService.registerFormater(Schemas.file, { label: '${path}', separator: nativeSep, tildify: !platform.isWindows, @@ -172,7 +172,7 @@ Registry.as(WorkbenchExtensions.Workbench).regi Registry.as(WorkbenchExtensions.Workbench).registerWorkbenchContribution(DirtyFilesTracker, LifecyclePhase.Starting); // Register uri display for file uris -Registry.as(WorkbenchExtensions.Workbench).registerWorkbenchContribution(FileUriDisplayContribution, LifecyclePhase.Starting); +Registry.as(WorkbenchExtensions.Workbench).registerWorkbenchContribution(FileUriLabelContribution, LifecyclePhase.Starting); // Configuration diff --git a/src/vs/workbench/parts/localizations/electron-browser/localizationsActions.ts b/src/vs/workbench/parts/localizations/electron-browser/localizationsActions.ts index 2290be2e5d0..3eeb2028a11 100644 --- a/src/vs/workbench/parts/localizations/electron-browser/localizationsActions.ts +++ b/src/vs/workbench/parts/localizations/electron-browser/localizationsActions.ts @@ -13,7 +13,7 @@ import { join } from 'vs/base/common/paths'; import URI from 'vs/base/common/uri'; import { IEditorService } from 'vs/workbench/services/editor/common/editorService'; import { language } from 'vs/base/common/platform'; -import { IUriDisplayService } from 'vs/platform/uriDisplay/common/uriDisplay'; +import { IUriLabelService } from 'vs/platform/uriLabel/common/uriLabel'; export class ConfigureLocaleAction extends Action { public static readonly ID = 'workbench.action.configureLocale'; @@ -32,7 +32,7 @@ export class ConfigureLocaleAction extends Action { @IFileService private fileService: IFileService, @IEnvironmentService private environmentService: IEnvironmentService, @IEditorService private editorService: IEditorService, - @IUriDisplayService private uriDisplayService: IUriDisplayService + @IUriLabelService private uriLabelService: IUriLabelService ) { super(id, label); } @@ -49,7 +49,7 @@ export class ConfigureLocaleAction extends Action { resource: stat.resource }); }, (error) => { - throw new Error(localize('fail.createSettings', "Unable to create '{0}' ({1}).", this.uriDisplayService.getLabel(file, true), error)); + throw new Error(localize('fail.createSettings', "Unable to create '{0}' ({1}).", this.uriLabelService.getLabel(file, true), error)); }); } } diff --git a/src/vs/workbench/parts/markers/electron-browser/markersTreeViewer.ts b/src/vs/workbench/parts/markers/electron-browser/markersTreeViewer.ts index 133884c00dd..f9549b81f58 100644 --- a/src/vs/workbench/parts/markers/electron-browser/markersTreeViewer.ts +++ b/src/vs/workbench/parts/markers/electron-browser/markersTreeViewer.ts @@ -21,7 +21,7 @@ import { IThemeService } from 'vs/platform/theme/common/themeService'; import { IDisposable } from 'vs/base/common/lifecycle'; import { ActionBar, IActionItemProvider } from 'vs/base/browser/ui/actionbar/actionbar'; import { QuickFixAction } from 'vs/workbench/parts/markers/electron-browser/markersPanelActions'; -import { IUriDisplayService } from 'vs/platform/uriDisplay/common/uriDisplay'; +import { IUriLabelService } from 'vs/platform/uriLabel/common/uriLabel'; interface IResourceMarkersTemplateData { resourceLabel: ResourceLabel; @@ -99,7 +99,7 @@ export class Renderer implements IRenderer { private actionItemProvider: IActionItemProvider, @IInstantiationService private instantiationService: IInstantiationService, @IThemeService private themeService: IThemeService, - @IUriDisplayService private uriDisplayService: IUriDisplayService + @IUriLabelService private uriLabelService: IUriLabelService ) { } @@ -208,7 +208,7 @@ export class Renderer implements IRenderer { if (templateData.resourceLabel instanceof FileLabel) { templateData.resourceLabel.setFile(element.uri, { matches: element.uriMatches }); } else { - templateData.resourceLabel.setLabel({ name: element.name, description: this.uriDisplayService.getLabel(element.uri, true), resource: element.uri }, { matches: element.uriMatches }); + templateData.resourceLabel.setLabel({ name: element.name, description: this.uriLabelService.getLabel(element.uri, true), resource: element.uri }, { matches: element.uriMatches }); } (templateData).count.setCount(element.filteredCount); } @@ -235,7 +235,7 @@ export class Renderer implements IRenderer { private renderRelatedInfoElement(tree: ITree, element: RelatedInformation, templateData: IRelatedInformationTemplateData) { templateData.resourceLabel.set(paths.basename(element.raw.resource.fsPath), element.uriMatches); - templateData.resourceLabel.element.title = this.uriDisplayService.getLabel(element.raw.resource, true); + templateData.resourceLabel.element.title = this.uriLabelService.getLabel(element.raw.resource, true); templateData.lnCol.textContent = Messages.MARKERS_PANEL_AT_LINE_COL_NUMBER(element.raw.startLineNumber, element.raw.startColumn); templateData.description.set(element.raw.message, element.messageMatches); templateData.description.element.title = element.raw.message; @@ -272,13 +272,13 @@ export class Renderer implements IRenderer { export class MarkersTreeAccessibilityProvider implements IAccessibilityProvider { constructor( - @IUriDisplayService private uriDisplayServie: IUriDisplayService + @IUriLabelService private uriLabelServie: IUriLabelService ) { } public getAriaLabel(tree: ITree, element: any): string { if (element instanceof ResourceMarkers) { - const path = this.uriDisplayServie.getLabel(element.uri, true) || element.uri.fsPath; + const path = this.uriLabelServie.getLabel(element.uri, true) || element.uri.fsPath; return Messages.MARKERS_TREE_ARIA_LABEL_RESOURCE(element.filteredCount, element.name, paths.dirname(path)); } if (element instanceof Marker) { diff --git a/src/vs/workbench/parts/search/browser/openFileHandler.ts b/src/vs/workbench/parts/search/browser/openFileHandler.ts index baf0b860cc8..d504966ecc3 100644 --- a/src/vs/workbench/parts/search/browser/openFileHandler.ts +++ b/src/vs/workbench/parts/search/browser/openFileHandler.ts @@ -33,7 +33,7 @@ import { getOutOfWorkspaceEditorResources } from 'vs/workbench/parts/search/comm import { IEditorService } from 'vs/workbench/services/editor/common/editorService'; import { prepareQuery, IPreparedQuery } from 'vs/base/parts/quickopen/common/quickOpenScorer'; import { IFileService } from 'vs/platform/files/common/files'; -import { IUriDisplayService } from 'vs/platform/uriDisplay/common/uriDisplay'; +import { IUriLabelService } from 'vs/platform/uriLabel/common/uriLabel'; import { untildify } from 'vs/base/common/labels'; export class FileQuickOpenModel extends QuickOpenModel { @@ -127,7 +127,7 @@ export class OpenFileHandler extends QuickOpenHandler { @ISearchService private searchService: ISearchService, @IEnvironmentService private environmentService: IEnvironmentService, @IFileService private fileService: IFileService, - @IUriDisplayService private uriDisplayService: IUriDisplayService + @IUriLabelService private uriLabelService: IUriLabelService ) { super(); @@ -173,7 +173,7 @@ export class OpenFileHandler extends QuickOpenHandler { const fileMatch = complete.results[i]; const label = paths.basename(fileMatch.resource.fsPath); - const description = this.uriDisplayService.getLabel(resources.dirname(fileMatch.resource), true); + const description = this.uriLabelService.getLabel(resources.dirname(fileMatch.resource), true); results.push(this.instantiationService.createInstance(FileEntry, fileMatch.resource, label, description, iconClass)); } diff --git a/src/vs/workbench/parts/search/browser/openSymbolHandler.ts b/src/vs/workbench/parts/search/browser/openSymbolHandler.ts index 17472a73e75..cf6acbc1f1e 100644 --- a/src/vs/workbench/parts/search/browser/openSymbolHandler.ts +++ b/src/vs/workbench/parts/search/browser/openSymbolHandler.ts @@ -23,7 +23,7 @@ import { IConfigurationService } from 'vs/platform/configuration/common/configur import { IWorkspaceSymbolProvider, getWorkspaceSymbols, IWorkspaceSymbol } from 'vs/workbench/parts/search/common/search'; import { basename } from 'vs/base/common/paths'; import { IEditorService } from 'vs/workbench/services/editor/common/editorService'; -import { IUriDisplayService } from 'vs/platform/uriDisplay/common/uriDisplay'; +import { IUriLabelService } from 'vs/platform/uriLabel/common/uriLabel'; class SymbolEntry extends EditorQuickOpenEntry { @@ -34,7 +34,7 @@ class SymbolEntry extends EditorQuickOpenEntry { private _provider: IWorkspaceSymbolProvider, @IConfigurationService private readonly _configurationService: IConfigurationService, @IEditorService editorService: IEditorService, - @IUriDisplayService private _uriDisplayService: IUriDisplayService + @IUriLabelService private _uriLabelService: IUriLabelService ) { super(editorService); } @@ -53,7 +53,7 @@ class SymbolEntry extends EditorQuickOpenEntry { if (containerName) { return `${containerName} — ${basename(this._bearing.location.uri.fsPath)}`; } else { - return this._uriDisplayService.getLabel(this._bearing.location.uri, true); + return this._uriLabelService.getLabel(this._bearing.location.uri, true); } } return containerName; diff --git a/src/vs/workbench/parts/search/browser/searchResultsView.ts b/src/vs/workbench/parts/search/browser/searchResultsView.ts index 4a27ccf12d5..bc1aae507f7 100644 --- a/src/vs/workbench/parts/search/browser/searchResultsView.ts +++ b/src/vs/workbench/parts/search/browser/searchResultsView.ts @@ -27,7 +27,7 @@ import { IContextMenuService } from 'vs/platform/contextview/browser/contextView import { IMenuService, MenuId, IMenu } from 'vs/platform/actions/common/actions'; import { WorkbenchTreeController, WorkbenchTree } from 'vs/platform/list/browser/listService'; import { fillInContextMenuActions } from 'vs/platform/actions/browser/menuItemActionItem'; -import { IUriDisplayService } from 'vs/platform/uriDisplay/common/uriDisplay'; +import { IUriLabelService } from 'vs/platform/uriLabel/common/uriLabel'; export class SearchDataSource implements IDataSource { @@ -318,7 +318,7 @@ export class SearchRenderer extends Disposable implements IRenderer { export class SearchAccessibilityProvider implements IAccessibilityProvider { constructor( - @IUriDisplayService private uriDisplayService: IUriDisplayService + @IUriLabelService private uriLabelService: IUriLabelService ) { } @@ -328,7 +328,7 @@ export class SearchAccessibilityProvider implements IAccessibilityProvider { } if (element instanceof FileMatch) { - const path = this.uriDisplayService.getLabel(element.resource(), true) || element.resource().fsPath; + const path = this.uriLabelService.getLabel(element.resource(), true) || element.resource().fsPath; return nls.localize('fileMatchAriaLabel', "{0} matches in file {1} of folder {2}, Search result", element.count(), element.name(), paths.dirname(path)); } diff --git a/src/vs/workbench/parts/welcome/page/electron-browser/welcomePage.ts b/src/vs/workbench/parts/welcome/page/electron-browser/welcomePage.ts index c27b1e12bc6..9ad196cfe57 100644 --- a/src/vs/workbench/parts/welcome/page/electron-browser/welcomePage.ts +++ b/src/vs/workbench/parts/welcome/page/electron-browser/welcomePage.ts @@ -40,7 +40,7 @@ import { getIdAndVersionFromLocalExtensionId } from 'vs/platform/extensionManage import { INotificationService, Severity } from 'vs/platform/notification/common/notification'; import { TimeoutTimer } from 'vs/base/common/async'; import { areSameExtensions } from 'vs/platform/extensionManagement/common/extensionManagementUtil'; -import { IUriDisplayService } from 'vs/platform/uriDisplay/common/uriDisplay'; +import { IUriLabelService } from 'vs/platform/uriLabel/common/uriLabel'; used(); @@ -226,7 +226,7 @@ class WelcomePage { @IWorkspaceContextService private contextService: IWorkspaceContextService, @IConfigurationService private configurationService: IConfigurationService, @IEnvironmentService private environmentService: IEnvironmentService, - @IUriDisplayService private uriDisplayService: IUriDisplayService, + @IUriLabelService private uriLabelService: IUriLabelService, @INotificationService private notificationService: INotificationService, @IExtensionEnablementService private extensionEnablementService: IExtensionEnablementService, @IExtensionGalleryService private extensionGalleryService: IExtensionGalleryService, @@ -283,9 +283,9 @@ class WelcomePage { let resource: URI; if (isSingleFolderWorkspaceIdentifier(workspace)) { resource = workspace; - label = getWorkspaceLabel(workspace, this.environmentService, this.uriDisplayService); + label = getWorkspaceLabel(workspace, this.environmentService, this.uriLabelService); } else if (isWorkspaceIdentifier(workspace)) { - label = getWorkspaceLabel(workspace, this.environmentService, this.uriDisplayService); + label = getWorkspaceLabel(workspace, this.environmentService, this.uriLabelService); resource = URI.file(workspace.configPath); } else { label = getBaseLabel(workspace); @@ -307,7 +307,7 @@ class WelcomePage { } parentFolderPath = tildify(parentFolder, this.environmentService.userHome); } else { - parentFolderPath = this.uriDisplayService.getLabel(resource); + parentFolderPath = this.uriLabelService.getLabel(resource); } diff --git a/src/vs/workbench/services/bulkEdit/electron-browser/bulkEditService.ts b/src/vs/workbench/services/bulkEdit/electron-browser/bulkEditService.ts index 7fb340f111a..e120c966d99 100644 --- a/src/vs/workbench/services/bulkEdit/electron-browser/bulkEditService.ts +++ b/src/vs/workbench/services/bulkEdit/electron-browser/bulkEditService.ts @@ -24,7 +24,7 @@ import { ILogService } from 'vs/platform/log/common/log'; import { emptyProgressRunner, IProgress, IProgressRunner } from 'vs/platform/progress/common/progress'; import { IEditorService } from 'vs/workbench/services/editor/common/editorService'; import { ITextFileService } from 'vs/workbench/services/textfile/common/textfiles'; -import { IUriDisplayService } from 'vs/platform/uriDisplay/common/uriDisplay'; +import { IUriLabelService } from 'vs/platform/uriLabel/common/uriLabel'; abstract class Recording { @@ -233,7 +233,7 @@ export class BulkEdit { @ITextModelService private readonly _textModelService: ITextModelService, @IFileService private readonly _fileService: IFileService, @ITextFileService private readonly _textFileService: ITextFileService, - @IUriDisplayService private readonly _uriDisplayServie: IUriDisplayService + @IUriLabelService private readonly _uriLabelServie: IUriLabelService ) { this._editor = editor; this._progress = progress || emptyProgressRunner; @@ -339,7 +339,7 @@ export class BulkEdit { const conflicts = edits .filter(edit => recording.hasChanged(edit.resource)) - .map(edit => this._uriDisplayServie.getLabel(edit.resource, true)); + .map(edit => this._uriLabelServie.getLabel(edit.resource, true)); recording.stop(); @@ -369,7 +369,7 @@ export class BulkEditService implements IBulkEditService { @ITextModelService private readonly _textModelService: ITextModelService, @IFileService private readonly _fileService: IFileService, @ITextFileService private readonly _textFileService: ITextFileService, - @IUriDisplayService private readonly _uriDisplayService: IUriDisplayService + @IUriLabelService private readonly _uriLabelService: IUriLabelService ) { } @@ -400,7 +400,7 @@ export class BulkEditService implements IBulkEditService { } } - const bulkEdit = new BulkEdit(options.editor, options.progress, this._logService, this._textModelService, this._fileService, this._textFileService, this._uriDisplayService); + const bulkEdit = new BulkEdit(options.editor, options.progress, this._logService, this._textModelService, this._fileService, this._textFileService, this._uriLabelService); bulkEdit.add(edits); return TPromise.wrap(bulkEdit.perform().then(() => { diff --git a/src/vs/workbench/services/configuration/node/configurationService.ts b/src/vs/workbench/services/configuration/node/configurationService.ts index 02320795944..e954cacc4e1 100644 --- a/src/vs/workbench/services/configuration/node/configurationService.ts +++ b/src/vs/workbench/services/configuration/node/configurationService.ts @@ -41,7 +41,7 @@ import { UserConfiguration } from 'vs/platform/configuration/node/configuration' import { IJSONSchema, IJSONSchemaMap } from 'vs/base/common/jsonSchema'; import { localize } from 'vs/nls'; import { isEqual, hasToIgnoreCase } from 'vs/base/common/resources'; -import { IUriDisplayService } from 'vs/platform/uriDisplay/common/uriDisplay'; +import { IUriLabelService } from 'vs/platform/uriLabel/common/uriLabel'; export class WorkspaceService extends Disposable implements IWorkspaceConfigurationService, IWorkspaceContextService { @@ -69,7 +69,7 @@ export class WorkspaceService extends Disposable implements IWorkspaceConfigurat public readonly onDidChangeWorkbenchState: Event = this._onDidChangeWorkbenchState.event; private fileService: IFileService; - private uriDisplayService: IUriDisplayService; + private uriLabelService: IUriLabelService; private configurationEditingService: ConfigurationEditingService; private jsonEditingService: JSONEditingService; @@ -319,8 +319,8 @@ export class WorkspaceService extends Disposable implements IWorkspaceConfigurat }); } - acquireUriDisplayService(uriDisplayService: IUriDisplayService): void { - this.uriDisplayService = uriDisplayService; + acquireUriLabelService(uriLabelService: IUriLabelService): void { + this.uriLabelService = uriLabelService; } acquireInstantiationService(instantiationService: IInstantiationService): void { @@ -346,7 +346,7 @@ export class WorkspaceService extends Disposable implements IWorkspaceConfigurat .then(() => { const workspaceFolders = toWorkspaceFolders(this.workspaceConfiguration.getFolders(), URI.file(dirname(workspaceConfigPath.fsPath))); const workspaceId = workspaceIdentifier.id; - const workspaceName = getWorkspaceLabel({ id: workspaceId, configPath: workspaceConfigPath.fsPath }, this.environmentService, this.uriDisplayService); + const workspaceName = getWorkspaceLabel({ id: workspaceId, configPath: workspaceConfigPath.fsPath }, this.environmentService, this.uriLabelService); return new Workspace(workspaceId, workspaceName, workspaceFolders, workspaceConfigPath); }); } @@ -369,11 +369,11 @@ export class WorkspaceService extends Disposable implements IWorkspaceConfigurat } const id = createHash('md5').update(folder.fsPath).update(ctime ? String(ctime) : '').digest('hex'); - return new Workspace(id, getWorkspaceLabel(folder, this.environmentService, this.uriDisplayService), toWorkspaceFolders([{ path: folder.fsPath }]), null, ctime); + return new Workspace(id, getWorkspaceLabel(folder, this.environmentService, this.uriLabelService), toWorkspaceFolders([{ path: folder.fsPath }]), null, ctime); }); } else { const id = createHash('md5').update(folder.toString()).digest('hex'); - return TPromise.as(new Workspace(id, getWorkspaceLabel(folder, this.environmentService, this.uriDisplayService), toWorkspaceFolders([{ uri: folder.toString() }]), null)); + return TPromise.as(new Workspace(id, getWorkspaceLabel(folder, this.environmentService, this.uriLabelService), toWorkspaceFolders([{ uri: folder.toString() }]), null)); } } diff --git a/src/vs/workbench/services/editor/browser/editorService.ts b/src/vs/workbench/services/editor/browser/editorService.ts index 6250d63c405..32c50e0a867 100644 --- a/src/vs/workbench/services/editor/browser/editorService.ts +++ b/src/vs/workbench/services/editor/browser/editorService.ts @@ -28,7 +28,7 @@ import { Disposable, IDisposable, dispose, toDisposable } from 'vs/base/common/l import { coalesce } from 'vs/base/common/arrays'; import { isCodeEditor, isDiffEditor, ICodeEditor, IDiffEditor } from 'vs/editor/browser/editorBrowser'; import { IEditorGroupView, IEditorOpeningEvent, EditorGroupsServiceImpl, EditorServiceImpl } from 'vs/workbench/browser/parts/editor/editor'; -import { IUriDisplayService } from 'vs/platform/uriDisplay/common/uriDisplay'; +import { IUriLabelService } from 'vs/platform/uriLabel/common/uriLabel'; type ICachedEditorInput = ResourceEditorInput | IFileEditorInput | DataUriEditorInput; @@ -64,7 +64,7 @@ export class EditorService extends Disposable implements EditorServiceImpl { @IEditorGroupsService private editorGroupService: EditorGroupsServiceImpl, @IUntitledEditorService private untitledEditorService: IUntitledEditorService, @IInstantiationService private instantiationService: IInstantiationService, - @IUriDisplayService private uriDisplayService: IUriDisplayService, + @IUriLabelService private uriLabelService: IUriLabelService, @IFileService private fileService: IFileService, @IConfigurationService private configurationService: IConfigurationService ) { @@ -563,7 +563,7 @@ export class EditorService extends Disposable implements EditorServiceImpl { } // Otherwise: for diff labels prefer to see the path as part of the label - return this.uriDisplayService.getLabel(res, true); + return this.uriLabelService.getLabel(res, true); } //#endregion @@ -584,7 +584,7 @@ export class DelegatingEditorService extends EditorService { @IEditorGroupsService editorGroupService: EditorGroupsServiceImpl, @IUntitledEditorService untitledEditorService: IUntitledEditorService, @IInstantiationService instantiationService: IInstantiationService, - @IUriDisplayService uriDisplayService: IUriDisplayService, + @IUriLabelService uriLabelService: IUriLabelService, @IFileService fileService: IFileService, @IConfigurationService configurationService: IConfigurationService ) { @@ -592,7 +592,7 @@ export class DelegatingEditorService extends EditorService { editorGroupService, untitledEditorService, instantiationService, - uriDisplayService, + uriLabelService, fileService, configurationService ); diff --git a/src/vs/workbench/services/preferences/browser/preferencesService.ts b/src/vs/workbench/services/preferences/browser/preferencesService.ts index 1c87721d27a..8954289dfeb 100644 --- a/src/vs/workbench/services/preferences/browser/preferencesService.ts +++ b/src/vs/workbench/services/preferences/browser/preferencesService.ts @@ -36,7 +36,7 @@ import { INotificationService } from 'vs/platform/notification/common/notificati import { assign } from 'vs/base/common/objects'; import { IEditorService } from 'vs/workbench/services/editor/common/editorService'; import { IEditorGroup, IEditorGroupsService, GroupDirection } from 'vs/workbench/services/group/common/editorGroupsService'; -import { IUriDisplayService } from 'vs/platform/uriDisplay/common/uriDisplay'; +import { IUriLabelService } from 'vs/platform/uriLabel/common/uriLabel'; const emptyEditableSettingsContent = '{\n}'; @@ -70,7 +70,7 @@ export class PreferencesService extends Disposable implements IPreferencesServic @IModelService private modelService: IModelService, @IJSONEditingService private jsonEditingService: IJSONEditingService, @IModeService private modeService: IModeService, - @IUriDisplayService private uriDisplayService: IUriDisplayService + @IUriLabelService private uriLabelService: IUriLabelService ) { super(); // The default keybindings.json updates based on keyboard layouts, so here we make sure @@ -445,7 +445,7 @@ export class PreferencesService extends Disposable implements IPreferencesServic return this.fileService.resolveContent(resource, { acceptTextOnly: true }).then(null, error => { if ((error).fileOperationResult === FileOperationResult.FILE_NOT_FOUND) { return this.fileService.updateContent(resource, contents).then(null, error => { - return TPromise.wrapError(new Error(nls.localize('fail.createSettings', "Unable to create '{0}' ({1}).", this.uriDisplayService.getLabel(resource, true), error))); + return TPromise.wrapError(new Error(nls.localize('fail.createSettings', "Unable to create '{0}' ({1}).", this.uriLabelService.getLabel(resource, true), error))); }); } diff --git a/src/vs/workbench/test/electron-browser/api/mainThreadEditors.test.ts b/src/vs/workbench/test/electron-browser/api/mainThreadEditors.test.ts index b9728fac684..55d3113842c 100644 --- a/src/vs/workbench/test/electron-browser/api/mainThreadEditors.test.ts +++ b/src/vs/workbench/test/electron-browser/api/mainThreadEditors.test.ts @@ -28,7 +28,7 @@ import { BulkEditService } from 'vs/workbench/services/bulkEdit/electron-browser import { NullLogService } from 'vs/platform/log/common/log'; import { ITextModelService, ITextEditorModel } from 'vs/editor/common/services/resolverService'; import { IReference, ImmortalReference } from 'vs/base/common/lifecycle'; -import { UriDisplayService } from 'vs/platform/uriDisplay/common/uriDisplay'; +import { UriLabelService } from 'vs/platform/uriLabel/common/uriLabel'; suite('MainThreadEditors', () => { @@ -83,7 +83,7 @@ suite('MainThreadEditors', () => { } }; - const bulkEditService = new BulkEditService(new NullLogService(), modelService, new TestEditorService(), textModelService, new TestFileService(), textFileService, new UriDisplayService(TestEnvironmentService, new TestContextService())); + const bulkEditService = new BulkEditService(new NullLogService(), modelService, new TestEditorService(), textModelService, new TestFileService(), textFileService, new UriLabelService(TestEnvironmentService, new TestContextService())); const rpcProtocol = new TestRPCProtocol(); rpcProtocol.set(ExtHostContext.ExtHostDocuments, new class extends mock() { diff --git a/src/vs/workbench/test/workbenchTestServices.ts b/src/vs/workbench/test/workbenchTestServices.ts index f66a8628123..d7155fb2d67 100644 --- a/src/vs/workbench/test/workbenchTestServices.ts +++ b/src/vs/workbench/test/workbenchTestServices.ts @@ -75,7 +75,7 @@ import { IDecorationRenderOptions } from 'vs/editor/common/editorCommon'; import { EditorGroup } from 'vs/workbench/common/editor/editorGroup'; import { Dimension } from 'vs/base/browser/dom'; import { ILogService, LogLevel } from 'vs/platform/log/common/log'; -import { IUriDisplayService, UriDisplayService } from 'vs/platform/uriDisplay/common/uriDisplay'; +import { IUriLabelService, UriLabelService } from 'vs/platform/uriLabel/common/uriLabel'; export function createFileInput(instantiationService: IInstantiationService, resource: URI): FileEditorInput { return instantiationService.createInstance(FileEditorInput, resource, void 0); @@ -271,7 +271,7 @@ export function workbenchInstantiationService(): IInstantiationService { instantiationService.stub(IHashService, new TestHashService()); instantiationService.stub(ILogService, new TestLogService()); instantiationService.stub(IEditorGroupsService, new TestEditorGroupsService([new TestEditorGroup(0)])); - instantiationService.stub(IUriDisplayService, new UriDisplayService(TestEnvironmentService, workspaceContextService)); + instantiationService.stub(IUriLabelService, new UriLabelService(TestEnvironmentService, workspaceContextService)); const editorService = new TestEditorService(); instantiationService.stub(IEditorService, editorService); instantiationService.stub(ICodeEditorService, new TestCodeEditorService()); diff --git a/src/vs/workbench/workbench.main.ts b/src/vs/workbench/workbench.main.ts index bab2fdcc700..184ccb27ce7 100644 --- a/src/vs/workbench/workbench.main.ts +++ b/src/vs/workbench/workbench.main.ts @@ -17,7 +17,7 @@ import 'vs/editor/editor.all'; // Platform import 'vs/platform/widget/browser/contextScopedHistoryWidget'; -import 'vs/platform/uriDisplay/electron-browser/uriDisplay.contribution'; +import 'vs/platform/uriLabel/electron-browser/uriLabel.contribution'; // Menus/Actions import 'vs/workbench/services/actions/electron-browser/menusExtensionPoint'; From c5a73b8c25509b99a65986f8d65fcb033c40fde5 Mon Sep 17 00:00:00 2001 From: Johannes Rieken Date: Wed, 15 Aug 2018 17:45:48 +0200 Subject: [PATCH 0837/1276] update config util, #56302 --- .../browser/parts/editor/breadcrumbs.ts | 27 +++++++++++-------- .../parts/editor/breadcrumbsControl.ts | 6 ++--- .../browser/parts/editor/breadcrumbsModel.ts | 8 +++--- .../browser/parts/editor/titleControl.ts | 2 +- 4 files changed, 24 insertions(+), 19 deletions(-) diff --git a/src/vs/workbench/browser/parts/editor/breadcrumbs.ts b/src/vs/workbench/browser/parts/editor/breadcrumbs.ts index e0e5dfa0fc8..934697eb698 100644 --- a/src/vs/workbench/browser/parts/editor/breadcrumbs.ts +++ b/src/vs/workbench/browser/parts/editor/breadcrumbs.ts @@ -57,8 +57,10 @@ registerSingleton(IBreadcrumbsService, BreadcrumbsService); export abstract class BreadcrumbsConfig { name: string; - value: T; onDidChange: Event; + + abstract value(): T; + abstract value(value: T): Thenable; abstract dispose(): void; private constructor() { @@ -83,16 +85,19 @@ export abstract class BreadcrumbsConfig { } }); - return { - name, - get value() { - return value; - }, - set value(newValue: T) { - service.updateValue(name, newValue); - value = newValue; - }, - onDidChange: onDidChange.event, + return new class implements BreadcrumbsConfig{ + readonly name = name; + readonly onDidChange = onDidChange.event; + value(): T; + value(value: T): Thenable; + value(newValue?: T): any { + if (arguments.length === 0) { + return value; + } else { + value = newValue; + return service.updateValue(name, newValue); + } + } dispose(): void { listener.dispose(); onDidChange.dispose(); diff --git a/src/vs/workbench/browser/parts/editor/breadcrumbsControl.ts b/src/vs/workbench/browser/parts/editor/breadcrumbsControl.ts index 5936369fb46..8b312a086fd 100644 --- a/src/vs/workbench/browser/parts/editor/breadcrumbsControl.ts +++ b/src/vs/workbench/browser/parts/editor/breadcrumbsControl.ts @@ -270,7 +270,7 @@ export class BreadcrumbsControl { return; } - if (this._cfUseQuickPick.value) { + if (this._cfUseQuickPick.value()) { // using quick pick this._widget.setFocused(undefined); this._widget.setSelection(undefined); @@ -383,8 +383,8 @@ MenuRegistry.appendMenuItem(MenuId.MenubarViewMenu, { }); CommandsRegistry.registerCommand('breadcrumbs.toggle', accessor => { let config = accessor.get(IConfigurationService); - let value = BreadcrumbsConfig.IsEnabled.bindTo(config).value; - BreadcrumbsConfig.IsEnabled.bindTo(config).value = !value; + let value = BreadcrumbsConfig.IsEnabled.bindTo(config).value(); + BreadcrumbsConfig.IsEnabled.bindTo(config).value(!value); }); MenuRegistry.appendMenuItem(MenuId.CommandPalette, { diff --git a/src/vs/workbench/browser/parts/editor/breadcrumbsModel.ts b/src/vs/workbench/browser/parts/editor/breadcrumbsModel.ts index 142765257c1..0413ced3d63 100644 --- a/src/vs/workbench/browser/parts/editor/breadcrumbsModel.ts +++ b/src/vs/workbench/browser/parts/editor/breadcrumbsModel.ts @@ -81,16 +81,16 @@ export class EditorBreadcrumbsModel { let result: BreadcrumbElement[] = []; // file path elements - if (this._cfgFilePath.value === 'on') { + if (this._cfgFilePath.value() === 'on') { result = result.concat(this._fileInfo.path); - } else if (this._cfgFilePath.value === 'last' && this._fileInfo.path.length > 0) { + } else if (this._cfgFilePath.value() === 'last' && this._fileInfo.path.length > 0) { result = result.concat(this._fileInfo.path.slice(-1)); } // symbol path elements - if (this._cfgSymbolPath.value === 'on') { + if (this._cfgSymbolPath.value() === 'on') { result = result.concat(this._outlineElements); - } else if (this._cfgSymbolPath.value === 'last' && this._outlineElements.length > 0) { + } else if (this._cfgSymbolPath.value() === 'last' && this._outlineElements.length > 0) { result = result.concat(this._outlineElements.slice(-1)); } diff --git a/src/vs/workbench/browser/parts/editor/titleControl.ts b/src/vs/workbench/browser/parts/editor/titleControl.ts index ff452e13d8e..def12980c11 100644 --- a/src/vs/workbench/browser/parts/editor/titleControl.ts +++ b/src/vs/workbench/browser/parts/editor/titleControl.ts @@ -108,7 +108,7 @@ export abstract class TitleControl extends Themable { this.handleBreadcrumbsEnablementChange(); } })); - if (config.value) { + if (config.value()) { this.breadcrumbsControl = this.instantiationService.createInstance(BreadcrumbsControl, container, options, this.group); } } From c87cbe6376f49f4991c873253ce46ac0157cdb7c Mon Sep 17 00:00:00 2001 From: Johannes Rieken Date: Wed, 15 Aug 2018 17:55:28 +0200 Subject: [PATCH 0838/1276] fix #56302 --- .../parts/editor/breadcrumbsControl.ts | 51 +++++++++++-------- 1 file changed, 29 insertions(+), 22 deletions(-) diff --git a/src/vs/workbench/browser/parts/editor/breadcrumbsControl.ts b/src/vs/workbench/browser/parts/editor/breadcrumbsControl.ts index 8b312a086fd..0511af5b128 100644 --- a/src/vs/workbench/browser/parts/editor/breadcrumbsControl.ts +++ b/src/vs/workbench/browser/parts/editor/breadcrumbsControl.ts @@ -22,7 +22,7 @@ import { IConfigurationService } from 'vs/platform/configuration/common/configur import { ContextKeyExpr, IContextKey, IContextKeyService, RawContextKey } from 'vs/platform/contextkey/common/contextkey'; import { IContextViewService } from 'vs/platform/contextview/browser/contextView'; import { FileKind, IFileService } from 'vs/platform/files/common/files'; -import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; +import { IInstantiationService, ServicesAccessor } from 'vs/platform/instantiation/common/instantiation'; import { KeybindingsRegistry, KeybindingWeight } from 'vs/platform/keybinding/common/keybindingsRegistry'; import { IQuickOpenService } from 'vs/platform/quickOpen/common/quickOpen'; import { attachBreadcrumbsStyler } from 'vs/platform/theme/common/styler'; @@ -41,6 +41,7 @@ import { CommandsRegistry } from 'vs/platform/commands/common/commands'; import { tail } from 'vs/base/common/arrays'; import { WorkbenchListFocusContextKey } from 'vs/platform/list/browser/listService'; import { ColorIdentifier } from 'vs/platform/theme/common/colorRegistry'; +import { timeout } from 'vs/base/common/async'; class Item extends BreadcrumbsItem { @@ -366,6 +367,7 @@ export class BreadcrumbsControl { //#region commands +// toggle command MenuRegistry.appendMenuItem(MenuId.CommandPalette, { command: { id: 'breadcrumbs.toggle', @@ -387,6 +389,27 @@ CommandsRegistry.registerCommand('breadcrumbs.toggle', accessor => { BreadcrumbsConfig.IsEnabled.bindTo(config).value(!value); }); +// focus/focus-and-select +async function focusAndSelectHandler(accessor: ServicesAccessor, select: boolean): Promise { + const groups = accessor.get(IEditorGroupsService); + const breadcrumbs = accessor.get(IBreadcrumbsService); + const config = accessor.get(IConfigurationService); + // check if enabled and iff not enable + const isEnabled = BreadcrumbsConfig.IsEnabled.bindTo(config); + if (!isEnabled.value()) { + await isEnabled.value(true); + await timeout(50); // hacky - the widget might not be ready yet... + } + // find widget and focus/select + const widget = breadcrumbs.getWidget(groups.activeGroup.id); + if (widget) { + const item = tail(widget.getItems()); + widget.setFocused(item); + if (select) { + widget.setSelection(item, BreadcrumbsControl.Payload_Pick); + } + } +} MenuRegistry.appendMenuItem(MenuId.CommandPalette, { command: { id: 'breadcrumbs.focusAndSelect', @@ -398,34 +421,18 @@ KeybindingsRegistry.registerCommandAndKeybindingRule({ id: 'breadcrumbs.focusAndSelect', weight: KeybindingWeight.WorkbenchContrib, primary: KeyMod.CtrlCmd | KeyMod.Shift | KeyCode.US_DOT, - when: BreadcrumbsControl.CK_BreadcrumbsVisible, - handler(accessor) { - const groups = accessor.get(IEditorGroupsService); - const breadcrumbs = accessor.get(IBreadcrumbsService); - const widget = breadcrumbs.getWidget(groups.activeGroup.id); - if (widget) { - const item = tail(widget.getItems()); - widget.setFocused(item); - widget.setSelection(item, BreadcrumbsControl.Payload_Pick); - } - } + when: undefined, + handler: accessor => focusAndSelectHandler(accessor, true) }); KeybindingsRegistry.registerCommandAndKeybindingRule({ id: 'breadcrumbs.focus', weight: KeybindingWeight.WorkbenchContrib, primary: KeyMod.CtrlCmd | KeyMod.Shift | KeyCode.US_SEMICOLON, - when: BreadcrumbsControl.CK_BreadcrumbsVisible, - handler(accessor) { - const groups = accessor.get(IEditorGroupsService); - const breadcrumbs = accessor.get(IBreadcrumbsService); - const widget = breadcrumbs.getWidget(groups.activeGroup.id); - if (widget) { - const item = tail(widget.getItems()); - widget.setFocused(item); - } - } + when: undefined, + handler: accessor => focusAndSelectHandler(accessor, false) }); +// navigation KeybindingsRegistry.registerCommandAndKeybindingRule({ id: 'breadcrumbs.focusNext', weight: KeybindingWeight.WorkbenchContrib, From 059cc5b66f51c7c422da958e6901f0252fcc3c6a Mon Sep 17 00:00:00 2001 From: Johannes Rieken Date: Wed, 15 Aug 2018 18:20:09 +0200 Subject: [PATCH 0839/1276] fix unhandled error --- src/vs/workbench/api/node/extHostDecorations.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vs/workbench/api/node/extHostDecorations.ts b/src/vs/workbench/api/node/extHostDecorations.ts index 1cc31088fe1..9d1e58cfa35 100644 --- a/src/vs/workbench/api/node/extHostDecorations.ts +++ b/src/vs/workbench/api/node/extHostDecorations.ts @@ -53,7 +53,7 @@ export class ExtHostDecorations implements ExtHostDecorationsShape { } const { provider, extensionId } = this._provider.get(handle); return asWinJsPromise(token => provider.provideDecoration(URI.revive(uri), token)).then(data => { - if (data.letter && data.letter.length !== 1) { + if (data && data.letter && data.letter.length !== 1) { console.warn(`INVALID decoration from extension '${extensionId}'. The 'letter' must be set and be one character, not '${data.letter}'.`); } result[id] = data && [data.priority, data.bubble, data.title, data.letter, data.color, data.source]; From 53cfd4e21e0a819a4ec0b89fb07c872dcb6d2f0a Mon Sep 17 00:00:00 2001 From: Martin Aeschlimann Date: Wed, 15 Aug 2018 18:38:23 +0200 Subject: [PATCH 0840/1276] VS Code Hangs When Opening Specific PowerShell File. Fixes #56430 --- .../syntaxes/powershell.tmLanguage.json | 212 +++----- .../test/colorize-results/test_ps1.json | 514 ++++++------------ 2 files changed, 254 insertions(+), 472 deletions(-) diff --git a/extensions/powershell/syntaxes/powershell.tmLanguage.json b/extensions/powershell/syntaxes/powershell.tmLanguage.json index 0e3c0dbe84a..60dee137b19 100644 --- a/extensions/powershell/syntaxes/powershell.tmLanguage.json +++ b/extensions/powershell/syntaxes/powershell.tmLanguage.json @@ -4,7 +4,7 @@ "If you want to provide a fix or improvement, please create a pull request against the original repository.", "Once accepted there, we are happy to receive an update request." ], - "version": "https://github.com/PowerShell/EditorSyntax/commit/472c9447da4e3160bef211d5e1a0c2dee3cce497", + "version": "https://github.com/PowerShell/EditorSyntax/commit/6f5438611c54922ea94c81532a2dcfee72190039", "name": "PowerShell", "scopeName": "source.powershell", "patterns": [ @@ -71,17 +71,7 @@ }, { "begin": "(?&1 & set", + "c": " 2>&1 & set\"", "t": "source.powershell meta.scriptblock.powershell interpolated.simple.source.powershell string.quoted.double.powershell", "r": { "dark_plus": "string: #CE9178", @@ -1209,17 +1187,6 @@ "hc_black": "string: #CE9178" } }, - { - "c": "\"", - "t": "source.powershell meta.scriptblock.powershell interpolated.simple.source.powershell string.quoted.double.powershell punctuation.definition.string.end.powershell", - "r": { - "dark_plus": "string: #CE9178", - "light_plus": "string: #A31515", - "dark_vs": "string: #CE9178", - "light_vs": "string: #A31515", - "hc_black": "string: #CE9178" - } - }, { "c": ")", "t": "source.powershell meta.scriptblock.powershell punctuation.section.group.end.powershell", @@ -1299,13 +1266,13 @@ }, { "c": "$", - "t": "source.powershell meta.scriptblock.powershell meta.scriptblock.powershell interpolated.simple.source.powershell support.constant.automatic.powershell punctuation.definition.variable.powershell", + "t": "source.powershell meta.scriptblock.powershell meta.scriptblock.powershell interpolated.simple.source.powershell keyword.other.variable.definition.powershell", "r": { - "dark_plus": "default: #D4D4D4", - "light_plus": "default: #000000", - "dark_vs": "default: #D4D4D4", - "light_vs": "default: #000000", - "hc_black": "default: #FFFFFF" + "dark_plus": "keyword: #569CD6", + "light_plus": "keyword: #0000FF", + "dark_vs": "keyword: #569CD6", + "light_vs": "keyword: #0000FF", + "hc_black": "keyword: #569CD6" } }, { @@ -1353,18 +1320,7 @@ } }, { - "c": "'", - "t": "source.powershell meta.scriptblock.powershell meta.scriptblock.powershell interpolated.simple.source.powershell string.quoted.single.powershell punctuation.definition.string.begin.powershell", - "r": { - "dark_plus": "string: #CE9178", - "light_plus": "string: #A31515", - "dark_vs": "string: #CE9178", - "light_vs": "string: #A31515", - "hc_black": "string: #CE9178" - } - }, - { - "c": "^([^=]+)=(.*)", + "c": "'^([^=]+)=(.*)'", "t": "source.powershell meta.scriptblock.powershell meta.scriptblock.powershell interpolated.simple.source.powershell string.quoted.single.powershell", "r": { "dark_plus": "string: #CE9178", @@ -1374,17 +1330,6 @@ "hc_black": "string: #CE9178" } }, - { - "c": "'", - "t": "source.powershell meta.scriptblock.powershell meta.scriptblock.powershell interpolated.simple.source.powershell string.quoted.single.powershell punctuation.definition.string.end.powershell", - "r": { - "dark_plus": "string: #CE9178", - "light_plus": "string: #A31515", - "dark_vs": "string: #CE9178", - "light_vs": "string: #A31515", - "hc_black": "string: #CE9178" - } - }, { "c": ")", "t": "source.powershell meta.scriptblock.powershell meta.scriptblock.powershell punctuation.section.group.end.powershell", @@ -1486,13 +1431,13 @@ }, { "c": "$", - "t": "source.powershell meta.scriptblock.powershell meta.scriptblock.powershell meta.scriptblock.powershell interpolated.simple.source.powershell support.constant.automatic.powershell punctuation.definition.variable.powershell", + "t": "source.powershell meta.scriptblock.powershell meta.scriptblock.powershell meta.scriptblock.powershell interpolated.simple.source.powershell keyword.other.variable.definition.powershell", "r": { - "dark_plus": "default: #D4D4D4", - "light_plus": "default: #000000", - "dark_vs": "default: #D4D4D4", - "light_vs": "default: #000000", - "hc_black": "default: #FFFFFF" + "dark_plus": "keyword: #569CD6", + "light_plus": "keyword: #0000FF", + "dark_vs": "keyword: #569CD6", + "light_vs": "keyword: #0000FF", + "hc_black": "keyword: #569CD6" } }, { @@ -1563,13 +1508,13 @@ }, { "c": "$", - "t": "source.powershell meta.scriptblock.powershell meta.scriptblock.powershell meta.scriptblock.powershell interpolated.simple.source.powershell support.constant.automatic.powershell punctuation.definition.variable.powershell", + "t": "source.powershell meta.scriptblock.powershell meta.scriptblock.powershell meta.scriptblock.powershell interpolated.simple.source.powershell keyword.other.variable.definition.powershell", "r": { - "dark_plus": "default: #D4D4D4", - "light_plus": "default: #000000", - "dark_vs": "default: #D4D4D4", - "light_vs": "default: #000000", - "hc_black": "default: #FFFFFF" + "dark_plus": "keyword: #569CD6", + "light_plus": "keyword: #0000FF", + "dark_vs": "keyword: #569CD6", + "light_vs": "keyword: #0000FF", + "hc_black": "keyword: #569CD6" } }, { @@ -1727,18 +1672,7 @@ } }, { - "c": "'", - "t": "source.powershell string.quoted.single.powershell punctuation.definition.string.begin.powershell", - "r": { - "dark_plus": "string: #CE9178", - "light_plus": "string: #A31515", - "dark_vs": "string: #CE9178", - "light_vs": "string: #A31515", - "hc_black": "string: #CE9178" - } - }, - { - "c": "Initializing Azure PowerShell environment...", + "c": "'Initializing Azure PowerShell environment...'", "t": "source.powershell string.quoted.single.powershell", "r": { "dark_plus": "string: #CE9178", @@ -1748,26 +1682,15 @@ "hc_black": "string: #CE9178" } }, - { - "c": "'", - "t": "source.powershell string.quoted.single.powershell punctuation.definition.string.end.powershell", - "r": { - "dark_plus": "string: #CE9178", - "light_plus": "string: #A31515", - "dark_vs": "string: #CE9178", - "light_vs": "string: #A31515", - "hc_black": "string: #CE9178" - } - }, { "c": ";", - "t": "source.powershell punctuation.terminator.statement.powershell", + "t": "source.powershell keyword.other.statement-separator.powershell", "r": { - "dark_plus": "default: #D4D4D4", - "light_plus": "default: #000000", - "dark_vs": "default: #D4D4D4", - "light_vs": "default: #000000", - "hc_black": "default: #FFFFFF" + "dark_plus": "keyword: #569CD6", + "light_plus": "keyword: #0000FF", + "dark_vs": "keyword: #569CD6", + "light_vs": "keyword: #0000FF", + "hc_black": "keyword: #569CD6" } }, { @@ -1947,18 +1870,7 @@ } }, { - "c": "'", - "t": "source.powershell meta.scriptblock.powershell string.quoted.single.powershell punctuation.definition.string.begin.powershell", - "r": { - "dark_plus": "string: #CE9178", - "light_plus": "string: #A31515", - "dark_vs": "string: #CE9178", - "light_vs": "string: #A31515", - "hc_black": "string: #CE9178" - } - }, - { - "c": "Please launch command under administrator account. It is needed for environment setting up and unit test.", + "c": "'Please launch command under administrator account. It is needed for environment setting up and unit test.'", "t": "source.powershell meta.scriptblock.powershell string.quoted.single.powershell", "r": { "dark_plus": "string: #CE9178", @@ -1968,17 +1880,6 @@ "hc_black": "string: #CE9178" } }, - { - "c": "'", - "t": "source.powershell meta.scriptblock.powershell string.quoted.single.powershell punctuation.definition.string.end.powershell", - "r": { - "dark_plus": "string: #CE9178", - "light_plus": "string: #A31515", - "dark_vs": "string: #CE9178", - "light_vs": "string: #A31515", - "hc_black": "string: #CE9178" - } - }, { "c": " ", "t": "source.powershell meta.scriptblock.powershell", @@ -2014,13 +1915,13 @@ }, { "c": ";", - "t": "source.powershell meta.scriptblock.powershell punctuation.terminator.statement.powershell", + "t": "source.powershell meta.scriptblock.powershell keyword.other.statement-separator.powershell", "r": { - "dark_plus": "default: #D4D4D4", - "light_plus": "default: #000000", - "dark_vs": "default: #D4D4D4", - "light_vs": "default: #000000", - "hc_black": "default: #FFFFFF" + "dark_plus": "keyword: #569CD6", + "light_plus": "keyword: #0000FF", + "dark_vs": "keyword: #569CD6", + "light_vs": "keyword: #0000FF", + "hc_black": "keyword: #569CD6" } }, { @@ -2036,18 +1937,18 @@ }, { "c": "$", - "t": "source.powershell variable.other.readwrite.powershell punctuation.definition.variable.powershell", + "t": "source.powershell keyword.other.variable.definition.powershell", "r": { - "dark_plus": "variable: #9CDCFE", - "light_plus": "variable: #001080", - "dark_vs": "default: #D4D4D4", - "light_vs": "default: #000000", - "hc_black": "variable: #9CDCFE" + "dark_plus": "keyword: #569CD6", + "light_plus": "keyword: #0000FF", + "dark_vs": "keyword: #569CD6", + "light_vs": "keyword: #0000FF", + "hc_black": "keyword: #569CD6" } }, { "c": "env:", - "t": "source.powershell variable.other.readwrite.powershell support.variable.drive.powershell", + "t": "source.powershell support.variable.drive.powershell", "r": { "dark_plus": "support.variable: #9CDCFE", "light_plus": "support.variable: #001080", @@ -2168,18 +2069,18 @@ }, { "c": "$", - "t": "source.powershell variable.other.readwrite.powershell punctuation.definition.variable.powershell", + "t": "source.powershell keyword.other.variable.definition.powershell", "r": { - "dark_plus": "variable: #9CDCFE", - "light_plus": "variable: #001080", - "dark_vs": "default: #D4D4D4", - "light_vs": "default: #000000", - "hc_black": "variable: #9CDCFE" + "dark_plus": "keyword: #569CD6", + "light_plus": "keyword: #0000FF", + "dark_vs": "keyword: #569CD6", + "light_vs": "keyword: #0000FF", + "hc_black": "keyword: #569CD6" } }, { "c": "env:", - "t": "source.powershell variable.other.readwrite.powershell support.variable.drive.powershell", + "t": "source.powershell support.variable.drive.powershell", "r": { "dark_plus": "support.variable: #9CDCFE", "light_plus": "support.variable: #001080", @@ -2201,13 +2102,13 @@ }, { "c": ";", - "t": "source.powershell punctuation.terminator.statement.powershell", + "t": "source.powershell keyword.other.statement-separator.powershell", "r": { - "dark_plus": "default: #D4D4D4", - "light_plus": "default: #000000", - "dark_vs": "default: #D4D4D4", - "light_vs": "default: #000000", - "hc_black": "default: #FFFFFF" + "dark_plus": "keyword: #569CD6", + "light_plus": "keyword: #0000FF", + "dark_vs": "keyword: #569CD6", + "light_vs": "keyword: #0000FF", + "hc_black": "keyword: #569CD6" } }, { @@ -2289,7 +2190,7 @@ }, { "c": "\"", - "t": "source.powershell interpolated.simple.source.powershell string.quoted.double.powershell punctuation.definition.string.begin.powershell", + "t": "source.powershell interpolated.simple.source.powershell string.quoted.double.powershell", "r": { "dark_plus": "string: #CE9178", "light_plus": "string: #A31515", @@ -2300,18 +2201,18 @@ }, { "c": "$", - "t": "source.powershell interpolated.simple.source.powershell string.quoted.double.powershell variable.other.readwrite.powershell punctuation.definition.variable.powershell", + "t": "source.powershell interpolated.simple.source.powershell string.quoted.double.powershell keyword.other.variable.definition.powershell", "r": { - "dark_plus": "variable: #9CDCFE", - "light_plus": "variable: #001080", - "dark_vs": "string: #CE9178", - "light_vs": "string: #A31515", - "hc_black": "variable: #9CDCFE" + "dark_plus": "keyword: #569CD6", + "light_plus": "keyword: #0000FF", + "dark_vs": "keyword: #569CD6", + "light_vs": "keyword: #0000FF", + "hc_black": "keyword: #569CD6" } }, { "c": "env:", - "t": "source.powershell interpolated.simple.source.powershell string.quoted.double.powershell variable.other.readwrite.powershell support.variable.drive.powershell", + "t": "source.powershell interpolated.simple.source.powershell string.quoted.double.powershell support.variable.drive.powershell", "r": { "dark_plus": "support.variable: #9CDCFE", "light_plus": "support.variable: #001080", @@ -2332,7 +2233,7 @@ } }, { - "c": "\\Microsoft Visual Studio 12.0", + "c": "\\Microsoft Visual Studio 12.0\"", "t": "source.powershell interpolated.simple.source.powershell string.quoted.double.powershell", "r": { "dark_plus": "string: #CE9178", @@ -2342,17 +2243,6 @@ "hc_black": "string: #CE9178" } }, - { - "c": "\"", - "t": "source.powershell interpolated.simple.source.powershell string.quoted.double.powershell punctuation.definition.string.end.powershell", - "r": { - "dark_plus": "string: #CE9178", - "light_plus": "string: #A31515", - "dark_vs": "string: #CE9178", - "light_vs": "string: #A31515", - "hc_black": "string: #CE9178" - } - }, { "c": ")", "t": "source.powershell punctuation.section.group.end.powershell", @@ -2399,13 +2289,13 @@ }, { "c": "$", - "t": "source.powershell meta.scriptblock.powershell variable.other.readwrite.powershell punctuation.definition.variable.powershell", + "t": "source.powershell meta.scriptblock.powershell keyword.other.variable.definition.powershell", "r": { - "dark_plus": "variable: #9CDCFE", - "light_plus": "variable: #001080", - "dark_vs": "default: #D4D4D4", - "light_vs": "default: #000000", - "hc_black": "variable: #9CDCFE" + "dark_plus": "keyword: #569CD6", + "light_plus": "keyword: #0000FF", + "dark_vs": "keyword: #569CD6", + "light_vs": "keyword: #0000FF", + "hc_black": "keyword: #569CD6" } }, { @@ -2431,18 +2321,7 @@ } }, { - "c": "\"", - "t": "source.powershell meta.scriptblock.powershell string.quoted.double.powershell punctuation.definition.string.begin.powershell", - "r": { - "dark_plus": "string: #CE9178", - "light_plus": "string: #A31515", - "dark_vs": "string: #CE9178", - "light_vs": "string: #A31515", - "hc_black": "string: #CE9178" - } - }, - { - "c": "12.0", + "c": "\"12.0\"", "t": "source.powershell meta.scriptblock.powershell string.quoted.double.powershell", "r": { "dark_plus": "string: #CE9178", @@ -2452,17 +2331,6 @@ "hc_black": "string: #CE9178" } }, - { - "c": "\"", - "t": "source.powershell meta.scriptblock.powershell string.quoted.double.powershell punctuation.definition.string.end.powershell", - "r": { - "dark_plus": "string: #CE9178", - "light_plus": "string: #A31515", - "dark_vs": "string: #CE9178", - "light_vs": "string: #A31515", - "hc_black": "string: #CE9178" - } - }, { "c": "}", "t": "source.powershell meta.scriptblock.powershell punctuation.section.braces.end.powershell", @@ -2531,13 +2399,13 @@ }, { "c": "$", - "t": "source.powershell meta.scriptblock.powershell variable.other.readwrite.powershell punctuation.definition.variable.powershell", + "t": "source.powershell meta.scriptblock.powershell keyword.other.variable.definition.powershell", "r": { - "dark_plus": "variable: #9CDCFE", - "light_plus": "variable: #001080", - "dark_vs": "default: #D4D4D4", - "light_vs": "default: #000000", - "hc_black": "variable: #9CDCFE" + "dark_plus": "keyword: #569CD6", + "light_plus": "keyword: #0000FF", + "dark_vs": "keyword: #569CD6", + "light_vs": "keyword: #0000FF", + "hc_black": "keyword: #569CD6" } }, { @@ -2563,18 +2431,7 @@ } }, { - "c": "\"", - "t": "source.powershell meta.scriptblock.powershell string.quoted.double.powershell punctuation.definition.string.begin.powershell", - "r": { - "dark_plus": "string: #CE9178", - "light_plus": "string: #A31515", - "dark_vs": "string: #CE9178", - "light_vs": "string: #A31515", - "hc_black": "string: #CE9178" - } - }, - { - "c": "11.0", + "c": "\"11.0\"", "t": "source.powershell meta.scriptblock.powershell string.quoted.double.powershell", "r": { "dark_plus": "string: #CE9178", @@ -2584,17 +2441,6 @@ "hc_black": "string: #CE9178" } }, - { - "c": "\"", - "t": "source.powershell meta.scriptblock.powershell string.quoted.double.powershell punctuation.definition.string.end.powershell", - "r": { - "dark_plus": "string: #CE9178", - "light_plus": "string: #A31515", - "dark_vs": "string: #CE9178", - "light_vs": "string: #A31515", - "hc_black": "string: #CE9178" - } - }, { "c": "}", "t": "source.powershell meta.scriptblock.powershell punctuation.section.braces.end.powershell", @@ -2608,13 +2454,13 @@ }, { "c": "$", - "t": "source.powershell variable.other.readwrite.powershell punctuation.definition.variable.powershell", + "t": "source.powershell keyword.other.variable.definition.powershell", "r": { - "dark_plus": "variable: #9CDCFE", - "light_plus": "variable: #001080", - "dark_vs": "default: #D4D4D4", - "light_vs": "default: #000000", - "hc_black": "variable: #9CDCFE" + "dark_plus": "keyword: #569CD6", + "light_plus": "keyword: #0000FF", + "dark_vs": "keyword: #569CD6", + "light_vs": "keyword: #0000FF", + "hc_black": "keyword: #569CD6" } }, { @@ -2662,18 +2508,7 @@ } }, { - "c": "'", - "t": "source.powershell string.quoted.single.powershell punctuation.definition.string.begin.powershell", - "r": { - "dark_plus": "string: #CE9178", - "light_plus": "string: #A31515", - "dark_vs": "string: #CE9178", - "light_vs": "string: #A31515", - "hc_black": "string: #CE9178" - } - }, - { - "c": "\"{0}\\Microsoft Visual Studio {1}\\VC\\vcvarsall.bat\" x64", + "c": "'\"{0}\\Microsoft Visual Studio {1}\\VC\\vcvarsall.bat\" x64'", "t": "source.powershell string.quoted.single.powershell", "r": { "dark_plus": "string: #CE9178", @@ -2683,17 +2518,6 @@ "hc_black": "string: #CE9178" } }, - { - "c": "'", - "t": "source.powershell string.quoted.single.powershell punctuation.definition.string.end.powershell", - "r": { - "dark_plus": "string: #CE9178", - "light_plus": "string: #A31515", - "dark_vs": "string: #CE9178", - "light_vs": "string: #A31515", - "hc_black": "string: #CE9178" - } - }, { "c": " ", "t": "source.powershell", @@ -2729,18 +2553,18 @@ }, { "c": "$", - "t": "source.powershell variable.other.readwrite.powershell punctuation.definition.variable.powershell", + "t": "source.powershell keyword.other.variable.definition.powershell", "r": { - "dark_plus": "variable: #9CDCFE", - "light_plus": "variable: #001080", - "dark_vs": "default: #D4D4D4", - "light_vs": "default: #000000", - "hc_black": "variable: #9CDCFE" + "dark_plus": "keyword: #569CD6", + "light_plus": "keyword: #0000FF", + "dark_vs": "keyword: #569CD6", + "light_vs": "keyword: #0000FF", + "hc_black": "keyword: #569CD6" } }, { "c": "env:", - "t": "source.powershell variable.other.readwrite.powershell support.variable.drive.powershell", + "t": "source.powershell support.variable.drive.powershell", "r": { "dark_plus": "support.variable: #9CDCFE", "light_plus": "support.variable: #001080", @@ -2784,13 +2608,13 @@ }, { "c": "$", - "t": "source.powershell variable.other.readwrite.powershell punctuation.definition.variable.powershell", + "t": "source.powershell keyword.other.variable.definition.powershell", "r": { - "dark_plus": "variable: #9CDCFE", - "light_plus": "variable: #001080", - "dark_vs": "default: #D4D4D4", - "light_vs": "default: #000000", - "hc_black": "variable: #9CDCFE" + "dark_plus": "keyword: #569CD6", + "light_plus": "keyword: #0000FF", + "dark_vs": "keyword: #569CD6", + "light_vs": "keyword: #0000FF", + "hc_black": "keyword: #569CD6" } }, { @@ -2806,13 +2630,13 @@ }, { "c": ";", - "t": "source.powershell punctuation.terminator.statement.powershell", + "t": "source.powershell keyword.other.statement-separator.powershell", "r": { - "dark_plus": "default: #D4D4D4", - "light_plus": "default: #000000", - "dark_vs": "default: #D4D4D4", - "light_vs": "default: #000000", - "hc_black": "default: #FFFFFF" + "dark_plus": "keyword: #569CD6", + "light_plus": "keyword: #0000FF", + "dark_vs": "keyword: #569CD6", + "light_vs": "keyword: #0000FF", + "hc_black": "keyword: #569CD6" } }, { @@ -2861,13 +2685,13 @@ }, { "c": "$", - "t": "source.powershell variable.other.readwrite.powershell punctuation.definition.variable.powershell", + "t": "source.powershell keyword.other.variable.definition.powershell", "r": { - "dark_plus": "variable: #9CDCFE", - "light_plus": "variable: #001080", - "dark_vs": "default: #D4D4D4", - "light_vs": "default: #000000", - "hc_black": "variable: #9CDCFE" + "dark_plus": "keyword: #569CD6", + "light_plus": "keyword: #0000FF", + "dark_vs": "keyword: #569CD6", + "light_vs": "keyword: #0000FF", + "hc_black": "keyword: #569CD6" } }, { @@ -2883,13 +2707,13 @@ }, { "c": ";", - "t": "source.powershell punctuation.terminator.statement.powershell", + "t": "source.powershell keyword.other.statement-separator.powershell", "r": { - "dark_plus": "default: #D4D4D4", - "light_plus": "default: #000000", - "dark_vs": "default: #D4D4D4", - "light_vs": "default: #000000", - "hc_black": "default: #FFFFFF" + "dark_plus": "keyword: #569CD6", + "light_plus": "keyword: #0000FF", + "dark_vs": "keyword: #569CD6", + "light_vs": "keyword: #0000FF", + "hc_black": "keyword: #569CD6" } } ] \ No newline at end of file From 72509c562525774967c6fa90c234acfd0335b01a Mon Sep 17 00:00:00 2001 From: Martin Aeschlimann Date: Wed, 15 Aug 2018 18:20:04 +0200 Subject: [PATCH 0841/1276] VSCode hangs when opening python file. Fixes #56377 --- .../syntaxes/MagicPython.tmLanguage.json | 54 +++++++++---------- 1 file changed, 24 insertions(+), 30 deletions(-) diff --git a/extensions/python/syntaxes/MagicPython.tmLanguage.json b/extensions/python/syntaxes/MagicPython.tmLanguage.json index fc32d74cec5..44a995bc046 100644 --- a/extensions/python/syntaxes/MagicPython.tmLanguage.json +++ b/extensions/python/syntaxes/MagicPython.tmLanguage.json @@ -4,7 +4,7 @@ "If you want to provide a fix or improvement, please create a pull request against the original repository.", "Once accepted there, we are happy to receive an update request." ], - "version": "https://github.com/MagicStack/MagicPython/commit/fb56c6a98d684e30bed1b0f9647e85741a48f914", + "version": "https://github.com/MagicStack/MagicPython/commit/b453f26ed856c9b16a053517c41207e3a72cc7d5", "name": "MagicPython", "scopeName": "source.python", "patterns": [ @@ -97,8 +97,7 @@ }, "docstring-statement": { "begin": "^(?=\\s*[rR]?(\\'\\'\\'|\\\"\\\"\\\"|\\'|\\\"))", - "comment": "the string either terminates correctly or by the beginning of a new line (this is for single line docstrings that aren't terminated) AND it's not followed by another docstring", - "end": "((?<=\\1)|^)(?!\\s*[rR]?(\\'\\'\\'|\\\"\\\"\\\"|\\'|\\\"))", + "end": "(?<=\\'\\'\\'|\\\"\\\"\\\"|\\'|\\\")", "patterns": [ { "include": "#docstring" @@ -165,7 +164,7 @@ { "name": "string.quoted.docstring.single.python", "begin": "(\\'|\\\")", - "end": "(\\1)|(\\n)", + "end": "(\\1)|((?=^]? [-+ ]? \\#?\n \\d* ,? (\\.\\d+)? [bcdeEfFgGnosxX%]? )?\n })\n )\n", + "name": "constant.character.format.placeholder.other.python", + "match": "(?x)\n (?:\n {{ | }}\n | (?:\n {\n \\w*? (\\.[[:alpha:]_]\\w*? | \\[[^\\]'\"]+\\])*?\n (![rsa])?\n ( : \\w? [<>=^]? [-+ ]? \\#?\n \\d* ,? (\\.\\d+)? [bcdeEfFgGnosxX%]? )?\n })\n )\n", "captures": { - "1": { - "name": "constant.character.format.placeholder.other.python" - }, - "3": { + "2": { "name": "storage.type.format.python" }, - "4": { + "3": { "name": "storage.type.format.python" } } }, { - "name": "meta.format.brace.python", - "match": "(?x)\n (\n {\n \\w*? (\\.[[:alpha:]_]\\w*? | \\[[^\\]'\"]+\\])*?\n (![rsa])?\n (:)\n (\n [^'\"{}\\n]+?\n |\n \\{ [^'\"}\\n]*? \\}\n )*\n }\n )\n", - "captures": { - "1": { - "name": "constant.character.format.placeholder.other.python" + "name": "constant.character.format.placeholder.other.python", + "begin": "(?x)\n \\{\n \\w*? (\\.[[:alpha:]_]\\w*? | \\[[^\\]'\"]+\\])*?\n (![rsa])?\n (:)\n (?=[^'\"}\\n]*\\})\n", + "end": "\\}", + "beginCaptures": { + "2": { + "name": "storage.type.format.python" }, "3": { "name": "storage.type.format.python" - }, - "4": { - "name": "storage.type.format.python" } - } + }, + "patterns": [ + { + "match": "(?x) \\{ [^'\"}\\n]*? \\} (?=.*?\\})\n" + } + ] } ] }, @@ -4543,7 +4537,7 @@ }, "string-quoted-single-line": { "name": "string.quoted.single.python", - "begin": "(?:\\b([rR])(?=[uU]))?([uU])?((['\"]))", + "begin": "(\\b[rR](?=[uU]))?([uU])?((['\"]))", "end": "(\\3)|((? Date: Wed, 15 Aug 2018 09:44:37 -0700 Subject: [PATCH 0842/1276] Fixes #56465, revert label opacity --- src/vs/base/browser/ui/iconLabel/iconlabel.css | 1 + 1 file changed, 1 insertion(+) diff --git a/src/vs/base/browser/ui/iconLabel/iconlabel.css b/src/vs/base/browser/ui/iconLabel/iconlabel.css index 3516227e43d..785d2a0e44e 100644 --- a/src/vs/base/browser/ui/iconLabel/iconlabel.css +++ b/src/vs/base/browser/ui/iconLabel/iconlabel.css @@ -40,6 +40,7 @@ } .monaco-icon-label > .monaco-icon-label-description-container > .label-description { + opacity: .7; margin-left: 0.5em; font-size: 0.9em; white-space: pre; /* enable to show labels that include multiple whitespaces */ From 3d71869a0c4ba1df833b938a2534581250a31d90 Mon Sep 17 00:00:00 2001 From: Benjamin Pasero Date: Wed, 15 Aug 2018 18:56:58 +0200 Subject: [PATCH 0843/1276] :lipstick: --- .../workbench/parts/files/browser/editors/fileEditorTracker.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vs/workbench/parts/files/browser/editors/fileEditorTracker.ts b/src/vs/workbench/parts/files/browser/editors/fileEditorTracker.ts index e26679c5a69..adbae0c0793 100644 --- a/src/vs/workbench/parts/files/browser/editors/fileEditorTracker.ts +++ b/src/vs/workbench/parts/files/browser/editors/fileEditorTracker.ts @@ -82,7 +82,7 @@ export class FileEditorTracker extends Disposable implements IWorkbenchContribut if (configuration.workbench && configuration.workbench.editor && typeof configuration.workbench.editor.closeOnFileDelete === 'boolean') { this.closeOnFileDelete = configuration.workbench.editor.closeOnFileDelete; } else { - this.closeOnFileDelete = true; // default + this.closeOnFileDelete = false; // default } } From 11e2eef0d4dd22c8f78611b7b5c877a7b61d5a63 Mon Sep 17 00:00:00 2001 From: SteVen Batten Date: Wed, 15 Aug 2018 10:02:18 -0700 Subject: [PATCH 0844/1276] fixes #56225 --- src/vs/platform/contextview/browser/contextMenuHandler.ts | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/vs/platform/contextview/browser/contextMenuHandler.ts b/src/vs/platform/contextview/browser/contextMenuHandler.ts index 6a39c62dbc0..836a08a9935 100644 --- a/src/vs/platform/contextview/browser/contextMenuHandler.ts +++ b/src/vs/platform/contextview/browser/contextMenuHandler.ts @@ -25,6 +25,7 @@ export class ContextMenuHandler { private $el: Builder; private menuContainerElement: HTMLElement; + private focusToReturn: HTMLElement; constructor(element: HTMLElement, contextViewService: IContextViewService, telemetryService: ITelemetryService, notificationService: INotificationService) { this.setContainer(element); @@ -53,6 +54,8 @@ export class ContextMenuHandler { return; // Don't render an empty context menu } + this.focusToReturn = document.activeElement as HTMLElement; + this.contextViewService.showContextView({ getAnchor: () => delegate.getAnchor(), canRelayout: false, @@ -110,6 +113,11 @@ export class ContextMenuHandler { } this.contextViewService.hideContextView(false); + + // Restore focus here + if (this.focusToReturn) { + this.focusToReturn.focus(); + } } private onDidActionRun(e: IRunEvent): void { From beb70bbb7afc286243995aca7f24cefd587ccd29 Mon Sep 17 00:00:00 2001 From: Sandeep Somavarapu Date: Wed, 15 Aug 2018 20:19:56 +0200 Subject: [PATCH 0845/1276] Fix in master #56371 --- .../markers/electron-browser/markersModel.ts | 5 +++-- .../electron-browser/markersPanelActions.ts | 7 +++---- .../electron-browser/markersTreeController.ts | 15 ++++++--------- .../markers/electron-browser/markersTreeViewer.ts | 3 +-- 4 files changed, 13 insertions(+), 17 deletions(-) diff --git a/src/vs/workbench/parts/markers/electron-browser/markersModel.ts b/src/vs/workbench/parts/markers/electron-browser/markersModel.ts index 85e1d53e2ff..0535caf3743 100644 --- a/src/vs/workbench/parts/markers/electron-browser/markersModel.ts +++ b/src/vs/workbench/parts/markers/electron-browser/markersModel.ts @@ -121,7 +121,8 @@ export class Marker extends NodeWithId { constructor( id: string, - readonly raw: IMarker + readonly raw: IMarker, + readonly resourceMarkers: ResourceMarkers ) { super(id); } @@ -314,7 +315,7 @@ export class MarkersModel { this.updateResource(resource); rawMarkers.forEach((rawMarker, index) => { - const marker = new Marker(uri.toString() + index, rawMarker); + const marker = new Marker(uri.toString() + index, rawMarker, resource); if (rawMarker.relatedInformation) { const groupedByResource = groupBy(rawMarker.relatedInformation, MarkersModel._compareMarkersByUri); groupedByResource.sort((a, b) => compareUris(a[0].resource, b[0].resource)); diff --git a/src/vs/workbench/parts/markers/electron-browser/markersPanelActions.ts b/src/vs/workbench/parts/markers/electron-browser/markersPanelActions.ts index 56c76acfaf4..e706541c87c 100644 --- a/src/vs/workbench/parts/markers/electron-browser/markersPanelActions.ts +++ b/src/vs/workbench/parts/markers/electron-browser/markersPanelActions.ts @@ -30,7 +30,7 @@ import { localize } from 'vs/nls'; import { Checkbox } from 'vs/base/browser/ui/checkbox/checkbox'; import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; import { ContextScopedHistoryInputBox } from 'vs/platform/widget/browser/contextScopedHistoryWidget'; -import { Marker, ResourceMarkers } from 'vs/workbench/parts/markers/electron-browser/markersModel'; +import { Marker } from 'vs/workbench/parts/markers/electron-browser/markersModel'; import { applyCodeAction } from 'vs/editor/contrib/codeAction/codeActionCommands'; import { IBulkEditService } from 'vs/editor/browser/services/bulkEditService'; import { ICommandService } from 'vs/platform/commands/common/commands'; @@ -282,17 +282,16 @@ export class QuickFixAction extends Action { constructor( readonly marker: Marker, - readonly resourceMarkers: ResourceMarkers, @IBulkEditService private bulkEditService: IBulkEditService, @ICommandService private commandService: ICommandService, @IEditorService private editorService: IEditorService ) { super(QuickFixAction.ID, Messages.MARKERS_PANEL_ACTION_TOOLTIP_QUICKFIX, 'markers-panel-action-quickfix', false); - resourceMarkers.hasFixes(marker).then(hasFixes => this.enabled = hasFixes); + marker.resourceMarkers.hasFixes(marker).then(hasFixes => this.enabled = hasFixes); } async getQuickFixActions(): Promise { - const codeActions = await this.resourceMarkers.getFixes(this.marker); + const codeActions = await this.marker.resourceMarkers.getFixes(this.marker); return codeActions.map(codeAction => new Action( codeAction.command ? codeAction.command.id : codeAction.title, codeAction.title, diff --git a/src/vs/workbench/parts/markers/electron-browser/markersTreeController.ts b/src/vs/workbench/parts/markers/electron-browser/markersTreeController.ts index 142f95c65a2..e936b16e3f1 100644 --- a/src/vs/workbench/parts/markers/electron-browser/markersTreeController.ts +++ b/src/vs/workbench/parts/markers/electron-browser/markersTreeController.ts @@ -7,7 +7,7 @@ import { TPromise } from 'vs/base/common/winjs.base'; import * as mouse from 'vs/base/browser/mouseEvent'; import * as tree from 'vs/base/parts/tree/browser/tree'; -import { MarkersModel, Marker, ResourceMarkers } from 'vs/workbench/parts/markers/electron-browser/markersModel'; +import { MarkersModel, Marker } from 'vs/workbench/parts/markers/electron-browser/markersModel'; import { IContextMenuService } from 'vs/platform/contextview/browser/contextView'; import { IMenuService, MenuId } from 'vs/platform/actions/common/actions'; import { IAction } from 'vs/base/common/actions'; @@ -76,14 +76,11 @@ export class Controller extends WorkbenchTreeController { const result: IAction[] = []; if (element instanceof Marker) { - const parent = tree.getNavigator(element).parent(); - if (parent instanceof ResourceMarkers) { - const quickFixAction = this.instantiationService.createInstance(QuickFixAction, element, parent); - const quickFixActions = await quickFixAction.getQuickFixActions(); - if (quickFixActions.length) { - result.push(...quickFixActions); - result.push(new Separator()); - } + const quickFixAction = this.instantiationService.createInstance(QuickFixAction, element); + const quickFixActions = await quickFixAction.getQuickFixActions(); + if (quickFixActions.length) { + result.push(...quickFixActions); + result.push(new Separator()); } } diff --git a/src/vs/workbench/parts/markers/electron-browser/markersTreeViewer.ts b/src/vs/workbench/parts/markers/electron-browser/markersTreeViewer.ts index f9549b81f58..5e875bd0226 100644 --- a/src/vs/workbench/parts/markers/electron-browser/markersTreeViewer.ts +++ b/src/vs/workbench/parts/markers/electron-browser/markersTreeViewer.ts @@ -222,8 +222,7 @@ export class Renderer implements IRenderer { dom.toggleClass(templateData.source.element, 'marker-source', !!marker.source); templateData.actionBar.clear(); - const resourceMarkers: ResourceMarkers = tree.getNavigator(element).parent(); - const quickFixAction = this.instantiationService.createInstance(QuickFixAction, element, resourceMarkers); + const quickFixAction = this.instantiationService.createInstance(QuickFixAction, element); templateData.actionBar.push([quickFixAction], { icon: true, label: false }); templateData.description.set(marker.message, element.messageMatches); From 8ec26a222a9c09cda2d34be287b4d52bbea90956 Mon Sep 17 00:00:00 2001 From: Rob Lourens Date: Wed, 15 Aug 2018 10:51:29 -0700 Subject: [PATCH 0846/1276] Fix #56433 - search extraFileResources even when no folders open --- src/vs/workbench/services/search/node/searchService.ts | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/vs/workbench/services/search/node/searchService.ts b/src/vs/workbench/services/search/node/searchService.ts index 5d0ce0948d9..5bf7b93503c 100644 --- a/src/vs/workbench/services/search/node/searchService.ts +++ b/src/vs/workbench/services/search/node/searchService.ts @@ -207,12 +207,15 @@ export class SearchService extends Disposable implements ISearchService { } }); - if (diskSearchQueries.length) { - const diskSearchQuery = { + const diskSearchExtraFileResources = query.extraFileResources && query.extraFileResources.filter(res => res.scheme === 'file'); + + if (diskSearchQueries.length || diskSearchExtraFileResources) { + const diskSearchQuery: ISearchQuery = { ...query, ...{ folderQueries: diskSearchQueries - } + }, + extraFileResources: diskSearchExtraFileResources }; searchPs.push(this.diskSearch.search(diskSearchQuery, onProviderProgress)); From 66d37dcfc58943153cb9c093389fa62c88777f22 Mon Sep 17 00:00:00 2001 From: Sandeep Somavarapu Date: Wed, 15 Aug 2018 20:27:57 +0200 Subject: [PATCH 0847/1276] Fix tests #56371 --- .../markers/test/electron-browser/markersModel.test.ts | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/vs/workbench/parts/markers/test/electron-browser/markersModel.test.ts b/src/vs/workbench/parts/markers/test/electron-browser/markersModel.test.ts index b2bceb193b3..39eae5fb72b 100644 --- a/src/vs/workbench/parts/markers/test/electron-browser/markersModel.test.ts +++ b/src/vs/workbench/parts/markers/test/electron-browser/markersModel.test.ts @@ -140,19 +140,19 @@ suite('MarkersModel Test', () => { test('toString()', function () { let marker = aMarker('a/res1'); marker.code = '1234'; - assert.equal(JSON.stringify({ ...marker, resource: marker.resource.path }, null, '\t'), instantiationService.createInstance(Marker, '', marker).toString()); + assert.equal(JSON.stringify({ ...marker, resource: marker.resource.path }, null, '\t'), instantiationService.createInstance(Marker, '', marker, null).toString()); marker = aMarker('a/res2', MarkerSeverity.Warning); - assert.equal(JSON.stringify({ ...marker, resource: marker.resource.path }, null, '\t'), instantiationService.createInstance(Marker, '', marker).toString()); + assert.equal(JSON.stringify({ ...marker, resource: marker.resource.path }, null, '\t'), instantiationService.createInstance(Marker, '', marker, null).toString()); marker = aMarker('a/res2', MarkerSeverity.Info, 1, 2, 1, 8, 'Info', ''); - assert.equal(JSON.stringify({ ...marker, resource: marker.resource.path }, null, '\t'), instantiationService.createInstance(Marker, '', marker).toString()); + assert.equal(JSON.stringify({ ...marker, resource: marker.resource.path }, null, '\t'), instantiationService.createInstance(Marker, '', marker, null).toString()); marker = aMarker('a/res2', MarkerSeverity.Hint, 1, 2, 1, 8, 'Ignore message', 'Ignore'); - assert.equal(JSON.stringify({ ...marker, resource: marker.resource.path }, null, '\t'), instantiationService.createInstance(Marker, '', marker).toString()); + assert.equal(JSON.stringify({ ...marker, resource: marker.resource.path }, null, '\t'), instantiationService.createInstance(Marker, '', marker, null).toString()); marker = aMarker('a/res2', MarkerSeverity.Warning, 1, 2, 1, 8, 'Warning message', '', [{ startLineNumber: 2, startColumn: 5, endLineNumber: 2, endColumn: 10, message: 'some info', resource: URI.file('a/res3') }]); - const testObject = instantiationService.createInstance(Marker, '', marker); + const testObject = instantiationService.createInstance(Marker, '', marker, null); testObject.resourceRelatedInformation = marker.relatedInformation.map(r => new RelatedInformation('', r)); assert.equal(JSON.stringify({ ...marker, resource: marker.resource.path, relatedInformation: marker.relatedInformation.map(r => ({ ...r, resource: r.resource.path })) }, null, '\t'), testObject.toString()); }); From 5bab8f680e1968440a51d8dc7508a92d3a04d120 Mon Sep 17 00:00:00 2001 From: Jackson Kearl Date: Wed, 15 Aug 2018 12:05:04 -0700 Subject: [PATCH 0848/1276] Fix bug causing borderes in monaco inputs when a trasparent bacground is selected (#56493) --- .../parts/codeEditor/browser/media/suggestEnabledInput.css | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vs/workbench/parts/codeEditor/browser/media/suggestEnabledInput.css b/src/vs/workbench/parts/codeEditor/browser/media/suggestEnabledInput.css index 4cce699dee8..65fd4a3c8ba 100644 --- a/src/vs/workbench/parts/codeEditor/browser/media/suggestEnabledInput.css +++ b/src/vs/workbench/parts/codeEditor/browser/media/suggestEnabledInput.css @@ -11,7 +11,7 @@ .suggest-input-container .monaco-editor, .suggest-input-container .mtk1 { /* allow the embedded monaco to be styled from the outer context */ - background-color: inherit; + background-color: transparent; color: inherit; } From 22ab03e7a4dcb975d24d174a8b842526840e54d2 Mon Sep 17 00:00:00 2001 From: Rachel Macfarlane Date: Wed, 15 Aug 2018 12:46:17 -0700 Subject: [PATCH 0849/1276] Prevent comment ranges from shifting on edit --- .../electron-browser/commentThreadWidget.ts | 18 ------------------ 1 file changed, 18 deletions(-) diff --git a/src/vs/workbench/parts/comments/electron-browser/commentThreadWidget.ts b/src/vs/workbench/parts/comments/electron-browser/commentThreadWidget.ts index e859e123b94..d29bdb5fb5d 100644 --- a/src/vs/workbench/parts/comments/electron-browser/commentThreadWidget.ts +++ b/src/vs/workbench/parts/comments/electron-browser/commentThreadWidget.ts @@ -299,24 +299,6 @@ export class ReviewZoneWidget extends ZoneWidget { this._localToDispose.push(this.editor.onMouseDown(e => this.onEditorMouseDown(e))); this._localToDispose.push(this.editor.onMouseUp(e => this.onEditorMouseUp(e))); - this._localToDispose.push(this.editor.onDidChangeModelContent((e) => { - // If the widget has been opened, the position is set and can be relied on for updating the glyph position - if (this.position) { - if (this.position.lineNumber !== this._commentGlyph.getPosition().position.lineNumber) { - this._commentGlyph.setLineNumber(this.position.lineNumber); - } - } else { - // Otherwise manually calculate position change :( - const positionChange = e.changes.map(change => { - if (change.range.startLineNumber < change.range.endLineNumber) { - return change.range.startLineNumber - change.range.endLineNumber; - } else { - return change.text.split(e.eol).length - 1; - } - }).reduce((prev, curr) => prev + curr, 0); - this._commentGlyph.setLineNumber(this._commentGlyph.getPosition().position.lineNumber + positionChange); - } - })); var headHeight = Math.ceil(this.editor.getConfiguration().lineHeight * 1.2); this._headElement.style.height = `${headHeight}px`; this._headElement.style.lineHeight = this._headElement.style.height; From cb5558b99d633fb775b2ac0e56f7b7304ce3cff9 Mon Sep 17 00:00:00 2001 From: Rob Lourens Date: Wed, 15 Aug 2018 14:41:10 -0700 Subject: [PATCH 0850/1276] Fix #50641 - handle different settings scopes correctly in UI --- .../preferences/browser/preferencesActions.ts | 39 ++++----- .../preferences/browser/preferencesEditor.ts | 8 +- .../preferences/browser/settingsEditor2.ts | 32 ++++--- .../common/preferencesContribution.ts | 6 +- .../preferences.contribution.ts | 12 ++- .../preferences/browser/preferencesService.ts | 83 ++++++++++++++++--- .../preferences/common/preferences.ts | 11 ++- .../common/preferencesEditorInput.ts | 23 ++--- 8 files changed, 135 insertions(+), 79 deletions(-) diff --git a/src/vs/workbench/parts/preferences/browser/preferencesActions.ts b/src/vs/workbench/parts/preferences/browser/preferencesActions.ts index 60ec2e5e99d..e14be3af87a 100644 --- a/src/vs/workbench/parts/preferences/browser/preferencesActions.ts +++ b/src/vs/workbench/parts/preferences/browser/preferencesActions.ts @@ -45,13 +45,13 @@ export class OpenSettings2Action extends Action { constructor( id: string, label: string, - @IPreferencesService private preferencesService2: IPreferencesService + @IPreferencesService private preferencesService: IPreferencesService ) { super(id, label); } public run(event?: any): TPromise { - return this.preferencesService2.openSettings2(); + return this.preferencesService.openSettings(false); } } @@ -71,9 +71,8 @@ export class OpenSettingsAction extends Action { } public run(event?: any): TPromise { - return this.configurationService.getValue('workbench.settings.editor') === 'json' ? - this.preferencesService.openSettings() : - this.preferencesService.openSettings2(); + const jsonEditorPreferred = this.configurationService.getValue('workbench.settings.editor') === 'json'; + return this.preferencesService.openSettings(jsonEditorPreferred); } } @@ -110,9 +109,8 @@ export class OpenGlobalSettingsAction extends Action { } public run(event?: any): TPromise { - return this.configurationService.getValue('workbench.settings.editor') === 'json' ? - this.preferencesService.openGlobalSettings() : - this.preferencesService.openSettings2(); + const jsonEditorPreferred = this.configurationService.getValue('workbench.settings.editor') === 'json'; + return this.preferencesService.openGlobalSettings(jsonEditorPreferred); } } @@ -194,9 +192,8 @@ export class OpenWorkspaceSettingsAction extends Action { } public run(event?: any): TPromise { - return this.configurationService.getValue('workbench.settings.editor') === 'json' ? - this.preferencesService.openWorkspaceSettings() : - this.preferencesService.openSettings2(); + const jsonEditorPreferred = this.configurationService.getValue('workbench.settings.editor') === 'json'; + return this.preferencesService.openWorkspaceSettings(jsonEditorPreferred); } public dispose(): void { @@ -234,17 +231,15 @@ export class OpenFolderSettingsAction extends Action { } public run(): TPromise { - if (this.configurationService.getValue('workbench.settings.editor') === 'json') { - return this.commandService.executeCommand(PICK_WORKSPACE_FOLDER_COMMAND_ID) - .then(workspaceFolder => { - if (workspaceFolder) { - return this.commandService.executeCommand(OPEN_FOLDER_SETTINGS_COMMAND, workspaceFolder.uri); - } - return null; - }); - } else { - return this.preferencesService.openSettings2(); - } + return this.commandService.executeCommand(PICK_WORKSPACE_FOLDER_COMMAND_ID) + .then(workspaceFolder => { + if (workspaceFolder) { + const jsonEditorPreferred = this.configurationService.getValue('workbench.settings.editor') === 'json'; + return this.preferencesService.openFolderSettings(workspaceFolder.uri, jsonEditorPreferred); + } + + return null; + }); } public dispose(): void { diff --git a/src/vs/workbench/parts/preferences/browser/preferencesEditor.ts b/src/vs/workbench/parts/preferences/browser/preferencesEditor.ts index 3f1ba5f6ebd..a05b30b32be 100644 --- a/src/vs/workbench/parts/preferences/browser/preferencesEditor.ts +++ b/src/vs/workbench/parts/preferences/browser/preferencesEditor.ts @@ -120,7 +120,7 @@ export class PreferencesEditor extends BaseEditor { }); openSettings2Button.label = nls.localize('openSettings2Label', "new settings editor"); openSettings2Button.element.classList.add('open-settings2-button'); - this._register(openSettings2Button.onDidClick(() => this.preferencesService.openSettings2())); + this._register(openSettings2Button.onDidClick(() => this.preferencesService.openSettings(false))); this.searchWidget = this._register(this.instantiationService.createInstance(SearchWidget, this.headerContainer, { ariaLabel: nls.localize('SearchSettingsWidget.AriaLabel', "Search settings"), @@ -263,11 +263,11 @@ export class PreferencesEditor extends BaseEditor { const promise = this.input && this.input.isDirty() ? this.input.save() : TPromise.as(true); promise.done(value => { if (target === ConfigurationTarget.USER) { - this.preferencesService.switchSettings(ConfigurationTarget.USER, this.preferencesService.userSettingsResource); + this.preferencesService.switchSettings(ConfigurationTarget.USER, this.preferencesService.userSettingsResource, true); } else if (target === ConfigurationTarget.WORKSPACE) { - this.preferencesService.switchSettings(ConfigurationTarget.WORKSPACE, this.preferencesService.workspaceSettingsResource); + this.preferencesService.switchSettings(ConfigurationTarget.WORKSPACE, this.preferencesService.workspaceSettingsResource, true); } else if (target instanceof URI) { - this.preferencesService.switchSettings(ConfigurationTarget.WORKSPACE_FOLDER, target); + this.preferencesService.switchSettings(ConfigurationTarget.WORKSPACE_FOLDER, target, true); } }); } diff --git a/src/vs/workbench/parts/preferences/browser/settingsEditor2.ts b/src/vs/workbench/parts/preferences/browser/settingsEditor2.ts index 31e0b9e6e33..d715380fc68 100644 --- a/src/vs/workbench/parts/preferences/browser/settingsEditor2.ts +++ b/src/vs/workbench/parts/preferences/browser/settingsEditor2.ts @@ -43,6 +43,7 @@ import { IEditorGroup } from 'vs/workbench/services/group/common/editorGroupsSer import { IPreferencesService, ISearchResult, ISettingsEditorModel } from 'vs/workbench/services/preferences/common/preferences'; import { SettingsEditor2Input } from 'vs/workbench/services/preferences/common/preferencesEditorInput'; import { DefaultSettingsEditorModel } from 'vs/workbench/services/preferences/common/preferencesModels'; +import { ResourceEditorModel } from 'vs/workbench/common/editor/resourceEditorModel'; const $ = DOM.$; @@ -228,12 +229,15 @@ export class SettingsEditor2 extends BaseEditor { const targetWidgetContainer = DOM.append(headerControlsContainer, $('.settings-target-container')); this.settingsTargetsWidget = this._register(this.instantiationService.createInstance(SettingsTargetsWidget, targetWidgetContainer)); this.settingsTargetsWidget.settingsTarget = ConfigurationTarget.USER; - this.settingsTargetsWidget.onDidTargetChange(() => { - this.viewState.settingsTarget = this.settingsTargetsWidget.settingsTarget; - this.toolbar.context = { target: this.settingsTargetsWidget.settingsTarget }; - - this.settingsTreeModel.update(); - this.renderTree(); + this.settingsTargetsWidget.onDidTargetChange(target => { + this.viewState.settingsTarget = target; + if (target === ConfigurationTarget.USER) { + this.preferencesService.openGlobalSettings(); + } else if (target === ConfigurationTarget.WORKSPACE) { + this.preferencesService.switchSettings(ConfigurationTarget.WORKSPACE, this.preferencesService.workspaceSettingsResource); + } else if (target instanceof URI) { + this.preferencesService.switchSettings(ConfigurationTarget.WORKSPACE_FOLDER, target); + } }); this.createHeaderControls(headerControlsContainer); @@ -480,7 +484,7 @@ export class SettingsEditor2 extends BaseEditor { // Force a render afterwards because onDidConfigurationUpdate doesn't fire if the update doesn't result in an effective setting value change const settingsTarget = this.settingsTargetsWidget.settingsTarget; const resource = URI.isUri(settingsTarget) ? settingsTarget : undefined; - const configurationTarget = (resource ? undefined : settingsTarget); + const configurationTarget = (resource ? ConfigurationTarget.WORKSPACE_FOLDER : settingsTarget); const overrides: IConfigurationOverrides = { resource }; // If the user is changing the value back to the default, do a 'reset' instead @@ -567,13 +571,15 @@ export class SettingsEditor2 extends BaseEditor { private render(token: CancellationToken): TPromise { if (this.input) { return this.input.resolve() - .then((model: DefaultSettingsEditorModel) => { + .then(model => { if (token.isCancellationRequested) { return void 0; } - this._register(model.onDidChangeGroups(() => this.onConfigUpdate())); - this.defaultSettingsEditorModel = model; + return this.preferencesService.createPreferencesEditorModel((model).textEditorModel.uri); + }).then((defaultSettingsEditorModel: DefaultSettingsEditorModel) => { + this._register(defaultSettingsEditorModel.onDidChangeGroups(() => this.onConfigUpdate())); + this.defaultSettingsEditorModel = defaultSettingsEditorModel; return this.onConfigUpdate(); }); } @@ -945,11 +951,11 @@ class OpenSettingsAction extends Action { private _run(context?: ISettingsToolbarContext): TPromise { const target = context && context.target; if (target === ConfigurationTarget.USER) { - return this.preferencesService.openGlobalSettings(); + return this.preferencesService.openGlobalSettings(true); } else if (target === ConfigurationTarget.WORKSPACE) { - return this.preferencesService.openWorkspaceSettings(); + return this.preferencesService.openWorkspaceSettings(true); } else if (URI.isUri(target)) { - return this.preferencesService.openFolderSettings(target); + return this.preferencesService.openFolderSettings(target, true); } return TPromise.wrap(null); diff --git a/src/vs/workbench/parts/preferences/common/preferencesContribution.ts b/src/vs/workbench/parts/preferences/common/preferencesContribution.ts index f1c464e54c5..14494b0bdb3 100644 --- a/src/vs/workbench/parts/preferences/common/preferencesContribution.ts +++ b/src/vs/workbench/parts/preferences/common/preferencesContribution.ts @@ -82,7 +82,7 @@ export class PreferencesContribution implements IWorkbenchContribution { // Global User Settings File if (isEqual(resource, URI.file(this.environmentService.appSettingsPath), !isLinux)) { - return { override: this.preferencesService.openGlobalSettings(options, group) }; + return { override: this.preferencesService.openGlobalSettings(true, options, group) }; } // Single Folder Workspace Settings File @@ -90,7 +90,7 @@ export class PreferencesContribution implements IWorkbenchContribution { if (state === WorkbenchState.FOLDER) { const folders = this.workspaceService.getWorkspace().folders; if (isEqual(resource, folders[0].toResource(FOLDER_SETTINGS_PATH), hasToIgnoreCase(resource))) { - return { override: this.preferencesService.openWorkspaceSettings(options, group) }; + return { override: this.preferencesService.openWorkspaceSettings(true, options, group) }; } } @@ -99,7 +99,7 @@ export class PreferencesContribution implements IWorkbenchContribution { const folders = this.workspaceService.getWorkspace().folders; for (let i = 0; i < folders.length; i++) { if (isEqual(resource, folders[i].toResource(FOLDER_SETTINGS_PATH), hasToIgnoreCase(resource))) { - return { override: this.preferencesService.openFolderSettings(folders[i].uri, options, group) }; + return { override: this.preferencesService.openFolderSettings(folders[i].uri, true, options, group) }; } } } diff --git a/src/vs/workbench/parts/preferences/electron-browser/preferences.contribution.ts b/src/vs/workbench/parts/preferences/electron-browser/preferences.contribution.ts index 37c60e73f60..f12c7b9c456 100644 --- a/src/vs/workbench/parts/preferences/electron-browser/preferences.contribution.ts +++ b/src/vs/workbench/parts/preferences/electron-browser/preferences.contribution.ts @@ -152,11 +152,17 @@ class KeybindingsEditorInputFactory implements IEditorInputFactory { class SettingsEditor2InputFactory implements IEditorInputFactory { public serialize(editorInput: SettingsEditor2Input): string { - return JSON.stringify({}); + const input = editorInput; + + const serialized: ISerializedDefaultPreferencesEditorInput = { resource: input.getResource().toString() }; + + return JSON.stringify(serialized); } - public deserialize(instantiationService: IInstantiationService, serializedEditorInput: string): EditorInput { - return instantiationService.createInstance(SettingsEditor2Input); + public deserialize(instantiationService: IInstantiationService, serializedEditorInput: string): SettingsEditor2Input { + const deserialized: ISerializedDefaultPreferencesEditorInput = JSON.parse(serializedEditorInput); + + return instantiationService.createInstance(SettingsEditor2Input, URI.parse(deserialized.resource)); } } diff --git a/src/vs/workbench/services/preferences/browser/preferencesService.ts b/src/vs/workbench/services/preferences/browser/preferencesService.ts index 8954289dfeb..c7d519cf89f 100644 --- a/src/vs/workbench/services/preferences/browser/preferencesService.ts +++ b/src/vs/workbench/services/preferences/browser/preferencesService.ts @@ -45,6 +45,7 @@ export class PreferencesService extends Disposable implements IPreferencesServic _serviceBrand: any; private lastOpenedSettingsInput: PreferencesEditorInput = null; + private lastOpenedSettings2Input: SettingsEditor2Input = null; private readonly _onDispose: Emitter = new Emitter(); @@ -176,34 +177,52 @@ export class PreferencesService extends Disposable implements IPreferencesServic return this.editorService.openEditor({ resource: this.userSettingsResource }); } - openSettings(): TPromise { + openSettings(jsonEditor?: boolean): TPromise { + if (!jsonEditor) { + return this.openSettings2(); + } + const editorInput = this.getActiveSettingsEditorInput() || this.lastOpenedSettingsInput; const resource = editorInput ? editorInput.master.getResource() : this.userSettingsResource; const target = this.getConfigurationTargetFromSettingsResource(resource); return this.openOrSwitchSettings(target, resource); } - openGlobalSettings(options?: IEditorOptions, group?: IEditorGroup): TPromise { - return this.openOrSwitchSettings(ConfigurationTarget.USER, this.userSettingsResource, options, group); + private openSettings2(): TPromise { + const editorInput = this.getActiveSettingsEditor2Input() || this.lastOpenedSettings2Input; + const resource = editorInput ? editorInput.getResource() : this.userSettingsResource; + const target = this.getConfigurationTargetFromSettingsResource(resource); + return this.openOrSwitchSettings2(target); } - openSettings2(): TPromise { - return this.editorService.openEditor(this.instantiationService.createInstance(SettingsEditor2Input), { pinned: true }).then(() => null); + openGlobalSettings(jsonEditor?: boolean, options?: IEditorOptions, group?: IEditorGroup): TPromise { + return jsonEditor ? + this.openOrSwitchSettings(ConfigurationTarget.USER, this.userSettingsResource, options, group) : + this.openOrSwitchSettings2(ConfigurationTarget.USER, options, group); } - openWorkspaceSettings(options?: IEditorOptions, group?: IEditorGroup): TPromise { + openWorkspaceSettings(jsonEditor?: boolean, options?: IEditorOptions, group?: IEditorGroup): TPromise { if (this.contextService.getWorkbenchState() === WorkbenchState.EMPTY) { this.notificationService.info(nls.localize('openFolderFirst', "Open a folder first to create workspace settings")); return TPromise.as(null); } - return this.openOrSwitchSettings(ConfigurationTarget.WORKSPACE, this.workspaceSettingsResource, options, group); + + return jsonEditor ? + this.openOrSwitchSettings(ConfigurationTarget.WORKSPACE, this.workspaceSettingsResource, options, group) : + this.openOrSwitchSettings2(ConfigurationTarget.WORKSPACE, options, group); } - openFolderSettings(folder: URI, options?: IEditorOptions, group?: IEditorGroup): TPromise { - return this.openOrSwitchSettings(ConfigurationTarget.WORKSPACE_FOLDER, this.getEditableSettingsURI(ConfigurationTarget.WORKSPACE_FOLDER, folder), options, group); + openFolderSettings(folder: URI, jsonEditor?: boolean, options?: IEditorOptions, group?: IEditorGroup): TPromise { + return jsonEditor ? + this.openOrSwitchSettings(ConfigurationTarget.WORKSPACE_FOLDER, this.getEditableSettingsURI(ConfigurationTarget.WORKSPACE_FOLDER, folder), options, group) : + this.openOrSwitchSettings2(ConfigurationTarget.WORKSPACE_FOLDER, options, group); } - switchSettings(target: ConfigurationTarget, resource: URI): TPromise { + switchSettings(target: ConfigurationTarget, resource: URI, jsonEditor?: boolean): TPromise { + if (!jsonEditor) { + return this.switchSettings2(target); + } + const activeControl = this.editorService.activeControl; if (activeControl && activeControl.input instanceof PreferencesEditorInput) { return this.doSwitchSettings(target, resource, activeControl.input, activeControl.group).then(() => null); @@ -212,6 +231,16 @@ export class PreferencesService extends Disposable implements IPreferencesServic } } + switchSettings2(target: ConfigurationTarget): TPromise { + const activeControl = this.editorService.activeControl; + const resource = this.getDefaultSettingsResource(target); + if (activeControl && activeControl.input instanceof SettingsEditor2Input) { + return this.doSwitchSettings2(resource, activeControl.input, activeControl.group).then(() => null); + } else { + return this.doOpenSettings2(resource).then(() => null); + } + } + openGlobalKeybindingSettings(textual: boolean): TPromise { /* __GDPR__ "openKeybindings" : { @@ -271,6 +300,16 @@ export class PreferencesService extends Disposable implements IPreferencesServic return this.doOpenSettings(configurationTarget, resource, options, group); } + private openOrSwitchSettings2(configurationTarget: ConfigurationTarget, options?: IEditorOptions, group: IEditorGroup = this.editorGroupService.activeGroup): TPromise { + const editorInput = this.getActiveSettingsEditor2Input(group); + const resource = this.getDefaultSettingsResource(configurationTarget); + if (editorInput && editorInput.getResource().fsPath !== resource.fsPath) { + return this.doSwitchSettings2(resource, editorInput, group); + } + + return this.doOpenSettings2(resource, options, group); + } + private doOpenSettings(configurationTarget: ConfigurationTarget, resource: URI, options?: IEditorOptions, group?: IEditorGroup): TPromise { const openDefaultSettings = !!this.configurationService.getValue(DEFAULT_SETTINGS_EDITOR_SETTING); return this.getOrCreateEditableSettingsEditorInput(configurationTarget, resource) @@ -291,6 +330,12 @@ export class PreferencesService extends Disposable implements IPreferencesServic }); } + private doOpenSettings2(resource: URI, options?: IEditorOptions, group?: IEditorGroup): TPromise { + const settingsEditorInput = this.instantiationService.createInstance(SettingsEditor2Input, resource); + this.lastOpenedSettings2Input = settingsEditorInput; + return this.editorService.openEditor(settingsEditorInput, options, group); + } + private doSwitchSettings(target: ConfigurationTarget, resource: URI, input: PreferencesEditorInput, group: IEditorGroup): TPromise { return this.getOrCreateEditableSettingsEditorInput(target, this.getEditableSettingsURI(target, resource)) .then(toInput => { @@ -308,10 +353,28 @@ export class PreferencesService extends Disposable implements IPreferencesServic }); } + private doSwitchSettings2(resource: URI, input: SettingsEditor2Input, group: IEditorGroup): TPromise { + return group.openEditor(input).then(() => { + const replaceWith = this.instantiationService.createInstance(SettingsEditor2Input, resource); + + return group.replaceEditors([{ + editor: input, + replacement: replaceWith + }]).then(() => { + this.lastOpenedSettings2Input = replaceWith; + return group.activeControl; + }); + }); + } + private getActiveSettingsEditorInput(group: IEditorGroup = this.editorGroupService.activeGroup): PreferencesEditorInput { return group.editors.filter(e => e instanceof PreferencesEditorInput)[0]; } + private getActiveSettingsEditor2Input(group: IEditorGroup = this.editorGroupService.activeGroup): SettingsEditor2Input { + return group.editors.filter(e => e instanceof SettingsEditor2Input)[0]; + } + private getConfigurationTargetFromSettingsResource(resource: URI): ConfigurationTarget { if (this.userSettingsResource.toString() === resource.toString()) { return ConfigurationTarget.USER; diff --git a/src/vs/workbench/services/preferences/common/preferences.ts b/src/vs/workbench/services/preferences/common/preferences.ts index 6e8cd0cd871..db2511babc9 100644 --- a/src/vs/workbench/services/preferences/common/preferences.ts +++ b/src/vs/workbench/services/preferences/common/preferences.ts @@ -152,12 +152,11 @@ export interface IPreferencesService { createPreferencesEditorModel(uri: URI): TPromise>; openRawDefaultSettings(): TPromise; - openSettings(): TPromise; - openSettings2(): TPromise; - openGlobalSettings(options?: IEditorOptions, group?: IEditorGroup): TPromise; - openWorkspaceSettings(options?: IEditorOptions, group?: IEditorGroup): TPromise; - openFolderSettings(folder: URI, options?: IEditorOptions, group?: IEditorGroup): TPromise; - switchSettings(target: ConfigurationTarget, resource: URI): TPromise; + openSettings(jsonEditor?: boolean): TPromise; + openGlobalSettings(jsonEditor?: boolean, options?: IEditorOptions, group?: IEditorGroup): TPromise; + openWorkspaceSettings(jsonEditor?: boolean, options?: IEditorOptions, group?: IEditorGroup): TPromise; + openFolderSettings(folder: URI, jsonEditor?: boolean, options?: IEditorOptions, group?: IEditorGroup): TPromise; + switchSettings(target: ConfigurationTarget, resource: URI, jsonEditor?: boolean): TPromise; openGlobalKeybindingSettings(textual: boolean): TPromise; openDefaultKeybindingsFile(): TPromise; diff --git a/src/vs/workbench/services/preferences/common/preferencesEditorInput.ts b/src/vs/workbench/services/preferences/common/preferencesEditorInput.ts index 045707197af..19bf4306846 100644 --- a/src/vs/workbench/services/preferences/common/preferencesEditorInput.ts +++ b/src/vs/workbench/services/preferences/common/preferencesEditorInput.ts @@ -13,8 +13,6 @@ import { EditorInput, SideBySideEditorInput, Verbosity } from 'vs/workbench/comm import { ResourceEditorInput } from 'vs/workbench/common/editor/resourceEditorInput'; import { IHashService } from 'vs/workbench/services/hash/common/hashService'; import { KeybindingsEditorModel } from 'vs/workbench/services/preferences/common/keybindingsEditorModel'; -import { IPreferencesService } from './preferences'; -import { DefaultSettingsEditorModel } from './preferencesModels'; export class PreferencesEditorInput extends SideBySideEditorInput { public static readonly ID: string = 'workbench.editorinputs.preferencesEditorInput'; @@ -79,29 +77,18 @@ export class KeybindingsEditorInput extends EditorInput { } } -export class SettingsEditor2Input extends EditorInput { +export class SettingsEditor2Input extends ResourceEditorInput { public static readonly ID: string = 'workbench.input.settings2'; - constructor( - @IPreferencesService private preferencesService: IPreferencesService + constructor(defaultSettingsResource: URI, + @ITextModelService textModelResolverService: ITextModelService, + @IHashService hashService: IHashService ) { - super(); + super(nls.localize('settingsEditor2InputName', "Settings (Preview)"), '', defaultSettingsResource, textModelResolverService, hashService); } getTypeId(): string { return SettingsEditor2Input.ID; } - - getName(): string { - return nls.localize('settingsEditor2InputName', "Settings (Preview)"); - } - - resolve(): TPromise { - return >this.preferencesService.createPreferencesEditorModel(URI.parse('vscode://defaultsettings/0/settings.json')); - } - - matches(otherInput: any): boolean { - return otherInput instanceof SettingsEditor2Input; - } } From 7158f4997a14e0e4dd9b4fe9621ff2fbbc829251 Mon Sep 17 00:00:00 2001 From: Rob Lourens Date: Wed, 15 Aug 2018 15:04:44 -0700 Subject: [PATCH 0851/1276] Settings editor - add missing TOC title --- src/vs/workbench/parts/preferences/browser/tocTree.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/src/vs/workbench/parts/preferences/browser/tocTree.ts b/src/vs/workbench/parts/preferences/browser/tocTree.ts index 04b2710ebb3..dda5a903e9f 100644 --- a/src/vs/workbench/parts/preferences/browser/tocTree.ts +++ b/src/vs/workbench/parts/preferences/browser/tocTree.ts @@ -133,6 +133,7 @@ export class TOCRenderer implements IRenderer { DOM.toggleClass(template.labelElement, 'no-results', count === 0); template.labelElement.textContent = label; + template.labelElement.title = label; if (count) { template.countElement.textContent = ` (${count})`; From 13cc618c7936943960cf1fd145f133155a9b896b Mon Sep 17 00:00:00 2001 From: Rob Lourens Date: Wed, 15 Aug 2018 15:09:12 -0700 Subject: [PATCH 0852/1276] Settings editor - fix dupe cmd+, registrations --- .../preferences/electron-browser/preferences.contribution.ts | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/vs/workbench/parts/preferences/electron-browser/preferences.contribution.ts b/src/vs/workbench/parts/preferences/electron-browser/preferences.contribution.ts index f12c7b9c456..b81ff8c21d4 100644 --- a/src/vs/workbench/parts/preferences/electron-browser/preferences.contribution.ts +++ b/src/vs/workbench/parts/preferences/electron-browser/preferences.contribution.ts @@ -199,9 +199,10 @@ const category = nls.localize('preferences', "Preferences"); const registry = Registry.as(Extensions.WorkbenchActions); registry.registerWorkbenchAction(new SyncActionDescriptor(OpenRawDefaultSettingsAction, OpenRawDefaultSettingsAction.ID, OpenRawDefaultSettingsAction.LABEL), 'Preferences: Open Raw Default Settings', category); registry.registerWorkbenchAction(new SyncActionDescriptor(OpenSettingsAction, OpenSettingsAction.ID, OpenSettingsAction.LABEL, { primary: KeyMod.CtrlCmd | KeyCode.US_COMMA }), 'Preferences: Open Settings', category); -registry.registerWorkbenchAction(new SyncActionDescriptor(OpenSettingsJsonAction, OpenSettingsJsonAction.ID, OpenSettingsJsonAction.LABEL, { primary: KeyMod.CtrlCmd | KeyCode.US_COMMA }), 'Preferences: Open Settings (JSON)', category); -registry.registerWorkbenchAction(new SyncActionDescriptor(OpenSettings2Action, OpenSettings2Action.ID, OpenSettings2Action.LABEL, { primary: KeyMod.CtrlCmd | KeyCode.US_COMMA }), 'Preferences: Open Settings (UI)', category); +registry.registerWorkbenchAction(new SyncActionDescriptor(OpenSettingsJsonAction, OpenSettingsJsonAction.ID, OpenSettingsJsonAction.LABEL), 'Preferences: Open Settings (JSON)', category); +registry.registerWorkbenchAction(new SyncActionDescriptor(OpenSettings2Action, OpenSettings2Action.ID, OpenSettings2Action.LABEL), 'Preferences: Open Settings (UI)', category); registry.registerWorkbenchAction(new SyncActionDescriptor(OpenGlobalSettingsAction, OpenGlobalSettingsAction.ID, OpenGlobalSettingsAction.LABEL), 'Preferences: Open User Settings', category); + registry.registerWorkbenchAction(new SyncActionDescriptor(OpenGlobalKeybindingsAction, OpenGlobalKeybindingsAction.ID, OpenGlobalKeybindingsAction.LABEL, { primary: KeyChord(KeyMod.CtrlCmd | KeyCode.KEY_K, KeyMod.CtrlCmd | KeyCode.KEY_S) }), 'Preferences: Open Keyboard Shortcuts', category); registry.registerWorkbenchAction(new SyncActionDescriptor(OpenDefaultKeybindingsFileAction, OpenDefaultKeybindingsFileAction.ID, OpenDefaultKeybindingsFileAction.LABEL), 'Preferences: Open Default Keyboard Shortcuts File', category); registry.registerWorkbenchAction(new SyncActionDescriptor(OpenGlobalKeybindingsFileAction, OpenGlobalKeybindingsFileAction.ID, OpenGlobalKeybindingsFileAction.LABEL, { primary: null }), 'Preferences: Open Keyboard Shortcuts File', category); From 36d51e29c75e1e1a71fd1b701c5e4dfe1dea45b9 Mon Sep 17 00:00:00 2001 From: Rob Lourens Date: Wed, 15 Aug 2018 15:27:18 -0700 Subject: [PATCH 0853/1276] #55800 - format a set of well-known acronyms --- .../parts/preferences/browser/settingsLayout.ts | 13 +++++++++++++ .../parts/preferences/browser/settingsTreeModels.ts | 9 +++++++-- 2 files changed, 20 insertions(+), 2 deletions(-) diff --git a/src/vs/workbench/parts/preferences/browser/settingsLayout.ts b/src/vs/workbench/parts/preferences/browser/settingsLayout.ts index 475293ecc85..e8af427980c 100644 --- a/src/vs/workbench/parts/preferences/browser/settingsLayout.ts +++ b/src/vs/workbench/parts/preferences/browser/settingsLayout.ts @@ -197,3 +197,16 @@ export const tocData: ITOCEntry = { } ] }; + +export const knownAcronyms = new Set(); +[ + 'css', + 'html', + 'scss', + 'less', + 'json', + 'js', + 'ts', + 'ie', + 'id', +].forEach(str => knownAcronyms.add(str)); diff --git a/src/vs/workbench/parts/preferences/browser/settingsTreeModels.ts b/src/vs/workbench/parts/preferences/browser/settingsTreeModels.ts index 6daedddb33e..def09bdaf2d 100644 --- a/src/vs/workbench/parts/preferences/browser/settingsTreeModels.ts +++ b/src/vs/workbench/parts/preferences/browser/settingsTreeModels.ts @@ -9,7 +9,7 @@ import URI from 'vs/base/common/uri'; import { localize } from 'vs/nls'; import { ConfigurationTarget, IConfigurationService } from 'vs/platform/configuration/common/configuration'; import { SettingsTarget } from 'vs/workbench/parts/preferences/browser/preferencesWidgets'; -import { ITOCEntry } from 'vs/workbench/parts/preferences/browser/settingsLayout'; +import { ITOCEntry, knownAcronyms } from 'vs/workbench/parts/preferences/browser/settingsLayout'; import { IExtensionSetting, ISearchResult, ISetting } from 'vs/workbench/services/preferences/common/preferences'; import { isArray } from 'vs/base/common/types'; @@ -288,7 +288,12 @@ function wordifyKey(key: string): string { return key .replace(/\.([a-z])/g, (match, p1) => ` › ${p1.toUpperCase()}`) .replace(/([a-z])([A-Z])/g, '$1 $2') // fooBar => foo Bar - .replace(/^[a-z]/g, match => match.toUpperCase()); // foo => Foo + .replace(/^[a-z]/g, match => match.toUpperCase()) // foo => Foo + .replace(/\b\w+\b/g, match => { + return knownAcronyms.has(match.toLowerCase()) ? + match.toUpperCase() : + match; + }); } function trimCategoryForGroup(category: string, groupId: string): string { From 20395b9a1cb2c1873ec0ee113039c6133f48d002 Mon Sep 17 00:00:00 2001 From: Rob Lourens Date: Wed, 15 Aug 2018 15:40:13 -0700 Subject: [PATCH 0854/1276] Settings editor - use type=number for number input fields --- .../parts/preferences/browser/media/settingsEditor2.css | 5 +++++ src/vs/workbench/parts/preferences/browser/settingsTree.ts | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/src/vs/workbench/parts/preferences/browser/media/settingsEditor2.css b/src/vs/workbench/parts/preferences/browser/media/settingsEditor2.css index abd4361d58b..10de0ee25c0 100644 --- a/src/vs/workbench/parts/preferences/browser/media/settingsEditor2.css +++ b/src/vs/workbench/parts/preferences/browser/media/settingsEditor2.css @@ -278,6 +278,11 @@ width: 200px; } +.settings-editor > .settings-body > .settings-tree-container .setting-item.setting-item-number input[type=number]::-webkit-inner-spin-button { + /* Hide arrow button that shows in type=number fields */ + -webkit-appearance: none !important; +} + .settings-editor > .settings-body > .settings-tree-container .setting-item .setting-item-description-markdown * { margin: 0px; } diff --git a/src/vs/workbench/parts/preferences/browser/settingsTree.ts b/src/vs/workbench/parts/preferences/browser/settingsTree.ts index 157578cf08d..acabe226c13 100644 --- a/src/vs/workbench/parts/preferences/browser/settingsTree.ts +++ b/src/vs/workbench/parts/preferences/browser/settingsTree.ts @@ -520,7 +520,7 @@ export class SettingsRenderer implements ITreeRenderer { const common = this.renderCommonTemplate(tree, container, 'number'); const validationErrorMessageElement = DOM.append(container, $('.setting-item-validation-message')); - const inputBox = new InputBox(common.controlElement, this.contextViewService); + const inputBox = new InputBox(common.controlElement, this.contextViewService, { type: 'number' }); common.toDispose.push(inputBox); common.toDispose.push(attachInputBoxStyler(inputBox, this.themeService, { inputBackground: settingsNumberInputBackground, From 6cb1d95483ad6e4212988880045cd8829371cfb1 Mon Sep 17 00:00:00 2001 From: Jackson Kearl Date: Wed, 15 Aug 2018 15:50:35 -0700 Subject: [PATCH 0855/1276] Create new search input model for each instance of a settings editor (#56496) * Create new search input model for each instance of a settings editor * Move increment to render stage --- src/vs/workbench/parts/preferences/browser/settingsEditor2.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/vs/workbench/parts/preferences/browser/settingsEditor2.ts b/src/vs/workbench/parts/preferences/browser/settingsEditor2.ts index d715380fc68..ffe3cb7015d 100644 --- a/src/vs/workbench/parts/preferences/browser/settingsEditor2.ts +++ b/src/vs/workbench/parts/preferences/browser/settingsEditor2.ts @@ -50,6 +50,7 @@ const $ = DOM.$; export class SettingsEditor2 extends BaseEditor { public static readonly ID: string = 'workbench.editor.settings2'; + private static NUM_INSTANCES: number = 0; private static readonly SUGGESTIONS: string[] = [ '@modified', '@tag:usesOnlineServices', '@tag:new' @@ -217,7 +218,7 @@ export class SettingsEditor2 extends BaseEditor { provideResults: (query: string) => { return SettingsEditor2.SUGGESTIONS.filter(tag => query.indexOf(tag) === -1).map(tag => tag + ' '); } - }, searchBoxLabel, 'settingseditor:searchinput', { + }, searchBoxLabel, 'settingseditor:searchinput' + SettingsEditor2.NUM_INSTANCES++, { placeholderText: searchBoxLabel, focusContextKey: this.searchFocusContextKey, // TODO: Aria-live From e85bca2699994cab9a62203cac5505d705581861 Mon Sep 17 00:00:00 2001 From: Rob Lourens Date: Wed, 15 Aug 2018 16:43:30 -0700 Subject: [PATCH 0856/1276] #56296 - avoid unnecessary refreshes on startup onConfigUpdate is fired for every extension settings before the groups are in the model --- .../parts/preferences/browser/settingsEditor2.ts | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/src/vs/workbench/parts/preferences/browser/settingsEditor2.ts b/src/vs/workbench/parts/preferences/browser/settingsEditor2.ts index ffe3cb7015d..5b0763b5c48 100644 --- a/src/vs/workbench/parts/preferences/browser/settingsEditor2.ts +++ b/src/vs/workbench/parts/preferences/browser/settingsEditor2.ts @@ -697,9 +697,14 @@ export class SettingsEditor2 extends BaseEditor { } let refreshP: TPromise; - const elements = key && this.getElementsByKey(key); - if (elements && elements.length) { - refreshP = TPromise.join(elements.map(e => this.settingsTree.refresh(e))); + if (key) { + const elements = this.getElementsByKey(key); + if (elements && elements.length) { + refreshP = TPromise.join(elements.map(e => this.settingsTree.refresh(e))); + } else { + // Refresh requested for a key that we don't know about + return TPromise.wrap(null); + } } else { refreshP = this.settingsTree.refresh(); } From 98d3a0b3f238682131a448f33fd580d090f8e8e8 Mon Sep 17 00:00:00 2001 From: Ramya Achutha Rao Date: Wed, 15 Aug 2018 17:18:23 -0700 Subject: [PATCH 0857/1276] Update theme for error,rune types in Go #56515 --- extensions/theme-defaults/themes/dark_plus.json | 2 ++ extensions/theme-defaults/themes/light_plus.json | 2 ++ 2 files changed, 4 insertions(+) diff --git a/extensions/theme-defaults/themes/dark_plus.json b/extensions/theme-defaults/themes/dark_plus.json index 0ccbaeb606d..3e2c5ac607c 100644 --- a/extensions/theme-defaults/themes/dark_plus.json +++ b/extensions/theme-defaults/themes/dark_plus.json @@ -27,6 +27,8 @@ "storage.type.boolean.go", "storage.type.string.go", "storage.type.uintptr.go", + "storage.type.error.go", + "storage.type.rune.go", "storage.type.cs", "storage.type.generic.cs", "storage.type.modifier.cs", diff --git a/extensions/theme-defaults/themes/light_plus.json b/extensions/theme-defaults/themes/light_plus.json index 4c9985d44f2..726cae4058d 100644 --- a/extensions/theme-defaults/themes/light_plus.json +++ b/extensions/theme-defaults/themes/light_plus.json @@ -27,6 +27,8 @@ "storage.type.boolean.go", "storage.type.string.go", "storage.type.uintptr.go", + "storage.type.error.go", + "storage.type.rune.go", "storage.type.cs", "storage.type.generic.cs", "storage.type.modifier.cs", From 2336fc94c9164397961aa90dc1191fb09c815538 Mon Sep 17 00:00:00 2001 From: Rob Lourens Date: Wed, 15 Aug 2018 17:26:29 -0700 Subject: [PATCH 0858/1276] Settings editor - clean up leftover description styling --- .../preferences/browser/media/settingsEditor2.css | 15 +-------------- 1 file changed, 1 insertion(+), 14 deletions(-) diff --git a/src/vs/workbench/parts/preferences/browser/media/settingsEditor2.css b/src/vs/workbench/parts/preferences/browser/media/settingsEditor2.css index 10de0ee25c0..f46306d11e3 100644 --- a/src/vs/workbench/parts/preferences/browser/media/settingsEditor2.css +++ b/src/vs/workbench/parts/preferences/browser/media/settingsEditor2.css @@ -244,13 +244,6 @@ .settings-editor > .settings-body > .settings-tree-container .setting-item .setting-item-deprecation-message, .settings-editor > .settings-body > .settings-tree-container .setting-item .setting-item-description { margin-top: 3px; - overflow: hidden; - text-overflow: ellipsis; - height: 18px; - display: -webkit-box; - -webkit-line-clamp: 1; - -webkit-box-orient: vertical; - transform: translate3d(0px, 0px, 0px); } .settings-editor > .settings-body > .settings-tree-container .setting-item .setting-item-deprecation-message { @@ -302,17 +295,11 @@ visibility: hidden; } -.settings-editor > .settings-body > .settings-tree-container .setting-item.is-expanded .setting-item-description, -.settings-editor > .settings-body > .settings-tree-container .setting-item.setting-measure-helper .setting-item-description { - height: initial; - -webkit-line-clamp: initial; -} - .settings-editor > .settings-body > .settings-tree-container .setting-item .setting-item-enumDescription { display: none; } -.settings-editor > .settings-body > .settings-tree-container .setting-item.is-expanded .setting-item-enumDescription, +.settings-editor > .settings-body > .settings-tree-container .setting-item .setting-item-enumDescription, .settings-editor > .settings-body > .settings-tree-container .setting-item.setting-measure-helper .setting-item-enumDescription { display: block; } From 5c8e8d6b8eb91e9bb482edbe9fe5a71017fcc808 Mon Sep 17 00:00:00 2001 From: Rob Lourens Date: Wed, 15 Aug 2018 19:38:12 -0700 Subject: [PATCH 0859/1276] Bump ripgrep to 0.9.0 --- extensions/search-rg/package.json | 2 +- extensions/search-rg/yarn.lock | 6 +++--- package.json | 2 +- yarn.lock | 6 +++--- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/extensions/search-rg/package.json b/extensions/search-rg/package.json index c4621670df8..a967105f855 100644 --- a/extensions/search-rg/package.json +++ b/extensions/search-rg/package.json @@ -15,7 +15,7 @@ "dependencies": { "vscode-extension-telemetry": "0.0.18", "vscode-nls": "^3.2.4", - "vscode-ripgrep": "^1.0.1" + "vscode-ripgrep": "1.1.0" }, "devDependencies": { "@types/node": "8.0.33", diff --git a/extensions/search-rg/yarn.lock b/extensions/search-rg/yarn.lock index 1be6ca92db5..33381ca1f0d 100644 --- a/extensions/search-rg/yarn.lock +++ b/extensions/search-rg/yarn.lock @@ -1549,9 +1549,9 @@ vscode-nls@^3.2.4: version "3.2.4" resolved "https://registry.yarnpkg.com/vscode-nls/-/vscode-nls-3.2.4.tgz#2166b4183c8aea884d20727f5449e62be69fd398" -vscode-ripgrep@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/vscode-ripgrep/-/vscode-ripgrep-1.0.1.tgz#eff2f2b2a49921ac0acd3ff8dfecaaeebf0184cf" +vscode-ripgrep@1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/vscode-ripgrep/-/vscode-ripgrep-1.1.0.tgz#93c1e39d88342ee1b15530a12898ce930d511948" vscode@^1.1.17: version "1.1.17" diff --git a/package.json b/package.json index 71487dd58a3..9a367d0d70b 100644 --- a/package.json +++ b/package.json @@ -48,7 +48,7 @@ "vscode-chokidar": "1.6.2", "vscode-debugprotocol": "1.31.0", "vscode-nsfw": "1.0.17", - "vscode-ripgrep": "^1.0.1", + "vscode-ripgrep": "1.1.0", "vscode-textmate": "^4.0.1", "vscode-xterm": "3.7.0-beta4", "winreg": "^1.2.4", diff --git a/yarn.lock b/yarn.lock index a3d62b2ae38..454ff72215d 100644 --- a/yarn.lock +++ b/yarn.lock @@ -6115,9 +6115,9 @@ vscode-nsfw@1.0.17: nan "^2.0.0" promisify-node "^0.3.0" -vscode-ripgrep@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/vscode-ripgrep/-/vscode-ripgrep-1.0.1.tgz#eff2f2b2a49921ac0acd3ff8dfecaaeebf0184cf" +vscode-ripgrep@1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/vscode-ripgrep/-/vscode-ripgrep-1.1.0.tgz#93c1e39d88342ee1b15530a12898ce930d511948" vscode-textmate@^4.0.1: version "4.0.1" From 50d7fa2ebc358afb48ed24a7cc8dff208bcda632 Mon Sep 17 00:00:00 2001 From: Rob Lourens Date: Wed, 15 Aug 2018 19:58:51 -0700 Subject: [PATCH 0860/1276] Handle new error messages in ripgrep --- src/vs/base/common/strings.ts | 4 ++++ src/vs/base/test/common/strings.test.ts | 12 ++++++++++++ .../services/search/node/ripgrepTextSearch.ts | 7 ++++++- 3 files changed, 22 insertions(+), 1 deletion(-) diff --git a/src/vs/base/common/strings.ts b/src/vs/base/common/strings.ts index 31dff819977..5cb6ea76754 100644 --- a/src/vs/base/common/strings.ts +++ b/src/vs/base/common/strings.ts @@ -685,3 +685,7 @@ export function containsUppercaseCharacter(target: string, ignoreEscapedChars = return target.toLowerCase() !== target; } + +export function uppercaseFirstLetter(str: string): string { + return str.charAt(0).toUpperCase() + str.slice(1); +} \ No newline at end of file diff --git a/src/vs/base/test/common/strings.test.ts b/src/vs/base/test/common/strings.test.ts index 295c3adb50a..8d7c6c705da 100644 --- a/src/vs/base/test/common/strings.test.ts +++ b/src/vs/base/test/common/strings.test.ts @@ -381,4 +381,16 @@ suite('Strings', () => { assert.equal(strings.containsUppercaseCharacter(str, true), result, `Wrong result for ${str}`); }); }); + + test('uppercaseFirstLetter', () => { + [ + ['', ''], + ['foo', 'Foo'], + ['f', 'F'], + ['123', '123'], + ['.a', '.a'], + ].forEach(([inStr, result]) => { + assert.equal(strings.uppercaseFirstLetter(inStr), result, `Wrong result for ${inStr}`); + }); + }); }); diff --git a/src/vs/workbench/services/search/node/ripgrepTextSearch.ts b/src/vs/workbench/services/search/node/ripgrepTextSearch.ts index c9e4a7f498c..7f37a9f4ad3 100644 --- a/src/vs/workbench/services/search/node/ripgrepTextSearch.ts +++ b/src/vs/workbench/services/search/node/ripgrepTextSearch.ts @@ -149,12 +149,17 @@ export class RipgrepEngine { * "failed" when a fatal error was produced. */ export function rgErrorMsgForDisplay(msg: string): string | undefined { - const firstLine = msg.split('\n')[0].trim(); + const lines = msg.trim().split('\n'); + const firstLine = lines[0].trim(); if (strings.startsWith(firstLine, 'Error parsing regex')) { return firstLine; } + if (strings.startsWith(firstLine, 'regex parse error')) { + return strings.uppercaseFirstLetter(lines[lines.length - 1].trim()); + } + if (strings.startsWith(firstLine, 'error parsing glob') || strings.startsWith(firstLine, 'unsupported encoding')) { // Uppercase first letter From fd4d0c71de6477fa0cdfa072f9a35a3fc2d16dc5 Mon Sep 17 00:00:00 2001 From: Rob Lourens Date: Wed, 15 Aug 2018 20:04:43 -0700 Subject: [PATCH 0861/1276] Fix #48771 - prevent rg from checking global gitignores --- extensions/search-rg/src/ripgrepTextSearch.ts | 1 + src/vs/workbench/services/search/node/ripgrepTextSearch.ts | 1 + 2 files changed, 2 insertions(+) diff --git a/extensions/search-rg/src/ripgrepTextSearch.ts b/extensions/search-rg/src/ripgrepTextSearch.ts index 728365bff17..7ba477c724c 100644 --- a/extensions/search-rg/src/ripgrepTextSearch.ts +++ b/extensions/search-rg/src/ripgrepTextSearch.ts @@ -366,6 +366,7 @@ function getRgArgs(query: vscode.TextSearchQuery, options: vscode.TextSearchOpti } args.push('--no-config'); + args.push('--no-ignore-global'); // Folder to search args.push('--'); diff --git a/src/vs/workbench/services/search/node/ripgrepTextSearch.ts b/src/vs/workbench/services/search/node/ripgrepTextSearch.ts index 7f37a9f4ad3..56cb2ff5b99 100644 --- a/src/vs/workbench/services/search/node/ripgrepTextSearch.ts +++ b/src/vs/workbench/services/search/node/ripgrepTextSearch.ts @@ -507,6 +507,7 @@ function getRgArgs(config: IRawSearch) { } args.push('--no-config'); + args.push('--no-ignore-global'); // Folder to search args.push('--'); From 599251673b5de62a32645fa54ecb6fd9de4279be Mon Sep 17 00:00:00 2001 From: Rob Lourens Date: Wed, 15 Aug 2018 21:20:27 -0700 Subject: [PATCH 0862/1276] Fix #56296 - much faster refreshing by avoiding measuring rows when possible --- .../browser/media/settingsEditor2.css | 5 ++ .../parts/preferences/browser/settingsTree.ts | 54 ++++++++++++++----- 2 files changed, 47 insertions(+), 12 deletions(-) diff --git a/src/vs/workbench/parts/preferences/browser/media/settingsEditor2.css b/src/vs/workbench/parts/preferences/browser/media/settingsEditor2.css index f46306d11e3..f5df0d24495 100644 --- a/src/vs/workbench/parts/preferences/browser/media/settingsEditor2.css +++ b/src/vs/workbench/parts/preferences/browser/media/settingsEditor2.css @@ -295,6 +295,11 @@ visibility: hidden; } +.settings-editor.search-mode > .settings-body > .settings-tree-container .setting-measure-container.measure-bool-description .setting-item-description { + /* Allocate space for the checkbox control */ + margin-left: 27px; +} + .settings-editor > .settings-body > .settings-tree-container .setting-item .setting-item-enumDescription { display: none; } diff --git a/src/vs/workbench/parts/preferences/browser/settingsTree.ts b/src/vs/workbench/parts/preferences/browser/settingsTree.ts index acabe226c13..8cf3c9d980d 100644 --- a/src/vs/workbench/parts/preferences/browser/settingsTree.ts +++ b/src/vs/workbench/parts/preferences/browser/settingsTree.ts @@ -274,8 +274,9 @@ export class SettingsRenderer implements ITreeRenderer { private readonly _onDidFocusSetting: Emitter = new Emitter(); public readonly onDidFocusSetting: Event = this._onDidFocusSetting.event; - private measureContainer: HTMLElement; - private measureTemplatesPool = new Map(); + private descriptionMeasureContainer: HTMLElement; + private longestSingleLineDescription = 0; + private rowHeightCache = new Map(); private lastRenderedWidth: number; @@ -287,7 +288,11 @@ export class SettingsRenderer implements ITreeRenderer { @IInstantiationService private readonly instantiationService: IInstantiationService, @ICommandService private readonly commandService: ICommandService, ) { - this.measureContainer = DOM.append(_measureContainer, $('.setting-measure-container.monaco-tree-row')); + this.descriptionMeasureContainer = $('.setting-item-description'); + DOM.append(_measureContainer, + $('.setting-measure-container.monaco-tree-row', undefined, + $('.setting-item', undefined, + this.descriptionMeasureContainer))); } updateWidth(width: number): void { @@ -338,19 +343,44 @@ export class SettingsRenderer implements ITreeRenderer { } private measureSettingElementHeight(tree: ITree, element: SettingsTreeSettingElement): number { - const templateId = this.getTemplateId(tree, element); - const template: ISettingItemTemplate = this.measureTemplatesPool.get(templateId) || this.renderTemplate(tree, templateId, $('.setting-measure-helper')) as ISettingItemTemplate; - this.measureTemplatesPool.set(templateId, template); - this.renderElement(tree, element, templateId, template); + let heightExcludingDescription = 88; - this.measureContainer.appendChild(template.containerElement); - const height = this.measureContainer.offsetHeight; - this.measureContainer.removeChild(this.measureContainer.firstChild); - return height; + if (element.valueType === 'boolean') { + heightExcludingDescription = 60; + } + + return heightExcludingDescription + this.measureSettingDescription(element); + } + + private measureSettingDescription(element: SettingsTreeSettingElement): number { + if (element.description.length < this.longestSingleLineDescription * .8) { + // Most setting descriptions are one short line, so try to avoid measuring them. + // If the description is less than 80% of the longest single line description, assume this will also render to be one line. + return 18; + } + + const boolMeasureClass = 'measure-bool-description'; + if (element.valueType === 'boolean') { + this.descriptionMeasureContainer.classList.add(boolMeasureClass); + } else if (this.descriptionMeasureContainer.classList.contains(boolMeasureClass)) { + this.descriptionMeasureContainer.classList.remove(boolMeasureClass); + } + + // Remove markdown links and setting links + const measureText = element.description + .replace(/\[(.*)\]\(.*\)/g, '$1') + .replace(/`#(.*)#`/g, '$1'); + + this.descriptionMeasureContainer.innerText = measureText; + const h = this.descriptionMeasureContainer.offsetHeight; + if (h < 20 && measureText.length > this.longestSingleLineDescription) { + this.longestSingleLineDescription = measureText.length; + } + + return h; } getTemplateId(tree: ITree, element: SettingsTreeElement): string { - if (element instanceof SettingsTreeGroupElement) { return SETTINGS_GROUP_ELEMENT_TEMPLATE_ID; } From 5c63604e2c35b367e5c9e1efd6bc0d1e0896f41c Mon Sep 17 00:00:00 2001 From: Rob Lourens Date: Wed, 15 Aug 2018 21:39:52 -0700 Subject: [PATCH 0863/1276] Settings editor - fix "Open Settings (JSON)" command --- .../workbench/parts/preferences/browser/preferencesActions.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vs/workbench/parts/preferences/browser/preferencesActions.ts b/src/vs/workbench/parts/preferences/browser/preferencesActions.ts index e14be3af87a..5ae5ee293a8 100644 --- a/src/vs/workbench/parts/preferences/browser/preferencesActions.ts +++ b/src/vs/workbench/parts/preferences/browser/preferencesActions.ts @@ -90,7 +90,7 @@ export class OpenSettingsJsonAction extends Action { } public run(event?: any): TPromise { - return this.preferencesService.openSettings(); + return this.preferencesService.openSettings(true); } } From e2b722d26262a2a15c1e9246a6ab40475ea9c5ed Mon Sep 17 00:00:00 2001 From: Rob Lourens Date: Wed, 15 Aug 2018 21:40:19 -0700 Subject: [PATCH 0864/1276] Settings editor - bump search debounce times --- src/vs/workbench/parts/preferences/browser/settingsEditor2.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/vs/workbench/parts/preferences/browser/settingsEditor2.ts b/src/vs/workbench/parts/preferences/browser/settingsEditor2.ts index 5b0763b5c48..1872b03365d 100644 --- a/src/vs/workbench/parts/preferences/browser/settingsEditor2.ts +++ b/src/vs/workbench/parts/preferences/browser/settingsEditor2.ts @@ -112,8 +112,8 @@ export class SettingsEditor2 extends BaseEditor { ) { super(SettingsEditor2.ID, telemetryService, themeService); this.delayedFilterLogging = new Delayer(1000); - this.localSearchDelayer = new Delayer(100); - this.remoteSearchThrottle = new ThrottledDelayer(200); + this.localSearchDelayer = new Delayer(300); + this.remoteSearchThrottle = new ThrottledDelayer(400); this.viewState = { settingsTarget: ConfigurationTarget.USER }; this.delayRefreshOnLayout = new Delayer(100); From b57003f33007dac943640abc29c64b888a671463 Mon Sep 17 00:00:00 2001 From: Benjamin Pasero Date: Thu, 16 Aug 2018 07:38:54 +0200 Subject: [PATCH 0865/1276] NodeBuffer => Buffer --- extensions/git/src/encoding.ts | 2 +- extensions/git/src/typings/jschardet.d.ts | 2 +- .../src/features/validationProvider.ts | 2 +- src/typings/iconv-lite.d.ts | 4 ++-- src/typings/jschardet.d.ts | 2 +- src/vs/base/node/crypto.ts | 2 +- src/vs/base/node/decoder.ts | 2 +- src/vs/base/node/encoding.ts | 8 ++++---- src/vs/base/node/extfs.ts | 6 +++--- src/vs/base/node/pfs.ts | 2 +- src/vs/base/node/stream.ts | 4 ++-- .../files/node/watcher/win32/csharpWatcherService.ts | 6 +++--- .../workbench/services/search/node/worker/searchWorker.ts | 4 ++-- 13 files changed, 23 insertions(+), 23 deletions(-) diff --git a/extensions/git/src/encoding.ts b/extensions/git/src/encoding.ts index 4396105567f..d2bb831f123 100644 --- a/extensions/git/src/encoding.ts +++ b/extensions/git/src/encoding.ts @@ -9,7 +9,7 @@ import * as jschardet from 'jschardet'; jschardet.Constants.MINIMUM_THRESHOLD = 0.2; -function detectEncodingByBOM(buffer: NodeBuffer): string | null { +function detectEncodingByBOM(buffer: Buffer): string | null { if (!buffer || buffer.length < 2) { return null; } diff --git a/extensions/git/src/typings/jschardet.d.ts b/extensions/git/src/typings/jschardet.d.ts index 9c553b129eb..f252a47fd09 100644 --- a/extensions/git/src/typings/jschardet.d.ts +++ b/extensions/git/src/typings/jschardet.d.ts @@ -3,7 +3,7 @@ declare module 'jschardet' { encoding: string, confidence: number } - export function detect(buffer: NodeBuffer): IDetectedMap; + export function detect(buffer: Buffer): IDetectedMap; export const Constants: { MINIMUM_THRESHOLD: number, diff --git a/extensions/php-language-features/src/features/validationProvider.ts b/extensions/php-language-features/src/features/validationProvider.ts index d139fde1121..c3c513d3220 100644 --- a/extensions/php-language-features/src/features/validationProvider.ts +++ b/extensions/php-language-features/src/features/validationProvider.ts @@ -23,7 +23,7 @@ export class LineDecoder { this.remaining = null; } - public write(buffer: NodeBuffer): string[] { + public write(buffer: Buffer): string[] { var result: string[] = []; var value = this.remaining ? this.remaining + this.stringDecoder.write(buffer) diff --git a/src/typings/iconv-lite.d.ts b/src/typings/iconv-lite.d.ts index 2b66468d456..0ed342db377 100644 --- a/src/typings/iconv-lite.d.ts +++ b/src/typings/iconv-lite.d.ts @@ -6,9 +6,9 @@ /// declare module 'iconv-lite' { - export function decode(buffer: NodeBuffer, encoding: string): string; + export function decode(buffer: Buffer, encoding: string): string; - export function encode(content: string | NodeBuffer, encoding: string, options?: { addBOM?: boolean }): NodeBuffer; + export function encode(content: string | Buffer, encoding: string, options?: { addBOM?: boolean }): Buffer; export function encodingExists(encoding: string): boolean; diff --git a/src/typings/jschardet.d.ts b/src/typings/jschardet.d.ts index 9c553b129eb..f252a47fd09 100644 --- a/src/typings/jschardet.d.ts +++ b/src/typings/jschardet.d.ts @@ -3,7 +3,7 @@ declare module 'jschardet' { encoding: string, confidence: number } - export function detect(buffer: NodeBuffer): IDetectedMap; + export function detect(buffer: Buffer): IDetectedMap; export const Constants: { MINIMUM_THRESHOLD: number, diff --git a/src/vs/base/node/crypto.ts b/src/vs/base/node/crypto.ts index b658da126b6..4951a5dcc09 100644 --- a/src/vs/base/node/crypto.ts +++ b/src/vs/base/node/crypto.ts @@ -32,7 +32,7 @@ export function checksum(path: string, sha1hash: string): TPromise { input.once('error', done); input.once('end', done); hashStream.once('error', done); - hashStream.once('data', (data: NodeBuffer) => done(null, data.toString('hex'))); + hashStream.once('data', (data: Buffer) => done(null, data.toString('hex'))); }); return promise.then(hash => { diff --git a/src/vs/base/node/decoder.ts b/src/vs/base/node/decoder.ts index de145fc29b2..9cfb1094995 100644 --- a/src/vs/base/node/decoder.ts +++ b/src/vs/base/node/decoder.ts @@ -25,7 +25,7 @@ export class LineDecoder { this.remaining = null; } - public write(buffer: NodeBuffer): string[] { + public write(buffer: Buffer): string[] { let result: string[] = []; let value = this.remaining ? this.remaining + this.stringDecoder.write(buffer) diff --git a/src/vs/base/node/encoding.ts b/src/vs/base/node/encoding.ts index 2c68f89b6ba..f5dc3ab5ffa 100644 --- a/src/vs/base/node/encoding.ts +++ b/src/vs/base/node/encoding.ts @@ -119,11 +119,11 @@ export function bomLength(encoding: string): number { return 0; } -export function decode(buffer: NodeBuffer, encoding: string): string { +export function decode(buffer: Buffer, encoding: string): string { return iconv.decode(buffer, toNodeEncoding(encoding)); } -export function encode(content: string | NodeBuffer, encoding: string, options?: { addBOM?: boolean }): NodeBuffer { +export function encode(content: string | Buffer, encoding: string, options?: { addBOM?: boolean }): Buffer { return iconv.encode(content, toNodeEncoding(encoding), options); } @@ -147,7 +147,7 @@ function toNodeEncoding(enc: string): string { return enc; } -export function detectEncodingByBOMFromBuffer(buffer: NodeBuffer, bytesRead: number): string { +export function detectEncodingByBOMFromBuffer(buffer: Buffer, bytesRead: number): string { if (!buffer || bytesRead < 2) { return null; } @@ -193,7 +193,7 @@ const IGNORE_ENCODINGS = ['ascii', 'utf-8', 'utf-16', 'utf-32']; /** * Guesses the encoding from buffer. */ -export function guessEncodingByBuffer(buffer: NodeBuffer): TPromise { +export function guessEncodingByBuffer(buffer: Buffer): TPromise { return toWinJsPromise(import('jschardet')).then(jschardet => { jschardet.Constants.MINIMUM_THRESHOLD = MINIMUM_THRESHOLD; diff --git a/src/vs/base/node/extfs.ts b/src/vs/base/node/extfs.ts index 82e1cfd0fde..b52c4e36f0d 100644 --- a/src/vs/base/node/extfs.ts +++ b/src/vs/base/node/extfs.ts @@ -365,7 +365,7 @@ export interface IWriteFileOptions { } let canFlush = true; -export function writeFileAndFlush(path: string, data: string | NodeBuffer | NodeJS.ReadableStream, options: IWriteFileOptions, callback: (error?: Error) => void): void { +export function writeFileAndFlush(path: string, data: string | Buffer | NodeJS.ReadableStream, options: IWriteFileOptions, callback: (error?: Error) => void): void { options = ensureOptions(options); if (typeof data === 'string' || Buffer.isBuffer(data)) { @@ -466,7 +466,7 @@ function doWriteFileStreamAndFlush(path: string, reader: NodeJS.ReadableStream, // not in some cache. // // See https://github.com/nodejs/node/blob/v5.10.0/lib/fs.js#L1194 -function doWriteFileAndFlush(path: string, data: string | NodeBuffer, options: IWriteFileOptions, callback: (error?: Error) => void): void { +function doWriteFileAndFlush(path: string, data: string | Buffer, options: IWriteFileOptions, callback: (error?: Error) => void): void { if (options.encoding) { data = encode(data, options.encoding.charset, { addBOM: options.encoding.addBOM }); } @@ -503,7 +503,7 @@ function doWriteFileAndFlush(path: string, data: string | NodeBuffer, options: I }); } -export function writeFileAndFlushSync(path: string, data: string | NodeBuffer, options?: IWriteFileOptions): void { +export function writeFileAndFlushSync(path: string, data: string | Buffer, options?: IWriteFileOptions): void { options = ensureOptions(options); if (options.encoding) { diff --git a/src/vs/base/node/pfs.ts b/src/vs/base/node/pfs.ts index 6172b9a30ad..5678be80081 100644 --- a/src/vs/base/node/pfs.ts +++ b/src/vs/base/node/pfs.ts @@ -98,7 +98,7 @@ export function readFile(path: string, encoding?: string): TPromise } = Object.create(null); export function writeFile(path: string, data: string, options?: extfs.IWriteFileOptions): TPromise; -export function writeFile(path: string, data: NodeBuffer, options?: extfs.IWriteFileOptions): TPromise; +export function writeFile(path: string, data: Buffer, options?: extfs.IWriteFileOptions): TPromise; export function writeFile(path: string, data: Uint8Array, options?: extfs.IWriteFileOptions): TPromise; export function writeFile(path: string, data: NodeJS.ReadableStream, options?: extfs.IWriteFileOptions): TPromise; export function writeFile(path: string, data: any, options?: extfs.IWriteFileOptions): TPromise { diff --git a/src/vs/base/node/stream.ts b/src/vs/base/node/stream.ts index a9ba27bb005..a1919336918 100644 --- a/src/vs/base/node/stream.ts +++ b/src/vs/base/node/stream.ts @@ -10,7 +10,7 @@ import * as fs from 'fs'; import { TPromise } from 'vs/base/common/winjs.base'; export interface ReadResult { - buffer: NodeBuffer; + buffer: Buffer; bytesRead: number; } @@ -24,7 +24,7 @@ export function readExactlyByFile(file: string, totalBytes: number): TPromise { if (closeError) { return error(closeError); diff --git a/src/vs/workbench/services/files/node/watcher/win32/csharpWatcherService.ts b/src/vs/workbench/services/files/node/watcher/win32/csharpWatcherService.ts index 8c18ce5b640..93dc71bd159 100644 --- a/src/vs/workbench/services/files/node/watcher/win32/csharpWatcherService.ts +++ b/src/vs/workbench/services/files/node/watcher/win32/csharpWatcherService.ts @@ -46,7 +46,7 @@ export class OutOfProcessWin32FolderWatcher { const stdoutLineDecoder = new decoder.LineDecoder(); // Events over stdout - this.handle.stdout.on('data', (data: NodeBuffer) => { + this.handle.stdout.on('data', (data: Buffer) => { // Collect raw events from output const rawEvents: IRawFileChange[] = []; @@ -86,13 +86,13 @@ export class OutOfProcessWin32FolderWatcher { // Errors this.handle.on('error', (error: Error) => this.onError(error)); - this.handle.stderr.on('data', (data: NodeBuffer) => this.onError(data)); + this.handle.stderr.on('data', (data: Buffer) => this.onError(data)); // Exit this.handle.on('exit', (code: number, signal: string) => this.onExit(code, signal)); } - private onError(error: Error | NodeBuffer): void { + private onError(error: Error | Buffer): void { this.errorCallback('[FileWatcher] process error: ' + error.toString()); } diff --git a/src/vs/workbench/services/search/node/worker/searchWorker.ts b/src/vs/workbench/services/search/node/worker/searchWorker.ts index cdda1b2b257..d35999d4eda 100644 --- a/src/vs/workbench/services/search/node/worker/searchWorker.ts +++ b/src/vs/workbench/services/search/node/worker/searchWorker.ts @@ -177,8 +177,8 @@ export class SearchWorkerEngine { return clb(null); // return early if canceled or limit reached } - fs.read(fd, buffer, 0, buffer.length, null, (error: Error, bytesRead: number, buffer: NodeBuffer) => { - const decodeBuffer = (buffer: NodeBuffer, start: number, end: number): string => { + fs.read(fd, buffer, 0, buffer.length, null, (error: Error, bytesRead: number, buffer: Buffer) => { + const decodeBuffer = (buffer: Buffer, start: number, end: number): string => { if (options.encoding === UTF8 || options.encoding === UTF8_with_bom) { return buffer.toString(undefined, start, end); // much faster to use built in toString() when encoding is default } From 54408207e189d78bf963f84c75db853f28575ff8 Mon Sep 17 00:00:00 2001 From: Karthikayan Date: Thu, 16 Aug 2018 11:10:29 +0530 Subject: [PATCH 0866/1276] Notify number of outdated extensions on Check for Extension updates action (#56053) * show outdated extension for Check for Extension updates action * include CheckForUpdates also * avoid flicker perspection; show no. of outdated extensions * remove the temp code for local test * add prompt to update all extensions * Remove option to update all and refactor * Dont move focus, let the user do it if they choose to do so --- .../electron-browser/extensionsActions.ts | 30 +++++++++++++++---- 1 file changed, 25 insertions(+), 5 deletions(-) diff --git a/src/vs/workbench/parts/extensions/electron-browser/extensionsActions.ts b/src/vs/workbench/parts/extensions/electron-browser/extensionsActions.ts index 77daf931345..645a6674587 100644 --- a/src/vs/workbench/parts/extensions/electron-browser/extensionsActions.ts +++ b/src/vs/workbench/parts/extensions/electron-browser/extensionsActions.ts @@ -8,6 +8,7 @@ import { localize } from 'vs/nls'; import { TPromise } from 'vs/base/common/winjs.base'; import { IAction, Action } from 'vs/base/common/actions'; import { Throttler } from 'vs/base/common/async'; +import severity from 'vs/base/common/severity'; import * as DOM from 'vs/base/browser/dom'; import * as paths from 'vs/base/common/paths'; import { Event } from 'vs/base/common/event'; @@ -756,18 +757,37 @@ export class DisableAction extends Action { export class CheckForUpdatesAction extends Action { static readonly ID = 'workbench.extensions.action.checkForUpdates'; - static LABEL = localize('checkForUpdates', "Check for Updates"); + static LABEL = localize('checkForUpdates', "Check for Extension Updates"); constructor( - id = UpdateAllAction.ID, - label = UpdateAllAction.LABEL, - @IExtensionsWorkbenchService private extensionsWorkbenchService: IExtensionsWorkbenchService + id = CheckForUpdatesAction.ID, + label = CheckForUpdatesAction.LABEL, + @IExtensionsWorkbenchService private extensionsWorkbenchService: IExtensionsWorkbenchService, + @IViewletService private viewletService: IViewletService, + @INotificationService private notificationService: INotificationService ) { super(id, label, '', true); } + private checkUpdatesAndNotify(): void { + this.extensionsWorkbenchService.queryLocal().then( + extensions => { + const outdatedCount = extensions.filter(ext => ext.outdated === true).length; + let msgAvailableExtensions = localize('noUpdatesAvailable', "All Extensions are up to date."); + if (outdatedCount > 0) { + msgAvailableExtensions = outdatedCount === 1 ? localize('updateAvailable', "An Extension update is available.") + : localize('updatesAvailable', "{0} extensions updates are available.", outdatedCount); + this.viewletService.openViewlet(VIEWLET_ID, true) + .then(viewlet => viewlet as IExtensionsViewlet) + .then(viewlet => viewlet.search('')); + } + this.notificationService.notify({ severity: severity.Info, message: msgAvailableExtensions }); + } + ); + } + run(): TPromise { - return this.extensionsWorkbenchService.checkForUpdates(); + return this.extensionsWorkbenchService.checkForUpdates().then(() => this.checkUpdatesAndNotify()); } } From ea6d8a703738ad814f219ed3aaf5aa8a5d93dd42 Mon Sep 17 00:00:00 2001 From: Benjamin Pasero Date: Thu, 16 Aug 2018 07:41:39 +0200 Subject: [PATCH 0867/1276] debt - avoid deprecated buffer usage --- .../services/search/test/node/ripgrepTextSearch.test.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vs/workbench/services/search/test/node/ripgrepTextSearch.test.ts b/src/vs/workbench/services/search/test/node/ripgrepTextSearch.test.ts index ac23cfa0c7e..f55b1f172c7 100644 --- a/src/vs/workbench/services/search/test/node/ripgrepTextSearch.test.ts +++ b/src/vs/workbench/services/search/test/node/ripgrepTextSearch.test.ts @@ -157,7 +157,7 @@ suite('RipgrepParser', () => { test('Parses chunks broken in the middle of a multibyte character', () => { const text = getFileLine('foo/bar') + '\n' + getMatchLine(0, ['before漢', 'match', 'after']) + '\n'; - const buf = new Buffer(text); + const buf = Buffer.from(text); // Split the buffer at every possible position - it should still be parsed correctly for (let i = 0; i < buf.length; i++) { From f03b305c84631e7f6607fb4abbb2d52b93ba21cc Mon Sep 17 00:00:00 2001 From: Rob Lourens Date: Wed, 15 Aug 2018 21:44:34 -0700 Subject: [PATCH 0868/1276] Settings editor - avoid triggering reflow in layout() --- src/vs/workbench/parts/preferences/browser/settingsEditor2.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vs/workbench/parts/preferences/browser/settingsEditor2.ts b/src/vs/workbench/parts/preferences/browser/settingsEditor2.ts index 1872b03365d..cdc1939f1e7 100644 --- a/src/vs/workbench/parts/preferences/browser/settingsEditor2.ts +++ b/src/vs/workbench/parts/preferences/browser/settingsEditor2.ts @@ -907,7 +907,7 @@ export class SettingsEditor2 extends BaseEditor { } private layoutTrees(dimension: DOM.Dimension): void { - const listHeight = dimension.height - (DOM.getDomNodePagePosition(this.headerContainer).height + 11 /*padding*/); + const listHeight = dimension.height - (95 + 11 /* header height + padding*/); const settingsTreeHeight = listHeight - 14; this.settingsTreeContainer.style.height = `${settingsTreeHeight}px`; this.settingsTree.layout(settingsTreeHeight, 800); From 85892802d16336610d6ec4b31bef21f441ac95e8 Mon Sep 17 00:00:00 2001 From: Rob Lourens Date: Wed, 15 Aug 2018 21:48:16 -0700 Subject: [PATCH 0869/1276] Settings editor - tweak padding --- src/vs/workbench/parts/preferences/browser/settingsTree.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vs/workbench/parts/preferences/browser/settingsTree.ts b/src/vs/workbench/parts/preferences/browser/settingsTree.ts index 8cf3c9d980d..3a3e92fbd2f 100644 --- a/src/vs/workbench/parts/preferences/browser/settingsTree.ts +++ b/src/vs/workbench/parts/preferences/browser/settingsTree.ts @@ -343,7 +343,7 @@ export class SettingsRenderer implements ITreeRenderer { } private measureSettingElementHeight(tree: ITree, element: SettingsTreeSettingElement): number { - let heightExcludingDescription = 88; + let heightExcludingDescription = 86; if (element.valueType === 'boolean') { heightExcludingDescription = 60; From 723d7ba44eec7db01b7e3f51dbdbb3132f7d3013 Mon Sep 17 00:00:00 2001 From: Benjamin Pasero Date: Thu, 16 Aug 2018 08:26:45 +0200 Subject: [PATCH 0870/1276] fix #56384 --- src/vs/workbench/services/textfile/common/textFileService.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vs/workbench/services/textfile/common/textFileService.ts b/src/vs/workbench/services/textfile/common/textFileService.ts index f77b7d2ecc1..933b605bfb8 100644 --- a/src/vs/workbench/services/textfile/common/textFileService.ts +++ b/src/vs/workbench/services/textfile/common/textFileService.ts @@ -733,7 +733,7 @@ export abstract class TextFileService extends Disposable implements ITextFileSer // Handle target models if existing (if target URI is a folder, this can be multiple) let handleTargetModelPromise: TPromise = TPromise.as(void 0); - const dirtyTargetModels = this.getDirtyFileModels().filter(model => isEqualOrParent(model.getResource(), target, !platform.isLinux /* ignorecase */)); + const dirtyTargetModels = this.getDirtyFileModels().filter(model => isEqualOrParent(model.getResource(), target, false /* do not ignorecase, see https://github.com/Microsoft/vscode/issues/56384 */)); if (dirtyTargetModels.length) { handleTargetModelPromise = this.revertAll(dirtyTargetModels.map(targetModel => targetModel.getResource()), { soft: true }); } From e3ce88563100351f6dbedcd72be4075b9a48b959 Mon Sep 17 00:00:00 2001 From: Joao Moreno Date: Thu, 16 Aug 2018 09:10:32 +0200 Subject: [PATCH 0871/1276] protect tree against errors in render calls related to #56371 --- src/vs/base/parts/tree/browser/treeView.ts | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/src/vs/base/parts/tree/browser/treeView.ts b/src/vs/base/parts/tree/browser/treeView.ts index d9e1f612471..6b1e97a1a7f 100644 --- a/src/vs/base/parts/tree/browser/treeView.ts +++ b/src/vs/base/parts/tree/browser/treeView.ts @@ -59,10 +59,19 @@ export class RowCache implements Lifecycle.IDisposable { var row = document.createElement('div'); row.appendChild(content); + let templateData: any = null; + + try { + templateData = this.context.renderer.renderTemplate(this.context.tree, templateId, content); + } catch (err) { + console.error('Tree usage error: exception while rendering template'); + console.error(err); + } + result = { element: row, templateId: templateId, - templateData: this.context.renderer.renderTemplate(this.context.tree, templateId, content) + templateData }; } @@ -260,7 +269,12 @@ export class ViewItem implements IViewItem { this.element.style.width = 'fit-content'; } - this.context.renderer.renderElement(this.context.tree, this.model.getElement(), this.templateId, this.row.templateData); + try { + this.context.renderer.renderElement(this.context.tree, this.model.getElement(), this.templateId, this.row.templateData); + } catch (err) { + console.error('Tree usage error: exception while rendering element'); + console.error(err); + } if (this.context.horizontalScrolling) { this.width = DOM.getContentWidth(this.element) + paddingLeft; From 5dd346919f0ccc56b202a6bca6be6bca69d864a0 Mon Sep 17 00:00:00 2001 From: Benjamin Pasero Date: Thu, 16 Aug 2018 09:26:20 +0200 Subject: [PATCH 0872/1276] fix #56540 --- .../browser/editors/fileEditorTracker.ts | 30 ++++++++++--------- 1 file changed, 16 insertions(+), 14 deletions(-) diff --git a/src/vs/workbench/parts/files/browser/editors/fileEditorTracker.ts b/src/vs/workbench/parts/files/browser/editors/fileEditorTracker.ts index adbae0c0793..0d8ad43f255 100644 --- a/src/vs/workbench/parts/files/browser/editors/fileEditorTracker.ts +++ b/src/vs/workbench/parts/files/browser/editors/fileEditorTracker.ts @@ -218,9 +218,9 @@ export class FileEditorTracker extends Disposable implements IWorkbenchContribut private handleMovedFileInOpenedEditors(oldResource: URI, newResource: URI): void { this.editorGroupService.groups.forEach(group => { - group.editors.forEach(input => { - if (input instanceof FileEditorInput) { - const resource = input.getResource(); + group.editors.forEach(editor => { + if (editor instanceof FileEditorInput) { + const resource = editor.getResource(); // Update Editor if file (or any parent of the input) got renamed or moved if (resources.isEqualOrParent(resource, oldResource, resources.hasToIgnoreCase(resource))) { @@ -232,17 +232,19 @@ export class FileEditorTracker extends Disposable implements IWorkbenchContribut reopenFileResource = resources.joinPath(newResource, resource.path.substr(index + oldResource.path.length + 1)); // parent folder got moved } - // Reopen - this.editorService.openEditor({ - resource: reopenFileResource, - options: { - preserveFocus: true, - pinned: group.isPinned(input), - index: group.getIndexOfEditor(input), - inactive: !group.isActive(input), - viewState: this.getViewStateFor(oldResource, group) - } - }, group); + this.editorService.replaceEditors([{ + editor: { resource }, + replacement: { + resource: reopenFileResource, + options: { + preserveFocus: true, + pinned: group.isPinned(editor), + index: group.getIndexOfEditor(editor), + inactive: !group.isActive(editor), + viewState: this.getViewStateFor(oldResource, group) + } + }, + }], group); } } }); From d505bb4781daa07acfd961715ad2ee6c8a348591 Mon Sep 17 00:00:00 2001 From: Rob Lourens Date: Wed, 15 Aug 2018 10:02:54 -0700 Subject: [PATCH 0873/1276] Workaround #55649 --- extensions/typescript-language-features/package.json | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/extensions/typescript-language-features/package.json b/extensions/typescript-language-features/package.json index cf13bdf97cd..1f06df0476d 100644 --- a/extensions/typescript-language-features/package.json +++ b/extensions/typescript-language-features/package.json @@ -42,10 +42,7 @@ "onCommand:typescript.goToProjectConfig", "onCommand:typescript.openTsServerLog", "onCommand:workbench.action.tasks.runTask", - "workspaceContains:**/tsconfig.json", - "workspaceContains:**/jsconfig.json", - "workspaceContains:**/tsconfig.*.json", - "workspaceContains:**/jsconfig.*.json" + "onLanguage:jsonc" ], "main": "./out/extension", "contributes": { From 0430911b98c09a519d656dc2f2f019fa9b29ca11 Mon Sep 17 00:00:00 2001 From: Johannes Rieken Date: Thu, 16 Aug 2018 10:16:55 +0200 Subject: [PATCH 0874/1276] fix #56545 --- src/vs/base/browser/ui/breadcrumbs/breadcrumbsWidget.css | 1 - src/vs/workbench/browser/parts/editor/media/tabstitlecontrol.css | 1 + 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vs/base/browser/ui/breadcrumbs/breadcrumbsWidget.css b/src/vs/base/browser/ui/breadcrumbs/breadcrumbsWidget.css index f546b7edc88..da510856593 100644 --- a/src/vs/base/browser/ui/breadcrumbs/breadcrumbsWidget.css +++ b/src/vs/base/browser/ui/breadcrumbs/breadcrumbsWidget.css @@ -27,7 +27,6 @@ background-image: url(./collapsed.svg); opacity: .7; width: 16px; - min-width: 16px; height: 16px; display: inline-block; background-size: 16px; diff --git a/src/vs/workbench/browser/parts/editor/media/tabstitlecontrol.css b/src/vs/workbench/browser/parts/editor/media/tabstitlecontrol.css index 3ddf3029c20..9c57e2f5d7c 100644 --- a/src/vs/workbench/browser/parts/editor/media/tabstitlecontrol.css +++ b/src/vs/workbench/browser/parts/editor/media/tabstitlecontrol.css @@ -265,6 +265,7 @@ .monaco-workbench > .part.editor > .content .editor-group-container > .title .tabs-breadcrumbs .breadcrumbs-control .monaco-icon-label::before { height: 18px; /* tweak the icon size of the editor labels when icons are enabled */ + min-width: 16px; } .monaco-workbench > .part.editor > .content .editor-group-container > .title .tabs-breadcrumbs .breadcrumbs-control .monaco-breadcrumb-item { From d62f5b3da934786d8125c3f277becf61e10be102 Mon Sep 17 00:00:00 2001 From: Johannes Rieken Date: Thu, 16 Aug 2018 10:52:08 +0200 Subject: [PATCH 0875/1276] use ts loader, exclude node_module for now --- extensions/emmet/extension.webpack.config.js | 39 ++++++++++------ extensions/emmet/tsconfig.json | 3 +- extensions/git/extension.webpack.config.js | 48 ++++++++++++-------- extensions/git/tsconfig.json | 5 +- package.json | 1 + yarn.lock | 14 +++++- 6 files changed, 71 insertions(+), 39 deletions(-) diff --git a/extensions/emmet/extension.webpack.config.js b/extensions/emmet/extension.webpack.config.js index 752505a4108..7584366203a 100644 --- a/extensions/emmet/extension.webpack.config.js +++ b/extensions/emmet/extension.webpack.config.js @@ -8,31 +8,40 @@ const path = require('path'); module.exports = { - mode: 'production', - // mode: 'none', + // mode: 'production', + // stats: 'errors-only', + mode: 'none', context: __dirname, target: 'node', - resolve: { - mainFields: ['main'] - }, entry: { - extension: './out/extension.js', + extension: './src/extension.ts', + }, + resolve: { + mainFields: ['main'], + extensions: [".ts", ".js"] + }, + module: { + rules: [{ + test: /\.ts$/, + exclude: /node_modules/, + use: [{ + loader: 'ts-loader', + options: { transpileOnly: true } + }] + }] }, output: { filename: '[name].js', path: path.join(__dirname, 'dist'), libraryTarget: "commonjs", }, + devtool: 'source-map', externals: { 'vscode': 'commonjs vscode', + '@emmetio/css-parser': 'commonjs @emmetio/css-parser', + '@emmetio/html-matcher': 'commonjs @emmetio/html-matcher', + '@emmetio/math-expression': 'commonjs @emmetio/math-expression', + 'image-size': 'commonjs image-size', + 'vscode-emmet-helper': 'commonjs vscode-emmet-helper', }, - stats: 'errors-only', - devtool: 'source-map', - module: { - rules: [{ - test: /\.js$/, - use: ["source-map-loader"], - enforce: "pre" - }] - } }; diff --git a/extensions/emmet/tsconfig.json b/extensions/emmet/tsconfig.json index 0a6f9c5eaf7..796d66278f2 100644 --- a/extensions/emmet/tsconfig.json +++ b/extensions/emmet/tsconfig.json @@ -6,6 +6,7 @@ ], "module": "commonjs", "outDir": "./out", + "sourceMap": true, "noUnusedLocals": true, "strictNullChecks": true }, @@ -16,4 +17,4 @@ "include": [ "src/**/*" ] -} \ No newline at end of file +} diff --git a/extensions/git/extension.webpack.config.js b/extensions/git/extension.webpack.config.js index 28aa93b4918..d003265d2d5 100644 --- a/extensions/git/extension.webpack.config.js +++ b/extensions/git/extension.webpack.config.js @@ -9,42 +9,52 @@ const path = require('path'); const CopyWebpackPlugin = require('copy-webpack-plugin'); module.exports = { - mode: 'production', - // mode: 'none', + // mode: 'production', + // stats: 'errors-only', + mode: 'none', context: __dirname, target: 'node', node: { __dirname: false }, - resolve: { - mainFields: ['main'] - }, entry: { - main: './out/main.js', - ['askpass-main']: './out/askpass-main.js' + main: './src/main.ts', + ['askpass-main']: './src/askpass-main.ts' + }, + resolve: { + mainFields: ['main'], + extensions: [".ts", ".js"] + }, + module: { + rules: [{ + test: /\.ts$/, + exclude: /node_modules/, + use: [{ + loader: 'ts-loader', + options: { transpileOnly: true } + }] + }] }, output: { filename: '[name].js', path: path.join(__dirname, 'dist'), libraryTarget: "commonjs" }, - externals: { - 'vscode': 'commonjs vscode', - 'vscode-nls': 'commonjs vscode-nls', - }, plugins: [ new CopyWebpackPlugin([ { from: './out/*.sh', to: '[name].sh' }, { from: './out/nls.*.json', to: '[name].json' } ]) ], - stats: 'errors-only', devtool: 'source-map', - module: { - rules: [{ - test: /\.js$/, - use: ["source-map-loader"], - enforce: "pre" - }] - } + externals: { + 'vscode': 'commonjs vscode', + "byline": 'commonjs byline', + "file-type": 'commonjs file-type', + "iconv-lite": 'commonjs iconv-lite', + "jschardet": 'commonjs jschardet', + "vscode-extension-telemetry": 'commonjs vscode-extension-telemetry', + "vscode-nls": 'commonjs vscode-nls', + "which": 'commonjs which', + }, }; diff --git a/extensions/git/tsconfig.json b/extensions/git/tsconfig.json index a7eca805f97..15d19fc48a6 100644 --- a/extensions/git/tsconfig.json +++ b/extensions/git/tsconfig.json @@ -11,9 +11,10 @@ ], "strict": true, "experimentalDecorators": true, - "noUnusedLocals": true + "noUnusedLocals": true, + "sourceMap": true }, "include": [ "src/**/*" ] -} \ No newline at end of file +} diff --git a/package.json b/package.json index 1abde5c7836..4ce476468c7 100644 --- a/package.json +++ b/package.json @@ -118,6 +118,7 @@ "sinon": "^1.17.2", "source-map": "^0.4.4", "source-map-loader": "^0.2.3", + "ts-loader": "^4.4.2", "tslint": "^5.9.1", "typescript": "2.9.2", "typescript-formatter": "7.1.0", diff --git a/yarn.lock b/yarn.lock index 62cdd874b45..e3b7585aa1b 100644 --- a/yarn.lock +++ b/yarn.lock @@ -4312,7 +4312,7 @@ loader-runner@^2.3.0: version "2.3.0" resolved "https://registry.yarnpkg.com/loader-runner/-/loader-runner-2.3.0.tgz#f482aea82d543e07921700d5a46ef26fdac6b8a2" -loader-utils@^1.1.0: +loader-utils@^1.0.2, loader-utils@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/loader-utils/-/loader-utils-1.1.0.tgz#c98aef488bcceda2ffb5e2de646d6a754429f5cd" dependencies: @@ -6666,7 +6666,7 @@ semver@^4.1.0, semver@^4.3.4: version "4.3.6" resolved "https://registry.yarnpkg.com/semver/-/semver-4.3.6.tgz#300bc6e0e86374f7ba61068b5b1ecd57fc6532da" -semver@^5.4.1, semver@^5.5.0: +semver@^5.0.1, semver@^5.4.1, semver@^5.5.0: version "5.5.0" resolved "https://registry.yarnpkg.com/semver/-/semver-5.5.0.tgz#dc4bbc7a6ca9d916dee5d43516f0092b58f7b8ab" @@ -7415,6 +7415,16 @@ tryit@^1.0.1: version "1.0.3" resolved "https://registry.yarnpkg.com/tryit/-/tryit-1.0.3.tgz#393be730a9446fd1ead6da59a014308f36c289cb" +ts-loader@^4.4.2: + version "4.4.2" + resolved "https://registry.yarnpkg.com/ts-loader/-/ts-loader-4.4.2.tgz#778d4464b24436873c78f7f9e914d88194c2a248" + dependencies: + chalk "^2.3.0" + enhanced-resolve "^4.0.0" + loader-utils "^1.0.2" + micromatch "^3.1.4" + semver "^5.0.1" + tslib@^1.7.1: version "1.8.0" resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.8.0.tgz#dc604ebad64bcbf696d613da6c954aa0e7ea1eb6" From a25b5cc80516cadb593e6eb1e2bb0570e141fb23 Mon Sep 17 00:00:00 2001 From: Johannes Rieken Date: Thu, 16 Aug 2018 10:55:49 +0200 Subject: [PATCH 0876/1276] enforce certain compile options --- build/lib/extensions.js | 10 +++++++++- build/lib/extensions.ts | 5 ++++- 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/build/lib/extensions.js b/build/lib/extensions.js index 51b5dd2a576..a3973e86026 100644 --- a/build/lib/extensions.js +++ b/build/lib/extensions.js @@ -3,6 +3,14 @@ * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ +var __assign = (this && this.__assign) || Object.assign || function(t) { + for (var s, i = 1, n = arguments.length; i < n; i++) { + s = arguments[i]; + for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) + t[p] = s[p]; + } + return t; +}; Object.defineProperty(exports, "__esModule", { value: true }); var es = require("event-stream"); var assign = require("object-assign"); @@ -46,7 +54,7 @@ function fromLocal(extensionPath, sourceMappingURLBase) { return data; })) .pipe(packageJsonFilter.restore); - var webpackConfig = require(path.join(extensionPath, 'extension.webpack.config.js')); + var webpackConfig = __assign({}, require(path.join(extensionPath, 'extension.webpack.config.js')), { mode: 'production', stats: 'errors-only' }); var webpackStream = webpackGulp(webpackConfig, webpack) .pipe(es.through(function (data) { data.stat = data.stat || {}; diff --git a/build/lib/extensions.ts b/build/lib/extensions.ts index 206572f23ff..3922a3218d2 100644 --- a/build/lib/extensions.ts +++ b/build/lib/extensions.ts @@ -52,7 +52,10 @@ export function fromLocal(extensionPath: string, sourceMappingURLBase?: string): })) .pipe(packageJsonFilter.restore); - const webpackConfig = require(path.join(extensionPath, 'extension.webpack.config.js')); + const webpackConfig = { + ...require(path.join(extensionPath, 'extension.webpack.config.js')), + ...{ mode: 'production', stats: 'errors-only' } + }; const webpackStream = webpackGulp(webpackConfig, webpack) .pipe(es.through(function (data) { data.stat = data.stat || {}; From a7b66b92527a060abd319bafb658744dd6ee0008 Mon Sep 17 00:00:00 2001 From: Johannes Rieken Date: Thu, 16 Aug 2018 10:56:29 +0200 Subject: [PATCH 0877/1276] keep node_modules in extension bundle --- extensions/emmet/.vscodeignore | 1 - extensions/git/.vscodeignore | 2 -- 2 files changed, 3 deletions(-) diff --git a/extensions/emmet/.vscodeignore b/extensions/emmet/.vscodeignore index d278b9bf417..05dfeabaa1c 100644 --- a/extensions/emmet/.vscodeignore +++ b/extensions/emmet/.vscodeignore @@ -1,5 +1,4 @@ test/** src/** out/** -node_modules/** tsconfig.json diff --git a/extensions/git/.vscodeignore b/extensions/git/.vscodeignore index 57779dd2a63..894e6f24870 100644 --- a/extensions/git/.vscodeignore +++ b/extensions/git/.vscodeignore @@ -3,5 +3,3 @@ test/** out/** tsconfig.json build/** -node_modules/** -!node_modules/vscode-nls/** From b00ab5288f314f6ef8d82923d89a0555ad15eb06 Mon Sep 17 00:00:00 2001 From: Johannes Rieken Date: Thu, 16 Aug 2018 11:14:15 +0200 Subject: [PATCH 0878/1276] also fix width issue when not using tabs, #56545 --- src/vs/workbench/browser/parts/editor/breadcrumbsControl.ts | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/vs/workbench/browser/parts/editor/breadcrumbsControl.ts b/src/vs/workbench/browser/parts/editor/breadcrumbsControl.ts index 0511af5b128..a7842ff1691 100644 --- a/src/vs/workbench/browser/parts/editor/breadcrumbsControl.ts +++ b/src/vs/workbench/browser/parts/editor/breadcrumbsControl.ts @@ -140,7 +140,6 @@ export class BreadcrumbsControl { readonly domNode: HTMLDivElement; private readonly _widget: BreadcrumbsWidget; - private _dimension: dom.Dimension; private _disposables = new Array(); private _breadcrumbsDisposables = new Array(); @@ -191,7 +190,6 @@ export class BreadcrumbsControl { } layout(dim: dom.Dimension): void { - this._dimension = dim; this._widget.layout(dim); } @@ -296,7 +294,7 @@ export class BreadcrumbsControl { getAnchor: () => { let pickerHeight = 330; - let pickerWidth = Math.max(this._dimension.width / 2.59, dom.getTotalWidth(event.node)); + let pickerWidth = Math.max(window.innerWidth / 4.17, dom.getTotalWidth(event.node)); let pickerArrowSize = 8; let pickerArrowOffset: number; From ae6ac66cb5347c6190d719af772944b621241354 Mon Sep 17 00:00:00 2001 From: Johannes Rieken Date: Thu, 16 Aug 2018 11:49:05 +0200 Subject: [PATCH 0879/1276] use ts-loader compilerOptions --- extensions/emmet/extension.webpack.config.js | 7 ++++++- extensions/emmet/tsconfig.json | 1 - extensions/git/extension.webpack.config.js | 7 ++++++- extensions/git/tsconfig.json | 3 +-- 4 files changed, 13 insertions(+), 5 deletions(-) diff --git a/extensions/emmet/extension.webpack.config.js b/extensions/emmet/extension.webpack.config.js index 7584366203a..791034eac7f 100644 --- a/extensions/emmet/extension.webpack.config.js +++ b/extensions/emmet/extension.webpack.config.js @@ -26,7 +26,12 @@ module.exports = { exclude: /node_modules/, use: [{ loader: 'ts-loader', - options: { transpileOnly: true } + options: { + transpileOnly: true, + compilerOptions: { + "sourceMap": true, + } + } }] }] }, diff --git a/extensions/emmet/tsconfig.json b/extensions/emmet/tsconfig.json index 796d66278f2..b035483b959 100644 --- a/extensions/emmet/tsconfig.json +++ b/extensions/emmet/tsconfig.json @@ -6,7 +6,6 @@ ], "module": "commonjs", "outDir": "./out", - "sourceMap": true, "noUnusedLocals": true, "strictNullChecks": true }, diff --git a/extensions/git/extension.webpack.config.js b/extensions/git/extension.webpack.config.js index d003265d2d5..832583ffa27 100644 --- a/extensions/git/extension.webpack.config.js +++ b/extensions/git/extension.webpack.config.js @@ -31,7 +31,12 @@ module.exports = { exclude: /node_modules/, use: [{ loader: 'ts-loader', - options: { transpileOnly: true } + options: { + transpileOnly: true, + compilerOptions: { + "sourceMap": true, + } + } }] }] }, diff --git a/extensions/git/tsconfig.json b/extensions/git/tsconfig.json index 15d19fc48a6..7477ea05a83 100644 --- a/extensions/git/tsconfig.json +++ b/extensions/git/tsconfig.json @@ -11,8 +11,7 @@ ], "strict": true, "experimentalDecorators": true, - "noUnusedLocals": true, - "sourceMap": true + "noUnusedLocals": true }, "include": [ "src/**/*" From 130a2918c2bbbc266cb803d751abbae59d375c4a Mon Sep 17 00:00:00 2001 From: Sandeep Somavarapu Date: Thu, 16 Aug 2018 12:03:12 +0200 Subject: [PATCH 0880/1276] Fix in master #56317 --- .../markers/electron-browser/markersModel.ts | 18 +++++----- .../electron-browser/markersPanelActions.ts | 33 +++++++++++++++++-- .../electron-browser/markersTreeViewer.ts | 1 + 3 files changed, 41 insertions(+), 11 deletions(-) diff --git a/src/vs/workbench/parts/markers/electron-browser/markersModel.ts b/src/vs/workbench/parts/markers/electron-browser/markersModel.ts index 0535caf3743..e40b6fe56c7 100644 --- a/src/vs/workbench/parts/markers/electron-browser/markersModel.ts +++ b/src/vs/workbench/parts/markers/electron-browser/markersModel.ts @@ -15,10 +15,10 @@ import { groupBy, isFalsyOrEmpty, flatten } from 'vs/base/common/arrays'; import { values } from 'vs/base/common/map'; import * as glob from 'vs/base/common/glob'; import * as strings from 'vs/base/common/strings'; -import { ITextModelService } from 'vs/editor/common/services/resolverService'; import { CodeAction } from 'vs/editor/common/modes'; import { getCodeActions } from 'vs/editor/contrib/codeAction/codeAction'; import { CodeActionKind } from 'vs/editor/contrib/codeAction/codeActionTrigger'; +import { IModelService } from 'vs/editor/common/services/modelService'; function compareUris(a: URI, b: URI) { if (a.toString() < b.toString()) { @@ -48,7 +48,7 @@ export class ResourceMarkers extends NodeWithId { constructor( readonly uri: URI, - private textModelService: ITextModelService + private modelService: IModelService ) { super(uri.toString()); } @@ -72,6 +72,10 @@ export class ResourceMarkers extends NodeWithId { } public async hasFixes(marker: Marker): Promise { + if (!this.modelService.getModel(this.uri)) { + // Return early, If the model is not yet created + return false; + } if (!this._allFixesPromise) { this._allFixesPromise = this._getFixes(); } @@ -88,11 +92,9 @@ export class ResourceMarkers extends NodeWithId { } private async _getFixes(range?: Range): Promise { - const modelReference = await this.textModelService.createModelReference(this.uri); - if (modelReference) { - const model = modelReference.object.textEditorModel; + const model = this.modelService.getModel(this.uri); + if (model) { const codeActions = await getCodeActions(model, range ? range : model.getFullModelRange(), { type: 'manual', filter: { kind: CodeActionKind.QuickFix } }); - modelReference.dispose(); return codeActions; } return []; @@ -225,7 +227,7 @@ export class MarkersModel { constructor( markers: IMarker[] = [], - @ITextModelService private textModelService: ITextModelService + @IModelService private modelService: IModelService ) { this._markersByResource = new Map(); this._filterOptions = new FilterOptions(); @@ -311,7 +313,7 @@ export class MarkersModel { private createResource(uri: URI, rawMarkers: IMarker[]): ResourceMarkers { const markers: Marker[] = []; - const resource = new ResourceMarkers(uri, this.textModelService); + const resource = new ResourceMarkers(uri, this.modelService); this.updateResource(resource); rawMarkers.forEach((rawMarker, index) => { diff --git a/src/vs/workbench/parts/markers/electron-browser/markersPanelActions.ts b/src/vs/workbench/parts/markers/electron-browser/markersPanelActions.ts index e706541c87c..8f6b4ca4793 100644 --- a/src/vs/workbench/parts/markers/electron-browser/markersPanelActions.ts +++ b/src/vs/workbench/parts/markers/electron-browser/markersPanelActions.ts @@ -23,7 +23,7 @@ import { IThemeService } from 'vs/platform/theme/common/themeService'; import { attachInputBoxStyler, attachStylerCallback, attachCheckboxStyler } from 'vs/platform/theme/common/styler'; import { IMarkersWorkbenchService } from 'vs/workbench/parts/markers/electron-browser/markers'; import { Event, Emitter } from 'vs/base/common/event'; -import { IDisposable } from 'vs/base/common/lifecycle'; +import { IDisposable, dispose } from 'vs/base/common/lifecycle'; import { BaseActionItem, ActionItem } from 'vs/base/browser/ui/actionbar/actionbar'; import { badgeBackground, contrastBorder } from 'vs/platform/theme/common/colorRegistry'; import { localize } from 'vs/nls'; @@ -35,6 +35,8 @@ import { applyCodeAction } from 'vs/editor/contrib/codeAction/codeActionCommands import { IBulkEditService } from 'vs/editor/browser/services/bulkEditService'; import { ICommandService } from 'vs/platform/commands/common/commands'; import { IEditorService, ACTIVE_GROUP } from 'vs/workbench/services/editor/common/editorService'; +import { IModelService } from 'vs/editor/common/services/modelService'; +import { isEqual, hasToIgnoreCase } from 'vs/base/common/resources'; export class ToggleMarkersPanelAction extends TogglePanelAction { @@ -280,14 +282,34 @@ export class QuickFixAction extends Action { public static readonly ID: string = 'workbench.actions.problems.quickfix'; + private updated: boolean = false; + private disposables: IDisposable[] = []; + constructor( readonly marker: Marker, @IBulkEditService private bulkEditService: IBulkEditService, @ICommandService private commandService: ICommandService, - @IEditorService private editorService: IEditorService + @IEditorService private editorService: IEditorService, + @IModelService modelService: IModelService ) { super(QuickFixAction.ID, Messages.MARKERS_PANEL_ACTION_TOOLTIP_QUICKFIX, 'markers-panel-action-quickfix', false); - marker.resourceMarkers.hasFixes(marker).then(hasFixes => this.enabled = hasFixes); + if (modelService.getModel(this.marker.resourceMarkers.uri)) { + this.update(); + } else { + modelService.onModelAdded(model => { + if (isEqual(model.uri, marker.resource, hasToIgnoreCase(model.uri))) { + this.update(); + } + }, this, this.disposables); + } + + } + + private update(): void { + if (!this.updated) { + this.marker.resourceMarkers.hasFixes(this.marker).then(hasFixes => this.enabled = hasFixes); + this.updated = true; + } } async getQuickFixActions(): Promise { @@ -315,6 +337,11 @@ export class QuickFixAction extends Action { }, }, ACTIVE_GROUP).then(() => null); } + + dispose(): void { + dispose(this.disposables); + super.dispose(); + } } export class QuickFixActionItem extends ActionItem { diff --git a/src/vs/workbench/parts/markers/electron-browser/markersTreeViewer.ts b/src/vs/workbench/parts/markers/electron-browser/markersTreeViewer.ts index 5e875bd0226..20ca3e0b0d0 100644 --- a/src/vs/workbench/parts/markers/electron-browser/markersTreeViewer.ts +++ b/src/vs/workbench/parts/markers/electron-browser/markersTreeViewer.ts @@ -261,6 +261,7 @@ export class Renderer implements IRenderer { } else if (templateId === Renderer.MARKER_TEMPLATE_ID) { (templateData).description.dispose(); (templateData).source.dispose(); + (templateData).actionBar.dispose(); } else if (templateId === Renderer.RELATED_INFO_TEMPLATE_ID) { (templateData).description.dispose(); (templateData).resourceLabel.dispose(); From 699d778579995f2e423feef07437b275f4178c49 Mon Sep 17 00:00:00 2001 From: Johannes Rieken Date: Thu, 16 Aug 2018 12:31:23 +0200 Subject: [PATCH 0881/1276] add doc to vscode.Uri, #56108 --- src/vs/vscode.d.ts | 58 +++++++++++++++++++++++++++++++++++----------- 1 file changed, 45 insertions(+), 13 deletions(-) diff --git a/src/vs/vscode.d.ts b/src/vs/vscode.d.ts index 71081b8f94a..5828b5bb88a 100644 --- a/src/vs/vscode.d.ts +++ b/src/vs/vscode.d.ts @@ -1231,24 +1231,41 @@ declare module 'vscode' { */ export class Uri { + /** + * Create an URI from a string, e.g. `http://www.msft.com/some/path`, + * `file:///usr/home`, or `scheme:with/path`. + * + * @see [Uri.toString](#Uri.toString) + * @param value The string value of an Uri. + * @return A new Uri instance. + */ + static parse(value: string): Uri; + /** * Create an URI from a file system path. The [scheme](#Uri.scheme) * will be `file`. + * + * The *difference* between `Uri#parse` and `Uri#file` is that the latter treats the argument + * as path, not as stringified-uri. E.g. `Uri.file(path)` is *not* the same as + * `Uri.parse('file://' + path)` because the path might contain characters that are + * interpreted (# and ?). See the following sample: + * ```ts + const good = URI.file('/coding/c#/project1'); + good.scheme === 'file'; + good.path === '/coding/c#/project1'; + good.fragment === ''; + + const bad = URI.parse('file://' + '/coding/c#/project1'); + bad.scheme === 'file'; + bad.path === '/coding/c'; // path is now broken + bad.fragment === '/project1'; + ``` * * @param path A file system or UNC path. * @return A new Uri instance. */ static file(path: string): Uri; - /** - * Create an URI from a string. Will throw if the given value is not - * valid. - * - * @param value The string value of an Uri. - * @return A new Uri instance. - */ - static parse(value: string): Uri; - /** * Use the `file` and `parse` factory functions to create new `Uri` objects. */ @@ -1285,8 +1302,21 @@ declare module 'vscode' { * The string representing the corresponding file system path of this Uri. * * Will handle UNC paths and normalize windows drive letters to lower-case. Also - * uses the platform specific path separator. Will *not* validate the path for - * invalid characters and semantics. Will *not* look at the scheme of this Uri. + * uses the platform specific path separator. + * + * * Will *not* validate the path for invalid characters and semantics. + * * Will *not* look at the scheme of this Uri. + * * The resulting string shall *not* be used for display purposes but + * for disk operations, like `readFile` et al. + * + * The *difference* to the [`path`](#Uri.path)-property is the use of the platform specific + * path separator and the handling of UNC paths. The sample below outlines the difference: + * ```ts + const u = URI.parse('file://server/c$/folder/file.txt') + u.authority === 'server' + u.path === '/shares/c$/file.txt' + u.fsPath === '\\server\c$\folder\file.txt' + ``` */ readonly fsPath: string; @@ -1308,8 +1338,10 @@ declare module 'vscode' { /** * Returns a string representation of this Uri. The representation and normalization - * of a URI depends on the scheme. The resulting string can be safely used with - * [Uri.parse](#Uri.parse). + * of a URI depends on the scheme. + * + * * The resulting string can be safely used with [Uri.parse](#Uri.parse). + * * The resulting string shall *not* be used for display purposes. * * @param skipEncoding Do not percentage-encode the result, defaults to `false`. Note that * the `#` and `?` characters occurring in the path will always be encoded. From de6116b3ea27dcb42756d5cd194b0312fbd9e7e7 Mon Sep 17 00:00:00 2001 From: Johannes Rieken Date: Thu, 16 Aug 2018 13:08:51 +0200 Subject: [PATCH 0882/1276] fix #56362 --- .../ui/breadcrumbs/breadcrumbsWidget.css | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/src/vs/base/browser/ui/breadcrumbs/breadcrumbsWidget.css b/src/vs/base/browser/ui/breadcrumbs/breadcrumbsWidget.css index da510856593..afade1a3413 100644 --- a/src/vs/base/browser/ui/breadcrumbs/breadcrumbsWidget.css +++ b/src/vs/base/browser/ui/breadcrumbs/breadcrumbsWidget.css @@ -23,18 +23,20 @@ outline: none; } -.monaco-breadcrumbs .monaco-breadcrumb-item:not(:first-child)::before { - background-image: url(./collapsed.svg); - opacity: .7; - width: 16px; +.monaco-breadcrumbs .monaco-breadcrumb-item::before { + width: 14px; height: 16px; display: inline-block; - background-size: 16px; - background-position: 50% 50%; content: ' '; } -.vs-dark .monaco-breadcrumbs .monaco-breadcrumb-item:not(:first-child)::before { - background-image: url(./collpased-dark.svg); +.monaco-breadcrumbs .monaco-breadcrumb-item:not(:nth-child(2))::before { + background-image: url(./collapsed.svg); + opacity: .7; + background-size: 16px; + background-position: 50% 50%; } +.vs-dark .monaco-breadcrumbs .monaco-breadcrumb-item:not(:nth-child(2))::before { + background-image: url(./collpased-dark.svg); +} From e2b79d3c9d915f234c6761253776604991463ba6 Mon Sep 17 00:00:00 2001 From: Joao Moreno Date: Thu, 16 Aug 2018 13:43:32 +0200 Subject: [PATCH 0883/1276] comment --- src/vs/base/parts/tree/browser/tree.ts | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/vs/base/parts/tree/browser/tree.ts b/src/vs/base/parts/tree/browser/tree.ts index 12df5ccd031..64e2f7152f0 100644 --- a/src/vs/base/parts/tree/browser/tree.ts +++ b/src/vs/base/parts/tree/browser/tree.ts @@ -364,6 +364,10 @@ export interface IDataSource { /** * Returns the unique identifier of the given element. * No more than one element may use a given identifier. + * + * You should not attempt to "move" an element to a different + * parent by keeping its ID. The idea here is to have tree location + * related IDs (eg. full file path, in the Explorer example). */ getId(tree: ITree, element: any): string; From 235c4f56351684b3d5d726a1a577fc841108b306 Mon Sep 17 00:00:00 2001 From: Johannes Rieken Date: Thu, 16 Aug 2018 15:12:06 +0200 Subject: [PATCH 0884/1276] make picker width depend on window size, #56318 --- .../workbench/browser/parts/editor/breadcrumbsControl.ts | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/vs/workbench/browser/parts/editor/breadcrumbsControl.ts b/src/vs/workbench/browser/parts/editor/breadcrumbsControl.ts index a7842ff1691..125b7a5af66 100644 --- a/src/vs/workbench/browser/parts/editor/breadcrumbsControl.ts +++ b/src/vs/workbench/browser/parts/editor/breadcrumbsControl.ts @@ -294,7 +294,7 @@ export class BreadcrumbsControl { getAnchor: () => { let pickerHeight = 330; - let pickerWidth = Math.max(window.innerWidth / 4.17, dom.getTotalWidth(event.node)); + let pickerWidth = window.innerWidth / 4.17; let pickerArrowSize = 8; let pickerArrowOffset: number; @@ -305,7 +305,12 @@ export class BreadcrumbsControl { x = window.innerWidth - pickerWidth; } if (event.payload instanceof StandardMouseEvent) { - pickerArrowOffset = event.payload.posx - x - pickerArrowSize; + let maxPickerArrowOffset = pickerWidth - 2 * pickerArrowSize; + pickerArrowOffset = event.payload.posx - x; + if (pickerArrowOffset > maxPickerArrowOffset) { + x += pickerArrowOffset - maxPickerArrowOffset; + pickerArrowOffset = maxPickerArrowOffset; + } } else { pickerArrowOffset = (data.left + (data.width * .3)) - x; } From 6fc9fdf2484589488b8c0f1c8ce527e7bb1e0449 Mon Sep 17 00:00:00 2001 From: Johannes Rieken Date: Thu, 16 Aug 2018 15:14:00 +0200 Subject: [PATCH 0885/1276] real fix for #56360 --- .../browser/parts/editor/media/tabstitlecontrol.css | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/vs/workbench/browser/parts/editor/media/tabstitlecontrol.css b/src/vs/workbench/browser/parts/editor/media/tabstitlecontrol.css index 9c57e2f5d7c..beed3550130 100644 --- a/src/vs/workbench/browser/parts/editor/media/tabstitlecontrol.css +++ b/src/vs/workbench/browser/parts/editor/media/tabstitlecontrol.css @@ -265,13 +265,16 @@ .monaco-workbench > .part.editor > .content .editor-group-container > .title .tabs-breadcrumbs .breadcrumbs-control .monaco-icon-label::before { height: 18px; /* tweak the icon size of the editor labels when icons are enabled */ - min-width: 16px; } .monaco-workbench > .part.editor > .content .editor-group-container > .title .tabs-breadcrumbs .breadcrumbs-control .monaco-breadcrumb-item { max-width: 80%; } +.monaco-workbench > .part.editor > .content .editor-group-container > .title .tabs-breadcrumbs .breadcrumbs-control .monaco-breadcrumb-item::before { + min-width: 16px; +} + .monaco-workbench > .part.editor > .content .editor-group-container > .title .tabs-breadcrumbs .breadcrumbs-control .monaco-breadcrumb-item:last-child { padding-right: 8px; } From 92d7afab0ade8298128bd0d5dd432eca4138fd2d Mon Sep 17 00:00:00 2001 From: Johannes Rieken Date: Thu, 16 Aug 2018 15:14:15 +0200 Subject: [PATCH 0886/1276] :lipstick: --- .../browser/parts/editor/media/tabstitlecontrol.css | 5 ----- 1 file changed, 5 deletions(-) diff --git a/src/vs/workbench/browser/parts/editor/media/tabstitlecontrol.css b/src/vs/workbench/browser/parts/editor/media/tabstitlecontrol.css index beed3550130..4d77c434854 100644 --- a/src/vs/workbench/browser/parts/editor/media/tabstitlecontrol.css +++ b/src/vs/workbench/browser/parts/editor/media/tabstitlecontrol.css @@ -278,8 +278,3 @@ .monaco-workbench > .part.editor > .content .editor-group-container > .title .tabs-breadcrumbs .breadcrumbs-control .monaco-breadcrumb-item:last-child { padding-right: 8px; } - -/* .monaco-workbench > .part.editor > .content .editor-group-container > .title .tabs-breadcrumbs .breadcrumbs-control .monaco-breadcrumb-item:not(:last-child):not(:hover):not(.focused):not(.file) { - min-width: 33px; -} */ - From a17c20fb76357aa5d1486c56b301b24512a24ae7 Mon Sep 17 00:00:00 2001 From: Alex Dima Date: Thu, 16 Aug 2018 15:43:08 +0200 Subject: [PATCH 0887/1276] Fixes #56387: Handle SIGPIPE in extension host --- src/vs/workbench/node/extensionHostProcess.ts | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/vs/workbench/node/extensionHostProcess.ts b/src/vs/workbench/node/extensionHostProcess.ts index 9035333b54f..d8f7d90adf3 100644 --- a/src/vs/workbench/node/extensionHostProcess.ts +++ b/src/vs/workbench/node/extensionHostProcess.ts @@ -114,6 +114,10 @@ function connectToRenderer(protocol: IMessagePassingProtocol): Promise { + onUnexpectedError(new Error('Unexpected SIGPIPE')); + }); + // Kill oneself if one's parent dies. Much drama. setInterval(function () { try { From e7ea0aba93d00108fd688aceb4883f8931259ed0 Mon Sep 17 00:00:00 2001 From: Johannes Rieken Date: Thu, 16 Aug 2018 15:52:04 +0200 Subject: [PATCH 0888/1276] remove any-casts, wait for extensions to be ready --- src/vs/workbench/electron-browser/actions.ts | 39 +++++++++++--------- 1 file changed, 22 insertions(+), 17 deletions(-) diff --git a/src/vs/workbench/electron-browser/actions.ts b/src/vs/workbench/electron-browser/actions.ts index 5c5efee9c6c..42e89ca46f5 100644 --- a/src/vs/workbench/electron-browser/actions.ts +++ b/src/vs/workbench/electron-browser/actions.ts @@ -52,6 +52,7 @@ import { IModelService } from 'vs/editor/common/services/modelService'; import { IModeService } from 'vs/editor/common/services/modeService'; import { IQuickInputService, IQuickPickItem, IQuickInputButton, IQuickPickSeparator, IKeyMods } from 'vs/platform/quickinput/common/quickInput'; import { getIconClasses } from 'vs/workbench/browser/labels'; +import { timeout } from 'vs/base/common/async'; // --- actions @@ -304,15 +305,19 @@ export class ShowStartupPerformance extends Action { super(id, label); } - run(): TPromise { + async run(): TPromise { // Show dev tools this.windowService.openDevTools(); - // Print to console - setTimeout(() => { - (console).group('Startup Performance Measurement'); + Promise.all([ + timeout(1000), // needed to print a table + this.extensionService.whenInstalledExtensionsRegistered() + ]).then(() => { + const metrics: IStartupMetrics = this.timerService.startupMetrics; + + console.group('Startup Performance Measurement'); console.log(`OS: ${metrics.platform} (${metrics.release})`); console.log(`CPUs: ${metrics.cpus.model} (${metrics.cpus.count} x ${metrics.cpus.speed})`); console.log(`Memory (System): ${(metrics.totalmem / (1024 * 1024 * 1024)).toFixed(2)}GB (${(metrics.freemem / (1024 * 1024 * 1024)).toFixed(2)}GB free)`); @@ -328,20 +333,20 @@ export class ShowStartupPerformance extends Action { nodeModuleLoadTime = nodeModuleTimes.duration; } - (console).table(this.getStartupMetricsTable(nodeModuleLoadTime)); + console.table(this.getStartupMetricsTable(nodeModuleLoadTime)); if (this.environmentService.performance) { const data = this.analyzeLoaderStats(); for (let type in data) { - (console).groupCollapsed(`Loader: ${type}`); - (console).table(data[type]); - (console).groupEnd(); + console.groupCollapsed(`Loader: ${type}`); + console.table(data[type]); + console.groupEnd(); } } - (console).groupEnd(); + console.groupEnd(); - (console).group('Extension Activation Stats'); + console.group('Extension Activation Stats'); let extensionsActivationTimes: { [id: string]: ActivationTimes; } = {}; let extensionsStatus = this.extensionService.getExtensionsStatus(); for (let id in extensionsStatus) { @@ -350,18 +355,18 @@ export class ShowStartupPerformance extends Action { extensionsActivationTimes[id] = status.activationTimes; } } - (console).table(extensionsActivationTimes); - (console).groupEnd(); + console.table(extensionsActivationTimes); + console.groupEnd(); - (console).group('Raw Startup Timers (CSV)'); + console.group('Raw Startup Timers (CSV)'); let value = `Name\tStart\n`; let entries = getEntries('mark'); for (const entry of entries) { value += `${entry.name}\t${entry.startTime}\n`; } console.log(value); - (console).groupEnd(); - }, 1000); + console.groupEnd(); + }); return TPromise.as(true); } @@ -376,14 +381,14 @@ export class ShowStartupPerformance extends Action { table.push({ Topic: '[main] app.isReady => window.loadUrl()', 'Took (ms)': metrics.timers.ellapsedWindowLoad }); } - table.push({ Topic: '[renderer] window.loadUrl() => begin to require(workbench.main.js)', 'Took (ms)': metrics.timers.ellapsedWindowLoadToRequire }); + table.push({ Topic: '[main->renderer] window.loadUrl() => begin to require(workbench.main.js)', 'Took (ms)': metrics.timers.ellapsedWindowLoadToRequire }); table.push({ Topic: '[renderer] require(workbench.main.js)', 'Took (ms)': metrics.timers.ellapsedRequire }); if (nodeModuleLoadTime) { table.push({ Topic: '[renderer] -> of which require() node_modules', 'Took (ms)': nodeModuleLoadTime }); } - table.push({ Topic: '[renderer] create extension host => extensions onReady()', 'Took (ms)': metrics.timers.ellapsedExtensions }); + table.push({ Topic: '[renderer] register extensions & spawn extension host', 'Took (ms)': metrics.timers.ellapsedExtensions }); table.push({ Topic: '[renderer] restore viewlet', 'Took (ms)': metrics.timers.ellapsedViewletRestore }); table.push({ Topic: '[renderer] restore editor view state', 'Took (ms)': metrics.timers.ellapsedEditorRestore }); table.push({ Topic: '[renderer] overall workbench load', 'Took (ms)': metrics.timers.ellapsedWorkbench }); From 7749465d780ab40faab7087349bb05f39c7a6bf2 Mon Sep 17 00:00:00 2001 From: Joao Moreno Date: Thu, 16 Aug 2018 16:14:46 +0200 Subject: [PATCH 0889/1276] update messag --- src/vs/workbench/parts/update/electron-browser/update.ts | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/vs/workbench/parts/update/electron-browser/update.ts b/src/vs/workbench/parts/update/electron-browser/update.ts index 70def20275d..b966ed83ede 100644 --- a/src/vs/workbench/parts/update/electron-browser/update.ts +++ b/src/vs/workbench/parts/update/electron-browser/update.ts @@ -263,13 +263,12 @@ export class WinUserSetupContribution implements IWorkbenchContribution { } const handle = this.notificationService.prompt( - severity.Warning, - nls.localize('usersetupsystem', "You are running the system-wide installation of {0}, while having the user-wide distribution installed as well. Make sure you're running the {0} version you expect.", product.nameShort), + severity.Info, + nls.localize('usersetupsystem', "You are running the system-wide installation of {0}, while having the user-wide distribution installed as well.", product.nameShort), [ { label: nls.localize('ok', "OK"), run: () => null }, { - label: nls.localize('neveragain', "Don't Show Again"), - isSecondary: true, + label: nls.localize('okneveragain', "OK, Don't Show Again"), run: () => { neverShowAgain.action.run(handle); neverShowAgain.action.dispose(); From 585c22af98036503f26bfec8d79af31f9fd3fda9 Mon Sep 17 00:00:00 2001 From: 123 Date: Thu, 16 Aug 2018 22:16:51 +0800 Subject: [PATCH 0890/1276] [Fix a typo] s/clientWidth/clientHeight/ (#56544) --- src/vs/base/browser/dom.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/vs/base/browser/dom.ts b/src/vs/base/browser/dom.ts index ef90d9e037e..55d7a57ba6a 100644 --- a/src/vs/base/browser/dom.ts +++ b/src/vs/base/browser/dom.ts @@ -486,8 +486,8 @@ export function getClientArea(element: HTMLElement): Dimension { return new Dimension(window.innerWidth, window.innerHeight); } - // Try with document.body.clientWidth / document.body.clientHeigh - if (document.body && document.body.clientWidth && document.body.clientWidth) { + // Try with document.body.clientWidth / document.body.clientHeight + if (document.body && document.body.clientWidth && document.body.clientHeight) { return new Dimension(document.body.clientWidth, document.body.clientHeight); } From 9a03a86c0a54a24c355bd950ddad91a0e74de6dd Mon Sep 17 00:00:00 2001 From: Martin Aeschlimann Date: Thu, 16 Aug 2018 16:38:46 +0200 Subject: [PATCH 0891/1276] improve npm.fetchOnlinePackageInfo handling --- .../npm/src/features/bowerJSONContribution.ts | 23 +++++++++--------- .../src/features/packageJSONContribution.ts | 24 +++++++++++-------- 2 files changed, 25 insertions(+), 22 deletions(-) diff --git a/extensions/npm/src/features/bowerJSONContribution.ts b/extensions/npm/src/features/bowerJSONContribution.ts index 038057bf2b2..300d7dad1f0 100644 --- a/extensions/npm/src/features/bowerJSONContribution.ts +++ b/extensions/npm/src/features/bowerJSONContribution.ts @@ -27,23 +27,18 @@ export class BowerJSONContribution implements IJSONContribution { private xhr: XHRRequest; - public constructor(httprequestxhr: XHRRequest) { - - const getxhr = () => { - return workspace.getConfiguration('npm').get('fetchOnlinePackageInfo') === false ? xhrDisabled : httprequestxhr; - }; - this.xhr = getxhr(); - workspace.onDidChangeConfiguration((e) => { - if (e.affectsConfiguration('npm.fetchOnlinePackageInfo')) { - this.xhr = getxhr(); - } - }); + public constructor(xhr: XHRRequest) { + this.xhr = xhr; } public getDocumentSelector(): DocumentSelector { return [{ language: 'json', scheme: '*', pattern: '**/bower.json' }, { language: 'json', scheme: '*', pattern: '**/.bower.json' }]; } + private onlineEnabled() { + return !!workspace.getConfiguration('npm').get('fetchOnlinePackageInfo'); + } + public collectDefaultSuggestions(_resource: string, collector: ISuggestionsCollector): Thenable { const defaultValue = { 'name': '${1:name}', @@ -62,7 +57,7 @@ export class BowerJSONContribution implements IJSONContribution { public collectPropertySuggestions(_resource: string, location: Location, currentWord: string, addValue: boolean, isLast: boolean, collector: ISuggestionsCollector): Thenable | null { if ((location.matches(['dependencies']) || location.matches(['devDependencies']))) { - if (currentWord.length > 0) { + if (currentWord.length > 0 && this.onlineEnabled()) { const queryUrl = 'https://registry.bower.io/packages/search/' + encodeURIComponent(currentWord); return this.xhr({ @@ -156,6 +151,10 @@ export class BowerJSONContribution implements IJSONContribution { } private getInfo(pack: string): Thenable { + if (!this.onlineEnabled()) { + return Promise.resolve(undefined); + } + const queryUrl = 'https://registry.bower.io/packages/' + encodeURIComponent(pack); return this.xhr({ diff --git a/extensions/npm/src/features/packageJSONContribution.ts b/extensions/npm/src/features/packageJSONContribution.ts index 1576ded6a4d..38e4ce05310 100644 --- a/extensions/npm/src/features/packageJSONContribution.ts +++ b/extensions/npm/src/features/packageJSONContribution.ts @@ -34,16 +34,8 @@ export class PackageJSONContribution implements IJSONContribution { return [{ language: 'json', scheme: '*', pattern: '**/package.json' }]; } - public constructor(httprequestxhr: XHRRequest) { - const getxhr = () => { - return workspace.getConfiguration('npm').get('fetchOnlinePackageInfo') === false ? xhrDisabled : httprequestxhr; - }; - this.xhr = getxhr(); - workspace.onDidChangeConfiguration((e) => { - if (e.affectsConfiguration('npm.fetchOnlinePackageInfo')) { - this.xhr = getxhr(); - } - }); + public constructor(xhr: XHRRequest) { + this.xhr = xhr; } public collectDefaultSuggestions(_fileName: string, result: ISuggestionsCollector): Thenable { @@ -62,6 +54,10 @@ export class PackageJSONContribution implements IJSONContribution { return Promise.resolve(null); } + private onlineEnabled() { + return !!workspace.getConfiguration('npm').get('fetchOnlinePackageInfo'); + } + public collectPropertySuggestions( _resource: string, location: Location, @@ -70,6 +66,10 @@ export class PackageJSONContribution implements IJSONContribution { isLast: boolean, collector: ISuggestionsCollector ): Thenable | null { + if (!this.onlineEnabled()) { + return null; + } + if ((location.matches(['dependencies']) || location.matches(['devDependencies']) || location.matches(['optionalDependencies']) || location.matches(['peerDependencies']))) { let queryUrl: string; if (currentWord.length > 0) { @@ -219,6 +219,10 @@ export class PackageJSONContribution implements IJSONContribution { location: Location, result: ISuggestionsCollector ): Thenable | null { + if (!this.onlineEnabled()) { + return null; + } + if ((location.matches(['dependencies', '*']) || location.matches(['devDependencies', '*']) || location.matches(['optionalDependencies', '*']) || location.matches(['peerDependencies', '*']))) { const currentKey = location.path[location.path.length - 1]; if (typeof currentKey === 'string') { From 9842fb4d6127b7eaed4de9cd35c854f5989c8161 Mon Sep 17 00:00:00 2001 From: Benjamin Pasero Date: Thu, 16 Aug 2018 10:56:08 +0200 Subject: [PATCH 0892/1276] improve overlay cleanup scheduler (fixes flicker seen with Electron 3.0.x) --- .../browser/parts/editor/editorDropTarget.ts | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/src/vs/workbench/browser/parts/editor/editorDropTarget.ts b/src/vs/workbench/browser/parts/editor/editorDropTarget.ts index 2772e4746ca..f1469891010 100644 --- a/src/vs/workbench/browser/parts/editor/editorDropTarget.ts +++ b/src/vs/workbench/browser/parts/editor/editorDropTarget.ts @@ -17,6 +17,7 @@ import { isMacintosh } from 'vs/base/common/platform'; import { GroupDirection, MergeGroupMode } from 'vs/workbench/services/group/common/editorGroupsService'; import { toDisposable } from 'vs/base/common/lifecycle'; import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; +import { RunOnceScheduler } from 'vs/base/common/async'; interface IDropOperation { splitDirection?: GroupDirection; @@ -32,6 +33,8 @@ class DropOverlay extends Themable { private currentDropOperation: IDropOperation; private _disposed: boolean; + private cleanupOverlayScheduler: RunOnceScheduler; + private readonly editorTransfer = LocalSelectionTransfer.getInstance(); private readonly groupTransfer = LocalSelectionTransfer.getInstance(); @@ -43,6 +46,8 @@ class DropOverlay extends Themable { ) { super(themeService); + this.cleanupOverlayScheduler = this._register(new RunOnceScheduler(() => this.dispose(), 300)); + this.create(); } @@ -118,6 +123,11 @@ class DropOverlay extends Themable { // Position overlay this.positionOverlay(e.offsetX, e.offsetY, isDraggingGroup); + + // Make sure to stop any running cleanup scheduler to remove the overlay + if (this.cleanupOverlayScheduler.isScheduled()) { + this.cleanupOverlayScheduler.cancel(); + } }, onDragLeave: e => this.dispose(), @@ -144,9 +154,9 @@ class DropOverlay extends Themable { // To protect against this issue we always destroy the overlay as soon as we detect a // mouse event over it. The delay is used to guarantee we are not interfering with the // actual DROP event that can also trigger a mouse over event. - setTimeout(() => { - this.dispose(); - }, 300); + if (!this.cleanupOverlayScheduler.isScheduled()) { + this.cleanupOverlayScheduler.schedule(); + } })); } From f8dad22a02f1ae0e5e4cf1cb2c617a970016659a Mon Sep 17 00:00:00 2001 From: Johannes Rieken Date: Thu, 16 Aug 2018 16:00:07 +0200 Subject: [PATCH 0893/1276] debt - a tiny bit of promise removal --- src/vs/base/common/event.ts | 7 +++---- src/vs/base/parts/ipc/common/ipc.ts | 2 +- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/src/vs/base/common/event.ts b/src/vs/base/common/event.ts index 37887a5318f..203bcb896f9 100644 --- a/src/vs/base/common/event.ts +++ b/src/vs/base/common/event.ts @@ -8,7 +8,6 @@ import { onUnexpectedError } from 'vs/base/common/errors'; import { once as onceFn } from 'vs/base/common/functional'; import { combinedDisposable, Disposable, IDisposable, toDisposable } from 'vs/base/common/lifecycle'; import { LinkedList } from 'vs/base/common/linkedList'; -import { TPromise } from 'vs/base/common/winjs.base'; /** * To an event a function with one or zero parameters @@ -277,7 +276,7 @@ export function fromCallback(fn: (handler: (e: T) => void) => IDisposable): E return emitter.event; } -export function fromPromise(promise: TPromise): Event { +export function fromPromise(promise: Thenable): Event { const emitter = new Emitter(); let shouldEmit = false; @@ -295,8 +294,8 @@ export function fromPromise(promise: TPromise): Event { return emitter.event; } -export function toPromise(event: Event): TPromise { - return new TPromise(complete => { +export function toPromise(event: Event): Promise { + return new Promise(complete => { const sub = event(e => { sub.dispose(); complete(e); diff --git a/src/vs/base/parts/ipc/common/ipc.ts b/src/vs/base/parts/ipc/common/ipc.ts index 8543a0ba8bf..925e26aab62 100644 --- a/src/vs/base/parts/ipc/common/ipc.ts +++ b/src/vs/base/parts/ipc/common/ipc.ts @@ -375,7 +375,7 @@ export class ChannelClient implements IChannelClient, IDisposable { if (this.state === State.Idle) { return TPromise.as(null); } else { - return toPromise(this.onDidInitialize); + return TPromise.wrap(toPromise(this.onDidInitialize)); } } From e4c17011fdbae26d845889617fa832463004a974 Mon Sep 17 00:00:00 2001 From: Johannes Rieken Date: Thu, 16 Aug 2018 16:25:56 +0200 Subject: [PATCH 0894/1276] even more ITimerService simplifications, #56253 --- src/vs/workbench/electron-browser/actions.ts | 34 ++- src/vs/workbench/electron-browser/main.ts | 3 - src/vs/workbench/electron-browser/shell.ts | 5 - .../electron-browser/startupTimings.ts | 4 +- .../startupTimingsAppender.ts | 10 +- .../services/timer/common/timerService.ts | 218 --------------- .../timer/electron-browser/timerService.ts | 252 ++++++++++++++++-- 7 files changed, 255 insertions(+), 271 deletions(-) delete mode 100644 src/vs/workbench/services/timer/common/timerService.ts diff --git a/src/vs/workbench/electron-browser/actions.ts b/src/vs/workbench/electron-browser/actions.ts index 42e89ca46f5..084c8911004 100644 --- a/src/vs/workbench/electron-browser/actions.ts +++ b/src/vs/workbench/electron-browser/actions.ts @@ -22,7 +22,7 @@ import { IWorkspaceConfigurationService } from 'vs/workbench/services/configurat import { isMacintosh, isLinux, language } from 'vs/base/common/platform'; import * as browser from 'vs/base/browser/browser'; import { IIntegrityService } from 'vs/platform/integrity/common/integrity'; -import { ITimerService, IStartupMetrics } from 'vs/workbench/services/timer/common/timerService'; +import { ITimerService, IStartupMetrics } from 'vs/workbench/services/timer/electron-browser/timerService'; import { IEditorGroupsService, GroupDirection, GroupLocation, IFindGroupScope } from 'vs/workbench/services/group/common/editorGroupsService'; import { IPanelService } from 'vs/workbench/services/panel/common/panelService'; import { IPartService, Parts, Position as PartPosition } from 'vs/workbench/services/part/common/partService'; @@ -305,17 +305,15 @@ export class ShowStartupPerformance extends Action { super(id, label); } - async run(): TPromise { + run(): TPromise { // Show dev tools this.windowService.openDevTools(); Promise.all([ timeout(1000), // needed to print a table - this.extensionService.whenInstalledExtensionsRegistered() - ]).then(() => { - - const metrics: IStartupMetrics = this.timerService.startupMetrics; + this.timerService.startupMetrics + ]).then(([, metrics]) => { console.group('Startup Performance Measurement'); console.log(`OS: ${metrics.platform} (${metrics.release})`); @@ -333,7 +331,7 @@ export class ShowStartupPerformance extends Action { nodeModuleLoadTime = nodeModuleTimes.duration; } - console.table(this.getStartupMetricsTable(nodeModuleLoadTime)); + console.table(this.getStartupMetricsTable(metrics, nodeModuleLoadTime)); if (this.environmentService.performance) { const data = this.analyzeLoaderStats(); @@ -371,9 +369,8 @@ export class ShowStartupPerformance extends Action { return TPromise.as(true); } - private getStartupMetricsTable(nodeModuleLoadTime?: number): any[] { + private getStartupMetricsTable(metrics: IStartupMetrics, nodeModuleLoadTime?: number): any[] { const table: any[] = []; - const metrics: IStartupMetrics = this.timerService.startupMetrics; if (metrics.initialStartup) { table.push({ Topic: '[main] start => app.isReady', 'Took (ms)': metrics.timers.ellapsedAppReady }); @@ -913,8 +910,11 @@ export class ReportPerformanceIssueAction extends Action { } run(appendix?: string): TPromise { - this.integrityService.isPure().then(res => { - const issueUrl = this.generatePerformanceIssueUrl(product.reportIssueUrl, pkg.name, pkg.version, product.commit, product.date, res.isPure, appendix); + Promise.all([ + this.timerService.startupMetrics, + this.integrityService.isPure() + ]).then(([metrics, integrity]) => { + const issueUrl = this.generatePerformanceIssueUrl(metrics, product.reportIssueUrl, pkg.name, pkg.version, product.commit, product.date, integrity.isPure, appendix); window.open(issueUrl); }); @@ -922,7 +922,7 @@ export class ReportPerformanceIssueAction extends Action { return TPromise.wrap(true); } - private generatePerformanceIssueUrl(baseUrl: string, name: string, version: string, commit: string, date: string, isPure: boolean, appendix?: string): string { + private generatePerformanceIssueUrl(metrics: IStartupMetrics, baseUrl: string, name: string, version: string, commit: string, date: string, isPure: boolean, appendix?: string): string { if (!appendix) { appendix = `Additional Steps to Reproduce (if any): @@ -936,7 +936,6 @@ export class ReportPerformanceIssueAction extends Action { nodeModuleLoadTime = this.computeNodeModulesLoadTime(); } - const metrics: IStartupMetrics = this.timerService.startupMetrics; const osVersion = `${os.type()} ${os.arch()} ${os.release()}`; const queryStringPrefix = baseUrl.indexOf('?') === -1 ? '?' : '&'; @@ -953,7 +952,7 @@ export class ReportPerformanceIssueAction extends Action { - Empty Workspace: ${metrics.emptyWorkbench ? 'yes' : 'no'} - Timings: -${this.generatePerformanceTable(nodeModuleLoadTime)} +${this.generatePerformanceTable(metrics, nodeModuleLoadTime)} --- @@ -979,20 +978,19 @@ ${appendix}` return Math.round(total); } - private generatePerformanceTable(nodeModuleLoadTime?: number): string { + private generatePerformanceTable(metrics: IStartupMetrics, nodeModuleLoadTime?: number): string { let tableHeader = `|Component|Task|Time (ms)| |---|---|---|`; - const table = this.getStartupMetricsTable(nodeModuleLoadTime).map(e => { + const table = this.getStartupMetricsTable(metrics, nodeModuleLoadTime).map(e => { return `|${e.component}|${e.task}|${e.time}|`; }).join('\n'); return `${tableHeader}\n${table}`; } - private getStartupMetricsTable(nodeModuleLoadTime?: number): { component: string, task: string; time: number; }[] { + private getStartupMetricsTable(metrics: IStartupMetrics, nodeModuleLoadTime?: number): { component: string, task: string; time: number; }[] { const table: any[] = []; - const metrics: IStartupMetrics = this.timerService.startupMetrics; if (metrics.initialStartup) { table.push({ component: 'main', task: 'start => app.isReady', time: metrics.timers.ellapsedAppReady }); diff --git a/src/vs/workbench/electron-browser/main.ts b/src/vs/workbench/electron-browser/main.ts index 46037466246..f69daf2f901 100644 --- a/src/vs/workbench/electron-browser/main.ts +++ b/src/vs/workbench/electron-browser/main.ts @@ -24,7 +24,6 @@ import { ServiceCollection } from 'vs/platform/instantiation/common/serviceColle import { realpath } from 'vs/base/node/pfs'; import { EnvironmentService } from 'vs/platform/environment/node/environmentService'; import * as gracefulFs from 'graceful-fs'; -import { TimerService } from 'vs/workbench/services/timer/electron-browser/timerService'; import { KeyboardMapperFactory } from 'vs/workbench/services/keybinding/electron-browser/keybindingService'; import { IWindowConfiguration, IWindowsService } from 'vs/platform/windows/common/windows'; import { WindowsChannelClient } from 'vs/platform/windows/common/windowsIpc'; @@ -105,7 +104,6 @@ function openWorkbench(configuration: IWindowConfiguration): TPromise { // Since the configuration service is one of the core services that is used in so many places, we initialize it // right before startup of the workbench shell to have its data ready for consumers return createAndInitializeWorkspaceService(configuration, environmentService).then(workspaceService => { - const timerService = new TimerService(configuration, workspaceService.getWorkbenchState() === WorkbenchState.EMPTY); const storageService = createStorageService(workspaceService, environmentService); return domContentLoaded().then(() => { @@ -117,7 +115,6 @@ function openWorkbench(configuration: IWindowConfiguration): TPromise { configurationService: workspaceService, environmentService, logService, - timerService, storageService }, mainServices, mainProcessClient, configuration); shell.open(); diff --git a/src/vs/workbench/electron-browser/shell.ts b/src/vs/workbench/electron-browser/shell.ts index 7ad21d04307..33bea4a0ca0 100644 --- a/src/vs/workbench/electron-browser/shell.ts +++ b/src/vs/workbench/electron-browser/shell.ts @@ -63,7 +63,6 @@ import { DefaultURITransformer } from 'vs/base/common/uriIpc'; import { IExtensionManagementChannel, ExtensionManagementChannelClient } from 'vs/platform/extensionManagement/common/extensionManagementIpc'; import { IExtensionManagementService, IExtensionEnablementService, IExtensionManagementServerService } from 'vs/platform/extensionManagement/common/extensionManagement'; import { ExtensionEnablementService } from 'vs/platform/extensionManagement/common/extensionEnablementService'; -import { ITimerService } from 'vs/workbench/services/timer/common/timerService'; import { BareFontInfo } from 'vs/editor/common/config/fontInfo'; import { restoreFontInfo, readFontInfo, saveFontInfo } from 'vs/editor/browser/config/configuration'; import * as browser from 'vs/base/browser/browser'; @@ -106,7 +105,6 @@ export interface ICoreServices { configurationService: IConfigurationService; environmentService: IEnvironmentService; logService: ILogService; - timerService: ITimerService; storageService: IStorageService; } @@ -123,7 +121,6 @@ export class WorkbenchShell extends Disposable { private telemetryService: ITelemetryService; private extensionService: ExtensionService; private broadcastService: IBroadcastService; - private timerService: ITimerService; private themeService: WorkbenchThemeService; private lifecycleService: LifecycleService; private mainProcessServices: ServiceCollection; @@ -147,7 +144,6 @@ export class WorkbenchShell extends Disposable { this.configurationService = coreServices.configurationService; this.environmentService = coreServices.environmentService; this.logService = coreServices.logService; - this.timerService = coreServices.timerService; this.storageService = coreServices.storageService; this.mainProcessServices = mainProcessServices; @@ -320,7 +316,6 @@ export class WorkbenchShell extends Disposable { serviceCollection.set(IEnvironmentService, this.environmentService); serviceCollection.set(ILogService, this._register(this.logService)); - serviceCollection.set(ITimerService, this.timerService); serviceCollection.set(IStorageService, this.storageService); this.mainProcessServices.forEach((serviceIdentifier, serviceInstance) => { serviceCollection.set(serviceIdentifier, serviceInstance); diff --git a/src/vs/workbench/parts/performance/electron-browser/startupTimings.ts b/src/vs/workbench/parts/performance/electron-browser/startupTimings.ts index cbbe1712b66..c55249a7f97 100644 --- a/src/vs/workbench/parts/performance/electron-browser/startupTimings.ts +++ b/src/vs/workbench/parts/performance/electron-browser/startupTimings.ts @@ -11,7 +11,7 @@ import { IWindowsService } from 'vs/platform/windows/common/windows'; import { IWorkbenchContributionsRegistry, IWorkbenchContribution, Extensions } from 'vs/workbench/common/contributions'; import { Registry } from 'vs/platform/registry/common/platform'; import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry'; -import { ITimerService, IStartupMetrics } from 'vs/workbench/services/timer/common/timerService'; +import { ITimerService, IStartupMetrics } from 'vs/workbench/services/timer/electron-browser/timerService'; import { onUnexpectedError } from 'vs/base/common/errors'; import { IViewletService } from 'vs/workbench/services/viewlet/browser/viewlet'; import * as files from 'vs/workbench/parts/files/common/files'; @@ -181,7 +181,7 @@ class StartupTimings implements IWorkbenchContribution { editorIds }; - const metrics = this._timerService.startupMetrics; + const metrics = await this._timerService.startupMetrics; return { ...reflections, ...metrics }; } } diff --git a/src/vs/workbench/parts/performance/electron-browser/startupTimingsAppender.ts b/src/vs/workbench/parts/performance/electron-browser/startupTimingsAppender.ts index 2822fbb1890..a59a7ce84e9 100644 --- a/src/vs/workbench/parts/performance/electron-browser/startupTimingsAppender.ts +++ b/src/vs/workbench/parts/performance/electron-browser/startupTimingsAppender.ts @@ -5,12 +5,11 @@ 'use strict'; -import { IExtensionService } from 'vs/workbench/services/extensions/common/extensions'; import { ILifecycleService, LifecyclePhase } from 'vs/platform/lifecycle/common/lifecycle'; import { IWindowsService } from 'vs/platform/windows/common/windows'; import { IWorkbenchContributionsRegistry, IWorkbenchContribution, Extensions } from 'vs/workbench/common/contributions'; import { Registry } from 'vs/platform/registry/common/platform'; -import { ITimerService } from 'vs/workbench/services/timer/common/timerService'; +import { ITimerService } from 'vs/workbench/services/timer/electron-browser/timerService'; import { IEnvironmentService } from 'vs/platform/environment/common/environment'; import { nfcall } from 'vs/base/common/async'; import { appendFile } from 'fs'; @@ -22,7 +21,6 @@ class StartupTimingsAppender implements IWorkbenchContribution { @ITimerService timerService: ITimerService, @IWindowsService windowsService: IWindowsService, @ILifecycleService lifecycleService: ILifecycleService, - @IExtensionService extensionService: IExtensionService, @IEnvironmentService environmentService: IEnvironmentService, ) { @@ -33,9 +31,9 @@ class StartupTimingsAppender implements IWorkbenchContribution { Promise.all([ lifecycleService.when(LifecyclePhase.Eventually), - extensionService.whenInstalledExtensionsRegistered() - ]).then(() => { - const { startupMetrics } = timerService; + timerService.startupMetrics + ]).then(([, startupMetrics]) => { + return nfcall(appendFile, appendTo, `${product.nameShort}\t${product.commit || '0000000'}\t${Date.now()}\t${startupMetrics.ellapsed}\n`); }).then(() => { windowsService.quit(); diff --git a/src/vs/workbench/services/timer/common/timerService.ts b/src/vs/workbench/services/timer/common/timerService.ts deleted file mode 100644 index 8605a39e58f..00000000000 --- a/src/vs/workbench/services/timer/common/timerService.ts +++ /dev/null @@ -1,218 +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'; - -import { createDecorator } from 'vs/platform/instantiation/common/instantiation'; - -export const ITimerService = createDecorator('timerService'); - -/* __GDPR__FRAGMENT__ - "IMemoryInfo" : { - "workingSetSize" : { "classification": "SystemMetaData", "purpose": "PerformanceAndHealth", "isMeasurement": true }, - "peakWorkingSetSize": { "classification": "SystemMetaData", "purpose": "PerformanceAndHealth", "isMeasurement": true }, - "privateBytes": { "classification": "SystemMetaData", "purpose": "PerformanceAndHealth", "isMeasurement": true }, - "sharedBytes": { "classification": "SystemMetaData", "purpose": "PerformanceAndHealth", "isMeasurement": true } - } -*/ -export interface IMemoryInfo { - workingSetSize: number; - peakWorkingSetSize: number; - privateBytes: number; - sharedBytes: number; -} - -/* __GDPR__FRAGMENT__ - "IStartupMetrics" : { - "version" : { "classification": "SystemMetaData", "purpose": "PerformanceAndHealth" }, - "ellapsed" : { "classification": "SystemMetaData", "purpose": "PerformanceAndHealth", "isMeasurement": true }, - "timers.ellapsedAppReady" : { "classification": "SystemMetaData", "purpose": "PerformanceAndHealth", "isMeasurement": true }, - "timers.ellapsedWindowLoad" : { "classification": "SystemMetaData", "purpose": "PerformanceAndHealth", "isMeasurement": true }, - "timers.ellapsedWindowLoadToRequire" : { "classification": "SystemMetaData", "purpose": "PerformanceAndHealth", "isMeasurement": true }, - "timers.ellapsedExtensions" : { "classification": "SystemMetaData", "purpose": "PerformanceAndHealth", "isMeasurement": true }, - "timers.ellapsedExtensionsReady" : { "classification": "SystemMetaData", "purpose": "PerformanceAndHealth", "isMeasurement": true }, - "timers.ellapsedRequire" : { "classification": "SystemMetaData", "purpose": "PerformanceAndHealth", "isMeasurement": true }, - "timers.ellapsedViewletRestore" : { "classification": "SystemMetaData", "purpose": "PerformanceAndHealth", "isMeasurement": true }, - "timers.ellapsedEditorRestore" : { "classification": "SystemMetaData", "purpose": "PerformanceAndHealth", "isMeasurement": true }, - "timers.ellapsedWorkbench" : { "classification": "SystemMetaData", "purpose": "PerformanceAndHealth", "isMeasurement": true }, - "timers.ellapsedTimersToTimersComputed" : { "classification": "SystemMetaData", "purpose": "PerformanceAndHealth", "isMeasurement": true }, - "timers.ellapsedNlsGeneration" : { "classification": "SystemMetaData", "purpose": "PerformanceAndHealth", "isMeasurement": true }, - "platform" : { "classification": "SystemMetaData", "purpose": "PerformanceAndHealth" }, - "release" : { "classification": "SystemMetaData", "purpose": "PerformanceAndHealth" }, - "arch" : { "classification": "SystemMetaData", "purpose": "PerformanceAndHealth" }, - "totalmem" : { "classification": "SystemMetaData", "purpose": "PerformanceAndHealth", "isMeasurement": true }, - "freemem" : { "classification": "SystemMetaData", "purpose": "PerformanceAndHealth", "isMeasurement": true }, - "meminfo" : { "${inline}": [ "${IMemoryInfo}" ] }, - "cpus.count" : { "classification": "SystemMetaData", "purpose": "PerformanceAndHealth", "isMeasurement": true }, - "cpus.speed" : { "classification": "SystemMetaData", "purpose": "PerformanceAndHealth", "isMeasurement": true }, - "cpus.model" : { "classification": "SystemMetaData", "purpose": "PerformanceAndHealth" }, - "initialStartup" : { "classification": "SystemMetaData", "purpose": "PerformanceAndHealth", "isMeasurement": true }, - "hasAccessibilitySupport" : { "classification": "SystemMetaData", "purpose": "PerformanceAndHealth", "isMeasurement": true }, - "isVMLikelyhood" : { "classification": "SystemMetaData", "purpose": "PerformanceAndHealth", "isMeasurement": true }, - "emptyWorkbench" : { "classification": "SystemMetaData", "purpose": "PerformanceAndHealth", "isMeasurement": true }, - "loadavg" : { "classification": "SystemMetaData", "purpose": "PerformanceAndHealth" } - } -*/ -export interface IStartupMetrics { - - /** - * The version of these metrics. - */ - version: 1; - - /** - * The time it took to create the workbench. - * - * * Happens in the main-process *and* the renderer-process - * * Measured with the *start* and `didStartWorkbench`-performance mark. The *start* is either the start of the - * main process or the start of the renderer. - * * This should be looked at carefully because times vary depending on - * * This being the first window, the only window, or a reloaded window - * * Cached data being present and used or not - * * The numbers and types of editors being restored - * * The numbers of windows being restored (when starting 'fresh') - * * The viewlet being restored (esp. when it's a contributed viewlet) - */ - ellapsed: number; - - /** - * If this started the main process and renderer or just a renderer (new or reloaded). - */ - initialStartup: boolean; - - /** - * No folder, no file, no workspace has been opened - */ - emptyWorkbench: boolean; - - timers: { - /** - * The time it took to receieve the [`ready`](https://electronjs.org/docs/api/app#event-ready)-event. Measured from the first line - * of JavaScript code till receiving that event. - * - * * Happens in the main-process - * * Measured with the `main:started` and `main:appReady` performance marks. - * * This can be compared between insider and stable builds. - * * This should be looked at per OS version and per electron version. - * * This is often affected by AV software (and can change with AV software updates outside of our release-cycle). - * * It is not our code running here and we can only observe what's happening. - */ - ellapsedAppReady?: number; - - /** - * The time it took to generate NLS data. - * - * * Happens in the main-process - * * Measured with the `nlsGeneration:start` and `nlsGeneration:end` performance marks. - * * This only happens when a non-english locale is being used. - * * It is our code running here and we should monitor this carefully for regressions. - */ - ellapsedNlsGeneration: number; - - /** - * The time it took to tell electron to open/restore a renderer (browser window). - * - * * Happens in the main-process - * * Measured with the `main:appReady` and `main:loadWindow` performance marks. - * * This can be compared between insider and stable builds. - * * It is our code running here and we should monitor this carefully for regressions. - */ - ellapsedWindowLoad?: number; - - /** - * The time it took to create a new renderer (browser window) and to initialize that to the point - * of load the main-bundle (`workbench.main.js`). - * - * * Happens in the main-process *and* the renderer-process - * * Measured with the `main:loadWindow` and `willLoadWorkbenchMain` performance marks. - * * This can be compared between insider and stable builds. - * * It is mostly not our code running here and we can only observe what's happening. - * - */ - ellapsedWindowLoadToRequire: number; - - /** - * The time it took to load the main-bundle of the workbench, e.g `workbench.main.js`. - * - * * Happens in the renderer-process - * * Measured with the `willLoadWorkbenchMain` and `didLoadWorkbenchMain` performance marks. - * * This varies *a lot* when V8 cached data could be used or not - * * This should be looked at with and without V8 cached data usage and per electron/v8 version - * * This is affected by the size of our code bundle (which grows about 3-5% per release) - */ - ellapsedRequire: number; - - /** - * The time it took to read extensions' package.json-files *and* interpret them (invoking - * the contribution points). - * - * * Happens in the renderer-process - * * Measured with the `willLoadExtensions` and `didLoadExtensions` performance marks. - * * Reading of package.json-files is avoided by caching them all in a single file (after the read, - * until another extension is installed) - * * Happens in parallel to other things, depends on async timing - * - * todo@joh/ramya this measures an artifical dealy we have added, see https://github.com/Microsoft/vscode/blob/2f07ddae8bf56e969e3f4ba1447258ebc999672f/src/vs/workbench/services/extensions/electron-browser/extensionService.ts#L311-L326 - */ - ellapsedExtensions: number; - - // the time from start till `didLoadExtensions` - // remove? - ellapsedExtensionsReady: number; - - /** - * The time it took to restore the viewlet. - * - * * Happens in the renderer-process - * * Measured with the `willRestoreViewlet` and `didRestoreViewlet` performance marks. - * * This should be looked at per viewlet-type/id. - * * Happens in parallel to other things, depends on async timing - */ - ellapsedViewletRestore: number; - - /** - * The time it took to restore editors - that is text editor and complex editor likes the settings UI - * or webviews (markdown preview). - * - * * Happens in the renderer-process - * * Measured with the `willRestoreEditors` and `didRestoreEditors` performance marks. - * * This should be looked at per editor and per editor type. - * * Happens in parallel to other things, depends on async timing - * - * todo@joh/ramya We should probably measures each editor individually? - */ - ellapsedEditorRestore: number; - - /** - * The time it took to create the workbench. - * - * * Happens in the renderer-process - * * Measured with the `willStartWorkbench` and `didStartWorkbench` performance marks. - * - * todo@joh/ramya Not sure if this is useful because this includes too much - */ - ellapsedWorkbench: number; - - // the time it took to generate this object. - // remove? - ellapsedTimersToTimersComputed: number; - }; - - hasAccessibilitySupport: boolean; - isVMLikelyhood: number; - platform: string; - release: string; - arch: string; - totalmem: number; - freemem: number; - meminfo: IMemoryInfo; - cpus: { count: number; speed: number; model: string; }; - loadavg: number[]; -} - -export interface ITimerService { - _serviceBrand: any; - - readonly startupMetrics: IStartupMetrics; -} diff --git a/src/vs/workbench/services/timer/electron-browser/timerService.ts b/src/vs/workbench/services/timer/electron-browser/timerService.ts index a1f75b791ce..34489124af0 100644 --- a/src/vs/workbench/services/timer/electron-browser/timerService.ts +++ b/src/vs/workbench/services/timer/electron-browser/timerService.ts @@ -4,37 +4,246 @@ *--------------------------------------------------------------------------------------------*/ 'use strict'; -import { ITimerService, IStartupMetrics, IMemoryInfo } from 'vs/workbench/services/timer/common/timerService'; +import { createDecorator } from 'vs/platform/instantiation/common/instantiation'; import { virtualMachineHint } from 'vs/base/node/id'; import * as perf from 'vs/base/common/performance'; import * as os from 'os'; import { getAccessibilitySupport } from 'vs/base/browser/browser'; import { AccessibilitySupport } from 'vs/base/common/platform'; -import { IWindowConfiguration } from 'vs/platform/windows/common/windows'; +import { IWindowService } from 'vs/platform/windows/common/windows'; +import { IWorkspaceContextService, WorkbenchState } from 'vs/platform/workspace/common/workspace'; +import { IExtensionService } from 'vs/workbench/services/extensions/common/extensions'; +import { registerSingleton } from 'vs/platform/instantiation/common/extensions'; -export class TimerService implements ITimerService { - public _serviceBrand: any; +/* __GDPR__FRAGMENT__ + "IMemoryInfo" : { + "workingSetSize" : { "classification": "SystemMetaData", "purpose": "PerformanceAndHealth", "isMeasurement": true }, + "peakWorkingSetSize": { "classification": "SystemMetaData", "purpose": "PerformanceAndHealth", "isMeasurement": true }, + "privateBytes": { "classification": "SystemMetaData", "purpose": "PerformanceAndHealth", "isMeasurement": true }, + "sharedBytes": { "classification": "SystemMetaData", "purpose": "PerformanceAndHealth", "isMeasurement": true } + } +*/ +export interface IMemoryInfo { + workingSetSize: number; + peakWorkingSetSize: number; + privateBytes: number; + sharedBytes: number; +} - private _startupMetrics: IStartupMetrics; +/* __GDPR__FRAGMENT__ + "IStartupMetrics" : { + "version" : { "classification": "SystemMetaData", "purpose": "PerformanceAndHealth" }, + "ellapsed" : { "classification": "SystemMetaData", "purpose": "PerformanceAndHealth", "isMeasurement": true }, + "timers.ellapsedAppReady" : { "classification": "SystemMetaData", "purpose": "PerformanceAndHealth", "isMeasurement": true }, + "timers.ellapsedWindowLoad" : { "classification": "SystemMetaData", "purpose": "PerformanceAndHealth", "isMeasurement": true }, + "timers.ellapsedWindowLoadToRequire" : { "classification": "SystemMetaData", "purpose": "PerformanceAndHealth", "isMeasurement": true }, + "timers.ellapsedExtensions" : { "classification": "SystemMetaData", "purpose": "PerformanceAndHealth", "isMeasurement": true }, + "timers.ellapsedExtensionsReady" : { "classification": "SystemMetaData", "purpose": "PerformanceAndHealth", "isMeasurement": true }, + "timers.ellapsedRequire" : { "classification": "SystemMetaData", "purpose": "PerformanceAndHealth", "isMeasurement": true }, + "timers.ellapsedViewletRestore" : { "classification": "SystemMetaData", "purpose": "PerformanceAndHealth", "isMeasurement": true }, + "timers.ellapsedEditorRestore" : { "classification": "SystemMetaData", "purpose": "PerformanceAndHealth", "isMeasurement": true }, + "timers.ellapsedWorkbench" : { "classification": "SystemMetaData", "purpose": "PerformanceAndHealth", "isMeasurement": true }, + "timers.ellapsedTimersToTimersComputed" : { "classification": "SystemMetaData", "purpose": "PerformanceAndHealth", "isMeasurement": true }, + "timers.ellapsedNlsGeneration" : { "classification": "SystemMetaData", "purpose": "PerformanceAndHealth", "isMeasurement": true }, + "platform" : { "classification": "SystemMetaData", "purpose": "PerformanceAndHealth" }, + "release" : { "classification": "SystemMetaData", "purpose": "PerformanceAndHealth" }, + "arch" : { "classification": "SystemMetaData", "purpose": "PerformanceAndHealth" }, + "totalmem" : { "classification": "SystemMetaData", "purpose": "PerformanceAndHealth", "isMeasurement": true }, + "freemem" : { "classification": "SystemMetaData", "purpose": "PerformanceAndHealth", "isMeasurement": true }, + "meminfo" : { "${inline}": [ "${IMemoryInfo}" ] }, + "cpus.count" : { "classification": "SystemMetaData", "purpose": "PerformanceAndHealth", "isMeasurement": true }, + "cpus.speed" : { "classification": "SystemMetaData", "purpose": "PerformanceAndHealth", "isMeasurement": true }, + "cpus.model" : { "classification": "SystemMetaData", "purpose": "PerformanceAndHealth" }, + "initialStartup" : { "classification": "SystemMetaData", "purpose": "PerformanceAndHealth", "isMeasurement": true }, + "hasAccessibilitySupport" : { "classification": "SystemMetaData", "purpose": "PerformanceAndHealth", "isMeasurement": true }, + "isVMLikelyhood" : { "classification": "SystemMetaData", "purpose": "PerformanceAndHealth", "isMeasurement": true }, + "emptyWorkbench" : { "classification": "SystemMetaData", "purpose": "PerformanceAndHealth", "isMeasurement": true }, + "loadavg" : { "classification": "SystemMetaData", "purpose": "PerformanceAndHealth" } + } +*/ +export interface IStartupMetrics { + + /** + * The version of these metrics. + */ + version: 1; + + /** + * The time it took to create the workbench. + * + * * Happens in the main-process *and* the renderer-process + * * Measured with the *start* and `didStartWorkbench`-performance mark. The *start* is either the start of the + * main process or the start of the renderer. + * * This should be looked at carefully because times vary depending on + * * This being the first window, the only window, or a reloaded window + * * Cached data being present and used or not + * * The numbers and types of editors being restored + * * The numbers of windows being restored (when starting 'fresh') + * * The viewlet being restored (esp. when it's a contributed viewlet) + */ + ellapsed: number; + + /** + * If this started the main process and renderer or just a renderer (new or reloaded). + */ + initialStartup: boolean; + + /** + * No folder, no file, no workspace has been opened + */ + emptyWorkbench: boolean; + + timers: { + /** + * The time it took to receieve the [`ready`](https://electronjs.org/docs/api/app#event-ready)-event. Measured from the first line + * of JavaScript code till receiving that event. + * + * * Happens in the main-process + * * Measured with the `main:started` and `main:appReady` performance marks. + * * This can be compared between insider and stable builds. + * * This should be looked at per OS version and per electron version. + * * This is often affected by AV software (and can change with AV software updates outside of our release-cycle). + * * It is not our code running here and we can only observe what's happening. + */ + ellapsedAppReady?: number; + + /** + * The time it took to generate NLS data. + * + * * Happens in the main-process + * * Measured with the `nlsGeneration:start` and `nlsGeneration:end` performance marks. + * * This only happens when a non-english locale is being used. + * * It is our code running here and we should monitor this carefully for regressions. + */ + ellapsedNlsGeneration: number; + + /** + * The time it took to tell electron to open/restore a renderer (browser window). + * + * * Happens in the main-process + * * Measured with the `main:appReady` and `main:loadWindow` performance marks. + * * This can be compared between insider and stable builds. + * * It is our code running here and we should monitor this carefully for regressions. + */ + ellapsedWindowLoad?: number; + + /** + * The time it took to create a new renderer (browser window) and to initialize that to the point + * of load the main-bundle (`workbench.main.js`). + * + * * Happens in the main-process *and* the renderer-process + * * Measured with the `main:loadWindow` and `willLoadWorkbenchMain` performance marks. + * * This can be compared between insider and stable builds. + * * It is mostly not our code running here and we can only observe what's happening. + * + */ + ellapsedWindowLoadToRequire: number; + + /** + * The time it took to load the main-bundle of the workbench, e.g `workbench.main.js`. + * + * * Happens in the renderer-process + * * Measured with the `willLoadWorkbenchMain` and `didLoadWorkbenchMain` performance marks. + * * This varies *a lot* when V8 cached data could be used or not + * * This should be looked at with and without V8 cached data usage and per electron/v8 version + * * This is affected by the size of our code bundle (which grows about 3-5% per release) + */ + ellapsedRequire: number; + + /** + * The time it took to read extensions' package.json-files *and* interpret them (invoking + * the contribution points). + * + * * Happens in the renderer-process + * * Measured with the `willLoadExtensions` and `didLoadExtensions` performance marks. + * * Reading of package.json-files is avoided by caching them all in a single file (after the read, + * until another extension is installed) + * * Happens in parallel to other things, depends on async timing + * + * todo@joh/ramya this measures an artifical dealy we have added, see https://github.com/Microsoft/vscode/blob/2f07ddae8bf56e969e3f4ba1447258ebc999672f/src/vs/workbench/services/extensions/electron-browser/extensionService.ts#L311-L326 + */ + ellapsedExtensions: number; + + // the time from start till `didLoadExtensions` + // remove? + ellapsedExtensionsReady: number; + + /** + * The time it took to restore the viewlet. + * + * * Happens in the renderer-process + * * Measured with the `willRestoreViewlet` and `didRestoreViewlet` performance marks. + * * This should be looked at per viewlet-type/id. + * * Happens in parallel to other things, depends on async timing + */ + ellapsedViewletRestore: number; + + /** + * The time it took to restore editors - that is text editor and complex editor likes the settings UI + * or webviews (markdown preview). + * + * * Happens in the renderer-process + * * Measured with the `willRestoreEditors` and `didRestoreEditors` performance marks. + * * This should be looked at per editor and per editor type. + * * Happens in parallel to other things, depends on async timing + * + * todo@joh/ramya We should probably measures each editor individually? + */ + ellapsedEditorRestore: number; + + /** + * The time it took to create the workbench. + * + * * Happens in the renderer-process + * * Measured with the `willStartWorkbench` and `didStartWorkbench` performance marks. + * + * todo@joh/ramya Not sure if this is useful because this includes too much + */ + ellapsedWorkbench: number; + + // the time it took to generate this object. + // remove? + ellapsedTimersToTimersComputed: number; + }; + + hasAccessibilitySupport: boolean; + isVMLikelyhood: number; + platform: string; + release: string; + arch: string; + totalmem: number; + freemem: number; + meminfo: IMemoryInfo; + cpus: { count: number; speed: number; model: string; }; + loadavg: number[]; +} + +export interface ITimerService { + _serviceBrand: any; + readonly startupMetrics: Promise; +} + +class TimerService implements ITimerService { + + _serviceBrand: any; + + readonly startupMetrics: Promise; constructor( - private readonly _configuration: IWindowConfiguration, - private readonly _isEmptyWorkbench: boolean + @IWindowService private readonly _windowService: IWindowService, + @IWorkspaceContextService private readonly _contextService: IWorkspaceContextService, + @IExtensionService private readonly _extensionService: IExtensionService, ) { - // + + this.startupMetrics = Promise + .resolve(this._extensionService.whenInstalledExtensionsRegistered()) + .then(() => this._computeStartupMetrics()); } - get startupMetrics(): IStartupMetrics { - if (!this._startupMetrics) { - this._computeStartupMetrics(); - } - return this._startupMetrics; - } - - public _computeStartupMetrics(): void { + private _computeStartupMetrics(): IStartupMetrics { const now = Date.now(); - const initialStartup = !!this._configuration.isInitialStartup; + const initialStartup = !!this._windowService.getConfiguration().isInitialStartup; const startMark = initialStartup ? 'main:started' : 'main:loadWindow'; let totalmem: number; @@ -66,7 +275,7 @@ export class TimerService implements ITimerService { // ignore, be on the safe side with these hardware method calls } - this._startupMetrics = { + return { version: 1, ellapsed: perf.getDuration(startMark, 'didStartWorkbench'), timers: { @@ -93,7 +302,12 @@ export class TimerService implements ITimerService { initialStartup, isVMLikelyhood, hasAccessibilitySupport: getAccessibilitySupport() === AccessibilitySupport.Enabled, - emptyWorkbench: this._isEmptyWorkbench + emptyWorkbench: this._contextService.getWorkbenchState() === WorkbenchState.EMPTY }; } } + + +export const ITimerService = createDecorator('timerService'); + +registerSingleton(ITimerService, TimerService); From 4390abed32339f9cb6295d8d46ac886e67fd9c47 Mon Sep 17 00:00:00 2001 From: Johannes Rieken Date: Thu, 16 Aug 2018 16:49:52 +0200 Subject: [PATCH 0895/1276] merge startup reflections into timer service, #56253 --- .../electron-browser/startupTimings.ts | 137 ++---------------- .../timer/electron-browser/timerService.ts | 118 +++++++++++++-- 2 files changed, 118 insertions(+), 137 deletions(-) diff --git a/src/vs/workbench/parts/performance/electron-browser/startupTimings.ts b/src/vs/workbench/parts/performance/electron-browser/startupTimings.ts index c55249a7f97..d4a974c0c38 100644 --- a/src/vs/workbench/parts/performance/electron-browser/startupTimings.ts +++ b/src/vs/workbench/parts/performance/electron-browser/startupTimings.ts @@ -5,73 +5,20 @@ 'use strict'; -import { IExtensionService } from 'vs/workbench/services/extensions/common/extensions'; +import { onUnexpectedError } from 'vs/base/common/errors'; +import { isCodeEditor } from 'vs/editor/browser/editorBrowser'; import { ILifecycleService, LifecyclePhase, StartupKind } from 'vs/platform/lifecycle/common/lifecycle'; -import { IWindowsService } from 'vs/platform/windows/common/windows'; -import { IWorkbenchContributionsRegistry, IWorkbenchContribution, Extensions } from 'vs/workbench/common/contributions'; +import { ILogService } from 'vs/platform/log/common/log'; import { Registry } from 'vs/platform/registry/common/platform'; import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry'; -import { ITimerService, IStartupMetrics } from 'vs/workbench/services/timer/electron-browser/timerService'; -import { onUnexpectedError } from 'vs/base/common/errors'; -import { IViewletService } from 'vs/workbench/services/viewlet/browser/viewlet'; +import { IUpdateService } from 'vs/platform/update/common/update'; +import { IWindowsService } from 'vs/platform/windows/common/windows'; +import { Extensions, IWorkbenchContribution, IWorkbenchContributionsRegistry } from 'vs/workbench/common/contributions'; import * as files from 'vs/workbench/parts/files/common/files'; import { IEditorService } from 'vs/workbench/services/editor/common/editorService'; -import { isCodeEditor } from 'vs/editor/browser/editorBrowser'; -import { isFalsyOrEmpty } from 'vs/base/common/arrays'; -import { ILogService } from 'vs/platform/log/common/log'; import { IPanelService } from 'vs/workbench/services/panel/common/panelService'; -import { IUpdateService } from 'vs/platform/update/common/update'; - -/* __GDPR__FRAGMENT__ - "IStartupReflections" : { - "isLatestVersion": { "classification": "SystemMetaData", "purpose": "PerformanceAndHealth" }, - "didUseCachedData": { "classification": "SystemMetaData", "purpose": "PerformanceAndHealth" }, - "windowKind": { "classification": "SystemMetaData", "purpose": "PerformanceAndHealth" }, - "windowCount": { "classification": "SystemMetaData", "purpose": "PerformanceAndHealth" }, - "viewletId": { "classification": "SystemMetaData", "purpose": "PerformanceAndHealth" }, - "panelId": { "classification": "SystemMetaData", "purpose": "PerformanceAndHealth" }, - "editorIds": { "classification": "SystemMetaData", "purpose": "PerformanceAndHealth" } - } -*/ -interface IStartupReflections { - /** - * This is the latest (stable/insider) version. Iff not we should ignore this - * measurement. - */ - isLatestVersion: boolean; - - /** - * Whether we asked for and V8 accepted cached data. - */ - didUseCachedData: boolean; - - /** - * How/why the window was created. See https://github.com/Microsoft/vscode/blob/d1f57d871722f4d6ba63e4ef6f06287121ceb045/src/vs/platform/lifecycle/common/lifecycle.ts#L50 - */ - windowKind: number; - - /** - * The total number of windows that have been restored/created - */ - windowCount: number; - - /** - * The active viewlet id or `undedined` - */ - viewletId: string; - - /** - * The active panel id or `undefined` - */ - panelId: string; - - /** - * The editor input types or `[]` - */ - editorIds: string[]; -} - -type IStartupTimings = IStartupMetrics & IStartupReflections; +import { ITimerService, didUseCachedData } from 'vs/workbench/services/timer/electron-browser/timerService'; +import { IViewletService } from 'vs/workbench/services/viewlet/browser/viewlet'; class StartupTimings implements IWorkbenchContribution { @@ -84,7 +31,6 @@ class StartupTimings implements IWorkbenchContribution { @IPanelService private readonly _panelService: IPanelService, @ITelemetryService private readonly _telemetryService: ITelemetryService, @ILifecycleService private readonly _lifecycleService: ILifecycleService, - @IExtensionService private readonly _extensionService: IExtensionService, @IUpdateService private readonly _updateService: IUpdateService, ) { @@ -96,12 +42,11 @@ class StartupTimings implements IWorkbenchContribution { /* __GDPR__ "startupTimeVaried" : { "${include}": [ - "${IStartupMetrics}", - "${IStartupReflections}" + "${IStartupMetrics}" ] } */ - this._telemetryService.publicLog('startupTimeVaried', await this._getStartupTimings()); + this._telemetryService.publicLog('startupTimeVaried', await this._timerService.startupMetrics); } private async _reportStandardStartupTimes(): Promise { @@ -132,7 +77,7 @@ class StartupTimings implements IWorkbenchContribution { this._logService.info('no standard startup: panel is active'); return; } - if (!_didUseCachedData()) { + if (!didUseCachedData()) { this._logService.info('no standard startup: not using cached data'); return; } @@ -144,69 +89,15 @@ class StartupTimings implements IWorkbenchContribution { /* __GDPR__ "startupTime" : { "${include}": [ - "${IStartupMetrics}", - "${IStartupReflections}" + "${IStartupMetrics}" ] } */ - const timings = await this._getStartupTimings(); - this._telemetryService.publicLog('startupTime', timings); - this._logService.info('standard startup', timings); - } - - private async _getStartupTimings(): Promise { - - await Promise.all([ - this._extensionService.whenInstalledExtensionsRegistered(), - this._lifecycleService.when(LifecyclePhase.Eventually) - ]); - - const isLatestVersion = Boolean(await this._updateService.isLatestVersion()); - const didUseCachedData = _didUseCachedData(); - - const windowKind = this._lifecycleService.startupKind; - const windowCount = await this._windowsService.getWindowCount(); - - const viewletId = this._viewletService.getActiveViewlet() ? this._viewletService.getActiveViewlet().getId() : undefined; - const editorIds = this._editorService.visibleEditors.map(input => input.getTypeId()); - const panelId = this._panelService.getActivePanel() ? this._panelService.getActivePanel().getId() : undefined; - - const reflections = { - isLatestVersion, - didUseCachedData, - windowKind, - windowCount, - viewletId, - panelId, - editorIds - }; - const metrics = await this._timerService.startupMetrics; - return { ...reflections, ...metrics }; + this._telemetryService.publicLog('startupTime', metrics); + this._logService.info('standard startup', metrics); } } const registry = Registry.as(Extensions.Workbench); registry.registerWorkbenchContribution(StartupTimings, LifecyclePhase.Running); - - -//#region cached data logic - -function _didUseCachedData(): boolean { - // We surely don't use cached data when we don't tell the loader to do so - if (!Boolean((global).require.getConfig().nodeCachedDataDir)) { - return false; - } - // whenever cached data is produced or rejected a onNodeCachedData-callback is invoked. That callback - // stores data in the `MonacoEnvironment.onNodeCachedData` global. See: - // https://github.com/Microsoft/vscode/blob/efe424dfe76a492eab032343e2fa4cfe639939f0/src/vs/workbench/electron-browser/bootstrap/index.js#L299 - if (!isFalsyOrEmpty(MonacoEnvironment.onNodeCachedData)) { - return false; - } - return true; -} - -declare type OnNodeCachedDataArgs = [{ errorCode: string, path: string, detail?: string }, { path: string, length: number }]; -declare const MonacoEnvironment: { onNodeCachedData: OnNodeCachedDataArgs[] }; - -//#endregion diff --git a/src/vs/workbench/services/timer/electron-browser/timerService.ts b/src/vs/workbench/services/timer/electron-browser/timerService.ts index 34489124af0..ad0db011375 100644 --- a/src/vs/workbench/services/timer/electron-browser/timerService.ts +++ b/src/vs/workbench/services/timer/electron-browser/timerService.ts @@ -10,10 +10,16 @@ import * as perf from 'vs/base/common/performance'; import * as os from 'os'; import { getAccessibilitySupport } from 'vs/base/browser/browser'; import { AccessibilitySupport } from 'vs/base/common/platform'; -import { IWindowService } from 'vs/platform/windows/common/windows'; +import { IWindowService, IWindowsService } from 'vs/platform/windows/common/windows'; import { IWorkspaceContextService, WorkbenchState } from 'vs/platform/workspace/common/workspace'; import { IExtensionService } from 'vs/workbench/services/extensions/common/extensions'; import { registerSingleton } from 'vs/platform/instantiation/common/extensions'; +import { isFalsyOrEmpty } from 'vs/base/common/arrays'; +import { IUpdateService } from 'vs/platform/update/common/update'; +import { ILifecycleService } from 'vs/platform/lifecycle/common/lifecycle'; +import { IViewletService } from 'vs/workbench/services/viewlet/browser/viewlet'; +import { IPanelService } from 'vs/workbench/services/panel/common/panelService'; +import { IEditorService } from 'vs/workbench/services/editor/common/editorService'; /* __GDPR__FRAGMENT__ @@ -35,6 +41,13 @@ export interface IMemoryInfo { "IStartupMetrics" : { "version" : { "classification": "SystemMetaData", "purpose": "PerformanceAndHealth" }, "ellapsed" : { "classification": "SystemMetaData", "purpose": "PerformanceAndHealth", "isMeasurement": true }, + "isLatestVersion": { "classification": "SystemMetaData", "purpose": "PerformanceAndHealth" }, + "didUseCachedData": { "classification": "SystemMetaData", "purpose": "PerformanceAndHealth" }, + "windowKind": { "classification": "SystemMetaData", "purpose": "PerformanceAndHealth" }, + "windowCount": { "classification": "SystemMetaData", "purpose": "PerformanceAndHealth" }, + "viewletId": { "classification": "SystemMetaData", "purpose": "PerformanceAndHealth" }, + "panelId": { "classification": "SystemMetaData", "purpose": "PerformanceAndHealth" }, + "editorIds": { "classification": "SystemMetaData", "purpose": "PerformanceAndHealth" } "timers.ellapsedAppReady" : { "classification": "SystemMetaData", "purpose": "PerformanceAndHealth", "isMeasurement": true }, "timers.ellapsedWindowLoad" : { "classification": "SystemMetaData", "purpose": "PerformanceAndHealth", "isMeasurement": true }, "timers.ellapsedWindowLoadToRequire" : { "classification": "SystemMetaData", "purpose": "PerformanceAndHealth", "isMeasurement": true }, @@ -67,7 +80,53 @@ export interface IStartupMetrics { /** * The version of these metrics. */ - version: 1; + version: 2; + + /** + * If this started the main process and renderer or just a renderer (new or reloaded). + */ + initialStartup: boolean; + + /** + * No folder, no file, no workspace has been opened + */ + emptyWorkbench: boolean; + + /** + * This is the latest (stable/insider) version. Iff not we should ignore this + * measurement. + */ + isLatestVersion: boolean; + + /** + * Whether we asked for and V8 accepted cached data. + */ + didUseCachedData: boolean; + + /** + * How/why the window was created. See https://github.com/Microsoft/vscode/blob/d1f57d871722f4d6ba63e4ef6f06287121ceb045/src/vs/platform/lifecycle/common/lifecycle.ts#L50 + */ + windowKind: number; + + /** + * The total number of windows that have been restored/created + */ + windowCount: number; + + /** + * The active viewlet id or `undedined` + */ + viewletId: string; + + /** + * The active panel id or `undefined` + */ + panelId: string; + + /** + * The editor input types or `[]` + */ + editorIds: string[]; /** * The time it took to create the workbench. @@ -85,15 +144,8 @@ export interface IStartupMetrics { ellapsed: number; /** - * If this started the main process and renderer or just a renderer (new or reloaded). + * Individual timers... */ - initialStartup: boolean; - - /** - * No folder, no file, no workspace has been opened - */ - emptyWorkbench: boolean; - timers: { /** * The time it took to receieve the [`ready`](https://electronjs.org/docs/api/app#event-ready)-event. Measured from the first line @@ -231,17 +283,22 @@ class TimerService implements ITimerService { readonly startupMetrics: Promise; constructor( + @IWindowsService private readonly _windowsService: IWindowsService, @IWindowService private readonly _windowService: IWindowService, + @ILifecycleService private readonly _lifecycleService: ILifecycleService, @IWorkspaceContextService private readonly _contextService: IWorkspaceContextService, @IExtensionService private readonly _extensionService: IExtensionService, + @IUpdateService private readonly _updateService: IUpdateService, + @IViewletService private readonly _viewletService: IViewletService, + @IPanelService private readonly _panelService: IPanelService, + @IEditorService private readonly _editorService: IEditorService, ) { - this.startupMetrics = Promise .resolve(this._extensionService.whenInstalledExtensionsRegistered()) .then(() => this._computeStartupMetrics()); } - private _computeStartupMetrics(): IStartupMetrics { + private async _computeStartupMetrics(): Promise { const now = Date.now(); const initialStartup = !!this._windowService.getConfiguration().isInitialStartup; const startMark = initialStartup ? 'main:started' : 'main:loadWindow'; @@ -276,8 +333,19 @@ class TimerService implements ITimerService { } return { - version: 1, + version: 2, ellapsed: perf.getDuration(startMark, 'didStartWorkbench'), + + // reflections + isLatestVersion: Boolean(await this._updateService.isLatestVersion()), + didUseCachedData: didUseCachedData(), + windowKind: this._lifecycleService.startupKind, + windowCount: await this._windowsService.getWindowCount(), + viewletId: this._viewletService.getActiveViewlet() ? this._viewletService.getActiveViewlet().getId() : undefined, + editorIds: this._editorService.visibleEditors.map(input => input.getTypeId()), + panelId: this._panelService.getActivePanel() ? this._panelService.getActivePanel().getId() : undefined, + + // timers timers: { ellapsedAppReady: initialStartup ? perf.getDuration('main:started', 'main:appReady') : undefined, ellapsedNlsGeneration: perf.getDuration('nlsGeneration:start', 'nlsGeneration:end'), @@ -291,6 +359,8 @@ class TimerService implements ITimerService { ellapsedExtensionsReady: perf.getDuration(startMark, 'didLoadExtensions'), ellapsedTimersToTimersComputed: Date.now() - now, }, + + // system info platform, release, arch, @@ -307,7 +377,27 @@ class TimerService implements ITimerService { } } - export const ITimerService = createDecorator('timerService'); registerSingleton(ITimerService, TimerService); + +//#region cached data logic + +export function didUseCachedData(): boolean { + // We surely don't use cached data when we don't tell the loader to do so + if (!Boolean((global).require.getConfig().nodeCachedDataDir)) { + return false; + } + // whenever cached data is produced or rejected a onNodeCachedData-callback is invoked. That callback + // stores data in the `MonacoEnvironment.onNodeCachedData` global. See: + // https://github.com/Microsoft/vscode/blob/efe424dfe76a492eab032343e2fa4cfe639939f0/src/vs/workbench/electron-browser/bootstrap/index.js#L299 + if (!isFalsyOrEmpty(MonacoEnvironment.onNodeCachedData)) { + return false; + } + return true; +} + +declare type OnNodeCachedDataArgs = [{ errorCode: string, path: string, detail?: string }, { path: string, length: number }]; +declare const MonacoEnvironment: { onNodeCachedData: OnNodeCachedDataArgs[] }; + +//#endregion From eddf13fd7a2147658fdacf6cabb48c01bd6271db Mon Sep 17 00:00:00 2001 From: Johannes Rieken Date: Thu, 16 Aug 2018 17:35:56 +0200 Subject: [PATCH 0896/1276] workaround #56579 --- src/vs/base/common/event.ts | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/vs/base/common/event.ts b/src/vs/base/common/event.ts index 203bcb896f9..957011262c0 100644 --- a/src/vs/base/common/event.ts +++ b/src/vs/base/common/event.ts @@ -8,6 +8,7 @@ import { onUnexpectedError } from 'vs/base/common/errors'; import { once as onceFn } from 'vs/base/common/functional'; import { combinedDisposable, Disposable, IDisposable, toDisposable } from 'vs/base/common/lifecycle'; import { LinkedList } from 'vs/base/common/linkedList'; +import { TPromise } from 'vs/base/common/winjs.base'; /** * To an event a function with one or zero parameters @@ -294,8 +295,8 @@ export function fromPromise(promise: Thenable): Event { return emitter.event; } -export function toPromise(event: Event): Promise { - return new Promise(complete => { +export function toPromise(event: Event): Thenable { + return new TPromise(complete => { const sub = event(e => { sub.dispose(); complete(e); From 9714bb37b446d96fe8be2bfaf0f103fc847ac4c3 Mon Sep 17 00:00:00 2001 From: Johannes Rieken Date: Thu, 16 Aug 2018 17:40:34 +0200 Subject: [PATCH 0897/1276] better output from 'Startup Performance' action --- src/vs/workbench/electron-browser/actions.ts | 34 +++++++++---------- .../timer/electron-browser/timerService.ts | 2 +- 2 files changed, 18 insertions(+), 18 deletions(-) diff --git a/src/vs/workbench/electron-browser/actions.ts b/src/vs/workbench/electron-browser/actions.ts index 084c8911004..d87eb1c6f17 100644 --- a/src/vs/workbench/electron-browser/actions.ts +++ b/src/vs/workbench/electron-browser/actions.ts @@ -321,7 +321,9 @@ export class ShowStartupPerformance extends Action { console.log(`Memory (System): ${(metrics.totalmem / (1024 * 1024 * 1024)).toFixed(2)}GB (${(metrics.freemem / (1024 * 1024 * 1024)).toFixed(2)}GB free)`); console.log(`Memory (Process): ${(metrics.meminfo.workingSetSize / 1024).toFixed(2)}MB working set (${(metrics.meminfo.peakWorkingSetSize / 1024).toFixed(2)}MB peak, ${(metrics.meminfo.privateBytes / 1024).toFixed(2)}MB private, ${(metrics.meminfo.sharedBytes / 1024).toFixed(2)}MB shared)`); console.log(`VM (likelyhood): ${metrics.isVMLikelyhood}%`); + console.log(`Initial Startup: ${metrics.initialStartup}`); + console.log(`Has ${metrics.windowCount - 1} other windows`); console.log(`Screen Reader Active: ${metrics.hasAccessibilitySupport}`); console.log(`Empty Workspace: ${metrics.emptyWorkbench}`); @@ -369,29 +371,27 @@ export class ShowStartupPerformance extends Action { return TPromise.as(true); } - private getStartupMetricsTable(metrics: IStartupMetrics, nodeModuleLoadTime?: number): any[] { - const table: any[] = []; + private getStartupMetricsTable(metrics: IStartupMetrics, nodeModuleLoadTime?: number): any { + const table = Object.create(null); - if (metrics.initialStartup) { - table.push({ Topic: '[main] start => app.isReady', 'Took (ms)': metrics.timers.ellapsedAppReady }); - table.push({ Topic: '[main] nls:start => nls:end', 'Took (ms)': metrics.timers.ellapsedNlsGeneration }); - table.push({ Topic: '[main] app.isReady => window.loadUrl()', 'Took (ms)': metrics.timers.ellapsedWindowLoad }); - } + table['start => app.isReady'] = { Process: '[main]', 'Took (ms)': metrics.timers.ellapsedAppReady, Meta: metrics.initialStartup }; + table['nls:start => nls:end'] = { Process: '[main]', 'Took (ms)': metrics.timers.ellapsedNlsGeneration, Meta: metrics.initialStartup }; + table['app.isReady => window.loadUrl()'] = { Process: '[main]', 'Took (ms)': metrics.timers.ellapsedWindowLoad, Meta: metrics.initialStartup }; - table.push({ Topic: '[main->renderer] window.loadUrl() => begin to require(workbench.main.js)', 'Took (ms)': metrics.timers.ellapsedWindowLoadToRequire }); - table.push({ Topic: '[renderer] require(workbench.main.js)', 'Took (ms)': metrics.timers.ellapsedRequire }); + table['window.loadUrl() => begin to require(workbench.main.js)'] = { Process: '[main->renderer]', 'Took (ms)': metrics.timers.ellapsedWindowLoadToRequire }; + table['require(workbench.main.js)'] = { Process: '[renderer]', 'Took (ms)': metrics.timers.ellapsedRequire, Meta: metrics.didUseCachedData ? 'did use cached data' : 'did NOT use cached data' }; if (nodeModuleLoadTime) { - table.push({ Topic: '[renderer] -> of which require() node_modules', 'Took (ms)': nodeModuleLoadTime }); + table['[renderer] -> of which require() node_modules'] = { Process: '[renderer]', 'Took(ms)': nodeModuleLoadTime }; } - table.push({ Topic: '[renderer] register extensions & spawn extension host', 'Took (ms)': metrics.timers.ellapsedExtensions }); - table.push({ Topic: '[renderer] restore viewlet', 'Took (ms)': metrics.timers.ellapsedViewletRestore }); - table.push({ Topic: '[renderer] restore editor view state', 'Took (ms)': metrics.timers.ellapsedEditorRestore }); - table.push({ Topic: '[renderer] overall workbench load', 'Took (ms)': metrics.timers.ellapsedWorkbench }); - table.push({ Topic: '------------------------------------------------------' }); - table.push({ Topic: '[main, renderer] start => extensions ready', 'Took (ms)': metrics.timers.ellapsedExtensionsReady }); - table.push({ Topic: '[main, renderer] start => workbench ready', 'Took (ms)': metrics.ellapsed }); + table['register extensions & spawn extension host'] = { Process: '[renderer]', 'Took (ms)': metrics.timers.ellapsedExtensions }; + table['restore viewlet'] = { Process: '[renderer]', 'Took (ms)': metrics.timers.ellapsedViewletRestore, Meta: metrics.viewletId }; + table['restore editor view state'] = { Process: '[renderer]', 'Took (ms)': metrics.timers.ellapsedEditorRestore, Meta: metrics.editorIds.join(', ') }; + table['overall workbench load'] = { Process: '[renderer]', 'Took (ms)': metrics.timers.ellapsedWorkbench }; + + table['workbench ready'] = { Process: '[main, renderer]', 'Took (ms)': metrics.ellapsed }; + table['extensions registered'] = { Process: '[renderer]', 'Took (ms)': metrics.timers.ellapsedExtensionsReady }; return table; } diff --git a/src/vs/workbench/services/timer/electron-browser/timerService.ts b/src/vs/workbench/services/timer/electron-browser/timerService.ts index ad0db011375..8a1c7b23914 100644 --- a/src/vs/workbench/services/timer/electron-browser/timerService.ts +++ b/src/vs/workbench/services/timer/electron-browser/timerService.ts @@ -348,7 +348,7 @@ class TimerService implements ITimerService { // timers timers: { ellapsedAppReady: initialStartup ? perf.getDuration('main:started', 'main:appReady') : undefined, - ellapsedNlsGeneration: perf.getDuration('nlsGeneration:start', 'nlsGeneration:end'), + ellapsedNlsGeneration: initialStartup ? perf.getDuration('nlsGeneration:start', 'nlsGeneration:end') : undefined, ellapsedWindowLoad: initialStartup ? perf.getDuration('main:appReady', 'main:loadWindow') : undefined, ellapsedWindowLoadToRequire: perf.getDuration('main:loadWindow', 'willLoadWorkbenchMain'), ellapsedRequire: perf.getDuration('willLoadWorkbenchMain', 'didLoadWorkbenchMain'), From 8eeeed30d51f44e6a326a859b4608395c245d344 Mon Sep 17 00:00:00 2001 From: Miguel Solorio Date: Thu, 16 Aug 2018 09:55:44 -0700 Subject: [PATCH 0898/1276] Add empty text for review title --- .../parts/comments/electron-browser/media/review.css | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/vs/workbench/parts/comments/electron-browser/media/review.css b/src/vs/workbench/parts/comments/electron-browser/media/review.css index 853f55ca531..59769ab6c93 100644 --- a/src/vs/workbench/parts/comments/electron-browser/media/review.css +++ b/src/vs/workbench/parts/comments/electron-browser/media/review.css @@ -222,6 +222,10 @@ cursor: pointer; } +.monaco-editor .review-widget .head .review-title .filename:empty::after { + content: "Start discussion"; +} + .monaco-editor .review-widget .head .review-title .dirname:not(:empty) { font-size: 0.9em; margin-left: 0.5em; From 1094f6b1b5e4057ff3cef6b16b7d2020eddbaf34 Mon Sep 17 00:00:00 2001 From: Miguel Solorio Date: Thu, 16 Aug 2018 10:25:39 -0700 Subject: [PATCH 0899/1276] Update reply text area styling to match comment box --- .../comments/electron-browser/commentsEditorContribution.ts | 4 ++-- .../parts/comments/electron-browser/media/review.css | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/vs/workbench/parts/comments/electron-browser/commentsEditorContribution.ts b/src/vs/workbench/parts/comments/electron-browser/commentsEditorContribution.ts index 14deda0806e..021ac2e1b4a 100644 --- a/src/vs/workbench/parts/comments/electron-browser/commentsEditorContribution.ts +++ b/src/vs/workbench/parts/comments/electron-browser/commentsEditorContribution.ts @@ -17,7 +17,7 @@ import { EmbeddedCodeEditorWidget } from 'vs/editor/browser/widget/embeddedCodeE import { IEditorContribution } from 'vs/editor/common/editorCommon'; import { IRange } from 'vs/editor/common/core/range'; import * as modes from 'vs/editor/common/modes'; -import { peekViewEditorBackground, peekViewResultsBackground, peekViewResultsSelectionBackground } from 'vs/editor/contrib/referenceSearch/referencesWidget'; +import { peekViewEditorBackground, peekViewResultsBackground, peekViewResultsSelectionBackground, peekViewTitleBackground } from 'vs/editor/contrib/referenceSearch/referencesWidget'; import { IContextKey, IContextKeyService, RawContextKey } from 'vs/platform/contextkey/common/contextkey'; import { ServicesAccessor, IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; import { KeybindingsRegistry, KeybindingWeight } from 'vs/platform/keybinding/common/keybindingsRegistry'; @@ -602,7 +602,7 @@ registerThemingParticipant((theme, collector) => { `}`); } - let monacoEditorBackground = theme.getColor(peekViewEditorBackground); + let monacoEditorBackground = theme.getColor(peekViewTitleBackground); if (monacoEditorBackground) { collector.addRule( `.monaco-editor .review-widget .body .comment-form .review-thread-reply-button {` + diff --git a/src/vs/workbench/parts/comments/electron-browser/media/review.css b/src/vs/workbench/parts/comments/electron-browser/media/review.css index 59769ab6c93..c194e7d74fb 100644 --- a/src/vs/workbench/parts/comments/electron-browser/media/review.css +++ b/src/vs/workbench/parts/comments/electron-browser/media/review.css @@ -168,7 +168,7 @@ display: block; width: 100%; resize: vertical; - border-radius: 3px; + border-radius: 0; box-sizing: border-box; padding: 6px 12px; font-weight: 600; From f28979f6823a4f26e07b43b5a982a9d7cb73c48f Mon Sep 17 00:00:00 2001 From: Miguel Solorio Date: Thu, 16 Aug 2018 10:25:55 -0700 Subject: [PATCH 0900/1276] Add padding to comment text area --- .../workbench/parts/comments/electron-browser/media/review.css | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/vs/workbench/parts/comments/electron-browser/media/review.css b/src/vs/workbench/parts/comments/electron-browser/media/review.css index c194e7d74fb..efeeca09f97 100644 --- a/src/vs/workbench/parts/comments/electron-browser/media/review.css +++ b/src/vs/workbench/parts/comments/electron-browser/media/review.css @@ -160,7 +160,7 @@ .monaco-editor .review-widget .body .comment-form.expand .monaco-editor, .monaco-editor .review-widget .body .comment-form.expand .form-actions { display: block; - box-sizing: border-box; + box-sizing: content-box; } .monaco-editor .review-widget .body .comment-form .review-thread-reply-button { @@ -191,6 +191,7 @@ max-height: 500px; border-radius: 3px; border: 0px; + padding: 6px 12px; } .monaco-editor .review-widget .body .comment-form .form-actions { From aec8282727a2bd07009ed0f5ae520d3fa5f7238a Mon Sep 17 00:00:00 2001 From: Miguel Solorio Date: Thu, 16 Aug 2018 10:29:10 -0700 Subject: [PATCH 0901/1276] Remove right side padding of text area so scrollbar is flushed to edge --- .../workbench/parts/comments/electron-browser/media/review.css | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vs/workbench/parts/comments/electron-browser/media/review.css b/src/vs/workbench/parts/comments/electron-browser/media/review.css index efeeca09f97..6a3d41dd41d 100644 --- a/src/vs/workbench/parts/comments/electron-browser/media/review.css +++ b/src/vs/workbench/parts/comments/electron-browser/media/review.css @@ -191,7 +191,7 @@ max-height: 500px; border-radius: 3px; border: 0px; - padding: 6px 12px; + padding: 6px 0 6px 12px; } .monaco-editor .review-widget .body .comment-form .form-actions { From 1b61c2a1caaf98c4a993871d759e58321ea35646 Mon Sep 17 00:00:00 2001 From: Miguel Solorio Date: Thu, 16 Aug 2018 11:47:06 -0700 Subject: [PATCH 0902/1276] Remove unused variable --- .../comments/electron-browser/commentsEditorContribution.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vs/workbench/parts/comments/electron-browser/commentsEditorContribution.ts b/src/vs/workbench/parts/comments/electron-browser/commentsEditorContribution.ts index 021ac2e1b4a..db8cb6ebef0 100644 --- a/src/vs/workbench/parts/comments/electron-browser/commentsEditorContribution.ts +++ b/src/vs/workbench/parts/comments/electron-browser/commentsEditorContribution.ts @@ -17,7 +17,7 @@ import { EmbeddedCodeEditorWidget } from 'vs/editor/browser/widget/embeddedCodeE import { IEditorContribution } from 'vs/editor/common/editorCommon'; import { IRange } from 'vs/editor/common/core/range'; import * as modes from 'vs/editor/common/modes'; -import { peekViewEditorBackground, peekViewResultsBackground, peekViewResultsSelectionBackground, peekViewTitleBackground } from 'vs/editor/contrib/referenceSearch/referencesWidget'; +import { peekViewResultsBackground, peekViewResultsSelectionBackground, peekViewTitleBackground } from 'vs/editor/contrib/referenceSearch/referencesWidget'; import { IContextKey, IContextKeyService, RawContextKey } from 'vs/platform/contextkey/common/contextkey'; import { ServicesAccessor, IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; import { KeybindingsRegistry, KeybindingWeight } from 'vs/platform/keybinding/common/keybindingsRegistry'; From 5665c077c5cd60d1d1a9806e2e729f858e30dbab Mon Sep 17 00:00:00 2001 From: Peng Lyu Date: Thu, 16 Aug 2018 12:00:21 -0700 Subject: [PATCH 0903/1276] Fix microsoft/vscode-pull-request-github#168. Use editor font for code in comments. --- .../electron-browser/commentThreadWidget.ts | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/src/vs/workbench/parts/comments/electron-browser/commentThreadWidget.ts b/src/vs/workbench/parts/comments/electron-browser/commentThreadWidget.ts index d29bdb5fb5d..03253893920 100644 --- a/src/vs/workbench/parts/comments/electron-browser/commentThreadWidget.ts +++ b/src/vs/workbench/parts/comments/electron-browser/commentThreadWidget.ts @@ -117,6 +117,7 @@ export class ReviewZoneWidget extends ZoneWidget { private _commentGlyph: CommentGlyphWidget; private _owner: number; private _localToDispose: IDisposable[]; + private _globalToDispose: IDisposable[]; private _markdownRenderer: MarkdownRenderer; private _styleElement: HTMLStyleElement; private _error: HTMLElement; @@ -145,11 +146,17 @@ export class ReviewZoneWidget extends ZoneWidget { this._owner = owner; this._commentThread = commentThread; this._isCollapsed = commentThread.collapsibleState !== modes.CommentThreadCollapsibleState.Expanded; + this._globalToDispose = []; this._localToDispose = []; this.create(); this._styleElement = dom.createStyleSheet(this.domNode); - this.themeService.onThemeChange(this._applyTheme, this); + this._globalToDispose.push(this.themeService.onThemeChange(this._applyTheme, this)); + this._globalToDispose.push(this.editor.onDidChangeConfiguration(e => { + if (e.fontInfo) { + this._applyTheme(this.themeService.getTheme()); + } + })); this._applyTheme(this.themeService.getTheme()); this._markdownRenderer = new MarkdownRenderer(editor, this.modeService, this.openerService); @@ -627,6 +634,13 @@ export class ReviewZoneWidget extends ZoneWidget { content.push(`.monaco-editor .review-widget .body .comment-form .validation-error { background: ${errorBackground}; }`); } + const fontInfo = this.editor.getConfiguration().fontInfo; + content.push(`.monaco-editor .review-widget .body code { + font-family: ${fontInfo.fontFamily}; + font-size: ${fontInfo.fontSize}px; + font-weight: ${fontInfo.fontWeight}; + }`); + this._styleElement.innerHTML = content.join('\n'); // Editor decorations should also be responsive to theme changes @@ -656,6 +670,7 @@ export class ReviewZoneWidget extends ZoneWidget { this._commentGlyph = null; } + this._globalToDispose.forEach(global => global.dispose()); this._localToDispose.forEach(local => local.dispose()); this._onDidClose.fire(); } From acaf5a52a6802c035eb7d82ddea4f889f062e78c Mon Sep 17 00:00:00 2001 From: Rob Lourens Date: Thu, 16 Aug 2018 11:17:12 -0700 Subject: [PATCH 0904/1276] Fix #56538 - open json editor for "Edit in settings.json" command --- .../workbench/parts/preferences/browser/settingsEditor2.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/vs/workbench/parts/preferences/browser/settingsEditor2.ts b/src/vs/workbench/parts/preferences/browser/settingsEditor2.ts index cdc1939f1e7..ed4403427f7 100644 --- a/src/vs/workbench/parts/preferences/browser/settingsEditor2.ts +++ b/src/vs/workbench/parts/preferences/browser/settingsEditor2.ts @@ -300,11 +300,11 @@ export class SettingsEditor2 extends BaseEditor { const currentSettingsTarget = this.settingsTargetsWidget.settingsTarget; if (currentSettingsTarget === ConfigurationTarget.USER) { - return this.preferencesService.openGlobalSettings(); + return this.preferencesService.openGlobalSettings(true); } else if (currentSettingsTarget === ConfigurationTarget.WORKSPACE) { - return this.preferencesService.openWorkspaceSettings(); + return this.preferencesService.openWorkspaceSettings(true); } else { - return this.preferencesService.openFolderSettings(currentSettingsTarget); + return this.preferencesService.openFolderSettings(currentSettingsTarget, true); } } From 44a453a1967adadb1081d263619800c89af31fdf Mon Sep 17 00:00:00 2001 From: Rob Lourens Date: Thu, 16 Aug 2018 11:37:56 -0700 Subject: [PATCH 0905/1276] Fix #56539 - allow selecting text in setting name and description --- .../preferences/browser/media/settingsEditor2.css | 8 ++++++++ .../parts/preferences/browser/settingsTree.ts | 11 ++++------- 2 files changed, 12 insertions(+), 7 deletions(-) diff --git a/src/vs/workbench/parts/preferences/browser/media/settingsEditor2.css b/src/vs/workbench/parts/preferences/browser/media/settingsEditor2.css index f5df0d24495..084ed88990e 100644 --- a/src/vs/workbench/parts/preferences/browser/media/settingsEditor2.css +++ b/src/vs/workbench/parts/preferences/browser/media/settingsEditor2.css @@ -232,9 +232,15 @@ margin-right: 7px; } +.settings-editor > .settings-body > .settings-tree-container .setting-item .setting-item-cat-label-container { + float: left; +} + .settings-editor > .settings-body > .settings-tree-container .setting-item .setting-item-label, .settings-editor > .settings-body > .settings-tree-container .setting-item .setting-item-category { font-weight: 600; + user-select: text; + cursor: text; } .settings-editor > .settings-body > .settings-tree-container .setting-item .setting-item-category { @@ -244,6 +250,8 @@ .settings-editor > .settings-body > .settings-tree-container .setting-item .setting-item-deprecation-message, .settings-editor > .settings-body > .settings-tree-container .setting-item .setting-item-description { margin-top: 3px; + user-select: text; + cursor: text; } .settings-editor > .settings-body > .settings-tree-container .setting-item .setting-item-deprecation-message { diff --git a/src/vs/workbench/parts/preferences/browser/settingsTree.ts b/src/vs/workbench/parts/preferences/browser/settingsTree.ts index 3a3e92fbd2f..7505ddd24f0 100644 --- a/src/vs/workbench/parts/preferences/browser/settingsTree.ts +++ b/src/vs/workbench/parts/preferences/browser/settingsTree.ts @@ -468,8 +468,9 @@ export class SettingsRenderer implements ITreeRenderer { DOM.addClass(container, 'setting-item'); DOM.addClass(container, 'setting-item-' + typeClass); const titleElement = DOM.append(container, $('.setting-item-title')); - const categoryElement = DOM.append(titleElement, $('span.setting-item-category')); - const labelElement = DOM.append(titleElement, $('span.setting-item-label')); + const labelCategoryContainer = DOM.append(titleElement, $('.setting-item-cat-label-container')); + const categoryElement = DOM.append(labelCategoryContainer, $('span.setting-item-category')); + const labelElement = DOM.append(labelCategoryContainer, $('span.setting-item-label')); const isConfiguredElement = DOM.append(titleElement, $('span.setting-item-is-configured-label')); isConfiguredElement.textContent = localize('configured', "Modified"); const otherOverridesElement = DOM.append(titleElement, $('span.setting-item-overrides')); @@ -1138,11 +1139,7 @@ export class SettingsTreeController extends WorkbenchTreeController { return true; } - // Without this, clicking on the setting description causes the tree to lose focus. I don't know why. - // The superclass does not always call it because of DND which is not used here. - eventish.preventDefault(); - - return super.onLeftClick(tree, element, eventish, origin); + return false; } } From ff71abb2f453001dc61cf1a7242615c0c1972e02 Mon Sep 17 00:00:00 2001 From: Joao Moreno Date: Thu, 16 Aug 2018 22:52:25 +0200 Subject: [PATCH 0906/1276] fixes #56532 --- src/vs/workbench/parts/update/electron-browser/update.ts | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/vs/workbench/parts/update/electron-browser/update.ts b/src/vs/workbench/parts/update/electron-browser/update.ts index b966ed83ede..a7b6f45334a 100644 --- a/src/vs/workbench/parts/update/electron-browser/update.ts +++ b/src/vs/workbench/parts/update/electron-browser/update.ts @@ -249,6 +249,10 @@ export class WinUserSetupContribution implements IWorkbenchContribution { @IOpenerService private openerService: IOpenerService, @IUpdateService private updateService: IUpdateService ) { + if (!environmentService.isBuilt) { + return; + } + const neverShowAgain = new NeverShowAgain(WinUserSetupContribution.KEY_BOTH, this.storageService); if (!neverShowAgain.shouldShow()) { From 043e93f4225d0bace1984ac32b4609b73d5a09a2 Mon Sep 17 00:00:00 2001 From: Joao Moreno Date: Thu, 16 Aug 2018 23:11:50 +0200 Subject: [PATCH 0907/1276] fixes #56457 --- build/tfs/darwin/continuous-build-darwin.yml | 2 +- build/tfs/linux/continuous-build-linux.yml | 2 +- build/tfs/win32/continuous-build-win32.yml | 2 +- package.json | 5 ++--- 4 files changed, 5 insertions(+), 6 deletions(-) diff --git a/build/tfs/darwin/continuous-build-darwin.yml b/build/tfs/darwin/continuous-build-darwin.yml index 20070e08745..5fadd2b4d8d 100644 --- a/build/tfs/darwin/continuous-build-darwin.yml +++ b/build/tfs/darwin/continuous-build-darwin.yml @@ -15,7 +15,7 @@ steps: yarn gulp hygiene displayName: Run Hygiene Checks - script: | - yarn check-monaco-editor-compilation + yarn monaco-compile-check displayName: Run Monaco Editor Checks - script: | yarn compile diff --git a/build/tfs/linux/continuous-build-linux.yml b/build/tfs/linux/continuous-build-linux.yml index 7ec3aec74b9..abd9a9126dd 100644 --- a/build/tfs/linux/continuous-build-linux.yml +++ b/build/tfs/linux/continuous-build-linux.yml @@ -25,7 +25,7 @@ steps: yarn gulp hygiene displayName: Run Hygiene Checks - script: | - yarn check-monaco-editor-compilation + yarn monaco-compile-check displayName: Run Monaco Editor Checks - script: | yarn compile diff --git a/build/tfs/win32/continuous-build-win32.yml b/build/tfs/win32/continuous-build-win32.yml index 6490c637b78..a15484c7ce4 100644 --- a/build/tfs/win32/continuous-build-win32.yml +++ b/build/tfs/win32/continuous-build-win32.yml @@ -23,7 +23,7 @@ steps: - powershell: | . build/tfs/win32/exec.ps1 $ErrorActionPreference = "Stop" - exec { yarn check-monaco-editor-compilation } + exec { yarn monaco-compile-check } displayName: Run Monaco Editor Checks - powershell: | . build/tfs/win32/exec.ps1 diff --git a/package.json b/package.json index 9a367d0d70b..786f109e924 100644 --- a/package.json +++ b/package.json @@ -22,8 +22,7 @@ "update-localization-extension": "node build/npm/update-localization-extension.js", "smoketest": "cd test/smoke && node test/index.js", "monaco-compile-check": "tsc -p src/tsconfig.monaco.json --noEmit", - "download-builtin-extensions": "node build/lib/builtInExtensions.js", - "check-monaco-editor-compilation": "tsc -p src/tsconfig.monaco.json --noEmit" + "download-builtin-extensions": "node build/lib/builtInExtensions.js" }, "dependencies": { "applicationinsights": "0.18.0", @@ -138,4 +137,4 @@ "windows-mutex": "^0.2.0", "windows-process-tree": "0.2.2" } -} +} \ No newline at end of file From 35b0d44cd4355ecf9bc3a6c768b50ccf24739dc2 Mon Sep 17 00:00:00 2001 From: SteVen Batten <6561887+sbatten@users.noreply.github.com> Date: Thu, 16 Aug 2018 14:29:14 -0700 Subject: [PATCH 0908/1276] Menu extends ActionBar (#56509) * restructure the menu and actionbar ref #55258 * removing isMenu --- src/vs/base/browser/ui/actionbar/actionbar.ts | 57 ++---------- src/vs/base/browser/ui/menu/menu.ts | 90 +++++++++++-------- 2 files changed, 57 insertions(+), 90 deletions(-) diff --git a/src/vs/base/browser/ui/actionbar/actionbar.ts b/src/vs/base/browser/ui/actionbar/actionbar.ts index 6f480c13af0..0dc7a39304b 100644 --- a/src/vs/base/browser/ui/actionbar/actionbar.ts +++ b/src/vs/base/browser/ui/actionbar/actionbar.ts @@ -356,7 +356,6 @@ export interface IActionBarOptions { actionRunner?: IActionRunner; ariaLabel?: string; animated?: boolean; - isMenu?: boolean; } let defaultOptions: IActionBarOptions = { @@ -377,12 +376,12 @@ export class ActionBar implements IActionRunner { // Items public items: IActionItem[]; - private focusedItem: number; + protected focusedItem: number; private focusTracker: DOM.IFocusTracker; // Elements public domNode: HTMLElement; - private actionsList: HTMLElement; + protected actionsList: HTMLElement; private toDispose: lifecycle.IDisposable[]; @@ -490,48 +489,12 @@ export class ActionBar implements IActionRunner { this.actionsList = document.createElement('ul'); this.actionsList.className = 'actions-container'; - if (this.options.isMenu) { - this.actionsList.setAttribute('role', 'menu'); - } else { - this.actionsList.setAttribute('role', 'toolbar'); - } + this.actionsList.setAttribute('role', 'toolbar'); + if (this.options.ariaLabel) { this.actionsList.setAttribute('aria-label', this.options.ariaLabel); } - if (this.options.isMenu) { - this.domNode.tabIndex = 0; - - $(this.domNode).on(DOM.EventType.MOUSE_OUT, (e) => { - let relatedTarget = (e as MouseEvent).relatedTarget as HTMLElement; - if (!DOM.isAncestor(relatedTarget, this.domNode)) { - this.focusedItem = undefined; - this.updateFocus(); - e.stopPropagation(); - } - }); - - $(this.actionsList).on(DOM.EventType.MOUSE_OVER, (e) => { - let target = e.target as HTMLElement; - if (!target || !DOM.isAncestor(target, this.actionsList) || target === this.actionsList) { - return; - } - - while (target.parentElement !== this.actionsList) { - target = target.parentElement; - } - - if (DOM.hasClass(target, 'action-item')) { - const lastFocusedItem = this.focusedItem; - this.setFocusedItem(target); - - if (lastFocusedItem !== this.focusedItem) { - this.updateFocus(); - } - } - }); - } - this.domNode.appendChild(this.actionsList); container.appendChild(this.domNode); @@ -561,16 +524,6 @@ export class ActionBar implements IActionRunner { } } - private setFocusedItem(element: HTMLElement): void { - for (let i = 0; i < this.actionsList.children.length; i++) { - let elem = this.actionsList.children[i]; - if (element === elem) { - this.focusedItem = i; - break; - } - } - } - private updateFocusedItem(): void { for (let i = 0; i < this.actionsList.children.length; i++) { let elem = this.actionsList.children[i]; @@ -739,7 +692,7 @@ export class ActionBar implements IActionRunner { this.updateFocus(true); } - private updateFocus(fromRight?: boolean): void { + protected updateFocus(fromRight?: boolean): void { if (typeof this.focusedItem === 'undefined') { this.domNode.focus(); } diff --git a/src/vs/base/browser/ui/menu/menu.ts b/src/vs/base/browser/ui/menu/menu.ts index 4c94cfabb47..9f36741df63 100644 --- a/src/vs/base/browser/ui/menu/menu.ts +++ b/src/vs/base/browser/ui/menu/menu.ts @@ -7,12 +7,10 @@ import 'vs/css!./menu'; import * as nls from 'vs/nls'; -import { IDisposable } from 'vs/base/common/lifecycle'; import { IActionRunner, IAction, Action } from 'vs/base/common/actions'; import { ActionBar, IActionItemProvider, ActionsOrientation, Separator, ActionItem, IActionItemOptions, BaseActionItem } from 'vs/base/browser/ui/actionbar/actionbar'; import { ResolvedKeybinding, KeyCode } from 'vs/base/common/keyCodes'; -import { Event } from 'vs/base/common/event'; -import { addClass, EventType, EventHelper, EventLike, removeTabIndexAndUpdateFocus, isAncestor } from 'vs/base/browser/dom'; +import { addClass, EventType, EventHelper, EventLike, removeTabIndexAndUpdateFocus, isAncestor, hasClass } from 'vs/base/browser/dom'; import { StandardKeyboardEvent } from 'vs/base/browser/keyboardEvent'; import { $, Builder } from 'vs/base/browser/builder'; import { RunOnceScheduler } from 'vs/base/common/async'; @@ -37,34 +35,72 @@ interface ISubMenuData { submenu?: Menu; } -export class Menu { - - private actionBar: ActionBar; - private listener: IDisposable; +export class Menu extends ActionBar { constructor(container: HTMLElement, actions: IAction[], options: IMenuOptions = {}) { addClass(container, 'monaco-menu-container'); container.setAttribute('role', 'presentation'); - let menuContainer = document.createElement('div'); addClass(menuContainer, 'monaco-menu'); menuContainer.setAttribute('role', 'presentation'); container.appendChild(menuContainer); - let parentData: ISubMenuData = { - parent: this - }; - - this.actionBar = new ActionBar(menuContainer, { + super(menuContainer, { orientation: ActionsOrientation.VERTICAL, actionItemProvider: action => this.doGetActionItem(action, options, parentData), context: options.context, actionRunner: options.actionRunner, - isMenu: true, ariaLabel: options.ariaLabel }); - this.actionBar.push(actions, { icon: true, label: true, isMenu: true }); + this.actionsList.setAttribute('role', 'menu'); + + this.domNode.tabIndex = 0; + + $(this.domNode).on(EventType.MOUSE_OUT, (e) => { + let relatedTarget = (e as MouseEvent).relatedTarget as HTMLElement; + if (!isAncestor(relatedTarget, this.domNode)) { + this.focusedItem = undefined; + this.updateFocus(); + e.stopPropagation(); + } + }); + + $(this.actionsList).on(EventType.MOUSE_OVER, (e) => { + let target = e.target as HTMLElement; + if (!target || !isAncestor(target, this.actionsList) || target === this.actionsList) { + return; + } + + while (target.parentElement !== this.actionsList) { + target = target.parentElement; + } + + if (hasClass(target, 'action-item')) { + const lastFocusedItem = this.focusedItem; + this.setFocusedItem(target); + + if (lastFocusedItem !== this.focusedItem) { + this.updateFocus(); + } + } + }); + + let parentData: ISubMenuData = { + parent: this + }; + + this.push(actions, { icon: true, label: true, isMenu: true }); + } + + private setFocusedItem(element: HTMLElement): void { + for (let i = 0; i < this.actionsList.children.length; i++) { + let elem = this.actionsList.children[i]; + if (element === elem) { + this.focusedItem = i; + break; + } + } } private doGetActionItem(action: IAction, options: IMenuOptions, parentData: ISubMenuData): BaseActionItem { @@ -85,30 +121,8 @@ export class Menu { } } - public get onDidCancel(): Event { - return this.actionBar.onDidCancel; - } - - public get onDidBlur(): Event { - return this.actionBar.onDidBlur; - } - public focus(selectFirst = true) { - if (this.actionBar) { - this.actionBar.focus(selectFirst); - } - } - - public dispose() { - if (this.actionBar) { - this.actionBar.dispose(); - this.actionBar = null; - } - - if (this.listener) { - this.listener.dispose(); - this.listener = null; - } + super.focus(selectFirst); } } From 020c0d1d2dd77c7661a2f3d51eeadb26b942d167 Mon Sep 17 00:00:00 2001 From: Peng Lyu Date: Thu, 16 Aug 2018 15:20:18 -0700 Subject: [PATCH 0909/1276] Re microsoft/vscode-pull-request-github#227. Cmd enter to submit comment. --- .../parts/comments/electron-browser/commentThreadWidget.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vs/workbench/parts/comments/electron-browser/commentThreadWidget.ts b/src/vs/workbench/parts/comments/electron-browser/commentThreadWidget.ts index 03253893920..7b3b6262081 100644 --- a/src/vs/workbench/parts/comments/electron-browser/commentThreadWidget.ts +++ b/src/vs/workbench/parts/comments/electron-browser/commentThreadWidget.ts @@ -356,7 +356,7 @@ export class ReviewZoneWidget extends ZoneWidget { } } - if (this._commentEditor.getModel().getValueLength() !== 0 && ev.keyCode === KeyCode.Enter && ev.ctrlKey) { + if (this._commentEditor.getModel().getValueLength() !== 0 && ev.keyCode === KeyCode.Enter && (ev.ctrlKey || ev.metaKey)) { let lineNumber = this._commentGlyph.getPosition().position.lineNumber; this.createComment(lineNumber); } From 019cac9f75a44e385cfae068155f1b32aa238f98 Mon Sep 17 00:00:00 2001 From: Rob Lourens Date: Thu, 16 Aug 2018 17:09:06 -0700 Subject: [PATCH 0910/1276] Remove prefs editor TPromise#cancel - #56137 --- .../preferences/browser/preferencesEditor.ts | 56 ++++++++++--------- .../parts/preferences/common/preferences.ts | 3 +- .../electron-browser/preferencesSearch.ts | 16 +++++- 3 files changed, 46 insertions(+), 29 deletions(-) diff --git a/src/vs/workbench/parts/preferences/browser/preferencesEditor.ts b/src/vs/workbench/parts/preferences/browser/preferencesEditor.ts index a05b30b32be..5d9feab4b09 100644 --- a/src/vs/workbench/parts/preferences/browser/preferencesEditor.ts +++ b/src/vs/workbench/parts/preferences/browser/preferencesEditor.ts @@ -8,7 +8,7 @@ import { Button } from 'vs/base/browser/ui/button/button'; import { Widget } from 'vs/base/browser/ui/widget'; import * as arrays from 'vs/base/common/arrays'; import { Delayer, ThrottledDelayer } from 'vs/base/common/async'; -import { CancellationToken } from 'vs/base/common/cancellation'; +import { CancellationToken, CancellationTokenSource } from 'vs/base/common/cancellation'; import { IStringDictionary } from 'vs/base/common/collections'; import { getErrorMessage, isPromiseCanceledError, onUnexpectedError } from 'vs/base/common/errors'; import { Emitter, Event } from 'vs/base/common/event'; @@ -372,7 +372,7 @@ class PreferencesRenderersController extends Disposable { private _editablePreferencesRendererDisposables: IDisposable[] = []; private _settingsNavigator: SettingsNavigator; - private _remoteFilterInProgress: TPromise; + private _remoteFilterCancelToken: CancellationTokenSource; private _prefsModelsForSearch = new Map(); private _currentLocalSearchProvider: ISearchProvider; @@ -453,17 +453,20 @@ class PreferencesRenderersController extends Disposable { query = ''; } - if (this._remoteFilterInProgress && this._remoteFilterInProgress.cancel) { - // Resolved/rejected promises have no .cancel() - this._remoteFilterInProgress.cancel(); + if (this._remoteFilterCancelToken) { + this._remoteFilterCancelToken.cancel(); + this._remoteFilterCancelToken.dispose(); + this._remoteFilterCancelToken = null; } this._currentRemoteSearchProvider = (updateCurrentResults && this._currentRemoteSearchProvider) || this.preferencesSearchService.getRemoteSearchProvider(query); - this._remoteFilterInProgress = this.filterOrSearchPreferences(query, this._currentRemoteSearchProvider, 'nlpResult', nls.localize('nlpResult', "Natural Language Results"), 1, updateCurrentResults); - - return this._remoteFilterInProgress.then(() => { - this._remoteFilterInProgress = null; + this._remoteFilterCancelToken = new CancellationTokenSource(); + return this.filterOrSearchPreferences(query, this._currentRemoteSearchProvider, 'nlpResult', nls.localize('nlpResult', "Natural Language Results"), 1, this._remoteFilterCancelToken.token, updateCurrentResults).then(() => { + if (this._remoteFilterCancelToken) { + this._remoteFilterCancelToken.dispose(); + this._remoteFilterCancelToken = null; + } }, err => { if (isPromiseCanceledError(err)) { return null; @@ -479,18 +482,18 @@ class PreferencesRenderersController extends Disposable { } this._currentLocalSearchProvider = (updateCurrentResults && this._currentLocalSearchProvider) || this.preferencesSearchService.getLocalSearchProvider(query); - return this.filterOrSearchPreferences(query, this._currentLocalSearchProvider, 'filterResult', nls.localize('filterResult', "Filtered Results"), 0, updateCurrentResults); + return this.filterOrSearchPreferences(query, this._currentLocalSearchProvider, 'filterResult', nls.localize('filterResult', "Filtered Results"), 0, undefined, updateCurrentResults); } - private filterOrSearchPreferences(query: string, searchProvider: ISearchProvider, groupId: string, groupLabel: string, groupOrder: number, editableContentOnly?: boolean): TPromise { + private filterOrSearchPreferences(query: string, searchProvider: ISearchProvider, groupId: string, groupLabel: string, groupOrder: number, token?: CancellationToken, editableContentOnly?: boolean): TPromise { this._lastQuery = query; - const filterPs: TPromise[] = [this._filterOrSearchPreferences(query, this.editablePreferencesRenderer, searchProvider, groupId, groupLabel, groupOrder)]; + const filterPs: TPromise[] = [this._filterOrSearchPreferences(query, this.editablePreferencesRenderer, searchProvider, groupId, groupLabel, groupOrder, token)]; if (!editableContentOnly) { filterPs.push( - this._filterOrSearchPreferences(query, this.defaultPreferencesRenderer, searchProvider, groupId, groupLabel, groupOrder)); + this._filterOrSearchPreferences(query, this.defaultPreferencesRenderer, searchProvider, groupId, groupLabel, groupOrder, token)); filterPs.push( - this.searchAllSettingsTargets(query, searchProvider, groupId, groupLabel, groupOrder).then(() => null)); + this.searchAllSettingsTargets(query, searchProvider, groupId, groupLabel, groupOrder, token).then(() => null)); } return TPromise.join(filterPs).then(results => { @@ -507,22 +510,22 @@ class PreferencesRenderersController extends Disposable { }); } - private searchAllSettingsTargets(query: string, searchProvider: ISearchProvider, groupId: string, groupLabel: string, groupOrder: number): TPromise { + private searchAllSettingsTargets(query: string, searchProvider: ISearchProvider, groupId: string, groupLabel: string, groupOrder: number, token?: CancellationToken): TPromise { const searchPs = [ - this.searchSettingsTarget(query, searchProvider, ConfigurationTarget.WORKSPACE, groupId, groupLabel, groupOrder), - this.searchSettingsTarget(query, searchProvider, ConfigurationTarget.USER, groupId, groupLabel, groupOrder) + this.searchSettingsTarget(query, searchProvider, ConfigurationTarget.WORKSPACE, groupId, groupLabel, groupOrder, token), + this.searchSettingsTarget(query, searchProvider, ConfigurationTarget.USER, groupId, groupLabel, groupOrder, token) ]; for (const folder of this.workspaceContextService.getWorkspace().folders) { const folderSettingsResource = this.preferencesService.getFolderSettingsResource(folder.uri); - searchPs.push(this.searchSettingsTarget(query, searchProvider, folderSettingsResource, groupId, groupLabel, groupOrder)); + searchPs.push(this.searchSettingsTarget(query, searchProvider, folderSettingsResource, groupId, groupLabel, groupOrder, token)); } return TPromise.join(searchPs).then(() => { }); } - private searchSettingsTarget(query: string, provider: ISearchProvider, target: SettingsTarget, groupId: string, groupLabel: string, groupOrder: number): Promise { + private searchSettingsTarget(query: string, provider: ISearchProvider, target: SettingsTarget, groupId: string, groupLabel: string, groupOrder: number, token?: CancellationToken): Promise { if (!query) { // Don't open the other settings targets when query is empty this._onDidFilterResultsCountChange.fire({ target, count: 0 }); @@ -530,7 +533,7 @@ class PreferencesRenderersController extends Disposable { } return this.getPreferencesEditorModel(target).then(model => { - return model && this._filterOrSearchPreferencesModel('', model, provider, groupId, groupLabel, groupOrder); + return model && this._filterOrSearchPreferencesModel('', model, provider, groupId, groupLabel, groupOrder, token); }).then(result => { const count = result ? this._flatten(result.filteredGroups).length : 0; this._onDidFilterResultsCountChange.fire({ target, count }); @@ -588,20 +591,20 @@ class PreferencesRenderersController extends Disposable { } } - private _filterOrSearchPreferences(filter: string, preferencesRenderer: IPreferencesRenderer, provider: ISearchProvider, groupId: string, groupLabel: string, groupOrder: number): TPromise { + private _filterOrSearchPreferences(filter: string, preferencesRenderer: IPreferencesRenderer, provider: ISearchProvider, groupId: string, groupLabel: string, groupOrder: number, token?: CancellationToken): TPromise { if (!preferencesRenderer) { return TPromise.wrap(null); } const model = preferencesRenderer.preferencesModel; - return this._filterOrSearchPreferencesModel(filter, model, provider, groupId, groupLabel, groupOrder).then(filterResult => { + return this._filterOrSearchPreferencesModel(filter, model, provider, groupId, groupLabel, groupOrder, token).then(filterResult => { preferencesRenderer.filterPreferences(filterResult); return filterResult; }); } - private _filterOrSearchPreferencesModel(filter: string, model: ISettingsEditorModel, provider: ISearchProvider, groupId: string, groupLabel: string, groupOrder: number): TPromise { - const searchP = provider ? provider.searchModel(model) : TPromise.wrap(null); + private _filterOrSearchPreferencesModel(filter: string, model: ISettingsEditorModel, provider: ISearchProvider, groupId: string, groupLabel: string, groupOrder: number, token?: CancellationToken): TPromise { + const searchP = provider ? provider.searchModel(model, token) : TPromise.wrap(null); return searchP .then(null, err => { if (isPromiseCanceledError(err)) { @@ -623,6 +626,10 @@ class PreferencesRenderersController extends Disposable { } }) .then(searchResult => { + if (token && token.isCancellationRequested) { + searchResult = null; + } + const filterResult = searchResult ? model.updateResultGroup(groupId, { id: groupId, @@ -637,7 +644,6 @@ class PreferencesRenderersController extends Disposable { filterResult.exactMatch = searchResult && searchResult.exactMatch; } - return filterResult; }); } diff --git a/src/vs/workbench/parts/preferences/common/preferences.ts b/src/vs/workbench/parts/preferences/common/preferences.ts index f77fc18a455..d74acccec86 100644 --- a/src/vs/workbench/parts/preferences/common/preferences.ts +++ b/src/vs/workbench/parts/preferences/common/preferences.ts @@ -10,6 +10,7 @@ import { join } from 'vs/base/common/paths'; import { ISettingsEditorModel, ISearchResult } from 'vs/workbench/services/preferences/common/preferences'; import { IEditor } from 'vs/workbench/common/editor'; import { IKeybindingItemEntry } from 'vs/workbench/services/preferences/common/keybindingsEditorModel'; +import { CancellationToken } from 'vs/base/common/cancellation'; export interface IWorkbenchSettingsConfiguration { workbench: { @@ -40,7 +41,7 @@ export interface IPreferencesSearchService { } export interface ISearchProvider { - searchModel(preferencesModel: ISettingsEditorModel): TPromise; + searchModel(preferencesModel: ISettingsEditorModel, token?: CancellationToken): TPromise; } export interface IKeybindingsEditor extends IEditor { diff --git a/src/vs/workbench/parts/preferences/electron-browser/preferencesSearch.ts b/src/vs/workbench/parts/preferences/electron-browser/preferencesSearch.ts index 1fffc1a2884..5d619408ed9 100644 --- a/src/vs/workbench/parts/preferences/electron-browser/preferencesSearch.ts +++ b/src/vs/workbench/parts/preferences/electron-browser/preferencesSearch.ts @@ -21,6 +21,8 @@ import { Disposable } from 'vs/base/common/lifecycle'; import { IExtensionManagementService, LocalExtensionType, ILocalExtension, IExtensionEnablementService } from 'vs/platform/extensionManagement/common/extensionManagement'; import { ILogService } from 'vs/platform/log/common/log'; import { IPreferencesSearchService, ISearchProvider, IWorkbenchSettingsConfiguration } from 'vs/workbench/parts/preferences/common/preferences'; +import { CancellationToken } from 'vs/base/common/cancellation'; +import { canceled } from 'vs/base/common/errors'; export interface IEndpointDetails { urlBase: string; @@ -102,7 +104,7 @@ export class LocalSearchProvider implements ISearchProvider { .trim(); } - searchModel(preferencesModel: ISettingsEditorModel): TPromise { + searchModel(preferencesModel: ISettingsEditorModel, token?: CancellationToken): TPromise { if (!this._filter) { return TPromise.wrap(null); } @@ -173,12 +175,20 @@ class RemoteSearchProvider implements ISearchProvider { TPromise.wrap(null); } - searchModel(preferencesModel: ISettingsEditorModel): TPromise { - return this._remoteSearchP.then(remoteResult => { + searchModel(preferencesModel: ISettingsEditorModel, token?: CancellationToken): TPromise { + return this._remoteSearchP.then(result => { + return new Promise(r => { + setTimeout(() => r(result), 2000); + }); + }).then(remoteResult => { if (!remoteResult) { return null; } + if (token && token.isCancellationRequested) { + throw canceled(); + } + const resultKeys = Object.keys(remoteResult.scoredResults); const highScoreKey = top(resultKeys, (a, b) => remoteResult.scoredResults[b].score - remoteResult.scoredResults[a].score, 1)[0]; const highScore = highScoreKey ? remoteResult.scoredResults[highScoreKey].score : 0; From 55a85328c9dbef788974fcaac3ac0ec83cf64819 Mon Sep 17 00:00:00 2001 From: Rob Lourens Date: Thu, 16 Aug 2018 17:20:57 -0700 Subject: [PATCH 0911/1276] #56137 - remove TPromise#cancel from settings editor --- .../preferences/browser/settingsEditor2.ts | 75 ++++++++++--------- .../electron-browser/preferencesSearch.ts | 6 +- 2 files changed, 39 insertions(+), 42 deletions(-) diff --git a/src/vs/workbench/parts/preferences/browser/settingsEditor2.ts b/src/vs/workbench/parts/preferences/browser/settingsEditor2.ts index ed4403427f7..0f6fcf707d4 100644 --- a/src/vs/workbench/parts/preferences/browser/settingsEditor2.ts +++ b/src/vs/workbench/parts/preferences/browser/settingsEditor2.ts @@ -10,7 +10,7 @@ import { ToolBar } from 'vs/base/browser/ui/toolbar/toolbar'; import { Action } from 'vs/base/common/actions'; import * as arrays from 'vs/base/common/arrays'; import { Delayer, ThrottledDelayer } from 'vs/base/common/async'; -import { CancellationToken } from 'vs/base/common/cancellation'; +import { CancellationToken, CancellationTokenSource } from 'vs/base/common/cancellation'; import * as collections from 'vs/base/common/collections'; import { getErrorMessage, isPromiseCanceledError } from 'vs/base/common/errors'; import URI from 'vs/base/common/uri'; @@ -76,7 +76,7 @@ export class SettingsEditor2 extends BaseEditor { private delayedFilterLogging: Delayer; private localSearchDelayer: Delayer; private remoteSearchThrottle: ThrottledDelayer; - private searchInProgress: TPromise; + private searchCancelToken: CancellationTokenSource; private delayRefreshOnLayout: Delayer; private lastLayedoutWidth: number; @@ -749,11 +749,15 @@ export class SettingsEditor2 extends BaseEditor { query = query.trim(); if (query && query !== '@') { - return this.searchInProgress = TPromise.join([ - this.localSearchDelayer.trigger(() => this.localFilterPreferences(query)), - this.remoteSearchThrottle.trigger(() => this.remoteSearchPreferences(query), 500) + this.searchCancelToken = new CancellationTokenSource(); + return TPromise.join([ + this.localSearchDelayer.trigger(() => this.localFilterPreferences(query, this.searchCancelToken.token)), + this.remoteSearchThrottle.trigger(() => this.remoteSearchPreferences(query, this.searchCancelToken.token), 500) ]).then(() => { - this.searchInProgress = null; + if (this.searchCancelToken) { + this.searchCancelToken.dispose(); + this.searchCancelToken = null; + } }); } else { if (this.viewState.tagFilters && this.viewState.tagFilters.size) { @@ -764,8 +768,10 @@ export class SettingsEditor2 extends BaseEditor { this.localSearchDelayer.cancel(); this.remoteSearchThrottle.cancel(); - if (this.searchInProgress && this.searchInProgress.cancel) { - this.searchInProgress.cancel(); + if (this.searchCancelToken) { + this.searchCancelToken.cancel(); + this.searchCancelToken.dispose(); + this.searchCancelToken = null; } this.viewState.filterToCategory = null; @@ -843,47 +849,42 @@ export class SettingsEditor2 extends BaseEditor { this.telemetryService.publicLog('settingsEditor.filter', data); } - private localFilterPreferences(query: string): TPromise { + private localFilterPreferences(query: string, token?: CancellationToken): TPromise { const localSearchProvider = this.preferencesSearchService.getLocalSearchProvider(query); - return this.filterOrSearchPreferences(query, SearchResultIdx.Local, localSearchProvider); + return this.filterOrSearchPreferences(query, SearchResultIdx.Local, localSearchProvider, token); } - private remoteSearchPreferences(query: string): TPromise { + private remoteSearchPreferences(query: string, token?: CancellationToken): TPromise { const remoteSearchProvider = this.preferencesSearchService.getRemoteSearchProvider(query); - return this.filterOrSearchPreferences(query, SearchResultIdx.Remote, remoteSearchProvider); + return this.filterOrSearchPreferences(query, SearchResultIdx.Remote, remoteSearchProvider, token); } - private filterOrSearchPreferences(query: string, type: SearchResultIdx, searchProvider: ISearchProvider): TPromise { - let isCanceled = false; - return new TPromise(resolve => { - return this._filterOrSearchPreferencesModel(query, this.defaultSettingsEditorModel, searchProvider).then(result => { - if (isCanceled) { - // Handle cancellation like this because cancellation is lost inside the search provider due to async/await - return null; - } + private filterOrSearchPreferences(query: string, type: SearchResultIdx, searchProvider: ISearchProvider, token?: CancellationToken): TPromise { + return this._filterOrSearchPreferencesModel(query, this.defaultSettingsEditorModel, searchProvider, token).then(result => { + if (token && token.isCancellationRequested) { + // Handle cancellation like this because cancellation is lost inside the search provider due to async/await + return null; + } - if (!this.searchResultModel) { - this.searchResultModel = this.instantiationService.createInstance(SearchResultModel, this.viewState); - this.searchResultModel.setResult(type, result); - this.tocTreeModel.currentSearchModel = this.searchResultModel; - this.toggleSearchMode(); - this.settingsTree.setInput(this.searchResultModel.root); - } else { - this.searchResultModel.setResult(type, result); - } + if (!this.searchResultModel) { + this.searchResultModel = this.instantiationService.createInstance(SearchResultModel, this.viewState); + this.searchResultModel.setResult(type, result); + this.tocTreeModel.currentSearchModel = this.searchResultModel; + this.toggleSearchMode(); + this.settingsTree.setInput(this.searchResultModel.root); + } else { + this.searchResultModel.setResult(type, result); + } - this.tocTreeModel.update(); - expandAll(this.tocTree); + this.tocTreeModel.update(); + expandAll(this.tocTree); - resolve(this.renderTree()); - }); - }, () => { - isCanceled = true; + return this.renderTree(); }); } - private _filterOrSearchPreferencesModel(filter: string, model: ISettingsEditorModel, provider: ISearchProvider): TPromise { - const searchP = provider ? provider.searchModel(model) : TPromise.wrap(null); + private _filterOrSearchPreferencesModel(filter: string, model: ISettingsEditorModel, provider: ISearchProvider, token?: CancellationToken): TPromise { + const searchP = provider ? provider.searchModel(model, token) : TPromise.wrap(null); return searchP .then(null, err => { if (isPromiseCanceledError(err)) { diff --git a/src/vs/workbench/parts/preferences/electron-browser/preferencesSearch.ts b/src/vs/workbench/parts/preferences/electron-browser/preferencesSearch.ts index 5d619408ed9..ba12960ff57 100644 --- a/src/vs/workbench/parts/preferences/electron-browser/preferencesSearch.ts +++ b/src/vs/workbench/parts/preferences/electron-browser/preferencesSearch.ts @@ -176,11 +176,7 @@ class RemoteSearchProvider implements ISearchProvider { } searchModel(preferencesModel: ISettingsEditorModel, token?: CancellationToken): TPromise { - return this._remoteSearchP.then(result => { - return new Promise(r => { - setTimeout(() => r(result), 2000); - }); - }).then(remoteResult => { + return this._remoteSearchP.then(remoteResult => { if (!remoteResult) { return null; } From 5cf8f61b51d56028f9f14e0beb7bc0036d251b5c Mon Sep 17 00:00:00 2001 From: Rob Lourens Date: Thu, 16 Aug 2018 17:56:33 -0700 Subject: [PATCH 0912/1276] Fix #56612 - use blue indicator bar instead of 'Modified' text --- .../browser/media/settingsEditor2.css | 17 ++++++++++------- .../parts/preferences/browser/settingsTree.ts | 19 ++++++++----------- .../preferences/browser/settingsWidgets.ts | 17 +++++++++++------ 3 files changed, 29 insertions(+), 24 deletions(-) diff --git a/src/vs/workbench/parts/preferences/browser/media/settingsEditor2.css b/src/vs/workbench/parts/preferences/browser/media/settingsEditor2.css index 084ed88990e..abd326ee581 100644 --- a/src/vs/workbench/parts/preferences/browser/media/settingsEditor2.css +++ b/src/vs/workbench/parts/preferences/browser/media/settingsEditor2.css @@ -212,15 +212,18 @@ text-overflow: ellipsis; } -.settings-editor > .settings-body > .settings-tree-container .setting-item .setting-item-title .setting-item-is-configured-label { - font-style: italic; - opacity: 0.8; - margin-right: 7px; - display: none; +.settings-editor > .settings-body > .settings-tree-container .setting-item.is-configured::after { + display: block; + content: ' '; + position: absolute; + width: 2px; + left: 0px; + top: 15px; + bottom: 16px; } -.settings-editor > .settings-body > .settings-tree-container .setting-item.is-configured .setting-item-title .setting-item-is-configured-label { - display: inline-block; +.settings-editor > .settings-body > .settings-tree-container .setting-item-bool.setting-item.is-configured::after { + bottom: 23px; } .settings-editor > .settings-body > .settings-tree-container .setting-item .setting-item-title .setting-item-overrides { diff --git a/src/vs/workbench/parts/preferences/browser/settingsTree.ts b/src/vs/workbench/parts/preferences/browser/settingsTree.ts index 7505ddd24f0..480a73351c9 100644 --- a/src/vs/workbench/parts/preferences/browser/settingsTree.ts +++ b/src/vs/workbench/parts/preferences/browser/settingsTree.ts @@ -201,7 +201,6 @@ interface ISettingItemTemplate extends IDisposableTemplate { descriptionElement: HTMLElement; controlElement: HTMLElement; deprecationWarningElement: HTMLElement; - isConfiguredElement: HTMLElement; otherOverridesElement: HTMLElement; } @@ -471,8 +470,6 @@ export class SettingsRenderer implements ITreeRenderer { const labelCategoryContainer = DOM.append(titleElement, $('.setting-item-cat-label-container')); const categoryElement = DOM.append(labelCategoryContainer, $('span.setting-item-category')); const labelElement = DOM.append(labelCategoryContainer, $('span.setting-item-label')); - const isConfiguredElement = DOM.append(titleElement, $('span.setting-item-is-configured-label')); - isConfiguredElement.textContent = localize('configured', "Modified"); const otherOverridesElement = DOM.append(titleElement, $('span.setting-item-overrides')); const descriptionElement = DOM.append(container, $('.setting-item-description')); @@ -491,7 +488,6 @@ export class SettingsRenderer implements ITreeRenderer { descriptionElement, controlElement, deprecationWarningElement, - isConfiguredElement, otherOverridesElement }; @@ -585,8 +581,6 @@ export class SettingsRenderer implements ITreeRenderer { const titleElement = DOM.append(container, $('.setting-item-title')); const categoryElement = DOM.append(titleElement, $('span.setting-item-category')); const labelElement = DOM.append(titleElement, $('span.setting-item-label')); - const isConfiguredElement = DOM.append(titleElement, $('span.setting-item-is-configured-label')); - isConfiguredElement.textContent = localize('configured', "Modified"); const otherOverridesElement = DOM.append(titleElement, $('span.setting-item-overrides')); const descriptionAndValueElement = DOM.append(container, $('.setting-item-value-description')); @@ -616,7 +610,6 @@ export class SettingsRenderer implements ITreeRenderer { checkbox, descriptionElement, deprecationWarningElement, - isConfiguredElement, otherOverridesElement }; @@ -900,7 +893,8 @@ export class SettingsRenderer implements ITreeRenderer { // Setup and add ARIA attributes // Create id and label for control/input element - parent is wrapper div const id = (dataElement.displayCategory + '_' + dataElement.displayLabel).replace(/ /g, '_'); - const label = ' ' + dataElement.displayCategory + ' ' + dataElement.displayLabel + ' checkbox ' + (dataElement.value ? 'checked ' : 'unchecked ') + template.isConfiguredElement.textContent; + const modifiedText = dataElement.isConfigured ? 'Modified' : ''; + const label = ' ' + dataElement.displayCategory + ' ' + dataElement.displayLabel + ' checkbox ' + (dataElement.value ? 'checked ' : 'unchecked ') + modifiedText; // We use the parent control div for the aria-labelledby target // Does not appear you can use the direct label on the element itself within a tree @@ -920,7 +914,8 @@ export class SettingsRenderer implements ITreeRenderer { const displayOptions = getDisplayEnumOptions(dataElement.setting); template.selectBox.setOptions(displayOptions); - const label = ' ' + dataElement.displayCategory + ' ' + dataElement.displayLabel + ' combobox ' + template.isConfiguredElement.textContent; + const modifiedText = dataElement.isConfigured ? 'Modified' : ''; + const label = ' ' + dataElement.displayCategory + ' ' + dataElement.displayLabel + ' combobox ' + modifiedText; template.selectBox.setAriaLabel(label); @@ -956,7 +951,8 @@ export class SettingsRenderer implements ITreeRenderer { } private renderText(dataElement: SettingsTreeSettingElement, template: ISettingTextItemTemplate, onChange: (value: string) => void): void { - const label = ' ' + dataElement.displayCategory + ' ' + dataElement.displayLabel + ' ' + template.isConfiguredElement.textContent; + const modifiedText = dataElement.isConfigured ? 'Modified' : ''; + const label = ' ' + dataElement.displayCategory + ' ' + dataElement.displayLabel + ' ' + modifiedText; template.onChange = null; template.inputBox.value = dataElement.value; template.onChange = value => { renderValidations(dataElement, template, false, label); onChange(value); }; @@ -982,7 +978,8 @@ export class SettingsRenderer implements ITreeRenderer { private renderNumber(dataElement: SettingsTreeSettingElement, template: ISettingTextItemTemplate, onChange: (value: number) => void): void { - const label = ' ' + dataElement.displayCategory + ' ' + dataElement.displayLabel + ' number ' + template.isConfiguredElement.textContent; + const modifiedText = dataElement.isConfigured ? 'Modified' : ''; + const label = ' ' + dataElement.displayCategory + ' ' + dataElement.displayLabel + ' number ' + modifiedText; const numParseFn = (dataElement.valueType === 'integer' || dataElement.valueType === 'nullable-integer') ? parseInt : parseFloat; diff --git a/src/vs/workbench/parts/preferences/browser/settingsWidgets.ts b/src/vs/workbench/parts/preferences/browser/settingsWidgets.ts index 862ec4dde3b..2209276a406 100644 --- a/src/vs/workbench/parts/preferences/browser/settingsWidgets.ts +++ b/src/vs/workbench/parts/preferences/browser/settingsWidgets.ts @@ -9,6 +9,7 @@ import { ActionBar } from 'vs/base/browser/ui/actionbar/actionbar'; import { Button } from 'vs/base/browser/ui/button/button'; import { InputBox } from 'vs/base/browser/ui/inputbox/inputBox'; import { IAction } from 'vs/base/common/actions'; +import { Color, RGBA } from 'vs/base/common/color'; import { Emitter, Event } from 'vs/base/common/event'; import { KeyCode } from 'vs/base/common/keyCodes'; import { Disposable, dispose, IDisposable } from 'vs/base/common/lifecycle'; @@ -21,7 +22,11 @@ import { ICssStyleCollector, ITheme, IThemeService, registerThemingParticipant } const $ = DOM.$; export const settingsHeaderForeground = registerColor('settings.headerForeground', { light: '#444444', dark: '#e7e7e7', hc: '#ffffff' }, localize('headerForeground', "(For settings editor preview) The foreground color for a section header or active title.")); -export const modifiedItemForeground = registerColor('settings.modifiedItemForeground', { light: '#018101', dark: '#73C991', hc: '#73C991' }, localize('modifiedItemForeground', "(For settings editor preview) The foreground color for a the modified setting indicator.")); +export const modifiedItemIndicator = registerColor('settings.modifiedItemIndicator', { + light: new Color(new RGBA(102, 175, 224)), + dark: new Color(new RGBA(12, 125, 157)), + hc: new Color(new RGBA(0, 73, 122)) +}, localize('modifiedItemForeground', "(For settings editor preview) The color of the modified setting indicator.")); // Enum control colors export const settingsSelectBackground = registerColor('settings.dropdownBackground', { dark: selectBackground, light: selectBackground, hc: selectBackground }, localize('settingsDropdownBackground', "(For settings editor preview) Settings editor dropdown background.")); @@ -44,11 +49,6 @@ export const settingsNumberInputForeground = registerColor('settings.numberInput export const settingsNumberInputBorder = registerColor('settings.numberInputBorder', { dark: inputBorder, light: inputBorder, hc: inputBorder }, localize('numberInputBoxBorder', "(For settings editor preview) Settings editor number input box border.")); registerThemingParticipant((theme: ITheme, collector: ICssStyleCollector) => { - const modifiedItemForegroundColor = theme.getColor(modifiedItemForeground); - if (modifiedItemForegroundColor) { - collector.addRule(`.settings-editor > .settings-body > .settings-tree-container .setting-item.is-configured .setting-item-is-configured-label { color: ${modifiedItemForegroundColor}; }`); - } - const checkboxBackgroundColor = theme.getColor(settingsCheckboxBackground); if (checkboxBackgroundColor) { collector.addRule(`.settings-editor > .settings-body > .settings-tree-container .setting-item-bool .setting-value-checkbox { background-color: ${checkboxBackgroundColor} !important; }`); @@ -110,6 +110,11 @@ registerThemingParticipant((theme: ITheme, collector: ICssStyleCollector) => { if (codeTextForegroundColor) { collector.addRule(`.settings-editor > .settings-body > .settings-tree-container .setting-item .setting-item-description-markdown code { color: ${codeTextForegroundColor} }`); } + + const modifiedItemIndicatorColor = theme.getColor(modifiedItemIndicator); + if (modifiedItemIndicatorColor) { + collector.addRule(`.settings-editor > .settings-body > .settings-tree-container .setting-item.is-configured::after { background-color: ${modifiedItemIndicatorColor}; }`); + } }); export class ExcludeSettingListModel { From d2148923f578ed65cec6c8a10f396933b3d1d054 Mon Sep 17 00:00:00 2001 From: Rob Lourens Date: Thu, 16 Aug 2018 18:09:53 -0700 Subject: [PATCH 0913/1276] Revert "Fix #56415 - 'new' tag for settings" --- src/vs/editor/common/config/commonEditorConfig.ts | 6 ++---- src/vs/workbench/electron-browser/main.contribution.ts | 3 +-- .../workbench/parts/preferences/browser/settingsEditor2.ts | 6 +----- 3 files changed, 4 insertions(+), 11 deletions(-) diff --git a/src/vs/editor/common/config/commonEditorConfig.ts b/src/vs/editor/common/config/commonEditorConfig.ts index 35389354cef..07380bbb371 100644 --- a/src/vs/editor/common/config/commonEditorConfig.ts +++ b/src/vs/editor/common/config/commonEditorConfig.ts @@ -492,14 +492,12 @@ const editorConfiguration: IConfigurationNode = { 'editor.parameterHints.enabled': { 'type': 'boolean', 'default': EDITOR_DEFAULTS.contribInfo.parameterHints.enabled, - 'description': nls.localize('parameterHints.enabled', "Enables a pop-up that shows parameter documentation and type information as you type."), - 'tags': ['new'] + 'description': nls.localize('parameterHints.enabled', "Enables a pop-up that shows parameter documentation and type information as you type.") }, 'editor.parameterHints.cycle': { 'type': 'boolean', 'default': EDITOR_DEFAULTS.contribInfo.parameterHints.cycle, - 'description': nls.localize('parameterHints.cycle', "Controls whether the parameter hints menu cycles or closes when reaching the end of the list."), - 'tags': ['new'] + 'description': nls.localize('parameterHints.cycle', "Controls whether the parameter hints menu cycles or closes when reaching the end of the list.") }, 'editor.autoClosingBrackets': { 'type': 'boolean', diff --git a/src/vs/workbench/electron-browser/main.contribution.ts b/src/vs/workbench/electron-browser/main.contribution.ts index d1d7e6d8dbe..150d1754371 100644 --- a/src/vs/workbench/electron-browser/main.contribution.ts +++ b/src/vs/workbench/electron-browser/main.contribution.ts @@ -653,8 +653,7 @@ configurationRegistry.registerConfiguration({ ], 'description': nls.localize('settings.editor.desc', "Determines which settings editor to use by default."), 'default': 'ui', - 'scope': ConfigurationScope.WINDOW, - 'tags': ['new'] + 'scope': ConfigurationScope.WINDOW }, 'workbench.enableExperiments': { 'type': 'boolean', diff --git a/src/vs/workbench/parts/preferences/browser/settingsEditor2.ts b/src/vs/workbench/parts/preferences/browser/settingsEditor2.ts index 0f6fcf707d4..ea84a34cbad 100644 --- a/src/vs/workbench/parts/preferences/browser/settingsEditor2.ts +++ b/src/vs/workbench/parts/preferences/browser/settingsEditor2.ts @@ -53,7 +53,7 @@ export class SettingsEditor2 extends BaseEditor { private static NUM_INSTANCES: number = 0; private static readonly SUGGESTIONS: string[] = [ - '@modified', '@tag:usesOnlineServices', '@tag:new' + '@modified', '@tag:usesOnlineServices' ]; private defaultSettingsEditorModel: DefaultSettingsEditorModel; @@ -256,10 +256,6 @@ export class SettingsEditor2 extends BaseEditor { this.instantiationService.createInstance(FilterByTagAction, localize('filterModifiedLabel', "Show modified settings"), MODIFIED_SETTING_TAG, - this), - this.instantiationService.createInstance(FilterByTagAction, - localize('filterNewLabel', "Show new settings"), - 'new', this) ]; if (this.environmentService.appQuality !== 'stable') { From 3c052265d939d118f080708656c911dc01f6b308 Mon Sep 17 00:00:00 2001 From: Rob Lourens Date: Thu, 16 Aug 2018 19:08:09 -0700 Subject: [PATCH 0914/1276] Fix #56618 - add missing border to settings search box in light themes --- .../parts/preferences/browser/media/settingsEditor2.css | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/vs/workbench/parts/preferences/browser/media/settingsEditor2.css b/src/vs/workbench/parts/preferences/browser/media/settingsEditor2.css index abd326ee581..4110f029469 100644 --- a/src/vs/workbench/parts/preferences/browser/media/settingsEditor2.css +++ b/src/vs/workbench/parts/preferences/browser/media/settingsEditor2.css @@ -39,6 +39,10 @@ margin-right: 7px; } +.vs .settings-editor > .settings-header > .search-container > .suggest-input-container { + border: 1px solid #ddd; +} + .settings-editor > .settings-header > .settings-header-controls { height: 32px; display: flex; From 095758e055546648f1e95b9e1db0408d0e1c396b Mon Sep 17 00:00:00 2001 From: Nil Date: Wed, 15 Aug 2018 13:41:08 +0800 Subject: [PATCH 0915/1276] add 'search.collapseAllResults' setting --- .../parts/search/browser/searchResultsView.ts | 11 ++++++++++- .../search/electron-browser/search.contribution.ts | 6 ++++++ 2 files changed, 16 insertions(+), 1 deletion(-) diff --git a/src/vs/workbench/parts/search/browser/searchResultsView.ts b/src/vs/workbench/parts/search/browser/searchResultsView.ts index 4a27ccf12d5..d883b6ada0f 100644 --- a/src/vs/workbench/parts/search/browser/searchResultsView.ts +++ b/src/vs/workbench/parts/search/browser/searchResultsView.ts @@ -36,7 +36,10 @@ export class SearchDataSource implements IDataSource { private includeFolderMatch: boolean; private listener: IDisposable; - constructor(@IWorkspaceContextService private contextService: IWorkspaceContextService) { + constructor( + @IWorkspaceContextService private contextService: IWorkspaceContextService, + @IConfigurationService private configurationService: IConfigurationService, + ) { this.updateIncludeFolderMatch(); this.listener = this.contextService.onDidChangeWorkbenchState(() => this.updateIncludeFolderMatch()); } @@ -103,6 +106,12 @@ export class SearchDataSource implements IDataSource { if (numChildren <= 0) { return false; } + + const collapseOption = this.configurationService.getValue('search.collapseAllResults'); + if (collapseOption === 'alwaysCollapse') { + return false; + } + return numChildren < SearchDataSource.AUTOEXPAND_CHILD_LIMIT || element instanceof FolderMatch; } diff --git a/src/vs/workbench/parts/search/electron-browser/search.contribution.ts b/src/vs/workbench/parts/search/electron-browser/search.contribution.ts index 407f714fbf4..462b13819c8 100644 --- a/src/vs/workbench/parts/search/electron-browser/search.contribution.ts +++ b/src/vs/workbench/parts/search/electron-browser/search.contribution.ts @@ -620,6 +620,12 @@ configurationRegistry.registerConfiguration({ enum: ['sidebar', 'panel'], default: 'sidebar', description: nls.localize('search.location', "Controls whether the search will be shown as a view in the sidebar or as a panel in the panel area for more horizontal space."), + }, + 'search.collapseAllResults': { + type: 'string', + enum: ['auto', 'alwaysCollapse'], + default: 'auto', + description: nls.localize('search.collapseAllResults', "Controls whether the search results will be collapsed."), } } }); From fd610b4b6ab8d4735a4d84a2b59206ad3a9c8099 Mon Sep 17 00:00:00 2001 From: Rob Lourens Date: Thu, 16 Aug 2018 21:05:23 -0700 Subject: [PATCH 0916/1276] Settings editor - fix height difference between light/dark themes --- .../parts/codeEditor/browser/suggestEnabledInput.ts | 6 +++--- .../workbench/parts/preferences/browser/settingsEditor2.ts | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/vs/workbench/parts/codeEditor/browser/suggestEnabledInput.ts b/src/vs/workbench/parts/codeEditor/browser/suggestEnabledInput.ts index d85455c40dc..091350f5973 100644 --- a/src/vs/workbench/parts/codeEditor/browser/suggestEnabledInput.ts +++ b/src/vs/workbench/parts/codeEditor/browser/suggestEnabledInput.ts @@ -186,9 +186,9 @@ export class SuggestEnabledInput extends Component { this.placeholderText.style.color = this.getColor(inputPlaceholderForeground); const inputBorderColor = this.getColor(inputBorder); - this.stylingContainer.style.borderWidth = inputBorderColor ? '1px' : null; - this.stylingContainer.style.borderStyle = inputBorderColor ? 'solid' : null; - this.stylingContainer.style.borderColor = inputBorderColor; + this.stylingContainer.style.borderWidth = '1px'; + this.stylingContainer.style.borderStyle = 'solid'; + this.stylingContainer.style.borderColor = inputBorderColor || 'transparent'; let cursor = this.stylingContainer.getElementsByClassName('cursor')[0] as HTMLDivElement; if (cursor) { diff --git a/src/vs/workbench/parts/preferences/browser/settingsEditor2.ts b/src/vs/workbench/parts/preferences/browser/settingsEditor2.ts index ea84a34cbad..17beb717b30 100644 --- a/src/vs/workbench/parts/preferences/browser/settingsEditor2.ts +++ b/src/vs/workbench/parts/preferences/browser/settingsEditor2.ts @@ -904,7 +904,7 @@ export class SettingsEditor2 extends BaseEditor { } private layoutTrees(dimension: DOM.Dimension): void { - const listHeight = dimension.height - (95 + 11 /* header height + padding*/); + const listHeight = dimension.height - (97 + 11 /* header height + padding*/); const settingsTreeHeight = listHeight - 14; this.settingsTreeContainer.style.height = `${settingsTreeHeight}px`; this.settingsTree.layout(settingsTreeHeight, 800); From bbfcc67dc94e1b741d2507f5538ddccc7d8d70e6 Mon Sep 17 00:00:00 2001 From: Johannes Rieken Date: Fri, 17 Aug 2018 09:30:18 +0200 Subject: [PATCH 0917/1276] add ExtensionContext#logPath, #43275 --- src/vs/vscode.d.ts | 7 +++++++ src/vs/workbench/api/node/extHostExtensionActivator.ts | 1 + src/vs/workbench/api/node/extHostExtensionService.ts | 4 +++- 3 files changed, 11 insertions(+), 1 deletion(-) diff --git a/src/vs/vscode.d.ts b/src/vs/vscode.d.ts index 5828b5bb88a..6000b0300db 100644 --- a/src/vs/vscode.d.ts +++ b/src/vs/vscode.d.ts @@ -4537,6 +4537,13 @@ declare module 'vscode' { * [`globalState`](#ExtensionContext.globalState) to store key value data. */ storagePath: string | undefined; + + /** + * An absolute file path of a directory in which the extension can create log files. + * The directory might not exist on disk and creation is up to the extension. However, + * the parent directory is guaranteed to be existent. + */ + logPath: string; } /** diff --git a/src/vs/workbench/api/node/extHostExtensionActivator.ts b/src/vs/workbench/api/node/extHostExtensionActivator.ts index c37e7b2dfe7..cbd8a70d649 100644 --- a/src/vs/workbench/api/node/extHostExtensionActivator.ts +++ b/src/vs/workbench/api/node/extHostExtensionActivator.ts @@ -29,6 +29,7 @@ export interface IExtensionContext { asAbsolutePath(relativePath: string): string; logger: ExtHostLogger; readonly logDirectory: string; + readonly logPath: string; } /** diff --git a/src/vs/workbench/api/node/extHostExtensionService.ts b/src/vs/workbench/api/node/extHostExtensionService.ts index 61ec236d842..f29e288412b 100644 --- a/src/vs/workbench/api/node/extHostExtensionService.ts +++ b/src/vs/workbench/api/node/extHostExtensionService.ts @@ -366,9 +366,11 @@ export class ExtHostExtensionService implements ExtHostExtensionServiceShape { return that._extHostLogService.getExtLogger(extensionDescription.id); }, get logDirectory() { + console.warn(`this PROPOSED API has been RENAMED to 'logPath'`); checkProposedApiEnabled(extensionDescription); return that._extHostLogService.getLogDirectory(extensionDescription.id); - } + }, + logPath: that._extHostLogService.getLogDirectory(extensionDescription.id) }); }); } From c1989902c821384693e7dd58c6349b28a035ecb4 Mon Sep 17 00:00:00 2001 From: Joao Moreno Date: Fri, 17 Aug 2018 09:41:51 +0200 Subject: [PATCH 0918/1276] fixes #56586 --- src/vs/workbench/parts/update/electron-browser/update.ts | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/vs/workbench/parts/update/electron-browser/update.ts b/src/vs/workbench/parts/update/electron-browser/update.ts index a7b6f45334a..2e468debc61 100644 --- a/src/vs/workbench/parts/update/electron-browser/update.ts +++ b/src/vs/workbench/parts/update/electron-browser/update.ts @@ -303,8 +303,14 @@ export class WinUserSetupContribution implements IWorkbenchContribution { const handle = this.notificationService.prompt( severity.Info, - nls.localize('usersetup', "We recommend switching to our new User Setup distribution of {0} for Windows! Click [here]({1}) to learn more.", product.nameShort, WinUserSetupContribution.READ_MORE), + nls.localize('usersetup', "We recommend switching to our new User Setup distribution of {0} for Windows!", product.nameShort), [ + { + label: nls.localize('learnMore', "Learn More"), + run: () => { + return this.openerService.open(URI.parse(WinUserSetupContribution.READ_MORE)); + } + }, { label: nls.localize('downloadnow', "Download"), run: () => { @@ -317,7 +323,6 @@ export class WinUserSetupContribution implements IWorkbenchContribution { }, { label: nls.localize('neveragain', "Don't Show Again"), - isSecondary: true, run: () => { neverShowAgain.action.run(handle); neverShowAgain.action.dispose(); From b8a9ce26d6a2f6f2be3f8d01d581b06383c94b69 Mon Sep 17 00:00:00 2001 From: Benjamin Pasero Date: Fri, 17 Aug 2018 09:43:34 +0200 Subject: [PATCH 0919/1276] workaround #56633 --- src/vs/workbench/browser/parts/editor/editorGroupView.ts | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/vs/workbench/browser/parts/editor/editorGroupView.ts b/src/vs/workbench/browser/parts/editor/editorGroupView.ts index 2f4c869314a..3d7d84cc022 100644 --- a/src/vs/workbench/browser/parts/editor/editorGroupView.ts +++ b/src/vs/workbench/browser/parts/editor/editorGroupView.ts @@ -723,6 +723,11 @@ export class EditorGroupView extends Themable implements IEditorGroupView { openEditor(editor: EditorInput, options?: EditorOptions): TPromise { + // Guard against invalid inputs + if (!editor) { + return TPromise.as(void 0); + } + // Editor opening event allows for prevention const event = new EditorOpeningEvent(this._group.id, editor, options); this._onWillOpenEditor.fire(event); From 1c72ab243c302f2d69551077c1be1d13f04101d8 Mon Sep 17 00:00:00 2001 From: Johannes Rieken Date: Fri, 17 Aug 2018 09:46:03 +0200 Subject: [PATCH 0920/1276] remove proposed Logger-api, #43275 we keep the LogLevel-enum and the plan is to accept the log level when calling OutputChannel#appendLine so that logging is supported there --- src/vs/vscode.proposed.d.ts | 16 ------ src/vs/workbench/api/node/extHost.api.impl.ts | 5 +- .../api/node/extHostExtensionActivator.ts | 2 - .../api/node/extHostExtensionService.ts | 4 -- .../workbench/api/node/extHostLogService.ts | 50 ------------------- 5 files changed, 4 insertions(+), 73 deletions(-) diff --git a/src/vs/vscode.proposed.d.ts b/src/vs/vscode.proposed.d.ts index 3de4a7af9dd..7c10f6b6b56 100644 --- a/src/vs/vscode.proposed.d.ts +++ b/src/vs/vscode.proposed.d.ts @@ -434,23 +434,7 @@ declare module 'vscode' { Off = 7 } - /** - * A logger for writing to an extension's log file, and accessing its dedicated log directory. - */ - export interface Logger { - trace(message: string, ...args: any[]): void; - debug(message: string, ...args: any[]): void; - info(message: string, ...args: any[]): void; - warn(message: string, ...args: any[]): void; - error(message: string | Error, ...args: any[]): void; - critical(message: string | Error, ...args: any[]): void; - } - export interface ExtensionContext { - /** - * This extension's logger - */ - logger: Logger; /** * Path where an extension can write log files. diff --git a/src/vs/workbench/api/node/extHost.api.impl.ts b/src/vs/workbench/api/node/extHost.api.impl.ts index bc631fe2d4d..32884fedd83 100644 --- a/src/vs/workbench/api/node/extHost.api.impl.ts +++ b/src/vs/workbench/api/node/extHost.api.impl.ts @@ -227,7 +227,10 @@ export function createApiFactory( get language() { return platform.language; }, get appName() { return product.nameLong; }, get appRoot() { return initData.environment.appRoot; }, - get logLevel() { return extHostLogService.getLevel(); } + get logLevel() { + checkProposedApiEnabled(extension); + return extHostLogService.getLevel(); + } }); // namespace: extensions diff --git a/src/vs/workbench/api/node/extHostExtensionActivator.ts b/src/vs/workbench/api/node/extHostExtensionActivator.ts index cbd8a70d649..b392d0182f1 100644 --- a/src/vs/workbench/api/node/extHostExtensionActivator.ts +++ b/src/vs/workbench/api/node/extHostExtensionActivator.ts @@ -10,7 +10,6 @@ import Severity from 'vs/base/common/severity'; import { TPromise } from 'vs/base/common/winjs.base'; import { ExtensionDescriptionRegistry } from 'vs/workbench/services/extensions/node/extensionDescriptionRegistry'; import { IExtensionDescription } from 'vs/workbench/services/extensions/common/extensions'; -import { ExtHostLogger } from 'vs/workbench/api/node/extHostLogService'; const hasOwnProperty = Object.hasOwnProperty; const NO_OP_VOID_PROMISE = TPromise.wrap(void 0); @@ -27,7 +26,6 @@ export interface IExtensionContext { extensionPath: string; storagePath: string; asAbsolutePath(relativePath: string): string; - logger: ExtHostLogger; readonly logDirectory: string; readonly logPath: string; } diff --git a/src/vs/workbench/api/node/extHostExtensionService.ts b/src/vs/workbench/api/node/extHostExtensionService.ts index f29e288412b..06c52263022 100644 --- a/src/vs/workbench/api/node/extHostExtensionService.ts +++ b/src/vs/workbench/api/node/extHostExtensionService.ts @@ -361,10 +361,6 @@ export class ExtHostExtensionService implements ExtHostExtensionServiceShape { get extensionPath() { return extensionDescription.extensionLocation.fsPath; }, storagePath: this._storagePath.value(extensionDescription), asAbsolutePath: (relativePath: string) => { return join(extensionDescription.extensionLocation.fsPath, relativePath); }, - get logger() { - checkProposedApiEnabled(extensionDescription); - return that._extHostLogService.getExtLogger(extensionDescription.id); - }, get logDirectory() { console.warn(`this PROPOSED API has been RENAMED to 'logPath'`); checkProposedApiEnabled(extensionDescription); diff --git a/src/vs/workbench/api/node/extHostLogService.ts b/src/vs/workbench/api/node/extHostLogService.ts index 6708690a2f4..31b0113188f 100644 --- a/src/vs/workbench/api/node/extHostLogService.ts +++ b/src/vs/workbench/api/node/extHostLogService.ts @@ -4,7 +4,6 @@ *--------------------------------------------------------------------------------------------*/ 'use strict'; -import * as vscode from 'vscode'; import { join } from 'vs/base/common/paths'; import { LogLevel } from 'vs/workbench/api/node/extHostTypes'; import { ILogService, DelegatedLogService } from 'vs/platform/log/common/log'; @@ -14,8 +13,6 @@ import { ExtHostLogServiceShape } from 'vs/workbench/api/node/extHost.protocol'; export class ExtHostLogService extends DelegatedLogService implements ILogService, ExtHostLogServiceShape { - private _loggers: Map = new Map(); - constructor( private _windowId: number, logLevel: LogLevel, @@ -28,54 +25,7 @@ export class ExtHostLogService extends DelegatedLogService implements ILogServic this.setLevel(level); } - getExtLogger(extensionID: string): ExtHostLogger { - let logger = this._loggers.get(extensionID); - if (!logger) { - logger = this.createLogger(extensionID); - this._loggers.set(extensionID, logger); - } - return logger; - } - getLogDirectory(extensionID: string): string { return join(this._logsPath, `${extensionID}_${this._windowId}`); } - - private createLogger(extensionID: string): ExtHostLogger { - const logsDirPath = this.getLogDirectory(extensionID); - const logService = createSpdLogService(extensionID, this.getLevel(), logsDirPath); - this._register(this.onDidChangeLogLevel(level => logService.setLevel(level))); - return new ExtHostLogger(logService); - } -} - -export class ExtHostLogger implements vscode.Logger { - - constructor( - private readonly _logService: ILogService - ) { } - - trace(message: string, ...args: any[]): void { - return this._logService.trace(message, ...args); - } - - debug(message: string, ...args: any[]): void { - return this._logService.debug(message, ...args); - } - - info(message: string, ...args: any[]): void { - return this._logService.info(message, ...args); - } - - warn(message: string, ...args: any[]): void { - return this._logService.warn(message, ...args); - } - - error(message: string | Error, ...args: any[]): void { - return this._logService.error(message, ...args); - } - - critical(message: string | Error, ...args: any[]): void { - return this._logService.critical(message, ...args); - } } From 1a9a0bd306ebd49bc61def4c6747da4021492567 Mon Sep 17 00:00:00 2001 From: Johannes Rieken Date: Fri, 17 Aug 2018 09:49:25 +0200 Subject: [PATCH 0921/1276] :lipstick: sort lines in vscode-module export --- src/vs/workbench/api/node/extHost.api.impl.ts | 64 +++++++++---------- 1 file changed, 31 insertions(+), 33 deletions(-) diff --git a/src/vs/workbench/api/node/extHost.api.impl.ts b/src/vs/workbench/api/node/extHost.api.impl.ts index 32884fedd83..a8afbaabb36 100644 --- a/src/vs/workbench/api/node/extHost.api.impl.ts +++ b/src/vs/workbench/api/node/extHost.api.impl.ts @@ -688,39 +688,48 @@ export function createApiFactory( version: pkg.version, // namespaces commands, + debug, env, extensions, languages, + scm, + tasks, window, workspace, - scm, - debug, - tasks, // types Breakpoint: extHostTypes.Breakpoint, CancellationTokenSource: CancellationTokenSource, CodeAction: extHostTypes.CodeAction, CodeActionKind: extHostTypes.CodeActionKind, + CodeActionTrigger: extHostTypes.CodeActionTrigger, CodeLens: extHostTypes.CodeLens, Color: extHostTypes.Color, - ColorPresentation: extHostTypes.ColorPresentation, ColorInformation: extHostTypes.ColorInformation, - CodeActionTrigger: extHostTypes.CodeActionTrigger, - EndOfLine: extHostTypes.EndOfLine, + ColorPresentation: extHostTypes.ColorPresentation, + CommentThreadCollapsibleState: extHostTypes.CommentThreadCollapsibleState, CompletionItem: extHostTypes.CompletionItem, CompletionItemKind: extHostTypes.CompletionItemKind, CompletionList: extHostTypes.CompletionList, CompletionTriggerKind: extHostTypes.CompletionTriggerKind, + ConfigurationTarget: extHostTypes.ConfigurationTarget, DebugAdapterExecutable: extHostTypes.DebugAdapterExecutable, + DecorationRangeBehavior: extHostTypes.DecorationRangeBehavior, Diagnostic: extHostTypes.Diagnostic, DiagnosticRelatedInformation: extHostTypes.DiagnosticRelatedInformation, - DiagnosticTag: extHostTypes.DiagnosticTag, DiagnosticSeverity: extHostTypes.DiagnosticSeverity, + DiagnosticTag: extHostTypes.DiagnosticTag, Disposable: extHostTypes.Disposable, DocumentHighlight: extHostTypes.DocumentHighlight, DocumentHighlightKind: extHostTypes.DocumentHighlightKind, DocumentLink: extHostTypes.DocumentLink, + DocumentSymbol: extHostTypes.DocumentSymbol, + EndOfLine: extHostTypes.EndOfLine, EventEmitter: Emitter, + FileChangeType: extHostTypes.FileChangeType, + FileSystemError: extHostTypes.FileSystemError, + FileType: files.FileType, + FoldingRange: extHostTypes.FoldingRange, + FoldingRangeKind: extHostTypes.FoldingRangeKind, FunctionBreakpoint: extHostTypes.FunctionBreakpoint, Hover: extHostTypes.Hover, IndentAction: languageConfiguration.IndentAction, @@ -730,52 +739,41 @@ export function createApiFactory( OverviewRulerLane: OverviewRulerLane, ParameterInformation: extHostTypes.ParameterInformation, Position: extHostTypes.Position, + ProcessExecution: extHostTypes.ProcessExecution, + ProgressLocation: extHostTypes.ProgressLocation, QuickInputButtons: extHostTypes.QuickInputButtons, Range: extHostTypes.Range, + RelativePattern: extHostTypes.RelativePattern, Selection: extHostTypes.Selection, + ShellExecution: extHostTypes.ShellExecution, + ShellQuoting: extHostTypes.ShellQuoting, SignatureHelp: extHostTypes.SignatureHelp, SignatureInformation: extHostTypes.SignatureInformation, SnippetString: extHostTypes.SnippetString, SourceBreakpoint: extHostTypes.SourceBreakpoint, + SourceControlInputBoxValidationType: extHostTypes.SourceControlInputBoxValidationType, StatusBarAlignment: extHostTypes.StatusBarAlignment, SymbolInformation: extHostTypes.SymbolInformation, - DocumentSymbol: extHostTypes.DocumentSymbol, SymbolKind: extHostTypes.SymbolKind, - SourceControlInputBoxValidationType: extHostTypes.SourceControlInputBoxValidationType, + Task: extHostTypes.Task, + TaskGroup: extHostTypes.TaskGroup, + TaskPanelKind: extHostTypes.TaskPanelKind, + TaskRevealKind: extHostTypes.TaskRevealKind, + TaskScope: extHostTypes.TaskScope, TextDocumentSaveReason: extHostTypes.TextDocumentSaveReason, TextEdit: extHostTypes.TextEdit, TextEditorCursorStyle: TextEditorCursorStyle, TextEditorLineNumbersStyle: extHostTypes.TextEditorLineNumbersStyle, TextEditorRevealType: extHostTypes.TextEditorRevealType, TextEditorSelectionChangeKind: extHostTypes.TextEditorSelectionChangeKind, - DecorationRangeBehavior: extHostTypes.DecorationRangeBehavior, + ThemeColor: extHostTypes.ThemeColor, + ThemeIcon: extHostTypes.ThemeIcon, + TreeItem: extHostTypes.TreeItem, + TreeItemCollapsibleState: extHostTypes.TreeItemCollapsibleState, Uri: URI, ViewColumn: extHostTypes.ViewColumn, WorkspaceEdit: extHostTypes.WorkspaceEdit, - ProgressLocation: extHostTypes.ProgressLocation, - TreeItemCollapsibleState: extHostTypes.TreeItemCollapsibleState, - ThemeIcon: extHostTypes.ThemeIcon, - TreeItem: extHostTypes.TreeItem, - ThemeColor: extHostTypes.ThemeColor, // functions - TaskRevealKind: extHostTypes.TaskRevealKind, - TaskPanelKind: extHostTypes.TaskPanelKind, - TaskGroup: extHostTypes.TaskGroup, - ProcessExecution: extHostTypes.ProcessExecution, - ShellExecution: extHostTypes.ShellExecution, - ShellQuoting: extHostTypes.ShellQuoting, - TaskScope: extHostTypes.TaskScope, - Task: extHostTypes.Task, - ConfigurationTarget: extHostTypes.ConfigurationTarget, - RelativePattern: extHostTypes.RelativePattern, - - FileChangeType: extHostTypes.FileChangeType, - FileType: files.FileType, - FileSystemError: extHostTypes.FileSystemError, - FoldingRange: extHostTypes.FoldingRange, - FoldingRangeKind: extHostTypes.FoldingRangeKind, - - CommentThreadCollapsibleState: extHostTypes.CommentThreadCollapsibleState }; }; } From 95a07b513761cdc5f302acf48bb5cea16654b55c Mon Sep 17 00:00:00 2001 From: Benjamin Pasero Date: Fri, 17 Aug 2018 09:53:11 +0200 Subject: [PATCH 0922/1276] add more logging to diagnose #56553 --- .../test/electron-main/workspacesMainService.test.ts | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/vs/platform/workspaces/test/electron-main/workspacesMainService.test.ts b/src/vs/platform/workspaces/test/electron-main/workspacesMainService.test.ts index 210d5253765..b49fa1f295e 100644 --- a/src/vs/platform/workspaces/test/electron-main/workspacesMainService.test.ts +++ b/src/vs/platform/workspaces/test/electron-main/workspacesMainService.test.ts @@ -366,14 +366,22 @@ suite('WorkspacesMainService', () => { assert.equal(0, untitled.length); return createWorkspace([process.cwd(), os.tmpdir()]).then(untitledOne => { + assert.ok(fs.existsSync(untitledOne.configPath)); + untitled = service.getUntitledWorkspacesSync(); assert.equal(1, untitled.length); assert.equal(untitledOne.id, untitled[0].id); return createWorkspace([os.tmpdir(), process.cwd()]).then(untitledTwo => { + assert.ok(fs.existsSync(untitledTwo.configPath)); + untitled = service.getUntitledWorkspacesSync(); + if (untitled.length === 1) { + assert.fail('Unexpected workspaces count, contents:\n' + fs.readFileSync(untitledTwo.configPath, 'utf8')); + } + assert.equal(2, untitled.length); service.deleteUntitledWorkspaceSync(untitledOne); From eabf725b0fc29b9a608bec8a2083910935f19510 Mon Sep 17 00:00:00 2001 From: Johannes Rieken Date: Fri, 17 Aug 2018 09:55:50 +0200 Subject: [PATCH 0923/1276] fix #56604 --- src/vs/workbench/browser/parts/editor/breadcrumbsPicker.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/vs/workbench/browser/parts/editor/breadcrumbsPicker.ts b/src/vs/workbench/browser/parts/editor/breadcrumbsPicker.ts index e6eef49b484..fa061381046 100644 --- a/src/vs/workbench/browser/parts/editor/breadcrumbsPicker.ts +++ b/src/vs/workbench/browser/parts/editor/breadcrumbsPicker.ts @@ -20,11 +20,11 @@ import { localize } from 'vs/nls'; import { FileKind, IFileService, IFileStat } from 'vs/platform/files/common/files'; import { IInstantiationService, IConstructorSignature1 } from 'vs/platform/instantiation/common/instantiation'; import { HighlightingWorkbenchTree, IHighlightingTreeConfiguration, IHighlightingRenderer } from 'vs/platform/list/browser/listService'; -import { IThemeService, DARK } from 'vs/platform/theme/common/themeService'; +import { IThemeService } from 'vs/platform/theme/common/themeService'; import { FileLabel } from 'vs/workbench/browser/labels'; import { BreadcrumbElement, FileElement } from 'vs/workbench/browser/parts/editor/breadcrumbsModel'; import { onUnexpectedError } from 'vs/base/common/errors'; -import { breadcrumbsPickerBackground } from 'vs/platform/theme/common/colorRegistry'; +import { breadcrumbsPickerBackground, widgetShadow } from 'vs/platform/theme/common/colorRegistry'; import { FuzzyScore, createMatches, fuzzyScore } from 'vs/base/common/filters'; import { IWorkspaceContextService, IWorkspace, IWorkspaceFolder } from 'vs/platform/workspace/common/workspace'; import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; @@ -71,7 +71,7 @@ export abstract class BreadcrumbsPicker { this._treeContainer = document.createElement('div'); this._treeContainer.style.background = color.toString(); this._treeContainer.style.paddingTop = '2px'; - this._treeContainer.style.boxShadow = `0px 5px 8px ${(theme.type === DARK ? color.darken(.6) : color.darken(.2))}`; + this._treeContainer.style.boxShadow = `0px 5px 8px ${this._themeService.getTheme().getColor(widgetShadow)}`; this._domNode.appendChild(this._treeContainer); const treeConifg = this._completeTreeConfiguration({ dataSource: undefined, renderer: undefined }); From c37e51bc7dc7d414c3afbc57b725f4e8f03767f2 Mon Sep 17 00:00:00 2001 From: Benjamin Pasero Date: Fri, 17 Aug 2018 10:22:09 +0200 Subject: [PATCH 0924/1276] fix #55864 --- .../electron-browser/bootstrap/index.js | 31 ++++++++++--------- 1 file changed, 17 insertions(+), 14 deletions(-) diff --git a/src/vs/workbench/electron-browser/bootstrap/index.js b/src/vs/workbench/electron-browser/bootstrap/index.js index b16c9e2e461..8cbef8ef0a0 100644 --- a/src/vs/workbench/electron-browser/bootstrap/index.js +++ b/src/vs/workbench/electron-browser/bootstrap/index.js @@ -18,21 +18,23 @@ const electron = require('electron'); const remote = electron.remote; const ipc = electron.ipcRenderer; +Error.stackTraceLimit = 100; // increase number of stack frames (from 10, https://github.com/v8/v8/wiki/Stack-Trace-API) + process.lazyEnv = new Promise(function (resolve) { const handle = setTimeout(function () { resolve(); console.warn('renderer did not receive lazyEnv in time'); }, 10000); + ipc.once('vscode:acceptShellEnv', function (event, shellEnv) { clearTimeout(handle); assign(process.env, shellEnv); resolve(process.env); }); + ipc.send('vscode:fetchShellEnv'); }); -Error.stackTraceLimit = 100; // increase number of stack frames (from 10, https://github.com/v8/v8/wiki/Stack-Trace-API) - function onError(error, enableDeveloperTools) { if (enableDeveloperTools) { remote.getCurrentWebContents().openDevTools(); @@ -46,8 +48,7 @@ function onError(error, enableDeveloperTools) { } function assign(destination, source) { - return Object.keys(source) - .reduce(function (r, key) { r[key] = source[key]; return r; }, destination); + return Object.keys(source).reduce(function (r, key) { r[key] = source[key]; return r; }, destination); } function parseURLQueryArgs() { @@ -81,6 +82,10 @@ function readFile(file) { }); } +function writeFile(file, content) { + return new Promise((c, e) => fs.writeFile(file, content, 'utf8', err => err ? e(err) : c())); +} + function showPartsSplash(configuration) { perf.mark('willShowPartsSplash'); @@ -144,8 +149,6 @@ function showPartsSplash(configuration) { perf.mark('didShowPartsSplash'); } -const writeFile = (file, content) => new Promise((c, e) => fs.writeFile(file, content, 'utf8', err => err ? e(err) : c())); - function registerListeners(enableDeveloperTools) { // Devtools & reload support @@ -221,6 +224,14 @@ function main() { // Correctly inherit the parent's environment assign(process.env, configuration.userEnv); + // disable pinch zoom & apply zoom level early to avoid glitches + const zoomLevel = configuration.zoomLevel; + webFrame.setVisualZoomLevelLimits(1, 1); + if (typeof zoomLevel === 'number' && zoomLevel !== 0) { + webFrame.setZoomLevel(zoomLevel); + } + + // Parts splash showPartsSplash(configuration); // Get the nls configuration into the process.env as early as possible. @@ -269,13 +280,6 @@ function main() { const enableDeveloperTools = (process.env['VSCODE_DEV'] || !!configuration.extensionDevelopmentPath) && !configuration.extensionTestsPath; const unbind = registerListeners(enableDeveloperTools); - // disable pinch zoom & apply zoom level early to avoid glitches - const zoomLevel = configuration.zoomLevel; - webFrame.setVisualZoomLevelLimits(1, 1); - if (typeof zoomLevel === 'number' && zoomLevel !== 0) { - webFrame.setZoomLevel(zoomLevel); - } - // Load the loader and start loading the workbench const loaderFilename = configuration.appRoot + '/out/vs/loader.js'; const loaderSource = require('fs').readFileSync(loaderFilename); @@ -324,7 +328,6 @@ function main() { }); }); }); - } main(); From 92f4047fa1f772090c90025d9eaa68467bd3b6c4 Mon Sep 17 00:00:00 2001 From: Johannes Rieken Date: Fri, 17 Aug 2018 10:32:29 +0200 Subject: [PATCH 0925/1276] fix #56576 --- src/vs/platform/theme/common/colorRegistry.ts | 15 +++++++++------ .../parts/editor/media/breadcrumbscontrol.css | 4 ---- 2 files changed, 9 insertions(+), 10 deletions(-) diff --git a/src/vs/platform/theme/common/colorRegistry.ts b/src/vs/platform/theme/common/colorRegistry.ts index 8571fd6d2c9..674f67411d4 100644 --- a/src/vs/platform/theme/common/colorRegistry.ts +++ b/src/vs/platform/theme/common/colorRegistry.ts @@ -223,12 +223,6 @@ export const scrollbarSliderActiveBackground = registerColor('scrollbarSlider.ac export const progressBarBackground = registerColor('progressBar.background', { dark: Color.fromHex('#0E70C0'), light: Color.fromHex('#0E70C0'), hc: contrastBorder }, nls.localize('progressBarBackground', "Background color of the progress bar that can show for long running operations.")); -export const breadcrumbsForeground = registerColor('breadcrumb.foreground', { light: Color.fromHex('#6C6C6C').transparent(.7), dark: Color.fromHex('#CCCCCC').transparent(.7), hc: Color.white.transparent(.7) }, nls.localize('breadcrumbsFocusForeground', "Color of focused breadcrumb items.")); -export const breadcrumbsBackground = registerColor('breadcrumb.background', { light: '#fffffe', dark: '#1E1E1E', hc: Color.black }, nls.localize('breadcrumbsBackground', "Background color of breadcrumb items.")); -export const breadcrumbsFocusForeground = registerColor('breadcrumb.focusForeground', { light: '#6C6C6C', dark: '#CCCCCC', hc: Color.white }, nls.localize('breadcrumbsFocusForeground', "Color of focused breadcrumb items.")); -export const breadcrumbsActiveSelectionForeground = registerColor('breadcrumb.activeSelectionForeground', { light: '#6C6C6C', dark: '#CCCCCC', hc: Color.white }, nls.localize('breadcrumbsSelectedForegound', "Color of selected breadcrumb items.")); -export const breadcrumbsPickerBackground = registerColor('breadcrumbPicker.background', { light: '#ECECEC', dark: '#252526', hc: Color.black }, nls.localize('breadcrumbsSelectedBackground', "Background color of breadcrumb item picker.")); - /** * Editor background color. * Because of bug https://monacotools.visualstudio.com/DefaultCollection/Monaco/_workitems/edit/13254 @@ -295,6 +289,15 @@ export const diffRemovedOutline = registerColor('diffEditor.removedTextBorder', export const diffBorder = registerColor('diffEditor.border', { dark: null, light: null, hc: contrastBorder }, nls.localize('diffEditorBorder', 'Border color between the two text editors.')); +/** + * Breadcrumb colors + */ +export const breadcrumbsForeground = registerColor('breadcrumb.foreground', { light: Color.fromHex('#6C6C6C').transparent(.7), dark: Color.fromHex('#CCCCCC').transparent(.7), hc: Color.white.transparent(.7) }, nls.localize('breadcrumbsFocusForeground', "Color of focused breadcrumb items.")); +export const breadcrumbsBackground = registerColor('breadcrumb.background', { light: editorBackground, dark: editorBackground, hc: editorBackground }, nls.localize('breadcrumbsBackground', "Background color of breadcrumb items.")); +export const breadcrumbsFocusForeground = registerColor('breadcrumb.focusForeground', { light: '#6C6C6C', dark: '#CCCCCC', hc: Color.white }, nls.localize('breadcrumbsFocusForeground', "Color of focused breadcrumb items.")); +export const breadcrumbsActiveSelectionForeground = registerColor('breadcrumb.activeSelectionForeground', { light: '#6C6C6C', dark: '#CCCCCC', hc: Color.white }, nls.localize('breadcrumbsSelectedForegound', "Color of selected breadcrumb items.")); +export const breadcrumbsPickerBackground = registerColor('breadcrumbPicker.background', { light: editorWidgetBackground, dark: editorWidgetBackground, hc: editorWidgetBackground }, nls.localize('breadcrumbsSelectedBackground', "Background color of breadcrumb item picker.")); + /** * Merge-conflict colors */ diff --git a/src/vs/workbench/browser/parts/editor/media/breadcrumbscontrol.css b/src/vs/workbench/browser/parts/editor/media/breadcrumbscontrol.css index e03eee35663..cf1a913a8ef 100644 --- a/src/vs/workbench/browser/parts/editor/media/breadcrumbscontrol.css +++ b/src/vs/workbench/browser/parts/editor/media/breadcrumbscontrol.css @@ -7,10 +7,6 @@ display: none; } -.monaco-workbench>.part.editor>.content .editor-group-container:not(.active) .breadcrumbs-control { - opacity: .8; -} - .monaco-workbench>.part.editor>.content .editor-group-container .breadcrumbs-control .monaco-breadcrumb-item.selected .monaco-icon-label, .monaco-workbench>.part.editor>.content .editor-group-container .breadcrumbs-control .monaco-breadcrumb-item.focused .monaco-icon-label { text-decoration-line: underline; From 51d6507fe71375f4d7c6454baf9d527df826829f Mon Sep 17 00:00:00 2001 From: Joao Moreno Date: Fri, 17 Aug 2018 10:35:29 +0200 Subject: [PATCH 0926/1276] cleanup win32 continuous build --- build/tfs/win32/continuous-build-win32.yml | 36 ++++++---------------- 1 file changed, 9 insertions(+), 27 deletions(-) diff --git a/build/tfs/win32/continuous-build-win32.yml b/build/tfs/win32/continuous-build-win32.yml index a15484c7ce4..4e409f5d53d 100644 --- a/build/tfs/win32/continuous-build-win32.yml +++ b/build/tfs/win32/continuous-build-win32.yml @@ -6,49 +6,31 @@ steps: inputs: versionSpec: "1.3.2" - powershell: | - . build/tfs/win32/exec.ps1 - $ErrorActionPreference = "Stop" - exec { yarn } + yarn displayName: Install Dependencies - powershell: | - . build/tfs/win32/exec.ps1 - $ErrorActionPreference = "Stop" - exec { yarn gulp electron } + yarn gulp electron displayName: Download Electron - powershell: | - . build/tfs/win32/exec.ps1 - $ErrorActionPreference = "Stop" - exec { yarn gulp hygiene } + yarn gulp hygiene displayName: Run Hygiene Checks - powershell: | - . build/tfs/win32/exec.ps1 - $ErrorActionPreference = "Stop" - exec { yarn monaco-compile-check } + yarn monaco-compile-check displayName: Run Monaco Editor Checks - powershell: | - . build/tfs/win32/exec.ps1 - $ErrorActionPreference = "Stop" - exec { yarn compile } + yarn compile displayName: Compile Sources - powershell: | - . build/tfs/win32/exec.ps1 - $ErrorActionPreference = "Stop" - exec { yarn download-builtin-extensions } + yarn download-builtin-extensions displayName: Download Built-in Extensions - powershell: | - . build/tfs/win32/exec.ps1 - $ErrorActionPreference = "Stop" - exec { .\scripts\test.bat --tfs "Unit Tests" } + .\scripts\test.bat --tfs "Unit Tests" displayName: Run Unit Tests - powershell: | - . build/tfs/win32/exec.ps1 - $ErrorActionPreference = "Stop" - exec { .\scripts\test-integration.bat --tfs "Integration Tests" } + .\scripts\test-integration.bat --tfs "Integration Tests" displayName: Run Integration Tests - powershell: | - . build/tfs/win32/exec.ps1 - $ErrorActionPreference = "Stop" - exec { yarn smoketest --screenshots "$(Build.ArtifactStagingDirectory)\artifacts" --log "$(Build.ArtifactStagingDirectory)\artifacts\smoketest.log" } + yarn smoketest --screenshots "$(Build.ArtifactStagingDirectory)\artifacts" --log "$(Build.ArtifactStagingDirectory)\artifacts\smoketest.log" displayName: Run Smoke Tests continueOnError: true - task: PublishBuildArtifacts@1 From e87724805979982107237bf8be5e502cc75d355e Mon Sep 17 00:00:00 2001 From: Andre Weinand Date: Fri, 17 Aug 2018 10:54:17 +0200 Subject: [PATCH 0927/1276] node-debug@1.27.2 --- build/builtInExtensions.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build/builtInExtensions.json b/build/builtInExtensions.json index 112d0157ca6..b3efcd2cc65 100644 --- a/build/builtInExtensions.json +++ b/build/builtInExtensions.json @@ -1,7 +1,7 @@ [ { "name": "ms-vscode.node-debug", - "version": "1.27.1", + "version": "1.27.2", "repo": "https://github.com/Microsoft/vscode-node-debug" }, { From 315cce8314801ba9b25190682fad7fb48e797a9f Mon Sep 17 00:00:00 2001 From: Johannes Rieken Date: Fri, 17 Aug 2018 11:04:35 +0200 Subject: [PATCH 0928/1276] Revert "remove proposed Logger-api, #43275" This reverts commit 1c72ab243c302f2d69551077c1be1d13f04101d8. --- src/vs/vscode.proposed.d.ts | 16 ++++++ src/vs/workbench/api/node/extHost.api.impl.ts | 5 +- .../api/node/extHostExtensionActivator.ts | 2 + .../api/node/extHostExtensionService.ts | 4 ++ .../workbench/api/node/extHostLogService.ts | 50 +++++++++++++++++++ 5 files changed, 73 insertions(+), 4 deletions(-) diff --git a/src/vs/vscode.proposed.d.ts b/src/vs/vscode.proposed.d.ts index 7c10f6b6b56..3de4a7af9dd 100644 --- a/src/vs/vscode.proposed.d.ts +++ b/src/vs/vscode.proposed.d.ts @@ -434,7 +434,23 @@ declare module 'vscode' { Off = 7 } + /** + * A logger for writing to an extension's log file, and accessing its dedicated log directory. + */ + export interface Logger { + trace(message: string, ...args: any[]): void; + debug(message: string, ...args: any[]): void; + info(message: string, ...args: any[]): void; + warn(message: string, ...args: any[]): void; + error(message: string | Error, ...args: any[]): void; + critical(message: string | Error, ...args: any[]): void; + } + export interface ExtensionContext { + /** + * This extension's logger + */ + logger: Logger; /** * Path where an extension can write log files. diff --git a/src/vs/workbench/api/node/extHost.api.impl.ts b/src/vs/workbench/api/node/extHost.api.impl.ts index a8afbaabb36..ea64898c5b1 100644 --- a/src/vs/workbench/api/node/extHost.api.impl.ts +++ b/src/vs/workbench/api/node/extHost.api.impl.ts @@ -227,10 +227,7 @@ export function createApiFactory( get language() { return platform.language; }, get appName() { return product.nameLong; }, get appRoot() { return initData.environment.appRoot; }, - get logLevel() { - checkProposedApiEnabled(extension); - return extHostLogService.getLevel(); - } + get logLevel() { return extHostLogService.getLevel(); } }); // namespace: extensions diff --git a/src/vs/workbench/api/node/extHostExtensionActivator.ts b/src/vs/workbench/api/node/extHostExtensionActivator.ts index b392d0182f1..cbd8a70d649 100644 --- a/src/vs/workbench/api/node/extHostExtensionActivator.ts +++ b/src/vs/workbench/api/node/extHostExtensionActivator.ts @@ -10,6 +10,7 @@ import Severity from 'vs/base/common/severity'; import { TPromise } from 'vs/base/common/winjs.base'; import { ExtensionDescriptionRegistry } from 'vs/workbench/services/extensions/node/extensionDescriptionRegistry'; import { IExtensionDescription } from 'vs/workbench/services/extensions/common/extensions'; +import { ExtHostLogger } from 'vs/workbench/api/node/extHostLogService'; const hasOwnProperty = Object.hasOwnProperty; const NO_OP_VOID_PROMISE = TPromise.wrap(void 0); @@ -26,6 +27,7 @@ export interface IExtensionContext { extensionPath: string; storagePath: string; asAbsolutePath(relativePath: string): string; + logger: ExtHostLogger; readonly logDirectory: string; readonly logPath: string; } diff --git a/src/vs/workbench/api/node/extHostExtensionService.ts b/src/vs/workbench/api/node/extHostExtensionService.ts index 06c52263022..f29e288412b 100644 --- a/src/vs/workbench/api/node/extHostExtensionService.ts +++ b/src/vs/workbench/api/node/extHostExtensionService.ts @@ -361,6 +361,10 @@ export class ExtHostExtensionService implements ExtHostExtensionServiceShape { get extensionPath() { return extensionDescription.extensionLocation.fsPath; }, storagePath: this._storagePath.value(extensionDescription), asAbsolutePath: (relativePath: string) => { return join(extensionDescription.extensionLocation.fsPath, relativePath); }, + get logger() { + checkProposedApiEnabled(extensionDescription); + return that._extHostLogService.getExtLogger(extensionDescription.id); + }, get logDirectory() { console.warn(`this PROPOSED API has been RENAMED to 'logPath'`); checkProposedApiEnabled(extensionDescription); diff --git a/src/vs/workbench/api/node/extHostLogService.ts b/src/vs/workbench/api/node/extHostLogService.ts index 31b0113188f..6708690a2f4 100644 --- a/src/vs/workbench/api/node/extHostLogService.ts +++ b/src/vs/workbench/api/node/extHostLogService.ts @@ -4,6 +4,7 @@ *--------------------------------------------------------------------------------------------*/ 'use strict'; +import * as vscode from 'vscode'; import { join } from 'vs/base/common/paths'; import { LogLevel } from 'vs/workbench/api/node/extHostTypes'; import { ILogService, DelegatedLogService } from 'vs/platform/log/common/log'; @@ -13,6 +14,8 @@ import { ExtHostLogServiceShape } from 'vs/workbench/api/node/extHost.protocol'; export class ExtHostLogService extends DelegatedLogService implements ILogService, ExtHostLogServiceShape { + private _loggers: Map = new Map(); + constructor( private _windowId: number, logLevel: LogLevel, @@ -25,7 +28,54 @@ export class ExtHostLogService extends DelegatedLogService implements ILogServic this.setLevel(level); } + getExtLogger(extensionID: string): ExtHostLogger { + let logger = this._loggers.get(extensionID); + if (!logger) { + logger = this.createLogger(extensionID); + this._loggers.set(extensionID, logger); + } + return logger; + } + getLogDirectory(extensionID: string): string { return join(this._logsPath, `${extensionID}_${this._windowId}`); } + + private createLogger(extensionID: string): ExtHostLogger { + const logsDirPath = this.getLogDirectory(extensionID); + const logService = createSpdLogService(extensionID, this.getLevel(), logsDirPath); + this._register(this.onDidChangeLogLevel(level => logService.setLevel(level))); + return new ExtHostLogger(logService); + } +} + +export class ExtHostLogger implements vscode.Logger { + + constructor( + private readonly _logService: ILogService + ) { } + + trace(message: string, ...args: any[]): void { + return this._logService.trace(message, ...args); + } + + debug(message: string, ...args: any[]): void { + return this._logService.debug(message, ...args); + } + + info(message: string, ...args: any[]): void { + return this._logService.info(message, ...args); + } + + warn(message: string, ...args: any[]): void { + return this._logService.warn(message, ...args); + } + + error(message: string | Error, ...args: any[]): void { + return this._logService.error(message, ...args); + } + + critical(message: string | Error, ...args: any[]): void { + return this._logService.critical(message, ...args); + } } From 29a2ba63f49eae575d3e1b24098b5028a6c9f28a Mon Sep 17 00:00:00 2001 From: Johannes Rieken Date: Fri, 17 Aug 2018 11:04:56 +0200 Subject: [PATCH 0929/1276] perf-stats: fix column header --- src/vs/workbench/electron-browser/actions.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vs/workbench/electron-browser/actions.ts b/src/vs/workbench/electron-browser/actions.ts index d87eb1c6f17..e168d43fd25 100644 --- a/src/vs/workbench/electron-browser/actions.ts +++ b/src/vs/workbench/electron-browser/actions.ts @@ -382,7 +382,7 @@ export class ShowStartupPerformance extends Action { table['require(workbench.main.js)'] = { Process: '[renderer]', 'Took (ms)': metrics.timers.ellapsedRequire, Meta: metrics.didUseCachedData ? 'did use cached data' : 'did NOT use cached data' }; if (nodeModuleLoadTime) { - table['[renderer] -> of which require() node_modules'] = { Process: '[renderer]', 'Took(ms)': nodeModuleLoadTime }; + table['of which require() node_modules'] = { Process: '[renderer]', 'Took (ms)': nodeModuleLoadTime }; } table['register extensions & spawn extension host'] = { Process: '[renderer]', 'Took (ms)': metrics.timers.ellapsedExtensions }; From b0eab4769101fd8b63c5d97c97576e7dc7f72c3c Mon Sep 17 00:00:00 2001 From: Joao Moreno Date: Fri, 17 Aug 2018 11:54:17 +0200 Subject: [PATCH 0930/1276] fixes #56665 --- src/vs/base/parts/tree/browser/treeModel.ts | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/vs/base/parts/tree/browser/treeModel.ts b/src/vs/base/parts/tree/browser/treeModel.ts index c2323599e0b..c9f758c99ea 100644 --- a/src/vs/base/parts/tree/browser/treeModel.ts +++ b/src/vs/base/parts/tree/browser/treeModel.ts @@ -360,6 +360,10 @@ export class Item { } var result = this.lock.run(this, () => { + if (this.isExpanded()) { + return WinJS.TPromise.as(false); + } + var eventData: IItemExpandEvent = { item: this }; var result: WinJS.Promise; this._onExpand.fire(eventData); @@ -971,6 +975,8 @@ export class TreeModel { return WinJS.TPromise.as(null); } + console.log('REFRESH', element, recursive); + var eventData: IRefreshEvent = { item: item, recursive: recursive }; this._onRefresh.fire(eventData); return item.refresh(recursive).then(() => { @@ -985,6 +991,8 @@ export class TreeModel { return WinJS.TPromise.as(false); } + console.log('EXPAND', element); + return item.expand(); } From 18754c71fcf52bde2cc113fcd5fa3ab6911d92e0 Mon Sep 17 00:00:00 2001 From: Joao Moreno Date: Fri, 17 Aug 2018 11:59:32 +0200 Subject: [PATCH 0931/1276] remove console.log --- src/vs/base/parts/tree/browser/treeModel.ts | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/vs/base/parts/tree/browser/treeModel.ts b/src/vs/base/parts/tree/browser/treeModel.ts index c9f758c99ea..71c894337bb 100644 --- a/src/vs/base/parts/tree/browser/treeModel.ts +++ b/src/vs/base/parts/tree/browser/treeModel.ts @@ -975,8 +975,6 @@ export class TreeModel { return WinJS.TPromise.as(null); } - console.log('REFRESH', element, recursive); - var eventData: IRefreshEvent = { item: item, recursive: recursive }; this._onRefresh.fire(eventData); return item.refresh(recursive).then(() => { @@ -991,8 +989,6 @@ export class TreeModel { return WinJS.TPromise.as(false); } - console.log('EXPAND', element); - return item.expand(); } From 93d2e0e9414346736b92cbd26c0d83466b115e62 Mon Sep 17 00:00:00 2001 From: Joao Moreno Date: Fri, 17 Aug 2018 12:01:44 +0200 Subject: [PATCH 0932/1276] cleanup --- src/vs/base/parts/tree/browser/treeModel.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vs/base/parts/tree/browser/treeModel.ts b/src/vs/base/parts/tree/browser/treeModel.ts index 71c894337bb..38abf8eca45 100644 --- a/src/vs/base/parts/tree/browser/treeModel.ts +++ b/src/vs/base/parts/tree/browser/treeModel.ts @@ -360,7 +360,7 @@ export class Item { } var result = this.lock.run(this, () => { - if (this.isExpanded()) { + if (this.isExpanded() || !this.doesHaveChildren) { return WinJS.TPromise.as(false); } From 02d7e6682ffc5f66735aad2d52b9f42d453d2529 Mon Sep 17 00:00:00 2001 From: Johannes Rieken Date: Fri, 17 Aug 2018 12:08:28 +0200 Subject: [PATCH 0933/1276] move performance developer actions to perf-contribution, #56253 --- src/vs/workbench/electron-browser/actions.ts | 405 ----------------- .../electron-browser/main.contribution.ts | 3 +- .../performance/electron-browser/actions.ts | 408 ++++++++++++++++++ .../electron-browser/startupProfiler.ts | 3 +- 4 files changed, 411 insertions(+), 408 deletions(-) create mode 100644 src/vs/workbench/parts/performance/electron-browser/actions.ts diff --git a/src/vs/workbench/electron-browser/actions.ts b/src/vs/workbench/electron-browser/actions.ts index e168d43fd25..bdd05d8bf60 100644 --- a/src/vs/workbench/electron-browser/actions.ts +++ b/src/vs/workbench/electron-browser/actions.ts @@ -13,7 +13,6 @@ import { Action } from 'vs/base/common/actions'; import { IWindowService, IWindowsService, MenuBarVisibility } from 'vs/platform/windows/common/windows'; import * as nls from 'vs/nls'; import product from 'vs/platform/node/product'; -import pkg from 'vs/platform/node/package'; import * as errors from 'vs/base/common/errors'; import { IWorkspaceContextService, WorkbenchState } from 'vs/platform/workspace/common/workspace'; import { IEnvironmentService } from 'vs/platform/environment/common/environment'; @@ -21,22 +20,17 @@ import { IConfigurationService, ConfigurationTarget } from 'vs/platform/configur import { IWorkspaceConfigurationService } from 'vs/workbench/services/configuration/common/configuration'; import { isMacintosh, isLinux, language } from 'vs/base/common/platform'; import * as browser from 'vs/base/browser/browser'; -import { IIntegrityService } from 'vs/platform/integrity/common/integrity'; -import { ITimerService, IStartupMetrics } from 'vs/workbench/services/timer/electron-browser/timerService'; import { IEditorGroupsService, GroupDirection, GroupLocation, IFindGroupScope } from 'vs/workbench/services/group/common/editorGroupsService'; import { IPanelService } from 'vs/workbench/services/panel/common/panelService'; import { IPartService, Parts, Position as PartPosition } from 'vs/workbench/services/part/common/partService'; import { IViewletService } from 'vs/workbench/services/viewlet/browser/viewlet'; import { IKeybindingService } from 'vs/platform/keybinding/common/keybinding'; -import * as os from 'os'; import { webFrame, shell } from 'electron'; import { getBaseLabel } from 'vs/base/common/labels'; import { IViewlet } from 'vs/workbench/common/viewlet'; import { IPanel } from 'vs/workbench/common/panel'; import { IWorkspaceIdentifier, getWorkspaceLabel, ISingleFolderWorkspaceIdentifier, isSingleFolderWorkspaceIdentifier, isWorkspaceIdentifier } from 'vs/platform/workspaces/common/workspaces'; import { FileKind } from 'vs/platform/files/common/files'; -import { IExtensionService, ActivationTimes } from 'vs/workbench/services/extensions/common/extensions'; -import { getEntries } from 'vs/base/common/performance'; import { IssueType } from 'vs/platform/issue/common/issue'; import { domEvent } from 'vs/base/browser/event'; import { once } from 'vs/base/common/event'; @@ -52,7 +46,6 @@ import { IModelService } from 'vs/editor/common/services/modelService'; import { IModeService } from 'vs/editor/common/services/modeService'; import { IQuickInputService, IQuickPickItem, IQuickInputButton, IQuickPickSeparator, IKeyMods } from 'vs/platform/quickinput/common/quickInput'; import { getIconClasses } from 'vs/workbench/browser/labels'; -import { timeout } from 'vs/base/common/async'; // --- actions @@ -265,283 +258,6 @@ export class ZoomResetAction extends BaseZoomAction { } } -/* Copied from loader.ts */ -enum LoaderEventType { - LoaderAvailable = 1, - - BeginLoadingScript = 10, - EndLoadingScriptOK = 11, - EndLoadingScriptError = 12, - - BeginInvokeFactory = 21, - EndInvokeFactory = 22, - - NodeBeginEvaluatingScript = 31, - NodeEndEvaluatingScript = 32, - - NodeBeginNativeRequire = 33, - NodeEndNativeRequire = 34 -} - -interface ILoaderEvent { - type: LoaderEventType; - timestamp: number; - detail: string; -} - -export class ShowStartupPerformance extends Action { - - static readonly ID = 'workbench.action.appPerf'; - static readonly LABEL = nls.localize('appPerf', "Startup Performance"); - - constructor( - id: string, - label: string, - @IWindowService private windowService: IWindowService, - @ITimerService private timerService: ITimerService, - @IEnvironmentService private environmentService: IEnvironmentService, - @IExtensionService private extensionService: IExtensionService - ) { - super(id, label); - } - - run(): TPromise { - - // Show dev tools - this.windowService.openDevTools(); - - Promise.all([ - timeout(1000), // needed to print a table - this.timerService.startupMetrics - ]).then(([, metrics]) => { - - console.group('Startup Performance Measurement'); - console.log(`OS: ${metrics.platform} (${metrics.release})`); - console.log(`CPUs: ${metrics.cpus.model} (${metrics.cpus.count} x ${metrics.cpus.speed})`); - console.log(`Memory (System): ${(metrics.totalmem / (1024 * 1024 * 1024)).toFixed(2)}GB (${(metrics.freemem / (1024 * 1024 * 1024)).toFixed(2)}GB free)`); - console.log(`Memory (Process): ${(metrics.meminfo.workingSetSize / 1024).toFixed(2)}MB working set (${(metrics.meminfo.peakWorkingSetSize / 1024).toFixed(2)}MB peak, ${(metrics.meminfo.privateBytes / 1024).toFixed(2)}MB private, ${(metrics.meminfo.sharedBytes / 1024).toFixed(2)}MB shared)`); - console.log(`VM (likelyhood): ${metrics.isVMLikelyhood}%`); - - console.log(`Initial Startup: ${metrics.initialStartup}`); - console.log(`Has ${metrics.windowCount - 1} other windows`); - console.log(`Screen Reader Active: ${metrics.hasAccessibilitySupport}`); - console.log(`Empty Workspace: ${metrics.emptyWorkbench}`); - - let nodeModuleLoadTime: number; - if (this.environmentService.performance) { - const nodeModuleTimes = this.analyzeNodeModulesLoadTimes(); - nodeModuleLoadTime = nodeModuleTimes.duration; - } - - console.table(this.getStartupMetricsTable(metrics, nodeModuleLoadTime)); - - if (this.environmentService.performance) { - const data = this.analyzeLoaderStats(); - for (let type in data) { - console.groupCollapsed(`Loader: ${type}`); - console.table(data[type]); - console.groupEnd(); - } - } - - console.groupEnd(); - - console.group('Extension Activation Stats'); - let extensionsActivationTimes: { [id: string]: ActivationTimes; } = {}; - let extensionsStatus = this.extensionService.getExtensionsStatus(); - for (let id in extensionsStatus) { - const status = extensionsStatus[id]; - if (status.activationTimes) { - extensionsActivationTimes[id] = status.activationTimes; - } - } - console.table(extensionsActivationTimes); - console.groupEnd(); - - console.group('Raw Startup Timers (CSV)'); - let value = `Name\tStart\n`; - let entries = getEntries('mark'); - for (const entry of entries) { - value += `${entry.name}\t${entry.startTime}\n`; - } - console.log(value); - console.groupEnd(); - }); - - return TPromise.as(true); - } - - private getStartupMetricsTable(metrics: IStartupMetrics, nodeModuleLoadTime?: number): any { - const table = Object.create(null); - - table['start => app.isReady'] = { Process: '[main]', 'Took (ms)': metrics.timers.ellapsedAppReady, Meta: metrics.initialStartup }; - table['nls:start => nls:end'] = { Process: '[main]', 'Took (ms)': metrics.timers.ellapsedNlsGeneration, Meta: metrics.initialStartup }; - table['app.isReady => window.loadUrl()'] = { Process: '[main]', 'Took (ms)': metrics.timers.ellapsedWindowLoad, Meta: metrics.initialStartup }; - - table['window.loadUrl() => begin to require(workbench.main.js)'] = { Process: '[main->renderer]', 'Took (ms)': metrics.timers.ellapsedWindowLoadToRequire }; - table['require(workbench.main.js)'] = { Process: '[renderer]', 'Took (ms)': metrics.timers.ellapsedRequire, Meta: metrics.didUseCachedData ? 'did use cached data' : 'did NOT use cached data' }; - - if (nodeModuleLoadTime) { - table['of which require() node_modules'] = { Process: '[renderer]', 'Took (ms)': nodeModuleLoadTime }; - } - - table['register extensions & spawn extension host'] = { Process: '[renderer]', 'Took (ms)': metrics.timers.ellapsedExtensions }; - table['restore viewlet'] = { Process: '[renderer]', 'Took (ms)': metrics.timers.ellapsedViewletRestore, Meta: metrics.viewletId }; - table['restore editor view state'] = { Process: '[renderer]', 'Took (ms)': metrics.timers.ellapsedEditorRestore, Meta: metrics.editorIds.join(', ') }; - table['overall workbench load'] = { Process: '[renderer]', 'Took (ms)': metrics.timers.ellapsedWorkbench }; - - table['workbench ready'] = { Process: '[main, renderer]', 'Took (ms)': metrics.ellapsed }; - table['extensions registered'] = { Process: '[renderer]', 'Took (ms)': metrics.timers.ellapsedExtensionsReady }; - - return table; - } - - private analyzeNodeModulesLoadTimes(): { table: any[], duration: number } { - const stats = (require).getStats(); - const result = []; - - let total = 0; - - for (let i = 0, len = stats.length; i < len; i++) { - if (stats[i].type === LoaderEventType.NodeEndNativeRequire) { - if (stats[i - 1].type === LoaderEventType.NodeBeginNativeRequire && stats[i - 1].detail === stats[i].detail) { - const entry: any = {}; - const dur = (stats[i].timestamp - stats[i - 1].timestamp); - entry['Event'] = 'nodeRequire ' + stats[i].detail; - entry['Took (ms)'] = dur.toFixed(2); - total += dur; - entry['Start (ms)'] = '**' + stats[i - 1].timestamp.toFixed(2); - entry['End (ms)'] = '**' + stats[i - 1].timestamp.toFixed(2); - result.push(entry); - } - } - } - - if (total > 0) { - result.push({ Event: '------------------------------------------------------' }); - - const entry: any = {}; - entry['Event'] = '[renderer] total require() node_modules'; - entry['Took (ms)'] = total.toFixed(2); - entry['Start (ms)'] = '**'; - entry['End (ms)'] = '**'; - result.push(entry); - } - - return { table: result, duration: Math.round(total) }; - } - - private analyzeLoaderStats(): { [type: string]: any[] } { - const stats = (require).getStats().slice(0).sort((a: ILoaderEvent, b: ILoaderEvent) => { - if (a.detail < b.detail) { - return -1; - } else if (a.detail > b.detail) { - return 1; - } else if (a.type < b.type) { - return -1; - } else if (a.type > b.type) { - return 1; - } else { - return 0; - } - }); - - class Tick { - - readonly duration: number; - readonly detail: string; - - constructor(private readonly start: ILoaderEvent, private readonly end: ILoaderEvent) { - console.assert(start.detail === end.detail); - - this.duration = this.end.timestamp - this.start.timestamp; - this.detail = start.detail; - } - - toTableObject() { - return { - ['Path']: this.start.detail, - ['Took (ms)']: this.duration.toFixed(2), - // ['Start (ms)']: this.start.timestamp, - // ['End (ms)']: this.end.timestamp - }; - } - - static compareUsingStartTimestamp(a: Tick, b: Tick): number { - if (a.start.timestamp < b.start.timestamp) { - return -1; - } else if (a.start.timestamp > b.start.timestamp) { - return 1; - } else { - return 0; - } - } - } - - const ticks: { [type: number]: Tick[] } = { - [LoaderEventType.BeginLoadingScript]: [], - [LoaderEventType.BeginInvokeFactory]: [], - [LoaderEventType.NodeBeginEvaluatingScript]: [], - [LoaderEventType.NodeBeginNativeRequire]: [], - }; - - for (let i = 1; i < stats.length - 1; i++) { - const stat = stats[i]; - const nextStat = stats[i + 1]; - - if (nextStat.type - stat.type > 2) { - //bad?! - break; - } - - i += 1; - if (ticks[stat.type]) { - ticks[stat.type].push(new Tick(stat, nextStat)); - } - } - - ticks[LoaderEventType.BeginInvokeFactory].sort(Tick.compareUsingStartTimestamp); - ticks[LoaderEventType.BeginInvokeFactory].sort(Tick.compareUsingStartTimestamp); - ticks[LoaderEventType.NodeBeginEvaluatingScript].sort(Tick.compareUsingStartTimestamp); - ticks[LoaderEventType.NodeBeginNativeRequire].sort(Tick.compareUsingStartTimestamp); - - const ret = { - 'Load Script': ticks[LoaderEventType.BeginLoadingScript].map(t => t.toTableObject()), - '(Node) Load Script': ticks[LoaderEventType.NodeBeginNativeRequire].map(t => t.toTableObject()), - 'Eval Script': ticks[LoaderEventType.BeginInvokeFactory].map(t => t.toTableObject()), - '(Node) Eval Script': ticks[LoaderEventType.NodeBeginEvaluatingScript].map(t => t.toTableObject()), - }; - - function total(ticks: Tick[]): number { - let sum = 0; - for (const tick of ticks) { - sum += tick.duration; - } - return sum; - } - - // totals - ret['Load Script'].push({ - ['Path']: 'TOTAL TIME', - ['Took (ms)']: total(ticks[LoaderEventType.BeginLoadingScript]).toFixed(2) - }); - ret['Eval Script'].push({ - ['Path']: 'TOTAL TIME', - ['Took (ms)']: total(ticks[LoaderEventType.BeginInvokeFactory]).toFixed(2) - }); - ret['(Node) Load Script'].push({ - ['Path']: 'TOTAL TIME', - ['Took (ms)']: total(ticks[LoaderEventType.NodeBeginNativeRequire]).toFixed(2) - }); - ret['(Node) Eval Script'].push({ - ['Path']: 'TOTAL TIME', - ['Took (ms)']: total(ticks[LoaderEventType.NodeBeginEvaluatingScript]).toFixed(2) - }); - - return ret; - } -} - export class ReloadWindowAction extends Action { static readonly ID = 'workbench.action.reloadWindow'; @@ -893,127 +609,6 @@ export class ReportPerformanceIssueUsingReporterAction extends Action { } } -// NOTE: This is still used when running --prof-startup, which already opens a dialog, so the reporter is not used. -export class ReportPerformanceIssueAction extends Action { - - static readonly ID = 'workbench.action.reportPerformanceIssue'; - static readonly LABEL = nls.localize('reportPerformanceIssue', "Report Performance Issue"); - - constructor( - id: string, - label: string, - @IIntegrityService private integrityService: IIntegrityService, - @IEnvironmentService private environmentService: IEnvironmentService, - @ITimerService private timerService: ITimerService - ) { - super(id, label); - } - - run(appendix?: string): TPromise { - Promise.all([ - this.timerService.startupMetrics, - this.integrityService.isPure() - ]).then(([metrics, integrity]) => { - const issueUrl = this.generatePerformanceIssueUrl(metrics, product.reportIssueUrl, pkg.name, pkg.version, product.commit, product.date, integrity.isPure, appendix); - - window.open(issueUrl); - }); - - return TPromise.wrap(true); - } - - private generatePerformanceIssueUrl(metrics: IStartupMetrics, baseUrl: string, name: string, version: string, commit: string, date: string, isPure: boolean, appendix?: string): string { - - if (!appendix) { - appendix = `Additional Steps to Reproduce (if any): - -1. -2.`; - } - - let nodeModuleLoadTime: number; - if (this.environmentService.performance) { - nodeModuleLoadTime = this.computeNodeModulesLoadTime(); - } - - - const osVersion = `${os.type()} ${os.arch()} ${os.release()}`; - const queryStringPrefix = baseUrl.indexOf('?') === -1 ? '?' : '&'; - const body = encodeURIComponent( - `- VSCode Version: ${name} ${version}${isPure ? '' : ' **[Unsupported]**'} (${product.commit || 'Commit unknown'}, ${product.date || 'Date unknown'}) -- OS Version: ${osVersion} -- CPUs: ${metrics.cpus.model} (${metrics.cpus.count} x ${metrics.cpus.speed}) -- Memory (System): ${(metrics.totalmem / (1024 * 1024 * 1024)).toFixed(2)}GB (${(metrics.freemem / (1024 * 1024 * 1024)).toFixed(2)}GB free) -- Memory (Process): ${(metrics.meminfo.workingSetSize / 1024).toFixed(2)}MB working set (${(metrics.meminfo.peakWorkingSetSize / 1024).toFixed(2)}MB peak, ${(metrics.meminfo.privateBytes / 1024).toFixed(2)}MB private, ${(metrics.meminfo.sharedBytes / 1024).toFixed(2)}MB shared) -- Load (avg): ${metrics.loadavg.map(l => Math.round(l)).join(', ')} -- VM: ${metrics.isVMLikelyhood}% -- Initial Startup: ${metrics.initialStartup ? 'yes' : 'no'} -- Screen Reader: ${metrics.hasAccessibilitySupport ? 'yes' : 'no'} -- Empty Workspace: ${metrics.emptyWorkbench ? 'yes' : 'no'} -- Timings: - -${this.generatePerformanceTable(metrics, nodeModuleLoadTime)} - ---- - -${appendix}` - ); - - return `${baseUrl}${queryStringPrefix}body=${body}`; - } - - private computeNodeModulesLoadTime(): number { - const stats = (require).getStats(); - let total = 0; - - for (let i = 0, len = stats.length; i < len; i++) { - if (stats[i].type === LoaderEventType.NodeEndNativeRequire) { - if (stats[i - 1].type === LoaderEventType.NodeBeginNativeRequire && stats[i - 1].detail === stats[i].detail) { - const dur = (stats[i].timestamp - stats[i - 1].timestamp); - total += dur; - } - } - } - - return Math.round(total); - } - - private generatePerformanceTable(metrics: IStartupMetrics, nodeModuleLoadTime?: number): string { - let tableHeader = `|Component|Task|Time (ms)| -|---|---|---|`; - - const table = this.getStartupMetricsTable(metrics, nodeModuleLoadTime).map(e => { - return `|${e.component}|${e.task}|${e.time}|`; - }).join('\n'); - - return `${tableHeader}\n${table}`; - } - - private getStartupMetricsTable(metrics: IStartupMetrics, nodeModuleLoadTime?: number): { component: string, task: string; time: number; }[] { - const table: any[] = []; - - if (metrics.initialStartup) { - table.push({ component: 'main', task: 'start => app.isReady', time: metrics.timers.ellapsedAppReady }); - table.push({ component: 'main', task: 'app.isReady => window.loadUrl()', time: metrics.timers.ellapsedWindowLoad }); - } - - table.push({ component: 'renderer', task: 'window.loadUrl() => begin to require(workbench.main.js)', time: metrics.timers.ellapsedWindowLoadToRequire }); - table.push({ component: 'renderer', task: 'require(workbench.main.js)', time: metrics.timers.ellapsedRequire }); - - if (nodeModuleLoadTime) { - table.push({ component: 'renderer', task: '-> of which require() node_modules', time: nodeModuleLoadTime }); - } - - table.push({ component: 'renderer', task: 'create extension host => extensions onReady()', time: metrics.timers.ellapsedExtensions }); - table.push({ component: 'renderer', task: 'restore viewlet', time: metrics.timers.ellapsedViewletRestore }); - table.push({ component: 'renderer', task: 'restore editor view state', time: metrics.timers.ellapsedEditorRestore }); - table.push({ component: 'renderer', task: 'overall workbench load', time: metrics.timers.ellapsedWorkbench }); - table.push({ component: 'main + renderer', task: 'start => extensions ready', time: metrics.timers.ellapsedExtensionsReady }); - table.push({ component: 'main + renderer', task: 'start => workbench ready', time: metrics.ellapsed }); - - return table; - } -} export class KeybindingsReferenceAction extends Action { diff --git a/src/vs/workbench/electron-browser/main.contribution.ts b/src/vs/workbench/electron-browser/main.contribution.ts index 150d1754371..b5ea1f2025f 100644 --- a/src/vs/workbench/electron-browser/main.contribution.ts +++ b/src/vs/workbench/electron-browser/main.contribution.ts @@ -14,7 +14,7 @@ import { IConfigurationRegistry, Extensions as ConfigurationExtensions, Configur import { IWorkbenchActionRegistry, Extensions } from 'vs/workbench/common/actions'; import { KeyMod, KeyChord, KeyCode } from 'vs/base/common/keyCodes'; import { isWindows, isLinux, isMacintosh } from 'vs/base/common/platform'; -import { KeybindingsReferenceAction, OpenDocumentationUrlAction, OpenIntroductoryVideosUrlAction, OpenTipsAndTricksUrlAction, OpenIssueReporterAction, ReportPerformanceIssueUsingReporterAction, ZoomResetAction, ZoomOutAction, ZoomInAction, ToggleFullScreenAction, ToggleMenuBarAction, CloseWorkspaceAction, CloseCurrentWindowAction, SwitchWindow, NewWindowAction, NavigateUpAction, NavigateDownAction, NavigateLeftAction, NavigateRightAction, IncreaseViewSizeAction, DecreaseViewSizeAction, ShowStartupPerformance, ToggleSharedProcessAction, QuickSwitchWindow, QuickOpenRecentAction, inRecentFilesPickerContextKey, ShowAboutDialogAction, InspectContextKeysAction, OpenProcessExplorer, OpenTwitterUrlAction, OpenRequestFeatureUrlAction, OpenPrivacyStatementUrlAction, OpenLicenseUrlAction, OpenRecentAction } from 'vs/workbench/electron-browser/actions'; +import { KeybindingsReferenceAction, OpenDocumentationUrlAction, OpenIntroductoryVideosUrlAction, OpenTipsAndTricksUrlAction, OpenIssueReporterAction, ReportPerformanceIssueUsingReporterAction, ZoomResetAction, ZoomOutAction, ZoomInAction, ToggleFullScreenAction, ToggleMenuBarAction, CloseWorkspaceAction, CloseCurrentWindowAction, SwitchWindow, NewWindowAction, NavigateUpAction, NavigateDownAction, NavigateLeftAction, NavigateRightAction, IncreaseViewSizeAction, DecreaseViewSizeAction, ToggleSharedProcessAction, QuickSwitchWindow, QuickOpenRecentAction, inRecentFilesPickerContextKey, ShowAboutDialogAction, InspectContextKeysAction, OpenProcessExplorer, OpenTwitterUrlAction, OpenRequestFeatureUrlAction, OpenPrivacyStatementUrlAction, OpenLicenseUrlAction, OpenRecentAction } from 'vs/workbench/electron-browser/actions'; import { registerCommands, QUIT_ID } from 'vs/workbench/electron-browser/commands'; import { AddRootFolderAction, GlobalRemoveRootFolderAction, OpenWorkspaceAction, SaveWorkspaceAsAction, OpenWorkspaceConfigFileAction, DuplicateWorkspaceInNewWindowAction, OpenFileFolderAction, OpenFileAction, OpenFolderAction } from 'vs/workbench/browser/actions/workspaceActions'; import { ContextKeyExpr, RawContextKey } from 'vs/platform/contextkey/common/contextkey'; @@ -124,7 +124,6 @@ MenuRegistry.appendMenuItem(MenuId.CommandPalette, { // Developer related actions const developerCategory = nls.localize('developer', "Developer"); -workbenchActionsRegistry.registerWorkbenchAction(new SyncActionDescriptor(ShowStartupPerformance, ShowStartupPerformance.ID, ShowStartupPerformance.LABEL), 'Developer: Startup Performance', developerCategory); workbenchActionsRegistry.registerWorkbenchAction(new SyncActionDescriptor(ToggleSharedProcessAction, ToggleSharedProcessAction.ID, ToggleSharedProcessAction.LABEL), 'Developer: Toggle Shared Process', developerCategory); workbenchActionsRegistry.registerWorkbenchAction(new SyncActionDescriptor(InspectContextKeysAction, InspectContextKeysAction.ID, InspectContextKeysAction.LABEL), 'Developer: Inspect Context Keys', developerCategory); workbenchActionsRegistry.registerWorkbenchAction(new SyncActionDescriptor(OpenProcessExplorer, OpenProcessExplorer.ID, OpenProcessExplorer.LABEL), 'Developer: Open Process Explorer', developerCategory); diff --git a/src/vs/workbench/parts/performance/electron-browser/actions.ts b/src/vs/workbench/parts/performance/electron-browser/actions.ts new file mode 100644 index 00000000000..b6824084675 --- /dev/null +++ b/src/vs/workbench/parts/performance/electron-browser/actions.ts @@ -0,0 +1,408 @@ +/*--------------------------------------------------------------------------------------------- + * 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 { TPromise } from 'vs/base/common/winjs.base'; +import { Action } from 'vs/base/common/actions'; +import { IWindowService } from 'vs/platform/windows/common/windows'; +import * as nls from 'vs/nls'; +import product from 'vs/platform/node/product'; +import pkg from 'vs/platform/node/package'; +import { IEnvironmentService } from 'vs/platform/environment/common/environment'; +import { IIntegrityService } from 'vs/platform/integrity/common/integrity'; +import { ITimerService, IStartupMetrics } from 'vs/workbench/services/timer/electron-browser/timerService'; +import * as os from 'os'; +import { IExtensionService, ActivationTimes } from 'vs/workbench/services/extensions/common/extensions'; +import { getEntries } from 'vs/base/common/performance'; +import { timeout } from 'vs/base/common/async'; +import { StartupKind } from 'vs/platform/lifecycle/common/lifecycle'; +import { Registry } from 'vs/platform/registry/common/platform'; +import { IWorkbenchActionRegistry, Extensions } from 'vs/workbench/common/actions'; +import { SyncActionDescriptor } from 'vs/platform/actions/common/actions'; +import { forEach } from 'vs/base/common/collections'; + +/* Copied from loader.ts */ +enum LoaderEventType { + LoaderAvailable = 1, + + BeginLoadingScript = 10, + EndLoadingScriptOK = 11, + EndLoadingScriptError = 12, + + BeginInvokeFactory = 21, + EndInvokeFactory = 22, + + NodeBeginEvaluatingScript = 31, + NodeEndEvaluatingScript = 32, + + NodeBeginNativeRequire = 33, + NodeEndNativeRequire = 34 +} + +interface ILoaderEvent { + type: LoaderEventType; + timestamp: number; + detail: string; +} + + +class Info { + + static getTimerInfo(metrics: IStartupMetrics, nodeModuleLoadTime?: number): { [name: string]: Info } { + const table: { [name: string]: Info } = Object.create(null); + table['start => app.isReady'] = new Info(metrics.timers.ellapsedAppReady, '[main]', metrics.initialStartup); + table['nls:start => nls:end'] = new Info(metrics.timers.ellapsedNlsGeneration, '[main]', metrics.initialStartup); + table['app.isReady => window.loadUrl()'] = new Info(metrics.timers.ellapsedWindowLoad, '[main]', metrics.initialStartup); + + table['window.loadUrl() => begin to require(workbench.main.js)'] = new Info(metrics.timers.ellapsedWindowLoadToRequire, '[main->renderer]', StartupKind[metrics.windowKind]); + table['require(workbench.main.js)'] = new Info(metrics.timers.ellapsedRequire, '[renderer]', `cached data: ${(metrics.didUseCachedData ? 'YES' : 'NO')}${nodeModuleLoadTime ? `, node_modules took ${nodeModuleLoadTime}ms` : ''}`); + + table['register extensions & spawn extension host'] = new Info(metrics.timers.ellapsedExtensions, '[renderer]'); + table['restore viewlet'] = new Info(metrics.timers.ellapsedViewletRestore, '[renderer]', metrics.viewletId); + table['restore panel'] = new Info(metrics.timers.ellapsedPanelRestore, '[renderer]', metrics.panelId); + table['restore editors'] = new Info(metrics.timers.ellapsedEditorRestore, '[renderer]', `${metrics.editorIds.length}: ${metrics.editorIds.join(', ')}`); + table['overall workbench load'] = new Info(metrics.timers.ellapsedWorkbench, '[renderer]'); + + table['workbench ready'] = new Info(metrics.ellapsed, '[main->renderer]'); + table['extensions registered'] = new Info(metrics.timers.ellapsedExtensionsReady, '[renderer]'); + + return table; + } + + private constructor(readonly duration: number, readonly process: string, readonly info: string | boolean = '') { } +} + + +export class ShowStartupPerformance extends Action { + + static readonly ID = 'workbench.action.appPerf'; + static readonly LABEL = nls.localize('appPerf', "Startup Performance"); + + constructor( + id: string, + label: string, + @IWindowService private windowService: IWindowService, + @ITimerService private timerService: ITimerService, + @IEnvironmentService private environmentService: IEnvironmentService, + @IExtensionService private extensionService: IExtensionService + ) { + super(id, label); + } + + run(): TPromise { + + // Show dev tools + this.windowService.openDevTools(); + + Promise.all([ + timeout(1000), // needed to print a table + this.timerService.startupMetrics + ]).then(([, metrics]) => { + + console.group('Startup Performance Measurement'); + console.log(`OS: ${metrics.platform}(${metrics.release})`); + console.log(`CPUs: ${metrics.cpus.model}(${metrics.cpus.count} x ${metrics.cpus.speed})`); + console.log(`Memory(System): ${(metrics.totalmem / (1024 * 1024 * 1024)).toFixed(2)} GB(${(metrics.freemem / (1024 * 1024 * 1024)).toFixed(2)}GB free)`); + console.log(`Memory(Process): ${(metrics.meminfo.workingSetSize / 1024).toFixed(2)} MB working set(${(metrics.meminfo.peakWorkingSetSize / 1024).toFixed(2)}MB peak, ${(metrics.meminfo.privateBytes / 1024).toFixed(2)}MB private, ${(metrics.meminfo.sharedBytes / 1024).toFixed(2)}MB shared)`); + console.log(`VM(likelyhood): ${metrics.isVMLikelyhood}% `); + + console.log(`Initial Startup: ${metrics.initialStartup} `); + console.log(`Has ${metrics.windowCount - 1} other windows`); + console.log(`Screen Reader Active: ${metrics.hasAccessibilitySupport} `); + console.log(`Empty Workspace: ${metrics.emptyWorkbench} `); + + let nodeModuleLoadTime: number; + if (this.environmentService.performance) { + const nodeModuleTimes = this.analyzeNodeModulesLoadTimes(); + nodeModuleLoadTime = nodeModuleTimes.duration; + } + + console.table(Info.getTimerInfo(metrics, nodeModuleLoadTime)); + + if (this.environmentService.performance) { + const data = this.analyzeLoaderStats(); + for (let type in data) { + console.groupCollapsed(`Loader: ${type} `); + console.table(data[type]); + console.groupEnd(); + } + } + + console.groupEnd(); + + console.group('Extension Activation Stats'); + let extensionsActivationTimes: { [id: string]: ActivationTimes; } = {}; + let extensionsStatus = this.extensionService.getExtensionsStatus(); + for (let id in extensionsStatus) { + const status = extensionsStatus[id]; + if (status.activationTimes) { + extensionsActivationTimes[id] = status.activationTimes; + } + } + console.table(extensionsActivationTimes); + console.groupEnd(); + + console.group('Raw Startup Timers (CSV)'); + let value = `Name\tStart\n`; + let entries = getEntries('mark'); + for (const entry of entries) { + value += `${entry.name} \t${entry.startTime} \n`; + } + console.log(value); + console.groupEnd(); + }); + + return TPromise.as(true); + } + + private analyzeNodeModulesLoadTimes(): { table: any[], duration: number } { + const stats = (require).getStats(); + const result = []; + + let total = 0; + + for (let i = 0, len = stats.length; i < len; i++) { + if (stats[i].type === LoaderEventType.NodeEndNativeRequire) { + if (stats[i - 1].type === LoaderEventType.NodeBeginNativeRequire && stats[i - 1].detail === stats[i].detail) { + const entry: any = {}; + const dur = (stats[i].timestamp - stats[i - 1].timestamp); + entry['Event'] = 'nodeRequire ' + stats[i].detail; + entry['Took (ms)'] = dur.toFixed(2); + total += dur; + entry['Start (ms)'] = '**' + stats[i - 1].timestamp.toFixed(2); + entry['End (ms)'] = '**' + stats[i - 1].timestamp.toFixed(2); + result.push(entry); + } + } + } + + if (total > 0) { + result.push({ Event: '------------------------------------------------------' }); + + const entry: any = {}; + entry['Event'] = '[renderer] total require() node_modules'; + entry['Took (ms)'] = total.toFixed(2); + entry['Start (ms)'] = '**'; + entry['End (ms)'] = '**'; + result.push(entry); + } + + return { table: result, duration: Math.round(total) }; + } + + private analyzeLoaderStats(): { [type: string]: any[] } { + const stats = (require).getStats().slice(0).sort((a: ILoaderEvent, b: ILoaderEvent) => { + if (a.detail < b.detail) { + return -1; + } else if (a.detail > b.detail) { + return 1; + } else if (a.type < b.type) { + return -1; + } else if (a.type > b.type) { + return 1; + } else { + return 0; + } + }); + + class Tick { + + readonly duration: number; + readonly detail: string; + + constructor(private readonly start: ILoaderEvent, private readonly end: ILoaderEvent) { + console.assert(start.detail === end.detail); + + this.duration = this.end.timestamp - this.start.timestamp; + this.detail = start.detail; + } + + toTableObject() { + return { + ['Path']: this.start.detail, + ['Took (ms)']: this.duration.toFixed(2), + // ['Start (ms)']: this.start.timestamp, + // ['End (ms)']: this.end.timestamp + }; + } + + static compareUsingStartTimestamp(a: Tick, b: Tick): number { + if (a.start.timestamp < b.start.timestamp) { + return -1; + } else if (a.start.timestamp > b.start.timestamp) { + return 1; + } else { + return 0; + } + } + } + + const ticks: { [type: number]: Tick[] } = { + [LoaderEventType.BeginLoadingScript]: [], + [LoaderEventType.BeginInvokeFactory]: [], + [LoaderEventType.NodeBeginEvaluatingScript]: [], + [LoaderEventType.NodeBeginNativeRequire]: [], + }; + + for (let i = 1; i < stats.length - 1; i++) { + const stat = stats[i]; + const nextStat = stats[i + 1]; + + if (nextStat.type - stat.type > 2) { + //bad?! + break; + } + + i += 1; + if (ticks[stat.type]) { + ticks[stat.type].push(new Tick(stat, nextStat)); + } + } + + ticks[LoaderEventType.BeginInvokeFactory].sort(Tick.compareUsingStartTimestamp); + ticks[LoaderEventType.BeginInvokeFactory].sort(Tick.compareUsingStartTimestamp); + ticks[LoaderEventType.NodeBeginEvaluatingScript].sort(Tick.compareUsingStartTimestamp); + ticks[LoaderEventType.NodeBeginNativeRequire].sort(Tick.compareUsingStartTimestamp); + + const ret = { + 'Load Script': ticks[LoaderEventType.BeginLoadingScript].map(t => t.toTableObject()), + '(Node) Load Script': ticks[LoaderEventType.NodeBeginNativeRequire].map(t => t.toTableObject()), + 'Eval Script': ticks[LoaderEventType.BeginInvokeFactory].map(t => t.toTableObject()), + '(Node) Eval Script': ticks[LoaderEventType.NodeBeginEvaluatingScript].map(t => t.toTableObject()), + }; + + function total(ticks: Tick[]): number { + let sum = 0; + for (const tick of ticks) { + sum += tick.duration; + } + return sum; + } + + // totals + ret['Load Script'].push({ + ['Path']: 'TOTAL TIME', + ['Took (ms)']: total(ticks[LoaderEventType.BeginLoadingScript]).toFixed(2) + }); + ret['Eval Script'].push({ + ['Path']: 'TOTAL TIME', + ['Took (ms)']: total(ticks[LoaderEventType.BeginInvokeFactory]).toFixed(2) + }); + ret['(Node) Load Script'].push({ + ['Path']: 'TOTAL TIME', + ['Took (ms)']: total(ticks[LoaderEventType.NodeBeginNativeRequire]).toFixed(2) + }); + ret['(Node) Eval Script'].push({ + ['Path']: 'TOTAL TIME', + ['Took (ms)']: total(ticks[LoaderEventType.NodeBeginEvaluatingScript]).toFixed(2) + }); + + return ret; + } +} + + +// NOTE: This is still used when running --prof-startup, which already opens a dialog, so the reporter is not used. +export class ReportPerformanceIssueAction extends Action { + + static readonly ID = 'workbench.action.reportPerformanceIssue'; + static readonly LABEL = nls.localize('reportPerformanceIssue', "Report Performance Issue"); + + constructor( + id: string, + label: string, + @IIntegrityService private integrityService: IIntegrityService, + @IEnvironmentService private environmentService: IEnvironmentService, + @ITimerService private timerService: ITimerService + ) { + super(id, label); + } + + run(appendix?: string): TPromise { + Promise.all([ + this.timerService.startupMetrics, + this.integrityService.isPure() + ]).then(([metrics, integrity]) => { + const issueUrl = this.generatePerformanceIssueUrl(metrics, product.reportIssueUrl, pkg.name, pkg.version, product.commit, product.date, integrity.isPure, appendix); + + window.open(issueUrl); + }); + + return TPromise.wrap(true); + } + + private generatePerformanceIssueUrl(metrics: IStartupMetrics, baseUrl: string, name: string, version: string, _commit: string, _date: string, isPure: boolean, appendix?: string): string { + + if (!appendix) { + appendix = `Additional Steps to Reproduce(if any): + + 1. +2.`; + } + + let nodeModuleLoadTime: number; + if (this.environmentService.performance) { + nodeModuleLoadTime = this.computeNodeModulesLoadTime(); + } + + + const osVersion = `${os.type()} ${os.arch()} ${os.release()} `; + const queryStringPrefix = baseUrl.indexOf('?') === -1 ? '?' : '&'; + const body = encodeURIComponent( + `- VSCode Version: ${name} ${version} ${isPure ? '' : ' **[Unsupported]**'} (${product.commit || 'Commit unknown'}, ${product.date || 'Date unknown'}) + - OS Version: ${ osVersion} + - CPUs: ${ metrics.cpus.model} (${metrics.cpus.count} x ${metrics.cpus.speed}) + - Memory(System): ${ (metrics.totalmem / (1024 * 1024 * 1024)).toFixed(2)} GB(${(metrics.freemem / (1024 * 1024 * 1024)).toFixed(2)}GB free) < /code> + - Memory(Process): ${ (metrics.meminfo.workingSetSize / 1024).toFixed(2)} MB working set(${(metrics.meminfo.peakWorkingSetSize / 1024).toFixed(2)}MB peak, ${(metrics.meminfo.privateBytes / 1024).toFixed(2)}MB private, ${(metrics.meminfo.sharedBytes / 1024).toFixed(2)}MB shared) < /code> + - Load(avg): ${ metrics.loadavg.map(l => Math.round(l)).join(', ')} + - VM: ${ metrics.isVMLikelyhood}% + - Initial Startup: ${ metrics.initialStartup ? 'yes' : 'no'} + - Screen Reader: ${ metrics.hasAccessibilitySupport ? 'yes' : 'no'} + - Empty Workspace: ${ metrics.emptyWorkbench ? 'yes' : 'no'} + - Timings: + +${ this.generatePerformanceTable(metrics, nodeModuleLoadTime)} + +--- + + ${ appendix} ` + ); + + return `${baseUrl} ${queryStringPrefix} body = ${body} `; + } + + private computeNodeModulesLoadTime(): number { + const stats = (require).getStats(); + let total = 0; + + for (let i = 0, len = stats.length; i < len; i++) { + if (stats[i].type === LoaderEventType.NodeEndNativeRequire) { + if (stats[i - 1].type === LoaderEventType.NodeBeginNativeRequire && stats[i - 1].detail === stats[i].detail) { + const dur = (stats[i].timestamp - stats[i - 1].timestamp); + total += dur; + } + } + } + + return Math.round(total); + } + + private generatePerformanceTable(metrics: IStartupMetrics, nodeModuleLoadTime?: number): string { + let tableHeader = `| Component | Task | Duration(ms) | Info | +| ---| ---| ---| ---| `; + + let table = ''; + forEach(Info.getTimerInfo(metrics, nodeModuleLoadTime), e => { + table += `| ${e.value.process}| ${e.key}| ${e.value.duration}| ${e.value.info}|\n`; + }); + + return `${tableHeader} \n${table} `; + } +} + +Registry + .as(Extensions.WorkbenchActions) + .registerWorkbenchAction(new SyncActionDescriptor(ShowStartupPerformance, ShowStartupPerformance.ID, ShowStartupPerformance.LABEL), 'Developer: Startup Performance', nls.localize('developer', "Developer")); diff --git a/src/vs/workbench/parts/performance/electron-browser/startupProfiler.ts b/src/vs/workbench/parts/performance/electron-browser/startupProfiler.ts index 75df0ee2fa3..09fab3522c3 100644 --- a/src/vs/workbench/parts/performance/electron-browser/startupProfiler.ts +++ b/src/vs/workbench/parts/performance/electron-browser/startupProfiler.ts @@ -12,7 +12,7 @@ import { ILifecycleService, LifecyclePhase } from 'vs/platform/lifecycle/common/ import { IWindowsService } from 'vs/platform/windows/common/windows'; import { IWorkbenchContributionsRegistry, IWorkbenchContribution, Extensions } from 'vs/workbench/common/contributions'; import { Registry } from 'vs/platform/registry/common/platform'; -import { ReportPerformanceIssueAction } from 'vs/workbench/electron-browser/actions'; + import { TPromise } from 'vs/base/common/winjs.base'; import { join, dirname } from 'path'; import { localize } from 'vs/nls'; @@ -20,6 +20,7 @@ import { readdir, del, readFile } from 'vs/base/node/pfs'; import { basename } from 'vs/base/common/paths'; import { IDialogService } from 'vs/platform/dialogs/common/dialogs'; import { timeout } from 'vs/base/common/async'; +import { ReportPerformanceIssueAction } from 'vs/workbench/parts/performance/electron-browser/actions'; class StartupProfiler implements IWorkbenchContribution { From eb1fbf0ee656f1bdc5327d595fa0a90ba6e53240 Mon Sep 17 00:00:00 2001 From: Johannes Rieken Date: Fri, 17 Aug 2018 12:09:07 +0200 Subject: [PATCH 0934/1276] add `ellapsedPanelRestore` to perf metrics, #56253 --- src/vs/workbench/electron-browser/workbench.ts | 8 +++----- .../services/timer/electron-browser/timerService.ts | 12 ++++++++++++ 2 files changed, 15 insertions(+), 5 deletions(-) diff --git a/src/vs/workbench/electron-browser/workbench.ts b/src/vs/workbench/electron-browser/workbench.ts index 443d3f56d8f..78add76eb65 100644 --- a/src/vs/workbench/electron-browser/workbench.ts +++ b/src/vs/workbench/electron-browser/workbench.ts @@ -730,12 +730,10 @@ export class Workbench extends Disposable implements IPartService { const panelRegistry = Registry.as(PanelExtensions.Panels); const panelId = this.storageService.get(PanelPart.activePanelSettingsKey, StorageScope.WORKSPACE, panelRegistry.getDefaultPanelId()); if (!this.panelHidden && !!panelId) { + perf.mark('willRestorePanel'); const isPanelToRestoreEnabled = !!this.panelPart.getPanels().filter(p => p.id === panelId).length; - if (isPanelToRestoreEnabled) { - restorePromises.push(this.panelPart.openPanel(panelId, false)); - } else { - restorePromises.push(this.panelPart.openPanel(panelRegistry.getDefaultPanelId(), false)); - } + const panelIdToRestore = isPanelToRestoreEnabled ? panelId : panelRegistry.getDefaultPanelId(); + restorePromises.push(this.panelPart.openPanel(panelIdToRestore, false).then(() => perf.mark('didRestorePanel'))); } // Restore Zen Mode if active diff --git a/src/vs/workbench/services/timer/electron-browser/timerService.ts b/src/vs/workbench/services/timer/electron-browser/timerService.ts index 8a1c7b23914..573c22feccf 100644 --- a/src/vs/workbench/services/timer/electron-browser/timerService.ts +++ b/src/vs/workbench/services/timer/electron-browser/timerService.ts @@ -55,6 +55,7 @@ export interface IMemoryInfo { "timers.ellapsedExtensionsReady" : { "classification": "SystemMetaData", "purpose": "PerformanceAndHealth", "isMeasurement": true }, "timers.ellapsedRequire" : { "classification": "SystemMetaData", "purpose": "PerformanceAndHealth", "isMeasurement": true }, "timers.ellapsedViewletRestore" : { "classification": "SystemMetaData", "purpose": "PerformanceAndHealth", "isMeasurement": true }, + "timers.ellapsedPanelRestore" : { "classification": "SystemMetaData", "purpose": "PerformanceAndHealth", "isMeasurement": true }, "timers.ellapsedEditorRestore" : { "classification": "SystemMetaData", "purpose": "PerformanceAndHealth", "isMeasurement": true }, "timers.ellapsedWorkbench" : { "classification": "SystemMetaData", "purpose": "PerformanceAndHealth", "isMeasurement": true }, "timers.ellapsedTimersToTimersComputed" : { "classification": "SystemMetaData", "purpose": "PerformanceAndHealth", "isMeasurement": true }, @@ -231,6 +232,16 @@ export interface IStartupMetrics { */ ellapsedViewletRestore: number; + /** + * The time it took to restore the panel. + * + * * Happens in the renderer-process + * * Measured with the `willRestorePanel` and `didRestorePanel` performance marks. + * * This should be looked at per panel-type/id. + * * Happens in parallel to other things, depends on async timing + */ + ellapsedPanelRestore: number; + /** * The time it took to restore editors - that is text editor and complex editor likes the settings UI * or webviews (markdown preview). @@ -355,6 +366,7 @@ class TimerService implements ITimerService { ellapsedExtensions: perf.getDuration('willLoadExtensions', 'didLoadExtensions'), ellapsedEditorRestore: perf.getDuration('willRestoreEditors', 'didRestoreEditors'), ellapsedViewletRestore: perf.getDuration('willRestoreViewlet', 'didRestoreViewlet'), + ellapsedPanelRestore: perf.getDuration('willRestorePanel', 'didRestorePanel'), ellapsedWorkbench: perf.getDuration('willStartWorkbench', 'didStartWorkbench'), ellapsedExtensionsReady: perf.getDuration(startMark, 'didLoadExtensions'), ellapsedTimersToTimersComputed: Date.now() - now, From 7a3bd6d056a1aaaa7e68a647e1cce931e23f2443 Mon Sep 17 00:00:00 2001 From: Johannes Rieken Date: Fri, 17 Aug 2018 12:24:27 +0200 Subject: [PATCH 0935/1276] perf - make sure to compute startup metrics not too early, #56253 --- .../timer/electron-browser/timerService.ts | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/src/vs/workbench/services/timer/electron-browser/timerService.ts b/src/vs/workbench/services/timer/electron-browser/timerService.ts index 573c22feccf..feb7c0b467b 100644 --- a/src/vs/workbench/services/timer/electron-browser/timerService.ts +++ b/src/vs/workbench/services/timer/electron-browser/timerService.ts @@ -291,7 +291,7 @@ class TimerService implements ITimerService { _serviceBrand: any; - readonly startupMetrics: Promise; + private _startupMetrics: Promise; constructor( @IWindowsService private readonly _windowsService: IWindowsService, @@ -304,12 +304,19 @@ class TimerService implements ITimerService { @IPanelService private readonly _panelService: IPanelService, @IEditorService private readonly _editorService: IEditorService, ) { - this.startupMetrics = Promise - .resolve(this._extensionService.whenInstalledExtensionsRegistered()) - .then(() => this._computeStartupMetrics()); + } + + get startupMetrics(): Promise { + if (!this._startupMetrics) { + this._startupMetrics = Promise + .resolve(this._extensionService.whenInstalledExtensionsRegistered()) + .then(() => this._computeStartupMetrics()); + } + return this._startupMetrics; } private async _computeStartupMetrics(): Promise { + const now = Date.now(); const initialStartup = !!this._windowService.getConfiguration().isInitialStartup; const startMark = initialStartup ? 'main:started' : 'main:loadWindow'; From e2b5c5d870acc31c9ed55d101c7c15ccefcafcf1 Mon Sep 17 00:00:00 2001 From: Johannes Rieken Date: Fri, 17 Aug 2018 15:09:42 +0200 Subject: [PATCH 0936/1276] prevent picker overflow, #56318 --- .../browser/parts/editor/breadcrumbsControl.ts | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/vs/workbench/browser/parts/editor/breadcrumbsControl.ts b/src/vs/workbench/browser/parts/editor/breadcrumbsControl.ts index 125b7a5af66..d18f6210769 100644 --- a/src/vs/workbench/browser/parts/editor/breadcrumbsControl.ts +++ b/src/vs/workbench/browser/parts/editor/breadcrumbsControl.ts @@ -292,23 +292,23 @@ export class BreadcrumbsControl { return combinedDisposable([listener, picker]); }, getAnchor: () => { - + let maxInnerWidth = window.innerWidth - 8 /*a little less the the full widget*/; let pickerHeight = 330; - let pickerWidth = window.innerWidth / 4.17; + 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; let x = data.left; - if (x + pickerWidth >= window.innerWidth) { - x = window.innerWidth - pickerWidth; + 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 += pickerArrowOffset - maxPickerArrowOffset; + x = Math.min(maxInnerWidth - pickerWidth, x + pickerArrowOffset - maxPickerArrowOffset); pickerArrowOffset = maxPickerArrowOffset; } } else { From 1115196349c72cfacefc479ee0334f18dea4d193 Mon Sep 17 00:00:00 2001 From: Johannes Rieken Date: Fri, 17 Aug 2018 15:56:57 +0200 Subject: [PATCH 0937/1276] add a shared webpack conifg --- extensions/emmet/extension.webpack.config.js | 38 ++------------ extensions/git/extension.webpack.config.js | 40 +++------------ extensions/shared.webpack.config.js | 52 ++++++++++++++++++++ 3 files changed, 63 insertions(+), 67 deletions(-) create mode 100644 extensions/shared.webpack.config.js diff --git a/extensions/emmet/extension.webpack.config.js b/extensions/emmet/extension.webpack.config.js index 791034eac7f..55b15a2701a 100644 --- a/extensions/emmet/extension.webpack.config.js +++ b/extensions/emmet/extension.webpack.config.js @@ -5,44 +5,14 @@ 'use strict'; -const path = require('path'); +const sharedConfig = require('../shared.webpack.config'); -module.exports = { - // mode: 'production', - // stats: 'errors-only', - mode: 'none', - context: __dirname, - target: 'node', +const myConfig = { entry: { extension: './src/extension.ts', }, - resolve: { - mainFields: ['main'], - extensions: [".ts", ".js"] - }, - module: { - rules: [{ - test: /\.ts$/, - exclude: /node_modules/, - use: [{ - loader: 'ts-loader', - options: { - transpileOnly: true, - compilerOptions: { - "sourceMap": true, - } - } - }] - }] - }, - output: { - filename: '[name].js', - path: path.join(__dirname, 'dist'), - libraryTarget: "commonjs", - }, - devtool: 'source-map', externals: { - 'vscode': 'commonjs vscode', + 'vscode': 'commonjs vscode', // ignored because it doesn't exist '@emmetio/css-parser': 'commonjs @emmetio/css-parser', '@emmetio/html-matcher': 'commonjs @emmetio/html-matcher', '@emmetio/math-expression': 'commonjs @emmetio/math-expression', @@ -50,3 +20,5 @@ module.exports = { 'vscode-emmet-helper': 'commonjs vscode-emmet-helper', }, }; + +module.exports = { ...sharedConfig(__dirname), ...myConfig }; diff --git a/extensions/git/extension.webpack.config.js b/extensions/git/extension.webpack.config.js index 832583ffa27..75643a14039 100644 --- a/extensions/git/extension.webpack.config.js +++ b/extensions/git/extension.webpack.config.js @@ -5,55 +5,25 @@ 'use strict'; -const path = require('path'); +const sharedConfig = require('../shared.webpack.config'); const CopyWebpackPlugin = require('copy-webpack-plugin'); -module.exports = { - // mode: 'production', - // stats: 'errors-only', - mode: 'none', - context: __dirname, - target: 'node', +const myConfig = { node: { - __dirname: false + __dirname: false // leave the __dirname-behaviour intact }, entry: { main: './src/main.ts', ['askpass-main']: './src/askpass-main.ts' }, - resolve: { - mainFields: ['main'], - extensions: [".ts", ".js"] - }, - module: { - rules: [{ - test: /\.ts$/, - exclude: /node_modules/, - use: [{ - loader: 'ts-loader', - options: { - transpileOnly: true, - compilerOptions: { - "sourceMap": true, - } - } - }] - }] - }, - output: { - filename: '[name].js', - path: path.join(__dirname, 'dist'), - libraryTarget: "commonjs" - }, plugins: [ new CopyWebpackPlugin([ { from: './out/*.sh', to: '[name].sh' }, { from: './out/nls.*.json', to: '[name].json' } ]) ], - devtool: 'source-map', externals: { - 'vscode': 'commonjs vscode', + 'vscode': 'commonjs vscode', // ignored because it doesn't exist "byline": 'commonjs byline', "file-type": 'commonjs file-type', "iconv-lite": 'commonjs iconv-lite', @@ -63,3 +33,5 @@ module.exports = { "which": 'commonjs which', }, }; + +module.exports = { ...sharedConfig(__dirname), ...myConfig }; diff --git a/extensions/shared.webpack.config.js b/extensions/shared.webpack.config.js new file mode 100644 index 00000000000..8c48c9c5be9 --- /dev/null +++ b/extensions/shared.webpack.config.js @@ -0,0 +1,52 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +'use strict'; + +const path = require('path'); + +/** + * Function that must be invoked with __dirname and that + * returns a good default configuation for extensions that + * want to do webpack + */ +module.exports = function (extensionDir) { + return { + context: extensionDir, + mode: 'none', // this leaves the source code as close as possible to the original (when packaging we set this to 'production') + target: 'node', // extensions run in a node context + resolve: { + mainFields: ['main'], // prefer the main-entry of package.json files + extensions: [".ts", ".js"] // support ts-files and js-files + }, + module: { + rules: [{ + // configure TypeScript loader: + // * only transpile because we have a separate compilation pipeline + // * enable sources maps for end-to-end source maps + test: /\.ts$/, + exclude: /node_modules/, + use: [{ + loader: 'ts-loader', + options: { + transpileOnly: true, + compilerOptions: { + "sourceMap": true, + } + } + }] + }] + }, + output: { + // all output goes into `dist`. + // packaging depends on that and this must always be like it + filename: '[name].js', + path: path.join(extensionDir, 'dist'), + libraryTarget: "commonjs", + }, + // yes, really source maps + devtool: 'source-map' + }; +}; From 418808ac75aa1cceb4e2cd115c51c08094faa49e Mon Sep 17 00:00:00 2001 From: Johannes Rieken Date: Fri, 17 Aug 2018 15:57:09 +0200 Subject: [PATCH 0938/1276] remove unused dependency --- package.json | 1 - yarn.lock | 27 --------------------------- 2 files changed, 28 deletions(-) diff --git a/package.json b/package.json index 4ce476468c7..c7e62c12d3f 100644 --- a/package.json +++ b/package.json @@ -117,7 +117,6 @@ "rimraf": "^2.2.8", "sinon": "^1.17.2", "source-map": "^0.4.4", - "source-map-loader": "^0.2.3", "ts-loader": "^4.4.2", "tslint": "^5.9.1", "typescript": "2.9.2", diff --git a/yarn.lock b/yarn.lock index e3b7585aa1b..b56aa332449 100644 --- a/yarn.lock +++ b/yarn.lock @@ -540,12 +540,6 @@ async@^2.0.1: dependencies: lodash "^4.14.0" -async@^2.5.0: - version "2.6.1" - resolved "https://registry.yarnpkg.com/async/-/async-2.6.1.tgz#b245a23ca71930044ec53fa46aa00a3e87c6a610" - dependencies: - lodash "^4.17.10" - async@~0.2.8: version "0.2.10" resolved "https://registry.yarnpkg.com/async/-/async-0.2.10.tgz#b6bbe0b0674b9d719708ca38de8c237cb526c3d1" @@ -4320,15 +4314,6 @@ loader-utils@^1.0.2, loader-utils@^1.1.0: emojis-list "^2.0.0" json5 "^0.5.0" -loader-utils@~0.2.2: - version "0.2.17" - resolved "https://registry.yarnpkg.com/loader-utils/-/loader-utils-0.2.17.tgz#f86e6374d43205a6e6c60e9196f17c0299bfb348" - dependencies: - big.js "^3.1.3" - emojis-list "^2.0.0" - json5 "^0.5.0" - object-assign "^4.0.1" - locate-path@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-2.0.0.tgz#2b568b265eec944c6d9c0de9c3dbbbca0354cd8e" @@ -4571,10 +4556,6 @@ lodash@^4.0.0, lodash@^4.13.1, lodash@^4.14.0, lodash@^4.15.0, lodash@^4.3.0: version "4.17.4" resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.4.tgz#78203a4d1c328ae1d86dca6460e369b57f4055ae" -lodash@^4.17.10: - version "4.17.10" - resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.10.tgz#1b7793cf7259ea38fb3661d4d38b3260af8ae4e7" - lodash@~1.0.1: version "1.0.2" resolved "https://registry.yarnpkg.com/lodash/-/lodash-1.0.2.tgz#8f57560c83b59fc270bd3d561b690043430e2551" @@ -6860,14 +6841,6 @@ source-list-map@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/source-list-map/-/source-list-map-2.0.0.tgz#aaa47403f7b245a92fbc97ea08f250d6087ed085" -source-map-loader@^0.2.3: - version "0.2.3" - resolved "https://registry.yarnpkg.com/source-map-loader/-/source-map-loader-0.2.3.tgz#d4b0c8cd47d54edce3e6bfa0f523f452b5b0e521" - dependencies: - async "^2.5.0" - loader-utils "~0.2.2" - source-map "~0.6.1" - source-map-resolve@^0.3.0: version "0.3.1" resolved "https://registry.yarnpkg.com/source-map-resolve/-/source-map-resolve-0.3.1.tgz#610f6122a445b8dd51535a2a71b783dfc1248761" From d31da69aafd0d09f73a862905ceae419e786e67d Mon Sep 17 00:00:00 2001 From: Benjamin Pasero Date: Fri, 17 Aug 2018 15:57:58 +0200 Subject: [PATCH 0939/1276] update comment --- src/vs/code/electron-main/window.ts | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/vs/code/electron-main/window.ts b/src/vs/code/electron-main/window.ts index 9f7403ac236..98a4328213e 100644 --- a/src/vs/code/electron-main/window.ts +++ b/src/vs/code/electron-main/window.ts @@ -140,7 +140,11 @@ export class CodeWindow implements ICodeWindow { show: !isFullscreenOrMaximized, title: product.nameLong, webPreferences: { - 'backgroundThrottling': false, // by default if Code is in the background, intervals and timeouts get throttled, + // By default if Code is in the background, intervals and timeouts get throttled, so we + // want to enforce that Code stays in the foreground. This triggers a disable_hidden_ + // flag that Electron provides via patch: + // https://github.com/electron/libchromiumcontent/blob/master/patches/common/chromium/disable_hidden.patch + 'backgroundThrottling': false, disableBlinkFeatures: 'Auxclick' // disable auxclick events (see https://developers.google.com/web/updates/2016/10/auxclick) } }; From 7ade70797408fd9e6455d69b558c55b31ddb5095 Mon Sep 17 00:00:00 2001 From: Alex Dima Date: Fri, 17 Aug 2018 17:03:08 +0200 Subject: [PATCH 0940/1276] Fixes #56255: Remove unnecessary code --- gulpfile.js | 38 ++++---------------------------------- 1 file changed, 4 insertions(+), 34 deletions(-) diff --git a/gulpfile.js b/gulpfile.js index ebdca25bcb4..fe899377d79 100644 --- a/gulpfile.js +++ b/gulpfile.js @@ -36,42 +36,12 @@ gulp.task('clean-build', ['clean-client-build', 'clean-extensions-build']); gulp.task('compile-build', ['compile-client-build', 'compile-extensions-build']); gulp.task('watch-build', ['watch-client-build', 'watch-extensions-build']); -var ALL_EDITOR_TASKS = [ - // Always defined tasks - 'clean-client', - 'compile-client', - 'watch-client', - 'clean-client-build', - 'compile-client-build', - 'watch-client-build', - - // Editor tasks (defined in gulpfile.editor) - 'clean-optimized-editor', - 'optimize-editor', - 'clean-minified-editor', - 'minify-editor', - 'clean-editor-distro', - 'editor-distro', - 'analyze-editor-distro', - - // hygiene tasks - 'tslint', - 'hygiene', -]; - -var runningEditorTasks = process.argv.length > 2 && process.argv.slice(2).every(function (arg) { return (ALL_EDITOR_TASKS.indexOf(arg) !== -1); }); - process.on('unhandledRejection', (reason, p) => { console.log('Unhandled Rejection at: Promise', p, 'reason:', reason); process.exit(1); }); -if (runningEditorTasks) { - require(`./build/gulpfile.editor`); - require(`./build/gulpfile.hygiene`); -} else { - // Load all the gulpfiles only if running tasks other than the editor tasks - const build = path.join(__dirname, 'build'); - require('glob').sync('gulpfile.*.js', { cwd: build }) - .forEach(f => require(`./build/${f}`)); -} +// Load all the gulpfiles only if running tasks other than the editor tasks +const build = path.join(__dirname, 'build'); +require('glob').sync('gulpfile.*.js', { cwd: build }) + .forEach(f => require(`./build/${f}`)); From 22c1af5a3e5867da647d2484c4406aea35d6e392 Mon Sep 17 00:00:00 2001 From: Alex Dima Date: Fri, 17 Aug 2018 17:49:09 +0200 Subject: [PATCH 0941/1276] Fixes #54146: Only use halfwidth rightwards arrow if it doesn't break monospace --- .../editor/browser/config/charWidthReader.ts | 6 +--- src/vs/editor/browser/config/configuration.ts | 17 ++++++++++- .../browser/viewParts/lines/viewLine.ts | 4 +++ .../editor/browser/widget/diffEditorWidget.ts | 1 + src/vs/editor/browser/widget/diffReview.ts | 1 + src/vs/editor/common/config/fontInfo.ts | 4 +++ .../common/viewLayout/viewLineRenderer.ts | 9 +++++- src/vs/editor/standalone/browser/colorizer.ts | 3 ++ .../test/common/mocks/testConfiguration.ts | 1 + .../viewLayout/viewLineRenderer.test.ts | 29 +++++++++++++++++++ src/vs/monaco.d.ts | 3 +- 11 files changed, 70 insertions(+), 8 deletions(-) diff --git a/src/vs/editor/browser/config/charWidthReader.ts b/src/vs/editor/browser/config/charWidthReader.ts index 6e5d782a037..63ba2d59a99 100644 --- a/src/vs/editor/browser/config/charWidthReader.ts +++ b/src/vs/editor/browser/config/charWidthReader.ts @@ -29,11 +29,7 @@ export class CharWidthRequest { } } -interface ICharWidthReader { - read(): void; -} - -class DomCharWidthReader implements ICharWidthReader { +class DomCharWidthReader { private readonly _bareFontInfo: BareFontInfo; private readonly _requests: CharWidthRequest[]; diff --git a/src/vs/editor/browser/config/configuration.ts b/src/vs/editor/browser/config/configuration.ts index 74cb598bddf..f83aefc5125 100644 --- a/src/vs/editor/browser/config/configuration.ts +++ b/src/vs/editor/browser/config/configuration.ts @@ -90,6 +90,7 @@ export interface ISerializedFontInfo { readonly isMonospace: boolean; readonly typicalHalfwidthCharacterWidth: number; readonly typicalFullwidthCharacterWidth: number; + readonly canUseHalfwidthRightwardsArrow: boolean; readonly spaceWidth: number; readonly maxDigitWidth: number; } @@ -176,6 +177,7 @@ class CSSBasedConfiguration extends Disposable { isMonospace: readConfig.isMonospace, typicalHalfwidthCharacterWidth: Math.max(readConfig.typicalHalfwidthCharacterWidth, 5), typicalFullwidthCharacterWidth: Math.max(readConfig.typicalFullwidthCharacterWidth, 5), + canUseHalfwidthRightwardsArrow: readConfig.canUseHalfwidthRightwardsArrow, spaceWidth: Math.max(readConfig.spaceWidth, 5), maxDigitWidth: Math.max(readConfig.maxDigitWidth, 5), }, false); @@ -214,7 +216,9 @@ class CSSBasedConfiguration extends Disposable { const digit9 = this.createRequest('9', CharWidthRequestType.Regular, all, monospace); // monospace test: used for whitespace rendering - this.createRequest('→', CharWidthRequestType.Regular, all, monospace); + const rightwardsArrow = this.createRequest('→', CharWidthRequestType.Regular, all, monospace); + const halfwidthRightwardsArrow = this.createRequest('→', CharWidthRequestType.Regular, all, null); + this.createRequest('·', CharWidthRequestType.Regular, all, monospace); // monospace test: some characters @@ -256,6 +260,16 @@ class CSSBasedConfiguration extends Disposable { } } + let canUseHalfwidthRightwardsArrow = true; + if (isMonospace && halfwidthRightwardsArrow.width !== referenceWidth) { + // using a halfwidth rightwards arrow would break monospace... + canUseHalfwidthRightwardsArrow = false; + } + if (halfwidthRightwardsArrow.width > rightwardsArrow.width) { + // using a halfwidth rightwards arrow would paint a larger arrow than a regular rightwards arrow + canUseHalfwidthRightwardsArrow = false; + } + // let's trust the zoom level only 2s after it was changed. const canTrustBrowserZoomLevel = (browser.getTimeSinceLastZoomLevelChanged() > 2000); return new FontInfo({ @@ -268,6 +282,7 @@ class CSSBasedConfiguration extends Disposable { isMonospace: isMonospace, typicalHalfwidthCharacterWidth: typicalHalfwidthCharacter.width, typicalFullwidthCharacterWidth: typicalFullwidthCharacter.width, + canUseHalfwidthRightwardsArrow: canUseHalfwidthRightwardsArrow, spaceWidth: space.width, maxDigitWidth: maxDigitWidth }, canTrustBrowserZoomLevel); diff --git a/src/vs/editor/browser/viewParts/lines/viewLine.ts b/src/vs/editor/browser/viewParts/lines/viewLine.ts index 6e1338d6adb..01acc025bfe 100644 --- a/src/vs/editor/browser/viewParts/lines/viewLine.ts +++ b/src/vs/editor/browser/viewParts/lines/viewLine.ts @@ -74,6 +74,7 @@ export class ViewLineOptions { public readonly renderControlCharacters: boolean; public readonly spaceWidth: number; public readonly useMonospaceOptimizations: boolean; + public readonly canUseHalfwidthRightwardsArrow: boolean; public readonly lineHeight: number; public readonly stopRenderingLineAfter: number; public readonly fontLigatures: boolean; @@ -87,6 +88,7 @@ export class ViewLineOptions { config.editor.fontInfo.isMonospace && !config.editor.viewInfo.disableMonospaceOptimizations ); + this.canUseHalfwidthRightwardsArrow = config.editor.fontInfo.canUseHalfwidthRightwardsArrow; this.lineHeight = config.editor.lineHeight; this.stopRenderingLineAfter = config.editor.viewInfo.stopRenderingLineAfter; this.fontLigatures = config.editor.viewInfo.fontLigatures; @@ -99,6 +101,7 @@ export class ViewLineOptions { && this.renderControlCharacters === other.renderControlCharacters && this.spaceWidth === other.spaceWidth && this.useMonospaceOptimizations === other.useMonospaceOptimizations + && this.canUseHalfwidthRightwardsArrow === other.canUseHalfwidthRightwardsArrow && this.lineHeight === other.lineHeight && this.stopRenderingLineAfter === other.stopRenderingLineAfter && this.fontLigatures === other.fontLigatures @@ -190,6 +193,7 @@ export class ViewLine implements IVisibleLine { let renderLineInput = new RenderLineInput( options.useMonospaceOptimizations, + options.canUseHalfwidthRightwardsArrow, lineData.content, lineData.continuesWithWrappedLine, lineData.isBasicASCII, diff --git a/src/vs/editor/browser/widget/diffEditorWidget.ts b/src/vs/editor/browser/widget/diffEditorWidget.ts index 1a0970f501d..481a3d62bd4 100644 --- a/src/vs/editor/browser/widget/diffEditorWidget.ts +++ b/src/vs/editor/browser/widget/diffEditorWidget.ts @@ -1982,6 +1982,7 @@ class InlineViewZonesComputer extends ViewZonesComputer { const containsRTL = ViewLineRenderingData.containsRTL(lineContent, isBasicASCII, originalModel.mightContainRTL()); const output = renderViewLine(new RenderLineInput( (config.fontInfo.isMonospace && !config.viewInfo.disableMonospaceOptimizations), + config.fontInfo.canUseHalfwidthRightwardsArrow, lineContent, false, isBasicASCII, diff --git a/src/vs/editor/browser/widget/diffReview.ts b/src/vs/editor/browser/widget/diffReview.ts index fe42bf6cc0d..58b825408e6 100644 --- a/src/vs/editor/browser/widget/diffReview.ts +++ b/src/vs/editor/browser/widget/diffReview.ts @@ -769,6 +769,7 @@ export class DiffReview extends Disposable { const containsRTL = ViewLineRenderingData.containsRTL(lineContent, isBasicASCII, model.mightContainRTL()); const r = renderViewLine(new RenderLineInput( (config.fontInfo.isMonospace && !config.viewInfo.disableMonospaceOptimizations), + config.fontInfo.canUseHalfwidthRightwardsArrow, lineContent, false, isBasicASCII, diff --git a/src/vs/editor/common/config/fontInfo.ts b/src/vs/editor/common/config/fontInfo.ts index 24b105bbd4e..1c5b063979b 100644 --- a/src/vs/editor/common/config/fontInfo.ts +++ b/src/vs/editor/common/config/fontInfo.ts @@ -155,6 +155,7 @@ export class FontInfo extends BareFontInfo { readonly isMonospace: boolean; readonly typicalHalfwidthCharacterWidth: number; readonly typicalFullwidthCharacterWidth: number; + readonly canUseHalfwidthRightwardsArrow: boolean; readonly spaceWidth: number; readonly maxDigitWidth: number; @@ -171,6 +172,7 @@ export class FontInfo extends BareFontInfo { isMonospace: boolean; typicalHalfwidthCharacterWidth: number; typicalFullwidthCharacterWidth: number; + canUseHalfwidthRightwardsArrow: boolean; spaceWidth: number; maxDigitWidth: number; }, isTrusted: boolean) { @@ -179,6 +181,7 @@ export class FontInfo extends BareFontInfo { this.isMonospace = opts.isMonospace; this.typicalHalfwidthCharacterWidth = opts.typicalHalfwidthCharacterWidth; this.typicalFullwidthCharacterWidth = opts.typicalFullwidthCharacterWidth; + this.canUseHalfwidthRightwardsArrow = opts.canUseHalfwidthRightwardsArrow; this.spaceWidth = opts.spaceWidth; this.maxDigitWidth = opts.maxDigitWidth; } @@ -195,6 +198,7 @@ export class FontInfo extends BareFontInfo { && this.letterSpacing === other.letterSpacing && this.typicalHalfwidthCharacterWidth === other.typicalHalfwidthCharacterWidth && this.typicalFullwidthCharacterWidth === other.typicalFullwidthCharacterWidth + && this.canUseHalfwidthRightwardsArrow === other.canUseHalfwidthRightwardsArrow && this.spaceWidth === other.spaceWidth && this.maxDigitWidth === other.maxDigitWidth ); diff --git a/src/vs/editor/common/viewLayout/viewLineRenderer.ts b/src/vs/editor/common/viewLayout/viewLineRenderer.ts index 977f9a5235b..8b183bda4d1 100644 --- a/src/vs/editor/common/viewLayout/viewLineRenderer.ts +++ b/src/vs/editor/common/viewLayout/viewLineRenderer.ts @@ -35,6 +35,7 @@ class LinePart { export class RenderLineInput { public readonly useMonospaceOptimizations: boolean; + public readonly canUseHalfwidthRightwardsArrow: boolean; public readonly lineContent: string; public readonly continuesWithWrappedLine: boolean; public readonly isBasicASCII: boolean; @@ -51,6 +52,7 @@ export class RenderLineInput { constructor( useMonospaceOptimizations: boolean, + canUseHalfwidthRightwardsArrow: boolean, lineContent: string, continuesWithWrappedLine: boolean, isBasicASCII: boolean, @@ -66,6 +68,7 @@ export class RenderLineInput { fontLigatures: boolean ) { this.useMonospaceOptimizations = useMonospaceOptimizations; + this.canUseHalfwidthRightwardsArrow = canUseHalfwidthRightwardsArrow; this.lineContent = lineContent; this.continuesWithWrappedLine = continuesWithWrappedLine; this.isBasicASCII = isBasicASCII; @@ -90,6 +93,7 @@ export class RenderLineInput { public equals(other: RenderLineInput): boolean { return ( this.useMonospaceOptimizations === other.useMonospaceOptimizations + && this.canUseHalfwidthRightwardsArrow === other.canUseHalfwidthRightwardsArrow && this.lineContent === other.lineContent && this.continuesWithWrappedLine === other.continuesWithWrappedLine && this.isBasicASCII === other.isBasicASCII @@ -303,6 +307,7 @@ export function renderViewLine2(input: RenderLineInput): RenderLineOutput2 { class ResolvedRenderLineInput { constructor( public readonly fontIsMonospace: boolean, + public readonly canUseHalfwidthRightwardsArrow: boolean, public readonly lineContent: string, public readonly len: number, public readonly isOverflowing: boolean, @@ -358,6 +363,7 @@ function resolveRenderLineInput(input: RenderLineInput): ResolvedRenderLineInput return new ResolvedRenderLineInput( useMonospaceOptimizations, + input.canUseHalfwidthRightwardsArrow, lineContent, len, isOverflowing, @@ -613,6 +619,7 @@ function _applyInlineDecorations(lineContent: string, len: number, tokens: LineP */ function _renderLine(input: ResolvedRenderLineInput, sb: IStringBuilder): RenderLineOutput { const fontIsMonospace = input.fontIsMonospace; + const canUseHalfwidthRightwardsArrow = input.canUseHalfwidthRightwardsArrow; const containsForeignElements = input.containsForeignElements; const lineContent = input.lineContent; const len = input.len; @@ -688,7 +695,7 @@ function _renderLine(input: ResolvedRenderLineInput, sb: IStringBuilder): Render tabsCharDelta += insertSpacesCount - 1; charOffsetInPart += insertSpacesCount - 1; if (insertSpacesCount > 0) { - if (insertSpacesCount > 1) { + if (!canUseHalfwidthRightwardsArrow || insertSpacesCount > 1) { sb.write1(0x2192); // RIGHTWARDS ARROW } else { sb.write1(0xffeb); // HALFWIDTH RIGHTWARDS ARROW diff --git a/src/vs/editor/standalone/browser/colorizer.ts b/src/vs/editor/standalone/browser/colorizer.ts index 39afc2b54ba..c079eaa094b 100644 --- a/src/vs/editor/standalone/browser/colorizer.ts +++ b/src/vs/editor/standalone/browser/colorizer.ts @@ -100,6 +100,7 @@ export class Colorizer { const containsRTL = ViewLineRenderingData.containsRTL(line, isBasicASCII, mightContainRTL); let renderResult = renderViewLine(new RenderLineInput( false, + true, line, false, isBasicASCII, @@ -153,6 +154,7 @@ function _fakeColorize(lines: string[], tabSize: number): string { const containsRTL = ViewLineRenderingData.containsRTL(line, isBasicASCII, /* check for RTL */true); let renderResult = renderViewLine(new RenderLineInput( false, + true, line, false, isBasicASCII, @@ -188,6 +190,7 @@ function _actualColorize(lines: string[], tabSize: number, tokenizationSupport: const containsRTL = ViewLineRenderingData.containsRTL(line, isBasicASCII, /* check for RTL */true); let renderResult = renderViewLine(new RenderLineInput( false, + true, line, false, isBasicASCII, diff --git a/src/vs/editor/test/common/mocks/testConfiguration.ts b/src/vs/editor/test/common/mocks/testConfiguration.ts index b94830a8456..0492346bff7 100644 --- a/src/vs/editor/test/common/mocks/testConfiguration.ts +++ b/src/vs/editor/test/common/mocks/testConfiguration.ts @@ -39,6 +39,7 @@ export class TestConfiguration extends CommonEditorConfiguration { isMonospace: true, typicalHalfwidthCharacterWidth: 10, typicalFullwidthCharacterWidth: 20, + canUseHalfwidthRightwardsArrow: true, spaceWidth: 10, maxDigitWidth: 10, }, true); diff --git a/src/vs/editor/test/common/viewLayout/viewLineRenderer.test.ts b/src/vs/editor/test/common/viewLayout/viewLineRenderer.test.ts index 59705ec0d93..968b1a20126 100644 --- a/src/vs/editor/test/common/viewLayout/viewLineRenderer.test.ts +++ b/src/vs/editor/test/common/viewLayout/viewLineRenderer.test.ts @@ -29,6 +29,7 @@ suite('viewLineRenderer.renderLine', () => { function assertCharacterReplacement(lineContent: string, tabSize: number, expected: string, expectedCharOffsetInPart: number[][], expectedPartLengts: number[]): void { let _actual = renderViewLine(new RenderLineInput( false, + true, lineContent, false, strings.isBasicASCII(lineContent), @@ -77,6 +78,7 @@ suite('viewLineRenderer.renderLine', () => { function assertParts(lineContent: string, tabSize: number, parts: ViewLineToken[], expected: string, expectedCharOffsetInPart: number[][], expectedPartLengts: number[]): void { let _actual = renderViewLine(new RenderLineInput( false, + true, lineContent, false, true, @@ -115,6 +117,7 @@ suite('viewLineRenderer.renderLine', () => { test('overflow', () => { let _actual = renderViewLine(new RenderLineInput( false, + true, 'Hello world!', false, true, @@ -218,6 +221,7 @@ suite('viewLineRenderer.renderLine', () => { let _actual = renderViewLine(new RenderLineInput( false, + true, lineText, false, true, @@ -279,6 +283,7 @@ suite('viewLineRenderer.renderLine', () => { let _actual = renderViewLine(new RenderLineInput( false, + true, lineText, false, true, @@ -340,6 +345,7 @@ suite('viewLineRenderer.renderLine', () => { let _actual = renderViewLine(new RenderLineInput( false, + true, lineText, false, true, @@ -378,6 +384,7 @@ suite('viewLineRenderer.renderLine', () => { let _actual = renderViewLine(new RenderLineInput( false, + true, lineText, false, false, @@ -407,6 +414,7 @@ suite('viewLineRenderer.renderLine', () => { let lineParts = createViewLineTokens([createPart(lineText.length, 1)]); let actual = renderViewLine(new RenderLineInput( false, + true, lineText, false, true, @@ -506,6 +514,7 @@ suite('viewLineRenderer.renderLine', () => { let lineParts = createViewLineTokens([createPart(lineText.length, 1)]); let actual = renderViewLine(new RenderLineInput( false, + true, lineText, false, true, @@ -541,6 +550,7 @@ suite('viewLineRenderer.renderLine', () => { let lineParts = createViewLineTokens([createPart(lineText.length, 1)]); let actual = renderViewLine(new RenderLineInput( false, + true, lineText, false, false, @@ -569,6 +579,7 @@ suite('viewLineRenderer.renderLine', () => { ]; let actual = renderViewLine(new RenderLineInput( false, + true, lineText, false, false, @@ -613,6 +624,7 @@ suite('viewLineRenderer.renderLine', () => { ].join(''); let _actual = renderViewLine(new RenderLineInput( + true, true, lineText, false, @@ -696,6 +708,7 @@ suite('viewLineRenderer.renderLine 2', () => { function testCreateLineParts(fontIsMonospace: boolean, lineContent: string, tokens: ViewLineToken[], fauxIndentLength: number, renderWhitespace: 'none' | 'boundary' | 'all', expected: string): void { let actual = renderViewLine(new RenderLineInput( fontIsMonospace, + true, lineContent, false, true, @@ -720,6 +733,7 @@ suite('viewLineRenderer.renderLine 2', () => { let actual = renderViewLine(new RenderLineInput( false, + true, lineContent, false, true, @@ -749,6 +763,7 @@ suite('viewLineRenderer.renderLine 2', () => { let lineContent = '\'let url = `http://***/_api/web/lists/GetByTitle(\\\'Teambuildingaanvragen\\\')/items`;\''; let actual = renderViewLine(new RenderLineInput( + true, true, lineContent, false, @@ -1016,6 +1031,7 @@ suite('viewLineRenderer.renderLine 2', () => { test('createLineParts can handle unsorted inline decorations', () => { let actual = renderViewLine(new RenderLineInput( false, + true, 'Hello world', false, true, @@ -1059,6 +1075,7 @@ suite('viewLineRenderer.renderLine 2', () => { let actual = renderViewLine(new RenderLineInput( false, + true, lineContent, false, true, @@ -1090,6 +1107,7 @@ suite('viewLineRenderer.renderLine 2', () => { let actual = renderViewLine(new RenderLineInput( false, + true, lineContent, false, true, @@ -1122,6 +1140,7 @@ suite('viewLineRenderer.renderLine 2', () => { let actual = renderViewLine(new RenderLineInput( false, + true, lineContent, false, true, @@ -1149,6 +1168,7 @@ suite('viewLineRenderer.renderLine 2', () => { test('issue #37208: Collapsing bullet point containing emoji in Markdown document results in [??] character', () => { let actual = renderViewLine(new RenderLineInput( + true, true, ' 1. 🙏', false, @@ -1178,6 +1198,7 @@ suite('viewLineRenderer.renderLine 2', () => { test('issue #37401: Allow both before and after decorations on empty line', () => { let actual = renderViewLine(new RenderLineInput( + true, true, '', false, @@ -1209,6 +1230,7 @@ suite('viewLineRenderer.renderLine 2', () => { test('issue #38935: GitLens end-of-line blame no longer rendering', () => { let actual = renderViewLine(new RenderLineInput( + true, true, '\t}', false, @@ -1241,6 +1263,7 @@ suite('viewLineRenderer.renderLine 2', () => { test('issue #22832: Consider fullwidth characters when rendering tabs', () => { let actual = renderViewLine(new RenderLineInput( + true, true, 'asd = "擦"\t\t#asd', false, @@ -1269,6 +1292,7 @@ suite('viewLineRenderer.renderLine 2', () => { test('issue #22832: Consider fullwidth characters when rendering tabs (render whitespace)', () => { let actual = renderViewLine(new RenderLineInput( + true, true, 'asd = "擦"\t\t#asd', false, @@ -1303,6 +1327,7 @@ suite('viewLineRenderer.renderLine 2', () => { test('issue #22352: COMBINING ACUTE ACCENT (U+0301)', () => { let actual = renderViewLine(new RenderLineInput( + true, true, '12345689012345678901234568901234567890123456890abába', false, @@ -1331,6 +1356,7 @@ suite('viewLineRenderer.renderLine 2', () => { test('issue #22352: Partially Broken Complex Script Rendering of Tamil', () => { let actual = renderViewLine(new RenderLineInput( + true, true, ' JoyShareல் பின்தொடர்ந்து, விடீயோ, ஜோக்குகள், அனிமேசன், நகைச்சுவை படங்கள் மற்றும் செய்திகளை பெறுவீர்', false, @@ -1363,6 +1389,7 @@ suite('viewLineRenderer.renderLine 2', () => { test('issue #42700: Hindi characters are not being rendered properly', () => { let actual = renderViewLine(new RenderLineInput( + true, true, ' वो ऐसा क्या है जो हमारे अंदर भी है और बाहर भी है। जिसकी वजह से हम सब हैं। जिसने इस सृष्टि की रचना की है।', false, @@ -1390,6 +1417,7 @@ suite('viewLineRenderer.renderLine 2', () => { test('issue #38123: editor.renderWhitespace: "boundary" renders whitespace at line wrap point when line is wrapped', () => { let actual = renderViewLine(new RenderLineInput( + true, true, 'This is a long line which never uses more than two spaces. ', true, @@ -1418,6 +1446,7 @@ suite('viewLineRenderer.renderLine 2', () => { function createTestGetColumnOfLinePartOffset(lineContent: string, tabSize: number, parts: ViewLineToken[], expectedPartLengths: number[]): (partIndex: number, partLength: number, offset: number, expected: number) => void { let renderLineOutput = renderViewLine(new RenderLineInput( false, + true, lineContent, false, true, diff --git a/src/vs/monaco.d.ts b/src/vs/monaco.d.ts index 7a7340a5649..24d801781d3 100644 --- a/src/vs/monaco.d.ts +++ b/src/vs/monaco.d.ts @@ -181,7 +181,7 @@ declare namespace monaco { good.scheme === 'file'; good.path === '/coding/c#/project1'; good.fragment === ''; - + const bad = Uri.parse('file://' + '/coding/c#/project1'); bad.scheme === 'file'; bad.path === '/coding/c'; // path is now broken @@ -4102,6 +4102,7 @@ declare namespace monaco.editor { readonly isMonospace: boolean; readonly typicalHalfwidthCharacterWidth: number; readonly typicalFullwidthCharacterWidth: number; + readonly canUseHalfwidthRightwardsArrow: boolean; readonly spaceWidth: number; readonly maxDigitWidth: number; } From c98ed761589d892f0bec192f7b6f5e3dcc6ca50e Mon Sep 17 00:00:00 2001 From: Johannes Rieken Date: Fri, 17 Aug 2018 17:58:57 +0200 Subject: [PATCH 0942/1276] add a way to opt out of ts-loader so that vscode-nls-tricks survive --- extensions/git/extension.webpack.config.js | 6 +-- extensions/shared.webpack.config.js | 45 +++++++++++++--------- 2 files changed, 29 insertions(+), 22 deletions(-) diff --git a/extensions/git/extension.webpack.config.js b/extensions/git/extension.webpack.config.js index 75643a14039..743109f4343 100644 --- a/extensions/git/extension.webpack.config.js +++ b/extensions/git/extension.webpack.config.js @@ -13,8 +13,8 @@ const myConfig = { __dirname: false // leave the __dirname-behaviour intact }, entry: { - main: './src/main.ts', - ['askpass-main']: './src/askpass-main.ts' + main: './out/main.js', + ['askpass-main']: './out/askpass-main.js' }, plugins: [ new CopyWebpackPlugin([ @@ -34,4 +34,4 @@ const myConfig = { }, }; -module.exports = { ...sharedConfig(__dirname), ...myConfig }; +module.exports = { ...sharedConfig(__dirname, false), ...myConfig }; diff --git a/extensions/shared.webpack.config.js b/extensions/shared.webpack.config.js index 8c48c9c5be9..12ccb0c39dc 100644 --- a/extensions/shared.webpack.config.js +++ b/extensions/shared.webpack.config.js @@ -12,32 +12,17 @@ const path = require('path'); * returns a good default configuation for extensions that * want to do webpack */ -module.exports = function (extensionDir) { - return { +module.exports = function (extensionDir, useTsLoader = true) { + let config = { context: extensionDir, mode: 'none', // this leaves the source code as close as possible to the original (when packaging we set this to 'production') target: 'node', // extensions run in a node context resolve: { mainFields: ['main'], // prefer the main-entry of package.json files - extensions: [".ts", ".js"] // support ts-files and js-files + extensions: [".js"] }, module: { - rules: [{ - // configure TypeScript loader: - // * only transpile because we have a separate compilation pipeline - // * enable sources maps for end-to-end source maps - test: /\.ts$/, - exclude: /node_modules/, - use: [{ - loader: 'ts-loader', - options: { - transpileOnly: true, - compilerOptions: { - "sourceMap": true, - } - } - }] - }] + rules: [] }, output: { // all output goes into `dist`. @@ -49,4 +34,26 @@ module.exports = function (extensionDir) { // yes, really source maps devtool: 'source-map' }; + + if (useTsLoader) { + config.resolve.extensions = [".ts", ".js"]; // support ts-files and js-files + config.module.rules = [{ + // configure TypeScript loader: + // * only transpile because we have a separate compilation pipeline + // * enable sources maps for end-to-end source maps + test: /\.ts$/, + exclude: /node_modules/, + use: [{ + loader: 'ts-loader', + options: { + transpileOnly: true, + compilerOptions: { + "sourceMap": true, + } + } + }] + }]; + } + + return config; }; From 22edd3e651dbe418d29e57895e2ae18aa125e09b Mon Sep 17 00:00:00 2001 From: Alex Dima Date: Fri, 17 Aug 2018 18:06:49 +0200 Subject: [PATCH 0943/1276] Push monaco.d.ts change --- src/vs/monaco.d.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vs/monaco.d.ts b/src/vs/monaco.d.ts index 24d801781d3..76dcf491ff9 100644 --- a/src/vs/monaco.d.ts +++ b/src/vs/monaco.d.ts @@ -181,7 +181,7 @@ declare namespace monaco { good.scheme === 'file'; good.path === '/coding/c#/project1'; good.fragment === ''; - + const bad = Uri.parse('file://' + '/coding/c#/project1'); bad.scheme === 'file'; bad.path === '/coding/c'; // path is now broken From faadee87a554aa8fbf8a82a601576ca097b7a0aa Mon Sep 17 00:00:00 2001 From: Christopher Leidigh Date: Fri, 17 Aug 2018 13:10:45 -0400 Subject: [PATCH 0944/1276] SelectBox: Prevent layout/hide on no room/offscreen Fixes: #55750 (#56173) --- .../browser/ui/contextview/contextview.ts | 5 ++ .../browser/ui/selectBox/selectBoxCustom.ts | 82 ++++++++++++++----- 2 files changed, 65 insertions(+), 22 deletions(-) diff --git a/src/vs/base/browser/ui/contextview/contextview.ts b/src/vs/base/browser/ui/contextview/contextview.ts index 8da408322a4..c16fc27af11 100644 --- a/src/vs/base/browser/ui/contextview/contextview.ts +++ b/src/vs/base/browser/ui/contextview/contextview.ts @@ -173,6 +173,11 @@ export class ContextView { } private doLayout(): void { + // Check that we still have a delegate - this.delegate.layout may have hidden + if (!this.isVisible()) { + return; + } + // Get anchor let anchor = this.delegate.getAnchor(); diff --git a/src/vs/base/browser/ui/selectBox/selectBoxCustom.ts b/src/vs/base/browser/ui/selectBox/selectBoxCustom.ts index d78f3f89e15..7a4b27ed1cf 100644 --- a/src/vs/base/browser/ui/selectBox/selectBoxCustom.ts +++ b/src/vs/base/browser/ui/selectBox/selectBoxCustom.ts @@ -82,7 +82,7 @@ class SelectListRenderer implements IRenderer { private static readonly DEFAULT_DROPDOWN_MINIMUM_BOTTOM_MARGIN = 32; - private static readonly DEFAULT_DROPDOWN_MINIMUM_TOP_MARGIN = 42; + private static readonly DEFAULT_DROPDOWN_MINIMUM_TOP_MARGIN = 2; private static readonly DEFAULT_MINIMUM_VISIBLE_OPTIONS = 3; private _isVisible: boolean; @@ -393,9 +393,11 @@ export class SelectBoxList implements ISelectBoxDelegate, IVirtualDelegate (window.innerHeight - 22) + || selectPosition.top < SelectBoxList.DEFAULT_DROPDOWN_MINIMUM_TOP_MARGIN + || ((maxVisibleOptionsBelow < 1) && (maxVisibleOptionsAbove < 1))) { + // Indicate we cannot open + return false; + } + + // Determine if we have to flip up // Always show complete list items - never more than Max available vertical height - if (listHeight + verticalPadding > maxSelectDropDownHeight) { - const maxVisibleOptions = ((Math.floor((maxSelectDropDownHeight - verticalPadding) / this.getHeight()))); - - // Check if we can at least show min items otherwise flip above - if (maxVisibleOptions < SelectBoxList.DEFAULT_MINIMUM_VISIBLE_OPTIONS) { - this._dropDownPosition = AnchorPosition.ABOVE; - } else { - this._dropDownPosition = AnchorPosition.BELOW; - } + if (maxVisibleOptionsBelow < SelectBoxList.DEFAULT_MINIMUM_VISIBLE_OPTIONS + && maxVisibleOptionsAbove > maxVisibleOptionsBelow + && this.options.length > maxVisibleOptionsBelow + ) { + this._dropDownPosition = AnchorPosition.ABOVE; + } else { + this._dropDownPosition = AnchorPosition.BELOW; } // Do full layout on showSelectDropDown only - return; + return true; + } + + // Check if select out of viewport or cutting into status bar + if ((selectPosition.top + selectPosition.height) > (window.innerHeight - 22) + || selectPosition.top < SelectBoxList.DEFAULT_DROPDOWN_MINIMUM_TOP_MARGIN + || (this._dropDownPosition === AnchorPosition.BELOW && maxVisibleOptionsBelow < 1) + || (this._dropDownPosition === AnchorPosition.ABOVE && maxVisibleOptionsAbove < 1)) { + // Cannot properly layout, close and hide + this.hideSelectDropDown(true); + return false; } // Make visible to enable measurements @@ -486,15 +514,22 @@ export class SelectBoxList implements ISelectBoxDelegate, IVirtualDelegate maxSelectDropDownHeight) { - listHeight = ((Math.floor((maxSelectDropDownHeight - verticalPadding) / this.getHeight())) * this.getHeight()); + if (minRequiredDropDownHeight > maxSelectDropDownHeightBelow) { + listHeight = (maxVisibleOptionsBelow * this.getHeight() + verticalPadding); } } else { // Set container height to max from select top to margin (default/minTopMargin) - maxSelectDropDownHeight = (selectPosition.top - SelectBoxList.DEFAULT_DROPDOWN_MINIMUM_TOP_MARGIN); - if (listHeight + verticalPadding > maxSelectDropDownHeight) { - listHeight = ((Math.floor((maxSelectDropDownHeight - SelectBoxList.DEFAULT_DROPDOWN_MINIMUM_TOP_MARGIN) / this.getHeight())) * this.getHeight()); + if (minRequiredDropDownHeight > maxSelectDropDownHeightAbove) { + // listHeight = ((Math.floor((maxSelectDropDownHeightBelow - verticalPadding) / this.getHeight())) * this.getHeight()); + listHeight = (maxVisibleOptionsAbove * this.getHeight() + verticalPadding); } } @@ -522,6 +557,9 @@ export class SelectBoxList implements ISelectBoxDelegate, IVirtualDelegate Date: Fri, 17 Aug 2018 10:31:51 -0700 Subject: [PATCH 0945/1276] #48641 - add 'alwaysExpand' option --- .../parts/search/browser/searchResultsView.ts | 4 +++- .../search/electron-browser/search.contribution.ts | 11 ++++++++--- 2 files changed, 11 insertions(+), 4 deletions(-) diff --git a/src/vs/workbench/parts/search/browser/searchResultsView.ts b/src/vs/workbench/parts/search/browser/searchResultsView.ts index 3f928a4bc09..099ff25cb84 100644 --- a/src/vs/workbench/parts/search/browser/searchResultsView.ts +++ b/src/vs/workbench/parts/search/browser/searchResultsView.ts @@ -107,9 +107,11 @@ export class SearchDataSource implements IDataSource { return false; } - const collapseOption = this.configurationService.getValue('search.collapseAllResults'); + const collapseOption = this.configurationService.getValue('search.collapseResults'); if (collapseOption === 'alwaysCollapse') { return false; + } else if (collapseOption === 'alwaysExpand') { + return true; } return numChildren < SearchDataSource.AUTOEXPAND_CHILD_LIMIT || element instanceof FolderMatch; diff --git a/src/vs/workbench/parts/search/electron-browser/search.contribution.ts b/src/vs/workbench/parts/search/electron-browser/search.contribution.ts index 462b13819c8..2deab589339 100644 --- a/src/vs/workbench/parts/search/electron-browser/search.contribution.ts +++ b/src/vs/workbench/parts/search/electron-browser/search.contribution.ts @@ -621,11 +621,16 @@ configurationRegistry.registerConfiguration({ default: 'sidebar', description: nls.localize('search.location', "Controls whether the search will be shown as a view in the sidebar or as a panel in the panel area for more horizontal space."), }, - 'search.collapseAllResults': { + 'search.collapseResults': { type: 'string', - enum: ['auto', 'alwaysCollapse'], + enum: ['auto', 'alwaysCollapse', 'alwaysExpand'], + enumDescriptions: [ + 'Files with less than 10 results are expanded. Others are collapsed.', + '', + '' + ], default: 'auto', - description: nls.localize('search.collapseAllResults', "Controls whether the search results will be collapsed."), + description: nls.localize('search.collapseAllResults', "Controls whether the search results will be collapsed or expanded."), } } }); From b0a34ceac3cee4a155f209843d39c663b0b8beb4 Mon Sep 17 00:00:00 2001 From: Rob Lourens Date: Fri, 17 Aug 2018 10:46:22 -0700 Subject: [PATCH 0946/1276] Fix #56487 - Don't search in models that aren't open --- src/vs/workbench/services/search/node/searchService.ts | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/vs/workbench/services/search/node/searchService.ts b/src/vs/workbench/services/search/node/searchService.ts index 5bf7b93503c..9d4f029f1bb 100644 --- a/src/vs/workbench/services/search/node/searchService.ts +++ b/src/vs/workbench/services/search/node/searchService.ts @@ -27,6 +27,7 @@ import { IUntitledEditorService } from 'vs/workbench/services/untitled/common/un import { IRawSearch, IRawSearchService, ISerializedFileMatch, ISerializedSearchComplete, ISerializedSearchProgressItem, isSerializedSearchComplete, isSerializedSearchSuccess, ITelemetryEvent } from './search'; import { ISearchChannel, SearchChannelClient } from './searchIpc'; import { getPathFromAmdModule } from 'vs/base/common/amd'; +import { IEditorService } from 'vs/workbench/services/editor/common/editorService'; export class SearchService extends Disposable implements ISearchService { public _serviceBrand: any; @@ -39,6 +40,7 @@ export class SearchService extends Disposable implements ISearchService { constructor( @IModelService private modelService: IModelService, @IUntitledEditorService private untitledEditorService: IUntitledEditorService, + @IEditorService private editorService: IEditorService, @IEnvironmentService environmentService: IEnvironmentService, @ITelemetryService private telemetryService: ITelemetryService, @IConfigurationService private configurationService: IConfigurationService, @@ -235,6 +237,10 @@ export class SearchService extends Disposable implements ISearchService { return; } + if (!this.editorService.isOpen({ resource })) { + return; + } + // Support untitled files if (resource.scheme === Schemas.untitled) { if (!this.untitledEditorService.exists(resource)) { From f5215d5f63a0d3a59064c8d0f957f2ef5b646aa4 Mon Sep 17 00:00:00 2001 From: Rob Lourens Date: Fri, 17 Aug 2018 11:22:25 -0700 Subject: [PATCH 0947/1276] Fix #53132 - remove duplicate TOC groups --- .../preferences/browser/settingsLayout.ts | 18 ++-------- .../parts/preferences/browser/settingsTree.ts | 35 +++++++++++-------- .../preferences/browser/settingsTreeModels.ts | 15 ++++---- .../parts/preferences/browser/tocTree.ts | 5 +-- 4 files changed, 35 insertions(+), 38 deletions(-) diff --git a/src/vs/workbench/parts/preferences/browser/settingsLayout.ts b/src/vs/workbench/parts/preferences/browser/settingsLayout.ts index e8af427980c..5f1c8d11a0e 100644 --- a/src/vs/workbench/parts/preferences/browser/settingsLayout.ts +++ b/src/vs/workbench/parts/preferences/browser/settingsLayout.ts @@ -27,6 +27,7 @@ export const tocData: ITOCEntry = { { id: 'editor', label: localize('textEditor', "Text Editor"), + settings: ['editor.*'], children: [ { id: 'editor/cursor', @@ -67,17 +68,13 @@ export const tocData: ITOCEntry = { id: 'editor/files', label: localize('files', "Files"), settings: ['files.*'] - }, - { - id: 'editor/editor', - label: localize('textEditor', "Text Editor"), - settings: ['editor.*'] } ] }, { id: 'workbench', label: localize('workbench', "Workbench"), + settings: ['workbench.*'], children: [ { id: 'workbench/appearance', @@ -103,27 +100,18 @@ export const tocData: ITOCEntry = { id: 'workbench/zenmode', label: localize('zenMode', "Zen Mode"), settings: ['zenmode.*'] - }, - { - id: 'workbench/workbench', - label: localize('workbench', "Workbench"), - settings: ['workbench.*'] } ] }, { id: 'window', label: localize('window', "Window"), + settings: ['window.*'], children: [ { id: 'window/newWindow', label: localize('newWindow', "New Window"), settings: ['window.*newwindow*'] - }, - { - id: 'window/window', - label: localize('window', "Window"), - settings: ['window.*'] } ] }, diff --git a/src/vs/workbench/parts/preferences/browser/settingsTree.ts b/src/vs/workbench/parts/preferences/browser/settingsTree.ts index 480a73351c9..fd87decac7a 100644 --- a/src/vs/workbench/parts/preferences/browser/settingsTree.ts +++ b/src/vs/workbench/parts/preferences/browser/settingsTree.ts @@ -93,23 +93,28 @@ export function resolveExtensionsSettings(groups: ISettingsGroup[]): ITOCEntry { } function _resolveSettingsTree(tocData: ITOCEntry, allSettings: Set): ITOCEntry { - if (tocData.settings) { - return { - id: tocData.id, - label: tocData.label, - settings: arrays.flatten(tocData.settings.map(pattern => getMatchingSettings(allSettings, pattern))) - }; - } else if (tocData.children) { - return { - id: tocData.id, - label: tocData.label, - children: tocData.children - .map(child => _resolveSettingsTree(child, allSettings)) - .filter(child => (child.children && child.children.length) || (child.settings && child.settings.length)) - }; + let children: ITOCEntry[]; + if (tocData.children) { + children = tocData.children + .map(child => _resolveSettingsTree(child, allSettings)) + .filter(child => (child.children && child.children.length) || (child.settings && child.settings.length)); } - return null; + let settings: ISetting[]; + if (tocData.settings) { + settings = arrays.flatten(tocData.settings.map(pattern => getMatchingSettings(allSettings, pattern))); + } + + if (!children && !settings) { + return null; + } + + return { + id: tocData.id, + label: tocData.label, + children, + settings + }; } function getMatchingSettings(allSettings: Set, pattern: string): ISetting[] { diff --git a/src/vs/workbench/parts/preferences/browser/settingsTreeModels.ts b/src/vs/workbench/parts/preferences/browser/settingsTreeModels.ts index def09bdaf2d..d7fbaedc6c1 100644 --- a/src/vs/workbench/parts/preferences/browser/settingsTreeModels.ts +++ b/src/vs/workbench/parts/preferences/browser/settingsTreeModels.ts @@ -214,13 +214,16 @@ export class SettingsTreeModel { element.parent = parent; element.level = this.getDepth(element); - if (tocEntry.children) { - element.children = tocEntry.children.map(child => this.createSettingsTreeGroupElement(child, element)); - } else if (tocEntry.settings) { - element.children = tocEntry.settings.map(s => this.createSettingsTreeSettingElement(s, element)) + element.children = []; + if (tocEntry.settings) { + const settingChildren = tocEntry.settings.map(s => this.createSettingsTreeSettingElement(s, element)) .filter(el => el.setting.deprecationMessage ? el.isConfigured : true); - } else { - element.children = []; + element.children.push(...settingChildren); + } + + if (tocEntry.children) { + const groupChildren = tocEntry.children.map(child => this.createSettingsTreeGroupElement(child, element)); + element.children.push(...groupChildren); } this._treeElementsById.set(element.id, element); diff --git a/src/vs/workbench/parts/preferences/browser/tocTree.ts b/src/vs/workbench/parts/preferences/browser/tocTree.ts index dda5a903e9f..48702ecc7b2 100644 --- a/src/vs/workbench/parts/preferences/browser/tocTree.ts +++ b/src/vs/workbench/parts/preferences/browser/tocTree.ts @@ -88,7 +88,7 @@ export class TOCDataSource implements IDataSource { hasChildren(tree: ITree, element: TOCTreeElement): boolean { return element instanceof TOCTreeModel || - (element instanceof SettingsTreeGroupElement && element.children && element.children.every(child => child instanceof SettingsTreeGroupElement)); + (element instanceof SettingsTreeGroupElement && element.children && element.children.some(child => child instanceof SettingsTreeGroupElement)); } getChildren(tree: ITree, element: TOCTreeElement): TPromise { @@ -96,7 +96,8 @@ export class TOCDataSource implements IDataSource { } private _getChildren(element: TOCTreeElement): SettingsTreeElement[] { - return element.children; + return (element.children) + .filter(child => child instanceof SettingsTreeGroupElement); } getParent(tree: ITree, element: TOCTreeElement): TPromise { From 9f9c5acc1e766744e9ba88d1f6f92bded8255b56 Mon Sep 17 00:00:00 2001 From: Rob Lourens Date: Fri, 17 Aug 2018 12:03:24 -0700 Subject: [PATCH 0948/1276] Settings editor - calculate labels lazily for perf --- .../preferences/browser/settingsTreeModels.ts | 30 +++++++++++++++---- 1 file changed, 24 insertions(+), 6 deletions(-) diff --git a/src/vs/workbench/parts/preferences/browser/settingsTreeModels.ts b/src/vs/workbench/parts/preferences/browser/settingsTreeModels.ts index d7fbaedc6c1..be293cc59f9 100644 --- a/src/vs/workbench/parts/preferences/browser/settingsTreeModels.ts +++ b/src/vs/workbench/parts/preferences/browser/settingsTreeModels.ts @@ -42,8 +42,8 @@ export class SettingsTreeNewExtensionsElement extends SettingsTreeElement { export class SettingsTreeSettingElement extends SettingsTreeElement { setting: ISetting; - displayCategory: string; - displayLabel: string; + _displayCategory: string; + _displayLabel: string; /** * scopeValue || defaultValue, for rendering convenience. @@ -79,6 +79,28 @@ export class SettingsTreeSettingElement extends SettingsTreeElement { this.update(inspectResult); } + get displayCategory(): string { + if (!this._displayCategory) { + this.initLabel(); + } + + return this._displayCategory; + } + + get displayLabel(): string { + if (!this._displayLabel) { + this.initLabel(); + } + + return this._displayLabel; + } + + private initLabel(): void { + const displayKeyFormat = settingKeyToDisplayFormat(this.setting.key, this.parent.id); + this._displayLabel = displayKeyFormat.label; + this._displayCategory = displayKeyFormat.category; + } + update(inspectResult: IInspectResult): void { const { isConfigured, inspected, targetSelector } = inspectResult; @@ -92,10 +114,6 @@ export class SettingsTreeSettingElement extends SettingsTreeElement { overriddenScopeList.push(localize('user', "User")); } - const displayKeyFormat = settingKeyToDisplayFormat(this.setting.key, this.parent.id); - this.displayLabel = displayKeyFormat.label; - this.displayCategory = displayKeyFormat.category; - this.value = displayValue; this.scopeValue = isConfigured && inspected[targetSelector]; this.defaultValue = inspected.default; From 19b17ef7460372cb07fbbe36ba0c3b0c5ad6bca2 Mon Sep 17 00:00:00 2001 From: Rob Lourens Date: Fri, 17 Aug 2018 12:10:17 -0700 Subject: [PATCH 0949/1276] Settings editor - cache settingLayout regex patterns for perf --- .../parts/preferences/browser/settingsTree.ts | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/src/vs/workbench/parts/preferences/browser/settingsTree.ts b/src/vs/workbench/parts/preferences/browser/settingsTree.ts index fd87decac7a..f62d62535aa 100644 --- a/src/vs/workbench/parts/preferences/browser/settingsTree.ts +++ b/src/vs/workbench/parts/preferences/browser/settingsTree.ts @@ -131,12 +131,23 @@ function getMatchingSettings(allSettings: Set, pattern: string): ISett return result.sort((a, b) => a.key.localeCompare(b.key)); } -function settingMatches(s: ISetting, pattern: string): boolean { +const settingPatternCache = new Map(); + +function createSettingMatchRegExp(pattern: string): RegExp { pattern = escapeRegExpCharacters(pattern) .replace(/\\\*/g, '.*'); - const regexp = new RegExp(`^${pattern}`, 'i'); - return regexp.test(s.key); + return new RegExp(`^${pattern}`, 'i'); +} + +function settingMatches(s: ISetting, pattern: string): boolean { + let regExp = settingPatternCache.get(pattern); + if (!regExp) { + regExp = createSettingMatchRegExp(pattern); + settingPatternCache.set(pattern, regExp); + } + + return regExp.test(s.key); } function getFlatSettings(settingsGroups: ISettingsGroup[]) { From 2c74afbf80693ef4071b2c5e6d538255688c8c56 Mon Sep 17 00:00:00 2001 From: Rob Lourens Date: Fri, 17 Aug 2018 12:12:54 -0700 Subject: [PATCH 0950/1276] Settings editor - fix initially unselected TOC item --- src/vs/workbench/parts/preferences/browser/settingsEditor2.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/vs/workbench/parts/preferences/browser/settingsEditor2.ts b/src/vs/workbench/parts/preferences/browser/settingsEditor2.ts index 17beb717b30..79f54fa5d8b 100644 --- a/src/vs/workbench/parts/preferences/browser/settingsEditor2.ts +++ b/src/vs/workbench/parts/preferences/browser/settingsEditor2.ts @@ -147,8 +147,10 @@ export class SettingsEditor2 extends BaseEditor { this.inSettingsEditorContextKey.set(true); return super.setInput(input, options, token) .then(() => new Promise(process.nextTick)) // Force setInput to be async + .then(() => this.render(token)) .then(() => { - return this.render(token); + // Init TOC selection + this.updateTreeScrollSync(); }); } From a1b5114111b3491acc541cfab9daabac80adc7d9 Mon Sep 17 00:00:00 2001 From: Rob Lourens Date: Fri, 17 Aug 2018 12:54:26 -0700 Subject: [PATCH 0951/1276] Also include markdownDescription in exported config --- .../services/configuration/node/configurationService.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/vs/workbench/services/configuration/node/configurationService.ts b/src/vs/workbench/services/configuration/node/configurationService.ts index e954cacc4e1..df5c45ce917 100644 --- a/src/vs/workbench/services/configuration/node/configurationService.ts +++ b/src/vs/workbench/services/configuration/node/configurationService.ts @@ -742,7 +742,7 @@ export class DefaultConfigurationExportHelper { const processProperty = (name: string, prop: IConfigurationPropertySchema) => { const propDetails: IExportedConfigurationNode = { name, - description: prop.description, + description: prop.description || prop.markdownDescription || '', default: prop.default, type: prop.type }; @@ -751,8 +751,8 @@ export class DefaultConfigurationExportHelper { propDetails.enum = prop.enum; } - if (prop.enumDescriptions) { - propDetails.enumDescriptions = prop.enumDescriptions; + if (prop.enumDescriptions || prop.markdownEnumDescriptions) { + propDetails.enumDescriptions = prop.enumDescriptions || prop.markdownEnumDescriptions; } settings.push(propDetails); From b538f1e8fec2860b0068a4ccb4a00bba843996ac Mon Sep 17 00:00:00 2001 From: Rob Lourens Date: Fri, 17 Aug 2018 12:56:24 -0700 Subject: [PATCH 0952/1276] Settings editor - add "modified" to title tooltip --- src/vs/workbench/parts/preferences/browser/settingsTree.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vs/workbench/parts/preferences/browser/settingsTree.ts b/src/vs/workbench/parts/preferences/browser/settingsTree.ts index f62d62535aa..3b76acd214e 100644 --- a/src/vs/workbench/parts/preferences/browser/settingsTree.ts +++ b/src/vs/workbench/parts/preferences/browser/settingsTree.ts @@ -833,7 +833,7 @@ export class SettingsRenderer implements ITreeRenderer { DOM.toggleClass(template.containerElement, 'is-expanded', true); template.containerElement.setAttribute(SettingsRenderer.SETTING_KEY_ATTR, element.setting.key); - const titleTooltip = setting.key; + const titleTooltip = setting.key + (element.isConfigured ? ' - Modified' : ''); template.categoryElement.textContent = element.displayCategory && (element.displayCategory + ': '); template.categoryElement.title = titleTooltip; From 350efab258cd0c973dfc02a71ad609919a9d45b3 Mon Sep 17 00:00:00 2001 From: Rob Lourens Date: Fri, 17 Aug 2018 12:59:36 -0700 Subject: [PATCH 0953/1276] Settings editor - enable settings in new extensions #49474 --- .../workbench/parts/preferences/browser/settingsEditor2.ts | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/vs/workbench/parts/preferences/browser/settingsEditor2.ts b/src/vs/workbench/parts/preferences/browser/settingsEditor2.ts index 79f54fa5d8b..70cdf42068a 100644 --- a/src/vs/workbench/parts/preferences/browser/settingsEditor2.ts +++ b/src/vs/workbench/parts/preferences/browser/settingsEditor2.ts @@ -854,7 +854,12 @@ export class SettingsEditor2 extends BaseEditor { private remoteSearchPreferences(query: string, token?: CancellationToken): TPromise { const remoteSearchProvider = this.preferencesSearchService.getRemoteSearchProvider(query); - return this.filterOrSearchPreferences(query, SearchResultIdx.Remote, remoteSearchProvider, token); + const newExtSearchProvider = this.preferencesSearchService.getRemoteSearchProvider(query, true); + + return TPromise.join([ + this.filterOrSearchPreferences(query, SearchResultIdx.Remote, remoteSearchProvider, token), + this.filterOrSearchPreferences(query, SearchResultIdx.NewExtensions, newExtSearchProvider, token) + ]).then(() => { }); } private filterOrSearchPreferences(query: string, type: SearchResultIdx, searchProvider: ISearchProvider, token?: CancellationToken): TPromise { From 1db4cac7af627623be2edbf4f9b40ae7f6c71844 Mon Sep 17 00:00:00 2001 From: SteVen Batten <6561887+sbatten@users.noreply.github.com> Date: Fri, 17 Aug 2018 15:42:52 -0700 Subject: [PATCH 0954/1276] new mnemonics behavior (#56617) * new mnemonics behavior * fixing bubbling and mnemonics showing in menus * updating rendering and removing conflicts with keybindings * fix submenu dismissal behavior --- src/vs/base/browser/ui/menu/menu.ts | 161 +++++++++++++++--- .../browser/parts/titlebar/menubarControl.ts | 126 +++++++++----- 2 files changed, 220 insertions(+), 67 deletions(-) diff --git a/src/vs/base/browser/ui/menu/menu.ts b/src/vs/base/browser/ui/menu/menu.ts index 9f36741df63..b4a02afc7dc 100644 --- a/src/vs/base/browser/ui/menu/menu.ts +++ b/src/vs/base/browser/ui/menu/menu.ts @@ -7,13 +7,15 @@ import 'vs/css!./menu'; import * as nls from 'vs/nls'; +import * as strings from 'vs/base/common/strings'; import { IActionRunner, IAction, Action } from 'vs/base/common/actions'; import { ActionBar, IActionItemProvider, ActionsOrientation, Separator, ActionItem, IActionItemOptions, BaseActionItem } from 'vs/base/browser/ui/actionbar/actionbar'; -import { ResolvedKeybinding, KeyCode } from 'vs/base/common/keyCodes'; -import { addClass, EventType, EventHelper, EventLike, removeTabIndexAndUpdateFocus, isAncestor, hasClass } from 'vs/base/browser/dom'; +import { ResolvedKeybinding, KeyCode, KeyCodeUtils } from 'vs/base/common/keyCodes'; +import { addClass, EventType, EventHelper, EventLike, removeTabIndexAndUpdateFocus, isAncestor, hasClass, addDisposableListener } from 'vs/base/browser/dom'; import { StandardKeyboardEvent } from 'vs/base/browser/keyboardEvent'; import { $, Builder } from 'vs/base/browser/builder'; import { RunOnceScheduler } from 'vs/base/common/async'; +import { IDisposable } from 'vs/base/common/lifecycle'; export interface IMenuOptions { context?: any; @@ -21,6 +23,7 @@ export interface IMenuOptions { actionRunner?: IActionRunner; getKeyBinding?: (action: IAction) => ResolvedKeybinding; ariaLabel?: string; + enableMnemonics?: boolean; } @@ -36,8 +39,11 @@ interface ISubMenuData { } export class Menu extends ActionBar { + private mnemonics: Map>; + private menuDisposables: IDisposable[]; constructor(container: HTMLElement, actions: IAction[], options: IMenuOptions = {}) { + addClass(container, 'monaco-menu-container'); container.setAttribute('role', 'presentation'); let menuContainer = document.createElement('div'); @@ -57,6 +63,34 @@ export class Menu extends ActionBar { this.domNode.tabIndex = 0; + this.menuDisposables = []; + + if (options.enableMnemonics) { + this.menuDisposables.push(addDisposableListener(menuContainer, EventType.KEY_DOWN, (e) => { + const key = KeyCodeUtils.fromString(e.key); + if (this.mnemonics.has(key)) { + EventHelper.stop(e, true); + const actions = this.mnemonics.get(key); + + if (actions.length === 1) { + if (actions[0] instanceof SubmenuActionItem) { + this.focusItemByElement(actions[0].container); + } + + actions[0].onClick(event); + } + + if (actions.length > 1) { + const action = actions.shift(); + this.focusItemByElement(action.container); + + actions.push(action); + this.mnemonics.set(key, actions); + } + } + })); + } + $(this.domNode).on(EventType.MOUSE_OUT, (e) => { let relatedTarget = (e as MouseEvent).relatedTarget as HTMLElement; if (!isAncestor(relatedTarget, this.domNode)) { @@ -90,9 +124,20 @@ export class Menu extends ActionBar { parent: this }; + this.mnemonics = new Map>(); + this.push(actions, { icon: true, label: true, isMenu: true }); } + private focusItemByElement(element: HTMLElement) { + const lastFocusedItem = this.focusedItem; + this.setFocusedItem(element); + + if (lastFocusedItem !== this.focusedItem) { + this.updateFocus(); + } + } + private setFocusedItem(element: HTMLElement): void { for (let i = 0; i < this.actionsList.children.length; i++) { let elem = this.actionsList.children[i]; @@ -107,9 +152,25 @@ export class Menu extends ActionBar { if (action instanceof Separator) { return new ActionItem(options.context, action, { icon: true }); } else if (action instanceof SubmenuAction) { - return new SubmenuActionItem(action, action.entries, parentData, options); + const menuActionItem = new SubmenuActionItem(action, action.entries, parentData, options); + + if (options.enableMnemonics) { + const mnemonic = menuActionItem.getMnemonic(); + if (mnemonic && menuActionItem.isEnabled()) { + let actionItems = []; + if (this.mnemonics.has(mnemonic)) { + actionItems = this.mnemonics.get(mnemonic); + } + + actionItems.push(menuActionItem); + + this.mnemonics.set(mnemonic, actionItems); + } + } + + return menuActionItem; } else { - const menuItemOptions: IActionItemOptions = {}; + const menuItemOptions: IMenuItemOptions = { enableMnemonics: options.enableMnemonics }; if (options.getKeyBinding) { const keybinding = options.getKeyBinding(action); if (keybinding) { @@ -117,7 +178,23 @@ export class Menu extends ActionBar { } } - return new MenuActionItem(options.context, action, menuItemOptions); + const menuActionItem = new MenuActionItem(options.context, action, menuItemOptions); + + if (options.enableMnemonics) { + const mnemonic = menuActionItem.getMnemonic(); + if (mnemonic && menuActionItem.isEnabled()) { + let actionItems = []; + if (this.mnemonics.has(mnemonic)) { + actionItems = this.mnemonics.get(mnemonic); + } + + actionItems.push(menuActionItem); + + this.mnemonics.set(mnemonic, actionItems); + } + } + + return menuActionItem; } } @@ -126,16 +203,23 @@ export class Menu extends ActionBar { } } +interface IMenuItemOptions extends IActionItemOptions { + enableMnemonics?: boolean; +} + class MenuActionItem extends BaseActionItem { static MNEMONIC_REGEX: RegExp = /&&(.)/g; + static ESCAPED_MNEMONIC_REGEX: RegExp = /&&(.)/g; + public container: HTMLElement; protected $e: Builder; protected $label: Builder; protected $check: Builder; - protected options: IActionItemOptions; + protected options: IMenuItemOptions; + protected mnemonic: KeyCode; private cssClass: string; - constructor(ctx: any, action: IAction, options: IActionItemOptions = {}) { + constructor(ctx: any, action: IAction, options: IMenuItemOptions = {}) { options.isMenu = true; super(action, action, options); @@ -143,11 +227,24 @@ class MenuActionItem extends BaseActionItem { this.options.icon = options.icon !== undefined ? options.icon : false; this.options.label = options.label !== undefined ? options.label : true; this.cssClass = ''; + + // Set mnemonic + if (this.options.label && options.enableMnemonics) { + let label = this.getAction().label; + if (label) { + let matches = MenuActionItem.MNEMONIC_REGEX.exec(label); + if (matches && matches.length === 2) { + this.mnemonic = KeyCodeUtils.fromString(matches[1].toLocaleLowerCase()); + } + } + } } - public render(container: HTMLElement): void { + render(container: HTMLElement): void { super.render(container); + this.container = container; + this.$e = $('a.action-menu-item').appendTo(this.builder); if (this._action.id === Separator.ID) { // A separator is a presentation item @@ -170,12 +267,12 @@ class MenuActionItem extends BaseActionItem { this._updateChecked(); } - public focus(): void { + focus(): void { super.focus(); this.$e.domFocus(); } - public _updateLabel(): void { + _updateLabel(): void { if (this.options.label) { let label = this.getAction().label; if (label) { @@ -185,20 +282,25 @@ class MenuActionItem extends BaseActionItem { let ariaLabel = label.replace(MenuActionItem.MNEMONIC_REGEX, mnemonic); - this.$e.getHTMLElement().accessKey = mnemonic.toLocaleLowerCase(); + this.mnemonic = KeyCodeUtils.fromString(mnemonic.toLocaleLowerCase()); + this.$label.attr('aria-label', ariaLabel); } else { this.$label.attr('aria-label', label); } - label = label.replace(MenuActionItem.MNEMONIC_REGEX, '$1\u0332'); + if (this.options.enableMnemonics) { + label = strings.escape(label).replace(MenuActionItem.ESCAPED_MNEMONIC_REGEX, '$1'); + } else { + label = strings.escape(label).replace(MenuActionItem.ESCAPED_MNEMONIC_REGEX, '$1'); + } } - this.$label.text(label); + this.$label.innerHtml(label); } } - public _updateTooltip(): void { + _updateTooltip(): void { let title: string = null; if (this.getAction().tooltip) { @@ -217,7 +319,7 @@ class MenuActionItem extends BaseActionItem { } } - public _updateClass(): void { + _updateClass(): void { if (this.cssClass) { this.$e.removeClass(this.cssClass); } @@ -233,7 +335,7 @@ class MenuActionItem extends BaseActionItem { } } - public _updateEnabled(): void { + _updateEnabled(): void { if (this.getAction().enabled) { this.builder.removeClass('disabled'); this.$e.removeClass('disabled'); @@ -245,13 +347,17 @@ class MenuActionItem extends BaseActionItem { } } - public _updateChecked(): void { + _updateChecked(): void { if (this.getAction().checked) { this.$e.addClass('checked'); } else { this.$e.removeClass('checked'); } } + + getMnemonic(): KeyCode { + return this.mnemonic; + } } class SubmenuActionItem extends MenuActionItem { @@ -267,7 +373,7 @@ class SubmenuActionItem extends MenuActionItem { private parentData: ISubMenuData, private submenuOptions?: IMenuOptions ) { - super(action, action, { label: true, isMenu: true }); + super(action, action, submenuOptions); this.showScheduler = new RunOnceScheduler(() => { if (this.mouseOver) { @@ -284,7 +390,7 @@ class SubmenuActionItem extends MenuActionItem { }, 750); } - public render(container: HTMLElement): void { + render(container: HTMLElement): void { super.render(container); this.$e.addClass('monaco-submenu-item'); @@ -326,10 +432,11 @@ class SubmenuActionItem extends MenuActionItem { }); } - public onClick(e: EventLike) { + onClick(e: EventLike) { // stop clicking from trying to run an action EventHelper.stop(e, true); + this.cleanupExistingSubmenu(false); this.createSubmenu(false); } @@ -376,6 +483,16 @@ class SubmenuActionItem extends MenuActionItem { this.parentData.submenu = new Menu(this.submenuContainer.getHTMLElement(), this.submenuActions, this.submenuOptions); + + this.parentData.submenu.onDidCancel(() => { + this.parentData.parent.focus(); + this.parentData.submenu.dispose(); + this.parentData.submenu = null; + + this.submenuContainer.dispose(); + this.submenuContainer = null; + }); + this.parentData.submenu.focus(selectFirstItem); this.mysubmenu = this.parentData.submenu; @@ -384,7 +501,7 @@ class SubmenuActionItem extends MenuActionItem { } } - public dispose() { + dispose() { super.dispose(); this.hideScheduler.dispose(); @@ -399,4 +516,4 @@ class SubmenuActionItem extends MenuActionItem { this.submenuContainer = null; } } -} \ No newline at end of file +} diff --git a/src/vs/workbench/browser/parts/titlebar/menubarControl.ts b/src/vs/workbench/browser/parts/titlebar/menubarControl.ts index d383476fbd5..be531b51d72 100644 --- a/src/vs/workbench/browser/parts/titlebar/menubarControl.ts +++ b/src/vs/workbench/browser/parts/titlebar/menubarControl.ts @@ -18,7 +18,7 @@ import * as DOM from 'vs/base/browser/dom'; import { IKeybindingService } from 'vs/platform/keybinding/common/keybinding'; import { isMacintosh } from 'vs/base/common/platform'; import { Menu, IMenuOptions, SubmenuAction } from 'vs/base/browser/ui/menu/menu'; -import { KeyCode } from 'vs/base/common/keyCodes'; +import { KeyCode, KeyCodeUtils } from 'vs/base/common/keyCodes'; import { StandardKeyboardEvent } from 'vs/base/browser/keyboardEvent'; import { IConfigurationService, IConfigurationChangeEvent } from 'vs/platform/configuration/common/configuration'; import { Event, Emitter } from 'vs/base/common/event'; @@ -103,9 +103,10 @@ export class MenubarControl extends Disposable { private container: HTMLElement; private recentlyOpened: IRecentlyOpened; private updatePending: boolean; - private _modifierKeyStatus: IModifierKeyStatus; private _focusState: MenubarState; + private _mnemonicsInUse: boolean; private openedViaKeyboard: boolean; + private mnemonics: Map; private _onVisibilityChange: Emitter; @@ -143,7 +144,7 @@ export class MenubarControl extends Disposable { this.topLevelMenus['Preferences'] = this._register(this.menuService.createMenu(MenuId.MenubarPreferencesMenu, this.contextKeyService)); } - this.menuUpdater = this._register(new RunOnceScheduler(() => this.doSetupMenubar(), 100)); + this.menuUpdater = this._register(new RunOnceScheduler(() => this.doSetupMenubar(), 200)); this.actionRunner = this._register(new ActionRunner()); this._register(this.actionRunner.onDidBeforeRun(() => { @@ -306,6 +307,14 @@ export class MenubarControl extends Disposable { this._focusState = value; } + private get mnemonicsInUse(): boolean { + return this._mnemonicsInUse; + } + + private set mnemonicsInUse(value: boolean) { + this._mnemonicsInUse = value; + } + private get isVisible(): boolean { return this.focusState >= MenubarState.VISIBLE; } @@ -351,6 +360,9 @@ export class MenubarControl extends Disposable { } else { this.focusState = MenubarState.VISIBLE; } + + this.mnemonicsInUse = false; + this.updateMnemonicVisibility(false); } private hideMenubar(): void { @@ -364,16 +376,15 @@ export class MenubarControl extends Disposable { } private onModifierKeyToggled(modifierKeyStatus: IModifierKeyStatus): void { - this._modifierKeyStatus = modifierKeyStatus; const allModifiersReleased = !modifierKeyStatus.altKey && !modifierKeyStatus.ctrlKey && !modifierKeyStatus.shiftKey; if (this.currentMenubarVisibility === 'hidden') { return; } - if (allModifiersReleased && modifierKeyStatus.lastKeyPressed === 'alt' && modifierKeyStatus.lastKeyReleased === 'alt') { if (!this.isFocused) { + this.mnemonicsInUse = true; this.focusedMenu = { index: 0 }; this.focusState = MenubarState.FOCUSED; } else if (!this.isOpen) { @@ -381,18 +392,22 @@ export class MenubarControl extends Disposable { } } - if (this.currentEnableMenuBarMnemonics && this.customMenus) { - this.customMenus.forEach(customMenu => { - if (customMenu.titleElement.children.length) { - let child = customMenu.titleElement.children.item(0) as HTMLElement; - if (child) { - child.style.textDecoration = modifierKeyStatus.altKey ? 'underline' : null; - } - } - }); + if (this.currentEnableMenuBarMnemonics && this.customMenus && !this.isOpen) { + this.updateMnemonicVisibility(modifierKeyStatus.altKey || this.mnemonicsInUse); } } + private updateMnemonicVisibility(visible: boolean): void { + this.customMenus.forEach(customMenu => { + if (customMenu.titleElement.children.length) { + let child = customMenu.titleElement.children.item(0) as HTMLElement; + if (child) { + child.style.textDecoration = visible ? 'underline' : null; + } + } + }); + } + private onRecentlyOpenedChange(): void { this.windowService.getRecentlyOpened().then(recentlyOpened => { this.recentlyOpened = recentlyOpened; @@ -448,12 +463,8 @@ export class MenubarControl extends Disposable { this.menuUpdater.schedule(); } - private clearMnemonic(topLevelElement: HTMLElement): void { - topLevelElement.accessKey = null; - } - - private registerMnemonic(topLevelElement: HTMLElement, mnemonic: string): void { - topLevelElement.accessKey = mnemonic.toLocaleLowerCase(); + private registerMnemonic(menuIndex: number, mnemonic: string): void { + this.mnemonics.set(KeyCodeUtils.fromString(mnemonic), menuIndex); } private setCheckedStatus(action: IAction | IMenubarMenuItemAction) { @@ -624,6 +635,7 @@ export class MenubarControl extends Disposable { const firstTimeSetup = this.customMenus === undefined; if (firstTimeSetup) { this.customMenus = []; + this.mnemonics = new Map(); } let idx = 0; @@ -651,12 +663,11 @@ export class MenubarControl extends Disposable { let displayTitle = this.topLevelTitles[menuTitle].replace(/&&(.)/g, this.currentEnableMenuBarMnemonics ? '$1' : '$1'); this.customMenus[menuIndex].titleElement.innerHTML = displayTitle; - // Clear and register mnemonics due to updated settings - this.clearMnemonic(this.customMenus[menuIndex].buttonElement); - if (this.currentEnableMenuBarMnemonics) { + // Register mnemonics + if (firstTimeSetup) { let mnemonic = (/&&(.)/g).exec(this.topLevelTitles[menuTitle]); if (mnemonic && mnemonic[1]) { - this.registerMnemonic(this.customMenus[menuIndex].buttonElement, mnemonic[1]); + this.registerMnemonic(menuIndex, mnemonic[1]); } } @@ -714,27 +725,7 @@ export class MenubarControl extends Disposable { })); this._register(DOM.addDisposableListener(this.customMenus[menuIndex].buttonElement, DOM.EventType.CLICK, (e) => { - // This should only happen for mnemonics and we shouldn't trigger them - if (this.currentMenubarVisibility === 'hidden') { - return; - } - - if (this._modifierKeyStatus && (this._modifierKeyStatus.shiftKey || this._modifierKeyStatus.ctrlKey)) { - return; // supress keyboard shortcuts that shouldn't conflict - } - - if (this.isOpen) { - if (this.isCurrentMenu(menuIndex)) { - this.setUnfocusedState(); - } else { - this.cleanupCustomMenu(); - this.showCustomMenu(menuIndex, this.openedViaKeyboard); - } - } else { - this.focusedMenu = { index: menuIndex }; - this.openedViaKeyboard = (e as MouseEvent).detail === 0; // Indicates mouse was not clicked - this.focusState = MenubarState.OPEN; - } + this.onMenuTriggered(menuIndex, true); e.preventDefault(); e.stopPropagation(); @@ -757,6 +748,7 @@ export class MenubarControl extends Disposable { this._register(DOM.addDisposableListener(this.container, DOM.EventType.KEY_DOWN, (e) => { let event = new StandardKeyboardEvent(e as KeyboardEvent); let eventHandled = true; + const key = !!e.key ? KeyCodeUtils.fromString(e.key) : KeyCode.Unknown; if (event.equals(KeyCode.LeftArrow) || (event.shiftKey && event.keyCode === KeyCode.Tab)) { this.focusPrevious(); @@ -764,6 +756,9 @@ export class MenubarControl extends Disposable { this.focusNext(); } else if (event.equals(KeyCode.Escape) && this.isFocused && !this.isOpen) { this.setUnfocusedState(); + } else if (!event.ctrlKey && this.currentEnableMenuBarMnemonics && this.mnemonicsInUse && this.mnemonics.has(key)) { + const menuIndex = this.mnemonics.get(key); + this.onMenuTriggered(menuIndex, false); } else { eventHandled = false; } @@ -801,6 +796,44 @@ export class MenubarControl extends Disposable { } } })); + + this._register(DOM.addDisposableListener(window, DOM.EventType.KEY_DOWN, (e) => { + if (!this.currentEnableMenuBarMnemonics || !e.altKey || e.ctrlKey) { + return; + } + + const key = KeyCodeUtils.fromString(e.key); + if (!this.mnemonics.has(key)) { + return; + } + + // Prevent conflicts with keybindings + const standardKeyboardEvent = new StandardKeyboardEvent(e); + const resolvedResult = this.keybindingService.softDispatch(standardKeyboardEvent, standardKeyboardEvent.target); + if (resolvedResult) { + return; + } + + this.mnemonicsInUse = true; + + const menuIndex = this.mnemonics.get(key); + this.onMenuTriggered(menuIndex, false); + })); + } + } + + private onMenuTriggered(menuIndex: number, clicked: boolean) { + if (this.isOpen) { + if (this.isCurrentMenu(menuIndex)) { + this.setUnfocusedState(); + } else { + this.cleanupCustomMenu(); + this.showCustomMenu(menuIndex, this.openedViaKeyboard); + } + } else { + this.focusedMenu = { index: menuIndex }; + this.openedViaKeyboard = clicked; + this.focusState = MenubarState.OPEN; } } @@ -946,6 +979,8 @@ export class MenubarControl extends Disposable { private cleanupCustomMenu(): void { if (this.focusedMenu) { + // Remove focus from the menus first + this.customMenus[this.focusedMenu.index].buttonElement.focus(); if (this.focusedMenu.holder) { DOM.removeClass(this.focusedMenu.holder.parentElement, 'open'); @@ -973,6 +1008,7 @@ export class MenubarControl extends Disposable { let menuOptions: IMenuOptions = { getKeyBinding: (action) => this.keybindingService.lookupKeybinding(action.id), actionRunner: this.actionRunner, + enableMnemonics: this.mnemonicsInUse }; let menuWidget = this._register(new Menu(menuHolder, customMenu.actions, menuOptions)); From 5669f1d0a61c4b5662c88561ae62a4650a6e6f78 Mon Sep 17 00:00:00 2001 From: Andre Weinand Date: Sat, 18 Aug 2018 01:37:34 +0200 Subject: [PATCH 0955/1276] node-debug@1.27.3 --- build/builtInExtensions.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build/builtInExtensions.json b/build/builtInExtensions.json index b3efcd2cc65..9235407a613 100644 --- a/build/builtInExtensions.json +++ b/build/builtInExtensions.json @@ -1,7 +1,7 @@ [ { "name": "ms-vscode.node-debug", - "version": "1.27.2", + "version": "1.27.3", "repo": "https://github.com/Microsoft/vscode-node-debug" }, { From a19a0a6cebb313e92ae0b6bb3ed0b200c4f16f37 Mon Sep 17 00:00:00 2001 From: Rob Lourens Date: Fri, 17 Aug 2018 16:17:29 -0700 Subject: [PATCH 0956/1276] Fix #54140 - implement context menu button --- .../browser/media/configure-inverse.svg | 1 + .../preferences/browser/media/configure.svg | 1 + .../browser/media/settingsEditor2.css | 49 +++++++++++++++- .../preferences/browser/settingsEditor2.ts | 2 +- .../parts/preferences/browser/settingsTree.ts | 57 +++++++++++++++++-- 5 files changed, 102 insertions(+), 8 deletions(-) create mode 100644 src/vs/workbench/parts/preferences/browser/media/configure-inverse.svg create mode 100644 src/vs/workbench/parts/preferences/browser/media/configure.svg diff --git a/src/vs/workbench/parts/preferences/browser/media/configure-inverse.svg b/src/vs/workbench/parts/preferences/browser/media/configure-inverse.svg new file mode 100644 index 00000000000..bbfbd366eb9 --- /dev/null +++ b/src/vs/workbench/parts/preferences/browser/media/configure-inverse.svg @@ -0,0 +1 @@ +configure \ No newline at end of file diff --git a/src/vs/workbench/parts/preferences/browser/media/configure.svg b/src/vs/workbench/parts/preferences/browser/media/configure.svg new file mode 100644 index 00000000000..c97bb48bdcc --- /dev/null +++ b/src/vs/workbench/parts/preferences/browser/media/configure.svg @@ -0,0 +1 @@ +configure \ No newline at end of file diff --git a/src/vs/workbench/parts/preferences/browser/media/settingsEditor2.css b/src/vs/workbench/parts/preferences/browser/media/settingsEditor2.css index 4110f029469..27f4b7f24f2 100644 --- a/src/vs/workbench/parts/preferences/browser/media/settingsEditor2.css +++ b/src/vs/workbench/parts/preferences/browser/media/settingsEditor2.css @@ -131,7 +131,50 @@ .settings-editor > .settings-body > .settings-tree-container .setting-measure-container { /** 11px for scrollbar + 208px for TOC margin */ width: calc(100% - 219px); - margin-left: 208px; + margin-left: 188px; + padding-left: 20px; +} + +.settings-editor > .settings-body > .settings-tree-container .setting-measure-container { + /* 20 from monaco-tree-wrapper + 20 from monaco-tree-row */ + padding-left: 40px; +} + +.settings-editor > .settings-body .settings-tree-container .monaco-tree-rows { + width: calc(100% - 20px); +} + +.settings-editor > .settings-body .settings-tree-container .monaco-tree-row > .content::before { + /* Hide twisties */ + display: none !important; +} + +.settings-editor > .settings-body .settings-tree-container .monaco-toolbar { + display: none; + position: absolute; + left: -23px; + top: 11px; +} + +.settings-editor > .settings-body .settings-tree-container .monaco-tree-row:hover .monaco-toolbar { + display: flex; +} + +.settings-editor > .settings-body .settings-tree-container .monaco-toolbar .toolbar-toggle-more { + display: block; + width: 22px; + height: 22px; + background-position: center; + background-repeat: no-repeat; + background-size: 16px; +} + +.vs .settings-editor > .settings-body .settings-tree-container .monaco-toolbar .toolbar-toggle-more { + background-image: url('configure.svg'); +} + +.vs-dark .settings-editor > .settings-body .settings-tree-container .monaco-toolbar .toolbar-toggle-more { + background-image: url('configure-inverse.svg'); } .settings-editor > .settings-body .settings-toc-container { @@ -171,11 +214,11 @@ margin-left: 3px; } -.settings-editor > .settings-body .settings-toc-container .monaco-tree-row.has-children > .content:before { +.settings-editor > .settings-body .settings-toc-container .monaco-tree-row.has-children > .content::before { opacity: 0.9; } -.settings-editor > .settings-body .settings-toc-container .monaco-tree-row.has-children.selected > .content:before { +.settings-editor > .settings-body .settings-toc-container .monaco-tree-row.has-children.selected > .content::before { opacity: 1; } diff --git a/src/vs/workbench/parts/preferences/browser/settingsEditor2.ts b/src/vs/workbench/parts/preferences/browser/settingsEditor2.ts index 70cdf42068a..3c242ed3deb 100644 --- a/src/vs/workbench/parts/preferences/browser/settingsEditor2.ts +++ b/src/vs/workbench/parts/preferences/browser/settingsEditor2.ts @@ -493,7 +493,7 @@ export class SettingsEditor2 extends BaseEditor { } return this.configurationService.updateValue(key, value, overrides, configurationTarget) - .then(() => this.renderTree(key)) // to draw "Modified" TODO + .then(() => this.renderTree(key)) .then(() => { const reportModifiedProps = { key, diff --git a/src/vs/workbench/parts/preferences/browser/settingsTree.ts b/src/vs/workbench/parts/preferences/browser/settingsTree.ts index 3b76acd214e..cff2867413d 100644 --- a/src/vs/workbench/parts/preferences/browser/settingsTree.ts +++ b/src/vs/workbench/parts/preferences/browser/settingsTree.ts @@ -27,7 +27,7 @@ import { Tree } from 'vs/base/parts/tree/browser/treeImpl'; import { localize } from 'vs/nls'; import { ICommandService } from 'vs/platform/commands/common/commands'; import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; -import { IContextViewService } from 'vs/platform/contextview/browser/contextView'; +import { IContextViewService, IContextMenuService } from 'vs/platform/contextview/browser/contextView'; import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; import { WorkbenchTreeController } from 'vs/platform/list/browser/listService'; import { IOpenerService } from 'vs/platform/opener/common/opener'; @@ -39,6 +39,9 @@ import { ISettingsEditorViewState, isExcludeSetting, SettingsTreeElement, Settin import { ExcludeSettingWidget, IExcludeDataItem, settingsHeaderForeground, settingsNumberInputBackground, settingsNumberInputBorder, settingsNumberInputForeground, settingsSelectBackground, settingsSelectBorder, settingsSelectForeground, settingsTextInputBackground, settingsTextInputBorder, settingsTextInputForeground } from 'vs/workbench/parts/preferences/browser/settingsWidgets'; import { ISetting, ISettingsGroup } from 'vs/workbench/services/preferences/common/preferences'; import { alert as ariaAlert } from 'vs/base/browser/ui/aria/aria'; +import { ToolBar } from 'vs/base/browser/ui/toolbar/toolbar'; +import { Action, IAction } from 'vs/base/common/actions'; +import { IClipboardService } from 'vs/platform/clipboard/common/clipboardService'; const $ = DOM.$; @@ -218,6 +221,7 @@ interface ISettingItemTemplate extends IDisposableTemplate { controlElement: HTMLElement; deprecationWarningElement: HTMLElement; otherOverridesElement: HTMLElement; + toolbar: ToolBar; } interface ISettingBoolItemTemplate extends ISettingItemTemplate { @@ -295,6 +299,8 @@ export class SettingsRenderer implements ITreeRenderer { private rowHeightCache = new Map(); private lastRenderedWidth: number; + private settingActions: IAction[]; + constructor( _measureContainer: HTMLElement, @IThemeService private themeService: IThemeService, @@ -302,12 +308,24 @@ export class SettingsRenderer implements ITreeRenderer { @IOpenerService private readonly openerService: IOpenerService, @IInstantiationService private readonly instantiationService: IInstantiationService, @ICommandService private readonly commandService: ICommandService, + @IContextMenuService private contextMenuService: IContextMenuService ) { this.descriptionMeasureContainer = $('.setting-item-description'); DOM.append(_measureContainer, $('.setting-measure-container.monaco-tree-row', undefined, $('.setting-item', undefined, this.descriptionMeasureContainer))); + + this.settingActions = [ + this.instantiationService.createInstance(CopySettingIdAction), + new Action('settings.resetSetting', localize('resetSettingLabel', "Reset Setting"), undefined, undefined, (context: SettingsTreeSettingElement) => { + if (context) { + this._onDidChangeSetting.fire({ key: context.setting.key, value: undefined }); + } + + return TPromise.wrap(null); + }) + ]; } updateWidth(width: number): void { @@ -495,6 +513,11 @@ export class SettingsRenderer implements ITreeRenderer { const deprecationWarningElement = DOM.append(container, $('.setting-item-deprecation-message')); const toDispose = []; + + const toolbar = new ToolBar(container, this.contextMenuService, {}); + toolbar.setActions([], this.settingActions)(); + toDispose.push(toolbar); + const template: ISettingItemTemplate = { toDispose, @@ -504,7 +527,8 @@ export class SettingsRenderer implements ITreeRenderer { descriptionElement, controlElement, deprecationWarningElement, - otherOverridesElement + otherOverridesElement, + toolbar }; // Prevent clicks from being handled by list @@ -616,6 +640,10 @@ export class SettingsRenderer implements ITreeRenderer { })); checkbox.domNode.classList.add(SettingsRenderer.CONTROL_CLASS); + const toolbar = new ToolBar(container, this.contextMenuService, {}); + toolbar.setActions([], this.settingActions)(); + toDispose.push(toolbar); + const template: ISettingBoolItemTemplate = { toDispose, @@ -626,7 +654,8 @@ export class SettingsRenderer implements ITreeRenderer { checkbox, descriptionElement, deprecationWarningElement, - otherOverridesElement + otherOverridesElement, + toolbar }; this.addSettingElementFocusHandler(template); @@ -826,6 +855,7 @@ export class SettingsRenderer implements ITreeRenderer { private renderSettingElement(tree: ITree, element: SettingsTreeSettingElement, templateId: string, template: ISettingItemTemplate | ISettingBoolItemTemplate): void { template.context = element; + template.toolbar.context = element; const setting = element.setting; @@ -1271,7 +1301,7 @@ export class SettingsTree extends NonExpandableOrSelectableTree { ariaLabel: localize('treeAriaLabel', "Settings"), showLoading: false, indentPixels: 0, - twistiePixels: 0, + twistiePixels: 20, // Actually for gear button }; super(container, @@ -1339,3 +1369,22 @@ export class SettingsTree extends NonExpandableOrSelectableTree { })); } } + +class CopySettingIdAction extends Action { + static readonly ID = 'settings.copySettingId'; + static readonly LABEL = localize('copySettingIdLabel', "Copy Setting ID"); + + constructor( + @IClipboardService private clipboardService: IClipboardService + ) { + super(CopySettingIdAction.ID, CopySettingIdAction.LABEL); + } + + run(context: SettingsTreeSettingElement): TPromise { + if (context) { + this.clipboardService.writeText(context.setting.key); + } + + return TPromise.as(null); + } +} From 0b8e20847a7730235a449b0150c0b19613cb1636 Mon Sep 17 00:00:00 2001 From: Rob Lourens Date: Fri, 17 Aug 2018 18:40:02 -0700 Subject: [PATCH 0957/1276] #54140 - add keyboard shortcut for setting context menu --- .../browser/media/settingsEditor2.css | 4 ++ .../preferences/browser/settingsEditor2.ts | 31 +++++++--- .../parts/preferences/browser/settingsTree.ts | 61 ++++++++++++++----- .../preferences/browser/settingsTreeModels.ts | 2 +- .../parts/preferences/common/preferences.ts | 1 + .../preferences.contribution.ts | 18 +++++- 6 files changed, 93 insertions(+), 24 deletions(-) diff --git a/src/vs/workbench/parts/preferences/browser/media/settingsEditor2.css b/src/vs/workbench/parts/preferences/browser/media/settingsEditor2.css index 27f4b7f24f2..7e038adc1d1 100644 --- a/src/vs/workbench/parts/preferences/browser/media/settingsEditor2.css +++ b/src/vs/workbench/parts/preferences/browser/media/settingsEditor2.css @@ -160,6 +160,10 @@ display: flex; } +.settings-editor > .settings-body .settings-tree-container .monaco-tree-row .setting-item.focused .monaco-toolbar { + display: flex; +} + .settings-editor > .settings-body .settings-tree-container .monaco-toolbar .toolbar-toggle-more { display: block; width: 22px; diff --git a/src/vs/workbench/parts/preferences/browser/settingsEditor2.ts b/src/vs/workbench/parts/preferences/browser/settingsEditor2.ts index 3c242ed3deb..14ef50470e2 100644 --- a/src/vs/workbench/parts/preferences/browser/settingsEditor2.ts +++ b/src/vs/workbench/parts/preferences/browser/settingsEditor2.ts @@ -186,6 +186,23 @@ export class SettingsEditor2 extends BaseEditor { } } + showContextMenu(): void { + const settingDOMElement = this.settingsTreeRenderer.getSettingDOMElementForDOMElement(document.activeElement); + if (!settingDOMElement) { + return; + } + + const focusedKey = this.settingsTreeRenderer.getKeyForDOMElementInSetting(settingDOMElement); + if (!focusedKey) { + return; + } + + const elements = this.currentSettingsModel.getElementsByName(focusedKey); + if (elements && elements[0]) { + this.settingsTreeRenderer.showContextMenu(elements[0], settingDOMElement); + } + } + focusSearch(): void { this.searchWidget.focus(); } @@ -275,12 +292,8 @@ export class SettingsEditor2 extends BaseEditor { this.toolbar.context = { target: this.settingsTargetsWidget.settingsTarget }; } - private getElementsByKey(settingKey: string): SettingsTreeSettingElement[] | null { - return this.currentSettingsModel.getElementByName(settingKey); - } - private revealSettingByKey(settingKey: string): void { - const elements = this.getElementsByKey(settingKey); + const elements = this.currentSettingsModel.getElementsByName(settingKey); if (elements && elements[0]) { this.settingsTree.reveal(elements[0]); @@ -413,7 +426,9 @@ export class SettingsEditor2 extends BaseEditor { }); })); this._register(this.settingsTreeRenderer.onDidClickSettingLink(settingName => this.revealSettingByKey(settingName))); - this._register(this.settingsTreeRenderer.onDidFocusSetting(element => this.settingsTree.reveal(element))); + this._register(this.settingsTreeRenderer.onDidFocusSetting(element => { + this.settingsTree.reveal(element); + })); this.settingsTree = this._register(this.instantiationService.createInstance(SettingsTree, this.settingsTreeContainer, @@ -696,7 +711,7 @@ export class SettingsEditor2 extends BaseEditor { let refreshP: TPromise; if (key) { - const elements = this.getElementsByKey(key); + const elements = this.currentSettingsModel.getElementsByName(key); if (elements && elements.length) { refreshP = TPromise.join(elements.map(e => this.settingsTree.refresh(e))); } else { @@ -714,7 +729,7 @@ export class SettingsEditor2 extends BaseEditor { } private updateModifiedLabelForKey(key: string): void { - const dataElements = this.getElementsByKey(key); + const dataElements = this.currentSettingsModel.getElementsByName(key); const isModified = dataElements && dataElements[0] && dataElements[0].isConfigured; // all elements are either configured or not const elements = this.settingsTreeRenderer.getDOMElementsForSettingKey(this.settingsTree.getHTMLElement(), key); if (elements && elements[0]) { diff --git a/src/vs/workbench/parts/preferences/browser/settingsTree.ts b/src/vs/workbench/parts/preferences/browser/settingsTree.ts index cff2867413d..3b30e7efc61 100644 --- a/src/vs/workbench/parts/preferences/browser/settingsTree.ts +++ b/src/vs/workbench/parts/preferences/browser/settingsTree.ts @@ -7,10 +7,13 @@ import * as DOM from 'vs/base/browser/dom'; import { renderMarkdown } from 'vs/base/browser/htmlContentRenderer'; import { StandardKeyboardEvent } from 'vs/base/browser/keyboardEvent'; import { IMouseEvent } from 'vs/base/browser/mouseEvent'; +import { alert as ariaAlert } from 'vs/base/browser/ui/aria/aria'; import { Button } from 'vs/base/browser/ui/button/button'; import { Checkbox } from 'vs/base/browser/ui/checkbox/checkbox'; import { InputBox } from 'vs/base/browser/ui/inputbox/inputBox'; import { SelectBox } from 'vs/base/browser/ui/selectBox/selectBox'; +import { ToolBar } from 'vs/base/browser/ui/toolbar/toolbar'; +import { Action, IAction } from 'vs/base/common/actions'; import * as arrays from 'vs/base/common/arrays'; import { Color, RGBA } from 'vs/base/common/color'; import { onUnexpectedError } from 'vs/base/common/errors'; @@ -25,23 +28,20 @@ import { IAccessibilityProvider, IDataSource, IFilter, IRenderer as ITreeRendere import { DefaultTreestyler } from 'vs/base/parts/tree/browser/treeDefaults'; import { Tree } from 'vs/base/parts/tree/browser/treeImpl'; import { localize } from 'vs/nls'; +import { IClipboardService } from 'vs/platform/clipboard/common/clipboardService'; import { ICommandService } from 'vs/platform/commands/common/commands'; import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; -import { IContextViewService, IContextMenuService } from 'vs/platform/contextview/browser/contextView'; +import { IContextMenuService, IContextViewService } from 'vs/platform/contextview/browser/contextView'; import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; import { WorkbenchTreeController } from 'vs/platform/list/browser/listService'; import { IOpenerService } from 'vs/platform/opener/common/opener'; -import { editorBackground, focusBorder, foreground, errorForeground, inputValidationErrorBackground, inputValidationErrorBorder } from 'vs/platform/theme/common/colorRegistry'; +import { editorBackground, errorForeground, focusBorder, foreground, inputValidationErrorBackground, inputValidationErrorBorder } from 'vs/platform/theme/common/colorRegistry'; import { attachButtonStyler, attachInputBoxStyler, attachSelectBoxStyler, attachStyler } from 'vs/platform/theme/common/styler'; import { ICssStyleCollector, ITheme, IThemeService, registerThemingParticipant } from 'vs/platform/theme/common/themeService'; import { ITOCEntry } from 'vs/workbench/parts/preferences/browser/settingsLayout'; import { ISettingsEditorViewState, isExcludeSetting, SettingsTreeElement, SettingsTreeGroupElement, SettingsTreeNewExtensionsElement, SettingsTreeSettingElement } from 'vs/workbench/parts/preferences/browser/settingsTreeModels'; import { ExcludeSettingWidget, IExcludeDataItem, settingsHeaderForeground, settingsNumberInputBackground, settingsNumberInputBorder, settingsNumberInputForeground, settingsSelectBackground, settingsSelectBorder, settingsSelectForeground, settingsTextInputBackground, settingsTextInputBorder, settingsTextInputForeground } from 'vs/workbench/parts/preferences/browser/settingsWidgets'; import { ISetting, ISettingsGroup } from 'vs/workbench/services/preferences/common/preferences'; -import { alert as ariaAlert } from 'vs/base/browser/ui/aria/aria'; -import { ToolBar } from 'vs/base/browser/ui/toolbar/toolbar'; -import { Action, IAction } from 'vs/base/common/actions'; -import { IClipboardService } from 'vs/platform/clipboard/common/clipboardService'; const $ = DOM.$; @@ -328,6 +328,17 @@ export class SettingsRenderer implements ITreeRenderer { ]; } + showContextMenu(element: SettingsTreeSettingElement, settingDOMElement: HTMLElement): void { + const toolbarElement: HTMLElement = settingDOMElement.querySelector('.toolbar-toggle-more'); + if (toolbarElement) { + this.contextMenuService.showContextMenu({ + getActions: () => TPromise.wrap(this.settingActions), + getAnchor: () => toolbarElement, + getActionsContext: () => element + }); + } + } + updateWidth(width: number): void { if (this.lastRenderedWidth !== width) { this.rowHeightCache = new Map(); @@ -514,9 +525,7 @@ export class SettingsRenderer implements ITreeRenderer { const toDispose = []; - const toolbar = new ToolBar(container, this.contextMenuService, {}); - toolbar.setActions([], this.settingActions)(); - toDispose.push(toolbar); + const toolbar = this.renderSettingToolbar(container); const template: ISettingItemTemplate = { toDispose, @@ -545,11 +554,21 @@ export class SettingsRenderer implements ITreeRenderer { } private addSettingElementFocusHandler(template: ISettingItemTemplate): void { - template.toDispose.push(DOM.addDisposableListener(template.containerElement, 'focus', e => { + const focusTracker = DOM.trackFocus(template.containerElement); + template.toDispose.push(focusTracker); + focusTracker.onDidBlur(() => { + if (template.containerElement.classList.contains('focused')) { + template.containerElement.classList.remove('focused'); + } + }); + + focusTracker.onDidFocus(() => { + template.containerElement.classList.add('focused'); + if (template.context) { this._onDidFocusSetting.fire(template.context); } - }, true)); + }); } private renderSettingTextTemplate(tree: ITree, container: HTMLElement, type = 'text'): ISettingTextItemTemplate { @@ -614,6 +633,17 @@ export class SettingsRenderer implements ITreeRenderer { return template; } + private renderSettingToolbar(container: HTMLElement): ToolBar { + const toolbar = new ToolBar(container, this.contextMenuService, {}); + toolbar.setActions([], this.settingActions)(); + const button = container.querySelector('.toolbar-toggle-more'); + if (button) { + (button).tabIndex = -1; + } + + return toolbar; + } + private renderSettingBoolTemplate(tree: ITree, container: HTMLElement): ISettingBoolItemTemplate { DOM.addClass(container, 'setting-item'); DOM.addClass(container, 'setting-item-bool'); @@ -639,9 +669,7 @@ export class SettingsRenderer implements ITreeRenderer { } })); checkbox.domNode.classList.add(SettingsRenderer.CONTROL_CLASS); - - const toolbar = new ToolBar(container, this.contextMenuService, {}); - toolbar.setActions([], this.settingActions)(); + const toolbar = this.renderSettingToolbar(container); toDispose.push(toolbar); const template: ISettingBoolItemTemplate = { @@ -853,6 +881,11 @@ export class SettingsRenderer implements ITreeRenderer { return treeContainer.querySelectorAll(`[${SettingsRenderer.SETTING_KEY_ATTR}="${key}"]`); } + public getKeyForDOMElementInSetting(element: HTMLElement): string { + const settingElement = this.getSettingDOMElementForDOMElement(element); + return settingElement && settingElement.getAttribute(SettingsRenderer.SETTING_KEY_ATTR); + } + private renderSettingElement(tree: ITree, element: SettingsTreeSettingElement, templateId: string, template: ISettingItemTemplate | ISettingBoolItemTemplate): void { template.context = element; template.toolbar.context = element; diff --git a/src/vs/workbench/parts/preferences/browser/settingsTreeModels.ts b/src/vs/workbench/parts/preferences/browser/settingsTreeModels.ts index be293cc59f9..a603d2906cc 100644 --- a/src/vs/workbench/parts/preferences/browser/settingsTreeModels.ts +++ b/src/vs/workbench/parts/preferences/browser/settingsTreeModels.ts @@ -210,7 +210,7 @@ export class SettingsTreeModel { return this._treeElementsById.get(id); } - getElementByName(name: string): SettingsTreeSettingElement[] { + getElementsByName(name: string): SettingsTreeSettingElement[] { return this._treeElementsBySettingName.get(name); } diff --git a/src/vs/workbench/parts/preferences/common/preferences.ts b/src/vs/workbench/parts/preferences/common/preferences.ts index d74acccec86..8d084c1559a 100644 --- a/src/vs/workbench/parts/preferences/common/preferences.ts +++ b/src/vs/workbench/parts/preferences/common/preferences.ts @@ -75,6 +75,7 @@ export const SETTINGS_EDITOR_COMMAND_FOCUS_FILE = 'settings.action.focusSettings export const SETTINGS_EDITOR_COMMAND_EDIT_FOCUSED_SETTING = 'settings.action.editFocusedSetting'; export const SETTINGS_EDITOR_COMMAND_FOCUS_SETTINGS_FROM_SEARCH = 'settings.action.focusSettingsFromSearch'; export const SETTINGS_EDITOR_COMMAND_FOCUS_SETTINGS_LIST = 'settings.action.focusSettingsList'; +export const SETTINGS_EDITOR_COMMAND_SHOW_CONTEXT_MENU = 'settings.action.showContextMenu'; export const KEYBINDINGS_EDITOR_COMMAND_SEARCH = 'keybindings.editor.searchKeybindings'; export const KEYBINDINGS_EDITOR_COMMAND_CLEAR_SEARCH_RESULTS = 'keybindings.editor.clearSearchResults'; diff --git a/src/vs/workbench/parts/preferences/electron-browser/preferences.contribution.ts b/src/vs/workbench/parts/preferences/electron-browser/preferences.contribution.ts index b81ff8c21d4..7159ac5c1b1 100644 --- a/src/vs/workbench/parts/preferences/electron-browser/preferences.contribution.ts +++ b/src/vs/workbench/parts/preferences/electron-browser/preferences.contribution.ts @@ -22,7 +22,7 @@ import { KeybindingsEditor } from 'vs/workbench/parts/preferences/browser/keybin import { OpenDefaultKeybindingsFileAction, OpenRawDefaultSettingsAction, OpenSettingsAction, OpenGlobalSettingsAction, OpenGlobalKeybindingsFileAction, OpenWorkspaceSettingsAction, OpenFolderSettingsAction, ConfigureLanguageBasedSettingsAction, OPEN_FOLDER_SETTINGS_COMMAND, OpenGlobalKeybindingsAction, OpenSettings2Action, OpenSettingsJsonAction } from 'vs/workbench/parts/preferences/browser/preferencesActions'; import { IKeybindingsEditor, IPreferencesSearchService, CONTEXT_KEYBINDING_FOCUS, CONTEXT_KEYBINDINGS_EDITOR, CONTEXT_KEYBINDINGS_SEARCH_FOCUS, KEYBINDINGS_EDITOR_COMMAND_DEFINE, KEYBINDINGS_EDITOR_COMMAND_REMOVE, KEYBINDINGS_EDITOR_COMMAND_SEARCH, - KEYBINDINGS_EDITOR_COMMAND_COPY, KEYBINDINGS_EDITOR_COMMAND_RESET, KEYBINDINGS_EDITOR_COMMAND_COPY_COMMAND, KEYBINDINGS_EDITOR_COMMAND_SHOW_SIMILAR, KEYBINDINGS_EDITOR_COMMAND_FOCUS_KEYBINDINGS, KEYBINDINGS_EDITOR_COMMAND_CLEAR_SEARCH_RESULTS, SETTINGS_EDITOR_COMMAND_SEARCH, CONTEXT_SETTINGS_EDITOR, SETTINGS_EDITOR_COMMAND_FOCUS_FILE, CONTEXT_SETTINGS_SEARCH_FOCUS, SETTINGS_EDITOR_COMMAND_CLEAR_SEARCH_RESULTS, SETTINGS_EDITOR_COMMAND_FOCUS_NEXT_SETTING, SETTINGS_EDITOR_COMMAND_FOCUS_PREVIOUS_SETTING, SETTINGS_EDITOR_COMMAND_EDIT_FOCUSED_SETTING, SETTINGS_EDITOR_COMMAND_FOCUS_SETTINGS_FROM_SEARCH, CONTEXT_TOC_ROW_FOCUS, SETTINGS_EDITOR_COMMAND_FOCUS_SETTINGS_LIST + KEYBINDINGS_EDITOR_COMMAND_COPY, KEYBINDINGS_EDITOR_COMMAND_RESET, KEYBINDINGS_EDITOR_COMMAND_COPY_COMMAND, KEYBINDINGS_EDITOR_COMMAND_SHOW_SIMILAR, KEYBINDINGS_EDITOR_COMMAND_FOCUS_KEYBINDINGS, KEYBINDINGS_EDITOR_COMMAND_CLEAR_SEARCH_RESULTS, SETTINGS_EDITOR_COMMAND_SEARCH, CONTEXT_SETTINGS_EDITOR, SETTINGS_EDITOR_COMMAND_FOCUS_FILE, CONTEXT_SETTINGS_SEARCH_FOCUS, SETTINGS_EDITOR_COMMAND_CLEAR_SEARCH_RESULTS, SETTINGS_EDITOR_COMMAND_FOCUS_NEXT_SETTING, SETTINGS_EDITOR_COMMAND_FOCUS_PREVIOUS_SETTING, SETTINGS_EDITOR_COMMAND_EDIT_FOCUSED_SETTING, SETTINGS_EDITOR_COMMAND_FOCUS_SETTINGS_FROM_SEARCH, CONTEXT_TOC_ROW_FOCUS, SETTINGS_EDITOR_COMMAND_FOCUS_SETTINGS_LIST, SETTINGS_EDITOR_COMMAND_SHOW_CONTEXT_MENU } from 'vs/workbench/parts/preferences/common/preferences'; import { IInstantiationService, ServicesAccessor } from 'vs/platform/instantiation/common/instantiation'; import { IWorkbenchContributionsRegistry, Extensions as WorkbenchExtensions } from 'vs/workbench/common/contributions'; @@ -470,6 +470,22 @@ const focusSettingsListCommand = new FocusSettingsListCommand({ }); focusSettingsListCommand.register(); +class ShowContextMenuCommand extends SettingsCommand { + public runCommand(accessor: ServicesAccessor, args: any): void { + const preferencesEditor = this.getPreferencesEditor(accessor); + if (preferencesEditor instanceof SettingsEditor2) { + preferencesEditor.showContextMenu(); + } + } +} + +const showContextMenuCommand = new ShowContextMenuCommand({ + id: SETTINGS_EDITOR_COMMAND_SHOW_CONTEXT_MENU, + precondition: ContextKeyExpr.and(CONTEXT_SETTINGS_EDITOR), + kbOpts: { primary: KeyMod.Shift | KeyCode.F9, weight: KeybindingWeight.WorkbenchContrib } +}); +showContextMenuCommand.register(); + // Preferences menu MenuRegistry.appendMenuItem(MenuId.MenubarPreferencesMenu, { From 277fe3d3f1963d8c6e1916d250539bd585c059b5 Mon Sep 17 00:00:00 2001 From: Rob Lourens Date: Fri, 17 Aug 2018 19:08:02 -0700 Subject: [PATCH 0958/1276] #54140 - add more setting context actions --- .../parts/preferences/browser/settingsTree.ts | 44 +++++++++++++++++++ 1 file changed, 44 insertions(+) diff --git a/src/vs/workbench/parts/preferences/browser/settingsTree.ts b/src/vs/workbench/parts/preferences/browser/settingsTree.ts index 3b30e7efc61..8da16030613 100644 --- a/src/vs/workbench/parts/preferences/browser/settingsTree.ts +++ b/src/vs/workbench/parts/preferences/browser/settingsTree.ts @@ -7,6 +7,7 @@ import * as DOM from 'vs/base/browser/dom'; import { renderMarkdown } from 'vs/base/browser/htmlContentRenderer'; import { StandardKeyboardEvent } from 'vs/base/browser/keyboardEvent'; import { IMouseEvent } from 'vs/base/browser/mouseEvent'; +import { Separator } from 'vs/base/browser/ui/actionbar/actionbar'; import { alert as ariaAlert } from 'vs/base/browser/ui/aria/aria'; import { Button } from 'vs/base/browser/ui/button/button'; import { Checkbox } from 'vs/base/browser/ui/checkbox/checkbox'; @@ -317,7 +318,10 @@ export class SettingsRenderer implements ITreeRenderer { this.descriptionMeasureContainer))); this.settingActions = [ + this.instantiationService.createInstance(CopySettingNameAction), this.instantiationService.createInstance(CopySettingIdAction), + this.instantiationService.createInstance(CopySettingAsJSONAction), + new Separator(), new Action('settings.resetSetting', localize('resetSettingLabel', "Reset Setting"), undefined, undefined, (context: SettingsTreeSettingElement) => { if (context) { this._onDidChangeSetting.fire({ key: context.setting.key, value: undefined }); @@ -1421,3 +1425,43 @@ class CopySettingIdAction extends Action { return TPromise.as(null); } } + +class CopySettingAsJSONAction extends Action { + static readonly ID = 'settings.copySettingAsJSON'; + static readonly LABEL = localize('copySettingAsJSONLabel', "Copy Setting as JSON"); + + constructor( + @IClipboardService private clipboardService: IClipboardService + ) { + super(CopySettingAsJSONAction.ID, CopySettingAsJSONAction.LABEL); + } + + run(context: SettingsTreeSettingElement): TPromise { + if (context) { + const jsonResult = `"${context.setting.key}": ${JSON.stringify(context.value)}`; + this.clipboardService.writeText(jsonResult); + } + + return TPromise.as(null); + } +} + +class CopySettingNameAction extends Action { + static readonly ID = 'settings.copySettingName'; + static readonly LABEL = localize('copySettingNameLabel', "Copy Setting Name"); + + constructor( + @IClipboardService private clipboardService: IClipboardService + ) { + super(CopySettingNameAction.ID, CopySettingNameAction.LABEL); + } + + run(context: SettingsTreeSettingElement): TPromise { + if (context) { + const name = `${context.displayCategory}: ${context.displayLabel}`; + this.clipboardService.writeText(name); + } + + return TPromise.as(null); + } +} From 5190e3007b00e6505282f9dbd237730d0f055e94 Mon Sep 17 00:00:00 2001 From: Rob Lourens Date: Fri, 17 Aug 2018 20:11:45 -0700 Subject: [PATCH 0959/1276] Fix #56625 - parse setting name from JSON line And some other fixes --- .../preferences/browser/settingsEditor2.ts | 29 ++++++++++++------- .../preferences/browser/settingsTreeModels.ts | 2 +- .../parts/preferences/browser/tocTree.ts | 16 ++++++---- 3 files changed, 29 insertions(+), 18 deletions(-) diff --git a/src/vs/workbench/parts/preferences/browser/settingsEditor2.ts b/src/vs/workbench/parts/preferences/browser/settingsEditor2.ts index 14ef50470e2..cd7d9207aae 100644 --- a/src/vs/workbench/parts/preferences/browser/settingsEditor2.ts +++ b/src/vs/workbench/parts/preferences/browser/settingsEditor2.ts @@ -76,7 +76,7 @@ export class SettingsEditor2 extends BaseEditor { private delayedFilterLogging: Delayer; private localSearchDelayer: Delayer; private remoteSearchThrottle: ThrottledDelayer; - private searchCancelToken: CancellationTokenSource; + private searchInProgress: CancellationTokenSource; private delayRefreshOnLayout: Delayer; private lastLayedoutWidth: number; @@ -747,6 +747,11 @@ export class SettingsEditor2 extends BaseEditor { }); } + private parseSettingFromJSON(query: string): string { + const match = query.match(/"([a-zA-Z.]+)": /); + return match && match[1]; + } + private triggerSearch(query: string): TPromise { this.viewState.tagFilters = new Set(); if (query) { @@ -762,14 +767,16 @@ export class SettingsEditor2 extends BaseEditor { query = query.trim(); if (query && query !== '@') { - this.searchCancelToken = new CancellationTokenSource(); + query = this.parseSettingFromJSON(query) || query; + + this.searchInProgress = new CancellationTokenSource(); return TPromise.join([ - this.localSearchDelayer.trigger(() => this.localFilterPreferences(query, this.searchCancelToken.token)), - this.remoteSearchThrottle.trigger(() => this.remoteSearchPreferences(query, this.searchCancelToken.token), 500) + this.localSearchDelayer.trigger(() => this.searchInProgress ? this.localFilterPreferences(query, this.searchInProgress.token) : TPromise.wrap(null)), + this.remoteSearchThrottle.trigger(() => this.searchInProgress ? this.remoteSearchPreferences(query, this.searchInProgress.token) : TPromise.wrap(null), 500) ]).then(() => { - if (this.searchCancelToken) { - this.searchCancelToken.dispose(); - this.searchCancelToken = null; + if (this.searchInProgress) { + this.searchInProgress.dispose(); + this.searchInProgress = null; } }); } else { @@ -781,10 +788,10 @@ export class SettingsEditor2 extends BaseEditor { this.localSearchDelayer.cancel(); this.remoteSearchThrottle.cancel(); - if (this.searchCancelToken) { - this.searchCancelToken.cancel(); - this.searchCancelToken.dispose(); - this.searchCancelToken = null; + if (this.searchInProgress) { + this.searchInProgress.cancel(); + this.searchInProgress.dispose(); + this.searchInProgress = null; } this.viewState.filterToCategory = null; diff --git a/src/vs/workbench/parts/preferences/browser/settingsTreeModels.ts b/src/vs/workbench/parts/preferences/browser/settingsTreeModels.ts index a603d2906cc..9de906b243f 100644 --- a/src/vs/workbench/parts/preferences/browser/settingsTreeModels.ts +++ b/src/vs/workbench/parts/preferences/browser/settingsTreeModels.ts @@ -429,7 +429,7 @@ export class SearchResultModel extends SettingsTreeModel { settings: this.getFlatSettings() }); - if (this.newExtensionSearchResults) { + if (this.newExtensionSearchResults && this.newExtensionSearchResults.filterMatches.length) { const newExtElement = new SettingsTreeNewExtensionsElement(); newExtElement.parent = this._root; newExtElement.id = 'newExtensions'; diff --git a/src/vs/workbench/parts/preferences/browser/tocTree.ts b/src/vs/workbench/parts/preferences/browser/tocTree.ts index 48702ecc7b2..e15e90024d9 100644 --- a/src/vs/workbench/parts/preferences/browser/tocTree.ts +++ b/src/vs/workbench/parts/preferences/browser/tocTree.ts @@ -49,15 +49,21 @@ export class TOCTreeModel { } private updateGroupCount(group: SettingsTreeGroupElement): void { - group.count = this._currentSearchModel ? - this.getSearchResultChildrenCount(group) : - undefined; - group.children.forEach(child => { if (child instanceof SettingsTreeGroupElement) { this.updateGroupCount(child); } }); + + if (this._currentSearchModel) { + const childCount = group.children + .filter(child => child instanceof SettingsTreeGroupElement) + .reduce((acc, cur) => acc + (cur).count, 0); + + group.count = childCount + this.getSearchResultChildrenCount(group); + } else { + group.count = undefined; + } } private getSearchResultChildrenCount(group: SettingsTreeGroupElement): number { @@ -70,8 +76,6 @@ export class TOCTreeModel { return group.children.some(child => { if (child instanceof SettingsTreeSettingElement) { return child.setting.key === setting.key && child.matchesAllTags(this.viewState.tagFilters); - } else if (child instanceof SettingsTreeGroupElement) { - return this.groupContainsSetting(child, setting); } else { return false; } From 91487f00b9af645222cf3e4422727347a6a5b8ee Mon Sep 17 00:00:00 2001 From: Rob Lourens Date: Fri, 17 Aug 2018 20:17:49 -0700 Subject: [PATCH 0960/1276] Settings editor - clear TOC selection when searching. Don't show 'new extension' button when it's filtered out. --- .../workbench/parts/preferences/browser/settingsEditor2.ts | 3 ++- src/vs/workbench/parts/preferences/browser/settingsTree.ts | 6 ++++++ 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/src/vs/workbench/parts/preferences/browser/settingsEditor2.ts b/src/vs/workbench/parts/preferences/browser/settingsEditor2.ts index cd7d9207aae..eb5dfc01ee0 100644 --- a/src/vs/workbench/parts/preferences/browser/settingsEditor2.ts +++ b/src/vs/workbench/parts/preferences/browser/settingsEditor2.ts @@ -898,10 +898,11 @@ export class SettingsEditor2 extends BaseEditor { this.toggleSearchMode(); this.settingsTree.setInput(this.searchResultModel.root); } else { + this.tocTreeModel.update(); this.searchResultModel.setResult(type, result); } - this.tocTreeModel.update(); + this.tocTree.setSelection([]); expandAll(this.tocTree); return this.renderTree(); diff --git a/src/vs/workbench/parts/preferences/browser/settingsTree.ts b/src/vs/workbench/parts/preferences/browser/settingsTree.ts index 8da16030613..a2d84965939 100644 --- a/src/vs/workbench/parts/preferences/browser/settingsTree.ts +++ b/src/vs/workbench/parts/preferences/browser/settingsTree.ts @@ -1188,6 +1188,12 @@ export class SettingsTreeFilter implements IFilter { return element.children.some(child => this.isVisible(tree, child)); } + if (element instanceof SettingsTreeNewExtensionsElement) { + if ((this.viewState.tagFilters && this.viewState.tagFilters.size) || this.viewState.filterToCategory) { + return false; + } + } + return true; } From b61d4b191701b2e97da039922d8fb965193a7759 Mon Sep 17 00:00:00 2001 From: Rob Lourens Date: Fri, 17 Aug 2018 20:27:22 -0700 Subject: [PATCH 0961/1276] Settings editor - fix context menu on 'exclude' type controls, format JSON copy better --- .../parts/preferences/browser/media/settingsWidgets.css | 2 +- src/vs/workbench/parts/preferences/browser/settingsTree.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/vs/workbench/parts/preferences/browser/media/settingsWidgets.css b/src/vs/workbench/parts/preferences/browser/media/settingsWidgets.css index b34fee0b67b..deb7ff3d83c 100644 --- a/src/vs/workbench/parts/preferences/browser/media/settingsWidgets.css +++ b/src/vs/workbench/parts/preferences/browser/media/settingsWidgets.css @@ -26,7 +26,7 @@ white-space: pre; } -.settings-editor > .settings-body > .settings-tree-container .setting-item.setting-item-exclude .monaco-action-bar { +.settings-editor > .settings-body > .settings-tree-container .setting-item.setting-item-exclude .setting-exclude-row .monaco-action-bar { display: none; position: absolute; right: 0px; diff --git a/src/vs/workbench/parts/preferences/browser/settingsTree.ts b/src/vs/workbench/parts/preferences/browser/settingsTree.ts index a2d84965939..508a60488b2 100644 --- a/src/vs/workbench/parts/preferences/browser/settingsTree.ts +++ b/src/vs/workbench/parts/preferences/browser/settingsTree.ts @@ -1444,7 +1444,7 @@ class CopySettingAsJSONAction extends Action { run(context: SettingsTreeSettingElement): TPromise { if (context) { - const jsonResult = `"${context.setting.key}": ${JSON.stringify(context.value)}`; + const jsonResult = `"${context.setting.key}": ${JSON.stringify(context.value, undefined, ' ')}`; this.clipboardService.writeText(jsonResult); } From d74f93bd3a9482a033bfdf26d7ea1ebefc160517 Mon Sep 17 00:00:00 2001 From: Rob Lourens Date: Fri, 17 Aug 2018 21:23:18 -0700 Subject: [PATCH 0962/1276] Fix #50652 - fix exact setting key search for ui editor. Also fix "new extension" button blinking at the top during search --- .../preferences/browser/settingsEditor2.ts | 45 ++++++++++++------- .../preferences/browser/settingsTreeModels.ts | 4 +- 2 files changed, 33 insertions(+), 16 deletions(-) diff --git a/src/vs/workbench/parts/preferences/browser/settingsEditor2.ts b/src/vs/workbench/parts/preferences/browser/settingsEditor2.ts index eb5dfc01ee0..c1c7cbc7476 100644 --- a/src/vs/workbench/parts/preferences/browser/settingsEditor2.ts +++ b/src/vs/workbench/parts/preferences/browser/settingsEditor2.ts @@ -113,7 +113,7 @@ export class SettingsEditor2 extends BaseEditor { super(SettingsEditor2.ID, telemetryService, themeService); this.delayedFilterLogging = new Delayer(1000); this.localSearchDelayer = new Delayer(300); - this.remoteSearchThrottle = new ThrottledDelayer(400); + this.remoteSearchThrottle = new ThrottledDelayer(200); this.viewState = { settingsTarget: ConfigurationTarget.USER }; this.delayRefreshOnLayout = new Delayer(100); @@ -768,17 +768,7 @@ export class SettingsEditor2 extends BaseEditor { query = query.trim(); if (query && query !== '@') { query = this.parseSettingFromJSON(query) || query; - - this.searchInProgress = new CancellationTokenSource(); - return TPromise.join([ - this.localSearchDelayer.trigger(() => this.searchInProgress ? this.localFilterPreferences(query, this.searchInProgress.token) : TPromise.wrap(null)), - this.remoteSearchThrottle.trigger(() => this.searchInProgress ? this.remoteSearchPreferences(query, this.searchInProgress.token) : TPromise.wrap(null), 500) - ]).then(() => { - if (this.searchInProgress) { - this.searchInProgress.dispose(); - this.searchInProgress = null; - } - }); + return this.triggerFilterPreferences(query); } else { if (this.viewState.tagFilters && this.viewState.tagFilters.size) { this.searchResultModel = this.createFilterModel(); @@ -869,7 +859,32 @@ export class SettingsEditor2 extends BaseEditor { this.telemetryService.publicLog('settingsEditor.filter', data); } - private localFilterPreferences(query: string, token?: CancellationToken): TPromise { + private triggerFilterPreferences(query: string): TPromise { + if (this.searchInProgress) { + this.searchInProgress.cancel(); + this.searchInProgress = null; + } + + // Trigger the local search. If it didn't find an exact match, trigger the remote search. + const searchInProgress = this.searchInProgress = new CancellationTokenSource(); + return this.localSearchDelayer.trigger(() => { + if (searchInProgress && !searchInProgress.token.isCancellationRequested) { + return this.localFilterPreferences(query).then(result => { + if (!result.exactMatch) { + this.remoteSearchThrottle.trigger(() => { + return searchInProgress && !searchInProgress.token.isCancellationRequested ? + this.remoteSearchPreferences(query, this.searchInProgress.token) : + TPromise.wrap(null); + }); + } + }); + } else { + return TPromise.wrap(null); + } + }); + } + + private localFilterPreferences(query: string, token?: CancellationToken): TPromise { const localSearchProvider = this.preferencesSearchService.getLocalSearchProvider(query); return this.filterOrSearchPreferences(query, SearchResultIdx.Local, localSearchProvider, token); } @@ -884,7 +899,7 @@ export class SettingsEditor2 extends BaseEditor { ]).then(() => { }); } - private filterOrSearchPreferences(query: string, type: SearchResultIdx, searchProvider: ISearchProvider, token?: CancellationToken): TPromise { + private filterOrSearchPreferences(query: string, type: SearchResultIdx, searchProvider: ISearchProvider, token?: CancellationToken): TPromise { return this._filterOrSearchPreferencesModel(query, this.defaultSettingsEditorModel, searchProvider, token).then(result => { if (token && token.isCancellationRequested) { // Handle cancellation like this because cancellation is lost inside the search provider due to async/await @@ -905,7 +920,7 @@ export class SettingsEditor2 extends BaseEditor { this.tocTree.setSelection([]); expandAll(this.tocTree); - return this.renderTree(); + return this.renderTree().then(() => result); }); } diff --git a/src/vs/workbench/parts/preferences/browser/settingsTreeModels.ts b/src/vs/workbench/parts/preferences/browser/settingsTreeModels.ts index 9de906b243f..b113a1343e0 100644 --- a/src/vs/workbench/parts/preferences/browser/settingsTreeModels.ts +++ b/src/vs/workbench/parts/preferences/browser/settingsTreeModels.ts @@ -400,7 +400,9 @@ export class SearchResultModel extends SettingsTreeModel { remoteResult.filterMatches = remoteResult.filterMatches.filter(m => !localMatchKeys.has(m.setting.key)); } - this.newExtensionSearchResults = objects.deepClone(this.rawSearchResults[SearchResultIdx.NewExtensions]); + if (remoteResult) { + this.newExtensionSearchResults = objects.deepClone(this.rawSearchResults[SearchResultIdx.NewExtensions]); + } this.cachedUniqueSearchResults = [localResult, remoteResult]; return this.cachedUniqueSearchResults; From 41de04ca3a705f2f5bcab041fa131af6fdd5a5ec Mon Sep 17 00:00:00 2001 From: Rob Lourens Date: Fri, 17 Aug 2018 21:31:43 -0700 Subject: [PATCH 0963/1276] Fix #55695 - setting links should use formatted name, not key --- .../workbench/parts/preferences/browser/settingsTree.ts | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/vs/workbench/parts/preferences/browser/settingsTree.ts b/src/vs/workbench/parts/preferences/browser/settingsTree.ts index 508a60488b2..4d8cf28b8db 100644 --- a/src/vs/workbench/parts/preferences/browser/settingsTree.ts +++ b/src/vs/workbench/parts/preferences/browser/settingsTree.ts @@ -40,7 +40,7 @@ import { editorBackground, errorForeground, focusBorder, foreground, inputValida import { attachButtonStyler, attachInputBoxStyler, attachSelectBoxStyler, attachStyler } from 'vs/platform/theme/common/styler'; import { ICssStyleCollector, ITheme, IThemeService, registerThemingParticipant } from 'vs/platform/theme/common/themeService'; import { ITOCEntry } from 'vs/workbench/parts/preferences/browser/settingsLayout'; -import { ISettingsEditorViewState, isExcludeSetting, SettingsTreeElement, SettingsTreeGroupElement, SettingsTreeNewExtensionsElement, SettingsTreeSettingElement } from 'vs/workbench/parts/preferences/browser/settingsTreeModels'; +import { ISettingsEditorViewState, isExcludeSetting, SettingsTreeElement, SettingsTreeGroupElement, SettingsTreeNewExtensionsElement, SettingsTreeSettingElement, settingKeyToDisplayFormat } from 'vs/workbench/parts/preferences/browser/settingsTreeModels'; import { ExcludeSettingWidget, IExcludeDataItem, settingsHeaderForeground, settingsNumberInputBackground, settingsNumberInputBorder, settingsNumberInputForeground, settingsSelectBackground, settingsSelectBorder, settingsSelectForeground, settingsTextInputBackground, settingsTextInputBorder, settingsTextInputForeground } from 'vs/workbench/parts/preferences/browser/settingsWidgets'; import { ISetting, ISettingsGroup } from 'vs/workbench/services/preferences/common/preferences'; @@ -1138,7 +1138,11 @@ function cleanRenderedMarkdown(element: Node): void { } function fixSettingLinks(text: string): string { - return text.replace(/`#([^#]*)#`/g, (match, settingName) => `[\`${settingName}\`](#${settingName})`); + return text.replace(/`#([^#]*)#`/g, (match, settingName) => { + const targetDisplayFormat = settingKeyToDisplayFormat(settingName); + const targetName = `${targetDisplayFormat.category}: ${targetDisplayFormat.label}`; + return `[${targetName}](#${settingName})`; + }); } function getDisplayEnumOptions(setting: ISetting): string[] { From b6411f27b0e41588fa897d51c34eafb636f6cbae Mon Sep 17 00:00:00 2001 From: Rob Lourens Date: Fri, 17 Aug 2018 21:52:20 -0700 Subject: [PATCH 0964/1276] Fix #56331 - disable horizontal scrolling on TOC --- src/vs/workbench/parts/preferences/browser/tocTree.ts | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/vs/workbench/parts/preferences/browser/tocTree.ts b/src/vs/workbench/parts/preferences/browser/tocTree.ts index e15e90024d9..817cff659c1 100644 --- a/src/vs/workbench/parts/preferences/browser/tocTree.ts +++ b/src/vs/workbench/parts/preferences/browser/tocTree.ts @@ -5,7 +5,7 @@ import * as DOM from 'vs/base/browser/dom'; import { TPromise } from 'vs/base/common/winjs.base'; -import { IDataSource, IRenderer, ITree, ITreeConfiguration } from 'vs/base/parts/tree/browser/tree'; +import { IDataSource, IRenderer, ITree, ITreeConfiguration, ITreeOptions } from 'vs/base/parts/tree/browser/tree'; import { DefaultTreestyler, OpenMode } from 'vs/base/parts/tree/browser/treeDefaults'; import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; import { IContextKeyService } from 'vs/platform/contextkey/common/contextkey'; @@ -18,6 +18,7 @@ import { SettingsAccessibilityProvider, SettingsTreeFilter } from 'vs/workbench/ import { ISettingsEditorViewState, SearchResultModel, SettingsTreeElement, SettingsTreeGroupElement, SettingsTreeSettingElement } from 'vs/workbench/parts/preferences/browser/settingsTreeModels'; import { settingsHeaderForeground } from 'vs/workbench/parts/preferences/browser/settingsWidgets'; import { ISetting } from 'vs/workbench/services/preferences/common/preferences'; +import { ScrollbarVisibility } from 'vs/base/common/scrollable'; const $ = DOM.$; @@ -174,9 +175,10 @@ export class TOCTree extends WorkbenchTree { ...configuration }; - const options = { + const options: ITreeOptions = { showLoading: false, - twistiePixels: 15 + twistiePixels: 15, + horizontalScrollMode: ScrollbarVisibility.Hidden }; super(container, From d90c85c5d0f50e758575144a49e2e8ce7f321600 Mon Sep 17 00:00:00 2001 From: Rob Lourens Date: Sun, 19 Aug 2018 19:56:28 -0700 Subject: [PATCH 0965/1276] Fix #56154 - Remove uri.parse('') from search view --- .../parts/search/browser/searchResultsView.ts | 6 +- .../parts/search/common/searchModel.ts | 63 +++++++++++-------- 2 files changed, 42 insertions(+), 27 deletions(-) diff --git a/src/vs/workbench/parts/search/browser/searchResultsView.ts b/src/vs/workbench/parts/search/browser/searchResultsView.ts index 099ff25cb84..628d70b17e7 100644 --- a/src/vs/workbench/parts/search/browser/searchResultsView.ts +++ b/src/vs/workbench/parts/search/browser/searchResultsView.ts @@ -246,7 +246,7 @@ export class SearchRenderer extends Disposable implements IRenderer { } private renderFolderMatch(tree: ITree, folderMatch: FolderMatch, templateData: IFolderMatchTemplate): void { - if (folderMatch.hasRoot()) { + if (folderMatch.hasResource()) { const workspaceFolder = this.contextService.getWorkspaceFolder(folderMatch.resource()); if (workspaceFolder && resources.isEqual(workspaceFolder.uri, folderMatch.resource())) { templateData.label.setFile(folderMatch.resource(), { fileKind: FileKind.ROOT_FOLDER, hidePath: true }); @@ -335,7 +335,9 @@ export class SearchAccessibilityProvider implements IAccessibilityProvider { public getAriaLabel(tree: ITree, element: FileMatchOrMatch): string { if (element instanceof FolderMatch) { - return nls.localize('folderMatchAriaLabel', "{0} matches in folder root {1}, Search result", element.count(), element.name()); + return element.hasResource() ? + nls.localize('folderMatchAriaLabel', "{0} matches in folder root {1}, Search result", element.count(), element.name()) : + nls.localize('otherFilesAriaLabel', "{0} matches outside of the workspace, Search result", element.count()); } if (element instanceof FileMatch) { diff --git a/src/vs/workbench/parts/search/common/searchModel.ts b/src/vs/workbench/parts/search/common/searchModel.ts index 0705774d83c..32b4b28571b 100644 --- a/src/vs/workbench/parts/search/common/searchModel.ts +++ b/src/vs/workbench/parts/search/common/searchModel.ts @@ -348,7 +348,7 @@ export class FolderMatch extends Disposable { private _unDisposedFileMatches: ResourceMap; private _replacingAll: boolean = false; - constructor(private _resource: URI, private _id: string, private _index: number, private _query: ISearchQuery, private _parent: SearchResult, private _searchModel: SearchModel, @IReplaceService private replaceService: IReplaceService, + constructor(private _resource: URI | null, private _id: string, private _index: number, private _query: ISearchQuery, private _parent: SearchResult, private _searchModel: SearchModel, @IReplaceService private replaceService: IReplaceService, @IInstantiationService private instantiationService: IInstantiationService) { super(); this._fileMatches = new ResourceMap(); @@ -371,7 +371,7 @@ export class FolderMatch extends Disposable { return this._id; } - public resource(): URI { + public resource(): URI | null { return this._resource; } @@ -387,8 +387,8 @@ export class FolderMatch extends Disposable { return this._parent; } - public hasRoot(): boolean { - return this._resource.fsPath !== ''; + public hasResource(): boolean { + return !!this._resource; } public add(raw: IFileMatch[], silent: boolean): void { @@ -525,6 +525,7 @@ export class SearchResult extends Disposable { public readonly onChange: Event = this._onChange.event; private _folderMatches: FolderMatch[] = []; + private _otherFilesMatch: FolderMatch; private _folderMatchesMap: TernarySearchTree = TernarySearchTree.forPaths(); private _showHighlights: boolean; @@ -539,17 +540,19 @@ export class SearchResult extends Disposable { public set query(query: ISearchQuery) { // When updating the query we could change the roots, so ensure we clean up the old roots first. this.clear(); - const otherFiles = URI.parse(''); - this._folderMatches = (query.folderQueries || []).map((fq) => fq.folder).concat([otherFiles]).map((resource, index) => { - const id = resource.toString() || 'otherFiles'; - const folderMatch = this.instantiationService.createInstance(FolderMatch, resource, id, index, query, this, this._searchModel); - const disposable = folderMatch.onChange((event) => this._onChange.fire(event)); - folderMatch.onDispose(() => disposable.dispose()); - return folderMatch; - }); - // otherFiles is the fallback for missing values in the TrieMap. So we do not insert it. - this._folderMatches.slice(0, this.folderMatches.length - 1) - .forEach(fm => this._folderMatchesMap.set(fm.resource().fsPath, fm)); + this._folderMatches = (query.folderQueries || []) + .map(fq => fq.folder) + .map((resource, index) => this.createFolderMatch(resource, resource.toString(), index, query)); + this._folderMatches.forEach(fm => this._folderMatchesMap.set(fm.resource().fsPath, fm)); + + this._otherFilesMatch = this.createFolderMatch(null, 'otherFiles', this._folderMatches.length + 1, query); + } + + private createFolderMatch(resource: URI | null, id: string, index: number, query: ISearchQuery): FolderMatch { + const folderMatch = this.instantiationService.createInstance(FolderMatch, resource, id, index, query, this, this._searchModel); + const disposable = folderMatch.onChange((event) => this._onChange.fire(event)); + folderMatch.onDispose(() => disposable.dispose()); + return folderMatch; } public get searchModel(): SearchModel { @@ -558,27 +561,34 @@ export class SearchResult extends Disposable { public add(allRaw: IFileMatch[], silent: boolean = false): void { // Split up raw into a list per folder so we can do a batch add per folder. - let rawPerFolder = new ResourceMap(); + const rawPerFolder = new ResourceMap(); + const otherFileMatches: IFileMatch[] = []; this._folderMatches.forEach((folderMatch) => rawPerFolder.set(folderMatch.resource(), [])); allRaw.forEach(rawFileMatch => { let folderMatch = this.getFolderMatch(rawFileMatch.resource); - if (folderMatch) { + if (folderMatch.resource()) { rawPerFolder.get(folderMatch.resource()).push(rawFileMatch); + } else { + otherFileMatches.push(rawFileMatch); } }); + rawPerFolder.forEach((raw) => { if (!raw.length) { return; } - let folderMatch = this.getFolderMatch(raw[0].resource); + + const folderMatch = this.getFolderMatch(raw[0].resource); if (folderMatch) { folderMatch.add(raw, silent); } }); + + this.otherFiles.add(otherFileMatches, silent); } public clear(): void { - this._folderMatches.forEach((folderMatch) => folderMatch.clear()); + this.folderMatches().forEach((folderMatch) => folderMatch.clear()); this.disposeMatches(); } @@ -615,19 +625,21 @@ export class SearchResult extends Disposable { } public folderMatches(): FolderMatch[] { - return this._folderMatches.concat(); + return this._otherFilesMatch ? + this._folderMatches.concat(this._otherFilesMatch) : + this._folderMatches.concat(); } public matches(): FileMatch[] { let matches: FileMatch[][] = []; - this._folderMatches.forEach((folderMatch) => { + this.folderMatches().forEach((folderMatch) => { matches.push(folderMatch.matches()); }); return [].concat(...matches); } public isEmpty(): boolean { - return this._folderMatches.every((folderMatch) => folderMatch.isEmpty()); + return this.folderMatches().every((folderMatch) => folderMatch.isEmpty()); } public fileCount(): number { @@ -674,18 +686,19 @@ export class SearchResult extends Disposable { } private get otherFiles(): FolderMatch { - return this._folderMatches[this._folderMatches.length - 1]; + return this._otherFilesMatch; } private set replacingAll(running: boolean) { - this._folderMatches.forEach((folderMatch) => { + this.folderMatches().forEach((folderMatch) => { folderMatch.replacingAll = running; }); } private disposeMatches(): void { - this._folderMatches.forEach(folderMatch => folderMatch.dispose()); + this.folderMatches().forEach(folderMatch => folderMatch.dispose()); this._folderMatches = []; + this._otherFilesMatch = null; this._folderMatchesMap = TernarySearchTree.forPaths(); this._rangeHighlightDecorations.removeHighlightRange(); } From 00649474f2e43a84c61ddbbbc356060257328372 Mon Sep 17 00:00:00 2001 From: Rob Lourens Date: Sun, 19 Aug 2018 21:22:31 -0700 Subject: [PATCH 0966/1276] #55883 - remove some TPromise#cancel from extHostSearch --- src/vs/workbench/api/node/extHostSearch.ts | 97 +++++++++++----------- 1 file changed, 48 insertions(+), 49 deletions(-) diff --git a/src/vs/workbench/api/node/extHostSearch.ts b/src/vs/workbench/api/node/extHostSearch.ts index 47b7f055eee..f7124e5e951 100644 --- a/src/vs/workbench/api/node/extHostSearch.ts +++ b/src/vs/workbench/api/node/extHostSearch.ts @@ -5,7 +5,7 @@ 'use strict'; import * as path from 'path'; -import { CancellationTokenSource } from 'vs/base/common/cancellation'; +import { CancellationTokenSource, CancellationToken } from 'vs/base/common/cancellation'; import { toErrorMessage } from 'vs/base/common/errorMessage'; import * as glob from 'vs/base/common/glob'; import * as resources from 'vs/base/common/resources'; @@ -80,8 +80,15 @@ export class ExtHostSearch implements ExtHostSearchShape { const provider = this._fileSearchProvider.get(handle); const query = reviveQuery(rawQuery); if (provider) { - return this._fileSearchManager.fileSearch(query, provider, batch => { - this._proxy.$handleFileMatch(handle, session, batch.map(p => p.resource)); + let cancelSource = new CancellationTokenSource(); + return new TPromise((c, e) => { + this._fileSearchManager.fileSearch(query, provider, batch => { + this._proxy.$handleFileMatch(handle, session, batch.map(p => p.resource)); + }, cancelSource.token).then(c, e); + }, () => { + // TODO IPC promise cancellation #53526 + cancelSource.cancel(); + cancelSource.dispose(); }); } else { const indexProvider = this._fileIndexProvider.get(handle); @@ -645,27 +652,19 @@ class FileSearchManager { private static readonly BATCH_SIZE = 512; - fileSearch(config: ISearchQuery, provider: vscode.FileSearchProvider, onBatch: (matches: IFileMatch[]) => void): TPromise { - let searchP: TPromise; - return new TPromise((c, e) => { - const engine = new FileSearchEngine(config, provider); + fileSearch(config: ISearchQuery, provider: vscode.FileSearchProvider, onBatch: (matches: IFileMatch[]) => void, token: CancellationToken): TPromise { + const engine = new FileSearchEngine(config, provider); - const onInternalResult = (batch: IInternalFileMatch[]) => { - onBatch(batch.map(m => this.rawMatchToSearchItem(m))); - }; + const onInternalResult = (batch: IInternalFileMatch[]) => { + onBatch(batch.map(m => this.rawMatchToSearchItem(m))); + }; - searchP = this.doSearch(engine, FileSearchManager.BATCH_SIZE, onInternalResult).then( - result => { - c({ - limitHit: result.limitHit - }); - }, - e); - }, () => { - if (searchP) { - searchP.cancel(); - } - }); + return this.doSearch(engine, FileSearchManager.BATCH_SIZE, onInternalResult, token).then( + result => { + return { + limitHit: result.limitHit + }; + }); } private rawMatchToSearchItem(match: IInternalFileMatch): IFileMatch { @@ -681,34 +680,34 @@ class FileSearchManager { } } - private doSearch(engine: FileSearchEngine, batchSize: number, onResultBatch: (matches: IInternalFileMatch[]) => void): TPromise { - return new TPromise((c, e) => { - const _onResult = match => { - if (match) { - batch.push(match); - if (batchSize > 0 && batch.length >= batchSize) { - onResultBatch(batch); - batch = []; - } - } - }; - - let batch: IInternalFileMatch[] = []; - engine.search(_onResult).then(result => { - if (batch.length) { - onResultBatch(batch); - } - - c(result); - }, error => { - if (batch.length) { - onResultBatch(batch); - } - - e(error); - }); - }, () => { + private doSearch(engine: FileSearchEngine, batchSize: number, onResultBatch: (matches: IInternalFileMatch[]) => void, token: CancellationToken): TPromise { + token.onCancellationRequested(() => { engine.cancel(); }); + + const _onResult = match => { + if (match) { + batch.push(match); + if (batchSize > 0 && batch.length >= batchSize) { + onResultBatch(batch); + batch = []; + } + } + }; + + let batch: IInternalFileMatch[] = []; + return engine.search(_onResult).then(result => { + if (batch.length) { + onResultBatch(batch); + } + + return result; + }, error => { + if (batch.length) { + onResultBatch(batch); + } + + return TPromise.wrapError(error); + }); } } From f0278ff4fa6b1a3886e7167edc0f9683b877db36 Mon Sep 17 00:00:00 2001 From: Rob Lourens Date: Sun, 19 Aug 2018 21:44:13 -0700 Subject: [PATCH 0967/1276] Fix #54768 - Copy current search to json editor for "Open settings.json" --- .../preferences/browser/settingsEditor2.ts | 39 ++++--------------- 1 file changed, 8 insertions(+), 31 deletions(-) diff --git a/src/vs/workbench/parts/preferences/browser/settingsEditor2.ts b/src/vs/workbench/parts/preferences/browser/settingsEditor2.ts index c1c7cbc7476..4b11beedfcf 100644 --- a/src/vs/workbench/parts/preferences/browser/settingsEditor2.ts +++ b/src/vs/workbench/parts/preferences/browser/settingsEditor2.ts @@ -286,7 +286,14 @@ export class SettingsEditor2 extends BaseEditor { this)); actions.push(new Separator()); } - actions.push(this.instantiationService.createInstance(OpenSettingsAction)); + actions.push(new Action('settings.openSettingsJson', localize('openSettingsJsonLabel', "Open settings.json"), undefined, undefined, () => { + return this.openSettingsFile().then(editor => { + const currentSearch = this.searchWidget.getValue(); + if (editor instanceof PreferencesEditor && currentSearch) { + editor.focusSearch(currentSearch); + } + }); + })); this.toolbar.setActions([], actions)(); this.toolbar.context = { target: this.settingsTargetsWidget.settingsTarget }; @@ -980,36 +987,6 @@ interface ISettingsToolbarContext { target: SettingsTarget; } -class OpenSettingsAction extends Action { - static readonly ID = 'settings.openSettingsJson'; - static readonly LABEL = localize('openSettingsJsonLabel', "Open settings.json"); - - constructor( - @IPreferencesService private readonly preferencesService: IPreferencesService, - ) { - super(OpenSettingsAction.ID, OpenSettingsAction.LABEL, 'open-settings-json'); - } - - - run(context?: ISettingsToolbarContext): TPromise { - return this._run(context) - .then(() => { }); - } - - private _run(context?: ISettingsToolbarContext): TPromise { - const target = context && context.target; - if (target === ConfigurationTarget.USER) { - return this.preferencesService.openGlobalSettings(true); - } else if (target === ConfigurationTarget.WORKSPACE) { - return this.preferencesService.openWorkspaceSettings(true); - } else if (URI.isUri(target)) { - return this.preferencesService.openFolderSettings(target, true); - } - - return TPromise.wrap(null); - } -} - class FilterByTagAction extends Action { static readonly ID = 'settings.filterByTag'; From 74be6d1f94850f8783aac9e629fe0e74270143dd Mon Sep 17 00:00:00 2001 From: Rob Lourens Date: Sun, 19 Aug 2018 22:30:56 -0700 Subject: [PATCH 0968/1276] Fix #55858 - edit files.exclude on double click --- .../preferences/browser/settingsWidgets.ts | 92 +++++++++++++------ 1 file changed, 63 insertions(+), 29 deletions(-) diff --git a/src/vs/workbench/parts/preferences/browser/settingsWidgets.ts b/src/vs/workbench/parts/preferences/browser/settingsWidgets.ts index 2209276a406..9cb48336843 100644 --- a/src/vs/workbench/parts/preferences/browser/settingsWidgets.ts +++ b/src/vs/workbench/parts/preferences/browser/settingsWidgets.ts @@ -208,33 +208,8 @@ export class ExcludeSettingWidget extends Disposable { DOM.append(container, this.renderAddButton()); this.renderList(); - this._register(DOM.addDisposableListener(this.listElement, 'click', (e: MouseEvent) => { - if (!e.target) { - return; - } - - const element = DOM.findParentWithClass((e.target), 'setting-exclude-row'); - if (!element) { - return; - } - - const targetIdxStr = element.getAttribute('data-index'); - if (!targetIdxStr) { - return; - } - - const targetIdx = parseInt(targetIdxStr); - - if (this.model.getSelected() === targetIdx) { - return; - } - - this.model.select(targetIdx); - this.renderList(); - e.preventDefault(); - e.stopPropagation(); - })); - + this._register(DOM.addDisposableListener(this.listElement, DOM.EventType.CLICK, e => this.onListClick(e))); + this._register(DOM.addDisposableListener(this.listElement, DOM.EventType.DBLCLICK, e => this.onListDoubleClick(e))); this._register(DOM.addStandardDisposableListener(this.listElement, 'keydown', (e: KeyboardEvent) => { if (e.keyCode === KeyCode.UpArrow) { @@ -256,6 +231,61 @@ export class ExcludeSettingWidget extends Disposable { this.renderList(); } + private onListClick(e: MouseEvent): void { + const targetIdx = this.getClickedItemIndex(e); + if (targetIdx < 0) { + return; + } + + if (this.model.getSelected() === targetIdx) { + return; + } + + this.model.select(targetIdx); + this.renderList(); + e.preventDefault(); + e.stopPropagation(); + } + + private onListDoubleClick(e: MouseEvent): void { + const targetIdx = this.getClickedItemIndex(e); + if (targetIdx < 0) { + return; + } + + const item = this.model.items[targetIdx]; + if (item) { + this.editSetting(item.pattern); + e.preventDefault(); + e.stopPropagation(); + } + } + + private getClickedItemIndex(e: MouseEvent): number { + if (!e.target) { + return -1; + } + + const actionbar = DOM.findParentWithClass(e.target, 'monaco-action-bar'); + if (actionbar) { + // Don't handle doubleclicks inside the action bar + return -1; + } + + const element = DOM.findParentWithClass((e.target), 'setting-exclude-row'); + if (!element) { + return -1; + } + + const targetIdxStr = element.getAttribute('data-index'); + if (!targetIdxStr) { + return -1; + } + + const targetIdx = parseInt(targetIdxStr); + return targetIdx; + } + private renderList(): void { const focused = DOM.isAncestor(document.activeElement, this.listElement); @@ -290,12 +320,16 @@ export class ExcludeSettingWidget extends Disposable { id: 'workbench.action.editExcludeItem', tooltip: localize('editExcludeItem', "Edit Exclude Item"), run: () => { - this.model.setEditKey(key); - this.renderList(); + this.editSetting(key); } }; } + private editSetting(key: string): void { + this.model.setEditKey(key); + this.renderList(); + } + private renderItem(item: IExcludeViewItem, idx: number, listFocused: boolean): HTMLElement { return item.editing ? this.renderEditItem(item) : From df334b1dd6b9a43edf3799cf50a7ad4b38273f4a Mon Sep 17 00:00:00 2001 From: Benjamin Pasero Date: Mon, 20 Aug 2018 07:41:36 +0200 Subject: [PATCH 0969/1276] fix #56715 --- src/vs/workbench/browser/parts/editor/noTabsTitleControl.ts | 2 ++ src/vs/workbench/browser/parts/editor/tabsTitleControl.ts | 2 ++ 2 files changed, 4 insertions(+) diff --git a/src/vs/workbench/browser/parts/editor/noTabsTitleControl.ts b/src/vs/workbench/browser/parts/editor/noTabsTitleControl.ts index 6b1cdc64ca1..1cf163403ee 100644 --- a/src/vs/workbench/browser/parts/editor/noTabsTitleControl.ts +++ b/src/vs/workbench/browser/parts/editor/noTabsTitleControl.ts @@ -88,6 +88,8 @@ export class NoTabsTitleControl extends TitleControl { // Close editor on middle mouse click if (e instanceof MouseEvent && e.button === 1 /* Middle Button */) { + EventHelper.stop(e, true /* for https://github.com/Microsoft/vscode/issues/56715 */); + this.group.closeEditor(this.group.activeEditor); } } diff --git a/src/vs/workbench/browser/parts/editor/tabsTitleControl.ts b/src/vs/workbench/browser/parts/editor/tabsTitleControl.ts index 5a73b95db7c..e764810c07e 100644 --- a/src/vs/workbench/browser/parts/editor/tabsTitleControl.ts +++ b/src/vs/workbench/browser/parts/editor/tabsTitleControl.ts @@ -490,6 +490,8 @@ export class TabsTitleControl extends TitleControl { tab.blur(); if (e.button === 1 /* Middle Button*/ && !this.originatesFromTabActionBar(e)) { + e.stopPropagation(); // for https://github.com/Microsoft/vscode/issues/56715 + this.blockRevealActiveTabOnce(); this.closeOneEditorAction.run({ groupId: this.group.id, editorIndex: index }); } From bb50de5845b1dbd5e8d21a4b3ce9a1fc1d1a500b Mon Sep 17 00:00:00 2001 From: Benjamin Pasero Date: Mon, 20 Aug 2018 07:41:48 +0200 Subject: [PATCH 0970/1276] :lipstick: --- src/vs/workbench/browser/layout.ts | 2 -- src/vs/workbench/services/part/common/partService.ts | 5 ----- src/vs/workbench/test/workbenchTestServices.ts | 2 -- 3 files changed, 9 deletions(-) diff --git a/src/vs/workbench/browser/layout.ts b/src/vs/workbench/browser/layout.ts index 5089f6ff8af..5008ce7eb35 100644 --- a/src/vs/workbench/browser/layout.ts +++ b/src/vs/workbench/browser/layout.ts @@ -70,7 +70,6 @@ export class WorkbenchLayout extends Disposable implements IVerticalSashLayoutPr private _panelHeight: number; private _panelWidth: number; - // Take parts as an object bag since instatation service does not have typings for constructors with 9+ arguments constructor( private parent: HTMLElement, private workbenchContainer: HTMLElement, @@ -704,7 +703,6 @@ export class WorkbenchLayout extends Disposable implements IVerticalSashLayoutPr return this.panelMaximized; } - // change part size along the main axis resizePart(part: Parts, sizeChange: number): void { const panelPosition = this.partService.getPanelPosition(); const sizeChangePxWidth = this.workbenchSize.width * (sizeChange / 100); diff --git a/src/vs/workbench/services/part/common/partService.ts b/src/vs/workbench/services/part/common/partService.ts index 887597600b8..71c7b465467 100644 --- a/src/vs/workbench/services/part/common/partService.ts +++ b/src/vs/workbench/services/part/common/partService.ts @@ -50,11 +50,6 @@ export interface IPartService { */ onEditorLayout: Event; - /** - * Asks the part service to layout all parts. - */ - layout(options?: ILayoutOptions): void; - /** * Asks the part service to if all parts have been created. */ diff --git a/src/vs/workbench/test/workbenchTestServices.ts b/src/vs/workbench/test/workbenchTestServices.ts index d7155fb2d67..c0970077503 100644 --- a/src/vs/workbench/test/workbenchTestServices.ts +++ b/src/vs/workbench/test/workbenchTestServices.ts @@ -399,8 +399,6 @@ export class TestPartService implements IPartService { return this._onEditorLayout.event; } - public layout(): void { } - public isCreated(): boolean { return true; } From c252511ed3dbd667fafe9953d106f98688a6b29a Mon Sep 17 00:00:00 2001 From: Joao Moreno Date: Mon, 20 Aug 2018 09:21:59 +0200 Subject: [PATCH 0971/1276] empty commit From 73db88ffc1c3bc71a57e372c1388621bf747a866 Mon Sep 17 00:00:00 2001 From: Pine Wu Date: Tue, 14 Aug 2018 09:28:29 -0700 Subject: [PATCH 0972/1276] @import and url() link. Fix Microsoft/vscode#29899 --- .../server/src/cssServerMain.ts | 32 ++++++++++++++----- 1 file changed, 24 insertions(+), 8 deletions(-) diff --git a/extensions/css-language-features/server/src/cssServerMain.ts b/extensions/css-language-features/server/src/cssServerMain.ts index 8a822ce8b64..f303eb3b1b0 100644 --- a/extensions/css-language-features/server/src/cssServerMain.ts +++ b/extensions/css-language-features/server/src/cssServerMain.ts @@ -86,6 +86,9 @@ connection.onInitialize((params: InitializeParams): InitializeResult => { referencesProvider: true, definitionProvider: true, documentHighlightProvider: true, + documentLinkProvider: { + resolveProvider: false + }, codeActionProvider: true, renameProvider: true, colorProvider: {}, @@ -227,29 +230,42 @@ connection.onDocumentSymbol((documentSymbolParams, token) => { }, [], `Error while computing document symbols for ${documentSymbolParams.textDocument.uri}`, token); }); -connection.onDefinition((documentSymbolParams, token) => { +connection.onDefinition((documentDefinitionParams, token) => { return runSafe(() => { - const document = documents.get(documentSymbolParams.textDocument.uri); + const document = documents.get(documentDefinitionParams.textDocument.uri); if (document) { const stylesheet = stylesheets.get(document); - return getLanguageService(document).findDefinition(document, documentSymbolParams.position, stylesheet); + return getLanguageService(document).findDefinition(document, documentDefinitionParams.position, stylesheet); } return null; - }, null, `Error while computing definitions for ${documentSymbolParams.textDocument.uri}`, token); + }, null, `Error while computing definitions for ${documentDefinitionParams.textDocument.uri}`, token); }); -connection.onDocumentHighlight((documentSymbolParams, token) => { +connection.onDocumentHighlight((documentHighlightParams, token) => { return runSafe(() => { - const document = documents.get(documentSymbolParams.textDocument.uri); + const document = documents.get(documentHighlightParams.textDocument.uri); if (document) { const stylesheet = stylesheets.get(document); - return getLanguageService(document).findDocumentHighlights(document, documentSymbolParams.position, stylesheet); + return getLanguageService(document).findDocumentHighlights(document, documentHighlightParams.position, stylesheet); } return []; - }, [], `Error while computing document highlights for ${documentSymbolParams.textDocument.uri}`, token); + }, [], `Error while computing document highlights for ${documentHighlightParams.textDocument.uri}`, token); }); + +connection.onDocumentLinks((documentLinkParams, token) => { + return runSafe(() => { + const document = documents.get(documentLinkParams.textDocument.uri); + if (document) { + const stylesheet = stylesheets.get(document); + return getLanguageService(document).findDocumentLinks(document, stylesheet); + } + return []; + }, [], `Error while computing document links for ${documentLinkParams.textDocument.uri}`, token); +}); + + connection.onReferences((referenceParams, token) => { return runSafe(() => { const document = documents.get(referenceParams.textDocument.uri); From 90743215aa2faea9ab9c94c8b328ef3d8c7f8c8b Mon Sep 17 00:00:00 2001 From: Pine Wu Date: Thu, 16 Aug 2018 16:01:28 -0700 Subject: [PATCH 0973/1276] DocumentContext to remove `url` dependency from service --- .../server/src/cssServerMain.ts | 9 +++-- .../server/src/utils/documentContext.ts | 40 +++++++++++++++++++ 2 files changed, 45 insertions(+), 4 deletions(-) create mode 100644 extensions/css-language-features/server/src/utils/documentContext.ts diff --git a/extensions/css-language-features/server/src/cssServerMain.ts b/extensions/css-language-features/server/src/cssServerMain.ts index f303eb3b1b0..853f6690473 100644 --- a/extensions/css-language-features/server/src/cssServerMain.ts +++ b/extensions/css-language-features/server/src/cssServerMain.ts @@ -7,14 +7,14 @@ import { createConnection, IConnection, TextDocuments, InitializeParams, InitializeResult, ServerCapabilities, ConfigurationRequest, WorkspaceFolder } from 'vscode-languageserver'; - +import URI from 'vscode-uri'; import { TextDocument, CompletionList } from 'vscode-languageserver-types'; import { getCSSLanguageService, getSCSSLanguageService, getLESSLanguageService, LanguageSettings, LanguageService, Stylesheet } from 'vscode-css-languageservice'; import { getLanguageModelCache } from './languageModelCache'; -import { formatError, runSafe } from './utils/runner'; -import URI from 'vscode-uri'; import { getPathCompletionParticipant } from './pathCompletion'; +import { formatError, runSafe } from './utils/runner'; +import { getDocumentContext } from './utils/documentContext'; export interface Settings { css: LanguageSettings; @@ -258,8 +258,9 @@ connection.onDocumentLinks((documentLinkParams, token) => { return runSafe(() => { const document = documents.get(documentLinkParams.textDocument.uri); if (document) { + const documentContext = getDocumentContext(document.uri, workspaceFolders); const stylesheet = stylesheets.get(document); - return getLanguageService(document).findDocumentLinks(document, stylesheet); + return getLanguageService(document).findDocumentLinks(document, stylesheet, documentContext); } return []; }, [], `Error while computing document links for ${documentLinkParams.textDocument.uri}`, token); diff --git a/extensions/css-language-features/server/src/utils/documentContext.ts b/extensions/css-language-features/server/src/utils/documentContext.ts new file mode 100644 index 00000000000..b37993b7655 --- /dev/null +++ b/extensions/css-language-features/server/src/utils/documentContext.ts @@ -0,0 +1,40 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ +'use strict'; + +import { DocumentContext } from 'vscode-css-languageservice'; +import { endsWith, startsWith } from '../utils/strings'; +import * as url from 'url'; +import { WorkspaceFolder } from 'vscode-languageserver'; + +export function getDocumentContext(documentUri: string, workspaceFolders: WorkspaceFolder[]): DocumentContext { + function getRootFolder(): string | undefined { + for (let folder of workspaceFolders) { + let folderURI = folder.uri; + if (!endsWith(folderURI, '/')) { + folderURI = folderURI + '/'; + } + if (startsWith(documentUri, folderURI)) { + return folderURI; + } + } + return void 0; + } + + return { + resolveReference: (ref, base = documentUri) => { + if (ref[0] === '/') { // resolve absolute path against the current workspace folder + if (startsWith(base, 'file://')) { + let folderUri = getRootFolder(); + if (folderUri) { + return folderUri + ref.substr(1); + } + } + } + return url.resolve(base, ref); + }, + }; +} + From 73ca0345bc091212e254821aa86156a2f0220743 Mon Sep 17 00:00:00 2001 From: Pine Wu Date: Mon, 20 Aug 2018 01:06:23 -0700 Subject: [PATCH 0974/1276] Update css-languageservice --- extensions/css-language-features/server/package.json | 2 +- extensions/css-language-features/server/yarn.lock | 12 ++++++++---- 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/extensions/css-language-features/server/package.json b/extensions/css-language-features/server/package.json index 98a8a370800..6e85706a2f1 100644 --- a/extensions/css-language-features/server/package.json +++ b/extensions/css-language-features/server/package.json @@ -8,7 +8,7 @@ "node": "*" }, "dependencies": { - "vscode-css-languageservice": "^3.0.10-next.2", + "vscode-css-languageservice": "^3.0.10-next.3", "vscode-languageserver": "^4.4.0" }, "devDependencies": { diff --git a/extensions/css-language-features/server/yarn.lock b/extensions/css-language-features/server/yarn.lock index 61e83d9a85d..c2ae2ced51a 100644 --- a/extensions/css-language-features/server/yarn.lock +++ b/extensions/css-language-features/server/yarn.lock @@ -194,11 +194,11 @@ supports-color@5.4.0: dependencies: has-flag "^3.0.0" -vscode-css-languageservice@^3.0.10-next.2: - version "3.0.10-next.2" - resolved "https://registry.yarnpkg.com/vscode-css-languageservice/-/vscode-css-languageservice-3.0.10-next.2.tgz#b703af89be433507836178efd7f88bb0669fc4e8" +vscode-css-languageservice@^3.0.10-next.3: + version "3.0.10-next.3" + resolved "https://registry.yarnpkg.com/vscode-css-languageservice/-/vscode-css-languageservice-3.0.10-next.3.tgz#d663f03b8a9bf11222bd2cd39e9aa05e1a58c58d" dependencies: - vscode-languageserver-types "^3.10.0" + vscode-languageserver-types "^3.10.1" vscode-nls "^3.2.4" vscode-jsonrpc@^3.6.2: @@ -216,6 +216,10 @@ vscode-languageserver-types@^3.10.0: version "3.10.0" resolved "https://registry.yarnpkg.com/vscode-languageserver-types/-/vscode-languageserver-types-3.10.0.tgz#944e5308f3b36a3f372c766f1a344e903ec9c389" +vscode-languageserver-types@^3.10.1: + version "3.10.1" + resolved "https://registry.yarnpkg.com/vscode-languageserver-types/-/vscode-languageserver-types-3.10.1.tgz#d5d5f44f688a3b2aa9857dc53cb9cacca73fe35a" + vscode-languageserver@^4.4.0: version "4.4.0" resolved "https://registry.yarnpkg.com/vscode-languageserver/-/vscode-languageserver-4.4.0.tgz#b6e8b37a739ccb629d92f3635f0099d191c856fa" From 6e559261f677793fea424c6eb5cb13d0301ffff1 Mon Sep 17 00:00:00 2001 From: Johannes Rieken Date: Mon, 20 Aug 2018 10:17:22 +0200 Subject: [PATCH 0975/1276] adopt new vscode-nls-dev, #56792 --- build/gulpfile.extensions.js | 4 +++- package.json | 4 ++-- yarn.lock | 6 +++--- 3 files changed, 8 insertions(+), 6 deletions(-) diff --git a/build/gulpfile.extensions.js b/build/gulpfile.extensions.js index 57d52b03b06..bedc9a293fb 100644 --- a/build/gulpfile.extensions.js +++ b/build/gulpfile.extensions.js @@ -8,6 +8,7 @@ require('events').EventEmitter.defaultMaxListeners = 100; const gulp = require('gulp'); const path = require('path'); +const fs = require('fs'); const tsb = require('gulp-tsb'); const es = require('event-stream'); const filter = require('gulp-filter'); @@ -74,6 +75,7 @@ const tasks = compilations.map(function (tsconfigFile) { tsOptions.base = path.dirname(absolutePath); const compilation = tsb.create(tsOptions, null, null, err => reporter(err.toString())); + const nlsOption = fs.existsSync(path.join(root, 'extension.webpack.config.js')) ? { keepFilenames: true } : undefined; return function () { const input = es.through(); @@ -89,7 +91,7 @@ const tasks = compilations.map(function (tsconfigFile) { .pipe(tsFilter) .pipe(util.loadSourcemaps()) .pipe(compilation()) - .pipe(build ? nlsDev.rewriteLocalizeCalls({ keepFilenames: true }) : es.through()) + .pipe(build ? nlsDev.rewriteLocalizeCalls(nlsOption) : es.through()) .pipe(build ? util.stripSourceMappingURL() : es.through()) .pipe(sourcemaps.write('.', { sourceMappingURL: !build ? null : f => `${baseUrl}/${f.relative}.map`, diff --git a/package.json b/package.json index d0e982ce0b7..5b73450aa47 100644 --- a/package.json +++ b/package.json @@ -125,7 +125,7 @@ "vinyl": "^0.4.5", "vinyl-fs": "^2.4.3", "vsce": "1.33.2", - "vscode-nls-dev": "3.1.0", + "vscode-nls-dev": "3.1.1", "webpack": "^4.16.5", "webpack-cli": "^3.1.0", "webpack-stream": "^5.1.1" @@ -142,4 +142,4 @@ "windows-mutex": "^0.2.0", "windows-process-tree": "0.2.2" } -} \ No newline at end of file +} diff --git a/yarn.lock b/yarn.lock index b56aa332449..e67580f77c1 100644 --- a/yarn.lock +++ b/yarn.lock @@ -7880,9 +7880,9 @@ vscode-fsevents@0.3.8: dependencies: nan "^2.3.0" -vscode-nls-dev@3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/vscode-nls-dev/-/vscode-nls-dev-3.1.0.tgz#afbd6c6291446a9f82cc19b781841ae307fa36c2" +vscode-nls-dev@3.1.1: + version "3.1.1" + resolved "https://registry.yarnpkg.com/vscode-nls-dev/-/vscode-nls-dev-3.1.1.tgz#e7fa2e8e641b1579b25779acfda0e5f7c28f1fb9" dependencies: clone "^2.1.1" event-stream "^3.3.4" From d8b0484dc878825898819bbc9d55578e5d3816d5 Mon Sep 17 00:00:00 2001 From: Benjamin Pasero Date: Mon, 20 Aug 2018 10:58:26 +0200 Subject: [PATCH 0976/1276] menu: integrated terminal => terminal --- src/vs/workbench/parts/terminal/common/terminalMenu.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vs/workbench/parts/terminal/common/terminalMenu.ts b/src/vs/workbench/parts/terminal/common/terminalMenu.ts index 52498a02f51..0223a9df008 100644 --- a/src/vs/workbench/parts/terminal/common/terminalMenu.ts +++ b/src/vs/workbench/parts/terminal/common/terminalMenu.ts @@ -16,7 +16,7 @@ export function setupTerminalMenu() { group: '4_panels', command: { id: TERMINAL_COMMAND_ID.TOGGLE, - title: nls.localize({ key: 'miToggleIntegratedTerminal', comment: ['&& denotes a mnemonic'] }, "&&Integrated Terminal") + title: nls.localize({ key: 'miToggleIntegratedTerminal', comment: ['&& denotes a mnemonic'] }, "&&Terminal") }, order: 3 }); From c0f818e5ae69aa81112bfe69158a66b731bcad69 Mon Sep 17 00:00:00 2001 From: Martin Aeschlimann Date: Mon, 20 Aug 2018 11:53:20 +0200 Subject: [PATCH 0977/1276] On Switching Files file is not selected in left pane. Fixes #56588 --- src/vs/base/common/resources.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vs/base/common/resources.ts b/src/vs/base/common/resources.ts index 53357fe29f5..cefcd007927 100644 --- a/src/vs/base/common/resources.ts +++ b/src/vs/base/common/resources.ts @@ -30,7 +30,7 @@ export function basenameOrAuthority(resource: URI): string { * @param base A uri which is "longer" * @param parentCandidate A uri which is "shorter" then `base` */ -export function isEqualOrParent(base: URI, parentCandidate: URI, ignoreCase?: boolean): boolean { +export function isEqualOrParent(base: URI, parentCandidate: URI, ignoreCase = hasToIgnoreCase(base)): boolean { if (base.scheme === parentCandidate.scheme) { if (base.scheme === Schemas.file) { return paths.isEqualOrParent(fsPath(base), fsPath(parentCandidate), ignoreCase); From 78f6a69173c63da3f9fe9654bbb194930da7cd0a Mon Sep 17 00:00:00 2001 From: isidor Date: Fri, 17 Aug 2018 10:53:58 +0200 Subject: [PATCH 0978/1276] move debug session to a seperate file in electron-browser --- .../parts/debug/browser/debugActions.ts | 6 +- src/vs/workbench/parts/debug/common/debug.ts | 6 +- .../parts/debug/common/debugModel.ts | 185 +----------------- .../debug/electron-browser/callStackView.ts | 3 +- .../debug/electron-browser/debugService.ts | 6 +- .../debug/electron-browser/debugSession.ts | 176 +++++++++++++++++ .../debug/test/browser/baseDebugView.test.ts | 5 +- .../debug/test/common/debugViewModel.test.ts | 5 +- .../parts/debug/test/common/mockDebug.ts | 49 ++++- .../debugModel.test.ts | 22 +-- 10 files changed, 257 insertions(+), 206 deletions(-) create mode 100644 src/vs/workbench/parts/debug/electron-browser/debugSession.ts rename src/vs/workbench/parts/debug/test/{node => electron-browser}/debugModel.test.ts (94%) diff --git a/src/vs/workbench/parts/debug/browser/debugActions.ts b/src/vs/workbench/parts/debug/browser/debugActions.ts index 04fd4058642..6191db0921c 100644 --- a/src/vs/workbench/parts/debug/browser/debugActions.ts +++ b/src/vs/workbench/parts/debug/browser/debugActions.ts @@ -14,7 +14,7 @@ import { IWorkspaceContextService, WorkbenchState } from 'vs/platform/workspace/ import { IFileService } from 'vs/platform/files/common/files'; import { IDebugService, State, ISession, IThread, IEnablement, IBreakpoint, IStackFrame, REPL_ID, SessionState } from 'vs/workbench/parts/debug/common/debug'; -import { Variable, Expression, Thread, Breakpoint, Session } from 'vs/workbench/parts/debug/common/debugModel'; +import { Variable, Expression, Thread, Breakpoint } from 'vs/workbench/parts/debug/common/debugModel'; import { IPartService } from 'vs/workbench/services/part/common/partService'; import { IPanelService } from 'vs/workbench/services/panel/common/panelService'; import { IEditorService } from 'vs/workbench/services/editor/common/editorService'; @@ -230,7 +230,7 @@ export class RestartAction extends AbstractDebugAction { } public run(session: ISession): TPromise { - if (!(session instanceof Session)) { + if (!session || !session.getId) { session = this.debugService.getViewModel().focusedSession; } @@ -325,7 +325,7 @@ export class StopAction extends AbstractDebugAction { } public run(session: ISession): TPromise { - if (!(session instanceof Session)) { + if (!session || !session.getId) { session = this.debugService.getViewModel().focusedSession; } diff --git a/src/vs/workbench/parts/debug/common/debug.ts b/src/vs/workbench/parts/debug/common/debug.ts index 6af33b36e60..d527aef5481 100644 --- a/src/vs/workbench/parts/debug/common/debug.ts +++ b/src/vs/workbench/parts/debug/common/debug.ts @@ -146,16 +146,20 @@ export enum SessionState { } export interface ISession extends ITreeElement { - getName(includeRoot: boolean): string; readonly configuration: IConfig; readonly raw: IRawSession; readonly state: SessionState; + + getName(includeRoot: boolean): string; getSourceForUri(modelUri: uri): Source; getThread(threadId: number): IThread; getAllThreads(): ReadonlyArray; getSource(raw: DebugProtocol.Source): Source; getLoadedSources(): TPromise; completions(frameId: number, text: string, position: Position, overwriteBefore: number): TPromise; + clearThreads(removeThreads: boolean, reference?: number): void; + + rawUpdate(data: IRawModelUpdate): void; } export interface IThread extends ITreeElement { diff --git a/src/vs/workbench/parts/debug/common/debugModel.ts b/src/vs/workbench/parts/debug/common/debugModel.ts index 3a58268ec72..6b8a4ef7cff 100644 --- a/src/vs/workbench/parts/debug/common/debugModel.ts +++ b/src/vs/workbench/parts/debug/common/debugModel.ts @@ -16,14 +16,11 @@ import severity from 'vs/base/common/severity'; import { isObject, isString, isUndefinedOrNull } from 'vs/base/common/types'; import { distinct } from 'vs/base/common/arrays'; import { Range, IRange } from 'vs/editor/common/core/range'; -import { ISuggestion } from 'vs/editor/common/modes'; -import { Position } from 'vs/editor/common/core/position'; import { ITreeElement, IExpression, IExpressionContainer, ISession, IStackFrame, IExceptionBreakpoint, IBreakpoint, IFunctionBreakpoint, IModel, IReplElementSource, - IConfig, IRawSession, IThread, IRawModelUpdate, IScope, IRawStoppedDetails, IEnablement, IBreakpointData, IExceptionInfo, IReplElement, SessionState, IBreakpointsChangeEvent, IBreakpointUpdateData, IBaseBreakpoint + IThread, IRawModelUpdate, IScope, IRawStoppedDetails, IEnablement, IBreakpointData, IExceptionInfo, IReplElement, IBreakpointsChangeEvent, IBreakpointUpdateData, IBaseBreakpoint } from 'vs/workbench/parts/debug/common/debug'; import { Source } from 'vs/workbench/parts/debug/common/debugSource'; -import { mixin } from 'vs/base/common/objects'; import { commonSuffixLength } from 'vs/base/common/strings'; import { sep } from 'vs/base/common/paths'; import { IEditorService } from 'vs/workbench/services/editor/common/editorService'; @@ -552,175 +549,6 @@ export class Thread implements IThread { } } -export class Session implements ISession { - - private sources: Map; - private threads: Map; - - constructor(private _configuration: { resolved: IConfig, unresolved: IConfig }, private session: IRawSession & ITreeElement) { - this.threads = new Map(); - this.sources = new Map(); - } - - public get configuration(): IConfig { - return this._configuration.resolved; - } - - public get unresolvedConfiguration(): IConfig { - return this._configuration.unresolved; - } - - public get raw(): IRawSession & ITreeElement { - return this.session; - } - - public set raw(value: IRawSession & ITreeElement) { - this.session = value; - } - - public getName(includeRoot: boolean): string { - return includeRoot && this.raw.root ? `${this.configuration.name} (${resources.basenameOrAuthority(this.raw.root.uri)})` : this.configuration.name; - } - - public get state(): SessionState { - return this.configuration.type === 'attach' ? SessionState.ATTACH : SessionState.LAUNCH; - } - - public getSourceForUri(modelUri: uri): Source { - return this.sources.get(modelUri.toString()); - } - - public getSource(raw: DebugProtocol.Source): Source { - let source = new Source(raw, this.getId()); - if (this.sources.has(source.uri.toString())) { - source = this.sources.get(source.uri.toString()); - source.raw = mixin(source.raw, raw); - if (source.raw && raw) { - // Always take the latest presentation hint from adapter #42139 - source.raw.presentationHint = raw.presentationHint; - } - } else { - this.sources.set(source.uri.toString(), source); - } - - return source; - } - - public getThread(threadId: number): Thread { - return this.threads.get(threadId); - } - - public getAllThreads(): IThread[] { - const result: IThread[] = []; - this.threads.forEach(t => result.push(t)); - return result; - } - - public getLoadedSources(): TPromise { - return this.raw.loadedSources({}).then(response => { - return response.body.sources.map(src => this.getSource(src)); - }, error => { - return []; - }); - } - - public getId(): string { - return this.session.getId(); - } - - public rawUpdate(data: IRawModelUpdate): void { - - if (data.thread && !this.threads.has(data.threadId)) { - // A new thread came in, initialize it. - this.threads.set(data.threadId, new Thread(this, data.thread.name, data.thread.id)); - } else if (data.thread && data.thread.name) { - // Just the thread name got updated #18244 - this.threads.get(data.threadId).name = data.thread.name; - } - - if (data.stoppedDetails) { - // Set the availability of the threads' callstacks depending on - // whether the thread is stopped or not - if (data.stoppedDetails.allThreadsStopped) { - this.threads.forEach(thread => { - thread.stoppedDetails = thread.threadId === data.threadId ? data.stoppedDetails : { reason: undefined }; - thread.stopped = true; - thread.clearCallStack(); - }); - } else if (this.threads.has(data.threadId)) { - // One thread is stopped, only update that thread. - const thread = this.threads.get(data.threadId); - thread.stoppedDetails = data.stoppedDetails; - thread.clearCallStack(); - thread.stopped = true; - } - } - } - - public clearThreads(removeThreads: boolean, reference: number = undefined): void { - if (reference !== undefined && reference !== null) { - if (this.threads.has(reference)) { - const thread = this.threads.get(reference); - thread.clearCallStack(); - thread.stoppedDetails = undefined; - thread.stopped = false; - - if (removeThreads) { - this.threads.delete(reference); - } - } - } else { - this.threads.forEach(thread => { - thread.clearCallStack(); - thread.stoppedDetails = undefined; - thread.stopped = false; - }); - - if (removeThreads) { - this.threads.clear(); - ExpressionContainer.allValues.clear(); - } - } - } - - public completions(frameId: number, text: string, position: Position, overwriteBefore: number): TPromise { - if (!this.raw.capabilities.supportsCompletionsRequest) { - return TPromise.as([]); - } - - return this.raw.completions({ - frameId, - text, - column: position.column, - line: position.lineNumber - }).then(response => { - const result: ISuggestion[] = []; - if (response && response.body && response.body.targets) { - response.body.targets.forEach(item => { - if (item && item.label) { - result.push({ - label: item.label, - insertText: item.text || item.label, - type: item.type, - filterText: item.start && item.length && text.substr(item.start, item.length).concat(item.label), - overwriteBefore: item.length || overwriteBefore - }); - } - }); - } - - return result; - }, () => []); - } - - setNotAvailable(modelUri: uri) { - const source = this.sources.get(modelUri.toString()); - if (source) { - source.available = false; - } - } -} - export class Enablement implements IEnablement { constructor( public enabled: boolean, @@ -905,7 +733,7 @@ export class ThreadAndSessionIds implements ITreeElement { export class Model implements IModel { - private sessions: Session[]; + private sessions: ISession[]; private toDispose: lifecycle.IDisposable[]; private replElements: IReplElement[]; private schedulers = new Map(); @@ -935,15 +763,12 @@ export class Model implements IModel { return 'root'; } - public getSessions(): Session[] { + public getSessions(): ISession[] { return this.sessions; } - public addSession(configuration: { resolved: IConfig, unresolved: IConfig }, raw: IRawSession & ITreeElement): Session { - const session = new Session(configuration, raw); + public addSession(session: ISession): void { this.sessions.push(session); - - return session; } public removeSession(id: string): void { @@ -1277,7 +1102,7 @@ export class Model implements IModel { } public sourceIsNotAvailable(uri: uri): void { - this.sessions.forEach(p => p.setNotAvailable(uri)); + this.sessions.forEach(p => p.getSourceForUri(uri).available = false); this._onDidChangeCallStack.fire(); } diff --git a/src/vs/workbench/parts/debug/electron-browser/callStackView.ts b/src/vs/workbench/parts/debug/electron-browser/callStackView.ts index 64e48d2f6d9..0298950898c 100644 --- a/src/vs/workbench/parts/debug/electron-browser/callStackView.ts +++ b/src/vs/workbench/parts/debug/electron-browser/callStackView.ts @@ -10,7 +10,7 @@ import { TPromise } from 'vs/base/common/winjs.base'; import * as errors from 'vs/base/common/errors'; import { TreeViewsViewletPanel, IViewletViewOptions } from 'vs/workbench/browser/parts/views/viewsViewlet'; import { IDebugService, State, IStackFrame, ISession, IThread, CONTEXT_CALLSTACK_ITEM_TYPE } from 'vs/workbench/parts/debug/common/debug'; -import { Thread, StackFrame, ThreadAndSessionIds, Session, Model } from 'vs/workbench/parts/debug/common/debugModel'; +import { Thread, StackFrame, ThreadAndSessionIds, Model } from 'vs/workbench/parts/debug/common/debugModel'; import { IContextMenuService } from 'vs/platform/contextview/browser/contextView'; import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; import { MenuId } from 'vs/platform/actions/common/actions'; @@ -28,6 +28,7 @@ import { Separator } from 'vs/base/browser/ui/actionbar/actionbar'; import { IContextKey, IContextKeyService } from 'vs/platform/contextkey/common/contextkey'; import { IViewletPanelOptions } from 'vs/workbench/browser/parts/views/panelViewlet'; import { IUriLabelService } from 'vs/platform/uriLabel/common/uriLabel'; +import { Session } from 'vs/workbench/parts/debug/electron-browser/debugSession'; const $ = dom.$; diff --git a/src/vs/workbench/parts/debug/electron-browser/debugService.ts b/src/vs/workbench/parts/debug/electron-browser/debugService.ts index a5e2dcee7a0..73c6353846b 100644 --- a/src/vs/workbench/parts/debug/electron-browser/debugService.ts +++ b/src/vs/workbench/parts/debug/electron-browser/debugService.ts @@ -28,7 +28,7 @@ import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry'; import { IStorageService, StorageScope } from 'vs/platform/storage/common/storage'; import * as debug from 'vs/workbench/parts/debug/common/debug'; import { RawDebugSession } from 'vs/workbench/parts/debug/electron-browser/rawDebugSession'; -import { Model, ExceptionBreakpoint, FunctionBreakpoint, Breakpoint, Expression, RawObjectReplElement, ExpressionContainer, Session, Thread } from 'vs/workbench/parts/debug/common/debugModel'; +import { Model, ExceptionBreakpoint, FunctionBreakpoint, Breakpoint, Expression, RawObjectReplElement, ExpressionContainer, Thread } from 'vs/workbench/parts/debug/common/debugModel'; import { ViewModel } from 'vs/workbench/parts/debug/common/debugViewModel'; import * as debugactions from 'vs/workbench/parts/debug/browser/debugActions'; import { ConfigurationManager } from 'vs/workbench/parts/debug/electron-browser/debugConfigurationManager'; @@ -55,6 +55,7 @@ import { normalizeDriveLetter } from 'vs/base/common/labels'; import { RunOnceScheduler } from 'vs/base/common/async'; import product from 'vs/platform/node/product'; import { deepClone, equals } from 'vs/base/common/objects'; +import { Session } from 'vs/workbench/parts/debug/electron-browser/debugSession'; const DEBUG_BREAKPOINTS_KEY = 'debug.breakpoint'; const DEBUG_BREAKPOINTS_ACTIVATED_KEY = 'debug.breakpointactivated'; @@ -895,7 +896,8 @@ export class DebugService implements debug.IDebugService { const raw = this.instantiationService.createInstance(RawDebugSession, sessionId, configuration.resolved.debugServer, dbg, customTelemetryService, root); if (!session) { - session = this.model.addSession(configuration, raw); + session = new Session(configuration, raw); + this.model.addSession(session); this.allSessions.set(session.getId(), session); } else { session.raw = raw; diff --git a/src/vs/workbench/parts/debug/electron-browser/debugSession.ts b/src/vs/workbench/parts/debug/electron-browser/debugSession.ts new file mode 100644 index 00000000000..75170c00238 --- /dev/null +++ b/src/vs/workbench/parts/debug/electron-browser/debugSession.ts @@ -0,0 +1,176 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import uri from 'vs/base/common/uri'; +import * as resources from 'vs/base/common/resources'; +import { TPromise } from 'vs/base/common/winjs.base'; +import { ISuggestion } from 'vs/editor/common/modes'; +import { Position } from 'vs/editor/common/core/position'; +import { ITreeElement, ISession, IConfig, IRawSession, IThread, IRawModelUpdate, SessionState } from 'vs/workbench/parts/debug/common/debug'; +import { Source } from 'vs/workbench/parts/debug/common/debugSource'; +import { mixin } from 'vs/base/common/objects'; +import { Thread, ExpressionContainer } from 'vs/workbench/parts/debug/common/debugModel'; + +export class Session implements ISession { + + private sources: Map; + private threads: Map; + + constructor(private _configuration: { resolved: IConfig, unresolved: IConfig }, private session: IRawSession & ITreeElement) { + this.threads = new Map(); + this.sources = new Map(); + } + + public get configuration(): IConfig { + return this._configuration.resolved; + } + + public get unresolvedConfiguration(): IConfig { + return this._configuration.unresolved; + } + + public get raw(): IRawSession & ITreeElement { + return this.session; + } + + public set raw(value: IRawSession & ITreeElement) { + this.session = value; + } + + public getName(includeRoot: boolean): string { + return includeRoot && this.raw.root ? `${this.configuration.name} (${resources.basenameOrAuthority(this.raw.root.uri)})` : this.configuration.name; + } + + public get state(): SessionState { + return this.configuration.type === 'attach' ? SessionState.ATTACH : SessionState.LAUNCH; + } + + public getSourceForUri(modelUri: uri): Source { + return this.sources.get(modelUri.toString()); + } + + public getSource(raw: DebugProtocol.Source): Source { + let source = new Source(raw, this.getId()); + if (this.sources.has(source.uri.toString())) { + source = this.sources.get(source.uri.toString()); + source.raw = mixin(source.raw, raw); + if (source.raw && raw) { + // Always take the latest presentation hint from adapter #42139 + source.raw.presentationHint = raw.presentationHint; + } + } else { + this.sources.set(source.uri.toString(), source); + } + + return source; + } + + public getThread(threadId: number): Thread { + return this.threads.get(threadId); + } + + public getAllThreads(): IThread[] { + const result: IThread[] = []; + this.threads.forEach(t => result.push(t)); + return result; + } + + public getLoadedSources(): TPromise { + return this.raw.loadedSources({}).then(response => { + return response.body.sources.map(src => this.getSource(src)); + }, error => { + return []; + }); + } + + public getId(): string { + return this.session.getId(); + } + + public rawUpdate(data: IRawModelUpdate): void { + + if (data.thread && !this.threads.has(data.threadId)) { + // A new thread came in, initialize it. + this.threads.set(data.threadId, new Thread(this, data.thread.name, data.thread.id)); + } else if (data.thread && data.thread.name) { + // Just the thread name got updated #18244 + this.threads.get(data.threadId).name = data.thread.name; + } + + if (data.stoppedDetails) { + // Set the availability of the threads' callstacks depending on + // whether the thread is stopped or not + if (data.stoppedDetails.allThreadsStopped) { + this.threads.forEach(thread => { + thread.stoppedDetails = thread.threadId === data.threadId ? data.stoppedDetails : { reason: undefined }; + thread.stopped = true; + thread.clearCallStack(); + }); + } else if (this.threads.has(data.threadId)) { + // One thread is stopped, only update that thread. + const thread = this.threads.get(data.threadId); + thread.stoppedDetails = data.stoppedDetails; + thread.clearCallStack(); + thread.stopped = true; + } + } + } + + public clearThreads(removeThreads: boolean, reference: number = undefined): void { + if (reference !== undefined && reference !== null) { + if (this.threads.has(reference)) { + const thread = this.threads.get(reference); + thread.clearCallStack(); + thread.stoppedDetails = undefined; + thread.stopped = false; + + if (removeThreads) { + this.threads.delete(reference); + } + } + } else { + this.threads.forEach(thread => { + thread.clearCallStack(); + thread.stoppedDetails = undefined; + thread.stopped = false; + }); + + if (removeThreads) { + this.threads.clear(); + ExpressionContainer.allValues.clear(); + } + } + } + + public completions(frameId: number, text: string, position: Position, overwriteBefore: number): TPromise { + if (!this.raw.capabilities.supportsCompletionsRequest) { + return TPromise.as([]); + } + + return this.raw.completions({ + frameId, + text, + column: position.column, + line: position.lineNumber + }).then(response => { + const result: ISuggestion[] = []; + if (response && response.body && response.body.targets) { + response.body.targets.forEach(item => { + if (item && item.label) { + result.push({ + label: item.label, + insertText: item.text || item.label, + type: item.type, + filterText: item.start && item.length && text.substr(item.start, item.length).concat(item.label), + overwriteBefore: item.length || overwriteBefore + }); + } + }); + } + + return result; + }, () => []); + } +} diff --git a/src/vs/workbench/parts/debug/test/browser/baseDebugView.test.ts b/src/vs/workbench/parts/debug/test/browser/baseDebugView.test.ts index d52a69598b8..837cb46a9b6 100644 --- a/src/vs/workbench/parts/debug/test/browser/baseDebugView.test.ts +++ b/src/vs/workbench/parts/debug/test/browser/baseDebugView.test.ts @@ -6,7 +6,7 @@ import * as assert from 'assert'; import { replaceWhitespace, renderExpressionValue, renderVariable } from 'vs/workbench/parts/debug/browser/baseDebugView'; import * as dom from 'vs/base/browser/dom'; -import { Expression, Variable, Session, Scope, StackFrame, Thread } from 'vs/workbench/parts/debug/common/debugModel'; +import { Expression, Variable, Scope, StackFrame, Thread } from 'vs/workbench/parts/debug/common/debugModel'; import { MockSession } from 'vs/workbench/parts/debug/test/common/mockDebug'; const $ = dom.$; @@ -52,8 +52,7 @@ suite('Debug - Base Debug View', () => { }); test('render variable', () => { - const rawSession = new MockSession(); - const session = new Session({ resolved: { name: 'mockSession', type: 'node', request: 'launch' }, unresolved: undefined }, rawSession); + const session = new MockSession(); const thread = new Thread(session, 'mockthread', 1); const stackFrame = new StackFrame(thread, 1, null, 'app.js', 'normal', { startLineNumber: 1, startColumn: 1, endLineNumber: undefined, endColumn: undefined }, 0); const scope = new Scope(stackFrame, 1, 'local', 1, false, 10, 10); diff --git a/src/vs/workbench/parts/debug/test/common/debugViewModel.test.ts b/src/vs/workbench/parts/debug/test/common/debugViewModel.test.ts index 733ae781c37..a466b211fe4 100644 --- a/src/vs/workbench/parts/debug/test/common/debugViewModel.test.ts +++ b/src/vs/workbench/parts/debug/test/common/debugViewModel.test.ts @@ -5,7 +5,7 @@ import * as assert from 'assert'; import { ViewModel } from 'vs/workbench/parts/debug/common/debugViewModel'; -import { StackFrame, Expression, Thread, Session } from 'vs/workbench/parts/debug/common/debugModel'; +import { StackFrame, Expression, Thread } from 'vs/workbench/parts/debug/common/debugModel'; import { MockSession } from 'vs/workbench/parts/debug/test/common/mockDebug'; import { MockContextKeyService } from 'vs/platform/keybinding/test/common/mockKeybindingService'; @@ -23,8 +23,7 @@ suite('Debug - View Model', () => { test('focused stack frame', () => { assert.equal(model.focusedStackFrame, null); assert.equal(model.focusedThread, null); - const mockSession = new MockSession(); - const session = new Session({ resolved: { name: 'mockSession', type: 'node', request: 'launch' }, unresolved: undefined }, mockSession); + const session = new MockSession(); const thread = new Thread(session, 'myThread', 1); const frame = new StackFrame(thread, 1, null, 'app.js', 'normal', { startColumn: 1, startLineNumber: 1, endColumn: undefined, endLineNumber: undefined }, 0); model.setFocus(frame, thread, session, false); diff --git a/src/vs/workbench/parts/debug/test/common/mockDebug.ts b/src/vs/workbench/parts/debug/test/common/mockDebug.ts index f92a322a3a0..c9914760a19 100644 --- a/src/vs/workbench/parts/debug/test/common/mockDebug.ts +++ b/src/vs/workbench/parts/debug/test/common/mockDebug.ts @@ -7,7 +7,10 @@ import uri from 'vs/base/common/uri'; import { Event, Emitter } from 'vs/base/common/event'; import { TPromise } from 'vs/base/common/winjs.base'; import { IWorkspaceFolder } from 'vs/platform/workspace/common/workspace'; -import { ILaunch, IDebugService, State, DebugEvent, ISession, IConfigurationManager, IStackFrame, IBreakpointData, IBreakpointUpdateData, IConfig, IModel, IViewModel, IRawSession, IBreakpoint, LoadedSourceEvent } from 'vs/workbench/parts/debug/common/debug'; +import { Position } from 'vs/editor/common/core/position'; +import { ILaunch, IDebugService, State, DebugEvent, ISession, IConfigurationManager, IStackFrame, IBreakpointData, IBreakpointUpdateData, IConfig, IModel, IViewModel, IRawSession, IBreakpoint, LoadedSourceEvent, SessionState, IThread, IRawModelUpdate } from 'vs/workbench/parts/debug/common/debug'; +import { Source } from 'vs/workbench/parts/debug/common/debugSource'; +import { ISuggestion } from 'vs/editor/common/modes'; export class MockDebugService implements IDebugService { public _serviceBrand: any; @@ -114,7 +117,49 @@ export class MockDebugService implements IDebugService { public sourceIsNotAvailable(uri: uri): void { } } -export class MockSession implements IRawSession { +export class MockSession implements ISession { + configuration: IConfig = { type: 'mock', request: 'launch' }; + raw: IRawSession = new MockRawSession(); + state = SessionState.LAUNCH; + + getName(includeRoot: boolean): string { + return 'mockname'; + } + + getSourceForUri(modelUri: uri): Source { + return null; + } + + getThread(threadId: number): IThread { + return null; + } + + getAllThreads(): ReadonlyArray { + return []; + } + + getSource(raw: DebugProtocol.Source): Source { + return undefined; + } + + getLoadedSources(): TPromise { + return TPromise.as([]); + } + + completions(frameId: number, text: string, position: Position, overwriteBefore: number): TPromise { + return TPromise.as([]); + } + + clearThreads(removeThreads: boolean, reference?: number): void { } + + rawUpdate(data: IRawModelUpdate): void { } + + getId(): string { + return 'mock'; + } +} + +export class MockRawSession implements IRawSession { public readyForBreakpoints = true; public emittedStopped = true; diff --git a/src/vs/workbench/parts/debug/test/node/debugModel.test.ts b/src/vs/workbench/parts/debug/test/electron-browser/debugModel.test.ts similarity index 94% rename from src/vs/workbench/parts/debug/test/node/debugModel.test.ts rename to src/vs/workbench/parts/debug/test/electron-browser/debugModel.test.ts index e480fb71cb6..3e448f864e7 100644 --- a/src/vs/workbench/parts/debug/test/node/debugModel.test.ts +++ b/src/vs/workbench/parts/debug/test/electron-browser/debugModel.test.ts @@ -6,18 +6,19 @@ import * as assert from 'assert'; import uri from 'vs/base/common/uri'; import severity from 'vs/base/common/severity'; -import { SimpleReplElement, Model, Session, Expression, RawObjectReplElement, StackFrame, Thread } from 'vs/workbench/parts/debug/common/debugModel'; +import { SimpleReplElement, Model, Expression, RawObjectReplElement, StackFrame, Thread } from 'vs/workbench/parts/debug/common/debugModel'; import * as sinon from 'sinon'; -import { MockSession } from 'vs/workbench/parts/debug/test/common/mockDebug'; +import { MockRawSession } from 'vs/workbench/parts/debug/test/common/mockDebug'; import { Source } from 'vs/workbench/parts/debug/common/debugSource'; +import { Session } from 'vs/workbench/parts/debug/electron-browser/debugSession'; suite('Debug - Model', () => { let model: Model; - let rawSession: MockSession; + let rawSession: MockRawSession; setup(() => { model = new Model([], true, [], [], []); - rawSession = new MockSession(); + rawSession = new MockRawSession(); }); teardown(() => { @@ -108,8 +109,8 @@ suite('Debug - Model', () => { test('threads simple', () => { const threadId = 1; const threadName = 'firstThread'; - - model.addSession({ resolved: { name: 'mockSession', type: 'node', request: 'launch' }, unresolved: undefined }, rawSession); + const session = new Session({ resolved: { name: 'mockSession', type: 'node', request: 'launch' }, unresolved: undefined }, rawSession); + model.addSession(session); assert.equal(model.getSessions().length, 1); model.rawUpdate({ sessionId: rawSession.getId(), @@ -119,7 +120,6 @@ suite('Debug - Model', () => { name: threadName } }); - const session = model.getSessions().filter(p => p.getId() === rawSession.getId()).pop(); assert.equal(session.getThread(threadId).name, threadName); @@ -140,7 +140,8 @@ suite('Debug - Model', () => { const stoppedReason = 'breakpoint'; // Add the threads - model.addSession({ resolved: { name: 'mockSession', type: 'node', request: 'launch' }, unresolved: undefined }, rawSession); + const session = new Session({ resolved: { name: 'mockSession', type: 'node', request: 'launch' }, unresolved: undefined }, rawSession); + model.addSession(session); model.rawUpdate({ sessionId: rawSession.getId(), threadId: threadId1, @@ -169,7 +170,6 @@ suite('Debug - Model', () => { allThreadsStopped: true }, }); - const session = model.getSessions().filter(p => p.getId() === rawSession.getId()).pop(); const thread1 = session.getThread(threadId1); const thread2 = session.getThread(threadId2); @@ -230,7 +230,8 @@ suite('Debug - Model', () => { const runningThreadId = 2; const runningThreadName = 'runningThread'; const stoppedReason = 'breakpoint'; - model.addSession({ resolved: { name: 'mockSession', type: 'node', request: 'launch' }, unresolved: undefined }, rawSession); + const session = new Session({ resolved: { name: 'mockSession', type: 'node', request: 'launch' }, unresolved: undefined }, rawSession); + model.addSession(session); // Add the threads model.rawUpdate({ sessionId: rawSession.getId(), @@ -260,7 +261,6 @@ suite('Debug - Model', () => { allThreadsStopped: false } }); - const session = model.getSessions().filter(p => p.getId() === rawSession.getId()).pop(); const stoppedThread = session.getThread(stoppedThreadId); const runningThread = session.getThread(runningThreadId); From 758be52acf26b54ec70fa31ee6c4eb4d89835670 Mon Sep 17 00:00:00 2001 From: isidor Date: Mon, 20 Aug 2018 11:58:07 +0200 Subject: [PATCH 0979/1276] Reify "DebugSession" fixes #48377 --- .../mainThreadDebugService.ts | 20 +- .../parts/debug/browser/debugActions.ts | 4 +- .../parts/debug/browser/debugEditorActions.ts | 2 +- .../parts/debug/browser/loadedScriptsView.ts | 20 +- src/vs/workbench/parts/debug/common/debug.ts | 47 +- .../debug/electron-browser/debugService.ts | 631 +++++------------- .../debug/electron-browser/debugSession.ts | 322 ++++++++- .../debug/electron-browser/rawDebugSession.ts | 24 +- .../parts/debug/test/common/mockDebug.ts | 60 +- .../test/electron-browser/debugModel.test.ts | 33 +- 10 files changed, 576 insertions(+), 587 deletions(-) diff --git a/src/vs/workbench/api/electron-browser/mainThreadDebugService.ts b/src/vs/workbench/api/electron-browser/mainThreadDebugService.ts index b98563c70b1..3769f8b0c6b 100644 --- a/src/vs/workbench/api/electron-browser/mainThreadDebugService.ts +++ b/src/vs/workbench/api/electron-browser/mainThreadDebugService.ts @@ -29,14 +29,22 @@ export class MainThreadDebugService implements MainThreadDebugServiceShape, IDeb private _debugAdapters: Map; private _debugAdaptersHandleCounter = 1; - constructor( extHostContext: IExtHostContext, @IDebugService private debugService: IDebugService ) { this._proxy = extHostContext.getProxy(ExtHostContext.ExtHostDebugService); this._toDispose = []; - this._toDispose.push(debugService.onDidNewSession(proc => this._proxy.$acceptDebugSessionStarted(proc.getId(), proc.configuration.type, proc.getName(false)))); + this._toDispose.push(debugService.onDidNewSession(session => { + this._proxy.$acceptDebugSessionStarted(session.getId(), session.configuration.type, session.getName(false)); + this._toDispose.push(session.onDidCustomEvent(event => { + if (event && event.sessionId) { + if (process) { + this._proxy.$acceptDebugSessionCustomEvent(event.sessionId, session.configuration.type, session.configuration.name, event); + } + } + })); + })); this._toDispose.push(debugService.onDidEndSession(proc => this._proxy.$acceptDebugSessionTerminated(proc.getId(), proc.configuration.type, proc.getName(false)))); this._toDispose.push(debugService.getViewModel().onDidFocusSession(proc => { if (proc) { @@ -46,14 +54,6 @@ export class MainThreadDebugService implements MainThreadDebugServiceShape, IDeb } })); - this._toDispose.push(debugService.onDidCustomEvent(event => { - if (event && event.sessionId) { - const process = this.debugService.getModel().getSessions().filter(p => p.getId() === event.sessionId).pop(); - if (process) { - this._proxy.$acceptDebugSessionCustomEvent(event.sessionId, process.configuration.type, process.configuration.name, event); - } - } - })); this._debugAdapters = new Map(); } diff --git a/src/vs/workbench/parts/debug/browser/debugActions.ts b/src/vs/workbench/parts/debug/browser/debugActions.ts index 6191db0921c..1d35bf5ea64 100644 --- a/src/vs/workbench/parts/debug/browser/debugActions.ts +++ b/src/vs/workbench/parts/debug/browser/debugActions.ts @@ -12,7 +12,7 @@ import { ICommandService } from 'vs/platform/commands/common/commands'; import * as aria from 'vs/base/browser/ui/aria/aria'; import { IWorkspaceContextService, WorkbenchState } from 'vs/platform/workspace/common/workspace'; import { IFileService } from 'vs/platform/files/common/files'; -import { IDebugService, State, ISession, IThread, IEnablement, IBreakpoint, IStackFrame, REPL_ID, SessionState } +import { IDebugService, State, ISession, IThread, IEnablement, IBreakpoint, IStackFrame, REPL_ID } from 'vs/workbench/parts/debug/common/debug'; import { Variable, Expression, Thread, Breakpoint } from 'vs/workbench/parts/debug/common/debugModel'; import { IPartService } from 'vs/workbench/services/part/common/partService'; @@ -226,7 +226,7 @@ export class RestartAction extends AbstractDebugAction { } private setLabel(session: ISession): void { - this.updateLabel(session && session.state === SessionState.ATTACH ? RestartAction.RECONNECT_LABEL : RestartAction.LABEL); + this.updateLabel(session && session.configuration.request === 'attach' ? RestartAction.RECONNECT_LABEL : RestartAction.LABEL); } public run(session: ISession): TPromise { diff --git a/src/vs/workbench/parts/debug/browser/debugEditorActions.ts b/src/vs/workbench/parts/debug/browser/debugEditorActions.ts index d6332e2f2ca..3d00826481d 100644 --- a/src/vs/workbench/parts/debug/browser/debugEditorActions.ts +++ b/src/vs/workbench/parts/debug/browser/debugEditorActions.ts @@ -118,7 +118,7 @@ class RunToCursorAction extends EditorAction { } let breakpointToRemove: IBreakpoint; - const oneTimeListener = debugService.getViewModel().focusedSession.raw.onDidEvent(event => { + const oneTimeListener = debugService.getViewModel().focusedSession.onDidCustomEvent(event => { if (event.event === 'stopped' || event.event === 'exit') { if (breakpointToRemove) { debugService.removeBreakpoints(breakpointToRemove.getId()); diff --git a/src/vs/workbench/parts/debug/browser/loadedScriptsView.ts b/src/vs/workbench/parts/debug/browser/loadedScriptsView.ts index 780b5ebb659..b8bd358a6cf 100644 --- a/src/vs/workbench/parts/debug/browser/loadedScriptsView.ts +++ b/src/vs/workbench/parts/debug/browser/loadedScriptsView.ts @@ -371,16 +371,18 @@ export class LoadedScriptsView extends TreeViewsViewletPanel { let timeout: number; - this.disposables.push(this.debugService.onDidLoadedSource(event => { - const sessionRoot = root.add(event.session); - sessionRoot.addPath(event.source); + this.disposables.push(this.debugService.onDidNewSession(session => { + this.disposables.push(session.onDidLoadedSource(event => { + const sessionRoot = root.add(session); + sessionRoot.addPath(event.source); - clearTimeout(timeout); - timeout = setTimeout(() => { - if (this.tree) { - this.tree.refresh(root, true); - } - }, 300); + clearTimeout(timeout); + timeout = setTimeout(() => { + if (this.tree) { + this.tree.refresh(root, true); + } + }, 300); + })); })); this.disposables.push(this.debugService.onDidEndSession(session => { diff --git a/src/vs/workbench/parts/debug/common/debug.ts b/src/vs/workbench/parts/debug/common/debug.ts index d527aef5481..d832d738ecb 100644 --- a/src/vs/workbench/parts/debug/common/debug.ts +++ b/src/vs/workbench/parts/debug/common/debug.ts @@ -109,7 +109,6 @@ export interface IExpression extends IReplElement, IExpressionContainer { } export interface IRawSession { - readonly root: IWorkspaceFolder; stackTrace(args: DebugProtocol.StackTraceArguments): TPromise; exceptionInfo(args: DebugProtocol.ExceptionInfoArguments): TPromise; scopes(args: DebugProtocol.ScopesArguments): TPromise; @@ -117,11 +116,9 @@ export interface IRawSession { evaluate(args: DebugProtocol.EvaluateArguments): TPromise; readonly capabilities: DebugProtocol.Capabilities; + disconnect(restart?: boolean): TPromise; terminate(restart?: boolean): TPromise; custom(request: string, args: any): TPromise; - onDidEvent: Event; - onDidInitialize: Event; - onDidExitAdapter: Event<{ sessionId: string }>; restartFrame(args: DebugProtocol.RestartFrameArguments, threadId: number): TPromise; next(args: DebugProtocol.NextArguments): TPromise; @@ -140,15 +137,11 @@ export interface IRawSession { } -export enum SessionState { - ATTACH, - LAUNCH -} - -export interface ISession extends ITreeElement { +export interface ISession extends ITreeElement, IDisposable { readonly configuration: IConfig; readonly raw: IRawSession; - readonly state: SessionState; + readonly state: State; + readonly root: IWorkspaceFolder; getName(includeRoot: boolean): string; getSourceForUri(modelUri: uri): Source; @@ -160,6 +153,18 @@ export interface ISession extends ITreeElement { clearThreads(removeThreads: boolean, reference?: number): void; rawUpdate(data: IRawModelUpdate): void; + + /** + * Allows to register on loaded source events. + */ + onDidLoadedSource: Event; + + /** + * Allows to register on custom DAP events. + */ + onDidCustomEvent: Event; + + onDidExitAdapter: Event; } export interface IThread extends ITreeElement { @@ -581,7 +586,6 @@ export interface DebugEvent extends DebugProtocol.Event { } export interface LoadedSourceEvent { - session: ISession; reason: string; source: Source; } @@ -609,16 +613,6 @@ export interface IDebugService { */ onDidEndSession: Event; - /** - * Allows to register on loaded source events. - */ - onDidLoadedSource: Event; - - /** - * Allows to register on custom DAP events. - */ - onDidCustomEvent: Event; - /** * Gets the current configuration manager. */ @@ -687,7 +681,7 @@ export interface IDebugService { /** * Appends the passed string to the debug repl. */ - logToRepl(value: string, sev?: severity): void; + logToRepl(value: string | IExpression, sev?: severity, source?: IReplElementSource): void; /** * Adds a new watch expression and evaluates it against the debug adapter. @@ -719,7 +713,7 @@ export interface IDebugService { /** * Restarts a session or creates a new one if there is no active session. */ - restartSession(session: ISession): TPromise; + restartSession(session: ISession, restartData?: any): TPromise; /** * Stops the session. If the session does not exist then stops all sessions. @@ -740,6 +734,11 @@ export interface IDebugService { * Gets the current view model. */ getViewModel(): IViewModel; + + /** + * Try to auto focus the top stack frame of the passed thread. + */ + tryToAutoFocusStackFrame(thread: IThread): TPromise; } // Editor interfaces diff --git a/src/vs/workbench/parts/debug/electron-browser/debugService.ts b/src/vs/workbench/parts/debug/electron-browser/debugService.ts index 73c6353846b..a360dabf1cc 100644 --- a/src/vs/workbench/parts/debug/electron-browser/debugService.ts +++ b/src/vs/workbench/parts/debug/electron-browser/debugService.ts @@ -4,13 +4,10 @@ *--------------------------------------------------------------------------------------------*/ import * as nls from 'vs/nls'; -import * as lifecycle from 'vs/base/common/lifecycle'; import { Event, Emitter } from 'vs/base/common/event'; import * as resources from 'vs/base/common/resources'; -import * as strings from 'vs/base/common/strings'; import { generateUuid } from 'vs/base/common/uuid'; import uri from 'vs/base/common/uri'; -import * as platform from 'vs/base/common/platform'; import { first, distinct } from 'vs/base/common/arrays'; import { isObject, isUndefinedOrNull } from 'vs/base/common/types'; import * as errors from 'vs/base/common/errors'; @@ -26,9 +23,8 @@ import { FileChangesEvent, FileChangeType, IFileService } from 'vs/platform/file import { IWindowService } from 'vs/platform/windows/common/windows'; import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry'; import { IStorageService, StorageScope } from 'vs/platform/storage/common/storage'; -import * as debug from 'vs/workbench/parts/debug/common/debug'; import { RawDebugSession } from 'vs/workbench/parts/debug/electron-browser/rawDebugSession'; -import { Model, ExceptionBreakpoint, FunctionBreakpoint, Breakpoint, Expression, RawObjectReplElement, ExpressionContainer, Thread } from 'vs/workbench/parts/debug/common/debugModel'; +import { Model, ExceptionBreakpoint, FunctionBreakpoint, Breakpoint, Expression, RawObjectReplElement } from 'vs/workbench/parts/debug/common/debugModel'; import { ViewModel } from 'vs/workbench/parts/debug/common/debugViewModel'; import * as debugactions from 'vs/workbench/parts/debug/browser/debugActions'; import { ConfigurationManager } from 'vs/workbench/parts/debug/electron-browser/debugConfigurationManager'; @@ -43,7 +39,7 @@ import { ITextFileService } from 'vs/workbench/services/textfile/common/textfile import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; import { IWorkspaceContextService, WorkbenchState, IWorkspaceFolder } from 'vs/platform/workspace/common/workspace'; import { IEditorService } from 'vs/workbench/services/editor/common/editorService'; -import { EXTENSION_LOG_BROADCAST_CHANNEL, EXTENSION_ATTACH_BROADCAST_CHANNEL, EXTENSION_TERMINATE_BROADCAST_CHANNEL, EXTENSION_CLOSE_EXTHOST_BROADCAST_CHANNEL, EXTENSION_RELOAD_BROADCAST_CHANNEL } from 'vs/platform/extensions/common/extensionHost'; +import { EXTENSION_LOG_BROADCAST_CHANNEL, EXTENSION_ATTACH_BROADCAST_CHANNEL, EXTENSION_TERMINATE_BROADCAST_CHANNEL, EXTENSION_RELOAD_BROADCAST_CHANNEL, EXTENSION_CLOSE_EXTHOST_BROADCAST_CHANNEL } from 'vs/platform/extensions/common/extensionHost'; import { IBroadcastService, IBroadcast } from 'vs/platform/broadcast/electron-browser/broadcastService'; import { IRemoteConsoleLog, parse, getFirstFrame } from 'vs/base/node/console'; import { Source } from 'vs/workbench/parts/debug/common/debugSource'; @@ -52,10 +48,11 @@ import { IDialogService } from 'vs/platform/dialogs/common/dialogs'; import { INotificationService } from 'vs/platform/notification/common/notification'; import { IAction, Action } from 'vs/base/common/actions'; import { normalizeDriveLetter } from 'vs/base/common/labels'; -import { RunOnceScheduler } from 'vs/base/common/async'; -import product from 'vs/platform/node/product'; import { deepClone, equals } from 'vs/base/common/objects'; import { Session } from 'vs/workbench/parts/debug/electron-browser/debugSession'; +import { equalsIgnoreCase } from 'vs/base/common/strings'; +import { dispose, IDisposable } from 'vs/base/common/lifecycle'; +import { IDebugService, State, ISession, CONTEXT_DEBUG_TYPE, CONTEXT_DEBUG_STATE, CONTEXT_IN_DEBUG_MODE, IThread, IDebugConfiguration, VIEWLET_ID, REPL_ID, IConfig, ILaunch, IViewModel, IConfigurationManager, IModel, IReplElementSource, IEnablement, IBreakpoint, IBreakpointData, IExpression, ICompound, IGlobalConfig, IStackFrame } from 'vs/workbench/parts/debug/common/debug'; const DEBUG_BREAKPOINTS_KEY = 'debug.breakpoint'; const DEBUG_BREAKPOINTS_ACTIVATED_KEY = 'debug.breakpointactivated'; @@ -63,29 +60,24 @@ const DEBUG_FUNCTION_BREAKPOINTS_KEY = 'debug.functionbreakpoint'; const DEBUG_EXCEPTION_BREAKPOINTS_KEY = 'debug.exceptionbreakpoint'; const DEBUG_WATCH_EXPRESSIONS_KEY = 'debug.watchexpressions'; -export class DebugService implements debug.IDebugService { - public _serviceBrand: any; +export class DebugService implements IDebugService { + _serviceBrand: any; - private sessionStates: Map; - private readonly _onDidChangeState: Emitter; - private readonly _onDidNewSession: Emitter; - private readonly _onDidEndSession: Emitter; - private readonly _onDidLoadedSource: Emitter; - private readonly _onDidCustomEvent: Emitter; + private readonly _onDidChangeState: Emitter; + private readonly _onDidNewSession: Emitter; + private readonly _onDidEndSession: Emitter; private model: Model; private viewModel: ViewModel; - private allSessions: Map; private configurationManager: ConfigurationManager; - private toDispose: lifecycle.IDisposable[]; - private toDisposeOnSessionEnd: Map; + private allSessions = new Map(); + private toDispose: IDisposable[]; private debugType: IContextKey; private debugState: IContextKey; private inDebugMode: IContextKey; private breakpointsToSendOnResourceSaved: Set; private firstSessionStart: boolean; private skipRunningTask: boolean; - private previousState: debug.State; - private fetchThreadsSchedulers: Map; + private previousState: State; constructor( @IStorageService private storageService: IStorageService, @@ -110,22 +102,16 @@ export class DebugService implements debug.IDebugService { @IConfigurationService private configurationService: IConfigurationService, ) { this.toDispose = []; - this.toDisposeOnSessionEnd = new Map(); this.breakpointsToSendOnResourceSaved = new Set(); - this._onDidChangeState = new Emitter(); - this._onDidNewSession = new Emitter(); - this._onDidEndSession = new Emitter(); - this._onDidLoadedSource = new Emitter(); - this._onDidCustomEvent = new Emitter(); - this.sessionStates = new Map(); - this.allSessions = new Map(); - this.fetchThreadsSchedulers = new Map(); + this._onDidChangeState = new Emitter(); + this._onDidNewSession = new Emitter(); + this._onDidEndSession = new Emitter(); this.configurationManager = this.instantiationService.createInstance(ConfigurationManager); this.toDispose.push(this.configurationManager); - this.debugType = debug.CONTEXT_DEBUG_TYPE.bindTo(contextKeyService); - this.debugState = debug.CONTEXT_DEBUG_STATE.bindTo(contextKeyService); - this.inDebugMode = debug.CONTEXT_IN_DEBUG_MODE.bindTo(contextKeyService); + this.debugType = CONTEXT_DEBUG_TYPE.bindTo(contextKeyService); + this.debugState = CONTEXT_DEBUG_STATE.bindTo(contextKeyService); + this.inDebugMode = CONTEXT_IN_DEBUG_MODE.bindTo(contextKeyService); this.model = new Model(this.loadBreakpoints(), this.storageService.getBoolean(DEBUG_BREAKPOINTS_ACTIVATED_KEY, StorageScope.WORKSPACE, true), this.loadFunctionBreakpoints(), this.loadExceptionBreakpoints(), this.loadWatchExpressions()); @@ -144,18 +130,17 @@ export class DebugService implements debug.IDebugService { this.toDispose.push(this.viewModel.onDidFocusSession(s => { const id = s ? s.getId() : undefined; this.model.setBreakpointsSessionId(id); + this.onStateChange(); })); } private onBroadcast(broadcast: IBroadcast): void { - // attach: PH is ready to be attached to const session = this.allSessions.get(broadcast.payload.debugId); if (!session) { // Ignore attach events for sessions that never existed (wrong vscode windows) return; } - const raw = session.raw; if (broadcast.channel === EXTENSION_ATTACH_BROADCAST_CHANNEL) { const initialAttach = session.configuration.request === 'launch'; @@ -164,22 +149,20 @@ export class DebugService implements debug.IDebugService { session.configuration.port = broadcast.payload.port; // Do not end process on initial attach (since the request is still 'launch') if (initialAttach) { - const root = raw.root; - lifecycle.dispose(this.toDisposeOnSessionEnd[raw.getId()]); - this.initializeRawSession(root, { resolved: session.configuration, unresolved: session.unresolvedConfiguration }, session.getId(), session).then(session => { - (session.raw).attach(session.configuration); - }); + const dbgr = this.configurationManager.getDebugger(session.configuration.type); + session.initialize(dbgr).then(() => (session.raw).attach(session.configuration)); } else { - const root = raw.root; - raw.disconnect().done(undefined, errors.onUnexpectedError); - this.doCreateSession(root, { resolved: session.configuration, unresolved: session.unresolvedConfiguration }, session.getId()); + if (session.raw) { + session.raw.disconnect().done(undefined, errors.onUnexpectedError); + } + this.doCreateSession(session.root, { resolved: session.configuration, unresolved: session.unresolvedConfiguration }, session.getId()); } return; } if (broadcast.channel === EXTENSION_TERMINATE_BROADCAST_CHANNEL) { - raw.terminate().done(undefined, errors.onUnexpectedError); + session.raw.terminate().done(undefined, errors.onUnexpectedError); return; } @@ -189,7 +172,7 @@ export class DebugService implements debug.IDebugService { let sev = extensionOutput.severity === 'warn' ? severity.Warning : extensionOutput.severity === 'error' ? severity.Error : severity.Info; const { args, stack } = parse(extensionOutput); - let source: debug.IReplElementSource; + let source: IReplElementSource; if (stack) { const frame = getFirstFrame(stack); if (frame) { @@ -264,7 +247,7 @@ export class DebugService implements debug.IDebugService { } } - private tryToAutoFocusStackFrame(thread: debug.IThread): TPromise { + tryToAutoFocusStackFrame(thread: IThread): TPromise { const callStack = thread.getCallStack(); if (!callStack.length || (this.viewModel.focusedStackFrame && this.viewModel.focusedStackFrame.thread.getId() === thread.getId())) { return TPromise.as(null); @@ -278,8 +261,8 @@ export class DebugService implements debug.IDebugService { this.focusStackFrame(stackFrameToFocus); if (thread.stoppedDetails) { - if (this.configurationService.getValue('debug').openDebug === 'openOnDebugBreak') { - this.viewletService.openViewlet(debug.VIEWLET_ID).done(undefined, errors.onUnexpectedError); + if (this.configurationService.getValue('debug').openDebug === 'openOnDebugBreak') { + this.viewletService.openViewlet(VIEWLET_ID).done(undefined, errors.onUnexpectedError); } this.windowService.focusWindow(); aria.alert(nls.localize('debuggingPaused', "Debugging paused, reason {0}, {1} {2}", thread.stoppedDetails.reason, stackFrameToFocus.source ? stackFrameToFocus.source.name : '', stackFrameToFocus.range.startLineNumber)); @@ -288,199 +271,6 @@ export class DebugService implements debug.IDebugService { return stackFrameToFocus.openInEditor(this.editorService, true); } - private registerSessionListeners(session: debug.ISession, raw: RawDebugSession): void { - this.toDisposeOnSessionEnd.get(raw.getId()).push(raw.onDidInitialize(event => { - aria.status(nls.localize('debuggingStarted', "Debugging started.")); - const sendConfigurationDone = () => { - if (raw && raw.capabilities.supportsConfigurationDoneRequest) { - return raw.configurationDone().done(null, e => { - // Disconnect the debug session on configuration done error #10596 - if (raw) { - raw.disconnect().done(undefined, errors.onUnexpectedError); - } - this.notificationService.error(e.message); - }); - } - }; - - this.sendAllBreakpoints(session).then(sendConfigurationDone, sendConfigurationDone) - .done(() => this.fetchThreads(raw), errors.onUnexpectedError); - })); - - this.toDisposeOnSessionEnd.get(session.getId()).push(raw.onDidStop(event => { - this.updateStateAndEmit(session.getId(), debug.State.Stopped); - this.fetchThreads(raw, event.body).done(() => { - const thread = session && session.getThread(event.body.threadId); - if (thread) { - // Call fetch call stack twice, the first only return the top stack frame. - // Second retrieves the rest of the call stack. For performance reasons #25605 - this.model.fetchCallStack(thread).then(() => { - return !event.body.preserveFocusHint ? this.tryToAutoFocusStackFrame(thread) : undefined; - }); - } - }, errors.onUnexpectedError); - })); - - this.toDisposeOnSessionEnd.get(session.getId()).push(raw.onDidThread(event => { - if (event.body.reason === 'started') { - // debounce to reduce threadsRequest frequency and improve performance - let scheduler = this.fetchThreadsSchedulers.get(session.getId()); - if (!scheduler) { - scheduler = new RunOnceScheduler(() => { - this.fetchThreads(raw).done(undefined, errors.onUnexpectedError); - }, 100); - this.fetchThreadsSchedulers.set(session.getId(), scheduler); - this.toDisposeOnSessionEnd.get(session.getId()).push(scheduler); - } - if (!scheduler.isScheduled()) { - scheduler.schedule(); - } - } else if (event.body.reason === 'exited') { - this.model.clearThreads(session.getId(), true, event.body.threadId); - } - })); - - this.toDisposeOnSessionEnd.get(session.getId()).push(raw.onDidTerminateDebugee(event => { - aria.status(nls.localize('debuggingStopped', "Debugging stopped.")); - if (session && session.getId() === event.sessionId) { - if (event.body && event.body.restart && session) { - this.restartSession(session, event.body.restart).done(null, err => this.notificationService.error(err.message)); - } else { - raw.disconnect().done(undefined, errors.onUnexpectedError); - } - } - })); - - this.toDisposeOnSessionEnd.get(session.getId()).push(raw.onDidContinued(event => { - const threadId = event.body.allThreadsContinued !== false ? undefined : event.body.threadId; - this.model.clearThreads(session.getId(), false, threadId); - if (this.viewModel.focusedSession.getId() === session.getId()) { - this.focusStackFrame(undefined, this.viewModel.focusedThread, this.viewModel.focusedSession); - } - this.updateStateAndEmit(session.getId(), debug.State.Running); - })); - - let outputPromises: TPromise[] = []; - this.toDisposeOnSessionEnd.get(session.getId()).push(raw.onDidOutput(event => { - if (!event.body) { - return; - } - - const outputSeverity = event.body.category === 'stderr' ? severity.Error : event.body.category === 'console' ? severity.Warning : severity.Info; - if (event.body.category === 'telemetry') { - // only log telemetry events from debug adapter if the debug extension provided the telemetry key - // and the user opted in telemetry - if (raw.customTelemetryService && this.telemetryService.isOptedIn) { - // __GDPR__TODO__ We're sending events in the name of the debug extension and we can not ensure that those are declared correctly. - raw.customTelemetryService.publicLog(event.body.output, event.body.data); - } - - return; - } - - // Make sure to append output in the correct order by properly waiting on preivous promises #33822 - const waitFor = outputPromises.slice(); - const source = event.body.source ? { - lineNumber: event.body.line, - column: event.body.column ? event.body.column : 1, - source: session.getSource(event.body.source) - } : undefined; - if (event.body.variablesReference) { - const container = new ExpressionContainer(session, event.body.variablesReference, generateUuid()); - outputPromises.push(container.getChildren().then(children => { - return TPromise.join(waitFor).then(() => children.forEach(child => { - // Since we can not display multiple trees in a row, we are displaying these variables one after the other (ignoring their names) - child.name = null; - this.logToRepl(child, outputSeverity, source); - })); - })); - } else if (typeof event.body.output === 'string') { - TPromise.join(waitFor).then(() => this.logToRepl(event.body.output, outputSeverity, source)); - } - TPromise.join(outputPromises).then(() => outputPromises = []); - })); - - this.toDisposeOnSessionEnd.get(session.getId()).push(raw.onDidBreakpoint(event => { - const id = event.body && event.body.breakpoint ? event.body.breakpoint.id : undefined; - const breakpoint = this.model.getBreakpoints().filter(bp => bp.idFromAdapter === id).pop(); - const functionBreakpoint = this.model.getFunctionBreakpoints().filter(bp => bp.idFromAdapter === id).pop(); - - if (event.body.reason === 'new' && event.body.breakpoint.source) { - const source = session.getSource(event.body.breakpoint.source); - const bps = this.model.addBreakpoints(source.uri, [{ - column: event.body.breakpoint.column, - enabled: true, - lineNumber: event.body.breakpoint.line, - }], false); - if (bps.length === 1) { - this.model.updateBreakpoints({ [bps[0].getId()]: event.body.breakpoint }); - } - } - - if (event.body.reason === 'removed') { - if (breakpoint) { - this.model.removeBreakpoints([breakpoint]); - } - if (functionBreakpoint) { - this.model.removeFunctionBreakpoints(functionBreakpoint.getId()); - } - } - - if (event.body.reason === 'changed') { - if (breakpoint) { - if (!breakpoint.column) { - event.body.breakpoint.column = undefined; - } - this.model.setBreakpointSessionData(session.getId(), { [breakpoint.getId()]: event.body.breakpoint }); - } - if (functionBreakpoint) { - this.model.setBreakpointSessionData(session.getId(), { [functionBreakpoint.getId()]: event.body.breakpoint }); - } - } - })); - - this.toDisposeOnSessionEnd.get(session.getId()).push(raw.onDidExitAdapter(event => { - // 'Run without debugging' mode VSCode must terminate the extension host. More details: #3905 - if (strings.equalsIgnoreCase(session.configuration.type, 'extensionhost') && this.sessionStates.get(session.getId()) === debug.State.Running && - session && session.raw.root && session.configuration.noDebug) { - this.broadcastService.broadcast({ - channel: EXTENSION_CLOSE_EXTHOST_BROADCAST_CHANNEL, - payload: [session.raw.root.uri.fsPath] - }); - } - if (session && session.getId() === event.sessionId) { - this.onExitAdapter(raw); - } - })); - - this.toDisposeOnSessionEnd.get(session.getId()).push(raw.onDidLoadedSource(event => { - this._onDidLoadedSource.fire({ - session: session, - reason: event.body.reason, - source: session.getSource(event.body.source) - }); - })); - - this.toDisposeOnSessionEnd.get(session.getId()).push(raw.onDidCustomEvent(event => { - this._onDidCustomEvent.fire(event); - })); - } - - private fetchThreads(session: RawDebugSession, stoppedDetails?: debug.IRawStoppedDetails): TPromise { - return session.threads().then(response => { - if (response && response.body && response.body.threads) { - response.body.threads.forEach(thread => { - this.model.rawUpdate({ - sessionId: session.getId(), - threadId: thread.id, - thread, - stoppedDetails: stoppedDetails && thread.id === stoppedDetails.threadId ? stoppedDetails : undefined - }); - }); - } - }); - } - private loadBreakpoints(): Breakpoint[] { let result: Breakpoint[]; try { @@ -525,64 +315,28 @@ export class DebugService implements debug.IDebugService { return result || []; } - public get state(): debug.State { - const focusedThread = this.viewModel.focusedThread; - if (focusedThread && focusedThread.stopped) { - return debug.State.Stopped; - } + get state(): State { const focusedSession = this.viewModel.focusedSession; - if (focusedSession && this.sessionStates.has(focusedSession.getId())) { - return this.sessionStates.get(focusedSession.getId()); - } - if (this.sessionStates.size > 0) { - return debug.State.Initializing; + if (focusedSession) { + return focusedSession.state; } - return debug.State.Inactive; + return State.Inactive; } - public get onDidChangeState(): Event { + get onDidChangeState(): Event { return this._onDidChangeState.event; } - public get onDidNewSession(): Event { + get onDidNewSession(): Event { return this._onDidNewSession.event; } - public get onDidEndSession(): Event { + get onDidEndSession(): Event { return this._onDidEndSession.event; } - public get onDidLoadedSource(): Event { - return this._onDidLoadedSource.event; - } - - public get onDidCustomEvent(): Event { - return this._onDidCustomEvent.event; - } - - private updateStateAndEmit(sessionId?: string, newState?: debug.State): void { - if (sessionId) { - if (newState === debug.State.Inactive) { - this.sessionStates.delete(sessionId); - } else { - this.sessionStates.set(sessionId, newState); - } - } - - const state = this.state; - if (this.previousState !== state) { - const stateLabel = debug.State[state]; - if (stateLabel) { - this.debugState.set(stateLabel.toLowerCase()); - this.inDebugMode.set(state !== debug.State.Inactive); - } - this.previousState = state; - this._onDidChangeState.fire(state); - } - } - - public focusStackFrame(stackFrame: debug.IStackFrame, thread?: debug.IThread, session?: debug.ISession, explicit?: boolean): void { + focusStackFrame(stackFrame: IStackFrame, thread?: IThread, session?: ISession, explicit?: boolean): void { if (!session) { if (stackFrame || thread) { session = stackFrame ? stackFrame.thread.session : thread.session; @@ -609,10 +363,9 @@ export class DebugService implements debug.IDebugService { } this.viewModel.setFocus(stackFrame, thread, session, explicit); - this.updateStateAndEmit(); } - public enableOrDisableBreakpoints(enable: boolean, breakpoint?: debug.IEnablement): TPromise { + enableOrDisableBreakpoints(enable: boolean, breakpoint?: IEnablement): TPromise { if (breakpoint) { this.model.setEnablement(breakpoint, enable); if (breakpoint instanceof Breakpoint) { @@ -628,14 +381,14 @@ export class DebugService implements debug.IDebugService { return this.sendAllBreakpoints(); } - public addBreakpoints(uri: uri, rawBreakpoints: debug.IBreakpointData[]): TPromise { + addBreakpoints(uri: uri, rawBreakpoints: IBreakpointData[]): TPromise { const breakpoints = this.model.addBreakpoints(uri, rawBreakpoints); breakpoints.forEach(bp => aria.status(nls.localize('breakpointAdded', "Added breakpoint, line {0}, file {1}", bp.lineNumber, uri.fsPath))); return this.sendBreakpoints(uri).then(() => breakpoints); } - public updateBreakpoints(uri: uri, data: { [id: string]: DebugProtocol.Breakpoint }, sendOnResourceSaved: boolean): void { + updateBreakpoints(uri: uri, data: { [id: string]: DebugProtocol.Breakpoint }, sendOnResourceSaved: boolean): void { this.model.updateBreakpoints(data); if (sendOnResourceSaved) { this.breakpointsToSendOnResourceSaved.add(uri.toString()); @@ -644,7 +397,7 @@ export class DebugService implements debug.IDebugService { } } - public removeBreakpoints(id?: string): TPromise { + removeBreakpoints(id?: string): TPromise { const toRemove = this.model.getBreakpoints().filter(bp => !id || bp.getId() === id); toRemove.forEach(bp => aria.status(nls.localize('breakpointRemoved', "Removed breakpoint, line {0}, file {1}", bp.lineNumber, bp.uri.fsPath))); const urisToClear = distinct(toRemove, bp => bp.uri.toString()).map(bp => bp.uri); @@ -654,37 +407,37 @@ export class DebugService implements debug.IDebugService { return TPromise.join(urisToClear.map(uri => this.sendBreakpoints(uri))); } - public setBreakpointsActivated(activated: boolean): TPromise { + setBreakpointsActivated(activated: boolean): TPromise { this.model.setBreakpointsActivated(activated); return this.sendAllBreakpoints(); } - public addFunctionBreakpoint(name?: string, id?: string): void { + addFunctionBreakpoint(name?: string, id?: string): void { const newFunctionBreakpoint = this.model.addFunctionBreakpoint(name || '', id); this.viewModel.setSelectedFunctionBreakpoint(newFunctionBreakpoint); } - public renameFunctionBreakpoint(id: string, newFunctionName: string): TPromise { + renameFunctionBreakpoint(id: string, newFunctionName: string): TPromise { this.model.renameFunctionBreakpoint(id, newFunctionName); return this.sendFunctionBreakpoints(); } - public removeFunctionBreakpoints(id?: string): TPromise { + removeFunctionBreakpoints(id?: string): TPromise { this.model.removeFunctionBreakpoints(id); return this.sendFunctionBreakpoints(); } - public addReplExpression(name: string): TPromise { + addReplExpression(name: string): TPromise { return this.model.addReplExpression(this.viewModel.focusedSession, this.viewModel.focusedStackFrame, name) // Evaluate all watch expressions and fetch variables again since repl evaluation might have changed some. .then(() => this.focusStackFrame(this.viewModel.focusedStackFrame, this.viewModel.focusedThread, this.viewModel.focusedSession)); } - public removeReplExpressions(): void { + removeReplExpressions(): void { this.model.removeReplExpressions(); } - public logToRepl(value: string | debug.IExpression, sev = severity.Info, source?: debug.IReplElementSource): void { + logToRepl(value: string | IExpression, sev = severity.Info, source?: IReplElementSource): void { const clearAnsiSequence = '\u001b[2J'; if (typeof value === 'string' && value.indexOf(clearAnsiSequence) >= 0) { // [2J is the ansi escape sequence for clearing the display http://ascii-table.com/ansi-escape-sequences.php @@ -696,31 +449,25 @@ export class DebugService implements debug.IDebugService { this.model.appendToRepl(value, sev, source); } - public addWatchExpression(name: string): void { + addWatchExpression(name: string): void { const we = this.model.addWatchExpression(name); this.viewModel.setSelectedExpression(we); } - public renameWatchExpression(id: string, newName: string): void { + renameWatchExpression(id: string, newName: string): void { return this.model.renameWatchExpression(id, newName); } - public moveWatchExpression(id: string, position: number): void { + moveWatchExpression(id: string, position: number): void { this.model.moveWatchExpression(id, position); } - public removeWatchExpressions(id?: string): void { + removeWatchExpressions(id?: string): void { this.model.removeWatchExpressions(id); } - public startDebugging(launch: debug.ILaunch, configOrName?: debug.IConfig | string, noDebug = false, unresolvedConfiguration?: debug.IConfig, ): TPromise { + startDebugging(launch: ILaunch, configOrName?: IConfig | string, noDebug = false, unresolvedConfiguration?: IConfig, ): TPromise { const sessionId = generateUuid(); - this.updateStateAndEmit(sessionId, debug.State.Initializing); - const wrapUpState = () => { - if (this.sessionStates.get(sessionId) === debug.State.Initializing) { - this.updateStateAndEmit(sessionId, debug.State.Inactive); - } - }; // make sure to save all files and that the configuration is up to date return this.extensionService.activateByEvent('onDebug').then(() => this.textFileService.saveAll().then(() => this.configurationService.reloadConfiguration(launch ? launch.workspace : undefined).then(() => @@ -730,7 +477,7 @@ export class DebugService implements debug.IDebugService { this.allSessions.clear(); } - let config: debug.IConfig, compound: debug.ICompound; + let config: IConfig, compound: ICompound; if (!configOrName) { configOrName = this.configurationManager.selectedConfiguration.name; } @@ -740,7 +487,7 @@ export class DebugService implements debug.IDebugService { const sessions = this.model.getSessions(); const alreadyRunningMessage = nls.localize('configurationAlreadyRunning', "There is already a debug configuration \"{0}\" running.", configOrName); - if (sessions.some(p => p.getName(false) === configOrName && (!launch || !launch.workspace || !p.raw.root || p.raw.root.uri.toString() === launch.workspace.uri.toString()))) { + if (sessions.some(s => s.getName(false) === configOrName && (!launch || !launch.workspace || !s.root || s.root.uri.toString() === launch.workspace.uri.toString()))) { return TPromise.wrapError(new Error(alreadyRunningMessage)); } if (compound && compound.configurations && sessions.some(p => compound.configurations.indexOf(p.getName(false)) !== -1)) { @@ -762,7 +509,7 @@ export class DebugService implements debug.IDebugService { return TPromise.as(null); } - let launchForName: debug.ILaunch; + let launchForName: ILaunch; if (typeof configData === 'string') { const launchesContainingName = this.configurationManager.getLaunches().filter(l => !!l.getConfiguration(name)); if (launchesContainingName.length === 1) { @@ -799,7 +546,7 @@ export class DebugService implements debug.IDebugService { type = config.type; } else { // a no-folder workspace has no launch.config - config = {}; + config = {}; } unresolvedConfiguration = unresolvedConfiguration || deepClone(config); @@ -820,13 +567,10 @@ export class DebugService implements debug.IDebugService { }) ).then(() => undefined); }) - ))).then(() => wrapUpState(), err => { - wrapUpState(); - return TPromise.wrapError(err); - }); + ))); } - private substituteVariables(launch: debug.ILaunch | undefined, config: debug.IConfig): TPromise { + private substituteVariables(launch: ILaunch | undefined, config: IConfig): TPromise { const dbg = this.configurationManager.getDebugger(config.type); if (dbg) { let folder: IWorkspaceFolder = undefined; @@ -848,7 +592,7 @@ export class DebugService implements debug.IDebugService { return TPromise.as(config); } - private createSession(launch: debug.ILaunch, config: debug.IConfig, unresolvedConfig: debug.IConfig, sessionId: string): TPromise { + private createSession(launch: ILaunch, config: IConfig, unresolvedConfig: IConfig, sessionId: string): TPromise { return this.textFileService.saveAll().then(() => this.substituteVariables(launch, config).then(resolvedConfig => { @@ -871,8 +615,6 @@ export class DebugService implements debug.IDebugService { return this.showError(message); } - this.toDisposeOnSessionEnd.set(sessionId, []); - const workspace = launch ? launch.workspace : undefined; return this.runTask(sessionId, workspace, resolvedConfig.preLaunchTask, resolvedConfig, unresolvedConfig, () => this.doCreateSession(workspace, { resolved: resolvedConfig, unresolved: unresolvedConfig }, sessionId) @@ -890,45 +632,16 @@ export class DebugService implements debug.IDebugService { ); } - private initializeRawSession(root: IWorkspaceFolder, configuration: { resolved: debug.IConfig, unresolved: debug.IConfig }, sessionId: string, session?: Session): TPromise { - const dbg = this.configurationManager.getDebugger(configuration.resolved.type); - return dbg.getCustomTelemetryService().then(customTelemetryService => { - - const raw = this.instantiationService.createInstance(RawDebugSession, sessionId, configuration.resolved.debugServer, dbg, customTelemetryService, root); - if (!session) { - session = new Session(configuration, raw); - this.model.addSession(session); - this.allSessions.set(session.getId(), session); - } else { - session.raw = raw; - } - this.registerSessionListeners(session, raw); - - return raw.initialize({ - clientID: 'vscode', - clientName: product.nameLong, - adapterID: configuration.resolved.type, - pathFormat: 'path', - linesStartAt1: true, - columnsStartAt1: true, - supportsVariableType: true, // #8858 - supportsVariablePaging: true, // #9537 - supportsRunInTerminalRequest: true, // #10574 - locale: platform.locale - }).then((result: DebugProtocol.InitializeResponse) => { - this.model.setExceptionBreakpoints(raw.capabilities.exceptionBreakpointFilters); - return session; - }); - }); - } - - private doCreateSession(root: IWorkspaceFolder, configuration: { resolved: debug.IConfig, unresolved: debug.IConfig }, sessionId: string): TPromise { + private doCreateSession(root: IWorkspaceFolder, configuration: { resolved: IConfig, unresolved: IConfig }, sessionId: string): TPromise { const resolved = configuration.resolved; resolved.__sessionId = sessionId; - const dbg = this.configurationManager.getDebugger(resolved.type); - return this.initializeRawSession(root, configuration, sessionId).then(session => { + const dbgr = this.configurationManager.getDebugger(resolved.type); + const session = this.instantiationService.createInstance(Session, sessionId, configuration, root, this.model); + this.allSessions.set(sessionId, session); + return session.initialize(dbgr).then(() => { + this.registerSessionListeners(session); const raw = session.raw; return (resolved.request === 'attach' ? raw.attach(resolved) : raw.launch(resolved)) .then((result: DebugProtocol.Response) => { @@ -938,15 +651,15 @@ export class DebugService implements debug.IDebugService { this.focusStackFrame(undefined, undefined, session); this._onDidNewSession.fire(session); - const internalConsoleOptions = resolved.internalConsoleOptions || this.configurationService.getValue('debug').internalConsoleOptions; + const internalConsoleOptions = resolved.internalConsoleOptions || this.configurationService.getValue('debug').internalConsoleOptions; if (internalConsoleOptions === 'openOnSessionStart' || (this.firstSessionStart && internalConsoleOptions === 'openOnFirstSessionStart')) { - this.panelService.openPanel(debug.REPL_ID, false).done(undefined, errors.onUnexpectedError); + this.panelService.openPanel(REPL_ID, false).done(undefined, errors.onUnexpectedError); } - const openDebug = this.configurationService.getValue('debug').openDebug; + const openDebug = this.configurationService.getValue('debug').openDebug; // Open debug viewlet based on the visibility of the side bar and openDebug setting if (openDebug === 'openOnSessionStart' || (openDebug === 'openOnFirstSessionStart' && this.firstSessionStart)) { - this.viewletService.openViewlet(debug.VIEWLET_ID); + this.viewletService.openViewlet(VIEWLET_ID); } this.firstSessionStart = false; @@ -954,7 +667,6 @@ export class DebugService implements debug.IDebugService { if (this.model.getSessions().length > 1) { this.viewModel.setMultiSessionView(true); } - this.updateStateAndEmit(raw.getId(), debug.State.Running); /* __GDPR__ "debugSessionStart" : { @@ -972,9 +684,9 @@ export class DebugService implements debug.IDebugService { breakpointCount: this.model.getBreakpoints().length, exceptionBreakpoints: this.model.getExceptionBreakpoints(), watchExpressionsCount: this.model.getWatchExpressions().length, - extensionName: dbg.extensionDescription.id, - isBuiltin: dbg.extensionDescription.isBuiltin, - launchJsonExists: root && !!this.configurationService.getValue('launch', { resource: root.uri }) + extensionName: dbgr.extensionDescription.id, + isBuiltin: dbgr.extensionDescription.isBuiltin, + launchJsonExists: root && !!this.configurationService.getValue('launch', { resource: root.uri }) }); }).then(() => session, (error: Error | string) => { if (errors.isPromiseCanceledError(error)) { @@ -990,16 +702,15 @@ export class DebugService implements debug.IDebugService { } */ this.telemetryService.publicLog('debugMisconfiguration', { type: resolved ? resolved.type : undefined, error: errorMessage }); - this.updateStateAndEmit(raw.getId(), debug.State.Inactive); if (!raw.disconnected) { raw.disconnect(); } else if (session) { - this.model.removeSession(session.getId()); + dispose(session); } // Show the repl if some error got logged there #5870 if (this.model.getReplElements().length > 0) { - this.panelService.openPanel(debug.REPL_ID, false).done(undefined, errors.onUnexpectedError); + this.panelService.openPanel(REPL_ID, false).done(undefined, errors.onUnexpectedError); } this.showError(errorMessage, errors.isErrorWithActions(error) ? error.actions : []); @@ -1008,6 +719,83 @@ export class DebugService implements debug.IDebugService { }); } + private onStateChange(): void { + const state = this.state; + if (this.previousState !== state) { + const stateLabel = State[state]; + if (stateLabel) { + this.debugState.set(stateLabel.toLowerCase()); + this.inDebugMode.set(state !== State.Inactive); + } + this.previousState = state; + this._onDidChangeState.fire(state); + } + } + + private registerSessionListeners(session: Session): void { + const toDispose: IDisposable[] = []; + + toDispose.push(session.onDidChangeState((state) => { + if (state === State.Running && this.viewModel.focusedSession.getId() === session.getId()) { + this.focusStackFrame(undefined); + } + this.onStateChange(); + })); + + toDispose.push(session.onDidExitAdapter(() => { + // 'Run without debugging' mode VSCode must terminate the extension host. More details: #3905 + if (equalsIgnoreCase(session.configuration.type, 'extensionhost') && session.state === State.Running && session.configuration.noDebug) { + this.broadcastService.broadcast({ + channel: EXTENSION_CLOSE_EXTHOST_BROADCAST_CHANNEL, + payload: [session.root.uri.fsPath] + }); + } + + + const breakpoints = this.model.getBreakpoints(); + /* __GDPR__ + "debugSessionStop" : { + "type" : { "classification": "SystemMetaData", "purpose": "FeatureInsight" }, + "success": { "classification": "SystemMetaData", "purpose": "FeatureInsight", "isMeasurement": true }, + "sessionLengthInSeconds": { "classification": "SystemMetaData", "purpose": "FeatureInsight", "isMeasurement": true }, + "breakpointCount": { "classification": "SystemMetaData", "purpose": "FeatureInsight", "isMeasurement": true }, + "watchExpressionsCount": { "classification": "SystemMetaData", "purpose": "FeatureInsight", "isMeasurement": true } + } + */ + this.telemetryService.publicLog('debugSessionStop', { + type: session && session.configuration.type, + success: (session.raw).emittedStopped || breakpoints.length === 0, + sessionLengthInSeconds: (session.raw).getLengthInSeconds(), + breakpointCount: breakpoints.length, + watchExpressionsCount: this.model.getWatchExpressions().length + }); + + if (session.configuration.postDebugTask) { + this.doRunTask(session.getId(), session.root, session.configuration.postDebugTask).done(undefined, err => + this.notificationService.error(err) + ); + } + toDispose.push(session); + dispose(toDispose); + this._onDidEndSession.fire(session); + + const focusedSession = this.viewModel.focusedSession; + if (focusedSession && focusedSession.getId() === session.getId()) { + this.focusStackFrame(null); + } + + if (this.model.getSessions().length === 0) { + this.debugType.reset(); + this.viewModel.setMultiSessionView(false); + + if (this.partService.isVisible(Parts.SIDEBAR_PART) && this.configurationService.getValue('debug').openExplorerOnEnd) { + this.viewletService.openViewlet(EXPLORER_VIEWLET_ID).done(null, errors.onUnexpectedError); + } + } + + })); + } + private showError(message: string, actions: IAction[] = []): TPromise { const configureAction = this.instantiationService.createInstance(debugactions.ConfigureAction, debugactions.ConfigureAction.ID, debugactions.ConfigureAction.LABEL); actions.push(configureAction); @@ -1020,7 +808,7 @@ export class DebugService implements debug.IDebugService { }); } - private runTask(sessionId: string, root: IWorkspaceFolder, taskId: string | TaskIdentifier, config: debug.IConfig, unresolvedConfig: debug.IConfig, onSuccess: () => TPromise): TPromise { + private runTask(sessionId: string, root: IWorkspaceFolder, taskId: string | TaskIdentifier, config: IConfig, unresolvedConfig: IConfig, onSuccess: () => TPromise): TPromise { const debugAnywayAction = new Action('debug.debugAnyway', nls.localize('debugAnyway', "Debug Anyway"), undefined, true, () => { return this.doCreateSession(root, { resolved: config, unresolved: unresolvedConfig }, sessionId); }); @@ -1079,16 +867,12 @@ export class DebugService implements debug.IDebugService { // task is already running - nothing to do. return TPromise.as(null); } - this.toDisposeOnSessionEnd.get(sessionId).push( - once(TaskEventKind.Active, this.taskService.onDidStateChange)(() => { - taskStarted = true; - }) - ); + once(TaskEventKind.Active, this.taskService.onDidStateChange)((taskEvent) => { + taskStarted = true; + }); const taskPromise = this.taskService.run(task); if (task.isBackground) { - return new TPromise((c, e) => this.toDisposeOnSessionEnd.get(sessionId).push( - once(TaskEventKind.Inactive, this.taskService.onDidStateChange)(() => c(null))) - ); + return new TPromise((c, e) => once(TaskEventKind.Inactive, this.taskService.onDidStateChange)(() => c(null))); } return taskPromise; @@ -1112,16 +896,16 @@ export class DebugService implements debug.IDebugService { }); } - public sourceIsNotAvailable(uri: uri): void { + sourceIsNotAvailable(uri: uri): void { this.model.sourceIsNotAvailable(uri); } - public restartSession(session: debug.ISession, restartData?: any): TPromise { + restartSession(session: ISession, restartData?: any): TPromise { return this.textFileService.saveAll().then(() => { const unresolvedConfiguration = (session).unresolvedConfiguration; if (session.raw.capabilities.supportsRestartRequest) { - return this.runTask(session.getId(), session.raw.root, session.configuration.postDebugTask, session.configuration, unresolvedConfiguration, - () => this.runTask(session.getId(), session.raw.root, session.configuration.preLaunchTask, session.configuration, unresolvedConfiguration, + return this.runTask(session.getId(), session.root, session.configuration.postDebugTask, session.configuration, unresolvedConfiguration, + () => this.runTask(session.getId(), session.root, session.configuration.preLaunchTask, session.configuration, unresolvedConfiguration, () => session.raw.custom('restart', null))); } @@ -1131,11 +915,11 @@ export class DebugService implements debug.IDebugService { this.skipRunningTask = !!restartData; // If the restart is automatic disconnect, otherwise send the terminate signal #55064 - return (!!restartData ? (session.raw).disconnect(true) : session.raw.terminate(true)).then(() => { - if (strings.equalsIgnoreCase(session.configuration.type, 'extensionHost') && session.raw.root) { + return (!!restartData ? session.raw.disconnect(true) : session.raw.terminate(true)).then(() => { + if (equalsIgnoreCase(session.configuration.type, 'extensionHost') && session.root) { return this.broadcastService.broadcast({ channel: EXTENSION_RELOAD_BROADCAST_CHANNEL, - payload: [session.raw.root.uri.fsPath] + payload: [session.root.uri.fsPath] }); } @@ -1144,7 +928,7 @@ export class DebugService implements debug.IDebugService { // Read the configuration again if a launch.json has been changed, if not just use the inmemory configuration let configToUse = session.configuration; - const launch = session.raw.root ? this.configurationManager.getLaunch(session.raw.root.uri) : undefined; + const launch = session.root ? this.configurationManager.getLaunch(session.root.uri) : undefined; if (launch) { const config = launch.getConfiguration(session.configuration.name); if (config && !equals(config, unresolvedConfiguration)) { @@ -1171,7 +955,7 @@ export class DebugService implements debug.IDebugService { }); } - public stopSession(session: debug.ISession): TPromise { + stopSession(session: ISession): TPromise { if (session) { return session.raw.terminate(); } @@ -1181,80 +965,32 @@ export class DebugService implements debug.IDebugService { return TPromise.join(sessions.map(s => s.raw.terminate(false))); } - this.sessionStates.clear(); this._onDidChangeState.fire(); return undefined; } - private onExitAdapter(raw: RawDebugSession): void { - const breakpoints = this.model.getBreakpoints(); - const session = this.model.getSessions().filter(p => p.getId() === raw.getId()).pop(); - /* __GDPR__ - "debugSessionStop" : { - "type" : { "classification": "SystemMetaData", "purpose": "FeatureInsight" }, - "success": { "classification": "SystemMetaData", "purpose": "FeatureInsight", "isMeasurement": true }, - "sessionLengthInSeconds": { "classification": "SystemMetaData", "purpose": "FeatureInsight", "isMeasurement": true }, - "breakpointCount": { "classification": "SystemMetaData", "purpose": "FeatureInsight", "isMeasurement": true }, - "watchExpressionsCount": { "classification": "SystemMetaData", "purpose": "FeatureInsight", "isMeasurement": true } - } - */ - this.telemetryService.publicLog('debugSessionStop', { - type: session && session.configuration.type, - success: raw.emittedStopped || breakpoints.length === 0, - sessionLengthInSeconds: raw.getLengthInSeconds(), - breakpointCount: breakpoints.length, - watchExpressionsCount: this.model.getWatchExpressions().length - }); - - this.model.removeSession(raw.getId()); - if (session) { - this._onDidEndSession.fire(session); - if (session.configuration.postDebugTask) { - this.doRunTask(session.getId(), session.raw.root, session.configuration.postDebugTask).done(undefined, err => - this.notificationService.error(err) - ); - } - } - - lifecycle.dispose(this.toDisposeOnSessionEnd.get(raw.getId())); - const focusedSession = this.viewModel.focusedSession; - if (focusedSession && focusedSession.getId() === raw.getId()) { - this.focusStackFrame(null); - } - this.updateStateAndEmit(raw.getId(), debug.State.Inactive); - - if (this.model.getSessions().length === 0) { - this.debugType.reset(); - this.viewModel.setMultiSessionView(false); - - if (this.partService.isVisible(Parts.SIDEBAR_PART) && this.configurationService.getValue('debug').openExplorerOnEnd) { - this.viewletService.openViewlet(EXPLORER_VIEWLET_ID).done(null, errors.onUnexpectedError); - } - } - } - - public getModel(): debug.IModel { + getModel(): IModel { return this.model; } - public getViewModel(): debug.IViewModel { + getViewModel(): IViewModel { return this.viewModel; } - public getConfigurationManager(): debug.IConfigurationManager { + getConfigurationManager(): IConfigurationManager { return this.configurationManager; } - private sendAllBreakpoints(session?: debug.ISession): TPromise { + private sendAllBreakpoints(session?: ISession): TPromise { return TPromise.join(distinct(this.model.getBreakpoints(), bp => bp.uri.toString()).map(bp => this.sendBreakpoints(bp.uri, false, session))) .then(() => this.sendFunctionBreakpoints(session)) // send exception breakpoints at the end since some debug adapters rely on the order .then(() => this.sendExceptionBreakpoints(session)); } - private sendBreakpoints(modelUri: uri, sourceModified = false, session?: debug.ISession): TPromise { + private sendBreakpoints(modelUri: uri, sourceModified = false, session?: ISession): TPromise { - const sendBreakpointsToSession = (session: debug.ISession): TPromise => { + const sendBreakpointsToSession = (session: ISession): TPromise => { const raw = session.raw; if (!raw.readyForBreakpoints) { return TPromise.as(null); @@ -1291,15 +1027,15 @@ export class DebugService implements debug.IDebugService { for (let i = 0; i < breakpointsToSend.length; i++) { data[breakpointsToSend[i].getId()] = response.body.breakpoints[i]; } - this.model.setBreakpointSessionData(raw.getId(), data); + this.model.setBreakpointSessionData(session.getId(), data); }); }; return this.sendToOneOrAllSessions(session, sendBreakpointsToSession); } - private sendFunctionBreakpoints(session?: debug.ISession): TPromise { - const sendFunctionBreakpointsToSession = (session: debug.ISession): TPromise => { + private sendFunctionBreakpoints(session?: ISession): TPromise { + const sendFunctionBreakpointsToSession = (session: ISession): TPromise => { const raw = session.raw; if (!raw.readyForBreakpoints || !raw.capabilities.supportsFunctionBreakpoints) { return TPromise.as(null); @@ -1315,15 +1051,15 @@ export class DebugService implements debug.IDebugService { for (let i = 0; i < breakpointsToSend.length; i++) { data[breakpointsToSend[i].getId()] = response.body.breakpoints[i]; } - this.model.setBreakpointSessionData(raw.getId(), data); + this.model.setBreakpointSessionData(session.getId(), data); }); }; return this.sendToOneOrAllSessions(session, sendFunctionBreakpointsToSession); } - private sendExceptionBreakpoints(session?: debug.ISession): TPromise { - const sendExceptionBreakpointsToSession = (session: debug.ISession): TPromise => { + private sendExceptionBreakpoints(session?: ISession): TPromise { + const sendExceptionBreakpointsToSession = (session: ISession): TPromise => { const raw = session.raw; if (!raw.readyForBreakpoints || this.model.getExceptionBreakpoints().length === 0) { return TPromise.as(null); @@ -1336,7 +1072,7 @@ export class DebugService implements debug.IDebugService { return this.sendToOneOrAllSessions(session, sendExceptionBreakpointsToSession); } - private sendToOneOrAllSessions(session: debug.ISession, send: (session: debug.ISession) => TPromise): TPromise { + private sendToOneOrAllSessions(session: ISession, send: (session: ISession) => TPromise): TPromise { if (session) { return send(session); } @@ -1395,8 +1131,7 @@ export class DebugService implements debug.IDebugService { } } - public dispose(): void { - this.toDisposeOnSessionEnd.forEach(toDispose => lifecycle.dispose(toDispose)); - this.toDispose = lifecycle.dispose(this.toDispose); + dispose(): void { + this.toDispose = dispose(this.toDispose); } } diff --git a/src/vs/workbench/parts/debug/electron-browser/debugSession.ts b/src/vs/workbench/parts/debug/electron-browser/debugSession.ts index 75170c00238..1be9dbc2494 100644 --- a/src/vs/workbench/parts/debug/electron-browser/debugSession.ts +++ b/src/vs/workbench/parts/debug/electron-browser/debugSession.ts @@ -5,53 +5,95 @@ import uri from 'vs/base/common/uri'; import * as resources from 'vs/base/common/resources'; +import * as nls from 'vs/nls'; +import * as platform from 'vs/base/common/platform'; +import * as errors from 'vs/base/common/errors'; +import severity from 'vs/base/common/severity'; import { TPromise } from 'vs/base/common/winjs.base'; +import { Event, Emitter } from 'vs/base/common/event'; import { ISuggestion } from 'vs/editor/common/modes'; import { Position } from 'vs/editor/common/core/position'; -import { ITreeElement, ISession, IConfig, IRawSession, IThread, IRawModelUpdate, SessionState } from 'vs/workbench/parts/debug/common/debug'; +import * as aria from 'vs/base/browser/ui/aria/aria'; +import { ISession, IConfig, IThread, IRawModelUpdate, IDebugService, IRawStoppedDetails, State, IRawSession, LoadedSourceEvent, DebugEvent } from 'vs/workbench/parts/debug/common/debug'; import { Source } from 'vs/workbench/parts/debug/common/debugSource'; import { mixin } from 'vs/base/common/objects'; -import { Thread, ExpressionContainer } from 'vs/workbench/parts/debug/common/debugModel'; +import { Thread, ExpressionContainer, Model } from 'vs/workbench/parts/debug/common/debugModel'; +import { RawDebugSession } from 'vs/workbench/parts/debug/electron-browser/rawDebugSession'; +import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; +import { Debugger } from 'vs/workbench/parts/debug/node/debugger'; +import product from 'vs/platform/node/product'; +import { INotificationService } from 'vs/platform/notification/common/notification'; +import { IWorkspaceFolder } from 'vs/platform/workspace/common/workspace'; +import { IDisposable, dispose } from 'vs/base/common/lifecycle'; +import { RunOnceScheduler } from 'vs/base/common/async'; +import { generateUuid } from 'vs/base/common/uuid'; +import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry'; export class Session implements ISession { - private sources: Map; - private threads: Map; + private sources = new Map(); + private threads = new Map(); + private rawListeners: IDisposable[] = []; + private fetchThreadsScheduler: RunOnceScheduler; + private _raw: RawDebugSession; + private _state: State; + private readonly _onDidLoadedSource = new Emitter(); + private readonly _onDidCustomEvent = new Emitter(); + private readonly _onDidChangeState = new Emitter(); + private readonly _onDidExitAdapter = new Emitter(); - constructor(private _configuration: { resolved: IConfig, unresolved: IConfig }, private session: IRawSession & ITreeElement) { - this.threads = new Map(); - this.sources = new Map(); + constructor( + private id: string, + private _configuration: { resolved: IConfig, unresolved: IConfig }, + public root: IWorkspaceFolder, + private model: Model, + @IInstantiationService private instantiationService: IInstantiationService, + @INotificationService private notificationService: INotificationService, + @IDebugService private debugService: IDebugService, + @ITelemetryService private telemetryService: ITelemetryService, + ) { + this.model.addSession(this); + this.state = State.Initializing; } - public get configuration(): IConfig { + get raw(): IRawSession { + return this._raw; + } + + get configuration(): IConfig { return this._configuration.resolved; } - public get unresolvedConfiguration(): IConfig { + get unresolvedConfiguration(): IConfig { return this._configuration.unresolved; } - public get raw(): IRawSession & ITreeElement { - return this.session; + getName(includeRoot: boolean): string { + return includeRoot && this.root ? `${this.configuration.name} (${resources.basenameOrAuthority(this.root.uri)})` : this.configuration.name; } - public set raw(value: IRawSession & ITreeElement) { - this.session = value; + get state(): State { + return this._state; } - public getName(includeRoot: boolean): string { - return includeRoot && this.raw.root ? `${this.configuration.name} (${resources.basenameOrAuthority(this.raw.root.uri)})` : this.configuration.name; + set state(value: State) { + this._state = value; + this._onDidChangeState.fire(value); } - public get state(): SessionState { - return this.configuration.type === 'attach' ? SessionState.ATTACH : SessionState.LAUNCH; + get onDidChangeState(): Event { + return this._onDidChangeState.event; } - public getSourceForUri(modelUri: uri): Source { + getId(): string { + return this.id; + } + + getSourceForUri(modelUri: uri): Source { return this.sources.get(modelUri.toString()); } - public getSource(raw: DebugProtocol.Source): Source { + getSource(raw: DebugProtocol.Source): Source { let source = new Source(raw, this.getId()); if (this.sources.has(source.uri.toString())) { source = this.sources.get(source.uri.toString()); @@ -67,29 +109,37 @@ export class Session implements ISession { return source; } - public getThread(threadId: number): Thread { + getThread(threadId: number): Thread { return this.threads.get(threadId); } - public getAllThreads(): IThread[] { + getAllThreads(): IThread[] { const result: IThread[] = []; this.threads.forEach(t => result.push(t)); return result; } - public getLoadedSources(): TPromise { - return this.raw.loadedSources({}).then(response => { + getLoadedSources(): TPromise { + return this._raw.loadedSources({}).then(response => { return response.body.sources.map(src => this.getSource(src)); - }, error => { + }, () => { return []; }); } - public getId(): string { - return this.session.getId(); + get onDidLoadedSource(): Event { + return this._onDidLoadedSource.event; } - public rawUpdate(data: IRawModelUpdate): void { + get onDidCustomEvent(): Event { + return this._onDidCustomEvent.event; + } + + get onDidExitAdapter(): Event { + return this._onDidExitAdapter.event; + } + + rawUpdate(data: IRawModelUpdate): void { if (data.thread && !this.threads.has(data.threadId)) { // A new thread came in, initialize it. @@ -118,7 +168,7 @@ export class Session implements ISession { } } - public clearThreads(removeThreads: boolean, reference: number = undefined): void { + clearThreads(removeThreads: boolean, reference: number = undefined): void { if (reference !== undefined && reference !== null) { if (this.threads.has(reference)) { const thread = this.threads.get(reference); @@ -144,12 +194,12 @@ export class Session implements ISession { } } - public completions(frameId: number, text: string, position: Position, overwriteBefore: number): TPromise { - if (!this.raw.capabilities.supportsCompletionsRequest) { + completions(frameId: number, text: string, position: Position, overwriteBefore: number): TPromise { + if (!this._raw.capabilities.supportsCompletionsRequest) { return TPromise.as([]); } - return this.raw.completions({ + return this._raw.completions({ frameId, text, column: position.column, @@ -173,4 +223,214 @@ export class Session implements ISession { return result; }, () => []); } + + initialize(dbgr: Debugger): TPromise { + return dbgr.getCustomTelemetryService().then(customTelemetryService => { + if (this._raw) { + // If there was already a connection make sure to remove old listeners + dispose(this.rawListeners); + } + this._raw = this.instantiationService.createInstance(RawDebugSession, this.id, this._configuration.resolved.debugServer, dbgr, customTelemetryService, this.root); + this.registerListeners(); + + return this._raw.initialize({ + clientID: 'vscode', + clientName: product.nameLong, + adapterID: this.configuration.type, + pathFormat: 'path', + linesStartAt1: true, + columnsStartAt1: true, + supportsVariableType: true, // #8858 + supportsVariablePaging: true, // #9537 + supportsRunInTerminalRequest: true, // #10574 + locale: platform.locale + }).then(() => { + this.state = State.Running; + this.model.setExceptionBreakpoints(this._raw.capabilities.exceptionBreakpointFilters); + }); + }); + } + + private registerListeners(): void { + this.rawListeners.push(this._raw.onDidInitialize(() => { + aria.status(nls.localize('debuggingStarted', "Debugging started.")); + const sendConfigurationDone = () => { + if (this._raw && this._raw.capabilities.supportsConfigurationDoneRequest) { + return this._raw.configurationDone().done(null, e => { + // Disconnect the debug session on configuration done error #10596 + if (this._raw) { + this._raw.disconnect().done(undefined, errors.onUnexpectedError); + } + this.notificationService.error(e.message); + }); + } + }; + + // Send all breakpoints + this.debugService.setBreakpointsActivated(true).then(sendConfigurationDone, sendConfigurationDone) + .done(() => this.fetchThreads(), errors.onUnexpectedError); + })); + + this.rawListeners.push(this._raw.onDidStop(event => { + this.state = State.Stopped; + this.fetchThreads(event.body).done(() => { + const thread = this.getThread(event.body.threadId); + if (thread) { + // Call fetch call stack twice, the first only return the top stack frame. + // Second retrieves the rest of the call stack. For performance reasons #25605 + this.model.fetchCallStack(thread).then(() => { + return !event.body.preserveFocusHint ? this.debugService.tryToAutoFocusStackFrame(thread) : undefined; + }); + } + }, errors.onUnexpectedError); + })); + + this.rawListeners.push(this._raw.onDidThread(event => { + if (event.body.reason === 'started') { + // debounce to reduce threadsRequest frequency and improve performance + if (!this.fetchThreadsScheduler) { + this.fetchThreadsScheduler = new RunOnceScheduler(() => { + this.fetchThreads().done(undefined, errors.onUnexpectedError); + }, 100); + this.rawListeners.push(this.fetchThreadsScheduler); + } + if (!this.fetchThreadsScheduler.isScheduled()) { + this.fetchThreadsScheduler.schedule(); + } + } else if (event.body.reason === 'exited') { + this.model.clearThreads(this.getId(), true, event.body.threadId); + } + })); + + this.rawListeners.push(this._raw.onDidTerminateDebugee(event => { + aria.status(nls.localize('debuggingStopped', "Debugging stopped.")); + if (event.body && event.body.restart) { + this.debugService.restartSession(this, event.body.restart).done(null, err => this.notificationService.error(err.message)); + } else { + this._raw.disconnect().done(undefined, errors.onUnexpectedError); + } + })); + + this.rawListeners.push(this._raw.onDidContinued(event => { + const threadId = event.body.allThreadsContinued !== false ? undefined : event.body.threadId; + this.model.clearThreads(this.getId(), false, threadId); + this.state = State.Running; + })); + + let outputPromises: TPromise[] = []; + this.rawListeners.push(this._raw.onDidOutput(event => { + if (!event.body) { + return; + } + + const outputSeverity = event.body.category === 'stderr' ? severity.Error : event.body.category === 'console' ? severity.Warning : severity.Info; + if (event.body.category === 'telemetry') { + // only log telemetry events from debug adapter if the debug extension provided the telemetry key + // and the user opted in telemetry + if (this._raw.customTelemetryService && this.telemetryService.isOptedIn) { + // __GDPR__TODO__ We're sending events in the name of the debug extension and we can not ensure that those are declared correctly. + this._raw.customTelemetryService.publicLog(event.body.output, event.body.data); + } + + return; + } + + // Make sure to append output in the correct order by properly waiting on preivous promises #33822 + const waitFor = outputPromises.slice(); + const source = event.body.source ? { + lineNumber: event.body.line, + column: event.body.column ? event.body.column : 1, + source: this.getSource(event.body.source) + } : undefined; + if (event.body.variablesReference) { + const container = new ExpressionContainer(this, event.body.variablesReference, generateUuid()); + outputPromises.push(container.getChildren().then(children => { + return TPromise.join(waitFor).then(() => children.forEach(child => { + // Since we can not display multiple trees in a row, we are displaying these variables one after the other (ignoring their names) + child.name = null; + this.debugService.logToRepl(child, outputSeverity, source); + })); + })); + } else if (typeof event.body.output === 'string') { + TPromise.join(waitFor).then(() => this.debugService.logToRepl(event.body.output, outputSeverity, source)); + } + TPromise.join(outputPromises).then(() => outputPromises = []); + })); + + this.rawListeners.push(this._raw.onDidBreakpoint(event => { + const id = event.body && event.body.breakpoint ? event.body.breakpoint.id : undefined; + const breakpoint = this.model.getBreakpoints().filter(bp => bp.idFromAdapter === id).pop(); + const functionBreakpoint = this.model.getFunctionBreakpoints().filter(bp => bp.idFromAdapter === id).pop(); + + if (event.body.reason === 'new' && event.body.breakpoint.source) { + const source = this.getSource(event.body.breakpoint.source); + const bps = this.model.addBreakpoints(source.uri, [{ + column: event.body.breakpoint.column, + enabled: true, + lineNumber: event.body.breakpoint.line, + }], false); + if (bps.length === 1) { + this.model.updateBreakpoints({ [bps[0].getId()]: event.body.breakpoint }); + } + } + + if (event.body.reason === 'removed') { + if (breakpoint) { + this.model.removeBreakpoints([breakpoint]); + } + if (functionBreakpoint) { + this.model.removeFunctionBreakpoints(functionBreakpoint.getId()); + } + } + + if (event.body.reason === 'changed') { + if (breakpoint) { + if (!breakpoint.column) { + event.body.breakpoint.column = undefined; + } + this.model.setBreakpointSessionData(this.getId(), { [breakpoint.getId()]: event.body.breakpoint }); + } + if (functionBreakpoint) { + this.model.setBreakpointSessionData(this.getId(), { [functionBreakpoint.getId()]: event.body.breakpoint }); + } + } + })); + + this.rawListeners.push(this._raw.onDidLoadedSource(event => { + this._onDidLoadedSource.fire({ + reason: event.body.reason, + source: this.getSource(event.body.source) + }); + })); + + this.rawListeners.push(this._raw.onDidCustomEvent(event => { + this._onDidCustomEvent.fire(event); + })); + + this.rawListeners.push(this._raw.onDidExitAdapter(() => this._onDidExitAdapter.fire())); + } + + private fetchThreads(stoppedDetails?: IRawStoppedDetails): TPromise { + return this._raw.threads().then(response => { + if (response && response.body && response.body.threads) { + response.body.threads.forEach(thread => { + this.model.rawUpdate({ + sessionId: this.getId(), + threadId: thread.id, + thread, + stoppedDetails: stoppedDetails && thread.id === stoppedDetails.threadId ? stoppedDetails : undefined + }); + }); + } + }); + } + + dispose(): void { + dispose(this.rawListeners); + this.model.removeSession(this.getId()); + if (!this._raw.disconnected) { + this._raw.disconnect().done(undefined, errors.onUnexpectedError); + } + this._raw = undefined; + } } diff --git a/src/vs/workbench/parts/debug/electron-browser/rawDebugSession.ts b/src/vs/workbench/parts/debug/electron-browser/rawDebugSession.ts index 93891ff0b4e..c98bfcb2347 100644 --- a/src/vs/workbench/parts/debug/electron-browser/rawDebugSession.ts +++ b/src/vs/workbench/parts/debug/electron-browser/rawDebugSession.ts @@ -16,10 +16,9 @@ import { IWorkspaceFolder } from 'vs/platform/workspace/common/workspace'; import { INotificationService } from 'vs/platform/notification/common/notification'; import { formatPII } from 'vs/workbench/parts/debug/common/debugUtils'; import { SocketDebugAdapter } from 'vs/workbench/parts/debug/node/debugAdapter'; -import { SessionState, DebugEvent, IRawSession, IDebugAdapter } from 'vs/workbench/parts/debug/common/debug'; +import { DebugEvent, IRawSession, IDebugAdapter } from 'vs/workbench/parts/debug/common/debug'; import { CancellationToken, CancellationTokenSource } from 'vs/base/common/cancellation'; - export interface SessionExitedEvent extends DebugEvent { body: { exitCode: number, @@ -48,7 +47,7 @@ export class RawDebugSession implements IRawSession { private cancellationTokens: CancellationTokenSource[]; private _capabilities: DebugProtocol.Capabilities; private allThreadsContinued: boolean; - private state: SessionState = SessionState.LAUNCH; + private isAttached: boolean; private readonly _onDidInitialize: Emitter; private readonly _onDidStop: Emitter; @@ -64,11 +63,11 @@ export class RawDebugSession implements IRawSession { private readonly _onDidEvent: Emitter; constructor( - private id: string, + private sessionId: string, private debugServerPort: number, private _debugger: Debugger, public customTelemetryService: ITelemetryService, - public root: IWorkspaceFolder, + private root: IWorkspaceFolder, @INotificationService private notificationService: INotificationService, @ITelemetryService private telemetryService: ITelemetryService, @IOutputService private outputService: IOutputService @@ -92,10 +91,6 @@ export class RawDebugSession implements IRawSession { this._onDidEvent = new Emitter(); } - public getId(): string { - return this.id; - } - public get onDidInitialize(): Event { return this._onDidInitialize.event; } @@ -239,7 +234,7 @@ export class RawDebugSession implements IRawSession { } private onDapEvent(event: DebugEvent): void { - event.sessionId = this.id; + event.sessionId = this.sessionId; if (event.event === 'loadedSource') { // most frequent comes first this._onDidLoadedSource.fire(event); @@ -293,7 +288,7 @@ export class RawDebugSession implements IRawSession { } public attach(args: DebugProtocol.AttachRequestArguments): TPromise { - this.state = SessionState.ATTACH; + this.isAttached = true; return this.send('attach', args).then(response => this.readCapabilities(response)); } @@ -352,7 +347,7 @@ export class RawDebugSession implements IRawSession { } public terminate(restart = false): TPromise { - if (this.capabilities.supportsTerminateRequest && !this.terminated && this.state === SessionState.LAUNCH) { + if (this.capabilities.supportsTerminateRequest && !this.terminated && !this.isAttached) { this.terminated = true; return this.send('terminate', { restart }); } @@ -516,13 +511,12 @@ export class RawDebugSession implements IRawSession { this.cachedInitServerP = null; } - this._onDidExitAdapter.fire({ sessionId: this.getId() }); + this._onDidExitAdapter.fire({ sessionId: this.sessionId }); this.disconnected = true; if (!this.debugAdapter || this.debugAdapter instanceof SocketDebugAdapter) { return TPromise.as(null); } - return this.debugAdapter.stopSession(); } @@ -537,6 +531,6 @@ export class RawDebugSession implements IRawSession { if (!this.disconnected) { this.notificationService.error(nls.localize('debugAdapterCrash', "Debug adapter process has terminated unexpectedly")); } - this._onDidExitAdapter.fire({ sessionId: this.getId() }); + this._onDidExitAdapter.fire({ sessionId: this.sessionId }); } } diff --git a/src/vs/workbench/parts/debug/test/common/mockDebug.ts b/src/vs/workbench/parts/debug/test/common/mockDebug.ts index c9914760a19..6e272e451b8 100644 --- a/src/vs/workbench/parts/debug/test/common/mockDebug.ts +++ b/src/vs/workbench/parts/debug/test/common/mockDebug.ts @@ -4,25 +4,22 @@ *--------------------------------------------------------------------------------------------*/ import uri from 'vs/base/common/uri'; -import { Event, Emitter } from 'vs/base/common/event'; +import { Event } from 'vs/base/common/event'; import { TPromise } from 'vs/base/common/winjs.base'; import { IWorkspaceFolder } from 'vs/platform/workspace/common/workspace'; import { Position } from 'vs/editor/common/core/position'; -import { ILaunch, IDebugService, State, DebugEvent, ISession, IConfigurationManager, IStackFrame, IBreakpointData, IBreakpointUpdateData, IConfig, IModel, IViewModel, IRawSession, IBreakpoint, LoadedSourceEvent, SessionState, IThread, IRawModelUpdate } from 'vs/workbench/parts/debug/common/debug'; +import { ILaunch, IDebugService, State, DebugEvent, ISession, IConfigurationManager, IStackFrame, IBreakpointData, IBreakpointUpdateData, IConfig, IModel, IViewModel, IRawSession, IBreakpoint, LoadedSourceEvent, IThread, IRawModelUpdate } from 'vs/workbench/parts/debug/common/debug'; import { Source } from 'vs/workbench/parts/debug/common/debugSource'; import { ISuggestion } from 'vs/editor/common/modes'; export class MockDebugService implements IDebugService { + public _serviceBrand: any; public get state(): State { return null; } - public get onDidCustomEvent(): Event { - return null; - } - public get onDidNewSession(): Event { return null; } @@ -35,10 +32,6 @@ export class MockDebugService implements IDebugService { return null; } - public get onDidLoadedSource(): Event { - return null; - } - public getConfigurationManager(): IConfigurationManager { return null; } @@ -115,12 +108,18 @@ export class MockDebugService implements IDebugService { public logToRepl(value: string): void { } public sourceIsNotAvailable(uri: uri): void { } + + public tryToAutoFocusStackFrame(thread: IThread): TPromise { + return TPromise.as(null); + } } export class MockSession implements ISession { + configuration: IConfig = { type: 'mock', request: 'launch' }; raw: IRawSession = new MockRawSession(); - state = SessionState.LAUNCH; + state = State.Stopped; + root: IWorkspaceFolder; getName(includeRoot: boolean): string { return 'mockname'; @@ -134,6 +133,18 @@ export class MockSession implements ISession { return null; } + get onDidCustomEvent(): Event { + return null; + } + + get onDidLoadedSource(): Event { + return null; + } + + get onDidExitAdapter(): Event { + return null; + } + getAllThreads(): ReadonlyArray { return []; } @@ -157,6 +168,8 @@ export class MockSession implements ISession { getId(): string { return 'mock'; } + + dispose(): void { } } export class MockRawSession implements IRawSession { @@ -164,12 +177,6 @@ export class MockRawSession implements IRawSession { public readyForBreakpoints = true; public emittedStopped = true; - public getId() { - return 'mockrawsession'; - } - - public root: IWorkspaceFolder; - public getLengthInSeconds(): number { return 100; } @@ -216,21 +223,6 @@ export class MockRawSession implements IRawSession { return {}; } - public get onDidEvent(): Event { - return null; - } - - public get onDidInitialize(): Event { - const emitter = new Emitter(); - return emitter.event; - } - - public get onDidExitAdapter(): Event<{ sessionId: string }> { - const emitter = new Emitter<{ sessionId: string }>(); - return emitter.event; - } - - public custom(request: string, args: any): TPromise { return TPromise.as(null); } @@ -239,6 +231,10 @@ export class MockRawSession implements IRawSession { return TPromise.as(null); } + public disconnect(restart?: boolean): TPromise { + return TPromise.as(null); + } + public threads(): TPromise { return TPromise.as(null); } diff --git a/src/vs/workbench/parts/debug/test/electron-browser/debugModel.test.ts b/src/vs/workbench/parts/debug/test/electron-browser/debugModel.test.ts index 3e448f864e7..5aa97ff564d 100644 --- a/src/vs/workbench/parts/debug/test/electron-browser/debugModel.test.ts +++ b/src/vs/workbench/parts/debug/test/electron-browser/debugModel.test.ts @@ -109,11 +109,11 @@ suite('Debug - Model', () => { test('threads simple', () => { const threadId = 1; const threadName = 'firstThread'; - const session = new Session({ resolved: { name: 'mockSession', type: 'node', request: 'launch' }, unresolved: undefined }, rawSession); - model.addSession(session); + const session = new Session('mock', { resolved: { name: 'mockSession', type: 'node', request: 'launch' }, unresolved: undefined }, undefined, model, undefined, undefined, undefined, undefined); + assert.equal(model.getSessions().length, 1); model.rawUpdate({ - sessionId: rawSession.getId(), + sessionId: 'mock', threadId: threadId, thread: { id: threadId, @@ -140,10 +140,11 @@ suite('Debug - Model', () => { const stoppedReason = 'breakpoint'; // Add the threads - const session = new Session({ resolved: { name: 'mockSession', type: 'node', request: 'launch' }, unresolved: undefined }, rawSession); - model.addSession(session); + const session = new Session('mock', { resolved: { name: 'mockSession', type: 'node', request: 'launch' }, unresolved: undefined }, undefined, model, undefined, undefined, undefined, undefined); + session['_raw'] = rawSession; + model.rawUpdate({ - sessionId: rawSession.getId(), + sessionId: 'mock', threadId: threadId1, thread: { id: threadId1, @@ -152,7 +153,7 @@ suite('Debug - Model', () => { }); model.rawUpdate({ - sessionId: rawSession.getId(), + sessionId: 'mock', threadId: threadId2, thread: { id: threadId2, @@ -162,7 +163,7 @@ suite('Debug - Model', () => { // Stopped event with all threads stopped model.rawUpdate({ - sessionId: rawSession.getId(), + sessionId: 'mock', threadId: threadId1, stoppedDetails: { reason: stoppedReason, @@ -230,11 +231,12 @@ suite('Debug - Model', () => { const runningThreadId = 2; const runningThreadName = 'runningThread'; const stoppedReason = 'breakpoint'; - const session = new Session({ resolved: { name: 'mockSession', type: 'node', request: 'launch' }, unresolved: undefined }, rawSession); - model.addSession(session); + const session = new Session('mock', { resolved: { name: 'mockSession', type: 'node', request: 'launch' }, unresolved: undefined }, undefined, model, undefined, undefined, undefined, undefined); + session['_raw'] = rawSession; + // Add the threads model.rawUpdate({ - sessionId: rawSession.getId(), + sessionId: 'mock', threadId: stoppedThreadId, thread: { id: stoppedThreadId, @@ -243,7 +245,7 @@ suite('Debug - Model', () => { }); model.rawUpdate({ - sessionId: rawSession.getId(), + sessionId: 'mock', threadId: runningThreadId, thread: { id: runningThreadId, @@ -253,7 +255,7 @@ suite('Debug - Model', () => { // Stopped event with only one thread stopped model.rawUpdate({ - sessionId: rawSession.getId(), + sessionId: 'mock', threadId: stoppedThreadId, stoppedDetails: { reason: stoppedReason, @@ -341,7 +343,8 @@ suite('Debug - Model', () => { test('repl expressions', () => { assert.equal(model.getReplElements().length, 0); - const session = new Session({ resolved: { name: 'mockSession', type: 'node', request: 'launch' }, unresolved: undefined }, rawSession); + const session = new Session('mock', { resolved: { name: 'mockSession', type: 'node', request: 'launch' }, unresolved: undefined }, undefined, model, undefined, undefined, undefined, undefined); + session['_raw'] = rawSession; const thread = new Thread(session, 'mockthread', 1); const stackFrame = new StackFrame(thread, 1, null, 'app.js', 'normal', { startLineNumber: 1, startColumn: 1, endLineNumber: 1, endColumn: 10 }, 1); model.addReplExpression(session, stackFrame, 'myVariable').done(); @@ -360,7 +363,7 @@ suite('Debug - Model', () => { }); test('stack frame get specific source name', () => { - const session = new Session({ resolved: { name: 'mockSession', type: 'node', request: 'launch' }, unresolved: undefined }, rawSession); + const session = new Session('mock', { resolved: { name: 'mockSession', type: 'node', request: 'launch' }, unresolved: undefined }, undefined, model, undefined, undefined, undefined, undefined); let firstStackFrame: StackFrame; let secondStackFrame: StackFrame; const thread = new class extends Thread { From 1f1b778104ea9338e898261d8b106489ad2d7784 Mon Sep 17 00:00:00 2001 From: Martin Aeschlimann Date: Mon, 20 Aug 2018 12:09:42 +0200 Subject: [PATCH 0980/1276] resource.isEqual / isEqualOrParent: use isIgnore default bahaviour --- src/vs/base/common/resources.ts | 2 +- src/vs/code/electron-main/windows.ts | 10 +++++----- src/vs/code/node/windowsFinder.ts | 10 +++++----- .../platform/backup/electron-main/backupMainService.ts | 4 ++-- .../history/electron-main/historyMainService.ts | 8 ++++---- .../parts/files/browser/editors/fileEditorTracker.ts | 6 +++--- src/vs/workbench/parts/files/common/explorerModel.ts | 2 +- .../markers/electron-browser/markersPanelActions.ts | 4 ++-- .../preferences/common/preferencesContribution.ts | 6 +++--- .../parts/snippets/electron-browser/snippetsService.ts | 2 +- .../services/configuration/node/configuration.ts | 2 +- .../configuration/node/configurationService.ts | 4 ++-- .../jsonschemas/common/jsonValidationExtensionPoint.ts | 2 +- .../services/textMate/electron-browser/TMSyntax.ts | 2 +- .../services/textfile/common/textFileEditorModel.ts | 6 +++--- .../themes/electron-browser/colorThemeStore.ts | 2 +- .../themes/electron-browser/fileIconThemeStore.ts | 2 +- .../services/workspace/node/workspaceEditingService.ts | 4 ++-- src/vs/workbench/test/workbenchTestServices.ts | 4 ++-- 19 files changed, 41 insertions(+), 41 deletions(-) diff --git a/src/vs/base/common/resources.ts b/src/vs/base/common/resources.ts index cefcd007927..ac6103d1ae0 100644 --- a/src/vs/base/common/resources.ts +++ b/src/vs/base/common/resources.ts @@ -46,7 +46,7 @@ function isEqualAuthority(a1: string, a2: string, ignoreCase?: boolean) { return a1 === a2 || ignoreCase && a1 && a2 && equalsIgnoreCase(a1, a2); } -export function isEqual(first: URI, second: URI, ignoreCase?: boolean): boolean { +export function isEqual(first: URI, second: URI, ignoreCase = hasToIgnoreCase(first)): boolean { const identityEquals = (first === second); if (identityEquals) { return true; diff --git a/src/vs/code/electron-main/windows.ts b/src/vs/code/electron-main/windows.ts index ee30f9a282b..5c9051ca65d 100644 --- a/src/vs/code/electron-main/windows.ts +++ b/src/vs/code/electron-main/windows.ts @@ -37,7 +37,7 @@ import { normalizeNFC } from 'vs/base/common/normalization'; import URI from 'vs/base/common/uri'; import { Queue } from 'vs/base/common/async'; import { exists } from 'vs/base/node/pfs'; -import { getComparisonKey, isEqual, hasToIgnoreCase, normalizePath } from 'vs/base/common/resources'; +import { getComparisonKey, isEqual, normalizePath } from 'vs/base/common/resources'; import { endsWith } from 'vs/base/common/strings'; enum WindowError { @@ -328,7 +328,7 @@ export class WindowsManager implements IWindowsMainService { else if (!win.isExtensionDevelopmentHost && (!!win.openedWorkspace || !!win.openedFolderUri)) { this.windowsState.openedWindows.forEach(o => { const sameWorkspace = win.openedWorkspace && o.workspace && o.workspace.id === win.openedWorkspace.id; - const sameFolder = win.openedFolderUri && o.folderUri && isEqual(o.folderUri, win.openedFolderUri, hasToIgnoreCase(o.folderUri)); + const sameFolder = win.openedFolderUri && o.folderUri && isEqual(o.folderUri, win.openedFolderUri); if (sameWorkspace || sameFolder) { o.uiState = state.uiState; @@ -444,7 +444,7 @@ export class WindowsManager implements IWindowsMainService { const usedWindow = usedWindows[i]; if ( (usedWindow.openedWorkspace && workspacesToRestore.some(workspace => workspace.id === usedWindow.openedWorkspace.id)) || // skip over restored workspace - (usedWindow.openedFolderUri && foldersToRestore.some(folder => isEqual(folder, usedWindow.openedFolderUri, hasToIgnoreCase(folder)))) || // skip over restored folder + (usedWindow.openedFolderUri && foldersToRestore.some(folder => isEqual(folder, usedWindow.openedFolderUri))) || // skip over restored folder (usedWindow.backupPath && emptyToRestore.some(empty => empty === basename(usedWindow.backupPath))) // skip over restored empty window ) { continue; @@ -660,7 +660,7 @@ export class WindowsManager implements IWindowsMainService { // Open remaining ones allFoldersToOpen.forEach(folderToOpen => { - if (windowsOnFolderPath.some(win => isEqual(win.openedFolderUri, folderToOpen, hasToIgnoreCase(win.openedFolderUri)))) { + if (windowsOnFolderPath.some(win => isEqual(win.openedFolderUri, folderToOpen))) { return; // ignore folders that are already open } @@ -1324,7 +1324,7 @@ export class WindowsManager implements IWindowsMainService { // Known Folder - load from stored settings if (configuration.folderUri) { - const stateForFolder = this.windowsState.openedWindows.filter(o => o.folderUri && isEqual(o.folderUri, configuration.folderUri, hasToIgnoreCase(o.folderUri))).map(o => o.uiState); + const stateForFolder = this.windowsState.openedWindows.filter(o => o.folderUri && isEqual(o.folderUri, configuration.folderUri)).map(o => o.uiState); if (stateForFolder.length) { return stateForFolder[0]; } diff --git a/src/vs/code/node/windowsFinder.ts b/src/vs/code/node/windowsFinder.ts index fa5fba59882..b69d3eec0db 100644 --- a/src/vs/code/node/windowsFinder.ts +++ b/src/vs/code/node/windowsFinder.ts @@ -10,7 +10,7 @@ import * as paths from 'vs/base/common/paths'; import { OpenContext } from 'vs/platform/windows/common/windows'; import { IWorkspaceIdentifier, IResolvedWorkspace, ISingleFolderWorkspaceIdentifier, isSingleFolderWorkspaceIdentifier, isWorkspaceIdentifier } from 'vs/platform/workspaces/common/workspaces'; import URI from 'vs/base/common/uri'; -import { hasToIgnoreCase, isEqual, isEqualOrParent } from 'vs/base/common/resources'; +import { isEqual, isEqualOrParent } from 'vs/base/common/resources'; export interface ISimpleWindow { openedWorkspace?: IWorkspaceIdentifier; @@ -49,13 +49,13 @@ function findWindowOnFilePath(windows: W[], fileUri: UR for (let i = 0; i < workspaceWindows.length; i++) { const window = workspaceWindows[i]; const resolvedWorkspace = workspaceResolver(window.openedWorkspace); - if (resolvedWorkspace && resolvedWorkspace.folders.some(folder => isEqualOrParent(fileUri, folder.uri, hasToIgnoreCase(fileUri)))) { + if (resolvedWorkspace && resolvedWorkspace.folders.some(folder => isEqualOrParent(fileUri, folder.uri))) { return window; } } // Then go with single folder windows that are parent of the provided file path - const singleFolderWindowsOnFilePath = windows.filter(window => window.openedFolderUri && isEqualOrParent(fileUri, window.openedFolderUri, hasToIgnoreCase(fileUri))); + const singleFolderWindowsOnFilePath = windows.filter(window => window.openedFolderUri && isEqualOrParent(fileUri, window.openedFolderUri)); if (singleFolderWindowsOnFilePath.length) { return singleFolderWindowsOnFilePath.sort((a, b) => -(a.openedFolderUri.path.length - b.openedFolderUri.path.length))[0]; } @@ -74,7 +74,7 @@ export function findWindowOnWorkspace(windows: W[], wor for (const window of windows) { // match on folder if (isSingleFolderWorkspaceIdentifier(workspace)) { - if (window.openedFolderUri && isEqual(window.openedFolderUri, workspace, hasToIgnoreCase(window.openedFolderUri))) { + if (window.openedFolderUri && isEqual(window.openedFolderUri, workspace)) { return window; } } @@ -111,7 +111,7 @@ export function findWindowOnWorkspaceOrFolderUri(window } // check for folder path - if (window.openedFolderUri && isEqual(window.openedFolderUri, uri, hasToIgnoreCase(uri))) { + if (window.openedFolderUri && isEqual(window.openedFolderUri, uri)) { return window; } } diff --git a/src/vs/platform/backup/electron-main/backupMainService.ts b/src/vs/platform/backup/electron-main/backupMainService.ts index 8c879b66d8b..278490fc6fe 100644 --- a/src/vs/platform/backup/electron-main/backupMainService.ts +++ b/src/vs/platform/backup/electron-main/backupMainService.ts @@ -121,7 +121,7 @@ export class BackupMainService implements IBackupMainService { } public registerFolderBackupSync(folderUri: URI): string { - if (!this.folderWorkspaces.some(uri => areResourcesEquals(folderUri, uri, hasToIgnoreCase(folderUri)))) { + if (!this.folderWorkspaces.some(uri => areResourcesEquals(folderUri, uri))) { this.folderWorkspaces.push(folderUri); this.saveSync(); } @@ -129,7 +129,7 @@ export class BackupMainService implements IBackupMainService { } public unregisterFolderBackupSync(folderUri: URI): void { - let index = arrays.firstIndex(this.folderWorkspaces, uri => areResourcesEquals(folderUri, uri, hasToIgnoreCase(folderUri))); + let index = arrays.firstIndex(this.folderWorkspaces, uri => areResourcesEquals(folderUri, uri)); if (index !== -1) { this.folderWorkspaces.splice(index, 1); this.saveSync(); diff --git a/src/vs/platform/history/electron-main/historyMainService.ts b/src/vs/platform/history/electron-main/historyMainService.ts index 3f2657d3851..84f4d3146e5 100644 --- a/src/vs/platform/history/electron-main/historyMainService.ts +++ b/src/vs/platform/history/electron-main/historyMainService.ts @@ -19,7 +19,7 @@ import { IHistoryMainService, IRecentlyOpened } from 'vs/platform/history/common import { IEnvironmentService } from 'vs/platform/environment/common/environment'; import { isEqual } from 'vs/base/common/paths'; import { RunOnceScheduler } from 'vs/base/common/async'; -import { getComparisonKey, isEqual as areResourcesEqual, hasToIgnoreCase, dirname } from 'vs/base/common/resources'; +import { getComparisonKey, isEqual as areResourcesEqual, dirname } from 'vs/base/common/resources'; import URI, { UriComponents } from 'vs/base/common/uri'; import { Schemas } from 'vs/base/common/network'; import { IUriLabelService } from 'vs/platform/uriLabel/common/uriLabel'; @@ -129,11 +129,11 @@ export class HistoryMainService implements IHistoryMainService { return isWorkspaceIdentifier(workspace) && isEqual(pathToRemove.configPath, workspace.configPath, !isLinux /* ignorecase */); } if (isSingleFolderWorkspaceIdentifier(pathToRemove)) { - return isSingleFolderWorkspaceIdentifier(workspace) && areResourcesEqual(pathToRemove, workspace, hasToIgnoreCase(pathToRemove)); + return isSingleFolderWorkspaceIdentifier(workspace) && areResourcesEqual(pathToRemove, workspace); } if (typeof pathToRemove === 'string') { if (isSingleFolderWorkspaceIdentifier(workspace)) { - return workspace.scheme === Schemas.file && areResourcesEqual(URI.file(pathToRemove), workspace, hasToIgnoreCase(workspace)); + return workspace.scheme === Schemas.file && areResourcesEqual(URI.file(pathToRemove), workspace); } if (isWorkspaceIdentifier(workspace)) { return isEqual(pathToRemove, workspace.configPath, !isLinux /* ignorecase */); @@ -149,7 +149,7 @@ export class HistoryMainService implements IHistoryMainService { // Remove file const pathToRemoveURI = pathToRemove instanceof URI ? pathToRemove : typeof pathToRemove === 'string' ? URI.file(pathToRemove) : null; if (pathToRemoveURI) { - index = arrays.firstIndex(mru.files, file => areResourcesEqual(file, pathToRemoveURI, hasToIgnoreCase(pathToRemoveURI))); + index = arrays.firstIndex(mru.files, file => areResourcesEqual(file, pathToRemoveURI)); } if (index >= 0) { mru.files.splice(index, 1); diff --git a/src/vs/workbench/parts/files/browser/editors/fileEditorTracker.ts b/src/vs/workbench/parts/files/browser/editors/fileEditorTracker.ts index 0d8ad43f255..f99b69abbcc 100644 --- a/src/vs/workbench/parts/files/browser/editors/fileEditorTracker.ts +++ b/src/vs/workbench/parts/files/browser/editors/fileEditorTracker.ts @@ -148,7 +148,7 @@ export class FileEditorTracker extends Disposable implements IWorkbenchContribut // Do NOT close any opened editor that matches the resource path (either equal or being parent) of the // resource we move to (movedTo). Otherwise we would close a resource that has been renamed to the same // path but different casing. - if (movedTo && resources.isEqualOrParent(resource, movedTo, resources.hasToIgnoreCase(resource))) { + if (movedTo && resources.isEqualOrParent(resource, movedTo)) { return; } @@ -156,7 +156,7 @@ export class FileEditorTracker extends Disposable implements IWorkbenchContribut if (arg1 instanceof FileChangesEvent) { matches = arg1.contains(resource, FileChangeType.DELETED); } else { - matches = resources.isEqualOrParent(resource, arg1, resources.hasToIgnoreCase(resource)); + matches = resources.isEqualOrParent(resource, arg1); } if (!matches) { @@ -223,7 +223,7 @@ export class FileEditorTracker extends Disposable implements IWorkbenchContribut const resource = editor.getResource(); // Update Editor if file (or any parent of the input) got renamed or moved - if (resources.isEqualOrParent(resource, oldResource, resources.hasToIgnoreCase(resource))) { + if (resources.isEqualOrParent(resource, oldResource)) { let reopenFileResource: URI; if (oldResource.toString() === resource.toString()) { reopenFileResource = newResource; // file got moved diff --git a/src/vs/workbench/parts/files/common/explorerModel.ts b/src/vs/workbench/parts/files/common/explorerModel.ts index 49d64d0a561..2b2127af5fc 100644 --- a/src/vs/workbench/parts/files/common/explorerModel.ts +++ b/src/vs/workbench/parts/files/common/explorerModel.ts @@ -157,7 +157,7 @@ export class ExplorerItem { // the folder is fully resolved if either it has a list of children or the client requested this by using the resolveTo // array of resource path to resolve. stat.isDirectoryResolved = !!raw.children || (!!resolveTo && resolveTo.some((r) => { - return resources.isEqualOrParent(r, stat.resource, resources.hasToIgnoreCase(r)); + return resources.isEqualOrParent(r, stat.resource); })); // Recurse into children diff --git a/src/vs/workbench/parts/markers/electron-browser/markersPanelActions.ts b/src/vs/workbench/parts/markers/electron-browser/markersPanelActions.ts index 8f6b4ca4793..d20ed821f30 100644 --- a/src/vs/workbench/parts/markers/electron-browser/markersPanelActions.ts +++ b/src/vs/workbench/parts/markers/electron-browser/markersPanelActions.ts @@ -36,7 +36,7 @@ import { IBulkEditService } from 'vs/editor/browser/services/bulkEditService'; import { ICommandService } from 'vs/platform/commands/common/commands'; import { IEditorService, ACTIVE_GROUP } from 'vs/workbench/services/editor/common/editorService'; import { IModelService } from 'vs/editor/common/services/modelService'; -import { isEqual, hasToIgnoreCase } from 'vs/base/common/resources'; +import { isEqual } from 'vs/base/common/resources'; export class ToggleMarkersPanelAction extends TogglePanelAction { @@ -297,7 +297,7 @@ export class QuickFixAction extends Action { this.update(); } else { modelService.onModelAdded(model => { - if (isEqual(model.uri, marker.resource, hasToIgnoreCase(model.uri))) { + if (isEqual(model.uri, marker.resource)) { this.update(); } }, this, this.disposables); diff --git a/src/vs/workbench/parts/preferences/common/preferencesContribution.ts b/src/vs/workbench/parts/preferences/common/preferencesContribution.ts index 14494b0bdb3..88c1483e5b6 100644 --- a/src/vs/workbench/parts/preferences/common/preferencesContribution.ts +++ b/src/vs/workbench/parts/preferences/common/preferencesContribution.ts @@ -24,7 +24,7 @@ import { IEditorInput } from 'vs/workbench/common/editor'; import { IWorkspaceContextService, WorkbenchState } from 'vs/platform/workspace/common/workspace'; import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; import { isLinux } from 'vs/base/common/platform'; -import { isEqual, hasToIgnoreCase } from 'vs/base/common/resources'; +import { isEqual } from 'vs/base/common/resources'; const schemaRegistry = Registry.as(JSONContributionRegistry.Extensions.JSONContribution); @@ -89,7 +89,7 @@ export class PreferencesContribution implements IWorkbenchContribution { const state = this.workspaceService.getWorkbenchState(); if (state === WorkbenchState.FOLDER) { const folders = this.workspaceService.getWorkspace().folders; - if (isEqual(resource, folders[0].toResource(FOLDER_SETTINGS_PATH), hasToIgnoreCase(resource))) { + if (isEqual(resource, folders[0].toResource(FOLDER_SETTINGS_PATH))) { return { override: this.preferencesService.openWorkspaceSettings(true, options, group) }; } } @@ -98,7 +98,7 @@ export class PreferencesContribution implements IWorkbenchContribution { else if (state === WorkbenchState.WORKSPACE) { const folders = this.workspaceService.getWorkspace().folders; for (let i = 0; i < folders.length; i++) { - if (isEqual(resource, folders[i].toResource(FOLDER_SETTINGS_PATH), hasToIgnoreCase(resource))) { + if (isEqual(resource, folders[i].toResource(FOLDER_SETTINGS_PATH))) { return { override: this.preferencesService.openFolderSettings(folders[i].uri, true, options, group) }; } } diff --git a/src/vs/workbench/parts/snippets/electron-browser/snippetsService.ts b/src/vs/workbench/parts/snippets/electron-browser/snippetsService.ts index abb914561cd..6ec87c8ce50 100644 --- a/src/vs/workbench/parts/snippets/electron-browser/snippetsService.ts +++ b/src/vs/workbench/parts/snippets/electron-browser/snippetsService.ts @@ -76,7 +76,7 @@ namespace schema { const extensionLocation = extension.description.extensionLocation; const snippetLocation = resources.joinPath(extensionLocation, snippet.path); - if (!resources.isEqualOrParent(snippetLocation, extensionLocation, resources.hasToIgnoreCase(snippetLocation))) { + if (!resources.isEqualOrParent(snippetLocation, extensionLocation)) { extension.collector.error(localize( 'invalid.path.1', "Expected `contributes.{0}.path` ({1}) to be included inside extension's folder ({2}). This might make the extension non-portable.", diff --git a/src/vs/workbench/services/configuration/node/configuration.ts b/src/vs/workbench/services/configuration/node/configuration.ts index 2df1c8ad96e..61a10f303f5 100644 --- a/src/vs/workbench/services/configuration/node/configuration.ts +++ b/src/vs/workbench/services/configuration/node/configuration.ts @@ -338,7 +338,7 @@ export class FileServiceBasedFolderConfiguration extends AbstractFolderConfigura return paths.normalize(relative(this.folderConfigurationPath.fsPath, resource.fsPath)); } } else { - if (resources.isEqualOrParent(resource, this.folderConfigurationPath, resources.hasToIgnoreCase(resource))) { + if (resources.isEqualOrParent(resource, this.folderConfigurationPath)) { return paths.normalize(relative(this.folderConfigurationPath.path, resource.path)); } } diff --git a/src/vs/workbench/services/configuration/node/configurationService.ts b/src/vs/workbench/services/configuration/node/configurationService.ts index df5c45ce917..eb73870a0be 100644 --- a/src/vs/workbench/services/configuration/node/configurationService.ts +++ b/src/vs/workbench/services/configuration/node/configurationService.ts @@ -40,7 +40,7 @@ import { massageFolderPathForWorkspace } from 'vs/platform/workspaces/node/works import { UserConfiguration } from 'vs/platform/configuration/node/configuration'; import { IJSONSchema, IJSONSchemaMap } from 'vs/base/common/jsonSchema'; import { localize } from 'vs/nls'; -import { isEqual, hasToIgnoreCase } from 'vs/base/common/resources'; +import { isEqual } from 'vs/base/common/resources'; import { IUriLabelService } from 'vs/platform/uriLabel/common/uriLabel'; export class WorkspaceService extends Disposable implements IWorkspaceConfigurationService, IWorkspaceContextService { @@ -133,7 +133,7 @@ export class WorkspaceService extends Disposable implements IWorkspaceConfigurat public isCurrentWorkspace(workspaceIdentifier: ISingleFolderWorkspaceIdentifier | IWorkspaceIdentifier): boolean { switch (this.getWorkbenchState()) { case WorkbenchState.FOLDER: - return isSingleFolderWorkspaceIdentifier(workspaceIdentifier) && isEqual(workspaceIdentifier, this.workspace.folders[0].uri, hasToIgnoreCase(workspaceIdentifier)); + return isSingleFolderWorkspaceIdentifier(workspaceIdentifier) && isEqual(workspaceIdentifier, this.workspace.folders[0].uri); case WorkbenchState.WORKSPACE: return isWorkspaceIdentifier(workspaceIdentifier) && this.workspace.id === workspaceIdentifier.id; } diff --git a/src/vs/workbench/services/jsonschemas/common/jsonValidationExtensionPoint.ts b/src/vs/workbench/services/jsonschemas/common/jsonValidationExtensionPoint.ts index 150400ab5c0..552888adf39 100644 --- a/src/vs/workbench/services/jsonschemas/common/jsonValidationExtensionPoint.ts +++ b/src/vs/workbench/services/jsonschemas/common/jsonValidationExtensionPoint.ts @@ -60,7 +60,7 @@ export class JSONValidationExtensionPoint { if (strings.startsWith(uri, './')) { try { const colorThemeLocation = resources.joinPath(extensionLocation, uri); - if (!resources.isEqualOrParent(colorThemeLocation, extensionLocation, resources.hasToIgnoreCase(colorThemeLocation))) { + if (!resources.isEqualOrParent(colorThemeLocation, extensionLocation)) { collector.warn(nls.localize('invalid.path.1', "Expected `contributes.{0}.url` ({1}) to be included inside extension's folder ({2}). This might make the extension non-portable.", configurationExtPoint.name, location, extensionLocation.path)); } } catch (e) { diff --git a/src/vs/workbench/services/textMate/electron-browser/TMSyntax.ts b/src/vs/workbench/services/textMate/electron-browser/TMSyntax.ts index cb08ce01cea..df7d609571b 100644 --- a/src/vs/workbench/services/textMate/electron-browser/TMSyntax.ts +++ b/src/vs/workbench/services/textMate/electron-browser/TMSyntax.ts @@ -313,7 +313,7 @@ export class TextMateService implements ITextMateService { } const grammarLocation = resources.joinPath(extensionLocation, syntax.path); - if (!resources.isEqualOrParent(grammarLocation, extensionLocation, resources.hasToIgnoreCase(grammarLocation))) { + if (!resources.isEqualOrParent(grammarLocation, extensionLocation)) { collector.warn(nls.localize('invalid.path.1', "Expected `contributes.{0}.path` ({1}) to be included inside extension's folder ({2}). This might make the extension non-portable.", grammarsExtPoint.name, grammarLocation.path, extensionLocation.path)); } diff --git a/src/vs/workbench/services/textfile/common/textFileEditorModel.ts b/src/vs/workbench/services/textfile/common/textFileEditorModel.ts index 6faef447dc3..bc21ebdd62e 100644 --- a/src/vs/workbench/services/textfile/common/textFileEditorModel.ts +++ b/src/vs/workbench/services/textfile/common/textFileEditorModel.ts @@ -33,7 +33,7 @@ import { INotificationService } from 'vs/platform/notification/common/notificati import { isLinux } from 'vs/base/common/platform'; import { IDisposable, toDisposable } from 'vs/base/common/lifecycle'; import { ILogService } from 'vs/platform/log/common/log'; -import { isEqual, isEqualOrParent, hasToIgnoreCase } from 'vs/base/common/resources'; +import { isEqual, isEqualOrParent } from 'vs/base/common/resources'; /** * The text file editor model listens to changes to its underlying code editor model and saves these changes through the file service back to the disk. @@ -795,14 +795,14 @@ export class TextFileEditorModel extends BaseTextEditorModel implements ITextFil } // Check for snippets - if (isEqualOrParent(this.resource, URI.file(path.join(this.environmentService.appSettingsHome, 'snippets')), hasToIgnoreCase(this.resource))) { + if (isEqualOrParent(this.resource, URI.file(path.join(this.environmentService.appSettingsHome, 'snippets')))) { return 'snippets'; } // Check for workspace settings file const folders = this.contextService.getWorkspace().folders; for (let i = 0; i < folders.length; i++) { - if (isEqualOrParent(this.resource, folders[i].toResource('.vscode'), hasToIgnoreCase(this.resource))) { + if (isEqualOrParent(this.resource, folders[i].toResource('.vscode'))) { const filename = path.basename(this.resource.fsPath); if (TextFileEditorModel.WHITELIST_WORKSPACE_JSON.indexOf(filename) > -1) { return `.vscode/${filename}`; diff --git a/src/vs/workbench/services/themes/electron-browser/colorThemeStore.ts b/src/vs/workbench/services/themes/electron-browser/colorThemeStore.ts index de23498235b..202f8be0707 100644 --- a/src/vs/workbench/services/themes/electron-browser/colorThemeStore.ts +++ b/src/vs/workbench/services/themes/electron-browser/colorThemeStore.ts @@ -95,7 +95,7 @@ export class ColorThemeStore { } const colorThemeLocation = resources.joinPath(extensionLocation, theme.path); - if (!resources.isEqualOrParent(colorThemeLocation, extensionLocation, resources.hasToIgnoreCase(colorThemeLocation))) { + if (!resources.isEqualOrParent(colorThemeLocation, extensionLocation)) { collector.warn(nls.localize('invalid.path.1', "Expected `contributes.{0}.path` ({1}) to be included inside extension's folder ({2}). This might make the extension non-portable.", themesExtPoint.name, colorThemeLocation.path, extensionLocation.path)); } diff --git a/src/vs/workbench/services/themes/electron-browser/fileIconThemeStore.ts b/src/vs/workbench/services/themes/electron-browser/fileIconThemeStore.ts index 1cb58bb40f0..a16ed89c917 100644 --- a/src/vs/workbench/services/themes/electron-browser/fileIconThemeStore.ts +++ b/src/vs/workbench/services/themes/electron-browser/fileIconThemeStore.ts @@ -97,7 +97,7 @@ export class FileIconThemeStore { } const iconThemeLocation = resources.joinPath(extensionLocation, iconTheme.path); - if (!resources.isEqualOrParent(iconThemeLocation, extensionLocation, resources.hasToIgnoreCase(iconThemeLocation))) { + if (!resources.isEqualOrParent(iconThemeLocation, extensionLocation)) { collector.warn(nls.localize('invalid.path.1', "Expected `contributes.{0}.path` ({1}) to be included inside extension's folder ({2}). This might make the extension non-portable.", iconThemeExtPoint.name, iconThemeLocation.path, extensionLocation.path)); } diff --git a/src/vs/workbench/services/workspace/node/workspaceEditingService.ts b/src/vs/workbench/services/workspace/node/workspaceEditingService.ts index 6caf2e400a4..3f31b7e7555 100644 --- a/src/vs/workbench/services/workspace/node/workspaceEditingService.ts +++ b/src/vs/workbench/services/workspace/node/workspaceEditingService.ts @@ -26,7 +26,7 @@ import { BackupFileService } from 'vs/workbench/services/backup/node/backupFileS import { ICommandService } from 'vs/platform/commands/common/commands'; import { distinct } from 'vs/base/common/arrays'; import { isLinux } from 'vs/base/common/platform'; -import { isEqual, hasToIgnoreCase } from 'vs/base/common/resources'; +import { isEqual } from 'vs/base/common/resources'; import { INotificationService, Severity } from 'vs/platform/notification/common/notification'; export class WorkspaceEditingService implements IWorkspaceEditingService { @@ -138,7 +138,7 @@ export class WorkspaceEditingService implements IWorkspaceEditingService { private includesSingleFolderWorkspace(folders: URI[]): boolean { if (this.contextService.getWorkbenchState() === WorkbenchState.FOLDER) { const workspaceFolder = this.contextService.getWorkspace().folders[0]; - return (folders.some(folder => isEqual(folder, workspaceFolder.uri, hasToIgnoreCase(folder)))); + return (folders.some(folder => isEqual(folder, workspaceFolder.uri))); } return false; diff --git a/src/vs/workbench/test/workbenchTestServices.ts b/src/vs/workbench/test/workbenchTestServices.ts index c0970077503..28b58ffa681 100644 --- a/src/vs/workbench/test/workbenchTestServices.ts +++ b/src/vs/workbench/test/workbenchTestServices.ts @@ -150,7 +150,7 @@ export class TestContextService implements IWorkspaceContextService { public isInsideWorkspace(resource: URI): boolean { if (resource && this.workspace) { - return resources.isEqualOrParent(resource, this.workspace.folders[0].uri, resources.hasToIgnoreCase(resource)); + return resources.isEqualOrParent(resource, this.workspace.folders[0].uri); } return false; @@ -161,7 +161,7 @@ export class TestContextService implements IWorkspaceContextService { } public isCurrentWorkspace(workspaceIdentifier: ISingleFolderWorkspaceIdentifier | IWorkspaceIdentifier): boolean { - return isSingleFolderWorkspaceIdentifier(workspaceIdentifier) && resources.isEqual(this.workspace.folders[0].uri, workspaceIdentifier, resources.hasToIgnoreCase(workspaceIdentifier)); + return isSingleFolderWorkspaceIdentifier(workspaceIdentifier) && resources.isEqual(this.workspace.folders[0].uri, workspaceIdentifier); } } From 669f2c8627741d4c48e199642b72dfa702c7f3d4 Mon Sep 17 00:00:00 2001 From: Johannes Rieken Date: Mon, 20 Aug 2018 12:18:30 +0200 Subject: [PATCH 0981/1276] use vscode-nls-dev-loader --- extensions/git/extension.webpack.config.js | 6 +-- extensions/shared.webpack.config.js | 49 ++++++++++------------ package.json | 2 +- yarn.lock | 6 +-- 4 files changed, 30 insertions(+), 33 deletions(-) diff --git a/extensions/git/extension.webpack.config.js b/extensions/git/extension.webpack.config.js index 743109f4343..75643a14039 100644 --- a/extensions/git/extension.webpack.config.js +++ b/extensions/git/extension.webpack.config.js @@ -13,8 +13,8 @@ const myConfig = { __dirname: false // leave the __dirname-behaviour intact }, entry: { - main: './out/main.js', - ['askpass-main']: './out/askpass-main.js' + main: './src/main.ts', + ['askpass-main']: './src/askpass-main.ts' }, plugins: [ new CopyWebpackPlugin([ @@ -34,4 +34,4 @@ const myConfig = { }, }; -module.exports = { ...sharedConfig(__dirname, false), ...myConfig }; +module.exports = { ...sharedConfig(__dirname), ...myConfig }; diff --git a/extensions/shared.webpack.config.js b/extensions/shared.webpack.config.js index 12ccb0c39dc..bbb8e580f7e 100644 --- a/extensions/shared.webpack.config.js +++ b/extensions/shared.webpack.config.js @@ -12,17 +12,36 @@ const path = require('path'); * returns a good default configuation for extensions that * want to do webpack */ -module.exports = function (extensionDir, useTsLoader = true) { - let config = { +module.exports = function (extensionDir) { + return { context: extensionDir, mode: 'none', // this leaves the source code as close as possible to the original (when packaging we set this to 'production') target: 'node', // extensions run in a node context resolve: { mainFields: ['main'], // prefer the main-entry of package.json files - extensions: [".js"] + extensions: ['.ts', '.js'] // support ts-files and js-files }, module: { - rules: [] + rules: [{ + test: /\.ts$/, + exclude: /node_modules/, + use: [{ + // vscode-nls-dev loader: + // * rewrite nls-calls + loader: 'vscode-nls-dev/lib/webpack-loader' + }, { + // configure TypeScript loader: + // * only transpile because we have a separate compilation pipeline + // * enable sources maps for end-to-end source maps + loader: 'ts-loader', + options: { + transpileOnly: true, + compilerOptions: { + "sourceMap": true, + } + } + }] + }] }, output: { // all output goes into `dist`. @@ -34,26 +53,4 @@ module.exports = function (extensionDir, useTsLoader = true) { // yes, really source maps devtool: 'source-map' }; - - if (useTsLoader) { - config.resolve.extensions = [".ts", ".js"]; // support ts-files and js-files - config.module.rules = [{ - // configure TypeScript loader: - // * only transpile because we have a separate compilation pipeline - // * enable sources maps for end-to-end source maps - test: /\.ts$/, - exclude: /node_modules/, - use: [{ - loader: 'ts-loader', - options: { - transpileOnly: true, - compilerOptions: { - "sourceMap": true, - } - } - }] - }]; - } - - return config; }; diff --git a/package.json b/package.json index 5b73450aa47..0564808a470 100644 --- a/package.json +++ b/package.json @@ -125,7 +125,7 @@ "vinyl": "^0.4.5", "vinyl-fs": "^2.4.3", "vsce": "1.33.2", - "vscode-nls-dev": "3.1.1", + "vscode-nls-dev": "3.2.0", "webpack": "^4.16.5", "webpack-cli": "^3.1.0", "webpack-stream": "^5.1.1" diff --git a/yarn.lock b/yarn.lock index e67580f77c1..49c567af992 100644 --- a/yarn.lock +++ b/yarn.lock @@ -7880,9 +7880,9 @@ vscode-fsevents@0.3.8: dependencies: nan "^2.3.0" -vscode-nls-dev@3.1.1: - version "3.1.1" - resolved "https://registry.yarnpkg.com/vscode-nls-dev/-/vscode-nls-dev-3.1.1.tgz#e7fa2e8e641b1579b25779acfda0e5f7c28f1fb9" +vscode-nls-dev@3.2.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/vscode-nls-dev/-/vscode-nls-dev-3.2.0.tgz#c4fe3977393b2785b82a7f0ccb2e47fd547c8657" dependencies: clone "^2.1.1" event-stream "^3.3.4" From 7661d6f9d40e1f037430c709ba63d43e2b4f9dc8 Mon Sep 17 00:00:00 2001 From: Johannes Rieken Date: Mon, 20 Aug 2018 12:29:13 +0200 Subject: [PATCH 0982/1276] remove webpack knowlegde from gulpfile.extensions --- build/gulpfile.extensions.js | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/build/gulpfile.extensions.js b/build/gulpfile.extensions.js index bedc9a293fb..bd38427a422 100644 --- a/build/gulpfile.extensions.js +++ b/build/gulpfile.extensions.js @@ -8,7 +8,6 @@ require('events').EventEmitter.defaultMaxListeners = 100; const gulp = require('gulp'); const path = require('path'); -const fs = require('fs'); const tsb = require('gulp-tsb'); const es = require('event-stream'); const filter = require('gulp-filter'); @@ -75,7 +74,6 @@ const tasks = compilations.map(function (tsconfigFile) { tsOptions.base = path.dirname(absolutePath); const compilation = tsb.create(tsOptions, null, null, err => reporter(err.toString())); - const nlsOption = fs.existsSync(path.join(root, 'extension.webpack.config.js')) ? { keepFilenames: true } : undefined; return function () { const input = es.through(); @@ -91,7 +89,7 @@ const tasks = compilations.map(function (tsconfigFile) { .pipe(tsFilter) .pipe(util.loadSourcemaps()) .pipe(compilation()) - .pipe(build ? nlsDev.rewriteLocalizeCalls(nlsOption) : es.through()) + .pipe(build ? nlsDev.rewriteLocalizeCalls() : es.through()) .pipe(build ? util.stripSourceMappingURL() : es.through()) .pipe(sourcemaps.write('.', { sourceMappingURL: !build ? null : f => `${baseUrl}/${f.relative}.map`, From bc05425af67e5481999db4a092ce716572501db6 Mon Sep 17 00:00:00 2001 From: Johannes Rieken Date: Mon, 20 Aug 2018 12:46:34 +0200 Subject: [PATCH 0983/1276] one more update... --- package.json | 2 +- yarn.lock | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/package.json b/package.json index 0564808a470..864d2fa74c6 100644 --- a/package.json +++ b/package.json @@ -125,7 +125,7 @@ "vinyl": "^0.4.5", "vinyl-fs": "^2.4.3", "vsce": "1.33.2", - "vscode-nls-dev": "3.2.0", + "vscode-nls-dev": "3.2.1", "webpack": "^4.16.5", "webpack-cli": "^3.1.0", "webpack-stream": "^5.1.1" diff --git a/yarn.lock b/yarn.lock index 49c567af992..071f2d8c7c9 100644 --- a/yarn.lock +++ b/yarn.lock @@ -7880,9 +7880,9 @@ vscode-fsevents@0.3.8: dependencies: nan "^2.3.0" -vscode-nls-dev@3.2.0: - version "3.2.0" - resolved "https://registry.yarnpkg.com/vscode-nls-dev/-/vscode-nls-dev-3.2.0.tgz#c4fe3977393b2785b82a7f0ccb2e47fd547c8657" +vscode-nls-dev@3.2.1: + version "3.2.1" + resolved "https://registry.yarnpkg.com/vscode-nls-dev/-/vscode-nls-dev-3.2.1.tgz#8aa9537b67d1e6e7ea4c6c4f80043c46c8a725ea" dependencies: clone "^2.1.1" event-stream "^3.3.4" From 7b5dc58be23808a478f3c7b09e7dd2b527091745 Mon Sep 17 00:00:00 2001 From: isidor Date: Mon, 20 Aug 2018 13:59:06 +0200 Subject: [PATCH 0984/1276] debug: cleanup EH debugging --- .../debug/electron-browser/debugService.ts | 27 +++++++------------ .../debug/electron-browser/debugSession.ts | 8 +++--- 2 files changed, 13 insertions(+), 22 deletions(-) diff --git a/src/vs/workbench/parts/debug/electron-browser/debugService.ts b/src/vs/workbench/parts/debug/electron-browser/debugService.ts index a360dabf1cc..4c2c1026a84 100644 --- a/src/vs/workbench/parts/debug/electron-browser/debugService.ts +++ b/src/vs/workbench/parts/debug/electron-browser/debugService.ts @@ -143,20 +143,10 @@ export class DebugService implements IDebugService { } if (broadcast.channel === EXTENSION_ATTACH_BROADCAST_CHANNEL) { - const initialAttach = session.configuration.request === 'launch'; - session.configuration.request = 'attach'; session.configuration.port = broadcast.payload.port; - // Do not end process on initial attach (since the request is still 'launch') - if (initialAttach) { - const dbgr = this.configurationManager.getDebugger(session.configuration.type); - session.initialize(dbgr).then(() => (session.raw).attach(session.configuration)); - } else { - if (session.raw) { - session.raw.disconnect().done(undefined, errors.onUnexpectedError); - } - this.doCreateSession(session.root, { resolved: session.configuration, unresolved: session.unresolvedConfiguration }, session.getId()); - } + const dbgr = this.configurationManager.getDebugger(session.configuration.type); + session.initialize(dbgr).then(() => (session.raw).attach(session.configuration)); return; } @@ -914,14 +904,15 @@ export class DebugService implements IDebugService { // Do not run preLaunch and postDebug tasks for automatic restarts this.skipRunningTask = !!restartData; + if (equalsIgnoreCase(session.configuration.type, 'extensionHost') && session.root) { + return this.broadcastService.broadcast({ + channel: EXTENSION_RELOAD_BROADCAST_CHANNEL, + payload: [session.root.uri.fsPath] + }); + } + // If the restart is automatic disconnect, otherwise send the terminate signal #55064 return (!!restartData ? session.raw.disconnect(true) : session.raw.terminate(true)).then(() => { - if (equalsIgnoreCase(session.configuration.type, 'extensionHost') && session.root) { - return this.broadcastService.broadcast({ - channel: EXTENSION_RELOAD_BROADCAST_CHANNEL, - payload: [session.root.uri.fsPath] - }); - } return new TPromise((c, e) => { setTimeout(() => { diff --git a/src/vs/workbench/parts/debug/electron-browser/debugSession.ts b/src/vs/workbench/parts/debug/electron-browser/debugSession.ts index 1be9dbc2494..b80961dab3a 100644 --- a/src/vs/workbench/parts/debug/electron-browser/debugSession.ts +++ b/src/vs/workbench/parts/debug/electron-browser/debugSession.ts @@ -225,11 +225,11 @@ export class Session implements ISession { } initialize(dbgr: Debugger): TPromise { + if (this._raw) { + // If there was already a connection make sure to remove old listeners + this.rawListeners = dispose(this.rawListeners); + } return dbgr.getCustomTelemetryService().then(customTelemetryService => { - if (this._raw) { - // If there was already a connection make sure to remove old listeners - dispose(this.rawListeners); - } this._raw = this.instantiationService.createInstance(RawDebugSession, this.id, this._configuration.resolved.debugServer, dbgr, customTelemetryService, this.root); this.registerListeners(); From 9f492373ed57a85847c4223f4783749e510f3cf1 Mon Sep 17 00:00:00 2001 From: Sandeep Somavarapu Date: Mon, 20 Aug 2018 15:16:40 +0200 Subject: [PATCH 0985/1276] - Use URI to install from vsix - Implement zip and unzip extensions APIs - Sync extension across management servers - Download service to download zips --- package.json | 5 +- src/typings/glob.d.ts | 302 ++++++++++++++++++ src/typings/yazl.d.ts | 15 + src/vs/base/node/zip.ts | 22 ++ .../sharedProcess/sharedProcessMain.ts | 6 + src/vs/code/node/cliProcessMain.ts | 6 +- src/vs/platform/download/common/download.ts | 20 ++ src/vs/platform/download/node/download.ts | 20 ++ src/vs/platform/download/node/downloadIpc.ts | 121 +++++++ .../common/extensionManagement.ts | 4 +- .../common/extensionManagementIpc.ts | 21 +- .../common/extensionManagementUtil.ts | 26 +- .../common/multiExtensionManagement.ts | 84 ++++- .../node/extensionManagementService.ts | 35 +- src/vs/workbench/electron-browser/shell.ts | 6 +- .../node/extensionsWorkbenchService.ts | 2 +- yarn.lock | 2 +- 17 files changed, 679 insertions(+), 18 deletions(-) create mode 100644 src/typings/glob.d.ts create mode 100644 src/typings/yazl.d.ts create mode 100644 src/vs/platform/download/common/download.ts create mode 100644 src/vs/platform/download/node/download.ts create mode 100644 src/vs/platform/download/node/downloadIpc.ts diff --git a/package.json b/package.json index 5b73450aa47..115548fd6f8 100644 --- a/package.json +++ b/package.json @@ -29,6 +29,7 @@ "fast-plist": "0.1.2", "gc-signals": "^0.0.1", "getmac": "1.4.1", + "glob": "^5.0.13", "graceful-fs": "4.1.11", "http-proxy-agent": "^2.1.0", "https-proxy-agent": "^2.2.1", @@ -51,7 +52,8 @@ "vscode-textmate": "^4.0.1", "vscode-xterm": "3.7.0-beta4", "winreg": "^1.2.4", - "yauzl": "^2.9.1" + "yauzl": "^2.9.1", + "yazl": "^2.4.3" }, "devDependencies": { "7zip": "0.0.6", @@ -71,7 +73,6 @@ "eslint": "^3.4.0", "event-stream": "^3.1.7", "express": "^4.13.1", - "glob": "^5.0.13", "gulp": "^3.8.9", "gulp-atom-electron": "^1.16.1", "gulp-azure-storage": "^0.7.0", diff --git a/src/typings/glob.d.ts b/src/typings/glob.d.ts new file mode 100644 index 00000000000..c2574b3f0ee --- /dev/null +++ b/src/typings/glob.d.ts @@ -0,0 +1,302 @@ +// Generated by typings +// Source: https://raw.githubusercontent.com/typed-typings/npm-minimatch/74f47de8acb42d668491987fc6bc144e7d9aa891/minimatch.d.ts +declare module '~glob~minimatch/minimatch' { +function minimatch (target: string, pattern: string, options?: minimatch.Options): boolean; + +namespace minimatch { + export function match (list: string[], pattern: string, options?: Options): string[]; + export function filter (pattern: string, options?: Options): (element: string, indexed: number, array: string[]) => boolean; + export function makeRe (pattern: string, options?: Options): RegExp; + + /** + * All options are `false` by default. + */ + export interface Options { + /** + * Dump a ton of stuff to stderr. + */ + debug?: boolean; + /** + * Do not expand `{a,b}` and `{1..3}` brace sets. + */ + nobrace?: boolean; + /** + * Disable `**` matching against multiple folder names. + */ + noglobstar?: boolean; + /** + * Allow patterns to match filenames starting with a period, even if the pattern does not explicitly have a period in that spot. + * + * Note that by default, `a\/**\/b` will not match `a/.d/b`, unless `dot` is set. + */ + dot?: boolean; + /** + * Disable "extglob" style patterns like `+(a|b)`. + */ + noext?: boolean; + /** + * Perform a case-insensitive match. + */ + nocase?: boolean; + /** + * When a match is not found by `minimatch.match`, return a list containing the pattern itself if this option is set. When not set, an empty list is returned if there are no matches. + */ + nonull?: boolean; + /** + * If set, then patterns without slashes will be matched against the basename of the path if it contains slashes. For example, `a?b` would match the path `/xyz/123/acb`, but not `/xyz/acb/123`. + */ + matchBase?: boolean; + /** + * Suppress the behavior of treating `#` at the start of a pattern as a comment. + */ + nocomment?: boolean; + /** + * Suppress the behavior of treating a leading `!` character as negation. + */ + nonegate?: boolean; + /** + * Returns from negate expressions the same as if they were not negated. (Ie, true on a hit, false on a miss.) + */ + flipNegate?: boolean; + } + + export class Minimatch { + constructor (pattern: string, options?: Options); + + /** + * The original pattern the minimatch object represents. + */ + pattern: string; + /** + * The options supplied to the constructor. + */ + options: Options; + + /** + * Created by the `makeRe` method. A single regular expression expressing the entire pattern. This is useful in cases where you wish to use the pattern somewhat like `fnmatch(3)` with `FNM_PATH` enabled. + */ + regexp: RegExp; + /** + * True if the pattern is negated. + */ + negate: boolean; + /** + * True if the pattern is a comment. + */ + comment: boolean; + /** + * True if the pattern is `""`. + */ + empty: boolean; + + /** + * Generate the regexp member if necessary, and return it. Will return false if the pattern is invalid. + */ + makeRe (): RegExp | boolean; + /** + * Return true if the filename matches the pattern, or false otherwise. + */ + match (fname: string): boolean; + /** + * Take a `/-`split filename, and match it against a single row in the `regExpSet`. This method is mainly for internal use, but is exposed so that it can be used by a glob-walker that needs to avoid excessive filesystem calls. + */ + matchOne (fileArray: string[], patternArray: string[], partial: boolean): boolean; + } +} + +export = minimatch; +} +declare module '~glob~minimatch' { +import main = require('~glob~minimatch/minimatch'); +export = main; +} + +// Generated by typings +// Source: https://raw.githubusercontent.com/types/npm-glob/59ca0f5d4696a8d4da27858035316c1014133fcb/glob.d.ts +declare module '~glob/glob' { +import events = require('events'); +import fs = require('fs'); +import minimatch = require('~glob~minimatch'); + +function glob (pattern: string, cb: (err: Error, matches: string[]) => void): void; +function glob (pattern: string, options: glob.Options, cb: (err: Error, matches: string[]) => void): void; + +namespace glob { + export function sync (pattern: string, options?: Options): string[]; + export function hasMagic (pattern: string, options?: Options): boolean; + + export interface Cache { + [path: string]: boolean | string | string[]; + } + + export interface StatCache { + [path: string]: fs.Stats; + } + + export interface Symlinks { + [path: string]: boolean; + } + + export interface Options extends minimatch.Options { + /** + * The current working directory in which to search. Defaults to `process.cwd()`. + */ + cwd?: string; + /** + * The place where patterns starting with `/` will be mounted onto. Defaults to `path.resolve(options.cwd, "/")` (`/` on Unix systems, and `C:\` or some such on Windows.) + */ + root?: string; + /** + * Include `.dot` files in normal matches and `globstar` matches. Note that an explicit dot in a portion of the pattern will always match dot files. + */ + dot?: boolean; + /** + * By default, a pattern starting with a forward-slash will be "mounted" onto the root setting, so that a valid filesystem path is returned. Set this flag to disable that behavior. + */ + nomount?: boolean; + /** + * Add a `/` character to directory matches. Note that this requires additional stat calls. + */ + mark?: boolean; + /** + * Don't sort the results. + */ + nosort?: boolean; + /** + * Set to true to stat all results. This reduces performance somewhat, and is completely unnecessary, unless `readdir` is presumed to be an untrustworthy indicator of file existence. + */ + stat?: boolean; + /** + * When an unusual error is encountered when attempting to read a directory, a warning will be printed to stderr. Set the `silent` option to true to suppress these warnings. + */ + silent?: boolean; + /** + * When an unusual error is encountered when attempting to read a directory, the process will just continue on in search of other matches. Set the `strict` option to raise an error in these cases. + */ + strict?: boolean; + /** + * See `cache` property above. Pass in a previously generated cache object to save some fs calls. + */ + cache?: Cache; + /** + * A cache of results of filesystem information, to prevent unnecessary stat calls. While it should not normally be necessary to set this, you may pass the statCache from one glob() call to the options object of another, if you know that the filesystem will not change between calls. (See https://github.com/isaacs/node-glob#race-conditions) + */ + statCache?: StatCache; + /** + * A cache of known symbolic links. You may pass in a previously generated `symlinks` object to save lstat calls when resolving `**` matches. + */ + symlinks?: Symlinks; + /** + * DEPRECATED: use `glob.sync(pattern, opts)` instead. + */ + sync?: boolean; + /** + * In some cases, brace-expanded patterns can result in the same file showing up multiple times in the result set. By default, this implementation prevents duplicates in the result set. Set this flag to disable that behavior. + */ + nounique?: boolean; + /** + * Set to never return an empty set, instead returning a set containing the pattern itself. This is the default in glob(3). + */ + nonull?: boolean; + /** + * Set to enable debug logging in minimatch and glob. + */ + debug?: boolean; + /** + * Do not expand `{a,b}` and `{1..3}` brace sets. + */ + nobrace?: boolean; + /** + * Do not match `**` against multiple filenames. (Ie, treat it as a normal `*` instead.) + */ + noglobstar?: boolean; + /** + * Do not match `+(a|b)` "extglob" patterns. + */ + noext?: boolean; + /** + * Perform a case-insensitive match. Note: on case-insensitive filesystems, non-magic patterns will match by default, since `stat` and `readdir` will not raise errors. + */ + nocase?: boolean; + /** + * Perform a basename-only match if the pattern does not contain any slash characters. That is, `*.js` would be treated as equivalent to `**\/*.js`, matching all js files in all directories. + */ + matchBase?: any; + /** + * Do not match directories, only files. (Note: to match only directories, simply put a `/` at the end of the pattern.) + */ + nodir?: boolean; + /** + * Add a pattern or an array of glob patterns to exclude matches. Note: `ignore` patterns are always in `dot:true` mode, regardless of any other settings. + */ + ignore?: string | string[]; + /** + * Follow symlinked directories when expanding `**` patterns. Note that this can result in a lot of duplicate references in the presence of cyclic links. + */ + follow?: boolean; + /** + * Set to true to call `fs.realpath` on all of the results. In the case of a symlink that cannot be resolved, the full absolute path to the matched entry is returned (though it will usually be a broken symlink) + */ + realpath?: boolean; + } + + export class Glob extends events.EventEmitter { + constructor (pattern: string, cb?: (err: Error, matches: string[]) => void); + constructor (pattern: string, options: Options, cb?: (err: Error, matches: string[]) => void); + + /** + * The minimatch object that the glob uses. + */ + minimatch: minimatch.Minimatch; + /** + * The options object passed in. + */ + options: Options; + /** + * Boolean which is set to true when calling `abort()`. There is no way at this time to continue a glob search after aborting, but you can re-use the statCache to avoid having to duplicate syscalls. + * @type {boolean} + */ + aborted: boolean; + /** + * Convenience object. + */ + cache: Cache; + /** + * Cache of `fs.stat` results, to prevent statting the same path multiple times. + */ + statCache: StatCache; + /** + * A record of which paths are symbolic links, which is relevant in resolving `**` patterns. + */ + symlinks: Symlinks; + /** + * An optional object which is passed to `fs.realpath` to minimize unnecessary syscalls. It is stored on the instantiated Glob object, and may be re-used. + */ + realpathCache: { [path: string]: string }; + found: string[]; + + /** + * Temporarily stop the search. + */ + pause(): void; + /** + * Resume the search. + */ + resume(): void; + /** + * Stop the search forever. + */ + abort(): void; + } +} + +export = glob; +} +declare module 'glob/glob' { +import main = require('~glob/glob'); +export = main; +} +declare module 'glob' { +import main = require('~glob/glob'); +export = main; +} diff --git a/src/typings/yazl.d.ts b/src/typings/yazl.d.ts new file mode 100644 index 00000000000..0aa227a6c82 --- /dev/null +++ b/src/typings/yazl.d.ts @@ -0,0 +1,15 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +declare module 'yazl' { + import * as stream from 'stream'; + + class ZipFile { + outputStream: stream.Stream; + addBuffer(buffer: Buffer, path: string); + addFile(localPath: string, path: string); + end(); + } +} \ No newline at end of file diff --git a/src/vs/base/node/zip.ts b/src/vs/base/node/zip.ts index 652fb21c73b..4ef2b283769 100644 --- a/src/vs/base/node/zip.ts +++ b/src/vs/base/node/zip.ts @@ -11,6 +11,7 @@ import { nfcall, ninvoke, SimpleThrottler } from 'vs/base/common/async'; import { mkdirp, rimraf } from 'vs/base/node/pfs'; import { TPromise } from 'vs/base/common/winjs.base'; import { open as _openZip, Entry, ZipFile } from 'yauzl'; +import * as yazl from 'yazl'; import { ILogService } from 'vs/platform/log/common/log'; export interface IExtractOptions { @@ -151,6 +152,27 @@ function openZip(zipFile: string, lazy: boolean = false): TPromise { .then(null, err => TPromise.wrapError(toExtractError(err))); } +export interface IFile { + path: string; + contents?: Buffer | string; + localPath?: string; +} + +export function zip(zipPath: string, files: IFile[]): TPromise { + return new TPromise((c, e) => { + const zip = new yazl.ZipFile(); + files.forEach(f => f.contents ? zip.addBuffer(typeof f.contents === 'string' ? new Buffer(f.contents, 'utf8') : f.contents, f.path) : zip.addFile(f.localPath, f.path)); + zip.end(); + + const zipStream = createWriteStream(zipPath); + zip.outputStream.pipe(zipStream); + + zip.outputStream.once('error', e); + zipStream.once('error', e); + zipStream.once('finish', () => c(zipPath)); + }); +} + export function extract(zipPath: string, targetPath: string, options: IExtractOptions = {}, logService: ILogService): TPromise { const sourcePathRegex = new RegExp(options.sourcePath ? `^${options.sourcePath}` : ''); diff --git a/src/vs/code/electron-browser/sharedProcess/sharedProcessMain.ts b/src/vs/code/electron-browser/sharedProcess/sharedProcessMain.ts index 547d1bd99d6..c8c5fb57de0 100644 --- a/src/vs/code/electron-browser/sharedProcess/sharedProcessMain.ts +++ b/src/vs/code/electron-browser/sharedProcess/sharedProcessMain.ts @@ -43,6 +43,8 @@ import { LocalizationsChannel } from 'vs/platform/localizations/common/localizat import { DialogChannelClient } from 'vs/platform/dialogs/common/dialogIpc'; import { IDialogService } from 'vs/platform/dialogs/common/dialogs'; import { IDisposable, dispose } from 'vs/base/common/lifecycle'; +import { IDownloadService } from 'vs/platform/download/common/download'; +import { DownloadServiceChannelClient } from 'vs/platform/download/node/downloadIpc'; export interface ISharedProcessConfiguration { readonly machineId: string; @@ -84,9 +86,13 @@ function main(server: Server, initData: ISharedProcessInitData, configuration: I const activeWindowManager = new ActiveWindowManager(windowsService); const route = () => activeWindowManager.getActiveClientId(); + const dialogChannel = server.getChannel('dialog', { routeCall: route, routeEvent: route }); services.set(IDialogService, new DialogChannelClient(dialogChannel)); + const downloadChannel = server.getChannel('download', { routeCall: route, routeEvent: route }); + services.set(IDownloadService, new DownloadServiceChannelClient(downloadChannel)); + const instantiationService = new InstantiationService(services); instantiationService.invokeFunction(accessor => { diff --git a/src/vs/code/node/cliProcessMain.ts b/src/vs/code/node/cliProcessMain.ts index 08bd0945583..bc78b2e1464 100644 --- a/src/vs/code/node/cliProcessMain.ts +++ b/src/vs/code/node/cliProcessMain.ts @@ -41,6 +41,9 @@ import { IDialogService } from 'vs/platform/dialogs/common/dialogs'; import { CommandLineDialogService } from 'vs/platform/dialogs/node/dialogService'; import { areSameExtensions, getGalleryExtensionIdFromLocal } from 'vs/platform/extensionManagement/common/extensionManagementUtil'; import Severity from 'vs/base/common/severity'; +import URI from 'vs/base/common/uri'; +import { IDownloadService } from 'vs/platform/download/common/download'; +import { DownloadService } from 'vs/platform/download/node/download'; const notFound = (id: string) => localize('notFound', "Extension '{0}' not found.", id); const notInstalled = (id: string) => localize('notInstalled', "Extension '{0}' is not installed.", id); @@ -101,7 +104,7 @@ class Main { .map(id => () => { const extension = path.isAbsolute(id) ? id : path.join(process.cwd(), id); - return this.extensionManagementService.install(extension).then(() => { + return this.extensionManagementService.install(URI.file(extension)).then(() => { console.log(localize('successVsixInstall', "Extension '{0}' was successfully installed!", getBaseLabel(extension))); }, error => { if (isPromiseCanceledError(error)) { @@ -240,6 +243,7 @@ export function main(argv: ParsedArgs): TPromise { services.set(IExtensionManagementService, new SyncDescriptor(ExtensionManagementService)); services.set(IExtensionGalleryService, new SyncDescriptor(ExtensionGalleryService)); services.set(IDialogService, new SyncDescriptor(CommandLineDialogService)); + services.set(IDownloadService, new SyncDescriptor(DownloadService)); const appenders: AppInsightsAppender[] = []; if (isBuilt && !extensionDevelopmentPath && !envService.args['disable-telemetry'] && product.enableTelemetry) { diff --git a/src/vs/platform/download/common/download.ts b/src/vs/platform/download/common/download.ts new file mode 100644 index 00000000000..80a9de7cbc0 --- /dev/null +++ b/src/vs/platform/download/common/download.ts @@ -0,0 +1,20 @@ +/*--------------------------------------------------------------------------------------------- + * 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 URI from 'vs/base/common/uri'; +import { createDecorator } from 'vs/platform/instantiation/common/instantiation'; +import { TPromise } from 'vs/base/common/winjs.base'; + +export const IDownloadService = createDecorator('downloadService'); + +export interface IDownloadService { + + _serviceBrand: any; + + download(location: URI, file: string): TPromise; + +} \ No newline at end of file diff --git a/src/vs/platform/download/node/download.ts b/src/vs/platform/download/node/download.ts new file mode 100644 index 00000000000..061d25c5df2 --- /dev/null +++ b/src/vs/platform/download/node/download.ts @@ -0,0 +1,20 @@ +/*--------------------------------------------------------------------------------------------- + * 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 URI from 'vs/base/common/uri'; +import { TPromise } from 'vs/base/common/winjs.base'; +import { IDownloadService } from 'vs/platform/download/common/download'; + +export class DownloadService implements IDownloadService { + + _serviceBrand: any; + + download(from: URI, to: string): TPromise { + throw new Error('Not supported'); + } + +} \ No newline at end of file diff --git a/src/vs/platform/download/node/downloadIpc.ts b/src/vs/platform/download/node/downloadIpc.ts new file mode 100644 index 00000000000..89b77323fc8 --- /dev/null +++ b/src/vs/platform/download/node/downloadIpc.ts @@ -0,0 +1,121 @@ +/*--------------------------------------------------------------------------------------------- + * 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 URI from 'vs/base/common/uri'; +import * as path from 'path'; +import * as fs from 'fs'; +import { TPromise } from 'vs/base/common/winjs.base'; +import { IChannel } from 'vs/base/parts/ipc/common/ipc'; +import { Event, Emitter, buffer } from 'vs/base/common/event'; +import { IDownloadService } from 'vs/platform/download/common/download'; +import { mkdirp } from 'vs/base/node/pfs'; +import { onUnexpectedError } from 'vs/base/common/errors'; + +export type UploadResponse = Buffer | Error | undefined; + +export function upload(uri: URI): Event { + const stream = new Emitter(); + fs.open(uri.fsPath, 'r', (err, fd) => { + if (err) { + if (err.code === 'ENOENT') { + stream.fire(new Error('File Not Found')); + } + return; + } + const finish = (err?: any) => { + if (err) { + stream.fire(err); + } else { + stream.fire(); + if (fd) { + fs.close(fd, err => { + if (err) { + onUnexpectedError(err); + } + }); + } + } + }; + let currentPosition: number = 0; + const readChunk = () => { + const chunkBuffer = Buffer.allocUnsafe(64 * 1024); // 64K Chunk + fs.read(fd, chunkBuffer, 0, chunkBuffer.length, currentPosition, (err, bytesRead) => { + currentPosition += bytesRead; + if (err) { + finish(err); + } else { + if (bytesRead === 0) { + // no more data -> finish + finish(); + } else { + stream.fire(chunkBuffer.slice(0, bytesRead)); + readChunk(); + } + } + }); + }; + // start reading + readChunk(); + }); + return stream.event; +} + +export interface IDownloadServiceChannel extends IChannel { + listen(event: 'upload', uri: URI): Event; + listen(event: string, arg?: any): Event; +} + +export class DownloadServiceChannel implements IDownloadServiceChannel { + + constructor() { } + + listen(event: string, arg?: any): Event { + switch (event) { + case 'upload': return buffer(upload(arg)); + } + return undefined; + } + + call(command: string, arg?: any): TPromise { + throw new Error('No calls'); + } +} + +export class DownloadServiceChannelClient implements IDownloadService { + + _serviceBrand: any; + + constructor(private channel: IDownloadServiceChannel) { } + + download(from: URI, to: string): TPromise { + const dirName = path.dirname(to); + let out: fs.WriteStream; + return new TPromise((c, e) => { + return mkdirp(dirName) + .then(() => { + out = fs.createWriteStream(to); + out.once('close', () => c(null)); + out.once('error', e); + const uploadStream = this.channel.listen('upload', from); + const disposable = uploadStream((result: Buffer | Error | undefined) => { + if (result === void 0) { + out.end(); + out.close(); + disposable.dispose(); + c(null); + } else if (result instanceof Buffer) { + out.write(result); + } else if (result instanceof Error) { + out.close(); + disposable.dispose(); + e(result); + } + }); + }); + }); + } +} \ No newline at end of file diff --git a/src/vs/platform/extensionManagement/common/extensionManagement.ts b/src/vs/platform/extensionManagement/common/extensionManagement.ts index f7a4416631b..bc65fb0b024 100644 --- a/src/vs/platform/extensionManagement/common/extensionManagement.ts +++ b/src/vs/platform/extensionManagement/common/extensionManagement.ts @@ -306,7 +306,9 @@ export interface IExtensionManagementService { onUninstallExtension: Event; onDidUninstallExtension: Event; - install(zipPath: string): TPromise; + zip(extension: ILocalExtension): TPromise; + unzip(zipLocation: URI): TPromise; + install(vsix: URI): TPromise; installFromGallery(extension: IGalleryExtension): TPromise; uninstall(extension: ILocalExtension, force?: boolean): TPromise; reinstallFromGallery(extension: ILocalExtension): TPromise; diff --git a/src/vs/platform/extensionManagement/common/extensionManagementIpc.ts b/src/vs/platform/extensionManagement/common/extensionManagementIpc.ts index 4180af7c8a3..40048fe5efa 100644 --- a/src/vs/platform/extensionManagement/common/extensionManagementIpc.ts +++ b/src/vs/platform/extensionManagement/common/extensionManagementIpc.ts @@ -17,7 +17,10 @@ export interface IExtensionManagementChannel extends IChannel { listen(event: 'onDidInstallExtension'): Event; listen(event: 'onUninstallExtension'): Event; listen(event: 'onDidUninstallExtension'): Event; - call(command: 'install', args: [string]): TPromise; + + call(command: 'zip', args: [ILocalExtension]): TPromise; + call(command: 'unzip', args: [URI]): TPromise; + call(command: 'install', args: [URI]): TPromise; call(command: 'installFromGallery', args: [IGalleryExtension]): TPromise; call(command: 'uninstall', args: [ILocalExtension, boolean]): TPromise; call(command: 'reinstallFromGallery', args: [ILocalExtension]): TPromise; @@ -53,7 +56,9 @@ export class ExtensionManagementChannel implements IExtensionManagementChannel { call(command: string, args?: any): TPromise { switch (command) { - case 'install': return this.service.install(args[0]); + case 'zip': return this.service.zip(this._transform(args[0])); + case 'unzip': return this.service.unzip(URI.revive(args[0])); + case 'install': return this.service.install(URI.revive(args[0])); case 'installFromGallery': return this.service.installFromGallery(args[0]); case 'uninstall': return this.service.uninstall(this._transform(args[0]), args[1]); case 'reinstallFromGallery': return this.service.reinstallFromGallery(this._transform(args[0])); @@ -81,8 +86,16 @@ export class ExtensionManagementChannelClient implements IExtensionManagementSer get onUninstallExtension(): Event { return this.channel.listen('onUninstallExtension'); } get onDidUninstallExtension(): Event { return this.channel.listen('onDidUninstallExtension'); } - install(zipPath: string): TPromise { - return this.channel.call('install', [zipPath]); + zip(extension: ILocalExtension): TPromise { + return this.channel.call('zip', [extension]).then(result => URI.revive(this.uriTransformer.transformIncoming(result))); + } + + unzip(zipLocation: URI): TPromise { + return this.channel.call('unzip', [zipLocation]); + } + + install(vsix: URI): TPromise { + return this.channel.call('install', [vsix]); } installFromGallery(extension: IGalleryExtension): TPromise { diff --git a/src/vs/platform/extensionManagement/common/extensionManagementUtil.ts b/src/vs/platform/extensionManagement/common/extensionManagementUtil.ts index 505673fa7fc..f07dafd169f 100644 --- a/src/vs/platform/extensionManagement/common/extensionManagementUtil.ts +++ b/src/vs/platform/extensionManagement/common/extensionManagementUtil.ts @@ -5,7 +5,7 @@ 'use strict'; -import { ILocalExtension, IGalleryExtension, EXTENSION_IDENTIFIER_REGEX, IExtensionIdentifier, IReportedExtension } from 'vs/platform/extensionManagement/common/extensionManagement'; +import { ILocalExtension, IGalleryExtension, EXTENSION_IDENTIFIER_REGEX, IExtensionIdentifier, IReportedExtension, IExtensionManifest } from 'vs/platform/extensionManagement/common/extensionManagement'; export function areSameExtensions(a: IExtensionIdentifier, b: IExtensionIdentifier): boolean { if (a.uuid && b.uuid) { @@ -117,4 +117,28 @@ export function getMaliciousExtensionsSet(report: IReportedExtension[]): Set, server) => { emitter.add(server.extensionManagementService.onInstallExtension); return emitter; }, new EventMultiplexer()).event; this.onDidInstallExtension = this.servers.reduce((emitter: EventMultiplexer, server) => { emitter.add(server.extensionManagementService.onDidInstallExtension); return emitter; }, new EventMultiplexer()).event; this.onUninstallExtension = this.servers.reduce((emitter: EventMultiplexer, server) => { emitter.add(server.extensionManagementService.onUninstallExtension); return emitter; }, new EventMultiplexer()).event; this.onDidUninstallExtension = this.servers.reduce((emitter: EventMultiplexer, server) => { emitter.add(server.extensionManagementService.onDidUninstallExtension); return emitter; }, new EventMultiplexer()).event; + this.syncExtensions(); } getInstalled(type?: LocalExtensionType): TPromise { @@ -49,8 +58,16 @@ export class MulitExtensionManagementService implements IExtensionManagementServ return this.getServer(extension).extensionManagementService.updateMetadata(extension, metadata); } - install(zipPath: string): TPromise { - return this.extensionManagementServerService.getLocalExtensionManagementServer().extensionManagementService.install(zipPath); + zip(extension: ILocalExtension): TPromise { + throw new Error('Not Supported'); + } + + unzip(zipLocation: URI): TPromise { + return TPromise.join(this.servers.map(({ extensionManagementService }) => extensionManagementService.unzip(zipLocation))).then(() => null); + } + + install(vsix: URI): TPromise { + return TPromise.join(this.servers.map(({ extensionManagementService }) => extensionManagementService.install(vsix))).then(() => null); } installFromGallery(extension: IGalleryExtension): TPromise { @@ -64,4 +81,65 @@ export class MulitExtensionManagementService implements IExtensionManagementServ private getServer(extension: ILocalExtension): IExtensionManagementServer { return this.extensionManagementServerService.getExtensionManagementServer(extension.location); } + + private async syncExtensions(): Promise { + const localServer = this.extensionManagementServerService.getLocalExtensionManagementServer(); + localServer.extensionManagementService.getInstalled() + .then(async localExtensions => { + const workspaceExtensions = localExtensions.filter(e => isWorkspaceExtension(e.manifest)); + const otherServers = this.servers.filter(s => s !== localServer); + + const extensionsToSync: Map = await this.getExtensionsToSync(workspaceExtensions, otherServers); + + if (extensionsToSync.size > 0) { + const handler = this.notificationService.notify({ severity: Severity.Info, message: localize('synchronising', "Synchronizing workspace extensions...") }); + handler.progress.infinite(); + const promises: TPromise[] = []; + const vsixById: Map> = new Map>(); + extensionsToSync.forEach((extensions, server) => { + for (const extension of extensions) { + let vsix = vsixById.get(extension.galleryIdentifier.id); + if (!vsix) { + vsix = localServer.extensionManagementService.zip(extension); + vsixById.set(extension.galleryIdentifier.id, vsix); + promises.push(vsix); + } + promises.push(vsix.then(location => server.extensionManagementService.unzip(location))); + } + }); + TPromise.join(promises).then(() => { + handler.progress.done(); + handler.updateMessage(localize('Synchronize.finished', "Finished synchronizing workspace extensions. Please reload now.")); + handler.updateActions({ + primary: [ + new Action('Synchronize.reloadNow', localize('Synchronize.reloadNow', "Reload Now"), null, true, () => this.windowService.reloadWindow()) + ] + }); + }); + } + }, err => { + console.log(err); + }); + } + + private async getExtensionsToSync(workspaceExtensions: ILocalExtension[], servers: IExtensionManagementServer[]): Promise> { + const extensionsToSync: Map = new Map(); + for (const server of servers) { + const extensions = await server.extensionManagementService.getInstalled(); + const groupedById = this.groupById(extensions); + const toSync = workspaceExtensions.filter(e => !groupedById.has(e.galleryIdentifier.id)); + if (toSync.length) { + extensionsToSync.set(server, toSync); + } + } + return extensionsToSync; + } + + private groupById(extensions: ILocalExtension[]): Map { + const result: Map = new Map(); + for (const extension of extensions) { + result.set(extension.galleryIdentifier.id, extension); + } + return result; + } } \ No newline at end of file diff --git a/src/vs/platform/extensionManagement/node/extensionManagementService.ts b/src/vs/platform/extensionManagement/node/extensionManagementService.ts index fca1b8fcc1e..ba5c82e925f 100644 --- a/src/vs/platform/extensionManagement/node/extensionManagementService.ts +++ b/src/vs/platform/extensionManagement/node/extensionManagementService.ts @@ -7,12 +7,13 @@ import * as nls from 'vs/nls'; import * as path from 'path'; +import * as glob from 'glob'; import * as pfs from 'vs/base/node/pfs'; import * as errors from 'vs/base/common/errors'; import { assign } from 'vs/base/common/objects'; import { toDisposable, Disposable } from 'vs/base/common/lifecycle'; import { flatten } from 'vs/base/common/arrays'; -import { extract, buffer, ExtractError } from 'vs/base/node/zip'; +import { extract, buffer, ExtractError, zip, IFile } from 'vs/base/node/zip'; import { TPromise, ValueCallback, ErrorCallback } from 'vs/base/common/winjs.base'; import { IExtensionManagementService, IExtensionGalleryService, ILocalExtension, @@ -41,6 +42,9 @@ import { toErrorMessage } from 'vs/base/common/errorMessage'; import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry'; import { isEngineValid } from 'vs/platform/extensions/node/extensionValidator'; import { getPathFromAmdModule } from 'vs/base/common/amd'; +import { tmpdir } from 'os'; +import { generateUuid } from 'vs/base/common/uuid'; +import { IDownloadService } from 'vs/platform/download/common/download'; const SystemExtensionsRoot = path.normalize(path.join(getPathFromAmdModule(require, ''), '..', 'extensions')); const ERROR_SCANNING_SYS_EXTENSIONS = 'scanningSystem'; @@ -136,6 +140,7 @@ export class ExtensionManagementService extends Disposable implements IExtension @IDialogService private dialogService: IDialogService, @IExtensionGalleryService private galleryService: IExtensionGalleryService, @ILogService private logService: ILogService, + @IDownloadService private downloadService: IDownloadService, @ITelemetryService private telemetryService: ITelemetryService, ) { super(); @@ -153,8 +158,32 @@ export class ExtensionManagementService extends Disposable implements IExtension })); } - install(zipPath: string): TPromise { - zipPath = path.resolve(zipPath); + zip(extension: ILocalExtension): TPromise { + return this.collectFiles(extension) + .then(files => zip(path.join(tmpdir(), generateUuid()), files)) + .then(path => URI.file(path)); + } + + unzip(zipLocation: URI): TPromise { + const downloadedLocation = path.join(tmpdir(), generateUuid()); + return this.downloadService.download(zipLocation, downloadedLocation).then(() => this.install(URI.file(downloadedLocation))); + } + + private collectFiles(extension: ILocalExtension): TPromise { + return new TPromise((c, e) => { + glob('**', { cwd: extension.location.fsPath, nodir: true, dot: true }, (err: Error, files: string[]) => { + if (err) { + e(err); + } else { + c(files.map(f => f.replace(/\\/g, '/')) + .map(f => ({ path: `extension/${f}`, localPath: path.join(extension.location.fsPath, f) }))); + } + }); + }); + } + + install(vsix: URI): TPromise { + const zipPath = path.resolve(vsix.fsPath); return validateLocalExtension(zipPath) .then(manifest => { diff --git a/src/vs/workbench/electron-browser/shell.ts b/src/vs/workbench/electron-browser/shell.ts index 33bea4a0ca0..4df8355c558 100644 --- a/src/vs/workbench/electron-browser/shell.ts +++ b/src/vs/workbench/electron-browser/shell.ts @@ -96,6 +96,7 @@ import { OpenerService } from 'vs/editor/browser/services/openerService'; import { SearchHistoryService } from 'vs/workbench/services/search/node/searchHistoryService'; import { MulitExtensionManagementService } from 'vs/platform/extensionManagement/common/multiExtensionManagement'; import { ExtensionManagementServerService } from 'vs/workbench/services/extensions/node/extensionManagementServerService'; +import { DownloadServiceChannel } from 'vs/platform/download/node/downloadIpc'; /** * Services that we require for the Shell @@ -335,7 +336,10 @@ export class WorkbenchShell extends Disposable { .then(() => connectNet(this.environmentService.sharedIPCHandle, `window:${this.configuration.windowId}`)); sharedProcess - .done(client => client.registerChannel('dialog', instantiationService.createInstance(DialogChannel))); + .done(client => { + client.registerChannel('download', instantiationService.createInstance(DownloadServiceChannel)); + client.registerChannel('dialog', instantiationService.createInstance(DialogChannel)); + }); // Warm up font cache information before building up too many dom elements restoreFontInfo(this.storageService); diff --git a/src/vs/workbench/parts/extensions/node/extensionsWorkbenchService.ts b/src/vs/workbench/parts/extensions/node/extensionsWorkbenchService.ts index dde370485c8..cf54929edc3 100644 --- a/src/vs/workbench/parts/extensions/node/extensionsWorkbenchService.ts +++ b/src/vs/workbench/parts/extensions/node/extensionsWorkbenchService.ts @@ -672,7 +672,7 @@ export class ExtensionsWorkbenchService implements IExtensionsWorkbenchService, location: ProgressLocation.Extensions, title: nls.localize('installingVSIXExtension', 'Installing extension from VSIX...'), source: `${extension}` - }, () => this.extensionService.install(extension).then(() => null)); + }, () => this.extensionService.install(URI.file(extension)).then(() => null)); } if (!(extension instanceof Extension)) { diff --git a/yarn.lock b/yarn.lock index e67580f77c1..9123288ecb7 100644 --- a/yarn.lock +++ b/yarn.lock @@ -8241,7 +8241,7 @@ yauzl@^2.2.1, yauzl@^2.3.1, yauzl@^2.9.1: buffer-crc32 "~0.2.3" fd-slicer "~1.0.1" -yazl@^2.2.1, yazl@^2.2.2: +yazl@^2.2.1, yazl@^2.2.2, yazl@^2.4.3: version "2.4.3" resolved "https://registry.yarnpkg.com/yazl/-/yazl-2.4.3.tgz#ec26e5cc87d5601b9df8432dbdd3cd2e5173a071" dependencies: From 01365dbe260a751dc4baf8a18b8bdd514a79229e Mon Sep 17 00:00:00 2001 From: Johannes Rieken Date: Mon, 20 Aug 2018 15:23:56 +0200 Subject: [PATCH 0986/1276] webpack - more defaults for extensions --- extensions/emmet/extension.webpack.config.js | 6 +- extensions/git/extension.webpack.config.js | 9 +-- extensions/shared.webpack.config.js | 79 +++++++++++++++++--- package.json | 1 + yarn.lock | 8 +- 5 files changed, 83 insertions(+), 20 deletions(-) diff --git a/extensions/emmet/extension.webpack.config.js b/extensions/emmet/extension.webpack.config.js index 55b15a2701a..b86756e4aa8 100644 --- a/extensions/emmet/extension.webpack.config.js +++ b/extensions/emmet/extension.webpack.config.js @@ -5,14 +5,14 @@ 'use strict'; -const sharedConfig = require('../shared.webpack.config'); +const withDefaults = require('../shared.webpack.config'); const myConfig = { + context: __dirname, entry: { extension: './src/extension.ts', }, externals: { - 'vscode': 'commonjs vscode', // ignored because it doesn't exist '@emmetio/css-parser': 'commonjs @emmetio/css-parser', '@emmetio/html-matcher': 'commonjs @emmetio/html-matcher', '@emmetio/math-expression': 'commonjs @emmetio/math-expression', @@ -21,4 +21,4 @@ const myConfig = { }, }; -module.exports = { ...sharedConfig(__dirname), ...myConfig }; +module.exports = withDefaults(myConfig); diff --git a/extensions/git/extension.webpack.config.js b/extensions/git/extension.webpack.config.js index 75643a14039..44e0d7dff17 100644 --- a/extensions/git/extension.webpack.config.js +++ b/extensions/git/extension.webpack.config.js @@ -5,10 +5,11 @@ 'use strict'; -const sharedConfig = require('../shared.webpack.config'); +const withDefaults = require('../shared.webpack.config'); const CopyWebpackPlugin = require('copy-webpack-plugin'); const myConfig = { + context: __dirname, node: { __dirname: false // leave the __dirname-behaviour intact }, @@ -18,12 +19,10 @@ const myConfig = { }, plugins: [ new CopyWebpackPlugin([ - { from: './out/*.sh', to: '[name].sh' }, - { from: './out/nls.*.json', to: '[name].json' } + { from: './out/*.sh', to: '[name].sh' } ]) ], externals: { - 'vscode': 'commonjs vscode', // ignored because it doesn't exist "byline": 'commonjs byline', "file-type": 'commonjs file-type', "iconv-lite": 'commonjs iconv-lite', @@ -34,4 +33,4 @@ const myConfig = { }, }; -module.exports = { ...sharedConfig(__dirname), ...myConfig }; +module.exports = withDefaults(myConfig); diff --git a/extensions/shared.webpack.config.js b/extensions/shared.webpack.config.js index bbb8e580f7e..7195a844fc8 100644 --- a/extensions/shared.webpack.config.js +++ b/extensions/shared.webpack.config.js @@ -6,15 +6,11 @@ 'use strict'; const path = require('path'); +const CopyWebpackPlugin = require('copy-webpack-plugin'); +const merge = require('merge-options'); -/** - * Function that must be invoked with __dirname and that - * returns a good default configuation for extensions that - * want to do webpack - */ -module.exports = function (extensionDir) { - return { - context: extensionDir, +module.exports = function withDefaults(extConfig) { + let defaultConfig = { mode: 'none', // this leaves the source code as close as possible to the original (when packaging we set this to 'production') target: 'node', // extensions run in a node context resolve: { @@ -43,14 +39,75 @@ module.exports = function (extensionDir) { }] }] }, + plugins: [ + new CopyWebpackPlugin([{ from: './out/nls.*.json', to: '[name].json' }]) // copy nls files + ], + externals: { + 'vscode': 'commonjs vscode', // ignored because it doesn't exist + }, output: { // all output goes into `dist`. // packaging depends on that and this must always be like it filename: '[name].js', - path: path.join(extensionDir, 'dist'), + path: path.join(extConfig.context, 'dist'), libraryTarget: "commonjs", }, // yes, really source maps devtool: 'source-map' - }; -}; + } + + return merge(defaultConfig, extConfig); +} + +// /** +// * Function that must be invoked with __dirname and that +// * returns a good default configuation for extensions that +// * want to do webpack +// */ +// module.exports = function (extensionDir) { +// return { +// context: extensionDir, +// mode: 'none', // this leaves the source code as close as possible to the original (when packaging we set this to 'production') +// target: 'node', // extensions run in a node context +// resolve: { +// mainFields: ['main'], // prefer the main-entry of package.json files +// extensions: ['.ts', '.js'] // support ts-files and js-files +// }, +// module: { +// rules: [{ +// test: /\.ts$/, +// exclude: /node_modules/, +// use: [{ +// // vscode-nls-dev loader: +// // * rewrite nls-calls +// loader: 'vscode-nls-dev/lib/webpack-loader' +// }, { +// // configure TypeScript loader: +// // * only transpile because we have a separate compilation pipeline +// // * enable sources maps for end-to-end source maps +// loader: 'ts-loader', +// options: { +// transpileOnly: true, +// compilerOptions: { +// "sourceMap": true, +// } +// } +// }] +// }] +// }, +// plugins: [ +// new CopyWebpackPlugin([ +// { from: './out/nls.*.json', to: '[name].json' } +// ]) +// ], +// output: { +// // all output goes into `dist`. +// // packaging depends on that and this must always be like it +// filename: '[name].js', +// path: path.join(extensionDir, 'dist'), +// libraryTarget: "commonjs", +// }, +// // yes, really source maps +// devtool: 'source-map' +// }; +// }; diff --git a/package.json b/package.json index 864d2fa74c6..136b3a54767 100644 --- a/package.json +++ b/package.json @@ -102,6 +102,7 @@ "istanbul": "^0.3.17", "jsdom-no-contextify": "^3.1.0", "lazy.js": "^0.4.2", + "merge-options": "^1.0.1", "mime": "^1.4.1", "minimatch": "^2.0.10", "mkdirp": "^0.5.0", diff --git a/yarn.lock b/yarn.lock index 071f2d8c7c9..a791e42fb98 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3909,7 +3909,7 @@ is-path-inside@^1.0.0: dependencies: path-is-inside "^1.0.1" -is-plain-obj@^1.0.0: +is-plain-obj@^1.0.0, is-plain-obj@^1.1: version "1.1.0" resolved "https://registry.yarnpkg.com/is-plain-obj/-/is-plain-obj-1.1.0.tgz#71a50c8429dfca773c92a390a4a03b39fcd51d3e" @@ -4724,6 +4724,12 @@ merge-descriptors@1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/merge-descriptors/-/merge-descriptors-1.0.1.tgz#b00aaa556dd8b44568150ec9d1b953f3f90cbb61" +merge-options@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/merge-options/-/merge-options-1.0.1.tgz#2a64b24457becd4e4dc608283247e94ce589aa32" + dependencies: + is-plain-obj "^1.1" + merge-stream@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/merge-stream/-/merge-stream-1.0.1.tgz#4041202d508a342ba00174008df0c251b8c135e1" From 4bf5813f7962f0fa488901dfa793386fec3dd871 Mon Sep 17 00:00:00 2001 From: Johannes Rieken Date: Mon, 20 Aug 2018 15:29:54 +0200 Subject: [PATCH 0987/1276] :lipstick: --- extensions/shared.webpack.config.js | 53 ----------------------------- 1 file changed, 53 deletions(-) diff --git a/extensions/shared.webpack.config.js b/extensions/shared.webpack.config.js index 7195a844fc8..b98d911ce80 100644 --- a/extensions/shared.webpack.config.js +++ b/extensions/shared.webpack.config.js @@ -58,56 +58,3 @@ module.exports = function withDefaults(extConfig) { return merge(defaultConfig, extConfig); } - -// /** -// * Function that must be invoked with __dirname and that -// * returns a good default configuation for extensions that -// * want to do webpack -// */ -// module.exports = function (extensionDir) { -// return { -// context: extensionDir, -// mode: 'none', // this leaves the source code as close as possible to the original (when packaging we set this to 'production') -// target: 'node', // extensions run in a node context -// resolve: { -// mainFields: ['main'], // prefer the main-entry of package.json files -// extensions: ['.ts', '.js'] // support ts-files and js-files -// }, -// module: { -// rules: [{ -// test: /\.ts$/, -// exclude: /node_modules/, -// use: [{ -// // vscode-nls-dev loader: -// // * rewrite nls-calls -// loader: 'vscode-nls-dev/lib/webpack-loader' -// }, { -// // configure TypeScript loader: -// // * only transpile because we have a separate compilation pipeline -// // * enable sources maps for end-to-end source maps -// loader: 'ts-loader', -// options: { -// transpileOnly: true, -// compilerOptions: { -// "sourceMap": true, -// } -// } -// }] -// }] -// }, -// plugins: [ -// new CopyWebpackPlugin([ -// { from: './out/nls.*.json', to: '[name].json' } -// ]) -// ], -// output: { -// // all output goes into `dist`. -// // packaging depends on that and this must always be like it -// filename: '[name].js', -// path: path.join(extensionDir, 'dist'), -// libraryTarget: "commonjs", -// }, -// // yes, really source maps -// devtool: 'source-map' -// }; -// }; From 66205890dd3cb6b4f2c42bb662bdd372c3dad9df Mon Sep 17 00:00:00 2001 From: Johannes Rieken Date: Mon, 20 Aug 2018 15:31:33 +0200 Subject: [PATCH 0988/1276] Revert "Revert "remove proposed Logger-api, #43275"" This reverts commit 315cce8314801ba9b25190682fad7fb48e797a9f. --- src/vs/vscode.proposed.d.ts | 16 ------ src/vs/workbench/api/node/extHost.api.impl.ts | 5 +- .../api/node/extHostExtensionActivator.ts | 2 - .../api/node/extHostExtensionService.ts | 4 -- .../workbench/api/node/extHostLogService.ts | 50 ------------------- 5 files changed, 4 insertions(+), 73 deletions(-) diff --git a/src/vs/vscode.proposed.d.ts b/src/vs/vscode.proposed.d.ts index 3de4a7af9dd..7c10f6b6b56 100644 --- a/src/vs/vscode.proposed.d.ts +++ b/src/vs/vscode.proposed.d.ts @@ -434,23 +434,7 @@ declare module 'vscode' { Off = 7 } - /** - * A logger for writing to an extension's log file, and accessing its dedicated log directory. - */ - export interface Logger { - trace(message: string, ...args: any[]): void; - debug(message: string, ...args: any[]): void; - info(message: string, ...args: any[]): void; - warn(message: string, ...args: any[]): void; - error(message: string | Error, ...args: any[]): void; - critical(message: string | Error, ...args: any[]): void; - } - export interface ExtensionContext { - /** - * This extension's logger - */ - logger: Logger; /** * Path where an extension can write log files. diff --git a/src/vs/workbench/api/node/extHost.api.impl.ts b/src/vs/workbench/api/node/extHost.api.impl.ts index ea64898c5b1..a8afbaabb36 100644 --- a/src/vs/workbench/api/node/extHost.api.impl.ts +++ b/src/vs/workbench/api/node/extHost.api.impl.ts @@ -227,7 +227,10 @@ export function createApiFactory( get language() { return platform.language; }, get appName() { return product.nameLong; }, get appRoot() { return initData.environment.appRoot; }, - get logLevel() { return extHostLogService.getLevel(); } + get logLevel() { + checkProposedApiEnabled(extension); + return extHostLogService.getLevel(); + } }); // namespace: extensions diff --git a/src/vs/workbench/api/node/extHostExtensionActivator.ts b/src/vs/workbench/api/node/extHostExtensionActivator.ts index cbd8a70d649..b392d0182f1 100644 --- a/src/vs/workbench/api/node/extHostExtensionActivator.ts +++ b/src/vs/workbench/api/node/extHostExtensionActivator.ts @@ -10,7 +10,6 @@ import Severity from 'vs/base/common/severity'; import { TPromise } from 'vs/base/common/winjs.base'; import { ExtensionDescriptionRegistry } from 'vs/workbench/services/extensions/node/extensionDescriptionRegistry'; import { IExtensionDescription } from 'vs/workbench/services/extensions/common/extensions'; -import { ExtHostLogger } from 'vs/workbench/api/node/extHostLogService'; const hasOwnProperty = Object.hasOwnProperty; const NO_OP_VOID_PROMISE = TPromise.wrap(void 0); @@ -27,7 +26,6 @@ export interface IExtensionContext { extensionPath: string; storagePath: string; asAbsolutePath(relativePath: string): string; - logger: ExtHostLogger; readonly logDirectory: string; readonly logPath: string; } diff --git a/src/vs/workbench/api/node/extHostExtensionService.ts b/src/vs/workbench/api/node/extHostExtensionService.ts index f29e288412b..06c52263022 100644 --- a/src/vs/workbench/api/node/extHostExtensionService.ts +++ b/src/vs/workbench/api/node/extHostExtensionService.ts @@ -361,10 +361,6 @@ export class ExtHostExtensionService implements ExtHostExtensionServiceShape { get extensionPath() { return extensionDescription.extensionLocation.fsPath; }, storagePath: this._storagePath.value(extensionDescription), asAbsolutePath: (relativePath: string) => { return join(extensionDescription.extensionLocation.fsPath, relativePath); }, - get logger() { - checkProposedApiEnabled(extensionDescription); - return that._extHostLogService.getExtLogger(extensionDescription.id); - }, get logDirectory() { console.warn(`this PROPOSED API has been RENAMED to 'logPath'`); checkProposedApiEnabled(extensionDescription); diff --git a/src/vs/workbench/api/node/extHostLogService.ts b/src/vs/workbench/api/node/extHostLogService.ts index 6708690a2f4..31b0113188f 100644 --- a/src/vs/workbench/api/node/extHostLogService.ts +++ b/src/vs/workbench/api/node/extHostLogService.ts @@ -4,7 +4,6 @@ *--------------------------------------------------------------------------------------------*/ 'use strict'; -import * as vscode from 'vscode'; import { join } from 'vs/base/common/paths'; import { LogLevel } from 'vs/workbench/api/node/extHostTypes'; import { ILogService, DelegatedLogService } from 'vs/platform/log/common/log'; @@ -14,8 +13,6 @@ import { ExtHostLogServiceShape } from 'vs/workbench/api/node/extHost.protocol'; export class ExtHostLogService extends DelegatedLogService implements ILogService, ExtHostLogServiceShape { - private _loggers: Map = new Map(); - constructor( private _windowId: number, logLevel: LogLevel, @@ -28,54 +25,7 @@ export class ExtHostLogService extends DelegatedLogService implements ILogServic this.setLevel(level); } - getExtLogger(extensionID: string): ExtHostLogger { - let logger = this._loggers.get(extensionID); - if (!logger) { - logger = this.createLogger(extensionID); - this._loggers.set(extensionID, logger); - } - return logger; - } - getLogDirectory(extensionID: string): string { return join(this._logsPath, `${extensionID}_${this._windowId}`); } - - private createLogger(extensionID: string): ExtHostLogger { - const logsDirPath = this.getLogDirectory(extensionID); - const logService = createSpdLogService(extensionID, this.getLevel(), logsDirPath); - this._register(this.onDidChangeLogLevel(level => logService.setLevel(level))); - return new ExtHostLogger(logService); - } -} - -export class ExtHostLogger implements vscode.Logger { - - constructor( - private readonly _logService: ILogService - ) { } - - trace(message: string, ...args: any[]): void { - return this._logService.trace(message, ...args); - } - - debug(message: string, ...args: any[]): void { - return this._logService.debug(message, ...args); - } - - info(message: string, ...args: any[]): void { - return this._logService.info(message, ...args); - } - - warn(message: string, ...args: any[]): void { - return this._logService.warn(message, ...args); - } - - error(message: string | Error, ...args: any[]): void { - return this._logService.error(message, ...args); - } - - critical(message: string | Error, ...args: any[]): void { - return this._logService.critical(message, ...args); - } } From 7b926ed9336a2816c17398cad8eb31af06cc564a Mon Sep 17 00:00:00 2001 From: Sandeep Somavarapu Date: Mon, 20 Aug 2018 15:34:07 +0200 Subject: [PATCH 0989/1276] Implement download service using request service --- src/vs/platform/download/node/download.ts | 20 ---------- .../platform/download/node/downloadService.ts | 38 +++++++++++++++++++ src/vs/workbench/electron-browser/shell.ts | 3 ++ 3 files changed, 41 insertions(+), 20 deletions(-) delete mode 100644 src/vs/platform/download/node/download.ts create mode 100644 src/vs/platform/download/node/downloadService.ts diff --git a/src/vs/platform/download/node/download.ts b/src/vs/platform/download/node/download.ts deleted file mode 100644 index 061d25c5df2..00000000000 --- a/src/vs/platform/download/node/download.ts +++ /dev/null @@ -1,20 +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'; - -import URI from 'vs/base/common/uri'; -import { TPromise } from 'vs/base/common/winjs.base'; -import { IDownloadService } from 'vs/platform/download/common/download'; - -export class DownloadService implements IDownloadService { - - _serviceBrand: any; - - download(from: URI, to: string): TPromise { - throw new Error('Not supported'); - } - -} \ No newline at end of file diff --git a/src/vs/platform/download/node/downloadService.ts b/src/vs/platform/download/node/downloadService.ts new file mode 100644 index 00000000000..e59afec589a --- /dev/null +++ b/src/vs/platform/download/node/downloadService.ts @@ -0,0 +1,38 @@ +/*--------------------------------------------------------------------------------------------- + * 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 URI from 'vs/base/common/uri'; +import { TPromise } from 'vs/base/common/winjs.base'; +import { IDownloadService } from 'vs/platform/download/common/download'; +import { IRequestService } from 'vs/platform/request/node/request'; +import { Schemas } from 'vs/base/common/network'; +import { copy } from 'vs/base/node/pfs'; +import { download, asText } from 'vs/base/node/request'; + +export class DownloadService implements IDownloadService { + + _serviceBrand: any; + + constructor( + @IRequestService private requestService: IRequestService + ) { } + + download(from: URI, to: string): TPromise { + if (from.scheme === Schemas.file) { + return copy(from.fsPath, to); + } + return this.requestService.request({ url: from.path }) + .then(context => { + if (context.res.statusCode === 200) { + return download(to, context); + } + return asText(context) + .then(message => TPromise.wrapError(new Error(`Expected 200, got back ${context.res.statusCode} instead.\n\n${message}`))); + }); + } + +} \ No newline at end of file diff --git a/src/vs/workbench/electron-browser/shell.ts b/src/vs/workbench/electron-browser/shell.ts index 4df8355c558..00236f97a7b 100644 --- a/src/vs/workbench/electron-browser/shell.ts +++ b/src/vs/workbench/electron-browser/shell.ts @@ -97,6 +97,8 @@ import { SearchHistoryService } from 'vs/workbench/services/search/node/searchHi import { MulitExtensionManagementService } from 'vs/platform/extensionManagement/common/multiExtensionManagement'; import { ExtensionManagementServerService } from 'vs/workbench/services/extensions/node/extensionManagementServerService'; import { DownloadServiceChannel } from 'vs/platform/download/node/downloadIpc'; +import { IDownloadService } from 'vs/platform/download/common/download'; +import { DownloadService } from 'vs/platform/download/node/downloadService'; /** * Services that we require for the Shell @@ -389,6 +391,7 @@ export class WorkbenchShell extends Disposable { serviceCollection.set(IExtensionEnablementService, extensionEnablementService); serviceCollection.set(IRequestService, new SyncDescriptor(RequestService)); + serviceCollection.set(IDownloadService, new SyncDescriptor(DownloadService)); this.extensionService = instantiationService.createInstance(ExtensionService); serviceCollection.set(IExtensionService, this.extensionService); From 8eb36b9cf4f7d5e02bcd66196aaea68b66ccdbce Mon Sep 17 00:00:00 2001 From: Sandeep Somavarapu Date: Mon, 20 Aug 2018 15:38:54 +0200 Subject: [PATCH 0990/1276] fix compilation --- src/vs/code/node/cliProcessMain.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vs/code/node/cliProcessMain.ts b/src/vs/code/node/cliProcessMain.ts index bc78b2e1464..9ed28b80f05 100644 --- a/src/vs/code/node/cliProcessMain.ts +++ b/src/vs/code/node/cliProcessMain.ts @@ -43,7 +43,7 @@ import { areSameExtensions, getGalleryExtensionIdFromLocal } from 'vs/platform/e import Severity from 'vs/base/common/severity'; import URI from 'vs/base/common/uri'; import { IDownloadService } from 'vs/platform/download/common/download'; -import { DownloadService } from 'vs/platform/download/node/download'; +import { DownloadService } from 'vs/platform/download/node/downloadService'; const notFound = (id: string) => localize('notFound', "Extension '{0}' not found.", id); const notInstalled = (id: string) => localize('notInstalled', "Extension '{0}' is not installed.", id); From 27c72d4ea482398c69010276c1a21276a653287e Mon Sep 17 00:00:00 2001 From: Johannes Rieken Date: Mon, 20 Aug 2018 15:42:09 +0200 Subject: [PATCH 0991/1276] remove logDirectory, #43275 --- .../src/utils/logDirectoryProvider.ts | 6 +++--- src/vs/vscode.proposed.d.ts | 10 ---------- src/vs/workbench/api/node/extHostExtensionActivator.ts | 1 - src/vs/workbench/api/node/extHostExtensionService.ts | 7 +------ 4 files changed, 4 insertions(+), 20 deletions(-) diff --git a/extensions/typescript-language-features/src/utils/logDirectoryProvider.ts b/extensions/typescript-language-features/src/utils/logDirectoryProvider.ts index fba55ea03e1..5f97d445a90 100644 --- a/extensions/typescript-language-features/src/utils/logDirectoryProvider.ts +++ b/extensions/typescript-language-features/src/utils/logDirectoryProvider.ts @@ -28,13 +28,13 @@ export default class LogDirectoryProvider { @memoize private logDirectory(): string | undefined { try { - const path = this.context.logDirectory; + const path = this.context.logPath; if (!fs.existsSync(path)) { fs.mkdirSync(path); } - return this.context.logDirectory; + return this.context.logPath; } catch { return undefined; } } -} \ No newline at end of file +} diff --git a/src/vs/vscode.proposed.d.ts b/src/vs/vscode.proposed.d.ts index 7c10f6b6b56..9b3a074851d 100644 --- a/src/vs/vscode.proposed.d.ts +++ b/src/vs/vscode.proposed.d.ts @@ -434,16 +434,6 @@ declare module 'vscode' { Off = 7 } - export interface ExtensionContext { - - /** - * Path where an extension can write log files. - * - * Extensions must create this directory before writing to it. The parent directory will always exist. - */ - readonly logDirectory: string; - } - export namespace env { /** * Current logging level. diff --git a/src/vs/workbench/api/node/extHostExtensionActivator.ts b/src/vs/workbench/api/node/extHostExtensionActivator.ts index b392d0182f1..5218f66cda6 100644 --- a/src/vs/workbench/api/node/extHostExtensionActivator.ts +++ b/src/vs/workbench/api/node/extHostExtensionActivator.ts @@ -26,7 +26,6 @@ export interface IExtensionContext { extensionPath: string; storagePath: string; asAbsolutePath(relativePath: string): string; - readonly logDirectory: string; readonly logPath: string; } diff --git a/src/vs/workbench/api/node/extHostExtensionService.ts b/src/vs/workbench/api/node/extHostExtensionService.ts index 06c52263022..2fe2cf9cd2e 100644 --- a/src/vs/workbench/api/node/extHostExtensionService.ts +++ b/src/vs/workbench/api/node/extHostExtensionService.ts @@ -12,7 +12,7 @@ import { TPromise } from 'vs/base/common/winjs.base'; import { ExtensionDescriptionRegistry } from 'vs/workbench/services/extensions/node/extensionDescriptionRegistry'; import { IExtensionDescription } from 'vs/workbench/services/extensions/common/extensions'; import { ExtHostStorage } from 'vs/workbench/api/node/extHostStorage'; -import { createApiFactory, initializeExtensionApi, checkProposedApiEnabled } from 'vs/workbench/api/node/extHost.api.impl'; +import { createApiFactory, initializeExtensionApi } from 'vs/workbench/api/node/extHost.api.impl'; import { MainContext, MainThreadExtensionServiceShape, IWorkspaceData, IEnvironment, IInitData, ExtHostExtensionServiceShape, MainThreadTelemetryShape, IMainContext } from './extHost.protocol'; import { IExtensionMemento, ExtensionsActivator, ActivatedExtension, IExtensionAPI, IExtensionContext, EmptyExtension, IExtensionModule, ExtensionActivationTimesBuilder, ExtensionActivationTimes, ExtensionActivationReason, ExtensionActivatedByEvent } from 'vs/workbench/api/node/extHostExtensionActivator'; import { ExtHostConfiguration } from 'vs/workbench/api/node/extHostConfiguration'; @@ -361,11 +361,6 @@ export class ExtHostExtensionService implements ExtHostExtensionServiceShape { get extensionPath() { return extensionDescription.extensionLocation.fsPath; }, storagePath: this._storagePath.value(extensionDescription), asAbsolutePath: (relativePath: string) => { return join(extensionDescription.extensionLocation.fsPath, relativePath); }, - get logDirectory() { - console.warn(`this PROPOSED API has been RENAMED to 'logPath'`); - checkProposedApiEnabled(extensionDescription); - return that._extHostLogService.getLogDirectory(extensionDescription.id); - }, logPath: that._extHostLogService.getLogDirectory(extensionDescription.id) }); }); From e512c12761803ffc86d4ea6c0e8a1e267d6072e7 Mon Sep 17 00:00:00 2001 From: Joao Moreno Date: Mon, 20 Aug 2018 15:47:06 +0200 Subject: [PATCH 0992/1276] ipc: protocol should be buffer based, not JSON based --- src/vs/base/parts/ipc/common/ipc.electron.ts | 21 +- src/vs/base/parts/ipc/common/ipc.ts | 182 ++++++++++-------- .../electron-browser/ipc.electron-browser.ts | 2 +- .../ipc/electron-main/ipc.electron-main.ts | 4 +- src/vs/base/parts/ipc/node/ipc.cp.ts | 15 +- src/vs/base/parts/ipc/node/ipc.net.ts | 54 +++--- .../base/parts/ipc/test/node/ipc.net.test.ts | 22 ++- .../workbench/common/extensionHostProtocol.ts | 37 ++++ src/vs/workbench/node/extensionHostProcess.ts | 9 +- .../electron-browser/extensionHost.ts | 11 +- .../services/extensions/node/rpcProtocol.ts | 39 ++-- 11 files changed, 233 insertions(+), 163 deletions(-) create mode 100644 src/vs/workbench/common/extensionHostProtocol.ts diff --git a/src/vs/base/parts/ipc/common/ipc.electron.ts b/src/vs/base/parts/ipc/common/ipc.electron.ts index 43422887433..6578a800a9b 100644 --- a/src/vs/base/parts/ipc/common/ipc.electron.ts +++ b/src/vs/base/parts/ipc/common/ipc.electron.ts @@ -7,26 +7,29 @@ import { IDisposable, dispose } from 'vs/base/common/lifecycle'; import { IMessagePassingProtocol } from 'vs/base/parts/ipc/common/ipc'; import { Event, Emitter } from 'vs/base/common/event'; +/** + * This implementation doesn't perform well since it uses base64 encoding for buffers. + * Electron 3.0 should have suport for buffers in IPC: https://github.com/electron/electron/pull/13055 + */ + export interface Sender { - send(channel: string, ...args: any[]): void; + send(channel: string, msg: string): void; } export class Protocol implements IMessagePassingProtocol { private listener: IDisposable; - private _onMessage: Event; - get onMessage(): Event { return this._onMessage; } + private _onMessage = new Emitter(); + get onMessage(): Event { return this._onMessage.event; } - constructor(private sender: Sender, onMessageEvent: Event) { - const emitter = new Emitter(); - onMessageEvent(msg => emitter.fire(msg)); - this._onMessage = emitter.event; + constructor(private sender: Sender, onMessageEvent: Event) { + onMessageEvent(msg => this._onMessage.fire(Buffer.from(msg, 'base64'))); } - send(message: any): void { + send(message: Buffer): void { try { - this.sender.send('ipc:message', message); + this.sender.send('ipc:message', message.toString('base64')); } catch (e) { // systems are going down } diff --git a/src/vs/base/parts/ipc/common/ipc.ts b/src/vs/base/parts/ipc/common/ipc.ts index 925e26aab62..75ebb4a4659 100644 --- a/src/vs/base/parts/ipc/common/ipc.ts +++ b/src/vs/base/parts/ipc/common/ipc.ts @@ -9,54 +9,50 @@ import { Promise, TPromise } from 'vs/base/common/winjs.base'; import { IDisposable, toDisposable, dispose } from 'vs/base/common/lifecycle'; import { Event, Emitter, once, filterEvent, toPromise, Relay } from 'vs/base/common/event'; -enum MessageType { - RequestPromise, - RequestPromiseCancel, - ResponseInitialize, - ResponsePromiseSuccess, - ResponsePromiseError, - ResponsePromiseErrorObj, - - RequestEventListen, - RequestEventDispose, - ResponseEventFire, +export enum RequestType { + Promise = 100, + PromiseCancel = 101, + EventListen = 102, + EventDispose = 103 } -function isResponse(messageType: MessageType): boolean { - return messageType === MessageType.ResponseInitialize - || messageType === MessageType.ResponsePromiseSuccess - || messageType === MessageType.ResponsePromiseError - || messageType === MessageType.ResponsePromiseErrorObj - || messageType === MessageType.ResponseEventFire; -} - -interface IRawMessage { - id: number; - type: MessageType; -} - -interface IRawRequest extends IRawMessage { - channelName?: string; - name?: string; - arg?: any; -} +type IRawPromiseRequest = { type: RequestType.Promise; id: number; channelName: string; name: string; arg: any; }; +type IRawPromiseCancelRequest = { type: RequestType.PromiseCancel, id: number }; +type IRawEventListenRequest = { type: RequestType.EventListen; id: number; channelName: string; name: string; arg: any; }; +type IRawEventDisposeRequest = { type: RequestType.EventDispose, id: number }; +type IRawRequest = IRawPromiseRequest | IRawPromiseCancelRequest | IRawEventListenRequest | IRawEventDisposeRequest; interface IRequest { raw: IRawRequest; flush?: () => void; } -interface IRawResponse extends IRawMessage { - data: any; +export enum ResponseType { + Initialize = 200, + PromiseSuccess = 201, + PromiseError = 202, + PromiseErrorObj = 203, + EventFire = 204 } +function isResponse(msg: { type: RequestType | ResponseType }): boolean { + return msg.type >= 200 && msg.type < 300; +} + +type IRawInitializeResponse = { type: ResponseType.Initialize }; +type IRawPromiseSuccessResponse = { type: ResponseType.PromiseSuccess; id: number; data: any }; +type IRawPromiseErrorResponse = { type: ResponseType.PromiseError; id: number; data: any }; +type IRawPromiseErrorObjResponse = { type: ResponseType.PromiseErrorObj; id: number; data: any }; +type IRawEventFireResponse = { type: ResponseType.EventFire; id: number; data: any }; +type IRawResponse = IRawInitializeResponse | IRawPromiseSuccessResponse | IRawPromiseErrorResponse | IRawPromiseErrorObjResponse | IRawEventFireResponse; + interface IHandler { (response: IRawResponse): void; } export interface IMessagePassingProtocol { - send(request: any): void; - onMessage: Event; + send(buffer: Buffer): void; + onMessage: Event; } enum State { @@ -112,8 +108,6 @@ export interface IRoutingChannelClient { getChannel(channelName: string, router: IClientRouter): T; } -// TODO@joao cleanup this mess! - export class ChannelServer implements IChannelServer, IDisposable { private channels: { [name: string]: IChannel } = Object.create(null); @@ -121,32 +115,15 @@ export class ChannelServer implements IChannelServer, IDisposable { private protocolListener: IDisposable; constructor(private protocol: IMessagePassingProtocol) { - this.protocolListener = this.protocol.onMessage(r => this.onMessage(r)); - this.protocol.send({ type: MessageType.ResponseInitialize }); + this.protocolListener = this.protocol.onMessage(msg => this.onRawMessage(msg)); + this.sendResponse({ type: ResponseType.Initialize }); } registerChannel(channelName: string, channel: IChannel): void { this.channels[channelName] = channel; } - private onMessage(request: IRawRequest): void { - switch (request.type) { - case MessageType.RequestPromise: - this.onPromise(request); - break; - - case MessageType.RequestEventListen: - this.onEventListen(request); - break; - - case MessageType.RequestPromiseCancel: - case MessageType.RequestEventDispose: - this.disposeActiveRequest(request); - break; - } - } - - private onPromise(request: IRawRequest): void { + private onPromise(request: IRawPromiseRequest): void { const channel = this.channels[request.channelName]; let promise: Promise; @@ -159,19 +136,19 @@ export class ChannelServer implements IChannelServer, IDisposable { const id = request.id; const requestPromise = promise.then(data => { - this.protocol.send({ id, data, type: MessageType.ResponsePromiseSuccess }); + this.sendResponse({ id, data, type: ResponseType.PromiseSuccess }); delete this.activeRequests[request.id]; }, data => { if (data instanceof Error) { - this.protocol.send({ + this.sendResponse({ id, data: { message: data.message, name: data.name, stack: data.stack ? (data.stack.split ? data.stack.split('\n') : data.stack) : void 0 - }, type: MessageType.ResponsePromiseError + }, type: ResponseType.PromiseError }); } else { - this.protocol.send({ id, data, type: MessageType.ResponsePromiseErrorObj }); + this.sendResponse({ id, data, type: ResponseType.PromiseErrorObj }); } delete this.activeRequests[request.id]; @@ -180,12 +157,12 @@ export class ChannelServer implements IChannelServer, IDisposable { this.activeRequests[request.id] = toDisposable(() => requestPromise.cancel()); } - private onEventListen(request: IRawRequest): void { + private onEventListen(request: IRawEventListenRequest): void { const channel = this.channels[request.channelName]; const id = request.id; const event = channel.listen(request.name, request.arg); - const disposable = event(data => this.protocol.send({ id, data, type: MessageType.ResponseEventFire })); + const disposable = event(data => this.sendResponse({ id, data, type: ResponseType.EventFire })); this.activeRequests[request.id] = disposable; } @@ -199,6 +176,39 @@ export class ChannelServer implements IChannelServer, IDisposable { } } + private onRawMessage(message: Buffer): void { + this.onRequest(JSON.parse(message.toString())); + } + + private onRequest(request: IRawRequest): void { + switch (request.type) { + case RequestType.Promise: + this.onPromise(request); + break; + + case RequestType.EventListen: + this.onEventListen(request); + break; + + case RequestType.PromiseCancel: + case RequestType.EventDispose: + this.disposeActiveRequest(request); + break; + } + } + + private sendResponse(response: IRawResponse) { + this.sendRawMessage(Buffer.from(JSON.stringify(response))); + } + + private sendRawMessage(message: Buffer) { + try { + this.protocol.send(message); + } catch (err) { + // noop + } + } + public dispose(): void { this.protocolListener.dispose(); this.protocolListener = null; @@ -224,7 +234,7 @@ export class ChannelClient implements IChannelClient, IDisposable { readonly onDidInitialize = this._onDidInitialize.event; constructor(private protocol: IMessagePassingProtocol) { - this.protocolListener = this.protocol.onMessage(r => this.onMessage(r)); + this.protocolListener = this.protocol.onMessage(msg => this.onRawMessage(msg)); } getChannel(channelName: string): T { @@ -236,8 +246,8 @@ export class ChannelClient implements IChannelClient, IDisposable { private requestPromise(channelName: string, name: string, arg: any): TPromise { const id = this.lastRequestId++; - const type = MessageType.RequestPromise; - const request = { raw: { id, type, channelName, name, arg } }; + const type = RequestType.Promise; + const request: IRequest = { raw: { id, type, channelName, name, arg } }; const activeRequest = this.state === State.Uninitialized ? this.bufferRequest(request) @@ -255,8 +265,9 @@ export class ChannelClient implements IChannelClient, IDisposable { private requestEvent(channelName: string, name: string, arg: any): Event { const id = this.lastRequestId++; - const type = MessageType.RequestEventListen; - const request = { raw: { id, type, channelName, name, arg } }; + const type = RequestType.EventListen; + const raw: IRawRequest = { id, type, channelName, name, arg }; + const request: IRequest = { raw }; let uninitializedPromise: TPromise | null = null; const emitter = new Emitter({ @@ -264,7 +275,7 @@ export class ChannelClient implements IChannelClient, IDisposable { uninitializedPromise = this.whenInitialized(); uninitializedPromise.then(() => { uninitializedPromise = null; - this.send(request.raw); + this.sendRequest(request.raw); }); }, onLastListenerRemove: () => { @@ -272,12 +283,12 @@ export class ChannelClient implements IChannelClient, IDisposable { uninitializedPromise.cancel(); uninitializedPromise = null; } else { - this.send({ id, type: MessageType.RequestEventDispose }); + this.sendRequest({ id, type: RequestType.EventDispose }); } } }); - this.handlers[id] = response => emitter.fire(response.data); + this.handlers[id] = (response: IRawEventFireResponse) => emitter.fire(response.data); return emitter.event; } @@ -287,12 +298,12 @@ export class ChannelClient implements IChannelClient, IDisposable { return new TPromise((c, e) => { this.handlers[id] = response => { switch (response.type) { - case MessageType.ResponsePromiseSuccess: + case ResponseType.PromiseSuccess: delete this.handlers[id]; c(response.data); break; - case MessageType.ResponsePromiseError: + case ResponseType.PromiseError: delete this.handlers[id]; const error = new Error(response.data.message); (error).stack = response.data.stack; @@ -300,16 +311,16 @@ export class ChannelClient implements IChannelClient, IDisposable { e(error); break; - case MessageType.ResponsePromiseErrorObj: + case ResponseType.PromiseErrorObj: delete this.handlers[id]; e(response.data); break; } }; - this.send(request.raw); + this.sendRequest(request.raw); }, - () => this.send({ id, type: MessageType.RequestPromiseCancel })); + () => this.sendRequest({ id, type: RequestType.PromiseCancel })); } private bufferRequest(request: IRequest): Promise { @@ -344,12 +355,16 @@ export class ChannelClient implements IChannelClient, IDisposable { }); } - private onMessage(response: IRawResponse): void { - if (!isResponse(response.type)) { + private onRawMessage(message: Buffer): void { + this.onResponse(JSON.parse(message.toString())); + } + + private onResponse(response: IRawResponse): void { + if (!isResponse(response)) { return; } - if (this.state === State.Uninitialized && response.type === MessageType.ResponseInitialize) { + if (response.type === ResponseType.Initialize) { this.state = State.Idle; this._onDidInitialize.fire(); this.bufferedRequests.forEach(r => r.flush && r.flush()); @@ -363,9 +378,13 @@ export class ChannelClient implements IChannelClient, IDisposable { } } - private send(raw: IRawRequest) { + private sendRequest(request: IRawRequest) { + this.sendRawMessage(Buffer.from(JSON.stringify(request))); + } + + private sendRawMessage(message: Buffer) { try { - this.protocol.send(raw); + this.protocol.send(message); } catch (err) { // noop } @@ -410,13 +429,14 @@ export class IPCServer implements IChannelServer, IRoutingChannelClient, IDispos onDidClientConnect(({ protocol, onDidClientDisconnect }) => { const onFirstMessage = once(protocol.onMessage); - onFirstMessage(id => { + onFirstMessage(rawId => { const channelServer = new ChannelServer(protocol); const channelClient = new ChannelClient(protocol); Object.keys(this.channels) .forEach(name => channelServer.registerChannel(name, this.channels[name])); + const id = rawId.toString(); this.channelClients[id] = channelClient; this.onClientAdded.fire(id); @@ -492,7 +512,7 @@ export class IPCClient implements IChannelClient, IChannelServer, IDisposable { private channelServer: ChannelServer; constructor(protocol: IMessagePassingProtocol, id: string) { - protocol.send(id); + protocol.send(Buffer.from(id)); this.channelClient = new ChannelClient(protocol); this.channelServer = new ChannelServer(protocol); } diff --git a/src/vs/base/parts/ipc/electron-browser/ipc.electron-browser.ts b/src/vs/base/parts/ipc/electron-browser/ipc.electron-browser.ts index 7e3ce8ddd1e..85928ffbe7c 100644 --- a/src/vs/base/parts/ipc/electron-browser/ipc.electron-browser.ts +++ b/src/vs/base/parts/ipc/electron-browser/ipc.electron-browser.ts @@ -11,7 +11,7 @@ import { ipcRenderer } from 'electron'; export class Client extends IPCClient { private static createProtocol(): Protocol { - const onMessage = fromNodeEventEmitter(ipcRenderer, 'ipc:message', (_, message) => message); + const onMessage = fromNodeEventEmitter(ipcRenderer, 'ipc:message', (_, message: string) => message); ipcRenderer.send('ipc:hello'); return new Protocol(ipcRenderer, onMessage); } diff --git a/src/vs/base/parts/ipc/electron-main/ipc.electron-main.ts b/src/vs/base/parts/ipc/electron-main/ipc.electron-main.ts index af67f10d6ca..9e53b78b98f 100644 --- a/src/vs/base/parts/ipc/electron-main/ipc.electron-main.ts +++ b/src/vs/base/parts/ipc/electron-main/ipc.electron-main.ts @@ -17,8 +17,8 @@ interface IIPCEvent { message: string; } -function createScopedOnMessageEvent(senderId: number): Event { - const onMessage = fromNodeEventEmitter(ipcMain, 'ipc:message', (event, message) => ({ event, message })); +function createScopedOnMessageEvent(senderId: number): Event { + const onMessage = fromNodeEventEmitter(ipcMain, 'ipc:message', (event, message: string) => ({ event, message })); const onMessageFromSender = filterEvent(onMessage, ({ event }) => event.sender.getId() === senderId); return mapEvent(onMessageFromSender, ({ message }) => message); } diff --git a/src/vs/base/parts/ipc/node/ipc.cp.ts b/src/vs/base/parts/ipc/node/ipc.cp.ts index 1221c2c7dfa..65083397bf4 100644 --- a/src/vs/base/parts/ipc/node/ipc.cp.ts +++ b/src/vs/base/parts/ipc/node/ipc.cp.ts @@ -13,11 +13,16 @@ import { createQueuedSender } from 'vs/base/node/processes'; import { ChannelServer as IPCServer, ChannelClient as IPCClient, IChannelClient, IChannel } from 'vs/base/parts/ipc/common/ipc'; import { isRemoteConsoleLog, log } from 'vs/base/node/console'; +/** + * This implementation doesn't perform well since it uses base64 encoding for buffers. + * We should move all implementations to use named ipc.net, so we stop depending on cp.fork. + */ + export class Server extends IPCServer { constructor() { super({ - send: r => { try { process.send(r); } catch (e) { /* not much to do */ } }, - onMessage: fromNodeEventEmitter(process, 'message', msg => msg) + send: r => { try { process.send(r.toString('base64')); } catch (e) { /* not much to do */ } }, + onMessage: fromNodeEventEmitter(process, 'message', msg => Buffer.from(msg, 'base64')) }); process.once('disconnect', () => this.dispose()); @@ -185,7 +190,7 @@ export class Client implements IChannelClient, IDisposable { this.child = fork(this.modulePath, args, forkOpts); - const onMessageEmitter = new Emitter(); + const onMessageEmitter = new Emitter(); const onRawMessage = fromNodeEventEmitter(this.child, 'message', msg => msg); onRawMessage(msg => { @@ -197,11 +202,11 @@ export class Client implements IChannelClient, IDisposable { } // Anything else goes to the outside - onMessageEmitter.fire(msg); + onMessageEmitter.fire(Buffer.from(msg, 'base64')); }); const sender = this.options.useQueue ? createQueuedSender(this.child) : this.child; - const send = r => this.child && this.child.connected && sender.send(r); + const send = (r: Buffer) => this.child && this.child.connected && sender.send(r.toString('base64')); const onMessage = onMessageEmitter.event; const protocol = { send, onMessage }; diff --git a/src/vs/base/parts/ipc/node/ipc.net.ts b/src/vs/base/parts/ipc/node/ipc.net.ts index e82503e1eb0..dc592860c30 100644 --- a/src/vs/base/parts/ipc/node/ipc.net.ts +++ b/src/vs/base/parts/ipc/node/ipc.net.ts @@ -25,9 +25,17 @@ export function generateRandomPipeName(): string { } } +/** + * A message has the following format: + * + * [bodyLen|message] + * [header^|data^^^] + * [u32be^^|buffer^] + */ + export class Protocol implements IDisposable, IMessagePassingProtocol { - private static readonly _headerLen = 5; + private static readonly _headerLen = 4; private _isDisposed: boolean; private _chunks: Buffer[]; @@ -37,8 +45,8 @@ export class Protocol implements IDisposable, IMessagePassingProtocol { private _socketEndListener: () => void; private _socketCloseListener: () => void; - private _onMessage = new Emitter(); - readonly onMessage: Event = this._onMessage.event; + private _onMessage = new Emitter(); + readonly onMessage: Event = this._onMessage.event; private _onClose = new Emitter(); readonly onClose: Event = this._onClose.event; @@ -51,7 +59,6 @@ export class Protocol implements IDisposable, IMessagePassingProtocol { const state = { readHead: true, - bodyIsJson: false, bodyLen: -1, }; @@ -68,8 +75,7 @@ export class Protocol implements IDisposable, IMessagePassingProtocol { if (totalLength >= Protocol._headerLen) { const all = Buffer.concat(this._chunks); - state.bodyIsJson = all.readInt8(0) === 1; - state.bodyLen = all.readInt32BE(1); + state.bodyLen = all.readUInt32BE(0); state.readHead = false; const rest = all.slice(Protocol._headerLen); @@ -87,21 +93,17 @@ export class Protocol implements IDisposable, IMessagePassingProtocol { if (totalLength >= state.bodyLen) { const all = Buffer.concat(this._chunks); - let message = all.toString('utf8', 0, state.bodyLen); - if (state.bodyIsJson) { - message = JSON.parse(message); - } + const buffer = all.slice(0, state.bodyLen); - // ensure the public getBuffer returns a valid value if invoked from the event listeners + // ensure the getBuffer returns a valid value if invoked from the event listeners const rest = all.slice(state.bodyLen); totalLength = rest.length; this._chunks = [rest]; - state.bodyIsJson = false; state.bodyLen = -1; state.readHead = true; - this._onMessage.fire(message); + this._onMessage.fire(buffer); if (this._isDisposed) { // check if an event listener lead to our disposal @@ -145,7 +147,7 @@ export class Protocol implements IDisposable, IMessagePassingProtocol { _socket.once('close', this._socketCloseListener); } - public dispose(): void { + dispose(): void { this._isDisposed = true; this._firstChunkTimer.dispose(); this._socket.removeListener('data', this._socketDataListener); @@ -153,30 +155,18 @@ export class Protocol implements IDisposable, IMessagePassingProtocol { this._socket.removeListener('close', this._socketCloseListener); } - public end(): void { + end(): void { this._socket.end(); } - public getBuffer(): Buffer { + getBuffer(): Buffer { return Buffer.concat(this._chunks); } - public send(message: any): void { - - // [bodyIsJson|bodyLen|message] - // |^header^^^^^^^^^^^|^data^^] - + send(buffer: Buffer): void { const header = Buffer.alloc(Protocol._headerLen); - - // ensure string - if (typeof message !== 'string') { - message = JSON.stringify(message); - header.writeInt8(1, 0, true); - } - const data = Buffer.from(message); - header.writeInt32BE(data.length, 1, true); - - this._writeSoon(header, data); + header.writeUInt32BE(buffer.length, 0, true); + this._writeSoon(header, buffer); } private _writeBuffer = new class { @@ -241,7 +231,7 @@ export class Server extends IPCServer { export class Client extends IPCClient { - public static fromSocket(socket: Socket, id: string): Client { + static fromSocket(socket: Socket, id: string): Client { return new Client(new Protocol(socket), id); } diff --git a/src/vs/base/parts/ipc/test/node/ipc.net.test.ts b/src/vs/base/parts/ipc/test/node/ipc.net.test.ts index eb6ddffba02..4d65c7e1091 100644 --- a/src/vs/base/parts/ipc/test/node/ipc.net.test.ts +++ b/src/vs/base/parts/ipc/test/node/ipc.net.test.ts @@ -49,18 +49,20 @@ suite('IPC, Socket Protocol', () => { return new TPromise(resolve => { const sub = b.onMessage(data => { sub.dispose(); - assert.equal(data, 'foobarfarboo'); + assert.equal(data.toString(), 'foobarfarboo'); resolve(null); }); - a.send('foobarfarboo'); + a.send(Buffer.from('foobarfarboo')); }).then(() => { return new TPromise(resolve => { const sub = b.onMessage(data => { sub.dispose(); - assert.equal(data, 123); + assert.equal(data.readInt8(0), 123); resolve(null); }); - a.send(123); + const buffer = new Buffer(1); + buffer.writeInt8(123, 0); + a.send(buffer); }); }); }); @@ -78,11 +80,11 @@ suite('IPC, Socket Protocol', () => { data: 'Hello World'.split('') }; - a.send(data); + a.send(Buffer.from(JSON.stringify(data))); return new TPromise(resolve => { b.onMessage(msg => { - assert.deepEqual(msg, data); + assert.deepEqual(JSON.parse(msg.toString()), data); resolve(null); }); }); @@ -100,7 +102,7 @@ suite('IPC, Socket Protocol', () => { assert.equal(stream.listenerCount('end'), 2); receiver1.onMessage((msg) => { - assert.equal(msg.value, 1); + assert.equal(JSON.parse(msg.toString()).value, 1); let buffer = receiver1.getBuffer(); receiver1.dispose(); @@ -110,15 +112,15 @@ suite('IPC, Socket Protocol', () => { const receiver2 = new Protocol(stream, buffer); receiver2.onMessage((msg) => { - assert.equal(msg.value, 2); + assert.equal(JSON.parse(msg.toString()).value, 2); resolve(void 0); }); }); const msg1 = { value: 1 }; const msg2 = { value: 2 }; - sender.send(msg1); - sender.send(msg2); + sender.send(Buffer.from(JSON.stringify(msg1))); + sender.send(Buffer.from(JSON.stringify(msg2))); return result; }); diff --git a/src/vs/workbench/common/extensionHostProtocol.ts b/src/vs/workbench/common/extensionHostProtocol.ts new file mode 100644 index 00000000000..d42efb9a53a --- /dev/null +++ b/src/vs/workbench/common/extensionHostProtocol.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. + *--------------------------------------------------------------------------------------------*/ + +'use strict'; + +export enum MessageType { + Initialized, + Ready, + Terminate +} + +export function createMessageOfType(type: MessageType): Buffer { + const result = new Buffer(1); + + switch (type) { + case MessageType.Initialized: result.writeUInt8(1, 0); break; + case MessageType.Ready: result.writeUInt8(2, 0); break; + case MessageType.Terminate: result.writeUInt8(3, 0); break; + } + + return result; +} + +export function isMessageOfType(message: Buffer, type: MessageType): boolean { + if (message.length !== 1) { + return false; + } + + switch (message.readUInt8(0)) { + case 1: return type === MessageType.Initialized; + case 2: return type === MessageType.Ready; + case 3: return type === MessageType.Terminate; + default: return false; + } +} \ No newline at end of file diff --git a/src/vs/workbench/node/extensionHostProcess.ts b/src/vs/workbench/node/extensionHostProcess.ts index d8f7d90adf3..75fa349e619 100644 --- a/src/vs/workbench/node/extensionHostProcess.ts +++ b/src/vs/workbench/node/extensionHostProcess.ts @@ -12,6 +12,7 @@ import { IMessagePassingProtocol } from 'vs/base/parts/ipc/common/ipc'; import { Protocol } from 'vs/base/parts/ipc/node/ipc.net'; import { createConnection } from 'net'; import { Event, filterEvent } from 'vs/base/common/event'; +import { createMessageOfType, MessageType, isMessageOfType } from 'vs/workbench/common/extensionHostProtocol'; // With Electron 2.x and node.js 8.x the "natives" module // can cause a native crash (see https://github.com/nodejs/node/issues/19891 and @@ -61,7 +62,7 @@ function createExtHostProtocol(): Promise { private _terminating = false; readonly onMessage: Event = filterEvent(protocol.onMessage, msg => { - if (msg.type !== '__$terminate') { + if (!isMessageOfType(msg, MessageType.Terminate)) { return true; } this._terminating = true; @@ -85,7 +86,7 @@ function connectToRenderer(protocol: IMessagePassingProtocol): Promise { first.dispose(); - const initData = JSON.parse(raw); + const initData = JSON.parse(raw.toString()); // Print a console message when rejection isn't handled within N seconds. For details: // see https://nodejs.org/api/process.html#process_event_unhandledrejection @@ -128,13 +129,13 @@ function connectToRenderer(protocol: IMessagePassingProtocol): Promise; @@ -340,13 +341,13 @@ export class ExtensionHostProcessWorker implements IExtensionHostStarter { const disposable = protocol.onMessage(msg => { - if (msg === 'ready') { + if (isMessageOfType(msg, MessageType.Ready)) { // 1) Extension Host is ready to receive messages, initialize it - this._createExtHostInitData().then(data => protocol.send(JSON.stringify(data))); + this._createExtHostInitData().then(data => protocol.send(Buffer.from(JSON.stringify(data)))); return; } - if (msg === 'initialized') { + if (isMessageOfType(msg, MessageType.Initialized)) { // 2) Extension Host is initialized clearTimeout(handle); @@ -470,9 +471,7 @@ export class ExtensionHostProcessWorker implements IExtensionHostStarter { // Send the extension host a request to terminate itself // (graceful termination) - protocol.send({ - type: '__$terminate' - }); + protocol.send(createMessageOfType(MessageType.Terminate)); // Give the extension host 60s, after which we will // try to kill the process and release any resources diff --git a/src/vs/workbench/services/extensions/node/rpcProtocol.ts b/src/vs/workbench/services/extensions/node/rpcProtocol.ts index 6830dfa03c8..b37097898e8 100644 --- a/src/vs/workbench/services/extensions/node/rpcProtocol.ts +++ b/src/vs/workbench/services/extensions/node/rpcProtocol.ts @@ -159,12 +159,12 @@ export class RPCProtocol implements IRPCProtocol { } } - private _receiveOneMessage(rawmsg: string): void { + private _receiveOneMessage(rawmsg: Buffer): void { if (this._isDisposed) { return; } - let msg = JSON.parse(rawmsg); + let msg = JSON.parse(rawmsg.toString()); if (this._uriTransformer) { msg = transformIncomingURIs(msg, this._uriTransformer); } @@ -196,10 +196,10 @@ export class RPCProtocol implements IRPCProtocol { if (this._uriTransformer) { r = transformOutgoingURIs(r, this._uriTransformer); } - this._multiplexor.send(MessageFactory.replyOK(callId, r)); + this._multiplexor.send(Buffer.from(MessageFactory.replyOK(callId, r))); }, (err) => { delete this._invokedHandlers[callId]; - this._multiplexor.send(MessageFactory.replyErr(callId, err)); + this._multiplexor.send(Buffer.from(MessageFactory.replyErr(callId, err))); }); } @@ -268,14 +268,14 @@ export class RPCProtocol implements IRPCProtocol { const callId = String(++this._lastMessageId); const result = new LazyPromise(() => { - this._multiplexor.send(MessageFactory.cancel(callId)); + this._multiplexor.send(Buffer.from(MessageFactory.cancel(callId))); }); this._pendingRPCReplies[callId] = result; if (this._uriTransformer) { args = transformOutgoingURIs(args, this._uriTransformer); } - this._multiplexor.send(MessageFactory.request(callId, proxyId, methodName, args)); + this._multiplexor.send(Buffer.from(MessageFactory.request(callId, proxyId, methodName, args))); return result; } } @@ -290,28 +290,41 @@ class RPCMultiplexer { private readonly _protocol: IMessagePassingProtocol; private readonly _sendAccumulatedBound: () => void; - private _messagesToSend: string[]; + private _messagesToSend: Buffer[]; - constructor(protocol: IMessagePassingProtocol, onMessage: (msg: string) => void) { + constructor(protocol: IMessagePassingProtocol, onMessage: (msg: Buffer) => void) { this._protocol = protocol; this._sendAccumulatedBound = this._sendAccumulated.bind(this); this._messagesToSend = []; this._protocol.onMessage(data => { - for (let i = 0, len = data.length; i < len; i++) { - onMessage(data[i]); + let i = 0; + + while (i < data.length) { + const size = data.readUInt32BE(i); + onMessage(data.slice(i + 4, i + 4 + size)); + i += 4 + size; } }); } private _sendAccumulated(): void { - const tmp = this._messagesToSend; + const size = this._messagesToSend.reduce((r, b) => r + 4 + b.byteLength, 0); + const buffer = new Buffer(size); + let i = 0; + + for (const msg of this._messagesToSend) { + buffer.writeUInt32BE(msg.byteLength, i); + msg.copy(buffer, i + 4); + i += 4 + msg.byteLength; + } + this._messagesToSend = []; - this._protocol.send(tmp); + this._protocol.send(buffer); } - public send(msg: string): void { + public send(msg: Buffer): void { if (this._messagesToSend.length === 0) { process.nextTick(this._sendAccumulatedBound); } From ebe2979d0c05a2914132106d2f4ea6aabcfe301f Mon Sep 17 00:00:00 2001 From: isidor Date: Mon, 20 Aug 2018 15:47:06 +0200 Subject: [PATCH 0993/1276] debugService: run task return a success boolean --- .../debug/electron-browser/debugService.ts | 24 +++++++++++-------- 1 file changed, 14 insertions(+), 10 deletions(-) diff --git a/src/vs/workbench/parts/debug/electron-browser/debugService.ts b/src/vs/workbench/parts/debug/electron-browser/debugService.ts index 4c2c1026a84..6499553b46c 100644 --- a/src/vs/workbench/parts/debug/electron-browser/debugService.ts +++ b/src/vs/workbench/parts/debug/electron-browser/debugService.ts @@ -606,9 +606,13 @@ export class DebugService implements IDebugService { } const workspace = launch ? launch.workspace : undefined; - return this.runTask(sessionId, workspace, resolvedConfig.preLaunchTask, resolvedConfig, unresolvedConfig, - () => this.doCreateSession(workspace, { resolved: resolvedConfig, unresolved: unresolvedConfig }, sessionId) - ); + return this.runTask(sessionId, workspace, resolvedConfig.preLaunchTask, resolvedConfig, unresolvedConfig).then(success => { + if (!success) { + return undefined; + } + + return this.doCreateSession(workspace, { resolved: resolvedConfig, unresolved: unresolvedConfig }, sessionId); + }); }, err => { if (err && err.message) { return this.showError(err.message); @@ -798,7 +802,7 @@ export class DebugService implements IDebugService { }); } - private runTask(sessionId: string, root: IWorkspaceFolder, taskId: string | TaskIdentifier, config: IConfig, unresolvedConfig: IConfig, onSuccess: () => TPromise): TPromise { + private runTask(sessionId: string, root: IWorkspaceFolder, taskId: string | TaskIdentifier, config: IConfig, unresolvedConfig: IConfig): TPromise { const debugAnywayAction = new Action('debug.debugAnyway', nls.localize('debugAnyway', "Debug Anyway"), undefined, true, () => { return this.doCreateSession(root, { resolved: config, unresolved: unresolvedConfig }, sessionId); }); @@ -808,7 +812,7 @@ export class DebugService implements IDebugService { const successExitCode = taskSummary && taskSummary.exitCode === 0; const failureExitCode = taskSummary && taskSummary.exitCode !== undefined && taskSummary.exitCode !== 0; if (successExitCode || (errorCount === 0 && !failureExitCode)) { - return onSuccess(); + return true; } const message = errorCount > 1 ? nls.localize('preLaunchTaskErrors', "Build errors have been detected during preLaunchTask '{0}'.", config.preLaunchTask) : @@ -819,9 +823,9 @@ export class DebugService implements IDebugService { return this.panelService.openPanel(Constants.MARKERS_PANEL_ID).then(() => undefined); }); - return this.showError(message, [debugAnywayAction, showErrorsAction]); + return this.showError(message, [debugAnywayAction, showErrorsAction]).then(() => false); }, (err: TaskError) => { - return this.showError(err.message, [debugAnywayAction, this.taskService.configureAction()]); + return this.showError(err.message, [debugAnywayAction, this.taskService.configureAction()]).then(() => false); }); } @@ -894,9 +898,9 @@ export class DebugService implements IDebugService { return this.textFileService.saveAll().then(() => { const unresolvedConfiguration = (session).unresolvedConfiguration; if (session.raw.capabilities.supportsRestartRequest) { - return this.runTask(session.getId(), session.root, session.configuration.postDebugTask, session.configuration, unresolvedConfiguration, - () => this.runTask(session.getId(), session.root, session.configuration.preLaunchTask, session.configuration, unresolvedConfiguration, - () => session.raw.custom('restart', null))); + return this.runTask(session.getId(), session.root, session.configuration.postDebugTask, session.configuration, unresolvedConfiguration) + .then(success => success ? this.runTask(session.getId(), session.root, session.configuration.preLaunchTask, session.configuration, unresolvedConfiguration) + .then(success => success ? session.raw.custom('restart', null) : undefined) : TPromise.as(undefined)); } const focusedSession = this.viewModel.focusedSession; From 287d9621225ced66b72e695af77f3715977f9301 Mon Sep 17 00:00:00 2001 From: Matt Bierner Date: Mon, 20 Aug 2018 12:11:37 +0200 Subject: [PATCH 0994/1276] Fix potential npe on code actions #56501 --- src/vs/editor/contrib/codeAction/codeActionWidget.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/vs/editor/contrib/codeAction/codeActionWidget.ts b/src/vs/editor/contrib/codeAction/codeActionWidget.ts index b680ed6008b..ebf9f659b0f 100644 --- a/src/vs/editor/contrib/codeAction/codeActionWidget.ts +++ b/src/vs/editor/contrib/codeAction/codeActionWidget.ts @@ -30,7 +30,7 @@ export class CodeActionContextMenu { show(fixes: Thenable, at: { x: number; y: number } | Position) { - const actions = fixes.then(value => { + const actions = fixes ? fixes.then(value => { return value.map(action => { return new Action(action.command ? action.command.id : action.title, action.title, undefined, true, () => { return always( @@ -41,10 +41,10 @@ export class CodeActionContextMenu { }).then(actions => { if (!this._editor.getDomNode()) { // cancel when editor went off-dom - return TPromise.wrapError(canceled()); + return TPromise.wrapError(canceled()); } return actions; - }); + }) : TPromise.as([] as Action[]); this._contextMenuService.showContextMenu({ getAnchor: () => { From d039671ad1d0ec35695be60b7ddbe95f73ceb117 Mon Sep 17 00:00:00 2001 From: Matt Bierner Date: Mon, 20 Aug 2018 12:11:46 +0200 Subject: [PATCH 0995/1276] Update js/ts grammars --- .../syntaxes/JavaScript.tmLanguage.json | 193 ++++++++++-------- .../syntaxes/JavaScriptReact.tmLanguage.json | 193 ++++++++++-------- .../syntaxes/TypeScript.tmLanguage.json | 193 ++++++++++-------- .../syntaxes/TypeScriptReact.tmLanguage.json | 193 ++++++++++-------- 4 files changed, 448 insertions(+), 324 deletions(-) diff --git a/extensions/javascript/syntaxes/JavaScript.tmLanguage.json b/extensions/javascript/syntaxes/JavaScript.tmLanguage.json index 2b6ae46fe6d..c22cec229fa 100644 --- a/extensions/javascript/syntaxes/JavaScript.tmLanguage.json +++ b/extensions/javascript/syntaxes/JavaScript.tmLanguage.json @@ -4,7 +4,7 @@ "If you want to provide a fix or improvement, please create a pull request against the original repository.", "Once accepted there, we are happy to receive an update request." ], - "version": "https://github.com/Microsoft/TypeScript-TmLanguage/commit/858d33f03943e4ec040e81cbabbc3f7892157c18", + "version": "https://github.com/Microsoft/TypeScript-TmLanguage/commit/d33674e802be357bff20cf8b0a4c966be54c39c4", "name": "JavaScript (with React support)", "scopeName": "source.js", "patterns": [ @@ -93,6 +93,10 @@ }, { "include": "#export-declaration" + }, + { + "name": "storage.modifier.js", + "match": "(?)\n )) |\n ((async\\s*)?(\n ((<\\s*$)|([\\(]\\s*([\\{\\[]\\s*)?$)) |\n # sure shot arrow functions even if => is on new line\n(\n (<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<])*\\>)*>\\s*)?\n [(]\\s*\n (\n ([)]\\s*:) | # ():\n ((\\.\\.\\.\\s*)?[_$[:alpha:]][_$[:alnum:]]*\\s*:) # [(]param: | [(]...param:\n )\n) |\n(\n [<]\\s*[_$[:alpha:]][_$[:alnum:]]*\\s+extends\\s*[^=>] # < typeparam extends\n) |\n# arrow function possible to detect only with => on same line\n(\n (<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<])*\\>)*>\\s*)? # typeparameters\n \\(\\s*(([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\])|(\\.\\.\\.\\s*[_$[:alpha:]]))([^()]|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\)))*)?\\) # parameters\n (\\s*:\\s*([^<>\\(\\)]|\\<[^<>]+\\>|\\([^\\(\\)]+\\))+)? # return type\n \\s*=> # arrow operator\n)\n ))\n)) |\n# typeannotation is fn type: < | () | (... | (param: | (param, | (param? | (param= | (param) =>\n(:\\s*(\n (<) |\n ([(]\\s*(\n ([)]) |\n (\\.\\.\\.) |\n ([_$[:alnum:]]+\\s*(\n ([:,?=])|\n ([)]\\s*=>)\n ))\n ))\n)) |\n(:\\s*((<\\s*$)|([\\(]\\s*([\\{\\[]\\s*)?$))) |\n(:\\s*(=>|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(<[^<>]*>)|[^<>(),=])+=\\s*(\n ((async\\s+)?(\n (function\\s*[(<*]) |\n (function\\s+) |\n ([_$[:alpha:]][_$[:alnum:]]*\\s*=>)\n )) |\n ((async\\s*)?(\n ((<\\s*$)|([\\(]\\s*([\\{\\[]\\s*)?$)) |\n # sure shot arrow functions even if => is on new line\n(\n (<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<])*\\>)*>\\s*)?\n [(]\\s*\n (\n ([)]\\s*:) | # ():\n ((\\.\\.\\.\\s*)?[_$[:alpha:]][_$[:alnum:]]*\\s*:) # [(]param: | [(]...param:\n )\n) |\n(\n [<]\\s*[_$[:alpha:]][_$[:alnum:]]*\\s+extends\\s*[^=>] # < typeparam extends\n) |\n# arrow function possible to detect only with => on same line\n(\n (<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<])*\\>)*>\\s*)? # typeparameters\n \\(\\s*(([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\])|(\\.\\.\\.\\s*[_$[:alpha:]]))([^()]|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\)))*)?\\) # parameters\n (\\s*:\\s*([^<>\\(\\)]|\\<[^<>]+\\>|\\([^\\(\\)]+\\))+)? # return type\n \\s*=> # arrow operator\n)\n ))\n)))", + "captures": { + "1": { + "name": "meta.definition.property.js entity.name.function.js" }, - { - "include": "#string" - }, - { - "include": "#array-literal" - }, - { - "include": "#numeric-literal" - }, - { - "include": "#comment" - }, - { - "match": "(?x)([_$[:alpha:]][_$[:alnum:]]*)(\\?)?(?=(\\?\\s*)?\\s*\n# function assignment |\n(=\\s*(\n ((async\\s+)?(\n (function\\s*[(<*]) |\n (function\\s+) |\n ([_$[:alpha:]][_$[:alnum:]]*\\s*=>)\n )) |\n ((async\\s*)?(\n ((<\\s*$)|([\\(]\\s*([\\{\\[]\\s*)?$)) |\n # sure shot arrow functions even if => is on new line\n(\n (<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<])*\\>)*>\\s*)?\n [(]\\s*\n (\n ([)]\\s*:) | # ():\n ((\\.\\.\\.\\s*)?[_$[:alpha:]][_$[:alnum:]]*\\s*:) # [(]param: | [(]...param:\n )\n) |\n(\n [<]\\s*[_$[:alpha:]][_$[:alnum:]]*\\s+extends\\s*[^=>] # < typeparam extends\n) |\n# arrow function possible to detect only with => on same line\n(\n (<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<])*\\>)*>\\s*)? # typeparameters\n \\(\\s*(([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\])|(\\.\\.\\.\\s*[_$[:alpha:]]))([^()]|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\)))*)?\\) # parameters\n (\\s*:\\s*([^<>\\(\\)]|\\<[^<>]+\\>|\\([^\\(\\)]+\\))+)? # return type\n \\s*=> # arrow operator\n)\n ))\n)) |\n# typeannotation is fn type: < | () | (... | (param: | (param, | (param? | (param= | (param) =>\n(:\\s*(\n (<) |\n ([(]\\s*(\n ([)]) |\n (\\.\\.\\.) |\n ([_$[:alnum:]]+\\s*(\n ([:,?=])|\n ([)]\\s*=>)\n ))\n ))\n)) |\n(:\\s*((<\\s*$)|([\\(]\\s*([\\{\\[]\\s*)?$))) |\n(:\\s*(=>|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(<[^<>]*>)|[^<>(),=])+=\\s*(\n ((async\\s+)?(\n (function\\s*[(<*]) |\n (function\\s+) |\n ([_$[:alpha:]][_$[:alnum:]]*\\s*=>)\n )) |\n ((async\\s*)?(\n ((<\\s*$)|([\\(]\\s*([\\{\\[]\\s*)?$)) |\n # sure shot arrow functions even if => is on new line\n(\n (<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<])*\\>)*>\\s*)?\n [(]\\s*\n (\n ([)]\\s*:) | # ():\n ((\\.\\.\\.\\s*)?[_$[:alpha:]][_$[:alnum:]]*\\s*:) # [(]param: | [(]...param:\n )\n) |\n(\n [<]\\s*[_$[:alpha:]][_$[:alnum:]]*\\s+extends\\s*[^=>] # < typeparam extends\n) |\n# arrow function possible to detect only with => on same line\n(\n (<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<])*\\>)*>\\s*)? # typeparameters\n \\(\\s*(([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\])|(\\.\\.\\.\\s*[_$[:alpha:]]))([^()]|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\)))*)?\\) # parameters\n (\\s*:\\s*([^<>\\(\\)]|\\<[^<>]+\\>|\\([^\\(\\)]+\\))+)? # return type\n \\s*=> # arrow operator\n)\n ))\n)))", - "captures": { - "1": { - "name": "meta.definition.property.js entity.name.function.js" - }, - "2": { - "name": "keyword.operator.optional.js" - } - } - }, - { - "name": "meta.definition.property.js variable.object.property.js", - "match": "[_$[:alpha:]][_$[:alnum:]]*" - }, - { - "name": "keyword.operator.optional.js", - "match": "\\?" + "2": { + "name": "keyword.operator.optional.js" } - ] + } + }, + { + "name": "meta.definition.property.js variable.object.property.js", + "match": "[_$[:alpha:]][_$[:alnum:]]*" + }, + { + "name": "keyword.operator.optional.js", + "match": "\\?" } ] }, @@ -1107,21 +1113,24 @@ }, "function-declaration": { "name": "meta.function.js", - "begin": "(?\\,\\.\\[=]|&(?!&)|\\|(?!\\|)))))([^<>\\(]|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(?<==)\\>|\\<\\s*(((keyof|infer)\\s+)|(([_$[:alpha:]][_$[:alnum:]]*|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\])|(\\'[^\\']*\\')|(\\\"[^\\\"]*\\\")|(\\`[^\\`]*\\`))(?=\\s*([\\<\\>\\,\\.\\[=]|&(?!&)|\\|(?!\\|)))))([^<>\\(]|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(?<==)\\>)*(?!=)\\>)*(?!=)>\\s*)?\\()", - "end": "(?<=\\))(?!(([_$[:alpha:]][_$[:alnum:]]*\\s*\\??\\.\\s*)*|(\\??\\.\\s*)?)([_$[:alpha:]][_$[:alnum:]]*)\\s*(\\?\\.\\s*)?(<\\s*(((keyof|infer)\\s+)|(([_$[:alpha:]][_$[:alnum:]]*|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\])|(\\'[^\\']*\\')|(\\\"[^\\\"]*\\\")|(\\`[^\\`]*\\`))(?=\\s*([\\<\\>\\,\\.\\[=]|&(?!&)|\\|(?!\\|)))))([^<>\\(]|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(?<==)\\>|\\<\\s*(((keyof|infer)\\s+)|(([_$[:alpha:]][_$[:alnum:]]*|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\])|(\\'[^\\']*\\')|(\\\"[^\\\"]*\\\")|(\\`[^\\`]*\\`))(?=\\s*([\\<\\>\\,\\.\\[=]|&(?!&)|\\|(?!\\|)))))([^<>\\(]|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(?<==)\\>)*(?!=)\\>)*(?!=)>\\s*)?\\()", + "begin": "(?=(([_$[:alpha:]][_$[:alnum:]]*\\s*\\??\\.\\s*)*|(\\??\\.\\s*)?)([_$[:alpha:]][_$[:alnum:]]*)\\s*(\\?\\.\\s*)?(<\\s*(((keyof|infer)\\s+)|(\\*(?=\\s*[,>]))|(([_$[:alpha:]][_$[:alnum:]]*|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\])|(\\'[^\\']*\\')|(\\\"[^\\\"]*\\\")|(\\`[^\\`]*\\`))(?=\\s*([\\<\\>\\,\\.\\[]|=>|&(?!&)|\\|(?!\\|)))))([^<>\\(]|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(?<==)\\>|\\<\\s*(((keyof|infer)\\s+)|(\\*(?=\\s*[,>]))|(([_$[:alpha:]][_$[:alnum:]]*|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\])|(\\'[^\\']*\\')|(\\\"[^\\\"]*\\\")|(\\`[^\\`]*\\`))(?=\\s*([\\<\\>\\,\\.\\[]|=>|&(?!&)|\\|(?!\\|)))))([^<>\\(]|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(?<==)\\>)*(?!=)\\>)*(?!=)>\\s*)?\\()", + "end": "(?<=\\))(?!(([_$[:alpha:]][_$[:alnum:]]*\\s*\\??\\.\\s*)*|(\\??\\.\\s*)?)([_$[:alpha:]][_$[:alnum:]]*)\\s*(\\?\\.\\s*)?(<\\s*(((keyof|infer)\\s+)|(\\*(?=\\s*[,>]))|(([_$[:alpha:]][_$[:alnum:]]*|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\])|(\\'[^\\']*\\')|(\\\"[^\\\"]*\\\")|(\\`[^\\`]*\\`))(?=\\s*([\\<\\>\\,\\.\\[]|=>|&(?!&)|\\|(?!\\|)))))([^<>\\(]|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(?<==)\\>|\\<\\s*(((keyof|infer)\\s+)|(\\*(?=\\s*[,>]))|(([_$[:alpha:]][_$[:alnum:]]*|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\])|(\\'[^\\']*\\')|(\\\"[^\\\"]*\\\")|(\\`[^\\`]*\\`))(?=\\s*([\\<\\>\\,\\.\\[]|=>|&(?!&)|\\|(?!\\|)))))([^<>\\(]|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(?<==)\\>)*(?!=)\\>)*(?!=)>\\s*)?\\()", "patterns": [ { "name": "meta.function-call.js", "begin": "(?=(([_$[:alpha:]][_$[:alnum:]]*\\s*\\??\\.\\s*)*|(\\??\\.\\s*)?)([_$[:alpha:]][_$[:alnum:]]*))", - "end": "(?=\\s*(\\?\\.\\s*)?(<\\s*(((keyof|infer)\\s+)|(([_$[:alpha:]][_$[:alnum:]]*|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\])|(\\'[^\\']*\\')|(\\\"[^\\\"]*\\\")|(\\`[^\\`]*\\`))(?=\\s*([\\<\\>\\,\\.\\[=]|&(?!&)|\\|(?!\\|)))))([^<>\\(]|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(?<==)\\>|\\<\\s*(((keyof|infer)\\s+)|(([_$[:alpha:]][_$[:alnum:]]*|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\])|(\\'[^\\']*\\')|(\\\"[^\\\"]*\\\")|(\\`[^\\`]*\\`))(?=\\s*([\\<\\>\\,\\.\\[=]|&(?!&)|\\|(?!\\|)))))([^<>\\(]|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(?<==)\\>)*(?!=)\\>)*(?!=)>\\s*)?\\()", + "end": "(?=\\s*(\\?\\.\\s*)?(<\\s*(((keyof|infer)\\s+)|(\\*(?=\\s*[,>]))|(([_$[:alpha:]][_$[:alnum:]]*|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\])|(\\'[^\\']*\\')|(\\\"[^\\\"]*\\\")|(\\`[^\\`]*\\`))(?=\\s*([\\<\\>\\,\\.\\[]|=>|&(?!&)|\\|(?!\\|)))))([^<>\\(]|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(?<==)\\>|\\<\\s*(((keyof|infer)\\s+)|(\\*(?=\\s*[,>]))|(([_$[:alpha:]][_$[:alnum:]]*|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\])|(\\'[^\\']*\\')|(\\\"[^\\\"]*\\\")|(\\`[^\\`]*\\`))(?=\\s*([\\<\\>\\,\\.\\[]|=>|&(?!&)|\\|(?!\\|)))))([^<>\\(]|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(?<==)\\>)*(?!=)\\>)*(?!=)>\\s*)?\\()", "patterns": [ { "include": "#literal" @@ -3495,6 +3528,10 @@ }, { "include": "#punctuation-comma" + }, + { + "name": "keyword.operator.assignment.js", + "match": "(=)(?!>)" } ] }, @@ -3863,13 +3900,10 @@ "include": "#typeof-operator" }, { - "begin": "(?:([&|])|(=(?!>)))(?=\\s*\\{)", + "begin": "([&|\\*])(?=\\s*\\{)", "beginCaptures": { - "1": { + "0": { "name": "keyword.operator.type.js" - }, - "2": { - "name": "keyword.operator.assignment.js" } }, "end": "(?<=\\})", @@ -3880,13 +3914,10 @@ ] }, { - "begin": "([&|])|(=(?!>))", + "begin": "[&|\\*]", "beginCaptures": { - "1": { + "0": { "name": "keyword.operator.type.js" - }, - "2": { - "name": "keyword.operator.assignment.js" } }, "end": "(?=\\S)" @@ -4018,7 +4049,7 @@ "patterns": [ { "name": "string.template.js", - "begin": "([_$[:alpha:]][_$[:alnum:]]*)\\s*(?=(<\\s*(((keyof|infer)\\s+)|(([_$[:alpha:]][_$[:alnum:]]*|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\])|(\\'[^\\']*\\')|(\\\"[^\\\"]*\\\")|(\\`[^\\`]*\\`))(?=\\s*([\\<\\>\\,\\.\\[=]|&(?!&)|\\|(?!\\|)))))([^<>\\(]|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(?<==)\\>|\\<\\s*(((keyof|infer)\\s+)|(([_$[:alpha:]][_$[:alnum:]]*|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\])|(\\'[^\\']*\\')|(\\\"[^\\\"]*\\\")|(\\`[^\\`]*\\`))(?=\\s*([\\<\\>\\,\\.\\[=]|&(?!&)|\\|(?!\\|)))))([^<>\\(]|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(?<==)\\>)*(?!=)\\>)*(?!=)>\\s*)`)", + "begin": "([_$[:alpha:]][_$[:alnum:]]*)\\s*(?=(<\\s*(((keyof|infer)\\s+)|(\\*(?=\\s*[,>]))|(([_$[:alpha:]][_$[:alnum:]]*|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\])|(\\'[^\\']*\\')|(\\\"[^\\\"]*\\\")|(\\`[^\\`]*\\`))(?=\\s*([\\<\\>\\,\\.\\[]|=>|&(?!&)|\\|(?!\\|)))))([^<>\\(]|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(?<==)\\>|\\<\\s*(((keyof|infer)\\s+)|(\\*(?=\\s*[,>]))|(([_$[:alpha:]][_$[:alnum:]]*|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\])|(\\'[^\\']*\\')|(\\\"[^\\\"]*\\\")|(\\`[^\\`]*\\`))(?=\\s*([\\<\\>\\,\\.\\[]|=>|&(?!&)|\\|(?!\\|)))))([^<>\\(]|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(?<==)\\>)*(?!=)\\>)*(?!=)>\\s*)`)", "beginCaptures": { "1": { "name": "entity.name.function.tagged-template.js" diff --git a/extensions/javascript/syntaxes/JavaScriptReact.tmLanguage.json b/extensions/javascript/syntaxes/JavaScriptReact.tmLanguage.json index 15eeb04d7fc..5da9fb79ada 100644 --- a/extensions/javascript/syntaxes/JavaScriptReact.tmLanguage.json +++ b/extensions/javascript/syntaxes/JavaScriptReact.tmLanguage.json @@ -4,7 +4,7 @@ "If you want to provide a fix or improvement, please create a pull request against the original repository.", "Once accepted there, we are happy to receive an update request." ], - "version": "https://github.com/Microsoft/TypeScript-TmLanguage/commit/858d33f03943e4ec040e81cbabbc3f7892157c18", + "version": "https://github.com/Microsoft/TypeScript-TmLanguage/commit/d33674e802be357bff20cf8b0a4c966be54c39c4", "name": "JavaScript (with React support)", "scopeName": "source.js.jsx", "patterns": [ @@ -93,6 +93,10 @@ }, { "include": "#export-declaration" + }, + { + "name": "storage.modifier.js.jsx", + "match": "(?)\n )) |\n ((async\\s*)?(\n ((<\\s*$)|([\\(]\\s*([\\{\\[]\\s*)?$)) |\n # sure shot arrow functions even if => is on new line\n(\n (<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<])*\\>)*>\\s*)?\n [(]\\s*\n (\n ([)]\\s*:) | # ():\n ((\\.\\.\\.\\s*)?[_$[:alpha:]][_$[:alnum:]]*\\s*:) # [(]param: | [(]...param:\n )\n) |\n(\n [<]\\s*[_$[:alpha:]][_$[:alnum:]]*\\s+extends\\s*[^=>] # < typeparam extends\n) |\n# arrow function possible to detect only with => on same line\n(\n (<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<])*\\>)*>\\s*)? # typeparameters\n \\(\\s*(([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\])|(\\.\\.\\.\\s*[_$[:alpha:]]))([^()]|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\)))*)?\\) # parameters\n (\\s*:\\s*([^<>\\(\\)]|\\<[^<>]+\\>|\\([^\\(\\)]+\\))+)? # return type\n \\s*=> # arrow operator\n)\n ))\n)) |\n# typeannotation is fn type: < | () | (... | (param: | (param, | (param? | (param= | (param) =>\n(:\\s*(\n (<) |\n ([(]\\s*(\n ([)]) |\n (\\.\\.\\.) |\n ([_$[:alnum:]]+\\s*(\n ([:,?=])|\n ([)]\\s*=>)\n ))\n ))\n)) |\n(:\\s*((<\\s*$)|([\\(]\\s*([\\{\\[]\\s*)?$))) |\n(:\\s*(=>|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(<[^<>]*>)|[^<>(),=])+=\\s*(\n ((async\\s+)?(\n (function\\s*[(<*]) |\n (function\\s+) |\n ([_$[:alpha:]][_$[:alnum:]]*\\s*=>)\n )) |\n ((async\\s*)?(\n ((<\\s*$)|([\\(]\\s*([\\{\\[]\\s*)?$)) |\n # sure shot arrow functions even if => is on new line\n(\n (<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<])*\\>)*>\\s*)?\n [(]\\s*\n (\n ([)]\\s*:) | # ():\n ((\\.\\.\\.\\s*)?[_$[:alpha:]][_$[:alnum:]]*\\s*:) # [(]param: | [(]...param:\n )\n) |\n(\n [<]\\s*[_$[:alpha:]][_$[:alnum:]]*\\s+extends\\s*[^=>] # < typeparam extends\n) |\n# arrow function possible to detect only with => on same line\n(\n (<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<])*\\>)*>\\s*)? # typeparameters\n \\(\\s*(([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\])|(\\.\\.\\.\\s*[_$[:alpha:]]))([^()]|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\)))*)?\\) # parameters\n (\\s*:\\s*([^<>\\(\\)]|\\<[^<>]+\\>|\\([^\\(\\)]+\\))+)? # return type\n \\s*=> # arrow operator\n)\n ))\n)))", + "captures": { + "1": { + "name": "meta.definition.property.js.jsx entity.name.function.js.jsx" }, - { - "include": "#string" - }, - { - "include": "#array-literal" - }, - { - "include": "#numeric-literal" - }, - { - "include": "#comment" - }, - { - "match": "(?x)([_$[:alpha:]][_$[:alnum:]]*)(\\?)?(?=(\\?\\s*)?\\s*\n# function assignment |\n(=\\s*(\n ((async\\s+)?(\n (function\\s*[(<*]) |\n (function\\s+) |\n ([_$[:alpha:]][_$[:alnum:]]*\\s*=>)\n )) |\n ((async\\s*)?(\n ((<\\s*$)|([\\(]\\s*([\\{\\[]\\s*)?$)) |\n # sure shot arrow functions even if => is on new line\n(\n (<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<])*\\>)*>\\s*)?\n [(]\\s*\n (\n ([)]\\s*:) | # ():\n ((\\.\\.\\.\\s*)?[_$[:alpha:]][_$[:alnum:]]*\\s*:) # [(]param: | [(]...param:\n )\n) |\n(\n [<]\\s*[_$[:alpha:]][_$[:alnum:]]*\\s+extends\\s*[^=>] # < typeparam extends\n) |\n# arrow function possible to detect only with => on same line\n(\n (<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<])*\\>)*>\\s*)? # typeparameters\n \\(\\s*(([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\])|(\\.\\.\\.\\s*[_$[:alpha:]]))([^()]|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\)))*)?\\) # parameters\n (\\s*:\\s*([^<>\\(\\)]|\\<[^<>]+\\>|\\([^\\(\\)]+\\))+)? # return type\n \\s*=> # arrow operator\n)\n ))\n)) |\n# typeannotation is fn type: < | () | (... | (param: | (param, | (param? | (param= | (param) =>\n(:\\s*(\n (<) |\n ([(]\\s*(\n ([)]) |\n (\\.\\.\\.) |\n ([_$[:alnum:]]+\\s*(\n ([:,?=])|\n ([)]\\s*=>)\n ))\n ))\n)) |\n(:\\s*((<\\s*$)|([\\(]\\s*([\\{\\[]\\s*)?$))) |\n(:\\s*(=>|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(<[^<>]*>)|[^<>(),=])+=\\s*(\n ((async\\s+)?(\n (function\\s*[(<*]) |\n (function\\s+) |\n ([_$[:alpha:]][_$[:alnum:]]*\\s*=>)\n )) |\n ((async\\s*)?(\n ((<\\s*$)|([\\(]\\s*([\\{\\[]\\s*)?$)) |\n # sure shot arrow functions even if => is on new line\n(\n (<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<])*\\>)*>\\s*)?\n [(]\\s*\n (\n ([)]\\s*:) | # ():\n ((\\.\\.\\.\\s*)?[_$[:alpha:]][_$[:alnum:]]*\\s*:) # [(]param: | [(]...param:\n )\n) |\n(\n [<]\\s*[_$[:alpha:]][_$[:alnum:]]*\\s+extends\\s*[^=>] # < typeparam extends\n) |\n# arrow function possible to detect only with => on same line\n(\n (<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<])*\\>)*>\\s*)? # typeparameters\n \\(\\s*(([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\])|(\\.\\.\\.\\s*[_$[:alpha:]]))([^()]|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\)))*)?\\) # parameters\n (\\s*:\\s*([^<>\\(\\)]|\\<[^<>]+\\>|\\([^\\(\\)]+\\))+)? # return type\n \\s*=> # arrow operator\n)\n ))\n)))", - "captures": { - "1": { - "name": "meta.definition.property.js.jsx entity.name.function.js.jsx" - }, - "2": { - "name": "keyword.operator.optional.js.jsx" - } - } - }, - { - "name": "meta.definition.property.js.jsx variable.object.property.js.jsx", - "match": "[_$[:alpha:]][_$[:alnum:]]*" - }, - { - "name": "keyword.operator.optional.js.jsx", - "match": "\\?" + "2": { + "name": "keyword.operator.optional.js.jsx" } - ] + } + }, + { + "name": "meta.definition.property.js.jsx variable.object.property.js.jsx", + "match": "[_$[:alpha:]][_$[:alnum:]]*" + }, + { + "name": "keyword.operator.optional.js.jsx", + "match": "\\?" } ] }, @@ -1107,21 +1113,24 @@ }, "function-declaration": { "name": "meta.function.js.jsx", - "begin": "(?\\,\\.\\[=]|&(?!&)|\\|(?!\\|)))))([^<>\\(]|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(?<==)\\>|\\<\\s*(((keyof|infer)\\s+)|(([_$[:alpha:]][_$[:alnum:]]*|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\])|(\\'[^\\']*\\')|(\\\"[^\\\"]*\\\")|(\\`[^\\`]*\\`))(?=\\s*([\\<\\>\\,\\.\\[=]|&(?!&)|\\|(?!\\|)))))([^<>\\(]|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(?<==)\\>)*(?!=)\\>)*(?!=)>\\s*)?\\()", - "end": "(?<=\\))(?!(([_$[:alpha:]][_$[:alnum:]]*\\s*\\??\\.\\s*)*|(\\??\\.\\s*)?)([_$[:alpha:]][_$[:alnum:]]*)\\s*(\\?\\.\\s*)?(<\\s*(((keyof|infer)\\s+)|(([_$[:alpha:]][_$[:alnum:]]*|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\])|(\\'[^\\']*\\')|(\\\"[^\\\"]*\\\")|(\\`[^\\`]*\\`))(?=\\s*([\\<\\>\\,\\.\\[=]|&(?!&)|\\|(?!\\|)))))([^<>\\(]|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(?<==)\\>|\\<\\s*(((keyof|infer)\\s+)|(([_$[:alpha:]][_$[:alnum:]]*|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\])|(\\'[^\\']*\\')|(\\\"[^\\\"]*\\\")|(\\`[^\\`]*\\`))(?=\\s*([\\<\\>\\,\\.\\[=]|&(?!&)|\\|(?!\\|)))))([^<>\\(]|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(?<==)\\>)*(?!=)\\>)*(?!=)>\\s*)?\\()", + "begin": "(?=(([_$[:alpha:]][_$[:alnum:]]*\\s*\\??\\.\\s*)*|(\\??\\.\\s*)?)([_$[:alpha:]][_$[:alnum:]]*)\\s*(\\?\\.\\s*)?(<\\s*(((keyof|infer)\\s+)|(\\*(?=\\s*[,>]))|(([_$[:alpha:]][_$[:alnum:]]*|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\])|(\\'[^\\']*\\')|(\\\"[^\\\"]*\\\")|(\\`[^\\`]*\\`))(?=\\s*([\\<\\>\\,\\.\\[]|=>|&(?!&)|\\|(?!\\|)))))([^<>\\(]|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(?<==)\\>|\\<\\s*(((keyof|infer)\\s+)|(\\*(?=\\s*[,>]))|(([_$[:alpha:]][_$[:alnum:]]*|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\])|(\\'[^\\']*\\')|(\\\"[^\\\"]*\\\")|(\\`[^\\`]*\\`))(?=\\s*([\\<\\>\\,\\.\\[]|=>|&(?!&)|\\|(?!\\|)))))([^<>\\(]|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(?<==)\\>)*(?!=)\\>)*(?!=)>\\s*)?\\()", + "end": "(?<=\\))(?!(([_$[:alpha:]][_$[:alnum:]]*\\s*\\??\\.\\s*)*|(\\??\\.\\s*)?)([_$[:alpha:]][_$[:alnum:]]*)\\s*(\\?\\.\\s*)?(<\\s*(((keyof|infer)\\s+)|(\\*(?=\\s*[,>]))|(([_$[:alpha:]][_$[:alnum:]]*|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\])|(\\'[^\\']*\\')|(\\\"[^\\\"]*\\\")|(\\`[^\\`]*\\`))(?=\\s*([\\<\\>\\,\\.\\[]|=>|&(?!&)|\\|(?!\\|)))))([^<>\\(]|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(?<==)\\>|\\<\\s*(((keyof|infer)\\s+)|(\\*(?=\\s*[,>]))|(([_$[:alpha:]][_$[:alnum:]]*|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\])|(\\'[^\\']*\\')|(\\\"[^\\\"]*\\\")|(\\`[^\\`]*\\`))(?=\\s*([\\<\\>\\,\\.\\[]|=>|&(?!&)|\\|(?!\\|)))))([^<>\\(]|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(?<==)\\>)*(?!=)\\>)*(?!=)>\\s*)?\\()", "patterns": [ { "name": "meta.function-call.js.jsx", "begin": "(?=(([_$[:alpha:]][_$[:alnum:]]*\\s*\\??\\.\\s*)*|(\\??\\.\\s*)?)([_$[:alpha:]][_$[:alnum:]]*))", - "end": "(?=\\s*(\\?\\.\\s*)?(<\\s*(((keyof|infer)\\s+)|(([_$[:alpha:]][_$[:alnum:]]*|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\])|(\\'[^\\']*\\')|(\\\"[^\\\"]*\\\")|(\\`[^\\`]*\\`))(?=\\s*([\\<\\>\\,\\.\\[=]|&(?!&)|\\|(?!\\|)))))([^<>\\(]|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(?<==)\\>|\\<\\s*(((keyof|infer)\\s+)|(([_$[:alpha:]][_$[:alnum:]]*|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\])|(\\'[^\\']*\\')|(\\\"[^\\\"]*\\\")|(\\`[^\\`]*\\`))(?=\\s*([\\<\\>\\,\\.\\[=]|&(?!&)|\\|(?!\\|)))))([^<>\\(]|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(?<==)\\>)*(?!=)\\>)*(?!=)>\\s*)?\\()", + "end": "(?=\\s*(\\?\\.\\s*)?(<\\s*(((keyof|infer)\\s+)|(\\*(?=\\s*[,>]))|(([_$[:alpha:]][_$[:alnum:]]*|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\])|(\\'[^\\']*\\')|(\\\"[^\\\"]*\\\")|(\\`[^\\`]*\\`))(?=\\s*([\\<\\>\\,\\.\\[]|=>|&(?!&)|\\|(?!\\|)))))([^<>\\(]|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(?<==)\\>|\\<\\s*(((keyof|infer)\\s+)|(\\*(?=\\s*[,>]))|(([_$[:alpha:]][_$[:alnum:]]*|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\])|(\\'[^\\']*\\')|(\\\"[^\\\"]*\\\")|(\\`[^\\`]*\\`))(?=\\s*([\\<\\>\\,\\.\\[]|=>|&(?!&)|\\|(?!\\|)))))([^<>\\(]|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(?<==)\\>)*(?!=)\\>)*(?!=)>\\s*)?\\()", "patterns": [ { "include": "#literal" @@ -3495,6 +3528,10 @@ }, { "include": "#punctuation-comma" + }, + { + "name": "keyword.operator.assignment.js.jsx", + "match": "(=)(?!>)" } ] }, @@ -3863,13 +3900,10 @@ "include": "#typeof-operator" }, { - "begin": "(?:([&|])|(=(?!>)))(?=\\s*\\{)", + "begin": "([&|\\*])(?=\\s*\\{)", "beginCaptures": { - "1": { + "0": { "name": "keyword.operator.type.js.jsx" - }, - "2": { - "name": "keyword.operator.assignment.js.jsx" } }, "end": "(?<=\\})", @@ -3880,13 +3914,10 @@ ] }, { - "begin": "([&|])|(=(?!>))", + "begin": "[&|\\*]", "beginCaptures": { - "1": { + "0": { "name": "keyword.operator.type.js.jsx" - }, - "2": { - "name": "keyword.operator.assignment.js.jsx" } }, "end": "(?=\\S)" @@ -4018,7 +4049,7 @@ "patterns": [ { "name": "string.template.js.jsx", - "begin": "([_$[:alpha:]][_$[:alnum:]]*)\\s*(?=(<\\s*(((keyof|infer)\\s+)|(([_$[:alpha:]][_$[:alnum:]]*|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\])|(\\'[^\\']*\\')|(\\\"[^\\\"]*\\\")|(\\`[^\\`]*\\`))(?=\\s*([\\<\\>\\,\\.\\[=]|&(?!&)|\\|(?!\\|)))))([^<>\\(]|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(?<==)\\>|\\<\\s*(((keyof|infer)\\s+)|(([_$[:alpha:]][_$[:alnum:]]*|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\])|(\\'[^\\']*\\')|(\\\"[^\\\"]*\\\")|(\\`[^\\`]*\\`))(?=\\s*([\\<\\>\\,\\.\\[=]|&(?!&)|\\|(?!\\|)))))([^<>\\(]|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(?<==)\\>)*(?!=)\\>)*(?!=)>\\s*)`)", + "begin": "([_$[:alpha:]][_$[:alnum:]]*)\\s*(?=(<\\s*(((keyof|infer)\\s+)|(\\*(?=\\s*[,>]))|(([_$[:alpha:]][_$[:alnum:]]*|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\])|(\\'[^\\']*\\')|(\\\"[^\\\"]*\\\")|(\\`[^\\`]*\\`))(?=\\s*([\\<\\>\\,\\.\\[]|=>|&(?!&)|\\|(?!\\|)))))([^<>\\(]|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(?<==)\\>|\\<\\s*(((keyof|infer)\\s+)|(\\*(?=\\s*[,>]))|(([_$[:alpha:]][_$[:alnum:]]*|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\])|(\\'[^\\']*\\')|(\\\"[^\\\"]*\\\")|(\\`[^\\`]*\\`))(?=\\s*([\\<\\>\\,\\.\\[]|=>|&(?!&)|\\|(?!\\|)))))([^<>\\(]|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(?<==)\\>)*(?!=)\\>)*(?!=)>\\s*)`)", "beginCaptures": { "1": { "name": "entity.name.function.tagged-template.js.jsx" diff --git a/extensions/typescript-basics/syntaxes/TypeScript.tmLanguage.json b/extensions/typescript-basics/syntaxes/TypeScript.tmLanguage.json index 6f5bc2d554d..9b62ccbf2a7 100644 --- a/extensions/typescript-basics/syntaxes/TypeScript.tmLanguage.json +++ b/extensions/typescript-basics/syntaxes/TypeScript.tmLanguage.json @@ -4,7 +4,7 @@ "If you want to provide a fix or improvement, please create a pull request against the original repository.", "Once accepted there, we are happy to receive an update request." ], - "version": "https://github.com/Microsoft/TypeScript-TmLanguage/commit/858d33f03943e4ec040e81cbabbc3f7892157c18", + "version": "https://github.com/Microsoft/TypeScript-TmLanguage/commit/d33674e802be357bff20cf8b0a4c966be54c39c4", "name": "TypeScript", "scopeName": "source.ts", "patterns": [ @@ -93,6 +93,10 @@ }, { "include": "#export-declaration" + }, + { + "name": "storage.modifier.ts", + "match": "(?)\n )) |\n ((async\\s*)?(\n ((<\\s*$)|((<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<])*\\>)*>\\s*)?[\\(]\\s*([\\{\\[]\\s*)?$)) |\n # sure shot arrow functions even if => is on new line\n(\n (<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<])*\\>)*>\\s*)?\n [(]\\s*\n (\n ([)]\\s*:) | # ():\n ((\\.\\.\\.\\s*)?[_$[:alpha:]][_$[:alnum:]]*\\s*:) # [(]param: | [(]...param:\n )\n) |\n(\n [<]\\s*[_$[:alpha:]][_$[:alnum:]]*\\s+extends\\s*[^=>] # < typeparam extends\n) |\n# arrow function possible to detect only with => on same line\n(\n (<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<])*\\>)*>\\s*)? # typeparameters\n \\(\\s*(([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\])|(\\.\\.\\.\\s*[_$[:alpha:]]))([^()]|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\)))*)?\\) # parameters\n (\\s*:\\s*([^<>\\(\\)]|\\<[^<>]+\\>|\\([^\\(\\)]+\\))+)? # return type\n \\s*=> # arrow operator\n)\n ))\n)) |\n# typeannotation is fn type: < | () | (... | (param: | (param, | (param? | (param= | (param) =>\n(:\\s*(\n (<) |\n ([(]\\s*(\n ([)]) |\n (\\.\\.\\.) |\n ([_$[:alnum:]]+\\s*(\n ([:,?=])|\n ([)]\\s*=>)\n ))\n ))\n)) |\n(:\\s*((<\\s*$)|((<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<])*\\>)*>\\s*)?[\\(]\\s*([\\{\\[]\\s*)?$))) |\n(:\\s*(=>|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(<[^<>]*>)|[^<>(),=])+=\\s*(\n ((async\\s+)?(\n (function\\s*[(<*]) |\n (function\\s+) |\n ([_$[:alpha:]][_$[:alnum:]]*\\s*=>)\n )) |\n ((async\\s*)?(\n ((<\\s*$)|((<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<])*\\>)*>\\s*)?[\\(]\\s*([\\{\\[]\\s*)?$)) |\n # sure shot arrow functions even if => is on new line\n(\n (<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<])*\\>)*>\\s*)?\n [(]\\s*\n (\n ([)]\\s*:) | # ():\n ((\\.\\.\\.\\s*)?[_$[:alpha:]][_$[:alnum:]]*\\s*:) # [(]param: | [(]...param:\n )\n) |\n(\n [<]\\s*[_$[:alpha:]][_$[:alnum:]]*\\s+extends\\s*[^=>] # < typeparam extends\n) |\n# arrow function possible to detect only with => on same line\n(\n (<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<])*\\>)*>\\s*)? # typeparameters\n \\(\\s*(([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\])|(\\.\\.\\.\\s*[_$[:alpha:]]))([^()]|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\)))*)?\\) # parameters\n (\\s*:\\s*([^<>\\(\\)]|\\<[^<>]+\\>|\\([^\\(\\)]+\\))+)? # return type\n \\s*=> # arrow operator\n)\n ))\n)))", + "captures": { + "1": { + "name": "meta.definition.property.ts entity.name.function.ts" }, - { - "include": "#string" - }, - { - "include": "#array-literal" - }, - { - "include": "#numeric-literal" - }, - { - "include": "#comment" - }, - { - "match": "(?x)([_$[:alpha:]][_$[:alnum:]]*)(\\?)?(?=(\\?\\s*)?\\s*\n# function assignment |\n(=\\s*(\n ((async\\s+)?(\n (function\\s*[(<*]) |\n (function\\s+) |\n ([_$[:alpha:]][_$[:alnum:]]*\\s*=>)\n )) |\n ((async\\s*)?(\n ((<\\s*$)|((<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<])*\\>)*>\\s*)?[\\(]\\s*([\\{\\[]\\s*)?$)) |\n # sure shot arrow functions even if => is on new line\n(\n (<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<])*\\>)*>\\s*)?\n [(]\\s*\n (\n ([)]\\s*:) | # ():\n ((\\.\\.\\.\\s*)?[_$[:alpha:]][_$[:alnum:]]*\\s*:) # [(]param: | [(]...param:\n )\n) |\n(\n [<]\\s*[_$[:alpha:]][_$[:alnum:]]*\\s+extends\\s*[^=>] # < typeparam extends\n) |\n# arrow function possible to detect only with => on same line\n(\n (<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<])*\\>)*>\\s*)? # typeparameters\n \\(\\s*(([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\])|(\\.\\.\\.\\s*[_$[:alpha:]]))([^()]|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\)))*)?\\) # parameters\n (\\s*:\\s*([^<>\\(\\)]|\\<[^<>]+\\>|\\([^\\(\\)]+\\))+)? # return type\n \\s*=> # arrow operator\n)\n ))\n)) |\n# typeannotation is fn type: < | () | (... | (param: | (param, | (param? | (param= | (param) =>\n(:\\s*(\n (<) |\n ([(]\\s*(\n ([)]) |\n (\\.\\.\\.) |\n ([_$[:alnum:]]+\\s*(\n ([:,?=])|\n ([)]\\s*=>)\n ))\n ))\n)) |\n(:\\s*((<\\s*$)|((<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<])*\\>)*>\\s*)?[\\(]\\s*([\\{\\[]\\s*)?$))) |\n(:\\s*(=>|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(<[^<>]*>)|[^<>(),=])+=\\s*(\n ((async\\s+)?(\n (function\\s*[(<*]) |\n (function\\s+) |\n ([_$[:alpha:]][_$[:alnum:]]*\\s*=>)\n )) |\n ((async\\s*)?(\n ((<\\s*$)|((<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<])*\\>)*>\\s*)?[\\(]\\s*([\\{\\[]\\s*)?$)) |\n # sure shot arrow functions even if => is on new line\n(\n (<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<])*\\>)*>\\s*)?\n [(]\\s*\n (\n ([)]\\s*:) | # ():\n ((\\.\\.\\.\\s*)?[_$[:alpha:]][_$[:alnum:]]*\\s*:) # [(]param: | [(]...param:\n )\n) |\n(\n [<]\\s*[_$[:alpha:]][_$[:alnum:]]*\\s+extends\\s*[^=>] # < typeparam extends\n) |\n# arrow function possible to detect only with => on same line\n(\n (<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<])*\\>)*>\\s*)? # typeparameters\n \\(\\s*(([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\])|(\\.\\.\\.\\s*[_$[:alpha:]]))([^()]|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\)))*)?\\) # parameters\n (\\s*:\\s*([^<>\\(\\)]|\\<[^<>]+\\>|\\([^\\(\\)]+\\))+)? # return type\n \\s*=> # arrow operator\n)\n ))\n)))", - "captures": { - "1": { - "name": "meta.definition.property.ts entity.name.function.ts" - }, - "2": { - "name": "keyword.operator.optional.ts" - } - } - }, - { - "name": "meta.definition.property.ts variable.object.property.ts", - "match": "[_$[:alpha:]][_$[:alnum:]]*" - }, - { - "name": "keyword.operator.optional.ts", - "match": "\\?" + "2": { + "name": "keyword.operator.optional.ts" } - ] + } + }, + { + "name": "meta.definition.property.ts variable.object.property.ts", + "match": "[_$[:alpha:]][_$[:alnum:]]*" + }, + { + "name": "keyword.operator.optional.ts", + "match": "\\?" } ] }, @@ -1104,21 +1110,24 @@ }, "function-declaration": { "name": "meta.function.ts", - "begin": "(?\\,\\.\\[=]|&(?!&)|\\|(?!\\|)))))([^<>\\(]|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(?<==)\\>|\\<\\s*(((keyof|infer)\\s+)|(([_$[:alpha:]][_$[:alnum:]]*|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\])|(\\'[^\\']*\\')|(\\\"[^\\\"]*\\\")|(\\`[^\\`]*\\`))(?=\\s*([\\<\\>\\,\\.\\[=]|&(?!&)|\\|(?!\\|)))))([^<>\\(]|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(?<==)\\>)*(?!=)\\>)*(?!=)>\\s*)?\\()", - "end": "(?<=\\))(?!(([_$[:alpha:]][_$[:alnum:]]*\\s*\\??\\.\\s*)*|(\\??\\.\\s*)?)([_$[:alpha:]][_$[:alnum:]]*)\\s*(\\?\\.\\s*)?(<\\s*(((keyof|infer)\\s+)|(([_$[:alpha:]][_$[:alnum:]]*|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\])|(\\'[^\\']*\\')|(\\\"[^\\\"]*\\\")|(\\`[^\\`]*\\`))(?=\\s*([\\<\\>\\,\\.\\[=]|&(?!&)|\\|(?!\\|)))))([^<>\\(]|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(?<==)\\>|\\<\\s*(((keyof|infer)\\s+)|(([_$[:alpha:]][_$[:alnum:]]*|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\])|(\\'[^\\']*\\')|(\\\"[^\\\"]*\\\")|(\\`[^\\`]*\\`))(?=\\s*([\\<\\>\\,\\.\\[=]|&(?!&)|\\|(?!\\|)))))([^<>\\(]|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(?<==)\\>)*(?!=)\\>)*(?!=)>\\s*)?\\()", + "begin": "(?=(([_$[:alpha:]][_$[:alnum:]]*\\s*\\??\\.\\s*)*|(\\??\\.\\s*)?)([_$[:alpha:]][_$[:alnum:]]*)\\s*(\\?\\.\\s*)?(<\\s*(((keyof|infer)\\s+)|(\\*(?=\\s*[,>]))|(([_$[:alpha:]][_$[:alnum:]]*|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\])|(\\'[^\\']*\\')|(\\\"[^\\\"]*\\\")|(\\`[^\\`]*\\`))(?=\\s*([\\<\\>\\,\\.\\[]|=>|&(?!&)|\\|(?!\\|)))))([^<>\\(]|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(?<==)\\>|\\<\\s*(((keyof|infer)\\s+)|(\\*(?=\\s*[,>]))|(([_$[:alpha:]][_$[:alnum:]]*|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\])|(\\'[^\\']*\\')|(\\\"[^\\\"]*\\\")|(\\`[^\\`]*\\`))(?=\\s*([\\<\\>\\,\\.\\[]|=>|&(?!&)|\\|(?!\\|)))))([^<>\\(]|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(?<==)\\>)*(?!=)\\>)*(?!=)>\\s*)?\\()", + "end": "(?<=\\))(?!(([_$[:alpha:]][_$[:alnum:]]*\\s*\\??\\.\\s*)*|(\\??\\.\\s*)?)([_$[:alpha:]][_$[:alnum:]]*)\\s*(\\?\\.\\s*)?(<\\s*(((keyof|infer)\\s+)|(\\*(?=\\s*[,>]))|(([_$[:alpha:]][_$[:alnum:]]*|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\])|(\\'[^\\']*\\')|(\\\"[^\\\"]*\\\")|(\\`[^\\`]*\\`))(?=\\s*([\\<\\>\\,\\.\\[]|=>|&(?!&)|\\|(?!\\|)))))([^<>\\(]|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(?<==)\\>|\\<\\s*(((keyof|infer)\\s+)|(\\*(?=\\s*[,>]))|(([_$[:alpha:]][_$[:alnum:]]*|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\])|(\\'[^\\']*\\')|(\\\"[^\\\"]*\\\")|(\\`[^\\`]*\\`))(?=\\s*([\\<\\>\\,\\.\\[]|=>|&(?!&)|\\|(?!\\|)))))([^<>\\(]|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(?<==)\\>)*(?!=)\\>)*(?!=)>\\s*)?\\()", "patterns": [ { "name": "meta.function-call.ts", "begin": "(?=(([_$[:alpha:]][_$[:alnum:]]*\\s*\\??\\.\\s*)*|(\\??\\.\\s*)?)([_$[:alpha:]][_$[:alnum:]]*))", - "end": "(?=\\s*(\\?\\.\\s*)?(<\\s*(((keyof|infer)\\s+)|(([_$[:alpha:]][_$[:alnum:]]*|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\])|(\\'[^\\']*\\')|(\\\"[^\\\"]*\\\")|(\\`[^\\`]*\\`))(?=\\s*([\\<\\>\\,\\.\\[=]|&(?!&)|\\|(?!\\|)))))([^<>\\(]|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(?<==)\\>|\\<\\s*(((keyof|infer)\\s+)|(([_$[:alpha:]][_$[:alnum:]]*|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\])|(\\'[^\\']*\\')|(\\\"[^\\\"]*\\\")|(\\`[^\\`]*\\`))(?=\\s*([\\<\\>\\,\\.\\[=]|&(?!&)|\\|(?!\\|)))))([^<>\\(]|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(?<==)\\>)*(?!=)\\>)*(?!=)>\\s*)?\\()", + "end": "(?=\\s*(\\?\\.\\s*)?(<\\s*(((keyof|infer)\\s+)|(\\*(?=\\s*[,>]))|(([_$[:alpha:]][_$[:alnum:]]*|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\])|(\\'[^\\']*\\')|(\\\"[^\\\"]*\\\")|(\\`[^\\`]*\\`))(?=\\s*([\\<\\>\\,\\.\\[]|=>|&(?!&)|\\|(?!\\|)))))([^<>\\(]|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(?<==)\\>|\\<\\s*(((keyof|infer)\\s+)|(\\*(?=\\s*[,>]))|(([_$[:alpha:]][_$[:alnum:]]*|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\])|(\\'[^\\']*\\')|(\\\"[^\\\"]*\\\")|(\\`[^\\`]*\\`))(?=\\s*([\\<\\>\\,\\.\\[]|=>|&(?!&)|\\|(?!\\|)))))([^<>\\(]|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(?<==)\\>)*(?!=)\\>)*(?!=)>\\s*)?\\()", "patterns": [ { "include": "#literal" @@ -3529,6 +3562,10 @@ }, { "include": "#punctuation-comma" + }, + { + "name": "keyword.operator.assignment.ts", + "match": "(=)(?!>)" } ] }, @@ -3897,13 +3934,10 @@ "include": "#typeof-operator" }, { - "begin": "(?:([&|])|(=(?!>)))(?=\\s*\\{)", + "begin": "([&|\\*])(?=\\s*\\{)", "beginCaptures": { - "1": { + "0": { "name": "keyword.operator.type.ts" - }, - "2": { - "name": "keyword.operator.assignment.ts" } }, "end": "(?<=\\})", @@ -3914,13 +3948,10 @@ ] }, { - "begin": "([&|])|(=(?!>))", + "begin": "[&|\\*]", "beginCaptures": { - "1": { + "0": { "name": "keyword.operator.type.ts" - }, - "2": { - "name": "keyword.operator.assignment.ts" } }, "end": "(?=\\S)" @@ -4052,7 +4083,7 @@ "patterns": [ { "name": "string.template.ts", - "begin": "([_$[:alpha:]][_$[:alnum:]]*)\\s*(?=(<\\s*(((keyof|infer)\\s+)|(([_$[:alpha:]][_$[:alnum:]]*|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\])|(\\'[^\\']*\\')|(\\\"[^\\\"]*\\\")|(\\`[^\\`]*\\`))(?=\\s*([\\<\\>\\,\\.\\[=]|&(?!&)|\\|(?!\\|)))))([^<>\\(]|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(?<==)\\>|\\<\\s*(((keyof|infer)\\s+)|(([_$[:alpha:]][_$[:alnum:]]*|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\])|(\\'[^\\']*\\')|(\\\"[^\\\"]*\\\")|(\\`[^\\`]*\\`))(?=\\s*([\\<\\>\\,\\.\\[=]|&(?!&)|\\|(?!\\|)))))([^<>\\(]|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(?<==)\\>)*(?!=)\\>)*(?!=)>\\s*)`)", + "begin": "([_$[:alpha:]][_$[:alnum:]]*)\\s*(?=(<\\s*(((keyof|infer)\\s+)|(\\*(?=\\s*[,>]))|(([_$[:alpha:]][_$[:alnum:]]*|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\])|(\\'[^\\']*\\')|(\\\"[^\\\"]*\\\")|(\\`[^\\`]*\\`))(?=\\s*([\\<\\>\\,\\.\\[]|=>|&(?!&)|\\|(?!\\|)))))([^<>\\(]|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(?<==)\\>|\\<\\s*(((keyof|infer)\\s+)|(\\*(?=\\s*[,>]))|(([_$[:alpha:]][_$[:alnum:]]*|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\])|(\\'[^\\']*\\')|(\\\"[^\\\"]*\\\")|(\\`[^\\`]*\\`))(?=\\s*([\\<\\>\\,\\.\\[]|=>|&(?!&)|\\|(?!\\|)))))([^<>\\(]|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(?<==)\\>)*(?!=)\\>)*(?!=)>\\s*)`)", "beginCaptures": { "1": { "name": "entity.name.function.tagged-template.ts" diff --git a/extensions/typescript-basics/syntaxes/TypeScriptReact.tmLanguage.json b/extensions/typescript-basics/syntaxes/TypeScriptReact.tmLanguage.json index bb8426dd854..b58cdd088f1 100644 --- a/extensions/typescript-basics/syntaxes/TypeScriptReact.tmLanguage.json +++ b/extensions/typescript-basics/syntaxes/TypeScriptReact.tmLanguage.json @@ -4,7 +4,7 @@ "If you want to provide a fix or improvement, please create a pull request against the original repository.", "Once accepted there, we are happy to receive an update request." ], - "version": "https://github.com/Microsoft/TypeScript-TmLanguage/commit/858d33f03943e4ec040e81cbabbc3f7892157c18", + "version": "https://github.com/Microsoft/TypeScript-TmLanguage/commit/d33674e802be357bff20cf8b0a4c966be54c39c4", "name": "TypeScriptReact", "scopeName": "source.tsx", "patterns": [ @@ -93,6 +93,10 @@ }, { "include": "#export-declaration" + }, + { + "name": "storage.modifier.tsx", + "match": "(?)\n )) |\n ((async\\s*)?(\n ((<\\s*$)|([\\(]\\s*([\\{\\[]\\s*)?$)) |\n # sure shot arrow functions even if => is on new line\n(\n (<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<])*\\>)*>\\s*)?\n [(]\\s*\n (\n ([)]\\s*:) | # ():\n ((\\.\\.\\.\\s*)?[_$[:alpha:]][_$[:alnum:]]*\\s*:) # [(]param: | [(]...param:\n )\n) |\n(\n [<]\\s*[_$[:alpha:]][_$[:alnum:]]*\\s+extends\\s*[^=>] # < typeparam extends\n) |\n# arrow function possible to detect only with => on same line\n(\n (<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<])*\\>)*>\\s*)? # typeparameters\n \\(\\s*(([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\])|(\\.\\.\\.\\s*[_$[:alpha:]]))([^()]|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\)))*)?\\) # parameters\n (\\s*:\\s*([^<>\\(\\)]|\\<[^<>]+\\>|\\([^\\(\\)]+\\))+)? # return type\n \\s*=> # arrow operator\n)\n ))\n)) |\n# typeannotation is fn type: < | () | (... | (param: | (param, | (param? | (param= | (param) =>\n(:\\s*(\n (<) |\n ([(]\\s*(\n ([)]) |\n (\\.\\.\\.) |\n ([_$[:alnum:]]+\\s*(\n ([:,?=])|\n ([)]\\s*=>)\n ))\n ))\n)) |\n(:\\s*((<\\s*$)|([\\(]\\s*([\\{\\[]\\s*)?$))) |\n(:\\s*(=>|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(<[^<>]*>)|[^<>(),=])+=\\s*(\n ((async\\s+)?(\n (function\\s*[(<*]) |\n (function\\s+) |\n ([_$[:alpha:]][_$[:alnum:]]*\\s*=>)\n )) |\n ((async\\s*)?(\n ((<\\s*$)|([\\(]\\s*([\\{\\[]\\s*)?$)) |\n # sure shot arrow functions even if => is on new line\n(\n (<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<])*\\>)*>\\s*)?\n [(]\\s*\n (\n ([)]\\s*:) | # ():\n ((\\.\\.\\.\\s*)?[_$[:alpha:]][_$[:alnum:]]*\\s*:) # [(]param: | [(]...param:\n )\n) |\n(\n [<]\\s*[_$[:alpha:]][_$[:alnum:]]*\\s+extends\\s*[^=>] # < typeparam extends\n) |\n# arrow function possible to detect only with => on same line\n(\n (<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<])*\\>)*>\\s*)? # typeparameters\n \\(\\s*(([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\])|(\\.\\.\\.\\s*[_$[:alpha:]]))([^()]|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\)))*)?\\) # parameters\n (\\s*:\\s*([^<>\\(\\)]|\\<[^<>]+\\>|\\([^\\(\\)]+\\))+)? # return type\n \\s*=> # arrow operator\n)\n ))\n)))", + "captures": { + "1": { + "name": "meta.definition.property.tsx entity.name.function.tsx" }, - { - "include": "#string" - }, - { - "include": "#array-literal" - }, - { - "include": "#numeric-literal" - }, - { - "include": "#comment" - }, - { - "match": "(?x)([_$[:alpha:]][_$[:alnum:]]*)(\\?)?(?=(\\?\\s*)?\\s*\n# function assignment |\n(=\\s*(\n ((async\\s+)?(\n (function\\s*[(<*]) |\n (function\\s+) |\n ([_$[:alpha:]][_$[:alnum:]]*\\s*=>)\n )) |\n ((async\\s*)?(\n ((<\\s*$)|([\\(]\\s*([\\{\\[]\\s*)?$)) |\n # sure shot arrow functions even if => is on new line\n(\n (<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<])*\\>)*>\\s*)?\n [(]\\s*\n (\n ([)]\\s*:) | # ():\n ((\\.\\.\\.\\s*)?[_$[:alpha:]][_$[:alnum:]]*\\s*:) # [(]param: | [(]...param:\n )\n) |\n(\n [<]\\s*[_$[:alpha:]][_$[:alnum:]]*\\s+extends\\s*[^=>] # < typeparam extends\n) |\n# arrow function possible to detect only with => on same line\n(\n (<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<])*\\>)*>\\s*)? # typeparameters\n \\(\\s*(([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\])|(\\.\\.\\.\\s*[_$[:alpha:]]))([^()]|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\)))*)?\\) # parameters\n (\\s*:\\s*([^<>\\(\\)]|\\<[^<>]+\\>|\\([^\\(\\)]+\\))+)? # return type\n \\s*=> # arrow operator\n)\n ))\n)) |\n# typeannotation is fn type: < | () | (... | (param: | (param, | (param? | (param= | (param) =>\n(:\\s*(\n (<) |\n ([(]\\s*(\n ([)]) |\n (\\.\\.\\.) |\n ([_$[:alnum:]]+\\s*(\n ([:,?=])|\n ([)]\\s*=>)\n ))\n ))\n)) |\n(:\\s*((<\\s*$)|([\\(]\\s*([\\{\\[]\\s*)?$))) |\n(:\\s*(=>|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(<[^<>]*>)|[^<>(),=])+=\\s*(\n ((async\\s+)?(\n (function\\s*[(<*]) |\n (function\\s+) |\n ([_$[:alpha:]][_$[:alnum:]]*\\s*=>)\n )) |\n ((async\\s*)?(\n ((<\\s*$)|([\\(]\\s*([\\{\\[]\\s*)?$)) |\n # sure shot arrow functions even if => is on new line\n(\n (<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<])*\\>)*>\\s*)?\n [(]\\s*\n (\n ([)]\\s*:) | # ():\n ((\\.\\.\\.\\s*)?[_$[:alpha:]][_$[:alnum:]]*\\s*:) # [(]param: | [(]...param:\n )\n) |\n(\n [<]\\s*[_$[:alpha:]][_$[:alnum:]]*\\s+extends\\s*[^=>] # < typeparam extends\n) |\n# arrow function possible to detect only with => on same line\n(\n (<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<])*\\>)*>\\s*)? # typeparameters\n \\(\\s*(([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\])|(\\.\\.\\.\\s*[_$[:alpha:]]))([^()]|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\)))*)?\\) # parameters\n (\\s*:\\s*([^<>\\(\\)]|\\<[^<>]+\\>|\\([^\\(\\)]+\\))+)? # return type\n \\s*=> # arrow operator\n)\n ))\n)))", - "captures": { - "1": { - "name": "meta.definition.property.tsx entity.name.function.tsx" - }, - "2": { - "name": "keyword.operator.optional.tsx" - } - } - }, - { - "name": "meta.definition.property.tsx variable.object.property.tsx", - "match": "[_$[:alpha:]][_$[:alnum:]]*" - }, - { - "name": "keyword.operator.optional.tsx", - "match": "\\?" + "2": { + "name": "keyword.operator.optional.tsx" } - ] + } + }, + { + "name": "meta.definition.property.tsx variable.object.property.tsx", + "match": "[_$[:alpha:]][_$[:alnum:]]*" + }, + { + "name": "keyword.operator.optional.tsx", + "match": "\\?" } ] }, @@ -1107,21 +1113,24 @@ }, "function-declaration": { "name": "meta.function.tsx", - "begin": "(?\\,\\.\\[=]|&(?!&)|\\|(?!\\|)))))([^<>\\(]|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(?<==)\\>|\\<\\s*(((keyof|infer)\\s+)|(([_$[:alpha:]][_$[:alnum:]]*|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\])|(\\'[^\\']*\\')|(\\\"[^\\\"]*\\\")|(\\`[^\\`]*\\`))(?=\\s*([\\<\\>\\,\\.\\[=]|&(?!&)|\\|(?!\\|)))))([^<>\\(]|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(?<==)\\>)*(?!=)\\>)*(?!=)>\\s*)?\\()", - "end": "(?<=\\))(?!(([_$[:alpha:]][_$[:alnum:]]*\\s*\\??\\.\\s*)*|(\\??\\.\\s*)?)([_$[:alpha:]][_$[:alnum:]]*)\\s*(\\?\\.\\s*)?(<\\s*(((keyof|infer)\\s+)|(([_$[:alpha:]][_$[:alnum:]]*|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\])|(\\'[^\\']*\\')|(\\\"[^\\\"]*\\\")|(\\`[^\\`]*\\`))(?=\\s*([\\<\\>\\,\\.\\[=]|&(?!&)|\\|(?!\\|)))))([^<>\\(]|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(?<==)\\>|\\<\\s*(((keyof|infer)\\s+)|(([_$[:alpha:]][_$[:alnum:]]*|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\])|(\\'[^\\']*\\')|(\\\"[^\\\"]*\\\")|(\\`[^\\`]*\\`))(?=\\s*([\\<\\>\\,\\.\\[=]|&(?!&)|\\|(?!\\|)))))([^<>\\(]|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(?<==)\\>)*(?!=)\\>)*(?!=)>\\s*)?\\()", + "begin": "(?=(([_$[:alpha:]][_$[:alnum:]]*\\s*\\??\\.\\s*)*|(\\??\\.\\s*)?)([_$[:alpha:]][_$[:alnum:]]*)\\s*(\\?\\.\\s*)?(<\\s*(((keyof|infer)\\s+)|(\\*(?=\\s*[,>]))|(([_$[:alpha:]][_$[:alnum:]]*|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\])|(\\'[^\\']*\\')|(\\\"[^\\\"]*\\\")|(\\`[^\\`]*\\`))(?=\\s*([\\<\\>\\,\\.\\[]|=>|&(?!&)|\\|(?!\\|)))))([^<>\\(]|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(?<==)\\>|\\<\\s*(((keyof|infer)\\s+)|(\\*(?=\\s*[,>]))|(([_$[:alpha:]][_$[:alnum:]]*|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\])|(\\'[^\\']*\\')|(\\\"[^\\\"]*\\\")|(\\`[^\\`]*\\`))(?=\\s*([\\<\\>\\,\\.\\[]|=>|&(?!&)|\\|(?!\\|)))))([^<>\\(]|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(?<==)\\>)*(?!=)\\>)*(?!=)>\\s*)?\\()", + "end": "(?<=\\))(?!(([_$[:alpha:]][_$[:alnum:]]*\\s*\\??\\.\\s*)*|(\\??\\.\\s*)?)([_$[:alpha:]][_$[:alnum:]]*)\\s*(\\?\\.\\s*)?(<\\s*(((keyof|infer)\\s+)|(\\*(?=\\s*[,>]))|(([_$[:alpha:]][_$[:alnum:]]*|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\])|(\\'[^\\']*\\')|(\\\"[^\\\"]*\\\")|(\\`[^\\`]*\\`))(?=\\s*([\\<\\>\\,\\.\\[]|=>|&(?!&)|\\|(?!\\|)))))([^<>\\(]|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(?<==)\\>|\\<\\s*(((keyof|infer)\\s+)|(\\*(?=\\s*[,>]))|(([_$[:alpha:]][_$[:alnum:]]*|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\])|(\\'[^\\']*\\')|(\\\"[^\\\"]*\\\")|(\\`[^\\`]*\\`))(?=\\s*([\\<\\>\\,\\.\\[]|=>|&(?!&)|\\|(?!\\|)))))([^<>\\(]|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(?<==)\\>)*(?!=)\\>)*(?!=)>\\s*)?\\()", "patterns": [ { "name": "meta.function-call.tsx", "begin": "(?=(([_$[:alpha:]][_$[:alnum:]]*\\s*\\??\\.\\s*)*|(\\??\\.\\s*)?)([_$[:alpha:]][_$[:alnum:]]*))", - "end": "(?=\\s*(\\?\\.\\s*)?(<\\s*(((keyof|infer)\\s+)|(([_$[:alpha:]][_$[:alnum:]]*|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\])|(\\'[^\\']*\\')|(\\\"[^\\\"]*\\\")|(\\`[^\\`]*\\`))(?=\\s*([\\<\\>\\,\\.\\[=]|&(?!&)|\\|(?!\\|)))))([^<>\\(]|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(?<==)\\>|\\<\\s*(((keyof|infer)\\s+)|(([_$[:alpha:]][_$[:alnum:]]*|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\])|(\\'[^\\']*\\')|(\\\"[^\\\"]*\\\")|(\\`[^\\`]*\\`))(?=\\s*([\\<\\>\\,\\.\\[=]|&(?!&)|\\|(?!\\|)))))([^<>\\(]|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(?<==)\\>)*(?!=)\\>)*(?!=)>\\s*)?\\()", + "end": "(?=\\s*(\\?\\.\\s*)?(<\\s*(((keyof|infer)\\s+)|(\\*(?=\\s*[,>]))|(([_$[:alpha:]][_$[:alnum:]]*|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\])|(\\'[^\\']*\\')|(\\\"[^\\\"]*\\\")|(\\`[^\\`]*\\`))(?=\\s*([\\<\\>\\,\\.\\[]|=>|&(?!&)|\\|(?!\\|)))))([^<>\\(]|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(?<==)\\>|\\<\\s*(((keyof|infer)\\s+)|(\\*(?=\\s*[,>]))|(([_$[:alpha:]][_$[:alnum:]]*|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\])|(\\'[^\\']*\\')|(\\\"[^\\\"]*\\\")|(\\`[^\\`]*\\`))(?=\\s*([\\<\\>\\,\\.\\[]|=>|&(?!&)|\\|(?!\\|)))))([^<>\\(]|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(?<==)\\>)*(?!=)\\>)*(?!=)>\\s*)?\\()", "patterns": [ { "include": "#literal" @@ -3495,6 +3528,10 @@ }, { "include": "#punctuation-comma" + }, + { + "name": "keyword.operator.assignment.tsx", + "match": "(=)(?!>)" } ] }, @@ -3863,13 +3900,10 @@ "include": "#typeof-operator" }, { - "begin": "(?:([&|])|(=(?!>)))(?=\\s*\\{)", + "begin": "([&|\\*])(?=\\s*\\{)", "beginCaptures": { - "1": { + "0": { "name": "keyword.operator.type.tsx" - }, - "2": { - "name": "keyword.operator.assignment.tsx" } }, "end": "(?<=\\})", @@ -3880,13 +3914,10 @@ ] }, { - "begin": "([&|])|(=(?!>))", + "begin": "[&|\\*]", "beginCaptures": { - "1": { + "0": { "name": "keyword.operator.type.tsx" - }, - "2": { - "name": "keyword.operator.assignment.tsx" } }, "end": "(?=\\S)" @@ -4018,7 +4049,7 @@ "patterns": [ { "name": "string.template.tsx", - "begin": "([_$[:alpha:]][_$[:alnum:]]*)\\s*(?=(<\\s*(((keyof|infer)\\s+)|(([_$[:alpha:]][_$[:alnum:]]*|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\])|(\\'[^\\']*\\')|(\\\"[^\\\"]*\\\")|(\\`[^\\`]*\\`))(?=\\s*([\\<\\>\\,\\.\\[=]|&(?!&)|\\|(?!\\|)))))([^<>\\(]|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(?<==)\\>|\\<\\s*(((keyof|infer)\\s+)|(([_$[:alpha:]][_$[:alnum:]]*|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\])|(\\'[^\\']*\\')|(\\\"[^\\\"]*\\\")|(\\`[^\\`]*\\`))(?=\\s*([\\<\\>\\,\\.\\[=]|&(?!&)|\\|(?!\\|)))))([^<>\\(]|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(?<==)\\>)*(?!=)\\>)*(?!=)>\\s*)`)", + "begin": "([_$[:alpha:]][_$[:alnum:]]*)\\s*(?=(<\\s*(((keyof|infer)\\s+)|(\\*(?=\\s*[,>]))|(([_$[:alpha:]][_$[:alnum:]]*|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\])|(\\'[^\\']*\\')|(\\\"[^\\\"]*\\\")|(\\`[^\\`]*\\`))(?=\\s*([\\<\\>\\,\\.\\[]|=>|&(?!&)|\\|(?!\\|)))))([^<>\\(]|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(?<==)\\>|\\<\\s*(((keyof|infer)\\s+)|(\\*(?=\\s*[,>]))|(([_$[:alpha:]][_$[:alnum:]]*|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\])|(\\'[^\\']*\\')|(\\\"[^\\\"]*\\\")|(\\`[^\\`]*\\`))(?=\\s*([\\<\\>\\,\\.\\[]|=>|&(?!&)|\\|(?!\\|)))))([^<>\\(]|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(?<==)\\>)*(?!=)\\>)*(?!=)>\\s*)`)", "beginCaptures": { "1": { "name": "entity.name.function.tagged-template.tsx" From 2719dec19803a3eca4faea93c0ff228a9136115d Mon Sep 17 00:00:00 2001 From: Matt Bierner Date: Mon, 20 Aug 2018 15:50:37 +0200 Subject: [PATCH 0996/1276] Update markdown grammar Fixes #55635 --- .../syntaxes/markdown.tmLanguage.json | 40 ++++++++++++++++++- 1 file changed, 38 insertions(+), 2 deletions(-) diff --git a/extensions/markdown-basics/syntaxes/markdown.tmLanguage.json b/extensions/markdown-basics/syntaxes/markdown.tmLanguage.json index d49d0688467..b1ca0418053 100644 --- a/extensions/markdown-basics/syntaxes/markdown.tmLanguage.json +++ b/extensions/markdown-basics/syntaxes/markdown.tmLanguage.json @@ -4,7 +4,7 @@ "If you want to provide a fix or improvement, please create a pull request against the original repository.", "Once accepted there, we are happy to receive an update request." ], - "version": "https://github.com/microsoft/vscode-markdown-tm-grammar/commit/4504240cdb13a4640f64fc98a0adb858226a879e", + "version": "https://github.com/microsoft/vscode-markdown-tm-grammar/commit/826a9c47f16a3d567c3691636fd19f189f65fca5", "name": "Markdown", "scopeName": "text.html.markdown", "patterns": [ @@ -165,6 +165,9 @@ { "include": "#fenced_code_block_dart" }, + { + "include": "#fenced_code_block_handlebars" + }, { "include": "#fenced_code_block_unknown" }, @@ -1685,6 +1688,39 @@ } ] }, + "fenced_code_block_handlebars": { + "begin": "(^|\\G)(\\s*)(`{3,}|~{3,})\\s*(?i:(handlebars|hbs)(\\s+[^`~]*)?$)", + "name": "markup.fenced_code.block.markdown", + "end": "(^|\\G)(\\2|\\s{0,3})(\\3)\\s*$", + "beginCaptures": { + "3": { + "name": "punctuation.definition.markdown" + }, + "5": { + "name": "fenced_code.block.language" + }, + "6": { + "name": "fenced_code.block.language.attributes" + } + }, + "endCaptures": { + "3": { + "name": "punctuation.definition.markdown" + } + }, + "patterns": [ + { + "begin": "(^|\\G)(\\s*)(.*)", + "while": "(^|\\G)(?!\\s*([`~]{3,})\\s*$)", + "contentName": "meta.embedded.block.handlebars", + "patterns": [ + { + "include": "text.html.handlebars" + } + ] + } + ] + }, "fenced_code_block_unknown": { "begin": "(^|\\G)(\\s*)(`{3,}|~{3,})\\s*(?=([^`~]*)?$)", "beginCaptures": { @@ -1994,7 +2030,7 @@ "while": "(^|\\G)([ ]{4}|\\t)" }, "separator": { - "match": "(^|\\G)[ ]{0,3}([\\*\\-\\_])([ ]{0,2}\\2){2,}[ \\t]*$\\n?", + "match": "(^|\\G)[ ]{0,3}([*-_])([ ]{0,2}\\2){2,}[ \\t]*$\\n?", "name": "meta.separator.markdown" } } From 95bdfe00647f0b6f8fc7d76cbcf734b664f41df8 Mon Sep 17 00:00:00 2001 From: isidor Date: Mon, 20 Aug 2018 15:53:15 +0200 Subject: [PATCH 0997/1276] debug: move firstSessionStart to view model --- .../parts/debug/common/debugViewModel.ts | 30 ++++++++++--------- .../debug/electron-browser/debugService.ts | 8 ++--- 2 files changed, 19 insertions(+), 19 deletions(-) diff --git a/src/vs/workbench/parts/debug/common/debugViewModel.ts b/src/vs/workbench/parts/debug/common/debugViewModel.ts index c5816ddb628..efb8ee26930 100644 --- a/src/vs/workbench/parts/debug/common/debugViewModel.ts +++ b/src/vs/workbench/parts/debug/common/debugViewModel.ts @@ -9,6 +9,8 @@ import { IContextKeyService, IContextKey } from 'vs/platform/contextkey/common/c export class ViewModel implements IViewModel { + firstSessionStart = true; + private _focusedStackFrame: IStackFrame; private _focusedSession: ISession; private _focusedThread: IThread; @@ -32,15 +34,15 @@ export class ViewModel implements IViewModel { this.loadedScriptsSupportedContextKey = CONTEXT_LOADED_SCRIPTS_SUPPORTED.bindTo(contextKeyService); } - public getId(): string { + getId(): string { return 'root'; } - public get focusedSession(): ISession { + get focusedSession(): ISession { return this._focusedSession; } - public get focusedThread(): IThread { + get focusedThread(): IThread { if (this._focusedStackFrame) { return this._focusedStackFrame.thread; } @@ -54,11 +56,11 @@ export class ViewModel implements IViewModel { return undefined; } - public get focusedStackFrame(): IStackFrame { + get focusedStackFrame(): IStackFrame { return this._focusedStackFrame; } - public setFocus(stackFrame: IStackFrame, thread: IThread, session: ISession, explicit: boolean): void { + setFocus(stackFrame: IStackFrame, thread: IThread, session: ISession, explicit: boolean): void { let shouldEmit = this._focusedSession !== session || this._focusedThread !== thread || this._focusedStackFrame !== stackFrame; if (this._focusedSession !== session) { @@ -75,42 +77,42 @@ export class ViewModel implements IViewModel { } } - public get onDidFocusSession(): Event { + get onDidFocusSession(): Event { return this._onDidFocusSession.event; } - public get onDidFocusStackFrame(): Event<{ stackFrame: IStackFrame, explicit: boolean }> { + get onDidFocusStackFrame(): Event<{ stackFrame: IStackFrame, explicit: boolean }> { return this._onDidFocusStackFrame.event; } - public getSelectedExpression(): IExpression { + getSelectedExpression(): IExpression { return this.selectedExpression; } - public setSelectedExpression(expression: IExpression) { + setSelectedExpression(expression: IExpression) { this.selectedExpression = expression; this.expressionSelectedContextKey.set(!!expression); this._onDidSelectExpression.fire(expression); } - public get onDidSelectExpression(): Event { + get onDidSelectExpression(): Event { return this._onDidSelectExpression.event; } - public getSelectedFunctionBreakpoint(): IFunctionBreakpoint { + getSelectedFunctionBreakpoint(): IFunctionBreakpoint { return this.selectedFunctionBreakpoint; } - public setSelectedFunctionBreakpoint(functionBreakpoint: IFunctionBreakpoint): void { + setSelectedFunctionBreakpoint(functionBreakpoint: IFunctionBreakpoint): void { this.selectedFunctionBreakpoint = functionBreakpoint; this.breakpointSelectedContextKey.set(!!functionBreakpoint); } - public isMultiSessionView(): boolean { + isMultiSessionView(): boolean { return this.multiSessionView; } - public setMultiSessionView(isMultiSessionView: boolean): void { + setMultiSessionView(isMultiSessionView: boolean): void { this.multiSessionView = isMultiSessionView; } } diff --git a/src/vs/workbench/parts/debug/electron-browser/debugService.ts b/src/vs/workbench/parts/debug/electron-browser/debugService.ts index 6499553b46c..75bea9f8577 100644 --- a/src/vs/workbench/parts/debug/electron-browser/debugService.ts +++ b/src/vs/workbench/parts/debug/electron-browser/debugService.ts @@ -75,7 +75,6 @@ export class DebugService implements IDebugService { private debugState: IContextKey; private inDebugMode: IContextKey; private breakpointsToSendOnResourceSaved: Set; - private firstSessionStart: boolean; private skipRunningTask: boolean; private previousState: State; @@ -117,7 +116,6 @@ export class DebugService implements IDebugService { this.loadExceptionBreakpoints(), this.loadWatchExpressions()); this.toDispose.push(this.model); this.viewModel = new ViewModel(contextKeyService); - this.firstSessionStart = true; this.registerListeners(); } @@ -646,16 +644,16 @@ export class DebugService implements IDebugService { this._onDidNewSession.fire(session); const internalConsoleOptions = resolved.internalConsoleOptions || this.configurationService.getValue('debug').internalConsoleOptions; - if (internalConsoleOptions === 'openOnSessionStart' || (this.firstSessionStart && internalConsoleOptions === 'openOnFirstSessionStart')) { + if (internalConsoleOptions === 'openOnSessionStart' || (this.viewModel.firstSessionStart && internalConsoleOptions === 'openOnFirstSessionStart')) { this.panelService.openPanel(REPL_ID, false).done(undefined, errors.onUnexpectedError); } const openDebug = this.configurationService.getValue('debug').openDebug; // Open debug viewlet based on the visibility of the side bar and openDebug setting - if (openDebug === 'openOnSessionStart' || (openDebug === 'openOnFirstSessionStart' && this.firstSessionStart)) { + if (openDebug === 'openOnSessionStart' || (openDebug === 'openOnFirstSessionStart' && this.viewModel.firstSessionStart)) { this.viewletService.openViewlet(VIEWLET_ID); } - this.firstSessionStart = false; + this.viewModel.firstSessionStart = false; this.debugType.set(resolved.type); if (this.model.getSessions().length > 1) { From b871eb5db1669d5b0d14a230aae531114ca1e837 Mon Sep 17 00:00:00 2001 From: Johannes Rieken Date: Mon, 20 Aug 2018 15:53:32 +0200 Subject: [PATCH 0998/1276] :lipstick: remove outdated comment --- src/vs/workbench/electron-browser/bootstrap/index.js | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/vs/workbench/electron-browser/bootstrap/index.js b/src/vs/workbench/electron-browser/bootstrap/index.js index 8cbef8ef0a0..74ad36e324a 100644 --- a/src/vs/workbench/electron-browser/bootstrap/index.js +++ b/src/vs/workbench/electron-browser/bootstrap/index.js @@ -3,8 +3,6 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -// Warning: Do not use the `let` declarator in this file, it breaks our minification - 'use strict'; /*global window,document,define*/ From 1cd754493fe8b90c237a93759fe2ef43c368d088 Mon Sep 17 00:00:00 2001 From: isidor Date: Mon, 20 Aug 2018 16:02:55 +0200 Subject: [PATCH 0999/1276] debug: fix initializing state --- .../parts/debug/electron-browser/debugService.ts | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/src/vs/workbench/parts/debug/electron-browser/debugService.ts b/src/vs/workbench/parts/debug/electron-browser/debugService.ts index 75bea9f8577..1a54c5824b4 100644 --- a/src/vs/workbench/parts/debug/electron-browser/debugService.ts +++ b/src/vs/workbench/parts/debug/electron-browser/debugService.ts @@ -76,6 +76,7 @@ export class DebugService implements IDebugService { private inDebugMode: IContextKey; private breakpointsToSendOnResourceSaved: Set; private skipRunningTask: boolean; + private initializing = false; private previousState: State; constructor( @@ -308,6 +309,9 @@ export class DebugService implements IDebugService { if (focusedSession) { return focusedSession.state; } + if (this.initializing) { + return State.Initializing; + } return State.Inactive; } @@ -581,6 +585,8 @@ export class DebugService implements IDebugService { } private createSession(launch: ILaunch, config: IConfig, unresolvedConfig: IConfig, sessionId: string): TPromise { + this.initializing = true; + this.onStateChange(); return this.textFileService.saveAll().then(() => this.substituteVariables(launch, config).then(resolvedConfig => { @@ -621,7 +627,10 @@ export class DebugService implements IDebugService { return launch && launch.openConfigFile(false).then(editor => void 0); }) - ); + ).then(() => { + this.initializing = false; + this.onStateChange(); + }); } private doCreateSession(root: IWorkspaceFolder, configuration: { resolved: IConfig, unresolved: IConfig }, sessionId: string): TPromise { From 8281fa7fadd56655744e747f8d2d138ba34c46b8 Mon Sep 17 00:00:00 2001 From: isidor Date: Mon, 20 Aug 2018 16:18:45 +0200 Subject: [PATCH 1000/1276] do not attempt edit operation for for read-only editors fixes #53257 --- src/vs/editor/common/services/resolverService.ts | 2 ++ src/vs/editor/standalone/browser/simpleServices.ts | 4 ++++ .../services/bulkEdit/electron-browser/bulkEditService.ts | 3 +++ src/vs/workbench/services/textfile/common/textfiles.ts | 2 -- 4 files changed, 9 insertions(+), 2 deletions(-) diff --git a/src/vs/editor/common/services/resolverService.ts b/src/vs/editor/common/services/resolverService.ts index 173713e7018..56dca5511ff 100644 --- a/src/vs/editor/common/services/resolverService.ts +++ b/src/vs/editor/common/services/resolverService.ts @@ -42,4 +42,6 @@ export interface ITextEditorModel extends IEditorModel { * Provides access to the underlying `ITextModel`. */ textEditorModel: ITextModel; + + isReadonly(): boolean; } diff --git a/src/vs/editor/standalone/browser/simpleServices.ts b/src/vs/editor/standalone/browser/simpleServices.ts index 231c2e182c3..e73c429819f 100644 --- a/src/vs/editor/standalone/browser/simpleServices.ts +++ b/src/vs/editor/standalone/browser/simpleServices.ts @@ -69,6 +69,10 @@ export class SimpleModel implements ITextEditorModel { return this.model; } + public isReadonly(): boolean { + return false; + } + public dispose(): void { this._onDispose.fire(); } diff --git a/src/vs/workbench/services/bulkEdit/electron-browser/bulkEditService.ts b/src/vs/workbench/services/bulkEdit/electron-browser/bulkEditService.ts index e120c966d99..e7ab928dda6 100644 --- a/src/vs/workbench/services/bulkEdit/electron-browser/bulkEditService.ts +++ b/src/vs/workbench/services/bulkEdit/electron-browser/bulkEditService.ts @@ -180,6 +180,9 @@ class BulkEditModel implements IDisposable { if (!model || !model.textEditorModel) { throw new Error(`Cannot load file ${key}`); } + if (model.isReadonly) { + throw new Error(localize('editorIsReadonly', "Cannot edit a read-only editor.")); + } let task: ModelEditTask; if (this._editor && this._editor.getModel().uri.toString() === model.textEditorModel.uri.toString()) { diff --git a/src/vs/workbench/services/textfile/common/textfiles.ts b/src/vs/workbench/services/textfile/common/textfiles.ts index 132e8b15c47..008c6d19155 100644 --- a/src/vs/workbench/services/textfile/common/textfiles.ts +++ b/src/vs/workbench/services/textfile/common/textfiles.ts @@ -254,8 +254,6 @@ export interface ITextFileEditorModel extends ITextEditorModel, IEncodingSupport isResolved(): boolean; - isReadonly(): boolean; - isDisposed(): boolean; } From b14b7827d5246382d9f2cb5d63c7753f3aa2c709 Mon Sep 17 00:00:00 2001 From: Joao Moreno Date: Mon, 20 Aug 2018 16:44:02 +0200 Subject: [PATCH 1001/1276] ipc: allow buffers to be sent over IPC --- src/vs/base/parts/ipc/common/ipc.ts | 129 +++++++++++++++++++++++++--- 1 file changed, 116 insertions(+), 13 deletions(-) diff --git a/src/vs/base/parts/ipc/common/ipc.ts b/src/vs/base/parts/ipc/common/ipc.ts index 75ebb4a4659..8a87e9434d7 100644 --- a/src/vs/base/parts/ipc/common/ipc.ts +++ b/src/vs/base/parts/ipc/common/ipc.ts @@ -35,13 +35,9 @@ export enum ResponseType { EventFire = 204 } -function isResponse(msg: { type: RequestType | ResponseType }): boolean { - return msg.type >= 200 && msg.type < 300; -} - type IRawInitializeResponse = { type: ResponseType.Initialize }; type IRawPromiseSuccessResponse = { type: ResponseType.PromiseSuccess; id: number; data: any }; -type IRawPromiseErrorResponse = { type: ResponseType.PromiseError; id: number; data: any }; +type IRawPromiseErrorResponse = { type: ResponseType.PromiseError; id: number; data: { message: string, name: string, stack: string[] | undefined } }; type IRawPromiseErrorObjResponse = { type: ResponseType.PromiseErrorObj; id: number; data: any }; type IRawEventFireResponse = { type: ResponseType.EventFire; id: number; data: any }; type IRawResponse = IRawInitializeResponse | IRawPromiseSuccessResponse | IRawPromiseErrorResponse | IRawPromiseErrorObjResponse | IRawEventFireResponse; @@ -108,6 +104,55 @@ export interface IRoutingChannelClient { getChannel(channelName: string, router: IClientRouter): T; } +enum BodyType { + Undefined, + String, + Buffer, + Object +} + +const empty = new Buffer(0); + +function serializeBody(body: any): { buffer: Buffer, type: BodyType } { + if (typeof body === 'undefined') { + return { buffer: empty, type: BodyType.Undefined }; + } else if (typeof body === 'string') { + return { buffer: Buffer.from(body), type: BodyType.String }; + } else if (Buffer.isBuffer(body)) { + return { buffer: body, type: BodyType.Buffer }; + } else { + return { buffer: Buffer.from(JSON.stringify(body)), type: BodyType.Object }; + } +} + +function serialize(header: any, body: any = undefined): Buffer { + const headerSizeBuffer = new Buffer(4); + const { buffer: bodyBuffer, type: bodyType } = serializeBody(body); + const headerBuffer = Buffer.from(JSON.stringify([header, bodyType])); + headerSizeBuffer.writeUInt32BE(headerBuffer.byteLength, 0); + + return Buffer.concat([headerSizeBuffer, headerBuffer, bodyBuffer]); +} + +function deserializeBody(bodyBuffer: Buffer, bodyType: BodyType): any { + switch (bodyType) { + case BodyType.Undefined: return undefined; + case BodyType.String: return bodyBuffer.toString(); + case BodyType.Buffer: return bodyBuffer; + case BodyType.Object: return JSON.parse(bodyBuffer.toString()); + } +} + +function deserialize(buffer: Buffer): { header: any, body: any } { + const headerSize = buffer.readUInt32BE(0); + const headerBuffer = buffer.slice(4, 4 + headerSize); + const bodyBuffer = buffer.slice(4 + headerSize); + const [header, bodyType] = JSON.parse(headerBuffer.toString()); + const body = deserializeBody(bodyBuffer, bodyType); + + return { header, body }; +} + export class ChannelServer implements IChannelServer, IDisposable { private channels: { [name: string]: IChannel } = Object.create(null); @@ -177,7 +222,24 @@ export class ChannelServer implements IChannelServer, IDisposable { } private onRawMessage(message: Buffer): void { - this.onRequest(JSON.parse(message.toString())); + const { header, body } = deserialize(message); + const type: RequestType = header[0]; + let request: IRawRequest; + + switch (type) { + case RequestType.Promise: + case RequestType.EventListen: + request = { type: header[0], id: header[1], channelName: header[2], name: header[3], arg: body }; + break; + case RequestType.PromiseCancel: + case RequestType.EventDispose: + request = { type: header[0], id: header[1] }; + break; + default: + return; + } + + this.onRequest(request); } private onRequest(request: IRawRequest): void { @@ -198,7 +260,21 @@ export class ChannelServer implements IChannelServer, IDisposable { } private sendResponse(response: IRawResponse) { - this.sendRawMessage(Buffer.from(JSON.stringify(response))); + let buffer: Buffer; + + switch (response.type) { + case ResponseType.Initialize: + buffer = serialize([response.type]); + break; + case ResponseType.PromiseSuccess: + case ResponseType.PromiseError: + case ResponseType.EventFire: + case ResponseType.PromiseErrorObj: + buffer = serialize([response.type, response.id], response.data); + break; + } + + this.sendRawMessage(buffer); } private sendRawMessage(message: Buffer) { @@ -356,14 +432,28 @@ export class ChannelClient implements IChannelClient, IDisposable { } private onRawMessage(message: Buffer): void { - this.onResponse(JSON.parse(message.toString())); + const { header, body } = deserialize(message); + const type: ResponseType = header[0]; + let response: IRawResponse; + + switch (type) { + case ResponseType.Initialize: + response = { type: header[0] }; + break; + case ResponseType.PromiseSuccess: + case ResponseType.PromiseError: + case ResponseType.EventFire: + case ResponseType.PromiseErrorObj: + response = { type: header[0], id: header[1], data: body }; + break; + default: + return; + } + + this.onResponse(response); } private onResponse(response: IRawResponse): void { - if (!isResponse(response)) { - return; - } - if (response.type === ResponseType.Initialize) { this.state = State.Idle; this._onDidInitialize.fire(); @@ -379,7 +469,20 @@ export class ChannelClient implements IChannelClient, IDisposable { } private sendRequest(request: IRawRequest) { - this.sendRawMessage(Buffer.from(JSON.stringify(request))); + let buffer: Buffer; + + switch (request.type) { + case RequestType.Promise: + case RequestType.EventListen: + buffer = serialize([request.type, request.id, request.channelName, request.name], request.arg); + break; + case RequestType.PromiseCancel: + case RequestType.EventDispose: + buffer = serialize([request.type, request.id]); + break; + } + + this.sendRawMessage(buffer); } private sendRawMessage(message: Buffer) { From 0e3a2219afbeed2996549468f6d656ce4713aeab Mon Sep 17 00:00:00 2001 From: isidor Date: Mon, 20 Aug 2018 16:49:37 +0200 Subject: [PATCH 1002/1276] open editors: focus active group even if it does not have an editor fixes #56806 --- .../parts/files/electron-browser/views/openEditorsView.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vs/workbench/parts/files/electron-browser/views/openEditorsView.ts b/src/vs/workbench/parts/files/electron-browser/views/openEditorsView.ts index a9eb1724a80..58bc06b153f 100644 --- a/src/vs/workbench/parts/files/electron-browser/views/openEditorsView.ts +++ b/src/vs/workbench/parts/files/electron-browser/views/openEditorsView.ts @@ -389,7 +389,7 @@ export class OpenEditorsView extends ViewletPanel { } private focusActiveEditor(): void { - if (this.editorGroupService.activeGroup && this.editorGroupService.activeGroup.activeEditor /* could be empty */) { + if (this.editorGroupService.activeGroup) { const index = this.getIndex(this.editorGroupService.activeGroup, this.editorGroupService.activeGroup.activeEditor); this.list.setFocus([index]); this.list.setSelection([index]); From c1a965c63c1d3cc13f57b8ec09ef49f89d8d79db Mon Sep 17 00:00:00 2001 From: isidor Date: Mon, 20 Aug 2018 16:54:37 +0200 Subject: [PATCH 1003/1276] debug: npe fixes #56666 --- .../parts/debug/electron-browser/debugConfigurationManager.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vs/workbench/parts/debug/electron-browser/debugConfigurationManager.ts b/src/vs/workbench/parts/debug/electron-browser/debugConfigurationManager.ts index 7a0cba2221a..2d2fd7ce3bc 100644 --- a/src/vs/workbench/parts/debug/electron-browser/debugConfigurationManager.ts +++ b/src/vs/workbench/parts/debug/electron-browser/debugConfigurationManager.ts @@ -350,7 +350,7 @@ export class ConfigurationManager implements IConfigurationManager { const picks = candidates.map(c => ({ label: c.label, debugger: c })); return this.quickInputService.pick<(typeof picks)[0]>([...picks, { type: 'separator' }, { label: 'More...', debugger: undefined }], { placeHolder: nls.localize('selectDebug', "Select Environment") }) .then(picked => { - if (picked.debugger) { + if (picked && picked.debugger) { return picked.debugger; } if (picked) { From 410c161181eda613d35016f2cd34b8b59c128ca6 Mon Sep 17 00:00:00 2001 From: Matt Bierner Date: Mon, 20 Aug 2018 16:50:32 +0200 Subject: [PATCH 1004/1276] Update markdown grammar Fixes #56735 --- .../markdown-basics/syntaxes/markdown.tmLanguage.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/extensions/markdown-basics/syntaxes/markdown.tmLanguage.json b/extensions/markdown-basics/syntaxes/markdown.tmLanguage.json index b1ca0418053..fd2e9302712 100644 --- a/extensions/markdown-basics/syntaxes/markdown.tmLanguage.json +++ b/extensions/markdown-basics/syntaxes/markdown.tmLanguage.json @@ -4,7 +4,7 @@ "If you want to provide a fix or improvement, please create a pull request against the original repository.", "Once accepted there, we are happy to receive an update request." ], - "version": "https://github.com/microsoft/vscode-markdown-tm-grammar/commit/826a9c47f16a3d567c3691636fd19f189f65fca5", + "version": "https://github.com/microsoft/vscode-markdown-tm-grammar/commit/082f5ac70a35e7a0979c8450729d216b59789ad6", "name": "Markdown", "scopeName": "text.html.markdown", "patterns": [ @@ -2094,7 +2094,7 @@ "name": "meta.other.valid-ampersand.markdown" }, "bold": { - "begin": "(?x)\n ((?]*+> # HTML tags\n | (?`+)([^`]|(?!(?(?!`))`)*+\\k\n # Raw\n | \\\\[\\\\`*_{}\\[\\]()#.!+\\->]?+ # Escapes\n | \\[\n (\n (? # Named group\n [^\\[\\]\\\\] # Match most chars\n | \\\\. # Escaped chars\n | \\[ \\g*+ \\] # Nested brackets\n )*+\n \\]\n (\n ( # Reference Link\n [ ]? # Optional space\n \\[[^\\]]*+\\] # Ref name\n )\n | ( # Inline Link\n \\( # Opening paren\n [ \\t]*+ # Optional whitespace\n ? # URL\n [ \\t]*+ # Optional whitespace\n ( # Optional Title\n (?['\"])\n (.*?)\n \\k<title>\n )?\n \\)\n )\n )\n )\n | (?!(?<=\\S)\\1). # Everything besides\n # style closer\n )++\n (?<=\\S)(?=__\\b|\\*\\*)\\1 # Close\n )\n", + "begin": "(?x)\n (\\*\\*(?=\\w)|(?<!\\w)\\*\\*|(?<!\\w)\\b__)(?=\\S) # Open\n (?=\n (\n <[^>]*+> # HTML tags\n | (?<raw>`+)([^`]|(?!(?<!`)\\k<raw>(?!`))`)*+\\k<raw>\n # Raw\n | \\\\[\\\\`*_{}\\[\\]()#.!+\\->]?+ # Escapes\n | \\[\n (\n (?<square> # Named group\n [^\\[\\]\\\\] # Match most chars\n | \\\\. # Escaped chars\n | \\[ \\g<square>*+ \\] # Nested brackets\n )*+\n \\]\n (\n ( # Reference Link\n [ ]? # Optional space\n \\[[^\\]]*+\\] # Ref name\n )\n | ( # Inline Link\n \\( # Opening paren\n [ \\t]*+ # Optional whitespace\n <?(.*?)>? # URL\n [ \\t]*+ # Optional whitespace\n ( # Optional Title\n (?<title>['\"])\n (.*?)\n \\k<title>\n )?\n \\)\n )\n )\n )\n | (?!(?<=\\S)\\1). # Everything besides\n # style closer\n )++\n (?<=\\S)(?=__\\b|\\*\\*)\\1 # Close\n )\n", "captures": { "1": { "name": "punctuation.definition.bold.markdown" @@ -2236,7 +2236,7 @@ "name": "meta.image.reference.markdown" }, "italic": { - "begin": "(?x) (\\*\\b|\\b_)(?=\\S) # Open\n (?=\n (\n <[^>]*+> # HTML tags\n | (?<raw>`+)([^`]|(?!(?<!`)\\k<raw>(?!`))`)*+\\k<raw>\n # Raw\n | \\\\[\\\\`*_{}\\[\\]()#.!+\\->]?+ # Escapes\n | \\[\n (\n (?<square> # Named group\n [^\\[\\]\\\\] # Match most chars\n | \\\\. # Escaped chars\n | \\[ \\g<square>*+ \\] # Nested brackets\n )*+\n \\]\n (\n ( # Reference Link\n [ ]? # Optional space\n \\[[^\\]]*+\\] # Ref name\n )\n | ( # Inline Link\n \\( # Opening paren\n [ \\t]*+ # Optional whtiespace\n <?(.*?)>? # URL\n [ \\t]*+ # Optional whtiespace\n ( # Optional Title\n (?<title>['\"])\n (.*?)\n \\k<title>\n )?\n \\)\n )\n )\n )\n | \\1\\1 # Must be bold closer\n | (?!(?<=\\S)\\1). # Everything besides\n # style closer\n )++\n (?<=\\S)(?=_\\b|\\*)\\1 # Close\n )\n", + "begin": "(?x) (\\*(?=\\w)|(?<!\\w)\\*|(?<!\\w)\\b_)(?=\\S) # Open\n (?=\n (\n <[^>]*+> # HTML tags\n | (?<raw>`+)([^`]|(?!(?<!`)\\k<raw>(?!`))`)*+\\k<raw>\n # Raw\n | \\\\[\\\\`*_{}\\[\\]()#.!+\\->]?+ # Escapes\n | \\[\n (\n (?<square> # Named group\n [^\\[\\]\\\\] # Match most chars\n | \\\\. # Escaped chars\n | \\[ \\g<square>*+ \\] # Nested brackets\n )*+\n \\]\n (\n ( # Reference Link\n [ ]? # Optional space\n \\[[^\\]]*+\\] # Ref name\n )\n | ( # Inline Link\n \\( # Opening paren\n [ \\t]*+ # Optional whtiespace\n <?(.*?)>? # URL\n [ \\t]*+ # Optional whtiespace\n ( # Optional Title\n (?<title>['\"])\n (.*?)\n \\k<title>\n )?\n \\)\n )\n )\n )\n | \\1\\1 # Must be bold closer\n | (?!(?<=\\S)\\1). # Everything besides\n # style closer\n )++\n (?<=\\S)(?=_\\b|\\*)\\1 # Close\n )\n", "captures": { "1": { "name": "punctuation.definition.italic.markdown" From 94c4f0a47d752f00d4848cde3e1cab8c91b53d4e Mon Sep 17 00:00:00 2001 From: Matt Bierner <matb@microsoft.com> Date: Mon, 20 Aug 2018 16:59:43 +0200 Subject: [PATCH 1005/1276] Update markdown grammar Fixes #3948 --- .../markdown-basics/syntaxes/markdown.tmLanguage.json | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/extensions/markdown-basics/syntaxes/markdown.tmLanguage.json b/extensions/markdown-basics/syntaxes/markdown.tmLanguage.json index fd2e9302712..1036f52cab4 100644 --- a/extensions/markdown-basics/syntaxes/markdown.tmLanguage.json +++ b/extensions/markdown-basics/syntaxes/markdown.tmLanguage.json @@ -4,7 +4,7 @@ "If you want to provide a fix or improvement, please create a pull request against the original repository.", "Once accepted there, we are happy to receive an update request." ], - "version": "https://github.com/microsoft/vscode-markdown-tm-grammar/commit/082f5ac70a35e7a0979c8450729d216b59789ad6", + "version": "https://github.com/microsoft/vscode-markdown-tm-grammar/commit/935f7a6d1da73e16231be18c545d7991d3698075", "name": "Markdown", "scopeName": "text.html.markdown", "patterns": [ @@ -189,7 +189,7 @@ "begin": "(^|\\G)[ ]{0,3}(>) ?", "captures": { "2": { - "name": "beginning.punctuation.definition.quote.markdown" + "name": "punctuation.definition.quote.begin.markdown" } }, "name": "markup.quote.markdown", @@ -1973,7 +1973,7 @@ "begin": "(^|\\G)([ ]{0,3})([*+-])([ ]{1,3}|\\t)", "beginCaptures": { "3": { - "name": "beginning.punctuation.definition.list.markdown" + "name": "punctuation.definition.list.begin.markdown" } }, "comment": "Currently does not support un-indented second lines.", @@ -1992,7 +1992,7 @@ "begin": "(^|\\G)([ ]{0,3})([0-9]+\\.)([ ]{1,3}|\\t)", "beginCaptures": { "3": { - "name": "beginning.punctuation.definition.list.markdown" + "name": "punctuation.definition.list.begin.markdown" } }, "name": "markup.list.numbered.markdown", From 9da44453a0cf299a2f7ebc6fb7f3e9276e0439d9 Mon Sep 17 00:00:00 2001 From: Matt Bierner <matb@microsoft.com> Date: Mon, 20 Aug 2018 17:01:55 +0200 Subject: [PATCH 1006/1276] Update grammar tests --- .../test/colorize-results/test_md.json | 150 +++++++++--------- .../test/colorize-results/test_ts.json | 4 +- 2 files changed, 77 insertions(+), 77 deletions(-) diff --git a/extensions/markdown-basics/test/colorize-results/test_md.json b/extensions/markdown-basics/test/colorize-results/test_md.json index dc9ce77ffe7..5663fd051bd 100644 --- a/extensions/markdown-basics/test/colorize-results/test_md.json +++ b/extensions/markdown-basics/test/colorize-results/test_md.json @@ -1211,12 +1211,12 @@ }, { "c": "*", - "t": "text.html.markdown markup.list.unnumbered.markdown beginning.punctuation.definition.list.markdown", + "t": "text.html.markdown markup.list.unnumbered.markdown punctuation.definition.list.begin.markdown", "r": { - "dark_plus": "beginning.punctuation.definition.list.markdown: #6796E6", - "light_plus": "beginning.punctuation.definition.list.markdown: #0451A5", - "dark_vs": "beginning.punctuation.definition.list.markdown: #6796E6", - "light_vs": "beginning.punctuation.definition.list.markdown: #0451A5", + "dark_plus": "default: #D4D4D4", + "light_plus": "default: #000000", + "dark_vs": "default: #D4D4D4", + "light_vs": "default: #000000", "hc_black": "default: #FFFFFF" } }, @@ -1244,12 +1244,12 @@ }, { "c": "-", - "t": "text.html.markdown markup.list.unnumbered.markdown beginning.punctuation.definition.list.markdown", + "t": "text.html.markdown markup.list.unnumbered.markdown punctuation.definition.list.begin.markdown", "r": { - "dark_plus": "beginning.punctuation.definition.list.markdown: #6796E6", - "light_plus": "beginning.punctuation.definition.list.markdown: #0451A5", - "dark_vs": "beginning.punctuation.definition.list.markdown: #6796E6", - "light_vs": "beginning.punctuation.definition.list.markdown: #0451A5", + "dark_plus": "default: #D4D4D4", + "light_plus": "default: #000000", + "dark_vs": "default: #D4D4D4", + "light_vs": "default: #000000", "hc_black": "default: #FFFFFF" } }, @@ -1277,12 +1277,12 @@ }, { "c": "+", - "t": "text.html.markdown markup.list.unnumbered.markdown beginning.punctuation.definition.list.markdown", + "t": "text.html.markdown markup.list.unnumbered.markdown punctuation.definition.list.begin.markdown", "r": { - "dark_plus": "beginning.punctuation.definition.list.markdown: #6796E6", - "light_plus": "beginning.punctuation.definition.list.markdown: #0451A5", - "dark_vs": "beginning.punctuation.definition.list.markdown: #6796E6", - "light_vs": "beginning.punctuation.definition.list.markdown: #0451A5", + "dark_plus": "default: #D4D4D4", + "light_plus": "default: #000000", + "dark_vs": "default: #D4D4D4", + "light_vs": "default: #000000", "hc_black": "default: #FFFFFF" } }, @@ -1321,12 +1321,12 @@ }, { "c": "+", - "t": "text.html.markdown markup.list.unnumbered.markdown markup.list.unnumbered.markdown beginning.punctuation.definition.list.markdown", + "t": "text.html.markdown markup.list.unnumbered.markdown markup.list.unnumbered.markdown punctuation.definition.list.begin.markdown", "r": { - "dark_plus": "beginning.punctuation.definition.list.markdown: #6796E6", - "light_plus": "beginning.punctuation.definition.list.markdown: #0451A5", - "dark_vs": "beginning.punctuation.definition.list.markdown: #6796E6", - "light_vs": "beginning.punctuation.definition.list.markdown: #0451A5", + "dark_plus": "default: #D4D4D4", + "light_plus": "default: #000000", + "dark_vs": "default: #D4D4D4", + "light_vs": "default: #000000", "hc_black": "default: #FFFFFF" } }, @@ -1596,12 +1596,12 @@ }, { "c": ">", - "t": "text.html.markdown markup.quote.markdown beginning.punctuation.definition.quote.markdown", + "t": "text.html.markdown markup.quote.markdown punctuation.definition.quote.begin.markdown", "r": { - "dark_plus": "beginning.punctuation.definition.quote.markdown: #6A9955", - "light_plus": "beginning.punctuation.definition.quote.markdown: #0451A5", - "dark_vs": "beginning.punctuation.definition.quote.markdown: #6A9955", - "light_vs": "beginning.punctuation.definition.quote.markdown: #0451A5", + "dark_plus": "default: #D4D4D4", + "light_plus": "default: #000000", + "dark_vs": "default: #D4D4D4", + "light_vs": "default: #000000", "hc_black": "default: #FFFFFF" } }, @@ -1629,23 +1629,23 @@ }, { "c": ">", - "t": "text.html.markdown markup.quote.markdown beginning.punctuation.definition.quote.markdown", + "t": "text.html.markdown markup.quote.markdown punctuation.definition.quote.begin.markdown", "r": { - "dark_plus": "beginning.punctuation.definition.quote.markdown: #6A9955", - "light_plus": "beginning.punctuation.definition.quote.markdown: #0451A5", - "dark_vs": "beginning.punctuation.definition.quote.markdown: #6A9955", - "light_vs": "beginning.punctuation.definition.quote.markdown: #0451A5", + "dark_plus": "default: #D4D4D4", + "light_plus": "default: #000000", + "dark_vs": "default: #D4D4D4", + "light_vs": "default: #000000", "hc_black": "default: #FFFFFF" } }, { "c": ">", - "t": "text.html.markdown markup.quote.markdown markup.quote.markdown beginning.punctuation.definition.quote.markdown", + "t": "text.html.markdown markup.quote.markdown markup.quote.markdown punctuation.definition.quote.begin.markdown", "r": { - "dark_plus": "beginning.punctuation.definition.quote.markdown: #6A9955", - "light_plus": "beginning.punctuation.definition.quote.markdown: #0451A5", - "dark_vs": "beginning.punctuation.definition.quote.markdown: #6A9955", - "light_vs": "beginning.punctuation.definition.quote.markdown: #0451A5", + "dark_plus": "default: #D4D4D4", + "light_plus": "default: #000000", + "dark_vs": "default: #D4D4D4", + "light_vs": "default: #000000", "hc_black": "default: #FFFFFF" } }, @@ -1673,12 +1673,12 @@ }, { "c": "1.", - "t": "text.html.markdown markup.list.numbered.markdown beginning.punctuation.definition.list.markdown", + "t": "text.html.markdown markup.list.numbered.markdown punctuation.definition.list.begin.markdown", "r": { - "dark_plus": "beginning.punctuation.definition.list.markdown: #6796E6", - "light_plus": "beginning.punctuation.definition.list.markdown: #0451A5", - "dark_vs": "beginning.punctuation.definition.list.markdown: #6796E6", - "light_vs": "beginning.punctuation.definition.list.markdown: #0451A5", + "dark_plus": "default: #D4D4D4", + "light_plus": "default: #000000", + "dark_vs": "default: #D4D4D4", + "light_vs": "default: #000000", "hc_black": "default: #FFFFFF" } }, @@ -1717,12 +1717,12 @@ }, { "c": ">", - "t": "text.html.markdown markup.list.numbered.markdown markup.quote.markdown beginning.punctuation.definition.quote.markdown", + "t": "text.html.markdown markup.list.numbered.markdown markup.quote.markdown punctuation.definition.quote.begin.markdown", "r": { - "dark_plus": "beginning.punctuation.definition.quote.markdown: #6A9955", - "light_plus": "beginning.punctuation.definition.quote.markdown: #0451A5", - "dark_vs": "beginning.punctuation.definition.quote.markdown: #6A9955", - "light_vs": "beginning.punctuation.definition.quote.markdown: #0451A5", + "dark_plus": "default: #D4D4D4", + "light_plus": "default: #000000", + "dark_vs": "default: #D4D4D4", + "light_vs": "default: #000000", "hc_black": "default: #FFFFFF" } }, @@ -1750,12 +1750,12 @@ }, { "c": "2.", - "t": "text.html.markdown markup.list.numbered.markdown beginning.punctuation.definition.list.markdown", + "t": "text.html.markdown markup.list.numbered.markdown punctuation.definition.list.begin.markdown", "r": { - "dark_plus": "beginning.punctuation.definition.list.markdown: #6796E6", - "light_plus": "beginning.punctuation.definition.list.markdown: #0451A5", - "dark_vs": "beginning.punctuation.definition.list.markdown: #6796E6", - "light_vs": "beginning.punctuation.definition.list.markdown: #0451A5", + "dark_plus": "default: #D4D4D4", + "light_plus": "default: #000000", + "dark_vs": "default: #D4D4D4", + "light_vs": "default: #000000", "hc_black": "default: #FFFFFF" } }, @@ -1783,12 +1783,12 @@ }, { "c": "3.", - "t": "text.html.markdown markup.list.numbered.markdown beginning.punctuation.definition.list.markdown", + "t": "text.html.markdown markup.list.numbered.markdown punctuation.definition.list.begin.markdown", "r": { - "dark_plus": "beginning.punctuation.definition.list.markdown: #6796E6", - "light_plus": "beginning.punctuation.definition.list.markdown: #0451A5", - "dark_vs": "beginning.punctuation.definition.list.markdown: #6796E6", - "light_vs": "beginning.punctuation.definition.list.markdown: #0451A5", + "dark_plus": "default: #D4D4D4", + "light_plus": "default: #000000", + "dark_vs": "default: #D4D4D4", + "light_vs": "default: #000000", "hc_black": "default: #FFFFFF" } }, @@ -2245,12 +2245,12 @@ }, { "c": "*", - "t": "text.html.markdown markup.list.unnumbered.markdown beginning.punctuation.definition.list.markdown", + "t": "text.html.markdown markup.list.unnumbered.markdown punctuation.definition.list.begin.markdown", "r": { - "dark_plus": "beginning.punctuation.definition.list.markdown: #6796E6", - "light_plus": "beginning.punctuation.definition.list.markdown: #0451A5", - "dark_vs": "beginning.punctuation.definition.list.markdown: #6796E6", - "light_vs": "beginning.punctuation.definition.list.markdown: #0451A5", + "dark_plus": "default: #D4D4D4", + "light_plus": "default: #000000", + "dark_vs": "default: #D4D4D4", + "light_vs": "default: #000000", "hc_black": "default: #FFFFFF" } }, @@ -2278,12 +2278,12 @@ }, { "c": "*", - "t": "text.html.markdown markup.list.unnumbered.markdown beginning.punctuation.definition.list.markdown", + "t": "text.html.markdown markup.list.unnumbered.markdown punctuation.definition.list.begin.markdown", "r": { - "dark_plus": "beginning.punctuation.definition.list.markdown: #6796E6", - "light_plus": "beginning.punctuation.definition.list.markdown: #0451A5", - "dark_vs": "beginning.punctuation.definition.list.markdown: #6796E6", - "light_vs": "beginning.punctuation.definition.list.markdown: #0451A5", + "dark_plus": "default: #D4D4D4", + "light_plus": "default: #000000", + "dark_vs": "default: #D4D4D4", + "light_vs": "default: #000000", "hc_black": "default: #FFFFFF" } }, @@ -2421,12 +2421,12 @@ }, { "c": "*", - "t": "text.html.markdown markup.list.unnumbered.markdown beginning.punctuation.definition.list.markdown", + "t": "text.html.markdown markup.list.unnumbered.markdown punctuation.definition.list.begin.markdown", "r": { - "dark_plus": "beginning.punctuation.definition.list.markdown: #6796E6", - "light_plus": "beginning.punctuation.definition.list.markdown: #0451A5", - "dark_vs": "beginning.punctuation.definition.list.markdown: #6796E6", - "light_vs": "beginning.punctuation.definition.list.markdown: #0451A5", + "dark_plus": "default: #D4D4D4", + "light_plus": "default: #000000", + "dark_vs": "default: #D4D4D4", + "light_vs": "default: #000000", "hc_black": "default: #FFFFFF" } }, @@ -2454,12 +2454,12 @@ }, { "c": "*", - "t": "text.html.markdown markup.list.unnumbered.markdown beginning.punctuation.definition.list.markdown", + "t": "text.html.markdown markup.list.unnumbered.markdown punctuation.definition.list.begin.markdown", "r": { - "dark_plus": "beginning.punctuation.definition.list.markdown: #6796E6", - "light_plus": "beginning.punctuation.definition.list.markdown: #0451A5", - "dark_vs": "beginning.punctuation.definition.list.markdown: #6796E6", - "light_vs": "beginning.punctuation.definition.list.markdown: #0451A5", + "dark_plus": "default: #D4D4D4", + "light_plus": "default: #000000", + "dark_vs": "default: #D4D4D4", + "light_vs": "default: #000000", "hc_black": "default: #FFFFFF" } }, diff --git a/extensions/typescript-basics/test/colorize-results/test_ts.json b/extensions/typescript-basics/test/colorize-results/test_ts.json index 3246facbff2..bf74c1c2174 100644 --- a/extensions/typescript-basics/test/colorize-results/test_ts.json +++ b/extensions/typescript-basics/test/colorize-results/test_ts.json @@ -1860,7 +1860,7 @@ }, { "c": " ", - "t": "source.ts meta.namespace.declaration.ts meta.block.ts meta.class.ts", + "t": "source.ts meta.namespace.declaration.ts meta.block.ts meta.class.ts meta.field.declaration.ts", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -1871,7 +1871,7 @@ }, { "c": "world", - "t": "source.ts meta.namespace.declaration.ts meta.block.ts meta.class.ts variable.other.readwrite.ts", + "t": "source.ts meta.namespace.declaration.ts meta.block.ts meta.class.ts meta.field.declaration.ts meta.definition.property.ts variable.object.property.ts", "r": { "dark_plus": "variable: #9CDCFE", "light_plus": "variable: #001080", From 53e57b5ea03e19ec1002f1c0a2d69fa1dd2cc01b Mon Sep 17 00:00:00 2001 From: isidor <inikolic@microsoft.com> Date: Mon, 20 Aug 2018 17:44:46 +0200 Subject: [PATCH 1007/1276] longTitle should be absolute fixes #56550 --- src/vs/workbench/parts/files/common/editors/fileEditorInput.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vs/workbench/parts/files/common/editors/fileEditorInput.ts b/src/vs/workbench/parts/files/common/editors/fileEditorInput.ts index 6f171a925b3..232a677b82c 100644 --- a/src/vs/workbench/parts/files/common/editors/fileEditorInput.ts +++ b/src/vs/workbench/parts/files/common/editors/fileEditorInput.ts @@ -175,7 +175,7 @@ export class FileEditorInput extends EditorInput implements IFileEditorInput { @memoize private get longTitle(): string { - return this.uriLabelService.getLabel(this.resource, true); + return this.uriLabelService.getLabel(this.resource); } getTitle(verbosity: Verbosity): string { From 2c7366cf33891c315abe73fd345a246f1058fdb7 Mon Sep 17 00:00:00 2001 From: Joao Moreno <joao.moreno@microsoft.com> Date: Mon, 20 Aug 2018 17:58:07 +0200 Subject: [PATCH 1008/1276] fix broken layering --- .../electron-browser/ipc.electron-browser.ts | 4 +- .../ipc/electron-main/ipc.electron-main.ts | 4 +- src/vs/base/parts/ipc/node/ipc.cp.ts | 2 +- .../ipc/{common => node}/ipc.electron.ts | 2 +- src/vs/base/parts/ipc/node/ipc.net.ts | 2 +- src/vs/base/parts/ipc/{common => node}/ipc.ts | 0 .../base/parts/ipc/test/node/testService.ts | 2 +- src/vs/base/test/node/uri.test.data.txt | 4 +- .../issue/issueReporterMain.ts | 8 +- .../sharedProcess/sharedProcessMain.ts | 12 +- src/vs/code/electron-main/app.ts | 18 +- src/vs/code/electron-main/launch.ts | 2 +- .../dialogs/{common => node}/dialogIpc.ts | 2 +- src/vs/platform/driver/common/driver.ts | 292 ------------------ .../driver/electron-browser/driver.ts | 4 +- .../platform/driver/electron-main/driver.ts | 4 +- src/vs/platform/driver/node/driver.ts | 286 ++++++++++++++++- .../extensionManagementIpc.ts | 4 +- .../issue/{common => node}/issueIpc.ts | 4 +- .../{common => node}/localizationsIpc.ts | 2 +- .../platform/log/{common => node}/logIpc.ts | 2 +- .../menubar/{common => node}/menubarIpc.ts | 2 +- .../{common => node}/telemetryIpc.ts | 2 +- .../update/{common => node}/updateIpc.ts | 4 +- .../platform/url/{common => node}/urlIpc.ts | 4 +- .../windows/{common => node}/windowsIpc.ts | 2 +- .../{common => node}/workspacesIpc.ts | 2 +- src/vs/workbench/electron-browser/main.ts | 14 +- src/vs/workbench/electron-browser/shell.ts | 12 +- .../workbench/electron-browser/workbench.ts | 2 +- src/vs/workbench/node/extensionHostMain.ts | 2 +- src/vs/workbench/node/extensionHostProcess.ts | 2 +- src/vs/workbench/parts/debug/node/debugger.ts | 2 +- .../parts/debug/node/telemetryApp.ts | 2 +- .../electron-browser/extensionHost.ts | 2 +- .../electron-browser/extensionService.ts | 2 +- .../services/extensions/node/rpcProtocol.ts | 2 +- .../files/node/watcher/nsfw/watcherIpc.ts | 2 +- .../files/node/watcher/nsfw/watcherService.ts | 2 +- .../files/node/watcher/unix/watcherIpc.ts | 2 +- .../files/node/watcher/unix/watcherService.ts | 2 +- .../services/search/node/searchIpc.ts | 2 +- .../services/search/node/searchService.ts | 2 +- .../search/node/textSearchWorkerProvider.ts | 2 +- .../search/node/worker/searchWorkerIpc.ts | 2 +- 45 files changed, 363 insertions(+), 371 deletions(-) rename src/vs/base/parts/ipc/{common => node}/ipc.electron.ts (94%) rename src/vs/base/parts/ipc/{common => node}/ipc.ts (100%) rename src/vs/platform/dialogs/{common => node}/dialogIpc.ts (96%) delete mode 100644 src/vs/platform/driver/common/driver.ts rename src/vs/platform/extensionManagement/{common => node}/extensionManagementIpc.ts (97%) rename src/vs/platform/issue/{common => node}/issueIpc.ts (95%) rename src/vs/platform/localizations/{common => node}/localizationsIpc.ts (96%) rename src/vs/platform/log/{common => node}/logIpc.ts (97%) rename src/vs/platform/menubar/{common => node}/menubarIpc.ts (96%) rename src/vs/platform/telemetry/{common => node}/telemetryIpc.ts (96%) rename src/vs/platform/update/{common => node}/updateIpc.ts (95%) rename src/vs/platform/url/{common => node}/urlIpc.ts (94%) rename src/vs/platform/windows/{common => node}/windowsIpc.ts (99%) rename src/vs/platform/workspaces/{common => node}/workspacesIpc.ts (97%) diff --git a/src/vs/base/parts/ipc/electron-browser/ipc.electron-browser.ts b/src/vs/base/parts/ipc/electron-browser/ipc.electron-browser.ts index 85928ffbe7c..a61c756d6f0 100644 --- a/src/vs/base/parts/ipc/electron-browser/ipc.electron-browser.ts +++ b/src/vs/base/parts/ipc/electron-browser/ipc.electron-browser.ts @@ -4,8 +4,8 @@ *--------------------------------------------------------------------------------------------*/ import { fromNodeEventEmitter } from 'vs/base/common/event'; -import { IPCClient } from 'vs/base/parts/ipc/common/ipc'; -import { Protocol } from 'vs/base/parts/ipc/common/ipc.electron'; +import { IPCClient } from 'vs/base/parts/ipc/node/ipc'; +import { Protocol } from 'vs/base/parts/ipc/node/ipc.electron'; import { ipcRenderer } from 'electron'; export class Client extends IPCClient { diff --git a/src/vs/base/parts/ipc/electron-main/ipc.electron-main.ts b/src/vs/base/parts/ipc/electron-main/ipc.electron-main.ts index 9e53b78b98f..47da2f529f5 100644 --- a/src/vs/base/parts/ipc/electron-main/ipc.electron-main.ts +++ b/src/vs/base/parts/ipc/electron-main/ipc.electron-main.ts @@ -4,8 +4,8 @@ *--------------------------------------------------------------------------------------------*/ import { Event, filterEvent, mapEvent, fromNodeEventEmitter } from 'vs/base/common/event'; -import { IPCServer, ClientConnectionEvent } from 'vs/base/parts/ipc/common/ipc'; -import { Protocol } from 'vs/base/parts/ipc/common/ipc.electron'; +import { IPCServer, ClientConnectionEvent } from 'vs/base/parts/ipc/node/ipc'; +import { Protocol } from 'vs/base/parts/ipc/node/ipc.electron'; import { ipcMain } from 'electron'; interface WebContents extends Electron.WebContents { diff --git a/src/vs/base/parts/ipc/node/ipc.cp.ts b/src/vs/base/parts/ipc/node/ipc.cp.ts index 65083397bf4..9c709880779 100644 --- a/src/vs/base/parts/ipc/node/ipc.cp.ts +++ b/src/vs/base/parts/ipc/node/ipc.cp.ts @@ -10,7 +10,7 @@ import { Delayer } from 'vs/base/common/async'; import { deepClone, assign } from 'vs/base/common/objects'; import { Emitter, fromNodeEventEmitter, Event } from 'vs/base/common/event'; import { createQueuedSender } from 'vs/base/node/processes'; -import { ChannelServer as IPCServer, ChannelClient as IPCClient, IChannelClient, IChannel } from 'vs/base/parts/ipc/common/ipc'; +import { ChannelServer as IPCServer, ChannelClient as IPCClient, IChannelClient, IChannel } from 'vs/base/parts/ipc/node/ipc'; import { isRemoteConsoleLog, log } from 'vs/base/node/console'; /** diff --git a/src/vs/base/parts/ipc/common/ipc.electron.ts b/src/vs/base/parts/ipc/node/ipc.electron.ts similarity index 94% rename from src/vs/base/parts/ipc/common/ipc.electron.ts rename to src/vs/base/parts/ipc/node/ipc.electron.ts index 6578a800a9b..56236c39d1c 100644 --- a/src/vs/base/parts/ipc/common/ipc.electron.ts +++ b/src/vs/base/parts/ipc/node/ipc.electron.ts @@ -4,7 +4,7 @@ *--------------------------------------------------------------------------------------------*/ import { IDisposable, dispose } from 'vs/base/common/lifecycle'; -import { IMessagePassingProtocol } from 'vs/base/parts/ipc/common/ipc'; +import { IMessagePassingProtocol } from 'vs/base/parts/ipc/node/ipc'; import { Event, Emitter } from 'vs/base/common/event'; /** diff --git a/src/vs/base/parts/ipc/node/ipc.net.ts b/src/vs/base/parts/ipc/node/ipc.net.ts index dc592860c30..3360b004e34 100644 --- a/src/vs/base/parts/ipc/node/ipc.net.ts +++ b/src/vs/base/parts/ipc/node/ipc.net.ts @@ -8,7 +8,7 @@ import { Socket, Server as NetServer, createConnection, createServer } from 'net'; import { TPromise } from 'vs/base/common/winjs.base'; import { Event, Emitter, once, mapEvent, fromNodeEventEmitter } from 'vs/base/common/event'; -import { IMessagePassingProtocol, ClientConnectionEvent, IPCServer, IPCClient } from 'vs/base/parts/ipc/common/ipc'; +import { IMessagePassingProtocol, ClientConnectionEvent, IPCServer, IPCClient } from 'vs/base/parts/ipc/node/ipc'; import { join } from 'path'; import { tmpdir } from 'os'; import { generateUuid } from 'vs/base/common/uuid'; diff --git a/src/vs/base/parts/ipc/common/ipc.ts b/src/vs/base/parts/ipc/node/ipc.ts similarity index 100% rename from src/vs/base/parts/ipc/common/ipc.ts rename to src/vs/base/parts/ipc/node/ipc.ts diff --git a/src/vs/base/parts/ipc/test/node/testService.ts b/src/vs/base/parts/ipc/test/node/testService.ts index f90d54708f6..51506dc67bd 100644 --- a/src/vs/base/parts/ipc/test/node/testService.ts +++ b/src/vs/base/parts/ipc/test/node/testService.ts @@ -5,7 +5,7 @@ 'use strict'; import { TPromise } from 'vs/base/common/winjs.base'; -import { IChannel } from 'vs/base/parts/ipc/common/ipc'; +import { IChannel } from 'vs/base/parts/ipc/node/ipc'; import { Event, Emitter } from 'vs/base/common/event'; export interface IMarcoPoloEvent { diff --git a/src/vs/base/test/node/uri.test.data.txt b/src/vs/base/test/node/uri.test.data.txt index bb0b5b62957..22e9869aaea 100644 --- a/src/vs/base/test/node/uri.test.data.txt +++ b/src/vs/base/test/node/uri.test.data.txt @@ -2299,8 +2299,8 @@ /users/foo/src/vs/base/parts/ipc/test/node/ipc.test.ts /users/foo/src/vs/base/parts/ipc/test/node/testService.ts /users/foo/src/vs/base/parts/ipc/common -/users/foo/src/vs/base/parts/ipc/common/ipc.electron.ts -/users/foo/src/vs/base/parts/ipc/common/ipc.ts +/users/foo/src/vs/base/parts/ipc/node/ipc.electron.ts +/users/foo/src/vs/base/parts/ipc/node/ipc.ts /users/foo/src/vs/base/parts/ipc/electron-browser /users/foo/src/vs/base/parts/ipc/electron-browser/ipc.electron-browser.ts /users/foo/src/vs/base/parts/ipc/node diff --git a/src/vs/code/electron-browser/issue/issueReporterMain.ts b/src/vs/code/electron-browser/issue/issueReporterMain.ts index 2e25cb33248..66861d351bf 100644 --- a/src/vs/code/electron-browser/issue/issueReporterMain.ts +++ b/src/vs/code/electron-browser/issue/issueReporterMain.ts @@ -19,25 +19,25 @@ import { debounce } from 'vs/base/common/decorators'; import * as platform from 'vs/base/common/platform'; import { Disposable } from 'vs/base/common/lifecycle'; import { Client as ElectronIPCClient } from 'vs/base/parts/ipc/electron-browser/ipc.electron-browser'; -import { getDelayedChannel } from 'vs/base/parts/ipc/common/ipc'; +import { getDelayedChannel } from 'vs/base/parts/ipc/node/ipc'; import { connect as connectNet } from 'vs/base/parts/ipc/node/ipc.net'; import { ServiceCollection } from 'vs/platform/instantiation/common/serviceCollection'; import { IWindowConfiguration, IWindowsService } from 'vs/platform/windows/common/windows'; import { NullTelemetryService, combinedAppender, LogAppender } from 'vs/platform/telemetry/common/telemetryUtils'; import { IEnvironmentService } from 'vs/platform/environment/common/environment'; import { ITelemetryServiceConfig, TelemetryService } from 'vs/platform/telemetry/common/telemetryService'; -import { ITelemetryAppenderChannel, TelemetryAppenderClient } from 'vs/platform/telemetry/common/telemetryIpc'; +import { ITelemetryAppenderChannel, TelemetryAppenderClient } from 'vs/platform/telemetry/node/telemetryIpc'; import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry'; import { InstantiationService } from 'vs/platform/instantiation/common/instantiationService'; import { resolveCommonProperties } from 'vs/platform/telemetry/node/commonProperties'; -import { WindowsChannelClient } from 'vs/platform/windows/common/windowsIpc'; +import { WindowsChannelClient } from 'vs/platform/windows/node/windowsIpc'; import { EnvironmentService } from 'vs/platform/environment/node/environmentService'; import { IssueReporterModel } from 'vs/code/electron-browser/issue/issueReporterModel'; import { IssueReporterData, IssueReporterStyles, IssueType, ISettingsSearchIssueReporterData, IssueReporterFeatures } from 'vs/platform/issue/common/issue'; import BaseHtml from 'vs/code/electron-browser/issue/issueReporterPage'; import { ILocalExtension } from 'vs/platform/extensionManagement/common/extensionManagement'; import { createSpdLogService } from 'vs/platform/log/node/spdlogService'; -import { LogLevelSetterChannelClient, FollowerLogService } from 'vs/platform/log/common/logIpc'; +import { LogLevelSetterChannelClient, FollowerLogService } from 'vs/platform/log/node/logIpc'; import { ILogService, getLogLevel } from 'vs/platform/log/common/log'; import { OcticonLabel } from 'vs/base/browser/ui/octiconLabel/octiconLabel'; import { normalizeGitHubUrl } from 'vs/code/electron-browser/issue/issueReporterUtil'; diff --git a/src/vs/code/electron-browser/sharedProcess/sharedProcessMain.ts b/src/vs/code/electron-browser/sharedProcess/sharedProcessMain.ts index 547d1bd99d6..41e12a59df4 100644 --- a/src/vs/code/electron-browser/sharedProcess/sharedProcessMain.ts +++ b/src/vs/code/electron-browser/sharedProcess/sharedProcessMain.ts @@ -16,7 +16,7 @@ import { SyncDescriptor } from 'vs/platform/instantiation/common/descriptors'; import { InstantiationService } from 'vs/platform/instantiation/common/instantiationService'; import { IEnvironmentService, ParsedArgs } from 'vs/platform/environment/common/environment'; import { EnvironmentService } from 'vs/platform/environment/node/environmentService'; -import { ExtensionManagementChannel } from 'vs/platform/extensionManagement/common/extensionManagementIpc'; +import { ExtensionManagementChannel } from 'vs/platform/extensionManagement/node/extensionManagementIpc'; import { IExtensionManagementService, IExtensionGalleryService } from 'vs/platform/extensionManagement/common/extensionManagement'; import { ExtensionManagementService } from 'vs/platform/extensionManagement/node/extensionManagementService'; import { ExtensionGalleryService } from 'vs/platform/extensionManagement/node/extensionGalleryService'; @@ -27,20 +27,20 @@ import { RequestService } from 'vs/platform/request/electron-browser/requestServ import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry'; import { combinedAppender, NullTelemetryService, ITelemetryAppender, NullAppender, LogAppender } from 'vs/platform/telemetry/common/telemetryUtils'; import { resolveCommonProperties } from 'vs/platform/telemetry/node/commonProperties'; -import { TelemetryAppenderChannel } from 'vs/platform/telemetry/common/telemetryIpc'; +import { TelemetryAppenderChannel } from 'vs/platform/telemetry/node/telemetryIpc'; import { TelemetryService, ITelemetryServiceConfig } from 'vs/platform/telemetry/common/telemetryService'; import { AppInsightsAppender } from 'vs/platform/telemetry/node/appInsightsAppender'; import { IWindowsService, ActiveWindowManager } from 'vs/platform/windows/common/windows'; -import { WindowsChannelClient } from 'vs/platform/windows/common/windowsIpc'; +import { WindowsChannelClient } from 'vs/platform/windows/node/windowsIpc'; import { ipcRenderer } from 'electron'; import { createSharedProcessContributions } from 'vs/code/electron-browser/sharedProcess/contrib/contributions'; import { createSpdLogService } from 'vs/platform/log/node/spdlogService'; import { ILogService, LogLevel } from 'vs/platform/log/common/log'; -import { LogLevelSetterChannelClient, FollowerLogService } from 'vs/platform/log/common/logIpc'; +import { LogLevelSetterChannelClient, FollowerLogService } from 'vs/platform/log/node/logIpc'; import { LocalizationsService } from 'vs/platform/localizations/node/localizations'; import { ILocalizationsService } from 'vs/platform/localizations/common/localizations'; -import { LocalizationsChannel } from 'vs/platform/localizations/common/localizationsIpc'; -import { DialogChannelClient } from 'vs/platform/dialogs/common/dialogIpc'; +import { LocalizationsChannel } from 'vs/platform/localizations/node/localizationsIpc'; +import { DialogChannelClient } from 'vs/platform/dialogs/node/dialogIpc'; import { IDialogService } from 'vs/platform/dialogs/common/dialogs'; import { IDisposable, dispose } from 'vs/base/common/lifecycle'; diff --git a/src/vs/code/electron-main/app.ts b/src/vs/code/electron-main/app.ts index c0185b039e9..8f10bd2b5fb 100644 --- a/src/vs/code/electron-main/app.ts +++ b/src/vs/code/electron-main/app.ts @@ -9,12 +9,12 @@ import { app, ipcMain as ipc, systemPreferences } from 'electron'; import * as platform from 'vs/base/common/platform'; import { WindowsManager } from 'vs/code/electron-main/windows'; import { IWindowsService, OpenContext, ActiveWindowManager } from 'vs/platform/windows/common/windows'; -import { WindowsChannel } from 'vs/platform/windows/common/windowsIpc'; +import { WindowsChannel } from 'vs/platform/windows/node/windowsIpc'; import { WindowsService } from 'vs/platform/windows/electron-main/windowsService'; import { ILifecycleService } from 'vs/platform/lifecycle/electron-main/lifecycleMain'; import { getShellEnvironment } from 'vs/code/node/shellEnv'; import { IUpdateService } from 'vs/platform/update/common/update'; -import { UpdateChannel } from 'vs/platform/update/common/updateIpc'; +import { UpdateChannel } from 'vs/platform/update/node/updateIpc'; import { Server as ElectronIPCServer } from 'vs/base/parts/ipc/electron-main/ipc.electron-main'; import { Server, connect, Client } from 'vs/base/parts/ipc/node/ipc.net'; import { SharedProcess } from 'vs/code/electron-main/sharedProcess'; @@ -28,13 +28,13 @@ import { IStateService } from 'vs/platform/state/common/state'; import { IEnvironmentService } from 'vs/platform/environment/common/environment'; import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; import { IURLService } from 'vs/platform/url/common/url'; -import { URLHandlerChannelClient, URLServiceChannel } from 'vs/platform/url/common/urlIpc'; +import { URLHandlerChannelClient, URLServiceChannel } from 'vs/platform/url/node/urlIpc'; import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry'; import { NullTelemetryService, combinedAppender, LogAppender } from 'vs/platform/telemetry/common/telemetryUtils'; -import { ITelemetryAppenderChannel, TelemetryAppenderClient } from 'vs/platform/telemetry/common/telemetryIpc'; +import { ITelemetryAppenderChannel, TelemetryAppenderClient } from 'vs/platform/telemetry/node/telemetryIpc'; import { TelemetryService, ITelemetryServiceConfig } from 'vs/platform/telemetry/common/telemetryService'; import { resolveCommonProperties } from 'vs/platform/telemetry/node/commonProperties'; -import { getDelayedChannel } from 'vs/base/parts/ipc/common/ipc'; +import { getDelayedChannel } from 'vs/base/parts/ipc/node/ipc'; import product from 'vs/platform/node/product'; import pkg from 'vs/platform/node/package'; import { ProxyAuthHandler } from './auth'; @@ -47,22 +47,22 @@ import { isUndefinedOrNull } from 'vs/base/common/types'; import { CodeWindow } from 'vs/code/electron-main/window'; import { KeyboardLayoutMonitor } from 'vs/code/electron-main/keyboard'; import URI from 'vs/base/common/uri'; -import { WorkspacesChannel } from 'vs/platform/workspaces/common/workspacesIpc'; +import { WorkspacesChannel } from 'vs/platform/workspaces/node/workspacesIpc'; import { IWorkspacesMainService } from 'vs/platform/workspaces/common/workspaces'; import { getMachineId } from 'vs/base/node/id'; import { Win32UpdateService } from 'vs/platform/update/electron-main/updateService.win32'; import { LinuxUpdateService } from 'vs/platform/update/electron-main/updateService.linux'; import { DarwinUpdateService } from 'vs/platform/update/electron-main/updateService.darwin'; import { IIssueService } from 'vs/platform/issue/common/issue'; -import { IssueChannel } from 'vs/platform/issue/common/issueIpc'; +import { IssueChannel } from 'vs/platform/issue/node/issueIpc'; import { IssueService } from 'vs/platform/issue/electron-main/issueService'; -import { LogLevelSetterChannel } from 'vs/platform/log/common/logIpc'; +import { LogLevelSetterChannel } from 'vs/platform/log/node/logIpc'; import * as errors from 'vs/base/common/errors'; import { ElectronURLListener } from 'vs/platform/url/electron-main/electronUrlListener'; import { serve as serveDriver } from 'vs/platform/driver/electron-main/driver'; import { IMenubarService } from 'vs/platform/menubar/common/menubar'; import { MenubarService } from 'vs/platform/menubar/electron-main/menubarService'; -import { MenubarChannel } from 'vs/platform/menubar/common/menubarIpc'; +import { MenubarChannel } from 'vs/platform/menubar/node/menubarIpc'; import { IUriLabelService } from 'vs/platform/uriLabel/common/uriLabel'; import { CodeMenu } from 'vs/code/electron-main/menus'; import { hasArgs } from 'vs/platform/environment/node/argv'; diff --git a/src/vs/code/electron-main/launch.ts b/src/vs/code/electron-main/launch.ts index a3affdb0597..352720bb914 100644 --- a/src/vs/code/electron-main/launch.ts +++ b/src/vs/code/electron-main/launch.ts @@ -6,7 +6,7 @@ 'use strict'; import { TPromise } from 'vs/base/common/winjs.base'; -import { IChannel } from 'vs/base/parts/ipc/common/ipc'; +import { IChannel } from 'vs/base/parts/ipc/node/ipc'; import { ILogService } from 'vs/platform/log/common/log'; import { IURLService } from 'vs/platform/url/common/url'; import { IProcessEnvironment, isMacintosh } from 'vs/base/common/platform'; diff --git a/src/vs/platform/dialogs/common/dialogIpc.ts b/src/vs/platform/dialogs/node/dialogIpc.ts similarity index 96% rename from src/vs/platform/dialogs/common/dialogIpc.ts rename to src/vs/platform/dialogs/node/dialogIpc.ts index 0a73419d531..06a2376ea0c 100644 --- a/src/vs/platform/dialogs/common/dialogIpc.ts +++ b/src/vs/platform/dialogs/node/dialogIpc.ts @@ -6,7 +6,7 @@ 'use strict'; import { TPromise } from 'vs/base/common/winjs.base'; -import { IChannel } from 'vs/base/parts/ipc/common/ipc'; +import { IChannel } from 'vs/base/parts/ipc/node/ipc'; import { IDialogService, IConfirmation, IConfirmationResult } from 'vs/platform/dialogs/common/dialogs'; import Severity from 'vs/base/common/severity'; import { Event } from 'vs/base/common/event'; diff --git a/src/vs/platform/driver/common/driver.ts b/src/vs/platform/driver/common/driver.ts deleted file mode 100644 index 82e907f2e25..00000000000 --- a/src/vs/platform/driver/common/driver.ts +++ /dev/null @@ -1,292 +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'; - -import { TPromise } from 'vs/base/common/winjs.base'; -import { createDecorator } from 'vs/platform/instantiation/common/instantiation'; -import { IChannel } from 'vs/base/parts/ipc/common/ipc'; -import { Event } from 'vs/base/common/event'; - -export const ID = 'driverService'; -export const IDriver = createDecorator<IDriver>(ID); - -// !! Do not remove the following START and END markers, they are parsed by the smoketest build - -//*START -export interface IElement { - tagName: string; - className: string; - textContent: string; - attributes: { [name: string]: string; }; - children: IElement[]; - top: number; - left: number; -} - -export interface IDriver { - _serviceBrand: any; - - getWindowIds(): TPromise<number[]>; - capturePage(windowId: number): TPromise<string>; - reloadWindow(windowId: number): TPromise<void>; - dispatchKeybinding(windowId: number, keybinding: string): TPromise<void>; - click(windowId: number, selector: string, xoffset?: number | undefined, yoffset?: number | undefined): TPromise<void>; - doubleClick(windowId: number, selector: string): TPromise<void>; - setValue(windowId: number, selector: string, text: string): TPromise<void>; - getTitle(windowId: number): TPromise<string>; - isActiveElement(windowId: number, selector: string): TPromise<boolean>; - getElements(windowId: number, selector: string, recursive?: boolean): TPromise<IElement[]>; - typeInEditor(windowId: number, selector: string, text: string): TPromise<void>; - getTerminalBuffer(windowId: number, selector: string): TPromise<string[]>; - writeInTerminal(windowId: number, selector: string, text: string): TPromise<void>; -} -//*END - -export interface IDriverChannel extends IChannel { - call(command: 'getWindowIds'): TPromise<number[]>; - call(command: 'capturePage'): TPromise<string>; - call(command: 'reloadWindow', arg: number): TPromise<void>; - call(command: 'dispatchKeybinding', arg: [number, string]): TPromise<void>; - call(command: 'click', arg: [number, string, number | undefined, number | undefined]): TPromise<void>; - call(command: 'doubleClick', arg: [number, string]): TPromise<void>; - call(command: 'setValue', arg: [number, string, string]): TPromise<void>; - call(command: 'getTitle', arg: [number]): TPromise<string>; - call(command: 'isActiveElement', arg: [number, string]): TPromise<boolean>; - call(command: 'getElements', arg: [number, string, boolean]): TPromise<IElement[]>; - call(command: 'typeInEditor', arg: [number, string, string]): TPromise<void>; - call(command: 'getTerminalBuffer', arg: [number, string]): TPromise<string[]>; - call(command: 'writeInTerminal', arg: [number, string, string]): TPromise<void>; - call(command: string, arg: any): TPromise<any>; -} - -export class DriverChannel implements IDriverChannel { - - constructor(private driver: IDriver) { } - - listen<T>(event: string): Event<T> { - throw new Error('No event found'); - } - - call(command: string, arg?: any): TPromise<any> { - switch (command) { - case 'getWindowIds': return this.driver.getWindowIds(); - case 'capturePage': return this.driver.capturePage(arg); - case 'reloadWindow': return this.driver.reloadWindow(arg); - case 'dispatchKeybinding': return this.driver.dispatchKeybinding(arg[0], arg[1]); - case 'click': return this.driver.click(arg[0], arg[1], arg[2], arg[3]); - case 'doubleClick': return this.driver.doubleClick(arg[0], arg[1]); - case 'setValue': return this.driver.setValue(arg[0], arg[1], arg[2]); - case 'getTitle': return this.driver.getTitle(arg[0]); - case 'isActiveElement': return this.driver.isActiveElement(arg[0], arg[1]); - case 'getElements': return this.driver.getElements(arg[0], arg[1], arg[2]); - case 'typeInEditor': return this.driver.typeInEditor(arg[0], arg[1], arg[2]); - case 'getTerminalBuffer': return this.driver.getTerminalBuffer(arg[0], arg[1]); - case 'writeInTerminal': return this.driver.writeInTerminal(arg[0], arg[1], arg[2]); - } - - return undefined; - } -} - -export class DriverChannelClient implements IDriver { - - _serviceBrand: any; - - constructor(private channel: IDriverChannel) { } - - getWindowIds(): TPromise<number[]> { - return this.channel.call('getWindowIds'); - } - - capturePage(windowId: number): TPromise<string> { - return this.channel.call('capturePage', windowId); - } - - reloadWindow(windowId: number): TPromise<void> { - return this.channel.call('reloadWindow', windowId); - } - - dispatchKeybinding(windowId: number, keybinding: string): TPromise<void> { - return this.channel.call('dispatchKeybinding', [windowId, keybinding]); - } - - click(windowId: number, selector: string, xoffset: number | undefined, yoffset: number | undefined): TPromise<void> { - return this.channel.call('click', [windowId, selector, xoffset, yoffset]); - } - - doubleClick(windowId: number, selector: string): TPromise<void> { - return this.channel.call('doubleClick', [windowId, selector]); - } - - setValue(windowId: number, selector: string, text: string): TPromise<void> { - return this.channel.call('setValue', [windowId, selector, text]); - } - - getTitle(windowId: number): TPromise<string> { - return this.channel.call('getTitle', [windowId]); - } - - isActiveElement(windowId: number, selector: string): TPromise<boolean> { - return this.channel.call('isActiveElement', [windowId, selector]); - } - - getElements(windowId: number, selector: string, recursive: boolean): TPromise<IElement[]> { - return this.channel.call('getElements', [windowId, selector, recursive]); - } - - typeInEditor(windowId: number, selector: string, text: string): TPromise<void> { - return this.channel.call('typeInEditor', [windowId, selector, text]); - } - - getTerminalBuffer(windowId: number, selector: string): TPromise<string[]> { - return this.channel.call('getTerminalBuffer', [windowId, selector]); - } - - writeInTerminal(windowId: number, selector: string, text: string): TPromise<void> { - return this.channel.call('writeInTerminal', [windowId, selector, text]); - } -} - -export interface IDriverOptions { - verbose: boolean; -} - -export interface IWindowDriverRegistry { - registerWindowDriver(windowId: number): TPromise<IDriverOptions>; - reloadWindowDriver(windowId: number): TPromise<void>; -} - -export interface IWindowDriverRegistryChannel extends IChannel { - call(command: 'registerWindowDriver', arg: number): TPromise<IDriverOptions>; - call(command: 'reloadWindowDriver', arg: number): TPromise<void>; - call(command: string, arg: any): TPromise<any>; -} - -export class WindowDriverRegistryChannel implements IWindowDriverRegistryChannel { - - constructor(private registry: IWindowDriverRegistry) { } - - listen<T>(event: string): Event<T> { - throw new Error('No event found'); - } - - call(command: string, arg?: any): TPromise<any> { - switch (command) { - case 'registerWindowDriver': return this.registry.registerWindowDriver(arg); - case 'reloadWindowDriver': return this.registry.reloadWindowDriver(arg); - } - - return undefined; - } -} - -export class WindowDriverRegistryChannelClient implements IWindowDriverRegistry { - - _serviceBrand: any; - - constructor(private channel: IWindowDriverRegistryChannel) { } - - registerWindowDriver(windowId: number): TPromise<IDriverOptions> { - return this.channel.call('registerWindowDriver', windowId); - } - - reloadWindowDriver(windowId: number): TPromise<void> { - return this.channel.call('reloadWindowDriver', windowId); - } -} - -export interface IWindowDriver { - click(selector: string, xoffset?: number | undefined, yoffset?: number | undefined): TPromise<void>; - doubleClick(selector: string): TPromise<void>; - setValue(selector: string, text: string): TPromise<void>; - getTitle(): TPromise<string>; - isActiveElement(selector: string): TPromise<boolean>; - getElements(selector: string, recursive: boolean): TPromise<IElement[]>; - typeInEditor(selector: string, text: string): TPromise<void>; - getTerminalBuffer(selector: string): TPromise<string[]>; - writeInTerminal(selector: string, text: string): TPromise<void>; -} - -export interface IWindowDriverChannel extends IChannel { - call(command: 'click', arg: [string, number | undefined, number | undefined]): TPromise<void>; - call(command: 'doubleClick', arg: string): TPromise<void>; - call(command: 'setValue', arg: [string, string]): TPromise<void>; - call(command: 'getTitle'): TPromise<string>; - call(command: 'isActiveElement', arg: string): TPromise<boolean>; - call(command: 'getElements', arg: [string, boolean]): TPromise<IElement[]>; - call(command: 'typeInEditor', arg: [string, string]): TPromise<void>; - call(command: 'getTerminalBuffer', arg: string): TPromise<string[]>; - call(command: 'writeInTerminal', arg: [string, string]): TPromise<void>; - call(command: string, arg: any): TPromise<any>; -} - -export class WindowDriverChannel implements IWindowDriverChannel { - - constructor(private driver: IWindowDriver) { } - - listen<T>(event: string): Event<T> { - throw new Error('No event found'); - } - - call(command: string, arg?: any): TPromise<any> { - switch (command) { - case 'click': return this.driver.click(arg[0], arg[1], arg[2]); - case 'doubleClick': return this.driver.doubleClick(arg); - case 'setValue': return this.driver.setValue(arg[0], arg[1]); - case 'getTitle': return this.driver.getTitle(); - case 'isActiveElement': return this.driver.isActiveElement(arg); - case 'getElements': return this.driver.getElements(arg[0], arg[1]); - case 'typeInEditor': return this.driver.typeInEditor(arg[0], arg[1]); - case 'getTerminalBuffer': return this.driver.getTerminalBuffer(arg); - case 'writeInTerminal': return this.driver.writeInTerminal(arg[0], arg[1]); - } - - return undefined; - } -} - -export class WindowDriverChannelClient implements IWindowDriver { - - _serviceBrand: any; - - constructor(private channel: IWindowDriverChannel) { } - - click(selector: string, xoffset?: number, yoffset?: number): TPromise<void> { - return this.channel.call('click', [selector, xoffset, yoffset]); - } - - doubleClick(selector: string): TPromise<void> { - return this.channel.call('doubleClick', selector); - } - - setValue(selector: string, text: string): TPromise<void> { - return this.channel.call('setValue', [selector, text]); - } - - getTitle(): TPromise<string> { - return this.channel.call('getTitle'); - } - - isActiveElement(selector: string): TPromise<boolean> { - return this.channel.call('isActiveElement', selector); - } - - getElements(selector: string, recursive: boolean): TPromise<IElement[]> { - return this.channel.call('getElements', [selector, recursive]); - } - - typeInEditor(selector: string, text: string): TPromise<void> { - return this.channel.call('typeInEditor', [selector, text]); - } - - getTerminalBuffer(selector: string): TPromise<string[]> { - return this.channel.call('getTerminalBuffer', selector); - } - - writeInTerminal(selector: string, text: string): TPromise<void> { - return this.channel.call('writeInTerminal', [selector, text]); - } -} \ No newline at end of file diff --git a/src/vs/platform/driver/electron-browser/driver.ts b/src/vs/platform/driver/electron-browser/driver.ts index 6b4d876f49d..46a202f2c79 100644 --- a/src/vs/platform/driver/electron-browser/driver.ts +++ b/src/vs/platform/driver/electron-browser/driver.ts @@ -7,8 +7,8 @@ import { TPromise } from 'vs/base/common/winjs.base'; import { IDisposable, toDisposable, combinedDisposable } from 'vs/base/common/lifecycle'; -import { IWindowDriver, IElement, WindowDriverChannel, WindowDriverRegistryChannelClient } from 'vs/platform/driver/common/driver'; -import { IPCClient } from 'vs/base/parts/ipc/common/ipc'; +import { IWindowDriver, IElement, WindowDriverChannel, WindowDriverRegistryChannelClient } from 'vs/platform/driver/node/driver'; +import { IPCClient } from 'vs/base/parts/ipc/node/ipc'; import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; import { getTopLeftOffset, getClientArea } from 'vs/base/browser/dom'; import * as electron from 'electron'; diff --git a/src/vs/platform/driver/electron-main/driver.ts b/src/vs/platform/driver/electron-main/driver.ts index f9667d4d695..a17e1d9ac75 100644 --- a/src/vs/platform/driver/electron-main/driver.ts +++ b/src/vs/platform/driver/electron-main/driver.ts @@ -6,12 +6,12 @@ 'use strict'; import { TPromise } from 'vs/base/common/winjs.base'; -import { IDriver, DriverChannel, IElement, IWindowDriverChannel, WindowDriverChannelClient, IWindowDriverRegistry, WindowDriverRegistryChannel, IWindowDriver, IDriverOptions } from 'vs/platform/driver/common/driver'; +import { IDriver, DriverChannel, IElement, IWindowDriverChannel, WindowDriverChannelClient, IWindowDriverRegistry, WindowDriverRegistryChannel, IWindowDriver, IDriverOptions } from 'vs/platform/driver/node/driver'; import { IWindowsMainService } from 'vs/platform/windows/electron-main/windows'; import { serve as serveNet } from 'vs/base/parts/ipc/node/ipc.net'; import { combinedDisposable, IDisposable } from 'vs/base/common/lifecycle'; import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; -import { IPCServer, IClientRouter } from 'vs/base/parts/ipc/common/ipc'; +import { IPCServer, IClientRouter } from 'vs/base/parts/ipc/node/ipc'; import { SimpleKeybinding, KeyCode } from 'vs/base/common/keyCodes'; import { USLayoutResolvedKeybinding } from 'vs/platform/keybinding/common/usLayoutResolvedKeybinding'; import { OS } from 'vs/base/common/platform'; diff --git a/src/vs/platform/driver/node/driver.ts b/src/vs/platform/driver/node/driver.ts index 1f5df95b0c7..5e1da358de0 100644 --- a/src/vs/platform/driver/node/driver.ts +++ b/src/vs/platform/driver/node/driver.ts @@ -5,8 +5,292 @@ 'use strict'; -import { IDriver, DriverChannelClient } from 'vs/platform/driver/common/driver'; import { connect as connectNet, Client } from 'vs/base/parts/ipc/node/ipc.net'; +import { TPromise } from 'vs/base/common/winjs.base'; +import { createDecorator } from 'vs/platform/instantiation/common/instantiation'; +import { IChannel } from 'vs/base/parts/ipc/node/ipc'; +import { Event } from 'vs/base/common/event'; + +export const ID = 'driverService'; +export const IDriver = createDecorator<IDriver>(ID); + +// !! Do not remove the following START and END markers, they are parsed by the smoketest build + +//*START +export interface IElement { + tagName: string; + className: string; + textContent: string; + attributes: { [name: string]: string; }; + children: IElement[]; + top: number; + left: number; +} + +export interface IDriver { + _serviceBrand: any; + + getWindowIds(): TPromise<number[]>; + capturePage(windowId: number): TPromise<string>; + reloadWindow(windowId: number): TPromise<void>; + dispatchKeybinding(windowId: number, keybinding: string): TPromise<void>; + click(windowId: number, selector: string, xoffset?: number | undefined, yoffset?: number | undefined): TPromise<void>; + doubleClick(windowId: number, selector: string): TPromise<void>; + setValue(windowId: number, selector: string, text: string): TPromise<void>; + getTitle(windowId: number): TPromise<string>; + isActiveElement(windowId: number, selector: string): TPromise<boolean>; + getElements(windowId: number, selector: string, recursive?: boolean): TPromise<IElement[]>; + typeInEditor(windowId: number, selector: string, text: string): TPromise<void>; + getTerminalBuffer(windowId: number, selector: string): TPromise<string[]>; + writeInTerminal(windowId: number, selector: string, text: string): TPromise<void>; +} +//*END + +export interface IDriverChannel extends IChannel { + call(command: 'getWindowIds'): TPromise<number[]>; + call(command: 'capturePage'): TPromise<string>; + call(command: 'reloadWindow', arg: number): TPromise<void>; + call(command: 'dispatchKeybinding', arg: [number, string]): TPromise<void>; + call(command: 'click', arg: [number, string, number | undefined, number | undefined]): TPromise<void>; + call(command: 'doubleClick', arg: [number, string]): TPromise<void>; + call(command: 'setValue', arg: [number, string, string]): TPromise<void>; + call(command: 'getTitle', arg: [number]): TPromise<string>; + call(command: 'isActiveElement', arg: [number, string]): TPromise<boolean>; + call(command: 'getElements', arg: [number, string, boolean]): TPromise<IElement[]>; + call(command: 'typeInEditor', arg: [number, string, string]): TPromise<void>; + call(command: 'getTerminalBuffer', arg: [number, string]): TPromise<string[]>; + call(command: 'writeInTerminal', arg: [number, string, string]): TPromise<void>; + call(command: string, arg: any): TPromise<any>; +} + +export class DriverChannel implements IDriverChannel { + + constructor(private driver: IDriver) { } + + listen<T>(event: string): Event<T> { + throw new Error('No event found'); + } + + call(command: string, arg?: any): TPromise<any> { + switch (command) { + case 'getWindowIds': return this.driver.getWindowIds(); + case 'capturePage': return this.driver.capturePage(arg); + case 'reloadWindow': return this.driver.reloadWindow(arg); + case 'dispatchKeybinding': return this.driver.dispatchKeybinding(arg[0], arg[1]); + case 'click': return this.driver.click(arg[0], arg[1], arg[2], arg[3]); + case 'doubleClick': return this.driver.doubleClick(arg[0], arg[1]); + case 'setValue': return this.driver.setValue(arg[0], arg[1], arg[2]); + case 'getTitle': return this.driver.getTitle(arg[0]); + case 'isActiveElement': return this.driver.isActiveElement(arg[0], arg[1]); + case 'getElements': return this.driver.getElements(arg[0], arg[1], arg[2]); + case 'typeInEditor': return this.driver.typeInEditor(arg[0], arg[1], arg[2]); + case 'getTerminalBuffer': return this.driver.getTerminalBuffer(arg[0], arg[1]); + case 'writeInTerminal': return this.driver.writeInTerminal(arg[0], arg[1], arg[2]); + } + + return undefined; + } +} + +export class DriverChannelClient implements IDriver { + + _serviceBrand: any; + + constructor(private channel: IDriverChannel) { } + + getWindowIds(): TPromise<number[]> { + return this.channel.call('getWindowIds'); + } + + capturePage(windowId: number): TPromise<string> { + return this.channel.call('capturePage', windowId); + } + + reloadWindow(windowId: number): TPromise<void> { + return this.channel.call('reloadWindow', windowId); + } + + dispatchKeybinding(windowId: number, keybinding: string): TPromise<void> { + return this.channel.call('dispatchKeybinding', [windowId, keybinding]); + } + + click(windowId: number, selector: string, xoffset: number | undefined, yoffset: number | undefined): TPromise<void> { + return this.channel.call('click', [windowId, selector, xoffset, yoffset]); + } + + doubleClick(windowId: number, selector: string): TPromise<void> { + return this.channel.call('doubleClick', [windowId, selector]); + } + + setValue(windowId: number, selector: string, text: string): TPromise<void> { + return this.channel.call('setValue', [windowId, selector, text]); + } + + getTitle(windowId: number): TPromise<string> { + return this.channel.call('getTitle', [windowId]); + } + + isActiveElement(windowId: number, selector: string): TPromise<boolean> { + return this.channel.call('isActiveElement', [windowId, selector]); + } + + getElements(windowId: number, selector: string, recursive: boolean): TPromise<IElement[]> { + return this.channel.call('getElements', [windowId, selector, recursive]); + } + + typeInEditor(windowId: number, selector: string, text: string): TPromise<void> { + return this.channel.call('typeInEditor', [windowId, selector, text]); + } + + getTerminalBuffer(windowId: number, selector: string): TPromise<string[]> { + return this.channel.call('getTerminalBuffer', [windowId, selector]); + } + + writeInTerminal(windowId: number, selector: string, text: string): TPromise<void> { + return this.channel.call('writeInTerminal', [windowId, selector, text]); + } +} + +export interface IDriverOptions { + verbose: boolean; +} + +export interface IWindowDriverRegistry { + registerWindowDriver(windowId: number): TPromise<IDriverOptions>; + reloadWindowDriver(windowId: number): TPromise<void>; +} + +export interface IWindowDriverRegistryChannel extends IChannel { + call(command: 'registerWindowDriver', arg: number): TPromise<IDriverOptions>; + call(command: 'reloadWindowDriver', arg: number): TPromise<void>; + call(command: string, arg: any): TPromise<any>; +} + +export class WindowDriverRegistryChannel implements IWindowDriverRegistryChannel { + + constructor(private registry: IWindowDriverRegistry) { } + + listen<T>(event: string): Event<T> { + throw new Error('No event found'); + } + + call(command: string, arg?: any): TPromise<any> { + switch (command) { + case 'registerWindowDriver': return this.registry.registerWindowDriver(arg); + case 'reloadWindowDriver': return this.registry.reloadWindowDriver(arg); + } + + return undefined; + } +} + +export class WindowDriverRegistryChannelClient implements IWindowDriverRegistry { + + _serviceBrand: any; + + constructor(private channel: IWindowDriverRegistryChannel) { } + + registerWindowDriver(windowId: number): TPromise<IDriverOptions> { + return this.channel.call('registerWindowDriver', windowId); + } + + reloadWindowDriver(windowId: number): TPromise<void> { + return this.channel.call('reloadWindowDriver', windowId); + } +} + +export interface IWindowDriver { + click(selector: string, xoffset?: number | undefined, yoffset?: number | undefined): TPromise<void>; + doubleClick(selector: string): TPromise<void>; + setValue(selector: string, text: string): TPromise<void>; + getTitle(): TPromise<string>; + isActiveElement(selector: string): TPromise<boolean>; + getElements(selector: string, recursive: boolean): TPromise<IElement[]>; + typeInEditor(selector: string, text: string): TPromise<void>; + getTerminalBuffer(selector: string): TPromise<string[]>; + writeInTerminal(selector: string, text: string): TPromise<void>; +} + +export interface IWindowDriverChannel extends IChannel { + call(command: 'click', arg: [string, number | undefined, number | undefined]): TPromise<void>; + call(command: 'doubleClick', arg: string): TPromise<void>; + call(command: 'setValue', arg: [string, string]): TPromise<void>; + call(command: 'getTitle'): TPromise<string>; + call(command: 'isActiveElement', arg: string): TPromise<boolean>; + call(command: 'getElements', arg: [string, boolean]): TPromise<IElement[]>; + call(command: 'typeInEditor', arg: [string, string]): TPromise<void>; + call(command: 'getTerminalBuffer', arg: string): TPromise<string[]>; + call(command: 'writeInTerminal', arg: [string, string]): TPromise<void>; + call(command: string, arg: any): TPromise<any>; +} + +export class WindowDriverChannel implements IWindowDriverChannel { + + constructor(private driver: IWindowDriver) { } + + listen<T>(event: string): Event<T> { + throw new Error('No event found'); + } + + call(command: string, arg?: any): TPromise<any> { + switch (command) { + case 'click': return this.driver.click(arg[0], arg[1], arg[2]); + case 'doubleClick': return this.driver.doubleClick(arg); + case 'setValue': return this.driver.setValue(arg[0], arg[1]); + case 'getTitle': return this.driver.getTitle(); + case 'isActiveElement': return this.driver.isActiveElement(arg); + case 'getElements': return this.driver.getElements(arg[0], arg[1]); + case 'typeInEditor': return this.driver.typeInEditor(arg[0], arg[1]); + case 'getTerminalBuffer': return this.driver.getTerminalBuffer(arg); + case 'writeInTerminal': return this.driver.writeInTerminal(arg[0], arg[1]); + } + + return undefined; + } +} + +export class WindowDriverChannelClient implements IWindowDriver { + + _serviceBrand: any; + + constructor(private channel: IWindowDriverChannel) { } + + click(selector: string, xoffset?: number, yoffset?: number): TPromise<void> { + return this.channel.call('click', [selector, xoffset, yoffset]); + } + + doubleClick(selector: string): TPromise<void> { + return this.channel.call('doubleClick', selector); + } + + setValue(selector: string, text: string): TPromise<void> { + return this.channel.call('setValue', [selector, text]); + } + + getTitle(): TPromise<string> { + return this.channel.call('getTitle'); + } + + isActiveElement(selector: string): TPromise<boolean> { + return this.channel.call('isActiveElement', selector); + } + + getElements(selector: string, recursive: boolean): TPromise<IElement[]> { + return this.channel.call('getElements', [selector, recursive]); + } + + typeInEditor(selector: string, text: string): TPromise<void> { + return this.channel.call('typeInEditor', [selector, text]); + } + + getTerminalBuffer(selector: string): TPromise<string[]> { + return this.channel.call('getTerminalBuffer', selector); + } + + writeInTerminal(selector: string, text: string): TPromise<void> { + return this.channel.call('writeInTerminal', [selector, text]); + } +} export async function connect(handle: string): Promise<{ client: Client, driver: IDriver }> { const client = await connectNet(handle, 'driverClient'); diff --git a/src/vs/platform/extensionManagement/common/extensionManagementIpc.ts b/src/vs/platform/extensionManagement/node/extensionManagementIpc.ts similarity index 97% rename from src/vs/platform/extensionManagement/common/extensionManagementIpc.ts rename to src/vs/platform/extensionManagement/node/extensionManagementIpc.ts index 4180af7c8a3..87e02f53354 100644 --- a/src/vs/platform/extensionManagement/common/extensionManagementIpc.ts +++ b/src/vs/platform/extensionManagement/node/extensionManagementIpc.ts @@ -6,8 +6,8 @@ 'use strict'; import { TPromise } from 'vs/base/common/winjs.base'; -import { IChannel } from 'vs/base/parts/ipc/common/ipc'; -import { IExtensionManagementService, ILocalExtension, InstallExtensionEvent, DidInstallExtensionEvent, IGalleryExtension, LocalExtensionType, DidUninstallExtensionEvent, IExtensionIdentifier, IGalleryMetadata, IReportedExtension } from './extensionManagement'; +import { IChannel } from 'vs/base/parts/ipc/node/ipc'; +import { IExtensionManagementService, ILocalExtension, InstallExtensionEvent, DidInstallExtensionEvent, IGalleryExtension, LocalExtensionType, DidUninstallExtensionEvent, IExtensionIdentifier, IGalleryMetadata, IReportedExtension } from '../common/extensionManagement'; import { Event, buffer, mapEvent } from 'vs/base/common/event'; import URI from 'vs/base/common/uri'; import { IURITransformer } from 'vs/base/common/uriIpc'; diff --git a/src/vs/platform/issue/common/issueIpc.ts b/src/vs/platform/issue/node/issueIpc.ts similarity index 95% rename from src/vs/platform/issue/common/issueIpc.ts rename to src/vs/platform/issue/node/issueIpc.ts index d45c1d870ee..e58dff508b8 100644 --- a/src/vs/platform/issue/common/issueIpc.ts +++ b/src/vs/platform/issue/node/issueIpc.ts @@ -6,8 +6,8 @@ 'use strict'; import { TPromise } from 'vs/base/common/winjs.base'; -import { IChannel } from 'vs/base/parts/ipc/common/ipc'; -import { IIssueService, IssueReporterData, ProcessExplorerData } from './issue'; +import { IChannel } from 'vs/base/parts/ipc/node/ipc'; +import { IIssueService, IssueReporterData, ProcessExplorerData } from '../common/issue'; import { Event } from 'vs/base/common/event'; export interface IIssueChannel extends IChannel { diff --git a/src/vs/platform/localizations/common/localizationsIpc.ts b/src/vs/platform/localizations/node/localizationsIpc.ts similarity index 96% rename from src/vs/platform/localizations/common/localizationsIpc.ts rename to src/vs/platform/localizations/node/localizationsIpc.ts index 2f06fb819ac..386f26d66e5 100644 --- a/src/vs/platform/localizations/common/localizationsIpc.ts +++ b/src/vs/platform/localizations/node/localizationsIpc.ts @@ -6,7 +6,7 @@ 'use strict'; import { TPromise } from 'vs/base/common/winjs.base'; -import { IChannel } from 'vs/base/parts/ipc/common/ipc'; +import { IChannel } from 'vs/base/parts/ipc/node/ipc'; import { Event, buffer } from 'vs/base/common/event'; import { ILocalizationsService, LanguageType } from 'vs/platform/localizations/common/localizations'; diff --git a/src/vs/platform/log/common/logIpc.ts b/src/vs/platform/log/node/logIpc.ts similarity index 97% rename from src/vs/platform/log/common/logIpc.ts rename to src/vs/platform/log/node/logIpc.ts index 24bccff9463..ca2cb87d67c 100644 --- a/src/vs/platform/log/common/logIpc.ts +++ b/src/vs/platform/log/node/logIpc.ts @@ -3,7 +3,7 @@ * 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 { IChannel } from 'vs/base/parts/ipc/node/ipc'; import { TPromise } from 'vs/base/common/winjs.base'; import { LogLevel, ILogService, DelegatedLogService } from 'vs/platform/log/common/log'; import { Event, buffer } from 'vs/base/common/event'; diff --git a/src/vs/platform/menubar/common/menubarIpc.ts b/src/vs/platform/menubar/node/menubarIpc.ts similarity index 96% rename from src/vs/platform/menubar/common/menubarIpc.ts rename to src/vs/platform/menubar/node/menubarIpc.ts index 25a28a13845..c75535de80c 100644 --- a/src/vs/platform/menubar/common/menubarIpc.ts +++ b/src/vs/platform/menubar/node/menubarIpc.ts @@ -4,7 +4,7 @@ *--------------------------------------------------------------------------------------------*/ 'use strict'; -import { IChannel } from 'vs/base/parts/ipc/common/ipc'; +import { IChannel } from 'vs/base/parts/ipc/node/ipc'; import { TPromise } from 'vs/base/common/winjs.base'; import { IMenubarService, IMenubarData, IMenubarKeybinding } from 'vs/platform/menubar/common/menubar'; import { Event } from 'vs/base/common/event'; diff --git a/src/vs/platform/telemetry/common/telemetryIpc.ts b/src/vs/platform/telemetry/node/telemetryIpc.ts similarity index 96% rename from src/vs/platform/telemetry/common/telemetryIpc.ts rename to src/vs/platform/telemetry/node/telemetryIpc.ts index f08e0c0969c..4f5de9b6fa9 100644 --- a/src/vs/platform/telemetry/common/telemetryIpc.ts +++ b/src/vs/platform/telemetry/node/telemetryIpc.ts @@ -6,7 +6,7 @@ 'use strict'; import { TPromise } from 'vs/base/common/winjs.base'; -import { IChannel } from 'vs/base/parts/ipc/common/ipc'; +import { IChannel } from 'vs/base/parts/ipc/node/ipc'; import { ITelemetryAppender } from 'vs/platform/telemetry/common/telemetryUtils'; import { Event } from 'vs/base/common/event'; diff --git a/src/vs/platform/update/common/updateIpc.ts b/src/vs/platform/update/node/updateIpc.ts similarity index 95% rename from src/vs/platform/update/common/updateIpc.ts rename to src/vs/platform/update/node/updateIpc.ts index aa2e8fd304e..f671ad3f004 100644 --- a/src/vs/platform/update/common/updateIpc.ts +++ b/src/vs/platform/update/node/updateIpc.ts @@ -6,10 +6,10 @@ 'use strict'; import { TPromise } from 'vs/base/common/winjs.base'; -import { IChannel } from 'vs/base/parts/ipc/common/ipc'; +import { IChannel } from 'vs/base/parts/ipc/node/ipc'; import { Event, Emitter } from 'vs/base/common/event'; import { onUnexpectedError } from 'vs/base/common/errors'; -import { IUpdateService, State } from './update'; +import { IUpdateService, State } from 'vs/platform/update/common/update'; export interface IUpdateChannel extends IChannel { listen(event: 'onStateChange'): Event<State>; diff --git a/src/vs/platform/url/common/urlIpc.ts b/src/vs/platform/url/node/urlIpc.ts similarity index 94% rename from src/vs/platform/url/common/urlIpc.ts rename to src/vs/platform/url/node/urlIpc.ts index 5cc4e919f95..e56f4e49260 100644 --- a/src/vs/platform/url/common/urlIpc.ts +++ b/src/vs/platform/url/node/urlIpc.ts @@ -6,11 +6,11 @@ 'use strict'; import { TPromise } from 'vs/base/common/winjs.base'; -import { IChannel } from 'vs/base/parts/ipc/common/ipc'; -import { IURLHandler, IURLService } from './url'; +import { IChannel } from 'vs/base/parts/ipc/node/ipc'; import URI from 'vs/base/common/uri'; import { IDisposable } from 'vs/base/common/lifecycle'; import { Event } from 'vs/base/common/event'; +import { IURLService, IURLHandler } from 'vs/platform/url/common/url'; export interface IURLServiceChannel extends IChannel { call(command: 'open', url: string): TPromise<boolean>; diff --git a/src/vs/platform/windows/common/windowsIpc.ts b/src/vs/platform/windows/node/windowsIpc.ts similarity index 99% rename from src/vs/platform/windows/common/windowsIpc.ts rename to src/vs/platform/windows/node/windowsIpc.ts index a23fd06d07a..48d66e15864 100644 --- a/src/vs/platform/windows/common/windowsIpc.ts +++ b/src/vs/platform/windows/node/windowsIpc.ts @@ -7,7 +7,7 @@ import { TPromise } from 'vs/base/common/winjs.base'; import { Event, buffer } from 'vs/base/common/event'; -import { IChannel } from 'vs/base/parts/ipc/common/ipc'; +import { IChannel } from 'vs/base/parts/ipc/node/ipc'; import { IWindowsService, INativeOpenDialogOptions, IEnterWorkspaceResult, CrashReporterStartOptions, IMessageBoxResult, MessageBoxOptions, SaveDialogOptions, OpenDialogOptions, IDevToolsOptions } from 'vs/platform/windows/common/windows'; import { IWorkspaceIdentifier, IWorkspaceFolderCreationData, ISingleFolderWorkspaceIdentifier, isWorkspaceIdentifier } from 'vs/platform/workspaces/common/workspaces'; import { IRecentlyOpened } from 'vs/platform/history/common/history'; diff --git a/src/vs/platform/workspaces/common/workspacesIpc.ts b/src/vs/platform/workspaces/node/workspacesIpc.ts similarity index 97% rename from src/vs/platform/workspaces/common/workspacesIpc.ts rename to src/vs/platform/workspaces/node/workspacesIpc.ts index e123da0b4c7..67ef8942458 100644 --- a/src/vs/platform/workspaces/common/workspacesIpc.ts +++ b/src/vs/platform/workspaces/node/workspacesIpc.ts @@ -6,7 +6,7 @@ 'use strict'; import { TPromise } from 'vs/base/common/winjs.base'; -import { IChannel } from 'vs/base/parts/ipc/common/ipc'; +import { IChannel } from 'vs/base/parts/ipc/node/ipc'; import { IWorkspacesService, IWorkspaceIdentifier, IWorkspaceFolderCreationData, IWorkspacesMainService } from 'vs/platform/workspaces/common/workspaces'; import URI from 'vs/base/common/uri'; import { Event } from 'vs/base/common/event'; diff --git a/src/vs/workbench/electron-browser/main.ts b/src/vs/workbench/electron-browser/main.ts index f69daf2f901..08edc11b168 100644 --- a/src/vs/workbench/electron-browser/main.ts +++ b/src/vs/workbench/electron-browser/main.ts @@ -26,26 +26,26 @@ import { EnvironmentService } from 'vs/platform/environment/node/environmentServ import * as gracefulFs from 'graceful-fs'; import { KeyboardMapperFactory } from 'vs/workbench/services/keybinding/electron-browser/keybindingService'; import { IWindowConfiguration, IWindowsService } from 'vs/platform/windows/common/windows'; -import { WindowsChannelClient } from 'vs/platform/windows/common/windowsIpc'; +import { WindowsChannelClient } from 'vs/platform/windows/node/windowsIpc'; import { IStorageService } from 'vs/platform/storage/common/storage'; import { IEnvironmentService } from 'vs/platform/environment/common/environment'; import { StorageService, inMemoryLocalStorageInstance, IStorage } from 'vs/platform/storage/common/storageService'; import { Client as ElectronIPCClient } from 'vs/base/parts/ipc/electron-browser/ipc.electron-browser'; import { webFrame } from 'electron'; -import { UpdateChannelClient } from 'vs/platform/update/common/updateIpc'; +import { UpdateChannelClient } from 'vs/platform/update/node/updateIpc'; import { IUpdateService } from 'vs/platform/update/common/update'; -import { URLHandlerChannel, URLServiceChannelClient } from 'vs/platform/url/common/urlIpc'; +import { URLHandlerChannel, URLServiceChannelClient } from 'vs/platform/url/node/urlIpc'; import { IURLService } from 'vs/platform/url/common/url'; -import { WorkspacesChannelClient } from 'vs/platform/workspaces/common/workspacesIpc'; +import { WorkspacesChannelClient } from 'vs/platform/workspaces/node/workspacesIpc'; import { IWorkspacesService, ISingleFolderWorkspaceIdentifier } from 'vs/platform/workspaces/common/workspaces'; import { createSpdLogService } from 'vs/platform/log/node/spdlogService'; import * as fs from 'fs'; import { ConsoleLogService, MultiplexLogService, ILogService } from 'vs/platform/log/common/log'; -import { IssueChannelClient } from 'vs/platform/issue/common/issueIpc'; +import { IssueChannelClient } from 'vs/platform/issue/node/issueIpc'; import { IIssueService } from 'vs/platform/issue/common/issue'; -import { LogLevelSetterChannelClient, FollowerLogService } from 'vs/platform/log/common/logIpc'; +import { LogLevelSetterChannelClient, FollowerLogService } from 'vs/platform/log/node/logIpc'; import { RelayURLService } from 'vs/platform/url/common/urlService'; -import { MenubarChannelClient } from 'vs/platform/menubar/common/menubarIpc'; +import { MenubarChannelClient } from 'vs/platform/menubar/node/menubarIpc'; import { IMenubarService } from 'vs/platform/menubar/common/menubar'; import { Schemas } from 'vs/base/common/network'; diff --git a/src/vs/workbench/electron-browser/shell.ts b/src/vs/workbench/electron-browser/shell.ts index 33bea4a0ca0..67a1afec44a 100644 --- a/src/vs/workbench/electron-browser/shell.ts +++ b/src/vs/workbench/electron-browser/shell.ts @@ -19,7 +19,7 @@ import pkg from 'vs/platform/node/package'; import { Workbench, IWorkbenchStartedInfo } from 'vs/workbench/electron-browser/workbench'; import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry'; import { NullTelemetryService, configurationTelemetry, combinedAppender, LogAppender } from 'vs/platform/telemetry/common/telemetryUtils'; -import { ITelemetryAppenderChannel, TelemetryAppenderClient } from 'vs/platform/telemetry/common/telemetryIpc'; +import { ITelemetryAppenderChannel, TelemetryAppenderClient } from 'vs/platform/telemetry/node/telemetryIpc'; import { TelemetryService, ITelemetryServiceConfig } from 'vs/platform/telemetry/common/telemetryService'; import ErrorTelemetry from 'vs/platform/telemetry/browser/errorTelemetry'; import { ElectronWindow } from 'vs/workbench/electron-browser/window'; @@ -57,10 +57,9 @@ import { WorkbenchModeServiceImpl } from 'vs/workbench/services/mode/common/work import { IModeService } from 'vs/editor/common/services/modeService'; import { IUntitledEditorService, UntitledEditorService } from 'vs/workbench/services/untitled/common/untitledEditorService'; import { ICrashReporterService, NullCrashReporterService, CrashReporterService } from 'vs/workbench/services/crashReporter/electron-browser/crashReporterService'; -import { getDelayedChannel, IPCClient } from 'vs/base/parts/ipc/common/ipc'; +import { getDelayedChannel, IPCClient } from 'vs/base/parts/ipc/node/ipc'; import { connect as connectNet } from 'vs/base/parts/ipc/node/ipc.net'; -import { DefaultURITransformer } from 'vs/base/common/uriIpc'; -import { IExtensionManagementChannel, ExtensionManagementChannelClient } from 'vs/platform/extensionManagement/common/extensionManagementIpc'; +import { IExtensionManagementChannel, ExtensionManagementChannelClient } from 'vs/platform/extensionManagement/node/extensionManagementIpc'; import { IExtensionManagementService, IExtensionEnablementService, IExtensionManagementServerService } from 'vs/platform/extensionManagement/common/extensionManagement'; import { ExtensionEnablementService } from 'vs/platform/extensionManagement/common/extensionEnablementService'; import { BareFontInfo } from 'vs/editor/common/config/fontInfo'; @@ -81,7 +80,7 @@ import { ILogService } from 'vs/platform/log/common/log'; import { WORKBENCH_BACKGROUND } from 'vs/workbench/common/theme'; import { stat } from 'fs'; import { join } from 'path'; -import { ILocalizationsChannel, LocalizationsChannelClient } from 'vs/platform/localizations/common/localizationsIpc'; +import { ILocalizationsChannel, LocalizationsChannelClient } from 'vs/platform/localizations/node/localizationsIpc'; import { ILocalizationsService } from 'vs/platform/localizations/common/localizations'; import { IWorkbenchIssueService } from 'vs/workbench/services/issue/common/issue'; import { WorkbenchIssueService } from 'vs/workbench/services/issue/electron-browser/workbenchIssueService'; @@ -89,13 +88,14 @@ import { INotificationService } from 'vs/platform/notification/common/notificati import { NotificationService } from 'vs/workbench/services/notification/common/notificationService'; import { IDialogService } from 'vs/platform/dialogs/common/dialogs'; import { DialogService } from 'vs/workbench/services/dialogs/electron-browser/dialogService'; -import { DialogChannel } from 'vs/platform/dialogs/common/dialogIpc'; +import { DialogChannel } from 'vs/platform/dialogs/node/dialogIpc'; import { EventType, addDisposableListener, addClass } from 'vs/base/browser/dom'; import { IOpenerService } from 'vs/platform/opener/common/opener'; import { OpenerService } from 'vs/editor/browser/services/openerService'; import { SearchHistoryService } from 'vs/workbench/services/search/node/searchHistoryService'; import { MulitExtensionManagementService } from 'vs/platform/extensionManagement/common/multiExtensionManagement'; import { ExtensionManagementServerService } from 'vs/workbench/services/extensions/node/extensionManagementServerService'; +import { DefaultURITransformer } from 'vs/base/common/uriIpc'; /** * Services that we require for the Shell diff --git a/src/vs/workbench/electron-browser/workbench.ts b/src/vs/workbench/electron-browser/workbench.ts index 78add76eb65..5a3ee22e21c 100644 --- a/src/vs/workbench/electron-browser/workbench.ts +++ b/src/vs/workbench/electron-browser/workbench.ts @@ -103,7 +103,7 @@ import { NotificationsAlerts } from 'vs/workbench/browser/parts/notifications/no import { NotificationsStatus } from 'vs/workbench/browser/parts/notifications/notificationsStatus'; import { registerNotificationCommands } from 'vs/workbench/browser/parts/notifications/notificationsCommands'; import { NotificationsToasts } from 'vs/workbench/browser/parts/notifications/notificationsToasts'; -import { IPCClient } from 'vs/base/parts/ipc/common/ipc'; +import { IPCClient } from 'vs/base/parts/ipc/node/ipc'; import { registerWindowDriver } from 'vs/platform/driver/electron-browser/driver'; import { IPreferencesService } from 'vs/workbench/services/preferences/common/preferences'; import { PreferencesService } from 'vs/workbench/services/preferences/browser/preferencesService'; diff --git a/src/vs/workbench/node/extensionHostMain.ts b/src/vs/workbench/node/extensionHostMain.ts index b848a88609d..60c93fae43e 100644 --- a/src/vs/workbench/node/extensionHostMain.ts +++ b/src/vs/workbench/node/extensionHostMain.ts @@ -20,7 +20,7 @@ import * as errors from 'vs/base/common/errors'; import * as glob from 'vs/base/common/glob'; import { ExtensionActivatedByEvent } from 'vs/workbench/api/node/extHostExtensionActivator'; import { IDisposable, dispose } from 'vs/base/common/lifecycle'; -import { IMessagePassingProtocol } from 'vs/base/parts/ipc/common/ipc'; +import { IMessagePassingProtocol } from 'vs/base/parts/ipc/node/ipc'; import { RPCProtocol } from 'vs/workbench/services/extensions/node/rpcProtocol'; import URI from 'vs/base/common/uri'; import { ExtHostLogService } from 'vs/workbench/api/node/extHostLogService'; diff --git a/src/vs/workbench/node/extensionHostProcess.ts b/src/vs/workbench/node/extensionHostProcess.ts index 75fa349e619..c2ea02afd05 100644 --- a/src/vs/workbench/node/extensionHostProcess.ts +++ b/src/vs/workbench/node/extensionHostProcess.ts @@ -8,7 +8,7 @@ import { onUnexpectedError } from 'vs/base/common/errors'; import { ExtensionHostMain, exit } from 'vs/workbench/node/extensionHostMain'; import { IInitData } from 'vs/workbench/api/node/extHost.protocol'; -import { IMessagePassingProtocol } from 'vs/base/parts/ipc/common/ipc'; +import { IMessagePassingProtocol } from 'vs/base/parts/ipc/node/ipc'; import { Protocol } from 'vs/base/parts/ipc/node/ipc.net'; import { createConnection } from 'net'; import { Event, filterEvent } from 'vs/base/common/event'; diff --git a/src/vs/workbench/parts/debug/node/debugger.ts b/src/vs/workbench/parts/debug/node/debugger.ts index a341ff73572..ccb0083218c 100644 --- a/src/vs/workbench/parts/debug/node/debugger.ts +++ b/src/vs/workbench/parts/debug/node/debugger.ts @@ -8,7 +8,7 @@ import { TPromise } from 'vs/base/common/winjs.base'; import { Client as TelemetryClient } from 'vs/base/parts/ipc/node/ipc.cp'; import * as strings from 'vs/base/common/strings'; import * as objects from 'vs/base/common/objects'; -import { TelemetryAppenderClient } from 'vs/platform/telemetry/common/telemetryIpc'; +import { TelemetryAppenderClient } from 'vs/platform/telemetry/node/telemetryIpc'; import { IJSONSchema, IJSONSchemaSnippet } from 'vs/base/common/jsonSchema'; import { IWorkspaceFolder } from 'vs/platform/workspace/common/workspace'; import { IConfig, IDebuggerContribution, IAdapterExecutable, INTERNAL_CONSOLE_OPTIONS_SCHEMA, IConfigurationManager, IDebugAdapter, IDebugConfiguration, ITerminalSettings } from 'vs/workbench/parts/debug/common/debug'; diff --git a/src/vs/workbench/parts/debug/node/telemetryApp.ts b/src/vs/workbench/parts/debug/node/telemetryApp.ts index db5e7ec6f62..490dc714fcc 100644 --- a/src/vs/workbench/parts/debug/node/telemetryApp.ts +++ b/src/vs/workbench/parts/debug/node/telemetryApp.ts @@ -5,7 +5,7 @@ import { Server } from 'vs/base/parts/ipc/node/ipc.cp'; import { AppInsightsAppender } from 'vs/platform/telemetry/node/appInsightsAppender'; -import { TelemetryAppenderChannel } from 'vs/platform/telemetry/common/telemetryIpc'; +import { TelemetryAppenderChannel } from 'vs/platform/telemetry/node/telemetryIpc'; const appender = new AppInsightsAppender(process.argv[2], JSON.parse(process.argv[3]), process.argv[4]); process.once('exit', () => appender.dispose()); diff --git a/src/vs/workbench/services/extensions/electron-browser/extensionHost.ts b/src/vs/workbench/services/extensions/electron-browser/extensionHost.ts index bc7cd00e3c0..48e978387d3 100644 --- a/src/vs/workbench/services/extensions/electron-browser/extensionHost.ts +++ b/src/vs/workbench/services/extensions/electron-browser/extensionHost.ts @@ -19,7 +19,7 @@ import { ChildProcess, fork } from 'child_process'; import { ipcRenderer as ipc } from 'electron'; import product from 'vs/platform/node/product'; import { IEnvironmentService } from 'vs/platform/environment/common/environment'; -import { IMessagePassingProtocol } from 'vs/base/parts/ipc/common/ipc'; +import { IMessagePassingProtocol } from 'vs/base/parts/ipc/node/ipc'; import { generateRandomPipeName, Protocol } from 'vs/base/parts/ipc/node/ipc.net'; import { createServer, Server, Socket } from 'net'; import { Event, Emitter, debounceEvent, mapEvent, anyEvent, fromNodeEventEmitter } from 'vs/base/common/event'; diff --git a/src/vs/workbench/services/extensions/electron-browser/extensionService.ts b/src/vs/workbench/services/extensions/electron-browser/extensionService.ts index 6e8576b4e4d..6ba4c161c5a 100644 --- a/src/vs/workbench/services/extensions/electron-browser/extensionService.ts +++ b/src/vs/workbench/services/extensions/electron-browser/extensionService.ts @@ -28,7 +28,7 @@ import { IEnvironmentService } from 'vs/platform/environment/common/environment' import { IStorageService } from 'vs/platform/storage/common/storage'; import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; import { ExtensionHostProcessWorker, IExtensionHostStarter } from 'vs/workbench/services/extensions/electron-browser/extensionHost'; -import { IMessagePassingProtocol } from 'vs/base/parts/ipc/common/ipc'; +import { IMessagePassingProtocol } from 'vs/base/parts/ipc/node/ipc'; import { ExtHostCustomersRegistry } from 'vs/workbench/api/electron-browser/extHostCustomers'; import { IWindowService } from 'vs/platform/windows/common/windows'; import { IDisposable, Disposable } from 'vs/base/common/lifecycle'; diff --git a/src/vs/workbench/services/extensions/node/rpcProtocol.ts b/src/vs/workbench/services/extensions/node/rpcProtocol.ts index b37097898e8..024e9551d87 100644 --- a/src/vs/workbench/services/extensions/node/rpcProtocol.ts +++ b/src/vs/workbench/services/extensions/node/rpcProtocol.ts @@ -6,7 +6,7 @@ import { TPromise } from 'vs/base/common/winjs.base'; import * as errors from 'vs/base/common/errors'; -import { IMessagePassingProtocol } from 'vs/base/parts/ipc/common/ipc'; +import { IMessagePassingProtocol } from 'vs/base/parts/ipc/node/ipc'; import { LazyPromise } from 'vs/workbench/services/extensions/node/lazyPromise'; import { ProxyIdentifier, IRPCProtocol } from 'vs/workbench/services/extensions/node/proxyIdentifier'; import { CharCode } from 'vs/base/common/charCode'; diff --git a/src/vs/workbench/services/files/node/watcher/nsfw/watcherIpc.ts b/src/vs/workbench/services/files/node/watcher/nsfw/watcherIpc.ts index 1502478f301..e90d6db72e0 100644 --- a/src/vs/workbench/services/files/node/watcher/nsfw/watcherIpc.ts +++ b/src/vs/workbench/services/files/node/watcher/nsfw/watcherIpc.ts @@ -6,7 +6,7 @@ 'use strict'; import { TPromise } from 'vs/base/common/winjs.base'; -import { IChannel } from 'vs/base/parts/ipc/common/ipc'; +import { IChannel } from 'vs/base/parts/ipc/node/ipc'; import { IWatcherRequest, IWatcherService, IWatcherOptions, IWatchError } from './watcher'; import { Event } from 'vs/base/common/event'; import { IRawFileChange } from 'vs/workbench/services/files/node/watcher/common'; diff --git a/src/vs/workbench/services/files/node/watcher/nsfw/watcherService.ts b/src/vs/workbench/services/files/node/watcher/nsfw/watcherService.ts index f522fba51c8..680109ec93a 100644 --- a/src/vs/workbench/services/files/node/watcher/nsfw/watcherService.ts +++ b/src/vs/workbench/services/files/node/watcher/nsfw/watcherService.ts @@ -5,7 +5,7 @@ 'use strict'; -import { getNextTickChannel } from 'vs/base/parts/ipc/common/ipc'; +import { getNextTickChannel } from 'vs/base/parts/ipc/node/ipc'; import { Client } from 'vs/base/parts/ipc/node/ipc.cp'; import { toFileChangesEvent, IRawFileChange } from 'vs/workbench/services/files/node/watcher/common'; import { IWatcherChannel, WatcherChannelClient } from 'vs/workbench/services/files/node/watcher/nsfw/watcherIpc'; diff --git a/src/vs/workbench/services/files/node/watcher/unix/watcherIpc.ts b/src/vs/workbench/services/files/node/watcher/unix/watcherIpc.ts index 1502478f301..e90d6db72e0 100644 --- a/src/vs/workbench/services/files/node/watcher/unix/watcherIpc.ts +++ b/src/vs/workbench/services/files/node/watcher/unix/watcherIpc.ts @@ -6,7 +6,7 @@ 'use strict'; import { TPromise } from 'vs/base/common/winjs.base'; -import { IChannel } from 'vs/base/parts/ipc/common/ipc'; +import { IChannel } from 'vs/base/parts/ipc/node/ipc'; import { IWatcherRequest, IWatcherService, IWatcherOptions, IWatchError } from './watcher'; import { Event } from 'vs/base/common/event'; import { IRawFileChange } from 'vs/workbench/services/files/node/watcher/common'; 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 2dc1effa571..a83b1e7590e 100644 --- a/src/vs/workbench/services/files/node/watcher/unix/watcherService.ts +++ b/src/vs/workbench/services/files/node/watcher/unix/watcherService.ts @@ -5,7 +5,7 @@ 'use strict'; -import { getNextTickChannel } from 'vs/base/parts/ipc/common/ipc'; +import { getNextTickChannel } from 'vs/base/parts/ipc/node/ipc'; import { Client } from 'vs/base/parts/ipc/node/ipc.cp'; import { toFileChangesEvent, IRawFileChange } from 'vs/workbench/services/files/node/watcher/common'; import { IWatcherChannel, WatcherChannelClient } from 'vs/workbench/services/files/node/watcher/unix/watcherIpc'; diff --git a/src/vs/workbench/services/search/node/searchIpc.ts b/src/vs/workbench/services/search/node/searchIpc.ts index 3450ab3e2fd..abbedd4b875 100644 --- a/src/vs/workbench/services/search/node/searchIpc.ts +++ b/src/vs/workbench/services/search/node/searchIpc.ts @@ -6,7 +6,7 @@ 'use strict'; import { TPromise } from 'vs/base/common/winjs.base'; -import { IChannel } from 'vs/base/parts/ipc/common/ipc'; +import { IChannel } from 'vs/base/parts/ipc/node/ipc'; import { IRawSearchService, IRawSearch, ISerializedSearchComplete, ISerializedSearchProgressItem, ITelemetryEvent } from './search'; import { Event } from 'vs/base/common/event'; diff --git a/src/vs/workbench/services/search/node/searchService.ts b/src/vs/workbench/services/search/node/searchService.ts index 9d4f029f1bb..6466f0e05f4 100644 --- a/src/vs/workbench/services/search/node/searchService.ts +++ b/src/vs/workbench/services/search/node/searchService.ts @@ -14,7 +14,7 @@ import * as strings from 'vs/base/common/strings'; import uri from 'vs/base/common/uri'; import { TPromise } from 'vs/base/common/winjs.base'; import * as pfs from 'vs/base/node/pfs'; -import { getNextTickChannel } from 'vs/base/parts/ipc/common/ipc'; +import { getNextTickChannel } from 'vs/base/parts/ipc/node/ipc'; import { Client, IIPCOptions } from 'vs/base/parts/ipc/node/ipc.cp'; import { IModelService } from 'vs/editor/common/services/modelService'; import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; diff --git a/src/vs/workbench/services/search/node/textSearchWorkerProvider.ts b/src/vs/workbench/services/search/node/textSearchWorkerProvider.ts index 14a7e52b6d6..16bc22f00b4 100644 --- a/src/vs/workbench/services/search/node/textSearchWorkerProvider.ts +++ b/src/vs/workbench/services/search/node/textSearchWorkerProvider.ts @@ -7,7 +7,7 @@ import * as os from 'os'; -import * as ipc from 'vs/base/parts/ipc/common/ipc'; +import * as ipc from 'vs/base/parts/ipc/node/ipc'; import { Client } from 'vs/base/parts/ipc/node/ipc.cp'; import { ISearchWorker, ISearchWorkerChannel, SearchWorkerChannelClient } from './worker/searchWorkerIpc'; diff --git a/src/vs/workbench/services/search/node/worker/searchWorkerIpc.ts b/src/vs/workbench/services/search/node/worker/searchWorkerIpc.ts index 70aade1c801..be137d2fc97 100644 --- a/src/vs/workbench/services/search/node/worker/searchWorkerIpc.ts +++ b/src/vs/workbench/services/search/node/worker/searchWorkerIpc.ts @@ -6,7 +6,7 @@ 'use strict'; import { TPromise } from 'vs/base/common/winjs.base'; -import { IChannel } from 'vs/base/parts/ipc/common/ipc'; +import { IChannel } from 'vs/base/parts/ipc/node/ipc'; import { ISerializedFileMatch } from '../search'; import { IPatternInfo } from 'vs/platform/search/common/search'; import { SearchWorker } from './searchWorker'; From f7b8c9b7df54f23b02fb36ba0cb12a5a96c8c4e9 Mon Sep 17 00:00:00 2001 From: Johannes Rieken <johannes.rieken@gmail.com> Date: Mon, 20 Aug 2018 17:56:20 +0200 Subject: [PATCH 1009/1276] perf - tweak data for --prof-append-timers --- .../performance/electron-browser/startupTimingsAppender.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vs/workbench/parts/performance/electron-browser/startupTimingsAppender.ts b/src/vs/workbench/parts/performance/electron-browser/startupTimingsAppender.ts index a59a7ce84e9..9bf3aeb1cf9 100644 --- a/src/vs/workbench/parts/performance/electron-browser/startupTimingsAppender.ts +++ b/src/vs/workbench/parts/performance/electron-browser/startupTimingsAppender.ts @@ -34,7 +34,7 @@ class StartupTimingsAppender implements IWorkbenchContribution { timerService.startupMetrics ]).then(([, startupMetrics]) => { - return nfcall(appendFile, appendTo, `${product.nameShort}\t${product.commit || '0000000'}\t${Date.now()}\t${startupMetrics.ellapsed}\n`); + return nfcall(appendFile, appendTo, `${startupMetrics.ellapsed}\t${product.nameLong}\t${product.commit || '0000000'}\n`); }).then(() => { windowsService.quit(); }).catch(err => { From 2dc09277aa1611e7d7099f2d6eb5b43b37f13183 Mon Sep 17 00:00:00 2001 From: Benjamin Pasero <benjpas@microsoft.com> Date: Mon, 20 Aug 2018 18:46:14 +0200 Subject: [PATCH 1010/1276] Merge "Terminal" and "Task" menu (fixes #56836) --- src/vs/code/electron-main/menus.ts | 69 +++++++------------ src/vs/platform/actions/common/actions.ts | 1 - .../browser/parts/titlebar/menubarControl.ts | 9 +-- .../electron-browser/task.contribution.ts | 28 ++++---- .../parts/terminal/common/terminalMenu.ts | 66 ++---------------- 5 files changed, 44 insertions(+), 129 deletions(-) diff --git a/src/vs/code/electron-main/menus.ts b/src/vs/code/electron-main/menus.ts index 9d5657cff26..0f11f0d2cb0 100644 --- a/src/vs/code/electron-main/menus.ts +++ b/src/vs/code/electron-main/menus.ts @@ -242,16 +242,16 @@ export class CodeMenu { const gotoMenuItem = new MenuItem({ label: this.mnemonicLabel(nls.localize({ key: 'mGoto', comment: ['&& denotes a mnemonic'] }, "&&Go")), submenu: gotoMenu }); this.setGotoMenu(gotoMenu); - // Terminal - const terminalMenu = new Menu(); - const terminalMenuItem = new MenuItem({ label: this.mnemonicLabel(nls.localize({ key: 'mTerminal', comment: ['&& denotes a mnemonic'] }, "Ter&&minal")), submenu: terminalMenu }); - this.setTerminalMenu(terminalMenu); - // Debug const debugMenu = new Menu(); const debugMenuItem = new MenuItem({ label: this.mnemonicLabel(nls.localize({ key: 'mDebug', comment: ['&& denotes a mnemonic'] }, "&&Debug")), submenu: debugMenu }); this.setDebugMenu(debugMenu); + // Terminal + const terminalMenu = new Menu(); + const terminalMenuItem = new MenuItem({ label: this.mnemonicLabel(nls.localize({ key: 'mTerminal', comment: ['&& denotes a mnemonic'] }, "&&Terminal")), submenu: terminalMenu }); + this.setTerminalMenu(terminalMenu); + // Mac: Window let macWindowMenuItem: Electron.MenuItem; if (isMacintosh) { @@ -265,10 +265,6 @@ export class CodeMenu { const helpMenuItem = new MenuItem({ label: this.mnemonicLabel(nls.localize({ key: 'mHelp', comment: ['&& denotes a mnemonic'] }, "&&Help")), submenu: helpMenu, role: 'help' }); this.setHelpMenu(helpMenu); - // Tasks - const taskMenu = new Menu(); - const taskMenuItem = new MenuItem({ label: this.mnemonicLabel(nls.localize({ key: 'mTask', comment: ['&& denotes a mnemonic'] }, "&&Tasks")), submenu: taskMenu }); - this.setTaskMenu(taskMenu); // Menu Structure if (macApplicationMenuItem) { @@ -280,9 +276,8 @@ export class CodeMenu { menubar.append(selectionMenuItem); menubar.append(viewMenuItem); menubar.append(gotoMenuItem); - menubar.append(terminalMenuItem); menubar.append(debugMenuItem); - menubar.append(taskMenuItem); + menubar.append(terminalMenuItem); if (macWindowMenuItem) { menubar.append(macWindowMenuItem); @@ -885,28 +880,33 @@ export class CodeMenu { private setTerminalMenu(terminalMenu: Electron.Menu): void { const newTerminal = this.createMenuItem(nls.localize({ key: 'miNewTerminal', comment: ['&& denotes a mnemonic'] }, "&&New Terminal"), 'workbench.action.terminal.new'); const splitTerminal = this.createMenuItem(nls.localize({ key: 'miSplitTerminal', comment: ['&& denotes a mnemonic'] }, "&&Split Terminal"), 'workbench.action.terminal.split'); - const killTerminal = this.createMenuItem(nls.localize({ key: 'miKillTerminal', comment: ['&& denotes a mnemonic'] }, "&&Kill Terminal"), 'workbench.action.terminal.kill'); - const clear = this.createMenuItem(nls.localize({ key: 'miClear', comment: ['&& denotes a mnemonic'] }, "&&Clear"), 'workbench.action.terminal.clear'); + const runActiveFile = this.createMenuItem(nls.localize({ key: 'miRunActiveFile', comment: ['&& denotes a mnemonic'] }, "Run &&Active File"), 'workbench.action.terminal.runActiveFile'); const runSelectedText = this.createMenuItem(nls.localize({ key: 'miRunSelectedText', comment: ['&& denotes a mnemonic'] }, "Run &&Selected Text"), 'workbench.action.terminal.runSelectedText'); - const scrollToPreviousCommand = this.createMenuItem(nls.localize({ key: 'miScrollToPreviousCommand', comment: ['&& denotes a mnemonic'] }, "Scroll To Previous Command"), 'workbench.action.terminal.scrollToPreviousCommand'); - const scrollToNextCommand = this.createMenuItem(nls.localize({ key: 'miScrollToNextCommand', comment: ['&& denotes a mnemonic'] }, "Scroll To Next Command"), 'workbench.action.terminal.scrollToNextCommand'); - const selectToPreviousCommand = this.createMenuItem(nls.localize({ key: 'miSelectToPreviousCommand', comment: ['&& denotes a mnemonic'] }, "Select To Previous Command"), 'workbench.action.terminal.selectToPreviousCommand'); - const selectToNextCommand = this.createMenuItem(nls.localize({ key: 'miSelectToNextCommand', comment: ['&& denotes a mnemonic'] }, "Select To Next Command"), 'workbench.action.terminal.selectToNextCommand'); + + const runTask = this.createMenuItem(nls.localize({ key: 'miRunTask', comment: ['&& denotes a mnemonic'] }, "&&Run Task..."), 'workbench.action.tasks.runTask'); + const buildTask = this.createMenuItem(nls.localize({ key: 'miBuildTask', comment: ['&& denotes a mnemonic'] }, "Run &&Build Task..."), 'workbench.action.tasks.build'); + const showTasks = this.createMenuItem(nls.localize({ key: 'miRunningTask', comment: ['&& denotes a mnemonic'] }, "Show Runnin&&g Tasks..."), 'workbench.action.tasks.showTasks'); + const restartTask = this.createMenuItem(nls.localize({ key: 'miRestartTask', comment: ['&& denotes a mnemonic'] }, "R&&estart Running Task..."), 'workbench.action.tasks.restartTask'); + const terminateTask = this.createMenuItem(nls.localize({ key: 'miTerminateTask', comment: ['&& denotes a mnemonic'] }, "&&Terminate Task..."), 'workbench.action.tasks.terminate'); + const configureTask = this.createMenuItem(nls.localize({ key: 'miConfigureTask', comment: ['&& denotes a mnemonic'] }, "&&Configure Tasks..."), 'workbench.action.tasks.configureTaskRunner'); + const configureBuildTask = this.createMenuItem(nls.localize({ key: 'miConfigureBuildTask', comment: ['&& denotes a mnemonic'] }, "Configure De&&fault Build Task..."), 'workbench.action.tasks.configureDefaultBuildTask'); const menuItems: MenuItem[] = [ newTerminal, splitTerminal, - killTerminal, __separator__(), - clear, + runTask, + buildTask, runActiveFile, runSelectedText, __separator__(), - scrollToPreviousCommand, - scrollToNextCommand, - selectToPreviousCommand, - selectToNextCommand + terminateTask, + restartTask, + showTasks, + __separator__(), + configureTask, + configureBuildTask ]; menuItems.forEach(item => terminalMenu.append(item)); @@ -1087,29 +1087,6 @@ export class CodeMenu { } } - private setTaskMenu(taskMenu: Electron.Menu): void { - const runTask = this.createMenuItem(nls.localize({ key: 'miRunTask', comment: ['&& denotes a mnemonic'] }, "&&Run Task..."), 'workbench.action.tasks.runTask'); - const buildTask = this.createMenuItem(nls.localize({ key: 'miBuildTask', comment: ['&& denotes a mnemonic'] }, "Run &&Build Task..."), 'workbench.action.tasks.build'); - const showTasks = this.createMenuItem(nls.localize({ key: 'miRunningTask', comment: ['&& denotes a mnemonic'] }, "Show Runnin&&g Tasks..."), 'workbench.action.tasks.showTasks'); - const restartTask = this.createMenuItem(nls.localize({ key: 'miRestartTask', comment: ['&& denotes a mnemonic'] }, "R&&estart Running Task..."), 'workbench.action.tasks.restartTask'); - const terminateTask = this.createMenuItem(nls.localize({ key: 'miTerminateTask', comment: ['&& denotes a mnemonic'] }, "&&Terminate Task..."), 'workbench.action.tasks.terminate'); - const configureTask = this.createMenuItem(nls.localize({ key: 'miConfigureTask', comment: ['&& denotes a mnemonic'] }, "&&Configure Tasks..."), 'workbench.action.tasks.configureTaskRunner'); - const configureBuildTask = this.createMenuItem(nls.localize({ key: 'miConfigureBuildTask', comment: ['&& denotes a mnemonic'] }, "Configure De&&fault Build Task..."), 'workbench.action.tasks.configureDefaultBuildTask'); - - [ - //__separator__(), - runTask, - buildTask, - __separator__(), - terminateTask, - restartTask, - showTasks, - __separator__(), - configureTask, - configureBuildTask - ].forEach(item => taskMenu.append(item)); - } - private openAccessibilityOptions(): void { const win = new BrowserWindow({ alwaysOnTop: true, diff --git a/src/vs/platform/actions/common/actions.ts b/src/vs/platform/actions/common/actions.ts index f0ba370d22d..e3095b53b9b 100644 --- a/src/vs/platform/actions/common/actions.ts +++ b/src/vs/platform/actions/common/actions.ts @@ -97,7 +97,6 @@ export class MenuId { static readonly MenubarSwitchGroupMenu = new MenuId(); static readonly MenubarDebugMenu = new MenuId(); static readonly MenubarNewBreakpointMenu = new MenuId(); - static readonly MenubarTasksMenu = new MenuId(); static readonly MenubarPreferencesMenu = new MenuId(); static readonly MenubarHelpMenu = new MenuId(); static readonly MenubarTerminalMenu = new MenuId(); diff --git a/src/vs/workbench/browser/parts/titlebar/menubarControl.ts b/src/vs/workbench/browser/parts/titlebar/menubarControl.ts index be531b51d72..fc7cf8af33c 100644 --- a/src/vs/workbench/browser/parts/titlebar/menubarControl.ts +++ b/src/vs/workbench/browser/parts/titlebar/menubarControl.ts @@ -69,9 +69,8 @@ export class MenubarControl extends Disposable { 'Selection': IMenu; 'View': IMenu; 'Go': IMenu; - 'Terminal': IMenu; 'Debug': IMenu; - 'Tasks': IMenu; + 'Terminal': IMenu; 'Window'?: IMenu; 'Help': IMenu; [index: string]: IMenu; @@ -83,9 +82,8 @@ export class MenubarControl extends Disposable { 'Selection': nls.localize({ key: 'mSelection', comment: ['&& denotes a mnemonic'] }, "&&Selection"), 'View': nls.localize({ key: 'mView', comment: ['&& denotes a mnemonic'] }, "&&View"), 'Go': nls.localize({ key: 'mGoto', comment: ['&& denotes a mnemonic'] }, "&&Go"), - 'Terminal': nls.localize({ key: 'mTerminal', comment: ['&& denotes a mnemonic'] }, "Ter&&minal"), 'Debug': nls.localize({ key: 'mDebug', comment: ['&& denotes a mnemonic'] }, "&&Debug"), - 'Tasks': nls.localize({ key: 'mTasks', comment: ['&& denotes a mnemonic'] }, "&&Tasks"), + 'Terminal': nls.localize({ key: 'mTerminal', comment: ['&& denotes a mnemonic'] }, "Ter&&minal"), 'Help': nls.localize({ key: 'mHelp', comment: ['&& denotes a mnemonic'] }, "&&Help") }; @@ -134,9 +132,8 @@ export class MenubarControl extends Disposable { 'Selection': this._register(this.menuService.createMenu(MenuId.MenubarSelectionMenu, this.contextKeyService)), 'View': this._register(this.menuService.createMenu(MenuId.MenubarViewMenu, this.contextKeyService)), 'Go': this._register(this.menuService.createMenu(MenuId.MenubarGoMenu, this.contextKeyService)), - 'Terminal': this._register(this.menuService.createMenu(MenuId.MenubarTerminalMenu, this.contextKeyService)), 'Debug': this._register(this.menuService.createMenu(MenuId.MenubarDebugMenu, this.contextKeyService)), - 'Tasks': this._register(this.menuService.createMenu(MenuId.MenubarTasksMenu, this.contextKeyService)), + 'Terminal': this._register(this.menuService.createMenu(MenuId.MenubarTerminalMenu, this.contextKeyService)), 'Help': this._register(this.menuService.createMenu(MenuId.MenubarHelpMenu, this.contextKeyService)) }; diff --git a/src/vs/workbench/parts/tasks/electron-browser/task.contribution.ts b/src/vs/workbench/parts/tasks/electron-browser/task.contribution.ts index f6c79e586a7..0e0288da207 100644 --- a/src/vs/workbench/parts/tasks/electron-browser/task.contribution.ts +++ b/src/vs/workbench/parts/tasks/electron-browser/task.contribution.ts @@ -2419,8 +2419,8 @@ class TaskService implements ITaskService { } } -MenuRegistry.appendMenuItem(MenuId.MenubarTasksMenu, { - group: '1_run', +MenuRegistry.appendMenuItem(MenuId.MenubarTerminalMenu, { + group: '2_run', command: { id: 'workbench.action.tasks.runTask', title: nls.localize({ key: 'miRunTask', comment: ['&& denotes a mnemonic'] }, "&&Run Task...") @@ -2428,8 +2428,8 @@ MenuRegistry.appendMenuItem(MenuId.MenubarTasksMenu, { order: 1 }); -MenuRegistry.appendMenuItem(MenuId.MenubarTasksMenu, { - group: '1_run', +MenuRegistry.appendMenuItem(MenuId.MenubarTerminalMenu, { + group: '2_run', command: { id: 'workbench.action.tasks.build', title: nls.localize({ key: 'miBuildTask', comment: ['&& denotes a mnemonic'] }, "Run &&Build Task...") @@ -2438,8 +2438,8 @@ MenuRegistry.appendMenuItem(MenuId.MenubarTasksMenu, { }); // Manage Tasks -MenuRegistry.appendMenuItem(MenuId.MenubarTasksMenu, { - group: '2_manage', +MenuRegistry.appendMenuItem(MenuId.MenubarTerminalMenu, { + group: '3_manage', command: { precondition: TASK_RUNNING_STATE, id: 'workbench.action.tasks.showTasks', @@ -2448,8 +2448,8 @@ MenuRegistry.appendMenuItem(MenuId.MenubarTasksMenu, { order: 1 }); -MenuRegistry.appendMenuItem(MenuId.MenubarTasksMenu, { - group: '2_manage', +MenuRegistry.appendMenuItem(MenuId.MenubarTerminalMenu, { + group: '3_manage', command: { precondition: TASK_RUNNING_STATE, id: 'workbench.action.tasks.restartTask', @@ -2458,8 +2458,8 @@ MenuRegistry.appendMenuItem(MenuId.MenubarTasksMenu, { order: 2 }); -MenuRegistry.appendMenuItem(MenuId.MenubarTasksMenu, { - group: '2_manage', +MenuRegistry.appendMenuItem(MenuId.MenubarTerminalMenu, { + group: '3_manage', command: { precondition: TASK_RUNNING_STATE, id: 'workbench.action.tasks.terminate', @@ -2469,8 +2469,8 @@ MenuRegistry.appendMenuItem(MenuId.MenubarTasksMenu, { }); // Configure Tasks -MenuRegistry.appendMenuItem(MenuId.MenubarTasksMenu, { - group: '3_configure', +MenuRegistry.appendMenuItem(MenuId.MenubarTerminalMenu, { + group: '4_configure', command: { id: 'workbench.action.tasks.configureTaskRunner', title: nls.localize({ key: 'miConfigureTask', comment: ['&& denotes a mnemonic'] }, "&&Configure Tasks...") @@ -2478,8 +2478,8 @@ MenuRegistry.appendMenuItem(MenuId.MenubarTasksMenu, { order: 1 }); -MenuRegistry.appendMenuItem(MenuId.MenubarTasksMenu, { - group: '3_configure', +MenuRegistry.appendMenuItem(MenuId.MenubarTerminalMenu, { + group: '4_configure', command: { id: 'workbench.action.tasks.configureDefaultBuildTask', title: nls.localize({ key: 'miConfigureBuildTask', comment: ['&& denotes a mnemonic'] }, "Configure De&&fault Build Task...") diff --git a/src/vs/workbench/parts/terminal/common/terminalMenu.ts b/src/vs/workbench/parts/terminal/common/terminalMenu.ts index 0223a9df008..873c8c688a5 100644 --- a/src/vs/workbench/parts/terminal/common/terminalMenu.ts +++ b/src/vs/workbench/parts/terminal/common/terminalMenu.ts @@ -22,9 +22,9 @@ export function setupTerminalMenu() { }); // Manage - const manageGroup = '1_manage'; + const createGroup = '1_create'; MenuRegistry.appendMenuItem(MenuId.MenubarTerminalMenu, { - group: manageGroup, + group: createGroup, command: { id: TERMINAL_COMMAND_ID.NEW, title: nls.localize({ key: 'miNewTerminal', comment: ['&& denotes a mnemonic'] }, "&&New Terminal") @@ -32,7 +32,7 @@ export function setupTerminalMenu() { order: 1 }); MenuRegistry.appendMenuItem(MenuId.MenubarTerminalMenu, { - group: manageGroup, + group: createGroup, command: { id: TERMINAL_COMMAND_ID.SPLIT, title: nls.localize({ key: 'miSplitTerminal', comment: ['&& denotes a mnemonic'] }, "&&Split Terminal"), @@ -41,34 +41,15 @@ export function setupTerminalMenu() { order: 2 }); - MenuRegistry.appendMenuItem(MenuId.MenubarTerminalMenu, { - group: manageGroup, - command: { - id: TERMINAL_COMMAND_ID.KILL, - title: nls.localize({ key: 'miKillTerminal', comment: ['&& denotes a mnemonic'] }, "&&Kill Terminal"), - precondition: ContextKeyExpr.has('terminalIsOpen') - }, - order: 3 - }); - // Run const runGroup = '2_run'; - MenuRegistry.appendMenuItem(MenuId.MenubarTerminalMenu, { - group: runGroup, - command: { - id: TERMINAL_COMMAND_ID.CLEAR, - title: nls.localize({ key: 'miClear', comment: ['&& denotes a mnemonic'] }, "&&Clear"), - precondition: ContextKeyExpr.has('terminalIsOpen') - }, - order: 1 - }); MenuRegistry.appendMenuItem(MenuId.MenubarTerminalMenu, { group: runGroup, command: { id: TERMINAL_COMMAND_ID.RUN_ACTIVE_FILE, title: nls.localize({ key: 'miRunActiveFile', comment: ['&& denotes a mnemonic'] }, "Run &&Active File") }, - order: 2 + order: 3 }); MenuRegistry.appendMenuItem(MenuId.MenubarTerminalMenu, { group: runGroup, @@ -76,45 +57,6 @@ export function setupTerminalMenu() { id: TERMINAL_COMMAND_ID.RUN_SELECTED_TEXT, title: nls.localize({ key: 'miRunSelectedText', comment: ['&& denotes a mnemonic'] }, "Run &&Selected Text") }, - order: 3 - }); - - // Navigation - const navigationGroup = '3_navigation'; - MenuRegistry.appendMenuItem(MenuId.MenubarTerminalMenu, { - group: navigationGroup, - command: { - id: TERMINAL_COMMAND_ID.SCROLL_TO_PREVIOUS_COMMAND, - title: nls.localize({ key: 'miScrollToPreviousCommand', comment: ['&& denotes a mnemonic'] }, "Scroll To Previous Command"), - precondition: ContextKeyExpr.has('terminalIsOpen') - }, - order: 1 - }); - MenuRegistry.appendMenuItem(MenuId.MenubarTerminalMenu, { - group: navigationGroup, - command: { - id: TERMINAL_COMMAND_ID.SCROLL_TO_NEXT_COMMAND, - title: nls.localize({ key: 'miScrollToNextCommand', comment: ['&& denotes a mnemonic'] }, "Scroll To Next Command"), - precondition: ContextKeyExpr.has('terminalIsOpen') - }, - order: 2 - }); - MenuRegistry.appendMenuItem(MenuId.MenubarTerminalMenu, { - group: navigationGroup, - command: { - id: TERMINAL_COMMAND_ID.SELECT_TO_PREVIOUS_COMMAND, - title: nls.localize({ key: 'miSelectToPreviousCommand', comment: ['&& denotes a mnemonic'] }, "Select To Previous Command"), - precondition: ContextKeyExpr.has('terminalIsOpen') - }, - order: 3 - }); - MenuRegistry.appendMenuItem(MenuId.MenubarTerminalMenu, { - group: navigationGroup, - command: { - id: TERMINAL_COMMAND_ID.SELECT_TO_NEXT_COMMAND, - title: nls.localize({ key: 'miSelectToNextCommand', comment: ['&& denotes a mnemonic'] }, "Select To Next Command"), - precondition: ContextKeyExpr.has('terminalIsOpen') - }, order: 4 }); } From ff8009d5d35b1b9b92317b8989139856761efbaa Mon Sep 17 00:00:00 2001 From: Benjamin Pasero <benjpas@microsoft.com> Date: Mon, 20 Aug 2018 18:46:53 +0200 Subject: [PATCH 1011/1276] Revert "open editors: focus active group even if it does not have an editor" This reverts commit 0e3a2219afbeed2996549468f6d656ce4713aeab. --- .../parts/files/electron-browser/views/openEditorsView.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vs/workbench/parts/files/electron-browser/views/openEditorsView.ts b/src/vs/workbench/parts/files/electron-browser/views/openEditorsView.ts index 58bc06b153f..a9eb1724a80 100644 --- a/src/vs/workbench/parts/files/electron-browser/views/openEditorsView.ts +++ b/src/vs/workbench/parts/files/electron-browser/views/openEditorsView.ts @@ -389,7 +389,7 @@ export class OpenEditorsView extends ViewletPanel { } private focusActiveEditor(): void { - if (this.editorGroupService.activeGroup) { + if (this.editorGroupService.activeGroup && this.editorGroupService.activeGroup.activeEditor /* could be empty */) { const index = this.getIndex(this.editorGroupService.activeGroup, this.editorGroupService.activeGroup.activeEditor); this.list.setFocus([index]); this.list.setSelection([index]); From aaa778b5e24c1af3aac43e840dce39ed861423f0 Mon Sep 17 00:00:00 2001 From: Nikolai Vavilov <vvnicholas@gmail.com> Date: Mon, 20 Aug 2018 19:55:12 +0300 Subject: [PATCH 1012/1276] Use 'r+' with truncation when saving existing files on Windows (#42899) * Use 'r+' with truncation when saving existing files on Windows Opening a file with 'w' flag removes its alternate data streams. To prevent this, extend the logic used for hidden files to all existing files. Fixes: https://github.com/Microsoft/vscode/issues/6363 * adopt truncate for saving as admin --- src/vs/code/node/cli.ts | 21 +++++++++---------- .../files/electron-browser/fileService.ts | 21 ++++++++++--------- 2 files changed, 21 insertions(+), 21 deletions(-) diff --git a/src/vs/code/node/cli.ts b/src/vs/code/node/cli.ts index 3ca3fd9ec94..a5f35fb14c1 100644 --- a/src/vs/code/node/cli.ts +++ b/src/vs/code/node/cli.ts @@ -87,18 +87,17 @@ export async function main(argv: string[]): Promise<any> { // Write source to target const data = fs.readFileSync(source); - try { + if (isWindows) { + // On Windows we use a different strategy of saving the file + // by first truncating the file and then writing with r+ mode. + // This helps to save hidden files on Windows + // (see https://github.com/Microsoft/vscode/issues/931) and + // prevent removing alternate data streams + // (see https://github.com/Microsoft/vscode/issues/6363) + fs.truncateSync(target, 0); + writeFileAndFlushSync(target, data, { flag: 'r+' }); + } else { writeFileAndFlushSync(target, data); - } catch (error) { - // On Windows and if the file exists with an EPERM error, we try a different strategy of saving the file - // by first truncating the file and then writing with r+ mode. This helps to save hidden files on Windows - // (see https://github.com/Microsoft/vscode/issues/931) - if (isWindows && error.code === 'EPERM') { - fs.truncateSync(target, 0); - writeFileAndFlushSync(target, data, { flag: 'r+' }); - } else { - throw error; - } } // Restore previous mode as needed diff --git a/src/vs/workbench/services/files/electron-browser/fileService.ts b/src/vs/workbench/services/files/electron-browser/fileService.ts index b91d4371d27..44a594f32b3 100644 --- a/src/vs/workbench/services/files/electron-browser/fileService.ts +++ b/src/vs/workbench/services/files/electron-browser/fileService.ts @@ -607,22 +607,23 @@ export class FileService extends Disposable implements IFileService { return addBomPromise.then(addBom => { // 4.) set contents and resolve - return this.doSetContentsAndResolve(resource, absolutePath, value, addBom, encodingToWrite).then(void 0, error => { - if (!exists || error.code !== 'EPERM' || !isWindows) { - return TPromise.wrapError(error); - } + if (!exists || !isWindows) { + return this.doSetContentsAndResolve(resource, absolutePath, value, addBom, encodingToWrite); + } - // On Windows and if the file exists with an EPERM error, we try a different strategy of saving the file - // by first truncating the file and then writing with r+ mode. This helps to save hidden files on Windows - // (see https://github.com/Microsoft/vscode/issues/931) + // On Windows and if the file exists, we use a different strategy of saving the file + // by first truncating the file and then writing with r+ mode. This helps to save hidden files on Windows + // (see https://github.com/Microsoft/vscode/issues/931) and prevent removing alternate data streams + // (see https://github.com/Microsoft/vscode/issues/6363) + else { - // 5.) truncate + // 4.) truncate return pfs.truncate(absolutePath, 0).then(() => { - // 6.) set contents (this time with r+ mode) and resolve again + // 5.) set contents (with r+ mode) and resolve return this.doSetContentsAndResolve(resource, absolutePath, value, addBom, encodingToWrite, { flag: 'r+' }); }); - }); + } }); }); }).then(null, error => { From f54c36f7b997a8e5e934397719b28ff0ec1ff45a Mon Sep 17 00:00:00 2001 From: Benjamin Pasero <benjpas@microsoft.com> Date: Mon, 20 Aug 2018 19:03:25 +0200 Subject: [PATCH 1013/1276] fix tests --- .../services/bulkEdit/electron-browser/bulkEditService.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vs/workbench/services/bulkEdit/electron-browser/bulkEditService.ts b/src/vs/workbench/services/bulkEdit/electron-browser/bulkEditService.ts index e7ab928dda6..8e787b56880 100644 --- a/src/vs/workbench/services/bulkEdit/electron-browser/bulkEditService.ts +++ b/src/vs/workbench/services/bulkEdit/electron-browser/bulkEditService.ts @@ -180,7 +180,7 @@ class BulkEditModel implements IDisposable { if (!model || !model.textEditorModel) { throw new Error(`Cannot load file ${key}`); } - if (model.isReadonly) { + if (model.isReadonly()) { throw new Error(localize('editorIsReadonly', "Cannot edit a read-only editor.")); } From 334c4051e0c80c5febb3bc88f9fbb86f75925740 Mon Sep 17 00:00:00 2001 From: Rob Lourens <roblourens@gmail.com> Date: Mon, 20 Aug 2018 11:20:22 -0700 Subject: [PATCH 1014/1276] Fix #56726 - don't block "shift+f10" in input boxes in the settings tree --- src/vs/base/parts/tree/browser/treeView.ts | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/vs/base/parts/tree/browser/treeView.ts b/src/vs/base/parts/tree/browser/treeView.ts index 6b1e97a1a7f..5616313787e 100644 --- a/src/vs/base/parts/tree/browser/treeView.ts +++ b/src/vs/base/parts/tree/browser/treeView.ts @@ -1315,15 +1315,15 @@ export class TreeView extends HeightMap { this.didJustPressContextMenuKey = event.keyCode === KeyCode.ContextMenu || (event.shiftKey && event.keyCode === KeyCode.F10); + if (event.target && event.target.tagName && event.target.tagName.toLowerCase() === 'input') { + return; // Ignore event if target is a form input field (avoids browser specific issues) + } + if (this.didJustPressContextMenuKey) { event.preventDefault(); event.stopPropagation(); } - if (event.target && event.target.tagName && event.target.tagName.toLowerCase() === 'input') { - return; // Ignore event if target is a form input field (avoids browser specific issues) - } - this.context.controller.onKeyDown(this.context.tree, event); } From ac6a7ad54b5d956ba3eccb46ff63bad97c25a28b Mon Sep 17 00:00:00 2001 From: Joao Moreno <joao.moreno@microsoft.com> Date: Mon, 20 Aug 2018 21:07:05 +0200 Subject: [PATCH 1015/1276] fix driver copy task --- test/smoke/tools/copy-driver-definition.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/smoke/tools/copy-driver-definition.js b/test/smoke/tools/copy-driver-definition.js index fedf0c28432..643e60a67fe 100644 --- a/test/smoke/tools/copy-driver-definition.js +++ b/test/smoke/tools/copy-driver-definition.js @@ -7,7 +7,7 @@ const fs = require('fs'); const path = require('path'); const root = path.dirname(path.dirname(path.dirname(__dirname))); -const driverPath = path.join(root, 'src/vs/platform/driver/common/driver.ts'); +const driverPath = path.join(root, 'src/vs/platform/driver/node/driver.ts'); let contents = fs.readFileSync(driverPath, 'utf8'); contents = /\/\/\*START([\s\S]*)\/\/\*END/mi.exec(contents)[1].trim(); From af9d9ac56087a7b2ec7024cd44c824654a34bc96 Mon Sep 17 00:00:00 2001 From: Rachel Macfarlane <ramacfar@microsoft.com> Date: Mon, 20 Aug 2018 12:54:03 -0700 Subject: [PATCH 1016/1276] Preserve focus on comments panel when selecting comments, fixes https://github.com/Microsoft/vscode-pull-request-github/issues/198 --- .../parts/comments/electron-browser/commentThreadWidget.ts | 3 --- .../workbench/parts/comments/electron-browser/commentsPanel.ts | 1 - 2 files changed, 4 deletions(-) diff --git a/src/vs/workbench/parts/comments/electron-browser/commentThreadWidget.ts b/src/vs/workbench/parts/comments/electron-browser/commentThreadWidget.ts index 7b3b6262081..992b6092d61 100644 --- a/src/vs/workbench/parts/comments/electron-browser/commentThreadWidget.ts +++ b/src/vs/workbench/parts/comments/electron-browser/commentThreadWidget.ts @@ -175,8 +175,6 @@ export class ReviewZoneWidget extends ZoneWidget { this.show({ lineNumber: this._commentThread.range.startLineNumber, column: 1 }, 2); } - this._bodyElement.focus(); - if (commentId) { let height = this.editor.getLayoutInfo().height; let matchedNode = this._commentElements.filter(commentNode => commentNode.comment.commentId === commentId); @@ -185,7 +183,6 @@ export class ReviewZoneWidget extends ZoneWidget { const commentCoords = dom.getDomNodePagePosition(matchedNode[0].domNode); this.editor.setScrollTop(this.editor.getTopForLineNumber(this._commentThread.range.startLineNumber) - height / 2 + commentCoords.top - commentThreadCoords.top); - matchedNode[0].focus(); return; } } diff --git a/src/vs/workbench/parts/comments/electron-browser/commentsPanel.ts b/src/vs/workbench/parts/comments/electron-browser/commentsPanel.ts index 4701e552987..44c69e089f7 100644 --- a/src/vs/workbench/parts/comments/electron-browser/commentsPanel.ts +++ b/src/vs/workbench/parts/comments/electron-browser/commentsPanel.ts @@ -232,7 +232,6 @@ export class CommentsPanel extends Panel { const control = editor.getControl(); if (threadToReveal && isCodeEditor(control)) { const controller = ReviewController.get(control); - console.log(commentToReveal.command); controller.revealCommentThread(threadToReveal, commentToReveal.commentId); } setCommentsForFile = null; From 84ad71193cc4a8e98613aa7f94f76fb9a16a8d3d Mon Sep 17 00:00:00 2001 From: Sandeep Somavarapu <sasomava@microsoft.com> Date: Mon, 20 Aug 2018 23:39:05 +0200 Subject: [PATCH 1017/1276] Use URI transformer for download service channel --- .../electron-browser/sharedProcess/sharedProcessMain.ts | 3 ++- src/vs/platform/download/node/downloadIpc.ts | 6 ++++-- .../extensionManagement/common/extensionManagementIpc.ts | 6 +++--- src/vs/workbench/electron-browser/shell.ts | 2 +- 4 files changed, 10 insertions(+), 7 deletions(-) diff --git a/src/vs/code/electron-browser/sharedProcess/sharedProcessMain.ts b/src/vs/code/electron-browser/sharedProcess/sharedProcessMain.ts index c8c5fb57de0..5a361b5f4ad 100644 --- a/src/vs/code/electron-browser/sharedProcess/sharedProcessMain.ts +++ b/src/vs/code/electron-browser/sharedProcess/sharedProcessMain.ts @@ -45,6 +45,7 @@ import { IDialogService } from 'vs/platform/dialogs/common/dialogs'; import { IDisposable, dispose } from 'vs/base/common/lifecycle'; import { IDownloadService } from 'vs/platform/download/common/download'; import { DownloadServiceChannelClient } from 'vs/platform/download/node/downloadIpc'; +import { DefaultURITransformer } from 'vs/base/common/uriIpc'; export interface ISharedProcessConfiguration { readonly machineId: string; @@ -91,7 +92,7 @@ function main(server: Server, initData: ISharedProcessInitData, configuration: I services.set(IDialogService, new DialogChannelClient(dialogChannel)); const downloadChannel = server.getChannel('download', { routeCall: route, routeEvent: route }); - services.set(IDownloadService, new DownloadServiceChannelClient(downloadChannel)); + services.set(IDownloadService, new DownloadServiceChannelClient(downloadChannel, DefaultURITransformer)); const instantiationService = new InstantiationService(services); diff --git a/src/vs/platform/download/node/downloadIpc.ts b/src/vs/platform/download/node/downloadIpc.ts index 89b77323fc8..8dca2440d29 100644 --- a/src/vs/platform/download/node/downloadIpc.ts +++ b/src/vs/platform/download/node/downloadIpc.ts @@ -14,6 +14,7 @@ import { Event, Emitter, buffer } from 'vs/base/common/event'; import { IDownloadService } from 'vs/platform/download/common/download'; import { mkdirp } from 'vs/base/node/pfs'; import { onUnexpectedError } from 'vs/base/common/errors'; +import { IURITransformer } from 'vs/base/common/uriIpc'; export type UploadResponse = Buffer | Error | undefined; @@ -75,7 +76,7 @@ export class DownloadServiceChannel implements IDownloadServiceChannel { listen(event: string, arg?: any): Event<any> { switch (event) { - case 'upload': return buffer(upload(arg)); + case 'upload': return buffer(upload(URI.revive(arg))); } return undefined; } @@ -89,9 +90,10 @@ export class DownloadServiceChannelClient implements IDownloadService { _serviceBrand: any; - constructor(private channel: IDownloadServiceChannel) { } + constructor(private channel: IDownloadServiceChannel, private uriTransformer: IURITransformer) { } download(from: URI, to: string): TPromise<void> { + from = this.uriTransformer.transformOutgoing(from); const dirName = path.dirname(to); let out: fs.WriteStream; return new TPromise((c, e) => { diff --git a/src/vs/platform/extensionManagement/common/extensionManagementIpc.ts b/src/vs/platform/extensionManagement/common/extensionManagementIpc.ts index 40048fe5efa..236e45979b3 100644 --- a/src/vs/platform/extensionManagement/common/extensionManagementIpc.ts +++ b/src/vs/platform/extensionManagement/common/extensionManagementIpc.ts @@ -87,15 +87,15 @@ export class ExtensionManagementChannelClient implements IExtensionManagementSer get onDidUninstallExtension(): Event<DidUninstallExtensionEvent> { return this.channel.listen('onDidUninstallExtension'); } zip(extension: ILocalExtension): TPromise<URI> { - return this.channel.call('zip', [extension]).then(result => URI.revive(this.uriTransformer.transformIncoming(result))); + return this.channel.call('zip', [this._transformOutgoing(extension)]).then(result => URI.revive(this.uriTransformer.transformIncoming(result))); } unzip(zipLocation: URI): TPromise<void> { - return this.channel.call('unzip', [zipLocation]); + return this.channel.call('unzip', [this.uriTransformer.transformOutgoing(zipLocation)]); } install(vsix: URI): TPromise<void> { - return this.channel.call('install', [vsix]); + return this.channel.call('install', [this.uriTransformer.transformOutgoing(vsix)]); } installFromGallery(extension: IGalleryExtension): TPromise<void> { diff --git a/src/vs/workbench/electron-browser/shell.ts b/src/vs/workbench/electron-browser/shell.ts index 00236f97a7b..d440340a68b 100644 --- a/src/vs/workbench/electron-browser/shell.ts +++ b/src/vs/workbench/electron-browser/shell.ts @@ -339,7 +339,7 @@ export class WorkbenchShell extends Disposable { sharedProcess .done(client => { - client.registerChannel('download', instantiationService.createInstance(DownloadServiceChannel)); + client.registerChannel('download', new DownloadServiceChannel()); client.registerChannel('dialog', instantiationService.createInstance(DialogChannel)); }); From 0b772cda9c53f5ee858fdd6b1f0a0f12b5bddc51 Mon Sep 17 00:00:00 2001 From: Daniel Imms <daimms@microsoft.com> Date: Mon, 20 Aug 2018 15:15:21 -0700 Subject: [PATCH 1018/1276] Prevent undefined from showing up in terminal dropdown Prefer empty string --- src/vs/workbench/parts/terminal/common/terminalService.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vs/workbench/parts/terminal/common/terminalService.ts b/src/vs/workbench/parts/terminal/common/terminalService.ts index c1650928b9d..69b56fe9739 100644 --- a/src/vs/workbench/parts/terminal/common/terminalService.ts +++ b/src/vs/workbench/parts/terminal/common/terminalService.ts @@ -117,7 +117,7 @@ export abstract class TerminalService implements ITerminalService { } public getTabLabels(): string[] { - return this._terminalTabs.filter(tab => tab.terminalInstances.length > 0).map((tab, index) => `${index + 1}: ${tab.title}`); + return this._terminalTabs.filter(tab => tab.terminalInstances.length > 0).map((tab, index) => `${index + 1}: ${tab.title ? tab.title : ''}`); } private _removeTab(tab: ITerminalTab): void { From 61cb8d0ef0cbf10ef72011351458fe2a5b980b13 Mon Sep 17 00:00:00 2001 From: Daniel Imms <daimms@microsoft.com> Date: Mon, 20 Aug 2018 15:47:22 -0700 Subject: [PATCH 1019/1276] Give terminal process listeners a chance to init --- src/vs/workbench/parts/terminal/node/terminalProcess.ts | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/vs/workbench/parts/terminal/node/terminalProcess.ts b/src/vs/workbench/parts/terminal/node/terminalProcess.ts index 5500c17791a..5da6bdacde8 100644 --- a/src/vs/workbench/parts/terminal/node/terminalProcess.ts +++ b/src/vs/workbench/parts/terminal/node/terminalProcess.ts @@ -79,7 +79,11 @@ export class TerminalProcess implements ITerminalChildProcess, IDisposable { } private _setupTitlePolling() { - this._sendProcessTitle(); + // Send initial timeout async to give event listeners a chance to init + setTimeout(() => { + this._sendProcessTitle(); + }, 0); + // Setup polling setInterval(() => { if (this._currentTitle !== this._ptyProcess.process) { this._sendProcessTitle(); From 32cb4411058c0301f22009a25c7fbbb6581a31b9 Mon Sep 17 00:00:00 2001 From: Rachel Macfarlane <ramacfar@microsoft.com> Date: Mon, 20 Aug 2018 15:56:19 -0700 Subject: [PATCH 1020/1276] Localize strings in commentThreadWidget --- .../electron-browser/commentThreadWidget.ts | 46 +++++++++---------- .../electron-browser/media/review.css | 4 -- 2 files changed, 22 insertions(+), 28 deletions(-) diff --git a/src/vs/workbench/parts/comments/electron-browser/commentThreadWidget.ts b/src/vs/workbench/parts/comments/electron-browser/commentThreadWidget.ts index 992b6092d61..d5a2d3db43b 100644 --- a/src/vs/workbench/parts/comments/electron-browser/commentThreadWidget.ts +++ b/src/vs/workbench/parts/comments/electron-browser/commentThreadWidget.ts @@ -99,9 +99,7 @@ export class CommentNode { let INMEM_MODEL_ID = 0; export class ReviewZoneWidget extends ZoneWidget { private _headElement: HTMLElement; - protected _primaryHeading: HTMLElement; - protected _secondaryHeading: HTMLElement; - protected _metaHeading: HTMLElement; + protected _headingLabel: HTMLElement; protected _actionbarWidget: ActionBar; private _bodyElement: HTMLElement; private _commentEditor: ICodeEditor; @@ -205,13 +203,8 @@ export class ReviewZoneWidget extends ZoneWidget { appendTo(this._headElement). getHTMLElement(); - this._primaryHeading = $('span.filename').appendTo(titleElement).getHTMLElement(); - this._secondaryHeading = $('span.dirname').appendTo(titleElement).getHTMLElement(); - this._metaHeading = $('span.meta').appendTo(titleElement).getHTMLElement(); - - if (this._commentThread.comments.length) { - this.createParticipantsLabel(); - } + this._headingLabel = $('span.filename').appendTo(titleElement).getHTMLElement(); + this.createThreadLabel(); const actionsContainer = $('.review-actions').appendTo(this._headElement); this._actionbarWidget = new ActionBar(actionsContainer.getHTMLElement(), {}); @@ -288,8 +281,7 @@ export class ReviewZoneWidget extends ZoneWidget { this._commentThread = commentThread; this._commentElements = newCommentNodeList; - let secondaryHeading = this._commentThread.comments.filter(arrays.uniqueFilter(comment => comment.userName)).map(comment => `@${comment.userName}`).join(', '); - $(this._secondaryHeading).safeInnerHtml(secondaryHeading); + this.createThreadLabel(); } protected _doLayout(heightInPixel: number, widthInPixel: number): void { @@ -423,7 +415,6 @@ export class ReviewZoneWidget extends ZoneWidget { if (newCommentThread) { this.createReplyButton(); - this.createParticipantsLabel(); } } @@ -446,20 +437,23 @@ export class ReviewZoneWidget extends ZoneWidget { } } - createParticipantsLabel() { - const primaryHeading = 'Participants:'; - $(this._primaryHeading).safeInnerHtml(primaryHeading); - this._primaryHeading.setAttribute('aria-label', primaryHeading); + private createThreadLabel() { + let label: string; + if (this._commentThread.comments.length) { + const participantsList = this._commentThread.comments.filter(arrays.uniqueFilter(comment => comment.userName)).map(comment => `@${comment.userName}`).join(', '); + label = nls.localize('commentThreadParticipants', "Participants: {0}", participantsList); + } else { + label = nls.localize('startThread', "Start discussion"); + } - const secondaryHeading = this._commentThread.comments.filter(arrays.uniqueFilter(comment => comment.userName)).map(comment => `@${comment.userName}`).join(', '); - $(this._secondaryHeading).safeInnerHtml(secondaryHeading); - this._secondaryHeading.setAttribute('aria-label', secondaryHeading); + $(this._headingLabel).safeInnerHtml(label); + this._headingLabel.setAttribute('aria-label', label); } - createReplyButton() { + private createReplyButton() { this._reviewThreadReplyButton = <HTMLButtonElement>$('button.review-thread-reply-button').appendTo(this._commentForm).getHTMLElement(); - this._reviewThreadReplyButton.title = 'Reply...'; - this._reviewThreadReplyButton.textContent = 'Reply...'; + this._reviewThreadReplyButton.title = nls.localize('reply', "Reply..."); + this._reviewThreadReplyButton.textContent = nls.localize('reply', "Reply..."); // bind click/escape actions for reviewThreadReplyButton and textArea this._reviewThreadReplyButton.onclick = () => { if (!dom.hasClass(this._commentForm, 'expand')) { @@ -493,7 +487,11 @@ export class ReviewZoneWidget extends ZoneWidget { if (model) { let valueLength = model.getValueLength(); const hasExistingComments = this._commentThread.comments.length > 0; - let placeholder = valueLength > 0 ? '' : (hasExistingComments ? 'Reply... (press Ctrl+Enter to submit)' : 'Type a new comment (press Ctrl+Enter to submit)'); + let placeholder = valueLength > 0 + ? '' + : (hasExistingComments + ? nls.localize('replytoCommentThread', "Reply... (press Ctrl+Enter to submit)") + : nls.localize('createCommentThread', "Type a new comment (press Ctrl+Enter to submit)")); const decorations = [{ range: { startLineNumber: 0, diff --git a/src/vs/workbench/parts/comments/electron-browser/media/review.css b/src/vs/workbench/parts/comments/electron-browser/media/review.css index 6a3d41dd41d..fec55286837 100644 --- a/src/vs/workbench/parts/comments/electron-browser/media/review.css +++ b/src/vs/workbench/parts/comments/electron-browser/media/review.css @@ -223,10 +223,6 @@ cursor: pointer; } -.monaco-editor .review-widget .head .review-title .filename:empty::after { - content: "Start discussion"; -} - .monaco-editor .review-widget .head .review-title .dirname:not(:empty) { font-size: 0.9em; margin-left: 0.5em; From f8168e6c2ed6da949c1b7137e69e0499913b5792 Mon Sep 17 00:00:00 2001 From: Daniel Imms <daimms@microsoft.com> Date: Mon, 20 Aug 2018 16:16:52 -0700 Subject: [PATCH 1021/1276] Don't request terminal processes before ext host is ready --- .../terminal/node/terminalProcessExtHostProxy.ts | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/src/vs/workbench/parts/terminal/node/terminalProcessExtHostProxy.ts b/src/vs/workbench/parts/terminal/node/terminalProcessExtHostProxy.ts index 52bc33c6fa5..cac16c5ff22 100644 --- a/src/vs/workbench/parts/terminal/node/terminalProcessExtHostProxy.ts +++ b/src/vs/workbench/parts/terminal/node/terminalProcessExtHostProxy.ts @@ -7,6 +7,7 @@ import { ITerminalChildProcess } from 'vs/workbench/parts/terminal/node/terminal import { Event, Emitter } from 'vs/base/common/event'; import { ITerminalService, ITerminalProcessExtHostProxy, IShellLaunchConfig } from 'vs/workbench/parts/terminal/common/terminal'; import { IDisposable } from 'vs/base/common/lifecycle'; +import { IExtensionService } from 'vs/workbench/services/extensions/common/extensions'; export class TerminalProcessExtHostProxy implements ITerminalChildProcess, ITerminalProcessExtHostProxy { private _disposables: IDisposable[] = []; @@ -32,10 +33,15 @@ export class TerminalProcessExtHostProxy implements ITerminalChildProcess, ITerm shellLaunchConfig: IShellLaunchConfig, cols: number, rows: number, - @ITerminalService private _terminalService: ITerminalService + @ITerminalService private _terminalService: ITerminalService, + @IExtensionService private readonly _extensionService: IExtensionService ) { - // TODO: Return TPromise<boolean> indicating success? Teardown if failure? - this._terminalService.requestExtHostProcess(this, shellLaunchConfig, cols, rows); + this._extensionService.whenInstalledExtensionsRegistered().then(() => { + // TODO: MainThreadTerminalService is not ready at this point, fix this + setTimeout(() => { + this._terminalService.requestExtHostProcess(this, shellLaunchConfig, cols, rows); + }, 0); + }); } public dispose(): void { From 4c05804c47730e88f1e079fd5163516639648cce Mon Sep 17 00:00:00 2001 From: Ramya Achutha Rao <ramyar@microsoft.com> Date: Mon, 20 Aug 2018 17:58:50 -0700 Subject: [PATCH 1022/1276] Update GDPR annotation errors --- .../workbench/services/textfile/common/textFileEditorModel.ts | 4 ++-- .../workbench/services/timer/electron-browser/timerService.ts | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/vs/workbench/services/textfile/common/textFileEditorModel.ts b/src/vs/workbench/services/textfile/common/textFileEditorModel.ts index bc21ebdd62e..b9e1a1a9937 100644 --- a/src/vs/workbench/services/textfile/common/textFileEditorModel.ts +++ b/src/vs/workbench/services/textfile/common/textFileEditorModel.ts @@ -357,7 +357,7 @@ export class TextFileEditorModel extends BaseTextEditorModel implements ITextFil if (settingsType) { /* __GDPR__ "settingsRead" : { - "settingsType": { "classification": "SystemMetaData", "purpose": "FeatureInsight" }, + "settingsType": { "classification": "SystemMetaData", "purpose": "FeatureInsight" } } */ this.telemetryService.publicLog('settingsRead', { settingsType }); // Do not log read to user settings.json and .vscode folder as a fileGet event as it ruins our JSON usage data @@ -719,7 +719,7 @@ export class TextFileEditorModel extends BaseTextEditorModel implements ITextFil if (settingsType) { /* __GDPR__ "settingsWritten" : { - "settingsType": { "classification": "SystemMetaData", "purpose": "FeatureInsight" }, + "settingsType": { "classification": "SystemMetaData", "purpose": "FeatureInsight" } } */ this.telemetryService.publicLog('settingsWritten', { settingsType }); // Do not log write to user settings.json and .vscode folder as a filePUT event as it ruins our JSON usage data diff --git a/src/vs/workbench/services/timer/electron-browser/timerService.ts b/src/vs/workbench/services/timer/electron-browser/timerService.ts index feb7c0b467b..3134aa7889c 100644 --- a/src/vs/workbench/services/timer/electron-browser/timerService.ts +++ b/src/vs/workbench/services/timer/electron-browser/timerService.ts @@ -47,7 +47,7 @@ export interface IMemoryInfo { "windowCount": { "classification": "SystemMetaData", "purpose": "PerformanceAndHealth" }, "viewletId": { "classification": "SystemMetaData", "purpose": "PerformanceAndHealth" }, "panelId": { "classification": "SystemMetaData", "purpose": "PerformanceAndHealth" }, - "editorIds": { "classification": "SystemMetaData", "purpose": "PerformanceAndHealth" } + "editorIds": { "classification": "SystemMetaData", "purpose": "PerformanceAndHealth" }, "timers.ellapsedAppReady" : { "classification": "SystemMetaData", "purpose": "PerformanceAndHealth", "isMeasurement": true }, "timers.ellapsedWindowLoad" : { "classification": "SystemMetaData", "purpose": "PerformanceAndHealth", "isMeasurement": true }, "timers.ellapsedWindowLoadToRequire" : { "classification": "SystemMetaData", "purpose": "PerformanceAndHealth", "isMeasurement": true }, From 3067e4c30efef358288b6218c409f75dfa74977d Mon Sep 17 00:00:00 2001 From: Benjamin Pasero <benjpas@microsoft.com> Date: Tue, 21 Aug 2018 07:20:52 +0200 Subject: [PATCH 1023/1276] fix tests more --- .../test/electron-browser/api/mainThreadEditors.test.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/src/vs/workbench/test/electron-browser/api/mainThreadEditors.test.ts b/src/vs/workbench/test/electron-browser/api/mainThreadEditors.test.ts index 55d3113842c..19ef6688f08 100644 --- a/src/vs/workbench/test/electron-browser/api/mainThreadEditors.test.ts +++ b/src/vs/workbench/test/electron-browser/api/mainThreadEditors.test.ts @@ -79,6 +79,7 @@ suite('MainThreadEditors', () => { const textEditorModel: ITextEditorModel = new class extends mock<ITextEditorModel>() { textEditorModel = modelService.getModel(resource); }; + textEditorModel.isReadonly = () => false; return TPromise.as(new ImmortalReference(textEditorModel)); } }; From 07796186d388044595cd101c49378c7cd48b350b Mon Sep 17 00:00:00 2001 From: Johannes Rieken <johannes.rieken@gmail.com> Date: Tue, 21 Aug 2018 10:27:03 +0200 Subject: [PATCH 1024/1276] fix #56877 --- extensions/git/extension.webpack.config.js | 3 ++- extensions/shared.webpack.config.js | 8 ++------ 2 files changed, 4 insertions(+), 7 deletions(-) diff --git a/extensions/git/extension.webpack.config.js b/extensions/git/extension.webpack.config.js index 44e0d7dff17..35f3239228b 100644 --- a/extensions/git/extension.webpack.config.js +++ b/extensions/git/extension.webpack.config.js @@ -19,7 +19,8 @@ const myConfig = { }, plugins: [ new CopyWebpackPlugin([ - { from: './out/*.sh', to: '[name].sh' } + { from: './out/*.sh', to: '[name].sh' }, + { from: './out/nls.*.json', to: '[name].json' } ]) ], externals: { diff --git a/extensions/shared.webpack.config.js b/extensions/shared.webpack.config.js index b98d911ce80..14a79dfdcd5 100644 --- a/extensions/shared.webpack.config.js +++ b/extensions/shared.webpack.config.js @@ -6,7 +6,6 @@ 'use strict'; const path = require('path'); -const CopyWebpackPlugin = require('copy-webpack-plugin'); const merge = require('merge-options'); module.exports = function withDefaults(extConfig) { @@ -39,9 +38,6 @@ module.exports = function withDefaults(extConfig) { }] }] }, - plugins: [ - new CopyWebpackPlugin([{ from: './out/nls.*.json', to: '[name].json' }]) // copy nls files - ], externals: { 'vscode': 'commonjs vscode', // ignored because it doesn't exist }, @@ -54,7 +50,7 @@ module.exports = function withDefaults(extConfig) { }, // yes, really source maps devtool: 'source-map' - } + }; return merge(defaultConfig, extConfig); -} +}; From eea3e8adf40182aa4a80043a92c9fddcb6454656 Mon Sep 17 00:00:00 2001 From: isidor <inikolic@microsoft.com> Date: Tue, 21 Aug 2018 10:27:42 +0200 Subject: [PATCH 1025/1276] open editors: focus active group even if it does not have an editor. Make sure list is not empty fixes #56806 --- .../parts/files/electron-browser/views/openEditorsView.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vs/workbench/parts/files/electron-browser/views/openEditorsView.ts b/src/vs/workbench/parts/files/electron-browser/views/openEditorsView.ts index a9eb1724a80..8c3919f02bf 100644 --- a/src/vs/workbench/parts/files/electron-browser/views/openEditorsView.ts +++ b/src/vs/workbench/parts/files/electron-browser/views/openEditorsView.ts @@ -389,7 +389,7 @@ export class OpenEditorsView extends ViewletPanel { } private focusActiveEditor(): void { - if (this.editorGroupService.activeGroup && this.editorGroupService.activeGroup.activeEditor /* could be empty */) { + if (this.list.length && this.editorGroupService.activeGroup) { const index = this.getIndex(this.editorGroupService.activeGroup, this.editorGroupService.activeGroup.activeEditor); this.list.setFocus([index]); this.list.setSelection([index]); From 4754feafb0d174c84b876b87c0a77d9f959ba311 Mon Sep 17 00:00:00 2001 From: Joao Moreno <joao.moreno@microsoft.com> Date: Tue, 21 Aug 2018 10:42:38 +0200 Subject: [PATCH 1026/1276] fixes #56736 --- .../electron-browser/update.contribution.ts | 7 +- .../parts/update/electron-browser/update.ts | 129 +----------------- 2 files changed, 2 insertions(+), 134 deletions(-) diff --git a/src/vs/workbench/parts/update/electron-browser/update.contribution.ts b/src/vs/workbench/parts/update/electron-browser/update.contribution.ts index a87651e4bfc..4e791267124 100644 --- a/src/vs/workbench/parts/update/electron-browser/update.contribution.ts +++ b/src/vs/workbench/parts/update/electron-browser/update.contribution.ts @@ -13,9 +13,8 @@ import { IWorkbenchContributionsRegistry, Extensions as WorkbenchExtensions } fr import { IGlobalActivityRegistry, GlobalActivityExtensions } from 'vs/workbench/common/activity'; import { IWorkbenchActionRegistry, Extensions as ActionExtensions } from 'vs/workbench/common/actions'; import { SyncActionDescriptor } from 'vs/platform/actions/common/actions'; -import { ShowCurrentReleaseNotesAction, ProductContribution, UpdateContribution, Win3264BitContribution, WinUserSetupContribution } from './update'; +import { ShowCurrentReleaseNotesAction, ProductContribution, UpdateContribution, Win3264BitContribution } from './update'; import { LifecyclePhase } from 'vs/platform/lifecycle/common/lifecycle'; -import product from 'vs/platform/node/product'; const workbench = Registry.as<IWorkbenchContributionsRegistry>(WorkbenchExtensions.Workbench); @@ -25,10 +24,6 @@ if (platform.isWindows) { if (process.arch === 'ia32') { workbench.registerWorkbenchContribution(Win3264BitContribution, LifecyclePhase.Running); } - - if (product.target !== 'user') { - workbench.registerWorkbenchContribution(WinUserSetupContribution, LifecyclePhase.Running); - } } Registry.as<IGlobalActivityRegistry>(GlobalActivityExtensions) diff --git a/src/vs/workbench/parts/update/electron-browser/update.ts b/src/vs/workbench/parts/update/electron-browser/update.ts index 2e468debc61..675bea320d2 100644 --- a/src/vs/workbench/parts/update/electron-browser/update.ts +++ b/src/vs/workbench/parts/update/electron-browser/update.ts @@ -21,7 +21,7 @@ import { IOpenerService } from 'vs/platform/opener/common/opener'; import { ICommandService } from 'vs/platform/commands/common/commands'; import { IWorkbenchContribution } from 'vs/workbench/common/contributions'; import { IStorageService, StorageScope } from 'vs/platform/storage/common/storage'; -import { IUpdateService, State as UpdateState, StateType, IUpdate, UpdateType } from 'vs/platform/update/common/update'; +import { IUpdateService, State as UpdateState, StateType, IUpdate } from 'vs/platform/update/common/update'; import * as semver from 'semver'; import { IEnvironmentService } from 'vs/platform/environment/common/environment'; import { INotificationService, INotificationHandle } from 'vs/platform/notification/common/notification'; @@ -209,133 +209,6 @@ export class Win3264BitContribution implements IWorkbenchContribution { } } -async function isUserSetupInstalled(): Promise<boolean> { - const rawUserAppId = process.arch === 'x64' ? product.win32x64UserAppId : product.win32UserAppId; - const userAppId = rawUserAppId.replace(/^\{\{/, '{'); - const Registry = await import('winreg'); - const key = new Registry({ - hive: Registry.HKCU, - key: `\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\${userAppId}_is1` - }); - - try { - await new Promise((c, e) => key.get('', (err, result) => err ? e(err) : c(result))); - } catch (err) { - return false; - } - - return true; -} - -export class WinUserSetupContribution implements IWorkbenchContribution { - - private static readonly KEY = 'update/win32-usersetup'; - private static readonly KEY_BOTH = 'update/win32-usersetup-both'; - - private static readonly STABLE_URL = 'https://vscode-update.azurewebsites.net/latest/win32-x64-user/stable'; - private static readonly STABLE_URL_32BIT = 'https://vscode-update.azurewebsites.net/latest/win32-user/stable'; - private static readonly INSIDER_URL = 'https://vscode-update.azurewebsites.net/latest/win32-x64-user/insider'; - private static readonly INSIDER_URL_32BIT = 'https://vscode-update.azurewebsites.net/latest/win32-user/insider'; - - // TODO@joao this needs to change to the 1.26 release notes - private static readonly READ_MORE = 'https://aka.ms/vscode-win32-user-setup'; - - private disposables: IDisposable[] = []; - - constructor( - @IStorageService private storageService: IStorageService, - @INotificationService private notificationService: INotificationService, - @IEnvironmentService private environmentService: IEnvironmentService, - @IOpenerService private openerService: IOpenerService, - @IUpdateService private updateService: IUpdateService - ) { - if (!environmentService.isBuilt) { - return; - } - - const neverShowAgain = new NeverShowAgain(WinUserSetupContribution.KEY_BOTH, this.storageService); - - if (!neverShowAgain.shouldShow()) { - return; - } - - isUserSetupInstalled().then(userSetupIsInstalled => { - if (!userSetupIsInstalled) { - updateService.onStateChange(this.onUpdateStateChange, this, this.disposables); - this.onUpdateStateChange(this.updateService.state); - return; - } - - const handle = this.notificationService.prompt( - severity.Info, - nls.localize('usersetupsystem', "You are running the system-wide installation of {0}, while having the user-wide distribution installed as well.", product.nameShort), - [ - { label: nls.localize('ok', "OK"), run: () => null }, - { - label: nls.localize('okneveragain', "OK, Don't Show Again"), - run: () => { - neverShowAgain.action.run(handle); - neverShowAgain.action.dispose(); - } - }] - ); - }); - } - - private onUpdateStateChange(state: UpdateState): void { - if (state.type !== StateType.Idle) { - return; - } - - if (state.updateType !== UpdateType.Setup) { - return; - } - - if (!this.environmentService.isBuilt || this.environmentService.disableUpdates) { - return; - } - - const neverShowAgain = new NeverShowAgain(WinUserSetupContribution.KEY, this.storageService); - - if (!neverShowAgain.shouldShow()) { - return; - } - - const handle = this.notificationService.prompt( - severity.Info, - nls.localize('usersetup', "We recommend switching to our new User Setup distribution of {0} for Windows!", product.nameShort), - [ - { - label: nls.localize('learnMore', "Learn More"), - run: () => { - return this.openerService.open(URI.parse(WinUserSetupContribution.READ_MORE)); - } - }, - { - label: nls.localize('downloadnow', "Download"), - run: () => { - const url = product.quality === 'insider' - ? (process.arch === 'ia32' ? WinUserSetupContribution.INSIDER_URL_32BIT : WinUserSetupContribution.INSIDER_URL) - : (process.arch === 'ia32' ? WinUserSetupContribution.STABLE_URL_32BIT : WinUserSetupContribution.STABLE_URL); - - return this.openerService.open(URI.parse(url)); - } - }, - { - label: nls.localize('neveragain', "Don't Show Again"), - run: () => { - neverShowAgain.action.run(handle); - neverShowAgain.action.dispose(); - } - }] - ); - } - - dispose(): void { - this.disposables = dispose(this.disposables); - } -} - class CommandAction extends Action { constructor( From 728e657c4938cbcb2cc350263d5fcaaf5755bacc Mon Sep 17 00:00:00 2001 From: Sandeep Somavarapu <sasomava@microsoft.com> Date: Tue, 21 Aug 2018 11:21:57 +0200 Subject: [PATCH 1027/1276] Make download service optional --- src/vs/code/node/cliProcessMain.ts | 3 -- .../platform/download/node/downloadService.ts | 38 ------------------- .../node/extensionManagementService.ts | 6 ++- src/vs/workbench/electron-browser/shell.ts | 3 -- 4 files changed, 5 insertions(+), 45 deletions(-) delete mode 100644 src/vs/platform/download/node/downloadService.ts diff --git a/src/vs/code/node/cliProcessMain.ts b/src/vs/code/node/cliProcessMain.ts index 9ed28b80f05..0731a9d7b13 100644 --- a/src/vs/code/node/cliProcessMain.ts +++ b/src/vs/code/node/cliProcessMain.ts @@ -42,8 +42,6 @@ import { CommandLineDialogService } from 'vs/platform/dialogs/node/dialogService import { areSameExtensions, getGalleryExtensionIdFromLocal } from 'vs/platform/extensionManagement/common/extensionManagementUtil'; import Severity from 'vs/base/common/severity'; import URI from 'vs/base/common/uri'; -import { IDownloadService } from 'vs/platform/download/common/download'; -import { DownloadService } from 'vs/platform/download/node/downloadService'; const notFound = (id: string) => localize('notFound', "Extension '{0}' not found.", id); const notInstalled = (id: string) => localize('notInstalled', "Extension '{0}' is not installed.", id); @@ -243,7 +241,6 @@ export function main(argv: ParsedArgs): TPromise<void> { services.set(IExtensionManagementService, new SyncDescriptor(ExtensionManagementService)); services.set(IExtensionGalleryService, new SyncDescriptor(ExtensionGalleryService)); services.set(IDialogService, new SyncDescriptor(CommandLineDialogService)); - services.set(IDownloadService, new SyncDescriptor(DownloadService)); const appenders: AppInsightsAppender[] = []; if (isBuilt && !extensionDevelopmentPath && !envService.args['disable-telemetry'] && product.enableTelemetry) { diff --git a/src/vs/platform/download/node/downloadService.ts b/src/vs/platform/download/node/downloadService.ts deleted file mode 100644 index e59afec589a..00000000000 --- a/src/vs/platform/download/node/downloadService.ts +++ /dev/null @@ -1,38 +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'; - -import URI from 'vs/base/common/uri'; -import { TPromise } from 'vs/base/common/winjs.base'; -import { IDownloadService } from 'vs/platform/download/common/download'; -import { IRequestService } from 'vs/platform/request/node/request'; -import { Schemas } from 'vs/base/common/network'; -import { copy } from 'vs/base/node/pfs'; -import { download, asText } from 'vs/base/node/request'; - -export class DownloadService implements IDownloadService { - - _serviceBrand: any; - - constructor( - @IRequestService private requestService: IRequestService - ) { } - - download(from: URI, to: string): TPromise<void> { - if (from.scheme === Schemas.file) { - return copy(from.fsPath, to); - } - return this.requestService.request({ url: from.path }) - .then(context => { - if (context.res.statusCode === 200) { - return download(to, context); - } - return asText(context) - .then(message => TPromise.wrapError(new Error(`Expected 200, got back ${context.res.statusCode} instead.\n\n${message}`))); - }); - } - -} \ No newline at end of file diff --git a/src/vs/platform/extensionManagement/node/extensionManagementService.ts b/src/vs/platform/extensionManagement/node/extensionManagementService.ts index ba5c82e925f..08d00874143 100644 --- a/src/vs/platform/extensionManagement/node/extensionManagementService.ts +++ b/src/vs/platform/extensionManagement/node/extensionManagementService.ts @@ -45,6 +45,7 @@ import { getPathFromAmdModule } from 'vs/base/common/amd'; import { tmpdir } from 'os'; import { generateUuid } from 'vs/base/common/uuid'; import { IDownloadService } from 'vs/platform/download/common/download'; +import { optional } from 'vs/platform/instantiation/common/instantiation'; const SystemExtensionsRoot = path.normalize(path.join(getPathFromAmdModule(require, ''), '..', 'extensions')); const ERROR_SCANNING_SYS_EXTENSIONS = 'scanningSystem'; @@ -140,7 +141,7 @@ export class ExtensionManagementService extends Disposable implements IExtension @IDialogService private dialogService: IDialogService, @IExtensionGalleryService private galleryService: IExtensionGalleryService, @ILogService private logService: ILogService, - @IDownloadService private downloadService: IDownloadService, + @optional(IDownloadService) private downloadService: IDownloadService, @ITelemetryService private telemetryService: ITelemetryService, ) { super(); @@ -165,6 +166,9 @@ export class ExtensionManagementService extends Disposable implements IExtension } unzip(zipLocation: URI): TPromise<void> { + if (!this.downloadService) { + throw new Error('Download service is not available'); + } const downloadedLocation = path.join(tmpdir(), generateUuid()); return this.downloadService.download(zipLocation, downloadedLocation).then(() => this.install(URI.file(downloadedLocation))); } diff --git a/src/vs/workbench/electron-browser/shell.ts b/src/vs/workbench/electron-browser/shell.ts index d440340a68b..33cd10f079b 100644 --- a/src/vs/workbench/electron-browser/shell.ts +++ b/src/vs/workbench/electron-browser/shell.ts @@ -97,8 +97,6 @@ import { SearchHistoryService } from 'vs/workbench/services/search/node/searchHi import { MulitExtensionManagementService } from 'vs/platform/extensionManagement/common/multiExtensionManagement'; import { ExtensionManagementServerService } from 'vs/workbench/services/extensions/node/extensionManagementServerService'; import { DownloadServiceChannel } from 'vs/platform/download/node/downloadIpc'; -import { IDownloadService } from 'vs/platform/download/common/download'; -import { DownloadService } from 'vs/platform/download/node/downloadService'; /** * Services that we require for the Shell @@ -391,7 +389,6 @@ export class WorkbenchShell extends Disposable { serviceCollection.set(IExtensionEnablementService, extensionEnablementService); serviceCollection.set(IRequestService, new SyncDescriptor(RequestService)); - serviceCollection.set(IDownloadService, new SyncDescriptor(DownloadService)); this.extensionService = instantiationService.createInstance(ExtensionService); serviceCollection.set(IExtensionService, this.extensionService); From 6e8f35d30cdaec7902d66f0a6a0dddfa42115add Mon Sep 17 00:00:00 2001 From: Sandeep Somavarapu <sasomava@microsoft.com> Date: Tue, 21 Aug 2018 11:28:31 +0200 Subject: [PATCH 1028/1276] Add builtin-extensions-dir property to environment --- src/vs/platform/environment/common/environment.ts | 2 ++ src/vs/platform/environment/node/environmentService.ts | 10 ++++++++++ .../node/extensionManagementService.ts | 6 +++--- 3 files changed, 15 insertions(+), 3 deletions(-) diff --git a/src/vs/platform/environment/common/environment.ts b/src/vs/platform/environment/common/environment.ts index 52431b2e260..7338d3e798d 100644 --- a/src/vs/platform/environment/common/environment.ts +++ b/src/vs/platform/environment/common/environment.ts @@ -32,6 +32,7 @@ export interface ParsedArgs { log?: string; logExtensionHostCommunication?: boolean; 'extensions-dir'?: string; + 'builtin-extensions-dir'?: string; extensionDevelopmentPath?: string; extensionTestsPath?: string; debugPluginHost?: string; @@ -104,6 +105,7 @@ export interface IEnvironmentService { isExtensionDevelopment: boolean; disableExtensions: boolean | string[]; + builtinExtensionsPath: string; extensionsPath: string; extensionDevelopmentPath: string; extensionTestsPath: string; diff --git a/src/vs/platform/environment/node/environmentService.ts b/src/vs/platform/environment/node/environmentService.ts index 2224b6afd17..1117c904fb7 100644 --- a/src/vs/platform/environment/node/environmentService.ts +++ b/src/vs/platform/environment/node/environmentService.ts @@ -132,6 +132,16 @@ export class EnvironmentService implements IEnvironmentService { @memoize get installSourcePath(): string { return path.join(this.userDataPath, 'installSource'); } + @memoize + get builtinExtensionsPath(): string { + const fromArgs = parsePathArg(this._args['builtin-extensions-dir'], process); + if (fromArgs) { + return fromArgs; + } else { + return path.normalize(path.join(getPathFromAmdModule(require, ''), '..', 'extensions')); + } + } + @memoize get extensionsPath(): string { const fromArgs = parsePathArg(this._args['extensions-dir'], process); diff --git a/src/vs/platform/extensionManagement/node/extensionManagementService.ts b/src/vs/platform/extensionManagement/node/extensionManagementService.ts index 08d00874143..e66fb49545c 100644 --- a/src/vs/platform/extensionManagement/node/extensionManagementService.ts +++ b/src/vs/platform/extensionManagement/node/extensionManagementService.ts @@ -41,13 +41,11 @@ import { ExtensionsLifecycle } from 'vs/platform/extensionManagement/node/extens import { toErrorMessage } from 'vs/base/common/errorMessage'; import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry'; import { isEngineValid } from 'vs/platform/extensions/node/extensionValidator'; -import { getPathFromAmdModule } from 'vs/base/common/amd'; import { tmpdir } from 'os'; import { generateUuid } from 'vs/base/common/uuid'; import { IDownloadService } from 'vs/platform/download/common/download'; import { optional } from 'vs/platform/instantiation/common/instantiation'; -const SystemExtensionsRoot = path.normalize(path.join(getPathFromAmdModule(require, ''), '..', 'extensions')); const ERROR_SCANNING_SYS_EXTENSIONS = 'scanningSystem'; const ERROR_SCANNING_USER_EXTENSIONS = 'scanningUser'; const INSTALL_ERROR_UNSET_UNINSTALLED = 'unsetUninstalled'; @@ -114,6 +112,7 @@ export class ExtensionManagementService extends Disposable implements IExtension _serviceBrand: any; + private systemExtensionsPath: string; private extensionsPath: string; private uninstalledPath: string; private uninstalledFileLimiter: Limiter<void>; @@ -145,6 +144,7 @@ export class ExtensionManagementService extends Disposable implements IExtension @ITelemetryService private telemetryService: ITelemetryService, ) { super(); + this.systemExtensionsPath = environmentService.builtinExtensionsPath; this.extensionsPath = environmentService.extensionsPath; this.uninstalledPath = path.join(this.extensionsPath, '.obsolete'); this.uninstalledFileLimiter = new Limiter(1); @@ -753,7 +753,7 @@ export class ExtensionManagementService extends Disposable implements IExtension private scanSystemExtensions(): TPromise<ILocalExtension[]> { this.logService.trace('Started scanning system extensions'); - return this.scanExtensions(SystemExtensionsRoot, LocalExtensionType.System) + return this.scanExtensions(this.systemExtensionsPath, LocalExtensionType.System) .then(result => { this.logService.info('Scanned system extensions:', result.length); return result; From a80a55d975b40041a1a01b35d9ee72f057c384cf Mon Sep 17 00:00:00 2001 From: Sandeep Somavarapu <sasomava@microsoft.com> Date: Tue, 21 Aug 2018 11:30:06 +0200 Subject: [PATCH 1029/1276] Use fs readstream to upload buffer --- src/vs/platform/download/node/downloadIpc.ts | 56 +++----------------- 1 file changed, 8 insertions(+), 48 deletions(-) diff --git a/src/vs/platform/download/node/downloadIpc.ts b/src/vs/platform/download/node/downloadIpc.ts index 8dca2440d29..fa914daf42a 100644 --- a/src/vs/platform/download/node/downloadIpc.ts +++ b/src/vs/platform/download/node/downloadIpc.ts @@ -13,55 +13,16 @@ import { IChannel } from 'vs/base/parts/ipc/common/ipc'; import { Event, Emitter, buffer } from 'vs/base/common/event'; import { IDownloadService } from 'vs/platform/download/common/download'; import { mkdirp } from 'vs/base/node/pfs'; -import { onUnexpectedError } from 'vs/base/common/errors'; import { IURITransformer } from 'vs/base/common/uriIpc'; -export type UploadResponse = Buffer | Error | undefined; +export type UploadResponse = Buffer | string | undefined; export function upload(uri: URI): Event<UploadResponse> { - const stream = new Emitter<Buffer | Error | undefined>(); - fs.open(uri.fsPath, 'r', (err, fd) => { - if (err) { - if (err.code === 'ENOENT') { - stream.fire(new Error('File Not Found')); - } - return; - } - const finish = (err?: any) => { - if (err) { - stream.fire(err); - } else { - stream.fire(); - if (fd) { - fs.close(fd, err => { - if (err) { - onUnexpectedError(err); - } - }); - } - } - }; - let currentPosition: number = 0; - const readChunk = () => { - const chunkBuffer = Buffer.allocUnsafe(64 * 1024); // 64K Chunk - fs.read(fd, chunkBuffer, 0, chunkBuffer.length, currentPosition, (err, bytesRead) => { - currentPosition += bytesRead; - if (err) { - finish(err); - } else { - if (bytesRead === 0) { - // no more data -> finish - finish(); - } else { - stream.fire(chunkBuffer.slice(0, bytesRead)); - readChunk(); - } - } - }); - }; - // start reading - readChunk(); - }); + const stream = new Emitter<UploadResponse>(); + const readstream = fs.createReadStream(uri.fsPath); + readstream.on('data', data => stream.fire(data)); + readstream.on('error', error => stream.fire(error.toString())); + readstream.on('close', () => stream.fire()); return stream.event; } @@ -103,15 +64,14 @@ export class DownloadServiceChannelClient implements IDownloadService { out.once('close', () => c(null)); out.once('error', e); const uploadStream = this.channel.listen('upload', from); - const disposable = uploadStream((result: Buffer | Error | undefined) => { + const disposable = uploadStream((result: UploadResponse) => { if (result === void 0) { out.end(); - out.close(); disposable.dispose(); c(null); } else if (result instanceof Buffer) { out.write(result); - } else if (result instanceof Error) { + } else if (typeof result === 'string') { out.close(); disposable.dispose(); e(result); From 823a3b6386dad362e123ee06709c318adb593655 Mon Sep 17 00:00:00 2001 From: Sandeep Somavarapu <sasomava@microsoft.com> Date: Tue, 21 Aug 2018 11:32:13 +0200 Subject: [PATCH 1030/1276] - Synchronise built in extensions - Check for workspace extensions while installing --- .../common/extensionManagement.ts | 4 +- .../common/extensionManagementIpc.ts | 12 +- .../common/multiExtensionManagement.ts | 113 +++++++++++------- .../node/extensionManagementService.ts | 33 ++--- 4 files changed, 95 insertions(+), 67 deletions(-) diff --git a/src/vs/platform/extensionManagement/common/extensionManagement.ts b/src/vs/platform/extensionManagement/common/extensionManagement.ts index bc65fb0b024..c2762381422 100644 --- a/src/vs/platform/extensionManagement/common/extensionManagement.ts +++ b/src/vs/platform/extensionManagement/common/extensionManagement.ts @@ -307,8 +307,8 @@ export interface IExtensionManagementService { onDidUninstallExtension: Event<DidUninstallExtensionEvent>; zip(extension: ILocalExtension): TPromise<URI>; - unzip(zipLocation: URI): TPromise<void>; - install(vsix: URI): TPromise<void>; + unzip(zipLocation: URI, type: LocalExtensionType): TPromise<IExtensionIdentifier>; + install(vsix: URI): TPromise<IExtensionIdentifier>; installFromGallery(extension: IGalleryExtension): TPromise<void>; uninstall(extension: ILocalExtension, force?: boolean): TPromise<void>; reinstallFromGallery(extension: ILocalExtension): TPromise<void>; diff --git a/src/vs/platform/extensionManagement/common/extensionManagementIpc.ts b/src/vs/platform/extensionManagement/common/extensionManagementIpc.ts index 236e45979b3..0cc96ff179b 100644 --- a/src/vs/platform/extensionManagement/common/extensionManagementIpc.ts +++ b/src/vs/platform/extensionManagement/common/extensionManagementIpc.ts @@ -19,8 +19,8 @@ export interface IExtensionManagementChannel extends IChannel { listen(event: 'onDidUninstallExtension'): Event<DidUninstallExtensionEvent>; call(command: 'zip', args: [ILocalExtension]): TPromise<URI>; - call(command: 'unzip', args: [URI]): TPromise<void>; - call(command: 'install', args: [URI]): TPromise<void>; + call(command: 'unzip', args: [URI, LocalExtensionType]): TPromise<IExtensionIdentifier>; + call(command: 'install', args: [URI]): TPromise<IExtensionIdentifier>; call(command: 'installFromGallery', args: [IGalleryExtension]): TPromise<void>; call(command: 'uninstall', args: [ILocalExtension, boolean]): TPromise<void>; call(command: 'reinstallFromGallery', args: [ILocalExtension]): TPromise<void>; @@ -57,7 +57,7 @@ export class ExtensionManagementChannel implements IExtensionManagementChannel { call(command: string, args?: any): TPromise<any> { switch (command) { case 'zip': return this.service.zip(this._transform(args[0])); - case 'unzip': return this.service.unzip(URI.revive(args[0])); + case 'unzip': return this.service.unzip(URI.revive(args[0]), args[1]); case 'install': return this.service.install(URI.revive(args[0])); case 'installFromGallery': return this.service.installFromGallery(args[0]); case 'uninstall': return this.service.uninstall(this._transform(args[0]), args[1]); @@ -90,11 +90,11 @@ export class ExtensionManagementChannelClient implements IExtensionManagementSer return this.channel.call('zip', [this._transformOutgoing(extension)]).then(result => URI.revive(this.uriTransformer.transformIncoming(result))); } - unzip(zipLocation: URI): TPromise<void> { - return this.channel.call('unzip', [this.uriTransformer.transformOutgoing(zipLocation)]); + unzip(zipLocation: URI, type: LocalExtensionType): TPromise<IExtensionIdentifier> { + return this.channel.call('unzip', [this.uriTransformer.transformOutgoing(zipLocation), type]); } - install(vsix: URI): TPromise<void> { + install(vsix: URI): TPromise<IExtensionIdentifier> { return this.channel.call('install', [this.uriTransformer.transformOutgoing(vsix)]); } diff --git a/src/vs/platform/extensionManagement/common/multiExtensionManagement.ts b/src/vs/platform/extensionManagement/common/multiExtensionManagement.ts index 461e59c1ae0..1120f19f351 100644 --- a/src/vs/platform/extensionManagement/common/multiExtensionManagement.ts +++ b/src/vs/platform/extensionManagement/common/multiExtensionManagement.ts @@ -10,12 +10,13 @@ import { IExtensionManagementServerService, IExtensionManagementServer } from 'vs/platform/extensionManagement/common/extensionManagement'; import { flatten } from 'vs/base/common/arrays'; -import { isWorkspaceExtension } from 'vs/platform/extensionManagement/common/extensionManagementUtil'; +import { isWorkspaceExtension, areSameExtensions } from 'vs/platform/extensionManagement/common/extensionManagementUtil'; import URI from 'vs/base/common/uri'; import { INotificationService, Severity } from 'vs/platform/notification/common/notification'; import { localize } from 'vs/nls'; import { IWindowService } from 'vs/platform/windows/common/windows'; import { Action } from 'vs/base/common/actions'; +import { ILogService } from 'vs/platform/log/common/log'; export class MulitExtensionManagementService implements IExtensionManagementService { @@ -27,13 +28,18 @@ export class MulitExtensionManagementService implements IExtensionManagementServ onDidUninstallExtension: Event<DidUninstallExtensionEvent>; private readonly servers: IExtensionManagementServer[]; + private readonly localServer: IExtensionManagementServer; + private readonly otherServers: IExtensionManagementServer[]; constructor( @IExtensionManagementServerService private extensionManagementServerService: IExtensionManagementServerService, @INotificationService private notificationService: INotificationService, - @IWindowService private windowService: IWindowService + @IWindowService private windowService: IWindowService, + @ILogService private logService: ILogService ) { this.servers = this.extensionManagementServerService.extensionManagementServers; + this.localServer = this.extensionManagementServerService.getLocalExtensionManagementServer(); + this.otherServers = this.servers.filter(s => s !== this.localServer); this.onInstallExtension = this.servers.reduce((emitter: EventMultiplexer<InstallExtensionEvent>, server) => { emitter.add(server.extensionManagementService.onInstallExtension); return emitter; }, new EventMultiplexer<InstallExtensionEvent>()).event; this.onDidInstallExtension = this.servers.reduce((emitter: EventMultiplexer<DidInstallExtensionEvent>, server) => { emitter.add(server.extensionManagementService.onDidInstallExtension); return emitter; }, new EventMultiplexer<DidInstallExtensionEvent>()).event; this.onUninstallExtension = this.servers.reduce((emitter: EventMultiplexer<IExtensionIdentifier>, server) => { emitter.add(server.extensionManagementService.onUninstallExtension); return emitter; }, new EventMultiplexer<IExtensionIdentifier>()).event; @@ -62,16 +68,34 @@ export class MulitExtensionManagementService implements IExtensionManagementServ throw new Error('Not Supported'); } - unzip(zipLocation: URI): TPromise<void> { - return TPromise.join(this.servers.map(({ extensionManagementService }) => extensionManagementService.unzip(zipLocation))).then(() => null); + unzip(zipLocation: URI, type: LocalExtensionType): TPromise<IExtensionIdentifier> { + return TPromise.join(this.servers.map(({ extensionManagementService }) => extensionManagementService.unzip(zipLocation, type))).then(() => null); } - install(vsix: URI): TPromise<void> { - return TPromise.join(this.servers.map(({ extensionManagementService }) => extensionManagementService.install(vsix))).then(() => null); + install(vsix: URI): TPromise<IExtensionIdentifier> { + return this.localServer.extensionManagementService.install(vsix) + .then(extensionIdentifer => this.localServer.extensionManagementService.getInstalled(LocalExtensionType.User) + .then(installed => { + const extension = installed.filter(i => areSameExtensions(i.identifier, extensionIdentifer))[0]; + if (extension && isWorkspaceExtension(extension.manifest)) { + return TPromise.join(this.otherServers.map(server => server.extensionManagementService.install(vsix))) + .then(() => extensionIdentifer); + } + return extensionIdentifer; + })); } - installFromGallery(extension: IGalleryExtension): TPromise<void> { - return TPromise.join(this.servers.map(({ extensionManagementService }) => extensionManagementService.installFromGallery(extension))).then(() => null); + installFromGallery(gallery: IGalleryExtension): TPromise<void> { + return this.localServer.extensionManagementService.installFromGallery(gallery) + .then(() => this.localServer.extensionManagementService.getInstalled(LocalExtensionType.User)) + .then(installed => { + const extension = installed.filter(i => areSameExtensions(i.galleryIdentifier, gallery.identifier))[0]; + if (extension && isWorkspaceExtension(extension.manifest)) { + return TPromise.join(this.otherServers.map(server => server.extensionManagementService.installFromGallery(gallery))) + .then(() => null); + } + return null; + }); } getExtensionsReport(): TPromise<IReportedExtension[]> { @@ -83,51 +107,35 @@ export class MulitExtensionManagementService implements IExtensionManagementServ } private async syncExtensions(): Promise<void> { - const localServer = this.extensionManagementServerService.getLocalExtensionManagementServer(); - localServer.extensionManagementService.getInstalled() + this.localServer.extensionManagementService.getInstalled() .then(async localExtensions => { const workspaceExtensions = localExtensions.filter(e => isWorkspaceExtension(e.manifest)); - const otherServers = this.servers.filter(s => s !== localServer); - - const extensionsToSync: Map<IExtensionManagementServer, ILocalExtension[]> = await this.getExtensionsToSync(workspaceExtensions, otherServers); - + const extensionsToSync: Map<IExtensionManagementServer, ILocalExtension[]> = await this.getExtensionsToSync(workspaceExtensions); if (extensionsToSync.size > 0) { - const handler = this.notificationService.notify({ severity: Severity.Info, message: localize('synchronising', "Synchronizing workspace extensions...") }); + const handler = this.notificationService.notify({ severity: Severity.Info, message: localize('synchronising', "Synchronising workspace extensions...") }); handler.progress.infinite(); - const promises: TPromise<any>[] = []; - const vsixById: Map<string, TPromise<URI>> = new Map<string, TPromise<URI>>(); - extensionsToSync.forEach((extensions, server) => { - for (const extension of extensions) { - let vsix = vsixById.get(extension.galleryIdentifier.id); - if (!vsix) { - vsix = localServer.extensionManagementService.zip(extension); - vsixById.set(extension.galleryIdentifier.id, vsix); - promises.push(vsix); - } - promises.push(vsix.then(location => server.extensionManagementService.unzip(location))); - } - }); - TPromise.join(promises).then(() => { + this.doSyncExtensions(extensionsToSync).then(() => { handler.progress.done(); - handler.updateMessage(localize('Synchronize.finished', "Finished synchronizing workspace extensions. Please reload now.")); + handler.updateMessage(localize('Synchronize.finished', "Finished synchronising workspace extensions. Please reload now.")); handler.updateActions({ primary: [ new Action('Synchronize.reloadNow', localize('Synchronize.reloadNow', "Reload Now"), null, true, () => this.windowService.reloadWindow()) ] }); + }, error => { + handler.progress.done(); + handler.updateMessage(error); }); } - }, err => { - console.log(err); - }); + }, err => this.logService.error('Error while Synchronisation', err)); } - private async getExtensionsToSync(workspaceExtensions: ILocalExtension[], servers: IExtensionManagementServer[]): Promise<Map<IExtensionManagementServer, ILocalExtension[]>> { + private async getExtensionsToSync(workspaceExtensions: ILocalExtension[]): Promise<Map<IExtensionManagementServer, ILocalExtension[]>> { const extensionsToSync: Map<IExtensionManagementServer, ILocalExtension[]> = new Map<IExtensionManagementServer, ILocalExtension[]>(); - for (const server of servers) { + for (const server of this.otherServers) { const extensions = await server.extensionManagementService.getInstalled(); - const groupedById = this.groupById(extensions); - const toSync = workspaceExtensions.filter(e => !groupedById.has(e.galleryIdentifier.id)); + const groupedByVersionId: Map<string, ILocalExtension> = extensions.reduce((groupedById, extension) => groupedById.set(`${extension.galleryIdentifier.id}-${extension.manifest.version}`, extension), new Map<string, ILocalExtension>()); + const toSync = workspaceExtensions.filter(e => !groupedByVersionId.has(`${e.galleryIdentifier.id}-${e.manifest.version}`)); if (toSync.length) { extensionsToSync.set(server, toSync); } @@ -135,11 +143,30 @@ export class MulitExtensionManagementService implements IExtensionManagementServ return extensionsToSync; } - private groupById(extensions: ILocalExtension[]): Map<string, ILocalExtension> { - const result: Map<string, ILocalExtension> = new Map<string, ILocalExtension>(); - for (const extension of extensions) { - result.set(extension.galleryIdentifier.id, extension); - } - return result; + private async doSyncExtensions(extensionsToSync: Map<IExtensionManagementServer, ILocalExtension[]>): Promise<void> { + const ids: string[] = []; + const vsixResolvers: TPromise<URI>[] = []; + + extensionsToSync.forEach(extensions => { + for (const extension of extensions) { + if (ids.indexOf(extension.galleryIdentifier.id) === -1) { + ids.push(extension.galleryIdentifier.id); + vsixResolvers.push(this.localServer.extensionManagementService.zip(extension)); + } + } + }); + + const vsixs = await TPromise.join(vsixResolvers); + const promises: Promise<any>[] = []; + extensionsToSync.forEach((extensions, server) => { + let promise: Promise<any> = Promise.resolve(); + extensions.forEach(extension => { + const index = ids.indexOf(extension.galleryIdentifier.id); + promise = promise.then(() => server.extensionManagementService.unzip(vsixs[index], extension.type)); + }); + promises.push(promise); + }); + + await Promise.all(promises); } } \ No newline at end of file diff --git a/src/vs/platform/extensionManagement/node/extensionManagementService.ts b/src/vs/platform/extensionManagement/node/extensionManagementService.ts index e66fb49545c..e2dcef51377 100644 --- a/src/vs/platform/extensionManagement/node/extensionManagementService.ts +++ b/src/vs/platform/extensionManagement/node/extensionManagementService.ts @@ -165,12 +165,12 @@ export class ExtensionManagementService extends Disposable implements IExtension .then(path => URI.file(path)); } - unzip(zipLocation: URI): TPromise<void> { + unzip(zipLocation: URI, type: LocalExtensionType): TPromise<IExtensionIdentifier> { if (!this.downloadService) { throw new Error('Download service is not available'); } const downloadedLocation = path.join(tmpdir(), generateUuid()); - return this.downloadService.download(zipLocation, downloadedLocation).then(() => this.install(URI.file(downloadedLocation))); + return this.downloadService.download(zipLocation, downloadedLocation).then(() => this.install(URI.file(downloadedLocation), type)); } private collectFiles(extension: ILocalExtension): TPromise<IFile[]> { @@ -186,14 +186,14 @@ export class ExtensionManagementService extends Disposable implements IExtension }); } - install(vsix: URI): TPromise<void> { + install(vsix: URI, type: LocalExtensionType = LocalExtensionType.User): TPromise<IExtensionIdentifier> { const zipPath = path.resolve(vsix.fsPath); return validateLocalExtension(zipPath) .then(manifest => { const identifier = { id: getLocalExtensionIdFromManifest(manifest) }; if (manifest.engines && manifest.engines.vscode && !isEngineValid(manifest.engines.vscode)) { - return TPromise.wrapError<void>(new Error(nls.localize('incompatible', "Unable to install Extension '{0}' as it is not compatible with Code '{1}'.", identifier.id, pkg.version))); + return TPromise.wrapError<IExtensionIdentifier>(new Error(nls.localize('incompatible', "Unable to install Extension '{0}' as it is not compatible with Code '{1}'.", identifier.id, pkg.version))); } return this.removeIfExists(identifier.id) .then( @@ -204,10 +204,10 @@ export class ExtensionManagementService extends Disposable implements IExtension this._onInstallExtension.fire({ identifier, zipPath }); return this.getMetadata(getGalleryExtensionId(manifest.publisher, manifest.name)) .then( - metadata => this.installFromZipPath(identifier, zipPath, metadata, manifest), - error => this.installFromZipPath(identifier, zipPath, null, manifest)) + metadata => this.installFromZipPath(identifier, zipPath, metadata, type), + error => this.installFromZipPath(identifier, zipPath, null, type)) .then( - () => { this.logService.info('Successfully installed the extension:', identifier.id); }, + () => { this.logService.info('Successfully installed the extension:', identifier.id); return identifier; }, e => { this.logService.error('Failed to install the extension:', identifier.id, e.message); return TPromise.wrapError(e); @@ -248,11 +248,11 @@ export class ExtensionManagementService extends Disposable implements IExtension }); } - private installFromZipPath(identifier: IExtensionIdentifier, zipPath: string, metadata: IGalleryMetadata, manifest: IExtensionManifest): TPromise<ILocalExtension> { + private installFromZipPath(identifier: IExtensionIdentifier, zipPath: string, metadata: IGalleryMetadata, type: LocalExtensionType): TPromise<ILocalExtension> { return this.toNonCancellablePromise(this.getInstalled() .then(installed => { const operation = this.getOperation({ id: getIdFromLocalExtensionId(identifier.id), uuid: identifier.uuid }, installed); - return this.installExtension({ zipPath, id: identifier.id, metadata }) + return this.installExtension({ zipPath, id: identifier.id, metadata }, type) .then(local => this.installDependenciesAndPackExtensions(local, null).then(() => local, error => this.uninstall(local, true).then(() => TPromise.wrapError(error), () => TPromise.wrapError(error)))) .then( local => { this._onDidInstallExtension.fire({ identifier, zipPath, local, operation }); return local; }, @@ -284,7 +284,7 @@ export class ExtensionManagementService extends Disposable implements IExtension const existingExtension = installed.filter(i => areSameExtensions(i.galleryIdentifier, extension.identifier))[0]; operation = existingExtension ? InstallOperation.Update : InstallOperation.Install; return this.downloadInstallableExtension(extension, operation) - .then(installableExtension => this.installExtension(installableExtension).then(local => always(pfs.rimraf(installableExtension.zipPath), () => null).then(() => local))) + .then(installableExtension => this.installExtension(installableExtension, LocalExtensionType.User).then(local => always(pfs.rimraf(installableExtension.zipPath), () => null).then(() => local))) .then(local => this.installDependenciesAndPackExtensions(local, existingExtension) .then(() => local, error => this.uninstall(local, true).then(() => TPromise.wrapError(error), () => TPromise.wrapError(error)))); }) @@ -380,14 +380,14 @@ export class ExtensionManagementService extends Disposable implements IExtension error => TPromise.wrapError<InstallableExtension>(new ExtensionManagementError(this.joinErrors(error).message, INSTALL_ERROR_GALLERY))); } - private installExtension(installableExtension: InstallableExtension): TPromise<ILocalExtension> { + private installExtension(installableExtension: InstallableExtension, type: LocalExtensionType): TPromise<ILocalExtension> { return this.unsetUninstalledAndGetLocal(installableExtension.id) .then( local => { if (local) { return local; } - return this.extractAndInstall(installableExtension); + return this.extractAndInstall(installableExtension, type); }, e => { if (isMacintosh) { @@ -414,14 +414,15 @@ export class ExtensionManagementService extends Disposable implements IExtension }); } - private extractAndInstall({ zipPath, id, metadata }: InstallableExtension): TPromise<ILocalExtension> { - const tempPath = path.join(this.extensionsPath, `.${id}`); - const extensionPath = path.join(this.extensionsPath, id); + private extractAndInstall({ zipPath, id, metadata }: InstallableExtension, type: LocalExtensionType): TPromise<ILocalExtension> { + const location = type === LocalExtensionType.User ? this.extensionsPath : this.systemExtensionsPath; + const tempPath = path.join(location, `.${id}`); + const extensionPath = path.join(location, id); return pfs.rimraf(extensionPath) .then(() => this.extractAndRename(id, zipPath, tempPath, extensionPath), e => TPromise.wrapError(new ExtensionManagementError(nls.localize('errorDeleting', "Unable to delete the existing folder '{0}' while installing the extension '{1}'. Please delete the folder manually and try again", extensionPath, id), INSTALL_ERROR_DELETING))) .then(() => { this.logService.info('Installation completed.', id); - return this.scanExtension(id, this.extensionsPath, LocalExtensionType.User); + return this.scanExtension(id, location, type); }) .then(local => { if (metadata) { From 23418d34ee944e1a36a8a73299fc6491b7110926 Mon Sep 17 00:00:00 2001 From: Sandeep Somavarapu <sasomava@microsoft.com> Date: Tue, 21 Aug 2018 11:32:35 +0200 Subject: [PATCH 1031/1276] Add debug extensions to workspace list --- .../extensionManagement/common/extensionManagementUtil.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/vs/platform/extensionManagement/common/extensionManagementUtil.ts b/src/vs/platform/extensionManagement/common/extensionManagementUtil.ts index f07dafd169f..111bd6319d2 100644 --- a/src/vs/platform/extensionManagement/common/extensionManagementUtil.ts +++ b/src/vs/platform/extensionManagement/common/extensionManagementUtil.ts @@ -136,6 +136,8 @@ export function isWorkspaceExtension(manifest: IExtensionManifest): boolean { 'vscode.npm', 'vscode.php-language-features', 'vscode.typescript-language-features', + 'ms-vscode.node-debug', + 'ms-vscode.node-debug2', 'ms-python.python', 'eg2.tslint' ].indexOf(extensionId) !== -1; From a8deffb86a4e9e21d50b81c55e1a8442cb22f84c Mon Sep 17 00:00:00 2001 From: Joao Moreno <joao.moreno@microsoft.com> Date: Tue, 21 Aug 2018 12:04:47 +0200 Subject: [PATCH 1032/1276] remove unused code --- extensions/git/src/iterators.ts | 57 --------------------------------- 1 file changed, 57 deletions(-) delete mode 100644 extensions/git/src/iterators.ts diff --git a/extensions/git/src/iterators.ts b/extensions/git/src/iterators.ts deleted file mode 100644 index 3b0f741f310..00000000000 --- a/extensions/git/src/iterators.ts +++ /dev/null @@ -1,57 +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'; - -function* filter<T>(it: IterableIterator<T>, condition: (t: T, i: number) => boolean): IterableIterator<T> { - let i = 0; - for (let t of it) { - if (condition(t, i++)) { - yield t; - } - } -} - -function* map<T, R>(it: IterableIterator<T>, fn: (t: T, i: number) => R): IterableIterator<R> { - let i = 0; - for (let t of it) { - yield fn(t, i++); - } -} - -export interface FunctionalIterator<T> extends Iterable<T> { - filter(condition: (t: T, i: number) => boolean): FunctionalIterator<T>; - map<R>(fn: (t: T, i: number) => R): FunctionalIterator<R>; - toArray(): T[]; -} - -class FunctionalIteratorImpl<T> implements FunctionalIterator<T> { - - constructor(private iterator: IterableIterator<T>) { } - - filter(condition: (t: T, i: number) => boolean): FunctionalIterator<T> { - return new FunctionalIteratorImpl(filter(this.iterator, condition)); - } - - map<R>(fn: (t: T, i: number) => R): FunctionalIterator<R> { - return new FunctionalIteratorImpl(map<T, R>(this.iterator, fn)); - } - - toArray(): T[] { - return Array.from(this.iterator); - } - - [Symbol.iterator](): IterableIterator<T> { - return this.iterator; - } -} - -export function iterate<T>(obj: T[] | IterableIterator<T>): FunctionalIterator<T> { - if (Array.isArray(obj)) { - return new FunctionalIteratorImpl(obj[Symbol.iterator]()); - } - - return new FunctionalIteratorImpl(obj); -} \ No newline at end of file From 0633c77f80ac8b3c128a047a0804e844ff33f315 Mon Sep 17 00:00:00 2001 From: Joao Moreno <joao.moreno@microsoft.com> Date: Tue, 21 Aug 2018 12:04:52 +0200 Subject: [PATCH 1033/1276] api.d.ts --- extensions/git/src/api.d.ts | 31 ++++++++++++++++ extensions/git/src/api.impl.ts | 42 ++++++++++++++++++++++ extensions/git/src/api.ts | 65 ---------------------------------- extensions/git/src/main.ts | 10 +++--- 4 files changed, 79 insertions(+), 69 deletions(-) create mode 100644 extensions/git/src/api.d.ts create mode 100644 extensions/git/src/api.impl.ts delete mode 100644 extensions/git/src/api.ts diff --git a/extensions/git/src/api.d.ts b/extensions/git/src/api.d.ts new file mode 100644 index 00000000000..3273c7e4c00 --- /dev/null +++ b/extensions/git/src/api.d.ts @@ -0,0 +1,31 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import { Uri, SourceControlInputBox } from 'vscode'; + +declare module GitExtension { + export interface API { + + } + + // export const availableVersions: string[]; + // export function getAPI(version: string): API; + + //#region Deprecated API + export interface InputBox { + value: string; + } + + export interface Repository { + readonly rootUri: Uri; + readonly inputBox: InputBox; + } + //#endregion +} + +export interface GitExtension { + getRepositories(): Promise<GitExtension.Repository[]>; + getGitPath(): Promise<string>; +} \ No newline at end of file diff --git a/extensions/git/src/api.impl.ts b/extensions/git/src/api.impl.ts new file mode 100644 index 00000000000..ff702cf52e8 --- /dev/null +++ b/extensions/git/src/api.impl.ts @@ -0,0 +1,42 @@ +/*--------------------------------------------------------------------------------------------- + * 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 { Model } from './model'; +import { Repository as ModelRepository } from './repository'; +import { Uri, SourceControlInputBox } from 'vscode'; +import { GitExtension } from './api'; + +class InputBoxImpl implements GitExtension.InputBox { + set value(value: string) { this.inputBox.value = value; } + get value(): string { return this.inputBox.value; } + constructor(private inputBox: SourceControlInputBox) { } +} + +class RepositoryImpl implements GitExtension.Repository { + + readonly rootUri: Uri; + readonly inputBox: GitExtension.InputBox; + + constructor(repository: ModelRepository) { + this.rootUri = Uri.file(repository.root); + this.inputBox = new InputBoxImpl(repository.inputBox); + } +} + +export function createGitExtension(model?: Model): GitExtension { + if (!model) { + return { + getGitPath() { throw new Error('Git model not found'); }, + getRepositories() { throw new Error('Git model not found'); } + }; + } + + return { + async getGitPath() { return model.git.path; }, + async getRepositories() { return model.repositories.map(repository => new RepositoryImpl(repository)); } + }; +} diff --git a/extensions/git/src/api.ts b/extensions/git/src/api.ts deleted file mode 100644 index cfce4c9ed8b..00000000000 --- a/extensions/git/src/api.ts +++ /dev/null @@ -1,65 +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'; - -import { Model } from './model'; -import { Repository as ModelRepository } from './repository'; -import { Uri, SourceControlInputBox } from 'vscode'; - -export interface InputBox { - value: string; -} - -export class InputBoxImpl implements InputBox { - set value(value: string) { this.inputBox.value = value; } - get value(): string { return this.inputBox.value; } - constructor(private inputBox: SourceControlInputBox) { } -} - -export interface Repository { - readonly rootUri: Uri; - readonly inputBox: InputBox; -} - -export class RepositoryImpl implements Repository { - - readonly rootUri: Uri; - readonly inputBox: InputBox; - - constructor(repository: ModelRepository) { - this.rootUri = Uri.file(repository.root); - this.inputBox = new InputBoxImpl(repository.inputBox); - } -} - -export interface API { - getRepositories(): Promise<Repository[]>; - getGitPath(): Promise<string>; -} - -export class APIImpl implements API { - - constructor(private model: Model) { } - - async getGitPath(): Promise<string> { - return this.model.git.path; - } - - async getRepositories(): Promise<Repository[]> { - return this.model.repositories.map(repository => new RepositoryImpl(repository)); - } -} - -export class NoopAPIImpl implements API { - - async getGitPath(): Promise<string> { - throw new Error('Git model not found'); - } - - async getRepositories(): Promise<Repository[]> { - throw new Error('Git model not found'); - } -} diff --git a/extensions/git/src/main.ts b/extensions/git/src/main.ts index 186dd806118..f4833c8985f 100644 --- a/extensions/git/src/main.ts +++ b/extensions/git/src/main.ts @@ -7,6 +7,7 @@ import * as nls from 'vscode-nls'; const localize = nls.loadMessageBundle(); + import { ExtensionContext, workspace, window, Disposable, commands, Uri, OutputChannel } from 'vscode'; import { findGit, Git, IGit } from './git'; import { Model } from './model'; @@ -16,8 +17,9 @@ import { GitDecorations } from './decorationProvider'; import { Askpass } from './askpass'; import { toDisposable, filterEvent, eventToPromise } from './util'; import TelemetryReporter from 'vscode-extension-telemetry'; -import { API, NoopAPIImpl, APIImpl } from './api'; +import { GitExtension } from './api'; import { GitProtocolHandler } from './protocolHandler'; +import { createGitExtension } from './api.impl'; const deactivateTasks: { (): Promise<any>; }[] = []; @@ -69,7 +71,7 @@ async function createModel(context: ExtensionContext, outputChannel: OutputChann return model; } -export async function activate(context: ExtensionContext): Promise<API> { +export async function activate(context: ExtensionContext): Promise<GitExtension> { const disposables: Disposable[] = []; context.subscriptions.push(new Disposable(() => Disposable.from(...disposables).dispose())); @@ -92,7 +94,7 @@ export async function activate(context: ExtensionContext): Promise<API> { try { const model = await createModel(context, outputChannel, telemetryReporter, disposables); - return new APIImpl(model); + return createGitExtension(model); } catch (err) { if (!/Git installation not found/.test(err.message || '')) { throw err; @@ -121,7 +123,7 @@ export async function activate(context: ExtensionContext): Promise<API> { } } - return new NoopAPIImpl(); + return createGitExtension(); } } From 92c776bc995d617fff6941f2196d591cc4f8e2b3 Mon Sep 17 00:00:00 2001 From: Alex Dima <alexdima@microsoft.com> Date: Tue, 21 Aug 2018 12:19:10 +0200 Subject: [PATCH 1034/1276] Move packaging extensions to lib/extensions.ts --- build/dependencies.js | 2 +- build/gulpfile.vscode.js | 42 +++++------------------------- build/lib/extensions.js | 50 +++++++++++++++++++++++++++++++++++ build/lib/extensions.ts | 56 ++++++++++++++++++++++++++++++++++++++++ 4 files changed, 114 insertions(+), 36 deletions(-) diff --git a/build/dependencies.js b/build/dependencies.js index a0b1ee01dc5..2adf7e29ca7 100644 --- a/build/dependencies.js +++ b/build/dependencies.js @@ -43,7 +43,7 @@ function asYarnDependency(prefix, tree) { } function getYarnProductionDependencies(cwd) { - const raw = cp.execSync('yarn list --json', { cwd, encoding: 'utf8', env: { ...process.env, NODE_ENV: 'production' }, stdio: [null, null, 'ignore'] }); + const raw = cp.execSync('yarn list --json', { cwd, encoding: 'utf8', env: { ...process.env, NODE_ENV: 'production' }, stdio: [null, null, 'inherit'] }); const match = /^{"type":"tree".*$/m.exec(raw); if (!match || match.length !== 1) { diff --git a/build/gulpfile.vscode.js b/build/gulpfile.vscode.js index d79071e56bc..b06987077c9 100644 --- a/build/gulpfile.vscode.js +++ b/build/gulpfile.vscode.js @@ -29,7 +29,6 @@ const packageJson = require('../package.json'); const product = require('../product.json'); const crypto = require('crypto'); const i18n = require('./lib/i18n'); -const glob = require('glob'); const deps = require('./dependencies'); const getElectronVersion = require('./lib/electron').getElectronVersion; const createAsar = require('./lib/asar').createAsar; @@ -44,15 +43,6 @@ const nodeModules = ['electron', 'original-fs'] .concat(baseModules); // Build -const builtInExtensions = require('./builtInExtensions.json'); - -const excludedExtensions = [ - 'vscode-api-tests', - 'vscode-colorize-tests', - 'ms-vscode.node-debug', - 'ms-vscode.node-debug2', -]; - const vscodeEntryPoints = _.flatten([ buildfile.entrypoint('vs/workbench/workbench.main'), buildfile.base, @@ -227,34 +217,16 @@ function packageTask(platform, arch, opts) { ]); const src = gulp.src(out + '/**', { base: '.' }) - .pipe(rename(function (path) { path.dirname = path.dirname.replace(new RegExp('^' + out), 'out'); })); - - const root = path.resolve(path.join(__dirname, '..')); - const localExtensionDescriptions = glob.sync('extensions/*/package.json') - .map(manifestPath => { - const extensionPath = path.dirname(path.join(root, manifestPath)); - const extensionName = path.basename(extensionPath); - return { name: extensionName, path: extensionPath }; - }) - .filter(({ name }) => excludedExtensions.indexOf(name) === -1) - .filter(({ name }) => builtInExtensions.every(b => b.name !== name)); - - const localExtensions = es.merge(...localExtensionDescriptions.map(extension => { - return ext.fromLocal(extension.path, sourceMappingURLBase) - .pipe(rename(p => p.dirname = `extensions/${extension.name}/${p.dirname}`)); - })); - - const localExtensionDependencies = gulp.src('extensions/node_modules/**', { base: '.' }); - - const marketplaceExtensions = es.merge(...builtInExtensions.map(extension => { - return ext.fromMarketplace(extension.name, extension.version) - .pipe(rename(p => p.dirname = `extensions/${extension.name}/${p.dirname}`)); - })); - - const sources = es.merge(src, localExtensions, localExtensionDependencies, marketplaceExtensions) + .pipe(rename(function (path) { path.dirname = path.dirname.replace(new RegExp('^' + out), 'out'); })) .pipe(util.setExecutableBit(['**/*.sh'])) .pipe(filter(['**', '!**/*.js.map'])); + const root = path.resolve(path.join(__dirname, '..')); + + const sources = es.merge(src, ext.packageExtensionsStream({ + sourceMappingURLBase: sourceMappingURLBase + })); + let version = packageJson.version; // @ts-ignore JSON checking: quality is optional const quality = product.quality; diff --git a/build/lib/extensions.js b/build/lib/extensions.js index a3973e86026..202cded3dcc 100644 --- a/build/lib/extensions.js +++ b/build/lib/extensions.js @@ -28,6 +28,10 @@ var fs = require("fs"); var path = require("path"); var vsce = require("vsce"); var File = require("vinyl"); +var glob = require("glob"); +var gulp = require("gulp"); +var util2 = require("./util"); +var root = path.resolve(path.join(__dirname, '..', '..')); function fromLocal(extensionPath, sourceMappingURLBase) { var result = es.through(); vsce.listFiles({ cwd: extensionPath, packageManager: vsce.PackageManager.Yarn }).then(function (fileNames) { @@ -175,3 +179,49 @@ function fromMarketplace(extensionName, version) { })); } exports.fromMarketplace = fromMarketplace; +var excludedExtensions = [ + 'vscode-api-tests', + 'vscode-colorize-tests', + 'ms-vscode.node-debug', + 'ms-vscode.node-debug2', +]; +var builtInExtensions = require('../builtInExtensions.json'); +function packageExtensionsStream(opts) { + opts = opts || {}; + var localExtensionDescriptions = glob.sync('extensions/*/package.json') + .map(function (manifestPath) { + var extensionPath = path.dirname(path.join(root, manifestPath)); + var extensionName = path.basename(extensionPath); + return { name: extensionName, path: extensionPath }; + }) + .filter(function (_a) { + var name = _a.name; + return excludedExtensions.indexOf(name) === -1; + }) + .filter(function (_a) { + var name = _a.name; + return opts.desiredExtensions ? opts.desiredExtensions.indexOf(name) >= 0 : true; + }) + .filter(function (_a) { + var name = _a.name; + return builtInExtensions.every(function (b) { return b.name !== name; }); + }); + var localExtensions = es.merge.apply(es, localExtensionDescriptions.map(function (extension) { + return fromLocal(extension.path, opts.sourceMappingURLBase) + .pipe(rename(function (p) { return p.dirname = "extensions/" + extension.name + "/" + p.dirname; })); + })); + var localExtensionDependencies = gulp.src('extensions/node_modules/**', { base: '.' }); + var marketplaceExtensions = es.merge.apply(es, builtInExtensions + .filter(function (_a) { + var name = _a.name; + return opts.desiredExtensions ? opts.desiredExtensions.indexOf(name) >= 0 : true; + }) + .map(function (extension) { + return fromMarketplace(extension.name, extension.version) + .pipe(rename(function (p) { return p.dirname = "extensions/" + extension.name + "/" + p.dirname; })); + })); + return es.merge(localExtensions, localExtensionDependencies, marketplaceExtensions) + .pipe(util2.setExecutableBit(['**/*.sh'])) + .pipe(filter(['**', '!**/*.js.map'])); +} +exports.packageExtensionsStream = packageExtensionsStream; diff --git a/build/lib/extensions.ts b/build/lib/extensions.ts index 3922a3218d2..3c74455ccad 100644 --- a/build/lib/extensions.ts +++ b/build/lib/extensions.ts @@ -20,6 +20,11 @@ import * as fs from 'fs'; import * as path from 'path'; import * as vsce from 'vsce'; import * as File from 'vinyl'; +import * as glob from 'glob'; +import * as gulp from 'gulp'; +import * as util2 from './util'; + +const root = path.resolve(path.join(__dirname, '..', '..')); export function fromLocal(extensionPath: string, sourceMappingURLBase?: string): Stream { let result = es.through(); @@ -191,3 +196,54 @@ export function fromMarketplace(extensionName: string, version: string): Stream })); })); } + +interface IPackageExtensionsOptions { + /** + * Set to undefined to package all of them. + */ + desiredExtensions?: string[]; + sourceMappingURLBase?: string; +} + +const excludedExtensions = [ + 'vscode-api-tests', + 'vscode-colorize-tests', + 'ms-vscode.node-debug', + 'ms-vscode.node-debug2', +]; + +const builtInExtensions: { name: string, version: string, repo: string; }[] = require('../builtInExtensions.json'); + +export function packageExtensionsStream(opts?: IPackageExtensionsOptions): NodeJS.ReadWriteStream { + opts = opts || {}; + + const localExtensionDescriptions = (<string[]>glob.sync('extensions/*/package.json')) + .map(manifestPath => { + const extensionPath = path.dirname(path.join(root, manifestPath)); + const extensionName = path.basename(extensionPath); + return { name: extensionName, path: extensionPath }; + }) + .filter(({ name }) => excludedExtensions.indexOf(name) === -1) + .filter(({ name }) => opts.desiredExtensions ? opts.desiredExtensions.indexOf(name) >= 0 : true) + .filter(({ name }) => builtInExtensions.every(b => b.name !== name)); + + const localExtensions = es.merge(...localExtensionDescriptions.map(extension => { + return fromLocal(extension.path, opts.sourceMappingURLBase) + .pipe(rename(p => p.dirname = `extensions/${extension.name}/${p.dirname}`)); + })); + + const localExtensionDependencies = gulp.src('extensions/node_modules/**', { base: '.' }); + + const marketplaceExtensions = es.merge( + ...builtInExtensions + .filter(({ name }) => opts.desiredExtensions ? opts.desiredExtensions.indexOf(name) >= 0 : true) + .map(extension => { + return fromMarketplace(extension.name, extension.version) + .pipe(rename(p => p.dirname = `extensions/${extension.name}/${p.dirname}`)); + }) + ); + + return es.merge(localExtensions, localExtensionDependencies, marketplaceExtensions) + .pipe(util2.setExecutableBit(['**/*.sh'])) + .pipe(filter(['**', '!**/*.js.map'])); +} \ No newline at end of file From de3f3aa853046572ddf0042e95f1483a9eff3e19 Mon Sep 17 00:00:00 2001 From: Alex Dima <alexdima@microsoft.com> Date: Tue, 21 Aug 2018 12:43:36 +0200 Subject: [PATCH 1035/1276] Update yarn version used on build machines --- build/tfs/darwin/continuous-build-darwin.yml | 2 +- build/tfs/darwin/product-build-darwin.yml | 2 +- build/tfs/linux/continuous-build-linux.yml | 2 +- build/tfs/linux/product-build-linux.yml | 2 +- build/tfs/win32/continuous-build-win32.yml | 2 +- build/tfs/win32/product-build-win32.yml | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) diff --git a/build/tfs/darwin/continuous-build-darwin.yml b/build/tfs/darwin/continuous-build-darwin.yml index 5fadd2b4d8d..9d3f6254cd6 100644 --- a/build/tfs/darwin/continuous-build-darwin.yml +++ b/build/tfs/darwin/continuous-build-darwin.yml @@ -4,7 +4,7 @@ steps: versionSpec: "8.9.1" - task: geeklearningio.gl-vsts-tasks-yarn.yarn-installer-task.YarnInstaller@2 inputs: - versionSpec: "1.3.2" + versionSpec: "1.9.4" - script: | yarn displayName: Install Dependencies diff --git a/build/tfs/darwin/product-build-darwin.yml b/build/tfs/darwin/product-build-darwin.yml index 0dd31503586..c823012c1df 100644 --- a/build/tfs/darwin/product-build-darwin.yml +++ b/build/tfs/darwin/product-build-darwin.yml @@ -5,7 +5,7 @@ steps: - task: geeklearningio.gl-vsts-tasks-yarn.yarn-installer-task.YarnInstaller@2 inputs: - versionSpec: "1.3.2" + versionSpec: "1.9.4" - script: | set -e diff --git a/build/tfs/linux/continuous-build-linux.yml b/build/tfs/linux/continuous-build-linux.yml index abd9a9126dd..9c2e125447b 100644 --- a/build/tfs/linux/continuous-build-linux.yml +++ b/build/tfs/linux/continuous-build-linux.yml @@ -14,7 +14,7 @@ steps: versionSpec: "8.9.1" - task: geeklearningio.gl-vsts-tasks-yarn.yarn-installer-task.YarnInstaller@2 inputs: - versionSpec: "1.3.2" + versionSpec: "1.9.4" - script: | yarn displayName: Install Dependencies diff --git a/build/tfs/linux/product-build-linux.yml b/build/tfs/linux/product-build-linux.yml index 9505d71ff34..f38980542e8 100644 --- a/build/tfs/linux/product-build-linux.yml +++ b/build/tfs/linux/product-build-linux.yml @@ -5,7 +5,7 @@ steps: - task: geeklearningio.gl-vsts-tasks-yarn.yarn-installer-task.YarnInstaller@2 inputs: - versionSpec: "1.3.2" + versionSpec: "1.9.4" - script: | set -e diff --git a/build/tfs/win32/continuous-build-win32.yml b/build/tfs/win32/continuous-build-win32.yml index 4e409f5d53d..780c9a0e197 100644 --- a/build/tfs/win32/continuous-build-win32.yml +++ b/build/tfs/win32/continuous-build-win32.yml @@ -4,7 +4,7 @@ steps: versionSpec: "8.9.1" - task: geeklearningio.gl-vsts-tasks-yarn.yarn-installer-task.YarnInstaller@2 inputs: - versionSpec: "1.3.2" + versionSpec: "1.9.4" - powershell: | yarn displayName: Install Dependencies diff --git a/build/tfs/win32/product-build-win32.yml b/build/tfs/win32/product-build-win32.yml index c887ade31fd..31288bdbdda 100644 --- a/build/tfs/win32/product-build-win32.yml +++ b/build/tfs/win32/product-build-win32.yml @@ -5,7 +5,7 @@ steps: - task: geeklearningio.gl-vsts-tasks-yarn.yarn-installer-task.YarnInstaller@2 inputs: - versionSpec: "1.3.2" + versionSpec: "1.9.4" - powershell: | . build/tfs/win32/exec.ps1 From bced36add0af4330af08feef5a5264ac3d89603f Mon Sep 17 00:00:00 2001 From: Alex Dima <alexdima@microsoft.com> Date: Tue, 21 Aug 2018 12:43:51 +0200 Subject: [PATCH 1036/1276] Mark optional property --- build/lib/bundle.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build/lib/bundle.ts b/build/lib/bundle.ts index da38acec4f4..43855048c1f 100644 --- a/build/lib/bundle.ts +++ b/build/lib/bundle.ts @@ -46,7 +46,7 @@ export interface IEntryPoint { name: string; include?: string[]; exclude?: string[]; - prepend: string[]; + prepend?: string[]; append?: string[]; dest?: string; } From e3bb3a2f4a92e29716441d42718af17c9876beb7 Mon Sep 17 00:00:00 2001 From: Sandeep Somavarapu <sasomava@microsoft.com> Date: Tue, 21 Aug 2018 13:02:03 +0200 Subject: [PATCH 1037/1276] fix compilation --- src/vs/platform/download/node/downloadIpc.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vs/platform/download/node/downloadIpc.ts b/src/vs/platform/download/node/downloadIpc.ts index fa914daf42a..bcd744a2406 100644 --- a/src/vs/platform/download/node/downloadIpc.ts +++ b/src/vs/platform/download/node/downloadIpc.ts @@ -9,7 +9,7 @@ import URI from 'vs/base/common/uri'; import * as path from 'path'; import * as fs from 'fs'; import { TPromise } from 'vs/base/common/winjs.base'; -import { IChannel } from 'vs/base/parts/ipc/common/ipc'; +import { IChannel } from 'vs/base/parts/ipc/node/ipc'; import { Event, Emitter, buffer } from 'vs/base/common/event'; import { IDownloadService } from 'vs/platform/download/common/download'; import { mkdirp } from 'vs/base/node/pfs'; From 64556a39c8b97e762d098a650d0dbc5cf15d5ea3 Mon Sep 17 00:00:00 2001 From: Johannes Rieken <johannes.rieken@gmail.com> Date: Tue, 21 Aug 2018 15:56:36 +0200 Subject: [PATCH 1038/1276] perf - wait longer when no cached data was used --- .../startupTimingsAppender.ts | 23 ++++++++++++------- 1 file changed, 15 insertions(+), 8 deletions(-) diff --git a/src/vs/workbench/parts/performance/electron-browser/startupTimingsAppender.ts b/src/vs/workbench/parts/performance/electron-browser/startupTimingsAppender.ts index 9bf3aeb1cf9..676b7c3e4f3 100644 --- a/src/vs/workbench/parts/performance/electron-browser/startupTimingsAppender.ts +++ b/src/vs/workbench/parts/performance/electron-browser/startupTimingsAppender.ts @@ -9,10 +9,10 @@ import { ILifecycleService, LifecyclePhase } from 'vs/platform/lifecycle/common/ import { IWindowsService } from 'vs/platform/windows/common/windows'; import { IWorkbenchContributionsRegistry, IWorkbenchContribution, Extensions } from 'vs/workbench/common/contributions'; import { Registry } from 'vs/platform/registry/common/platform'; -import { ITimerService } from 'vs/workbench/services/timer/electron-browser/timerService'; +import { ITimerService, didUseCachedData } from 'vs/workbench/services/timer/electron-browser/timerService'; import { IEnvironmentService } from 'vs/platform/environment/common/environment'; -import { nfcall } from 'vs/base/common/async'; -import { appendFile } from 'fs'; +import { nfcall, timeout } from 'vs/base/common/async'; +import { appendFile, } from 'fs'; import product from 'vs/platform/node/product'; class StartupTimingsAppender implements IWorkbenchContribution { @@ -26,14 +26,14 @@ class StartupTimingsAppender implements IWorkbenchContribution { let appendTo = environmentService.args['prof-append-timers']; if (!appendTo) { + // nothing to do return; } Promise.all([ - lifecycleService.when(LifecyclePhase.Eventually), - timerService.startupMetrics - ]).then(([, startupMetrics]) => { - + timerService.startupMetrics, + this._waitWhenNoCachedData(), + ]).then(([startupMetrics]) => { return nfcall(appendFile, appendTo, `${startupMetrics.ellapsed}\t${product.nameLong}\t${product.commit || '0000000'}\n`); }).then(() => { windowsService.quit(); @@ -42,7 +42,14 @@ class StartupTimingsAppender implements IWorkbenchContribution { windowsService.quit(); }); } + + private _waitWhenNoCachedData(): Promise<void> { + // wait 15s for cached data to be produced + return !didUseCachedData() + ? timeout(15000) + : Promise.resolve(); + } } const registry = Registry.as<IWorkbenchContributionsRegistry>(Extensions.Workbench); -registry.registerWorkbenchContribution(StartupTimingsAppender, LifecyclePhase.Running); +registry.registerWorkbenchContribution(StartupTimingsAppender, LifecyclePhase.Eventually); From ad4fecadebac63223a3f1c8f5cc9cc9eb2d82647 Mon Sep 17 00:00:00 2001 From: Joao Moreno <joao.moreno@microsoft.com> Date: Tue, 21 Aug 2018 16:04:00 +0200 Subject: [PATCH 1039/1276] git: getAPI --- extensions/git/package.json | 1 + extensions/git/src/api/api.ts | 43 +++++++++++++++++++ extensions/git/src/api/api0.ts | 18 ++++++++ .../git/src/{api.impl.ts => api/extension.ts} | 13 +++--- extensions/git/src/{api.d.ts => api/git.d.ts} | 5 +-- extensions/git/src/main.ts | 6 ++- extensions/git/yarn.lock | 4 ++ 7 files changed, 80 insertions(+), 10 deletions(-) create mode 100644 extensions/git/src/api/api.ts create mode 100644 extensions/git/src/api/api0.ts rename extensions/git/src/{api.impl.ts => api/extension.ts} (79%) rename extensions/git/src/{api.d.ts => api/git.d.ts} (94%) diff --git a/extensions/git/package.json b/extensions/git/package.json index 712f071eb3a..41f2020898c 100644 --- a/extensions/git/package.json +++ b/extensions/git/package.json @@ -1197,6 +1197,7 @@ "file-type": "^7.2.0", "iconv-lite": "0.4.19", "jschardet": "^1.6.0", + "semver": "^5.5.1", "vscode-extension-telemetry": "0.0.18", "vscode-nls": "^3.2.4", "which": "^1.3.0" diff --git a/extensions/git/src/api/api.ts b/extensions/git/src/api/api.ts new file mode 100644 index 00000000000..6244f0580e6 --- /dev/null +++ b/extensions/git/src/api/api.ts @@ -0,0 +1,43 @@ +/*--------------------------------------------------------------------------------------------- + * 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 { Model } from '../model'; +import { GitExtension } from './git'; +import * as semver from 'semver'; + +interface ApiCtor { + new(model: Model): GitExtension.API; +} + +const versions: string[] = []; +const apis = new Map<string, ApiCtor>(); + +export function getAPI(model: Model, range: string): GitExtension.API { + if (!range) { + throw new Error(`Please provide a Git extension API version range. Available versions: [${versions.join(', ')}]`); + } + + const version = semver.maxSatisfying(versions, range); + + if (!version) { + throw new Error(`There's no available Git extension API for the given range: '${range}'. Available versions: [${versions.join(', ')}]`); + } + + const api = apis.get(version)!; + return new api(model); +} + +export function Api(version: string): Function { + return function (ctor: ApiCtor) { + if (apis.has(version)) { + throw new Error(`Git extension API version ${version} already registered.`); + } + + versions.push(version); + apis.set(version, ctor); + }; +} \ No newline at end of file diff --git a/extensions/git/src/api/api0.ts b/extensions/git/src/api/api0.ts new file mode 100644 index 00000000000..95dd53446dc --- /dev/null +++ b/extensions/git/src/api/api0.ts @@ -0,0 +1,18 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +'use strict'; + +import { Model } from '../model'; +import { GitExtension } from './git'; +import { Api } from './api'; + +@Api('0.1.0') +export class ApiImpl implements GitExtension.API { + + constructor(model: Model) { + // console.log(model); + } +} diff --git a/extensions/git/src/api.impl.ts b/extensions/git/src/api/extension.ts similarity index 79% rename from extensions/git/src/api.impl.ts rename to extensions/git/src/api/extension.ts index ff702cf52e8..0f6386693ce 100644 --- a/extensions/git/src/api.impl.ts +++ b/extensions/git/src/api/extension.ts @@ -5,10 +5,11 @@ 'use strict'; -import { Model } from './model'; -import { Repository as ModelRepository } from './repository'; +import { Model } from '../model'; +import { Repository as ModelRepository } from '../repository'; import { Uri, SourceControlInputBox } from 'vscode'; -import { GitExtension } from './api'; +import { GitExtension } from './git'; +import { getAPI } from './api'; class InputBoxImpl implements GitExtension.InputBox { set value(value: string) { this.inputBox.value = value; } @@ -31,12 +32,14 @@ export function createGitExtension(model?: Model): GitExtension { if (!model) { return { getGitPath() { throw new Error('Git model not found'); }, - getRepositories() { throw new Error('Git model not found'); } + getRepositories() { throw new Error('Git model not found'); }, + getAPI() { throw new Error('Git model not found'); } }; } return { async getGitPath() { return model.git.path; }, - async getRepositories() { return model.repositories.map(repository => new RepositoryImpl(repository)); } + async getRepositories() { return model.repositories.map(repository => new RepositoryImpl(repository)); }, + getAPI(range: string) { return getAPI(model, range); } }; } diff --git a/extensions/git/src/api.d.ts b/extensions/git/src/api/git.d.ts similarity index 94% rename from extensions/git/src/api.d.ts rename to extensions/git/src/api/git.d.ts index 3273c7e4c00..f8a22cb1c4b 100644 --- a/extensions/git/src/api.d.ts +++ b/extensions/git/src/api/git.d.ts @@ -10,9 +10,6 @@ declare module GitExtension { } - // export const availableVersions: string[]; - // export function getAPI(version: string): API; - //#region Deprecated API export interface InputBox { value: string; @@ -28,4 +25,6 @@ declare module GitExtension { export interface GitExtension { getRepositories(): Promise<GitExtension.Repository[]>; getGitPath(): Promise<string>; + // export const availableVersions: string[]; + getAPI(range: string): GitExtension.API; } \ No newline at end of file diff --git a/extensions/git/src/main.ts b/extensions/git/src/main.ts index f4833c8985f..82e98d2cea9 100644 --- a/extensions/git/src/main.ts +++ b/extensions/git/src/main.ts @@ -17,9 +17,11 @@ import { GitDecorations } from './decorationProvider'; import { Askpass } from './askpass'; import { toDisposable, filterEvent, eventToPromise } from './util'; import TelemetryReporter from 'vscode-extension-telemetry'; -import { GitExtension } from './api'; +import { GitExtension } from './api/git'; import { GitProtocolHandler } from './protocolHandler'; -import { createGitExtension } from './api.impl'; +import { createGitExtension } from './api/extension'; + +import './api/api0'; const deactivateTasks: { (): Promise<any>; }[] = []; diff --git a/extensions/git/yarn.lock b/extensions/git/yarn.lock index cf3f64be853..d47f44ccf7a 100644 --- a/extensions/git/yarn.lock +++ b/extensions/git/yarn.lock @@ -251,6 +251,10 @@ semver@^5.3.0: version "5.5.0" resolved "https://registry.yarnpkg.com/semver/-/semver-5.5.0.tgz#dc4bbc7a6ca9d916dee5d43516f0092b58f7b8ab" +semver@^5.5.1: + version "5.5.1" + resolved "https://registry.yarnpkg.com/semver/-/semver-5.5.1.tgz#7dfdd8814bdb7cabc7be0fb1d734cfb66c940477" + supports-color@3.1.2: version "3.1.2" resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-3.1.2.tgz#72a262894d9d408b956ca05ff37b2ed8a6e2a2d5" From 6bba18bddf54539dbd857b19bcbd727e81995798 Mon Sep 17 00:00:00 2001 From: Sandeep Somavarapu <sasomava@microsoft.com> Date: Tue, 21 Aug 2018 16:25:00 +0200 Subject: [PATCH 1040/1276] remove dependency on glob --- .../node/extensionManagementService.ts | 34 +++++++++++++------ 1 file changed, 23 insertions(+), 11 deletions(-) diff --git a/src/vs/platform/extensionManagement/node/extensionManagementService.ts b/src/vs/platform/extensionManagement/node/extensionManagementService.ts index e2dcef51377..a48cd5e5ed4 100644 --- a/src/vs/platform/extensionManagement/node/extensionManagementService.ts +++ b/src/vs/platform/extensionManagement/node/extensionManagementService.ts @@ -7,7 +7,6 @@ import * as nls from 'vs/nls'; import * as path from 'path'; -import * as glob from 'glob'; import * as pfs from 'vs/base/node/pfs'; import * as errors from 'vs/base/common/errors'; import { assign } from 'vs/base/common/objects'; @@ -160,7 +159,7 @@ export class ExtensionManagementService extends Disposable implements IExtension } zip(extension: ILocalExtension): TPromise<URI> { - return this.collectFiles(extension) + return TPromise.wrap(this.collectFiles(extension)) .then(files => zip(path.join(tmpdir(), generateUuid()), files)) .then(path => URI.file(path)); } @@ -173,17 +172,30 @@ export class ExtensionManagementService extends Disposable implements IExtension return this.downloadService.download(zipLocation, downloadedLocation).then(() => this.install(URI.file(downloadedLocation), type)); } - private collectFiles(extension: ILocalExtension): TPromise<IFile[]> { - return new TPromise((c, e) => { - glob('**', { cwd: extension.location.fsPath, nodir: true, dot: true }, (err: Error, files: string[]) => { - if (err) { - e(err); - } else { - c(files.map(f => f.replace(/\\/g, '/')) - .map(f => (<IFile>{ path: `extension/${f}`, localPath: path.join(extension.location.fsPath, f) }))); + private collectFiles(extension: ILocalExtension): Promise<IFile[]> { + + const collectFilesFromDirectory = async (dir): Promise<string[]> => { + let entries = await pfs.readdir(dir); + entries = entries.map(e => path.join(dir, e)); + const stats = await Promise.all(entries.map(e => pfs.stat(e))); + let promise: Promise<string[]> = Promise.resolve([]); + stats.forEach((stat, index) => { + const entry = entries[index]; + if (stat.isFile()) { + promise = promise.then(result => ([...result, entry])); + } + if (stat.isDirectory()) { + promise = promise + .then(result => collectFilesFromDirectory(entry) + .then(files => ([...result, ...files]))); } }); - }); + return promise; + }; + + return collectFilesFromDirectory(extension.location.fsPath) + .then(files => files.map(f => (<IFile>{ path: `extension/${path.relative(extension.location.fsPath, f)}`, localPath: f }))); + } install(vsix: URI, type: LocalExtensionType = LocalExtensionType.User): TPromise<IExtensionIdentifier> { From 8dc35942447211a66a68eae368f9d2f352a8622a Mon Sep 17 00:00:00 2001 From: Sandeep Somavarapu <sasomava@microsoft.com> Date: Tue, 21 Aug 2018 16:26:48 +0200 Subject: [PATCH 1041/1276] remove glob dep in package.json --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 839cb95988a..c8d92f96eaf 100644 --- a/package.json +++ b/package.json @@ -29,7 +29,6 @@ "fast-plist": "0.1.2", "gc-signals": "^0.0.1", "getmac": "1.4.1", - "glob": "^5.0.13", "graceful-fs": "4.1.11", "http-proxy-agent": "^2.1.0", "https-proxy-agent": "^2.2.1", @@ -73,6 +72,7 @@ "eslint": "^3.4.0", "event-stream": "^3.1.7", "express": "^4.13.1", + "glob": "^5.0.13", "gulp": "^3.8.9", "gulp-atom-electron": "^1.16.1", "gulp-azure-storage": "^0.7.0", From 4b3a8227a88e2a249f5cccc01920ca67c0b6fd39 Mon Sep 17 00:00:00 2001 From: Sandeep Somavarapu <sasomava@microsoft.com> Date: Tue, 21 Aug 2018 16:30:09 +0200 Subject: [PATCH 1042/1276] remove glob.d.ts --- src/typings/glob.d.ts | 302 ------------------------------------------ 1 file changed, 302 deletions(-) delete mode 100644 src/typings/glob.d.ts diff --git a/src/typings/glob.d.ts b/src/typings/glob.d.ts deleted file mode 100644 index c2574b3f0ee..00000000000 --- a/src/typings/glob.d.ts +++ /dev/null @@ -1,302 +0,0 @@ -// Generated by typings -// Source: https://raw.githubusercontent.com/typed-typings/npm-minimatch/74f47de8acb42d668491987fc6bc144e7d9aa891/minimatch.d.ts -declare module '~glob~minimatch/minimatch' { -function minimatch (target: string, pattern: string, options?: minimatch.Options): boolean; - -namespace minimatch { - export function match (list: string[], pattern: string, options?: Options): string[]; - export function filter (pattern: string, options?: Options): (element: string, indexed: number, array: string[]) => boolean; - export function makeRe (pattern: string, options?: Options): RegExp; - - /** - * All options are `false` by default. - */ - export interface Options { - /** - * Dump a ton of stuff to stderr. - */ - debug?: boolean; - /** - * Do not expand `{a,b}` and `{1..3}` brace sets. - */ - nobrace?: boolean; - /** - * Disable `**` matching against multiple folder names. - */ - noglobstar?: boolean; - /** - * Allow patterns to match filenames starting with a period, even if the pattern does not explicitly have a period in that spot. - * - * Note that by default, `a\/**\/b` will not match `a/.d/b`, unless `dot` is set. - */ - dot?: boolean; - /** - * Disable "extglob" style patterns like `+(a|b)`. - */ - noext?: boolean; - /** - * Perform a case-insensitive match. - */ - nocase?: boolean; - /** - * When a match is not found by `minimatch.match`, return a list containing the pattern itself if this option is set. When not set, an empty list is returned if there are no matches. - */ - nonull?: boolean; - /** - * If set, then patterns without slashes will be matched against the basename of the path if it contains slashes. For example, `a?b` would match the path `/xyz/123/acb`, but not `/xyz/acb/123`. - */ - matchBase?: boolean; - /** - * Suppress the behavior of treating `#` at the start of a pattern as a comment. - */ - nocomment?: boolean; - /** - * Suppress the behavior of treating a leading `!` character as negation. - */ - nonegate?: boolean; - /** - * Returns from negate expressions the same as if they were not negated. (Ie, true on a hit, false on a miss.) - */ - flipNegate?: boolean; - } - - export class Minimatch { - constructor (pattern: string, options?: Options); - - /** - * The original pattern the minimatch object represents. - */ - pattern: string; - /** - * The options supplied to the constructor. - */ - options: Options; - - /** - * Created by the `makeRe` method. A single regular expression expressing the entire pattern. This is useful in cases where you wish to use the pattern somewhat like `fnmatch(3)` with `FNM_PATH` enabled. - */ - regexp: RegExp; - /** - * True if the pattern is negated. - */ - negate: boolean; - /** - * True if the pattern is a comment. - */ - comment: boolean; - /** - * True if the pattern is `""`. - */ - empty: boolean; - - /** - * Generate the regexp member if necessary, and return it. Will return false if the pattern is invalid. - */ - makeRe (): RegExp | boolean; - /** - * Return true if the filename matches the pattern, or false otherwise. - */ - match (fname: string): boolean; - /** - * Take a `/-`split filename, and match it against a single row in the `regExpSet`. This method is mainly for internal use, but is exposed so that it can be used by a glob-walker that needs to avoid excessive filesystem calls. - */ - matchOne (fileArray: string[], patternArray: string[], partial: boolean): boolean; - } -} - -export = minimatch; -} -declare module '~glob~minimatch' { -import main = require('~glob~minimatch/minimatch'); -export = main; -} - -// Generated by typings -// Source: https://raw.githubusercontent.com/types/npm-glob/59ca0f5d4696a8d4da27858035316c1014133fcb/glob.d.ts -declare module '~glob/glob' { -import events = require('events'); -import fs = require('fs'); -import minimatch = require('~glob~minimatch'); - -function glob (pattern: string, cb: (err: Error, matches: string[]) => void): void; -function glob (pattern: string, options: glob.Options, cb: (err: Error, matches: string[]) => void): void; - -namespace glob { - export function sync (pattern: string, options?: Options): string[]; - export function hasMagic (pattern: string, options?: Options): boolean; - - export interface Cache { - [path: string]: boolean | string | string[]; - } - - export interface StatCache { - [path: string]: fs.Stats; - } - - export interface Symlinks { - [path: string]: boolean; - } - - export interface Options extends minimatch.Options { - /** - * The current working directory in which to search. Defaults to `process.cwd()`. - */ - cwd?: string; - /** - * The place where patterns starting with `/` will be mounted onto. Defaults to `path.resolve(options.cwd, "/")` (`/` on Unix systems, and `C:\` or some such on Windows.) - */ - root?: string; - /** - * Include `.dot` files in normal matches and `globstar` matches. Note that an explicit dot in a portion of the pattern will always match dot files. - */ - dot?: boolean; - /** - * By default, a pattern starting with a forward-slash will be "mounted" onto the root setting, so that a valid filesystem path is returned. Set this flag to disable that behavior. - */ - nomount?: boolean; - /** - * Add a `/` character to directory matches. Note that this requires additional stat calls. - */ - mark?: boolean; - /** - * Don't sort the results. - */ - nosort?: boolean; - /** - * Set to true to stat all results. This reduces performance somewhat, and is completely unnecessary, unless `readdir` is presumed to be an untrustworthy indicator of file existence. - */ - stat?: boolean; - /** - * When an unusual error is encountered when attempting to read a directory, a warning will be printed to stderr. Set the `silent` option to true to suppress these warnings. - */ - silent?: boolean; - /** - * When an unusual error is encountered when attempting to read a directory, the process will just continue on in search of other matches. Set the `strict` option to raise an error in these cases. - */ - strict?: boolean; - /** - * See `cache` property above. Pass in a previously generated cache object to save some fs calls. - */ - cache?: Cache; - /** - * A cache of results of filesystem information, to prevent unnecessary stat calls. While it should not normally be necessary to set this, you may pass the statCache from one glob() call to the options object of another, if you know that the filesystem will not change between calls. (See https://github.com/isaacs/node-glob#race-conditions) - */ - statCache?: StatCache; - /** - * A cache of known symbolic links. You may pass in a previously generated `symlinks` object to save lstat calls when resolving `**` matches. - */ - symlinks?: Symlinks; - /** - * DEPRECATED: use `glob.sync(pattern, opts)` instead. - */ - sync?: boolean; - /** - * In some cases, brace-expanded patterns can result in the same file showing up multiple times in the result set. By default, this implementation prevents duplicates in the result set. Set this flag to disable that behavior. - */ - nounique?: boolean; - /** - * Set to never return an empty set, instead returning a set containing the pattern itself. This is the default in glob(3). - */ - nonull?: boolean; - /** - * Set to enable debug logging in minimatch and glob. - */ - debug?: boolean; - /** - * Do not expand `{a,b}` and `{1..3}` brace sets. - */ - nobrace?: boolean; - /** - * Do not match `**` against multiple filenames. (Ie, treat it as a normal `*` instead.) - */ - noglobstar?: boolean; - /** - * Do not match `+(a|b)` "extglob" patterns. - */ - noext?: boolean; - /** - * Perform a case-insensitive match. Note: on case-insensitive filesystems, non-magic patterns will match by default, since `stat` and `readdir` will not raise errors. - */ - nocase?: boolean; - /** - * Perform a basename-only match if the pattern does not contain any slash characters. That is, `*.js` would be treated as equivalent to `**\/*.js`, matching all js files in all directories. - */ - matchBase?: any; - /** - * Do not match directories, only files. (Note: to match only directories, simply put a `/` at the end of the pattern.) - */ - nodir?: boolean; - /** - * Add a pattern or an array of glob patterns to exclude matches. Note: `ignore` patterns are always in `dot:true` mode, regardless of any other settings. - */ - ignore?: string | string[]; - /** - * Follow symlinked directories when expanding `**` patterns. Note that this can result in a lot of duplicate references in the presence of cyclic links. - */ - follow?: boolean; - /** - * Set to true to call `fs.realpath` on all of the results. In the case of a symlink that cannot be resolved, the full absolute path to the matched entry is returned (though it will usually be a broken symlink) - */ - realpath?: boolean; - } - - export class Glob extends events.EventEmitter { - constructor (pattern: string, cb?: (err: Error, matches: string[]) => void); - constructor (pattern: string, options: Options, cb?: (err: Error, matches: string[]) => void); - - /** - * The minimatch object that the glob uses. - */ - minimatch: minimatch.Minimatch; - /** - * The options object passed in. - */ - options: Options; - /** - * Boolean which is set to true when calling `abort()`. There is no way at this time to continue a glob search after aborting, but you can re-use the statCache to avoid having to duplicate syscalls. - * @type {boolean} - */ - aborted: boolean; - /** - * Convenience object. - */ - cache: Cache; - /** - * Cache of `fs.stat` results, to prevent statting the same path multiple times. - */ - statCache: StatCache; - /** - * A record of which paths are symbolic links, which is relevant in resolving `**` patterns. - */ - symlinks: Symlinks; - /** - * An optional object which is passed to `fs.realpath` to minimize unnecessary syscalls. It is stored on the instantiated Glob object, and may be re-used. - */ - realpathCache: { [path: string]: string }; - found: string[]; - - /** - * Temporarily stop the search. - */ - pause(): void; - /** - * Resume the search. - */ - resume(): void; - /** - * Stop the search forever. - */ - abort(): void; - } -} - -export = glob; -} -declare module 'glob/glob' { -import main = require('~glob/glob'); -export = main; -} -declare module 'glob' { -import main = require('~glob/glob'); -export = main; -} From ac96d6041814aee47a7a4acd229502c7498b2504 Mon Sep 17 00:00:00 2001 From: isidor <inikolic@microsoft.com> Date: Tue, 21 Aug 2018 16:33:47 +0200 Subject: [PATCH 1043/1276] debug: do not de-attach all session listeners when raw session goes down fixes #55025 --- .../debug/electron-browser/debugService.ts | 18 +++++++++--------- .../debug/electron-browser/debugSession.ts | 5 +++-- 2 files changed, 12 insertions(+), 11 deletions(-) diff --git a/src/vs/workbench/parts/debug/electron-browser/debugService.ts b/src/vs/workbench/parts/debug/electron-browser/debugService.ts index 1a54c5824b4..182570ef159 100644 --- a/src/vs/workbench/parts/debug/electron-browser/debugService.ts +++ b/src/vs/workbench/parts/debug/electron-browser/debugService.ts @@ -145,7 +145,10 @@ export class DebugService implements IDebugService { session.configuration.request = 'attach'; session.configuration.port = broadcast.payload.port; const dbgr = this.configurationManager.getDebugger(session.configuration.type); - session.initialize(dbgr).then(() => (<RawDebugSession>session.raw).attach(session.configuration)); + session.initialize(dbgr).then(() => { + (<RawDebugSession>session.raw).attach(session.configuration); + this.focusStackFrame(undefined, undefined, session); + }); return; } @@ -734,16 +737,14 @@ export class DebugService implements IDebugService { } private registerSessionListeners(session: Session): void { - const toDispose: IDisposable[] = []; - - toDispose.push(session.onDidChangeState((state) => { - if (state === State.Running && this.viewModel.focusedSession.getId() === session.getId()) { + this.toDispose.push(session.onDidChangeState((state) => { + if (state === State.Running && this.viewModel.focusedSession && this.viewModel.focusedSession.getId() === session.getId()) { this.focusStackFrame(undefined); } this.onStateChange(); })); - toDispose.push(session.onDidExitAdapter(() => { + this.toDispose.push(session.onDidExitAdapter(() => { // 'Run without debugging' mode VSCode must terminate the extension host. More details: #3905 if (equalsIgnoreCase(session.configuration.type, 'extensionhost') && session.state === State.Running && session.configuration.noDebug) { this.broadcastService.broadcast({ @@ -776,13 +777,12 @@ export class DebugService implements IDebugService { this.notificationService.error(err) ); } - toDispose.push(session); - dispose(toDispose); + session.dispose(); this._onDidEndSession.fire(session); const focusedSession = this.viewModel.focusedSession; if (focusedSession && focusedSession.getId() === session.getId()) { - this.focusStackFrame(null); + this.focusStackFrame(undefined); } if (this.model.getSessions().length === 0) { diff --git a/src/vs/workbench/parts/debug/electron-browser/debugSession.ts b/src/vs/workbench/parts/debug/electron-browser/debugSession.ts index b80961dab3a..b9d3af99d1f 100644 --- a/src/vs/workbench/parts/debug/electron-browser/debugSession.ts +++ b/src/vs/workbench/parts/debug/electron-browser/debugSession.ts @@ -52,7 +52,6 @@ export class Session implements ISession { @IDebugService private debugService: IDebugService, @ITelemetryService private telemetryService: ITelemetryService, ) { - this.model.addSession(this); this.state = State.Initializing; } @@ -227,8 +226,9 @@ export class Session implements ISession { initialize(dbgr: Debugger): TPromise<void> { if (this._raw) { // If there was already a connection make sure to remove old listeners - this.rawListeners = dispose(this.rawListeners); + this.dispose(); } + return dbgr.getCustomTelemetryService().then(customTelemetryService => { this._raw = this.instantiationService.createInstance(RawDebugSession, this.id, this._configuration.resolved.debugServer, dbgr, customTelemetryService, this.root); this.registerListeners(); @@ -245,6 +245,7 @@ export class Session implements ISession { supportsRunInTerminalRequest: true, // #10574 locale: platform.locale }).then(() => { + this.model.addSession(this); this.state = State.Running; this.model.setExceptionBreakpoints(this._raw.capabilities.exceptionBreakpointFilters); }); From a9e3a3d69e844623e1d25904272c2423d17b04e5 Mon Sep 17 00:00:00 2001 From: Johannes Rieken <johannes.rieken@gmail.com> Date: Tue, 21 Aug 2018 16:39:52 +0200 Subject: [PATCH 1044/1276] webpack - check js files, declare params, #56081 --- extensions/emmet/extension.webpack.config.js | 8 ++++---- extensions/git/extension.webpack.config.js | 9 +++++---- extensions/shared.webpack.config.js | 8 +++++++- package.json | 1 + yarn.lock | 21 +++++++++++++++++++- 5 files changed, 37 insertions(+), 10 deletions(-) diff --git a/extensions/emmet/extension.webpack.config.js b/extensions/emmet/extension.webpack.config.js index b86756e4aa8..d066fbf4bb4 100644 --- a/extensions/emmet/extension.webpack.config.js +++ b/extensions/emmet/extension.webpack.config.js @@ -3,11 +3,13 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ +//@ts-check + 'use strict'; const withDefaults = require('../shared.webpack.config'); -const myConfig = { +module.exports = withDefaults({ context: __dirname, entry: { extension: './src/extension.ts', @@ -19,6 +21,4 @@ const myConfig = { 'image-size': 'commonjs image-size', 'vscode-emmet-helper': 'commonjs vscode-emmet-helper', }, -}; - -module.exports = withDefaults(myConfig); +}); diff --git a/extensions/git/extension.webpack.config.js b/extensions/git/extension.webpack.config.js index 35f3239228b..1573e4928ab 100644 --- a/extensions/git/extension.webpack.config.js +++ b/extensions/git/extension.webpack.config.js @@ -3,12 +3,15 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ +//@ts-check + 'use strict'; const withDefaults = require('../shared.webpack.config'); const CopyWebpackPlugin = require('copy-webpack-plugin'); -const myConfig = { + +module.exports = withDefaults({ context: __dirname, node: { __dirname: false // leave the __dirname-behaviour intact @@ -32,6 +35,4 @@ const myConfig = { "vscode-nls": 'commonjs vscode-nls', "which": 'commonjs which', }, -}; - -module.exports = withDefaults(myConfig); +}); diff --git a/extensions/shared.webpack.config.js b/extensions/shared.webpack.config.js index 14a79dfdcd5..78ecff5f03b 100644 --- a/extensions/shared.webpack.config.js +++ b/extensions/shared.webpack.config.js @@ -3,12 +3,18 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ +//@ts-check +/** @typedef {import('webpack').Configuration} WebpackConfig **/ + 'use strict'; const path = require('path'); const merge = require('merge-options'); -module.exports = function withDefaults(extConfig) { + +module.exports = function withDefaults(/**@type WebpackConfig*/extConfig) { + + /** @type WebpackConfig */ let defaultConfig = { mode: 'none', // this leaves the source code as close as possible to the original (when packaging we set this to 'production') target: 'node', // extensions run in a node context diff --git a/package.json b/package.json index c8d92f96eaf..134505e89c0 100644 --- a/package.json +++ b/package.json @@ -60,6 +60,7 @@ "@types/minimist": "1.2.0", "@types/mocha": "2.2.39", "@types/sinon": "1.16.34", + "@types/webpack": "^4.4.10", "asar": "^0.14.0", "chromium-pickle-js": "^0.2.0", "clean-css": "3.4.6", diff --git a/yarn.lock b/yarn.lock index 8d3247c1e6e..f9f3b0b1d1c 100644 --- a/yarn.lock +++ b/yarn.lock @@ -43,6 +43,25 @@ version "1.16.34" resolved "https://registry.yarnpkg.com/@types/sinon/-/sinon-1.16.34.tgz#a9761fff33d0f7b3fe61875b577778a2576a9a03" +"@types/tapable@*": + version "1.0.4" + resolved "https://registry.yarnpkg.com/@types/tapable/-/tapable-1.0.4.tgz#b4ffc7dc97b498c969b360a41eee247f82616370" + +"@types/uglify-js@*": + version "3.0.3" + resolved "https://registry.yarnpkg.com/@types/uglify-js/-/uglify-js-3.0.3.tgz#801a5ca1dc642861f47c46d14b700ed2d610840b" + dependencies: + source-map "^0.6.1" + +"@types/webpack@^4.4.10": + version "4.4.10" + resolved "https://registry.yarnpkg.com/@types/webpack/-/webpack-4.4.10.tgz#2ecf12589142bc531549140612815b7d8b076358" + dependencies: + "@types/node" "*" + "@types/tapable" "*" + "@types/uglify-js" "*" + source-map "^0.6.0" + "@webassemblyjs/ast@1.5.13": version "1.5.13" resolved "https://registry.yarnpkg.com/@webassemblyjs/ast/-/ast-1.5.13.tgz#81155a570bd5803a30ec31436bc2c9c0ede38f25" @@ -6880,7 +6899,7 @@ source-map@0.4.x, source-map@^0.4.4: dependencies: amdefine ">=0.0.4" -source-map@0.X, source-map@>=0.5.6, source-map@^0.6.1, source-map@~0.6.1: +source-map@0.X, source-map@>=0.5.6, source-map@^0.6.0, source-map@^0.6.1, source-map@~0.6.1: version "0.6.1" resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263" From b00d1b40bc0db63ffa47367411d8c145a8bf0a4f Mon Sep 17 00:00:00 2001 From: Joao Moreno <joao.moreno@microsoft.com> Date: Tue, 21 Aug 2018 16:41:29 +0200 Subject: [PATCH 1045/1276] git api: expose gitPath --- extensions/git/src/api/api0.ts | 6 ++++-- extensions/git/src/api/git.d.ts | 3 ++- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/extensions/git/src/api/api0.ts b/extensions/git/src/api/api0.ts index 95dd53446dc..b65cfc3dc09 100644 --- a/extensions/git/src/api/api0.ts +++ b/extensions/git/src/api/api0.ts @@ -12,7 +12,9 @@ import { Api } from './api'; @Api('0.1.0') export class ApiImpl implements GitExtension.API { - constructor(model: Model) { - // console.log(model); + get gitPath(): string { + return this._model.git.path; } + + constructor(private _model: Model) { } } diff --git a/extensions/git/src/api/git.d.ts b/extensions/git/src/api/git.d.ts index f8a22cb1c4b..16d36bd7ada 100644 --- a/extensions/git/src/api/git.d.ts +++ b/extensions/git/src/api/git.d.ts @@ -6,8 +6,9 @@ import { Uri, SourceControlInputBox } from 'vscode'; declare module GitExtension { - export interface API { + export interface API { + readonly gitPath: string; } //#region Deprecated API From 257878e3b191a2e0e83fb62f6242cfbda898ecd8 Mon Sep 17 00:00:00 2001 From: Joao Moreno <joao.moreno@microsoft.com> Date: Tue, 21 Aug 2018 16:41:34 +0200 Subject: [PATCH 1046/1276] git api: deprecation --- extensions/git/src/api/api.ts | 12 +++++++ extensions/git/src/api/extension.ts | 54 ++++++++++++++++++++++------- 2 files changed, 53 insertions(+), 13 deletions(-) diff --git a/extensions/git/src/api/api.ts b/extensions/git/src/api/api.ts index 6244f0580e6..3f7d7303b8c 100644 --- a/extensions/git/src/api/api.ts +++ b/extensions/git/src/api/api.ts @@ -40,4 +40,16 @@ export function Api(version: string): Function { versions.push(version); apis.set(version, ctor); }; +} + +export function deprecated(target: any, key: string, descriptor: any): void { + if (typeof descriptor.value !== 'function') { + throw new Error('not supported'); + } + + const fn = descriptor.value; + descriptor.value = function () { + console.warn(`Git extension API method '${key}' is deprecated.`); + return fn.apply(this, arguments); + }; } \ No newline at end of file diff --git a/extensions/git/src/api/extension.ts b/extensions/git/src/api/extension.ts index 0f6386693ce..9f14f436f38 100644 --- a/extensions/git/src/api/extension.ts +++ b/extensions/git/src/api/extension.ts @@ -9,7 +9,7 @@ import { Model } from '../model'; import { Repository as ModelRepository } from '../repository'; import { Uri, SourceControlInputBox } from 'vscode'; import { GitExtension } from './git'; -import { getAPI } from './api'; +import { getAPI, deprecated } from './api'; class InputBoxImpl implements GitExtension.InputBox { set value(value: string) { this.inputBox.value = value; } @@ -28,18 +28,46 @@ class RepositoryImpl implements GitExtension.Repository { } } -export function createGitExtension(model?: Model): GitExtension { - if (!model) { - return { - getGitPath() { throw new Error('Git model not found'); }, - getRepositories() { throw new Error('Git model not found'); }, - getAPI() { throw new Error('Git model not found'); } - }; +class NoModelGitExtension implements GitExtension { + + @deprecated + async getGitPath(): Promise<string> { + throw new Error('Git model not found'); } - return { - async getGitPath() { return model.git.path; }, - async getRepositories() { return model.repositories.map(repository => new RepositoryImpl(repository)); }, - getAPI(range: string) { return getAPI(model, range); } - }; + @deprecated + async getRepositories(): Promise<GitExtension.Repository[]> { + throw new Error('Git model not found'); + } + + getAPI(): GitExtension.API { + throw new Error('Git model not found'); + } +} + +class GitExtensionImpl implements GitExtension { + + constructor(private _model: Model) { } + + @deprecated + async getGitPath(): Promise<string> { + return this._model.git.path; + } + + @deprecated + async getRepositories(): Promise<GitExtension.Repository[]> { + return this._model.repositories.map(repository => new RepositoryImpl(repository)); + } + + getAPI(range: string): GitExtension.API { + return getAPI(this._model, range); + } +} + +export function createGitExtension(model?: Model): GitExtension { + if (!model) { + return new NoModelGitExtension(); + } + + return new GitExtensionImpl(model); } From ee947947a7d87ee4138cdfcd09bd9fbf93cf26c2 Mon Sep 17 00:00:00 2001 From: Matt Bierner <matb@microsoft.com> Date: Tue, 21 Aug 2018 16:34:54 +0200 Subject: [PATCH 1047/1276] Fix duplicate markdown previews potentially being shown in the same editor group Fixes #56910 --- .../markdown-language-features/src/commands/showPreview.ts | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/extensions/markdown-language-features/src/commands/showPreview.ts b/extensions/markdown-language-features/src/commands/showPreview.ts index 3c4873ba424..bd59d575bbb 100644 --- a/extensions/markdown-language-features/src/commands/showPreview.ts +++ b/extensions/markdown-language-features/src/commands/showPreview.ts @@ -38,9 +38,10 @@ async function showPreview( return; } + const resourceColumn = (vscode.window.activeTextEditor && vscode.window.activeTextEditor.viewColumn) || vscode.ViewColumn.One; webviewManager.preview(resource, { - resourceColumn: (vscode.window.activeTextEditor && vscode.window.activeTextEditor.viewColumn) || vscode.ViewColumn.One, - previewColumn: previewSettings.sideBySide ? vscode.ViewColumn.Beside : vscode.ViewColumn.Active, + resourceColumn: resourceColumn, + previewColumn: previewSettings.sideBySide ? resourceColumn + 1 : resourceColumn, locked: !!previewSettings.locked }); From b371ad56756fb7946db7c231baad0b325525d740 Mon Sep 17 00:00:00 2001 From: isidor <inikolic@microsoft.com> Date: Tue, 21 Aug 2018 16:55:56 +0200 Subject: [PATCH 1048/1276] Need to react with a timeout on the blur event due to possible concurent splices fixes #56443 --- src/vs/workbench/parts/debug/browser/breakpointsView.ts | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/vs/workbench/parts/debug/browser/breakpointsView.ts b/src/vs/workbench/parts/debug/browser/breakpointsView.ts index 3784a56063b..45f200e54b0 100644 --- a/src/vs/workbench/parts/debug/browser/breakpointsView.ts +++ b/src/vs/workbench/parts/debug/browser/breakpointsView.ts @@ -518,9 +518,12 @@ class FunctionBreakpointInputRenderer implements IRenderer<IFunctionBreakpoint, } })); toDispose.push(dom.addDisposableListener(inputBox.inputElement, 'blur', () => { - if (!template.breakpoint.name) { - wrapUp(true); - } + // Need to react with a timeout on the blur event due to possible concurent splices #56443 + setTimeout(() => { + if (!template.breakpoint.name) { + wrapUp(true); + } + }); })); template.inputBox = inputBox; From cc5e8c15bf8fc738759c50c00b337791be636d5a Mon Sep 17 00:00:00 2001 From: Joao Moreno <joao.moreno@microsoft.com> Date: Tue, 21 Aug 2018 17:04:07 +0200 Subject: [PATCH 1049/1276] git api --- extensions/git/src/api/api0.ts | 28 ++++++++++++++++++++++++++++ extensions/git/src/api/extension.ts | 22 ++-------------------- extensions/git/src/api/git.d.ts | 6 +++--- 3 files changed, 33 insertions(+), 23 deletions(-) diff --git a/extensions/git/src/api/api0.ts b/extensions/git/src/api/api0.ts index b65cfc3dc09..63c404c9e7e 100644 --- a/extensions/git/src/api/api0.ts +++ b/extensions/git/src/api/api0.ts @@ -8,6 +8,26 @@ import { Model } from '../model'; import { GitExtension } from './git'; import { Api } from './api'; +import { Event, SourceControlInputBox, Uri } from 'vscode'; +import { mapEvent } from '../util'; +import { Repository } from '../repository'; + +class ApiInputBox implements GitExtension.InputBox { + set value(value: string) { this._inputBox.value = value; } + get value(): string { return this._inputBox.value; } + constructor(private _inputBox: SourceControlInputBox) { } +} + +export class ApiRepository implements GitExtension.Repository { + + readonly rootUri: Uri; + readonly inputBox: GitExtension.InputBox; + + constructor(_repository: Repository) { + this.rootUri = Uri.file(_repository.root); + this.inputBox = new ApiInputBox(_repository.inputBox); + } +} @Api('0.1.0') export class ApiImpl implements GitExtension.API { @@ -16,5 +36,13 @@ export class ApiImpl implements GitExtension.API { return this._model.git.path; } + get onDidOpenRepository(): Event<GitExtension.Repository> { + return mapEvent(this._model.onDidOpenRepository, r => new ApiRepository(r)); + } + + get onDidCloseRepository(): Event<GitExtension.Repository> { + return mapEvent(this._model.onDidCloseRepository, r => new ApiRepository(r)); + } + constructor(private _model: Model) { } } diff --git a/extensions/git/src/api/extension.ts b/extensions/git/src/api/extension.ts index 9f14f436f38..56868dc5092 100644 --- a/extensions/git/src/api/extension.ts +++ b/extensions/git/src/api/extension.ts @@ -6,27 +6,9 @@ 'use strict'; import { Model } from '../model'; -import { Repository as ModelRepository } from '../repository'; -import { Uri, SourceControlInputBox } from 'vscode'; import { GitExtension } from './git'; import { getAPI, deprecated } from './api'; - -class InputBoxImpl implements GitExtension.InputBox { - set value(value: string) { this.inputBox.value = value; } - get value(): string { return this.inputBox.value; } - constructor(private inputBox: SourceControlInputBox) { } -} - -class RepositoryImpl implements GitExtension.Repository { - - readonly rootUri: Uri; - readonly inputBox: GitExtension.InputBox; - - constructor(repository: ModelRepository) { - this.rootUri = Uri.file(repository.root); - this.inputBox = new InputBoxImpl(repository.inputBox); - } -} +import { ApiRepository } from './api0'; class NoModelGitExtension implements GitExtension { @@ -56,7 +38,7 @@ class GitExtensionImpl implements GitExtension { @deprecated async getRepositories(): Promise<GitExtension.Repository[]> { - return this._model.repositories.map(repository => new RepositoryImpl(repository)); + return this._model.repositories.map(repository => new ApiRepository(repository)); } getAPI(range: string): GitExtension.API { diff --git a/extensions/git/src/api/git.d.ts b/extensions/git/src/api/git.d.ts index 16d36bd7ada..f85b7efb2e4 100644 --- a/extensions/git/src/api/git.d.ts +++ b/extensions/git/src/api/git.d.ts @@ -3,15 +3,16 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -import { Uri, SourceControlInputBox } from 'vscode'; +import { Uri, SourceControlInputBox, Event } from 'vscode'; declare module GitExtension { export interface API { readonly gitPath: string; + readonly onDidOpenRepository: Event<Repository>; + readonly onDidCloseRepository: Event<Repository>; } - //#region Deprecated API export interface InputBox { value: string; } @@ -20,7 +21,6 @@ declare module GitExtension { readonly rootUri: Uri; readonly inputBox: InputBox; } - //#endregion } export interface GitExtension { From 3eaa5052c21711414c60c6e631603f28db630919 Mon Sep 17 00:00:00 2001 From: Matt Bierner <matb@microsoft.com> Date: Tue, 21 Aug 2018 17:04:50 +0200 Subject: [PATCH 1050/1276] Serialize webview id Fixes #56601 --- .../webview/electron-browser/webviewEditorInput.ts | 13 ++++++++++--- .../electron-browser/webviewEditorInputFactory.ts | 4 +++- .../electron-browser/webviewEditorService.ts | 6 ++++-- 3 files changed, 17 insertions(+), 6 deletions(-) diff --git a/src/vs/workbench/parts/webview/electron-browser/webviewEditorInput.ts b/src/vs/workbench/parts/webview/electron-browser/webviewEditorInput.ts index 912f937e607..df6c6b6774f 100644 --- a/src/vs/workbench/parts/webview/electron-browser/webviewEditorInput.ts +++ b/src/vs/workbench/parts/webview/electron-browser/webviewEditorInput.ts @@ -18,7 +18,6 @@ import { WebviewElement } from './webviewElement'; export class WebviewEditorInput extends EditorInput { private static handlePool = 0; - private static _styleElement?: HTMLStyleElement; private static _icons = new Map<number, { light: URI, dark: URI }>(); @@ -75,6 +74,7 @@ export class WebviewEditorInput extends EditorInput { constructor( public readonly viewType: string, + id: number | undefined, name: string, options: WebviewInputOptions, state: any, @@ -84,7 +84,14 @@ export class WebviewEditorInput extends EditorInput { @IPartService private readonly _partService: IPartService, ) { super(); - this._id = WebviewEditorInput.handlePool++; + + if (typeof id === 'number') { + this._id = id; + WebviewEditorInput.handlePool = Math.max(id, WebviewEditorInput.handlePool) + 1; + } else { + this._id = WebviewEditorInput.handlePool++; + } + this._name = name; this._options = options; this._events = events; @@ -154,7 +161,7 @@ export class WebviewEditorInput extends EditorInput { } public matches(other: IEditorInput): boolean { - return other && other === this; + return other === this || (other instanceof WebviewEditorInput && other._id === this._id); } public get group(): GroupIdentifier | undefined { diff --git a/src/vs/workbench/parts/webview/electron-browser/webviewEditorInputFactory.ts b/src/vs/workbench/parts/webview/electron-browser/webviewEditorInputFactory.ts index fc973d68479..860efe5d38c 100644 --- a/src/vs/workbench/parts/webview/electron-browser/webviewEditorInputFactory.ts +++ b/src/vs/workbench/parts/webview/electron-browser/webviewEditorInputFactory.ts @@ -11,6 +11,7 @@ import URI from 'vs/base/common/uri'; interface SerializedWebview { readonly viewType: string; + readonly id: number; readonly title: string; readonly options: WebviewInputOptions; readonly extensionLocation: string; @@ -41,6 +42,7 @@ export class WebviewEditorInputFactory implements IEditorInputFactory { const data: SerializedWebview = { viewType: input.viewType, + id: input.getId(), title: input.getName(), options: input.options, extensionLocation: input.extensionLocation.toString(), @@ -57,6 +59,6 @@ export class WebviewEditorInputFactory implements IEditorInputFactory { const data: SerializedWebview = JSON.parse(serializedEditorInput); const extensionLocation = URI.parse(data.extensionLocation); const iconPath = data.iconPath ? { light: URI.parse(data.iconPath.light), dark: URI.parse(data.iconPath.dark) } : undefined; - return this._webviewService.reviveWebview(data.viewType, data.title, iconPath, data.state, data.options, extensionLocation); + return this._webviewService.reviveWebview(data.viewType, data.id, data.title, iconPath, data.state, data.options, extensionLocation); } } diff --git a/src/vs/workbench/parts/webview/electron-browser/webviewEditorService.ts b/src/vs/workbench/parts/webview/electron-browser/webviewEditorService.ts index 99695243653..5c5b051b766 100644 --- a/src/vs/workbench/parts/webview/electron-browser/webviewEditorService.ts +++ b/src/vs/workbench/parts/webview/electron-browser/webviewEditorService.ts @@ -35,6 +35,7 @@ export interface IWebviewEditorService { reviveWebview( viewType: string, + id: number, title: string, iconPath: { light: URI, dark: URI } | undefined, state: any, @@ -107,7 +108,7 @@ export class WebviewEditorService implements IWebviewEditorService { extensionLocation: URI, events: WebviewEvents ): WebviewEditorInput { - const webviewInput = this._instantiationService.createInstance(WebviewEditorInput, viewType, title, options, {}, events, extensionLocation, undefined); + const webviewInput = this._instantiationService.createInstance(WebviewEditorInput, viewType, undefined, title, options, {}, events, extensionLocation, undefined); this._editorService.openEditor(webviewInput, { pinned: true, preserveFocus: showOptions.preserveFocus }, showOptions.group); return webviewInput; } @@ -126,13 +127,14 @@ export class WebviewEditorService implements IWebviewEditorService { reviveWebview( viewType: string, + id: number, title: string, iconPath: { light: URI, dark: URI } | undefined, state: any, options: WebviewInputOptions, extensionLocation: URI ): WebviewEditorInput { - const webviewInput = this._instantiationService.createInstance(WebviewEditorInput, viewType, title, options, state, {}, extensionLocation, { + const webviewInput = this._instantiationService.createInstance(WebviewEditorInput, viewType, id, title, options, state, {}, extensionLocation, { canRevive: (_webview) => { return true; }, From ad68ff316c472aea4acfa31b3a5bab3b101d968b Mon Sep 17 00:00:00 2001 From: Matt Bierner <matb@microsoft.com> Date: Tue, 21 Aug 2018 16:27:41 +0200 Subject: [PATCH 1051/1276] Remove std-fork --- .../src/typescriptServiceClient.ts | 127 +++++------ .../src/utils/electron.ts | 102 +-------- .../src/utils/electronForkStart.ts | 198 ------------------ 3 files changed, 73 insertions(+), 354 deletions(-) delete mode 100644 extensions/typescript-language-features/src/utils/electronForkStart.ts diff --git a/extensions/typescript-language-features/src/typescriptServiceClient.ts b/extensions/typescript-language-features/src/typescriptServiceClient.ts index 016f533b6e2..7d177d982a8 100644 --- a/extensions/typescript-language-features/src/typescriptServiceClient.ts +++ b/extensions/typescript-language-features/src/typescriptServiceClient.ts @@ -355,6 +355,7 @@ export default class TypeScriptServiceClient extends Disposable implements IType } } + private token: number = 0; private startService(resendModels: boolean = false): Promise<ForkedTsServerProcess> { let currentVersion = this.versionPicker.currentVersion; @@ -372,6 +373,7 @@ export default class TypeScriptServiceClient extends Disposable implements IType this.requestQueue = new RequestQueue(); this.callbacks = new CallbackMap(); this.lastError = null; + let mytoken = ++this.token; return this.servicePromise = new Promise<ForkedTsServerProcess>(async (resolve, reject) => { try { @@ -380,76 +382,83 @@ export default class TypeScriptServiceClient extends Disposable implements IType const tsServerForkOptions: electron.IForkOptions = { execArgv: debugPort ? [`--inspect=${debugPort}`] : [] // [`--debug-brk=5859`] }; - electron.fork(currentVersion.tsServerPath, tsServerForkArgs, tsServerForkOptions, this.logger, (err: any, childProcess: cp.ChildProcess | null) => { - if (err || !childProcess) { - this.lastError = err; - this.error('Starting TSServer failed with error.', err); - vscode.window.showErrorMessage(localize('serverCouldNotBeStarted', 'TypeScript language server couldn\'t be started. Error message is: {0}', err.message || err)); - /* __GDPR__ - "error" : { - "${include}": [ - "${TypeScriptCommonProperties}" - ] - } - */ - this.logTelemetry('error'); - this.resetClientVersion(); + const childProcess = electron.fork(currentVersion.tsServerPath, tsServerForkArgs, tsServerForkOptions, this.logger); + childProcess.once('error', (err: Error) => { + this.lastError = err; + this.error('Starting TSServer failed with error.', err); + vscode.window.showErrorMessage(localize('serverCouldNotBeStarted', 'TypeScript language server couldn\'t be started. Error message is: {0}', err.message || err)); + /* __GDPR__ + "error" : { + "${include}": [ + "${TypeScriptCommonProperties}" + ] + } + */ + this.logTelemetry('error'); + this.resetClientVersion(); + return; + }); + + this.info('Started TSServer'); + const handle = new ForkedTsServerProcess(childProcess); + this.lastStart = Date.now(); + + handle.onError((err: Error) => { + if (this.token !== mytoken) { + // this is coming from an old process return; } - - this.info('Started TSServer'); - const handle = new ForkedTsServerProcess(childProcess); - this.lastStart = Date.now(); - - handle.onError((err: Error) => { - this.lastError = err; - this.error('TSServer errored with error.', err); - if (this.tsServerLogFile) { - this.error(`TSServer log file: ${this.tsServerLogFile}`); + this.lastError = err; + this.error('TSServer errored with error.', err); + if (this.tsServerLogFile) { + this.error(`TSServer log file: ${this.tsServerLogFile}`); + } + /* __GDPR__ + "tsserver.error" : { + "${include}": [ + "${TypeScriptCommonProperties}" + ] } + */ + this.logTelemetry('tsserver.error'); + this.serviceExited(false); + }); + handle.onExit((code: any) => { + if (this.token !== mytoken) { + // this is coming from an old process + return; + } + if (code === null || typeof code === 'undefined') { + this.info('TSServer exited'); + } else { + this.error(`TSServer exited with code: ${code}`); /* __GDPR__ - "tsserver.error" : { + "tsserver.exitWithCode" : { + "code" : { "classification": "CallstackOrException", "purpose": "PerformanceAndHealth" }, "${include}": [ "${TypeScriptCommonProperties}" ] } */ - this.logTelemetry('tsserver.error'); - this.serviceExited(false); - }); - handle.onExit((code: any) => { - if (code === null || typeof code === 'undefined') { - this.info('TSServer exited'); - } else { - this.error(`TSServer exited with code: ${code}`); - /* __GDPR__ - "tsserver.exitWithCode" : { - "code" : { "classification": "CallstackOrException", "purpose": "PerformanceAndHealth" }, - "${include}": [ - "${TypeScriptCommonProperties}" - ] - } - */ - this.logTelemetry('tsserver.exitWithCode', { code: code }); - } + this.logTelemetry('tsserver.exitWithCode', { code: code }); + } - if (this.tsServerLogFile) { - this.info(`TSServer log file: ${this.tsServerLogFile}`); - } - this.serviceExited(!this.isRestarting); - this.isRestarting = false; - }); - - handle.createReader( - msg => { this.dispatchMessage(msg); }, - error => { this.error('ReaderError', error); }); - - this._onReady!.resolve(); - resolve(handle); - this._onTsServerStarted.fire(currentVersion.version); - - this.serviceStarted(resendModels); + if (this.tsServerLogFile) { + this.info(`TSServer log file: ${this.tsServerLogFile}`); + } + this.serviceExited(!this.isRestarting); + this.isRestarting = false; }); + + handle.createReader( + msg => { this.dispatchMessage(msg); }, + error => { this.error('ReaderError', error); }); + + this._onReady!.resolve(); + resolve(handle); + this._onTsServerStarted.fire(currentVersion.version); + + this.serviceStarted(resendModels); } catch (error) { reject(error); } diff --git a/extensions/typescript-language-features/src/utils/electron.ts b/extensions/typescript-language-features/src/utils/electron.ts index 46129f60f0e..b6ed76ceea0 100644 --- a/extensions/typescript-language-features/src/utils/electron.ts +++ b/extensions/typescript-language-features/src/utils/electron.ts @@ -7,7 +7,6 @@ import Logger from './logger'; import * as temp from './temp'; import path = require('path'); import fs = require('fs'); -import net = require('net'); import cp = require('child_process'); export interface IForkOptions { @@ -32,32 +31,10 @@ export function getTempFile(prefix: string): string { return path.join(getRootTempDir(), `${prefix}-${temp.makeRandomHexString(20)}.tmp`); } -function generatePipeName(): string { - return getPipeName(temp.makeRandomHexString(40)); -} - -function getPipeName(name: string): string { - const fullName = 'vscode-' + name; - if (process.platform === 'win32') { - return '\\\\.\\pipe\\' + fullName + '-sock'; - } - - // Mac/Unix: use socket file - return path.join(getRootTempDir(), fullName + '.sock'); -} - -function generatePatchedEnv( - env: any, - stdInPipeName: string, - stdOutPipeName: string, - stdErrPipeName: string -): any { +function generatePatchedEnv(env: any): any { const newEnv = Object.assign({}, env); // Set the two unique pipe names and the electron flag as process env - newEnv['STDIN_PIPE_NAME'] = stdInPipeName; - newEnv['STDOUT_PIPE_NAME'] = stdOutPipeName; - newEnv['STDERR_PIPE_NAME'] = stdErrPipeName; newEnv['ELECTRON_RUN_AS_NODE'] = '1'; // Ensure we always have a PATH set @@ -69,87 +46,18 @@ export function fork( modulePath: string, args: string[], options: IForkOptions, - logger: Logger, - callback: (error: any, cp: cp.ChildProcess | null) => void, -): void { - - let callbackCalled = false; - const resolve = (result: cp.ChildProcess) => { - if (callbackCalled) { - return; - } - callbackCalled = true; - callback(null, result); - }; - const reject = (err: any) => { - if (callbackCalled) { - return; - } - callbackCalled = true; - callback(err, null); - }; - - // Generate three unique pipe names - const stdInPipeName = generatePipeName(); - const stdOutPipeName = generatePipeName(); - const stdErrPipeName = generatePipeName(); - - - const newEnv = generatePatchedEnv(process.env, stdInPipeName, stdOutPipeName, stdErrPipeName); + logger: Logger +): cp.ChildProcess { + const newEnv = generatePatchedEnv(process.env); newEnv['NODE_PATH'] = path.join(modulePath, '..', '..', '..'); - let childProcess: cp.ChildProcess; - - // Begin listening to stderr pipe - let stdErrServer = net.createServer((stdErrStream) => { - // From now on the childProcess.stderr is available for reading - childProcess.stderr = stdErrStream; - }); - stdErrServer.listen(stdErrPipeName); - - // Begin listening to stdout pipe - let stdOutServer = net.createServer((stdOutStream) => { - // The child process will write exactly one chunk with content `ready` when it has installed a listener to the stdin pipe - - stdOutStream.once('data', (_chunk: Buffer) => { - // The child process is sending me the `ready` chunk, time to connect to the stdin pipe - childProcess.stdin = <any>net.connect(stdInPipeName); - - // From now on the childProcess.stdout is available for reading - childProcess.stdout = stdOutStream; - - resolve(childProcess); - }); - }); - stdOutServer.listen(stdOutPipeName); - - let serverClosed = false; - const closeServer = () => { - if (serverClosed) { - return; - } - serverClosed = true; - stdOutServer.close(); - stdErrServer.close(); - }; // Create the process logger.info('Forking TSServer', `PATH: ${newEnv['PATH']} `); - const bootstrapperPath = require.resolve('./electronForkStart'); - childProcess = cp.fork(bootstrapperPath, [modulePath].concat(args), { + return cp.fork(modulePath, args, { silent: true, cwd: options.cwd, env: newEnv, execArgv: options.execArgv }); - - childProcess.once('error', (err: Error) => { - closeServer(); - reject(err); - }); - - childProcess.once('exit', (err: Error) => { - closeServer(); - reject(err); - }); } diff --git a/extensions/typescript-language-features/src/utils/electronForkStart.ts b/extensions/typescript-language-features/src/utils/electronForkStart.ts deleted file mode 100644 index a29d9bca680..00000000000 --- a/extensions/typescript-language-features/src/utils/electronForkStart.ts +++ /dev/null @@ -1,198 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the MIT License. See License.txt in the project root for license information. - *--------------------------------------------------------------------------------------------*/ - -var net = require('net'), - fs = require('fs'); - -var ENABLE_LOGGING = false; - -var log = (function () { - if (!ENABLE_LOGGING) { - return function () { }; - } - var isFirst = true; - var LOG_LOCATION = 'C:\\stdFork.log'; - return function log(str: any) { - if (isFirst) { - isFirst = false; - fs.writeFileSync(LOG_LOCATION, str + '\n'); - return; - } - fs.appendFileSync(LOG_LOCATION, str + '\n'); - }; -})(); - -var stdInPipeName = process.env['STDIN_PIPE_NAME']; -var stdOutPipeName = process.env['STDOUT_PIPE_NAME']; -var stdErrPipeName = process.env['STDERR_PIPE_NAME']; - -log('STDIN_PIPE_NAME: ' + stdInPipeName); -log('STDOUT_PIPE_NAME: ' + stdOutPipeName); -log('STDERR_PIPE_NAME: ' + stdErrPipeName); -log('ELECTRON_RUN_AS_NODE: ' + process.env['ELECTRON_RUN_AS_NODE']); - -// stdout redirection to named pipe -(function () { - log('Beginning stdout redirection...'); - - // Create a writing stream to the stdout pipe - var stdOutStream = net.connect(stdOutPipeName); - - // unref stdOutStream to behave like a normal standard out - stdOutStream.unref(); - - // handle process.stdout - (<any>process).__defineGetter__('stdout', function () { return stdOutStream; }); - - // Create a writing stream to the stderr pipe - var stdErrStream = net.connect(stdErrPipeName); - - // unref stdErrStream to behave like a normal standard out - stdErrStream.unref(); - - // handle process.stderr - (<any>process).__defineGetter__('stderr', function () { return stdErrStream; }); - - var fsWriteSyncString = function (fd: number, str: string, _position: number, encoding?: string) { - // fs.writeSync(fd, string[, position[, encoding]]); - var buf = Buffer.from(str, encoding || 'utf8'); - return fsWriteSyncBuffer(fd, buf, 0, buf.length); - }; - - var fsWriteSyncBuffer = function (fd: number, buffer: Buffer, off: number, len: number) { - off = Math.abs(off | 0); - len = Math.abs(len | 0); - - // fs.writeSync(fd, buffer, offset, length[, position]); - var buffer_length = buffer.length; - - if (off > buffer_length) { - throw new Error('offset out of bounds'); - } - if (len > buffer_length) { - throw new Error('length out of bounds'); - } - if (((off + len) | 0) < off) { - throw new Error('off + len overflow'); - } - if (buffer_length - off < len) { - // Asking for more than is left over in the buffer - throw new Error('off + len > buffer.length'); - } - - var slicedBuffer = buffer; - if (off !== 0 || len !== buffer_length) { - slicedBuffer = buffer.slice(off, off + len); - } - - if (fd === 1) { - stdOutStream.write(slicedBuffer); - } else { - stdErrStream.write(slicedBuffer); - } - return slicedBuffer.length; - }; - - // handle fs.writeSync(1, ...) - var originalWriteSync = fs.writeSync; - fs.writeSync = function (fd: number, data: any, _position: number, _encoding?: string) { - if (fd !== 1 && fd !== 2) { - return originalWriteSync.apply(fs, arguments); - } - // usage: - // fs.writeSync(fd, buffer, offset, length[, position]); - // OR - // fs.writeSync(fd, string[, position[, encoding]]); - - if (data instanceof Buffer) { - return fsWriteSyncBuffer.apply(null, arguments); - } - - // For compatibility reasons with fs.writeSync, writing null will write "null", etc - if (typeof data !== 'string') { - data += ''; - } - - return fsWriteSyncString.apply(null, arguments); - }; - - log('Finished defining process.stdout, process.stderr and fs.writeSync'); -})(); - -// stdin redirection to named pipe -(function () { - - // Begin listening to stdin pipe - var server = net.createServer(function (stream: any) { - // Stop accepting new connections, keep the existing one alive - server.close(); - - log('Parent process has connected to my stdin. All should be good now.'); - - // handle process.stdin - (<any>process).__defineGetter__('stdin', function () { - return stream; - }); - - // Remove myself from process.argv - process.argv.splice(1, 1); - - // Load the actual program - var program = process.argv[1]; - log('Loading program: ' + program); - - // Unset the custom environmental variables that should not get inherited - delete process.env['STDIN_PIPE_NAME']; - delete process.env['STDOUT_PIPE_NAME']; - delete process.env['STDERR_PIPE_NAME']; - delete process.env['ELECTRON_RUN_AS_NODE']; - - require(program); - - log('Finished loading program.'); - - var stdinIsReferenced = true; - var timer = setInterval(function () { - var listenerCount = ( - stream.listeners('data').length + - stream.listeners('end').length + - stream.listeners('close').length + - stream.listeners('error').length - ); - // log('listenerCount: ' + listenerCount); - if (listenerCount <= 1) { - // No more "actual" listeners, only internal node - if (stdinIsReferenced) { - stdinIsReferenced = false; - // log('unreferencing stream!!!'); - stream.unref(); - } - } else { - // There are "actual" listeners - if (!stdinIsReferenced) { - stdinIsReferenced = true; - stream.ref(); - } - } - // log( - // '' + stream.listeners('data').length + - // ' ' + stream.listeners('end').length + - // ' ' + stream.listeners('close').length + - // ' ' + stream.listeners('error').length - // ); - }, 1000); - - if ((<any>timer).unref) { - (<any>timer).unref(); - } - }); - - - server.listen(stdInPipeName, function () { - // signal via stdout that the parent process can now begin writing to stdin pipe - process.stdout.write('ready'); - }); - -})(); \ No newline at end of file From 19a9d83d271fa7b100bc98a6ab7300fedd83a834 Mon Sep 17 00:00:00 2001 From: isidor <inikolic@microsoft.com> Date: Tue, 21 Aug 2018 17:14:55 +0200 Subject: [PATCH 1052/1276] explorerModel: do not use isEqualOrParent in find --- src/vs/workbench/parts/files/common/explorerModel.ts | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/vs/workbench/parts/files/common/explorerModel.ts b/src/vs/workbench/parts/files/common/explorerModel.ts index 2b2127af5fc..b299ed27968 100644 --- a/src/vs/workbench/parts/files/common/explorerModel.ts +++ b/src/vs/workbench/parts/files/common/explorerModel.ts @@ -15,7 +15,7 @@ import { IWorkspaceContextService } from 'vs/platform/workspace/common/workspace import { toResource, IEditorIdentifier, IEditorInput } from 'vs/workbench/common/editor'; import { IDisposable, dispose } from 'vs/base/common/lifecycle'; import { Schemas } from 'vs/base/common/network'; -import { rtrim } from 'vs/base/common/strings'; +import { rtrim, startsWithIgnoreCase, startsWith } from 'vs/base/common/strings'; import { IEditorGroup } from 'vs/workbench/services/group/common/editorGroupsService'; export class Model { @@ -342,7 +342,9 @@ export class ExplorerItem { */ public find(resource: URI): ExplorerItem { // Return if path found - if (resource && resources.isEqualOrParent(resource, this.resource)) { + // For performance reasons try to do the comparison as fast as possible + if (resource && this.resource.scheme === resource.scheme && this.resource.authority === resource.authority && + (resources.hasToIgnoreCase(resource) ? startsWithIgnoreCase(resource.path, this.resource.path) : startsWith(resource.path, this.resource.path))) { return this.findByPath(rtrim(resource.path, paths.sep), this.resource.path.length); } From e1a1e6d6d4e1e64fba2cad3aafbfe5bbc5571824 Mon Sep 17 00:00:00 2001 From: Johannes Rieken <johannes.rieken@gmail.com> Date: Tue, 21 Aug 2018 17:00:37 +0200 Subject: [PATCH 1053/1276] fix #56158 --- src/vs/workbench/browser/parts/editor/breadcrumbsModel.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vs/workbench/browser/parts/editor/breadcrumbsModel.ts b/src/vs/workbench/browser/parts/editor/breadcrumbsModel.ts index 0413ced3d63..07fd156d36c 100644 --- a/src/vs/workbench/browser/parts/editor/breadcrumbsModel.ts +++ b/src/vs/workbench/browser/parts/editor/breadcrumbsModel.ts @@ -176,7 +176,7 @@ export class EditorBreadcrumbsModel { this._updateOutlineElements(this._getOutlineElements(model, this._editor.getPosition())); this._outlineDisposables.push(this._editor.onDidChangeCursorPosition(_ => { timeout.cancelAndSet(() => { - if (!buffer.isDisposed() && versionIdThen === buffer.getVersionId()) { + if (!buffer.isDisposed() && versionIdThen === buffer.getVersionId() && this._editor.getModel()) { this._updateOutlineElements(this._getOutlineElements(model, this._editor.getPosition())); } }, 150); From 47d5f58297851dc337085698cb508ed6f21efc50 Mon Sep 17 00:00:00 2001 From: isidor <inikolic@microsoft.com> Date: Tue, 21 Aug 2018 17:45:57 +0200 Subject: [PATCH 1054/1276] debug remove stdFork usage fixes #41190 --- src/vs/workbench/parts/debug/node/debugAdapter.ts | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/vs/workbench/parts/debug/node/debugAdapter.ts b/src/vs/workbench/parts/debug/node/debugAdapter.ts index a322f0d8779..5168ed1a4c1 100644 --- a/src/vs/workbench/parts/debug/node/debugAdapter.ts +++ b/src/vs/workbench/parts/debug/node/debugAdapter.ts @@ -12,7 +12,6 @@ import * as paths from 'vs/base/common/paths'; import * as strings from 'vs/base/common/strings'; import * as objects from 'vs/base/common/objects'; import * as platform from 'vs/base/common/platform'; -import * as stdfork from 'vs/base/node/stdFork'; import { Emitter, Event } from 'vs/base/common/event'; import { TPromise } from 'vs/base/common/winjs.base'; import { ExtensionsChannelId } from 'vs/platform/extensionManagement/common/extensionManagement'; @@ -285,13 +284,14 @@ export class DebugAdapter extends StreamDebugAdapter { if (this.adapterExecutable.command === 'node' && this.outputService) { if (Array.isArray(this.adapterExecutable.args) && this.adapterExecutable.args.length > 0) { - stdfork.fork(this.adapterExecutable.args[0], this.adapterExecutable.args.slice(1), {}, (err, child) => { - if (err) { - e(new Error(nls.localize('unableToLaunchDebugAdapter', "Unable to launch debug adapter from '{0}'.", this.adapterExecutable.args[0]))); - } - this.serverProcess = child; - c(null); + const child = cp.fork(this.adapterExecutable.args[0], this.adapterExecutable.args.slice(1), { + stdio: ['pipe', 'pipe', 'pipe', 'ipc'] }); + if (!child.pid) { + e(new Error(nls.localize('unableToLaunchDebugAdapter', "Unable to launch debug adapter from '{0}'.", this.adapterExecutable.args[0]))); + } + this.serverProcess = child; + c(null); } else { e(new Error(nls.localize('unableToLaunchDebugAdapterNoArgs', "Unable to launch debug adapter."))); } From 51c2d9f86d3562985cc0e008665a7a9cf9c257ca Mon Sep 17 00:00:00 2001 From: isidor <inikolic@microsoft.com> Date: Tue, 21 Aug 2018 17:51:18 +0200 Subject: [PATCH 1055/1276] debug fix tests --- .../parts/debug/test/electron-browser/debugModel.test.ts | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/vs/workbench/parts/debug/test/electron-browser/debugModel.test.ts b/src/vs/workbench/parts/debug/test/electron-browser/debugModel.test.ts index 5aa97ff564d..bfde392d588 100644 --- a/src/vs/workbench/parts/debug/test/electron-browser/debugModel.test.ts +++ b/src/vs/workbench/parts/debug/test/electron-browser/debugModel.test.ts @@ -110,6 +110,7 @@ suite('Debug - Model', () => { const threadId = 1; const threadName = 'firstThread'; const session = new Session('mock', { resolved: { name: 'mockSession', type: 'node', request: 'launch' }, unresolved: undefined }, undefined, model, undefined, undefined, undefined, undefined); + model.addSession(session); assert.equal(model.getSessions().length, 1); model.rawUpdate({ @@ -141,6 +142,8 @@ suite('Debug - Model', () => { // Add the threads const session = new Session('mock', { resolved: { name: 'mockSession', type: 'node', request: 'launch' }, unresolved: undefined }, undefined, model, undefined, undefined, undefined, undefined); + model.addSession(session); + session['_raw'] = <any>rawSession; model.rawUpdate({ @@ -232,6 +235,8 @@ suite('Debug - Model', () => { const runningThreadName = 'runningThread'; const stoppedReason = 'breakpoint'; const session = new Session('mock', { resolved: { name: 'mockSession', type: 'node', request: 'launch' }, unresolved: undefined }, undefined, model, undefined, undefined, undefined, undefined); + model.addSession(session); + session['_raw'] = <any>rawSession; // Add the threads @@ -344,6 +349,8 @@ suite('Debug - Model', () => { test('repl expressions', () => { assert.equal(model.getReplElements().length, 0); const session = new Session('mock', { resolved: { name: 'mockSession', type: 'node', request: 'launch' }, unresolved: undefined }, undefined, model, undefined, undefined, undefined, undefined); + model.addSession(session); + session['_raw'] = <any>rawSession; const thread = new Thread(session, 'mockthread', 1); const stackFrame = new StackFrame(thread, 1, null, 'app.js', 'normal', { startLineNumber: 1, startColumn: 1, endLineNumber: 1, endColumn: 10 }, 1); @@ -364,6 +371,8 @@ suite('Debug - Model', () => { test('stack frame get specific source name', () => { const session = new Session('mock', { resolved: { name: 'mockSession', type: 'node', request: 'launch' }, unresolved: undefined }, undefined, model, undefined, undefined, undefined, undefined); + model.addSession(session); + let firstStackFrame: StackFrame; let secondStackFrame: StackFrame; const thread = new class extends Thread { From 890689e8e5f60657c8946a68d6d64e8b5c5f7b63 Mon Sep 17 00:00:00 2001 From: Sandeep Somavarapu <sasomava@microsoft.com> Date: Tue, 21 Aug 2018 16:40:03 +0200 Subject: [PATCH 1056/1276] Do not consider system extensions while syncing --- .../extensionManagement/common/multiExtensionManagement.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/vs/platform/extensionManagement/common/multiExtensionManagement.ts b/src/vs/platform/extensionManagement/common/multiExtensionManagement.ts index 1120f19f351..3eb32417e69 100644 --- a/src/vs/platform/extensionManagement/common/multiExtensionManagement.ts +++ b/src/vs/platform/extensionManagement/common/multiExtensionManagement.ts @@ -107,7 +107,7 @@ export class MulitExtensionManagementService implements IExtensionManagementServ } private async syncExtensions(): Promise<void> { - this.localServer.extensionManagementService.getInstalled() + this.localServer.extensionManagementService.getInstalled(LocalExtensionType.User) .then(async localExtensions => { const workspaceExtensions = localExtensions.filter(e => isWorkspaceExtension(e.manifest)); const extensionsToSync: Map<IExtensionManagementServer, ILocalExtension[]> = await this.getExtensionsToSync(workspaceExtensions); @@ -133,7 +133,7 @@ export class MulitExtensionManagementService implements IExtensionManagementServ private async getExtensionsToSync(workspaceExtensions: ILocalExtension[]): Promise<Map<IExtensionManagementServer, ILocalExtension[]>> { const extensionsToSync: Map<IExtensionManagementServer, ILocalExtension[]> = new Map<IExtensionManagementServer, ILocalExtension[]>(); for (const server of this.otherServers) { - const extensions = await server.extensionManagementService.getInstalled(); + const extensions = await server.extensionManagementService.getInstalled(LocalExtensionType.User); const groupedByVersionId: Map<string, ILocalExtension> = extensions.reduce((groupedById, extension) => groupedById.set(`${extension.galleryIdentifier.id}-${extension.manifest.version}`, extension), new Map<string, ILocalExtension>()); const toSync = workspaceExtensions.filter(e => !groupedByVersionId.has(`${e.galleryIdentifier.id}-${e.manifest.version}`)); if (toSync.length) { From f136003b5d810c2591bcb660284235c046948877 Mon Sep 17 00:00:00 2001 From: Sandeep Somavarapu <sasomava@microsoft.com> Date: Tue, 21 Aug 2018 17:59:04 +0200 Subject: [PATCH 1057/1276] Use gallery to synchronise extensions --- .../common/extensionManagement.ts | 4 +- .../common/extensionManagementUtil.ts | 4 +- .../common/multiExtensionManagement.ts | 22 +++-- .../node/extensionGalleryService.ts | 83 +++++++++++-------- .../node/extensionManagementService.ts | 79 ++++++++++-------- src/vs/workbench/electron-browser/shell.ts | 7 +- .../extensions.contribution.ts | 5 +- 7 files changed, 124 insertions(+), 80 deletions(-) diff --git a/src/vs/platform/extensionManagement/common/extensionManagement.ts b/src/vs/platform/extensionManagement/common/extensionManagement.ts index c2762381422..12243f5f237 100644 --- a/src/vs/platform/extensionManagement/common/extensionManagement.ts +++ b/src/vs/platform/extensionManagement/common/extensionManagement.ts @@ -255,7 +255,8 @@ export interface IReportedExtension { } export enum InstallOperation { - Install = 1, + None = 0, + Install, Update } @@ -276,6 +277,7 @@ export interface IExtensionGalleryService { loadCompatibleVersion(extension: IGalleryExtension): TPromise<IGalleryExtension>; loadAllDependencies(dependencies: IExtensionIdentifier[]): TPromise<IGalleryExtension[]>; getExtensionsReport(): TPromise<IReportedExtension[]>; + getExtension(id: IExtensionIdentifier, version?: string): TPromise<IGalleryExtension>; } export interface InstallExtensionEvent { diff --git a/src/vs/platform/extensionManagement/common/extensionManagementUtil.ts b/src/vs/platform/extensionManagement/common/extensionManagementUtil.ts index 111bd6319d2..208631c7b63 100644 --- a/src/vs/platform/extensionManagement/common/extensionManagementUtil.ts +++ b/src/vs/platform/extensionManagement/common/extensionManagementUtil.ts @@ -139,7 +139,9 @@ export function isWorkspaceExtension(manifest: IExtensionManifest): boolean { 'ms-vscode.node-debug', 'ms-vscode.node-debug2', 'ms-python.python', - 'eg2.tslint' + 'eg2.tslint', + 'dbaeumer.vscode-eslint', + 'eamodio.gitlens' ].indexOf(extensionId) !== -1; } return false; diff --git a/src/vs/platform/extensionManagement/common/multiExtensionManagement.ts b/src/vs/platform/extensionManagement/common/multiExtensionManagement.ts index 3eb32417e69..a542a04fd48 100644 --- a/src/vs/platform/extensionManagement/common/multiExtensionManagement.ts +++ b/src/vs/platform/extensionManagement/common/multiExtensionManagement.ts @@ -7,7 +7,7 @@ import { TPromise } from 'vs/base/common/winjs.base'; import { Event, EventMultiplexer } from 'vs/base/common/event'; import { IExtensionManagementService, ILocalExtension, IGalleryExtension, LocalExtensionType, InstallExtensionEvent, DidInstallExtensionEvent, IExtensionIdentifier, DidUninstallExtensionEvent, IReportedExtension, IGalleryMetadata, - IExtensionManagementServerService, IExtensionManagementServer + IExtensionManagementServerService, IExtensionManagementServer, IExtensionGalleryService, InstallOperation } from 'vs/platform/extensionManagement/common/extensionManagement'; import { flatten } from 'vs/base/common/arrays'; import { isWorkspaceExtension, areSameExtensions } from 'vs/platform/extensionManagement/common/extensionManagementUtil'; @@ -35,7 +35,8 @@ export class MulitExtensionManagementService implements IExtensionManagementServ @IExtensionManagementServerService private extensionManagementServerService: IExtensionManagementServerService, @INotificationService private notificationService: INotificationService, @IWindowService private windowService: IWindowService, - @ILogService private logService: ILogService + @ILogService private logService: ILogService, + @IExtensionGalleryService private extensionGalleryService: IExtensionGalleryService ) { this.servers = this.extensionManagementServerService.extensionManagementServers; this.localServer = this.extensionManagementServerService.getLocalExtensionManagementServer(); @@ -145,28 +146,37 @@ export class MulitExtensionManagementService implements IExtensionManagementServ private async doSyncExtensions(extensionsToSync: Map<IExtensionManagementServer, ILocalExtension[]>): Promise<void> { const ids: string[] = []; - const vsixResolvers: TPromise<URI>[] = []; + const zipLocationResolvers: TPromise<{ location: URI, vsix: boolean }>[] = []; extensionsToSync.forEach(extensions => { for (const extension of extensions) { if (ids.indexOf(extension.galleryIdentifier.id) === -1) { ids.push(extension.galleryIdentifier.id); - vsixResolvers.push(this.localServer.extensionManagementService.zip(extension)); + zipLocationResolvers.push(this.downloadFromGallery(extension).then(location => location ? { location, vsix: true } : this.localServer.extensionManagementService.zip(extension).then(location => ({ location, vsix: false })))); } } }); - const vsixs = await TPromise.join(vsixResolvers); + const zipLocations = await TPromise.join(zipLocationResolvers); const promises: Promise<any>[] = []; extensionsToSync.forEach((extensions, server) => { let promise: Promise<any> = Promise.resolve(); extensions.forEach(extension => { const index = ids.indexOf(extension.galleryIdentifier.id); - promise = promise.then(() => server.extensionManagementService.unzip(vsixs[index], extension.type)); + const { location, vsix } = zipLocations[index]; + promise = promise.then(() => vsix ? server.extensionManagementService.install(location) : server.extensionManagementService.unzip(location, extension.type)); }); promises.push(promise); }); await Promise.all(promises); } + + private downloadFromGallery(extension: ILocalExtension): TPromise<URI> { + if (this.extensionGalleryService.isEnabled()) { + return this.extensionGalleryService.getExtension(extension.galleryIdentifier, extension.manifest.version) + .then(galleryExtension => galleryExtension ? this.extensionGalleryService.download(galleryExtension, InstallOperation.None).then(location => URI.file(location)) : null); + } + return TPromise.as(null); + } } \ No newline at end of file diff --git a/src/vs/platform/extensionManagement/node/extensionGalleryService.ts b/src/vs/platform/extensionManagement/node/extensionGalleryService.ts index 18b43c9c0ef..4b9f49f66a5 100644 --- a/src/vs/platform/extensionManagement/node/extensionGalleryService.ts +++ b/src/vs/platform/extensionManagement/node/extensionGalleryService.ts @@ -3,7 +3,6 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -import { localize } from 'vs/nls'; import { tmpdir } from 'os'; import * as path from 'path'; import { TPromise } from 'vs/base/common/winjs.base'; @@ -280,8 +279,7 @@ function getIsPreview(flags: string): boolean { return flags.indexOf('preview') !== -1; } -function toExtension(galleryExtension: IRawGalleryExtension, extensionsGalleryUrl: string, index: number, query: Query, querySource?: string): IGalleryExtension { - const [version] = galleryExtension.versions; +function toExtension(galleryExtension: IRawGalleryExtension, version: IRawGalleryExtensionVersion, index: number, query: Query, querySource?: string): IGalleryExtension { const assets = { manifest: getVersionAsset(version, AssetType.Manifest), readme: getVersionAsset(version, AssetType.Details), @@ -364,6 +362,31 @@ export class ExtensionGalleryService implements IExtensionGalleryService { return !!this.extensionsGalleryUrl; } + getExtension({ id, uuid }: IExtensionIdentifier, version?: string): TPromise<IGalleryExtension> { + let query = new Query() + .withFlags(Flags.IncludeAssetUri, Flags.IncludeStatistics, Flags.IncludeFiles, Flags.IncludeVersionProperties) + .withPage(1, 1) + .withFilter(FilterType.Target, 'Microsoft.VisualStudio.Code') + .withFilter(FilterType.ExcludeWithFlags, flagsToString(Flags.Unpublished)); + + if (uuid) { + query = query.withFilter(FilterType.ExtensionId, uuid); + } else { + query = query.withFilter(FilterType.ExtensionName, id); + } + + return this.queryGallery(query).then(({ galleryExtensions }) => { + if (galleryExtensions.length) { + const galleryExtension = galleryExtensions[0]; + const versionAsset = version ? galleryExtension.versions.filter(v => v.version === version)[0] : galleryExtension.versions[0]; + if (versionAsset) { + return toExtension(galleryExtension, versionAsset, 0, query); + } + } + return null; + }); + } + query(options: IQueryOptions = {}): TPromise<IPager<IGalleryExtension>> { if (!this.isEnabled()) { return TPromise.wrapError<IPager<IGalleryExtension>>(new Error('No extension gallery service configured.')); @@ -425,7 +448,7 @@ export class ExtensionGalleryService implements IExtensionGalleryService { } return this.queryGallery(query).then(({ galleryExtensions, total }) => { - const extensions = galleryExtensions.map((e, index) => toExtension(e, this.extensionsGalleryUrl, index, query, options.source)); + const extensions = galleryExtensions.map((e, index) => toExtension(e, e.versions[0], index, query, options.source)); const pageSize = query.pageSize; const getPage = (pageIndex: number, ct: CancellationToken) => { if (ct.isCancellationRequested) { @@ -434,7 +457,7 @@ export class ExtensionGalleryService implements IExtensionGalleryService { const nextPageQuery = query.withPage(pageIndex + 1); const promise = this.queryGallery(nextPageQuery) - .then(({ galleryExtensions }) => galleryExtensions.map((e, index) => toExtension(e, this.extensionsGalleryUrl, index, nextPageQuery, options.source))); + .then(({ galleryExtensions }) => galleryExtensions.map((e, index) => toExtension(e, e.versions[0], index, nextPageQuery, options.source))); return wireCancellationToken(ct, promise); }; @@ -493,35 +516,29 @@ export class ExtensionGalleryService implements IExtensionGalleryService { } download(extension: IGalleryExtension, operation: InstallOperation): TPromise<string> { - return this.loadCompatibleVersion(extension) - .then(extension => { - if (!extension) { - return TPromise.wrapError(new Error(localize('notCompatibleDownload', "Unable to download because the extension compatible with current version '{0}' of VS Code is not found.", pkg.version))); - } - const zipPath = path.join(tmpdir(), generateUuid()); - const data = getGalleryExtensionTelemetryData(extension); - const startTime = new Date().getTime(); - /* __GDPR__ - "galleryService:downloadVSIX" : { - "duration": { "classification": "SystemMetaData", "purpose": "PerformanceAndHealth", "isMeasurement": true }, - "${include}": [ - "${GalleryExtensionTelemetryData}" - ] - } - */ - const log = (duration: number) => this.telemetryService.publicLog('galleryService:downloadVSIX', assign(data, { duration })); + const zipPath = path.join(tmpdir(), generateUuid()); + const data = getGalleryExtensionTelemetryData(extension); + const startTime = new Date().getTime(); + /* __GDPR__ + "galleryService:downloadVSIX" : { + "duration": { "classification": "SystemMetaData", "purpose": "PerformanceAndHealth", "isMeasurement": true }, + "${include}": [ + "${GalleryExtensionTelemetryData}" + ] + } + */ + const log = (duration: number) => this.telemetryService.publicLog('galleryService:downloadVSIX', assign(data, { duration })); - const operationParam = operation === InstallOperation.Install ? 'install' : operation === InstallOperation.Update ? 'update' : ''; - const downloadAsset = operationParam ? { - uri: `${extension.assets.download.uri}&${operationParam}=true`, - fallbackUri: `${extension.assets.download.fallbackUri}?${operationParam}=true` - } : extension.assets.download; + const operationParam = operation === InstallOperation.Install ? 'install' : operation === InstallOperation.Update ? 'update' : ''; + const downloadAsset = operationParam ? { + uri: `${extension.assets.download.uri}&${operationParam}=true`, + fallbackUri: `${extension.assets.download.fallbackUri}?${operationParam}=true` + } : extension.assets.download; - return this.getAsset(downloadAsset) - .then(context => download(zipPath, context)) - .then(() => log(new Date().getTime() - startTime)) - .then(() => zipPath); - }); + return this.getAsset(downloadAsset) + .then(context => download(zipPath, context)) + .then(() => log(new Date().getTime() - startTime)) + .then(() => zipPath); } getReadme(extension: IGalleryExtension): TPromise<string> { @@ -609,7 +626,7 @@ export class ExtensionGalleryService implements IExtensionGalleryService { for (let index = 0; index < result.galleryExtensions.length; index++) { const rawExtension = result.galleryExtensions[index]; if (ids.indexOf(rawExtension.extensionId) === -1) { - dependencies.push(toExtension(rawExtension, this.extensionsGalleryUrl, index, query, 'dependencies')); + dependencies.push(toExtension(rawExtension, rawExtension.versions[0], index, query, 'dependencies')); ids.push(rawExtension.extensionId); } } diff --git a/src/vs/platform/extensionManagement/node/extensionManagementService.ts b/src/vs/platform/extensionManagement/node/extensionManagementService.ts index a48cd5e5ed4..d235a328edb 100644 --- a/src/vs/platform/extensionManagement/node/extensionManagementService.ts +++ b/src/vs/platform/extensionManagement/node/extensionManagementService.ts @@ -44,6 +44,7 @@ import { tmpdir } from 'os'; import { generateUuid } from 'vs/base/common/uuid'; import { IDownloadService } from 'vs/platform/download/common/download'; import { optional } from 'vs/platform/instantiation/common/instantiation'; +import { Schemas } from 'vs/base/common/network'; const ERROR_SCANNING_SYS_EXTENSIONS = 'scanningSystem'; const ERROR_SCANNING_USER_EXTENSIONS = 'scanningUser'; @@ -165,11 +166,7 @@ export class ExtensionManagementService extends Disposable implements IExtension } unzip(zipLocation: URI, type: LocalExtensionType): TPromise<IExtensionIdentifier> { - if (!this.downloadService) { - throw new Error('Download service is not available'); - } - const downloadedLocation = path.join(tmpdir(), generateUuid()); - return this.downloadService.download(zipLocation, downloadedLocation).then(() => this.install(URI.file(downloadedLocation), type)); + return this.install(zipLocation, type); } private collectFiles(extension: ILocalExtension): Promise<IFile[]> { @@ -199,38 +196,52 @@ export class ExtensionManagementService extends Disposable implements IExtension } install(vsix: URI, type: LocalExtensionType = LocalExtensionType.User): TPromise<IExtensionIdentifier> { - const zipPath = path.resolve(vsix.fsPath); + return this.downloadVsix(vsix) + .then(downloadLocation => { + const zipPath = path.resolve(downloadLocation.fsPath); - return validateLocalExtension(zipPath) - .then(manifest => { - const identifier = { id: getLocalExtensionIdFromManifest(manifest) }; - if (manifest.engines && manifest.engines.vscode && !isEngineValid(manifest.engines.vscode)) { - return TPromise.wrapError<IExtensionIdentifier>(new Error(nls.localize('incompatible', "Unable to install Extension '{0}' as it is not compatible with Code '{1}'.", identifier.id, pkg.version))); - } - return this.removeIfExists(identifier.id) - .then( - () => this.checkOutdated(manifest) - .then(validated => { - if (validated) { - this.logService.info('Installing the extension:', identifier.id); - this._onInstallExtension.fire({ identifier, zipPath }); - return this.getMetadata(getGalleryExtensionId(manifest.publisher, manifest.name)) - .then( - metadata => this.installFromZipPath(identifier, zipPath, metadata, type), - error => this.installFromZipPath(identifier, zipPath, null, type)) - .then( - () => { this.logService.info('Successfully installed the extension:', identifier.id); return identifier; }, - e => { - this.logService.error('Failed to install the extension:', identifier.id, e.message); - return TPromise.wrapError(e); - }); - } - return null; - }), - e => TPromise.wrapError(new Error(nls.localize('restartCode', "Please restart Code before reinstalling {0}.", manifest.displayName || manifest.name)))); + return validateLocalExtension(zipPath) + .then(manifest => { + const identifier = { id: getLocalExtensionIdFromManifest(manifest) }; + if (manifest.engines && manifest.engines.vscode && !isEngineValid(manifest.engines.vscode)) { + return TPromise.wrapError<IExtensionIdentifier>(new Error(nls.localize('incompatible', "Unable to install Extension '{0}' as it is not compatible with Code '{1}'.", identifier.id, pkg.version))); + } + return this.removeIfExists(identifier.id) + .then( + () => this.checkOutdated(manifest) + .then(validated => { + if (validated) { + this.logService.info('Installing the extension:', identifier.id); + this._onInstallExtension.fire({ identifier, zipPath }); + return this.getMetadata(getGalleryExtensionId(manifest.publisher, manifest.name)) + .then( + metadata => this.installFromZipPath(identifier, zipPath, metadata, type), + error => this.installFromZipPath(identifier, zipPath, null, type)) + .then( + () => { this.logService.info('Successfully installed the extension:', identifier.id); return identifier; }, + e => { + this.logService.error('Failed to install the extension:', identifier.id, e.message); + return TPromise.wrapError(e); + }); + } + return null; + }), + e => TPromise.wrapError(new Error(nls.localize('restartCode', "Please restart Code before reinstalling {0}.", manifest.displayName || manifest.name)))); + }); }); } + private downloadVsix(vsix: URI): TPromise<URI> { + if (vsix.scheme === Schemas.file) { + return TPromise.as(vsix); + } + if (!this.downloadService) { + throw new Error('Download service is not available'); + } + const downloadedLocation = path.join(tmpdir(), generateUuid()); + return this.downloadService.download(vsix, downloadedLocation).then(() => URI.file(downloadedLocation)); + } + private removeIfExists(id: string): TPromise<void> { return this.getInstalled(LocalExtensionType.User) .then(installed => installed.filter(i => i.identifier.id === id)[0]) @@ -374,7 +385,7 @@ export class ExtensionManagementService extends Disposable implements IExtension compatible => { if (compatible) { this.logService.trace('Started downloading extension:', extension.name); - return this.galleryService.download(extension, operation) + return this.galleryService.download(compatible, operation) .then( zipPath => { this.logService.info('Downloaded extension:', extension.name, zipPath); diff --git a/src/vs/workbench/electron-browser/shell.ts b/src/vs/workbench/electron-browser/shell.ts index 326f3f38bd0..ae688e469bf 100644 --- a/src/vs/workbench/electron-browser/shell.ts +++ b/src/vs/workbench/electron-browser/shell.ts @@ -60,7 +60,7 @@ import { ICrashReporterService, NullCrashReporterService, CrashReporterService } import { getDelayedChannel, IPCClient } from 'vs/base/parts/ipc/node/ipc'; import { connect as connectNet } from 'vs/base/parts/ipc/node/ipc.net'; import { IExtensionManagementChannel, ExtensionManagementChannelClient } from 'vs/platform/extensionManagement/node/extensionManagementIpc'; -import { IExtensionManagementService, IExtensionEnablementService, IExtensionManagementServerService } from 'vs/platform/extensionManagement/common/extensionManagement'; +import { IExtensionManagementService, IExtensionEnablementService, IExtensionManagementServerService, IExtensionGalleryService } from 'vs/platform/extensionManagement/common/extensionManagement'; import { ExtensionEnablementService } from 'vs/platform/extensionManagement/common/extensionEnablementService'; import { BareFontInfo } from 'vs/editor/common/config/fontInfo'; import { restoreFontInfo, readFontInfo, saveFontInfo } from 'vs/editor/browser/config/configuration'; @@ -97,6 +97,7 @@ import { MulitExtensionManagementService } from 'vs/platform/extensionManagement import { ExtensionManagementServerService } from 'vs/workbench/services/extensions/node/extensionManagementServerService'; import { DownloadServiceChannel } from 'vs/platform/download/node/downloadIpc'; import { DefaultURITransformer } from 'vs/base/common/uriIpc'; +import { ExtensionGalleryService } from 'vs/platform/extensionManagement/node/extensionGalleryService'; /** * Services that we require for the Shell @@ -380,6 +381,9 @@ export class WorkbenchShell extends Disposable { serviceCollection.set(ILifecycleService, lifecycleService); this.lifecycleService = lifecycleService; + serviceCollection.set(IRequestService, new SyncDescriptor(RequestService)); + serviceCollection.set(IExtensionGalleryService, new SyncDescriptor(ExtensionGalleryService)); + const extensionManagementChannel = getDelayedChannel<IExtensionManagementChannel>(sharedProcess.then(c => c.getChannel('extensions'))); const extensionManagementChannelClient = new ExtensionManagementChannelClient(extensionManagementChannel, DefaultURITransformer); serviceCollection.set(IExtensionManagementServerService, new SyncDescriptor(ExtensionManagementServerService, extensionManagementChannelClient)); @@ -388,7 +392,6 @@ export class WorkbenchShell extends Disposable { const extensionEnablementService = this._register(instantiationService.createInstance(ExtensionEnablementService)); serviceCollection.set(IExtensionEnablementService, extensionEnablementService); - serviceCollection.set(IRequestService, new SyncDescriptor(RequestService)); this.extensionService = instantiationService.createInstance(ExtensionService); serviceCollection.set(IExtensionService, this.extensionService); diff --git a/src/vs/workbench/parts/extensions/electron-browser/extensions.contribution.ts b/src/vs/workbench/parts/extensions/electron-browser/extensions.contribution.ts index 5ce89339923..af62cf9de7b 100644 --- a/src/vs/workbench/parts/extensions/electron-browser/extensions.contribution.ts +++ b/src/vs/workbench/parts/extensions/electron-browser/extensions.contribution.ts @@ -10,8 +10,8 @@ import { KeyMod, KeyChord, KeyCode } from 'vs/base/common/keyCodes'; import { Registry } from 'vs/platform/registry/common/platform'; import { SyncActionDescriptor, MenuRegistry, MenuId } from 'vs/platform/actions/common/actions'; import { registerSingleton } from 'vs/platform/instantiation/common/extensions'; -import { IExtensionGalleryService, IExtensionTipsService, ExtensionsLabel, ExtensionsChannelId, PreferencesLabel } from 'vs/platform/extensionManagement/common/extensionManagement'; -import { ExtensionGalleryService } from 'vs/platform/extensionManagement/node/extensionGalleryService'; +import { IExtensionTipsService, ExtensionsLabel, ExtensionsChannelId, PreferencesLabel } from 'vs/platform/extensionManagement/common/extensionManagement'; + import { IWorkbenchActionRegistry, Extensions as WorkbenchActionExtensions } from 'vs/workbench/common/actions'; import { ExtensionTipsService } from 'vs/workbench/parts/extensions/electron-browser/extensionTipsService'; import { IWorkbenchContributionsRegistry, Extensions as WorkbenchExtensions } from 'vs/workbench/common/contributions'; @@ -44,7 +44,6 @@ import { EditorInput, IEditorInputFactory, IEditorInputFactoryRegistry, Extensio import { ExtensionHostProfileService } from 'vs/workbench/parts/extensions/electron-browser/extensionProfileService'; // Singletons -registerSingleton(IExtensionGalleryService, ExtensionGalleryService); registerSingleton(IExtensionsWorkbenchService, ExtensionsWorkbenchService); registerSingleton(IExtensionTipsService, ExtensionTipsService); registerSingleton(IExtensionHostProfileService, ExtensionHostProfileService); From 04e79adfcdf3b0474b89c0d3c38db069184a0c63 Mon Sep 17 00:00:00 2001 From: Matt Bierner <matb@microsoft.com> Date: Tue, 21 Aug 2018 18:13:57 +0200 Subject: [PATCH 1058/1276] Fix webview state not being restored in same session Fixes #56839 --- .../parts/webview/electron-browser/webviewEditor.ts | 2 +- .../parts/webview/electron-browser/webviewEditorInput.ts | 5 ++--- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/src/vs/workbench/parts/webview/electron-browser/webviewEditor.ts b/src/vs/workbench/parts/webview/electron-browser/webviewEditor.ts index 8eb67ef6b68..24e9760e39d 100644 --- a/src/vs/workbench/parts/webview/electron-browser/webviewEditor.ts +++ b/src/vs/workbench/parts/webview/electron-browser/webviewEditor.ts @@ -244,7 +244,7 @@ export class WebviewEditor extends BaseWebviewEditor { this._webview.initialScrollProgress = input.scrollYPercentage; } - this._webview.state = input.state.state; + this._webview.state = input.webviewState; this._content.setAttribute('aria-flowto', this._webviewContent.id); diff --git a/src/vs/workbench/parts/webview/electron-browser/webviewEditorInput.ts b/src/vs/workbench/parts/webview/electron-browser/webviewEditorInput.ts index df6c6b6774f..b49e917ed70 100644 --- a/src/vs/workbench/parts/webview/electron-browser/webviewEditorInput.ts +++ b/src/vs/workbench/parts/webview/electron-browser/webviewEditorInput.ts @@ -65,7 +65,6 @@ export class WebviewEditorInput extends EditorInput { private _group?: GroupIdentifier; private _scrollYPercentage: number = 0; private _state: any; - private _webviewState: string | undefined; private _revived: boolean = false; @@ -194,7 +193,7 @@ export class WebviewEditorInput extends EditorInput { } public get webviewState() { - return this._webviewState; + return this._state.state; } public get options(): WebviewInputOptions { @@ -266,7 +265,7 @@ export class WebviewEditorInput extends EditorInput { }, null, this._webviewDisposables); this._webview.onDidUpdateState(newState => { - this._webviewState = newState; + this._state.state = newState; }, null, this._webviewDisposables); } From 1708f4bc8e3533ede759443234c8ad96d77a08bc Mon Sep 17 00:00:00 2001 From: Matt Ferderer <matt@mattferderer.com> Date: Tue, 21 Aug 2018 11:14:54 -0500 Subject: [PATCH 1059/1276] Update Markdown link snippets to use https (#56851) As suggested in #56386 I switched the http to https for links and image links. --- extensions/markdown-basics/snippets/markdown.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/extensions/markdown-basics/snippets/markdown.json b/extensions/markdown-basics/snippets/markdown.json index 6bba2591d10..4a5152c18c8 100644 --- a/extensions/markdown-basics/snippets/markdown.json +++ b/extensions/markdown-basics/snippets/markdown.json @@ -60,12 +60,12 @@ }, "Insert link": { "prefix": "link", - "body": "[${1:text}](http://${2:link})$0", + "body": "[${1:text}](https://${2:link})$0", "description": "Insert link" }, "Insert image": { "prefix": "image", - "body": "![${1:alt}](http://${2:link})$0", + "body": "![${1:alt}](https://${2:link})$0", "description": "Insert image" } } From c93565448ab9988cbeb8a0eac4e3304dc97cc844 Mon Sep 17 00:00:00 2001 From: Jatin Sandilya <jats22@users.noreply.github.com> Date: Tue, 21 Aug 2018 22:25:32 +0530 Subject: [PATCH 1060/1276] Fix #55723 - Error on Await not bubbling up (#56767) --- .../parts/extensions/electron-browser/extensionsViews.ts | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/vs/workbench/parts/extensions/electron-browser/extensionsViews.ts b/src/vs/workbench/parts/extensions/electron-browser/extensionsViews.ts index 3bfb6cffba9..a01efaa710b 100644 --- a/src/vs/workbench/parts/extensions/electron-browser/extensionsViews.ts +++ b/src/vs/workbench/parts/extensions/electron-browser/extensionsViews.ts @@ -317,8 +317,7 @@ export class ExtensionsListView extends ViewletPanel { if (text !== query.value) { options = assign(options, { text: text.substr(0, 350), source: 'file-extension-tags' }); - const pager = await this.extensionsWorkbenchService.queryGallery(options); - return new PagedModel(pager); + return this.extensionsWorkbenchService.queryGallery(options).then(pager => new PagedModel(pager)); } } @@ -328,8 +327,7 @@ export class ExtensionsListView extends ViewletPanel { options.source = 'viewlet'; } - const pager = await this.extensionsWorkbenchService.queryGallery(options); - return new PagedModel(pager); + return this.extensionsWorkbenchService.queryGallery(options).then(pager => new PagedModel(pager)); } private sortExtensions(extensions: IExtension[], options: IQueryOptions): IExtension[] { From 9a6837f125cf332b881aba66bad24188973ef63f Mon Sep 17 00:00:00 2001 From: Rob Lourens <roblourens@gmail.com> Date: Tue, 21 Aug 2018 11:25:43 -0700 Subject: [PATCH 1061/1276] Fix unhandled cancel warnings from search process --- src/vs/base/common/arrays.ts | 7 ++++--- .../services/search/node/rawSearchService.ts | 13 ++++++++++--- 2 files changed, 14 insertions(+), 6 deletions(-) diff --git a/src/vs/base/common/arrays.ts b/src/vs/base/common/arrays.ts index 7ce398f38a8..5a05080631c 100644 --- a/src/vs/base/common/arrays.ts +++ b/src/vs/base/common/arrays.ts @@ -4,9 +4,10 @@ *--------------------------------------------------------------------------------------------*/ 'use strict'; -import { TPromise } from 'vs/base/common/winjs.base'; -import { ISplice } from 'vs/base/common/sequence'; import { CancellationToken } from 'vs/base/common/cancellation'; +import { canceled } from 'vs/base/common/errors'; +import { ISplice } from 'vs/base/common/sequence'; +import { TPromise } from 'vs/base/common/winjs.base'; /** * Returns the last element of an array. @@ -267,7 +268,7 @@ export function topAsync<T>(array: T[], compare: (a: T, b: T) => number, n: numb await new Promise(resolve => setTimeout(resolve)); // nextTick() would starve I/O. } if (token && token.isCancellationRequested) { - throw new Error('canceled'); + throw canceled(); } topStep(array, compare, result, i, m); } diff --git a/src/vs/workbench/services/search/node/rawSearchService.ts b/src/vs/workbench/services/search/node/rawSearchService.ts index b2617de2d7f..087d9451230 100644 --- a/src/vs/workbench/services/search/node/rawSearchService.ts +++ b/src/vs/workbench/services/search/node/rawSearchService.ts @@ -11,7 +11,7 @@ import { join, sep } from 'path'; import * as arrays from 'vs/base/common/arrays'; import { CancelablePromise, createCancelablePromise, toWinJsPromise } from 'vs/base/common/async'; import { CancellationToken } from 'vs/base/common/cancellation'; -import { canceled } from 'vs/base/common/errors'; +import { canceled, isPromiseCanceledError } from 'vs/base/common/errors'; import { Emitter, Event } from 'vs/base/common/event'; import * as objects from 'vs/base/common/objects'; import * as strings from 'vs/base/common/strings'; @@ -47,9 +47,16 @@ export class SearchService implements IRawSearchService { const emitter = new Emitter<ISerializedSearchProgressItem | ISerializedSearchComplete>({ onFirstListenerDidAdd: () => { promise = createCancelablePromise(token => { - return this.doFileSearch(FileSearchEngine, config, p => emitter.fire(p), token, batchSize) - .then(c => emitter.fire(c), err => emitter.fire({ type: 'error', error: { message: err.message, stack: err.stack } })); + return this.doFileSearch(FileSearchEngine, config, p => emitter.fire(p), token, batchSize); }); + + promise.then( + c => emitter.fire(c), + err => { + if (!isPromiseCanceledError(err)) { + emitter.fire({ type: 'error', error: { message: err.message, stack: err.stack } }); + } + }); }, onLastListenerRemove: () => { promise.cancel(); From 4f3ccc9a5c6e0fc8f224be132288b848005c4b95 Mon Sep 17 00:00:00 2001 From: Rob Lourens <roblourens@gmail.com> Date: Tue, 21 Aug 2018 11:26:05 -0700 Subject: [PATCH 1062/1276] Launch config changes --- .vscode/launch.json | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/.vscode/launch.json b/.vscode/launch.json index 2a12dea7bde..26dce40e474 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -19,6 +19,7 @@ "protocol": "inspector", "port": 5870, "restart": true, + "smartStep": true, "outFiles": [ "${workspaceFolder}/out/**/*.js" ] @@ -29,6 +30,7 @@ "name": "Attach to Shared Process", "protocol": "inspector", "port": 5871, + "smartStep": true, "outFiles": [ "${workspaceFolder}/out/**/*.js" ] @@ -39,6 +41,7 @@ "protocol": "inspector", "name": "Attach to Search Process", "port": 5876, + "smartStep": true, "outFiles": [ "${workspaceFolder}/out/**/*.js" ] @@ -49,6 +52,7 @@ "name": "Attach to CLI Process", "protocol": "inspector", "port": 5874, + "smartStep": true, "outFiles": [ "${workspaceFolder}/out/**/*.js" ] @@ -59,6 +63,7 @@ "name": "Attach to Main Process", "protocol": "inspector", "port": 5875, + "smartStep": true, "outFiles": [ "${workspaceFolder}/out/**/*.js" ] @@ -124,6 +129,7 @@ "type": "chrome", "request": "attach", "name": "Attach to VS Code", + "smartStep": true, "port": 9222 }, { @@ -143,6 +149,7 @@ "runtimeArgs": [ "--inspect=5875" ], + "smartStep": true, "skipFiles": [ "**/winjs*.js" ], @@ -201,7 +208,6 @@ "linux": { "runtimeExecutable": "${workspaceFolder}/.build/electron/code-oss" }, - "stopOnEntry": false, "outputCapture": "std", "args": [ "--delay", From 670d8bb7c5990650926752d144a191f7b02bd9b3 Mon Sep 17 00:00:00 2001 From: Rob Lourens <roblourens@gmail.com> Date: Tue, 21 Aug 2018 11:28:19 -0700 Subject: [PATCH 1063/1276] Remove obsolete process.nextTick calls in search, not needed without promise progress --- .../services/search/node/fileSearch.ts | 18 ++++++++---------- .../services/search/node/rawSearchService.ts | 16 ++++++---------- .../services/search/node/ripgrepTextSearch.ts | 19 +++++++++---------- 3 files changed, 23 insertions(+), 30 deletions(-) diff --git a/src/vs/workbench/services/search/node/fileSearch.ts b/src/vs/workbench/services/search/node/fileSearch.ts index b1683441fd7..67139e2a196 100644 --- a/src/vs/workbench/services/search/node/fileSearch.ts +++ b/src/vs/workbench/services/search/node/fileSearch.ts @@ -211,17 +211,15 @@ export class FileWalker { cmd = ripgrep.cmd; noSiblingsClauses = !Object.keys(ripgrep.siblingClauses).length; - process.nextTick(() => { - const escapedArgs = ripgrep.rgArgs.args - .map(arg => arg.match(/^-/) ? arg : `'${arg}'`) - .join(' '); + const escapedArgs = ripgrep.rgArgs.args + .map(arg => arg.match(/^-/) ? arg : `'${arg}'`) + .join(' '); - let rgCmd = `rg ${escapedArgs}\n - cwd: ${ripgrep.cwd}`; - if (ripgrep.rgArgs.siblingClauses) { - rgCmd += `\n - Sibling clauses: ${JSON.stringify(ripgrep.rgArgs.siblingClauses)}`; - } - onMessage({ message: rgCmd }); - }); + let rgCmd = `rg ${escapedArgs}\n - cwd: ${ripgrep.cwd}`; + if (ripgrep.rgArgs.siblingClauses) { + rgCmd += `\n - Sibling clauses: ${JSON.stringify(ripgrep.rgArgs.siblingClauses)}`; + } + onMessage({ message: rgCmd }); } else { cmd = this.spawnFindCmd(folderQuery); } diff --git a/src/vs/workbench/services/search/node/rawSearchService.ts b/src/vs/workbench/services/search/node/rawSearchService.ts index 087d9451230..ca61885074b 100644 --- a/src/vs/workbench/services/search/node/rawSearchService.ts +++ b/src/vs/workbench/services/search/node/rawSearchService.ts @@ -150,13 +150,11 @@ export class SearchService implements IRawSearchService { } return new TPromise<ISerializedSearchSuccess>((c, e) => { - process.nextTick(() => { // allow caller to register progress callback first - sortedSearch.then(([result, rawMatches]) => { - const serializedMatches = rawMatches.map(rawMatch => this.rawMatchToSearchItem(rawMatch)); - this.sendProgress(serializedMatches, progressCallback, batchSize); - c(result); - }, e); - }); + sortedSearch.then(([result, rawMatches]) => { + const serializedMatches = rawMatches.map(rawMatch => this.rawMatchToSearchItem(rawMatch)); + this.sendProgress(serializedMatches, progressCallback, batchSize); + c(result); + }, e); }); } @@ -409,9 +407,7 @@ export class SearchService implements IRawSearchService { } } }, (progress) => { - process.nextTick(() => { - progressCallback(progress); - }); + progressCallback(progress); }, (error, stats) => { if (batch.length) { progressCallback(batch); diff --git a/src/vs/workbench/services/search/node/ripgrepTextSearch.ts b/src/vs/workbench/services/search/node/ripgrepTextSearch.ts index 56cb2ff5b99..1f5bb2e4025 100644 --- a/src/vs/workbench/services/search/node/ripgrepTextSearch.ts +++ b/src/vs/workbench/services/search/node/ripgrepTextSearch.ts @@ -61,18 +61,17 @@ export class RipgrepEngine { } const cwd = platform.isWindows ? 'c:/' : '/'; - process.nextTick(() => { // Allow caller to register progress callback - const escapedArgs = rgArgs.args - .map(arg => arg.match(/^-/) ? arg : `'${arg}'`) - .join(' '); + const escapedArgs = rgArgs.args + .map(arg => arg.match(/^-/) ? arg : `'${arg}'`) + .join(' '); - let rgCmd = `rg ${escapedArgs}\n - cwd: ${cwd}`; - if (rgArgs.siblingClauses) { - rgCmd += `\n - Sibling clauses: ${JSON.stringify(rgArgs.siblingClauses)}`; - } + let rgCmd = `rg ${escapedArgs}\n - cwd: ${cwd}`; + if (rgArgs.siblingClauses) { + rgCmd += `\n - Sibling clauses: ${JSON.stringify(rgArgs.siblingClauses)}`; + } + + onMessage({ message: rgCmd }); - onMessage({ message: rgCmd }); - }); this.rgProc = cp.spawn(rgDiskPath, rgArgs.args, { cwd }); process.once('exit', this.killRgProcFn); From 57f13b7f263094f4839e8c91d425cb18dd8ebe78 Mon Sep 17 00:00:00 2001 From: Rob Lourens <roblourens@gmail.com> Date: Tue, 21 Aug 2018 11:31:41 -0700 Subject: [PATCH 1064/1276] Fix unhandled cancel warnings from text search --- .../services/search/node/rawSearchService.ts | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/src/vs/workbench/services/search/node/rawSearchService.ts b/src/vs/workbench/services/search/node/rawSearchService.ts index ca61885074b..48e8dbe3191 100644 --- a/src/vs/workbench/services/search/node/rawSearchService.ts +++ b/src/vs/workbench/services/search/node/rawSearchService.ts @@ -67,14 +67,21 @@ export class SearchService implements IRawSearchService { } public textSearch(config: IRawSearch): Event<ISerializedSearchProgressItem | ISerializedSearchComplete> { - let promise: CancelablePromise<void>; + let promise: CancelablePromise<ISerializedSearchComplete>; const emitter = new Emitter<ISerializedSearchProgressItem | ISerializedSearchComplete>({ onFirstListenerDidAdd: () => { promise = createCancelablePromise(token => { - return (config.useRipgrep ? this.ripgrepTextSearch(config, p => emitter.fire(p), token) : this.legacyTextSearch(config, p => emitter.fire(p), token)) - .then(c => emitter.fire(c), err => emitter.fire({ type: 'error', error: { message: err.message, stack: err.stack } })); + return (config.useRipgrep ? this.ripgrepTextSearch(config, p => emitter.fire(p), token) : this.legacyTextSearch(config, p => emitter.fire(p), token)); }); + + promise.then( + c => emitter.fire(c), + err => { + if (!isPromiseCanceledError(err)) { + emitter.fire({ type: 'error', error: { message: err.message, stack: err.stack } }); + } + }); }, onLastListenerRemove: () => { promise.cancel(); From 5b4d232d4e78db113a366cc033825f5d8497fb72 Mon Sep 17 00:00:00 2001 From: Connor Shea <connor.james.shea@gmail.com> Date: Tue, 21 Aug 2018 14:53:53 -0600 Subject: [PATCH 1065/1276] Add a missing compilation step for vscode-css-languageservice development, other misc docs fixes. --- extensions/css-language-features/CONTRIBUTING.md | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/extensions/css-language-features/CONTRIBUTING.md b/extensions/css-language-features/CONTRIBUTING.md index be3c614d9b7..38843f2fbaa 100644 --- a/extensions/css-language-features/CONTRIBUTING.md +++ b/extensions/css-language-features/CONTRIBUTING.md @@ -27,12 +27,13 @@ However, within this extension, you can run a development version of `vscode-css - Clone [Microsoft/vscode-css-languageservice](https://github.com/Microsoft/vscode-css-languageservice) - Run `yarn` in `vscode-css-languageservice` - Run `yarn link` in `vscode-css-languageservice`. This will compile and link `vscode-css-languageservice` -- In `css-language-features/server/`, run `npm link vscode-css-languageservice` +- In `css-language-features/server/`, run `yarn link vscode-css-languageservice` #### Testing the development version of `vscode-css-languageservice` - Open both `vscode-css-languageservice` and this extension in a single workspace with [multi-root workspace](https://code.visualstudio.com/docs/editor/multi-root-workspaces) feature -- Run `yarn watch` at `css-languagefeatures/server/` to recompile this extension with the linked version of `vscode-css-languageservice` +- Run `yarn watch` in `vscode-css-languageservice` to recompile the extension whenever it changes +- Run `yarn watch` at `css-language-features/server/` to recompile this extension with the linked version of `vscode-css-languageservice` - Make some changes in `vscode-css-languageservice` - Now when you run `Launch Extension` debug target, the launched instance will use your development version of `vscode-css-languageservice`. You can interactively test the language features. -- You can also run the `Debug Extension and Language Server` debug target, which will launch the extension and attach the debugger to the language server. After successful attach, you should be able to hit breakpoints in both `vscode-css-languageservice` and `css-language-features/server/` \ No newline at end of file +- You can also run the `Debug Extension and Language Server` debug target, which will launch the extension and attach the debugger to the language server. After successful attach, you should be able to hit breakpoints in both `vscode-css-languageservice` and `css-language-features/server/` From cfc010dc82066132b9d57d1c0e54cd6a7f7bd957 Mon Sep 17 00:00:00 2001 From: Peng Lyu <penn.lv@gmail.com> Date: Tue, 21 Aug 2018 13:57:01 -0700 Subject: [PATCH 1066/1276] Fix #56818. Mouse position validation for folding, scm and comments. --- src/vs/editor/contrib/folding/folding.ts | 2 +- .../workbench/parts/scm/electron-browser/dirtydiffDecorator.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/vs/editor/contrib/folding/folding.ts b/src/vs/editor/contrib/folding/folding.ts index 520ad0ac57d..ab87bfe286b 100644 --- a/src/vs/editor/contrib/folding/folding.ts +++ b/src/vs/editor/contrib/folding/folding.ts @@ -339,7 +339,7 @@ export class FoldingController implements IEditorContribution { // const gutterOffsetX = data.offsetX - data.glyphMarginWidth - data.lineNumbersWidth - data.glyphMarginLeft; // TODO@joao TODO@alex TODO@martin this is such that we don't collide with dirty diff - if (gutterOffsetX < 10) { + if (gutterOffsetX < 5) { // the whitespace between the border and the real folding icon border is 5px return; } diff --git a/src/vs/workbench/parts/scm/electron-browser/dirtydiffDecorator.ts b/src/vs/workbench/parts/scm/electron-browser/dirtydiffDecorator.ts index def130b2dd7..48417f8b9d3 100644 --- a/src/vs/workbench/parts/scm/electron-browser/dirtydiffDecorator.ts +++ b/src/vs/workbench/parts/scm/electron-browser/dirtydiffDecorator.ts @@ -712,7 +712,7 @@ export class DirtyDiffController implements IEditorContribution { const gutterOffsetX = data.offsetX - offsetLeftInGutter; // TODO@joao TODO@alex TODO@martin this is such that we don't collide with folding - if (gutterOffsetX < 0 || gutterOffsetX > 10) { + if (gutterOffsetX < -3 || gutterOffsetX > 6) { // dirty diff decoration on hover is 9px wide return; } From 37efc5d80278508951b58707b07c92db1eae761e Mon Sep 17 00:00:00 2001 From: Jackson Kearl <jkearl11@gmail.com> Date: Tue, 21 Aug 2018 14:08:12 -0700 Subject: [PATCH 1067/1276] Show warning when enabling proposed api for non-installed extensions (#55802) * Show warnieng when enabling proposed api for non-installed extensions * Address feedback * PR review changes --- .../extensions/electron-browser/extensionService.ts | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/src/vs/workbench/services/extensions/electron-browser/extensionService.ts b/src/vs/workbench/services/extensions/electron-browser/extensionService.ts index 6ba4c161c5a..ebac0353572 100644 --- a/src/vs/workbench/services/extensions/electron-browser/extensionService.ts +++ b/src/vs/workbench/services/extensions/electron-browser/extensionService.ts @@ -552,6 +552,17 @@ export class ExtensionService extends Disposable implements IExtensionService { const enableProposedApiFor: string | string[] = this._environmentService.args['enable-proposed-api'] || []; + const notFound = (id: string) => nls.localize('notFound', "Extension \`{0}\` cannot use PROPOSED API as it cannot be found", id); + + if (enableProposedApiFor.length) { + let allProposed = (enableProposedApiFor instanceof Array ? enableProposedApiFor : [enableProposedApiFor]); + allProposed.forEach(id => { + if (!allExtensions.some(description => description.id === id)) { + console.error(notFound(id)); + } + }); + } + const enableProposedApiForAll = !this._environmentService.isBuilt || (!!this._environmentService.extensionDevelopmentPath && product.nameLong.indexOf('Insiders') >= 0) || (enableProposedApiFor.length === 0 && 'enable-proposed-api' in this._environmentService.args); From f0736484243e1b426357148b6967e2561aa8ebde Mon Sep 17 00:00:00 2001 From: SteVen Batten <stbatt@microsoft.com> Date: Tue, 21 Aug 2018 14:38:17 -0700 Subject: [PATCH 1068/1276] fixes #56652 --- .../browser/parts/titlebar/menubarControl.ts | 32 +++++++++++++++---- 1 file changed, 25 insertions(+), 7 deletions(-) diff --git a/src/vs/workbench/browser/parts/titlebar/menubarControl.ts b/src/vs/workbench/browser/parts/titlebar/menubarControl.ts index fc7cf8af33c..f97d4cb75c9 100644 --- a/src/vs/workbench/browser/parts/titlebar/menubarControl.ts +++ b/src/vs/workbench/browser/parts/titlebar/menubarControl.ts @@ -102,8 +102,11 @@ export class MenubarControl extends Disposable { private recentlyOpened: IRecentlyOpened; private updatePending: boolean; private _focusState: MenubarState; + + // Input-related private _mnemonicsInUse: boolean; private openedViaKeyboard: boolean; + private awaitingAltRelease: boolean; private mnemonics: Map<KeyCode, number>; private _onVisibilityChange: Emitter<boolean>; @@ -379,18 +382,33 @@ export class MenubarControl extends Disposable { return; } + // Alt key pressed while menu is focused. This should return focus away from the menubar + if (this.isFocused && modifierKeyStatus.lastKeyPressed === 'alt' && modifierKeyStatus.altKey) { + this.setUnfocusedState(); + this.mnemonicsInUse = false; + this.awaitingAltRelease = true; + } + + // Clean alt key press and release if (allModifiersReleased && modifierKeyStatus.lastKeyPressed === 'alt' && modifierKeyStatus.lastKeyReleased === 'alt') { - if (!this.isFocused) { - this.mnemonicsInUse = true; - this.focusedMenu = { index: 0 }; - this.focusState = MenubarState.FOCUSED; - } else if (!this.isOpen) { - this.setUnfocusedState(); + if (!this.awaitingAltRelease) { + if (!this.isFocused) { + this.mnemonicsInUse = true; + this.focusedMenu = { index: 0 }; + this.focusState = MenubarState.FOCUSED; + } else if (!this.isOpen) { + this.setUnfocusedState(); + } } } + // Alt key released + if (allModifiersReleased && modifierKeyStatus.lastKeyReleased === 'alt') { + this.awaitingAltRelease = false; + } + if (this.currentEnableMenuBarMnemonics && this.customMenus && !this.isOpen) { - this.updateMnemonicVisibility(modifierKeyStatus.altKey || this.mnemonicsInUse); + this.updateMnemonicVisibility((!this.awaitingAltRelease && modifierKeyStatus.altKey) || this.mnemonicsInUse); } } From 216c26f67026c93c86a83e483c8f1f5230af268d Mon Sep 17 00:00:00 2001 From: SteVen Batten <stbatt@microsoft.com> Date: Tue, 21 Aug 2018 14:41:55 -0700 Subject: [PATCH 1069/1276] change to only check alt key is released --- src/vs/workbench/browser/parts/titlebar/menubarControl.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vs/workbench/browser/parts/titlebar/menubarControl.ts b/src/vs/workbench/browser/parts/titlebar/menubarControl.ts index f97d4cb75c9..1e22b3ed71b 100644 --- a/src/vs/workbench/browser/parts/titlebar/menubarControl.ts +++ b/src/vs/workbench/browser/parts/titlebar/menubarControl.ts @@ -403,7 +403,7 @@ export class MenubarControl extends Disposable { } // Alt key released - if (allModifiersReleased && modifierKeyStatus.lastKeyReleased === 'alt') { + if (!modifierKeyStatus.altKey && modifierKeyStatus.lastKeyReleased === 'alt') { this.awaitingAltRelease = false; } From 90f3b1c69a5347d2eea66ea098ed2c50122d6e30 Mon Sep 17 00:00:00 2001 From: Maira Wenzel <mairaw@microsoft.com> Date: Tue, 21 Aug 2018 15:23:55 -0700 Subject: [PATCH 1070/1276] fix double the --- 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 6000b0300db..2c063cbf7b9 100644 --- a/src/vs/vscode.d.ts +++ b/src/vs/vscode.d.ts @@ -2515,7 +2515,7 @@ declare module 'vscode' { * @param name The name of the symbol. * @param kind The kind of the symbol. * @param containerName The name of the symbol containing the symbol. - * @param location The the location of the symbol. + * @param location The location of the symbol. */ constructor(name: string, kind: SymbolKind, containerName: string, location: Location); From bae20e989262f919d6e9253b2492f14a83a5cbf5 Mon Sep 17 00:00:00 2001 From: Daniel Imms <daimms@microsoft.com> Date: Tue, 21 Aug 2018 15:28:36 -0700 Subject: [PATCH 1071/1276] vscode-xterm@3.7.0-beta5 Fixes #56628 --- package.json | 2 +- yarn.lock | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/package.json b/package.json index 134505e89c0..01a6d5185fb 100644 --- a/package.json +++ b/package.json @@ -49,7 +49,7 @@ "vscode-nsfw": "1.0.17", "vscode-ripgrep": "1.1.0", "vscode-textmate": "^4.0.1", - "vscode-xterm": "3.7.0-beta4", + "vscode-xterm": "3.7.0-beta5", "winreg": "^1.2.4", "yauzl": "^2.9.1", "yazl": "^2.4.3" diff --git a/yarn.lock b/yarn.lock index f9f3b0b1d1c..8c39006188f 100644 --- a/yarn.lock +++ b/yarn.lock @@ -7941,9 +7941,9 @@ vscode-textmate@^4.0.1: dependencies: oniguruma "^7.0.0" -vscode-xterm@3.7.0-beta4: - version "3.7.0-beta4" - resolved "https://registry.yarnpkg.com/vscode-xterm/-/vscode-xterm-3.7.0-beta4.tgz#f980d66f94f09ae80e100715dae60715dcae1ac6" +vscode-xterm@3.7.0-beta5: + version "3.7.0-beta5" + resolved "https://registry.yarnpkg.com/vscode-xterm/-/vscode-xterm-3.7.0-beta5.tgz#04c7564d1cc8d73b268f04046b3da050c6e59be7" vso-node-api@^6.1.2-preview: version "6.1.2-preview" From 14595011f1e66a48f38388889a18f39da941ca2e Mon Sep 17 00:00:00 2001 From: Andre Weinand <aweinand@microsoft.com> Date: Wed, 22 Aug 2018 01:08:34 +0200 Subject: [PATCH 1072/1276] move some auto-attach code back to node-debug --- extensions/debug-auto-launch/src/extension.ts | 32 +-- .../debug-auto-launch/src/nodeProcessTree.ts | 124 ------------ .../debug-auto-launch/src/processTree.ts | 186 ------------------ .../src/protocolDetection.ts | 58 ------ 4 files changed, 10 insertions(+), 390 deletions(-) delete mode 100644 extensions/debug-auto-launch/src/nodeProcessTree.ts delete mode 100644 extensions/debug-auto-launch/src/processTree.ts delete mode 100644 extensions/debug-auto-launch/src/protocolDetection.ts diff --git a/extensions/debug-auto-launch/src/extension.ts b/extensions/debug-auto-launch/src/extension.ts index e10846e111e..2676fbf6cd0 100644 --- a/extensions/debug-auto-launch/src/extension.ts +++ b/extensions/debug-auto-launch/src/extension.ts @@ -7,8 +7,6 @@ import * as vscode from 'vscode'; import * as nls from 'vscode-nls'; -import { basename } from 'path'; -import { pollProcesses, attachToProcess } from './nodeProcessTree'; const localize = nls.loadMessageBundle(); const ON_TEXT = localize('status.text.auto.attach.on', "Auto Attach: On"); @@ -17,10 +15,9 @@ const OFF_TEXT = localize('status.text.auto.attach.off', "Auto Attach: Off"); const TOGGLE_COMMAND = 'extension.node-debug.toggleAutoAttach'; let currentState: string; -let autoAttacher: vscode.Disposable | undefined; +let autoAttachStarted = false; let statusItem: vscode.StatusBarItem | undefined = undefined; - export function activate(context: vscode.ExtensionContext): void { context.subscriptions.push(vscode.commands.registerCommand(TOGGLE_COMMAND, toggleAutoAttach)); @@ -85,9 +82,9 @@ function updateAutoAttachInStatus(context: vscode.ExtensionContext) { statusItem.hide(); statusItem.text = OFF_TEXT; } - if (autoAttacher) { - autoAttacher.dispose(); - autoAttacher = undefined; + if (autoAttachStarted) { + autoAttachStarted = false; + vscode.commands.executeCommand('extension.node-debug.stopAutoAttach'); } } else { // 'on' or 'off' @@ -106,27 +103,18 @@ function updateAutoAttachInStatus(context: vscode.ExtensionContext) { if (newState === 'off') { statusItem.text = OFF_TEXT; - if (autoAttacher) { - autoAttacher.dispose(); - autoAttacher = undefined; + if (autoAttachStarted) { + autoAttachStarted = false; + vscode.commands.executeCommand('extension.node-debug.stopAutoAttach'); } + } else if (newState === 'on') { statusItem.text = ON_TEXT; const vscode_pid = process.env['VSCODE_PID']; const rootPid = vscode_pid ? parseInt(vscode_pid) : 0; - autoAttacher = startAutoAttach(rootPid); + vscode.commands.executeCommand('extension.node-debug.startAutoAttach', rootPid); + autoAttachStarted = true; } } } } - -function startAutoAttach(rootPid: number): vscode.Disposable { - - return pollProcesses(rootPid, true, (pid, cmdPath, args) => { - const cmdName = basename(cmdPath, '.exe'); - if (cmdName === 'node') { - const name = localize('process.with.pid.label', "Process {0}", pid); - attachToProcess(undefined, name, pid, args); - } - }); -} diff --git a/extensions/debug-auto-launch/src/nodeProcessTree.ts b/extensions/debug-auto-launch/src/nodeProcessTree.ts deleted file mode 100644 index 1a62971bc30..00000000000 --- a/extensions/debug-auto-launch/src/nodeProcessTree.ts +++ /dev/null @@ -1,124 +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'; - -import * as vscode from 'vscode'; -import { getProcessTree, ProcessTreeNode } from './processTree'; -import { analyseArguments } from './protocolDetection'; - -const pids = new Set<number>(); - -const POLL_INTERVAL = 1000; - -/** - * Poll for all subprocesses of given root process. - */ -export function pollProcesses(rootPid: number, inTerminal: boolean, cb: (pid: number, cmd: string, args: string) => void): vscode.Disposable { - - let stopped = false; - - function poll() { - //const start = Date.now(); - findChildProcesses(rootPid, inTerminal, cb).then(_ => { - //console.log(`duration: ${Date.now() - start}`); - setTimeout(_ => { - if (!stopped) { - poll(); - } - }, POLL_INTERVAL); - }); - } - - poll(); - - return new vscode.Disposable(() => stopped = true); -} - -export function attachToProcess(folder: vscode.WorkspaceFolder | undefined, name: string, pid: number, args: string, baseConfig?: vscode.DebugConfiguration) { - - if (pids.has(pid)) { - return; - } - pids.add(pid); - - const config: vscode.DebugConfiguration = { - type: 'node', - request: 'attach', - name: name, - stopOnEntry: false - }; - - if (baseConfig) { - // selectively copy attributes - if (baseConfig.timeout) { - config.timeout = baseConfig.timeout; - } - if (baseConfig.sourceMaps) { - config.sourceMaps = baseConfig.sourceMaps; - } - if (baseConfig.outFiles) { - config.outFiles = baseConfig.outFiles; - } - if (baseConfig.sourceMapPathOverrides) { - config.sourceMapPathOverrides = baseConfig.sourceMapPathOverrides; - } - if (baseConfig.smartStep) { - config.smartStep = baseConfig.smartStep; - } - if (baseConfig.skipFiles) { - config.skipFiles = baseConfig.skipFiles; - } - if (baseConfig.showAsyncStacks) { - config.sourceMaps = baseConfig.showAsyncStacks; - } - if (baseConfig.trace) { - config.trace = baseConfig.trace; - } - } - - let { usePort, protocol, port } = analyseArguments(args); - if (usePort) { - config.processId = `${protocol}${port}`; - } else { - if (protocol && port > 0) { - config.processId = `${pid}${protocol}${port}`; - } else { - config.processId = pid.toString(); - } - } - - vscode.debug.startDebugging(folder, config); -} - -function findChildProcesses(rootPid: number, inTerminal: boolean, cb: (pid: number, cmd: string, args: string) => void): Promise<void> { - - function walker(node: ProcessTreeNode, terminal: boolean, terminalPids: number[]) { - - if (terminalPids.indexOf(node.pid) >= 0) { - terminal = true; // found the terminal shell - } - - let { protocol } = analyseArguments(node.args); - if (terminal && protocol) { - cb(node.pid, node.command, node.args); - } - - for (const child of node.children || []) { - walker(child, terminal, terminalPids); - } - } - - return getProcessTree(rootPid).then(tree => { - if (tree) { - const terminals = vscode.window.terminals; - if (terminals.length > 0) { - Promise.all(terminals.map(terminal => terminal.processId)).then(terminalPids => { - walker(tree, !inTerminal, terminalPids); - }); - } - } - }); -} diff --git a/extensions/debug-auto-launch/src/processTree.ts b/extensions/debug-auto-launch/src/processTree.ts deleted file mode 100644 index f072d9cf58c..00000000000 --- a/extensions/debug-auto-launch/src/processTree.ts +++ /dev/null @@ -1,186 +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'; - -import { spawn, ChildProcess } from 'child_process'; -import { join } from 'path'; - -export class ProcessTreeNode { - children?: ProcessTreeNode[]; - - constructor(public pid: number, public ppid: number, public command: string, public args: string) { - } -} - -export async function getProcessTree(rootPid: number): Promise<ProcessTreeNode | undefined> { - - const map = new Map<number, ProcessTreeNode>(); - - map.set(0, new ProcessTreeNode(0, 0, '???', '')); - - try { - await getProcesses((pid: number, ppid: number, command: string, args: string) => { - if (pid !== ppid) { - map.set(pid, new ProcessTreeNode(pid, ppid, command, args)); - } - }); - } catch (err) { - return undefined; - } - - const values = map.values(); - for (const p of values) { - const parent = map.get(p.ppid); - if (parent && parent !== p) { - if (!parent.children) { - parent.children = []; - } - parent.children.push(p); - } - } - - if (!isNaN(rootPid) && rootPid > 0) { - return map.get(rootPid); - } - return map.get(0); -} - -export function getProcesses(one: (pid: number, ppid: number, command: string, args: string, date?: number) => void): Promise<void> { - - // returns a function that aggregates chunks of data until one or more complete lines are received and passes them to a callback. - function lines(callback: (a: string) => void) { - let unfinished = ''; // unfinished last line of chunk - return (data: string | Buffer) => { - const lines = data.toString().split(/\r?\n/); - const finishedLines = lines.slice(0, lines.length - 1); - finishedLines[0] = unfinished + finishedLines[0]; // complete previous unfinished line - unfinished = lines[lines.length - 1]; // remember unfinished last line of this chunk for next round - for (const s of finishedLines) { - callback(s); - } - }; - } - - return new Promise((resolve, reject) => { - - let proc: ChildProcess; - - if (process.platform === 'win32') { - - // attributes columns are in alphabetic order! - const CMD_PAT = /^(.*)\s+([0-9]+)\.[0-9]+[+-][0-9]+\s+([0-9]+)\s+([0-9]+)$/; - - const wmic = join(process.env['WINDIR'] || 'C:\\Windows', 'System32', 'wbem', 'WMIC.exe'); - proc = spawn(wmic, ['process', 'get', 'CommandLine,CreationDate,ParentProcessId,ProcessId']); - proc.stdout.setEncoding('utf8'); - proc.stdout.on('data', lines(line => { - let matches = CMD_PAT.exec(line.trim()); - if (matches && matches.length === 5) { - const pid = Number(matches[4]); - const ppid = Number(matches[3]); - const date = Number(matches[2]); - let args = matches[1].trim(); - if (!isNaN(pid) && !isNaN(ppid) && args) { - let command = args; - if (args[0] === '"') { - const end = args.indexOf('"', 1); - if (end > 0) { - command = args.substr(1, end - 1); - args = args.substr(end + 2); - } - } else { - const end = args.indexOf(' '); - if (end > 0) { - command = args.substr(0, end); - args = args.substr(end + 1); - } else { - args = ''; - } - } - one(pid, ppid, command, args, date); - } - } - })); - - } else if (process.platform === 'darwin') { // OS X - - proc = spawn('/bin/ps', ['-x', '-o', `pid,ppid,comm=${'a'.repeat(256)},command`]); - proc.stdout.setEncoding('utf8'); - proc.stdout.on('data', lines(line => { - - const pid = Number(line.substr(0, 5)); - const ppid = Number(line.substr(6, 5)); - const command = line.substr(12, 256).trim(); - const args = line.substr(269 + command.length); - - if (!isNaN(pid) && !isNaN(ppid)) { - one(pid, ppid, command, args); - } - })); - - } else { // linux - - proc = spawn('/bin/ps', ['-ax', '-o', 'pid,ppid,comm:20,command']); - proc.stdout.setEncoding('utf8'); - proc.stdout.on('data', lines(line => { - - const pid = Number(line.substr(0, 5)); - const ppid = Number(line.substr(6, 5)); - let command = line.substr(12, 20).trim(); - let args = line.substr(33); - - let pos = args.indexOf(command); - if (pos >= 0) { - pos = pos + command.length; - while (pos < args.length) { - if (args[pos] === ' ') { - break; - } - pos++; - } - command = args.substr(0, pos); - args = args.substr(pos + 1); - } - - if (!isNaN(pid) && !isNaN(ppid)) { - one(pid, ppid, command, args); - } - })); - } - - proc.on('error', err => { - reject(err); - }); - - proc.stderr.setEncoding('utf8'); - proc.stderr.on('data', data => { - reject(new Error(data.toString())); - }); - - proc.on('close', (code, signal) => { - if (code === 0) { - resolve(); - } else if (code > 0) { - reject(new Error(`process terminated with exit code: ${code}`)); - } - if (signal) { - reject(new Error(`process terminated with signal: ${signal}`)); - } - }); - - proc.on('exit', (code, signal) => { - if (code === 0) { - //resolve(); - } else if (code > 0) { - reject(new Error(`process terminated with exit code: ${code}`)); - } - if (signal) { - reject(new Error(`process terminated with signal: ${signal}`)); - } - }); - }); -} - diff --git a/extensions/debug-auto-launch/src/protocolDetection.ts b/extensions/debug-auto-launch/src/protocolDetection.ts deleted file mode 100644 index 9ccca40e849..00000000000 --- a/extensions/debug-auto-launch/src/protocolDetection.ts +++ /dev/null @@ -1,58 +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'; - -export const INSPECTOR_PORT_DEFAULT = 9229; -export const LEGACY_PORT_DEFAULT = 5858; - -export interface DebugArguments { - usePort: boolean; // if true debug by using the debug port - protocol?: 'legacy' | 'inspector'; - address?: string; - port: number; -} - -/* - * analyse the given command line arguments and extract debug port and protocol from it. - */ -export function analyseArguments(args: string): DebugArguments { - - const DEBUG_FLAGS_PATTERN = /--(inspect|debug)(-brk)?(=((\[[0-9a-fA-F:]*\]|[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+|[a-zA-Z0-9\.]*):)?(\d+))?/; - const DEBUG_PORT_PATTERN = /--(inspect|debug)-port=(\d+)/; - - const result: DebugArguments = { - usePort: false, - port: -1 - }; - - // match --debug, --debug=1234, --debug-brk, debug-brk=1234, --inspect, --inspect=1234, --inspect-brk, --inspect-brk=1234 - let matches = DEBUG_FLAGS_PATTERN.exec(args); - if (matches && matches.length >= 2) { - // attach via port - result.usePort = true; - if (matches.length >= 6 && matches[5]) { - result.address = matches[5]; - } - if (matches.length >= 7 && matches[6]) { - result.port = parseInt(matches[6]); - } - result.protocol = matches[1] === 'debug' ? 'legacy' : 'inspector'; - } - - // a debug-port=1234 or --inspect-port=1234 overrides the port - matches = DEBUG_PORT_PATTERN.exec(args); - if (matches && matches.length === 3) { - // override port - result.port = parseInt(matches[2]); - result.protocol = matches[1] === 'debug' ? 'legacy' : 'inspector'; - } - - if (result.port < 0) { - result.port = result.protocol === 'inspector' ? INSPECTOR_PORT_DEFAULT : LEGACY_PORT_DEFAULT; - } - - return result; -} From 84b747f86850e20e1c10cffd432ebfa164d3b56f Mon Sep 17 00:00:00 2001 From: Andre Weinand <aweinand@microsoft.com> Date: Wed, 22 Aug 2018 01:09:51 +0200 Subject: [PATCH 1073/1276] node-debug@1.27.4 --- build/builtInExtensions.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build/builtInExtensions.json b/build/builtInExtensions.json index 9235407a613..9179f321e7e 100644 --- a/build/builtInExtensions.json +++ b/build/builtInExtensions.json @@ -1,7 +1,7 @@ [ { "name": "ms-vscode.node-debug", - "version": "1.27.3", + "version": "1.27.4", "repo": "https://github.com/Microsoft/vscode-node-debug" }, { From 12e906cd4217c38761653845eb5eab9692547d19 Mon Sep 17 00:00:00 2001 From: Jackson Kearl <jkearl11@gmail.com> Date: Tue, 21 Aug 2018 16:43:57 -0700 Subject: [PATCH 1074/1276] Add a message showing no results in settigns search (#56868) * Add no reuslts message * Fix text alignment and color --- .../browser/media/settingsEditor2.css | 18 +++++++++ .../preferences/browser/settingsEditor2.ts | 40 ++++++++++++++++++- 2 files changed, 57 insertions(+), 1 deletion(-) diff --git a/src/vs/workbench/parts/preferences/browser/media/settingsEditor2.css b/src/vs/workbench/parts/preferences/browser/media/settingsEditor2.css index 7e038adc1d1..368bec216c8 100644 --- a/src/vs/workbench/parts/preferences/browser/media/settingsEditor2.css +++ b/src/vs/workbench/parts/preferences/browser/media/settingsEditor2.css @@ -39,10 +39,23 @@ margin-right: 7px; } +.settings-editor > .settings-header > .search-container { + position: relative; +} + .vs .settings-editor > .settings-header > .search-container > .suggest-input-container { border: 1px solid #ddd; } +.settings-editor > .settings-header > .search-container > .settings-count-widget { + margin: 6px 0px; + padding: 0px 8px; + border-radius: 2px; + position: absolute; + right: 10px; + top: 0; +} + .settings-editor > .settings-header > .settings-header-controls { height: 32px; display: flex; @@ -115,6 +128,11 @@ max-width: 1000px; } +.settings-editor > .settings-body > .no-results { + margin-top: 20px; + display: none; +} + .settings-editor.search-mode > .settings-body .settings-tree-container .monaco-tree-wrapper, .settings-editor.search-mode > .settings-body > .settings-tree-container .setting-measure-container { width: calc(100% - 11px); diff --git a/src/vs/workbench/parts/preferences/browser/settingsEditor2.ts b/src/vs/workbench/parts/preferences/browser/settingsEditor2.ts index 4b11beedfcf..ee26a5d7a0b 100644 --- a/src/vs/workbench/parts/preferences/browser/settingsEditor2.ts +++ b/src/vs/workbench/parts/preferences/browser/settingsEditor2.ts @@ -27,7 +27,7 @@ import { IInstantiationService } from 'vs/platform/instantiation/common/instanti import { WorkbenchTree } from 'vs/platform/list/browser/listService'; import { ILogService } from 'vs/platform/log/common/log'; import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry'; -import { attachButtonStyler } from 'vs/platform/theme/common/styler'; +import { attachButtonStyler, attachStylerCallback } from 'vs/platform/theme/common/styler'; import { IThemeService } from 'vs/platform/theme/common/themeService'; import { BaseEditor } from 'vs/workbench/browser/parts/editor/baseEditor'; import { EditorOptions, IEditor } from 'vs/workbench/common/editor'; @@ -44,6 +44,7 @@ import { IPreferencesService, ISearchResult, ISettingsEditorModel } from 'vs/wor import { SettingsEditor2Input } from 'vs/workbench/services/preferences/common/preferencesEditorInput'; import { DefaultSettingsEditorModel } from 'vs/workbench/services/preferences/common/preferencesModels'; import { ResourceEditorModel } from 'vs/workbench/common/editor/resourceEditorModel'; +import { badgeBackground, contrastBorder, badgeForeground, editorForeground } from 'vs/platform/theme/common/colorRegistry'; const $ = DOM.$; @@ -61,6 +62,7 @@ export class SettingsEditor2 extends BaseEditor { private rootElement: HTMLElement; private headerContainer: HTMLElement; private searchWidget: SuggestEnabledInput; + private countElement: HTMLElement; private settingsTargetsWidget: SettingsTargetsWidget; private toolbar: ToolBar; @@ -69,6 +71,7 @@ export class SettingsEditor2 extends BaseEditor { private settingsTreeRenderer: SettingsRenderer; private tocTreeModel: TOCTreeModel; private settingsTreeModel: SettingsTreeModel; + private noResultsMessage: HTMLElement; private tocTreeContainer: HTMLElement; private tocTree: WorkbenchTree; @@ -243,6 +246,19 @@ export class SettingsEditor2 extends BaseEditor { // TODO: Aria-live })); + this.countElement = DOM.append(searchContainer, DOM.$('.settings-count-widget')); + this._register(attachStylerCallback(this.themeService, { badgeBackground, contrastBorder, badgeForeground }, colors => { + const background = colors.badgeBackground ? colors.badgeBackground.toString() : null; + const border = colors.contrastBorder ? colors.contrastBorder.toString() : null; + + this.countElement.style.backgroundColor = background; + this.countElement.style.color = colors.badgeForeground.toString(); + + this.countElement.style.borderWidth = border ? '1px' : null; + this.countElement.style.borderStyle = border ? 'solid' : null; + this.countElement.style.borderColor = border; + })); + this._register(this.searchWidget.onInputDidChange(() => this.onSearchInputChanged())); const headerControlsContainer = DOM.append(this.headerContainer, $('.settings-header-controls')); @@ -329,6 +345,12 @@ export class SettingsEditor2 extends BaseEditor { private createBody(parent: HTMLElement): void { const bodyContainer = DOM.append(parent, $('.settings-body')); + this.noResultsMessage = DOM.append(bodyContainer, $('.no-results')); + this.noResultsMessage.innerText = localize('noResults', "No Settings Found"); + this._register(attachStylerCallback(this.themeService, { editorForeground }, colors => { + this.noResultsMessage.style.color = colors.editorForeground ? colors.editorForeground.toString() : null; + })); + this.createFocusSink( bodyContainer, e => { @@ -746,6 +768,7 @@ export class SettingsEditor2 extends BaseEditor { private onSearchInputChanged(): void { const query = this.searchWidget.getValue().trim(); + if (query === '') { this.countElement.style.display = 'none'; this.noResultsMessage.style.display = 'none'; } this.delayedFilterLogging.cancel(); this.triggerSearch(query).then(() => { if (query && this.searchResultModel) { @@ -921,9 +944,13 @@ export class SettingsEditor2 extends BaseEditor { this.settingsTree.setInput(this.searchResultModel.root); } else { this.tocTreeModel.update(); + expandAll(this.tocTree); this.searchResultModel.setResult(type, result); } + let count = this.searchResultModel.getUniqueResults().map(result => result ? result.filterMatches.length : 0).reduce((a, b) => a + b); + this.renderResultCountMessages(count); + this.tocTree.setSelection([]); expandAll(this.tocTree); @@ -931,6 +958,17 @@ export class SettingsEditor2 extends BaseEditor { }); } + private renderResultCountMessages(count: number) { + switch (count) { + case 0: this.countElement.innerText = localize('noResults', "No Settings Found"); break; + case 1: this.countElement.innerText = localize('oneResult', "1 Setting Found"); break; + default: this.countElement.innerText = localize('moreThanOneResult', "{0} Settings Found", count); + } + + this.countElement.style.display = 'block'; + this.noResultsMessage.style.display = count === 0 ? 'block' : 'none'; + } + private _filterOrSearchPreferencesModel(filter: string, model: ISettingsEditorModel, provider: ISearchProvider, token?: CancellationToken): TPromise<ISearchResult> { const searchP = provider ? provider.searchModel(model, token) : TPromise.wrap(null); return searchP From 324e1095abc67970bbcc47de7da69bde125e379b Mon Sep 17 00:00:00 2001 From: Rob Lourens <roblourens@gmail.com> Date: Tue, 21 Aug 2018 17:35:21 -0700 Subject: [PATCH 1075/1276] #56950 - add telemetry for non-EH search --- src/vs/platform/search/common/search.ts | 31 ++-- .../parts/search/browser/openFileHandler.ts | 4 +- .../search/test/common/searchModel.test.ts | 22 +-- .../services/search/node/fileSearch.ts | 50 +++--- .../services/search/node/rawSearchService.ts | 146 ++++++++++-------- .../workbench/services/search/node/search.ts | 12 +- .../services/search/node/searchIpc.ts | 8 +- .../services/search/node/searchService.ts | 84 ++++++++-- .../services/search/node/textSearch.ts | 9 +- .../search/test/node/searchService.test.ts | 17 +- 10 files changed, 222 insertions(+), 161 deletions(-) diff --git a/src/vs/platform/search/common/search.ts b/src/vs/platform/search/common/search.ts index fff587381ba..81873a06f36 100644 --- a/src/vs/platform/search/common/search.ts +++ b/src/vs/platform/search/common/search.ts @@ -155,41 +155,40 @@ export interface ISearchProgressItem extends IFileMatch, IProgress { export interface ISearchCompleteStats { limitHit?: boolean; - stats?: ISearchStats; + stats?: IFileSearchStats; } export interface ISearchComplete extends ISearchCompleteStats { results: IFileMatch[]; } -export interface ISearchStats { +export interface IFileSearchStats { fromCache: boolean; + cacheOrSearchEngineStats: ISearchEngineStats | ICachedSearchStats; + resultCount: number; - unsortedResultTime?: number; - sortedResultTime?: number; + workspaceFolderCount: number; + type: 'fileIndexProver' | 'fileSearchProvider' | 'searchProcess'; + endToEndTime?: number; + sortingTime?: number; } -export interface ICachedSearchStats extends ISearchStats { - cacheLookupStartTime: number; - cacheFilterStartTime: number; - cacheLookupResultTime: number; +export interface ICachedSearchStats { + cacheWasResolved: boolean; + cacheLookupTime: number; + cacheFilterTime: number; cacheEntryCount: number; - joined?: ISearchStats; } -export interface IUncachedSearchStats extends ISearchStats { +export interface ISearchEngineStats { traversal: string; - errors: string[]; - fileWalkStartTime: number; - fileWalkResultTime: number; + fileWalkTime: number; directoriesWalked: number; filesWalked: number; - cmdForkStartTime?: number; - cmdForkResultTime?: number; + cmdTime: number; cmdResultCount?: number; } - // ---- very simple implementation of the search model -------------------- export class FileMatch implements IFileMatch { diff --git a/src/vs/workbench/parts/search/browser/openFileHandler.ts b/src/vs/workbench/parts/search/browser/openFileHandler.ts index d504966ecc3..60b96a6e491 100644 --- a/src/vs/workbench/parts/search/browser/openFileHandler.ts +++ b/src/vs/workbench/parts/search/browser/openFileHandler.ts @@ -25,7 +25,7 @@ import { EditorInput, IWorkbenchEditorConfiguration } from 'vs/workbench/common/ import { IResourceInput } from 'vs/platform/editor/common/editor'; import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; -import { IQueryOptions, ISearchService, ISearchStats, ISearchQuery, ISearchComplete } from 'vs/platform/search/common/search'; +import { IQueryOptions, ISearchService, IFileSearchStats, ISearchQuery, ISearchComplete } from 'vs/platform/search/common/search'; import { IWorkspaceContextService } from 'vs/platform/workspace/common/workspace'; import { IEnvironmentService } from 'vs/platform/environment/common/environment'; import { IRange } from 'vs/editor/common/core/range'; @@ -38,7 +38,7 @@ import { untildify } from 'vs/base/common/labels'; export class FileQuickOpenModel extends QuickOpenModel { - constructor(entries: QuickOpenEntry[], public stats?: ISearchStats) { + constructor(entries: QuickOpenEntry[], public stats?: IFileSearchStats) { super(entries); } } diff --git a/src/vs/workbench/parts/search/test/common/searchModel.test.ts b/src/vs/workbench/parts/search/test/common/searchModel.test.ts index 589973b27a6..e6570daef0d 100644 --- a/src/vs/workbench/parts/search/test/common/searchModel.test.ts +++ b/src/vs/workbench/parts/search/test/common/searchModel.test.ts @@ -16,7 +16,7 @@ import { ModelServiceImpl } from 'vs/editor/common/services/modelServiceImpl'; import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; import { TestConfigurationService } from 'vs/platform/configuration/test/common/testConfigurationService'; import { TestInstantiationService } from 'vs/platform/instantiation/test/common/instantiationServiceMock'; -import { IFileMatch, IFolderQuery, ILineMatch, ISearchComplete, ISearchProgressItem, ISearchQuery, ISearchService, IUncachedSearchStats } from 'vs/platform/search/common/search'; +import { IFileMatch, IFileSearchStats, IFolderQuery, ILineMatch, ISearchComplete, ISearchProgressItem, ISearchQuery, ISearchService } from 'vs/platform/search/common/search'; import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry'; import { NullTelemetryService } from 'vs/platform/telemetry/common/telemetryUtils'; import { SearchModel } from 'vs/workbench/parts/search/common/searchModel'; @@ -47,15 +47,19 @@ suite('SearchModel', () => { let instantiationService: TestInstantiationService; let restoreStubs: sinon.SinonStub[]; - const testSearchStats: IUncachedSearchStats = { + const testSearchStats: IFileSearchStats = { fromCache: false, - resultCount: 4, - traversal: 'node', - errors: [], - fileWalkStartTime: 0, - fileWalkResultTime: 1, - directoriesWalked: 2, - filesWalked: 3 + resultCount: 1, + type: 'searchProcess', + workspaceFolderCount: 1, + cacheOrSearchEngineStats: { + traversal: 'node', + fileWalkTime: 0, + cmdTime: 0, + cmdResultCount: 0, + directoriesWalked: 2, + filesWalked: 3 + } }; const folderQueries: IFolderQuery[] = [ diff --git a/src/vs/workbench/services/search/node/fileSearch.ts b/src/vs/workbench/services/search/node/fileSearch.ts index 67139e2a196..b6022a2edc1 100644 --- a/src/vs/workbench/services/search/node/fileSearch.ts +++ b/src/vs/workbench/services/search/node/fileSearch.ts @@ -6,28 +6,27 @@ 'use strict'; import * as childProcess from 'child_process'; -import { StringDecoder, NodeStringDecoder } from 'string_decoder'; -import { toErrorMessage } from 'vs/base/common/errorMessage'; import * as fs from 'fs'; import * as path from 'path'; -import { isEqualOrParent } from 'vs/base/common/paths'; import { Readable } from 'stream'; -import { TPromise } from 'vs/base/common/winjs.base'; - -import * as objects from 'vs/base/common/objects'; +import { NodeStringDecoder, StringDecoder } from 'string_decoder'; import * as arrays from 'vs/base/common/arrays'; +import { toErrorMessage } from 'vs/base/common/errorMessage'; +import * as glob from 'vs/base/common/glob'; +import * as normalization from 'vs/base/common/normalization'; +import * as objects from 'vs/base/common/objects'; +import { isEqualOrParent } from 'vs/base/common/paths'; import * as platform from 'vs/base/common/platform'; import * as strings from 'vs/base/common/strings'; -import * as normalization from 'vs/base/common/normalization'; import * as types from 'vs/base/common/types'; -import * as glob from 'vs/base/common/glob'; -import { IProgress, IUncachedSearchStats } from 'vs/platform/search/common/search'; - +import { TPromise } from 'vs/base/common/winjs.base'; import * as extfs from 'vs/base/node/extfs'; import * as flow from 'vs/base/node/flow'; -import { IRawFileMatch, IRawSearch, ISearchEngine, IFolderSearch, ISerializedSearchSuccess } from './search'; +import { IProgress, ISearchEngineStats } from 'vs/platform/search/common/search'; import { spawnRipgrepCmd } from './ripgrepFileSearch'; import { rgErrorMsgForDisplay } from './ripgrepTextSearch'; +import { IFolderSearch, IRawFileMatch, IRawSearch, ISearchEngine, ISearchEngineSuccess } from './search'; +import { StopWatch } from 'vs/base/common/stopwatch'; enum Traversal { Node = 1, @@ -60,13 +59,12 @@ export class FileWalker { private isLimitHit: boolean; private resultCount: number; private isCanceled: boolean; - private fileWalkStartTime: number; + private fileWalkSW: StopWatch; private directoriesWalked: number; private filesWalked: number; private traversal: Traversal; private errors: string[]; - private cmdForkStartTime: number; - private cmdForkResultTime: number; + private cmdSW: StopWatch; private cmdResultCount: number; private folderExcludePatterns: Map<string, AbsoluteAndRelativeParsedExpression>; @@ -120,7 +118,7 @@ export class FileWalker { } public walk(folderQueries: IFolderSearch[], extraFiles: string[], onResult: (result: IRawFileMatch) => void, onMessage: (message: IProgress) => void, done: (error: Error, isLimitHit: boolean) => void): void { - this.fileWalkStartTime = Date.now(); + this.fileWalkSW = StopWatch.create(); // Support that the file pattern is a full path to a file that exists if (this.isCanceled) { @@ -160,7 +158,7 @@ export class FileWalker { const isNodeTraversal = traverse === this.nodeJSTraversal; if (!isNodeTraversal) { - this.cmdForkStartTime = Date.now(); + this.cmdSW = StopWatch.create(); } // For each root folder @@ -225,6 +223,7 @@ export class FileWalker { } process.on('exit', killCmd); + this.cmdResultCount = 0; this.collectStdout(cmd, 'utf8', useRipgrep, onMessage, (err: Error, stdout?: string, last?: boolean) => { if (err) { done(err); @@ -360,7 +359,10 @@ export class FileWalker { let onData = (err: Error, stdout?: string, last?: boolean) => { if (err || last) { onData = () => { }; - this.cmdForkResultTime = Date.now(); + + if (this.cmdSW) { + this.cmdSW.stop(); + } } cb(err, stdout, last); }; @@ -508,18 +510,13 @@ export class FileWalker { }); } - public getStats(): IUncachedSearchStats { + public getStats(): ISearchEngineStats { return { - fromCache: false, + cmdTime: this.cmdSW.elapsed(), + fileWalkTime: this.fileWalkSW.elapsed(), traversal: Traversal[this.traversal], - errors: this.errors, - fileWalkStartTime: this.fileWalkStartTime, - fileWalkResultTime: Date.now(), directoriesWalked: this.directoriesWalked, filesWalked: this.filesWalked, - resultCount: this.resultCount, - cmdForkStartTime: this.cmdForkStartTime, - cmdForkResultTime: this.cmdForkResultTime, cmdResultCount: this.cmdResultCount }; } @@ -678,10 +675,9 @@ export class Engine implements ISearchEngine<IRawFileMatch> { this.walker = new FileWalker(config); } - public search(onResult: (result: IRawFileMatch) => void, onProgress: (progress: IProgress) => void, done: (error: Error, complete: ISerializedSearchSuccess) => void): void { + public search(onResult: (result: IRawFileMatch) => void, onProgress: (progress: IProgress) => void, done: (error: Error, complete: ISearchEngineSuccess) => void): void { this.walker.walk(this.folderQueries, this.extraFiles, onResult, onProgress, (err: Error, isLimitHit: boolean) => { done(err, { - type: 'success', limitHit: isLimitHit, stats: this.walker.getStats() }); diff --git a/src/vs/workbench/services/search/node/rawSearchService.ts b/src/vs/workbench/services/search/node/rawSearchService.ts index 48e8dbe3191..f2fef483afa 100644 --- a/src/vs/workbench/services/search/node/rawSearchService.ts +++ b/src/vs/workbench/services/search/node/rawSearchService.ts @@ -14,16 +14,17 @@ import { CancellationToken } from 'vs/base/common/cancellation'; import { canceled, isPromiseCanceledError } from 'vs/base/common/errors'; import { Emitter, Event } from 'vs/base/common/event'; import * as objects from 'vs/base/common/objects'; +import { StopWatch } from 'vs/base/common/stopwatch'; import * as strings from 'vs/base/common/strings'; import { TPromise } from 'vs/base/common/winjs.base'; import { compareItemsByScore, IItemAccessor, prepareQuery, ScorerCache } from 'vs/base/parts/quickopen/common/quickOpenScorer'; import { MAX_FILE_SIZE } from 'vs/platform/files/node/files'; -import { ICachedSearchStats, IProgress } from 'vs/platform/search/common/search'; +import { ICachedSearchStats, IFileSearchStats, IProgress } from 'vs/platform/search/common/search'; import { Engine as FileSearchEngine, FileWalker } from 'vs/workbench/services/search/node/fileSearch'; import { RipgrepEngine } from 'vs/workbench/services/search/node/ripgrepTextSearch'; import { Engine as TextSearchEngine } from 'vs/workbench/services/search/node/textSearch'; import { TextSearchWorkerProvider } from 'vs/workbench/services/search/node/textSearchWorkerProvider'; -import { IFileSearchProgressItem, IRawFileMatch, IRawSearch, IRawSearchService, ISearchEngine, ISerializedFileMatch, ISerializedSearchComplete, ISerializedSearchProgressItem, ISerializedSearchSuccess, ITelemetryEvent } from './search'; +import { IFileSearchProgressItem, IRawFileMatch, IRawSearch, IRawSearchService, ISearchEngine, ISearchEngineSuccess, ISerializedFileMatch, ISerializedSearchComplete, ISerializedSearchProgressItem, ISerializedSearchSuccess } from './search'; gracefulFs.gracefulify(fs); @@ -38,9 +39,6 @@ export class SearchService implements IRawSearchService { private textSearchWorkerProvider: TextSearchWorkerProvider; - private _onTelemetry = new Emitter<ITelemetryEvent>(); - readonly onTelemetry: Event<ITelemetryEvent> = this._onTelemetry.event; - public fileSearch(config: IRawSearch, batchSize = SearchService.BATCH_SIZE): Event<ISerializedSearchProgressItem | ISerializedSearchComplete> { let promise: CancelablePromise<ISerializedSearchSuccess>; @@ -138,10 +136,13 @@ export class SearchService implements IRawSearchService { } doFileSearch(EngineClass: { new(config: IRawSearch): ISearchEngine<IRawFileMatch>; }, config: IRawSearch, progressCallback: IProgressCallback, token?: CancellationToken, batchSize?: number): TPromise<ISerializedSearchSuccess> { + let resultCount = 0; const fileProgressCallback: IFileProgressCallback = progress => { if (Array.isArray(progress)) { + resultCount += progress.length; progressCallback(progress.map(m => this.rawMatchToSearchItem(m))); } else if ((<IRawFileMatch>progress).relativePath) { + resultCount++; progressCallback(this.rawMatchToSearchItem(<IRawFileMatch>progress)); } else { progressCallback(<IProgress>progress); @@ -167,7 +168,19 @@ export class SearchService implements IRawSearchService { const engine = new EngineClass(config); - return this.doSearch(engine, fileProgressCallback, batchSize, token); + return this.doSearch(engine, fileProgressCallback, batchSize, token).then(complete => { + return <ISerializedSearchSuccess>{ + limitHit: complete.limitHit, + type: 'success', + stats: { + cacheOrSearchEngineStats: complete.stats, + fromCache: false, + resultCount, + sortingTime: undefined, + workspaceFolderCount: config.folderQueries.length + } + }; + }); } private rawMatchToSearchItem(match: IRawFileMatch): ISerializedFileMatch { @@ -190,13 +203,7 @@ export class SearchService implements IRawSearchService { }; return this.doSearch(engine, innerProgressCallback, -1, token) - .then<[ISerializedSearchSuccess, IRawFileMatch[]]>(result => { - // __GDPR__TODO__ classify event - this._onTelemetry.fire({ - eventName: 'fileSearch', - data: result.stats - }); - + .then<[ISearchEngineSuccess, IRawFileMatch[]]>(result => { return [result, results]; }); }); @@ -204,30 +211,41 @@ export class SearchService implements IRawSearchService { let cache: Cache; if (config.cacheKey) { cache = this.getOrCreateCache(config.cacheKey); - cache.resultsToSearchCache[config.filePattern] = { + const cacheRow: ICacheRow = { promise: allResultsPromise, - event: emitter.event + event: emitter.event, + resolved: false }; - allResultsPromise.then(null, err => { + cache.resultsToSearchCache[config.filePattern] = cacheRow; + allResultsPromise.then(() => { + cacheRow.resolved = true; + }, err => { delete cache.resultsToSearchCache[config.filePattern]; }); + allResultsPromise = this.preventCancellation(allResultsPromise); } return toWinJsPromise<[ISerializedSearchSuccess, IRawFileMatch[]]>( allResultsPromise.then(([result, results]) => { const scorerCache: ScorerCache = cache ? cache.scorerCache : Object.create(null); - const unsortedResultTime = Date.now(); + const sortSW = (typeof config.maxResults !== 'number' || config.maxResults > 0) && StopWatch.create(); return this.sortResults(config, results, scorerCache, token) .then<[ISerializedSearchSuccess, IRawFileMatch[]]>(sortedResults => { - const sortedResultTime = Date.now(); + // sortingTime: -1 indicates a "sorted" search that was not sorted, i.e. populating the cache when quickopen is opened. + // Contrasting with findFiles which is not sorted and will have sortingTime: undefined + const sortingTime = sortSW ? sortSW.elapsed() : -1; return [{ type: 'success', - stats: objects.assign({}, result.stats, { - unsortedResultTime, - sortedResultTime - }), + stats: { + cacheOrSearchEngineStats: result.stats, + sortingTime, + fromCache: false, + type: 'searchProcess', + workspaceFolderCount: config.folderQueries.length, + resultCount: sortedResults.length + }, limitHit: result.limitHit || typeof config.maxResults === 'number' && results.length > config.maxResults } as ISerializedSearchSuccess, sortedResults]; }); @@ -249,35 +267,27 @@ export class SearchService implements IRawSearchService { return undefined; } - const cacheLookupStartTime = Date.now(); const cached = this.getResultsFromCache(cache, config.filePattern, progressCallback, token); if (cached) { return cached.then(([result, results, cacheStats]) => { - const cacheLookupResultTime = Date.now(); + const sortSW = StopWatch.create(); return this.sortResults(config, results, cache.scorerCache, token) .then<[ISerializedSearchSuccess, IRawFileMatch[]]>(sortedResults => { - const sortedResultTime = Date.now(); - - const stats: ICachedSearchStats = { + const sortingTime = sortSW.elapsed(); + const stats: IFileSearchStats = { fromCache: true, - cacheLookupStartTime: cacheLookupStartTime, - cacheFilterStartTime: cacheStats.cacheFilterStartTime, - cacheLookupResultTime: cacheLookupResultTime, - cacheEntryCount: cacheStats.cacheFilterResultCount, - resultCount: results.length + cacheOrSearchEngineStats: cacheStats, + type: 'searchProcess', + resultCount: results.length, + workspaceFolderCount: config.folderQueries.length, + sortingTime }; - if (config.sortByScore) { - stats.unsortedResultTime = cacheLookupResultTime; - stats.sortedResultTime = sortedResultTime; - } - if (!cacheStats.cacheWasResolved) { - stats.joined = result.stats; - } + return [ { type: 'success', limitHit: result.limitHit || typeof config.maxResults === 'number' && results.length > config.maxResults, - stats: stats + stats } as ISerializedSearchSuccess, sortedResults ]; @@ -308,11 +318,12 @@ export class SearchService implements IRawSearchService { } } - private getResultsFromCache(cache: Cache, searchValue: string, progressCallback: IFileProgressCallback, token?: CancellationToken): TPromise<[ISerializedSearchSuccess, IRawFileMatch[], CacheStats]> { + private getResultsFromCache(cache: Cache, searchValue: string, progressCallback: IFileProgressCallback, token?: CancellationToken): TPromise<[ISearchEngineSuccess, IRawFileMatch[], ICachedSearchStats]> { + const cacheLookupSW = StopWatch.create(); + // Find cache entries by prefix of search value const hasPathSep = searchValue.indexOf(sep) >= 0; - let cachedRow: CacheRow; - let wasResolved: boolean; + let cachedRow: ICacheRow; for (let previousSearch in cache.resultsToSearchCache) { // If we narrow down, we might be able to reuse the cached results if (strings.startsWith(searchValue, previousSearch)) { @@ -321,11 +332,10 @@ export class SearchService implements IRawSearchService { } const row = cache.resultsToSearchCache[previousSearch]; - row.promise.then(() => { wasResolved = false; }); - wasResolved = true; cachedRow = { promise: this.preventCancellation(row.promise), - event: row.event + event: row.event, + resolved: row.resolved }; break; } @@ -335,6 +345,9 @@ export class SearchService implements IRawSearchService { return null; } + const cacheLookupTime = cacheLookupSW.elapsed(); + const cacheFilterSW = StopWatch.create(); + const listener = cachedRow.event(progressCallback); if (token) { token.onCancellationRequested(() => { @@ -342,13 +355,11 @@ export class SearchService implements IRawSearchService { }); } - return toWinJsPromise(cachedRow.promise.then<[ISerializedSearchSuccess, IRawFileMatch[], CacheStats]>(([complete, cachedEntries]) => { + return toWinJsPromise(cachedRow.promise.then<[ISearchEngineSuccess, IRawFileMatch[], ICachedSearchStats]>(([complete, cachedEntries]) => { if (token && token.isCancellationRequested) { throw canceled(); } - const cacheFilterStartTime = Date.now(); - // Pattern match on results let results: IRawFileMatch[] = []; const normalizedSearchValueLowercase = strings.stripWildcards(searchValue).toLowerCase(); @@ -364,10 +375,11 @@ export class SearchService implements IRawSearchService { } return [complete, results, { - cacheWasResolved: wasResolved, - cacheFilterStartTime: cacheFilterStartTime, - cacheFilterResultCount: cachedEntries.length - }] as [ISerializedSearchSuccess, IRawFileMatch[], CacheStats]; // TS? + cacheWasResolved: cachedRow.resolved, + cacheLookupTime, + cacheFilterTime: cacheFilterSW.elapsed(), + cacheEntryCount: cachedEntries.length + }]; })); } @@ -388,14 +400,18 @@ export class SearchService implements IRawSearchService { if (error) { e(error); } else { - c(stats); + c({ + type: 'success', + limitHit: stats.limitHit, + stats: null + }); } }); }); } - private doSearch(engine: ISearchEngine<IRawFileMatch>, progressCallback: IFileProgressCallback, batchSize: number, token?: CancellationToken): TPromise<ISerializedSearchSuccess> { - return new TPromise<ISerializedSearchSuccess>((c, e) => { + private doSearch(engine: ISearchEngine<IRawFileMatch>, progressCallback: IFileProgressCallback, batchSize: number, token?: CancellationToken): TPromise<ISearchEngineSuccess> { + return new TPromise<ISearchEngineSuccess>((c, e) => { let batch: IRawFileMatch[] = []; if (token) { token.onCancellationRequested(() => engine.cancel()); @@ -415,14 +431,15 @@ export class SearchService implements IRawSearchService { } }, (progress) => { progressCallback(progress); - }, (error, stats) => { + }, (error, complete) => { if (batch.length) { progressCallback(batch); } + if (error) { e(error); } else { - c(stats); + c(complete); } }); }); @@ -452,15 +469,16 @@ export class SearchService implements IRawSearchService { } } -interface CacheRow { +interface ICacheRow { // TODO@roblou - never actually canceled - promise: CancelablePromise<[ISerializedSearchSuccess, IRawFileMatch[]]>; + promise: CancelablePromise<[ISearchEngineSuccess, IRawFileMatch[]]>; + resolved: boolean; event: Event<IFileSearchProgressItem>; } class Cache { - public resultsToSearchCache: { [searchValue: string]: CacheRow; } = Object.create(null); + public resultsToSearchCache: { [searchValue: string]: ICacheRow; } = Object.create(null); public scorerCache: ScorerCache = Object.create(null); } @@ -480,12 +498,6 @@ const FileMatchItemAccessor = new class implements IItemAccessor<IRawFileMatch> } }; -interface CacheStats { - cacheWasResolved: boolean; - cacheFilterStartTime: number; - cacheFilterResultCount: number; -} - /** * Collects items that have a size - before the cumulative size of collected items reaches START_BATCH_AFTER_COUNT, the callback is called for every * set of items collected. diff --git a/src/vs/workbench/services/search/node/search.ts b/src/vs/workbench/services/search/node/search.ts index 3bb3cc19b4d..1a9cde2f512 100644 --- a/src/vs/workbench/services/search/node/search.ts +++ b/src/vs/workbench/services/search/node/search.ts @@ -7,7 +7,7 @@ import { TPromise } from 'vs/base/common/winjs.base'; import { IExpression } from 'vs/base/common/glob'; -import { IProgress, ILineMatch, IPatternInfo, ISearchStats } from 'vs/platform/search/common/search'; +import { IProgress, ILineMatch, IPatternInfo, IFileSearchStats, ISearchEngineStats } from 'vs/platform/search/common/search'; import { ITelemetryData } from 'vs/platform/telemetry/common/telemetry'; import { Event } from 'vs/base/common/event'; @@ -45,7 +45,6 @@ export interface IRawSearchService { fileSearch(search: IRawSearch): Event<ISerializedSearchProgressItem | ISerializedSearchComplete>; textSearch(search: IRawSearch): Event<ISerializedSearchProgressItem | ISerializedSearchComplete>; clearCache(cacheKey: string): TPromise<void>; - readonly onTelemetry: Event<ITelemetryEvent>; } export interface IRawFileMatch { @@ -56,14 +55,19 @@ export interface IRawFileMatch { } export interface ISearchEngine<T> { - search: (onResult: (matches: T) => void, onProgress: (progress: IProgress) => void, done: (error: Error, complete: ISerializedSearchSuccess) => void) => void; + search: (onResult: (matches: T) => void, onProgress: (progress: IProgress) => void, done: (error: Error, complete: ISearchEngineSuccess) => void) => void; cancel: () => void; } export interface ISerializedSearchSuccess { type: 'success'; limitHit: boolean; - stats: ISearchStats; + stats: IFileSearchStats; +} + +export interface ISearchEngineSuccess { + limitHit: boolean; + stats: ISearchEngineStats; } export interface ISerializedSearchError { diff --git a/src/vs/workbench/services/search/node/searchIpc.ts b/src/vs/workbench/services/search/node/searchIpc.ts index abbedd4b875..1cc62837237 100644 --- a/src/vs/workbench/services/search/node/searchIpc.ts +++ b/src/vs/workbench/services/search/node/searchIpc.ts @@ -5,13 +5,12 @@ 'use strict'; +import { Event } from 'vs/base/common/event'; import { TPromise } from 'vs/base/common/winjs.base'; import { IChannel } from 'vs/base/parts/ipc/node/ipc'; -import { IRawSearchService, IRawSearch, ISerializedSearchComplete, ISerializedSearchProgressItem, ITelemetryEvent } from './search'; -import { Event } from 'vs/base/common/event'; +import { IRawSearch, IRawSearchService, ISerializedSearchComplete, ISerializedSearchProgressItem } from './search'; export interface ISearchChannel extends IChannel { - listen(event: 'telemetry'): Event<ITelemetryEvent>; listen(event: 'fileSearch', search: IRawSearch): Event<ISerializedSearchProgressItem | ISerializedSearchComplete>; listen(event: 'textSearch', search: IRawSearch): Event<ISerializedSearchProgressItem | ISerializedSearchComplete>; call(command: 'clearCache', cacheKey: string): TPromise<void>; @@ -24,7 +23,6 @@ export class SearchChannel implements ISearchChannel { listen<T>(event: string, arg?: any): Event<any> { switch (event) { - case 'telemetry': return this.service.onTelemetry; case 'fileSearch': return this.service.fileSearch(arg); case 'textSearch': return this.service.textSearch(arg); } @@ -41,8 +39,6 @@ export class SearchChannel implements ISearchChannel { export class SearchChannelClient implements IRawSearchService { - get onTelemetry(): Event<ITelemetryEvent> { return this.channel.listen('telemetry'); } - constructor(private channel: ISearchChannel) { } fileSearch(search: IRawSearch): Event<ISerializedSearchProgressItem | ISerializedSearchComplete> { diff --git a/src/vs/workbench/services/search/node/searchService.ts b/src/vs/workbench/services/search/node/searchService.ts index 6466f0e05f4..4e670d771a4 100644 --- a/src/vs/workbench/services/search/node/searchService.ts +++ b/src/vs/workbench/services/search/node/searchService.ts @@ -4,6 +4,7 @@ *--------------------------------------------------------------------------------------------*/ 'use strict'; +import { getPathFromAmdModule } from 'vs/base/common/amd'; import * as arrays from 'vs/base/common/arrays'; import { Event } from 'vs/base/common/event'; import { Disposable, IDisposable, toDisposable } from 'vs/base/common/lifecycle'; @@ -20,14 +21,13 @@ import { IModelService } from 'vs/editor/common/services/modelService'; import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; import { IDebugParams, IEnvironmentService } from 'vs/platform/environment/common/environment'; import { ILogService } from 'vs/platform/log/common/log'; -import { FileMatch, IFileMatch, IFolderQuery, IProgress, ISearchComplete, ISearchConfiguration, ISearchProgressItem, ISearchQuery, ISearchResultProvider, ISearchService, LineMatch, pathIncludedInQuery, QueryType, SearchProviderType } from 'vs/platform/search/common/search'; +import { FileMatch, IFileMatch, IFolderQuery, IProgress, ISearchComplete, ISearchConfiguration, ISearchProgressItem, ISearchQuery, ISearchResultProvider, ISearchService, LineMatch, pathIncludedInQuery, QueryType, SearchProviderType, ICachedSearchStats, ISearchEngineStats } from 'vs/platform/search/common/search'; import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry'; +import { IEditorService } from 'vs/workbench/services/editor/common/editorService'; import { IExtensionService } from 'vs/workbench/services/extensions/common/extensions'; import { IUntitledEditorService } from 'vs/workbench/services/untitled/common/untitledEditorService'; -import { IRawSearch, IRawSearchService, ISerializedFileMatch, ISerializedSearchComplete, ISerializedSearchProgressItem, isSerializedSearchComplete, isSerializedSearchSuccess, ITelemetryEvent } from './search'; +import { IRawSearch, IRawSearchService, ISerializedFileMatch, ISerializedSearchComplete, ISerializedSearchProgressItem, isSerializedSearchComplete, isSerializedSearchSuccess } from './search'; import { ISearchChannel, SearchChannelClient } from './searchIpc'; -import { getPathFromAmdModule } from 'vs/base/common/amd'; -import { IEditorService } from 'vs/workbench/services/editor/common/editorService'; export class SearchService extends Disposable implements ISearchService { public _serviceBrand: any; @@ -49,9 +49,6 @@ export class SearchService extends Disposable implements ISearchService { ) { super(); this.diskSearch = new DiskSearch(!environmentService.isBuilt || environmentService.verbose, /*timeout=*/undefined, environmentService.debugSearch); - this._register(this.diskSearch.onTelemetry(event => { - this.telemetryService.publicLog(event.eventName, event.data); - })); } public registerSearchResultProvider(scheme: string, type: SearchProviderType, provider: ISearchResultProvider): IDisposable { @@ -186,7 +183,7 @@ export class SearchService extends Disposable implements ISearchService { private searchWithProviders(query: ISearchQuery, onProviderProgress: (progress: ISearchProgressItem) => void) { const diskSearchQueries: IFolderQuery[] = []; - const searchPs = []; + const searchPs: TPromise<ISearchComplete>[] = []; query.folderQueries.forEach(fq => { let provider = query.type === QueryType.File ? @@ -223,7 +220,72 @@ export class SearchService extends Disposable implements ISearchService { searchPs.push(this.diskSearch.search(diskSearchQuery, onProviderProgress)); } - return TPromise.join(searchPs); + return TPromise.join(searchPs).then(completes => { + completes.forEach(complete => { + if (complete.stats) { + if (complete.stats.fromCache) { + const cacheStats: ICachedSearchStats = complete.stats.cacheOrSearchEngineStats as ICachedSearchStats; + + /* __GDPR__ + "cachedSearchComplete" : { + "resultCount" : { "classification": "SystemMetaData", "purpose": "PerformanceAndHealth", "isMeasurement": true }, + "workspaceFolderCount" : { "classification": "SystemMetaData", "purpose": "PerformanceAndHealth", "isMeasurement": true }, + "type" : { "classification": "SystemMetaData", "purpose": "PerformanceAndHealth" }, + "endToEndTime" : { "classification": "SystemMetaData", "purpose": "PerformanceAndHealth", "isMeasurement": true }, + "sortingTime" : { "classification": "SystemMetaData", "purpose": "PerformanceAndHealth", "isMeasurement": true }, + "cacheWasResolved" : { "classification": "SystemMetaData", "purpose": "PerformanceAndHealth" }, + "cacheLookupTime" : { "classification": "SystemMetaData", "purpose": "PerformanceAndHealth", "isMeasurement": true }, + "cacheFilterTime" : { "classification": "SystemMetaData", "purpose": "PerformanceAndHealth", "isMeasurement": true }, + "cacheEntryCount" : { "classification": "SystemMetaData", "purpose": "PerformanceAndHealth", "isMeasurement": true }, + } + */ + this.telemetryService.publicLog('cachedSearchComplete', { + resultCount: complete.stats.resultCount, + workspaceFolderCount: complete.stats.workspaceFolderCount, + type: complete.stats.type, + endToEndTime: complete.stats.endToEndTime, + sortingTime: complete.stats.sortingTime, + cacheWasResolved: cacheStats.cacheWasResolved, + cacheLookupTime: cacheStats.cacheLookupTime, + cacheFilterTime: cacheStats.cacheFilterTime, + cacheEntryCount: cacheStats.cacheEntryCount + }); + } else { + const searchEngineStats: ISearchEngineStats = complete.stats.cacheOrSearchEngineStats as ISearchEngineStats; + + /* __GDPR__ + "searchComplete" : { + "resultCount" : { "classification": "SystemMetaData", "purpose": "PerformanceAndHealth", "isMeasurement": true }, + "workspaceFolderCount" : { "classification": "SystemMetaData", "purpose": "PerformanceAndHealth", "isMeasurement": true }, + "type" : { "classification": "SystemMetaData", "purpose": "PerformanceAndHealth" }, + "endToEndTime" : { "classification": "SystemMetaData", "purpose": "PerformanceAndHealth", "isMeasurement": true }, + "sortingTime" : { "classification": "SystemMetaData", "purpose": "PerformanceAndHealth", "isMeasurement": true }, + "traversal" : { "classification": "SystemMetaData", "purpose": "PerformanceAndHealth" }, + "fileWalkTime" : { "classification": "SystemMetaData", "purpose": "PerformanceAndHealth", "isMeasurement": true }, + "directoriesWalked" : { "classification": "SystemMetaData", "purpose": "PerformanceAndHealth", "isMeasurement": true }, + "filesWalked" : { "classification": "SystemMetaData", "purpose": "PerformanceAndHealth", "isMeasurement": true }, + "cmdTime" : { "classification": "SystemMetaData", "purpose": "PerformanceAndHealth", "isMeasurement": true }, + "cmdResultCount" : { "classification": "SystemMetaData", "purpose": "PerformanceAndHealth", "isMeasurement": true } + } + */ + this.telemetryService.publicLog('searchComplete', { + resultCount: complete.stats.resultCount, + workspaceFolderCount: complete.stats.workspaceFolderCount, + type: complete.stats.type, + endToEndTime: complete.stats.endToEndTime, + sortingTime: complete.stats.sortingTime, + traversal: searchEngineStats.traversal, + fileWalkTime: searchEngineStats.fileWalkTime, + directoriesWalked: searchEngineStats.directoriesWalked, + filesWalked: searchEngineStats.filesWalked, + cmdTime: searchEngineStats.cmdTime, + cmdResultCount: searchEngineStats.cmdResultCount + }); + } + } + }); + return completes; + }); } private getLocalResults(query: ISearchQuery): ResourceMap<IFileMatch> { @@ -348,10 +410,6 @@ export class DiskSearch implements ISearchResultProvider { this.raw = new SearchChannelClient(channel); } - public get onTelemetry(): Event<ITelemetryEvent> { - return this.raw.onTelemetry; - } - public search(query: ISearchQuery, onProgress?: (p: ISearchProgressItem) => void): TPromise<ISearchComplete> { const folderQueries = query.folderQueries || []; return TPromise.join(folderQueries.map(q => q.folder.scheme === Schemas.file && pfs.exists(q.folder.fsPath))) diff --git a/src/vs/workbench/services/search/node/textSearch.ts b/src/vs/workbench/services/search/node/textSearch.ts index e2a14693c19..5c7cb143ea9 100644 --- a/src/vs/workbench/services/search/node/textSearch.ts +++ b/src/vs/workbench/services/search/node/textSearch.ts @@ -6,14 +6,12 @@ 'use strict'; import * as path from 'path'; - import { onUnexpectedError } from 'vs/base/common/errors'; import { IProgress } from 'vs/platform/search/common/search'; import { FileWalker } from 'vs/workbench/services/search/node/fileSearch'; - -import { ISerializedFileMatch, IRawSearch, ISearchEngine, ISerializedSearchSuccess } from './search'; -import { ISearchWorker } from './worker/searchWorkerIpc'; +import { IRawSearch, ISearchEngine, ISearchEngineSuccess, ISerializedFileMatch } from './search'; import { ITextSearchWorkerProvider } from './textSearchWorkerProvider'; +import { ISearchWorker } from './worker/searchWorkerIpc'; export class Engine implements ISearchEngine<ISerializedFileMatch[]> { @@ -60,7 +58,7 @@ export class Engine implements ISearchEngine<ISerializedFileMatch[]> { }); } - search(onResult: (match: ISerializedFileMatch[]) => void, onProgress: (progress: IProgress) => void, done: (error: Error, complete: ISerializedSearchSuccess) => void): void { + search(onResult: (match: ISerializedFileMatch[]) => void, onProgress: (progress: IProgress) => void, done: (error: Error, complete: ISearchEngineSuccess) => void): void { this.workers = this.workerProvider.getWorkers(); this.initializeWorkers(); @@ -86,7 +84,6 @@ export class Engine implements ISearchEngine<ISerializedFileMatch[]> { if (!this.isDone && this.processedBytes === this.totalBytes && this.walkerIsDone) { this.isDone = true; done(this.walkerError, { - type: 'success', limitHit: this.limitReached, stats: this.walker.getStats() }); diff --git a/src/vs/workbench/services/search/test/node/searchService.test.ts b/src/vs/workbench/services/search/test/node/searchService.test.ts index f679c79dc82..16a13400505 100644 --- a/src/vs/workbench/services/search/test/node/searchService.test.ts +++ b/src/vs/workbench/services/search/test/node/searchService.test.ts @@ -10,9 +10,9 @@ import * as path from 'path'; import { getPathFromAmdModule } from 'vs/base/common/amd'; import { CancelablePromise, createCancelablePromise } from 'vs/base/common/async'; import { Emitter, Event } from 'vs/base/common/event'; -import { IProgress, IUncachedSearchStats } from 'vs/platform/search/common/search'; +import { IProgress, ISearchEngineStats } from 'vs/platform/search/common/search'; import { SearchService as RawSearchService } from 'vs/workbench/services/search/node/rawSearchService'; -import { IFolderSearch, IRawFileMatch, IRawSearch, ISearchEngine, ISerializedFileMatch, ISerializedSearchComplete, ISerializedSearchProgressItem, ISerializedSearchSuccess } from 'vs/workbench/services/search/node/search'; +import { IFolderSearch, IRawFileMatch, IRawSearch, ISearchEngine, ISerializedFileMatch, ISerializedSearchComplete, ISerializedSearchProgressItem, ISerializedSearchSuccess, ISearchEngineSuccess } from 'vs/workbench/services/search/node/search'; import { DiskSearch } from 'vs/workbench/services/search/node/searchService'; const TEST_FOLDER_QUERIES = [ @@ -25,13 +25,10 @@ const MULTIROOT_QUERIES: IFolderSearch[] = [ { folder: path.join(TEST_FIXTURES, 'more') } ]; -const stats: IUncachedSearchStats = { - fromCache: false, - resultCount: 4, +const stats: ISearchEngineStats = { traversal: 'node', - errors: [], - fileWalkStartTime: 0, - fileWalkResultTime: 1, + fileWalkTime: 0, + cmdTime: 1, directoriesWalked: 2, filesWalked: 3 }; @@ -46,13 +43,12 @@ class TestSearchEngine implements ISearchEngine<IRawFileMatch> { TestSearchEngine.last = this; } - public search(onResult: (match: IRawFileMatch) => void, onProgress: (progress: IProgress) => void, done: (error: Error, complete: ISerializedSearchSuccess) => void): void { + public search(onResult: (match: IRawFileMatch) => void, onProgress: (progress: IProgress) => void, done: (error: Error, complete: ISearchEngineSuccess) => void): void { const self = this; (function next() { process.nextTick(() => { if (self.isCanceled) { done(null, { - type: 'success', limitHit: false, stats: stats }); @@ -61,7 +57,6 @@ class TestSearchEngine implements ISearchEngine<IRawFileMatch> { const result = self.result(); if (!result) { done(null, { - type: 'success', limitHit: false, stats: stats }); From da30e08b3939919a9e07928437d95bb4fdf7e8ee Mon Sep 17 00:00:00 2001 From: Jackson Kearl <jkearl11@gmail.com> Date: Tue, 21 Aug 2018 18:26:08 -0700 Subject: [PATCH 1076/1276] Fix issues related to setting height calcualtion (#56954) * Dont cache exclude settings, as they change frequently * Reset short line cache on window resize --- src/vs/workbench/parts/preferences/browser/settingsTree.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/vs/workbench/parts/preferences/browser/settingsTree.ts b/src/vs/workbench/parts/preferences/browser/settingsTree.ts index 4d8cf28b8db..986f941d88f 100644 --- a/src/vs/workbench/parts/preferences/browser/settingsTree.ts +++ b/src/vs/workbench/parts/preferences/browser/settingsTree.ts @@ -347,12 +347,13 @@ export class SettingsRenderer implements ITreeRenderer { if (this.lastRenderedWidth !== width) { this.rowHeightCache = new Map<string, number>(); } + this.longestSingleLineDescription = 0; this.lastRenderedWidth = width; } getHeight(tree: ITree, element: SettingsTreeElement): number { - if (this.rowHeightCache.has(element.id)) { + if (this.rowHeightCache.has(element.id) && !(element instanceof SettingsTreeSettingElement && isExcludeSetting(element.setting))) { return this.rowHeightCache.get(element.id); } From 7c8677d04a35ea6f659e2320af93768081223a00 Mon Sep 17 00:00:00 2001 From: Jackson Kearl <jkearl11@gmail.com> Date: Tue, 21 Aug 2018 18:26:29 -0700 Subject: [PATCH 1077/1276] Fix exclude controls not accounting for the description height (#56957) * Fix exclude controls not accounting for the description height * Tweak constant --- src/vs/workbench/parts/preferences/browser/settingsTree.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vs/workbench/parts/preferences/browser/settingsTree.ts b/src/vs/workbench/parts/preferences/browser/settingsTree.ts index 986f941d88f..57614ee92f5 100644 --- a/src/vs/workbench/parts/preferences/browser/settingsTree.ts +++ b/src/vs/workbench/parts/preferences/browser/settingsTree.ts @@ -388,7 +388,7 @@ export class SettingsRenderer implements ITreeRenderer { _getExcludeSettingHeight(element: SettingsTreeSettingElement): number { const displayValue = getExcludeDisplayValue(element); - return (displayValue.length + 1) * 22 + 80; + return (displayValue.length + 1) * 22 + 66 + this.measureSettingDescription(element); } private measureSettingElementHeight(tree: ITree, element: SettingsTreeSettingElement): number { From f2e49a20ace6c4440bc394a4e04e512a2e5c611a Mon Sep 17 00:00:00 2001 From: Itamar <itamar@next-insurance.com> Date: Tue, 21 Aug 2018 22:11:31 -0400 Subject: [PATCH 1078/1276] Hide the feedback form after clicking Submit a bug (#55938) --- .../parts/feedback/electron-browser/feedback.ts | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/vs/workbench/parts/feedback/electron-browser/feedback.ts b/src/vs/workbench/parts/feedback/electron-browser/feedback.ts index 2224b8c6846..47cdf3df9ec 100644 --- a/src/vs/workbench/parts/feedback/electron-browser/feedback.ts +++ b/src/vs/workbench/parts/feedback/electron-browser/feedback.ts @@ -216,6 +216,7 @@ export class FeedbackDropdown extends Dropdown { dom.EventHelper.stop(event); const actionId = 'workbench.action.openIssueReporter'; this.commandService.executeCommand(actionId).done(null, errors.onUnexpectedError); + this.hide(); /* __GDPR__ "workbenchActionExecuted" : { @@ -227,8 +228,12 @@ export class FeedbackDropdown extends Dropdown { }) .appendTo($contactUsContainer); - $('div').append($('a').attr('target', '_blank').attr('href', this.requestFeatureLink).text(nls.localize("request a missing feature", "Request a missing feature")).attr('tabindex', '0')) - .appendTo($contactUsContainer); + if (!!this.requestFeatureLink) { + $('div').append($('a').attr('target', '_blank').attr('href', this.requestFeatureLink).text(nls.localize("request a missing feature", "Request a missing feature")).attr('tabindex', '0')) + .on('click', event => { this.hide(); }) + .appendTo($contactUsContainer); + } + this.remainingCharacterCount = $('span.char-counter').text(this.getCharCountText(0)); From dd13d47e02a2d7f2b9371040a377ab773f302c10 Mon Sep 17 00:00:00 2001 From: Rob Lourens <roblourens@gmail.com> Date: Tue, 21 Aug 2018 19:52:33 -0700 Subject: [PATCH 1079/1276] #56950 - add search telemetry for EH-based search --- src/vs/platform/search/common/search.ts | 17 ++- .../api/node/extHostSearch.fileIndex.ts | 143 +++++++++++++----- src/vs/workbench/api/node/extHostSearch.ts | 54 +++++-- .../search/test/common/searchModel.test.ts | 3 +- .../services/search/node/fileSearch.ts | 5 +- .../services/search/node/rawSearchService.ts | 18 +-- .../services/search/node/searchService.ts | 22 +-- 7 files changed, 188 insertions(+), 74 deletions(-) diff --git a/src/vs/platform/search/common/search.ts b/src/vs/platform/search/common/search.ts index 81873a06f36..33b58382025 100644 --- a/src/vs/platform/search/common/search.ts +++ b/src/vs/platform/search/common/search.ts @@ -164,12 +164,10 @@ export interface ISearchComplete extends ISearchCompleteStats { export interface IFileSearchStats { fromCache: boolean; - cacheOrSearchEngineStats: ISearchEngineStats | ICachedSearchStats; + detailStats: ISearchEngineStats | ICachedSearchStats | IFileSearchProviderStats | IFileIndexProviderStats; resultCount: number; - workspaceFolderCount: number; type: 'fileIndexProver' | 'fileSearchProvider' | 'searchProcess'; - endToEndTime?: number; sortingTime?: number; } @@ -189,6 +187,19 @@ export interface ISearchEngineStats { cmdResultCount?: number; } +export interface IFileSearchProviderStats { + providerTime: number; + postProcessTime: number; +} + +export interface IFileIndexProviderStats { + providerTime: number; + providerResultCount: number; + fileWalkTime: number; + directoriesWalked: number; + filesWalked: number; +} + // ---- very simple implementation of the search model -------------------- export class FileMatch implements IFileMatch { diff --git a/src/vs/workbench/api/node/extHostSearch.fileIndex.ts b/src/vs/workbench/api/node/extHostSearch.fileIndex.ts index 90b8a578f1c..c4e2ab5fc70 100644 --- a/src/vs/workbench/api/node/extHostSearch.fileIndex.ts +++ b/src/vs/workbench/api/node/extHostSearch.fileIndex.ts @@ -10,12 +10,14 @@ import { CancellationTokenSource } from 'vs/base/common/cancellation'; import { toErrorMessage } from 'vs/base/common/errorMessage'; import * as glob from 'vs/base/common/glob'; import * as resources from 'vs/base/common/resources'; +import { StopWatch } from 'vs/base/common/stopwatch'; import * as strings from 'vs/base/common/strings'; import URI from 'vs/base/common/uri'; import { TPromise } from 'vs/base/common/winjs.base'; import { compareItemsByScore, IItemAccessor, prepareQuery, ScorerCache } from 'vs/base/parts/quickopen/common/quickOpenScorer'; -import { IFileMatch, IFolderQuery, IRawSearchQuery, ISearchCompleteStats, ISearchQuery } from 'vs/platform/search/common/search'; +import { ICachedSearchStats, IFileMatch, IFolderQuery, IRawSearchQuery, ISearchCompleteStats, ISearchQuery, IFileSearchStats, IFileIndexProviderStats } from 'vs/platform/search/common/search'; import * as vscode from 'vscode'; +import { canceled } from 'vs/base/common/errors'; export interface IInternalFileMatch { base: URI; @@ -135,10 +137,10 @@ export interface IDirectoryTree { pathToEntries: { [relativePath: string]: IDirectoryEntry[] }; } -// ??? -interface IInternalSearchComplete { +interface IInternalSearchComplete<T = IFileSearchStats> { limitHit: boolean; results: IInternalFileMatch[]; + stats: T; } export class FileIndexSearchEngine { @@ -151,6 +153,9 @@ export class FileIndexSearchEngine { private resultCount: number; private isCanceled: boolean; + private filesWalked = 0; + private dirsWalked = 0; + private activeCancellationTokens: Set<CancellationTokenSource>; private globalExcludePattern: glob.ParsedExpression; @@ -177,21 +182,22 @@ export class FileIndexSearchEngine { this.activeCancellationTokens = new Set(); } - public search(_onResult: (match: IInternalFileMatch) => void): TPromise<{ isLimitHit: boolean }> { + public search(_onResult: (match: IInternalFileMatch) => void): TPromise<{ isLimitHit: boolean, stats: IFileIndexProviderStats }> { if (this.config.folderQueries.length !== 1) { throw new Error('Searches just one folder'); } + // Searches a single folder const folderQuery = this.config.folderQueries[0]; - return new TPromise<{ isLimitHit: boolean }>((resolve, reject) => { + return new TPromise<{ isLimitHit: boolean, stats: IFileIndexProviderStats }>((resolve, reject) => { const onResult = (match: IInternalFileMatch) => { this.resultCount++; _onResult(match); }; if (this.isCanceled) { - return resolve({ isLimitHit: this.isLimitHit }); + throw canceled(); } // For each extra file @@ -210,8 +216,11 @@ export class FileIndexSearchEngine { } return this.searchInFolder(folderQuery, _onResult) - .then(() => { - resolve({ isLimitHit: this.isLimitHit }); + .then(stats => { + resolve({ + isLimitHit: this.isLimitHit, + stats + }); }, (errs: Error[]) => { const errMsg = errs .map(err => toErrorMessage(err)) @@ -222,7 +231,7 @@ export class FileIndexSearchEngine { }); } - private searchInFolder(fq: IFolderQuery<URI>, onResult: (match: IInternalFileMatch) => void): TPromise<void> { + private searchInFolder(fq: IFolderQuery<URI>, onResult: (match: IInternalFileMatch) => void): TPromise<IFileIndexProviderStats> { let cancellation = new CancellationTokenSource(); return new TPromise((resolve, reject) => { const options = this.getSearchOptionsForFolder(fq); @@ -249,12 +258,18 @@ export class FileIndexSearchEngine { this.addDirectoryEntries(tree, fq.folder, relativePath, onResult); }; + let providerSW: StopWatch; + let providerTime: number; + let fileWalkTime: number; new TPromise(resolve => process.nextTick(resolve)) .then(() => { this.activeCancellationTokens.add(cancellation); + providerSW = StopWatch.create(); return this.provider.provideFileIndex(options, cancellation.token); }) .then(results => { + providerTime = providerSW.elapsed(); + const postProcessSW = StopWatch.create(); this.activeCancellationTokens.delete(cancellation); if (this.isCanceled) { return null; @@ -263,11 +278,17 @@ export class FileIndexSearchEngine { results.forEach(onProviderResult); this.matchDirectoryTree(tree, queryTester, onResult); + fileWalkTime = postProcessSW.elapsed(); return null; }).then( () => { cancellation.dispose(); - resolve(undefined); + resolve(<IFileIndexProviderStats>{ + providerTime, + fileWalkTime, + directoriesWalked: this.dirsWalked, + filesWalked: this.filesWalked + }); }, err => { cancellation.dispose(); @@ -327,7 +348,7 @@ export class FileIndexSearchEngine { const self = this; const filePattern = this.filePattern; function matchDirectory(entries: IDirectoryEntry[]) { - // self.directoriesWalked++; + self.dirsWalked++; for (let i = 0, n = entries.length; i < n; i++) { const entry = entries[i]; const { relativePath, basename } = entry; @@ -345,7 +366,7 @@ export class FileIndexSearchEngine { if (sub) { matchDirectory(sub); } else { - // self.filesWalked++; + self.filesWalked++; if (relativePath === filePattern) { continue; // ignore file if its path matches with the file pattern because that is already matched above } @@ -427,7 +448,13 @@ export class FileIndexSearchManager { .then(complete => { this.sendAsBatches(complete.results, onBatch, FileIndexSearchManager.BATCH_SIZE); return <ISearchCompleteStats>{ - limitHit: complete.limitHit + limitHit: complete.limitHit, + stats: { + type: 'fileIndexProver', + detailStats: complete.stats, + fromCache: false, + resultCount: complete.results.length + } }; }); } @@ -452,7 +479,7 @@ export class FileIndexSearchManager { private doSortedSearch(engine: FileIndexSearchEngine, config: ISearchQuery): TPromise<IInternalSearchComplete> { let searchPromise: TPromise<void>; - let allResultsPromise = new TPromise<IInternalSearchComplete>((c, e) => { + let allResultsPromise = new TPromise<IInternalSearchComplete<IFileIndexProviderStats>>((c, e) => { searchPromise = this.doSearch(engine).then(c, e); }, () => { searchPromise.cancel(); @@ -462,8 +489,14 @@ export class FileIndexSearchManager { let cache: Cache; if (folderCacheKey) { cache = this.getOrCreateCache(folderCacheKey); - cache.resultsToSearchCache[config.filePattern] = allResultsPromise; - allResultsPromise.then(null, err => { + const cacheRow: ICacheRow = { + promise: allResultsPromise, + resolved: false + }; + cache.resultsToSearchCache[config.filePattern] = cacheRow; + allResultsPromise.then(() => { + cacheRow.resolved = true; + }, err => { delete cache.resultsToSearchCache[config.filePattern]; }); allResultsPromise = this.preventCancellation(allResultsPromise); @@ -473,12 +506,22 @@ export class FileIndexSearchManager { return new TPromise<IInternalSearchComplete>((c, e) => { chained = allResultsPromise.then(complete => { const scorerCache: ScorerCache = cache ? cache.scorerCache : Object.create(null); + const sortSW = (typeof config.maxResults !== 'number' || config.maxResults > 0) && StopWatch.create(); return this.sortResults(config, complete.results, scorerCache) .then(sortedResults => { - - c({ + // sortingTime: -1 indicates a "sorted" search that was not sorted, i.e. populating the cache when quickopen is opened. + // Contrasting with findFiles which is not sorted and will have sortingTime: undefined + const sortingTime = sortSW ? sortSW.elapsed() : -1; + c(<IInternalSearchComplete>{ limitHit: complete.limitHit || typeof config.maxResults === 'number' && complete.results.length > config.maxResults, // ?? - results: sortedResults + results: sortedResults, + stats: { + detailStats: complete.stats, + fromCache: false, + resultCount: sortedResults.length, + sortingTime, + type: 'fileIndexProver' + } }); }); }, e); @@ -507,11 +550,19 @@ export class FileIndexSearchManager { let chained: TPromise<void>; return new TPromise<IInternalSearchComplete>((c, e) => { chained = cached.then(complete => { + const sortSW = StopWatch.create(); return this.sortResults(config, complete.results, cache.scorerCache) .then(sortedResults => { - c({ + c(<IInternalSearchComplete<IFileSearchStats>>{ limitHit: complete.limitHit || typeof config.maxResults === 'number' && complete.results.length > config.maxResults, - results: sortedResults + results: sortedResults, + stats: { + fromCache: true, + detailStats: complete.stats, + type: 'fileIndexProver', + resultCount: sortedResults.length, + sortingTime: sortSW.elapsed() + } }); }); }, e); @@ -544,14 +595,16 @@ export class FileIndexSearchManager { } } - private getResultsFromCache(cache: Cache, searchValue: string): TPromise<IInternalSearchComplete> { + private getResultsFromCache(cache: Cache, searchValue: string): TPromise<IInternalSearchComplete<ICachedSearchStats>> { + const cacheLookupSW = StopWatch.create(); + if (path.isAbsolute(searchValue)) { return null; // bypass cache if user looks up an absolute path where matching goes directly on disk } // Find cache entries by prefix of search value const hasPathSep = searchValue.indexOf(path.sep) >= 0; - let cached: TPromise<IInternalSearchComplete>; + let cacheRow: ICacheRow; for (let previousSearch in cache.resultsToSearchCache) { // If we narrow down, we might be able to reuse the cached results @@ -560,18 +613,24 @@ export class FileIndexSearchManager { continue; // since a path character widens the search for potential more matches, require it in previous search too } - const c = cache.resultsToSearchCache[previousSearch]; - cached = this.preventCancellation(c); + const row = cache.resultsToSearchCache[previousSearch]; + cacheRow = { + promise: this.preventCancellation(row.promise), + resolved: row.resolved + }; break; } } - if (!cached) { + if (!cacheRow) { return null; } - return new TPromise<IInternalSearchComplete>((c, e) => { - cached.then(complete => { + const cacheLookupTime = cacheLookupSW.elapsed(); + const cacheFilterSW = StopWatch.create(); + + return new TPromise<IInternalSearchComplete<ICachedSearchStats>>((c, e) => { + cacheRow.promise.then(complete => { // Pattern match on results let results: IInternalFileMatch[] = []; const normalizedSearchValueLowercase = strings.stripWildcards(searchValue).toLowerCase(); @@ -586,24 +645,31 @@ export class FileIndexSearchManager { results.push(entry); } - c({ + c(<IInternalSearchComplete<ICachedSearchStats>>{ limitHit: complete.limitHit, - results + results, + stats: { + cacheWasResolved: cacheRow.resolved, + cacheLookupTime, + cacheFilterTime: cacheFilterSW.elapsed(), + cacheEntryCount: complete.results.length + } }); }, e); }, () => { - cached.cancel(); + cacheRow.promise.cancel(); }); } - private doSearch(engine: FileIndexSearchEngine): TPromise<IInternalSearchComplete> { + private doSearch(engine: FileIndexSearchEngine): TPromise<IInternalSearchComplete<IFileIndexProviderStats>> { const results: IInternalFileMatch[] = []; const onResult = match => results.push(match); - return new TPromise<IInternalSearchComplete>((c, e) => { + return new TPromise<IInternalSearchComplete<IFileIndexProviderStats>>((c, e) => { engine.search(onResult).then(result => { - c({ + c(<IInternalSearchComplete<IFileIndexProviderStats>>{ limitHit: result.isLimitHit, - results + results, + stats: result.stats }); }, e); }, () => { @@ -636,9 +702,14 @@ export class FileIndexSearchManager { } } +interface ICacheRow { + promise: TPromise<IInternalSearchComplete<IFileIndexProviderStats>>; + resolved: boolean; +} + class Cache { - public resultsToSearchCache: { [searchValue: string]: TPromise<IInternalSearchComplete>; } = Object.create(null); + public resultsToSearchCache: { [searchValue: string]: ICacheRow; } = Object.create(null); public scorerCache: ScorerCache = Object.create(null); } diff --git a/src/vs/workbench/api/node/extHostSearch.ts b/src/vs/workbench/api/node/extHostSearch.ts index f7124e5e951..95695f2674f 100644 --- a/src/vs/workbench/api/node/extHostSearch.ts +++ b/src/vs/workbench/api/node/extHostSearch.ts @@ -12,11 +12,13 @@ import * as resources from 'vs/base/common/resources'; import URI, { UriComponents } from 'vs/base/common/uri'; import { TPromise } from 'vs/base/common/winjs.base'; import * as extfs from 'vs/base/node/extfs'; -import { IFileMatch, IFolderQuery, IPatternInfo, IRawSearchQuery, ISearchCompleteStats, ISearchQuery } from 'vs/platform/search/common/search'; +import { IFileMatch, IFolderQuery, IPatternInfo, IRawSearchQuery, ISearchCompleteStats, ISearchQuery, IFileSearchProviderStats } from 'vs/platform/search/common/search'; import * as vscode from 'vscode'; import { ExtHostSearchShape, IMainContext, MainContext, MainThreadSearchShape } from './extHost.protocol'; import { toDisposable } from 'vs/base/common/lifecycle'; import { IInternalFileMatch, QueryGlobTester, resolvePatternsForProvider, IDirectoryTree, IDirectoryEntry, FileIndexSearchManager } from 'vs/workbench/api/node/extHostSearch.fileIndex'; +import { StopWatch } from 'vs/base/common/stopwatch'; +import { isPromiseCanceledError } from 'vs/base/common/errors'; export interface ISchemeTransformer { transformOutgoing(scheme: string): string; @@ -84,7 +86,11 @@ export class ExtHostSearch implements ExtHostSearchShape { return new TPromise((c, e) => { this._fileSearchManager.fileSearch(query, provider, batch => { this._proxy.$handleFileMatch(handle, session, batch.map(p => p.resource)); - }, cancelSource.token).then(c, e); + }, cancelSource.token).then(c, err => { + if (!isPromiseCanceledError(err)) { + e(err); + } + }); }, () => { // TODO IPC promise cancellation #53526 cancelSource.cancel(); @@ -95,6 +101,12 @@ export class ExtHostSearch implements ExtHostSearchShape { if (indexProvider) { return this._fileIndexSearchManager.fileSearch(query, indexProvider, batch => { this._proxy.$handleFileMatch(handle, session, batch.map(p => p.resource)); + }).then(null, err => { + if (!isPromiseCanceledError(err)) { + throw err; + } + + return null; }); } else { throw new Error('something went wrong'); @@ -474,8 +486,11 @@ class FileSearchEngine { // For each root folder TPromise.join(folderQueries.map(fq => { return this.searchInFolder(fq, onResult); - })).then(() => { - resolve({ limitHit: this.isLimitHit }); + })).then(stats => { + resolve({ + limitHit: this.isLimitHit, + stats: stats[0] // Only looking at single-folder workspace stats... + }); }, (errs: Error[]) => { const errMsg = errs .map(err => toErrorMessage(err)) @@ -486,7 +501,7 @@ class FileSearchEngine { }); } - private searchInFolder(fq: IFolderQuery<URI>, onResult: (match: IInternalFileMatch) => void): TPromise<void> { + private searchInFolder(fq: IFolderQuery<URI>, onResult: (match: IInternalFileMatch) => void): TPromise<IFileSearchProviderStats> { let cancellation = new CancellationTokenSource(); return new TPromise((resolve, reject) => { const options = this.getSearchOptionsForFolder(fq); @@ -495,10 +510,12 @@ class FileSearchEngine { const queryTester = new QueryGlobTester(this.config, fq); const noSiblingsClauses = !queryTester.hasSiblingExcludeClauses(); + let providerSW: StopWatch; new TPromise(_resolve => process.nextTick(_resolve)) .then(() => { this.activeCancellationTokens.add(cancellation); + providerSW = StopWatch.create(); return this.provider.provideFileSearchResults( { pattern: this.config.filePattern || '' @@ -507,8 +524,11 @@ class FileSearchEngine { cancellation.token); }) .then(results => { + const providerTime = providerSW.elapsed(); + const postProcessSW = StopWatch.create(); + if (this.isCanceled) { - return; + return null; } if (results) { @@ -533,11 +553,14 @@ class FileSearchEngine { } this.matchDirectoryTree(tree, queryTester, onResult); - return null; + return <IFileSearchProviderStats>{ + providerTime, + postProcessTime: postProcessSW.elapsed() + }; }).then( - () => { + stats => { cancellation.dispose(); - resolve(null); + resolve(stats); }, err => { cancellation.dispose(); @@ -646,6 +669,7 @@ class FileSearchEngine { interface IInternalSearchComplete { limitHit: boolean; + stats?: IFileSearchProviderStats; } class FileSearchManager { @@ -655,14 +679,22 @@ class FileSearchManager { fileSearch(config: ISearchQuery, provider: vscode.FileSearchProvider, onBatch: (matches: IFileMatch[]) => void, token: CancellationToken): TPromise<ISearchCompleteStats> { const engine = new FileSearchEngine(config, provider); + let resultCount = 0; const onInternalResult = (batch: IInternalFileMatch[]) => { + resultCount += batch.length; onBatch(batch.map(m => this.rawMatchToSearchItem(m))); }; return this.doSearch(engine, FileSearchManager.BATCH_SIZE, onInternalResult, token).then( result => { - return { - limitHit: result.limitHit + return <ISearchCompleteStats>{ + limitHit: result.limitHit, + stats: { + fromCache: false, + type: 'fileSearchProvider', + resultCount, + detailStats: result.stats + } }; }); } diff --git a/src/vs/workbench/parts/search/test/common/searchModel.test.ts b/src/vs/workbench/parts/search/test/common/searchModel.test.ts index e6570daef0d..d505add8c44 100644 --- a/src/vs/workbench/parts/search/test/common/searchModel.test.ts +++ b/src/vs/workbench/parts/search/test/common/searchModel.test.ts @@ -51,8 +51,7 @@ suite('SearchModel', () => { fromCache: false, resultCount: 1, type: 'searchProcess', - workspaceFolderCount: 1, - cacheOrSearchEngineStats: { + detailStats: { traversal: 'node', fileWalkTime: 0, cmdTime: 0, diff --git a/src/vs/workbench/services/search/node/fileSearch.ts b/src/vs/workbench/services/search/node/fileSearch.ts index b6022a2edc1..4de29bae7e6 100644 --- a/src/vs/workbench/services/search/node/fileSearch.ts +++ b/src/vs/workbench/services/search/node/fileSearch.ts @@ -118,7 +118,7 @@ export class FileWalker { } public walk(folderQueries: IFolderSearch[], extraFiles: string[], onResult: (result: IRawFileMatch) => void, onMessage: (message: IProgress) => void, done: (error: Error, isLimitHit: boolean) => void): void { - this.fileWalkSW = StopWatch.create(); + this.fileWalkSW = StopWatch.create(false); // Support that the file pattern is a full path to a file that exists if (this.isCanceled) { @@ -158,7 +158,7 @@ export class FileWalker { const isNodeTraversal = traverse === this.nodeJSTraversal; if (!isNodeTraversal) { - this.cmdSW = StopWatch.create(); + this.cmdSW = StopWatch.create(false); } // For each root folder @@ -174,6 +174,7 @@ export class FileWalker { } }); }, (errors, result) => { + this.fileWalkSW.stop(); const err = errors ? errors.filter(e => !!e)[0] : null; done(err, this.isLimitHit); }); diff --git a/src/vs/workbench/services/search/node/rawSearchService.ts b/src/vs/workbench/services/search/node/rawSearchService.ts index f2fef483afa..b0e6bafff60 100644 --- a/src/vs/workbench/services/search/node/rawSearchService.ts +++ b/src/vs/workbench/services/search/node/rawSearchService.ts @@ -173,11 +173,10 @@ export class SearchService implements IRawSearchService { limitHit: complete.limitHit, type: 'success', stats: { - cacheOrSearchEngineStats: complete.stats, + detailStats: complete.stats, fromCache: false, resultCount, - sortingTime: undefined, - workspaceFolderCount: config.folderQueries.length + sortingTime: undefined } }; }); @@ -229,7 +228,7 @@ export class SearchService implements IRawSearchService { return toWinJsPromise<[ISerializedSearchSuccess, IRawFileMatch[]]>( allResultsPromise.then(([result, results]) => { const scorerCache: ScorerCache = cache ? cache.scorerCache : Object.create(null); - const sortSW = (typeof config.maxResults !== 'number' || config.maxResults > 0) && StopWatch.create(); + const sortSW = (typeof config.maxResults !== 'number' || config.maxResults > 0) && StopWatch.create(false); return this.sortResults(config, results, scorerCache, token) .then<[ISerializedSearchSuccess, IRawFileMatch[]]>(sortedResults => { // sortingTime: -1 indicates a "sorted" search that was not sorted, i.e. populating the cache when quickopen is opened. @@ -239,7 +238,7 @@ export class SearchService implements IRawSearchService { return [{ type: 'success', stats: { - cacheOrSearchEngineStats: result.stats, + detailStats: result.stats, sortingTime, fromCache: false, type: 'searchProcess', @@ -270,16 +269,15 @@ export class SearchService implements IRawSearchService { const cached = this.getResultsFromCache(cache, config.filePattern, progressCallback, token); if (cached) { return cached.then(([result, results, cacheStats]) => { - const sortSW = StopWatch.create(); + const sortSW = StopWatch.create(false); return this.sortResults(config, results, cache.scorerCache, token) .then<[ISerializedSearchSuccess, IRawFileMatch[]]>(sortedResults => { const sortingTime = sortSW.elapsed(); const stats: IFileSearchStats = { fromCache: true, - cacheOrSearchEngineStats: cacheStats, + detailStats: cacheStats, type: 'searchProcess', resultCount: results.length, - workspaceFolderCount: config.folderQueries.length, sortingTime }; @@ -319,7 +317,7 @@ export class SearchService implements IRawSearchService { } private getResultsFromCache(cache: Cache, searchValue: string, progressCallback: IFileProgressCallback, token?: CancellationToken): TPromise<[ISearchEngineSuccess, IRawFileMatch[], ICachedSearchStats]> { - const cacheLookupSW = StopWatch.create(); + const cacheLookupSW = StopWatch.create(false); // Find cache entries by prefix of search value const hasPathSep = searchValue.indexOf(sep) >= 0; @@ -346,7 +344,7 @@ export class SearchService implements IRawSearchService { } const cacheLookupTime = cacheLookupSW.elapsed(); - const cacheFilterSW = StopWatch.create(); + const cacheFilterSW = StopWatch.create(false); const listener = cachedRow.event(progressCallback); if (token) { diff --git a/src/vs/workbench/services/search/node/searchService.ts b/src/vs/workbench/services/search/node/searchService.ts index 4e670d771a4..4d548ed6fa4 100644 --- a/src/vs/workbench/services/search/node/searchService.ts +++ b/src/vs/workbench/services/search/node/searchService.ts @@ -11,6 +11,7 @@ import { Disposable, IDisposable, toDisposable } from 'vs/base/common/lifecycle' import { ResourceMap, values } from 'vs/base/common/map'; import { Schemas } from 'vs/base/common/network'; import * as objects from 'vs/base/common/objects'; +import { StopWatch } from 'vs/base/common/stopwatch'; import * as strings from 'vs/base/common/strings'; import uri from 'vs/base/common/uri'; import { TPromise } from 'vs/base/common/winjs.base'; @@ -21,7 +22,7 @@ import { IModelService } from 'vs/editor/common/services/modelService'; import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; import { IDebugParams, IEnvironmentService } from 'vs/platform/environment/common/environment'; import { ILogService } from 'vs/platform/log/common/log'; -import { FileMatch, IFileMatch, IFolderQuery, IProgress, ISearchComplete, ISearchConfiguration, ISearchProgressItem, ISearchQuery, ISearchResultProvider, ISearchService, LineMatch, pathIncludedInQuery, QueryType, SearchProviderType, ICachedSearchStats, ISearchEngineStats } from 'vs/platform/search/common/search'; +import { FileMatch, ICachedSearchStats, IFileMatch, IFolderQuery, IProgress, ISearchComplete, ISearchConfiguration, ISearchEngineStats, ISearchProgressItem, ISearchQuery, ISearchResultProvider, ISearchService, LineMatch, pathIncludedInQuery, QueryType, SearchProviderType } from 'vs/platform/search/common/search'; import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry'; import { IEditorService } from 'vs/workbench/services/editor/common/editorService'; import { IExtensionService } from 'vs/workbench/services/extensions/common/extensions'; @@ -120,8 +121,6 @@ export class SearchService extends Disposable implements ISearchService { } }; - const startTime = Date.now(); - const schemesInQuery = query.folderQueries.map(fq => fq.folder.scheme); const providerActivations = schemesInQuery.map(scheme => this.extensionService.activateByEvent(`onSearch:${scheme}`)); @@ -148,7 +147,6 @@ export class SearchService extends Disposable implements ISearchService { }); combinedPromise = providerPromise.then(value => { - this.logService.debug(`SearchService#search: ${Date.now() - startTime}ms`); const values = [value]; const result: ISearchComplete = { @@ -182,6 +180,8 @@ export class SearchService extends Disposable implements ISearchService { } private searchWithProviders(query: ISearchQuery, onProviderProgress: (progress: ISearchProgressItem) => void) { + const e2eSW = StopWatch.create(false); + const diskSearchQueries: IFolderQuery[] = []; const searchPs: TPromise<ISearchComplete>[] = []; @@ -221,10 +221,12 @@ export class SearchService extends Disposable implements ISearchService { } return TPromise.join(searchPs).then(completes => { + const endToEndTime = e2eSW.elapsed(); + this.logService.trace(`SearchService#search: ${endToEndTime}ms`); completes.forEach(complete => { if (complete.stats) { if (complete.stats.fromCache) { - const cacheStats: ICachedSearchStats = complete.stats.cacheOrSearchEngineStats as ICachedSearchStats; + const cacheStats: ICachedSearchStats = complete.stats.detailStats as ICachedSearchStats; /* __GDPR__ "cachedSearchComplete" : { @@ -241,9 +243,9 @@ export class SearchService extends Disposable implements ISearchService { */ this.telemetryService.publicLog('cachedSearchComplete', { resultCount: complete.stats.resultCount, - workspaceFolderCount: complete.stats.workspaceFolderCount, + workspaceFolderCount: query.folderQueries.length, type: complete.stats.type, - endToEndTime: complete.stats.endToEndTime, + endToEndTime: endToEndTime, sortingTime: complete.stats.sortingTime, cacheWasResolved: cacheStats.cacheWasResolved, cacheLookupTime: cacheStats.cacheLookupTime, @@ -251,7 +253,7 @@ export class SearchService extends Disposable implements ISearchService { cacheEntryCount: cacheStats.cacheEntryCount }); } else { - const searchEngineStats: ISearchEngineStats = complete.stats.cacheOrSearchEngineStats as ISearchEngineStats; + const searchEngineStats: ISearchEngineStats = complete.stats.detailStats as ISearchEngineStats; /* __GDPR__ "searchComplete" : { @@ -270,9 +272,9 @@ export class SearchService extends Disposable implements ISearchService { */ this.telemetryService.publicLog('searchComplete', { resultCount: complete.stats.resultCount, - workspaceFolderCount: complete.stats.workspaceFolderCount, + workspaceFolderCount: query.folderQueries.length, type: complete.stats.type, - endToEndTime: complete.stats.endToEndTime, + endToEndTime: endToEndTime, sortingTime: complete.stats.sortingTime, traversal: searchEngineStats.traversal, fileWalkTime: searchEngineStats.fileWalkTime, From e0a68266321d1518bc12428b71d80524461a275b Mon Sep 17 00:00:00 2001 From: Rob Lourens <roblourens@gmail.com> Date: Tue, 21 Aug 2018 19:58:43 -0700 Subject: [PATCH 1080/1276] Fix tests --- src/vs/workbench/services/search/node/fileSearch.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vs/workbench/services/search/node/fileSearch.ts b/src/vs/workbench/services/search/node/fileSearch.ts index 4de29bae7e6..d86cbb9b37f 100644 --- a/src/vs/workbench/services/search/node/fileSearch.ts +++ b/src/vs/workbench/services/search/node/fileSearch.ts @@ -513,7 +513,7 @@ export class FileWalker { public getStats(): ISearchEngineStats { return { - cmdTime: this.cmdSW.elapsed(), + cmdTime: this.cmdSW && this.cmdSW.elapsed(), fileWalkTime: this.fileWalkSW.elapsed(), traversal: Traversal[this.traversal], directoriesWalked: this.directoriesWalked, From a493688be027a31337e313291522c2b5ac57c387 Mon Sep 17 00:00:00 2001 From: Benjamin Pasero <benjamin.pasero@gmail.com> Date: Wed, 22 Aug 2018 07:24:27 +0200 Subject: [PATCH 1081/1276] Debt: avoid promise.cancel in zip.ts (#56656) * avoid promise.cancel * use token properly --- src/vs/base/node/extfs.ts | 8 +- src/vs/base/node/zip.ts | 128 ++++++++++++---------- src/vs/base/test/node/extfs/extfs.test.ts | 20 +++- 3 files changed, 97 insertions(+), 59 deletions(-) diff --git a/src/vs/base/node/extfs.ts b/src/vs/base/node/extfs.ts index b52c4e36f0d..3b0b3866f3c 100644 --- a/src/vs/base/node/extfs.ts +++ b/src/vs/base/node/extfs.ts @@ -15,6 +15,7 @@ import * as uuid from 'vs/base/common/uuid'; import { TPromise } from 'vs/base/common/winjs.base'; import { encode, encodeStream } from 'vs/base/node/encoding'; import * as flow from 'vs/base/node/flow'; +import { CancellationToken } from 'vs/base/common/cancellation'; const loop = flow.loop; @@ -129,7 +130,7 @@ function doCopyFile(source: string, target: string, mode: number, callback: (err reader.pipe(writer); } -export function mkdirp(path: string, mode?: number): TPromise<boolean> { +export function mkdirp(path: string, mode?: number, token?: CancellationToken): TPromise<boolean> { const mkdir = () => { return nfcall(fs.mkdir, path, mode).then(null, (mkdirErr: NodeJS.ErrnoException) => { @@ -160,6 +161,11 @@ export function mkdirp(path: string, mode?: number): TPromise<boolean> { // recursively mkdir return mkdir().then(null, (err: NodeJS.ErrnoException) => { + // Respect cancellation + if (token && token.isCancellationRequested) { + return TPromise.as(false); + } + // ENOENT: a parent folder does not exist yet, continue // to create the parent folder and then try again. if (err.code === 'ENOENT') { diff --git a/src/vs/base/node/zip.ts b/src/vs/base/node/zip.ts index 4ef2b283769..70005628cbd 100644 --- a/src/vs/base/node/zip.ts +++ b/src/vs/base/node/zip.ts @@ -7,12 +7,14 @@ import * as nls from 'vs/nls'; import * as path from 'path'; import { createWriteStream, WriteStream } from 'fs'; import { Readable } from 'stream'; -import { nfcall, ninvoke, SimpleThrottler } from 'vs/base/common/async'; +import { nfcall, ninvoke, SimpleThrottler, createCancelablePromise, CancelablePromise } from 'vs/base/common/async'; import { mkdirp, rimraf } from 'vs/base/node/pfs'; import { TPromise } from 'vs/base/common/winjs.base'; import { open as _openZip, Entry, ZipFile } from 'yauzl'; import * as yazl from 'yazl'; import { ILogService } from 'vs/platform/log/common/log'; +import { CancellationToken } from 'vs/base/common/cancellation'; +import { once } from 'vs/base/common/event'; export interface IExtractOptions { overwrite?: boolean; @@ -70,7 +72,7 @@ function toExtractError(err: Error): ExtractError { return new ExtractError(type, err); } -function extractEntry(stream: Readable, fileName: string, mode: number, targetPath: string, options: IOptions): TPromise<void> { +function extractEntry(stream: Readable, fileName: string, mode: number, targetPath: string, options: IOptions, token: CancellationToken): TPromise<void> { const dirName = path.dirname(fileName); const targetDirName = path.join(targetPath, dirName); if (targetDirName.indexOf(targetPath) !== 0) { @@ -79,72 +81,86 @@ function extractEntry(stream: Readable, fileName: string, mode: number, targetPa const targetFileName = path.join(targetPath, fileName); let istream: WriteStream; - return mkdirp(targetDirName).then(() => new TPromise((c, e) => { + + once(token.onCancellationRequested)(() => { + if (istream) { + istream.close(); + } + }); + + return mkdirp(targetDirName, void 0, token).then(() => new TPromise((c, e) => { + if (token.isCancellationRequested) { + return; + } + istream = createWriteStream(targetFileName, { mode }); istream.once('close', () => c(null)); istream.once('error', e); stream.once('error', e); stream.pipe(istream); - }, () => { - if (istream) { - istream.close(); - } })); } -function extractZip(zipfile: ZipFile, targetPath: string, options: IOptions, logService: ILogService): TPromise<void> { - let isCanceled = false; - let last = TPromise.wrap<any>(null); +function extractZip(zipfile: ZipFile, targetPath: string, options: IOptions, logService: ILogService): CancelablePromise<void> { + let last = createCancelablePromise(() => Promise.resolve(null)); let extractedEntriesCount = 0; - return new TPromise((c, e) => { - const throttler = new SimpleThrottler(); + return createCancelablePromise(token => { - const readNextEntry = () => { - extractedEntriesCount++; - zipfile.readEntry(); - }; - - zipfile.once('error', e); - zipfile.once('close', () => last.then(() => { - if (isCanceled || zipfile.entryCount === extractedEntriesCount) { - c(null); - } else { - e(new ExtractError('Incomplete', new Error(nls.localize('incompleteExtract', "Incomplete. Found {0} of {1} entries", extractedEntriesCount, zipfile.entryCount)))); - } - }, e)); - zipfile.readEntry(); - zipfile.on('entry', (entry: Entry) => { - - if (isCanceled) { - return; - } - - if (!options.sourcePathRegex.test(entry.fileName)) { - readNextEntry(); - return; - } - - const fileName = entry.fileName.replace(options.sourcePathRegex, ''); - - // directory file names end with '/' - if (/\/$/.test(fileName)) { - const targetFileName = path.join(targetPath, fileName); - last = mkdirp(targetFileName).then(() => readNextEntry()); - return; - } - - const stream = ninvoke(zipfile, zipfile.openReadStream, entry); - const mode = modeFromEntry(entry); - - last = throttler.queue(() => stream.then(stream => extractEntry(stream, fileName, mode, targetPath, options).then(() => readNextEntry()))); + once(token.onCancellationRequested)(() => { + logService.debug(targetPath, 'Cancelled.'); + last.cancel(); + zipfile.close(); }); - }, () => { - logService.debug(targetPath, 'Cancelled.'); - isCanceled = true; - last.cancel(); - zipfile.close(); - }).then(null, err => TPromise.wrapError(toExtractError(err))); + + return new TPromise((c, e) => { + const throttler = new SimpleThrottler(); + + const readNextEntry = (token: CancellationToken) => { + if (token.isCancellationRequested) { + return; + } + + extractedEntriesCount++; + zipfile.readEntry(); + }; + + zipfile.once('error', e); + zipfile.once('close', () => last.then(() => { + if (token.isCancellationRequested || zipfile.entryCount === extractedEntriesCount) { + c(null); + } else { + e(new ExtractError('Incomplete', new Error(nls.localize('incompleteExtract', "Incomplete. Found {0} of {1} entries", extractedEntriesCount, zipfile.entryCount)))); + } + }, e)); + zipfile.readEntry(); + zipfile.on('entry', (entry: Entry) => { + + if (token.isCancellationRequested) { + return; + } + + if (!options.sourcePathRegex.test(entry.fileName)) { + readNextEntry(token); + return; + } + + const fileName = entry.fileName.replace(options.sourcePathRegex, ''); + + // directory file names end with '/' + if (/\/$/.test(fileName)) { + const targetFileName = path.join(targetPath, fileName); + last = createCancelablePromise(token => mkdirp(targetFileName, void 0, token).then(() => readNextEntry(token))); + return; + } + + const stream = ninvoke(zipfile, zipfile.openReadStream, entry); + const mode = modeFromEntry(entry); + + last = createCancelablePromise(token => throttler.queue(() => stream.then(stream => extractEntry(stream, fileName, mode, targetPath, options, token).then(() => readNextEntry(token))))); + }); + }); + }); } function openZip(zipFile: string, lazy: boolean = false): TPromise<ZipFile> { diff --git a/src/vs/base/test/node/extfs/extfs.test.ts b/src/vs/base/test/node/extfs/extfs.test.ts index d1740085fd0..aa45c33cc84 100644 --- a/src/vs/base/test/node/extfs/extfs.test.ts +++ b/src/vs/base/test/node/extfs/extfs.test.ts @@ -15,8 +15,7 @@ import { isLinux, isWindows } from 'vs/base/common/platform'; import * as uuid from 'vs/base/common/uuid'; import * as extfs from 'vs/base/node/extfs'; import { getPathFromAmdModule } from 'vs/base/common/amd'; - - +import { CancellationTokenSource } from 'vs/base/common/cancellation'; const ignore = () => { }; @@ -564,4 +563,21 @@ suite('Extfs', () => { extfs.del(parentDir, os.tmpdir(), done, ignore); }); }); + + test('mkdirp cancellation', (done) => { + const id = uuid.generateUuid(); + const parentDir = path.join(os.tmpdir(), 'vsctests', id); + const newDir = path.join(parentDir, 'extfs', id); + + const source = new CancellationTokenSource(); + + const mkdirpPromise = extfs.mkdirp(newDir, 493, source.token); + source.cancel(); + + return mkdirpPromise.then(res => { + assert.equal(res, false); + + extfs.del(parentDir, os.tmpdir(), done, ignore); + }); + }); }); From f938d63a285d470df9a407786d840b4d38d56503 Mon Sep 17 00:00:00 2001 From: Sandeep Somavarapu <sasomava@microsoft.com> Date: Wed, 22 Aug 2018 08:46:22 +0200 Subject: [PATCH 1082/1276] Sync only if there are other servers --- .../extensionManagement/common/multiExtensionManagement.ts | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/vs/platform/extensionManagement/common/multiExtensionManagement.ts b/src/vs/platform/extensionManagement/common/multiExtensionManagement.ts index a542a04fd48..d5e6c985b33 100644 --- a/src/vs/platform/extensionManagement/common/multiExtensionManagement.ts +++ b/src/vs/platform/extensionManagement/common/multiExtensionManagement.ts @@ -45,7 +45,10 @@ export class MulitExtensionManagementService implements IExtensionManagementServ this.onDidInstallExtension = this.servers.reduce((emitter: EventMultiplexer<DidInstallExtensionEvent>, server) => { emitter.add(server.extensionManagementService.onDidInstallExtension); return emitter; }, new EventMultiplexer<DidInstallExtensionEvent>()).event; this.onUninstallExtension = this.servers.reduce((emitter: EventMultiplexer<IExtensionIdentifier>, server) => { emitter.add(server.extensionManagementService.onUninstallExtension); return emitter; }, new EventMultiplexer<IExtensionIdentifier>()).event; this.onDidUninstallExtension = this.servers.reduce((emitter: EventMultiplexer<DidUninstallExtensionEvent>, server) => { emitter.add(server.extensionManagementService.onDidUninstallExtension); return emitter; }, new EventMultiplexer<DidUninstallExtensionEvent>()).event; - this.syncExtensions(); + + if (this.otherServers.length) { + this.syncExtensions(); + } } getInstalled(type?: LocalExtensionType): TPromise<ILocalExtension[]> { From d4f8481432a205b6d2f9874269d0b5712ef070a5 Mon Sep 17 00:00:00 2001 From: Benjamin Pasero <benjpas@microsoft.com> Date: Wed, 22 Aug 2018 09:28:47 +0200 Subject: [PATCH 1083/1276] fix #37129 --- src/vs/base/browser/ui/splitview/panelview.ts | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/src/vs/base/browser/ui/splitview/panelview.ts b/src/vs/base/browser/ui/splitview/panelview.ts index 31ad491bac6..c5143e3007b 100644 --- a/src/vs/base/browser/ui/splitview/panelview.ts +++ b/src/vs/base/browser/ui/splitview/panelview.ts @@ -11,7 +11,7 @@ import { Event, Emitter, chain } from 'vs/base/common/event'; import { domEvent } from 'vs/base/browser/event'; import { StandardKeyboardEvent } from 'vs/base/browser/keyboardEvent'; import { KeyCode } from 'vs/base/common/keyCodes'; -import { $, append, addClass, removeClass, toggleClass, trackFocus } from 'vs/base/browser/dom'; +import { $, append, addClass, removeClass, toggleClass, trackFocus, scheduleAtNextAnimationFrame } from 'vs/base/browser/dom'; import { firstIndex } from 'vs/base/common/arrays'; import { Color, RGBA } from 'vs/base/common/color'; import { SplitView, IView } from './splitview'; @@ -386,7 +386,14 @@ export class PanelView implements IDisposable { addPanel(panel: Panel, size: number, index = this.splitview.length): void { const disposables: IDisposable[] = []; - panel.onDidChange(this.setupAnimation, this, disposables); + disposables.push( + // fix https://github.com/Microsoft/vscode/issues/37129 by delaying the listener + // for changes to animate them. lots of views cause a onDidChange during their + // initial creation and this causes the view to animate even though it shows + // for the first time. animation should only be used to indicate new elements + // are added or existing ones removed in a view that is already showing + scheduleAtNextAnimationFrame(() => panel.onDidChange(this.setupAnimation, this, disposables)) + ); const panelItem = { panel, disposable: combinedDisposable(disposables) }; this.panelItems.splice(index, 0, panelItem); From 19c19e91b704cdf5f72adb20a3f7449e7f4559e1 Mon Sep 17 00:00:00 2001 From: isidor <inikolic@microsoft.com> Date: Wed, 22 Aug 2018 09:34:04 +0200 Subject: [PATCH 1084/1276] launch json faded decorations better contrast fixes #56794 --- extensions/configuration-editing/src/extension.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/extensions/configuration-editing/src/extension.ts b/extensions/configuration-editing/src/extension.ts index 68dbbf165b4..f6ec0b625e7 100644 --- a/extensions/configuration-editing/src/extension.ts +++ b/extensions/configuration-editing/src/extension.ts @@ -11,8 +11,8 @@ import { getLocation, visit, parse, ParseErrorCode } from 'jsonc-parser'; import * as path from 'path'; import { SettingsDocument } from './settingsDocumentHelper'; -const decoration = vscode.window.createTextEditorDecorationType({ - color: '#9e9e9e' +const fadedDecoration = vscode.window.createTextEditorDecorationType({ + color: '#777' }); let pendingLaunchJsonDecoration: NodeJS.Timer; @@ -241,7 +241,7 @@ function updateLaunchJsonDecorations(editor: vscode.TextEditor | undefined): voi } }); - editor.setDecorations(decoration, ranges); + editor.setDecorations(fadedDecoration, ranges); } vscode.languages.registerDocumentSymbolProvider({ pattern: '**/launch.json', language: 'jsonc' }, { From 5c2fdf815cc6a0545974affee49eabda4f795058 Mon Sep 17 00:00:00 2001 From: Johannes Rieken <johannes.rieken@gmail.com> Date: Wed, 22 Aug 2018 09:38:48 +0200 Subject: [PATCH 1085/1276] fix #56915 --- .../parts/editor/breadcrumbsControl.ts | 29 +++++++++++++++---- 1 file changed, 23 insertions(+), 6 deletions(-) diff --git a/src/vs/workbench/browser/parts/editor/breadcrumbsControl.ts b/src/vs/workbench/browser/parts/editor/breadcrumbsControl.ts index d18f6210769..c57aaa15765 100644 --- a/src/vs/workbench/browser/parts/editor/breadcrumbsControl.ts +++ b/src/vs/workbench/browser/parts/editor/breadcrumbsControl.ts @@ -21,7 +21,7 @@ import { OutlineElement, OutlineGroup, OutlineModel, TreeElement } from 'vs/edit import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; import { ContextKeyExpr, IContextKey, IContextKeyService, RawContextKey } from 'vs/platform/contextkey/common/contextkey'; import { IContextViewService } from 'vs/platform/contextview/browser/contextView'; -import { FileKind, IFileService } from 'vs/platform/files/common/files'; +import { FileKind, IFileService, IFileStat } from 'vs/platform/files/common/files'; import { IInstantiationService, ServicesAccessor } from 'vs/platform/instantiation/common/instantiation'; import { KeybindingsRegistry, KeybindingWeight } from 'vs/platform/keybinding/common/keybindingsRegistry'; import { IQuickOpenService } from 'vs/platform/quickOpen/common/quickOpen'; @@ -39,9 +39,10 @@ import { MenuRegistry, MenuId } from 'vs/platform/actions/common/actions'; import { localize } from 'vs/nls'; import { CommandsRegistry } from 'vs/platform/commands/common/commands'; import { tail } from 'vs/base/common/arrays'; -import { WorkbenchListFocusContextKey } from 'vs/platform/list/browser/listService'; +import { WorkbenchListFocusContextKey, IListService } from 'vs/platform/list/browser/listService'; import { ColorIdentifier } from 'vs/platform/theme/common/colorRegistry'; import { timeout } from 'vs/base/common/async'; +import URI from 'vs/base/common/uri'; class Item extends BreadcrumbsItem { @@ -513,10 +514,26 @@ KeybindingsRegistry.registerCommandAndKeybindingRule({ primary: KeyMod.CtrlCmd | KeyCode.Enter, 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); - widget.setSelection(widget.getFocused(), BreadcrumbsControl.Payload_RevealAside); + const editors = accessor.get(IEditorService); + const lists = accessor.get(IListService); + const element = <OutlineElement | IFileStat>lists.lastFocusedList.getFocus(); + if (element instanceof OutlineElement) { + // open symbol in editor + return editors.openEditor({ + resource: OutlineModel.get(element).textModel.uri, + options: { selection: Range.collapseToStart(element.symbol.selectionRange) } + }, SIDE_GROUP); + + } else if (URI.isUri(element.resource)) { + // open file in editor + return editors.openEditor({ + resource: element.resource, + }, SIDE_GROUP); + + } else { + // ignore + return undefined; + } } }); //#endregion From 95a1658bdda4528d0e428c6e541fc3e9b0da54fb Mon Sep 17 00:00:00 2001 From: Sandeep Somavarapu <sasomava@microsoft.com> Date: Wed, 22 Aug 2018 09:42:14 +0200 Subject: [PATCH 1086/1276] Fix #56477 --- src/vs/workbench/browser/parts/views/customView.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/vs/workbench/browser/parts/views/customView.ts b/src/vs/workbench/browser/parts/views/customView.ts index b79fd81f196..257a760877c 100644 --- a/src/vs/workbench/browser/parts/views/customView.ts +++ b/src/vs/workbench/browser/parts/views/customView.ts @@ -502,9 +502,9 @@ class TreeRenderer implements IRenderer { templateData.resourceLabel.clear(); templateData.actionBar.clear(); - if ((resource || node.themeIcon) && !icon) { + if (resource || node.themeIcon) { const fileDecorations = this.configurationService.getValue<{ colors: boolean, badges: boolean }>('explorer.decorations'); - templateData.resourceLabel.setLabel({ name: label, resource: resource ? resource : URI.parse('missing:_icon_resource') }, { fileKind: this.getFileKind(node), title, fileDecorations: fileDecorations, extraClasses: ['custom-view-tree-node-item-resourceLabel'] }); + templateData.resourceLabel.setLabel({ name: label, resource: resource ? resource : URI.parse('missing:_icon_resource') }, { fileKind: this.getFileKind(node), title, hideIcon: !!icon, fileDecorations, extraClasses: ['custom-view-tree-node-item-resourceLabel'] }); } else { templateData.resourceLabel.setLabel({ name: label }, { title, hideIcon: true, extraClasses: ['custom-view-tree-node-item-resourceLabel'] }); } From 67c9cac441d56ad49745df805c5828c7c5cfbccf Mon Sep 17 00:00:00 2001 From: Benjamin Pasero <benjpas@microsoft.com> Date: Wed, 22 Aug 2018 10:03:21 +0200 Subject: [PATCH 1087/1276] electron - move security related event handlers into one place --- src/vs/code/electron-main/app.ts | 12 +++++++++++- src/vs/code/electron-main/window.ts | 19 +------------------ 2 files changed, 12 insertions(+), 19 deletions(-) diff --git a/src/vs/code/electron-main/app.ts b/src/vs/code/electron-main/app.ts index 8f10bd2b5fb..1f1ab8d4ca7 100644 --- a/src/vs/code/electron-main/app.ts +++ b/src/vs/code/electron-main/app.ts @@ -5,7 +5,7 @@ 'use strict'; -import { app, ipcMain as ipc, systemPreferences } from 'electron'; +import { app, ipcMain as ipc, systemPreferences, shell } from 'electron'; import * as platform from 'vs/base/common/platform'; import { WindowsManager } from 'vs/code/electron-main/windows'; import { IWindowsService, OpenContext, ActiveWindowManager } from 'vs/platform/windows/common/windows'; @@ -136,6 +136,8 @@ export class CodeApplication { return srcUri.startsWith(URI.file(this.environmentService.appRoot.toLowerCase()).toString()); }; + // Security related measures (https://electronjs.org/docs/tutorial/security) + // DO NOT CHANGE without consulting the documentation app.on('web-contents-created', (event: any, contents) => { contents.on('will-attach-webview', (event: Electron.Event, webPreferences, params) => { delete webPreferences.preload; @@ -148,13 +150,21 @@ export class CodeApplication { // Otherwise prevent loading this.logService.error('webContents#web-contents-created: Prevented webview attach'); + event.preventDefault(); }); contents.on('will-navigate', event => { this.logService.error('webContents#will-navigate: Prevented webcontent navigation'); + event.preventDefault(); }); + + contents.on('new-window', (event: Event, url: string) => { + event.preventDefault(); // prevent code that wants to open links + + shell.openExternal(url); + }); }); let macOpenFileURIs: URI[] = []; diff --git a/src/vs/code/electron-main/window.ts b/src/vs/code/electron-main/window.ts index 98a4328213e..5f135d7e4e2 100644 --- a/src/vs/code/electron-main/window.ts +++ b/src/vs/code/electron-main/window.ts @@ -10,7 +10,7 @@ import * as objects from 'vs/base/common/objects'; import * as nls from 'vs/nls'; import URI from 'vs/base/common/uri'; import { IStateService } from 'vs/platform/state/common/state'; -import { shell, screen, BrowserWindow, systemPreferences, app, TouchBar, nativeImage } from 'electron'; +import { screen, BrowserWindow, systemPreferences, app, TouchBar, nativeImage } from 'electron'; import { TPromise, TValueCallback } from 'vs/base/common/winjs.base'; import { IEnvironmentService, ParsedArgs } from 'vs/platform/environment/common/environment'; import { ILogService } from 'vs/platform/log/common/log'; @@ -375,13 +375,6 @@ export class CodeWindow implements ICodeWindow { // App commands support this.registerNavigationListenerOn('app-command', 'browser-backward', 'browser-forward', false); - // Handle code that wants to open links - this._win.webContents.on('new-window', (event: Event, url: string) => { - event.preventDefault(); - - shell.openExternal(url); - }); - // Window Focus this._win.on('focus', () => { this._lastFocusTime = Date.now(); @@ -418,16 +411,6 @@ export class CodeWindow implements ICodeWindow { this.logService.warn('[electron event]: fail to load, ', errorDescription); }); - // Prevent any kind of navigation triggered by the user! - // But do not touch this in dev version because it will prevent "Reload" from dev tools - if (this.environmentService.isBuilt) { - this._win.webContents.on('will-navigate', (event: Event) => { - if (event) { - event.preventDefault(); - } - }); - } - // Handle configuration changes this.toDispose.push(this.configurationService.onDidChangeConfiguration(e => this.onConfigurationUpdated())); From fa7963564f19a135a46e38dfbea0faca416b0da4 Mon Sep 17 00:00:00 2001 From: Johannes Rieken <johannes.rieken@gmail.com> Date: Wed, 22 Aug 2018 09:48:27 +0200 Subject: [PATCH 1088/1276] prep for #55449 --- .../browser/parts/editor/breadcrumbs.ts | 28 ++++++++----------- .../parts/editor/breadcrumbsControl.ts | 10 +++---- .../browser/parts/editor/breadcrumbsModel.ts | 8 +++--- .../browser/parts/editor/titleControl.ts | 2 +- 4 files changed, 21 insertions(+), 27 deletions(-) diff --git a/src/vs/workbench/browser/parts/editor/breadcrumbs.ts b/src/vs/workbench/browser/parts/editor/breadcrumbs.ts index 934697eb698..d143e4b1d45 100644 --- a/src/vs/workbench/browser/parts/editor/breadcrumbs.ts +++ b/src/vs/workbench/browser/parts/editor/breadcrumbs.ts @@ -10,7 +10,7 @@ import { IDisposable } from 'vs/base/common/lifecycle'; import { createDecorator } from 'vs/platform/instantiation/common/instantiation'; import { GroupIdentifier } from 'vs/workbench/common/editor'; import { registerSingleton } from 'vs/platform/instantiation/common/extensions'; -import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; +import { IConfigurationService, IConfigurationOverrides } from 'vs/platform/configuration/common/configuration'; import { Emitter, Event } from 'vs/base/common/event'; import { Registry } from 'vs/platform/registry/common/platform'; import { IConfigurationRegistry, Extensions } from 'vs/platform/configuration/common/configurationRegistry'; @@ -57,10 +57,10 @@ registerSingleton(IBreadcrumbsService, BreadcrumbsService); export abstract class BreadcrumbsConfig<T> { name: string; - onDidChange: Event<T>; + onDidChange: Event<void>; - abstract value(): T; - abstract value(value: T): Thenable<void>; + abstract getValue(): T; + abstract updateValue(value: T): Thenable<void>; abstract dispose(): void; private constructor() { @@ -75,28 +75,22 @@ export abstract class BreadcrumbsConfig<T> { private static _stub<T>(name: string): { bindTo(service: IConfigurationService): BreadcrumbsConfig<T> } { return { bindTo(service) { - let value: T = service.getValue(name); - let onDidChange = new Emitter<T>(); + let onDidChange = new Emitter<void>(); let listener = service.onDidChangeConfiguration(e => { if (e.affectsConfiguration(name)) { - value = service.getValue(name); - onDidChange.fire(value); + onDidChange.fire(undefined); } }); return new class implements BreadcrumbsConfig<T>{ readonly name = name; readonly onDidChange = onDidChange.event; - value(): T; - value(value: T): Thenable<void>; - value(newValue?: T): any { - if (arguments.length === 0) { - return value; - } else { - value = newValue; - return service.updateValue(name, newValue); - } + getValue(overrides?: IConfigurationOverrides): T { + return service.getValue(name, overrides); + } + updateValue(newValue: T, overrides?: IConfigurationOverrides): Thenable<void> { + return service.updateValue(name, newValue, overrides); } dispose(): void { listener.dispose(); diff --git a/src/vs/workbench/browser/parts/editor/breadcrumbsControl.ts b/src/vs/workbench/browser/parts/editor/breadcrumbsControl.ts index c57aaa15765..3283d6ca571 100644 --- a/src/vs/workbench/browser/parts/editor/breadcrumbsControl.ts +++ b/src/vs/workbench/browser/parts/editor/breadcrumbsControl.ts @@ -270,7 +270,7 @@ export class BreadcrumbsControl { return; } - if (this._cfUseQuickPick.value()) { + if (this._cfUseQuickPick.getValue()) { // using quick pick this._widget.setFocused(undefined); this._widget.setSelection(undefined); @@ -389,8 +389,8 @@ MenuRegistry.appendMenuItem(MenuId.MenubarViewMenu, { }); CommandsRegistry.registerCommand('breadcrumbs.toggle', accessor => { let config = accessor.get(IConfigurationService); - let value = BreadcrumbsConfig.IsEnabled.bindTo(config).value(); - BreadcrumbsConfig.IsEnabled.bindTo(config).value(!value); + let value = BreadcrumbsConfig.IsEnabled.bindTo(config).getValue(); + BreadcrumbsConfig.IsEnabled.bindTo(config).updateValue(!value); }); // focus/focus-and-select @@ -400,8 +400,8 @@ async function focusAndSelectHandler(accessor: ServicesAccessor, select: boolean const config = accessor.get(IConfigurationService); // check if enabled and iff not enable const isEnabled = BreadcrumbsConfig.IsEnabled.bindTo(config); - if (!isEnabled.value()) { - await isEnabled.value(true); + if (!isEnabled.getValue()) { + await isEnabled.updateValue(true); await timeout(50); // hacky - the widget might not be ready yet... } // find widget and focus/select diff --git a/src/vs/workbench/browser/parts/editor/breadcrumbsModel.ts b/src/vs/workbench/browser/parts/editor/breadcrumbsModel.ts index 07fd156d36c..ba716837a6f 100644 --- a/src/vs/workbench/browser/parts/editor/breadcrumbsModel.ts +++ b/src/vs/workbench/browser/parts/editor/breadcrumbsModel.ts @@ -81,16 +81,16 @@ export class EditorBreadcrumbsModel { let result: BreadcrumbElement[] = []; // file path elements - if (this._cfgFilePath.value() === 'on') { + if (this._cfgFilePath.getValue() === 'on') { result = result.concat(this._fileInfo.path); - } else if (this._cfgFilePath.value() === 'last' && this._fileInfo.path.length > 0) { + } else if (this._cfgFilePath.getValue() === 'last' && this._fileInfo.path.length > 0) { result = result.concat(this._fileInfo.path.slice(-1)); } // symbol path elements - if (this._cfgSymbolPath.value() === 'on') { + if (this._cfgSymbolPath.getValue() === 'on') { result = result.concat(this._outlineElements); - } else if (this._cfgSymbolPath.value() === 'last' && this._outlineElements.length > 0) { + } else if (this._cfgSymbolPath.getValue() === 'last' && this._outlineElements.length > 0) { result = result.concat(this._outlineElements.slice(-1)); } diff --git a/src/vs/workbench/browser/parts/editor/titleControl.ts b/src/vs/workbench/browser/parts/editor/titleControl.ts index def12980c11..33838407bc5 100644 --- a/src/vs/workbench/browser/parts/editor/titleControl.ts +++ b/src/vs/workbench/browser/parts/editor/titleControl.ts @@ -108,7 +108,7 @@ export abstract class TitleControl extends Themable { this.handleBreadcrumbsEnablementChange(); } })); - if (config.value()) { + if (config.getValue()) { this.breadcrumbsControl = this.instantiationService.createInstance(BreadcrumbsControl, container, options, this.group); } } From 7bc7034b655cf41ee7f86c17b22f11e4031f4f7b Mon Sep 17 00:00:00 2001 From: Johannes Rieken <johannes.rieken@gmail.com> Date: Wed, 22 Aug 2018 10:18:44 +0200 Subject: [PATCH 1089/1276] add filtering for breadcrumbs picker, #55449 --- .../browser/parts/editor/breadcrumbs.ts | 7 ++- .../browser/parts/editor/breadcrumbsPicker.ts | 57 ++++++++++++++++++- 2 files changed, 60 insertions(+), 4 deletions(-) diff --git a/src/vs/workbench/browser/parts/editor/breadcrumbs.ts b/src/vs/workbench/browser/parts/editor/breadcrumbs.ts index d143e4b1d45..940ddfdc570 100644 --- a/src/vs/workbench/browser/parts/editor/breadcrumbs.ts +++ b/src/vs/workbench/browser/parts/editor/breadcrumbs.ts @@ -15,6 +15,7 @@ import { Emitter, Event } from 'vs/base/common/event'; import { Registry } from 'vs/platform/registry/common/platform'; import { IConfigurationRegistry, Extensions } from 'vs/platform/configuration/common/configurationRegistry'; import { localize } from 'vs/nls'; +import * as glob from 'vs/base/common/glob'; export const IBreadcrumbsService = createDecorator<IBreadcrumbsService>('IEditorBreadcrumbsService'); @@ -59,8 +60,8 @@ export abstract class BreadcrumbsConfig<T> { name: string; onDidChange: Event<void>; - abstract getValue(): T; - abstract updateValue(value: T): Thenable<void>; + abstract getValue(overrides?: IConfigurationOverrides): T; + abstract updateValue(value: T, overrides?: IConfigurationOverrides): Thenable<void>; abstract dispose(): void; private constructor() { @@ -72,6 +73,8 @@ export abstract class BreadcrumbsConfig<T> { static FilePath = BreadcrumbsConfig._stub<'on' | 'off' | 'last'>('breadcrumbs.filePath'); static SymbolPath = BreadcrumbsConfig._stub<'on' | 'off' | 'last'>('breadcrumbs.symbolPath'); + static FileExcludes = BreadcrumbsConfig._stub<glob.IExpression>('files.exclude'); + private static _stub<T>(name: string): { bindTo(service: IConfigurationService): BreadcrumbsConfig<T> } { return { bindTo(service) { diff --git a/src/vs/workbench/browser/parts/editor/breadcrumbsPicker.ts b/src/vs/workbench/browser/parts/editor/breadcrumbsPicker.ts index fa061381046..0efbd1a0909 100644 --- a/src/vs/workbench/browser/parts/editor/breadcrumbsPicker.ts +++ b/src/vs/workbench/browser/parts/editor/breadcrumbsPicker.ts @@ -9,10 +9,10 @@ import * as dom from 'vs/base/browser/dom'; import { compareFileNames } from 'vs/base/common/comparers'; import { Emitter, Event } from 'vs/base/common/event'; import { dispose, IDisposable } from 'vs/base/common/lifecycle'; -import { dirname, isEqual } from 'vs/base/common/resources'; +import { dirname, isEqual, basename } from 'vs/base/common/resources'; import URI from 'vs/base/common/uri'; import { TPromise } from 'vs/base/common/winjs.base'; -import { IDataSource, IRenderer, ISelectionEvent, ISorter, ITree } from 'vs/base/parts/tree/browser/tree'; +import { IDataSource, IRenderer, ISelectionEvent, ISorter, ITree, IFilter } from 'vs/base/parts/tree/browser/tree'; import 'vs/css!./media/breadcrumbscontrol'; import { OutlineElement, OutlineModel, TreeElement } from 'vs/editor/contrib/documentSymbols/outlineModel'; import { OutlineDataSource, OutlineItemComparator, OutlineRenderer } from 'vs/editor/contrib/documentSymbols/outlineTree'; @@ -28,6 +28,9 @@ import { breadcrumbsPickerBackground, widgetShadow } from 'vs/platform/theme/com import { FuzzyScore, createMatches, fuzzyScore } from 'vs/base/common/filters'; import { IWorkspaceContextService, IWorkspace, IWorkspaceFolder } from 'vs/platform/workspace/common/workspace'; import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; +import { BreadcrumbsConfig } from 'vs/workbench/browser/parts/editor/breadcrumbs'; +import * as glob from 'vs/base/common/glob'; +import { } from 'vs/base/common/paths'; export function createBreadcrumbsPicker(instantiationService: IInstantiationService, parent: HTMLElement, element: BreadcrumbElement): BreadcrumbsPicker { let ctor: IConstructorSignature1<HTMLElement, BreadcrumbsPicker> = element instanceof FileElement ? BreadcrumbsFilePicker : BreadcrumbsOutlinePicker; @@ -203,6 +206,52 @@ export class FileDataSource implements IDataSource { } } +export class FileFilter implements IFilter { + + private readonly _cachedExpressions = new Map<string, glob.ParsedExpression>(); + private readonly _disposables: IDisposable[] = []; + + constructor( + @IWorkspaceContextService private readonly _workspaceService: IWorkspaceContextService, + @IConfigurationService configService: IConfigurationService, + ) { + const config = BreadcrumbsConfig.FileExcludes.bindTo(configService); + const update = () => { + _workspaceService.getWorkspace().folders.forEach(folder => { + const excludesConfig = config.getValue({ resource: folder.uri }); + if (excludesConfig) { + this._cachedExpressions.set(folder.uri.toString(), glob.parse(excludesConfig)); + } + }); + }; + update(); + this._disposables.push( + config, + config.onDidChange(update), + _workspaceService.onDidChangeWorkspaceFolders(update) + ); + } + + dispose(): void { + dispose(this._disposables); + } + + isVisible(tree: ITree, element: IWorkspaceFolder | IFileStat): boolean { + if (IWorkspaceFolder.isIWorkspaceFolder(element)) { + // not a file + return true; + } + const folder = this._workspaceService.getWorkspaceFolder(element.resource); + if (!folder || !this._cachedExpressions.has(folder.uri.toString())) { + // no folder or no filer + return true; + } + + const expression = this._cachedExpressions.get(folder.uri.toString()); + return !expression(element.resource.path.substr(folder.uri.path.length), basename(element.resource)); + } +} + export class FileRenderer implements IRenderer, IHighlightingRenderer { private readonly _scores = new Map<string, FuzzyScore>(); @@ -317,9 +366,13 @@ export class BreadcrumbsFilePicker extends BreadcrumbsPicker { protected _completeTreeConfiguration(config: IHighlightingTreeConfiguration): IHighlightingTreeConfiguration { // todo@joh reuse explorer implementations? + const filter = this._instantiationService.createInstance(FileFilter); + this._disposables.push(filter); + config.dataSource = this._instantiationService.createInstance(FileDataSource); config.renderer = this._instantiationService.createInstance(FileRenderer); config.sorter = new FileSorter(); + config.filter = filter; return config; } From df2ecbfd07eefbca42e9e0bad53a6f1782e7b36e Mon Sep 17 00:00:00 2001 From: Sandeep Somavarapu <sasomava@microsoft.com> Date: Wed, 22 Aug 2018 10:20:09 +0200 Subject: [PATCH 1090/1276] Show the custom views contributed to custom view container by the same extension on the top --- .../api/browser/viewsContainersExtensionPoint.ts | 8 ++++---- src/vs/workbench/api/browser/viewsExtensionPoint.ts | 5 +++-- src/vs/workbench/common/views.ts | 8 ++++---- 3 files changed, 11 insertions(+), 10 deletions(-) diff --git a/src/vs/workbench/api/browser/viewsContainersExtensionPoint.ts b/src/vs/workbench/api/browser/viewsContainersExtensionPoint.ts index 56c7e90b3f2..fc67667e524 100644 --- a/src/vs/workbench/api/browser/viewsContainersExtensionPoint.ts +++ b/src/vs/workbench/api/browser/viewsContainersExtensionPoint.ts @@ -90,7 +90,7 @@ class ViewsContainersExtensionHandler implements IWorkbenchContribution { const cssClass = `extensionViewlet-test`; const icon = URI.parse(require.toUrl('./media/test.svg')); - this.registerCustomViewlet({ id: TEST_VIEW_CONTAINER_ID, title, icon }, TEST_VIEW_CONTAINER_ORDER, cssClass); + this.registerCustomViewlet({ id: TEST_VIEW_CONTAINER_ID, title, icon }, TEST_VIEW_CONTAINER_ORDER, cssClass, void 0); } private handleAndRegisterCustomViewContainers() { @@ -143,18 +143,18 @@ class ViewsContainersExtensionHandler implements IWorkbenchContribution { containers.forEach((descriptor, index) => { const cssClass = `extensionViewlet-${descriptor.id}`; const icon = resources.joinPath(extension.extensionLocation, descriptor.icon); - this.registerCustomViewlet({ id: `workbench.view.extension.${descriptor.id}`, title: descriptor.title, icon }, TEST_VIEW_CONTAINER_ORDER + index + 1, cssClass); + this.registerCustomViewlet({ id: `workbench.view.extension.${descriptor.id}`, title: descriptor.title, icon }, TEST_VIEW_CONTAINER_ORDER + index + 1, cssClass, extension.id); }); } - private registerCustomViewlet(descriptor: IUserFriendlyViewsContainerDescriptor2, order: number, cssClass: string): void { + private registerCustomViewlet(descriptor: IUserFriendlyViewsContainerDescriptor2, order: number, cssClass: string, extensionId: string): void { const viewContainersRegistry = Registry.as<IViewContainersRegistry>(ViewContainerExtensions.ViewContainersRegistry); const viewletRegistry = Registry.as<ViewletRegistry>(ViewletExtensions.Viewlets); const id = descriptor.id; if (!viewletRegistry.getViewlet(id)) { - viewContainersRegistry.registerViewContainer(id); + viewContainersRegistry.registerViewContainer(id, extensionId); // Register as viewlet class CustomViewlet extends ViewContainerViewlet { diff --git a/src/vs/workbench/api/browser/viewsExtensionPoint.ts b/src/vs/workbench/api/browser/viewsExtensionPoint.ts index ddb907b9065..edc30f694e0 100644 --- a/src/vs/workbench/api/browser/viewsExtensionPoint.ts +++ b/src/vs/workbench/api/browser/viewsExtensionPoint.ts @@ -113,7 +113,7 @@ class ViewsContainersExtensionHandler implements IWorkbenchContribution { } const registeredViews = ViewsRegistry.getViews(container); const viewIds = []; - const viewDescriptors = coalesce(entry.value.map(item => { + const viewDescriptors = coalesce(entry.value.map((item, index) => { // validate if (viewIds.indexOf(item.id) !== -1) { collector.error(localize('duplicateView1', "Cannot register multiple views with same id `{0}` in the view container `{1}`", item.id, container.id)); @@ -132,7 +132,8 @@ class ViewsContainersExtensionHandler implements IWorkbenchContribution { when: ContextKeyExpr.deserialize(item.when), canToggleVisibility: true, collapsed: this.showCollapsed(container), - treeViewer: this.instantiationService.createInstance(CustomTreeViewer, item.id, container) + treeViewer: this.instantiationService.createInstance(CustomTreeViewer, item.id, container), + order: extension.description.id === container.extensionId ? index + 1 : void 0 }; viewIds.push(viewDescriptor.id); diff --git a/src/vs/workbench/common/views.ts b/src/vs/workbench/common/views.ts index b1049fab080..b0723b21310 100644 --- a/src/vs/workbench/common/views.ts +++ b/src/vs/workbench/common/views.ts @@ -42,7 +42,7 @@ export interface IViewContainersRegistry { * * @returns the registered ViewContainer. */ - registerViewContainer(id: string): ViewContainer; + registerViewContainer(id: string, extensionId?: string): ViewContainer; /** * Returns the view container with given id. @@ -54,7 +54,7 @@ export interface IViewContainersRegistry { } export class ViewContainer { - protected constructor(readonly id: string) { } + protected constructor(readonly id: string, readonly extensionId: string) { } } class ViewContainersRegistryImpl implements IViewContainersRegistry { @@ -68,11 +68,11 @@ class ViewContainersRegistryImpl implements IViewContainersRegistry { return values(this.viewContainers); } - registerViewContainer(id: string): ViewContainer { + registerViewContainer(id: string, extensionId: string): ViewContainer { if (!this.viewContainers.has(id)) { const viewContainer = new class extends ViewContainer { constructor() { - super(id); + super(id, extensionId); } }; this.viewContainers.set(id, viewContainer); From 16c4adcb2a1c4c5371317f70618cc14889178d48 Mon Sep 17 00:00:00 2001 From: isidor <inikolic@microsoft.com> Date: Wed, 22 Aug 2018 10:25:23 +0200 Subject: [PATCH 1091/1276] debug quick open use fuzzy matching fixes #56931 --- src/vs/workbench/parts/debug/browser/debugQuickOpen.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/vs/workbench/parts/debug/browser/debugQuickOpen.ts b/src/vs/workbench/parts/debug/browser/debugQuickOpen.ts index 66905ae107a..86b46a38be1 100644 --- a/src/vs/workbench/parts/debug/browser/debugQuickOpen.ts +++ b/src/vs/workbench/parts/debug/browser/debugQuickOpen.ts @@ -98,7 +98,7 @@ export class DebugQuickOpenHandler extends Quickopen.QuickOpenHandler { const configManager = this.debugService.getConfigurationManager(); const launches = configManager.getLaunches(); for (let launch of launches) { - launch.getConfigurationNames().map(config => ({ config: config, highlights: Filters.matchesContiguousSubString(input, config) })) + launch.getConfigurationNames().map(config => ({ config: config, highlights: Filters.matchesFuzzy(input, config, true) })) .filter(({ highlights }) => !!highlights) .forEach(({ config, highlights }) => { if (launch === configManager.selectedConfiguration.launch && config === configManager.selectedConfiguration.name) { @@ -110,7 +110,7 @@ export class DebugQuickOpenHandler extends Quickopen.QuickOpenHandler { launches.filter(l => !l.hidden).forEach((l, index) => { const label = this.contextService.getWorkbenchState() === WorkbenchState.WORKSPACE ? nls.localize("addConfigTo", "Add Config ({0})...", l.name) : nls.localize('addConfiguration', "Add Configuration..."); - const entry = new AddConfigEntry(label, l, this.commandService, this.contextService, Filters.matchesContiguousSubString(input, label)); + const entry = new AddConfigEntry(label, l, this.commandService, this.contextService, Filters.matchesFuzzy(input, label, true)); if (index === 0) { configurations.push(new Model.QuickOpenEntryGroup(entry, undefined, true)); } else { From 0bae86799fb6760242850efd4c6070f45bb6aed8 Mon Sep 17 00:00:00 2001 From: Johannes Rieken <johannes.rieken@gmail.com> Date: Wed, 22 Aug 2018 10:37:32 +0200 Subject: [PATCH 1092/1276] only reuse existing colors, #56864 --- src/vs/platform/theme/common/colorRegistry.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/vs/platform/theme/common/colorRegistry.ts b/src/vs/platform/theme/common/colorRegistry.ts index 674f67411d4..3aeda392f74 100644 --- a/src/vs/platform/theme/common/colorRegistry.ts +++ b/src/vs/platform/theme/common/colorRegistry.ts @@ -292,10 +292,10 @@ export const diffBorder = registerColor('diffEditor.border', { dark: null, light /** * Breadcrumb colors */ -export const breadcrumbsForeground = registerColor('breadcrumb.foreground', { light: Color.fromHex('#6C6C6C').transparent(.7), dark: Color.fromHex('#CCCCCC').transparent(.7), hc: Color.white.transparent(.7) }, nls.localize('breadcrumbsFocusForeground', "Color of focused breadcrumb items.")); +export const breadcrumbsForeground = registerColor('breadcrumb.foreground', { light: transparent(foreground, .8), dark: transparent(foreground, .8), hc: transparent(foreground, .8) }, nls.localize('breadcrumbsFocusForeground', "Color of focused breadcrumb items.")); export const breadcrumbsBackground = registerColor('breadcrumb.background', { light: editorBackground, dark: editorBackground, hc: editorBackground }, nls.localize('breadcrumbsBackground', "Background color of breadcrumb items.")); -export const breadcrumbsFocusForeground = registerColor('breadcrumb.focusForeground', { light: '#6C6C6C', dark: '#CCCCCC', hc: Color.white }, nls.localize('breadcrumbsFocusForeground', "Color of focused breadcrumb items.")); -export const breadcrumbsActiveSelectionForeground = registerColor('breadcrumb.activeSelectionForeground', { light: '#6C6C6C', dark: '#CCCCCC', hc: Color.white }, nls.localize('breadcrumbsSelectedForegound', "Color of selected breadcrumb items.")); +export const breadcrumbsFocusForeground = registerColor('breadcrumb.focusForeground', { light: darken(foreground, .2), dark: lighten(foreground, .1), hc: lighten(foreground, .1) }, nls.localize('breadcrumbsFocusForeground', "Color of focused breadcrumb items.")); +export const breadcrumbsActiveSelectionForeground = registerColor('breadcrumb.activeSelectionForeground', { light: darken(foreground, .2), dark: lighten(foreground, .1), hc: lighten(foreground, .1) }, nls.localize('breadcrumbsSelectedForegound', "Color of selected breadcrumb items.")); export const breadcrumbsPickerBackground = registerColor('breadcrumbPicker.background', { light: editorWidgetBackground, dark: editorWidgetBackground, hc: editorWidgetBackground }, nls.localize('breadcrumbsSelectedBackground', "Background color of breadcrumb item picker.")); /** From 6607a81c12f4da1ef349023e67426d76fffbbf09 Mon Sep 17 00:00:00 2001 From: Benjamin Pasero <benjpas@microsoft.com> Date: Wed, 22 Aug 2018 10:42:36 +0200 Subject: [PATCH 1093/1276] debt - do not use deprecated Buffer() ctor --- build/gulpfile.editor.js | 2 +- src/vs/base/node/zip.ts | 2 +- src/vs/base/parts/ipc/node/ipc.ts | 4 ++-- src/vs/base/parts/ipc/test/node/ipc.net.test.ts | 2 +- src/vs/workbench/common/extensionHostProtocol.ts | 2 +- src/vs/workbench/services/extensions/node/rpcProtocol.ts | 2 +- test/smoke/src/main.ts | 2 +- 7 files changed, 8 insertions(+), 8 deletions(-) diff --git a/build/gulpfile.editor.js b/build/gulpfile.editor.js index 52d1f0fcf32..0c7a37b1f76 100644 --- a/build/gulpfile.editor.js +++ b/build/gulpfile.editor.js @@ -202,7 +202,7 @@ gulp.task('editor-distro', ['clean-editor-distro', 'compile-editor-esm', 'minify this.emit('data', new File({ path: data.path.replace(/monaco\.d\.ts/, 'editor.api.d.ts'), base: data.base, - contents: new Buffer(toExternalDTS(data.contents.toString())) + contents: Buffer.from(toExternalDTS(data.contents.toString())) })); })) .pipe(gulp.dest('out-monaco-editor-core/esm/vs/editor')), diff --git a/src/vs/base/node/zip.ts b/src/vs/base/node/zip.ts index 70005628cbd..9348104b49a 100644 --- a/src/vs/base/node/zip.ts +++ b/src/vs/base/node/zip.ts @@ -177,7 +177,7 @@ export interface IFile { export function zip(zipPath: string, files: IFile[]): TPromise<string> { return new TPromise<string>((c, e) => { const zip = new yazl.ZipFile(); - files.forEach(f => f.contents ? zip.addBuffer(typeof f.contents === 'string' ? new Buffer(f.contents, 'utf8') : f.contents, f.path) : zip.addFile(f.localPath, f.path)); + files.forEach(f => f.contents ? zip.addBuffer(typeof f.contents === 'string' ? Buffer.from(f.contents, 'utf8') : f.contents, f.path) : zip.addFile(f.localPath, f.path)); zip.end(); const zipStream = createWriteStream(zipPath); diff --git a/src/vs/base/parts/ipc/node/ipc.ts b/src/vs/base/parts/ipc/node/ipc.ts index 8a87e9434d7..0c17d1414c5 100644 --- a/src/vs/base/parts/ipc/node/ipc.ts +++ b/src/vs/base/parts/ipc/node/ipc.ts @@ -111,7 +111,7 @@ enum BodyType { Object } -const empty = new Buffer(0); +const empty = Buffer.allocUnsafe(0); function serializeBody(body: any): { buffer: Buffer, type: BodyType } { if (typeof body === 'undefined') { @@ -126,7 +126,7 @@ function serializeBody(body: any): { buffer: Buffer, type: BodyType } { } function serialize(header: any, body: any = undefined): Buffer { - const headerSizeBuffer = new Buffer(4); + const headerSizeBuffer = Buffer.allocUnsafe(4); const { buffer: bodyBuffer, type: bodyType } = serializeBody(body); const headerBuffer = Buffer.from(JSON.stringify([header, bodyType])); headerSizeBuffer.writeUInt32BE(headerBuffer.byteLength, 0); diff --git a/src/vs/base/parts/ipc/test/node/ipc.net.test.ts b/src/vs/base/parts/ipc/test/node/ipc.net.test.ts index 4d65c7e1091..8647efd5b5b 100644 --- a/src/vs/base/parts/ipc/test/node/ipc.net.test.ts +++ b/src/vs/base/parts/ipc/test/node/ipc.net.test.ts @@ -60,7 +60,7 @@ suite('IPC, Socket Protocol', () => { assert.equal(data.readInt8(0), 123); resolve(null); }); - const buffer = new Buffer(1); + const buffer = Buffer.allocUnsafe(1); buffer.writeInt8(123, 0); a.send(buffer); }); diff --git a/src/vs/workbench/common/extensionHostProtocol.ts b/src/vs/workbench/common/extensionHostProtocol.ts index d42efb9a53a..cd40f3f0ec5 100644 --- a/src/vs/workbench/common/extensionHostProtocol.ts +++ b/src/vs/workbench/common/extensionHostProtocol.ts @@ -12,7 +12,7 @@ export enum MessageType { } export function createMessageOfType(type: MessageType): Buffer { - const result = new Buffer(1); + const result = Buffer.allocUnsafe(1); switch (type) { case MessageType.Initialized: result.writeUInt8(1, 0); break; diff --git a/src/vs/workbench/services/extensions/node/rpcProtocol.ts b/src/vs/workbench/services/extensions/node/rpcProtocol.ts index 024e9551d87..a2b4a81e145 100644 --- a/src/vs/workbench/services/extensions/node/rpcProtocol.ts +++ b/src/vs/workbench/services/extensions/node/rpcProtocol.ts @@ -311,7 +311,7 @@ class RPCMultiplexer { private _sendAccumulated(): void { const size = this._messagesToSend.reduce((r, b) => r + 4 + b.byteLength, 0); - const buffer = new Buffer(size); + const buffer = Buffer.allocUnsafe(size); let i = 0; for (const msg of this._messagesToSend) { diff --git a/test/smoke/src/main.ts b/test/smoke/src/main.ts index 6ca50fe319c..dd17406a724 100644 --- a/test/smoke/src/main.ts +++ b/test/smoke/src/main.ts @@ -273,7 +273,7 @@ describe('Test', () => { const app = this.app as Application; const raw = await app.capturePage(); - const buffer = new Buffer(raw, 'base64'); + const buffer = Buffer.from(raw, 'base64'); const name = this.currentTest.fullTitle().replace(/[^a-z0-9\-]/ig, '_'); const screenshotPath = path.join(screenshotsPath, `${name}.png`); From 0310dc908ddf165b57ff1c4a18991aa6acc74fab Mon Sep 17 00:00:00 2001 From: isidor <inikolic@microsoft.com> Date: Wed, 22 Aug 2018 10:54:44 +0200 Subject: [PATCH 1094/1276] explorer model: compare authority in a case insensitive way --- src/vs/workbench/parts/files/common/explorerModel.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/vs/workbench/parts/files/common/explorerModel.ts b/src/vs/workbench/parts/files/common/explorerModel.ts index b299ed27968..6b66d23af4f 100644 --- a/src/vs/workbench/parts/files/common/explorerModel.ts +++ b/src/vs/workbench/parts/files/common/explorerModel.ts @@ -15,7 +15,7 @@ import { IWorkspaceContextService } from 'vs/platform/workspace/common/workspace import { toResource, IEditorIdentifier, IEditorInput } from 'vs/workbench/common/editor'; import { IDisposable, dispose } from 'vs/base/common/lifecycle'; import { Schemas } from 'vs/base/common/network'; -import { rtrim, startsWithIgnoreCase, startsWith } from 'vs/base/common/strings'; +import { rtrim, startsWithIgnoreCase, startsWith, equalsIgnoreCase } from 'vs/base/common/strings'; import { IEditorGroup } from 'vs/workbench/services/group/common/editorGroupsService'; export class Model { @@ -343,7 +343,7 @@ export class ExplorerItem { public find(resource: URI): ExplorerItem { // Return if path found // For performance reasons try to do the comparison as fast as possible - if (resource && this.resource.scheme === resource.scheme && this.resource.authority === resource.authority && + if (resource && this.resource.scheme === resource.scheme && equalsIgnoreCase(this.resource.authority, resource.authority) && (resources.hasToIgnoreCase(resource) ? startsWithIgnoreCase(resource.path, this.resource.path) : startsWith(resource.path, this.resource.path))) { return this.findByPath(rtrim(resource.path, paths.sep), this.resource.path.length); } From 749a7f314fbdb6195211f45e95d890c983f9bea8 Mon Sep 17 00:00:00 2001 From: Martin Aeschlimann <martinae@microsoft.com> Date: Wed, 22 Aug 2018 11:13:01 +0200 Subject: [PATCH 1095/1276] [html/css/json] improve vscodeignore --- extensions/css-language-features/.vscodeignore | 8 +++++++- extensions/html-language-features/.vscodeignore | 6 ++++-- extensions/json-language-features/.vscodeignore | 6 +++++- 3 files changed, 16 insertions(+), 4 deletions(-) diff --git a/extensions/css-language-features/.vscodeignore b/extensions/css-language-features/.vscodeignore index b85541d78ee..debeb96e691 100644 --- a/extensions/css-language-features/.vscodeignore +++ b/extensions/css-language-features/.vscodeignore @@ -1,5 +1,11 @@ +test/** +.vscode/** client/src/** client/tsconfig.json server/src/** +server/test/** +server/out/test/** +server/.vscode/** server/tsconfig.json -server/node_modules/@types/** \ No newline at end of file +**/node_modules/@types/** +**/node_modules/*/lib/esm/** \ No newline at end of file diff --git a/extensions/html-language-features/.vscodeignore b/extensions/html-language-features/.vscodeignore index da621e23a7a..fe4f2396293 100644 --- a/extensions/html-language-features/.vscodeignore +++ b/extensions/html-language-features/.vscodeignore @@ -1,8 +1,10 @@ test/** +.vscode/** server/tsconfig.json -server/node_modules/@types/** server/src/** server/test/** server/out/test/** client/tsconfig.json -client/src/** \ No newline at end of file +client/src/** +**/node_modules/*/lib/esm/** +**/node_modules/@types/** \ No newline at end of file diff --git a/extensions/json-language-features/.vscodeignore b/extensions/json-language-features/.vscodeignore index d30ea9070d5..eea89a1f649 100644 --- a/extensions/json-language-features/.vscodeignore +++ b/extensions/json-language-features/.vscodeignore @@ -1,7 +1,11 @@ test/** +.vscode/** client/tsconfig.json client/src/** server/bin server/tsconfig.json server/src/** -server/node_modules/@types/** \ No newline at end of file +server/test/** +server/node_modules/@types/** +**/node_modules/*/lib/esm/** +**/node_modules/@types/** \ No newline at end of file From 061f0f5ef44afa00a3d3b9867e44fd23c4b451ad Mon Sep 17 00:00:00 2001 From: Alex Dima <alexdima@microsoft.com> Date: Wed, 22 Aug 2018 11:20:41 +0200 Subject: [PATCH 1096/1276] Small stylistic changes --- src/vs/editor/common/config/editorOptions.ts | 2 +- .../editor/common/controller/cursorCommon.ts | 33 ++++++++++++------- .../common/controller/cursorTypeOperations.ts | 1 - .../languageConfigurationExtensionPoint.ts | 1 - 4 files changed, 22 insertions(+), 15 deletions(-) diff --git a/src/vs/editor/common/config/editorOptions.ts b/src/vs/editor/common/config/editorOptions.ts index 6ef2b811d3f..b642b3caae4 100644 --- a/src/vs/editor/common/config/editorOptions.ts +++ b/src/vs/editor/common/config/editorOptions.ts @@ -1718,7 +1718,7 @@ export class EditorOptionsValidator { let autoClosingBrackets: EditorAutoClosingStrategy; let autoClosingQuotes: EditorAutoClosingStrategy; let autoWrapping: EditorAutoWrappingStrategy; - if (typeof (opts.autoClosingBrackets) === 'boolean' && opts.autoClosingBrackets === false) { + if (typeof opts.autoClosingBrackets === 'boolean' && opts.autoClosingBrackets === false) { // backwards compatibility: disable all on boolean false autoClosingBrackets = 'never'; autoClosingQuotes = 'never'; diff --git a/src/vs/editor/common/controller/cursorCommon.ts b/src/vs/editor/common/controller/cursorCommon.ts index 3eb11919f8d..e9b777d1df3 100644 --- a/src/vs/editor/common/controller/cursorCommon.ts +++ b/src/vs/editor/common/controller/cursorCommon.ts @@ -20,7 +20,6 @@ import { IViewModel } from 'vs/editor/common/viewModel/viewModel'; import { CursorChangeReason } from 'vs/editor/common/controller/cursorEvents'; import { VerticalRevealType } from 'vs/editor/common/view/viewEvents'; import { TextModelResolvedOptions, ITextModel } from 'vs/editor/common/model'; -import { CharacterPairSupport } from 'vs/editor/common/modes/supports/characterPair'; export interface IColumnSelectData { toViewLineNumber: number; @@ -67,6 +66,10 @@ export interface CharacterMap { [char: string]: string; } +const autoCloseAlways = _ => true; +const autoCloseNever = _ => false; +const autoCloseBeforeWhitespace = (chr: string) => (chr === ' ' || chr === '\t'); + export class CursorConfiguration { _cursorMoveConfigurationBrand: void; @@ -138,8 +141,8 @@ export class CursorConfiguration { this._electricChars = null; this.shouldAutoCloseBefore = { - quote: CursorConfiguration._getShouldAutoclose(languageIdentifier, this.autoClosingQuotes), - bracket: CursorConfiguration._getShouldAutoclose(languageIdentifier, this.autoClosingBrackets) + quote: CursorConfiguration._getShouldAutoClose(languageIdentifier, this.autoClosingQuotes), + bracket: CursorConfiguration._getShouldAutoClose(languageIdentifier, this.autoClosingBrackets) }; let autoClosingPairs = CursorConfiguration._getAutoClosingPairs(languageIdentifier); @@ -193,20 +196,26 @@ export class CursorConfiguration { } } - private static _getShouldAutoclose(languageIdentifier: LanguageIdentifier, autoCloseConfig: EditorAutoClosingStrategy): (ch: string) => boolean { - let autoCloseBeforeSet = CursorConfiguration._getAutoCloseBeforeSet(languageIdentifier); - if (autoCloseConfig === 'beforeWhitespace') { return c => CharacterPairSupport.DEFAULT_AUTOCLOSE_BEFORE_WHITESPACE.indexOf(c) !== -1; } - if (autoCloseConfig === 'languageDefined') { return c => autoCloseBeforeSet.indexOf(c) !== -1; } - if (autoCloseConfig === 'always') { return c => true; } - return c => false; + private static _getShouldAutoClose(languageIdentifier: LanguageIdentifier, autoCloseConfig: EditorAutoClosingStrategy): (ch: string) => boolean { + switch (autoCloseConfig) { + case 'beforeWhitespace': + return autoCloseBeforeWhitespace; + case 'languageDefined': + return CursorConfiguration._getLanguageDefinedShouldAutoClose(languageIdentifier); + case 'always': + return autoCloseAlways; + case 'never': + return autoCloseNever; + } } - private static _getAutoCloseBeforeSet(languageIdentifier: LanguageIdentifier): string { + private static _getLanguageDefinedShouldAutoClose(languageIdentifier: LanguageIdentifier): (ch: string) => boolean { try { - return LanguageConfigurationRegistry.getAutoCloseBeforeSet(languageIdentifier.id); + const autoCloseBeforeSet = LanguageConfigurationRegistry.getAutoCloseBeforeSet(languageIdentifier.id); + return c => autoCloseBeforeSet.indexOf(c) !== -1; } catch (e) { onUnexpectedError(e); - return null; + return autoCloseNever; } } diff --git a/src/vs/editor/common/controller/cursorTypeOperations.ts b/src/vs/editor/common/controller/cursorTypeOperations.ts index 72546cb0c00..726a007bd83 100644 --- a/src/vs/editor/common/controller/cursorTypeOperations.ts +++ b/src/vs/editor/common/controller/cursorTypeOperations.ts @@ -532,7 +532,6 @@ export class TypeOperations { const position = selection.getPosition(); const lineText = model.getLineContent(position.lineNumber); - // Do not auto-close ' or " after a word character if (chIsQuote && position.column > 1) { const wordSeparators = getMapForWordSeparators(config.wordSeparators); diff --git a/src/vs/workbench/parts/codeEditor/electron-browser/languageConfiguration/languageConfigurationExtensionPoint.ts b/src/vs/workbench/parts/codeEditor/electron-browser/languageConfiguration/languageConfigurationExtensionPoint.ts index 000d7800bab..c739f208f75 100644 --- a/src/vs/workbench/parts/codeEditor/electron-browser/languageConfiguration/languageConfigurationExtensionPoint.ts +++ b/src/vs/workbench/parts/codeEditor/electron-browser/languageConfiguration/languageConfigurationExtensionPoint.ts @@ -280,7 +280,6 @@ export class LanguageConfigurationFileHandler { richEditConfig.autoCloseBefore = autoCloseBefore; } - if (configuration.wordPattern) { try { let wordPattern = this._parseRegex(configuration.wordPattern); From ec1c4aeaf531242bb5366479d8e2c46abb746630 Mon Sep 17 00:00:00 2001 From: Joao Moreno <joao.moreno@microsoft.com> Date: Wed, 22 Aug 2018 11:25:42 +0200 Subject: [PATCH 1097/1276] git api: expose repositories --- extensions/git/src/api/api0.ts | 4 ++++ extensions/git/src/api/git.d.ts | 26 +++++++++++++++++++++++--- 2 files changed, 27 insertions(+), 3 deletions(-) diff --git a/extensions/git/src/api/api0.ts b/extensions/git/src/api/api0.ts index 63c404c9e7e..ad7d5044cf9 100644 --- a/extensions/git/src/api/api0.ts +++ b/extensions/git/src/api/api0.ts @@ -44,5 +44,9 @@ export class ApiImpl implements GitExtension.API { return mapEvent(this._model.onDidCloseRepository, r => new ApiRepository(r)); } + get repositories(): GitExtension.Repository[] { + return this._model.repositories.map(r => new ApiRepository(r)); + } + constructor(private _model: Model) { } } diff --git a/extensions/git/src/api/git.d.ts b/extensions/git/src/api/git.d.ts index f85b7efb2e4..f83acfd9b98 100644 --- a/extensions/git/src/api/git.d.ts +++ b/extensions/git/src/api/git.d.ts @@ -9,6 +9,7 @@ declare module GitExtension { export interface API { readonly gitPath: string; + readonly repositories: Repository[]; readonly onDidOpenRepository: Event<Repository>; readonly onDidCloseRepository: Event<Repository>; } @@ -24,8 +25,27 @@ declare module GitExtension { } export interface GitExtension { - getRepositories(): Promise<GitExtension.Repository[]>; - getGitPath(): Promise<string>; - // export const availableVersions: string[]; + + /** + * Returns the latest available API compatible with the + * provided version range. + * + * @param range Semver version range for API compatibility. + * @returns API instance + */ getAPI(range: string): GitExtension.API; + + /** + * Returns the collection of active repositories. + * + * @deprecated Use `API.repositories` instead. + */ + getRepositories(): Promise<GitExtension.Repository[]>; + + /** + * Returns the path to the current git executable. + * + * @deprecated Use `API.gitPath` instead. + */ + getGitPath(): Promise<string>; } \ No newline at end of file From 456437dfaa603a3d9c432a0ab45a33495eb0fdc7 Mon Sep 17 00:00:00 2001 From: Joao Moreno <joao.moreno@microsoft.com> Date: Wed, 22 Aug 2018 11:30:07 +0200 Subject: [PATCH 1098/1276] git: api 1 --- extensions/git/src/api/{api0.ts => api1.ts} | 2 +- extensions/git/src/api/extension.ts | 2 +- extensions/git/src/main.ts | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) rename extensions/git/src/api/{api0.ts => api1.ts} (99%) diff --git a/extensions/git/src/api/api0.ts b/extensions/git/src/api/api1.ts similarity index 99% rename from extensions/git/src/api/api0.ts rename to extensions/git/src/api/api1.ts index ad7d5044cf9..e478785357a 100644 --- a/extensions/git/src/api/api0.ts +++ b/extensions/git/src/api/api1.ts @@ -29,7 +29,7 @@ export class ApiRepository implements GitExtension.Repository { } } -@Api('0.1.0') +@Api('1.0.0') export class ApiImpl implements GitExtension.API { get gitPath(): string { diff --git a/extensions/git/src/api/extension.ts b/extensions/git/src/api/extension.ts index 56868dc5092..7588ec4a2d9 100644 --- a/extensions/git/src/api/extension.ts +++ b/extensions/git/src/api/extension.ts @@ -8,7 +8,7 @@ import { Model } from '../model'; import { GitExtension } from './git'; import { getAPI, deprecated } from './api'; -import { ApiRepository } from './api0'; +import { ApiRepository } from './api1'; class NoModelGitExtension implements GitExtension { diff --git a/extensions/git/src/main.ts b/extensions/git/src/main.ts index 82e98d2cea9..96aa7e55472 100644 --- a/extensions/git/src/main.ts +++ b/extensions/git/src/main.ts @@ -21,7 +21,7 @@ import { GitExtension } from './api/git'; import { GitProtocolHandler } from './protocolHandler'; import { createGitExtension } from './api/extension'; -import './api/api0'; +import './api/api1'; const deactivateTasks: { (): Promise<any>; }[] = []; From 34f629f7d9fd08eaf6c6e4d8080f454fef9e2e8b Mon Sep 17 00:00:00 2001 From: isidor <inikolic@microsoft.com> Date: Wed, 22 Aug 2018 11:32:49 +0200 Subject: [PATCH 1099/1276] resources: introduce isFileSystemResource context key fixes #48275 --- src/vs/workbench/common/resources.ts | 18 ++++++++++++- .../fileActions.contribution.ts | 26 +++++++++---------- .../electron-browser/views/explorerView.ts | 1 + .../electron-browser/views/openEditorsView.ts | 1 + 4 files changed, 32 insertions(+), 14 deletions(-) diff --git a/src/vs/workbench/common/resources.ts b/src/vs/workbench/common/resources.ts index f58e4867ebe..52710ab2a8c 100644 --- a/src/vs/workbench/common/resources.ts +++ b/src/vs/workbench/common/resources.ts @@ -9,8 +9,10 @@ import URI from 'vs/base/common/uri'; import * as paths from 'vs/base/common/paths'; import { RawContextKey, IContextKeyService, IContextKey } from 'vs/platform/contextkey/common/contextkey'; import { IModeService } from 'vs/editor/common/services/modeService'; +import { IFileService } from 'vs/platform/files/common/files'; +import { dispose, IDisposable } from 'vs/base/common/lifecycle'; -export class ResourceContextKey implements IContextKey<URI> { +export class ResourceContextKey implements IContextKey<URI>, IDisposable { static Scheme = new RawContextKey<string>('resourceScheme', undefined); static Filename = new RawContextKey<string>('resourceFilename', undefined); @@ -18,6 +20,7 @@ export class ResourceContextKey implements IContextKey<URI> { static Resource = new RawContextKey<URI>('resource', undefined); static Extension = new RawContextKey<string>('resourceExtname', undefined); static HasResource = new RawContextKey<boolean>('resourceSet', false); + static IsFileSystemResource = new RawContextKey<boolean>('isFileSystemResource', false); private _resourceKey: IContextKey<URI>; private _schemeKey: IContextKey<string>; @@ -25,9 +28,12 @@ export class ResourceContextKey implements IContextKey<URI> { private _langIdKey: IContextKey<string>; private _extensionKey: IContextKey<string>; private _hasResource: IContextKey<boolean>; + private _isfileSystemResource: IContextKey<boolean>; + private toDispose: IDisposable[] = []; constructor( @IContextKeyService contextKeyService: IContextKeyService, + @IFileService private readonly _fileService: IFileService, @IModeService private readonly _modeService: IModeService ) { this._schemeKey = ResourceContextKey.Scheme.bindTo(contextKeyService); @@ -36,6 +42,11 @@ export class ResourceContextKey implements IContextKey<URI> { this._resourceKey = ResourceContextKey.Resource.bindTo(contextKeyService); this._extensionKey = ResourceContextKey.Extension.bindTo(contextKeyService); this._hasResource = ResourceContextKey.HasResource.bindTo(contextKeyService); + this._isfileSystemResource = ResourceContextKey.IsFileSystemResource.bindTo(contextKeyService); + this.toDispose.push(_fileService.onDidChangeFileSystemProviderRegistrations(() => { + const resource = this._resourceKey.get(); + this._isfileSystemResource.set(resource && _fileService.canHandleResource(resource)); + })); } set(value: URI) { @@ -45,6 +56,7 @@ export class ResourceContextKey implements IContextKey<URI> { this._langIdKey.set(value && this._modeService.getModeIdByFilenameOrFirstLine(value.fsPath)); this._extensionKey.set(value && paths.extname(value.fsPath)); this._hasResource.set(!!value); + this._isfileSystemResource.set(value && this._fileService.canHandleResource(value)); } reset(): void { @@ -59,6 +71,10 @@ export class ResourceContextKey implements IContextKey<URI> { get(): URI { return this._resourceKey.get(); } + + dispose(): void { + this.toDispose = dispose(this.toDispose); + } } /** diff --git a/src/vs/workbench/parts/files/electron-browser/fileActions.contribution.ts b/src/vs/workbench/parts/files/electron-browser/fileActions.contribution.ts index 1fd97d3e912..7a417cc526c 100644 --- a/src/vs/workbench/parts/files/electron-browser/fileActions.contribution.ts +++ b/src/vs/workbench/parts/files/electron-browser/fileActions.contribution.ts @@ -114,8 +114,8 @@ const copyRelativePathCommand = { // Editor Title Context Menu appendEditorTitleContextMenuItem(REVEAL_IN_OS_COMMAND_ID, REVEAL_IN_OS_LABEL, ResourceContextKey.Scheme.isEqualTo(Schemas.file)); -appendEditorTitleContextMenuItem(COPY_PATH_COMMAND_ID, copyPathCommand.title, ResourceContextKey.HasResource, copyRelativePathCommand); -appendEditorTitleContextMenuItem(REVEAL_IN_EXPLORER_COMMAND_ID, nls.localize('revealInSideBar', "Reveal in Side Bar"), ResourceContextKey.HasResource); +appendEditorTitleContextMenuItem(COPY_PATH_COMMAND_ID, copyPathCommand.title, ResourceContextKey.IsFileSystemResource, copyRelativePathCommand); +appendEditorTitleContextMenuItem(REVEAL_IN_EXPLORER_COMMAND_ID, nls.localize('revealInSideBar', "Reveal in Side Bar"), ResourceContextKey.IsFileSystemResource); function appendEditorTitleContextMenuItem(id: string, title: string, when: ContextKeyExpr, alt?: { id: string, title: string }): void { @@ -186,7 +186,7 @@ MenuRegistry.appendMenuItem(MenuId.OpenEditorsContext, { group: 'navigation', order: 10, command: openToSideCommand, - when: ResourceContextKey.HasResource + when: ResourceContextKey.IsFileSystemResource }); const revealInOsCommand = { @@ -197,7 +197,7 @@ MenuRegistry.appendMenuItem(MenuId.OpenEditorsContext, { group: 'navigation', order: 20, command: revealInOsCommand, - when: ResourceContextKey.Scheme.isEqualTo(Schemas.file) + when: ResourceContextKey.IsFileSystemResource }); MenuRegistry.appendMenuItem(MenuId.OpenEditorsContext, { @@ -205,7 +205,7 @@ MenuRegistry.appendMenuItem(MenuId.OpenEditorsContext, { order: 40, command: copyPathCommand, alt: copyRelativePathCommand, - when: ResourceContextKey.HasResource + when: ResourceContextKey.IsFileSystemResource }); MenuRegistry.appendMenuItem(MenuId.OpenEditorsContext, { @@ -216,7 +216,7 @@ MenuRegistry.appendMenuItem(MenuId.OpenEditorsContext, { title: SAVE_FILE_LABEL, precondition: DirtyEditorContext }, - when: ContextKeyExpr.and(ResourceContextKey.HasResource, AutoSaveContext.notEqualsTo('afterDelay') && AutoSaveContext.notEqualsTo('')) + when: ContextKeyExpr.and(ResourceContextKey.IsFileSystemResource, AutoSaveContext.notEqualsTo('afterDelay') && AutoSaveContext.notEqualsTo('')) }); MenuRegistry.appendMenuItem(MenuId.OpenEditorsContext, { @@ -227,7 +227,7 @@ MenuRegistry.appendMenuItem(MenuId.OpenEditorsContext, { title: nls.localize('revert', "Revert File"), precondition: DirtyEditorContext }, - when: ContextKeyExpr.and(ResourceContextKey.HasResource, AutoSaveContext.notEqualsTo('afterDelay') && AutoSaveContext.notEqualsTo('')) + when: ContextKeyExpr.and(ResourceContextKey.IsFileSystemResource, AutoSaveContext.notEqualsTo('afterDelay') && AutoSaveContext.notEqualsTo('')) }); MenuRegistry.appendMenuItem(MenuId.OpenEditorsContext, { @@ -256,7 +256,7 @@ MenuRegistry.appendMenuItem(MenuId.OpenEditorsContext, { title: nls.localize('compareWithSaved', "Compare with Saved"), precondition: DirtyEditorContext }, - when: ContextKeyExpr.and(ResourceContextKey.HasResource, AutoSaveContext.notEqualsTo('afterDelay') && AutoSaveContext.notEqualsTo(''), WorkbenchListDoubleSelection.toNegated()) + when: ContextKeyExpr.and(ResourceContextKey.IsFileSystemResource, AutoSaveContext.notEqualsTo('afterDelay') && AutoSaveContext.notEqualsTo(''), WorkbenchListDoubleSelection.toNegated()) }); const compareResourceCommand = { @@ -267,7 +267,7 @@ MenuRegistry.appendMenuItem(MenuId.OpenEditorsContext, { group: '3_compare', order: 20, command: compareResourceCommand, - when: ContextKeyExpr.and(ResourceContextKey.HasResource, ResourceSelectedForCompareContext, WorkbenchListDoubleSelection.toNegated()) + when: ContextKeyExpr.and(ResourceContextKey.IsFileSystemResource, ResourceSelectedForCompareContext, WorkbenchListDoubleSelection.toNegated()) }); const selectForCompareCommand = { @@ -278,7 +278,7 @@ MenuRegistry.appendMenuItem(MenuId.OpenEditorsContext, { group: '3_compare', order: 30, command: selectForCompareCommand, - when: ContextKeyExpr.and(ResourceContextKey.HasResource, WorkbenchListDoubleSelection.toNegated()) + when: ContextKeyExpr.and(ResourceContextKey.IsFileSystemResource, WorkbenchListDoubleSelection.toNegated()) }); const compareSelectedCommand = { @@ -289,7 +289,7 @@ MenuRegistry.appendMenuItem(MenuId.OpenEditorsContext, { group: '3_compare', order: 30, command: compareSelectedCommand, - when: ContextKeyExpr.and(ResourceContextKey.HasResource, WorkbenchListDoubleSelection) + when: ContextKeyExpr.and(ResourceContextKey.IsFileSystemResource, WorkbenchListDoubleSelection) }); MenuRegistry.appendMenuItem(MenuId.OpenEditorsContext, { @@ -415,7 +415,7 @@ MenuRegistry.appendMenuItem(MenuId.ExplorerContext, { order: 30, command: copyPathCommand, alt: copyRelativePathCommand, - when: ResourceContextKey.HasResource + when: ResourceContextKey.IsFileSystemResource }); MenuRegistry.appendMenuItem(MenuId.ExplorerContext, { @@ -554,4 +554,4 @@ MenuRegistry.appendMenuItem(MenuId.MenubarGoMenu, { title: nls.localize({ key: 'miGotoFile', comment: ['&& denotes a mnemonic'] }, "Go to &&File...") }, order: 1 -}); \ No newline at end of file +}); diff --git a/src/vs/workbench/parts/files/electron-browser/views/explorerView.ts b/src/vs/workbench/parts/files/electron-browser/views/explorerView.ts index 40850fe8f72..09e0a417b5f 100644 --- a/src/vs/workbench/parts/files/electron-browser/views/explorerView.ts +++ b/src/vs/workbench/parts/files/electron-browser/views/explorerView.ts @@ -118,6 +118,7 @@ export class ExplorerView extends TreeViewsViewletPanel implements IExplorerView this.decorationProvider = new ExplorerDecorationsProvider(this.model, contextService); decorationService.registerDecorationsProvider(this.decorationProvider); this.disposables.push(this.decorationProvider); + this.disposables.push(this.resourceContext); } private getFileEventsExcludes(root?: URI): glob.IExpression { diff --git a/src/vs/workbench/parts/files/electron-browser/views/openEditorsView.ts b/src/vs/workbench/parts/files/electron-browser/views/openEditorsView.ts index 8c3919f02bf..5aa65e9e21a 100644 --- a/src/vs/workbench/parts/files/electron-browser/views/openEditorsView.ts +++ b/src/vs/workbench/parts/files/electron-browser/views/openEditorsView.ts @@ -234,6 +234,7 @@ export class OpenEditorsView extends ViewletPanel { ExplorerFocusedContext.bindTo(this.list.contextKeyService); this.resourceContext = this.instantiationService.createInstance(ResourceContextKey); + this.disposables.push(this.resourceContext); this.groupFocusedContext = OpenEditorsGroupContext.bindTo(this.contextKeyService); this.dirtyEditorFocusedContext = DirtyEditorContext.bindTo(this.contextKeyService); From ffe5da332d35b342bc19fef5efc0aee81b40fe5c Mon Sep 17 00:00:00 2001 From: Johannes Rieken <johannes.rieken@gmail.com> Date: Wed, 22 Aug 2018 11:35:27 +0200 Subject: [PATCH 1100/1276] bundle node_modules and (shallow) exclude them from the extension #56081 --- extensions/emmet/.vscodeignore | 4 ++++ extensions/emmet/extension.webpack.config.js | 4 ---- extensions/git/.vscodeignore | 5 +++++ extensions/git/extension.webpack.config.js | 11 +---------- extensions/shared.webpack.config.js | 3 +++ 5 files changed, 13 insertions(+), 14 deletions(-) diff --git a/extensions/emmet/.vscodeignore b/extensions/emmet/.vscodeignore index 05dfeabaa1c..61ece8e14f8 100644 --- a/extensions/emmet/.vscodeignore +++ b/extensions/emmet/.vscodeignore @@ -2,3 +2,7 @@ test/** src/** out/** tsconfig.json +node_modules/@emmetio/css-parser/** +node_modules/@emmetio/html-matcher/** +node_modules/@emmetio/math-expression/** +node_modules/image-size/** diff --git a/extensions/emmet/extension.webpack.config.js b/extensions/emmet/extension.webpack.config.js index d066fbf4bb4..d5064ef4517 100644 --- a/extensions/emmet/extension.webpack.config.js +++ b/extensions/emmet/extension.webpack.config.js @@ -15,10 +15,6 @@ module.exports = withDefaults({ extension: './src/extension.ts', }, externals: { - '@emmetio/css-parser': 'commonjs @emmetio/css-parser', - '@emmetio/html-matcher': 'commonjs @emmetio/html-matcher', - '@emmetio/math-expression': 'commonjs @emmetio/math-expression', - 'image-size': 'commonjs image-size', 'vscode-emmet-helper': 'commonjs vscode-emmet-helper', }, }); diff --git a/extensions/git/.vscodeignore b/extensions/git/.vscodeignore index 894e6f24870..5c006f2a394 100644 --- a/extensions/git/.vscodeignore +++ b/extensions/git/.vscodeignore @@ -3,3 +3,8 @@ test/** out/** tsconfig.json build/** +node_modules/byline/** +node_modules/file-type/** +node_modules/iconv-lite/** +node_modules/jschardet/** +node_modules/which/** diff --git a/extensions/git/extension.webpack.config.js b/extensions/git/extension.webpack.config.js index 1573e4928ab..5f3997a61ca 100644 --- a/extensions/git/extension.webpack.config.js +++ b/extensions/git/extension.webpack.config.js @@ -25,14 +25,5 @@ module.exports = withDefaults({ { from: './out/*.sh', to: '[name].sh' }, { from: './out/nls.*.json', to: '[name].json' } ]) - ], - externals: { - "byline": 'commonjs byline', - "file-type": 'commonjs file-type', - "iconv-lite": 'commonjs iconv-lite', - "jschardet": 'commonjs jschardet', - "vscode-extension-telemetry": 'commonjs vscode-extension-telemetry', - "vscode-nls": 'commonjs vscode-nls', - "which": 'commonjs which', - }, + ] }); diff --git a/extensions/shared.webpack.config.js b/extensions/shared.webpack.config.js index 78ecff5f03b..ad169b3eb88 100644 --- a/extensions/shared.webpack.config.js +++ b/extensions/shared.webpack.config.js @@ -46,6 +46,9 @@ module.exports = function withDefaults(/**@type WebpackConfig*/extConfig) { }, externals: { 'vscode': 'commonjs vscode', // ignored because it doesn't exist + + "vscode-extension-telemetry": 'commonjs vscode-extension-telemetry', // commonly used + "vscode-nls": 'commonjs vscode-nls', }, output: { // all output goes into `dist`. From 5ebee3da043dd64faf1258803a1daeb0138ee80f Mon Sep 17 00:00:00 2001 From: isidor <inikolic@microsoft.com> Date: Wed, 22 Aug 2018 11:44:18 +0200 Subject: [PATCH 1101/1276] debug: preserveFocus when automatically opening launch.json fixes #56984 --- .../workbench/parts/debug/browser/debugActions.ts | 2 +- .../workbench/parts/debug/browser/debugCommands.ts | 2 +- src/vs/workbench/parts/debug/common/debug.ts | 2 +- .../electron-browser/debugConfigurationManager.ts | 14 +++++++++----- .../parts/debug/electron-browser/debugService.ts | 4 ++-- 5 files changed, 14 insertions(+), 10 deletions(-) diff --git a/src/vs/workbench/parts/debug/browser/debugActions.ts b/src/vs/workbench/parts/debug/browser/debugActions.ts index 1d35bf5ea64..f9b26e2ad32 100644 --- a/src/vs/workbench/parts/debug/browser/debugActions.ts +++ b/src/vs/workbench/parts/debug/browser/debugActions.ts @@ -113,7 +113,7 @@ export class ConfigureAction extends AbstractDebugAction { configurationManager.selectConfiguration(configurationManager.getLaunches()[0]); } - return configurationManager.selectedConfiguration.launch.openConfigFile(sideBySide); + return configurationManager.selectedConfiguration.launch.openConfigFile(sideBySide, false); } } diff --git a/src/vs/workbench/parts/debug/browser/debugCommands.ts b/src/vs/workbench/parts/debug/browser/debugCommands.ts index 7c09e489c3a..a827a84bb21 100644 --- a/src/vs/workbench/parts/debug/browser/debugCommands.ts +++ b/src/vs/workbench/parts/debug/browser/debugCommands.ts @@ -186,7 +186,7 @@ export function registerCommands(): void { } const launch = manager.getLaunches().filter(l => l.uri.toString() === launchUri).pop() || manager.selectedConfiguration.launch; - return launch.openConfigFile(false).done(({ editor, created }) => { + return launch.openConfigFile(false, false).done(({ editor, created }) => { if (editor && !created) { const codeEditor = <ICodeEditor>editor.getControl(); if (codeEditor) { diff --git a/src/vs/workbench/parts/debug/common/debug.ts b/src/vs/workbench/parts/debug/common/debug.ts index d832d738ecb..0c28a3e0db4 100644 --- a/src/vs/workbench/parts/debug/common/debug.ts +++ b/src/vs/workbench/parts/debug/common/debug.ts @@ -574,7 +574,7 @@ export interface ILaunch { /** * Opens the launch.json file. Creates if it does not exist. */ - openConfigFile(sideBySide: boolean, type?: string): TPromise<{ editor: IEditor, created: boolean }>; + openConfigFile(sideBySide: boolean, preserveFocus: boolean, type?: string): TPromise<{ editor: IEditor, created: boolean }>; } // Debug service interfaces diff --git a/src/vs/workbench/parts/debug/electron-browser/debugConfigurationManager.ts b/src/vs/workbench/parts/debug/electron-browser/debugConfigurationManager.ts index 2d2fd7ce3bc..2640da6c03a 100644 --- a/src/vs/workbench/parts/debug/electron-browser/debugConfigurationManager.ts +++ b/src/vs/workbench/parts/debug/electron-browser/debugConfigurationManager.ts @@ -442,7 +442,7 @@ class Launch implements ILaunch { return config.configurations.filter(config => config && config.name === name).shift(); } - public openConfigFile(sideBySide: boolean, type?: string): TPromise<{ editor: IEditor, created: boolean }> { + public openConfigFile(sideBySide: boolean, preserveFocus: boolean, type?: string): TPromise<{ editor: IEditor, created: boolean }> { const resource = this.uri; let created = false; @@ -487,6 +487,7 @@ class Launch implements ILaunch { resource, options: { selection, + preserveFocus, pinned: created, revealIfVisible: true }, @@ -521,8 +522,11 @@ class WorkspaceLaunch extends Launch implements ILaunch { return this.configurationService.inspect<IGlobalConfig>('launch').workspace; } - openConfigFile(sideBySide: boolean, type?: string): TPromise<{ editor: IEditor, created: boolean }> { - return this.editorService.openEditor({ resource: this.contextService.getWorkspace().configuration }).then(editor => ({ editor, created: false })); + openConfigFile(sideBySide: boolean, preserveFocus: boolean, type?: string): TPromise<{ editor: IEditor, created: boolean }> { + return this.editorService.openEditor({ + resource: this.contextService.getWorkspace().configuration, + options: { preserveFocus } + }, sideBySide ? SIDE_GROUP : ACTIVE_GROUP).then(editor => ({ editor, created: false })); } } @@ -555,7 +559,7 @@ class UserLaunch extends Launch implements ILaunch { return this.configurationService.inspect<IGlobalConfig>('launch').user; } - openConfigFile(sideBySide: boolean, type?: string): TPromise<{ editor: IEditor, created: boolean }> { - return this.preferencesService.openGlobalSettings().then(editor => ({ editor, created: false })); + openConfigFile(sideBySide: boolean, preserveFocus: boolean, type?: string): TPromise<{ editor: IEditor, created: boolean }> { + return this.preferencesService.openGlobalSettings(false, { preserveFocus }).then(editor => ({ editor, created: false })); } } diff --git a/src/vs/workbench/parts/debug/electron-browser/debugService.ts b/src/vs/workbench/parts/debug/electron-browser/debugService.ts index 182570ef159..21e321d5ea5 100644 --- a/src/vs/workbench/parts/debug/electron-browser/debugService.ts +++ b/src/vs/workbench/parts/debug/electron-browser/debugService.ts @@ -557,7 +557,7 @@ export class DebugService implements IDebugService { } if (launch && type) { - return launch.openConfigFile(false, type).done(undefined, errors.onUnexpectedError); + return launch.openConfigFile(false, true, type).done(undefined, errors.onUnexpectedError); } }) ).then(() => undefined); @@ -628,7 +628,7 @@ export class DebugService implements IDebugService { return this.showError(nls.localize('noFolderWorkspaceDebugError', "The active file can not be debugged. Make sure it is saved on disk and that you have a debug extension installed for that file type.")); } - return launch && launch.openConfigFile(false).then(editor => void 0); + return launch && launch.openConfigFile(false, true).then(editor => void 0); }) ).then(() => { this.initializing = false; From e8194084926b556505bfda7304358b934a68a92b Mon Sep 17 00:00:00 2001 From: Alex Dima <alexdima@microsoft.com> Date: Wed, 22 Aug 2018 11:57:08 +0200 Subject: [PATCH 1102/1276] More small stylistic changes --- .../editor/common/controller/cursorCommon.ts | 4 ++ .../controller/cursorDeleteOperations.ts | 4 +- .../common/controller/cursorTypeOperations.ts | 37 ++++++++++--------- 3 files changed, 26 insertions(+), 19 deletions(-) diff --git a/src/vs/editor/common/controller/cursorCommon.ts b/src/vs/editor/common/controller/cursorCommon.ts index e9b777d1df3..cba876a0772 100644 --- a/src/vs/editor/common/controller/cursorCommon.ts +++ b/src/vs/editor/common/controller/cursorCommon.ts @@ -576,3 +576,7 @@ export class CursorColumns { return column - 1 - (column - 1) % tabSize; } } + +export function isQuote(ch: string): boolean { + return (ch === '\'' || ch === '"' || ch === '`'); +} diff --git a/src/vs/editor/common/controller/cursorDeleteOperations.ts b/src/vs/editor/common/controller/cursorDeleteOperations.ts index db03dfd11bd..e16c0944cb9 100644 --- a/src/vs/editor/common/controller/cursorDeleteOperations.ts +++ b/src/vs/editor/common/controller/cursorDeleteOperations.ts @@ -5,7 +5,7 @@ 'use strict'; import { ReplaceCommand } from 'vs/editor/common/commands/replaceCommand'; -import { CursorColumns, CursorConfiguration, ICursorSimpleModel, EditOperationResult, EditOperationType } from 'vs/editor/common/controller/cursorCommon'; +import { CursorColumns, CursorConfiguration, ICursorSimpleModel, EditOperationResult, EditOperationType, isQuote } from 'vs/editor/common/controller/cursorCommon'; import { Range } from 'vs/editor/common/core/range'; import { Selection } from 'vs/editor/common/core/selection'; import { MoveOperations } from 'vs/editor/common/controller/cursorMoveOperations'; @@ -68,7 +68,7 @@ export class DeleteOperations { return false; } - if (character === '\'' || character === '"' || character === '`') { + if (isQuote(character)) { if (config.autoClosingQuotes === 'never') { return false; } diff --git a/src/vs/editor/common/controller/cursorTypeOperations.ts b/src/vs/editor/common/controller/cursorTypeOperations.ts index 726a007bd83..ac7158f32df 100644 --- a/src/vs/editor/common/controller/cursorTypeOperations.ts +++ b/src/vs/editor/common/controller/cursorTypeOperations.ts @@ -6,7 +6,7 @@ import { onUnexpectedError } from 'vs/base/common/errors'; import { ReplaceCommand, ReplaceCommandWithoutChangingPosition, ReplaceCommandWithOffsetCursorState } from 'vs/editor/common/commands/replaceCommand'; -import { CursorColumns, CursorConfiguration, ICursorSimpleModel, EditOperationResult, EditOperationType } from 'vs/editor/common/controller/cursorCommon'; +import { CursorColumns, CursorConfiguration, ICursorSimpleModel, EditOperationResult, EditOperationType, isQuote } from 'vs/editor/common/controller/cursorCommon'; import { Range } from 'vs/editor/common/core/range'; import { ICommand } from 'vs/editor/common/editorCommon'; import { ITextModel } from 'vs/editor/common/model'; @@ -437,8 +437,7 @@ export class TypeOperations { } private static _isAutoClosingCloseCharType(config: CursorConfiguration, model: ITextModel, selections: Selection[], ch: string): boolean { - const chIsQuote = (ch === '\'' || ch === '"' || ch === '`'); - const autoCloseConfig = chIsQuote ? config.autoClosingQuotes : config.autoClosingBrackets; + const autoCloseConfig = isQuote(ch) ? config.autoClosingQuotes : config.autoClosingBrackets; if (autoCloseConfig === 'never' || !config.autoClosingPairsClose.hasOwnProperty(ch)) { return false; @@ -514,7 +513,7 @@ export class TypeOperations { } private static _isAutoClosingOpenCharType(config: CursorConfiguration, model: ITextModel, selections: Selection[], ch: string): boolean { - const chIsQuote = (ch === '\'' || ch === '"' || ch === '`'); + const chIsQuote = isQuote(ch); const autoCloseConfig = chIsQuote ? config.autoClosingQuotes : config.autoClosingBrackets; if (autoCloseConfig === 'never' || !config.autoClosingPairsOpen.hasOwnProperty(ch)) { @@ -547,7 +546,7 @@ export class TypeOperations { if (characterAfter) { let isBeforeCloseBrace = TypeOperations._isBeforeClosingBrace(config, ch, characterAfter); - if (!(isBeforeCloseBrace || shouldAutoCloseBefore(characterAfter))) { + if (!isBeforeCloseBrace && !shouldAutoCloseBefore(characterAfter)) { return false; } } @@ -588,17 +587,22 @@ export class TypeOperations { }); } - private static _isSurroundSelectionType(config: CursorConfiguration, model: ITextModel, selections: Selection[], ch: string): boolean { - const chIsQuote = (ch === '\'' || ch === '"' || ch === '`'); - let autoWrapping = false; - if (chIsQuote && config.autoWrapping === 'quotes' || !chIsQuote && config.autoWrapping === 'brackets' || config.autoWrapping === 'always') { - autoWrapping = true; + private static _shouldSurroundChar(config: CursorConfiguration, ch: string): boolean { + if (isQuote(ch)) { + return (config.autoWrapping === 'quotes' || config.autoWrapping === 'always'); + } else { + // Character is a bracket + return (config.autoWrapping === 'brackets' || config.autoWrapping === 'always'); } + } - if (!autoWrapping || !config.surroundingPairs.hasOwnProperty(ch)) { + private static _isSurroundSelectionType(config: CursorConfiguration, model: ITextModel, selections: Selection[], ch: string): boolean { + if (!TypeOperations._shouldSurroundChar(config, ch) || !config.surroundingPairs.hasOwnProperty(ch)) { return false; } + const isTypingAQuoteCharacter = isQuote(ch); + for (let i = 0, len = selections.length; i < len; i++) { const selection = selections[i]; @@ -624,9 +628,9 @@ export class TypeOperations { return false; } - if (chIsQuote && selection.startLineNumber === selection.endLineNumber && selection.startColumn + 1 === selection.endColumn) { + if (isTypingAQuoteCharacter && selection.startLineNumber === selection.endLineNumber && selection.startColumn + 1 === selection.endColumn) { const selectionText = model.getValueInRange(selection); - if ((selectionText === '\'' || selectionText === '"' || selectionText === '`')) { + if (isQuote(selectionText)) { // Typing a quote character on top of another quote character // => disable surround selection type return false; @@ -749,7 +753,7 @@ export class TypeOperations { // As we are not typing in a new character, so we don't need to run `_runAutoClosingCloseCharType` // Next step, let's try to check if it's an open char. if (config.autoClosingPairsOpen.hasOwnProperty(ch)) { - if ((ch === '\'' || ch === '"') && position.column > 2) { + if (isQuote(ch) && position.column > 2) { const wordSeparators = getMapForWordSeparators(config.wordSeparators); const characterBeforeCode = lineText.charCodeAt(position.column - 3); const characterBeforeType = wordSeparators.get(characterBeforeCode); @@ -762,9 +766,8 @@ export class TypeOperations { if (characterAfter) { let isBeforeCloseBrace = TypeOperations._isBeforeClosingBrace(config, ch, characterAfter); - const chIsQuote = (ch === '\'' || ch === '"' || ch === '`'); - let shouldAutoCloseBefore = chIsQuote ? config.shouldAutoCloseBefore.quote : config.shouldAutoCloseBefore.bracket; - if (!(isBeforeCloseBrace || shouldAutoCloseBefore(characterAfter))) { + let shouldAutoCloseBefore = isQuote(ch) ? config.shouldAutoCloseBefore.quote : config.shouldAutoCloseBefore.bracket; + if (!isBeforeCloseBrace && !shouldAutoCloseBefore(characterAfter)) { continue; } } From 76f25881115baabcd1027307cde56664d6c2b534 Mon Sep 17 00:00:00 2001 From: Johannes Rieken <johannes.rieken@gmail.com> Date: Wed, 22 Aug 2018 12:04:55 +0200 Subject: [PATCH 1103/1276] debt - remove 'remote_schemes'-data, #48275 --- .../electron-browser/remoteFileService.ts | 27 +++++-------------- 1 file changed, 6 insertions(+), 21 deletions(-) diff --git a/src/vs/workbench/services/files/electron-browser/remoteFileService.ts b/src/vs/workbench/services/files/electron-browser/remoteFileService.ts index 0722e8dfc97..1b13bcc8717 100644 --- a/src/vs/workbench/services/files/electron-browser/remoteFileService.ts +++ b/src/vs/workbench/services/files/electron-browser/remoteFileService.ts @@ -6,7 +6,7 @@ import { flatten, isFalsyOrEmpty } from 'vs/base/common/arrays'; import { IDisposable, dispose, Disposable } from 'vs/base/common/lifecycle'; -import { TernarySearchTree, keys } from 'vs/base/common/map'; +import { TernarySearchTree } from 'vs/base/common/map'; import { Schemas } from 'vs/base/common/network'; import * as resources from 'vs/base/common/resources'; import URI from 'vs/base/common/uri'; @@ -161,12 +161,11 @@ class WorkspaceWatchLogic extends Disposable { export class RemoteFileService extends FileService { private readonly _provider: Map<string, IFileSystemProvider>; - private readonly _lastKnownSchemes: string[]; constructor( @IExtensionService private readonly _extensionService: IExtensionService, - @IStorageService private readonly _storageService: IStorageService, - @IEnvironmentService private readonly _environmentService: IEnvironmentService, + @IStorageService storageService: IStorageService, + @IEnvironmentService environmentService: IEnvironmentService, @IConfigurationService configurationService: IConfigurationService, @IWorkspaceContextService contextService: IWorkspaceContextService, @ILifecycleService lifecycleService: ILifecycleService, @@ -175,16 +174,15 @@ export class RemoteFileService extends FileService { ) { super( contextService, - _environmentService, + environmentService, textResourceConfigurationService, configurationService, lifecycleService, - _storageService, + storageService, notificationService ); this._provider = new Map<string, IFileSystemProvider>(); - this._lastKnownSchemes = JSON.parse(this._storageService.get('remote_schemes', undefined, '[]')); this._register(new WorkspaceWatchLogic(this, configurationService, contextService)); } @@ -195,7 +193,6 @@ export class RemoteFileService extends FileService { this._provider.set(scheme, provider); this._onDidChangeFileSystemProviderRegistrations.fire({ added: true, scheme, provider }); - this._storageService.store('remote_schemes', JSON.stringify(keys(this._provider))); const reg = provider.onDidChangeFile(changes => { // forward change events @@ -211,19 +208,7 @@ export class RemoteFileService extends FileService { } canHandleResource(resource: URI): boolean { - if (resource.scheme === Schemas.file || this._provider.has(resource.scheme)) { - return true; - } - // TODO@remote - // this needs to go, but this already went viral - // https://github.com/Microsoft/vscode/issues/48275 - if (this._lastKnownSchemes.indexOf(resource.scheme) < 0) { - return false; - } - if (!this._environmentService.isBuilt) { - console.warn('[remote] cache information required for ' + resource.toString()); - } - return true; + return resource.scheme === Schemas.file || this._provider.has(resource.scheme); } private _tryParseFileOperationResult(err: any): FileOperationResult { From 13414612090c61a6f31cb8504a969e3c405568c3 Mon Sep 17 00:00:00 2001 From: Dirk Baeumer <dirkb@microsoft.com> Date: Wed, 22 Aug 2018 12:10:44 +0200 Subject: [PATCH 1104/1276] Remove stdfork from processes.ts --- src/vs/base/node/processes.ts | 33 +++------------------------------ 1 file changed, 3 insertions(+), 30 deletions(-) diff --git a/src/vs/base/node/processes.ts b/src/vs/base/node/processes.ts index c08d79aaf2d..53f90f70954 100644 --- a/src/vs/base/node/processes.ts +++ b/src/vs/base/node/processes.ts @@ -6,7 +6,6 @@ import * as path from 'path'; import * as cp from 'child_process'; -import { fork } from 'vs/base/node/stdFork'; import * as nls from 'vs/nls'; import { TPromise, TValueCallback, ErrorCallback } from 'vs/base/common/winjs.base'; import * as Types from 'vs/base/common/types'; @@ -74,7 +73,6 @@ export function getWindowsShell(): string { export abstract class AbstractProcess<TProgressData> { private cmd: string; - private module: string; private args: string[]; private options: CommandOptions | ForkOptions; protected shell: boolean; @@ -107,18 +105,12 @@ export abstract class AbstractProcess<TProgressData> { public constructor(executable: Executable); public constructor(cmd: string, args: string[], shell: boolean, options: CommandOptions); - public constructor(module: string, args: string[], options: ForkOptions); - public constructor(arg1: string | Executable, arg2?: string[], arg3?: boolean | ForkOptions, arg4?: CommandOptions) { - if (arg4) { + public constructor(arg1: string | Executable, arg2?: string[], arg3?: boolean, arg4?: CommandOptions) { + if (arg2 !== void 0 && arg3 !== void 0 && arg4 !== void 0) { this.cmd = <string>arg1; this.args = arg2; - this.shell = <boolean>arg3; + this.shell = arg3; this.options = arg4; - } else if (arg3 && arg2) { - this.module = <string>arg1; - this.args = arg2; - this.shell = false; - this.options = <ForkOptions>arg3; } else { let executable = <Executable>arg1; this.cmd = executable.command; @@ -233,24 +225,6 @@ export abstract class AbstractProcess<TProgressData> { } else { if (this.cmd) { childProcess = cp.spawn(this.cmd, this.args, this.options); - } else if (this.module) { - this.childProcessPromise = new TPromise<cp.ChildProcess>((c, e) => { - fork(this.module, this.args, <ForkOptions>this.options, (error: any, childProcess: cp.ChildProcess) => { - if (error) { - e(error); - ee({ terminated: this.terminateRequested, error: error }); - return; - } - this.childProcess = childProcess; - if (this.pidResolve) { - this.pidResolve(Types.isNumber(childProcess.pid) ? childProcess.pid : -1); - this.pidResolve = undefined; - } - this.childProcess.on('close', closeHandler); - this.handleSpawn(childProcess, cc, pp, ee, false); - c(childProcess); - }); - }); } } if (childProcess) { @@ -345,7 +319,6 @@ export class LineProcess extends AbstractProcess<LineData> { public constructor(executable: Executable); public constructor(cmd: string, args: string[], shell: boolean, options: CommandOptions); - public constructor(module: string, args: string[], options: ForkOptions); public constructor(arg1: string | Executable, arg2?: string[], arg3?: boolean | ForkOptions, arg4?: CommandOptions) { super(<any>arg1, arg2, <any>arg3, arg4); } From 8983d89550c3aad751b0975be09c87038f679402 Mon Sep 17 00:00:00 2001 From: Joao Moreno <joao.moreno@microsoft.com> Date: Wed, 22 Aug 2018 12:31:46 +0200 Subject: [PATCH 1105/1276] git extension: expose exec/spawn --- extensions/git/src/api/api1.ts | 10 ++++++++++ extensions/git/src/api/git.d.ts | 19 ++++++++++++++++++- 2 files changed, 28 insertions(+), 1 deletion(-) diff --git a/extensions/git/src/api/api1.ts b/extensions/git/src/api/api1.ts index e478785357a..6673e030350 100644 --- a/extensions/git/src/api/api1.ts +++ b/extensions/git/src/api/api1.ts @@ -11,6 +11,7 @@ import { Api } from './api'; import { Event, SourceControlInputBox, Uri } from 'vscode'; import { mapEvent } from '../util'; import { Repository } from '../repository'; +import * as cp from 'child_process'; class ApiInputBox implements GitExtension.InputBox { set value(value: string) { this._inputBox.value = value; } @@ -49,4 +50,13 @@ export class ApiImpl implements GitExtension.API { } constructor(private _model: Model) { } + + exec(cwd: string, args: string[], options: GitExtension.SpawnOptions = {}): Promise<GitExtension.IExecResult<string>> { + return this._model.git.exec(cwd, args, options); + } + + spawn(cwd: string, args: string[], options: GitExtension.SpawnOptions = {}): cp.ChildProcess { + options = { cwd, ...options }; + return this._model.git.spawn(args, options); + } } diff --git a/extensions/git/src/api/git.d.ts b/extensions/git/src/api/git.d.ts index f83acfd9b98..1d1ab8514ba 100644 --- a/extensions/git/src/api/git.d.ts +++ b/extensions/git/src/api/git.d.ts @@ -3,15 +3,32 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -import { Uri, SourceControlInputBox, Event } from 'vscode'; +import { Uri, SourceControlInputBox, Event, CancellationToken } from 'vscode'; +import * as cp from 'child_process'; declare module GitExtension { + export interface IExecResult<T extends string | Buffer> { + readonly exitCode: number; + readonly stdout: T; + readonly stderr: string; + } + + export interface SpawnOptions extends cp.SpawnOptions { + readonly input?: string; + readonly encoding?: string; + readonly log?: boolean; + readonly cancellationToken?: CancellationToken; + } + export interface API { readonly gitPath: string; readonly repositories: Repository[]; readonly onDidOpenRepository: Event<Repository>; readonly onDidCloseRepository: Event<Repository>; + + exec(cwd: string, args: string[], options?: SpawnOptions): Promise<IExecResult<string>>; + spawn(cwd: string, args: string[], options?: SpawnOptions): cp.ChildProcess; } export interface InputBox { From a49378e26cf8265329fd2316c5792c7290e61fc2 Mon Sep 17 00:00:00 2001 From: Joao Moreno <joao.moreno@microsoft.com> Date: Wed, 22 Aug 2018 12:56:58 +0200 Subject: [PATCH 1106/1276] git: cleaner exports --- extensions/git/src/api/api.ts | 6 +-- extensions/git/src/api/api1.ts | 55 ++++++++++++---------- extensions/git/src/api/extension.ts | 10 ++-- extensions/git/src/api/git.d.ts | 72 +++++++++++++++-------------- 4 files changed, 75 insertions(+), 68 deletions(-) diff --git a/extensions/git/src/api/api.ts b/extensions/git/src/api/api.ts index 3f7d7303b8c..df818fdcd11 100644 --- a/extensions/git/src/api/api.ts +++ b/extensions/git/src/api/api.ts @@ -6,17 +6,17 @@ 'use strict'; import { Model } from '../model'; -import { GitExtension } from './git'; +import { API } from './git'; import * as semver from 'semver'; interface ApiCtor { - new(model: Model): GitExtension.API; + new(model: Model): API; } const versions: string[] = []; const apis = new Map<string, ApiCtor>(); -export function getAPI(model: Model, range: string): GitExtension.API { +export function getAPI(model: Model, range: string): API { if (!range) { throw new Error(`Please provide a Git extension API version range. Available versions: [${versions.join(', ')}]`); } diff --git a/extensions/git/src/api/api1.ts b/extensions/git/src/api/api1.ts index 6673e030350..3ae1126df13 100644 --- a/extensions/git/src/api/api1.ts +++ b/extensions/git/src/api/api1.ts @@ -6,57 +6,62 @@ 'use strict'; import { Model } from '../model'; -import { GitExtension } from './git'; +import { Repository as BaseRepository } from '../repository'; +import { InputBox, ExecResult, SpawnOptions, Git, API, Repository } from './git'; import { Api } from './api'; import { Event, SourceControlInputBox, Uri } from 'vscode'; import { mapEvent } from '../util'; -import { Repository } from '../repository'; import * as cp from 'child_process'; -class ApiInputBox implements GitExtension.InputBox { +class ApiInputBox implements InputBox { set value(value: string) { this._inputBox.value = value; } get value(): string { return this._inputBox.value; } constructor(private _inputBox: SourceControlInputBox) { } } -export class ApiRepository implements GitExtension.Repository { +export class ApiRepository implements Repository { readonly rootUri: Uri; - readonly inputBox: GitExtension.InputBox; + readonly inputBox: InputBox; - constructor(_repository: Repository) { + constructor(_repository: BaseRepository) { this.rootUri = Uri.file(_repository.root); this.inputBox = new ApiInputBox(_repository.inputBox); } } -@Api('1.0.0') -export class ApiImpl implements GitExtension.API { +export class ApiGit implements Git { - get gitPath(): string { - return this._model.git.path; - } - - get onDidOpenRepository(): Event<GitExtension.Repository> { - return mapEvent(this._model.onDidOpenRepository, r => new ApiRepository(r)); - } - - get onDidCloseRepository(): Event<GitExtension.Repository> { - return mapEvent(this._model.onDidCloseRepository, r => new ApiRepository(r)); - } - - get repositories(): GitExtension.Repository[] { - return this._model.repositories.map(r => new ApiRepository(r)); - } + get path(): string { return this._model.git.path; } constructor(private _model: Model) { } - exec(cwd: string, args: string[], options: GitExtension.SpawnOptions = {}): Promise<GitExtension.IExecResult<string>> { + exec(cwd: string, args: string[], options: SpawnOptions = {}): Promise<ExecResult<string>> { return this._model.git.exec(cwd, args, options); } - spawn(cwd: string, args: string[], options: GitExtension.SpawnOptions = {}): cp.ChildProcess { + spawn(cwd: string, args: string[], options: SpawnOptions = {}): cp.ChildProcess { options = { cwd, ...options }; return this._model.git.spawn(args, options); } } + +@Api('1.0.0') +export class ApiImpl implements API { + + readonly git = new ApiGit(this._model); + + get onDidOpenRepository(): Event<Repository> { + return mapEvent(this._model.onDidOpenRepository, r => new ApiRepository(r)); + } + + get onDidCloseRepository(): Event<Repository> { + return mapEvent(this._model.onDidCloseRepository, r => new ApiRepository(r)); + } + + get repositories(): Repository[] { + return this._model.repositories.map(r => new ApiRepository(r)); + } + + constructor(private _model: Model) { } +} diff --git a/extensions/git/src/api/extension.ts b/extensions/git/src/api/extension.ts index 7588ec4a2d9..294ad01aa4a 100644 --- a/extensions/git/src/api/extension.ts +++ b/extensions/git/src/api/extension.ts @@ -6,7 +6,7 @@ 'use strict'; import { Model } from '../model'; -import { GitExtension } from './git'; +import { GitExtension, Repository, API } from './git'; import { getAPI, deprecated } from './api'; import { ApiRepository } from './api1'; @@ -18,11 +18,11 @@ class NoModelGitExtension implements GitExtension { } @deprecated - async getRepositories(): Promise<GitExtension.Repository[]> { + async getRepositories(): Promise<Repository[]> { throw new Error('Git model not found'); } - getAPI(): GitExtension.API { + getAPI(): API { throw new Error('Git model not found'); } } @@ -37,11 +37,11 @@ class GitExtensionImpl implements GitExtension { } @deprecated - async getRepositories(): Promise<GitExtension.Repository[]> { + async getRepositories(): Promise<Repository[]> { return this._model.repositories.map(repository => new ApiRepository(repository)); } - getAPI(range: string): GitExtension.API { + getAPI(range: string): API { return getAPI(this._model, range); } } diff --git a/extensions/git/src/api/git.d.ts b/extensions/git/src/api/git.d.ts index 1d1ab8514ba..58156482a0f 100644 --- a/extensions/git/src/api/git.d.ts +++ b/extensions/git/src/api/git.d.ts @@ -6,41 +6,43 @@ import { Uri, SourceControlInputBox, Event, CancellationToken } from 'vscode'; import * as cp from 'child_process'; -declare module GitExtension { - - export interface IExecResult<T extends string | Buffer> { - readonly exitCode: number; - readonly stdout: T; - readonly stderr: string; - } - - export interface SpawnOptions extends cp.SpawnOptions { - readonly input?: string; - readonly encoding?: string; - readonly log?: boolean; - readonly cancellationToken?: CancellationToken; - } - - export interface API { - readonly gitPath: string; - readonly repositories: Repository[]; - readonly onDidOpenRepository: Event<Repository>; - readonly onDidCloseRepository: Event<Repository>; - - exec(cwd: string, args: string[], options?: SpawnOptions): Promise<IExecResult<string>>; - spawn(cwd: string, args: string[], options?: SpawnOptions): cp.ChildProcess; - } - - export interface InputBox { - value: string; - } - - export interface Repository { - readonly rootUri: Uri; - readonly inputBox: InputBox; - } +export interface ExecResult<T extends string | Buffer> { + readonly exitCode: number; + readonly stdout: T; + readonly stderr: string; } +export interface SpawnOptions extends cp.SpawnOptions { + readonly input?: string; + readonly encoding?: string; + readonly log?: boolean; + readonly cancellationToken?: CancellationToken; +} + +export interface Git { + readonly path: string; + exec(cwd: string, args: string[], options?: SpawnOptions): Promise<ExecResult<string>>; + spawn(cwd: string, args: string[], options?: SpawnOptions): cp.ChildProcess; +} + +export interface API { + readonly git: Git; + readonly repositories: Repository[]; + readonly onDidOpenRepository: Event<Repository>; + readonly onDidCloseRepository: Event<Repository>; +} + +export interface InputBox { + value: string; +} + +export interface Repository { + readonly rootUri: Uri; + readonly inputBox: InputBox; +} + +declare module GitExtension { } + export interface GitExtension { /** @@ -50,14 +52,14 @@ export interface GitExtension { * @param range Semver version range for API compatibility. * @returns API instance */ - getAPI(range: string): GitExtension.API; + getAPI(range: string): API; /** * Returns the collection of active repositories. * * @deprecated Use `API.repositories` instead. */ - getRepositories(): Promise<GitExtension.Repository[]>; + getRepositories(): Promise<Repository[]>; /** * Returns the path to the current git executable. From f9982d29d42603b21f4a44ef015092a17f57e5ae Mon Sep 17 00:00:00 2001 From: Joao Moreno <joao.moreno@microsoft.com> Date: Wed, 22 Aug 2018 13:06:26 +0200 Subject: [PATCH 1107/1276] git api: make cwd mandatory --- extensions/git/src/api/api1.ts | 7 +++---- extensions/git/src/api/git.d.ts | 5 +++-- extensions/git/src/git.ts | 4 ++++ 3 files changed, 10 insertions(+), 6 deletions(-) diff --git a/extensions/git/src/api/api1.ts b/extensions/git/src/api/api1.ts index 3ae1126df13..4d0db493a68 100644 --- a/extensions/git/src/api/api1.ts +++ b/extensions/git/src/api/api1.ts @@ -36,12 +36,11 @@ export class ApiGit implements Git { constructor(private _model: Model) { } - exec(cwd: string, args: string[], options: SpawnOptions = {}): Promise<ExecResult<string>> { - return this._model.git.exec(cwd, args, options); + exec(args: string[], options: SpawnOptions): Promise<ExecResult<string>> { + return this._model.git.exec2(args, options); } - spawn(cwd: string, args: string[], options: SpawnOptions = {}): cp.ChildProcess { - options = { cwd, ...options }; + spawn(args: string[], options: SpawnOptions): cp.ChildProcess { return this._model.git.spawn(args, options); } } diff --git a/extensions/git/src/api/git.d.ts b/extensions/git/src/api/git.d.ts index 58156482a0f..97766537cd9 100644 --- a/extensions/git/src/api/git.d.ts +++ b/extensions/git/src/api/git.d.ts @@ -13,6 +13,7 @@ export interface ExecResult<T extends string | Buffer> { } export interface SpawnOptions extends cp.SpawnOptions { + readonly cwd: string; readonly input?: string; readonly encoding?: string; readonly log?: boolean; @@ -21,8 +22,8 @@ export interface SpawnOptions extends cp.SpawnOptions { export interface Git { readonly path: string; - exec(cwd: string, args: string[], options?: SpawnOptions): Promise<ExecResult<string>>; - spawn(cwd: string, args: string[], options?: SpawnOptions): cp.ChildProcess; + exec(args: string[], options: SpawnOptions): Promise<ExecResult<string>>; + spawn(args: string[], options: SpawnOptions): cp.ChildProcess; } export interface API { diff --git a/extensions/git/src/git.ts b/extensions/git/src/git.ts index a360264a394..01e08bd3878 100644 --- a/extensions/git/src/git.ts +++ b/extensions/git/src/git.ts @@ -427,6 +427,10 @@ export class Git { return await this._exec(args, options); } + async exec2(args: string[], options: SpawnOptions = {}): Promise<IExecutionResult<string>> { + return await this._exec(args, options); + } + stream(cwd: string, args: string[], options: SpawnOptions = {}): cp.ChildProcess { options = assign({ cwd }, options || {}); return this.spawn(args, options); From 78d61d55f430cf388f672c7d91974c0c2396f01c Mon Sep 17 00:00:00 2001 From: Joao Moreno <joao.moreno@microsoft.com> Date: Wed, 22 Aug 2018 15:09:11 +0200 Subject: [PATCH 1108/1276] git: use simpler versioning scheme --- extensions/git/package.json | 1 - extensions/git/src/api/api.ts | 55 ----------------------------- extensions/git/src/api/api1.ts | 13 +------ extensions/git/src/api/extension.ts | 23 +++++++++--- extensions/git/src/api/git.d.ts | 39 ++------------------ extensions/git/src/main.ts | 2 -- extensions/git/yarn.lock | 4 --- 7 files changed, 23 insertions(+), 114 deletions(-) delete mode 100644 extensions/git/src/api/api.ts diff --git a/extensions/git/package.json b/extensions/git/package.json index 41f2020898c..712f071eb3a 100644 --- a/extensions/git/package.json +++ b/extensions/git/package.json @@ -1197,7 +1197,6 @@ "file-type": "^7.2.0", "iconv-lite": "0.4.19", "jschardet": "^1.6.0", - "semver": "^5.5.1", "vscode-extension-telemetry": "0.0.18", "vscode-nls": "^3.2.4", "which": "^1.3.0" diff --git a/extensions/git/src/api/api.ts b/extensions/git/src/api/api.ts deleted file mode 100644 index df818fdcd11..00000000000 --- a/extensions/git/src/api/api.ts +++ /dev/null @@ -1,55 +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'; - -import { Model } from '../model'; -import { API } from './git'; -import * as semver from 'semver'; - -interface ApiCtor { - new(model: Model): API; -} - -const versions: string[] = []; -const apis = new Map<string, ApiCtor>(); - -export function getAPI(model: Model, range: string): API { - if (!range) { - throw new Error(`Please provide a Git extension API version range. Available versions: [${versions.join(', ')}]`); - } - - const version = semver.maxSatisfying(versions, range); - - if (!version) { - throw new Error(`There's no available Git extension API for the given range: '${range}'. Available versions: [${versions.join(', ')}]`); - } - - const api = apis.get(version)!; - return new api(model); -} - -export function Api(version: string): Function { - return function (ctor: ApiCtor) { - if (apis.has(version)) { - throw new Error(`Git extension API version ${version} already registered.`); - } - - versions.push(version); - apis.set(version, ctor); - }; -} - -export function deprecated(target: any, key: string, descriptor: any): void { - if (typeof descriptor.value !== 'function') { - throw new Error('not supported'); - } - - const fn = descriptor.value; - descriptor.value = function () { - console.warn(`Git extension API method '${key}' is deprecated.`); - return fn.apply(this, arguments); - }; -} \ No newline at end of file diff --git a/extensions/git/src/api/api1.ts b/extensions/git/src/api/api1.ts index 4d0db493a68..75e81f6cb3c 100644 --- a/extensions/git/src/api/api1.ts +++ b/extensions/git/src/api/api1.ts @@ -7,11 +7,9 @@ import { Model } from '../model'; import { Repository as BaseRepository } from '../repository'; -import { InputBox, ExecResult, SpawnOptions, Git, API, Repository } from './git'; -import { Api } from './api'; +import { InputBox, Git, API, Repository } from './git'; import { Event, SourceControlInputBox, Uri } from 'vscode'; import { mapEvent } from '../util'; -import * as cp from 'child_process'; class ApiInputBox implements InputBox { set value(value: string) { this._inputBox.value = value; } @@ -35,17 +33,8 @@ export class ApiGit implements Git { get path(): string { return this._model.git.path; } constructor(private _model: Model) { } - - exec(args: string[], options: SpawnOptions): Promise<ExecResult<string>> { - return this._model.git.exec2(args, options); - } - - spawn(args: string[], options: SpawnOptions): cp.ChildProcess { - return this._model.git.spawn(args, options); - } } -@Api('1.0.0') export class ApiImpl implements API { readonly git = new ApiGit(this._model); diff --git a/extensions/git/src/api/extension.ts b/extensions/git/src/api/extension.ts index 294ad01aa4a..622d3110724 100644 --- a/extensions/git/src/api/extension.ts +++ b/extensions/git/src/api/extension.ts @@ -7,8 +7,19 @@ import { Model } from '../model'; import { GitExtension, Repository, API } from './git'; -import { getAPI, deprecated } from './api'; -import { ApiRepository } from './api1'; +import { ApiRepository, ApiImpl } from './api1'; + +export function deprecated(target: any, key: string, descriptor: any): void { + if (typeof descriptor.value !== 'function') { + throw new Error('not supported'); + } + + const fn = descriptor.value; + descriptor.value = function () { + console.warn(`Git extension API method '${key}' is deprecated.`); + return fn.apply(this, arguments); + }; +} class NoModelGitExtension implements GitExtension { @@ -41,8 +52,12 @@ class GitExtensionImpl implements GitExtension { return this._model.repositories.map(repository => new ApiRepository(repository)); } - getAPI(range: string): API { - return getAPI(this._model, range); + getAPI(version: number): API { + if (version !== 1) { + throw new Error(`No API version ${version} found.`); + } + + return new ApiImpl(this._model); } } diff --git a/extensions/git/src/api/git.d.ts b/extensions/git/src/api/git.d.ts index 97766537cd9..4d738531098 100644 --- a/extensions/git/src/api/git.d.ts +++ b/extensions/git/src/api/git.d.ts @@ -6,24 +6,8 @@ import { Uri, SourceControlInputBox, Event, CancellationToken } from 'vscode'; import * as cp from 'child_process'; -export interface ExecResult<T extends string | Buffer> { - readonly exitCode: number; - readonly stdout: T; - readonly stderr: string; -} - -export interface SpawnOptions extends cp.SpawnOptions { - readonly cwd: string; - readonly input?: string; - readonly encoding?: string; - readonly log?: boolean; - readonly cancellationToken?: CancellationToken; -} - export interface Git { readonly path: string; - exec(args: string[], options: SpawnOptions): Promise<ExecResult<string>>; - spawn(args: string[], options: SpawnOptions): cp.ChildProcess; } export interface API { @@ -42,30 +26,13 @@ export interface Repository { readonly inputBox: InputBox; } -declare module GitExtension { } - export interface GitExtension { /** - * Returns the latest available API compatible with the - * provided version range. + * Returns a specific API version. * - * @param range Semver version range for API compatibility. + * @param version Version number. * @returns API instance */ - getAPI(range: string): API; - - /** - * Returns the collection of active repositories. - * - * @deprecated Use `API.repositories` instead. - */ - getRepositories(): Promise<Repository[]>; - - /** - * Returns the path to the current git executable. - * - * @deprecated Use `API.gitPath` instead. - */ - getGitPath(): Promise<string>; + getAPI(version: 1): API; } \ No newline at end of file diff --git a/extensions/git/src/main.ts b/extensions/git/src/main.ts index 96aa7e55472..0d3ebc4d560 100644 --- a/extensions/git/src/main.ts +++ b/extensions/git/src/main.ts @@ -21,8 +21,6 @@ import { GitExtension } from './api/git'; import { GitProtocolHandler } from './protocolHandler'; import { createGitExtension } from './api/extension'; -import './api/api1'; - const deactivateTasks: { (): Promise<any>; }[] = []; export async function deactivate(): Promise<any> { diff --git a/extensions/git/yarn.lock b/extensions/git/yarn.lock index d47f44ccf7a..cf3f64be853 100644 --- a/extensions/git/yarn.lock +++ b/extensions/git/yarn.lock @@ -251,10 +251,6 @@ semver@^5.3.0: version "5.5.0" resolved "https://registry.yarnpkg.com/semver/-/semver-5.5.0.tgz#dc4bbc7a6ca9d916dee5d43516f0092b58f7b8ab" -semver@^5.5.1: - version "5.5.1" - resolved "https://registry.yarnpkg.com/semver/-/semver-5.5.1.tgz#7dfdd8814bdb7cabc7be0fb1d734cfb66c940477" - supports-color@3.1.2: version "3.1.2" resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-3.1.2.tgz#72a262894d9d408b956ca05ff37b2ed8a6e2a2d5" From 961ff68f9ade13fa1afafadffc1f381f1fcbaf7f Mon Sep 17 00:00:00 2001 From: Andre Weinand <aweinand@microsoft.com> Date: Wed, 22 Aug 2018 15:18:41 +0200 Subject: [PATCH 1109/1276] Remove 'ELECTRON_RUN_AS_NODE' env var on fork --- src/vs/workbench/parts/debug/node/debugAdapter.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/vs/workbench/parts/debug/node/debugAdapter.ts b/src/vs/workbench/parts/debug/node/debugAdapter.ts index 5168ed1a4c1..61d86a3bf25 100644 --- a/src/vs/workbench/parts/debug/node/debugAdapter.ts +++ b/src/vs/workbench/parts/debug/node/debugAdapter.ts @@ -285,7 +285,8 @@ export class DebugAdapter extends StreamDebugAdapter { if (this.adapterExecutable.command === 'node' && this.outputService) { if (Array.isArray(this.adapterExecutable.args) && this.adapterExecutable.args.length > 0) { const child = cp.fork(this.adapterExecutable.args[0], this.adapterExecutable.args.slice(1), { - stdio: ['pipe', 'pipe', 'pipe', 'ipc'] + execArgv: [ '-e', 'delete process.env.ELECTRON_RUN_AS_NODE;require(process.argv[1])' ].concat(process.execArgv || []), + silent: true }); if (!child.pid) { e(new Error(nls.localize('unableToLaunchDebugAdapter', "Unable to launch debug adapter from '{0}'.", this.adapterExecutable.args[0]))); From b4fc62b9c52c603e12ef807f4f4bca0edd901ef2 Mon Sep 17 00:00:00 2001 From: Manoel Lobo <manoel.lobo@gmail.com> Date: Wed, 22 Aug 2018 10:23:45 -0300 Subject: [PATCH 1110/1276] Add .eslintrc extension --- .eslintrc => .eslintrc.json | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename .eslintrc => .eslintrc.json (100%) diff --git a/.eslintrc b/.eslintrc.json similarity index 100% rename from .eslintrc rename to .eslintrc.json From 1845bc3a64aabb2899eff93d76f8291d8f74d64b Mon Sep 17 00:00:00 2001 From: Joao Moreno <joao.moreno@microsoft.com> Date: Wed, 22 Aug 2018 15:26:49 +0200 Subject: [PATCH 1111/1276] git api: onDidRunGitStatus --- extensions/git/src/api/api1.ts | 14 +++++++++----- extensions/git/src/api/git.d.ts | 18 +++++++++++------- 2 files changed, 20 insertions(+), 12 deletions(-) diff --git a/extensions/git/src/api/api1.ts b/extensions/git/src/api/api1.ts index 75e81f6cb3c..f6925fd0d55 100644 --- a/extensions/git/src/api/api1.ts +++ b/extensions/git/src/api/api1.ts @@ -19,12 +19,16 @@ class ApiInputBox implements InputBox { export class ApiRepository implements Repository { - readonly rootUri: Uri; - readonly inputBox: InputBox; + readonly rootUri: Uri = Uri.file(this._repository.root); + readonly inputBox: InputBox = new ApiInputBox(this._repository.inputBox); - constructor(_repository: BaseRepository) { - this.rootUri = Uri.file(_repository.root); - this.inputBox = new ApiInputBox(_repository.inputBox); + readonly onDidRunGitStatus: Event<void> = this._repository.onDidRunGitStatus; + + constructor(private _repository: BaseRepository) { + } + + status(): Promise<void> { + return this._repository.status(); } } diff --git a/extensions/git/src/api/git.d.ts b/extensions/git/src/api/git.d.ts index 4d738531098..449a62f7f2c 100644 --- a/extensions/git/src/api/git.d.ts +++ b/extensions/git/src/api/git.d.ts @@ -10,13 +10,6 @@ export interface Git { readonly path: string; } -export interface API { - readonly git: Git; - readonly repositories: Repository[]; - readonly onDidOpenRepository: Event<Repository>; - readonly onDidCloseRepository: Event<Repository>; -} - export interface InputBox { value: string; } @@ -24,6 +17,17 @@ export interface InputBox { export interface Repository { readonly rootUri: Uri; readonly inputBox: InputBox; + + readonly onDidRunGitStatus: Event<void>; + + status(): Promise<void>; +} + +export interface API { + readonly git: Git; + readonly repositories: Repository[]; + readonly onDidOpenRepository: Event<Repository>; + readonly onDidCloseRepository: Event<Repository>; } export interface GitExtension { From 2a299bb9d039773fe046f54c13b0ee47e5fc380f Mon Sep 17 00:00:00 2001 From: Benjamin Pasero <benjpas@microsoft.com> Date: Wed, 22 Aug 2018 15:32:07 +0200 Subject: [PATCH 1112/1276] tweak d.ts to avoid security and deprecation pitfalls --- src/typings/electron.d.ts | 10 +++++----- src/typings/node.d.ts | 12 ++++++------ src/vs/platform/download/node/downloadIpc.ts | 2 +- 3 files changed, 12 insertions(+), 12 deletions(-) diff --git a/src/typings/electron.d.ts b/src/typings/electron.d.ts index 445234b2076..56c03cf5e2d 100644 --- a/src/typings/electron.d.ts +++ b/src/typings/electron.d.ts @@ -6374,7 +6374,7 @@ declare namespace Electron { * When this attribute is present the guest page will be allowed to open new * windows. Popups are disabled by default. */ - allowpopups?: string; + // allowpopups?: string; ### VSCODE CHANGE (https://github.com/electron/electron/blob/master/docs/tutorial/security.md) ### /** * When this attribute is present the webview container will automatically resize * within the bounds specified by the attributes minwidth, minheight, maxwidth, and @@ -6407,7 +6407,7 @@ declare namespace Electron { * When this attribute is present the guest page will have web security disabled. * Web security is enabled by default. */ - disablewebsecurity?: string; + // disablewebsecurity?: string; ### VSCODE CHANGE(https://github.com/electron/electron/blob/master/docs/tutorial/security.md) ### /** * A value that links the webview to a specific webContents. When a webview first * loads a new webContents is created and this attribute is set to its instance @@ -8633,12 +8633,12 @@ declare namespace Electron { * websites by people), and set allowRunningInsecureContent to true if this options * has not been set by user. Default is true. */ - webSecurity?: boolean; + // webSecurity?: boolean; ### VSCODE CHANGE (https://github.com/electron/electron/blob/master/docs/tutorial/security.md) ### /** * Allow an https page to run JavaScript, CSS or plugins from http URLs. Default is * false. */ - allowRunningInsecureContent?: boolean; + // allowRunningInsecureContent?: boolean; ### VSCODE CHANGE (https://github.com/electron/electron/blob/master/docs/tutorial/security.md) ### /** * Enables image support. Default is true. */ @@ -8662,7 +8662,7 @@ declare namespace Electron { /** * Enables Chromium's experimental features. Default is false. */ - experimentalFeatures?: boolean; + // experimentalFeatures?: boolean; ### VSCODE CHANGE (https://github.com/electron/electron/blob/master/docs/tutorial/security.md) ### /** * Enables Chromium's experimental canvas features. Default is false. */ diff --git a/src/typings/node.d.ts b/src/typings/node.d.ts index b8e246d1ecf..c597abdda90 100644 --- a/src/typings/node.d.ts +++ b/src/typings/node.d.ts @@ -192,19 +192,19 @@ declare var Buffer: { * @param str String to store in buffer. * @param encoding encoding to use, optional. Default is 'utf8' */ - new(str: string, encoding?: string): Buffer; + // new(str: string, encoding?: string): Buffer; ### VSCODE CHANGE (new Buffer() is deprecated) /** * Allocates a new buffer of {size} octets. * * @param size count of octets to allocate. */ - new(size: number): Buffer; + // new(size: number): Buffer; ### VSCODE CHANGE (new Buffer() is deprecated) /** * Allocates a new buffer containing the given {array} of octets. * * @param array The octets to store. */ - new(array: Uint8Array): Buffer; + // new(array: Uint8Array): Buffer; ### VSCODE CHANGE (new Buffer() is deprecated) /** * Produces a Buffer backed by the same allocated memory as * the given {ArrayBuffer}. @@ -212,19 +212,19 @@ declare var Buffer: { * * @param arrayBuffer The ArrayBuffer with which to share memory. */ - new(arrayBuffer: ArrayBuffer): Buffer; + // new(arrayBuffer: ArrayBuffer): Buffer; ### VSCODE CHANGE (new Buffer() is deprecated) /** * Allocates a new buffer containing the given {array} of octets. * * @param array The octets to store. */ - new(array: any[]): Buffer; + // new(array: any[]): Buffer; ### VSCODE CHANGE (new Buffer() is deprecated) /** * Copies the passed {buffer} data onto a new {Buffer} instance. * * @param buffer The buffer to copy. */ - new(buffer: Buffer): Buffer; + // new(buffer: Buffer): Buffer; ### VSCODE CHANGE (new Buffer() is deprecated) prototype: Buffer; /** * When passed a reference to the .buffer property of a TypedArray instance, diff --git a/src/vs/platform/download/node/downloadIpc.ts b/src/vs/platform/download/node/downloadIpc.ts index bcd744a2406..606fdc05dc3 100644 --- a/src/vs/platform/download/node/downloadIpc.ts +++ b/src/vs/platform/download/node/downloadIpc.ts @@ -69,7 +69,7 @@ export class DownloadServiceChannelClient implements IDownloadService { out.end(); disposable.dispose(); c(null); - } else if (result instanceof Buffer) { + } else if (Buffer.isBuffer(result)) { out.write(result); } else if (typeof result === 'string') { out.close(); From ce5e9e85242c578151295d3a52c629eecb638336 Mon Sep 17 00:00:00 2001 From: Andre Weinand <aweinand@microsoft.com> Date: Wed, 22 Aug 2018 15:34:09 +0200 Subject: [PATCH 1113/1276] fix formatting --- src/vs/workbench/parts/debug/node/debugAdapter.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vs/workbench/parts/debug/node/debugAdapter.ts b/src/vs/workbench/parts/debug/node/debugAdapter.ts index 61d86a3bf25..d8431a24f48 100644 --- a/src/vs/workbench/parts/debug/node/debugAdapter.ts +++ b/src/vs/workbench/parts/debug/node/debugAdapter.ts @@ -285,7 +285,7 @@ export class DebugAdapter extends StreamDebugAdapter { if (this.adapterExecutable.command === 'node' && this.outputService) { if (Array.isArray(this.adapterExecutable.args) && this.adapterExecutable.args.length > 0) { const child = cp.fork(this.adapterExecutable.args[0], this.adapterExecutable.args.slice(1), { - execArgv: [ '-e', 'delete process.env.ELECTRON_RUN_AS_NODE;require(process.argv[1])' ].concat(process.execArgv || []), + execArgv: ['-e', 'delete process.env.ELECTRON_RUN_AS_NODE;require(process.argv[1])'].concat(process.execArgv || []), silent: true }); if (!child.pid) { From a9bc997f2371922a848825a2fb608e1d91e2cc02 Mon Sep 17 00:00:00 2001 From: Joao Moreno <joao.moreno@microsoft.com> Date: Wed, 22 Aug 2018 15:28:53 +0200 Subject: [PATCH 1114/1276] git api: remotes --- extensions/git/src/api/api1.ts | 6 +++--- extensions/git/src/api/git.d.ts | 8 ++++++++ 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/extensions/git/src/api/api1.ts b/extensions/git/src/api/api1.ts index f6925fd0d55..0057e80fdeb 100644 --- a/extensions/git/src/api/api1.ts +++ b/extensions/git/src/api/api1.ts @@ -7,7 +7,7 @@ import { Model } from '../model'; import { Repository as BaseRepository } from '../repository'; -import { InputBox, Git, API, Repository } from './git'; +import { InputBox, Git, API, Repository, Remote } from './git'; import { Event, SourceControlInputBox, Uri } from 'vscode'; import { mapEvent } from '../util'; @@ -21,11 +21,11 @@ export class ApiRepository implements Repository { readonly rootUri: Uri = Uri.file(this._repository.root); readonly inputBox: InputBox = new ApiInputBox(this._repository.inputBox); + get remotes(): Remote[] { return [...this._repository.remotes]; } readonly onDidRunGitStatus: Event<void> = this._repository.onDidRunGitStatus; - constructor(private _repository: BaseRepository) { - } + constructor(private _repository: BaseRepository) { } status(): Promise<void> { return this._repository.status(); diff --git a/extensions/git/src/api/git.d.ts b/extensions/git/src/api/git.d.ts index 449a62f7f2c..7ba18e0d70a 100644 --- a/extensions/git/src/api/git.d.ts +++ b/extensions/git/src/api/git.d.ts @@ -14,9 +14,17 @@ export interface InputBox { value: string; } +export interface Remote { + readonly name: string; + readonly fetchUrl?: string; + readonly pushUrl?: string; + readonly isReadOnly: boolean; +} + export interface Repository { readonly rootUri: Uri; readonly inputBox: InputBox; + readonly remotes: Remote[]; readonly onDidRunGitStatus: Event<void>; From 5b164efaa1d68edc1278ccacd48e8a0f092c16f7 Mon Sep 17 00:00:00 2001 From: isidor <inikolic@microsoft.com> Date: Wed, 22 Aug 2018 15:51:37 +0200 Subject: [PATCH 1115/1276] fixes #57004 --- src/vs/workbench/parts/debug/node/debugAdapter.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vs/workbench/parts/debug/node/debugAdapter.ts b/src/vs/workbench/parts/debug/node/debugAdapter.ts index a322f0d8779..13ca072228f 100644 --- a/src/vs/workbench/parts/debug/node/debugAdapter.ts +++ b/src/vs/workbench/parts/debug/node/debugAdapter.ts @@ -238,7 +238,7 @@ export class SocketDebugAdapter extends StreamDebugAdapter { } stopSession(): TPromise<void> { - if (this.socket !== null) { + if (this.socket) { this.socket.end(); this.socket = undefined; } From 1df5a2f9ef2defd16c7cc2251405e73f8987386b Mon Sep 17 00:00:00 2001 From: Johannes Rieken <johannes.rieken@gmail.com> Date: Wed, 22 Aug 2018 15:56:23 +0200 Subject: [PATCH 1116/1276] add log level change event, #43275 --- src/vs/vscode.proposed.d.ts | 7 +++++-- src/vs/workbench/api/node/extHost.api.impl.ts | 4 ++++ 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/src/vs/vscode.proposed.d.ts b/src/vs/vscode.proposed.d.ts index 9b3a074851d..48b1f768187 100644 --- a/src/vs/vscode.proposed.d.ts +++ b/src/vs/vscode.proposed.d.ts @@ -437,10 +437,13 @@ declare module 'vscode' { export namespace env { /** * Current logging level. - * - * @readonly */ export const logLevel: LogLevel; + + /** + * An [event](#Event) that fires when the log level has changed. + */ + export const onDidChangeLogLevel: Event<LogLevel>; } //#endregion diff --git a/src/vs/workbench/api/node/extHost.api.impl.ts b/src/vs/workbench/api/node/extHost.api.impl.ts index a8afbaabb36..8bf889401c0 100644 --- a/src/vs/workbench/api/node/extHost.api.impl.ts +++ b/src/vs/workbench/api/node/extHost.api.impl.ts @@ -230,6 +230,10 @@ export function createApiFactory( get logLevel() { checkProposedApiEnabled(extension); return extHostLogService.getLevel(); + }, + get onDidChangeLogLevel() { + checkProposedApiEnabled(extension); + return extHostLogService.onDidChangeLogLevel; } }); From e0195d75692add792e1e1758b9e27ef18485a856 Mon Sep 17 00:00:00 2001 From: isidor <inikolic@microsoft.com> Date: Wed, 22 Aug 2018 16:07:01 +0200 Subject: [PATCH 1117/1276] simplify copy path command --- src/vs/platform/uriLabel/common/uriLabel.ts | 14 ++++---- .../files/electron-browser/fileCommands.ts | 34 +++++-------------- 2 files changed, 15 insertions(+), 33 deletions(-) diff --git a/src/vs/platform/uriLabel/common/uriLabel.ts b/src/vs/platform/uriLabel/common/uriLabel.ts index f8c3a424a67..4cd0e873aa2 100644 --- a/src/vs/platform/uriLabel/common/uriLabel.ts +++ b/src/vs/platform/uriLabel/common/uriLabel.ts @@ -16,7 +16,7 @@ import { ltrim } from 'vs/base/common/strings'; export interface IUriLabelService { _serviceBrand: any; - getLabel(resource: URI, relative?: boolean): string; + getLabel(resource: URI, relative?: boolean, forceNoTildify?: boolean): string; registerFormater(schema: string, formater: UriLabelRules): IDisposable; onDidRegisterFormater: Event<{ scheme: string, formater: UriLabelRules }>; } @@ -52,7 +52,7 @@ export class UriLabelService implements IUriLabelService { return this._onDidRegisterFormater.event; } - getLabel(resource: URI, relative: boolean): string { + getLabel(resource: URI, relative: boolean, forceNoTildify?: boolean): string { if (!resource) { return undefined; } @@ -68,8 +68,8 @@ export class UriLabelService implements IUriLabelService { if (isEqual(baseResource.uri, resource, !isLinux)) { relativeLabel = ''; // no label if resources are identical } else { - const baseResourceLabel = this.formatUri(baseResource.uri, formater); - relativeLabel = ltrim(this.formatUri(resource, formater).substring(baseResourceLabel.length), formater.separator); + const baseResourceLabel = this.formatUri(baseResource.uri, formater, forceNoTildify); + relativeLabel = ltrim(this.formatUri(resource, formater, forceNoTildify).substring(baseResourceLabel.length), formater.separator); } const hasMultipleRoots = this.contextService.getWorkspace().folders.length > 1; @@ -82,7 +82,7 @@ export class UriLabelService implements IUriLabelService { } } - return this.formatUri(resource, formater); + return this.formatUri(resource, formater, forceNoTildify); } registerFormater(scheme: string, formater: UriLabelRules): IDisposable { @@ -94,7 +94,7 @@ export class UriLabelService implements IUriLabelService { }; } - private formatUri(resource: URI, formater: UriLabelRules): string { + private formatUri(resource: URI, formater: UriLabelRules, forceNoTildify: boolean): string { let label = formater.label.replace(labelMatchingRegexp, match => { switch (match) { case '${scheme}': return resource.scheme; @@ -109,7 +109,7 @@ export class UriLabelService implements IUriLabelService { label = label.charAt(1).toUpperCase() + label.substr(2); } - if (formater.tildify) { + if (formater.tildify && !forceNoTildify) { label = tildify(label, this.environmentService.userHome); } diff --git a/src/vs/workbench/parts/files/electron-browser/fileCommands.ts b/src/vs/workbench/parts/files/electron-browser/fileCommands.ts index 38cb4a1c6b9..a62dc4a0bdf 100644 --- a/src/vs/workbench/parts/files/electron-browser/fileCommands.ts +++ b/src/vs/workbench/parts/files/electron-browser/fileCommands.ts @@ -8,7 +8,6 @@ import * as nls from 'vs/nls'; import * as paths from 'vs/base/common/paths'; import { TPromise } from 'vs/base/common/winjs.base'; -import * as labels from 'vs/base/common/labels'; import URI from 'vs/base/common/uri'; import { toResource, IEditorCommandsContext } from 'vs/workbench/common/editor'; import { IWindowsService, IWindowService } from 'vs/platform/windows/common/windows'; @@ -31,7 +30,7 @@ import { IEditorViewState } from 'vs/editor/common/editorCommon'; import { getCodeEditor } from 'vs/editor/browser/editorBrowser'; import { KeybindingsRegistry, KeybindingWeight } from 'vs/platform/keybinding/common/keybindingsRegistry'; import { KeyMod, KeyCode, KeyChord } from 'vs/base/common/keyCodes'; -import { isWindows, isMacintosh, isLinux } from 'vs/base/common/platform'; +import { isWindows, isMacintosh } from 'vs/base/common/platform'; import { ITextModelService } from 'vs/editor/common/services/resolverService'; import { sequence } from 'vs/base/common/async'; import { getResourceForCommand, getMultiSelectedResources } from 'vs/workbench/parts/files/browser/files'; @@ -42,8 +41,7 @@ import { INotificationService } from 'vs/platform/notification/common/notificati import { EditorContextKeys } from 'vs/editor/common/editorContextKeys'; import { IEditorService, SIDE_GROUP } from 'vs/workbench/services/editor/common/editorService'; import { IEditorGroupsService } from 'vs/workbench/services/group/common/editorGroupsService'; -import { isEqual, basenameOrAuthority } from 'vs/base/common/resources'; -import { ltrim } from 'vs/base/common/strings'; +import { IUriLabelService } from 'vs/platform/uriLabel/common/uriLabel'; // Commands @@ -389,28 +387,12 @@ KeybindingsRegistry.registerCommandAndKeybindingRule({ } }); -function resourcesToClipboard(resources: URI[], clipboardService: IClipboardService, notificationService: INotificationService, contextService?: IWorkspaceContextService): void { +function resourcesToClipboard(resources: URI[], relative: boolean, clipboardService: IClipboardService, notificationService: INotificationService, uriLabelService: IUriLabelService): void { if (resources.length) { const lineDelimiter = isWindows ? '\r\n' : '\n'; - const text = resources.map(resource => { - if (contextService) { - const workspaceFolder = contextService.getWorkspaceFolder(resource); - if (workspaceFolder) { - if (isEqual(workspaceFolder.uri, resource, !isLinux)) { - return basenameOrAuthority(workspaceFolder.uri); - } - - return paths.normalize(ltrim(resource.path.substr(workspaceFolder.uri.path.length), paths.sep), true); - } - } - - if (resource.scheme === Schemas.file) { - return paths.normalize(labels.normalizeDriveLetter(resource.fsPath), true); - } - - return resource.toString(); - }).join(lineDelimiter); + const text = resources.map(resource => uriLabelService.getLabel(resource, relative, true)) + .join(lineDelimiter); clipboardService.writeText(text); } else { notificationService.info(nls.localize('openFileToCopy', "Open a file first to copy its path")); @@ -427,7 +409,7 @@ KeybindingsRegistry.registerCommandAndKeybindingRule({ id: COPY_PATH_COMMAND_ID, handler: (accessor, resource: URI | object) => { const resources = getMultiSelectedResources(resource, accessor.get(IListService), accessor.get(IEditorService)); - resourcesToClipboard(resources, accessor.get(IClipboardService), accessor.get(INotificationService)); + resourcesToClipboard(resources, false, accessor.get(IClipboardService), accessor.get(INotificationService), accessor.get(IUriLabelService)); } }); @@ -441,7 +423,7 @@ KeybindingsRegistry.registerCommandAndKeybindingRule({ id: COPY_RELATIVE_PATH_COMMAND_ID, handler: (accessor, resource: URI | object) => { const resources = getMultiSelectedResources(resource, accessor.get(IListService), accessor.get(IEditorService)); - resourcesToClipboard(resources, accessor.get(IClipboardService), accessor.get(INotificationService), accessor.get(IWorkspaceContextService)); + resourcesToClipboard(resources, true, accessor.get(IClipboardService), accessor.get(INotificationService), accessor.get(IUriLabelService)); } }); @@ -454,7 +436,7 @@ KeybindingsRegistry.registerCommandAndKeybindingRule({ const editorService = accessor.get(IEditorService); const activeInput = editorService.activeEditor; const resources = activeInput && activeInput.getResource() ? [activeInput.getResource()] : []; - resourcesToClipboard(resources, accessor.get(IClipboardService), accessor.get(INotificationService)); + resourcesToClipboard(resources, false, accessor.get(IClipboardService), accessor.get(INotificationService), accessor.get(IUriLabelService)); } }); From 59d0eadabfd8068b82347d4c0cef76dac46b3da9 Mon Sep 17 00:00:00 2001 From: isidor <inikolic@microsoft.com> Date: Wed, 22 Aug 2018 16:17:49 +0200 Subject: [PATCH 1118/1276] debug: npe fixes #56637 --- .../debug/electron-browser/rawDebugSession.ts | 71 +++++++++---------- 1 file changed, 34 insertions(+), 37 deletions(-) diff --git a/src/vs/workbench/parts/debug/electron-browser/rawDebugSession.ts b/src/vs/workbench/parts/debug/electron-browser/rawDebugSession.ts index c98bfcb2347..84f37b4e5c9 100644 --- a/src/vs/workbench/parts/debug/electron-browser/rawDebugSession.ts +++ b/src/vs/workbench/parts/debug/electron-browser/rawDebugSession.ts @@ -427,47 +427,44 @@ export class RawDebugSession implements IRawSession { } private dispatchRequest(request: DebugProtocol.Request): void { + const response: DebugProtocol.Response = { + type: 'response', + seq: 0, + command: request.command, + request_seq: request.seq, + success: true + }; + const sendResponse = (response) => this.debugAdapter && this.debugAdapter.sendResponse(response); - if (this.debugAdapter) { + if (request.command === 'runInTerminal') { - const response: DebugProtocol.Response = { - type: 'response', - seq: 0, - command: request.command, - request_seq: request.seq, - success: true - }; - - if (request.command === 'runInTerminal') { - - this._debugger.runInTerminal(<DebugProtocol.RunInTerminalRequestArguments>request.arguments).then(_ => { - response.body = {}; - this.debugAdapter.sendResponse(response); - }, err => { - response.success = false; - response.message = err.message; - this.debugAdapter.sendResponse(response); - }); - - } else if (request.command === 'handshake') { - try { - const vsda = <any>require.__$__nodeRequire('vsda'); - const obj = new vsda.signer(); - const sig = obj.sign(request.arguments.value); - response.body = { - signature: sig - }; - this.debugAdapter.sendResponse(response); - } catch (e) { - response.success = false; - response.message = e.message; - this.debugAdapter.sendResponse(response); - } - } else { + this._debugger.runInTerminal(<DebugProtocol.RunInTerminalRequestArguments>request.arguments).then(_ => { + response.body = {}; + sendResponse(response); + }, err => { response.success = false; - response.message = `unknown request '${request.command}'`; - this.debugAdapter.sendResponse(response); + response.message = err.message; + sendResponse(response); + }); + + } else if (request.command === 'handshake') { + try { + const vsda = <any>require.__$__nodeRequire('vsda'); + const obj = new vsda.signer(); + const sig = obj.sign(request.arguments.value); + response.body = { + signature: sig + }; + sendResponse(response); + } catch (e) { + response.success = false; + response.message = e.message; + sendResponse(response); } + } else { + response.success = false; + response.message = `unknown request '${request.command}'`; + sendResponse(response); } } From 07c6df15a4ce8ecabd82ae9f5fd9bbbde850836d Mon Sep 17 00:00:00 2001 From: isidor <inikolic@microsoft.com> Date: Wed, 22 Aug 2018 16:27:05 +0200 Subject: [PATCH 1119/1276] use the e.message as an error variable name fixes #56996 --- src/vs/workbench/parts/debug/common/debugModel.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vs/workbench/parts/debug/common/debugModel.ts b/src/vs/workbench/parts/debug/common/debugModel.ts index 6b8a4ef7cff..4ff1423918e 100644 --- a/src/vs/workbench/parts/debug/common/debugModel.ts +++ b/src/vs/workbench/parts/debug/common/debugModel.ts @@ -194,7 +194,7 @@ export class ExpressionContainer implements IExpressionContainer { return response && response.body && response.body.variables ? distinct(response.body.variables.filter(v => !!v && isString(v.name)), v => v.name).map( v => new Variable(this.session, this, v.variablesReference, v.name, v.evaluateName, v.value, v.namedVariables, v.indexedVariables, v.presentationHint, v.type) ) : []; - }, (e: Error) => [new Variable(this.session, this, 0, null, e.message, '', 0, 0, { kind: 'virtual' }, null, false)]); + }, (e: Error) => [new Variable(this.session, this, 0, e.message, e.message, '', 0, 0, { kind: 'virtual' }, null, false)]); } // The adapter explicitly sents the children count of an expression only if there are lots of children which should be chunked. From f08007bf9dc0654ea5e400e54423276759ad5241 Mon Sep 17 00:00:00 2001 From: Sandeep Somavarapu <sasomava@microsoft.com> Date: Wed, 22 Aug 2018 16:49:49 +0200 Subject: [PATCH 1120/1276] Fix #54495 --- .../browser/viewsContainersExtensionPoint.ts | 10 +- .../parts/activitybar/activitybarPart.ts | 43 +++--- .../workbench/browser/parts/compositeBar.ts | 141 ++++++++++-------- .../browser/parts/panel/panelPart.ts | 2 +- src/vs/workbench/browser/parts/views/views.ts | 2 +- .../progress/test/progressService.test.ts | 4 + .../services/viewlet/browser/viewlet.ts | 5 + .../viewlet/browser/viewletService.ts | 2 +- 8 files changed, 117 insertions(+), 92 deletions(-) diff --git a/src/vs/workbench/api/browser/viewsContainersExtensionPoint.ts b/src/vs/workbench/api/browser/viewsContainersExtensionPoint.ts index fc67667e524..ae49565113f 100644 --- a/src/vs/workbench/api/browser/viewsContainersExtensionPoint.ts +++ b/src/vs/workbench/api/browser/viewsContainersExtensionPoint.ts @@ -94,6 +94,7 @@ class ViewsContainersExtensionHandler implements IWorkbenchContribution { } private handleAndRegisterCustomViewContainers() { + let order = TEST_VIEW_CONTAINER_ORDER + 1; viewsContainersExtensionPoint.setHandler((extensions) => { for (let extension of extensions) { const { value, collector } = extension; @@ -103,7 +104,7 @@ class ViewsContainersExtensionHandler implements IWorkbenchContribution { } switch (entry.key) { case 'activitybar': - this.registerCustomViewContainers(entry.value, extension.description); + order = this.registerCustomViewContainers(entry.value, extension.description, order); break; } }); @@ -139,12 +140,13 @@ class ViewsContainersExtensionHandler implements IWorkbenchContribution { return true; } - private registerCustomViewContainers(containers: IUserFriendlyViewsContainerDescriptor[], extension: IExtensionDescription) { - containers.forEach((descriptor, index) => { + private registerCustomViewContainers(containers: IUserFriendlyViewsContainerDescriptor[], extension: IExtensionDescription, order: number): number { + containers.forEach(descriptor => { const cssClass = `extensionViewlet-${descriptor.id}`; const icon = resources.joinPath(extension.extensionLocation, descriptor.icon); - this.registerCustomViewlet({ id: `workbench.view.extension.${descriptor.id}`, title: descriptor.title, icon }, TEST_VIEW_CONTAINER_ORDER + index + 1, cssClass, extension.id); + this.registerCustomViewlet({ id: `workbench.view.extension.${descriptor.id}`, title: descriptor.title, icon }, order++, cssClass, extension.id); }); + return order; } private registerCustomViewlet(descriptor: IUserFriendlyViewsContainerDescriptor2, order: number, cssClass: string, extensionId: string): void { diff --git a/src/vs/workbench/browser/parts/activitybar/activitybarPart.ts b/src/vs/workbench/browser/parts/activitybar/activitybarPart.ts index 52d0ff4ccf3..70aa55141f3 100644 --- a/src/vs/workbench/browser/parts/activitybar/activitybarPart.ts +++ b/src/vs/workbench/browser/parts/activitybar/activitybarPart.ts @@ -87,20 +87,15 @@ export class ActivitybarPart extends Part { overflowActionSize: ActivitybarPart.ACTION_HEIGHT })); - const previousState = this.storageService.get(ActivitybarPart.PLACEHOLDER_VIEWLETS, StorageScope.GLOBAL, void 0); - if (previousState) { - let parsedPreviousState = <IPlaceholderComposite[]>JSON.parse(previousState); - parsedPreviousState.forEach((s) => { - if (typeof s.iconUrl === 'object') { - s.iconUrl = URI.revive(s.iconUrl); - } else { - s.iconUrl = void 0; - } - }); - this.placeholderComposites = parsedPreviousState; - } else { - this.placeholderComposites = this.compositeBar.getCompositesFromStorage().map(id => (<IPlaceholderComposite>{ id, iconUrl: void 0 })); - } + const previousState = this.storageService.get(ActivitybarPart.PLACEHOLDER_VIEWLETS, StorageScope.GLOBAL, '[]'); + this.placeholderComposites = <IPlaceholderComposite[]>JSON.parse(previousState); + this.placeholderComposites.forEach((s) => { + if (typeof s.iconUrl === 'object') { + s.iconUrl = URI.revive(s.iconUrl); + } else { + s.iconUrl = void 0; + } + }); this.registerListeners(); this.updateCompositebar(); @@ -119,7 +114,7 @@ export class ActivitybarPart extends Part { if (enabled) { this.compositeBar.addComposite(this.viewletService.getViewlet(id)); } else { - this.removeComposite(id); + this.removeComposite(id, true); } })); @@ -127,7 +122,7 @@ export class ActivitybarPart extends Part { } private onDidRegisterExtensions(): void { - this.removeNotExistingPlaceholderComposites(); + this.removeNotExistingComposites(); this.updateCompositebar(); } @@ -283,17 +278,21 @@ export class ActivitybarPart extends Part { } } - private removeNotExistingPlaceholderComposites(): void { - const viewlets = this.viewletService.getViewlets(); + private removeNotExistingComposites(): void { + const viewlets = this.viewletService.getAllViewlets(); for (const { id } of this.placeholderComposites) { if (viewlets.every(viewlet => viewlet.id !== id)) { - this.removeComposite(id); + this.removeComposite(id, false); } } } - private removeComposite(compositeId: string): void { - this.compositeBar.removeComposite(compositeId); + private removeComposite(compositeId: string, hide: boolean): void { + if (hide) { + this.compositeBar.hideComposite(compositeId); + } else { + this.compositeBar.removeComposite(compositeId); + } const compositeActions = this.compositeActions[compositeId]; if (compositeActions) { compositeActions.activityAction.dispose(); @@ -337,7 +336,7 @@ export class ActivitybarPart extends Part { } shutdown(): void { - const state = this.viewletService.getViewlets().map(viewlet => ({ id: viewlet.id, iconUrl: viewlet.iconUrl })); + const state = this.viewletService.getAllViewlets().map(({ id, iconUrl }) => ({ id, iconUrl })); this.storageService.store(ActivitybarPart.PLACEHOLDER_VIEWLETS, JSON.stringify(state), StorageScope.GLOBAL); super.shutdown(); diff --git a/src/vs/workbench/browser/parts/compositeBar.ts b/src/vs/workbench/browser/parts/compositeBar.ts index 8731222e1fe..266ad88a156 100644 --- a/src/vs/workbench/browser/parts/compositeBar.ts +++ b/src/vs/workbench/browser/parts/compositeBar.ts @@ -20,6 +20,7 @@ import { Dimension, $, addDisposableListener, EventType, EventHelper } from 'vs/ import { StandardMouseEvent } from 'vs/base/browser/mouseEvent'; import { IContextMenuService } from 'vs/platform/contextview/browser/contextView'; import { Widget } from 'vs/base/browser/ui/widget'; +import { isUndefinedOrNull } from 'vs/base/common/types'; export interface ICompositeBarOptions { icon: boolean; @@ -46,28 +47,22 @@ export class CompositeBar extends Widget implements ICompositeBar { private compositeOverflowActionItem: CompositeOverflowActivityActionItem; private model: CompositeBarModel; - private storedState: ISerializedCompositeBarItem[]; private visibleComposites: string[]; private compositeSizeInBar: Map<string, number>; constructor( private options: ICompositeBarOptions, @IInstantiationService private instantiationService: IInstantiationService, - @IStorageService private storageService: IStorageService, + @IStorageService storageService: IStorageService, @IContextMenuService private contextMenuService: IContextMenuService ) { super(); - this.model = new CompositeBarModel(options); - this.storedState = this.loadCompositeItemsFromStorage(); + this.model = new CompositeBarModel(options, storageService); this.visibleComposites = []; this.compositeSizeInBar = new Map<string, number>(); } - getCompositesFromStorage(): string[] { - return this.storedState.map(s => s.id); - } - create(parent: HTMLElement): HTMLElement { const actionBarDiv = parent.appendChild($('.composite-bar')); this.compositeSwitcherBar = this._register(new ActionBar(actionBarDiv, { @@ -93,7 +88,7 @@ export class CompositeBar extends Widget implements ICompositeBar { EventHelper.stop(e, true); CompositeActionItem.clearDraggedComposite(); - const targetItem = this.model.items[this.model.items.length - 1]; + const targetItem = this.model.visibleItems[this.model.visibleItems.length - 1]; if (targetItem && targetItem.id !== draggedCompositeId) { this.move(draggedCompositeId, targetItem.id); } @@ -113,38 +108,17 @@ export class CompositeBar extends Widget implements ICompositeBar { if (this.compositeSizeInBar.size === 0) { // Compute size of each composite by getting the size from the css renderer // Size is later used for overflow computation - this.computeSizes(this.model.items); + this.computeSizes(this.model.visibleItems); } this.updateCompositeSwitcher(); } addComposite({ id, name, order }: { id: string; name: string, order: number }): void { - const state = this.storedState.filter(s => s.id === id)[0]; - const pinned = state ? state.pinned : true; - let index = order >= 0 ? order : this.model.items.length; - - if (state) { - // Find the index by looking its previous item - index = 0; - for (let i = this.storedState.indexOf(state) - 1; i >= 0; i--) { - const previousItemId = this.storedState[i].id; - const previousItemIndex = this.model.findIndex(previousItemId); - if (previousItemIndex !== -1) { - index = previousItemIndex + 1; - break; - } - } - } - // Add to the model - if (this.model.add(id, name, order, index)) { + if (this.model.add(id, name, order)) { this.computeSizes([this.model.findItem(id)]); - if (pinned) { - this.pin(id); - } else { - this.updateCompositeSwitcher(); - } + this.updateCompositeSwitcher(); } } @@ -161,6 +135,12 @@ export class CompositeBar extends Widget implements ICompositeBar { } } + hideComposite(id: string): void { + if (this.model.hide(id)) { + this.updateCompositeSwitcher(); + } + } + activateComposite(id: string): void { const previousActiveItem = this.model.activeItem; if (this.model.activate(id)) { @@ -282,7 +262,7 @@ export class CompositeBar extends Widget implements ICompositeBar { return; // We have not been rendered yet so there is nothing to update. } - let compositesToShow = this.model.items.filter(item => + let compositesToShow = this.model.visibleItems.filter(item => item.pinned || (this.model.activeItem && this.model.activeItem.id === item.id) /* Show the active composite even if it is not pinned */ ).map(item => item.id); @@ -385,11 +365,11 @@ export class CompositeBar extends Widget implements ICompositeBar { } // Persist - this.saveCompositeItems(); + this.model.saveState(); } private getOverflowingComposites(): { id: string, name: string }[] { - let overflowingIds = this.model.items.filter(item => item.pinned).map(item => item.id); + let overflowingIds = this.model.visibleItems.filter(item => item.pinned).map(item => item.id); // Show the active composite even if it is not pinned if (this.model.activeItem && !this.model.activeItem.pinned) { @@ -397,13 +377,13 @@ export class CompositeBar extends Widget implements ICompositeBar { } overflowingIds = overflowingIds.filter(compositeId => this.visibleComposites.indexOf(compositeId) === -1); - return this.model.items.filter(c => overflowingIds.indexOf(c.id) !== -1); + return this.model.visibleItems.filter(c => overflowingIds.indexOf(c.id) !== -1); } private showContextMenu(e: MouseEvent): void { EventHelper.stop(e, true); const event = new StandardMouseEvent(e); - const actions: IAction[] = this.model.items + const actions: IAction[] = this.model.visibleItems .map(({ id, name, activityAction }) => (<IAction>{ id, label: name, @@ -427,24 +407,13 @@ export class CompositeBar extends Widget implements ICompositeBar { getActions: () => TPromise.as(actions), }); } - - private loadCompositeItemsFromStorage(): ISerializedCompositeBarItem[] { - const storedStates = <Array<string | ISerializedCompositeBarItem>>JSON.parse(this.storageService.get(this.options.storageId, StorageScope.GLOBAL, '[]')); - const compositeStates = <ISerializedCompositeBarItem[]>storedStates.map(c => - typeof c === 'string' /* migration from pinned states to composites states */ ? { id: c, pinned: true } : c); - return compositeStates; - } - - private saveCompositeItems(): void { - this.storedState = this.model.toJSON(); - this.storageService.store(this.options.storageId, JSON.stringify(this.storedState), StorageScope.GLOBAL); - } } interface ISerializedCompositeBarItem { id: string; pinned: boolean; order: number; + visible: boolean; } interface ICompositeBarItem extends ISerializedCompositeBarItem { @@ -456,15 +425,28 @@ interface ICompositeBarItem extends ISerializedCompositeBarItem { class CompositeBarModel { - readonly items: ICompositeBarItem[] = []; + private readonly options: ICompositeBarOptions; + readonly items: ICompositeBarItem[]; + activeItem: ICompositeBarItem; - constructor(private options: ICompositeBarOptions) { } + constructor( + options: ICompositeBarOptions, + private storageService: IStorageService, + ) { + this.options = options; + this.items = this.loadItemStates(); + } - private createCompositeBarItem(id: string, name: string, order: number, pinned: boolean): ICompositeBarItem { + get visibleItems(): ICompositeBarItem[] { + return this.items.filter(item => item.visible); + } + + private createCompositeBarItem(id: string, name: string, order: number, pinned: boolean, visible: boolean): ICompositeBarItem { const options = this.options; return { - id, name, pinned, order, activity: [], + id, name, pinned, order, visible, + activity: [], get activityAction() { return options.getActivityAction(id); }, @@ -474,20 +456,31 @@ class CompositeBarModel { }; } - add(id: string, name: string, order: number, index: number): boolean { + add(id: string, name: string, order: number): boolean { const item = this.findItem(id); if (item) { - item.order = order; + let changed = false; item.name = name; - return false; + if (!isUndefinedOrNull(order)) { + changed = item.order !== order; + item.order = order; + } + if (!item.visible) { + item.visible = true; + changed = true; + } + return changed; } else { - if (index === void 0) { - index = 0; + const item = this.createCompositeBarItem(id, name, order, false, true); + if (isUndefinedOrNull(order)) { + this.items.push(item); + } else { + let index = 0; while (index < this.items.length && this.items[index].order < order) { index++; } + this.items.splice(index, 0, item); } - this.items.splice(index, 0, this.createCompositeBarItem(id, name, order, false)); return true; } } @@ -502,6 +495,19 @@ class CompositeBarModel { return false; } + hide(id: string): boolean { + for (const item of this.items) { + if (item.id === id) { + if (item.visible) { + item.visible = false; + return true; + } + return false; + } + } + return false; + } + move(compositeId: string, toCompositeId: string): boolean { const fromIndex = this.findIndex(compositeId); @@ -610,7 +616,7 @@ class CompositeBarModel { return this.items.filter(item => item.id === id)[0]; } - findIndex(id: string): number { + private findIndex(id: string): number { for (let index = 0; index < this.items.length; index++) { if (this.items[index].id === id) { return index; @@ -619,7 +625,16 @@ class CompositeBarModel { return -1; } - toJSON(): ISerializedCompositeBarItem[] { - return this.items.map(({ id, pinned, order }) => ({ id, pinned, order })); + private loadItemStates(): ICompositeBarItem[] { + const storedStates = <Array<string | ISerializedCompositeBarItem>>JSON.parse(this.storageService.get(this.options.storageId, StorageScope.GLOBAL, '[]')); + return <ICompositeBarItem[]>storedStates.map(c => { + const serialized: ISerializedCompositeBarItem = typeof c === 'string' /* migration from pinned states to composites states */ ? { id: c, pinned: true, order: void 0, visible: true } : c; + return this.createCompositeBarItem(serialized.id, void 0, serialized.order, serialized.pinned, isUndefinedOrNull(serialized.visible) ? true : serialized.visible); + }); + } + + saveState(): void { + const serialized = this.items.map(({ id, pinned, order, visible }) => ({ id, pinned, order, visible })); + this.storageService.store(this.options.storageId, JSON.stringify(serialized), StorageScope.GLOBAL); } } diff --git a/src/vs/workbench/browser/parts/panel/panelPart.ts b/src/vs/workbench/browser/parts/panel/panelPart.ts index 13df252c82f..1880db49212 100644 --- a/src/vs/workbench/browser/parts/panel/panelPart.ts +++ b/src/vs/workbench/browser/parts/panel/panelPart.ts @@ -281,7 +281,7 @@ export class PanelPart extends CompositePart<Panel> implements IPanelService { } private removeComposite(compositeId: string): void { - this.compositeBar.removeComposite(compositeId); + this.compositeBar.hideComposite(compositeId); const compositeActions = this.compositeActions[compositeId]; if (compositeActions) { compositeActions.activityAction.dispose(); diff --git a/src/vs/workbench/browser/parts/views/views.ts b/src/vs/workbench/browser/parts/views/views.ts index 612b59f257f..2a49c79c496 100644 --- a/src/vs/workbench/browser/parts/views/views.ts +++ b/src/vs/workbench/browser/parts/views/views.ts @@ -496,7 +496,7 @@ export class ViewsService extends Disposable implements IViewsService { const viewContainersRegistry = Registry.as<IViewContainersRegistry>(ViewContainerExtensions.ViewContainersRegistry); viewContainersRegistry.all.forEach(viewContainer => this.onDidRegisterViewContainer(viewContainer)); this._register(viewContainersRegistry.onDidRegister(viewContainer => this.onDidRegisterViewContainer(viewContainer))); - this._register(Registry.as<ViewletRegistry>(ViewletExtensions.Viewlets).onDidRegister(viewlet => this.viewletService.setViewletEnablement(viewlet.id, this.storageService.getBoolean(`viewservice.${viewlet.id}.enablement`, StorageScope.GLOBAL, viewlet.id !== TEST_VIEW_CONTAINER_ID)))); + this._register(Registry.as<ViewletRegistry>(ViewletExtensions.Viewlets).onDidRegister(viewlet => this.viewletService.setViewletEnablement(viewlet.id, this.storageService.getBoolean(`viewservice.${viewlet.id}.enablement`, StorageScope.WORKSPACE, viewlet.id !== TEST_VIEW_CONTAINER_ID)))); } openView(id: string, focus: boolean): TPromise<IView> { diff --git a/src/vs/workbench/services/progress/test/progressService.test.ts b/src/vs/workbench/services/progress/test/progressService.test.ts index f1f23e0cea1..67dd539396e 100644 --- a/src/vs/workbench/services/progress/test/progressService.test.ts +++ b/src/vs/workbench/services/progress/test/progressService.test.ts @@ -40,6 +40,10 @@ class TestViewletService implements IViewletService { return []; } + public getAllViewlets(): ViewletDescriptor[] { + return []; + } + public getActiveViewlet(): IViewlet { return activeViewlet; } diff --git a/src/vs/workbench/services/viewlet/browser/viewlet.ts b/src/vs/workbench/services/viewlet/browser/viewlet.ts index 02006a2397a..a6903bb9fb9 100644 --- a/src/vs/workbench/services/viewlet/browser/viewlet.ts +++ b/src/vs/workbench/services/viewlet/browser/viewlet.ts @@ -41,6 +41,11 @@ export interface IViewletService { */ getViewlet(id: string): ViewletDescriptor; + /** + * Returns all viewlets + */ + getAllViewlets(): ViewletDescriptor[]; + /** * Returns all enabled viewlets */ diff --git a/src/vs/workbench/services/viewlet/browser/viewletService.ts b/src/vs/workbench/services/viewlet/browser/viewletService.ts index 979b3ca5f19..30f05343f48 100644 --- a/src/vs/workbench/services/viewlet/browser/viewletService.ts +++ b/src/vs/workbench/services/viewlet/browser/viewletService.ts @@ -92,7 +92,7 @@ export class ViewletService extends Disposable implements IViewletService { .filter(v => v.enabled); } - private getAllViewlets(): ViewletDescriptor[] { + getAllViewlets(): ViewletDescriptor[] { return this.viewletRegistry.getViewlets() .sort((v1, v2) => v1.order - v2.order); } From 6ec4953341391b7c76ae53ba43a61116b56f5ab0 Mon Sep 17 00:00:00 2001 From: Sandeep Somavarapu <sasomava@microsoft.com> Date: Wed, 22 Aug 2018 17:06:31 +0200 Subject: [PATCH 1121/1276] Description of resource should be the parent of the resource --- .../parts/markers/electron-browser/markersTreeViewer.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/vs/workbench/parts/markers/electron-browser/markersTreeViewer.ts b/src/vs/workbench/parts/markers/electron-browser/markersTreeViewer.ts index 20ca3e0b0d0..60deb20c1e7 100644 --- a/src/vs/workbench/parts/markers/electron-browser/markersTreeViewer.ts +++ b/src/vs/workbench/parts/markers/electron-browser/markersTreeViewer.ts @@ -22,6 +22,7 @@ import { IDisposable } from 'vs/base/common/lifecycle'; import { ActionBar, IActionItemProvider } from 'vs/base/browser/ui/actionbar/actionbar'; import { QuickFixAction } from 'vs/workbench/parts/markers/electron-browser/markersPanelActions'; import { IUriLabelService } from 'vs/platform/uriLabel/common/uriLabel'; +import { dirname } from 'vs/base/common/resources'; interface IResourceMarkersTemplateData { resourceLabel: ResourceLabel; @@ -208,7 +209,7 @@ export class Renderer implements IRenderer { if (templateData.resourceLabel instanceof FileLabel) { templateData.resourceLabel.setFile(element.uri, { matches: element.uriMatches }); } else { - templateData.resourceLabel.setLabel({ name: element.name, description: this.uriLabelService.getLabel(element.uri, true), resource: element.uri }, { matches: element.uriMatches }); + templateData.resourceLabel.setLabel({ name: element.name, description: this.uriLabelService.getLabel(dirname(element.uri), true), resource: element.uri }, { matches: element.uriMatches }); } (<IResourceMarkersTemplateData>templateData).count.setCount(element.filteredCount); } From 75f49fcd33f2815df4eceff5750b324931cae381 Mon Sep 17 00:00:00 2001 From: Johannes Rieken <johannes.rieken@gmail.com> Date: Wed, 22 Aug 2018 17:31:54 +0200 Subject: [PATCH 1122/1276] perf - fix loader stats --- src/typings/require.d.ts | 25 +- .../performance/electron-browser/actions.ts | 295 ++++++------------ 2 files changed, 122 insertions(+), 198 deletions(-) diff --git a/src/typings/require.d.ts b/src/typings/require.d.ts index 6278f80dfe7..028ee087293 100644 --- a/src/typings/require.d.ts +++ b/src/typings/require.d.ts @@ -3,6 +3,28 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ +declare const enum LoaderEventType { + LoaderAvailable = 1, + + BeginLoadingScript = 10, + EndLoadingScriptOK = 11, + EndLoadingScriptError = 12, + + BeginInvokeFactory = 21, + EndInvokeFactory = 22, + + NodeBeginEvaluatingScript = 31, + NodeEndEvaluatingScript = 32, + + NodeBeginNativeRequire = 33, + NodeEndNativeRequire = 34 +} + +declare class LoaderEvent { + readonly type: LoaderEventType; + readonly timestamp: number; + readonly detail: string; +} declare var define: { (moduleName: string, dependencies: string[], callback: (...args: any[]) => any): any; @@ -20,4 +42,5 @@ declare var require: { config(data: any): any; onError: Function; __$__nodeRequire<T>(moduleName: string): T; -}; \ No newline at end of file + getStats(): ReadonlyArray<LoaderEvent> +}; diff --git a/src/vs/workbench/parts/performance/electron-browser/actions.ts b/src/vs/workbench/parts/performance/electron-browser/actions.ts index b6824084675..178a2e15d7e 100644 --- a/src/vs/workbench/parts/performance/electron-browser/actions.ts +++ b/src/vs/workbench/parts/performance/electron-browser/actions.ts @@ -23,30 +23,7 @@ import { Registry } from 'vs/platform/registry/common/platform'; import { IWorkbenchActionRegistry, Extensions } from 'vs/workbench/common/actions'; import { SyncActionDescriptor } from 'vs/platform/actions/common/actions'; import { forEach } from 'vs/base/common/collections'; - -/* Copied from loader.ts */ -enum LoaderEventType { - LoaderAvailable = 1, - - BeginLoadingScript = 10, - EndLoadingScriptOK = 11, - EndLoadingScriptError = 12, - - BeginInvokeFactory = 21, - EndInvokeFactory = 22, - - NodeBeginEvaluatingScript = 31, - NodeEndEvaluatingScript = 32, - - NodeBeginNativeRequire = 33, - NodeEndNativeRequire = 34 -} - -interface ILoaderEvent { - type: LoaderEventType; - timestamp: number; - detail: string; -} +import { mergeSort } from 'vs/base/common/arrays'; class Info { @@ -75,6 +52,95 @@ class Info { private constructor(readonly duration: number, readonly process: string, readonly info: string | boolean = '') { } } +class LoaderStat { + + static getLoaderStats() { + + let seq = 1; + const amdLoad = new Map<string, LoaderStat>(); + const amdInvoke = new Map<string, LoaderStat>(); + const nodeRequire = new Map<string, LoaderStat>(); + const nodeEval = new Map<string, LoaderStat>(); + + function mark(map: Map<string, LoaderStat>, stat: LoaderEvent) { + if (map.has(stat.detail)) { + // console.warn('BAD events, DOUBLE start', stat); + // map.delete(stat.detail); + return; + } + map.set(stat.detail, new LoaderStat(-stat.timestamp, seq++)); + } + + function diff(map: Map<string, LoaderStat>, stat: LoaderEvent) { + let obj = map.get(stat.detail); + if (!obj) { + // console.warn('BAD events, end WITHOUT start', stat); + // map.delete(stat.detail); + return; + } + if (obj.duration >= 0) { + // console.warn('BAD events, DOUBLE end', stat); + // map.delete(stat.detail); + return; + } + obj.duration = (obj.duration + stat.timestamp); + } + + const stats = mergeSort(require.getStats().slice(0), (a, b) => a.timestamp - b.timestamp); + + for (const stat of stats) { + switch (stat.type) { + case LoaderEventType.BeginLoadingScript: + mark(amdLoad, stat); + break; + case LoaderEventType.EndLoadingScriptOK: + case LoaderEventType.EndLoadingScriptError: + diff(amdLoad, stat); + break; + + case LoaderEventType.BeginInvokeFactory: + mark(amdInvoke, stat); + break; + case LoaderEventType.EndInvokeFactory: + diff(amdInvoke, stat); + break; + + case LoaderEventType.NodeBeginNativeRequire: + mark(nodeRequire, stat); + break; + case LoaderEventType.NodeEndNativeRequire: + diff(nodeRequire, stat); + break; + + case LoaderEventType.NodeBeginEvaluatingScript: + mark(nodeEval, stat); + break; + case LoaderEventType.NodeEndEvaluatingScript: + diff(nodeEval, stat); + break; + } + } + + function toObject(map: Map<string, any>): { [name: string]: any } { + const result = Object.create(null); + map.forEach((value, index) => result[index] = value); + return result; + } + + let nodeRequireTotal = 0; + nodeRequire.forEach(value => nodeRequireTotal += value.duration); + + return { + amdLoad: toObject(amdLoad), + amdInvoke: toObject(amdInvoke), + nodeRequire: toObject(nodeRequire), + nodeEval: toObject(nodeEval), + nodeRequireTotal + }; + } + + constructor(public duration: number, public seq: number) { } +} export class ShowStartupPerformance extends Action { @@ -114,19 +180,15 @@ export class ShowStartupPerformance extends Action { console.log(`Screen Reader Active: ${metrics.hasAccessibilitySupport} `); console.log(`Empty Workspace: ${metrics.emptyWorkbench} `); - let nodeModuleLoadTime: number; - if (this.environmentService.performance) { - const nodeModuleTimes = this.analyzeNodeModulesLoadTimes(); - nodeModuleLoadTime = nodeModuleTimes.duration; - } - console.table(Info.getTimerInfo(metrics, nodeModuleLoadTime)); + const loaderStats = this.environmentService.performance && LoaderStat.getLoaderStats(); - if (this.environmentService.performance) { - const data = this.analyzeLoaderStats(); - for (let type in data) { - console.groupCollapsed(`Loader: ${type} `); - console.table(data[type]); + console.table(Info.getTimerInfo(metrics, loaderStats && loaderStats.nodeRequireTotal)); + + if (loaderStats) { + for (const key in loaderStats) { + console.groupCollapsed(`Loader: ${key} `); + console.table(loaderStats[key]); console.groupEnd(); } } @@ -157,151 +219,6 @@ export class ShowStartupPerformance extends Action { return TPromise.as(true); } - - private analyzeNodeModulesLoadTimes(): { table: any[], duration: number } { - const stats = <ILoaderEvent[]>(<any>require).getStats(); - const result = []; - - let total = 0; - - for (let i = 0, len = stats.length; i < len; i++) { - if (stats[i].type === LoaderEventType.NodeEndNativeRequire) { - if (stats[i - 1].type === LoaderEventType.NodeBeginNativeRequire && stats[i - 1].detail === stats[i].detail) { - const entry: any = {}; - const dur = (stats[i].timestamp - stats[i - 1].timestamp); - entry['Event'] = 'nodeRequire ' + stats[i].detail; - entry['Took (ms)'] = dur.toFixed(2); - total += dur; - entry['Start (ms)'] = '**' + stats[i - 1].timestamp.toFixed(2); - entry['End (ms)'] = '**' + stats[i - 1].timestamp.toFixed(2); - result.push(entry); - } - } - } - - if (total > 0) { - result.push({ Event: '------------------------------------------------------' }); - - const entry: any = {}; - entry['Event'] = '[renderer] total require() node_modules'; - entry['Took (ms)'] = total.toFixed(2); - entry['Start (ms)'] = '**'; - entry['End (ms)'] = '**'; - result.push(entry); - } - - return { table: result, duration: Math.round(total) }; - } - - private analyzeLoaderStats(): { [type: string]: any[] } { - const stats = <ILoaderEvent[]>(<any>require).getStats().slice(0).sort((a: ILoaderEvent, b: ILoaderEvent) => { - if (a.detail < b.detail) { - return -1; - } else if (a.detail > b.detail) { - return 1; - } else if (a.type < b.type) { - return -1; - } else if (a.type > b.type) { - return 1; - } else { - return 0; - } - }); - - class Tick { - - readonly duration: number; - readonly detail: string; - - constructor(private readonly start: ILoaderEvent, private readonly end: ILoaderEvent) { - console.assert(start.detail === end.detail); - - this.duration = this.end.timestamp - this.start.timestamp; - this.detail = start.detail; - } - - toTableObject() { - return { - ['Path']: this.start.detail, - ['Took (ms)']: this.duration.toFixed(2), - // ['Start (ms)']: this.start.timestamp, - // ['End (ms)']: this.end.timestamp - }; - } - - static compareUsingStartTimestamp(a: Tick, b: Tick): number { - if (a.start.timestamp < b.start.timestamp) { - return -1; - } else if (a.start.timestamp > b.start.timestamp) { - return 1; - } else { - return 0; - } - } - } - - const ticks: { [type: number]: Tick[] } = { - [LoaderEventType.BeginLoadingScript]: [], - [LoaderEventType.BeginInvokeFactory]: [], - [LoaderEventType.NodeBeginEvaluatingScript]: [], - [LoaderEventType.NodeBeginNativeRequire]: [], - }; - - for (let i = 1; i < stats.length - 1; i++) { - const stat = stats[i]; - const nextStat = stats[i + 1]; - - if (nextStat.type - stat.type > 2) { - //bad?! - break; - } - - i += 1; - if (ticks[stat.type]) { - ticks[stat.type].push(new Tick(stat, nextStat)); - } - } - - ticks[LoaderEventType.BeginInvokeFactory].sort(Tick.compareUsingStartTimestamp); - ticks[LoaderEventType.BeginInvokeFactory].sort(Tick.compareUsingStartTimestamp); - ticks[LoaderEventType.NodeBeginEvaluatingScript].sort(Tick.compareUsingStartTimestamp); - ticks[LoaderEventType.NodeBeginNativeRequire].sort(Tick.compareUsingStartTimestamp); - - const ret = { - 'Load Script': ticks[LoaderEventType.BeginLoadingScript].map(t => t.toTableObject()), - '(Node) Load Script': ticks[LoaderEventType.NodeBeginNativeRequire].map(t => t.toTableObject()), - 'Eval Script': ticks[LoaderEventType.BeginInvokeFactory].map(t => t.toTableObject()), - '(Node) Eval Script': ticks[LoaderEventType.NodeBeginEvaluatingScript].map(t => t.toTableObject()), - }; - - function total(ticks: Tick[]): number { - let sum = 0; - for (const tick of ticks) { - sum += tick.duration; - } - return sum; - } - - // totals - ret['Load Script'].push({ - ['Path']: 'TOTAL TIME', - ['Took (ms)']: total(ticks[LoaderEventType.BeginLoadingScript]).toFixed(2) - }); - ret['Eval Script'].push({ - ['Path']: 'TOTAL TIME', - ['Took (ms)']: total(ticks[LoaderEventType.BeginInvokeFactory]).toFixed(2) - }); - ret['(Node) Load Script'].push({ - ['Path']: 'TOTAL TIME', - ['Took (ms)']: total(ticks[LoaderEventType.NodeBeginNativeRequire]).toFixed(2) - }); - ret['(Node) Eval Script'].push({ - ['Path']: 'TOTAL TIME', - ['Took (ms)']: total(ticks[LoaderEventType.NodeBeginEvaluatingScript]).toFixed(2) - }); - - return ret; - } } @@ -345,7 +262,7 @@ export class ReportPerformanceIssueAction extends Action { let nodeModuleLoadTime: number; if (this.environmentService.performance) { - nodeModuleLoadTime = this.computeNodeModulesLoadTime(); + nodeModuleLoadTime = LoaderStat.getLoaderStats().nodeRequireTotal; } @@ -374,22 +291,6 @@ ${ this.generatePerformanceTable(metrics, nodeModuleLoadTime)} return `${baseUrl} ${queryStringPrefix} body = ${body} `; } - private computeNodeModulesLoadTime(): number { - const stats = <ILoaderEvent[]>(<any>require).getStats(); - let total = 0; - - for (let i = 0, len = stats.length; i < len; i++) { - if (stats[i].type === LoaderEventType.NodeEndNativeRequire) { - if (stats[i - 1].type === LoaderEventType.NodeBeginNativeRequire && stats[i - 1].detail === stats[i].detail) { - const dur = (stats[i].timestamp - stats[i - 1].timestamp); - total += dur; - } - } - } - - return Math.round(total); - } - private generatePerformanceTable(metrics: IStartupMetrics, nodeModuleLoadTime?: number): string { let tableHeader = `| Component | Task | Duration(ms) | Info | | ---| ---| ---| ---| `; From 9acd33950e9862e7fe5439512ca3c1f50c04d473 Mon Sep 17 00:00:00 2001 From: isidor <inikolic@microsoft.com> Date: Wed, 22 Aug 2018 17:40:25 +0200 Subject: [PATCH 1123/1276] move uriLabelService to be a core service. Configuraion service depends on it, not the other way around --- src/vs/code/electron-main/main.ts | 2 +- .../standalone/browser/simpleServices.ts | 4 +++ src/vs/platform/uriLabel/common/uriLabel.ts | 36 +++++++++++++++++-- .../platform/uriLabel/test/uriLabel.test.ts | 7 ++-- src/vs/workbench/electron-browser/main.ts | 12 ++++--- src/vs/workbench/electron-browser/shell.ts | 5 +++ .../workbench/electron-browser/workbench.ts | 6 ---- .../node/configurationService.ts | 15 +++----- .../configurationEditingService.test.ts | 3 +- .../configurationService.test.ts | 16 ++++++--- .../api/mainThreadEditors.test.ts | 4 +-- .../workbench/test/workbenchTestServices.ts | 2 +- 12 files changed, 76 insertions(+), 36 deletions(-) diff --git a/src/vs/code/electron-main/main.ts b/src/vs/code/electron-main/main.ts index dbe95eb11e2..5f09b85b211 100644 --- a/src/vs/code/electron-main/main.ts +++ b/src/vs/code/electron-main/main.ts @@ -58,7 +58,7 @@ function createServices(args: ParsedArgs, bufferLogService: BufferLogService): I const environmentService = new EnvironmentService(args, process.execPath); const consoleLogService = new ConsoleLogMainService(getLogLevel(environmentService)); const logService = new MultiplexLogService([consoleLogService, bufferLogService]); - const uriLabelService = new UriLabelService(environmentService, undefined); + const uriLabelService = new UriLabelService(environmentService); process.once('exit', () => logService.dispose()); diff --git a/src/vs/editor/standalone/browser/simpleServices.ts b/src/vs/editor/standalone/browser/simpleServices.ts index e73c429819f..46b76c734f8 100644 --- a/src/vs/editor/standalone/browser/simpleServices.ts +++ b/src/vs/editor/standalone/browser/simpleServices.ts @@ -609,6 +609,10 @@ export class SimpleUriLabelService implements IUriLabelService { return resource.path; } + public getWorkspaceLabel(workspace: IWorkspaceIdentifier | URI, options?: { verbose: boolean; }): string { + throw new Error('Not implemented'); + } + public registerFormater(schema: string, formater: UriLabelRules): IDisposable { throw new Error('Not implemented'); } diff --git a/src/vs/platform/uriLabel/common/uriLabel.ts b/src/vs/platform/uriLabel/common/uriLabel.ts index 4cd0e873aa2..f59ae2cb4b0 100644 --- a/src/vs/platform/uriLabel/common/uriLabel.ts +++ b/src/vs/platform/uriLabel/common/uriLabel.ts @@ -13,10 +13,15 @@ import { isEqual, basenameOrAuthority } from 'vs/base/common/resources'; import { isLinux, isWindows } from 'vs/base/common/platform'; import { tildify, getPathLabel } from 'vs/base/common/labels'; import { ltrim } from 'vs/base/common/strings'; +import { IWorkspaceIdentifier, ISingleFolderWorkspaceIdentifier, isSingleFolderWorkspaceIdentifier, WORKSPACE_EXTENSION } from 'vs/platform/workspaces/common/workspaces'; +import { localize } from 'vs/nls'; +import { isParent } from 'vs/platform/files/common/files'; +import { basename, dirname, join } from 'vs/base/common/paths'; export interface IUriLabelService { _serviceBrand: any; getLabel(resource: URI, relative?: boolean, forceNoTildify?: boolean): string; + getWorkspaceLabel(workspace: (IWorkspaceIdentifier | ISingleFolderWorkspaceIdentifier), options?: { verbose: boolean }): string; registerFormater(schema: string, formater: UriLabelRules): IDisposable; onDidRegisterFormater: Event<{ scheme: string, formater: UriLabelRules }>; } @@ -41,18 +46,21 @@ export class UriLabelService implements IUriLabelService { private readonly formaters = new Map<string, UriLabelRules>(); private readonly _onDidRegisterFormater = new Emitter<{ scheme: string, formater: UriLabelRules }>(); + private contextService: IWorkspaceContextService; constructor( @IEnvironmentService private environmentService: IEnvironmentService, - @IWorkspaceContextService private contextService: IWorkspaceContextService ) { } - get onDidRegisterFormater(): Event<{ scheme: string, formater: UriLabelRules }> { return this._onDidRegisterFormater.event; } - getLabel(resource: URI, relative: boolean, forceNoTildify?: boolean): string { + acquireContextService(contextService: IWorkspaceContextService): void { + this.contextService = contextService; + } + + getLabel(resource: URI, relative?: boolean, forceNoTildify?: boolean): string { if (!resource) { return undefined; } @@ -85,6 +93,28 @@ export class UriLabelService implements IUriLabelService { return this.formatUri(resource, formater, forceNoTildify); } + getWorkspaceLabel(workspace: (IWorkspaceIdentifier | ISingleFolderWorkspaceIdentifier), options?: { verbose: boolean }): string { + // Workspace: Single Folder + if (isSingleFolderWorkspaceIdentifier(workspace)) { + // Folder on disk + return options && options.verbose ? this.getLabel(workspace) : basenameOrAuthority(workspace); + } + + // Workspace: Untitled + if (isParent(workspace.configPath, this.environmentService.workspacesHome, !isLinux /* ignore case */)) { + return localize('untitledWorkspace', "Untitled (Workspace)"); + } + + // Workspace: Saved + const filename = basename(workspace.configPath); + const workspaceName = filename.substr(0, filename.length - WORKSPACE_EXTENSION.length - 1); + if (options && options.verbose) { + return localize('workspaceNameVerbose', "{0} (Workspace)", this.getLabel(URI.file(join(dirname(workspace.configPath), workspaceName)))); + } + + return localize('workspaceName', "{0} (Workspace)", workspaceName); + } + registerFormater(scheme: string, formater: UriLabelRules): IDisposable { this.formaters.set(scheme, formater); this._onDidRegisterFormater.fire({ scheme, formater }); diff --git a/src/vs/platform/uriLabel/test/uriLabel.test.ts b/src/vs/platform/uriLabel/test/uriLabel.test.ts index 8b36579e453..4c82a0d0eaf 100644 --- a/src/vs/platform/uriLabel/test/uriLabel.test.ts +++ b/src/vs/platform/uriLabel/test/uriLabel.test.ts @@ -4,7 +4,7 @@ *--------------------------------------------------------------------------------------------*/ import * as assert from 'assert'; -import { IUriLabelService, UriLabelService } from 'vs/platform/uriLabel/common/uriLabel'; +import { UriLabelService } from 'vs/platform/uriLabel/common/uriLabel'; import { TestEnvironmentService, TestContextService } from 'vs/workbench/test/workbenchTestServices'; import { Schemas } from 'vs/base/common/network'; import { TestWorkspace } from 'vs/platform/workspace/test/common/testWorkspace'; @@ -14,10 +14,11 @@ import { isWindows } from 'vs/base/common/platform'; suite('URI Label', () => { - let uriLabelService: IUriLabelService; + let uriLabelService: UriLabelService; setup(() => { - uriLabelService = new UriLabelService(TestEnvironmentService, new TestContextService()); + uriLabelService = new UriLabelService(TestEnvironmentService); + uriLabelService.acquireContextService(new TestContextService()); }); test('file scheme', function () { diff --git a/src/vs/workbench/electron-browser/main.ts b/src/vs/workbench/electron-browser/main.ts index 08edc11b168..43fe84321a2 100644 --- a/src/vs/workbench/electron-browser/main.ts +++ b/src/vs/workbench/electron-browser/main.ts @@ -48,6 +48,7 @@ import { RelayURLService } from 'vs/platform/url/common/urlService'; import { MenubarChannelClient } from 'vs/platform/menubar/node/menubarIpc'; import { IMenubarService } from 'vs/platform/menubar/common/menubar'; import { Schemas } from 'vs/base/common/network'; +import { IUriLabelService, UriLabelService } from 'vs/platform/uriLabel/common/uriLabel'; gracefulFs.gracefulify(fs); // enable gracefulFs @@ -98,13 +99,15 @@ function openWorkbench(configuration: IWindowConfiguration): TPromise<void> { const mainServices = createMainProcessServices(mainProcessClient, configuration); const environmentService = new EnvironmentService(configuration, configuration.execPath); + const uriLabelService = new UriLabelService(environmentService); const logService = createLogService(mainProcessClient, configuration, environmentService); logService.trace('openWorkbench configuration', JSON.stringify(configuration)); // Since the configuration service is one of the core services that is used in so many places, we initialize it // right before startup of the workbench shell to have its data ready for consumers - return createAndInitializeWorkspaceService(configuration, environmentService).then(workspaceService => { + return createAndInitializeWorkspaceService(configuration, environmentService, uriLabelService).then(workspaceService => { const storageService = createStorageService(workspaceService, environmentService); + uriLabelService.acquireContextService(workspaceService); return domContentLoaded().then(() => { @@ -115,7 +118,8 @@ function openWorkbench(configuration: IWindowConfiguration): TPromise<void> { configurationService: workspaceService, environmentService, logService, - storageService + storageService, + uriLabelService }, mainServices, mainProcessClient, configuration); shell.open(); @@ -131,10 +135,10 @@ function openWorkbench(configuration: IWindowConfiguration): TPromise<void> { }); } -function createAndInitializeWorkspaceService(configuration: IWindowConfiguration, environmentService: EnvironmentService): TPromise<WorkspaceService> { +function createAndInitializeWorkspaceService(configuration: IWindowConfiguration, environmentService: EnvironmentService, uriLabelService: IUriLabelService): TPromise<WorkspaceService> { return validateFolderUri(configuration.folderUri, configuration.verbose).then(validatedFolderUri => { - const workspaceService = new WorkspaceService(environmentService); + const workspaceService = new WorkspaceService(environmentService, uriLabelService); return workspaceService.initialize(configuration.workspace || validatedFolderUri || configuration).then(() => workspaceService, error => workspaceService); }); diff --git a/src/vs/workbench/electron-browser/shell.ts b/src/vs/workbench/electron-browser/shell.ts index ae688e469bf..594153f133d 100644 --- a/src/vs/workbench/electron-browser/shell.ts +++ b/src/vs/workbench/electron-browser/shell.ts @@ -98,6 +98,7 @@ import { ExtensionManagementServerService } from 'vs/workbench/services/extensio import { DownloadServiceChannel } from 'vs/platform/download/node/downloadIpc'; import { DefaultURITransformer } from 'vs/base/common/uriIpc'; import { ExtensionGalleryService } from 'vs/platform/extensionManagement/node/extensionGalleryService'; +import { IUriLabelService } from 'vs/platform/uriLabel/common/uriLabel'; /** * Services that we require for the Shell @@ -108,6 +109,7 @@ export interface ICoreServices { environmentService: IEnvironmentService; logService: ILogService; storageService: IStorageService; + uriLabelService: IUriLabelService; } /** @@ -117,6 +119,7 @@ export interface ICoreServices { export class WorkbenchShell extends Disposable { private storageService: IStorageService; private environmentService: IEnvironmentService; + private uriLabelService: IUriLabelService; private logService: ILogService; private configurationService: IConfigurationService; private contextService: IWorkspaceContextService; @@ -145,6 +148,7 @@ export class WorkbenchShell extends Disposable { this.contextService = coreServices.contextService; this.configurationService = coreServices.configurationService; this.environmentService = coreServices.environmentService; + this.uriLabelService = coreServices.uriLabelService; this.logService = coreServices.logService; this.storageService = coreServices.storageService; @@ -316,6 +320,7 @@ export class WorkbenchShell extends Disposable { serviceCollection.set(IWorkspaceContextService, this.contextService); serviceCollection.set(IConfigurationService, this.configurationService); serviceCollection.set(IEnvironmentService, this.environmentService); + serviceCollection.set(IUriLabelService, this.uriLabelService); serviceCollection.set(ILogService, this._register(this.logService)); serviceCollection.set(IStorageService, this.storageService); diff --git a/src/vs/workbench/electron-browser/workbench.ts b/src/vs/workbench/electron-browser/workbench.ts index 5a3ee22e21c..51f863b673a 100644 --- a/src/vs/workbench/electron-browser/workbench.ts +++ b/src/vs/workbench/electron-browser/workbench.ts @@ -116,7 +116,6 @@ import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry'; import { TelemetryService } from 'vs/platform/telemetry/common/telemetryService'; import { WorkbenchThemeService } from 'vs/workbench/services/themes/electron-browser/workbenchThemeService'; import { IWorkbenchThemeService } from 'vs/workbench/services/themes/common/workbenchThemeService'; -import { IUriLabelService, UriLabelService } from 'vs/platform/uriLabel/common/uriLabel'; interface WorkbenchParams { configuration: IWindowConfiguration; @@ -336,11 +335,6 @@ export class Workbench extends Disposable implements IPartService { // Clipboard serviceCollection.set(IClipboardService, new ClipboardService()); - // Uri Display - const uriLabelService = new UriLabelService(this.environmentService, this.contextService); - serviceCollection.set(IUriLabelService, uriLabelService); - this.configurationService.acquireUriLabelService(uriLabelService); - // Status bar this.statusbarPart = this.instantiationService.createInstance(StatusbarPart, Identifiers.STATUSBAR_PART); this._register(toDisposable(() => this.statusbarPart.shutdown())); diff --git a/src/vs/workbench/services/configuration/node/configurationService.ts b/src/vs/workbench/services/configuration/node/configurationService.ts index eb73870a0be..340c8499127 100644 --- a/src/vs/workbench/services/configuration/node/configurationService.ts +++ b/src/vs/workbench/services/configuration/node/configurationService.ts @@ -26,7 +26,7 @@ import { IWorkspaceConfigurationService, FOLDER_CONFIG_FOLDER_NAME, defaultSetti import { Registry } from 'vs/platform/registry/common/platform'; import { IConfigurationNode, IConfigurationRegistry, Extensions, IConfigurationPropertySchema, allSettings, windowSettings, resourceSettings, applicationSettings } from 'vs/platform/configuration/common/configurationRegistry'; import { createHash } from 'crypto'; -import { getWorkspaceLabel, IWorkspaceIdentifier, isWorkspaceIdentifier, IStoredWorkspaceFolder, isStoredWorkspaceFolder, IWorkspaceFolderCreationData, ISingleFolderWorkspaceIdentifier, isSingleFolderWorkspaceIdentifier } from 'vs/platform/workspaces/common/workspaces'; +import { IWorkspaceIdentifier, isWorkspaceIdentifier, IStoredWorkspaceFolder, isStoredWorkspaceFolder, IWorkspaceFolderCreationData, ISingleFolderWorkspaceIdentifier, isSingleFolderWorkspaceIdentifier } from 'vs/platform/workspaces/common/workspaces'; import { IWindowConfiguration } from 'vs/platform/windows/common/windows'; import { IExtensionService } from 'vs/workbench/services/extensions/common/extensions'; import { ICommandService } from 'vs/platform/commands/common/commands'; @@ -69,11 +69,10 @@ export class WorkspaceService extends Disposable implements IWorkspaceConfigurat public readonly onDidChangeWorkbenchState: Event<WorkbenchState> = this._onDidChangeWorkbenchState.event; private fileService: IFileService; - private uriLabelService: IUriLabelService; private configurationEditingService: ConfigurationEditingService; private jsonEditingService: JSONEditingService; - constructor(private environmentService: IEnvironmentService, private workspaceSettingsRootFolder: string = FOLDER_CONFIG_FOLDER_NAME) { + constructor(private environmentService: IEnvironmentService, private uriLabelService: IUriLabelService, private workspaceSettingsRootFolder: string = FOLDER_CONFIG_FOLDER_NAME) { super(); this.defaultConfiguration = new DefaultConfigurationModel(); @@ -319,10 +318,6 @@ export class WorkspaceService extends Disposable implements IWorkspaceConfigurat }); } - acquireUriLabelService(uriLabelService: IUriLabelService): void { - this.uriLabelService = uriLabelService; - } - acquireInstantiationService(instantiationService: IInstantiationService): void { this.configurationEditingService = instantiationService.createInstance(ConfigurationEditingService); this.jsonEditingService = instantiationService.createInstance(JSONEditingService); @@ -346,7 +341,7 @@ export class WorkspaceService extends Disposable implements IWorkspaceConfigurat .then(() => { const workspaceFolders = toWorkspaceFolders(this.workspaceConfiguration.getFolders(), URI.file(dirname(workspaceConfigPath.fsPath))); const workspaceId = workspaceIdentifier.id; - const workspaceName = getWorkspaceLabel({ id: workspaceId, configPath: workspaceConfigPath.fsPath }, this.environmentService, this.uriLabelService); + const workspaceName = this.uriLabelService.getWorkspaceLabel({ id: workspaceId, configPath: workspaceConfigPath.fsPath }); return new Workspace(workspaceId, workspaceName, workspaceFolders, workspaceConfigPath); }); } @@ -369,11 +364,11 @@ export class WorkspaceService extends Disposable implements IWorkspaceConfigurat } const id = createHash('md5').update(folder.fsPath).update(ctime ? String(ctime) : '').digest('hex'); - return new Workspace(id, getWorkspaceLabel(folder, this.environmentService, this.uriLabelService), toWorkspaceFolders([{ path: folder.fsPath }]), null, ctime); + return new Workspace(id, this.uriLabelService.getWorkspaceLabel(folder), toWorkspaceFolders([{ path: folder.fsPath }]), null, ctime); }); } else { const id = createHash('md5').update(folder.toString()).digest('hex'); - return TPromise.as(new Workspace(id, getWorkspaceLabel(folder, this.environmentService, this.uriLabelService), toWorkspaceFolders([{ uri: folder.toString() }]), null)); + return TPromise.as(new Workspace(id, this.uriLabelService.getWorkspaceLabel(folder), toWorkspaceFolders([{ uri: folder.toString() }]), null)); } } 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 a6ab72cead7..f201f562127 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 { INotificationService } from 'vs/platform/notification/common/notificati import { ICommandService } from 'vs/platform/commands/common/commands'; import { CommandService } from 'vs/workbench/services/commands/common/commandService'; import URI from 'vs/base/common/uri'; +import { UriLabelService } from 'vs/platform/uriLabel/common/uriLabel'; class SettingsTestEnvironmentService extends EnvironmentService { @@ -102,7 +103,7 @@ suite('ConfigurationEditingService', () => { instantiationService = <TestInstantiationService>workbenchInstantiationService(); const environmentService = new SettingsTestEnvironmentService(parseArgs(process.argv), process.execPath, globalSettingsFile); instantiationService.stub(IEnvironmentService, environmentService); - const workspaceService = new WorkspaceService(environmentService); + const workspaceService = new WorkspaceService(environmentService, new UriLabelService(environmentService)); instantiationService.stub(IWorkspaceContextService, workspaceService); return workspaceService.initialize(noWorkspace ? {} as IWindowConfiguration : URI.file(workspaceDir)).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 64e9352f99a..d4bc36c32d6 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 @@ -35,6 +35,7 @@ import { IJSONEditingService } from 'vs/workbench/services/configuration/common/ import { JSONEditingService } from 'vs/workbench/services/configuration/node/jsonEditingService'; import { IWorkspaceConfigurationService } from 'vs/workbench/services/configuration/common/configuration'; import { IWindowConfiguration } from 'vs/platform/windows/common/windows'; +import { UriLabelService } from 'vs/platform/uriLabel/common/uriLabel'; class SettingsTestEnvironmentService extends EnvironmentService { @@ -86,7 +87,8 @@ 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(environmentService); + const uriLabelService = new UriLabelService(environmentService); + workspaceContextService = new WorkspaceService(environmentService, uriLabelService); return (<WorkspaceService>workspaceContextService).initialize(URI.file(folderDir)); }); }); @@ -143,7 +145,8 @@ suite('WorkspaceContextService - Workspace', () => { parentResource = parentDir; const environmentService = new SettingsTestEnvironmentService(parseArgs(process.argv), process.execPath, path.join(parentDir, 'settings.json')); - const workspaceService = new WorkspaceService(environmentService); + const uriLabelService = new UriLabelService(environmentService); + const workspaceService = new WorkspaceService(environmentService, uriLabelService); const instantiationService = <TestInstantiationService>workbenchInstantiationService(); instantiationService.stub(IWorkspaceContextService, workspaceService); @@ -406,7 +409,8 @@ suite('WorkspaceService - Initialization', () => { const instantiationService = <TestInstantiationService>workbenchInstantiationService(); const environmentService = new SettingsTestEnvironmentService(parseArgs(process.argv), process.execPath, globalSettingsFile); - const workspaceService = new WorkspaceService(environmentService); + const uriLabelService = new UriLabelService(environmentService); + const workspaceService = new WorkspaceService(environmentService, uriLabelService); instantiationService.stub(IWorkspaceContextService, workspaceService); instantiationService.stub(IConfigurationService, workspaceService); instantiationService.stub(IEnvironmentService, environmentService); @@ -661,7 +665,8 @@ suite('WorkspaceConfigurationService - Folder', () => { const instantiationService = <TestInstantiationService>workbenchInstantiationService(); const environmentService = new SettingsTestEnvironmentService(parseArgs(process.argv), process.execPath, globalSettingsFile); - const workspaceService = new WorkspaceService(environmentService); + const uriLabelService = new UriLabelService(environmentService); + const workspaceService = new WorkspaceService(environmentService, uriLabelService); instantiationService.stub(IWorkspaceContextService, workspaceService); instantiationService.stub(IConfigurationService, workspaceService); instantiationService.stub(IEnvironmentService, environmentService); @@ -936,7 +941,8 @@ suite('WorkspaceConfigurationService-Multiroot', () => { parentResource = parentDir; environmentService = new SettingsTestEnvironmentService(parseArgs(process.argv), process.execPath, path.join(parentDir, 'settings.json')); - const workspaceService = new WorkspaceService(environmentService); + const uriLabelService = new UriLabelService(environmentService); + const workspaceService = new WorkspaceService(environmentService, uriLabelService); const instantiationService = <TestInstantiationService>workbenchInstantiationService(); instantiationService.stub(IWorkspaceContextService, workspaceService); diff --git a/src/vs/workbench/test/electron-browser/api/mainThreadEditors.test.ts b/src/vs/workbench/test/electron-browser/api/mainThreadEditors.test.ts index 19ef6688f08..0013574b689 100644 --- a/src/vs/workbench/test/electron-browser/api/mainThreadEditors.test.ts +++ b/src/vs/workbench/test/electron-browser/api/mainThreadEditors.test.ts @@ -21,7 +21,7 @@ import { Range } from 'vs/editor/common/core/range'; import { Position } from 'vs/editor/common/core/position'; import { IModelService } from 'vs/editor/common/services/modelService'; import { EditOperation } from 'vs/editor/common/core/editOperation'; -import { TestFileService, TestEditorService, TestEditorGroupsService, TestEnvironmentService, TestContextService } from 'vs/workbench/test/workbenchTestServices'; +import { TestFileService, TestEditorService, TestEditorGroupsService, TestEnvironmentService } from 'vs/workbench/test/workbenchTestServices'; import { TPromise } from 'vs/base/common/winjs.base'; import { ResourceTextEdit } from 'vs/editor/common/modes'; import { BulkEditService } from 'vs/workbench/services/bulkEdit/electron-browser/bulkEditService'; @@ -84,7 +84,7 @@ suite('MainThreadEditors', () => { } }; - const bulkEditService = new BulkEditService(new NullLogService(), modelService, new TestEditorService(), textModelService, new TestFileService(), textFileService, new UriLabelService(TestEnvironmentService, new TestContextService())); + const bulkEditService = new BulkEditService(new NullLogService(), modelService, new TestEditorService(), textModelService, new TestFileService(), textFileService, new UriLabelService(TestEnvironmentService)); const rpcProtocol = new TestRPCProtocol(); rpcProtocol.set(ExtHostContext.ExtHostDocuments, new class extends mock<ExtHostDocumentsShape>() { diff --git a/src/vs/workbench/test/workbenchTestServices.ts b/src/vs/workbench/test/workbenchTestServices.ts index 28b58ffa681..16c593921a9 100644 --- a/src/vs/workbench/test/workbenchTestServices.ts +++ b/src/vs/workbench/test/workbenchTestServices.ts @@ -271,7 +271,7 @@ export function workbenchInstantiationService(): IInstantiationService { instantiationService.stub(IHashService, new TestHashService()); instantiationService.stub(ILogService, new TestLogService()); instantiationService.stub(IEditorGroupsService, new TestEditorGroupsService([new TestEditorGroup(0)])); - instantiationService.stub(IUriLabelService, new UriLabelService(TestEnvironmentService, workspaceContextService)); + instantiationService.stub(IUriLabelService, new UriLabelService(TestEnvironmentService)); const editorService = new TestEditorService(); instantiationService.stub(IEditorService, editorService); instantiationService.stub(ICodeEditorService, new TestCodeEditorService()); From 63eb72070883c11f248428ead557265550b4aa4b Mon Sep 17 00:00:00 2001 From: isidor <inikolic@microsoft.com> Date: Wed, 22 Aug 2018 17:40:57 +0200 Subject: [PATCH 1124/1276] get rid of getWorkspaceLabel in workspaces.ts and adopt --- src/vs/code/electron-main/menubar.ts | 6 ++-- src/vs/code/electron-main/menus.ts | 6 ++-- .../electron-main/historyMainService.ts | 6 ++-- .../platform/workspaces/common/workspaces.ts | 35 ------------------- .../browser/parts/titlebar/menubarControl.ts | 8 ++--- src/vs/workbench/electron-browser/actions.ts | 6 ++-- .../page/electron-browser/welcomePage.ts | 9 ++--- 7 files changed, 17 insertions(+), 59 deletions(-) diff --git a/src/vs/code/electron-main/menubar.ts b/src/vs/code/electron-main/menubar.ts index 1bbfd9834bb..9aca1cca19f 100644 --- a/src/vs/code/electron-main/menubar.ts +++ b/src/vs/code/electron-main/menubar.ts @@ -19,7 +19,7 @@ import { IInstantiationService } from 'vs/platform/instantiation/common/instanti import { mnemonicMenuLabel as baseMnemonicLabel, unmnemonicLabel } from 'vs/base/common/labels'; import { IWindowsMainService, IWindowsCountChangedEvent } from 'vs/platform/windows/electron-main/windows'; import { IHistoryMainService } from 'vs/platform/history/common/history'; -import { IWorkspaceIdentifier, getWorkspaceLabel, ISingleFolderWorkspaceIdentifier, isSingleFolderWorkspaceIdentifier, isWorkspaceIdentifier } from 'vs/platform/workspaces/common/workspaces'; +import { IWorkspaceIdentifier, ISingleFolderWorkspaceIdentifier, isSingleFolderWorkspaceIdentifier, isWorkspaceIdentifier } from 'vs/platform/workspaces/common/workspaces'; import { IMenubarData, IMenubarKeybinding, MenubarMenuItem, isMenubarMenuItemSeparator, isMenubarMenuItemSubmenu, isMenubarMenuItemAction } from 'vs/platform/menubar/common/menubar'; import URI from 'vs/base/common/uri'; import { IUriLabelService } from 'vs/platform/uriLabel/common/uriLabel'; @@ -563,10 +563,10 @@ export class Menubar { let label: string; let uri: URI; if (isSingleFolderWorkspaceIdentifier(workspaceOrFile) && !isFile) { - label = unmnemonicLabel(getWorkspaceLabel(workspaceOrFile, this.environmentService, this.uriLabelService, { verbose: true })); + label = unmnemonicLabel(this.uriLabelService.getWorkspaceLabel(workspaceOrFile, { verbose: true })); uri = workspaceOrFile; } else if (isWorkspaceIdentifier(workspaceOrFile)) { - label = getWorkspaceLabel(workspaceOrFile, this.environmentService, this.uriLabelService, { verbose: true }); + label = this.uriLabelService.getWorkspaceLabel(workspaceOrFile, { verbose: true }); uri = URI.file(workspaceOrFile.configPath); } else { label = unmnemonicLabel(this.uriLabelService.getLabel(workspaceOrFile)); diff --git a/src/vs/code/electron-main/menus.ts b/src/vs/code/electron-main/menus.ts index 0f11f0d2cb0..3a27ba9c4d8 100644 --- a/src/vs/code/electron-main/menus.ts +++ b/src/vs/code/electron-main/menus.ts @@ -22,7 +22,7 @@ import { mnemonicMenuLabel as baseMnemonicLabel, unmnemonicLabel } from 'vs/base import { KeybindingsResolver } from 'vs/code/electron-main/keyboard'; import { IWindowsMainService, IWindowsCountChangedEvent } from 'vs/platform/windows/electron-main/windows'; import { IHistoryMainService } from 'vs/platform/history/common/history'; -import { IWorkspaceIdentifier, getWorkspaceLabel, ISingleFolderWorkspaceIdentifier, isSingleFolderWorkspaceIdentifier, isWorkspaceIdentifier } from 'vs/platform/workspaces/common/workspaces'; +import { IWorkspaceIdentifier, ISingleFolderWorkspaceIdentifier, isSingleFolderWorkspaceIdentifier, isWorkspaceIdentifier } from 'vs/platform/workspaces/common/workspaces'; import URI from 'vs/base/common/uri'; import { IUriLabelService } from 'vs/platform/uriLabel/common/uriLabel'; @@ -491,10 +491,10 @@ export class CodeMenu { let label: string; let uri: URI; if (isSingleFolderWorkspaceIdentifier(workspace)) { - label = unmnemonicLabel(getWorkspaceLabel(workspace, this.environmentService, this.uriLabelService, { verbose: true })); + label = unmnemonicLabel(this.uriLabelService.getWorkspaceLabel(workspace, { verbose: true })); uri = workspace; } else if (isWorkspaceIdentifier(workspace)) { - label = getWorkspaceLabel(workspace, this.environmentService, this.uriLabelService, { verbose: true }); + label = this.uriLabelService.getWorkspaceLabel(workspace, { verbose: true }); uri = URI.file(workspace.configPath); } else { uri = URI.file(workspace); diff --git a/src/vs/platform/history/electron-main/historyMainService.ts b/src/vs/platform/history/electron-main/historyMainService.ts index 84f4d3146e5..aaaeca45452 100644 --- a/src/vs/platform/history/electron-main/historyMainService.ts +++ b/src/vs/platform/history/electron-main/historyMainService.ts @@ -14,9 +14,8 @@ import { getBaseLabel } from 'vs/base/common/labels'; import { IPath } from 'vs/platform/windows/common/windows'; import { Event as CommonEvent, Emitter } from 'vs/base/common/event'; import { isWindows, isMacintosh, isLinux } from 'vs/base/common/platform'; -import { IWorkspaceIdentifier, IWorkspacesMainService, getWorkspaceLabel, IWorkspaceSavedEvent, ISingleFolderWorkspaceIdentifier, isSingleFolderWorkspaceIdentifier, isWorkspaceIdentifier } from 'vs/platform/workspaces/common/workspaces'; +import { IWorkspaceIdentifier, IWorkspacesMainService, IWorkspaceSavedEvent, ISingleFolderWorkspaceIdentifier, isSingleFolderWorkspaceIdentifier, isWorkspaceIdentifier } from 'vs/platform/workspaces/common/workspaces'; import { IHistoryMainService, IRecentlyOpened } from 'vs/platform/history/common/history'; -import { IEnvironmentService } from 'vs/platform/environment/common/environment'; import { isEqual } from 'vs/base/common/paths'; import { RunOnceScheduler } from 'vs/base/common/async'; import { getComparisonKey, isEqual as areResourcesEqual, dirname } from 'vs/base/common/resources'; @@ -52,7 +51,6 @@ export class HistoryMainService implements IHistoryMainService { @IStateService private stateService: IStateService, @ILogService private logService: ILogService, @IWorkspacesMainService private workspacesMainService: IWorkspacesMainService, - @IEnvironmentService private environmentService: IEnvironmentService, @IUriLabelService private uriLabelService: IUriLabelService ) { this.macOSRecentDocumentsUpdater = new RunOnceScheduler(() => this.updateMacOSRecentDocuments(), 800); @@ -368,7 +366,7 @@ export class HistoryMainService implements IHistoryMainService { type: 'custom', name: nls.localize('recentFolders', "Recent Workspaces"), items: this.getRecentlyOpened().workspaces.slice(0, 7 /* limit number of entries here */).map(workspace => { - const title = getWorkspaceLabel(workspace, this.environmentService, this.uriLabelService); + const title = this.uriLabelService.getWorkspaceLabel(workspace); let description; let args; if (isSingleFolderWorkspaceIdentifier(workspace)) { diff --git a/src/vs/platform/workspaces/common/workspaces.ts b/src/vs/platform/workspaces/common/workspaces.ts index 5c8c389fc85..44b42dde325 100644 --- a/src/vs/platform/workspaces/common/workspaces.ts +++ b/src/vs/platform/workspaces/common/workspaces.ts @@ -7,17 +7,10 @@ import { createDecorator } from 'vs/platform/instantiation/common/instantiation'; import { TPromise } from 'vs/base/common/winjs.base'; -import { isParent } from 'vs/platform/files/common/files'; import { localize } from 'vs/nls'; -import { basename, dirname, join } from 'vs/base/common/paths'; -import { isLinux } from 'vs/base/common/platform'; -import { IEnvironmentService } from 'vs/platform/environment/common/environment'; import { Event } from 'vs/base/common/event'; -import { getBaseLabel } from 'vs/base/common/labels'; import { IWorkspaceFolder } from 'vs/platform/workspace/common/workspace'; import URI from 'vs/base/common/uri'; -import { Schemas } from 'vs/base/common/network'; -import { IUriLabelService } from 'vs/platform/uriLabel/common/uriLabel'; export const IWorkspacesMainService = createDecorator<IWorkspacesMainService>('workspacesMainService'); export const IWorkspacesService = createDecorator<IWorkspacesService>('workspacesService'); @@ -113,34 +106,6 @@ export interface IWorkspacesService { createWorkspace(folders?: IWorkspaceFolderCreationData[]): TPromise<IWorkspaceIdentifier>; } -export function getWorkspaceLabel(workspace: (IWorkspaceIdentifier | ISingleFolderWorkspaceIdentifier), environmentService: IEnvironmentService, uriLabelService: IUriLabelService, options?: { verbose: boolean }): string { - - // Workspace: Single Folder - if (isSingleFolderWorkspaceIdentifier(workspace)) { - // Folder on disk - if (workspace.scheme === Schemas.file) { - return options && options.verbose ? uriLabelService.getLabel(workspace) : getBaseLabel(workspace); - } - - // Remote folder - return options && options.verbose ? uriLabelService.getLabel(workspace) : `${getBaseLabel(workspace)} (${workspace.scheme})`; - } - - // Workspace: Untitled - if (isParent(workspace.configPath, environmentService.workspacesHome, !isLinux /* ignore case */)) { - return localize('untitledWorkspace', "Untitled (Workspace)"); - } - - // Workspace: Saved - const filename = basename(workspace.configPath); - const workspaceName = filename.substr(0, filename.length - WORKSPACE_EXTENSION.length - 1); - if (options && options.verbose) { - return localize('workspaceNameVerbose', "{0} (Workspace)", uriLabelService.getLabel(URI.file(join(dirname(workspace.configPath), workspaceName)))); - } - - return localize('workspaceName', "{0} (Workspace)", workspaceName); -} - export function isSingleFolderWorkspaceIdentifier(obj: any): obj is ISingleFolderWorkspaceIdentifier { return obj instanceof URI; } diff --git a/src/vs/workbench/browser/parts/titlebar/menubarControl.ts b/src/vs/workbench/browser/parts/titlebar/menubarControl.ts index 1e22b3ed71b..676e4ab348a 100644 --- a/src/vs/workbench/browser/parts/titlebar/menubarControl.ts +++ b/src/vs/workbench/browser/parts/titlebar/menubarControl.ts @@ -25,8 +25,7 @@ import { Event, Emitter } from 'vs/base/common/event'; import { IDisposable, Disposable, dispose } from 'vs/base/common/lifecycle'; import { domEvent } from 'vs/base/browser/event'; import { IRecentlyOpened } from 'vs/platform/history/common/history'; -import { IWorkspaceIdentifier, getWorkspaceLabel, ISingleFolderWorkspaceIdentifier, isSingleFolderWorkspaceIdentifier, isWorkspaceIdentifier } from 'vs/platform/workspaces/common/workspaces'; -import { IEnvironmentService } from 'vs/platform/environment/common/environment'; +import { IWorkspaceIdentifier, ISingleFolderWorkspaceIdentifier, isSingleFolderWorkspaceIdentifier, isWorkspaceIdentifier } from 'vs/platform/workspaces/common/workspaces'; import { RunOnceScheduler } from 'vs/base/common/async'; import { MENUBAR_SELECTION_FOREGROUND, MENUBAR_SELECTION_BACKGROUND, MENUBAR_SELECTION_BORDER, TITLE_BAR_ACTIVE_FOREGROUND, TITLE_BAR_INACTIVE_FOREGROUND, MENU_BACKGROUND, MENU_FOREGROUND, MENU_SELECTION_BACKGROUND, MENU_SELECTION_FOREGROUND, MENU_SELECTION_BORDER } from 'vs/workbench/common/theme'; import URI from 'vs/base/common/uri'; @@ -122,7 +121,6 @@ export class MenubarControl extends Disposable { @IContextKeyService private contextKeyService: IContextKeyService, @IKeybindingService private keybindingService: IKeybindingService, @IConfigurationService private configurationService: IConfigurationService, - @IEnvironmentService private environmentService: IEnvironmentService, @IUriLabelService private uriLabelService: IUriLabelService, @IUpdateService private updateService: IUpdateService ) { @@ -533,10 +531,10 @@ export class MenubarControl extends Disposable { let uri: URI; if (isSingleFolderWorkspaceIdentifier(workspace) && !isFile) { - label = getWorkspaceLabel(workspace, this.environmentService, this.uriLabelService, { verbose: true }); + label = this.uriLabelService.getWorkspaceLabel(workspace, { verbose: true }); uri = workspace; } else if (isWorkspaceIdentifier(workspace)) { - label = getWorkspaceLabel(workspace, this.environmentService, this.uriLabelService, { verbose: true }); + label = this.uriLabelService.getWorkspaceLabel(workspace, { verbose: true }); uri = URI.file(workspace.configPath); } else { uri = workspace; diff --git a/src/vs/workbench/electron-browser/actions.ts b/src/vs/workbench/electron-browser/actions.ts index bdd05d8bf60..33500ca8c7e 100644 --- a/src/vs/workbench/electron-browser/actions.ts +++ b/src/vs/workbench/electron-browser/actions.ts @@ -29,7 +29,7 @@ import { webFrame, shell } from 'electron'; import { getBaseLabel } from 'vs/base/common/labels'; import { IViewlet } from 'vs/workbench/common/viewlet'; import { IPanel } from 'vs/workbench/common/panel'; -import { IWorkspaceIdentifier, getWorkspaceLabel, ISingleFolderWorkspaceIdentifier, isSingleFolderWorkspaceIdentifier, isWorkspaceIdentifier } from 'vs/platform/workspaces/common/workspaces'; +import { IWorkspaceIdentifier, ISingleFolderWorkspaceIdentifier, isSingleFolderWorkspaceIdentifier, isWorkspaceIdentifier } from 'vs/platform/workspaces/common/workspaces'; import { FileKind } from 'vs/platform/files/common/files'; import { IssueType } from 'vs/platform/issue/common/issue'; import { domEvent } from 'vs/base/browser/event'; @@ -441,11 +441,11 @@ export abstract class BaseOpenRecentAction extends Action { let description: string; if (isSingleFolderWorkspaceIdentifier(workspace) && fileKind !== FileKind.FILE) { resource = workspace; - label = getWorkspaceLabel(workspace, environmentService, uriLabelService); + label = uriLabelService.getWorkspaceLabel(workspace); description = uriLabelService.getLabel(dirname(resource)); } else if (isWorkspaceIdentifier(workspace)) { resource = URI.file(workspace.configPath); - label = getWorkspaceLabel(workspace, environmentService, uriLabelService); + label = uriLabelService.getWorkspaceLabel(workspace); description = uriLabelService.getLabel(dirname(resource)); } else { resource = workspace; diff --git a/src/vs/workbench/parts/welcome/page/electron-browser/welcomePage.ts b/src/vs/workbench/parts/welcome/page/electron-browser/welcomePage.ts index 9ad196cfe57..d0a84ee058b 100644 --- a/src/vs/workbench/parts/welcome/page/electron-browser/welcomePage.ts +++ b/src/vs/workbench/parts/welcome/page/electron-browser/welcomePage.ts @@ -33,8 +33,7 @@ import { registerThemingParticipant } from 'vs/platform/theme/common/themeServic import { registerColor, focusBorder, textLinkForeground, textLinkActiveForeground, foreground, descriptionForeground, contrastBorder, activeContrastBorder } from 'vs/platform/theme/common/colorRegistry'; import { getExtraColor } from 'vs/workbench/parts/welcome/walkThrough/node/walkThroughUtils'; import { IExtensionsWorkbenchService } from 'vs/workbench/parts/extensions/common/extensions'; -import { IStorageService } from 'vs/platform/storage/common/storage'; -import { IWorkspaceIdentifier, getWorkspaceLabel, ISingleFolderWorkspaceIdentifier, isSingleFolderWorkspaceIdentifier, isWorkspaceIdentifier } from 'vs/platform/workspaces/common/workspaces'; +import { IWorkspaceIdentifier, ISingleFolderWorkspaceIdentifier, isSingleFolderWorkspaceIdentifier, isWorkspaceIdentifier } from 'vs/platform/workspaces/common/workspaces'; import { IEditorInputFactory, EditorInput } from 'vs/workbench/common/editor'; import { getIdAndVersionFromLocalExtensionId } from 'vs/platform/extensionManagement/node/extensionManagementUtil'; import { INotificationService, Severity } from 'vs/platform/notification/common/notification'; @@ -55,9 +54,7 @@ export class WelcomePageContribution implements IWorkbenchContribution { @IConfigurationService configurationService: IConfigurationService, @IEditorService editorService: IEditorService, @IBackupFileService backupFileService: IBackupFileService, - @ITelemetryService telemetryService: ITelemetryService, @ILifecycleService lifecycleService: ILifecycleService, - @IStorageService storageService: IStorageService ) { const enabled = isWelcomePageEnabled(configurationService); if (enabled && lifecycleService.startupKind !== StartupKind.ReloadedWindow) { @@ -283,9 +280,9 @@ class WelcomePage { let resource: URI; if (isSingleFolderWorkspaceIdentifier(workspace)) { resource = workspace; - label = getWorkspaceLabel(workspace, this.environmentService, this.uriLabelService); + label = this.uriLabelService.getWorkspaceLabel(workspace); } else if (isWorkspaceIdentifier(workspace)) { - label = getWorkspaceLabel(workspace, this.environmentService, this.uriLabelService); + label = this.uriLabelService.getWorkspaceLabel(workspace); resource = URI.file(workspace.configPath); } else { label = getBaseLabel(workspace); From efdf77f46820ff9150941a265e2c2b95d5d2585c Mon Sep 17 00:00:00 2001 From: Miguel Solorio <miguel.solorio@microsoft.com> Date: Wed, 22 Aug 2018 09:59:42 -0700 Subject: [PATCH 1125/1276] Make arrow smaller and increase padding --- src/vs/workbench/electron-browser/media/shell.css | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/vs/workbench/electron-browser/media/shell.css b/src/vs/workbench/electron-browser/media/shell.css index 1ce2598e143..fe893480233 100644 --- a/src/vs/workbench/electron-browser/media/shell.css +++ b/src/vs/workbench/electron-browser/media/shell.css @@ -96,8 +96,8 @@ } .monaco-shell .monaco-menu .monaco-action-bar.vertical .submenu-indicator { - font-size: inherit; - padding: 0 1em; + font-size: 60%; + padding: 0 1.5em; } .monaco-shell .monaco-menu .action-item { From eb0b066ab7e93f02ec0dbc2bfae9f44d80a2bae5 Mon Sep 17 00:00:00 2001 From: Jackson Kearl <jkearl11@gmail.com> Date: Wed, 22 Aug 2018 10:40:40 -0700 Subject: [PATCH 1126/1276] Fix bug causing settings name to sometimes be improperly copied. (#56948) * Fix bug causing settigns name to sometimes be improperly copied. * Filter arros out on search * revernt change to name text * more aggressive filtering of the arrow symbols --- src/vs/workbench/parts/preferences/browser/settingsEditor2.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vs/workbench/parts/preferences/browser/settingsEditor2.ts b/src/vs/workbench/parts/preferences/browser/settingsEditor2.ts index ee26a5d7a0b..ca45a7487bf 100644 --- a/src/vs/workbench/parts/preferences/browser/settingsEditor2.ts +++ b/src/vs/workbench/parts/preferences/browser/settingsEditor2.ts @@ -770,7 +770,7 @@ export class SettingsEditor2 extends BaseEditor { const query = this.searchWidget.getValue().trim(); if (query === '') { this.countElement.style.display = 'none'; this.noResultsMessage.style.display = 'none'; } this.delayedFilterLogging.cancel(); - this.triggerSearch(query).then(() => { + this.triggerSearch(query.replace(/›/g, ' ')).then(() => { if (query && this.searchResultModel) { this.delayedFilterLogging.trigger(() => this.reportFilteringUsed(query, this.searchResultModel.getUniqueResults())); } From 4f31f23e97ded6a7af0974e736884095d1bb3c17 Mon Sep 17 00:00:00 2001 From: Miguel Solorio <miguel.solorio@microsoft.com> Date: Wed, 22 Aug 2018 10:58:43 -0700 Subject: [PATCH 1127/1276] Adjust padding on submenu arrow --- src/vs/workbench/electron-browser/media/shell.css | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vs/workbench/electron-browser/media/shell.css b/src/vs/workbench/electron-browser/media/shell.css index fe893480233..306a4b4e6db 100644 --- a/src/vs/workbench/electron-browser/media/shell.css +++ b/src/vs/workbench/electron-browser/media/shell.css @@ -97,7 +97,7 @@ .monaco-shell .monaco-menu .monaco-action-bar.vertical .submenu-indicator { font-size: 60%; - padding: 0 1.5em; + padding: 0 1.8em; } .monaco-shell .monaco-menu .action-item { From ba055a4e7eaa3e2ca14b5d6f8ab49227f90325f7 Mon Sep 17 00:00:00 2001 From: Rachel Macfarlane <ramacfar@microsoft.com> Date: Wed, 22 Aug 2018 11:11:00 -0700 Subject: [PATCH 1128/1276] Properly dispose of newCommentWidget, fixes https://github.com/Microsoft/vscode-pull-request-github/issues/235 --- .../parts/comments/common/reviewModel.ts | 29 -------------- .../electron-browser/commentThreadWidget.ts | 14 ++++++- .../commentsEditorContribution.ts | 39 +++++++------------ 3 files changed, 27 insertions(+), 55 deletions(-) delete mode 100644 src/vs/workbench/parts/comments/common/reviewModel.ts diff --git a/src/vs/workbench/parts/comments/common/reviewModel.ts b/src/vs/workbench/parts/comments/common/reviewModel.ts deleted file mode 100644 index 2c3b962122f..00000000000 --- a/src/vs/workbench/parts/comments/common/reviewModel.ts +++ /dev/null @@ -1,29 +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'; - -import { Emitter, Event } from 'vs/base/common/event'; - -export enum ReviewStyle { - Complete, - Inline, - Gutter -} - -export class ReviewModel { - private _style: ReviewStyle; - public get style(): ReviewStyle { return this._style; } - private _onDidChangeStyle = new Emitter<ReviewStyle>(); - public get onDidChangeStyle(): Event<ReviewStyle> { return this._onDidChangeStyle.event; } - - constructor() { - this._style = ReviewStyle.Inline; - } - - setStyle(style: ReviewStyle) { - this._style = style; - this._onDidChangeStyle.fire(this._style); - } -} \ No newline at end of file diff --git a/src/vs/workbench/parts/comments/electron-browser/commentThreadWidget.ts b/src/vs/workbench/parts/comments/electron-browser/commentThreadWidget.ts index d5a2d3db43b..098bc78a191 100644 --- a/src/vs/workbench/parts/comments/electron-browser/commentThreadWidget.ts +++ b/src/vs/workbench/parts/comments/electron-browser/commentThreadWidget.ts @@ -97,6 +97,7 @@ export class CommentNode { } let INMEM_MODEL_ID = 0; + export class ReviewZoneWidget extends ZoneWidget { private _headElement: HTMLElement; protected _headingLabel: HTMLElement; @@ -109,6 +110,7 @@ export class ReviewZoneWidget extends ZoneWidget { private _reviewThreadReplyButton: HTMLElement; private _resizeObserver: any; private _onDidClose = new Emitter<ReviewZoneWidget>(); + private _onDidCreateThread = new Emitter<ReviewZoneWidget>(); private _isCollapsed; private _toggleAction: Action; private _commentThread: modes.CommentThread; @@ -164,6 +166,10 @@ export class ReviewZoneWidget extends ZoneWidget { return this._onDidClose.event; } + public get onDidCreateThread(): Event<ReviewZoneWidget> { + return this._onDidCreateThread.event; + } + protected revealLine(lineNumber: number) { // we don't do anything here as we always do the reveal ourselves. } @@ -395,9 +401,9 @@ export class ReviewZoneWidget extends ZoneWidget { private async createComment(lineNumber: number): Promise<void> { try { let newCommentThread; + const isReply = this._commentThread.threadId !== null; - if (this._commentThread.threadId) { - // reply + if (isReply) { newCommentThread = await this.commentService.replyToCommentThread( this._owner, this.editor.getModel().uri, @@ -427,6 +433,10 @@ export class ReviewZoneWidget extends ZoneWidget { this._error.textContent = ''; dom.addClass(this._error, 'hidden'); this.update(newCommentThread); + + if (!isReply) { + this._onDidCreateThread.fire(this); + } } } catch (e) { this._error.textContent = e.message diff --git a/src/vs/workbench/parts/comments/electron-browser/commentsEditorContribution.ts b/src/vs/workbench/parts/comments/electron-browser/commentsEditorContribution.ts index db8cb6ebef0..60b5c2f04d0 100644 --- a/src/vs/workbench/parts/comments/electron-browser/commentsEditorContribution.ts +++ b/src/vs/workbench/parts/comments/electron-browser/commentsEditorContribution.ts @@ -24,7 +24,6 @@ import { KeybindingsRegistry, KeybindingWeight } from 'vs/platform/keybinding/co import { editorForeground, registerColor } from 'vs/platform/theme/common/colorRegistry'; import { IThemeService, registerThemingParticipant } from 'vs/platform/theme/common/themeService'; import { CommentThreadCollapsibleState } from 'vs/workbench/api/node/extHostTypes'; -import { ReviewModel } from 'vs/workbench/parts/comments/common/reviewModel'; import { ReviewZoneWidget, COMMENTEDITOR_DECORATION_KEY } from 'vs/workbench/parts/comments/electron-browser/commentThreadWidget'; import { ICommentService } from 'vs/workbench/parts/comments/electron-browser/commentService'; import { IModelService } from 'vs/editor/common/services/modelService'; @@ -169,7 +168,6 @@ export class ReviewController implements IEditorContribution { private _commentWidgets: ReviewZoneWidget[]; private _reviewPanelVisible: IContextKey<boolean>; private _commentInfos: modes.CommentInfo[]; - private _reviewModel: ReviewModel; // private _hasSetComments: boolean; private _commentingRangeDecorator: CommentingRangeDecorator; private mouseDownInfo: { lineNumber: number } | null = null; @@ -197,28 +195,8 @@ export class ReviewController implements IEditorContribution { // this._hasSetComments = false; this._reviewPanelVisible = ctxReviewPanelVisible.bindTo(contextKeyService); - this._reviewModel = new ReviewModel(); this._commentingRangeDecorator = new CommentingRangeDecorator(); - this._reviewModel.onDidChangeStyle(style => { - if (this._newCommentWidget) { - this._newCommentWidget.dispose(); - this._newCommentWidget = null; - } - - this._commentWidgets.forEach(zone => { - zone.dispose(); - }); - - this._commentInfos.forEach(info => { - info.threads.forEach(thread => { - let zoneWidget = new ReviewZoneWidget(this.instantiationService, this.modeService, this.modelService, this.themeService, this.commentService, this.openerService, this.editor, info.owner, thread, {}); - zoneWidget.display(thread.range.startLineNumber, this._commentingRangeDecorator.commentsOptions); - this._commentWidgets.push(zoneWidget); - }); - }); - }); - this.globalToDispose.push(this.commentService.onDidDeleteDataProvider(e => { // Remove new comment widget and glyph, refresh comments if (this._newCommentWidget) { @@ -352,6 +330,11 @@ export class ReviewController implements IEditorContribution { if (!editorURI) { return; } + + if (!this._commentInfos.some(info => info.owner === e.owner)) { + return; + } + let added = e.added.filter(thread => thread.resource.toString() === editorURI.toString()); let removed = e.removed.filter(thread => thread.resource.toString() === editorURI.toString()); let changed = e.changed.filter(thread => thread.resource.toString() === editorURI.toString()); @@ -409,9 +392,17 @@ export class ReviewController implements IEditorContribution { collapsibleState: CommentThreadCollapsibleState.Expanded, }, {}); - this._newCommentWidget.onDidClose(e => { + this.localToDispose.push(this._newCommentWidget.onDidClose(e => { this._newCommentWidget = null; - }); + })); + + this.localToDispose.push(this._newCommentWidget.onDidCreateThread(commentWidget => { + const thread = commentWidget.commentThread; + this._commentWidgets.push(commentWidget); + this._commentInfos.filter(info => info.owner === commentWidget.owner)[0].threads.push(thread); + this._newCommentWidget = null; + })); + this._newCommentWidget.display(lineNumber, this._commentingRangeDecorator.commentsOptions); } From 17a0bbba4efe8b80a8f426ea75f7e131dae0c39d Mon Sep 17 00:00:00 2001 From: Daniel Imms <daimms@microsoft.com> Date: Wed, 22 Aug 2018 11:33:31 -0700 Subject: [PATCH 1129/1276] Remove unused clean flatpak tasks --- build/gulpfile.vscode.linux.js | 3 --- 1 file changed, 3 deletions(-) diff --git a/build/gulpfile.vscode.linux.js b/build/gulpfile.vscode.linux.js index 49f2cad8ad7..61b29d260cf 100644 --- a/build/gulpfile.vscode.linux.js +++ b/build/gulpfile.vscode.linux.js @@ -214,9 +214,6 @@ gulp.task('clean-vscode-linux-arm-rpm', util.rimraf('.build/linux/rpm/armhf')); gulp.task('clean-vscode-linux-ia32-snap', util.rimraf('.build/linux/snap/x64')); gulp.task('clean-vscode-linux-x64-snap', util.rimraf('.build/linux/snap/x64')); gulp.task('clean-vscode-linux-arm-snap', util.rimraf('.build/linux/snap/x64')); -gulp.task('clean-vscode-linux-ia32-flatpak', util.rimraf('.build/linux/flatpak/i386')); -gulp.task('clean-vscode-linux-x64-flatpak', util.rimraf('.build/linux/flatpak/x86_64')); -gulp.task('clean-vscode-linux-arm-flatpak', util.rimraf('.build/linux/flatpak/arm')); gulp.task('vscode-linux-ia32-prepare-deb', ['clean-vscode-linux-ia32-deb'], prepareDebPackage('ia32')); gulp.task('vscode-linux-x64-prepare-deb', ['clean-vscode-linux-x64-deb'], prepareDebPackage('x64')); From 4a067ffd6b2bb795dfa2055d5ffadd5ba8282526 Mon Sep 17 00:00:00 2001 From: Daniel Imms <daimms@microsoft.com> Date: Wed, 22 Aug 2018 12:58:38 -0700 Subject: [PATCH 1130/1276] Guard proposed API createTerminalRenderer Fixes #56310 --- src/vs/workbench/api/node/extHost.api.impl.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/vs/workbench/api/node/extHost.api.impl.ts b/src/vs/workbench/api/node/extHost.api.impl.ts index 8bf889401c0..192159fe5c3 100644 --- a/src/vs/workbench/api/node/extHost.api.impl.ts +++ b/src/vs/workbench/api/node/extHost.api.impl.ts @@ -440,9 +440,9 @@ export function createApiFactory( } return extHostTerminalService.createTerminal(<string>nameOrOptions, shellPath, shellArgs); }, - createTerminalRenderer(name: string): vscode.TerminalRenderer { + createTerminalRenderer: proposedApiFunction(extension, (name: string) => { return extHostTerminalService.createTerminalRenderer(name); - }, + }), registerTreeDataProvider(viewId: string, treeDataProvider: vscode.TreeDataProvider<any>): vscode.Disposable { return extHostTreeViews.registerTreeDataProvider(viewId, treeDataProvider); }, From 38c2868bb5f792493818ab552ff4f853f2769767 Mon Sep 17 00:00:00 2001 From: Ilya Rodionov <ris58h@gmail.com> Date: Wed, 22 Aug 2018 23:10:00 +0300 Subject: [PATCH 1131/1276] Remove out of date params from doc comments. --- src/vs/editor/common/model.ts | 4 ---- src/vs/monaco.d.ts | 6 +----- 2 files changed, 1 insertion(+), 9 deletions(-) diff --git a/src/vs/editor/common/model.ts b/src/vs/editor/common/model.ts index d37319c25b5..66a35fabb48 100644 --- a/src/vs/editor/common/model.ts +++ b/src/vs/editor/common/model.ts @@ -747,7 +747,6 @@ export interface ITextModel { /** * Get the word under or besides `position`. * @param position The position to look for a word. - * @param skipSyntaxTokens Ignore syntax tokens, as identified by the mode. * @return The word under or besides `position`. Might be null. */ getWordAtPosition(position: IPosition): IWordAtPosition; @@ -755,7 +754,6 @@ export interface ITextModel { /** * Get the word under or besides `position` trimmed to `position`.column * @param position The position to look for a word. - * @param skipSyntaxTokens Ignore syntax tokens, as identified by the mode. * @return The word under or besides `position`. Will never be null. */ getWordUntilPosition(position: IPosition): IWordAtPosition; @@ -814,7 +812,6 @@ export interface ITextModel { /** * Get the word under or besides `position`. * @param position The position to look for a word. - * @param skipSyntaxTokens Ignore syntax tokens, as identified by the mode. * @return The word under or besides `position`. Might be null. */ getWordAtPosition(position: IPosition): IWordAtPosition; @@ -822,7 +819,6 @@ export interface ITextModel { /** * Get the word under or besides `position` trimmed to `position`.column * @param position The position to look for a word. - * @param skipSyntaxTokens Ignore syntax tokens, as identified by the mode. * @return The word under or besides `position`. Will never be null. */ getWordUntilPosition(position: IPosition): IWordAtPosition; diff --git a/src/vs/monaco.d.ts b/src/vs/monaco.d.ts index 76dcf491ff9..0d0895e902e 100644 --- a/src/vs/monaco.d.ts +++ b/src/vs/monaco.d.ts @@ -181,7 +181,7 @@ declare namespace monaco { good.scheme === 'file'; good.path === '/coding/c#/project1'; good.fragment === ''; - + const bad = Uri.parse('file://' + '/coding/c#/project1'); bad.scheme === 'file'; bad.path === '/coding/c'; // path is now broken @@ -1666,14 +1666,12 @@ declare namespace monaco.editor { /** * Get the word under or besides `position`. * @param position The position to look for a word. - * @param skipSyntaxTokens Ignore syntax tokens, as identified by the mode. * @return The word under or besides `position`. Might be null. */ getWordAtPosition(position: IPosition): IWordAtPosition; /** * Get the word under or besides `position` trimmed to `position`.column * @param position The position to look for a word. - * @param skipSyntaxTokens Ignore syntax tokens, as identified by the mode. * @return The word under or besides `position`. Will never be null. */ getWordUntilPosition(position: IPosition): IWordAtPosition; @@ -1684,14 +1682,12 @@ declare namespace monaco.editor { /** * Get the word under or besides `position`. * @param position The position to look for a word. - * @param skipSyntaxTokens Ignore syntax tokens, as identified by the mode. * @return The word under or besides `position`. Might be null. */ getWordAtPosition(position: IPosition): IWordAtPosition; /** * Get the word under or besides `position` trimmed to `position`.column * @param position The position to look for a word. - * @param skipSyntaxTokens Ignore syntax tokens, as identified by the mode. * @return The word under or besides `position`. Will never be null. */ getWordUntilPosition(position: IPosition): IWordAtPosition; From 3933e6b067d9aa2eaadccc4852eb2a3355092c17 Mon Sep 17 00:00:00 2001 From: Rob Lourens <roblourens@gmail.com> Date: Wed, 22 Aug 2018 14:28:37 -0700 Subject: [PATCH 1132/1276] Bump node2 #57018 --- build/builtInExtensions.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build/builtInExtensions.json b/build/builtInExtensions.json index 9179f321e7e..57f248322f1 100644 --- a/build/builtInExtensions.json +++ b/build/builtInExtensions.json @@ -6,7 +6,7 @@ }, { "name": "ms-vscode.node-debug2", - "version": "1.27.0", + "version": "1.27.1", "repo": "https://github.com/Microsoft/vscode-node-debug2" } ] From c545c10749b0fd94e153b325ae204ae920bedaff Mon Sep 17 00:00:00 2001 From: MarvinJWendt <github@marvinjwendt.com> Date: Thu, 23 Aug 2018 01:30:22 +0200 Subject: [PATCH 1133/1276] Grammar fix work flow -> workflow --- CONTRIBUTING.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 0d3f7dc4bf3..f3166331378 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -81,7 +81,7 @@ Don't feel bad if the developers can't reproduce the issue right away. They will ### Follow Your Issue -Once submitted, your report will go into the [issue tracking](https://github.com/Microsoft/vscode/wiki/Issue-Tracking) work flow. Be sure to understand what will happen next, so you know what to expect, and how to continue to assist throughout the process. +Once submitted, your report will go into the [issue tracking](https://github.com/Microsoft/vscode/wiki/Issue-Tracking) workflow. Be sure to understand what will happen next, so you know what to expect, and how to continue to assist throughout the process. ## Automated Issue Management From 98a9c2570e86d0c689c358939522131930f7e83c Mon Sep 17 00:00:00 2001 From: Rachel Macfarlane <ramacfar@microsoft.com> Date: Wed, 22 Aug 2018 17:40:55 -0700 Subject: [PATCH 1134/1276] Don't render images in comments panel, fixes https://github.com/Microsoft/vscode-pull-request-github/issues/214 --- .../comments/electron-browser/commentsTreeViewer.ts | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/vs/workbench/parts/comments/electron-browser/commentsTreeViewer.ts b/src/vs/workbench/parts/comments/electron-browser/commentsTreeViewer.ts index d8672d23d57..ed3f817715d 100644 --- a/src/vs/workbench/parts/comments/electron-browser/commentsTreeViewer.ts +++ b/src/vs/workbench/parts/comments/electron-browser/commentsTreeViewer.ts @@ -4,6 +4,7 @@ *--------------------------------------------------------------------------------------------*/ import * as dom from 'vs/base/browser/dom'; +import * as nls from 'vs/nls'; import { renderMarkdown } from 'vs/base/browser/htmlContentRenderer'; import { onUnexpectedError } from 'vs/base/common/errors'; import { Disposable } from 'vs/base/common/lifecycle'; @@ -156,6 +157,14 @@ export class CommentsModelRenderer implements ITreeRenderer { } }); + const images = renderedComment.getElementsByTagName('img'); + for (let i = 0; i < images.length; i++) { + const image = images[i]; + const textDescription = dom.$(''); + textDescription.textContent = image.alt ? nls.localize('imageWithLabel', "Image: {0}", image.alt) : nls.localize('image', "Image"); + image.parentNode.replaceChild(textDescription, image); + } + templateData.commentText.appendChild(renderedComment); } } From 0fb38550fff7fd490b7e7bffcc7842551f4d481f Mon Sep 17 00:00:00 2001 From: Rob Lourens <roblourens@gmail.com> Date: Wed, 22 Aug 2018 16:10:09 -0700 Subject: [PATCH 1135/1276] #56950 - add missing 'type' --- src/vs/workbench/services/search/node/rawSearchService.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/src/vs/workbench/services/search/node/rawSearchService.ts b/src/vs/workbench/services/search/node/rawSearchService.ts index b0e6bafff60..a4739c36df1 100644 --- a/src/vs/workbench/services/search/node/rawSearchService.ts +++ b/src/vs/workbench/services/search/node/rawSearchService.ts @@ -174,6 +174,7 @@ export class SearchService implements IRawSearchService { type: 'success', stats: { detailStats: complete.stats, + type: 'searchProcess', fromCache: false, resultCount, sortingTime: undefined From 54507ada7385c7c75fcdf33e8b40910343d2d7e8 Mon Sep 17 00:00:00 2001 From: Rob Lourens <roblourens@gmail.com> Date: Wed, 22 Aug 2018 16:30:44 -0700 Subject: [PATCH 1136/1276] #56950 - don't swallow promise cancellations inside the EH --- .../services/search/node/rawSearchService.ts | 14 +++----------- 1 file changed, 3 insertions(+), 11 deletions(-) diff --git a/src/vs/workbench/services/search/node/rawSearchService.ts b/src/vs/workbench/services/search/node/rawSearchService.ts index a4739c36df1..0f98cd5918a 100644 --- a/src/vs/workbench/services/search/node/rawSearchService.ts +++ b/src/vs/workbench/services/search/node/rawSearchService.ts @@ -11,7 +11,7 @@ import { join, sep } from 'path'; import * as arrays from 'vs/base/common/arrays'; import { CancelablePromise, createCancelablePromise, toWinJsPromise } from 'vs/base/common/async'; import { CancellationToken } from 'vs/base/common/cancellation'; -import { canceled, isPromiseCanceledError } from 'vs/base/common/errors'; +import { canceled } from 'vs/base/common/errors'; import { Emitter, Event } from 'vs/base/common/event'; import * as objects from 'vs/base/common/objects'; import { StopWatch } from 'vs/base/common/stopwatch'; @@ -50,11 +50,7 @@ export class SearchService implements IRawSearchService { promise.then( c => emitter.fire(c), - err => { - if (!isPromiseCanceledError(err)) { - emitter.fire({ type: 'error', error: { message: err.message, stack: err.stack } }); - } - }); + err => emitter.fire({ type: 'error', error: { message: err.message, stack: err.stack } })); }, onLastListenerRemove: () => { promise.cancel(); @@ -75,11 +71,7 @@ export class SearchService implements IRawSearchService { promise.then( c => emitter.fire(c), - err => { - if (!isPromiseCanceledError(err)) { - emitter.fire({ type: 'error', error: { message: err.message, stack: err.stack } }); - } - }); + err => emitter.fire({ type: 'error', error: { message: err.message, stack: err.stack } })); }, onLastListenerRemove: () => { promise.cancel(); From 34b3302bb46f21d9a30b5aa9b76330abd1c6882a Mon Sep 17 00:00:00 2001 From: Rob Lourens <roblourens@gmail.com> Date: Wed, 22 Aug 2018 17:27:21 -0700 Subject: [PATCH 1137/1276] #56950 - add details to text search telemetry --- src/vs/platform/search/common/search.ts | 6 +- src/vs/workbench/api/node/extHostSearch.ts | 11 +- .../parts/search/browser/openFileHandler.ts | 2 +- .../parts/search/common/searchModel.ts | 8 +- .../services/search/node/ripgrepTextSearch.ts | 10 +- .../workbench/services/search/node/search.ts | 4 +- .../services/search/node/searchService.ts | 129 +++++++++--------- .../search/test/node/searchService.test.ts | 8 +- 8 files changed, 100 insertions(+), 78 deletions(-) diff --git a/src/vs/platform/search/common/search.ts b/src/vs/platform/search/common/search.ts index 33b58382025..5129ea788b9 100644 --- a/src/vs/platform/search/common/search.ts +++ b/src/vs/platform/search/common/search.ts @@ -155,13 +155,17 @@ export interface ISearchProgressItem extends IFileMatch, IProgress { export interface ISearchCompleteStats { limitHit?: boolean; - stats?: IFileSearchStats; + stats?: IFileSearchStats | ITextSearchStats; } export interface ISearchComplete extends ISearchCompleteStats { results: IFileMatch[]; } +export interface ITextSearchStats { + type: 'textSearchProvider' | 'searchProcess'; +} + export interface IFileSearchStats { fromCache: boolean; detailStats: ISearchEngineStats | ICachedSearchStats | IFileSearchProviderStats | IFileIndexProviderStats; diff --git a/src/vs/workbench/api/node/extHostSearch.ts b/src/vs/workbench/api/node/extHostSearch.ts index 95695f2674f..afdaaa29ef2 100644 --- a/src/vs/workbench/api/node/extHostSearch.ts +++ b/src/vs/workbench/api/node/extHostSearch.ts @@ -302,10 +302,10 @@ class TextSearchEngine { this.activeCancellationTokens = new Set(); } - public search(onProgress: (matches: IFileMatch[]) => void): TPromise<{ limitHit: boolean }> { + public search(onProgress: (matches: IFileMatch[]) => void): TPromise<ISearchCompleteStats> { const folderQueries = this.config.folderQueries; - return new TPromise<{ limitHit: boolean }>((resolve, reject) => { + return new TPromise<ISearchCompleteStats>((resolve, reject) => { this.collector = new TextSearchResultsCollector(onProgress); const onResult = (match: vscode.TextSearchResult, folderIdx: number) => { @@ -329,7 +329,12 @@ class TextSearchEngine { return this.searchInFolder(fq, r => onResult(r, i)); })).then(() => { this.collector.flush(); - resolve({ limitHit: this.isLimitHit }); + resolve({ + limitHit: this.isLimitHit, + stats: { + type: 'textSearchProvider' + } + }); }, (errs: Error[]) => { const errMsg = errs .map(err => toErrorMessage(err)) diff --git a/src/vs/workbench/parts/search/browser/openFileHandler.ts b/src/vs/workbench/parts/search/browser/openFileHandler.ts index 60b96a6e491..ea39b43e3b4 100644 --- a/src/vs/workbench/parts/search/browser/openFileHandler.ts +++ b/src/vs/workbench/parts/search/browser/openFileHandler.ts @@ -178,7 +178,7 @@ export class OpenFileHandler extends QuickOpenHandler { results.push(this.instantiationService.createInstance(FileEntry, fileMatch.resource, label, description, iconClass)); } - return new FileQuickOpenModel(results, complete.stats); + return new FileQuickOpenModel(results, <IFileSearchStats>complete.stats); }); } diff --git a/src/vs/workbench/parts/search/common/searchModel.ts b/src/vs/workbench/parts/search/common/searchModel.ts index 32b4b28571b..f650dd07152 100644 --- a/src/vs/workbench/parts/search/common/searchModel.ts +++ b/src/vs/workbench/parts/search/common/searchModel.ts @@ -12,7 +12,7 @@ import { TPromise } from 'vs/base/common/winjs.base'; import URI from 'vs/base/common/uri'; import { values, ResourceMap, TernarySearchTree } from 'vs/base/common/map'; import { Event, Emitter, fromPromise, stopwatch, anyEvent } from 'vs/base/common/event'; -import { ISearchService, ISearchProgressItem, ISearchComplete, ISearchQuery, IPatternInfo, IFileMatch } from 'vs/platform/search/common/search'; +import { ISearchService, ISearchProgressItem, ISearchComplete, ISearchQuery, IPatternInfo, IFileMatch, ITextSearchStats } from 'vs/platform/search/common/search'; import { ReplacePattern } from 'vs/platform/search/common/replace'; import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry'; import { Range } from 'vs/editor/common/core/range'; @@ -809,6 +809,9 @@ export class SearchModel extends Disposable { const options: IPatternInfo = objects.assign({}, this._searchQuery.contentPattern); delete options.pattern; + + const stats = completed.stats as ITextSearchStats; + /* __GDPR__ "searchResultsShown" : { "count" : { "classification": "SystemMetaData", "purpose": "FeatureInsight", "isMeasurement": true }, @@ -823,7 +826,8 @@ export class SearchModel extends Disposable { fileCount: this._searchResult.fileCount(), options, duration, - useRipgrep: this._searchQuery.useRipgrep + useRipgrep: this._searchQuery.useRipgrep, + type: stats && stats.type }); return completed; } diff --git a/src/vs/workbench/services/search/node/ripgrepTextSearch.ts b/src/vs/workbench/services/search/node/ripgrepTextSearch.ts index 1f5bb2e4025..5acd1f01b5c 100644 --- a/src/vs/workbench/services/search/node/ripgrepTextSearch.ts +++ b/src/vs/workbench/services/search/node/ripgrepTextSearch.ts @@ -16,7 +16,7 @@ import * as strings from 'vs/base/common/strings'; import { TPromise } from 'vs/base/common/winjs.base'; import * as encoding from 'vs/base/node/encoding'; import * as extfs from 'vs/base/node/extfs'; -import { IProgress } from 'vs/platform/search/common/search'; +import { IProgress, ITextSearchStats } from 'vs/platform/search/common/search'; import { rgPath } from 'vscode-ripgrep'; import { FileMatch, IFolderSearch, IRawSearch, ISerializedFileMatch, LineMatch, ISerializedSearchSuccess } from './search'; @@ -50,7 +50,9 @@ export class RipgrepEngine { done(null, { type: 'success', limitHit: false, - stats: null + stats: <ITextSearchStats>{ + type: 'searchProcess' + } }); return; } @@ -96,7 +98,9 @@ export class RipgrepEngine { done(null, { type: 'success', limitHit: true, - stats: null + stats: { + type: 'searchProcess' + } }); }); diff --git a/src/vs/workbench/services/search/node/search.ts b/src/vs/workbench/services/search/node/search.ts index 1a9cde2f512..5bf3d2059e2 100644 --- a/src/vs/workbench/services/search/node/search.ts +++ b/src/vs/workbench/services/search/node/search.ts @@ -7,7 +7,7 @@ import { TPromise } from 'vs/base/common/winjs.base'; import { IExpression } from 'vs/base/common/glob'; -import { IProgress, ILineMatch, IPatternInfo, IFileSearchStats, ISearchEngineStats } from 'vs/platform/search/common/search'; +import { IProgress, ILineMatch, IPatternInfo, IFileSearchStats, ISearchEngineStats, ITextSearchStats } from 'vs/platform/search/common/search'; import { ITelemetryData } from 'vs/platform/telemetry/common/telemetry'; import { Event } from 'vs/base/common/event'; @@ -62,7 +62,7 @@ export interface ISearchEngine<T> { export interface ISerializedSearchSuccess { type: 'success'; limitHit: boolean; - stats: IFileSearchStats; + stats: IFileSearchStats | ITextSearchStats; } export interface ISearchEngineSuccess { diff --git a/src/vs/workbench/services/search/node/searchService.ts b/src/vs/workbench/services/search/node/searchService.ts index 4d548ed6fa4..c961c514b68 100644 --- a/src/vs/workbench/services/search/node/searchService.ts +++ b/src/vs/workbench/services/search/node/searchService.ts @@ -22,7 +22,7 @@ import { IModelService } from 'vs/editor/common/services/modelService'; import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; import { IDebugParams, IEnvironmentService } from 'vs/platform/environment/common/environment'; import { ILogService } from 'vs/platform/log/common/log'; -import { FileMatch, ICachedSearchStats, IFileMatch, IFolderQuery, IProgress, ISearchComplete, ISearchConfiguration, ISearchEngineStats, ISearchProgressItem, ISearchQuery, ISearchResultProvider, ISearchService, LineMatch, pathIncludedInQuery, QueryType, SearchProviderType } from 'vs/platform/search/common/search'; +import { FileMatch, ICachedSearchStats, IFileMatch, IFolderQuery, IProgress, ISearchComplete, ISearchConfiguration, ISearchEngineStats, ISearchProgressItem, ISearchQuery, ISearchResultProvider, ISearchService, LineMatch, pathIncludedInQuery, QueryType, SearchProviderType, IFileSearchStats } from 'vs/platform/search/common/search'; import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry'; import { IEditorService } from 'vs/workbench/services/editor/common/editorService'; import { IExtensionService } from 'vs/workbench/services/extensions/common/extensions'; @@ -224,72 +224,77 @@ export class SearchService extends Disposable implements ISearchService { const endToEndTime = e2eSW.elapsed(); this.logService.trace(`SearchService#search: ${endToEndTime}ms`); completes.forEach(complete => { - if (complete.stats) { - if (complete.stats.fromCache) { - const cacheStats: ICachedSearchStats = complete.stats.detailStats as ICachedSearchStats; - - /* __GDPR__ - "cachedSearchComplete" : { - "resultCount" : { "classification": "SystemMetaData", "purpose": "PerformanceAndHealth", "isMeasurement": true }, - "workspaceFolderCount" : { "classification": "SystemMetaData", "purpose": "PerformanceAndHealth", "isMeasurement": true }, - "type" : { "classification": "SystemMetaData", "purpose": "PerformanceAndHealth" }, - "endToEndTime" : { "classification": "SystemMetaData", "purpose": "PerformanceAndHealth", "isMeasurement": true }, - "sortingTime" : { "classification": "SystemMetaData", "purpose": "PerformanceAndHealth", "isMeasurement": true }, - "cacheWasResolved" : { "classification": "SystemMetaData", "purpose": "PerformanceAndHealth" }, - "cacheLookupTime" : { "classification": "SystemMetaData", "purpose": "PerformanceAndHealth", "isMeasurement": true }, - "cacheFilterTime" : { "classification": "SystemMetaData", "purpose": "PerformanceAndHealth", "isMeasurement": true }, - "cacheEntryCount" : { "classification": "SystemMetaData", "purpose": "PerformanceAndHealth", "isMeasurement": true }, - } - */ - this.telemetryService.publicLog('cachedSearchComplete', { - resultCount: complete.stats.resultCount, - workspaceFolderCount: query.folderQueries.length, - type: complete.stats.type, - endToEndTime: endToEndTime, - sortingTime: complete.stats.sortingTime, - cacheWasResolved: cacheStats.cacheWasResolved, - cacheLookupTime: cacheStats.cacheLookupTime, - cacheFilterTime: cacheStats.cacheFilterTime, - cacheEntryCount: cacheStats.cacheEntryCount - }); - } else { - const searchEngineStats: ISearchEngineStats = complete.stats.detailStats as ISearchEngineStats; - - /* __GDPR__ - "searchComplete" : { - "resultCount" : { "classification": "SystemMetaData", "purpose": "PerformanceAndHealth", "isMeasurement": true }, - "workspaceFolderCount" : { "classification": "SystemMetaData", "purpose": "PerformanceAndHealth", "isMeasurement": true }, - "type" : { "classification": "SystemMetaData", "purpose": "PerformanceAndHealth" }, - "endToEndTime" : { "classification": "SystemMetaData", "purpose": "PerformanceAndHealth", "isMeasurement": true }, - "sortingTime" : { "classification": "SystemMetaData", "purpose": "PerformanceAndHealth", "isMeasurement": true }, - "traversal" : { "classification": "SystemMetaData", "purpose": "PerformanceAndHealth" }, - "fileWalkTime" : { "classification": "SystemMetaData", "purpose": "PerformanceAndHealth", "isMeasurement": true }, - "directoriesWalked" : { "classification": "SystemMetaData", "purpose": "PerformanceAndHealth", "isMeasurement": true }, - "filesWalked" : { "classification": "SystemMetaData", "purpose": "PerformanceAndHealth", "isMeasurement": true }, - "cmdTime" : { "classification": "SystemMetaData", "purpose": "PerformanceAndHealth", "isMeasurement": true }, - "cmdResultCount" : { "classification": "SystemMetaData", "purpose": "PerformanceAndHealth", "isMeasurement": true } - } - */ - this.telemetryService.publicLog('searchComplete', { - resultCount: complete.stats.resultCount, - workspaceFolderCount: query.folderQueries.length, - type: complete.stats.type, - endToEndTime: endToEndTime, - sortingTime: complete.stats.sortingTime, - traversal: searchEngineStats.traversal, - fileWalkTime: searchEngineStats.fileWalkTime, - directoriesWalked: searchEngineStats.directoriesWalked, - filesWalked: searchEngineStats.filesWalked, - cmdTime: searchEngineStats.cmdTime, - cmdResultCount: searchEngineStats.cmdResultCount - }); - } - } + this.sendTelemetry(query, endToEndTime, complete); }); return completes; }); } + private sendTelemetry(query: ISearchQuery, endToEndTime: number, complete: ISearchComplete): void { + if (query.type === QueryType.File && complete.stats) { + const fileSearchStats = complete.stats as IFileSearchStats; + if (fileSearchStats.fromCache) { + const cacheStats: ICachedSearchStats = fileSearchStats.detailStats as ICachedSearchStats; + + /* __GDPR__ + "cachedSearchComplete" : { + "resultCount" : { "classification": "SystemMetaData", "purpose": "PerformanceAndHealth", "isMeasurement": true }, + "workspaceFolderCount" : { "classification": "SystemMetaData", "purpose": "PerformanceAndHealth", "isMeasurement": true }, + "type" : { "classification": "SystemMetaData", "purpose": "PerformanceAndHealth" }, + "endToEndTime" : { "classification": "SystemMetaData", "purpose": "PerformanceAndHealth", "isMeasurement": true }, + "sortingTime" : { "classification": "SystemMetaData", "purpose": "PerformanceAndHealth", "isMeasurement": true }, + "cacheWasResolved" : { "classification": "SystemMetaData", "purpose": "PerformanceAndHealth" }, + "cacheLookupTime" : { "classification": "SystemMetaData", "purpose": "PerformanceAndHealth", "isMeasurement": true }, + "cacheFilterTime" : { "classification": "SystemMetaData", "purpose": "PerformanceAndHealth", "isMeasurement": true }, + "cacheEntryCount" : { "classification": "SystemMetaData", "purpose": "PerformanceAndHealth", "isMeasurement": true }, + } + */ + this.telemetryService.publicLog('cachedSearchComplete', { + resultCount: fileSearchStats.resultCount, + workspaceFolderCount: query.folderQueries.length, + type: fileSearchStats.type, + endToEndTime: endToEndTime, + sortingTime: fileSearchStats.sortingTime, + cacheWasResolved: cacheStats.cacheWasResolved, + cacheLookupTime: cacheStats.cacheLookupTime, + cacheFilterTime: cacheStats.cacheFilterTime, + cacheEntryCount: cacheStats.cacheEntryCount + }); + } else { + const searchEngineStats: ISearchEngineStats = fileSearchStats.detailStats as ISearchEngineStats; + + /* __GDPR__ + "searchComplete" : { + "resultCount" : { "classification": "SystemMetaData", "purpose": "PerformanceAndHealth", "isMeasurement": true }, + "workspaceFolderCount" : { "classification": "SystemMetaData", "purpose": "PerformanceAndHealth", "isMeasurement": true }, + "type" : { "classification": "SystemMetaData", "purpose": "PerformanceAndHealth" }, + "endToEndTime" : { "classification": "SystemMetaData", "purpose": "PerformanceAndHealth", "isMeasurement": true }, + "sortingTime" : { "classification": "SystemMetaData", "purpose": "PerformanceAndHealth", "isMeasurement": true }, + "traversal" : { "classification": "SystemMetaData", "purpose": "PerformanceAndHealth" }, + "fileWalkTime" : { "classification": "SystemMetaData", "purpose": "PerformanceAndHealth", "isMeasurement": true }, + "directoriesWalked" : { "classification": "SystemMetaData", "purpose": "PerformanceAndHealth", "isMeasurement": true }, + "filesWalked" : { "classification": "SystemMetaData", "purpose": "PerformanceAndHealth", "isMeasurement": true }, + "cmdTime" : { "classification": "SystemMetaData", "purpose": "PerformanceAndHealth", "isMeasurement": true }, + "cmdResultCount" : { "classification": "SystemMetaData", "purpose": "PerformanceAndHealth", "isMeasurement": true } + } + */ + this.telemetryService.publicLog('searchComplete', { + resultCount: fileSearchStats.resultCount, + workspaceFolderCount: query.folderQueries.length, + type: fileSearchStats.type, + endToEndTime: endToEndTime, + sortingTime: fileSearchStats.sortingTime, + traversal: searchEngineStats.traversal, + fileWalkTime: searchEngineStats.fileWalkTime, + directoriesWalked: searchEngineStats.directoriesWalked, + filesWalked: searchEngineStats.filesWalked, + cmdTime: searchEngineStats.cmdTime, + cmdResultCount: searchEngineStats.cmdResultCount + }); + } + } + } + private getLocalResults(query: ISearchQuery): ResourceMap<IFileMatch> { const localResults = new ResourceMap<IFileMatch>(); diff --git a/src/vs/workbench/services/search/test/node/searchService.test.ts b/src/vs/workbench/services/search/test/node/searchService.test.ts index 16a13400505..37264624d97 100644 --- a/src/vs/workbench/services/search/test/node/searchService.test.ts +++ b/src/vs/workbench/services/search/test/node/searchService.test.ts @@ -10,7 +10,7 @@ import * as path from 'path'; import { getPathFromAmdModule } from 'vs/base/common/amd'; import { CancelablePromise, createCancelablePromise } from 'vs/base/common/async'; import { Emitter, Event } from 'vs/base/common/event'; -import { IProgress, ISearchEngineStats } from 'vs/platform/search/common/search'; +import { IProgress, ISearchEngineStats, IFileSearchStats } from 'vs/platform/search/common/search'; import { SearchService as RawSearchService } from 'vs/workbench/services/search/node/rawSearchService'; import { IFolderSearch, IRawFileMatch, IRawSearch, ISearchEngine, ISerializedFileMatch, ISerializedSearchComplete, ISerializedSearchProgressItem, ISerializedSearchSuccess, ISearchEngineSuccess } from 'vs/workbench/services/search/node/search'; import { DiskSearch } from 'vs/workbench/services/search/node/searchService'; @@ -297,7 +297,7 @@ suite('SearchService', () => { sortByScore: true, cacheKey: 'x' }, cb, undefined, -1).then(complete => { - assert.strictEqual(complete.stats.fromCache, false); + assert.strictEqual((<IFileSearchStats>complete.stats).fromCache, false); assert.deepStrictEqual(results, [path.normalize('/some/where/bcb'), path.normalize('/some/where/bbc'), path.normalize('/some/where/aab')]); }).then(() => { const results = []; @@ -314,7 +314,7 @@ suite('SearchService', () => { sortByScore: true, cacheKey: 'x' }, cb, undefined, -1).then(complete => { - assert.ok(complete.stats.fromCache); + assert.ok((<IFileSearchStats>complete.stats).fromCache); assert.deepStrictEqual(results, [path.normalize('/some/where/bcb'), path.normalize('/some/where/bbc')]); }, null); }).then(() => { @@ -340,7 +340,7 @@ suite('SearchService', () => { sortByScore: true, cacheKey: 'x' }, cb, undefined, -1).then(complete => { - assert.strictEqual(complete.stats.fromCache, false); + assert.strictEqual((<IFileSearchStats>complete.stats).fromCache, false); assert.deepStrictEqual(results, [path.normalize('/some/where/bc')]); }); }); From 07618102efdd63f09949ce54c161e7fd2a954ee8 Mon Sep 17 00:00:00 2001 From: Rob Lourens <roblourens@gmail.com> Date: Wed, 22 Aug 2018 19:08:40 -0700 Subject: [PATCH 1138/1276] Fix search unit tests --- src/vs/workbench/parts/search/common/searchModel.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vs/workbench/parts/search/common/searchModel.ts b/src/vs/workbench/parts/search/common/searchModel.ts index f650dd07152..cb1aa7e2c70 100644 --- a/src/vs/workbench/parts/search/common/searchModel.ts +++ b/src/vs/workbench/parts/search/common/searchModel.ts @@ -810,7 +810,7 @@ export class SearchModel extends Disposable { const options: IPatternInfo = objects.assign({}, this._searchQuery.contentPattern); delete options.pattern; - const stats = completed.stats as ITextSearchStats; + const stats = completed && completed.stats as ITextSearchStats; /* __GDPR__ "searchResultsShown" : { From e0b85fb2b3925fed05c89f0e19d9044b4141e702 Mon Sep 17 00:00:00 2001 From: Johannes Rieken <johannes.rieken@gmail.com> Date: Thu, 23 Aug 2018 09:53:31 +0200 Subject: [PATCH 1139/1276] fix #56979 --- src/vs/base/browser/ui/breadcrumbs/breadcrumbsWidget.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/vs/base/browser/ui/breadcrumbs/breadcrumbsWidget.ts b/src/vs/base/browser/ui/breadcrumbs/breadcrumbsWidget.ts index f5544a9cd9a..2ba476b8464 100644 --- a/src/vs/base/browser/ui/breadcrumbs/breadcrumbsWidget.ts +++ b/src/vs/base/browser/ui/breadcrumbs/breadcrumbsWidget.ts @@ -90,7 +90,8 @@ export class BreadcrumbsWidget { vertical: ScrollbarVisibility.Hidden, horizontal: ScrollbarVisibility.Auto, horizontalScrollbarSize: 3, - useShadows: false + useShadows: false, + scrollYToX: true }); this._disposables.push(this._scrollable); this._disposables.push(dom.addStandardDisposableListener(this._domNode, 'click', e => this._onClick(e))); From 1324e84235c291d0860276f7d767aecf774ce1de Mon Sep 17 00:00:00 2001 From: Johannes Rieken <johannes.rieken@gmail.com> Date: Thu, 23 Aug 2018 10:03:54 +0200 Subject: [PATCH 1140/1276] align breadcrumbs hight with section header height (22px), fixes #56022 --- src/vs/workbench/browser/parts/editor/breadcrumbsControl.ts | 2 +- .../workbench/browser/parts/editor/media/tabstitlecontrol.css | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/vs/workbench/browser/parts/editor/breadcrumbsControl.ts b/src/vs/workbench/browser/parts/editor/breadcrumbsControl.ts index 3283d6ca571..03257f1b0ed 100644 --- a/src/vs/workbench/browser/parts/editor/breadcrumbsControl.ts +++ b/src/vs/workbench/browser/parts/editor/breadcrumbsControl.ts @@ -125,7 +125,7 @@ export interface IBreadcrumbsControlOptions { export class BreadcrumbsControl { - static HEIGHT = 25; + static HEIGHT = 22; static readonly Payload_Reveal = {}; static readonly Payload_RevealAside = {}; diff --git a/src/vs/workbench/browser/parts/editor/media/tabstitlecontrol.css b/src/vs/workbench/browser/parts/editor/media/tabstitlecontrol.css index 4d77c434854..5486621c694 100644 --- a/src/vs/workbench/browser/parts/editor/media/tabstitlecontrol.css +++ b/src/vs/workbench/browser/parts/editor/media/tabstitlecontrol.css @@ -259,7 +259,7 @@ .monaco-workbench > .part.editor > .content .editor-group-container > .title .tabs-breadcrumbs .breadcrumbs-control { flex: 1 100%; - height: 25px; + height: 22px; cursor: default; } From 1b2dceffb409dbb1a31abafb7dcf445247687faa Mon Sep 17 00:00:00 2001 From: Benjamin Pasero <benjpas@microsoft.com> Date: Thu, 23 Aug 2018 10:08:46 +0200 Subject: [PATCH 1141/1276] :lipstick: (more for https://electronjs.org/docs/tutorial/security) --- src/vs/code/electron-main/app.ts | 31 +++++++++++++++++++------------ 1 file changed, 19 insertions(+), 12 deletions(-) diff --git a/src/vs/code/electron-main/app.ts b/src/vs/code/electron-main/app.ts index 1f1ab8d4ca7..d68fb99ae68 100644 --- a/src/vs/code/electron-main/app.ts +++ b/src/vs/code/electron-main/app.ts @@ -125,29 +125,22 @@ export class CodeApplication { } }); - const isValidWebviewSource = (source: string): boolean => { - if (!source) { - return false; - } - if (source === 'data:text/html;charset=utf-8,%3C%21DOCTYPE%20html%3E%0D%0A%3Chtml%20lang%3D%22en%22%20style%3D%22width%3A%20100%25%3B%20height%3A%20100%25%22%3E%0D%0A%3Chead%3E%0D%0A%09%3Ctitle%3EVirtual%20Document%3C%2Ftitle%3E%0D%0A%3C%2Fhead%3E%0D%0A%3Cbody%20style%3D%22margin%3A%200%3B%20overflow%3A%20hidden%3B%20width%3A%20100%25%3B%20height%3A%20100%25%22%3E%0D%0A%3C%2Fbody%3E%0D%0A%3C%2Fhtml%3E') { - return true; - } - const srcUri: any = URI.parse(source.toLowerCase()).toString(); - return srcUri.startsWith(URI.file(this.environmentService.appRoot.toLowerCase()).toString()); - }; - // Security related measures (https://electronjs.org/docs/tutorial/security) // DO NOT CHANGE without consulting the documentation app.on('web-contents-created', (event: any, contents) => { contents.on('will-attach-webview', (event: Electron.Event, webPreferences, params) => { + + // Ensure defaults delete webPreferences.preload; webPreferences.nodeIntegration = false; // Verify URLs being loaded - if (isValidWebviewSource(params.src) && isValidWebviewSource(webPreferences.preloadURL)) { + if (this.isValidWebviewSource(params.src) && this.isValidWebviewSource(webPreferences.preloadURL)) { return; } + delete webPreferences.preloadUrl; + // Otherwise prevent loading this.logService.error('webContents#web-contents-created: Prevented webview attach'); @@ -247,6 +240,20 @@ export class CodeApplication { }); } + private isValidWebviewSource(source: string): boolean { + if (!source) { + return false; + } + + if (source === 'data:text/html;charset=utf-8,%3C%21DOCTYPE%20html%3E%0D%0A%3Chtml%20lang%3D%22en%22%20style%3D%22width%3A%20100%25%3B%20height%3A%20100%25%22%3E%0D%0A%3Chead%3E%0D%0A%09%3Ctitle%3EVirtual%20Document%3C%2Ftitle%3E%0D%0A%3C%2Fhead%3E%0D%0A%3Cbody%20style%3D%22margin%3A%200%3B%20overflow%3A%20hidden%3B%20width%3A%20100%25%3B%20height%3A%20100%25%22%3E%0D%0A%3C%2Fbody%3E%0D%0A%3C%2Fhtml%3E') { + return true; + } + + const srcUri: any = URI.parse(source.toLowerCase()).toString(); + + return srcUri.startsWith(URI.file(this.environmentService.appRoot.toLowerCase()).toString()); + } + private onUnexpectedError(err: Error): void { if (err) { From 63ab3980b2ce01430c2349e099f5fd9301d9c6a2 Mon Sep 17 00:00:00 2001 From: Benjamin Pasero <benjpas@microsoft.com> Date: Thu, 23 Aug 2018 10:29:26 +0200 Subject: [PATCH 1142/1276] :lipstick: --- src/vs/code/{electron-main/contributions.ts => code.main.ts} | 0 src/vs/code/electron-main/main.ts | 2 +- 2 files changed, 1 insertion(+), 1 deletion(-) rename src/vs/code/{electron-main/contributions.ts => code.main.ts} (100%) diff --git a/src/vs/code/electron-main/contributions.ts b/src/vs/code/code.main.ts similarity index 100% rename from src/vs/code/electron-main/contributions.ts rename to src/vs/code/code.main.ts diff --git a/src/vs/code/electron-main/main.ts b/src/vs/code/electron-main/main.ts index dbe95eb11e2..3c2c255e3f7 100644 --- a/src/vs/code/electron-main/main.ts +++ b/src/vs/code/electron-main/main.ts @@ -5,7 +5,7 @@ 'use strict'; -import 'vs/code/electron-main/contributions'; +import 'vs/code/code.main'; import { app, dialog } from 'electron'; import { assign } from 'vs/base/common/objects'; import * as platform from 'vs/base/common/platform'; From c2f6520250af3a469790e50ad9ce84caca5bdedb Mon Sep 17 00:00:00 2001 From: Sandeep Somavarapu <sasomava@microsoft.com> Date: Thu, 23 Aug 2018 10:31:46 +0200 Subject: [PATCH 1143/1276] Disable only local extension when not running --- .../extensions/electron-browser/extensionsActions.ts | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/vs/workbench/parts/extensions/electron-browser/extensionsActions.ts b/src/vs/workbench/parts/extensions/electron-browser/extensionsActions.ts index 645a6674587..753719af952 100644 --- a/src/vs/workbench/parts/extensions/electron-browser/extensionsActions.ts +++ b/src/vs/workbench/parts/extensions/electron-browser/extensionsActions.ts @@ -18,7 +18,7 @@ import { IContextMenuService } from 'vs/platform/contextview/browser/contextView import { IDisposable, dispose, Disposable } from 'vs/base/common/lifecycle'; import { IExtension, ExtensionState, IExtensionsWorkbenchService, VIEWLET_ID, IExtensionsViewlet, AutoUpdateConfigurationKey } from 'vs/workbench/parts/extensions/common/extensions'; import { ExtensionsConfigurationInitialContent } from 'vs/workbench/parts/extensions/common/extensionsFileTemplate'; -import { LocalExtensionType, IExtensionEnablementService, IExtensionTipsService, EnablementState, ExtensionsLabel, IExtensionRecommendation, IGalleryExtension, IExtensionsConfigContent } from 'vs/platform/extensionManagement/common/extensionManagement'; +import { LocalExtensionType, IExtensionEnablementService, IExtensionTipsService, EnablementState, ExtensionsLabel, IExtensionRecommendation, IGalleryExtension, IExtensionsConfigContent, IExtensionManagementServerService } from 'vs/platform/extensionManagement/common/extensionManagement'; import { areSameExtensions } from 'vs/platform/extensionManagement/common/extensionManagementUtil'; import { IInstantiationService, ServicesAccessor } from 'vs/platform/instantiation/common/instantiation'; import { ToggleViewletAction } from 'vs/workbench/browser/viewlet'; @@ -909,6 +909,7 @@ export class ReloadAction extends Action { @IExtensionsWorkbenchService private extensionsWorkbenchService: IExtensionsWorkbenchService, @IWindowService private windowService: IWindowService, @IExtensionService private extensionService: IExtensionService, + @IExtensionManagementServerService private extensionManagementServerService: IExtensionManagementServerService, @IExtensionEnablementService private extensionEnablementService: IExtensionEnablementService ) { super('extensions.reload', localize('reloadAction', "Reload"), ReloadAction.DisabledClass, false); @@ -961,7 +962,10 @@ export class ReloadAction extends Action { return; } } else { - if (!isDisabled) { + const extensionServer = this.extensionManagementServerService.getExtensionManagementServer(installed.local.location); + const localServer = this.extensionManagementServerService.getLocalExtensionManagementServer(); + // Only extension from local server requires reload if it is not running on the server + if (extensionServer && extensionServer.authority === localServer.authority && !isDisabled) { // Requires reload to enable the extension this.enabled = true; this.tooltip = localize('postEnableTooltip', "Reload to activate"); From 44473c744892c2b20e327254473c8035875a1ac8 Mon Sep 17 00:00:00 2001 From: Daniel McNab <36049421+DJMcNab@users.noreply.github.com> Date: Thu, 23 Aug 2018 09:43:49 +0100 Subject: [PATCH 1144/1276] add rust region comments --- extensions/rust/language-configuration.json | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/extensions/rust/language-configuration.json b/extensions/rust/language-configuration.json index 34396c3121e..d0af7828288 100644 --- a/extensions/rust/language-configuration.json +++ b/extensions/rust/language-configuration.json @@ -20,5 +20,11 @@ ["(", ")"], ["\"", "\""], ["'", "'"] - ] + ], + "folding": { + "markers": { + "start": "^\\s//region", + "end": "^\\s//endregion" + } + } } From 84a0f5df4273840bcf99a6d203b96e703fc64f96 Mon Sep 17 00:00:00 2001 From: Johannes Rieken <johannes.rieken@gmail.com> Date: Thu, 23 Aug 2018 10:45:12 +0200 Subject: [PATCH 1145/1276] fix #56983 --- .../parts/editor/breadcrumbsControl.ts | 54 +++++++++++---- .../browser/parts/editor/breadcrumbsPicker.ts | 65 ++++++++++--------- 2 files changed, 77 insertions(+), 42 deletions(-) diff --git a/src/vs/workbench/browser/parts/editor/breadcrumbsControl.ts b/src/vs/workbench/browser/parts/editor/breadcrumbsControl.ts index 03257f1b0ed..9ec7d139d25 100644 --- a/src/vs/workbench/browser/parts/editor/breadcrumbsControl.ts +++ b/src/vs/workbench/browser/parts/editor/breadcrumbsControl.ts @@ -9,40 +9,41 @@ import * as dom from 'vs/base/browser/dom'; import { StandardMouseEvent } from 'vs/base/browser/mouseEvent'; import { BreadcrumbsItem, BreadcrumbsWidget, IBreadcrumbsItemEvent } from 'vs/base/browser/ui/breadcrumbs/breadcrumbsWidget'; import { IconLabel } from 'vs/base/browser/ui/iconLabel/iconLabel'; +import { tail } from 'vs/base/common/arrays'; +import { timeout } from 'vs/base/common/async'; import { KeyCode, KeyMod } from 'vs/base/common/keyCodes'; import { combinedDisposable, dispose, IDisposable } from 'vs/base/common/lifecycle'; import { Schemas } from 'vs/base/common/network'; import { isEqual } from 'vs/base/common/resources'; +import URI from 'vs/base/common/uri'; import 'vs/css!./media/breadcrumbscontrol'; import { ICodeEditor, isCodeEditor } from 'vs/editor/browser/editorBrowser'; import { Range } from 'vs/editor/common/core/range'; +import { ICodeEditorViewState, ScrollType } from 'vs/editor/common/editorCommon'; import { symbolKindToCssClass } from 'vs/editor/common/modes'; import { OutlineElement, OutlineGroup, OutlineModel, TreeElement } from 'vs/editor/contrib/documentSymbols/outlineModel'; +import { localize } from 'vs/nls'; +import { MenuId, MenuRegistry } from 'vs/platform/actions/common/actions'; +import { CommandsRegistry } from 'vs/platform/commands/common/commands'; import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; import { ContextKeyExpr, IContextKey, IContextKeyService, RawContextKey } from 'vs/platform/contextkey/common/contextkey'; import { IContextViewService } from 'vs/platform/contextview/browser/contextView'; import { FileKind, IFileService, IFileStat } from 'vs/platform/files/common/files'; import { IInstantiationService, ServicesAccessor } from 'vs/platform/instantiation/common/instantiation'; import { KeybindingsRegistry, KeybindingWeight } from 'vs/platform/keybinding/common/keybindingsRegistry'; +import { IListService, WorkbenchListFocusContextKey } from 'vs/platform/list/browser/listService'; import { IQuickOpenService } from 'vs/platform/quickOpen/common/quickOpen'; +import { ColorIdentifier } from 'vs/platform/theme/common/colorRegistry'; import { attachBreadcrumbsStyler } from 'vs/platform/theme/common/styler'; import { IThemeService } from 'vs/platform/theme/common/themeService'; import { IWorkspaceContextService } from 'vs/platform/workspace/common/workspace'; import { FileLabel } from 'vs/workbench/browser/labels'; import { BreadcrumbsConfig, IBreadcrumbsService } from 'vs/workbench/browser/parts/editor/breadcrumbs'; import { BreadcrumbElement, EditorBreadcrumbsModel, FileElement } from 'vs/workbench/browser/parts/editor/breadcrumbsModel'; -import { createBreadcrumbsPicker, BreadcrumbsPicker } from 'vs/workbench/browser/parts/editor/breadcrumbsPicker'; +import { BreadcrumbsPicker, createBreadcrumbsPicker } from 'vs/workbench/browser/parts/editor/breadcrumbsPicker'; import { EditorGroupView } from 'vs/workbench/browser/parts/editor/editorGroupView'; -import { IEditorService, SIDE_GROUP, SIDE_GROUP_TYPE, ACTIVE_GROUP_TYPE, ACTIVE_GROUP } from 'vs/workbench/services/editor/common/editorService'; +import { ACTIVE_GROUP, ACTIVE_GROUP_TYPE, IEditorService, SIDE_GROUP, SIDE_GROUP_TYPE } from 'vs/workbench/services/editor/common/editorService'; import { IEditorGroupsService } from 'vs/workbench/services/group/common/editorGroupsService'; -import { MenuRegistry, MenuId } from 'vs/platform/actions/common/actions'; -import { localize } from 'vs/nls'; -import { CommandsRegistry } from 'vs/platform/commands/common/commands'; -import { tail } from 'vs/base/common/arrays'; -import { WorkbenchListFocusContextKey, IListService } from 'vs/platform/list/browser/listService'; -import { ColorIdentifier } from 'vs/platform/theme/common/colorRegistry'; -import { timeout } from 'vs/base/common/async'; -import URI from 'vs/base/common/uri'; class Item extends BreadcrumbsItem { @@ -280,17 +281,42 @@ export class BreadcrumbsControl { // show picker let picker: BreadcrumbsPicker; + let editor = this._editorGroup.activeControl.getControl() as ICodeEditor; + let editorDecorations: string[] = []; + let editorViewState: ICodeEditorViewState; + this._contextViewService.showContextView({ render: (parent: HTMLElement) => { picker = createBreadcrumbsPicker(this._instantiationService, parent, element); - let listener = picker.onDidPickElement(data => { + let selectListener = picker.onDidPickElement(data => { + if (data.target) { + editorViewState = undefined; + } this._contextViewService.hideContextView(this); this._revealInEditor(event, data.target, this._getEditorGroup(data.payload && data.payload.originalEvent)); }); + let focusListener = picker.onDidFocusElement(data => { + if (!(data.target instanceof OutlineElement)) { + return; + } + if (!editorViewState) { + editorViewState = editor.saveViewState(); + } + const { symbol } = data.target; + editor.revealRangeInCenter(symbol.range, ScrollType.Smooth); + editorDecorations = editor.deltaDecorations(editorDecorations, [{ + range: symbol.range, + options: { + className: 'rangeHighlight', + isWholeLine: true + } + }]); + + }); this._breadcrumbsPickerShowing = true; this._updateCkBreadcrumbsActive(); - return combinedDisposable([listener, picker]); + return combinedDisposable([selectListener, focusListener, picker]); }, getAnchor: () => { let maxInnerWidth = window.innerWidth - 8 /*a little less the the full widget*/; @@ -320,6 +346,10 @@ export class BreadcrumbsControl { return { x, y }; }, onHide: (data) => { + editor.deltaDecorations(editorDecorations, []); + if (editorViewState) { + editor.restoreViewState(editorViewState); + } this._breadcrumbsPickerShowing = false; this._updateCkBreadcrumbsActive(); if (data === this) { diff --git a/src/vs/workbench/browser/parts/editor/breadcrumbsPicker.ts b/src/vs/workbench/browser/parts/editor/breadcrumbsPicker.ts index 0efbd1a0909..46296d827e9 100644 --- a/src/vs/workbench/browser/parts/editor/breadcrumbsPicker.ts +++ b/src/vs/workbench/browser/parts/editor/breadcrumbsPicker.ts @@ -7,30 +7,29 @@ import * as dom from 'vs/base/browser/dom'; import { compareFileNames } from 'vs/base/common/comparers'; +import { onUnexpectedError } from 'vs/base/common/errors'; import { Emitter, Event } from 'vs/base/common/event'; +import { createMatches, FuzzyScore, fuzzyScore } from 'vs/base/common/filters'; +import * as glob from 'vs/base/common/glob'; import { dispose, IDisposable } from 'vs/base/common/lifecycle'; -import { dirname, isEqual, basename } from 'vs/base/common/resources'; +import { basename, dirname, isEqual } from 'vs/base/common/resources'; import URI from 'vs/base/common/uri'; import { TPromise } from 'vs/base/common/winjs.base'; -import { IDataSource, IRenderer, ISelectionEvent, ISorter, ITree, IFilter } from 'vs/base/parts/tree/browser/tree'; +import { IDataSource, IFilter, IRenderer, ISorter, ITree } from 'vs/base/parts/tree/browser/tree'; import 'vs/css!./media/breadcrumbscontrol'; import { OutlineElement, OutlineModel, TreeElement } from 'vs/editor/contrib/documentSymbols/outlineModel'; import { OutlineDataSource, OutlineItemComparator, OutlineRenderer } from 'vs/editor/contrib/documentSymbols/outlineTree'; import { localize } from 'vs/nls'; -import { FileKind, IFileService, IFileStat } from 'vs/platform/files/common/files'; -import { IInstantiationService, IConstructorSignature1 } from 'vs/platform/instantiation/common/instantiation'; -import { HighlightingWorkbenchTree, IHighlightingTreeConfiguration, IHighlightingRenderer } from 'vs/platform/list/browser/listService'; -import { IThemeService } from 'vs/platform/theme/common/themeService'; -import { FileLabel } from 'vs/workbench/browser/labels'; -import { BreadcrumbElement, FileElement } from 'vs/workbench/browser/parts/editor/breadcrumbsModel'; -import { onUnexpectedError } from 'vs/base/common/errors'; -import { breadcrumbsPickerBackground, widgetShadow } from 'vs/platform/theme/common/colorRegistry'; -import { FuzzyScore, createMatches, fuzzyScore } from 'vs/base/common/filters'; -import { IWorkspaceContextService, IWorkspace, IWorkspaceFolder } from 'vs/platform/workspace/common/workspace'; 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 { HighlightingWorkbenchTree, IHighlightingRenderer, IHighlightingTreeConfiguration } from 'vs/platform/list/browser/listService'; +import { breadcrumbsPickerBackground, widgetShadow } from 'vs/platform/theme/common/colorRegistry'; +import { IThemeService } from 'vs/platform/theme/common/themeService'; +import { IWorkspace, IWorkspaceContextService, IWorkspaceFolder } from 'vs/platform/workspace/common/workspace'; +import { FileLabel } from 'vs/workbench/browser/labels'; import { BreadcrumbsConfig } from 'vs/workbench/browser/parts/editor/breadcrumbs'; -import * as glob from 'vs/base/common/glob'; -import { } from 'vs/base/common/paths'; +import { BreadcrumbElement, FileElement } from 'vs/workbench/browser/parts/editor/breadcrumbsModel'; export function createBreadcrumbsPicker(instantiationService: IInstantiationService, parent: HTMLElement, element: BreadcrumbElement): BreadcrumbsPicker { let ctor: IConstructorSignature1<HTMLElement, BreadcrumbsPicker> = element instanceof FileElement ? BreadcrumbsFilePicker : BreadcrumbsOutlinePicker; @@ -49,6 +48,9 @@ export abstract class BreadcrumbsPicker { private readonly _onDidPickElement = new Emitter<{ target: any, payload: any }>(); readonly onDidPickElement: Event<{ target: any, payload: any }> = this._onDidPickElement.event; + private readonly _onDidFocusElement = new Emitter<{ target: any, payload: any }>(); + readonly onDidFocusElement: Event<{ target: any, payload: any }> = this._onDidFocusElement.event; + constructor( parent: HTMLElement, @IInstantiationService protected readonly _instantiationService: IInstantiationService, @@ -87,13 +89,18 @@ export abstract class BreadcrumbsPicker { ); this._disposables.push(this._tree.onDidChangeSelection(e => { if (e.payload !== this._tree) { - const target = this._getTargetFromSelectionEvent(e); - if (!target) { - return; + const target = this._getTargetFromEvent(e.selection[0], e.payload); + if (target) { + setTimeout(_ => {// need to debounce here because this disposes the tree and the tree doesn't like to be disposed on click + this._onDidPickElement.fire({ target, payload: e.payload }); + }, 0); } - setTimeout(_ => {// need to debounce here because this disposes the tree and the tree doesn't like to be disposed on click - this._onDidPickElement.fire({ target, payload: e.payload }); - }, 0); + } + })); + this._disposables.push(this._tree.onDidChangeFocus(e => { + const target = this._getTargetFromEvent(e.focus, e.payload); + if (target) { + this._onDidFocusElement.fire({ target, payload: e.payload }); } })); @@ -147,7 +154,7 @@ export abstract class BreadcrumbsPicker { protected abstract _getInput(input: BreadcrumbElement): any; protected abstract _getInitialSelection(tree: ITree, input: BreadcrumbElement): any; protected abstract _completeTreeConfiguration(config: IHighlightingTreeConfiguration): IHighlightingTreeConfiguration; - protected abstract _getTargetFromSelectionEvent(e: ISelectionEvent): any | undefined; + protected abstract _getTargetFromEvent(element: any, payload: any): any | undefined; } //#region - Files @@ -376,10 +383,9 @@ export class BreadcrumbsFilePicker extends BreadcrumbsPicker { return config; } - protected _getTargetFromSelectionEvent(e: ISelectionEvent): any | undefined { - let [first] = e.selection; - if (first && !IWorkspaceFolder.isIWorkspaceFolder(first) && !(first as IFileStat).isDirectory) { - return new FileElement((first as IFileStat).resource, FileKind.FILE); + protected _getTargetFromEvent(element: any, _payload: any): any | undefined { + if (element && !IWorkspaceFolder.isIWorkspaceFolder(element) && !(element as IFileStat).isDirectory) { + return new FileElement((element as IFileStat).resource, FileKind.FILE); } } } @@ -415,13 +421,12 @@ export class BreadcrumbsOutlinePicker extends BreadcrumbsPicker { return config; } - protected _getTargetFromSelectionEvent(e: ISelectionEvent): any | undefined { - if (e.payload && e.payload.didClickOnTwistie) { + protected _getTargetFromEvent(element: any, payload: any): any | undefined { + if (payload && payload.didClickOnTwistie) { return; } - let [first] = e.selection; - if (first instanceof OutlineElement) { - return first; + if (element instanceof OutlineElement) { + return element; } } } From c522c96317c0aaa1250429a9d853e8702307a54b Mon Sep 17 00:00:00 2001 From: Daniel McNab <36049421+DJMcNab@users.noreply.github.com> Date: Thu, 23 Aug 2018 09:51:47 +0100 Subject: [PATCH 1146/1276] fix rust region comments --- extensions/rust/language-configuration.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/extensions/rust/language-configuration.json b/extensions/rust/language-configuration.json index d0af7828288..689f90d77ef 100644 --- a/extensions/rust/language-configuration.json +++ b/extensions/rust/language-configuration.json @@ -23,8 +23,8 @@ ], "folding": { "markers": { - "start": "^\\s//region", - "end": "^\\s//endregion" + "start": "^\\s*// region", + "end": "^\\s*// endregion" } } } From bfae34d7499c780f9b0109c99bc9366230858368 Mon Sep 17 00:00:00 2001 From: Matt Bierner <matb@microsoft.com> Date: Thu, 23 Aug 2018 10:54:11 +0200 Subject: [PATCH 1147/1276] Update js/ts grammar --- .../syntaxes/JavaScript.tmLanguage.json | 113 +++++++++++++----- .../syntaxes/JavaScriptReact.tmLanguage.json | 113 +++++++++++++----- .../syntaxes/TypeScript.tmLanguage.json | 113 +++++++++++++----- .../syntaxes/TypeScriptReact.tmLanguage.json | 113 +++++++++++++----- 4 files changed, 332 insertions(+), 120 deletions(-) diff --git a/extensions/javascript/syntaxes/JavaScript.tmLanguage.json b/extensions/javascript/syntaxes/JavaScript.tmLanguage.json index c22cec229fa..58c279763a6 100644 --- a/extensions/javascript/syntaxes/JavaScript.tmLanguage.json +++ b/extensions/javascript/syntaxes/JavaScript.tmLanguage.json @@ -4,7 +4,7 @@ "If you want to provide a fix or improvement, please create a pull request against the original repository.", "Once accepted there, we are happy to receive an update request." ], - "version": "https://github.com/Microsoft/TypeScript-TmLanguage/commit/d33674e802be357bff20cf8b0a4c966be54c39c4", + "version": "https://github.com/Microsoft/TypeScript-TmLanguage/commit/4407e8d57037cdb02e5fb670bcf318e0daebb40f", "name": "JavaScript (with React support)", "scopeName": "source.js", "patterns": [ @@ -96,7 +96,7 @@ }, { "name": "storage.modifier.js", - "match": "(?<![_$[:alnum:]])(?:(?<=\\.\\.\\.)|(?<!\\.))(declare)(?![_$[:alnum:]])(?:(?=\\.\\.\\.)|(?!\\.))" + "match": "(?<![_$[:alnum:]])(?:(?<=\\.\\.\\.)|(?<!\\.))(declare|export)(?![_$[:alnum:]])(?:(?=\\.\\.\\.)|(?!\\.))" } ] }, @@ -288,20 +288,24 @@ "patterns": [ { "name": "meta.var.expr.js", - "begin": "(?<![_$[:alnum:]])(?:(?<=\\.\\.\\.)|(?<!\\.))(?:(\\bexport)\\s+)?(?:(\\bdeclare)\\s+)?\\b(var|let)(?![_$[:alnum:]])(?:(?=\\.\\.\\.)|(?!\\.))", - "beginCaptures": { - "1": { - "name": "keyword.control.export.js" - }, - "2": { - "name": "storage.modifier.js" - }, - "3": { - "name": "storage.type.js" - } - }, - "end": "((?=;|}|(\\s+(of|in)\\s+)|^\\s*$|;|^\\s*abstract\\b|^\\s*async\\b|^\\s*class\\b|^\\s*const\\b|^\\s*declare\\b|^\\s*enum\\b|^\\s*export\\b|^\\s*function\\b|^\\s*import\\b|^\\s*interface\\b|^\\s*let\\b|^\\s*module\\b|^\\s*namespace\\b|^\\s*return\\b|^\\s*type\\b|^\\s*var\\b)|((?<=\\S)(?<!^let|[^\\._$[:alnum:]]let|^var|[^\\._$[:alnum:]]var)(?=\\s*$)))", + "begin": "(?=(?<![_$[:alnum:]])(?:(?<=\\.\\.\\.)|(?<!\\.))(?:(\\bexport)\\s+)?(?:(\\bdeclare)\\s+)?\\b(var|let)(?![_$[:alnum:]])(?:(?=\\.\\.\\.)|(?!\\.)))", + "end": "(?!(?<![_$[:alnum:]])(?:(?<=\\.\\.\\.)|(?<!\\.))(?:(\\bexport)\\s+)?(?:(\\bdeclare)\\s+)?\\b(var|let)(?![_$[:alnum:]])(?:(?=\\.\\.\\.)|(?!\\.)))((?=;|}|(\\s+(of|in)\\s+)|^\\s*$|;|(?:^\\s*(?:abstract|async|class|const|declare|enum|export|function|import|interface|let|module|namespace|return|type|var)\\b))|((?<!^let|[^\\._$[:alnum:]]let|^var|[^\\._$[:alnum:]]var)(?=\\s*$)))", "patterns": [ + { + "begin": "(?<![_$[:alnum:]])(?:(?<=\\.\\.\\.)|(?<!\\.))(?:(\\bexport)\\s+)?(?:(\\bdeclare)\\s+)?\\b(var|let)(?![_$[:alnum:]])(?:(?=\\.\\.\\.)|(?!\\.))\\s*", + "beginCaptures": { + "1": { + "name": "keyword.control.export.js" + }, + "2": { + "name": "storage.modifier.js" + }, + "3": { + "name": "storage.type.js" + } + }, + "end": "(?=\\S)" + }, { "include": "#destructuring-variable" }, @@ -315,7 +319,7 @@ "include": "#comment" }, { - "begin": "(,)\\s*(?!\\S)", + "begin": "(,)\\s*((?!\\S)|(?=\\/\\/))", "beginCaptures": { "1": { "name": "punctuation.separator.comma.js" @@ -323,6 +327,9 @@ }, "end": "(?<!,)(((?==|;|}|(\\s+(of|in)\\s+)|^\\s*$))|((?<=\\S)(?=\\s*$)))", "patterns": [ + { + "include": "#single-line-comment-consuming-line-ending" + }, { "include": "#comment" }, @@ -344,7 +351,7 @@ }, { "name": "meta.var.expr.js", - "begin": "(?<![_$[:alnum:]])(?:(?<=\\.\\.\\.)|(?<!\\.))(?:(\\bexport)\\s+)?(?:(\\bdeclare)\\s+)?\\b(const(?!\\s+enum\\b))(?![_$[:alnum:]])(?:(?=\\.\\.\\.)|(?!\\.))", + "begin": "(?=(?<![_$[:alnum:]])(?:(?<=\\.\\.\\.)|(?<!\\.))(?:(\\bexport)\\s+)?(?:(\\bdeclare)\\s+)?\\b(const(?!\\s+enum\\b))(?![_$[:alnum:]])(?:(?=\\.\\.\\.)|(?!\\.)))", "beginCaptures": { "1": { "name": "keyword.control.export.js" @@ -356,8 +363,23 @@ "name": "storage.type.js" } }, - "end": "((?=;|}|(\\s+(of|in)\\s+)|^\\s*$|;|^\\s*abstract\\b|^\\s*async\\b|^\\s*class\\b|^\\s*const\\b|^\\s*declare\\b|^\\s*enum\\b|^\\s*export\\b|^\\s*function\\b|^\\s*import\\b|^\\s*interface\\b|^\\s*let\\b|^\\s*module\\b|^\\s*namespace\\b|^\\s*return\\b|^\\s*type\\b|^\\s*var\\b)|((?<=\\S)(?<!^const|[^\\._$[:alnum:]]const)(?=\\s*$)))", + "end": "(?!(?<![_$[:alnum:]])(?:(?<=\\.\\.\\.)|(?<!\\.))(?:(\\bexport)\\s+)?(?:(\\bdeclare)\\s+)?\\b(const(?!\\s+enum\\b))(?![_$[:alnum:]])(?:(?=\\.\\.\\.)|(?!\\.)))((?=;|}|(\\s+(of|in)\\s+)|^\\s*$|;|(?:^\\s*(?:abstract|async|class|const|declare|enum|export|function|import|interface|let|module|namespace|return|type|var)\\b))|((?<!^const|[^\\._$[:alnum:]]const)(?=\\s*$)))", "patterns": [ + { + "begin": "(?<![_$[:alnum:]])(?:(?<=\\.\\.\\.)|(?<!\\.))(?:(\\bexport)\\s+)?(?:(\\bdeclare)\\s+)?\\b(const(?!\\s+enum\\b))(?![_$[:alnum:]])(?:(?=\\.\\.\\.)|(?!\\.))\\s*", + "beginCaptures": { + "1": { + "name": "keyword.control.export.js" + }, + "2": { + "name": "storage.modifier.js" + }, + "3": { + "name": "storage.type.js" + } + }, + "end": "(?=\\S)" + }, { "include": "#destructuring-const" }, @@ -371,7 +393,7 @@ "include": "#comment" }, { - "begin": "(,)\\s*(?!\\S)", + "begin": "(,)\\s*((?!\\S)|(?=\\/\\/))", "beginCaptures": { "1": { "name": "punctuation.separator.comma.js" @@ -379,6 +401,9 @@ }, "end": "(?<!,)(((?==|;|}|(\\s+(of|in)\\s+)|^\\s*$))|((?<=\\S)(?=\\s*$)))", "patterns": [ + { + "include": "#single-line-comment-consuming-line-ending" + }, { "include": "#comment" }, @@ -1032,13 +1057,13 @@ }, "field-declaration": { "name": "meta.field.declaration.js", - "begin": "(?x)(?<!\\()(?:(?<![_$[:alnum:]])(?:(?<=\\.\\.\\.)|(?<!\\.))(readonly)\\s+)?(?=\\s*((\\b(?<!\\$)0(x|X)[0-9a-fA-F][0-9a-fA-F_]*\\b(?!\\$))|(\\b(?<!\\$)0(b|B)[01][01_]*\\b(?!\\$))|(\\b(?<!\\$)0(o|O)?[0-7][0-7_]*\\b(?!\\$))|((?<!\\$)(?:\n (?:\\b[0-9][0-9_]*(\\.)[0-9][0-9_]*[eE][+-]?[0-9][0-9_]*\\b)| # 1.1E+3\n (?:\\b[0-9][0-9_]*(\\.)[eE][+-]?[0-9][0-9_]*\\b)| # 1.E+3\n (?:\\B(\\.)[0-9][0-9_]*[eE][+-]?[0-9][0-9_]*\\b)| # .1E+3\n (?:\\b[0-9][0-9_]*[eE][+-]?[0-9][0-9_]*\\b)| # 1E+3\n (?:\\b[0-9][0-9_]*(\\.)[0-9][0-9_]*\\b)| # 1.1\n (?:\\b[0-9][0-9_]*(\\.)\\B)| # 1.\n (?:\\B(\\.)[0-9][0-9_]*\\b)| # .1\n (?:\\b[0-9][0-9_]*\\b(?!\\.)) # 1\n)(?!\\$))|([_$[:alpha:]][_$[:alnum:]]*)|(\\'([^\\'\\\\]|\\\\\\'|\\\\)*\\')|(\\\"([^\\\"\\\\]|\\\\\\\"|\\\\)*\\\")|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])+\\]))\\s*(\\?\\s*)?(=|:|;|$))", + "begin": "(?x)(?<!\\()(?:(?<![_$[:alnum:]])(?:(?<=\\.\\.\\.)|(?<!\\.))(readonly)\\s+)?(?=\\s*((\\b(?<!\\$)0(x|X)[0-9a-fA-F][0-9a-fA-F_]*\\b(?!\\$))|(\\b(?<!\\$)0(b|B)[01][01_]*\\b(?!\\$))|(\\b(?<!\\$)0(o|O)?[0-7][0-7_]*\\b(?!\\$))|((?<!\\$)(?:\n (?:\\b[0-9][0-9_]*(\\.)[0-9][0-9_]*[eE][+-]?[0-9][0-9_]*\\b)| # 1.1E+3\n (?:\\b[0-9][0-9_]*(\\.)[eE][+-]?[0-9][0-9_]*\\b)| # 1.E+3\n (?:\\B(\\.)[0-9][0-9_]*[eE][+-]?[0-9][0-9_]*\\b)| # .1E+3\n (?:\\b[0-9][0-9_]*[eE][+-]?[0-9][0-9_]*\\b)| # 1E+3\n (?:\\b[0-9][0-9_]*(\\.)[0-9][0-9_]*\\b)| # 1.1\n (?:\\b[0-9][0-9_]*(\\.)\\B)| # 1.\n (?:\\B(\\.)[0-9][0-9_]*\\b)| # .1\n (?:\\b[0-9][0-9_]*\\b(?!\\.)) # 1\n)(?!\\$))|([_$[:alpha:]][_$[:alnum:]]*)|(\\'([^\\'\\\\]|\\\\\\'|\\\\)*\\')|(\\\"([^\\\"\\\\]|\\\\\\\"|\\\\)*\\\")|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])+\\]))\\s*(\\?\\s*)?(=|:|;|,|$))", "beginCaptures": { "1": { "name": "storage.modifier.js" } }, - "end": "(?x)(?=\\}|;|,|$|(^(?!\\s*((\\b(?<!\\$)0(x|X)[0-9a-fA-F][0-9a-fA-F_]*\\b(?!\\$))|(\\b(?<!\\$)0(b|B)[01][01_]*\\b(?!\\$))|(\\b(?<!\\$)0(o|O)?[0-7][0-7_]*\\b(?!\\$))|((?<!\\$)(?:\n (?:\\b[0-9][0-9_]*(\\.)[0-9][0-9_]*[eE][+-]?[0-9][0-9_]*\\b)| # 1.1E+3\n (?:\\b[0-9][0-9_]*(\\.)[eE][+-]?[0-9][0-9_]*\\b)| # 1.E+3\n (?:\\B(\\.)[0-9][0-9_]*[eE][+-]?[0-9][0-9_]*\\b)| # .1E+3\n (?:\\b[0-9][0-9_]*[eE][+-]?[0-9][0-9_]*\\b)| # 1E+3\n (?:\\b[0-9][0-9_]*(\\.)[0-9][0-9_]*\\b)| # 1.1\n (?:\\b[0-9][0-9_]*(\\.)\\B)| # 1.\n (?:\\B(\\.)[0-9][0-9_]*\\b)| # .1\n (?:\\b[0-9][0-9_]*\\b(?!\\.)) # 1\n)(?!\\$))|([_$[:alpha:]][_$[:alnum:]]*)|(\\'([^\\'\\\\]|\\\\\\'|\\\\)*\\')|(\\\"([^\\\"\\\\]|\\\\\\\"|\\\\)*\\\")|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])+\\]))\\s*(\\?\\s*)?(=|:|;|$))))|(?<=\\})", + "end": "(?x)(?=\\}|;|,|$|(^(?!\\s*((\\b(?<!\\$)0(x|X)[0-9a-fA-F][0-9a-fA-F_]*\\b(?!\\$))|(\\b(?<!\\$)0(b|B)[01][01_]*\\b(?!\\$))|(\\b(?<!\\$)0(o|O)?[0-7][0-7_]*\\b(?!\\$))|((?<!\\$)(?:\n (?:\\b[0-9][0-9_]*(\\.)[0-9][0-9_]*[eE][+-]?[0-9][0-9_]*\\b)| # 1.1E+3\n (?:\\b[0-9][0-9_]*(\\.)[eE][+-]?[0-9][0-9_]*\\b)| # 1.E+3\n (?:\\B(\\.)[0-9][0-9_]*[eE][+-]?[0-9][0-9_]*\\b)| # .1E+3\n (?:\\b[0-9][0-9_]*[eE][+-]?[0-9][0-9_]*\\b)| # 1E+3\n (?:\\b[0-9][0-9_]*(\\.)[0-9][0-9_]*\\b)| # 1.1\n (?:\\b[0-9][0-9_]*(\\.)\\B)| # 1.\n (?:\\B(\\.)[0-9][0-9_]*\\b)| # .1\n (?:\\b[0-9][0-9_]*\\b(?!\\.)) # 1\n)(?!\\$))|([_$[:alpha:]][_$[:alnum:]]*)|(\\'([^\\'\\\\]|\\\\\\'|\\\\)*\\')|(\\\"([^\\\"\\\\]|\\\\\\\"|\\\\)*\\\")|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])+\\]))\\s*(\\?\\s*)?(=|:|;|,|$))))|(?<=\\})", "patterns": [ { "include": "#variable-initializer" @@ -1166,6 +1191,9 @@ { "include": "#function-name" }, + { + "include": "#single-line-comment-consuming-line-ending" + }, { "include": "#function-body" } @@ -1853,7 +1881,7 @@ "name": "storage.type.namespace.js" } }, - "end": "(?<=\\})|(?=;|^\\s*abstract\\b|^\\s*async\\b|^\\s*class\\b|^\\s*const\\b|^\\s*declare\\b|^\\s*enum\\b|^\\s*export\\b|^\\s*function\\b|^\\s*import\\b|^\\s*interface\\b|^\\s*let\\b|^\\s*module\\b|^\\s*namespace\\b|^\\s*return\\b|^\\s*type\\b|^\\s*var\\b)", + "end": "(?<=\\})|(?=;|(?:^\\s*(?:abstract|async|class|const|declare|enum|export|function|import|interface|let|module|namespace|return|type|var)\\b))", "patterns": [ { "include": "#comment" @@ -1890,7 +1918,7 @@ "name": "entity.name.type.alias.js" } }, - "end": "(?=\\}|;|^\\s*abstract\\b|^\\s*async\\b|^\\s*class\\b|^\\s*const\\b|^\\s*declare\\b|^\\s*enum\\b|^\\s*export\\b|^\\s*function\\b|^\\s*import\\b|^\\s*interface\\b|^\\s*let\\b|^\\s*module\\b|^\\s*namespace\\b|^\\s*return\\b|^\\s*type\\b|^\\s*var\\b)", + "end": "(?=\\}|;|(?:^\\s*(?:abstract|async|class|const|declare|enum|export|function|import|interface|let|module|namespace|return|type|var)\\b))", "patterns": [ { "include": "#comment" @@ -1905,7 +1933,7 @@ "name": "keyword.operator.assignment.js" } }, - "end": "(?=\\}|;|^\\s*abstract\\b|^\\s*async\\b|^\\s*class\\b|^\\s*const\\b|^\\s*declare\\b|^\\s*enum\\b|^\\s*export\\b|^\\s*function\\b|^\\s*import\\b|^\\s*interface\\b|^\\s*let\\b|^\\s*module\\b|^\\s*namespace\\b|^\\s*return\\b|^\\s*type\\b|^\\s*var\\b)", + "end": "(?=\\}|;|(?:^\\s*(?:abstract|async|class|const|declare|enum|export|function|import|interface|let|module|namespace|return|type|var)\\b))", "patterns": [ { "include": "#type" @@ -2078,8 +2106,11 @@ "name": "keyword.control.default.js" } }, - "end": "(?=$|;|^\\s*abstract\\b|^\\s*async\\b|^\\s*class\\b|^\\s*const\\b|^\\s*declare\\b|^\\s*enum\\b|^\\s*export\\b|^\\s*function\\b|^\\s*import\\b|^\\s*interface\\b|^\\s*let\\b|^\\s*module\\b|^\\s*namespace\\b|^\\s*return\\b|^\\s*type\\b|^\\s*var\\b)", + "end": "(?=$|;|(?:^\\s*(?:abstract|async|class|const|declare|enum|export|function|import|interface|let|module|namespace|return|type|var)\\b))", "patterns": [ + { + "include": "#interface-declaration" + }, { "include": "#expression" } @@ -2087,13 +2118,13 @@ }, { "name": "meta.export.js", - "begin": "(?<![_$[:alnum:]])(?:(?<=\\.\\.\\.)|(?<!\\.))(export)(?!\\s*:)(?![_$[:alnum:]])(?:(?=\\.\\.\\.)|(?!\\.))", + "begin": "(?<![_$[:alnum:]])(?:(?<=\\.\\.\\.)|(?<!\\.))(export)(?!\\s*:)((?=\\s*[\\{*])|((?=\\s*[_$[:alpha:]][_$[:alnum:]]*(\\s|,))(?!\\s*(?:abstract|async|class|const|declare|enum|export|function|import|interface|let|module|namespace|return|type|var)\\b)))", "beginCaptures": { "0": { "name": "keyword.control.export.js" } }, - "end": "(?=$|;|^\\s*abstract\\b|^\\s*async\\b|^\\s*class\\b|^\\s*const\\b|^\\s*declare\\b|^\\s*enum\\b|^\\s*export\\b|^\\s*function\\b|^\\s*import\\b|^\\s*interface\\b|^\\s*let\\b|^\\s*module\\b|^\\s*namespace\\b|^\\s*return\\b|^\\s*type\\b|^\\s*var\\b)", + "end": "(?=$|;|(?:^\\s*(?:abstract|async|class|const|declare|enum|export|function|import|interface|let|module|namespace|return|type|var)\\b))", "patterns": [ { "include": "#import-export-declaration" @@ -2839,7 +2870,7 @@ "name": "keyword.control.as.js" } }, - "end": "(?=$|^|[;,:})\\]]|((?<![_$[:alnum:]])(?:(?<=\\.\\.\\.)|(?<!\\.))(as)\\s+))", + "end": "(?=$|^|[;,:})\\]]|((?<![_$[:alnum:]])(?:(?<=\\.\\.\\.)|(?<!\\.))(as)\\s+)|(\\s+\\<))", "patterns": [ { "include": "#type" @@ -4381,11 +4412,33 @@ "name": "punctuation.decorator.internaldeclaration.js" } }, - "end": "(?=^)", + "end": "(?=$)", "contentName": "comment.line.double-slash.js" } ] }, + "single-line-comment-consuming-line-ending": { + "begin": "(^[ \\t]+)?((//)(?:\\s*((@)internal)(?=\\s|$))?)", + "beginCaptures": { + "1": { + "name": "punctuation.whitespace.comment.leading.js" + }, + "2": { + "name": "comment.line.double-slash.js" + }, + "3": { + "name": "punctuation.definition.comment.js" + }, + "4": { + "name": "storage.type.internaldeclaration.js" + }, + "5": { + "name": "punctuation.decorator.internaldeclaration.js" + } + }, + "end": "(?=^)", + "contentName": "comment.line.double-slash.js" + }, "directives": { "name": "comment.line.triple-slash.directive.js", "begin": "^(///)\\s*(?=<(reference|amd-dependency|amd-module)(\\s+(path|types|no-default-lib|lib|name)\\s*=\\s*((\\'([^\\'\\\\]|\\\\\\'|\\\\)*\\')|(\\\"([^\\\"\\\\]|\\\\\\\"|\\\\)*\\\")))+\\s*/>\\s*$)", @@ -4394,7 +4447,7 @@ "name": "punctuation.definition.comment.js" } }, - "end": "(?=^)", + "end": "(?=$)", "patterns": [ { "name": "meta.tag.js", diff --git a/extensions/javascript/syntaxes/JavaScriptReact.tmLanguage.json b/extensions/javascript/syntaxes/JavaScriptReact.tmLanguage.json index 5da9fb79ada..230fbaa7a0a 100644 --- a/extensions/javascript/syntaxes/JavaScriptReact.tmLanguage.json +++ b/extensions/javascript/syntaxes/JavaScriptReact.tmLanguage.json @@ -4,7 +4,7 @@ "If you want to provide a fix or improvement, please create a pull request against the original repository.", "Once accepted there, we are happy to receive an update request." ], - "version": "https://github.com/Microsoft/TypeScript-TmLanguage/commit/d33674e802be357bff20cf8b0a4c966be54c39c4", + "version": "https://github.com/Microsoft/TypeScript-TmLanguage/commit/4407e8d57037cdb02e5fb670bcf318e0daebb40f", "name": "JavaScript (with React support)", "scopeName": "source.js.jsx", "patterns": [ @@ -96,7 +96,7 @@ }, { "name": "storage.modifier.js.jsx", - "match": "(?<![_$[:alnum:]])(?:(?<=\\.\\.\\.)|(?<!\\.))(declare)(?![_$[:alnum:]])(?:(?=\\.\\.\\.)|(?!\\.))" + "match": "(?<![_$[:alnum:]])(?:(?<=\\.\\.\\.)|(?<!\\.))(declare|export)(?![_$[:alnum:]])(?:(?=\\.\\.\\.)|(?!\\.))" } ] }, @@ -288,20 +288,24 @@ "patterns": [ { "name": "meta.var.expr.js.jsx", - "begin": "(?<![_$[:alnum:]])(?:(?<=\\.\\.\\.)|(?<!\\.))(?:(\\bexport)\\s+)?(?:(\\bdeclare)\\s+)?\\b(var|let)(?![_$[:alnum:]])(?:(?=\\.\\.\\.)|(?!\\.))", - "beginCaptures": { - "1": { - "name": "keyword.control.export.js.jsx" - }, - "2": { - "name": "storage.modifier.js.jsx" - }, - "3": { - "name": "storage.type.js.jsx" - } - }, - "end": "((?=;|}|(\\s+(of|in)\\s+)|^\\s*$|;|^\\s*abstract\\b|^\\s*async\\b|^\\s*class\\b|^\\s*const\\b|^\\s*declare\\b|^\\s*enum\\b|^\\s*export\\b|^\\s*function\\b|^\\s*import\\b|^\\s*interface\\b|^\\s*let\\b|^\\s*module\\b|^\\s*namespace\\b|^\\s*return\\b|^\\s*type\\b|^\\s*var\\b)|((?<=\\S)(?<!^let|[^\\._$[:alnum:]]let|^var|[^\\._$[:alnum:]]var)(?=\\s*$)))", + "begin": "(?=(?<![_$[:alnum:]])(?:(?<=\\.\\.\\.)|(?<!\\.))(?:(\\bexport)\\s+)?(?:(\\bdeclare)\\s+)?\\b(var|let)(?![_$[:alnum:]])(?:(?=\\.\\.\\.)|(?!\\.)))", + "end": "(?!(?<![_$[:alnum:]])(?:(?<=\\.\\.\\.)|(?<!\\.))(?:(\\bexport)\\s+)?(?:(\\bdeclare)\\s+)?\\b(var|let)(?![_$[:alnum:]])(?:(?=\\.\\.\\.)|(?!\\.)))((?=;|}|(\\s+(of|in)\\s+)|^\\s*$|;|(?:^\\s*(?:abstract|async|class|const|declare|enum|export|function|import|interface|let|module|namespace|return|type|var)\\b))|((?<!^let|[^\\._$[:alnum:]]let|^var|[^\\._$[:alnum:]]var)(?=\\s*$)))", "patterns": [ + { + "begin": "(?<![_$[:alnum:]])(?:(?<=\\.\\.\\.)|(?<!\\.))(?:(\\bexport)\\s+)?(?:(\\bdeclare)\\s+)?\\b(var|let)(?![_$[:alnum:]])(?:(?=\\.\\.\\.)|(?!\\.))\\s*", + "beginCaptures": { + "1": { + "name": "keyword.control.export.js.jsx" + }, + "2": { + "name": "storage.modifier.js.jsx" + }, + "3": { + "name": "storage.type.js.jsx" + } + }, + "end": "(?=\\S)" + }, { "include": "#destructuring-variable" }, @@ -315,7 +319,7 @@ "include": "#comment" }, { - "begin": "(,)\\s*(?!\\S)", + "begin": "(,)\\s*((?!\\S)|(?=\\/\\/))", "beginCaptures": { "1": { "name": "punctuation.separator.comma.js.jsx" @@ -323,6 +327,9 @@ }, "end": "(?<!,)(((?==|;|}|(\\s+(of|in)\\s+)|^\\s*$))|((?<=\\S)(?=\\s*$)))", "patterns": [ + { + "include": "#single-line-comment-consuming-line-ending" + }, { "include": "#comment" }, @@ -344,7 +351,7 @@ }, { "name": "meta.var.expr.js.jsx", - "begin": "(?<![_$[:alnum:]])(?:(?<=\\.\\.\\.)|(?<!\\.))(?:(\\bexport)\\s+)?(?:(\\bdeclare)\\s+)?\\b(const(?!\\s+enum\\b))(?![_$[:alnum:]])(?:(?=\\.\\.\\.)|(?!\\.))", + "begin": "(?=(?<![_$[:alnum:]])(?:(?<=\\.\\.\\.)|(?<!\\.))(?:(\\bexport)\\s+)?(?:(\\bdeclare)\\s+)?\\b(const(?!\\s+enum\\b))(?![_$[:alnum:]])(?:(?=\\.\\.\\.)|(?!\\.)))", "beginCaptures": { "1": { "name": "keyword.control.export.js.jsx" @@ -356,8 +363,23 @@ "name": "storage.type.js.jsx" } }, - "end": "((?=;|}|(\\s+(of|in)\\s+)|^\\s*$|;|^\\s*abstract\\b|^\\s*async\\b|^\\s*class\\b|^\\s*const\\b|^\\s*declare\\b|^\\s*enum\\b|^\\s*export\\b|^\\s*function\\b|^\\s*import\\b|^\\s*interface\\b|^\\s*let\\b|^\\s*module\\b|^\\s*namespace\\b|^\\s*return\\b|^\\s*type\\b|^\\s*var\\b)|((?<=\\S)(?<!^const|[^\\._$[:alnum:]]const)(?=\\s*$)))", + "end": "(?!(?<![_$[:alnum:]])(?:(?<=\\.\\.\\.)|(?<!\\.))(?:(\\bexport)\\s+)?(?:(\\bdeclare)\\s+)?\\b(const(?!\\s+enum\\b))(?![_$[:alnum:]])(?:(?=\\.\\.\\.)|(?!\\.)))((?=;|}|(\\s+(of|in)\\s+)|^\\s*$|;|(?:^\\s*(?:abstract|async|class|const|declare|enum|export|function|import|interface|let|module|namespace|return|type|var)\\b))|((?<!^const|[^\\._$[:alnum:]]const)(?=\\s*$)))", "patterns": [ + { + "begin": "(?<![_$[:alnum:]])(?:(?<=\\.\\.\\.)|(?<!\\.))(?:(\\bexport)\\s+)?(?:(\\bdeclare)\\s+)?\\b(const(?!\\s+enum\\b))(?![_$[:alnum:]])(?:(?=\\.\\.\\.)|(?!\\.))\\s*", + "beginCaptures": { + "1": { + "name": "keyword.control.export.js.jsx" + }, + "2": { + "name": "storage.modifier.js.jsx" + }, + "3": { + "name": "storage.type.js.jsx" + } + }, + "end": "(?=\\S)" + }, { "include": "#destructuring-const" }, @@ -371,7 +393,7 @@ "include": "#comment" }, { - "begin": "(,)\\s*(?!\\S)", + "begin": "(,)\\s*((?!\\S)|(?=\\/\\/))", "beginCaptures": { "1": { "name": "punctuation.separator.comma.js.jsx" @@ -379,6 +401,9 @@ }, "end": "(?<!,)(((?==|;|}|(\\s+(of|in)\\s+)|^\\s*$))|((?<=\\S)(?=\\s*$)))", "patterns": [ + { + "include": "#single-line-comment-consuming-line-ending" + }, { "include": "#comment" }, @@ -1032,13 +1057,13 @@ }, "field-declaration": { "name": "meta.field.declaration.js.jsx", - "begin": "(?x)(?<!\\()(?:(?<![_$[:alnum:]])(?:(?<=\\.\\.\\.)|(?<!\\.))(readonly)\\s+)?(?=\\s*((\\b(?<!\\$)0(x|X)[0-9a-fA-F][0-9a-fA-F_]*\\b(?!\\$))|(\\b(?<!\\$)0(b|B)[01][01_]*\\b(?!\\$))|(\\b(?<!\\$)0(o|O)?[0-7][0-7_]*\\b(?!\\$))|((?<!\\$)(?:\n (?:\\b[0-9][0-9_]*(\\.)[0-9][0-9_]*[eE][+-]?[0-9][0-9_]*\\b)| # 1.1E+3\n (?:\\b[0-9][0-9_]*(\\.)[eE][+-]?[0-9][0-9_]*\\b)| # 1.E+3\n (?:\\B(\\.)[0-9][0-9_]*[eE][+-]?[0-9][0-9_]*\\b)| # .1E+3\n (?:\\b[0-9][0-9_]*[eE][+-]?[0-9][0-9_]*\\b)| # 1E+3\n (?:\\b[0-9][0-9_]*(\\.)[0-9][0-9_]*\\b)| # 1.1\n (?:\\b[0-9][0-9_]*(\\.)\\B)| # 1.\n (?:\\B(\\.)[0-9][0-9_]*\\b)| # .1\n (?:\\b[0-9][0-9_]*\\b(?!\\.)) # 1\n)(?!\\$))|([_$[:alpha:]][_$[:alnum:]]*)|(\\'([^\\'\\\\]|\\\\\\'|\\\\)*\\')|(\\\"([^\\\"\\\\]|\\\\\\\"|\\\\)*\\\")|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])+\\]))\\s*(\\?\\s*)?(=|:|;|$))", + "begin": "(?x)(?<!\\()(?:(?<![_$[:alnum:]])(?:(?<=\\.\\.\\.)|(?<!\\.))(readonly)\\s+)?(?=\\s*((\\b(?<!\\$)0(x|X)[0-9a-fA-F][0-9a-fA-F_]*\\b(?!\\$))|(\\b(?<!\\$)0(b|B)[01][01_]*\\b(?!\\$))|(\\b(?<!\\$)0(o|O)?[0-7][0-7_]*\\b(?!\\$))|((?<!\\$)(?:\n (?:\\b[0-9][0-9_]*(\\.)[0-9][0-9_]*[eE][+-]?[0-9][0-9_]*\\b)| # 1.1E+3\n (?:\\b[0-9][0-9_]*(\\.)[eE][+-]?[0-9][0-9_]*\\b)| # 1.E+3\n (?:\\B(\\.)[0-9][0-9_]*[eE][+-]?[0-9][0-9_]*\\b)| # .1E+3\n (?:\\b[0-9][0-9_]*[eE][+-]?[0-9][0-9_]*\\b)| # 1E+3\n (?:\\b[0-9][0-9_]*(\\.)[0-9][0-9_]*\\b)| # 1.1\n (?:\\b[0-9][0-9_]*(\\.)\\B)| # 1.\n (?:\\B(\\.)[0-9][0-9_]*\\b)| # .1\n (?:\\b[0-9][0-9_]*\\b(?!\\.)) # 1\n)(?!\\$))|([_$[:alpha:]][_$[:alnum:]]*)|(\\'([^\\'\\\\]|\\\\\\'|\\\\)*\\')|(\\\"([^\\\"\\\\]|\\\\\\\"|\\\\)*\\\")|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])+\\]))\\s*(\\?\\s*)?(=|:|;|,|$))", "beginCaptures": { "1": { "name": "storage.modifier.js.jsx" } }, - "end": "(?x)(?=\\}|;|,|$|(^(?!\\s*((\\b(?<!\\$)0(x|X)[0-9a-fA-F][0-9a-fA-F_]*\\b(?!\\$))|(\\b(?<!\\$)0(b|B)[01][01_]*\\b(?!\\$))|(\\b(?<!\\$)0(o|O)?[0-7][0-7_]*\\b(?!\\$))|((?<!\\$)(?:\n (?:\\b[0-9][0-9_]*(\\.)[0-9][0-9_]*[eE][+-]?[0-9][0-9_]*\\b)| # 1.1E+3\n (?:\\b[0-9][0-9_]*(\\.)[eE][+-]?[0-9][0-9_]*\\b)| # 1.E+3\n (?:\\B(\\.)[0-9][0-9_]*[eE][+-]?[0-9][0-9_]*\\b)| # .1E+3\n (?:\\b[0-9][0-9_]*[eE][+-]?[0-9][0-9_]*\\b)| # 1E+3\n (?:\\b[0-9][0-9_]*(\\.)[0-9][0-9_]*\\b)| # 1.1\n (?:\\b[0-9][0-9_]*(\\.)\\B)| # 1.\n (?:\\B(\\.)[0-9][0-9_]*\\b)| # .1\n (?:\\b[0-9][0-9_]*\\b(?!\\.)) # 1\n)(?!\\$))|([_$[:alpha:]][_$[:alnum:]]*)|(\\'([^\\'\\\\]|\\\\\\'|\\\\)*\\')|(\\\"([^\\\"\\\\]|\\\\\\\"|\\\\)*\\\")|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])+\\]))\\s*(\\?\\s*)?(=|:|;|$))))|(?<=\\})", + "end": "(?x)(?=\\}|;|,|$|(^(?!\\s*((\\b(?<!\\$)0(x|X)[0-9a-fA-F][0-9a-fA-F_]*\\b(?!\\$))|(\\b(?<!\\$)0(b|B)[01][01_]*\\b(?!\\$))|(\\b(?<!\\$)0(o|O)?[0-7][0-7_]*\\b(?!\\$))|((?<!\\$)(?:\n (?:\\b[0-9][0-9_]*(\\.)[0-9][0-9_]*[eE][+-]?[0-9][0-9_]*\\b)| # 1.1E+3\n (?:\\b[0-9][0-9_]*(\\.)[eE][+-]?[0-9][0-9_]*\\b)| # 1.E+3\n (?:\\B(\\.)[0-9][0-9_]*[eE][+-]?[0-9][0-9_]*\\b)| # .1E+3\n (?:\\b[0-9][0-9_]*[eE][+-]?[0-9][0-9_]*\\b)| # 1E+3\n (?:\\b[0-9][0-9_]*(\\.)[0-9][0-9_]*\\b)| # 1.1\n (?:\\b[0-9][0-9_]*(\\.)\\B)| # 1.\n (?:\\B(\\.)[0-9][0-9_]*\\b)| # .1\n (?:\\b[0-9][0-9_]*\\b(?!\\.)) # 1\n)(?!\\$))|([_$[:alpha:]][_$[:alnum:]]*)|(\\'([^\\'\\\\]|\\\\\\'|\\\\)*\\')|(\\\"([^\\\"\\\\]|\\\\\\\"|\\\\)*\\\")|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])+\\]))\\s*(\\?\\s*)?(=|:|;|,|$))))|(?<=\\})", "patterns": [ { "include": "#variable-initializer" @@ -1166,6 +1191,9 @@ { "include": "#function-name" }, + { + "include": "#single-line-comment-consuming-line-ending" + }, { "include": "#function-body" } @@ -1853,7 +1881,7 @@ "name": "storage.type.namespace.js.jsx" } }, - "end": "(?<=\\})|(?=;|^\\s*abstract\\b|^\\s*async\\b|^\\s*class\\b|^\\s*const\\b|^\\s*declare\\b|^\\s*enum\\b|^\\s*export\\b|^\\s*function\\b|^\\s*import\\b|^\\s*interface\\b|^\\s*let\\b|^\\s*module\\b|^\\s*namespace\\b|^\\s*return\\b|^\\s*type\\b|^\\s*var\\b)", + "end": "(?<=\\})|(?=;|(?:^\\s*(?:abstract|async|class|const|declare|enum|export|function|import|interface|let|module|namespace|return|type|var)\\b))", "patterns": [ { "include": "#comment" @@ -1890,7 +1918,7 @@ "name": "entity.name.type.alias.js.jsx" } }, - "end": "(?=\\}|;|^\\s*abstract\\b|^\\s*async\\b|^\\s*class\\b|^\\s*const\\b|^\\s*declare\\b|^\\s*enum\\b|^\\s*export\\b|^\\s*function\\b|^\\s*import\\b|^\\s*interface\\b|^\\s*let\\b|^\\s*module\\b|^\\s*namespace\\b|^\\s*return\\b|^\\s*type\\b|^\\s*var\\b)", + "end": "(?=\\}|;|(?:^\\s*(?:abstract|async|class|const|declare|enum|export|function|import|interface|let|module|namespace|return|type|var)\\b))", "patterns": [ { "include": "#comment" @@ -1905,7 +1933,7 @@ "name": "keyword.operator.assignment.js.jsx" } }, - "end": "(?=\\}|;|^\\s*abstract\\b|^\\s*async\\b|^\\s*class\\b|^\\s*const\\b|^\\s*declare\\b|^\\s*enum\\b|^\\s*export\\b|^\\s*function\\b|^\\s*import\\b|^\\s*interface\\b|^\\s*let\\b|^\\s*module\\b|^\\s*namespace\\b|^\\s*return\\b|^\\s*type\\b|^\\s*var\\b)", + "end": "(?=\\}|;|(?:^\\s*(?:abstract|async|class|const|declare|enum|export|function|import|interface|let|module|namespace|return|type|var)\\b))", "patterns": [ { "include": "#type" @@ -2078,8 +2106,11 @@ "name": "keyword.control.default.js.jsx" } }, - "end": "(?=$|;|^\\s*abstract\\b|^\\s*async\\b|^\\s*class\\b|^\\s*const\\b|^\\s*declare\\b|^\\s*enum\\b|^\\s*export\\b|^\\s*function\\b|^\\s*import\\b|^\\s*interface\\b|^\\s*let\\b|^\\s*module\\b|^\\s*namespace\\b|^\\s*return\\b|^\\s*type\\b|^\\s*var\\b)", + "end": "(?=$|;|(?:^\\s*(?:abstract|async|class|const|declare|enum|export|function|import|interface|let|module|namespace|return|type|var)\\b))", "patterns": [ + { + "include": "#interface-declaration" + }, { "include": "#expression" } @@ -2087,13 +2118,13 @@ }, { "name": "meta.export.js.jsx", - "begin": "(?<![_$[:alnum:]])(?:(?<=\\.\\.\\.)|(?<!\\.))(export)(?!\\s*:)(?![_$[:alnum:]])(?:(?=\\.\\.\\.)|(?!\\.))", + "begin": "(?<![_$[:alnum:]])(?:(?<=\\.\\.\\.)|(?<!\\.))(export)(?!\\s*:)((?=\\s*[\\{*])|((?=\\s*[_$[:alpha:]][_$[:alnum:]]*(\\s|,))(?!\\s*(?:abstract|async|class|const|declare|enum|export|function|import|interface|let|module|namespace|return|type|var)\\b)))", "beginCaptures": { "0": { "name": "keyword.control.export.js.jsx" } }, - "end": "(?=$|;|^\\s*abstract\\b|^\\s*async\\b|^\\s*class\\b|^\\s*const\\b|^\\s*declare\\b|^\\s*enum\\b|^\\s*export\\b|^\\s*function\\b|^\\s*import\\b|^\\s*interface\\b|^\\s*let\\b|^\\s*module\\b|^\\s*namespace\\b|^\\s*return\\b|^\\s*type\\b|^\\s*var\\b)", + "end": "(?=$|;|(?:^\\s*(?:abstract|async|class|const|declare|enum|export|function|import|interface|let|module|namespace|return|type|var)\\b))", "patterns": [ { "include": "#import-export-declaration" @@ -2839,7 +2870,7 @@ "name": "keyword.control.as.js.jsx" } }, - "end": "(?=$|^|[;,:})\\]]|((?<![_$[:alnum:]])(?:(?<=\\.\\.\\.)|(?<!\\.))(as)\\s+))", + "end": "(?=$|^|[;,:})\\]]|((?<![_$[:alnum:]])(?:(?<=\\.\\.\\.)|(?<!\\.))(as)\\s+)|(\\s+\\<))", "patterns": [ { "include": "#type" @@ -4381,11 +4412,33 @@ "name": "punctuation.decorator.internaldeclaration.js.jsx" } }, - "end": "(?=^)", + "end": "(?=$)", "contentName": "comment.line.double-slash.js.jsx" } ] }, + "single-line-comment-consuming-line-ending": { + "begin": "(^[ \\t]+)?((//)(?:\\s*((@)internal)(?=\\s|$))?)", + "beginCaptures": { + "1": { + "name": "punctuation.whitespace.comment.leading.js.jsx" + }, + "2": { + "name": "comment.line.double-slash.js.jsx" + }, + "3": { + "name": "punctuation.definition.comment.js.jsx" + }, + "4": { + "name": "storage.type.internaldeclaration.js.jsx" + }, + "5": { + "name": "punctuation.decorator.internaldeclaration.js.jsx" + } + }, + "end": "(?=^)", + "contentName": "comment.line.double-slash.js.jsx" + }, "directives": { "name": "comment.line.triple-slash.directive.js.jsx", "begin": "^(///)\\s*(?=<(reference|amd-dependency|amd-module)(\\s+(path|types|no-default-lib|lib|name)\\s*=\\s*((\\'([^\\'\\\\]|\\\\\\'|\\\\)*\\')|(\\\"([^\\\"\\\\]|\\\\\\\"|\\\\)*\\\")))+\\s*/>\\s*$)", @@ -4394,7 +4447,7 @@ "name": "punctuation.definition.comment.js.jsx" } }, - "end": "(?=^)", + "end": "(?=$)", "patterns": [ { "name": "meta.tag.js.jsx", diff --git a/extensions/typescript-basics/syntaxes/TypeScript.tmLanguage.json b/extensions/typescript-basics/syntaxes/TypeScript.tmLanguage.json index 9b62ccbf2a7..7abcc55889e 100644 --- a/extensions/typescript-basics/syntaxes/TypeScript.tmLanguage.json +++ b/extensions/typescript-basics/syntaxes/TypeScript.tmLanguage.json @@ -4,7 +4,7 @@ "If you want to provide a fix or improvement, please create a pull request against the original repository.", "Once accepted there, we are happy to receive an update request." ], - "version": "https://github.com/Microsoft/TypeScript-TmLanguage/commit/d33674e802be357bff20cf8b0a4c966be54c39c4", + "version": "https://github.com/Microsoft/TypeScript-TmLanguage/commit/e2db601b62527357f772b48fb4a17965b11f844c", "name": "TypeScript", "scopeName": "source.ts", "patterns": [ @@ -96,7 +96,7 @@ }, { "name": "storage.modifier.ts", - "match": "(?<![_$[:alnum:]])(?:(?<=\\.\\.\\.)|(?<!\\.))(declare)(?![_$[:alnum:]])(?:(?=\\.\\.\\.)|(?!\\.))" + "match": "(?<![_$[:alnum:]])(?:(?<=\\.\\.\\.)|(?<!\\.))(declare|export)(?![_$[:alnum:]])(?:(?=\\.\\.\\.)|(?!\\.))" } ] }, @@ -285,20 +285,24 @@ "patterns": [ { "name": "meta.var.expr.ts", - "begin": "(?<![_$[:alnum:]])(?:(?<=\\.\\.\\.)|(?<!\\.))(?:(\\bexport)\\s+)?(?:(\\bdeclare)\\s+)?\\b(var|let)(?![_$[:alnum:]])(?:(?=\\.\\.\\.)|(?!\\.))", - "beginCaptures": { - "1": { - "name": "keyword.control.export.ts" - }, - "2": { - "name": "storage.modifier.ts" - }, - "3": { - "name": "storage.type.ts" - } - }, - "end": "((?=;|}|(\\s+(of|in)\\s+)|^\\s*$|;|^\\s*abstract\\b|^\\s*async\\b|^\\s*class\\b|^\\s*const\\b|^\\s*declare\\b|^\\s*enum\\b|^\\s*export\\b|^\\s*function\\b|^\\s*import\\b|^\\s*interface\\b|^\\s*let\\b|^\\s*module\\b|^\\s*namespace\\b|^\\s*return\\b|^\\s*type\\b|^\\s*var\\b)|((?<=\\S)(?<!^let|[^\\._$[:alnum:]]let|^var|[^\\._$[:alnum:]]var)(?=\\s*$)))", + "begin": "(?=(?<![_$[:alnum:]])(?:(?<=\\.\\.\\.)|(?<!\\.))(?:(\\bexport)\\s+)?(?:(\\bdeclare)\\s+)?\\b(var|let)(?![_$[:alnum:]])(?:(?=\\.\\.\\.)|(?!\\.)))", + "end": "(?!(?<![_$[:alnum:]])(?:(?<=\\.\\.\\.)|(?<!\\.))(?:(\\bexport)\\s+)?(?:(\\bdeclare)\\s+)?\\b(var|let)(?![_$[:alnum:]])(?:(?=\\.\\.\\.)|(?!\\.)))((?=;|}|(\\s+(of|in)\\s+)|^\\s*$|;|(?:^\\s*(?:abstract|async|class|const|declare|enum|export|function|import|interface|let|module|namespace|return|type|var)\\b))|((?<!^let|[^\\._$[:alnum:]]let|^var|[^\\._$[:alnum:]]var)(?=\\s*$)))", "patterns": [ + { + "begin": "(?<![_$[:alnum:]])(?:(?<=\\.\\.\\.)|(?<!\\.))(?:(\\bexport)\\s+)?(?:(\\bdeclare)\\s+)?\\b(var|let)(?![_$[:alnum:]])(?:(?=\\.\\.\\.)|(?!\\.))\\s*", + "beginCaptures": { + "1": { + "name": "keyword.control.export.ts" + }, + "2": { + "name": "storage.modifier.ts" + }, + "3": { + "name": "storage.type.ts" + } + }, + "end": "(?=\\S)" + }, { "include": "#destructuring-variable" }, @@ -312,7 +316,7 @@ "include": "#comment" }, { - "begin": "(,)\\s*(?!\\S)", + "begin": "(,)\\s*((?!\\S)|(?=\\/\\/))", "beginCaptures": { "1": { "name": "punctuation.separator.comma.ts" @@ -320,6 +324,9 @@ }, "end": "(?<!,)(((?==|;|}|(\\s+(of|in)\\s+)|^\\s*$))|((?<=\\S)(?=\\s*$)))", "patterns": [ + { + "include": "#single-line-comment-consuming-line-ending" + }, { "include": "#comment" }, @@ -341,7 +348,7 @@ }, { "name": "meta.var.expr.ts", - "begin": "(?<![_$[:alnum:]])(?:(?<=\\.\\.\\.)|(?<!\\.))(?:(\\bexport)\\s+)?(?:(\\bdeclare)\\s+)?\\b(const(?!\\s+enum\\b))(?![_$[:alnum:]])(?:(?=\\.\\.\\.)|(?!\\.))", + "begin": "(?=(?<![_$[:alnum:]])(?:(?<=\\.\\.\\.)|(?<!\\.))(?:(\\bexport)\\s+)?(?:(\\bdeclare)\\s+)?\\b(const(?!\\s+enum\\b))(?![_$[:alnum:]])(?:(?=\\.\\.\\.)|(?!\\.)))", "beginCaptures": { "1": { "name": "keyword.control.export.ts" @@ -353,8 +360,23 @@ "name": "storage.type.ts" } }, - "end": "((?=;|}|(\\s+(of|in)\\s+)|^\\s*$|;|^\\s*abstract\\b|^\\s*async\\b|^\\s*class\\b|^\\s*const\\b|^\\s*declare\\b|^\\s*enum\\b|^\\s*export\\b|^\\s*function\\b|^\\s*import\\b|^\\s*interface\\b|^\\s*let\\b|^\\s*module\\b|^\\s*namespace\\b|^\\s*return\\b|^\\s*type\\b|^\\s*var\\b)|((?<=\\S)(?<!^const|[^\\._$[:alnum:]]const)(?=\\s*$)))", + "end": "(?!(?<![_$[:alnum:]])(?:(?<=\\.\\.\\.)|(?<!\\.))(?:(\\bexport)\\s+)?(?:(\\bdeclare)\\s+)?\\b(const(?!\\s+enum\\b))(?![_$[:alnum:]])(?:(?=\\.\\.\\.)|(?!\\.)))((?=;|}|(\\s+(of|in)\\s+)|^\\s*$|;|(?:^\\s*(?:abstract|async|class|const|declare|enum|export|function|import|interface|let|module|namespace|return|type|var)\\b))|((?<!^const|[^\\._$[:alnum:]]const)(?=\\s*$)))", "patterns": [ + { + "begin": "(?<![_$[:alnum:]])(?:(?<=\\.\\.\\.)|(?<!\\.))(?:(\\bexport)\\s+)?(?:(\\bdeclare)\\s+)?\\b(const(?!\\s+enum\\b))(?![_$[:alnum:]])(?:(?=\\.\\.\\.)|(?!\\.))\\s*", + "beginCaptures": { + "1": { + "name": "keyword.control.export.ts" + }, + "2": { + "name": "storage.modifier.ts" + }, + "3": { + "name": "storage.type.ts" + } + }, + "end": "(?=\\S)" + }, { "include": "#destructuring-const" }, @@ -368,7 +390,7 @@ "include": "#comment" }, { - "begin": "(,)\\s*(?!\\S)", + "begin": "(,)\\s*((?!\\S)|(?=\\/\\/))", "beginCaptures": { "1": { "name": "punctuation.separator.comma.ts" @@ -376,6 +398,9 @@ }, "end": "(?<!,)(((?==|;|}|(\\s+(of|in)\\s+)|^\\s*$))|((?<=\\S)(?=\\s*$)))", "patterns": [ + { + "include": "#single-line-comment-consuming-line-ending" + }, { "include": "#comment" }, @@ -1029,13 +1054,13 @@ }, "field-declaration": { "name": "meta.field.declaration.ts", - "begin": "(?x)(?<!\\()(?:(?<![_$[:alnum:]])(?:(?<=\\.\\.\\.)|(?<!\\.))(readonly)\\s+)?(?=\\s*((\\b(?<!\\$)0(x|X)[0-9a-fA-F][0-9a-fA-F_]*\\b(?!\\$))|(\\b(?<!\\$)0(b|B)[01][01_]*\\b(?!\\$))|(\\b(?<!\\$)0(o|O)?[0-7][0-7_]*\\b(?!\\$))|((?<!\\$)(?:\n (?:\\b[0-9][0-9_]*(\\.)[0-9][0-9_]*[eE][+-]?[0-9][0-9_]*\\b)| # 1.1E+3\n (?:\\b[0-9][0-9_]*(\\.)[eE][+-]?[0-9][0-9_]*\\b)| # 1.E+3\n (?:\\B(\\.)[0-9][0-9_]*[eE][+-]?[0-9][0-9_]*\\b)| # .1E+3\n (?:\\b[0-9][0-9_]*[eE][+-]?[0-9][0-9_]*\\b)| # 1E+3\n (?:\\b[0-9][0-9_]*(\\.)[0-9][0-9_]*\\b)| # 1.1\n (?:\\b[0-9][0-9_]*(\\.)\\B)| # 1.\n (?:\\B(\\.)[0-9][0-9_]*\\b)| # .1\n (?:\\b[0-9][0-9_]*\\b(?!\\.)) # 1\n)(?!\\$))|([_$[:alpha:]][_$[:alnum:]]*)|(\\'([^\\'\\\\]|\\\\\\'|\\\\)*\\')|(\\\"([^\\\"\\\\]|\\\\\\\"|\\\\)*\\\")|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])+\\]))\\s*(\\?\\s*)?(=|:|;|$))", + "begin": "(?x)(?<!\\()(?:(?<![_$[:alnum:]])(?:(?<=\\.\\.\\.)|(?<!\\.))(readonly)\\s+)?(?=\\s*((\\b(?<!\\$)0(x|X)[0-9a-fA-F][0-9a-fA-F_]*\\b(?!\\$))|(\\b(?<!\\$)0(b|B)[01][01_]*\\b(?!\\$))|(\\b(?<!\\$)0(o|O)?[0-7][0-7_]*\\b(?!\\$))|((?<!\\$)(?:\n (?:\\b[0-9][0-9_]*(\\.)[0-9][0-9_]*[eE][+-]?[0-9][0-9_]*\\b)| # 1.1E+3\n (?:\\b[0-9][0-9_]*(\\.)[eE][+-]?[0-9][0-9_]*\\b)| # 1.E+3\n (?:\\B(\\.)[0-9][0-9_]*[eE][+-]?[0-9][0-9_]*\\b)| # .1E+3\n (?:\\b[0-9][0-9_]*[eE][+-]?[0-9][0-9_]*\\b)| # 1E+3\n (?:\\b[0-9][0-9_]*(\\.)[0-9][0-9_]*\\b)| # 1.1\n (?:\\b[0-9][0-9_]*(\\.)\\B)| # 1.\n (?:\\B(\\.)[0-9][0-9_]*\\b)| # .1\n (?:\\b[0-9][0-9_]*\\b(?!\\.)) # 1\n)(?!\\$))|([_$[:alpha:]][_$[:alnum:]]*)|(\\'([^\\'\\\\]|\\\\\\'|\\\\)*\\')|(\\\"([^\\\"\\\\]|\\\\\\\"|\\\\)*\\\")|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])+\\]))\\s*(\\?\\s*)?(=|:|;|,|$))", "beginCaptures": { "1": { "name": "storage.modifier.ts" } }, - "end": "(?x)(?=\\}|;|,|$|(^(?!\\s*((\\b(?<!\\$)0(x|X)[0-9a-fA-F][0-9a-fA-F_]*\\b(?!\\$))|(\\b(?<!\\$)0(b|B)[01][01_]*\\b(?!\\$))|(\\b(?<!\\$)0(o|O)?[0-7][0-7_]*\\b(?!\\$))|((?<!\\$)(?:\n (?:\\b[0-9][0-9_]*(\\.)[0-9][0-9_]*[eE][+-]?[0-9][0-9_]*\\b)| # 1.1E+3\n (?:\\b[0-9][0-9_]*(\\.)[eE][+-]?[0-9][0-9_]*\\b)| # 1.E+3\n (?:\\B(\\.)[0-9][0-9_]*[eE][+-]?[0-9][0-9_]*\\b)| # .1E+3\n (?:\\b[0-9][0-9_]*[eE][+-]?[0-9][0-9_]*\\b)| # 1E+3\n (?:\\b[0-9][0-9_]*(\\.)[0-9][0-9_]*\\b)| # 1.1\n (?:\\b[0-9][0-9_]*(\\.)\\B)| # 1.\n (?:\\B(\\.)[0-9][0-9_]*\\b)| # .1\n (?:\\b[0-9][0-9_]*\\b(?!\\.)) # 1\n)(?!\\$))|([_$[:alpha:]][_$[:alnum:]]*)|(\\'([^\\'\\\\]|\\\\\\'|\\\\)*\\')|(\\\"([^\\\"\\\\]|\\\\\\\"|\\\\)*\\\")|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])+\\]))\\s*(\\?\\s*)?(=|:|;|$))))|(?<=\\})", + "end": "(?x)(?=\\}|;|,|$|(^(?!\\s*((\\b(?<!\\$)0(x|X)[0-9a-fA-F][0-9a-fA-F_]*\\b(?!\\$))|(\\b(?<!\\$)0(b|B)[01][01_]*\\b(?!\\$))|(\\b(?<!\\$)0(o|O)?[0-7][0-7_]*\\b(?!\\$))|((?<!\\$)(?:\n (?:\\b[0-9][0-9_]*(\\.)[0-9][0-9_]*[eE][+-]?[0-9][0-9_]*\\b)| # 1.1E+3\n (?:\\b[0-9][0-9_]*(\\.)[eE][+-]?[0-9][0-9_]*\\b)| # 1.E+3\n (?:\\B(\\.)[0-9][0-9_]*[eE][+-]?[0-9][0-9_]*\\b)| # .1E+3\n (?:\\b[0-9][0-9_]*[eE][+-]?[0-9][0-9_]*\\b)| # 1E+3\n (?:\\b[0-9][0-9_]*(\\.)[0-9][0-9_]*\\b)| # 1.1\n (?:\\b[0-9][0-9_]*(\\.)\\B)| # 1.\n (?:\\B(\\.)[0-9][0-9_]*\\b)| # .1\n (?:\\b[0-9][0-9_]*\\b(?!\\.)) # 1\n)(?!\\$))|([_$[:alpha:]][_$[:alnum:]]*)|(\\'([^\\'\\\\]|\\\\\\'|\\\\)*\\')|(\\\"([^\\\"\\\\]|\\\\\\\"|\\\\)*\\\")|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])+\\]))\\s*(\\?\\s*)?(=|:|;|,|$))))|(?<=\\})", "patterns": [ { "include": "#variable-initializer" @@ -1163,6 +1188,9 @@ { "include": "#function-name" }, + { + "include": "#single-line-comment-consuming-line-ending" + }, { "include": "#function-body" } @@ -1850,7 +1878,7 @@ "name": "storage.type.namespace.ts" } }, - "end": "(?<=\\})|(?=;|^\\s*abstract\\b|^\\s*async\\b|^\\s*class\\b|^\\s*const\\b|^\\s*declare\\b|^\\s*enum\\b|^\\s*export\\b|^\\s*function\\b|^\\s*import\\b|^\\s*interface\\b|^\\s*let\\b|^\\s*module\\b|^\\s*namespace\\b|^\\s*return\\b|^\\s*type\\b|^\\s*var\\b)", + "end": "(?<=\\})|(?=;|(?:^\\s*(?:abstract|async|class|const|declare|enum|export|function|import|interface|let|module|namespace|return|type|var)\\b))", "patterns": [ { "include": "#comment" @@ -1887,7 +1915,7 @@ "name": "entity.name.type.alias.ts" } }, - "end": "(?=\\}|;|^\\s*abstract\\b|^\\s*async\\b|^\\s*class\\b|^\\s*const\\b|^\\s*declare\\b|^\\s*enum\\b|^\\s*export\\b|^\\s*function\\b|^\\s*import\\b|^\\s*interface\\b|^\\s*let\\b|^\\s*module\\b|^\\s*namespace\\b|^\\s*return\\b|^\\s*type\\b|^\\s*var\\b)", + "end": "(?=\\}|;|(?:^\\s*(?:abstract|async|class|const|declare|enum|export|function|import|interface|let|module|namespace|return|type|var)\\b))", "patterns": [ { "include": "#comment" @@ -1902,7 +1930,7 @@ "name": "keyword.operator.assignment.ts" } }, - "end": "(?=\\}|;|^\\s*abstract\\b|^\\s*async\\b|^\\s*class\\b|^\\s*const\\b|^\\s*declare\\b|^\\s*enum\\b|^\\s*export\\b|^\\s*function\\b|^\\s*import\\b|^\\s*interface\\b|^\\s*let\\b|^\\s*module\\b|^\\s*namespace\\b|^\\s*return\\b|^\\s*type\\b|^\\s*var\\b)", + "end": "(?=\\}|;|(?:^\\s*(?:abstract|async|class|const|declare|enum|export|function|import|interface|let|module|namespace|return|type|var)\\b))", "patterns": [ { "include": "#type" @@ -2075,8 +2103,11 @@ "name": "keyword.control.default.ts" } }, - "end": "(?=$|;|^\\s*abstract\\b|^\\s*async\\b|^\\s*class\\b|^\\s*const\\b|^\\s*declare\\b|^\\s*enum\\b|^\\s*export\\b|^\\s*function\\b|^\\s*import\\b|^\\s*interface\\b|^\\s*let\\b|^\\s*module\\b|^\\s*namespace\\b|^\\s*return\\b|^\\s*type\\b|^\\s*var\\b)", + "end": "(?=$|;|(?:^\\s*(?:abstract|async|class|const|declare|enum|export|function|import|interface|let|module|namespace|return|type|var)\\b))", "patterns": [ + { + "include": "#interface-declaration" + }, { "include": "#expression" } @@ -2084,13 +2115,13 @@ }, { "name": "meta.export.ts", - "begin": "(?<![_$[:alnum:]])(?:(?<=\\.\\.\\.)|(?<!\\.))(export)(?!\\s*:)(?![_$[:alnum:]])(?:(?=\\.\\.\\.)|(?!\\.))", + "begin": "(?<![_$[:alnum:]])(?:(?<=\\.\\.\\.)|(?<!\\.))(export)(?!\\s*:)((?=\\s*[\\{*])|((?=\\s*[_$[:alpha:]][_$[:alnum:]]*(\\s|,))(?!\\s*(?:abstract|async|class|const|declare|enum|export|function|import|interface|let|module|namespace|return|type|var)\\b)))", "beginCaptures": { "0": { "name": "keyword.control.export.ts" } }, - "end": "(?=$|;|^\\s*abstract\\b|^\\s*async\\b|^\\s*class\\b|^\\s*const\\b|^\\s*declare\\b|^\\s*enum\\b|^\\s*export\\b|^\\s*function\\b|^\\s*import\\b|^\\s*interface\\b|^\\s*let\\b|^\\s*module\\b|^\\s*namespace\\b|^\\s*return\\b|^\\s*type\\b|^\\s*var\\b)", + "end": "(?=$|;|(?:^\\s*(?:abstract|async|class|const|declare|enum|export|function|import|interface|let|module|namespace|return|type|var)\\b))", "patterns": [ { "include": "#import-export-declaration" @@ -2873,7 +2904,7 @@ "name": "keyword.control.as.ts" } }, - "end": "(?=$|^|[;,:})\\]]|((?<![_$[:alnum:]])(?:(?<=\\.\\.\\.)|(?<!\\.))(as)\\s+))", + "end": "(?=$|^|[;,:})\\]]|((?<![_$[:alnum:]])(?:(?<=\\.\\.\\.)|(?<!\\.))(as)\\s+)|(\\s+\\<))", "patterns": [ { "include": "#type" @@ -4415,11 +4446,33 @@ "name": "punctuation.decorator.internaldeclaration.ts" } }, - "end": "(?=^)", + "end": "(?=$)", "contentName": "comment.line.double-slash.ts" } ] }, + "single-line-comment-consuming-line-ending": { + "begin": "(^[ \\t]+)?((//)(?:\\s*((@)internal)(?=\\s|$))?)", + "beginCaptures": { + "1": { + "name": "punctuation.whitespace.comment.leading.ts" + }, + "2": { + "name": "comment.line.double-slash.ts" + }, + "3": { + "name": "punctuation.definition.comment.ts" + }, + "4": { + "name": "storage.type.internaldeclaration.ts" + }, + "5": { + "name": "punctuation.decorator.internaldeclaration.ts" + } + }, + "end": "(?=^)", + "contentName": "comment.line.double-slash.ts" + }, "directives": { "name": "comment.line.triple-slash.directive.ts", "begin": "^(///)\\s*(?=<(reference|amd-dependency|amd-module)(\\s+(path|types|no-default-lib|lib|name)\\s*=\\s*((\\'([^\\'\\\\]|\\\\\\'|\\\\)*\\')|(\\\"([^\\\"\\\\]|\\\\\\\"|\\\\)*\\\")))+\\s*/>\\s*$)", @@ -4428,7 +4481,7 @@ "name": "punctuation.definition.comment.ts" } }, - "end": "(?=^)", + "end": "(?=$)", "patterns": [ { "name": "meta.tag.ts", diff --git a/extensions/typescript-basics/syntaxes/TypeScriptReact.tmLanguage.json b/extensions/typescript-basics/syntaxes/TypeScriptReact.tmLanguage.json index b58cdd088f1..41b9e17d5e2 100644 --- a/extensions/typescript-basics/syntaxes/TypeScriptReact.tmLanguage.json +++ b/extensions/typescript-basics/syntaxes/TypeScriptReact.tmLanguage.json @@ -4,7 +4,7 @@ "If you want to provide a fix or improvement, please create a pull request against the original repository.", "Once accepted there, we are happy to receive an update request." ], - "version": "https://github.com/Microsoft/TypeScript-TmLanguage/commit/d33674e802be357bff20cf8b0a4c966be54c39c4", + "version": "https://github.com/Microsoft/TypeScript-TmLanguage/commit/4407e8d57037cdb02e5fb670bcf318e0daebb40f", "name": "TypeScriptReact", "scopeName": "source.tsx", "patterns": [ @@ -96,7 +96,7 @@ }, { "name": "storage.modifier.tsx", - "match": "(?<![_$[:alnum:]])(?:(?<=\\.\\.\\.)|(?<!\\.))(declare)(?![_$[:alnum:]])(?:(?=\\.\\.\\.)|(?!\\.))" + "match": "(?<![_$[:alnum:]])(?:(?<=\\.\\.\\.)|(?<!\\.))(declare|export)(?![_$[:alnum:]])(?:(?=\\.\\.\\.)|(?!\\.))" } ] }, @@ -288,20 +288,24 @@ "patterns": [ { "name": "meta.var.expr.tsx", - "begin": "(?<![_$[:alnum:]])(?:(?<=\\.\\.\\.)|(?<!\\.))(?:(\\bexport)\\s+)?(?:(\\bdeclare)\\s+)?\\b(var|let)(?![_$[:alnum:]])(?:(?=\\.\\.\\.)|(?!\\.))", - "beginCaptures": { - "1": { - "name": "keyword.control.export.tsx" - }, - "2": { - "name": "storage.modifier.tsx" - }, - "3": { - "name": "storage.type.tsx" - } - }, - "end": "((?=;|}|(\\s+(of|in)\\s+)|^\\s*$|;|^\\s*abstract\\b|^\\s*async\\b|^\\s*class\\b|^\\s*const\\b|^\\s*declare\\b|^\\s*enum\\b|^\\s*export\\b|^\\s*function\\b|^\\s*import\\b|^\\s*interface\\b|^\\s*let\\b|^\\s*module\\b|^\\s*namespace\\b|^\\s*return\\b|^\\s*type\\b|^\\s*var\\b)|((?<=\\S)(?<!^let|[^\\._$[:alnum:]]let|^var|[^\\._$[:alnum:]]var)(?=\\s*$)))", + "begin": "(?=(?<![_$[:alnum:]])(?:(?<=\\.\\.\\.)|(?<!\\.))(?:(\\bexport)\\s+)?(?:(\\bdeclare)\\s+)?\\b(var|let)(?![_$[:alnum:]])(?:(?=\\.\\.\\.)|(?!\\.)))", + "end": "(?!(?<![_$[:alnum:]])(?:(?<=\\.\\.\\.)|(?<!\\.))(?:(\\bexport)\\s+)?(?:(\\bdeclare)\\s+)?\\b(var|let)(?![_$[:alnum:]])(?:(?=\\.\\.\\.)|(?!\\.)))((?=;|}|(\\s+(of|in)\\s+)|^\\s*$|;|(?:^\\s*(?:abstract|async|class|const|declare|enum|export|function|import|interface|let|module|namespace|return|type|var)\\b))|((?<!^let|[^\\._$[:alnum:]]let|^var|[^\\._$[:alnum:]]var)(?=\\s*$)))", "patterns": [ + { + "begin": "(?<![_$[:alnum:]])(?:(?<=\\.\\.\\.)|(?<!\\.))(?:(\\bexport)\\s+)?(?:(\\bdeclare)\\s+)?\\b(var|let)(?![_$[:alnum:]])(?:(?=\\.\\.\\.)|(?!\\.))\\s*", + "beginCaptures": { + "1": { + "name": "keyword.control.export.tsx" + }, + "2": { + "name": "storage.modifier.tsx" + }, + "3": { + "name": "storage.type.tsx" + } + }, + "end": "(?=\\S)" + }, { "include": "#destructuring-variable" }, @@ -315,7 +319,7 @@ "include": "#comment" }, { - "begin": "(,)\\s*(?!\\S)", + "begin": "(,)\\s*((?!\\S)|(?=\\/\\/))", "beginCaptures": { "1": { "name": "punctuation.separator.comma.tsx" @@ -323,6 +327,9 @@ }, "end": "(?<!,)(((?==|;|}|(\\s+(of|in)\\s+)|^\\s*$))|((?<=\\S)(?=\\s*$)))", "patterns": [ + { + "include": "#single-line-comment-consuming-line-ending" + }, { "include": "#comment" }, @@ -344,7 +351,7 @@ }, { "name": "meta.var.expr.tsx", - "begin": "(?<![_$[:alnum:]])(?:(?<=\\.\\.\\.)|(?<!\\.))(?:(\\bexport)\\s+)?(?:(\\bdeclare)\\s+)?\\b(const(?!\\s+enum\\b))(?![_$[:alnum:]])(?:(?=\\.\\.\\.)|(?!\\.))", + "begin": "(?=(?<![_$[:alnum:]])(?:(?<=\\.\\.\\.)|(?<!\\.))(?:(\\bexport)\\s+)?(?:(\\bdeclare)\\s+)?\\b(const(?!\\s+enum\\b))(?![_$[:alnum:]])(?:(?=\\.\\.\\.)|(?!\\.)))", "beginCaptures": { "1": { "name": "keyword.control.export.tsx" @@ -356,8 +363,23 @@ "name": "storage.type.tsx" } }, - "end": "((?=;|}|(\\s+(of|in)\\s+)|^\\s*$|;|^\\s*abstract\\b|^\\s*async\\b|^\\s*class\\b|^\\s*const\\b|^\\s*declare\\b|^\\s*enum\\b|^\\s*export\\b|^\\s*function\\b|^\\s*import\\b|^\\s*interface\\b|^\\s*let\\b|^\\s*module\\b|^\\s*namespace\\b|^\\s*return\\b|^\\s*type\\b|^\\s*var\\b)|((?<=\\S)(?<!^const|[^\\._$[:alnum:]]const)(?=\\s*$)))", + "end": "(?!(?<![_$[:alnum:]])(?:(?<=\\.\\.\\.)|(?<!\\.))(?:(\\bexport)\\s+)?(?:(\\bdeclare)\\s+)?\\b(const(?!\\s+enum\\b))(?![_$[:alnum:]])(?:(?=\\.\\.\\.)|(?!\\.)))((?=;|}|(\\s+(of|in)\\s+)|^\\s*$|;|(?:^\\s*(?:abstract|async|class|const|declare|enum|export|function|import|interface|let|module|namespace|return|type|var)\\b))|((?<!^const|[^\\._$[:alnum:]]const)(?=\\s*$)))", "patterns": [ + { + "begin": "(?<![_$[:alnum:]])(?:(?<=\\.\\.\\.)|(?<!\\.))(?:(\\bexport)\\s+)?(?:(\\bdeclare)\\s+)?\\b(const(?!\\s+enum\\b))(?![_$[:alnum:]])(?:(?=\\.\\.\\.)|(?!\\.))\\s*", + "beginCaptures": { + "1": { + "name": "keyword.control.export.tsx" + }, + "2": { + "name": "storage.modifier.tsx" + }, + "3": { + "name": "storage.type.tsx" + } + }, + "end": "(?=\\S)" + }, { "include": "#destructuring-const" }, @@ -371,7 +393,7 @@ "include": "#comment" }, { - "begin": "(,)\\s*(?!\\S)", + "begin": "(,)\\s*((?!\\S)|(?=\\/\\/))", "beginCaptures": { "1": { "name": "punctuation.separator.comma.tsx" @@ -379,6 +401,9 @@ }, "end": "(?<!,)(((?==|;|}|(\\s+(of|in)\\s+)|^\\s*$))|((?<=\\S)(?=\\s*$)))", "patterns": [ + { + "include": "#single-line-comment-consuming-line-ending" + }, { "include": "#comment" }, @@ -1032,13 +1057,13 @@ }, "field-declaration": { "name": "meta.field.declaration.tsx", - "begin": "(?x)(?<!\\()(?:(?<![_$[:alnum:]])(?:(?<=\\.\\.\\.)|(?<!\\.))(readonly)\\s+)?(?=\\s*((\\b(?<!\\$)0(x|X)[0-9a-fA-F][0-9a-fA-F_]*\\b(?!\\$))|(\\b(?<!\\$)0(b|B)[01][01_]*\\b(?!\\$))|(\\b(?<!\\$)0(o|O)?[0-7][0-7_]*\\b(?!\\$))|((?<!\\$)(?:\n (?:\\b[0-9][0-9_]*(\\.)[0-9][0-9_]*[eE][+-]?[0-9][0-9_]*\\b)| # 1.1E+3\n (?:\\b[0-9][0-9_]*(\\.)[eE][+-]?[0-9][0-9_]*\\b)| # 1.E+3\n (?:\\B(\\.)[0-9][0-9_]*[eE][+-]?[0-9][0-9_]*\\b)| # .1E+3\n (?:\\b[0-9][0-9_]*[eE][+-]?[0-9][0-9_]*\\b)| # 1E+3\n (?:\\b[0-9][0-9_]*(\\.)[0-9][0-9_]*\\b)| # 1.1\n (?:\\b[0-9][0-9_]*(\\.)\\B)| # 1.\n (?:\\B(\\.)[0-9][0-9_]*\\b)| # .1\n (?:\\b[0-9][0-9_]*\\b(?!\\.)) # 1\n)(?!\\$))|([_$[:alpha:]][_$[:alnum:]]*)|(\\'([^\\'\\\\]|\\\\\\'|\\\\)*\\')|(\\\"([^\\\"\\\\]|\\\\\\\"|\\\\)*\\\")|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])+\\]))\\s*(\\?\\s*)?(=|:|;|$))", + "begin": "(?x)(?<!\\()(?:(?<![_$[:alnum:]])(?:(?<=\\.\\.\\.)|(?<!\\.))(readonly)\\s+)?(?=\\s*((\\b(?<!\\$)0(x|X)[0-9a-fA-F][0-9a-fA-F_]*\\b(?!\\$))|(\\b(?<!\\$)0(b|B)[01][01_]*\\b(?!\\$))|(\\b(?<!\\$)0(o|O)?[0-7][0-7_]*\\b(?!\\$))|((?<!\\$)(?:\n (?:\\b[0-9][0-9_]*(\\.)[0-9][0-9_]*[eE][+-]?[0-9][0-9_]*\\b)| # 1.1E+3\n (?:\\b[0-9][0-9_]*(\\.)[eE][+-]?[0-9][0-9_]*\\b)| # 1.E+3\n (?:\\B(\\.)[0-9][0-9_]*[eE][+-]?[0-9][0-9_]*\\b)| # .1E+3\n (?:\\b[0-9][0-9_]*[eE][+-]?[0-9][0-9_]*\\b)| # 1E+3\n (?:\\b[0-9][0-9_]*(\\.)[0-9][0-9_]*\\b)| # 1.1\n (?:\\b[0-9][0-9_]*(\\.)\\B)| # 1.\n (?:\\B(\\.)[0-9][0-9_]*\\b)| # .1\n (?:\\b[0-9][0-9_]*\\b(?!\\.)) # 1\n)(?!\\$))|([_$[:alpha:]][_$[:alnum:]]*)|(\\'([^\\'\\\\]|\\\\\\'|\\\\)*\\')|(\\\"([^\\\"\\\\]|\\\\\\\"|\\\\)*\\\")|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])+\\]))\\s*(\\?\\s*)?(=|:|;|,|$))", "beginCaptures": { "1": { "name": "storage.modifier.tsx" } }, - "end": "(?x)(?=\\}|;|,|$|(^(?!\\s*((\\b(?<!\\$)0(x|X)[0-9a-fA-F][0-9a-fA-F_]*\\b(?!\\$))|(\\b(?<!\\$)0(b|B)[01][01_]*\\b(?!\\$))|(\\b(?<!\\$)0(o|O)?[0-7][0-7_]*\\b(?!\\$))|((?<!\\$)(?:\n (?:\\b[0-9][0-9_]*(\\.)[0-9][0-9_]*[eE][+-]?[0-9][0-9_]*\\b)| # 1.1E+3\n (?:\\b[0-9][0-9_]*(\\.)[eE][+-]?[0-9][0-9_]*\\b)| # 1.E+3\n (?:\\B(\\.)[0-9][0-9_]*[eE][+-]?[0-9][0-9_]*\\b)| # .1E+3\n (?:\\b[0-9][0-9_]*[eE][+-]?[0-9][0-9_]*\\b)| # 1E+3\n (?:\\b[0-9][0-9_]*(\\.)[0-9][0-9_]*\\b)| # 1.1\n (?:\\b[0-9][0-9_]*(\\.)\\B)| # 1.\n (?:\\B(\\.)[0-9][0-9_]*\\b)| # .1\n (?:\\b[0-9][0-9_]*\\b(?!\\.)) # 1\n)(?!\\$))|([_$[:alpha:]][_$[:alnum:]]*)|(\\'([^\\'\\\\]|\\\\\\'|\\\\)*\\')|(\\\"([^\\\"\\\\]|\\\\\\\"|\\\\)*\\\")|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])+\\]))\\s*(\\?\\s*)?(=|:|;|$))))|(?<=\\})", + "end": "(?x)(?=\\}|;|,|$|(^(?!\\s*((\\b(?<!\\$)0(x|X)[0-9a-fA-F][0-9a-fA-F_]*\\b(?!\\$))|(\\b(?<!\\$)0(b|B)[01][01_]*\\b(?!\\$))|(\\b(?<!\\$)0(o|O)?[0-7][0-7_]*\\b(?!\\$))|((?<!\\$)(?:\n (?:\\b[0-9][0-9_]*(\\.)[0-9][0-9_]*[eE][+-]?[0-9][0-9_]*\\b)| # 1.1E+3\n (?:\\b[0-9][0-9_]*(\\.)[eE][+-]?[0-9][0-9_]*\\b)| # 1.E+3\n (?:\\B(\\.)[0-9][0-9_]*[eE][+-]?[0-9][0-9_]*\\b)| # .1E+3\n (?:\\b[0-9][0-9_]*[eE][+-]?[0-9][0-9_]*\\b)| # 1E+3\n (?:\\b[0-9][0-9_]*(\\.)[0-9][0-9_]*\\b)| # 1.1\n (?:\\b[0-9][0-9_]*(\\.)\\B)| # 1.\n (?:\\B(\\.)[0-9][0-9_]*\\b)| # .1\n (?:\\b[0-9][0-9_]*\\b(?!\\.)) # 1\n)(?!\\$))|([_$[:alpha:]][_$[:alnum:]]*)|(\\'([^\\'\\\\]|\\\\\\'|\\\\)*\\')|(\\\"([^\\\"\\\\]|\\\\\\\"|\\\\)*\\\")|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])+\\]))\\s*(\\?\\s*)?(=|:|;|,|$))))|(?<=\\})", "patterns": [ { "include": "#variable-initializer" @@ -1166,6 +1191,9 @@ { "include": "#function-name" }, + { + "include": "#single-line-comment-consuming-line-ending" + }, { "include": "#function-body" } @@ -1853,7 +1881,7 @@ "name": "storage.type.namespace.tsx" } }, - "end": "(?<=\\})|(?=;|^\\s*abstract\\b|^\\s*async\\b|^\\s*class\\b|^\\s*const\\b|^\\s*declare\\b|^\\s*enum\\b|^\\s*export\\b|^\\s*function\\b|^\\s*import\\b|^\\s*interface\\b|^\\s*let\\b|^\\s*module\\b|^\\s*namespace\\b|^\\s*return\\b|^\\s*type\\b|^\\s*var\\b)", + "end": "(?<=\\})|(?=;|(?:^\\s*(?:abstract|async|class|const|declare|enum|export|function|import|interface|let|module|namespace|return|type|var)\\b))", "patterns": [ { "include": "#comment" @@ -1890,7 +1918,7 @@ "name": "entity.name.type.alias.tsx" } }, - "end": "(?=\\}|;|^\\s*abstract\\b|^\\s*async\\b|^\\s*class\\b|^\\s*const\\b|^\\s*declare\\b|^\\s*enum\\b|^\\s*export\\b|^\\s*function\\b|^\\s*import\\b|^\\s*interface\\b|^\\s*let\\b|^\\s*module\\b|^\\s*namespace\\b|^\\s*return\\b|^\\s*type\\b|^\\s*var\\b)", + "end": "(?=\\}|;|(?:^\\s*(?:abstract|async|class|const|declare|enum|export|function|import|interface|let|module|namespace|return|type|var)\\b))", "patterns": [ { "include": "#comment" @@ -1905,7 +1933,7 @@ "name": "keyword.operator.assignment.tsx" } }, - "end": "(?=\\}|;|^\\s*abstract\\b|^\\s*async\\b|^\\s*class\\b|^\\s*const\\b|^\\s*declare\\b|^\\s*enum\\b|^\\s*export\\b|^\\s*function\\b|^\\s*import\\b|^\\s*interface\\b|^\\s*let\\b|^\\s*module\\b|^\\s*namespace\\b|^\\s*return\\b|^\\s*type\\b|^\\s*var\\b)", + "end": "(?=\\}|;|(?:^\\s*(?:abstract|async|class|const|declare|enum|export|function|import|interface|let|module|namespace|return|type|var)\\b))", "patterns": [ { "include": "#type" @@ -2078,8 +2106,11 @@ "name": "keyword.control.default.tsx" } }, - "end": "(?=$|;|^\\s*abstract\\b|^\\s*async\\b|^\\s*class\\b|^\\s*const\\b|^\\s*declare\\b|^\\s*enum\\b|^\\s*export\\b|^\\s*function\\b|^\\s*import\\b|^\\s*interface\\b|^\\s*let\\b|^\\s*module\\b|^\\s*namespace\\b|^\\s*return\\b|^\\s*type\\b|^\\s*var\\b)", + "end": "(?=$|;|(?:^\\s*(?:abstract|async|class|const|declare|enum|export|function|import|interface|let|module|namespace|return|type|var)\\b))", "patterns": [ + { + "include": "#interface-declaration" + }, { "include": "#expression" } @@ -2087,13 +2118,13 @@ }, { "name": "meta.export.tsx", - "begin": "(?<![_$[:alnum:]])(?:(?<=\\.\\.\\.)|(?<!\\.))(export)(?!\\s*:)(?![_$[:alnum:]])(?:(?=\\.\\.\\.)|(?!\\.))", + "begin": "(?<![_$[:alnum:]])(?:(?<=\\.\\.\\.)|(?<!\\.))(export)(?!\\s*:)((?=\\s*[\\{*])|((?=\\s*[_$[:alpha:]][_$[:alnum:]]*(\\s|,))(?!\\s*(?:abstract|async|class|const|declare|enum|export|function|import|interface|let|module|namespace|return|type|var)\\b)))", "beginCaptures": { "0": { "name": "keyword.control.export.tsx" } }, - "end": "(?=$|;|^\\s*abstract\\b|^\\s*async\\b|^\\s*class\\b|^\\s*const\\b|^\\s*declare\\b|^\\s*enum\\b|^\\s*export\\b|^\\s*function\\b|^\\s*import\\b|^\\s*interface\\b|^\\s*let\\b|^\\s*module\\b|^\\s*namespace\\b|^\\s*return\\b|^\\s*type\\b|^\\s*var\\b)", + "end": "(?=$|;|(?:^\\s*(?:abstract|async|class|const|declare|enum|export|function|import|interface|let|module|namespace|return|type|var)\\b))", "patterns": [ { "include": "#import-export-declaration" @@ -2839,7 +2870,7 @@ "name": "keyword.control.as.tsx" } }, - "end": "(?=$|^|[;,:})\\]]|((?<![_$[:alnum:]])(?:(?<=\\.\\.\\.)|(?<!\\.))(as)\\s+))", + "end": "(?=$|^|[;,:})\\]]|((?<![_$[:alnum:]])(?:(?<=\\.\\.\\.)|(?<!\\.))(as)\\s+)|(\\s+\\<))", "patterns": [ { "include": "#type" @@ -4381,11 +4412,33 @@ "name": "punctuation.decorator.internaldeclaration.tsx" } }, - "end": "(?=^)", + "end": "(?=$)", "contentName": "comment.line.double-slash.tsx" } ] }, + "single-line-comment-consuming-line-ending": { + "begin": "(^[ \\t]+)?((//)(?:\\s*((@)internal)(?=\\s|$))?)", + "beginCaptures": { + "1": { + "name": "punctuation.whitespace.comment.leading.tsx" + }, + "2": { + "name": "comment.line.double-slash.tsx" + }, + "3": { + "name": "punctuation.definition.comment.tsx" + }, + "4": { + "name": "storage.type.internaldeclaration.tsx" + }, + "5": { + "name": "punctuation.decorator.internaldeclaration.tsx" + } + }, + "end": "(?=^)", + "contentName": "comment.line.double-slash.tsx" + }, "directives": { "name": "comment.line.triple-slash.directive.tsx", "begin": "^(///)\\s*(?=<(reference|amd-dependency|amd-module)(\\s+(path|types|no-default-lib|lib|name)\\s*=\\s*((\\'([^\\'\\\\]|\\\\\\'|\\\\)*\\')|(\\\"([^\\\"\\\\]|\\\\\\\"|\\\\)*\\\")))+\\s*/>\\s*$)", @@ -4394,7 +4447,7 @@ "name": "punctuation.definition.comment.tsx" } }, - "end": "(?=^)", + "end": "(?=$)", "patterns": [ { "name": "meta.tag.tsx", From f4ce236ad4b6a924f0f803239ca5130a9030d89d Mon Sep 17 00:00:00 2001 From: Johannes Rieken <johannes.rieken@gmail.com> Date: Thu, 23 Aug 2018 10:56:37 +0200 Subject: [PATCH 1148/1276] keep editor position stable when revealing after previewing, #56983 --- src/vs/workbench/browser/parts/editor/breadcrumbsControl.ts | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/vs/workbench/browser/parts/editor/breadcrumbsControl.ts b/src/vs/workbench/browser/parts/editor/breadcrumbsControl.ts index 9ec7d139d25..f589bdf3995 100644 --- a/src/vs/workbench/browser/parts/editor/breadcrumbsControl.ts +++ b/src/vs/workbench/browser/parts/editor/breadcrumbsControl.ts @@ -383,7 +383,10 @@ export class BreadcrumbsControl { let model = OutlineModel.get(element); this._editorService.openEditor({ resource: model.textModel.uri, - options: { selection: Range.collapseToStart(element.symbol.selectionRange) } + options: { + selection: Range.collapseToStart(element.symbol.selectionRange), + revealInCenterIfOutsideViewport: true + } }, group); } } From 069c71374f35946564db5015a9ed66e7b9e3dc23 Mon Sep 17 00:00:00 2001 From: Matt Bierner <matb@microsoft.com> Date: Thu, 23 Aug 2018 11:34:59 +0200 Subject: [PATCH 1149/1276] Updating theme scopes for new markdown grammar --- .../test/colorize-results/test_md.json | 120 +++++++++--------- extensions/theme-defaults/themes/dark_vs.json | 4 +- .../theme-defaults/themes/light_vs.json | 4 +- 3 files changed, 64 insertions(+), 64 deletions(-) diff --git a/extensions/markdown-basics/test/colorize-results/test_md.json b/extensions/markdown-basics/test/colorize-results/test_md.json index 5663fd051bd..143c79aefd7 100644 --- a/extensions/markdown-basics/test/colorize-results/test_md.json +++ b/extensions/markdown-basics/test/colorize-results/test_md.json @@ -1213,10 +1213,10 @@ "c": "*", "t": "text.html.markdown markup.list.unnumbered.markdown punctuation.definition.list.begin.markdown", "r": { - "dark_plus": "default: #D4D4D4", - "light_plus": "default: #000000", - "dark_vs": "default: #D4D4D4", - "light_vs": "default: #000000", + "dark_plus": "punctuation.definition.list.begin.markdown: #6796E6", + "light_plus": "punctuation.definition.list.begin.markdown: #0451A5", + "dark_vs": "punctuation.definition.list.begin.markdown: #6796E6", + "light_vs": "punctuation.definition.list.begin.markdown: #0451A5", "hc_black": "default: #FFFFFF" } }, @@ -1246,10 +1246,10 @@ "c": "-", "t": "text.html.markdown markup.list.unnumbered.markdown punctuation.definition.list.begin.markdown", "r": { - "dark_plus": "default: #D4D4D4", - "light_plus": "default: #000000", - "dark_vs": "default: #D4D4D4", - "light_vs": "default: #000000", + "dark_plus": "punctuation.definition.list.begin.markdown: #6796E6", + "light_plus": "punctuation.definition.list.begin.markdown: #0451A5", + "dark_vs": "punctuation.definition.list.begin.markdown: #6796E6", + "light_vs": "punctuation.definition.list.begin.markdown: #0451A5", "hc_black": "default: #FFFFFF" } }, @@ -1279,10 +1279,10 @@ "c": "+", "t": "text.html.markdown markup.list.unnumbered.markdown punctuation.definition.list.begin.markdown", "r": { - "dark_plus": "default: #D4D4D4", - "light_plus": "default: #000000", - "dark_vs": "default: #D4D4D4", - "light_vs": "default: #000000", + "dark_plus": "punctuation.definition.list.begin.markdown: #6796E6", + "light_plus": "punctuation.definition.list.begin.markdown: #0451A5", + "dark_vs": "punctuation.definition.list.begin.markdown: #6796E6", + "light_vs": "punctuation.definition.list.begin.markdown: #0451A5", "hc_black": "default: #FFFFFF" } }, @@ -1323,10 +1323,10 @@ "c": "+", "t": "text.html.markdown markup.list.unnumbered.markdown markup.list.unnumbered.markdown punctuation.definition.list.begin.markdown", "r": { - "dark_plus": "default: #D4D4D4", - "light_plus": "default: #000000", - "dark_vs": "default: #D4D4D4", - "light_vs": "default: #000000", + "dark_plus": "punctuation.definition.list.begin.markdown: #6796E6", + "light_plus": "punctuation.definition.list.begin.markdown: #0451A5", + "dark_vs": "punctuation.definition.list.begin.markdown: #6796E6", + "light_vs": "punctuation.definition.list.begin.markdown: #0451A5", "hc_black": "default: #FFFFFF" } }, @@ -1598,10 +1598,10 @@ "c": ">", "t": "text.html.markdown markup.quote.markdown punctuation.definition.quote.begin.markdown", "r": { - "dark_plus": "default: #D4D4D4", - "light_plus": "default: #000000", - "dark_vs": "default: #D4D4D4", - "light_vs": "default: #000000", + "dark_plus": "punctuation.definition.quote.begin.markdown: #6A9955", + "light_plus": "punctuation.definition.quote.begin.markdown: #0451A5", + "dark_vs": "punctuation.definition.quote.begin.markdown: #6A9955", + "light_vs": "punctuation.definition.quote.begin.markdown: #0451A5", "hc_black": "default: #FFFFFF" } }, @@ -1631,10 +1631,10 @@ "c": ">", "t": "text.html.markdown markup.quote.markdown punctuation.definition.quote.begin.markdown", "r": { - "dark_plus": "default: #D4D4D4", - "light_plus": "default: #000000", - "dark_vs": "default: #D4D4D4", - "light_vs": "default: #000000", + "dark_plus": "punctuation.definition.quote.begin.markdown: #6A9955", + "light_plus": "punctuation.definition.quote.begin.markdown: #0451A5", + "dark_vs": "punctuation.definition.quote.begin.markdown: #6A9955", + "light_vs": "punctuation.definition.quote.begin.markdown: #0451A5", "hc_black": "default: #FFFFFF" } }, @@ -1642,10 +1642,10 @@ "c": ">", "t": "text.html.markdown markup.quote.markdown markup.quote.markdown punctuation.definition.quote.begin.markdown", "r": { - "dark_plus": "default: #D4D4D4", - "light_plus": "default: #000000", - "dark_vs": "default: #D4D4D4", - "light_vs": "default: #000000", + "dark_plus": "punctuation.definition.quote.begin.markdown: #6A9955", + "light_plus": "punctuation.definition.quote.begin.markdown: #0451A5", + "dark_vs": "punctuation.definition.quote.begin.markdown: #6A9955", + "light_vs": "punctuation.definition.quote.begin.markdown: #0451A5", "hc_black": "default: #FFFFFF" } }, @@ -1675,10 +1675,10 @@ "c": "1.", "t": "text.html.markdown markup.list.numbered.markdown punctuation.definition.list.begin.markdown", "r": { - "dark_plus": "default: #D4D4D4", - "light_plus": "default: #000000", - "dark_vs": "default: #D4D4D4", - "light_vs": "default: #000000", + "dark_plus": "punctuation.definition.list.begin.markdown: #6796E6", + "light_plus": "punctuation.definition.list.begin.markdown: #0451A5", + "dark_vs": "punctuation.definition.list.begin.markdown: #6796E6", + "light_vs": "punctuation.definition.list.begin.markdown: #0451A5", "hc_black": "default: #FFFFFF" } }, @@ -1719,10 +1719,10 @@ "c": ">", "t": "text.html.markdown markup.list.numbered.markdown markup.quote.markdown punctuation.definition.quote.begin.markdown", "r": { - "dark_plus": "default: #D4D4D4", - "light_plus": "default: #000000", - "dark_vs": "default: #D4D4D4", - "light_vs": "default: #000000", + "dark_plus": "punctuation.definition.quote.begin.markdown: #6A9955", + "light_plus": "punctuation.definition.quote.begin.markdown: #0451A5", + "dark_vs": "punctuation.definition.quote.begin.markdown: #6A9955", + "light_vs": "punctuation.definition.quote.begin.markdown: #0451A5", "hc_black": "default: #FFFFFF" } }, @@ -1752,10 +1752,10 @@ "c": "2.", "t": "text.html.markdown markup.list.numbered.markdown punctuation.definition.list.begin.markdown", "r": { - "dark_plus": "default: #D4D4D4", - "light_plus": "default: #000000", - "dark_vs": "default: #D4D4D4", - "light_vs": "default: #000000", + "dark_plus": "punctuation.definition.list.begin.markdown: #6796E6", + "light_plus": "punctuation.definition.list.begin.markdown: #0451A5", + "dark_vs": "punctuation.definition.list.begin.markdown: #6796E6", + "light_vs": "punctuation.definition.list.begin.markdown: #0451A5", "hc_black": "default: #FFFFFF" } }, @@ -1785,10 +1785,10 @@ "c": "3.", "t": "text.html.markdown markup.list.numbered.markdown punctuation.definition.list.begin.markdown", "r": { - "dark_plus": "default: #D4D4D4", - "light_plus": "default: #000000", - "dark_vs": "default: #D4D4D4", - "light_vs": "default: #000000", + "dark_plus": "punctuation.definition.list.begin.markdown: #6796E6", + "light_plus": "punctuation.definition.list.begin.markdown: #0451A5", + "dark_vs": "punctuation.definition.list.begin.markdown: #6796E6", + "light_vs": "punctuation.definition.list.begin.markdown: #0451A5", "hc_black": "default: #FFFFFF" } }, @@ -2247,10 +2247,10 @@ "c": "*", "t": "text.html.markdown markup.list.unnumbered.markdown punctuation.definition.list.begin.markdown", "r": { - "dark_plus": "default: #D4D4D4", - "light_plus": "default: #000000", - "dark_vs": "default: #D4D4D4", - "light_vs": "default: #000000", + "dark_plus": "punctuation.definition.list.begin.markdown: #6796E6", + "light_plus": "punctuation.definition.list.begin.markdown: #0451A5", + "dark_vs": "punctuation.definition.list.begin.markdown: #6796E6", + "light_vs": "punctuation.definition.list.begin.markdown: #0451A5", "hc_black": "default: #FFFFFF" } }, @@ -2280,10 +2280,10 @@ "c": "*", "t": "text.html.markdown markup.list.unnumbered.markdown punctuation.definition.list.begin.markdown", "r": { - "dark_plus": "default: #D4D4D4", - "light_plus": "default: #000000", - "dark_vs": "default: #D4D4D4", - "light_vs": "default: #000000", + "dark_plus": "punctuation.definition.list.begin.markdown: #6796E6", + "light_plus": "punctuation.definition.list.begin.markdown: #0451A5", + "dark_vs": "punctuation.definition.list.begin.markdown: #6796E6", + "light_vs": "punctuation.definition.list.begin.markdown: #0451A5", "hc_black": "default: #FFFFFF" } }, @@ -2423,10 +2423,10 @@ "c": "*", "t": "text.html.markdown markup.list.unnumbered.markdown punctuation.definition.list.begin.markdown", "r": { - "dark_plus": "default: #D4D4D4", - "light_plus": "default: #000000", - "dark_vs": "default: #D4D4D4", - "light_vs": "default: #000000", + "dark_plus": "punctuation.definition.list.begin.markdown: #6796E6", + "light_plus": "punctuation.definition.list.begin.markdown: #0451A5", + "dark_vs": "punctuation.definition.list.begin.markdown: #6796E6", + "light_vs": "punctuation.definition.list.begin.markdown: #0451A5", "hc_black": "default: #FFFFFF" } }, @@ -2456,10 +2456,10 @@ "c": "*", "t": "text.html.markdown markup.list.unnumbered.markdown punctuation.definition.list.begin.markdown", "r": { - "dark_plus": "default: #D4D4D4", - "light_plus": "default: #000000", - "dark_vs": "default: #D4D4D4", - "light_vs": "default: #000000", + "dark_plus": "punctuation.definition.list.begin.markdown: #6796E6", + "light_plus": "punctuation.definition.list.begin.markdown: #0451A5", + "dark_vs": "punctuation.definition.list.begin.markdown: #6796E6", + "light_vs": "punctuation.definition.list.begin.markdown: #0451A5", "hc_black": "default: #FFFFFF" } }, diff --git a/extensions/theme-defaults/themes/dark_vs.json b/extensions/theme-defaults/themes/dark_vs.json index 2cbdca4a8f1..37a510a9c9a 100644 --- a/extensions/theme-defaults/themes/dark_vs.json +++ b/extensions/theme-defaults/themes/dark_vs.json @@ -141,13 +141,13 @@ } }, { - "scope": "beginning.punctuation.definition.quote.markdown", + "scope": "punctuation.definition.quote.begin.markdown", "settings": { "foreground": "#6A9955" } }, { - "scope": "beginning.punctuation.definition.list.markdown", + "scope": "punctuation.definition.list.begin.markdown", "settings": { "foreground": "#6796e6" } diff --git a/extensions/theme-defaults/themes/light_vs.json b/extensions/theme-defaults/themes/light_vs.json index 4134ce0a4cb..66bb3d98dc9 100644 --- a/extensions/theme-defaults/themes/light_vs.json +++ b/extensions/theme-defaults/themes/light_vs.json @@ -140,8 +140,8 @@ }, { "scope": [ - "beginning.punctuation.definition.quote.markdown", - "beginning.punctuation.definition.list.markdown" + "punctuation.definition.quote.begin.markdown", + "punctuation.definition.list.begin.markdown" ], "settings": { "foreground": "#0451a5" From 030d26e61b040a274a74f49750ec891298f0dbd7 Mon Sep 17 00:00:00 2001 From: Johannes Rieken <johannes.rieken@gmail.com> Date: Thu, 23 Aug 2018 11:36:35 +0200 Subject: [PATCH 1150/1276] tweak node update/resue logic and add more info when errors happen, #56634, #57005, #57006 --- .../ui/breadcrumbs/breadcrumbsWidget.ts | 29 ++++++++++++------- 1 file changed, 19 insertions(+), 10 deletions(-) diff --git a/src/vs/base/browser/ui/breadcrumbs/breadcrumbsWidget.ts b/src/vs/base/browser/ui/breadcrumbs/breadcrumbsWidget.ts index 2ba476b8464..6028ef92c35 100644 --- a/src/vs/base/browser/ui/breadcrumbs/breadcrumbsWidget.ts +++ b/src/vs/base/browser/ui/breadcrumbs/breadcrumbsWidget.ts @@ -244,11 +244,20 @@ export class BreadcrumbsWidget { } setItems(items: BreadcrumbsItem[]): void { - let prefix = commonPrefixLength(this._items, items, (a, b) => a.equals(b)); - let removed = this._items.splice(prefix, this._items.length - prefix, ...items.slice(prefix)); - this._render(prefix); - dispose(removed); - this._focus(-1, undefined); + let prefix: number; + let removed: BreadcrumbsItem[]; + try { + prefix = commonPrefixLength(this._items, items, (a, b) => a.equals(b)); + removed = this._items.splice(prefix, this._items.length - prefix, ...items.slice(prefix)); + this._render(prefix); + dispose(removed); + this._focus(-1, undefined); + } catch (e) { + let newError = new Error(`BreadcrumbsItem#setItems: newItems: ${items.length}, prefix: ${prefix}, removed: ${removed.length}`); + newError.name = e.name; + newError.stack = e.stack; + throw newError; + } } private _render(start: number): void { @@ -258,11 +267,11 @@ export class BreadcrumbsWidget { this._renderItem(item, node); } // case a: more nodes -> remove them - for (; start < this._nodes.length; start++) { - this._nodes[start].remove(); - this._freeNodes.push(this._nodes[start]); + while (start < this._nodes.length) { + const free = this._nodes.pop(); + this._freeNodes.push(free); + free.remove(); } - this._nodes.length = this._items.length; // case b: more items -> render them for (; start < this._items.length; start++) { @@ -270,7 +279,7 @@ export class BreadcrumbsWidget { let node = this._freeNodes.length > 0 ? this._freeNodes.pop() : document.createElement('div'); this._renderItem(item, node); this._domNode.appendChild(node); - this._nodes[start] = node; + this._nodes.push(node); } this.layout(undefined); } From 6090860b4f8076e75c19d9b81bc97d6c24eae97d Mon Sep 17 00:00:00 2001 From: isidor <inikolic@microsoft.com> Date: Thu, 23 Aug 2018 11:59:31 +0200 Subject: [PATCH 1151/1276] workspaces: toWorkspaceIdentifier utility --- src/vs/platform/workspaces/common/workspaces.ts | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/src/vs/platform/workspaces/common/workspaces.ts b/src/vs/platform/workspaces/common/workspaces.ts index 44b42dde325..9384c7bd4c1 100644 --- a/src/vs/platform/workspaces/common/workspaces.ts +++ b/src/vs/platform/workspaces/common/workspaces.ts @@ -9,7 +9,7 @@ import { createDecorator } from 'vs/platform/instantiation/common/instantiation' import { TPromise } from 'vs/base/common/winjs.base'; import { localize } from 'vs/nls'; import { Event } from 'vs/base/common/event'; -import { IWorkspaceFolder } from 'vs/platform/workspace/common/workspace'; +import { IWorkspaceFolder, IWorkspace } from 'vs/platform/workspace/common/workspace'; import URI from 'vs/base/common/uri'; export const IWorkspacesMainService = createDecorator<IWorkspacesMainService>('workspacesMainService'); @@ -115,3 +115,18 @@ export function isWorkspaceIdentifier(obj: any): obj is IWorkspaceIdentifier { return workspaceIdentifier && typeof workspaceIdentifier.id === 'string' && typeof workspaceIdentifier.configPath === 'string'; } + +export function toWorkspaceIdentifier(workspace: IWorkspace): IWorkspaceIdentifier | ISingleFolderWorkspaceIdentifier | undefined { + if (workspace.configuration) { + return { + configPath: workspace.configuration.fsPath, + id: workspace.id + }; + } + if (workspace.folders.length === 1) { + return workspace.folders[0].uri; + } + + // Empty workspace + return undefined; +} From a03b3b5066642ac0d2a6db8c7b3efe6f47ed83d8 Mon Sep 17 00:00:00 2001 From: isidor <inikolic@microsoft.com> Date: Thu, 23 Aug 2018 11:59:51 +0200 Subject: [PATCH 1152/1276] remove .name from IWorkspace --- src/vs/code/electron-main/main.ts | 2 +- .../standalone/browser/simpleServices.ts | 6 ++--- src/vs/platform/uriLabel/common/uriLabel.ts | 22 +++++++++++-------- .../platform/uriLabel/test/uriLabel.test.ts | 3 +-- src/vs/platform/workspace/common/workspace.ts | 18 +-------------- .../workspace/test/common/testWorkspace.ts | 3 +-- .../workspace/test/common/workspace.test.ts | 8 +++---- .../electron-browser/mainThreadWorkspace.ts | 12 ++++++++-- src/vs/workbench/api/node/extHost.api.impl.ts | 2 +- src/vs/workbench/api/node/extHostWorkspace.ts | 12 ++++++++-- .../browser/parts/titlebar/titlebarPart.ts | 2 +- src/vs/workbench/electron-browser/main.ts | 12 ++++------ src/vs/workbench/electron-browser/shell.ts | 2 -- .../workbench/electron-browser/workbench.ts | 5 +++++ .../files/electron-browser/views/emptyView.ts | 2 +- .../electron-browser/views/explorerView.ts | 6 +++-- .../logs/electron-browser/logsActions.ts | 15 ++++++++----- .../search/test/common/queryBuilder.test.ts | 2 +- .../backupFileService.test.ts | 2 +- .../node/configurationService.ts | 10 ++++----- .../test/common/configurationModels.test.ts | 2 +- .../configurationEditingService.test.ts | 3 +-- .../configurationService.test.ts | 16 +++++--------- .../electron-browser/extensionHost.ts | 14 +++++++++--- .../test/electron-browser/fileService.test.ts | 8 +++---- .../keybindingEditing.test.ts | 2 +- .../parts/editor/breadcrumbModel.test.ts | 2 +- .../api/mainThreadEditors.test.ts | 4 ++-- .../workbench/test/workbenchTestServices.ts | 2 +- 29 files changed, 103 insertions(+), 96 deletions(-) diff --git a/src/vs/code/electron-main/main.ts b/src/vs/code/electron-main/main.ts index 5f09b85b211..dbe95eb11e2 100644 --- a/src/vs/code/electron-main/main.ts +++ b/src/vs/code/electron-main/main.ts @@ -58,7 +58,7 @@ function createServices(args: ParsedArgs, bufferLogService: BufferLogService): I const environmentService = new EnvironmentService(args, process.execPath); const consoleLogService = new ConsoleLogMainService(getLogLevel(environmentService)); const logService = new MultiplexLogService([consoleLogService, bufferLogService]); - const uriLabelService = new UriLabelService(environmentService); + const uriLabelService = new UriLabelService(environmentService, undefined); process.once('exit', () => logService.dispose()); diff --git a/src/vs/editor/standalone/browser/simpleServices.ts b/src/vs/editor/standalone/browser/simpleServices.ts index 46b76c734f8..2bd024ca87d 100644 --- a/src/vs/editor/standalone/browser/simpleServices.ts +++ b/src/vs/editor/standalone/browser/simpleServices.ts @@ -508,7 +508,7 @@ export class SimpleWorkspaceContextService implements IWorkspaceContextService { constructor() { const resource = URI.from({ scheme: SimpleWorkspaceContextService.SCHEME, authority: 'model', path: '/' }); - this.workspace = { id: '4064f6ec-cb38-4ad0-af64-ee6467e63c82', folders: [new WorkspaceFolder({ uri: resource, name: '', index: 0 })], name: resource.fsPath }; + this.workspace = { id: '4064f6ec-cb38-4ad0-af64-ee6467e63c82', folders: [new WorkspaceFolder({ uri: resource, name: '', index: 0 })] }; } public getWorkspace(): IWorkspace { @@ -609,8 +609,8 @@ export class SimpleUriLabelService implements IUriLabelService { return resource.path; } - public getWorkspaceLabel(workspace: IWorkspaceIdentifier | URI, options?: { verbose: boolean; }): string { - throw new Error('Not implemented'); + public getWorkspaceLabel(workspace: IWorkspaceIdentifier | URI | IWorkspace, options?: { verbose: boolean; }): string { + return ''; } public registerFormater(schema: string, formater: UriLabelRules): IDisposable { diff --git a/src/vs/platform/uriLabel/common/uriLabel.ts b/src/vs/platform/uriLabel/common/uriLabel.ts index f59ae2cb4b0..f676d7582ea 100644 --- a/src/vs/platform/uriLabel/common/uriLabel.ts +++ b/src/vs/platform/uriLabel/common/uriLabel.ts @@ -7,13 +7,13 @@ import URI from 'vs/base/common/uri'; import { IDisposable } from 'vs/base/common/lifecycle'; import { Event, Emitter } from 'vs/base/common/event'; import { IEnvironmentService } from 'vs/platform/environment/common/environment'; -import { IWorkspaceContextService } from 'vs/platform/workspace/common/workspace'; +import { IWorkspaceContextService, IWorkspace } from 'vs/platform/workspace/common/workspace'; import { createDecorator } from 'vs/platform/instantiation/common/instantiation'; import { isEqual, basenameOrAuthority } from 'vs/base/common/resources'; import { isLinux, isWindows } from 'vs/base/common/platform'; import { tildify, getPathLabel } from 'vs/base/common/labels'; import { ltrim } from 'vs/base/common/strings'; -import { IWorkspaceIdentifier, ISingleFolderWorkspaceIdentifier, isSingleFolderWorkspaceIdentifier, WORKSPACE_EXTENSION } from 'vs/platform/workspaces/common/workspaces'; +import { IWorkspaceIdentifier, ISingleFolderWorkspaceIdentifier, isSingleFolderWorkspaceIdentifier, WORKSPACE_EXTENSION, toWorkspaceIdentifier, isWorkspaceIdentifier } from 'vs/platform/workspaces/common/workspaces'; import { localize } from 'vs/nls'; import { isParent } from 'vs/platform/files/common/files'; import { basename, dirname, join } from 'vs/base/common/paths'; @@ -21,7 +21,7 @@ import { basename, dirname, join } from 'vs/base/common/paths'; export interface IUriLabelService { _serviceBrand: any; getLabel(resource: URI, relative?: boolean, forceNoTildify?: boolean): string; - getWorkspaceLabel(workspace: (IWorkspaceIdentifier | ISingleFolderWorkspaceIdentifier), options?: { verbose: boolean }): string; + getWorkspaceLabel(workspace: (IWorkspaceIdentifier | ISingleFolderWorkspaceIdentifier | IWorkspace), options?: { verbose: boolean }): string; registerFormater(schema: string, formater: UriLabelRules): IDisposable; onDidRegisterFormater: Event<{ scheme: string, formater: UriLabelRules }>; } @@ -46,20 +46,16 @@ export class UriLabelService implements IUriLabelService { private readonly formaters = new Map<string, UriLabelRules>(); private readonly _onDidRegisterFormater = new Emitter<{ scheme: string, formater: UriLabelRules }>(); - private contextService: IWorkspaceContextService; constructor( @IEnvironmentService private environmentService: IEnvironmentService, + @IWorkspaceContextService private contextService: IWorkspaceContextService ) { } get onDidRegisterFormater(): Event<{ scheme: string, formater: UriLabelRules }> { return this._onDidRegisterFormater.event; } - acquireContextService(contextService: IWorkspaceContextService): void { - this.contextService = contextService; - } - getLabel(resource: URI, relative?: boolean, forceNoTildify?: boolean): string { if (!resource) { return undefined; @@ -93,7 +89,14 @@ export class UriLabelService implements IUriLabelService { return this.formatUri(resource, formater, forceNoTildify); } - getWorkspaceLabel(workspace: (IWorkspaceIdentifier | ISingleFolderWorkspaceIdentifier), options?: { verbose: boolean }): string { + getWorkspaceLabel(workspace: (IWorkspaceIdentifier | ISingleFolderWorkspaceIdentifier | IWorkspace), options?: { verbose: boolean }): string { + if (!isWorkspaceIdentifier(workspace) && !isSingleFolderWorkspaceIdentifier(workspace)) { + workspace = toWorkspaceIdentifier(workspace); + if (!workspace) { + return ''; + } + } + // Workspace: Single Folder if (isSingleFolderWorkspaceIdentifier(workspace)) { // Folder on disk @@ -106,6 +109,7 @@ export class UriLabelService implements IUriLabelService { } // Workspace: Saved + console.log(workspace.configPath); const filename = basename(workspace.configPath); const workspaceName = filename.substr(0, filename.length - WORKSPACE_EXTENSION.length - 1); if (options && options.verbose) { diff --git a/src/vs/platform/uriLabel/test/uriLabel.test.ts b/src/vs/platform/uriLabel/test/uriLabel.test.ts index 4c82a0d0eaf..6efc8d528e9 100644 --- a/src/vs/platform/uriLabel/test/uriLabel.test.ts +++ b/src/vs/platform/uriLabel/test/uriLabel.test.ts @@ -17,8 +17,7 @@ suite('URI Label', () => { let uriLabelService: UriLabelService; setup(() => { - uriLabelService = new UriLabelService(TestEnvironmentService); - uriLabelService.acquireContextService(new TestContextService()); + uriLabelService = new UriLabelService(TestEnvironmentService, new TestContextService()); }); test('file scheme', function () { diff --git a/src/vs/platform/workspace/common/workspace.ts b/src/vs/platform/workspace/common/workspace.ts index 35d10686eb3..dcb2ca53a05 100644 --- a/src/vs/platform/workspace/common/workspace.ts +++ b/src/vs/platform/workspace/common/workspace.ts @@ -81,7 +81,6 @@ export namespace IWorkspace { export function isIWorkspace(thing: any): thing is IWorkspace { return thing && typeof thing === 'object' && typeof (thing as IWorkspace).id === 'string' - && typeof (thing as IWorkspace).name === 'string' && Array.isArray((thing as IWorkspace).folders); } } @@ -93,11 +92,6 @@ export interface IWorkspace { */ readonly id: string; - /** - * the name of the workspace. - */ - readonly name: string; - /** * Folders in the workspace. */ @@ -151,7 +145,6 @@ export class Workspace implements IWorkspace { constructor( private _id: string, - private _name: string = '', folders: WorkspaceFolder[] = [], private _configuration: URI = null, private _ctime?: number @@ -161,7 +154,6 @@ export class Workspace implements IWorkspace { update(workspace: Workspace) { this._id = workspace.id; - this._name = workspace.name; this._configuration = workspace.configuration; this._ctime = workspace.ctime; this.folders = workspace.folders; @@ -184,14 +176,6 @@ export class Workspace implements IWorkspace { return this._ctime; } - get name(): string { - return this._name; - } - - set name(name: string) { - this._name = name; - } - get configuration(): URI { return this._configuration; } @@ -216,7 +200,7 @@ export class Workspace implements IWorkspace { } toJSON(): IWorkspace { - return { id: this.id, folders: this.folders, name: this.name, configuration: this.configuration }; + return { id: this.id, folders: this.folders, configuration: this.configuration }; } } diff --git a/src/vs/platform/workspace/test/common/testWorkspace.ts b/src/vs/platform/workspace/test/common/testWorkspace.ts index 6a204873e0c..2fa9cd57e6e 100644 --- a/src/vs/platform/workspace/test/common/testWorkspace.ts +++ b/src/vs/platform/workspace/test/common/testWorkspace.ts @@ -13,7 +13,6 @@ export const TestWorkspace = testWorkspace(wsUri); export function testWorkspace(resource: URI): Workspace { return new Workspace( resource.toString(), - resource.fsPath, toWorkspaceFolders([{ path: resource.fsPath }]) ); -} \ No newline at end of file +} diff --git a/src/vs/platform/workspace/test/common/workspace.test.ts b/src/vs/platform/workspace/test/common/workspace.test.ts index ac6f0caf17f..58f24f3f4e4 100644 --- a/src/vs/platform/workspace/test/common/workspace.test.ts +++ b/src/vs/platform/workspace/test/common/workspace.test.ts @@ -14,7 +14,7 @@ suite('Workspace', () => { test('getFolder returns the folder with given uri', () => { const expected = new WorkspaceFolder({ uri: URI.file('/src/test'), name: '', index: 2 }); - let testObject = new Workspace('', '', [new WorkspaceFolder({ uri: URI.file('/src/main'), name: '', index: 0 }), expected, new WorkspaceFolder({ uri: URI.file('/src/code'), name: '', index: 2 })]); + let testObject = new Workspace('', [new WorkspaceFolder({ uri: URI.file('/src/main'), name: '', index: 0 }), expected, new WorkspaceFolder({ uri: URI.file('/src/code'), name: '', index: 2 })]); const actual = testObject.getFolder(expected.uri); @@ -23,7 +23,7 @@ suite('Workspace', () => { test('getFolder returns the folder if the uri is sub', () => { const expected = new WorkspaceFolder({ uri: URI.file('/src/test'), name: '', index: 0 }); - let testObject = new Workspace('', '', [expected, new WorkspaceFolder({ uri: URI.file('/src/main'), name: '', index: 1 }), new WorkspaceFolder({ uri: URI.file('/src/code'), name: '', index: 2 })]); + let testObject = new Workspace('', [expected, new WorkspaceFolder({ uri: URI.file('/src/main'), name: '', index: 1 }), new WorkspaceFolder({ uri: URI.file('/src/code'), name: '', index: 2 })]); const actual = testObject.getFolder(URI.file('/src/test/a')); @@ -32,7 +32,7 @@ suite('Workspace', () => { test('getFolder returns the closest folder if the uri is sub', () => { const expected = new WorkspaceFolder({ uri: URI.file('/src/test'), name: '', index: 2 }); - let testObject = new Workspace('', '', [new WorkspaceFolder({ uri: URI.file('/src/main'), name: '', index: 0 }), new WorkspaceFolder({ uri: URI.file('/src/code'), name: '', index: 1 }), expected]); + let testObject = new Workspace('', [new WorkspaceFolder({ uri: URI.file('/src/main'), name: '', index: 0 }), new WorkspaceFolder({ uri: URI.file('/src/code'), name: '', index: 1 }), expected]); const actual = testObject.getFolder(URI.file('/src/test/a')); @@ -40,7 +40,7 @@ suite('Workspace', () => { }); test('getFolder returns null if the uri is not sub', () => { - let testObject = new Workspace('', '', [new WorkspaceFolder({ uri: URI.file('/src/test'), name: '', index: 0 }), new WorkspaceFolder({ uri: URI.file('/src/code'), name: '', index: 1 })]); + let testObject = new Workspace('', [new WorkspaceFolder({ uri: URI.file('/src/test'), name: '', index: 0 }), new WorkspaceFolder({ uri: URI.file('/src/code'), name: '', index: 1 })]); const actual = testObject.getFolder(URI.file('/src/main/a')); diff --git a/src/vs/workbench/api/electron-browser/mainThreadWorkspace.ts b/src/vs/workbench/api/electron-browser/mainThreadWorkspace.ts index e797ba2ba0b..03f782d04e2 100644 --- a/src/vs/workbench/api/electron-browser/mainThreadWorkspace.ts +++ b/src/vs/workbench/api/electron-browser/mainThreadWorkspace.ts @@ -23,6 +23,7 @@ import { CommandsRegistry } from 'vs/platform/commands/common/commands'; import { IExtensionService } from 'vs/workbench/services/extensions/common/extensions'; import { areSameExtensions } from 'vs/platform/extensionManagement/common/extensionManagementUtil'; import { IWindowService } from 'vs/platform/windows/common/windows'; +import { IUriLabelService } from 'vs/platform/uriLabel/common/uriLabel'; @extHostNamedCustomer(MainContext.MainThreadWorkspace) export class MainThreadWorkspace implements MainThreadWorkspaceShape { @@ -40,6 +41,7 @@ export class MainThreadWorkspace implements MainThreadWorkspaceShape { @IWorkspaceEditingService private readonly _workspaceEditingService: IWorkspaceEditingService, @IStatusbarService private readonly _statusbarService: IStatusbarService, @IInstantiationService private readonly _instantiationService: IInstantiationService, + @IUriLabelService private readonly _uriLabelService: IUriLabelService ) { this._proxy = extHostContext.getProxy(ExtHostContext.ExtHostWorkspace); this._contextService.onDidChangeWorkspaceFolders(this._onDidChangeWorkspace, this, this._toDispose); @@ -99,7 +101,13 @@ export class MainThreadWorkspace implements MainThreadWorkspaceShape { } private _onDidChangeWorkspace(): void { - this._proxy.$acceptWorkspaceData(this._contextService.getWorkbenchState() === WorkbenchState.EMPTY ? null : this._contextService.getWorkspace()); + const workspace = this._contextService.getWorkbenchState() === WorkbenchState.EMPTY ? null : this._contextService.getWorkspace(); + this._proxy.$acceptWorkspaceData(workspace ? { + configuration: workspace.configuration, + folders: workspace.folders, + id: workspace.id, + name: this._uriLabelService.getWorkspaceLabel(workspace) + } : null); } // --- search --- @@ -230,4 +238,4 @@ CommandsRegistry.registerCommand('_workbench.enterWorkspace', async function (ac } return workspaceEditingService.enterWorkspace(workspace.fsPath); -}); \ No newline at end of file +}); diff --git a/src/vs/workbench/api/node/extHost.api.impl.ts b/src/vs/workbench/api/node/extHost.api.impl.ts index 8bf889401c0..59aced91890 100644 --- a/src/vs/workbench/api/node/extHost.api.impl.ts +++ b/src/vs/workbench/api/node/extHost.api.impl.ts @@ -485,7 +485,7 @@ export function createApiFactory( return extHostWorkspace.getWorkspaceFolders(); }, get name() { - return extHostWorkspace.workspace ? extHostWorkspace.workspace.name : undefined; + return extHostWorkspace.name; }, set name(value) { throw errors.readonly(); diff --git a/src/vs/workbench/api/node/extHostWorkspace.ts b/src/vs/workbench/api/node/extHostWorkspace.ts index 56e9d91c15c..e15ee1d920e 100644 --- a/src/vs/workbench/api/node/extHostWorkspace.ts +++ b/src/vs/workbench/api/node/extHostWorkspace.ts @@ -107,8 +107,8 @@ class ExtHostWorkspaceImpl extends Workspace { private readonly _workspaceFolders: vscode.WorkspaceFolder[] = []; private readonly _structure = TernarySearchTree.forPaths<vscode.WorkspaceFolder>(); - private constructor(id: string, name: string, folders: vscode.WorkspaceFolder[]) { - super(id, name, folders.map(f => new WorkspaceFolder(f))); + private constructor(id: string, private _name: string, folders: vscode.WorkspaceFolder[]) { + super(id, folders.map(f => new WorkspaceFolder(f))); // setup the workspace folder data structure folders.forEach(folder => { @@ -117,6 +117,10 @@ class ExtHostWorkspaceImpl extends Workspace { }); } + get name(): string { + return this._name; + } + get workspaceFolders(): vscode.WorkspaceFolder[] { return this._workspaceFolders.slice(0); } @@ -166,6 +170,10 @@ export class ExtHostWorkspace implements ExtHostWorkspaceShape { return this._actualWorkspace; } + get name(): string { + return this._actualWorkspace ? this._actualWorkspace.name : undefined; + } + private get _actualWorkspace(): ExtHostWorkspaceImpl { return this._unconfirmedWorkspace || this._confirmedWorkspace; } diff --git a/src/vs/workbench/browser/parts/titlebar/titlebarPart.ts b/src/vs/workbench/browser/parts/titlebar/titlebarPart.ts index 9a4bc78f8bf..597f47f2881 100644 --- a/src/vs/workbench/browser/parts/titlebar/titlebarPart.ts +++ b/src/vs/workbench/browser/parts/titlebar/titlebarPart.ts @@ -243,7 +243,7 @@ export class TitlebarPart extends Part implements ITitleService { const activeEditorShort = editor ? editor.getTitle(Verbosity.SHORT) : ''; const activeEditorMedium = editor ? editor.getTitle(Verbosity.MEDIUM) : activeEditorShort; const activeEditorLong = editor ? editor.getTitle(Verbosity.LONG) : activeEditorMedium; - const rootName = workspace.name; + const rootName = root ? this.uriLabelService.getWorkspaceLabel(root) : ''; const rootPath = root ? this.uriLabelService.getLabel(root) : ''; const folderName = folder ? folder.name : ''; const folderPath = folder ? this.uriLabelService.getLabel(folder.uri) : ''; diff --git a/src/vs/workbench/electron-browser/main.ts b/src/vs/workbench/electron-browser/main.ts index 43fe84321a2..08edc11b168 100644 --- a/src/vs/workbench/electron-browser/main.ts +++ b/src/vs/workbench/electron-browser/main.ts @@ -48,7 +48,6 @@ import { RelayURLService } from 'vs/platform/url/common/urlService'; import { MenubarChannelClient } from 'vs/platform/menubar/node/menubarIpc'; import { IMenubarService } from 'vs/platform/menubar/common/menubar'; import { Schemas } from 'vs/base/common/network'; -import { IUriLabelService, UriLabelService } from 'vs/platform/uriLabel/common/uriLabel'; gracefulFs.gracefulify(fs); // enable gracefulFs @@ -99,15 +98,13 @@ function openWorkbench(configuration: IWindowConfiguration): TPromise<void> { const mainServices = createMainProcessServices(mainProcessClient, configuration); const environmentService = new EnvironmentService(configuration, configuration.execPath); - const uriLabelService = new UriLabelService(environmentService); const logService = createLogService(mainProcessClient, configuration, environmentService); logService.trace('openWorkbench configuration', JSON.stringify(configuration)); // Since the configuration service is one of the core services that is used in so many places, we initialize it // right before startup of the workbench shell to have its data ready for consumers - return createAndInitializeWorkspaceService(configuration, environmentService, uriLabelService).then(workspaceService => { + return createAndInitializeWorkspaceService(configuration, environmentService).then(workspaceService => { const storageService = createStorageService(workspaceService, environmentService); - uriLabelService.acquireContextService(workspaceService); return domContentLoaded().then(() => { @@ -118,8 +115,7 @@ function openWorkbench(configuration: IWindowConfiguration): TPromise<void> { configurationService: workspaceService, environmentService, logService, - storageService, - uriLabelService + storageService }, mainServices, mainProcessClient, configuration); shell.open(); @@ -135,10 +131,10 @@ function openWorkbench(configuration: IWindowConfiguration): TPromise<void> { }); } -function createAndInitializeWorkspaceService(configuration: IWindowConfiguration, environmentService: EnvironmentService, uriLabelService: IUriLabelService): TPromise<WorkspaceService> { +function createAndInitializeWorkspaceService(configuration: IWindowConfiguration, environmentService: EnvironmentService): TPromise<WorkspaceService> { return validateFolderUri(configuration.folderUri, configuration.verbose).then(validatedFolderUri => { - const workspaceService = new WorkspaceService(environmentService, uriLabelService); + const workspaceService = new WorkspaceService(environmentService); return workspaceService.initialize(configuration.workspace || validatedFolderUri || configuration).then(() => workspaceService, error => workspaceService); }); diff --git a/src/vs/workbench/electron-browser/shell.ts b/src/vs/workbench/electron-browser/shell.ts index 594153f133d..4b366a0299c 100644 --- a/src/vs/workbench/electron-browser/shell.ts +++ b/src/vs/workbench/electron-browser/shell.ts @@ -109,7 +109,6 @@ export interface ICoreServices { environmentService: IEnvironmentService; logService: ILogService; storageService: IStorageService; - uriLabelService: IUriLabelService; } /** @@ -148,7 +147,6 @@ export class WorkbenchShell extends Disposable { this.contextService = coreServices.contextService; this.configurationService = coreServices.configurationService; this.environmentService = coreServices.environmentService; - this.uriLabelService = coreServices.uriLabelService; this.logService = coreServices.logService; this.storageService = coreServices.storageService; diff --git a/src/vs/workbench/electron-browser/workbench.ts b/src/vs/workbench/electron-browser/workbench.ts index 51f863b673a..851611cc3b3 100644 --- a/src/vs/workbench/electron-browser/workbench.ts +++ b/src/vs/workbench/electron-browser/workbench.ts @@ -116,6 +116,7 @@ import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry'; import { TelemetryService } from 'vs/platform/telemetry/common/telemetryService'; import { WorkbenchThemeService } from 'vs/workbench/services/themes/electron-browser/workbenchThemeService'; import { IWorkbenchThemeService } from 'vs/workbench/services/themes/common/workbenchThemeService'; +import { UriLabelService, IUriLabelService } from 'vs/platform/uriLabel/common/uriLabel'; interface WorkbenchParams { configuration: IWindowConfiguration; @@ -335,6 +336,10 @@ export class Workbench extends Disposable implements IPartService { // Clipboard serviceCollection.set(IClipboardService, new ClipboardService()); + // Uri Display + const uriLabelService = new UriLabelService(this.environmentService, this.contextService); + serviceCollection.set(IUriLabelService, uriLabelService); + // Status bar this.statusbarPart = this.instantiationService.createInstance(StatusbarPart, Identifiers.STATUSBAR_PART); this._register(toDisposable(() => this.statusbarPart.shutdown())); diff --git a/src/vs/workbench/parts/files/electron-browser/views/emptyView.ts b/src/vs/workbench/parts/files/electron-browser/views/emptyView.ts index f7ab5bd7f54..46326cd24ee 100644 --- a/src/vs/workbench/parts/files/electron-browser/views/emptyView.ts +++ b/src/vs/workbench/parts/files/electron-browser/views/emptyView.ts @@ -103,7 +103,7 @@ export class EmptyView extends ViewletPanel { if (this.button) { this.button.label = nls.localize('addFolder', "Add Folder"); } - this.titleDiv.text(this.contextService.getWorkspace().name); + this.titleDiv.text(EmptyView.NAME); } else { this.messageDiv.text(nls.localize('noFolderHelp', "You have not yet opened a folder.")); if (this.button) { diff --git a/src/vs/workbench/parts/files/electron-browser/views/explorerView.ts b/src/vs/workbench/parts/files/electron-browser/views/explorerView.ts index 09e0a417b5f..59f058f4c0b 100644 --- a/src/vs/workbench/parts/files/electron-browser/views/explorerView.ts +++ b/src/vs/workbench/parts/files/electron-browser/views/explorerView.ts @@ -43,6 +43,7 @@ import { Schemas } from 'vs/base/common/network'; import { INotificationService } from 'vs/platform/notification/common/notification'; import { IEditorService } from 'vs/workbench/services/editor/common/editorService'; import { IViewletPanelOptions } from 'vs/workbench/browser/parts/views/panelViewlet'; +import { IUriLabelService } from 'vs/platform/uriLabel/common/uriLabel'; export interface IExplorerViewOptions extends IViewletViewOptions { viewletState: FileViewletState; @@ -94,7 +95,8 @@ export class ExplorerView extends TreeViewsViewletPanel implements IExplorerView @IKeybindingService keybindingService: IKeybindingService, @IContextKeyService contextKeyService: IContextKeyService, @IConfigurationService configurationService: IConfigurationService, - @IDecorationsService decorationService: IDecorationsService + @IDecorationsService decorationService: IDecorationsService, + @IUriLabelService private uriLabelService: IUriLabelService ) { super({ ...(options as IViewletPanelOptions), ariaHeaderLabel: nls.localize('explorerSection', "Files Explorer Section") }, keybindingService, contextMenuService, configurationService); @@ -147,7 +149,7 @@ export class ExplorerView extends TreeViewsViewletPanel implements IExplorerView } public get name(): string { - return this.contextService.getWorkspace().name; + return this.uriLabelService.getWorkspaceLabel(this.contextService.getWorkspace()); } public get title(): string { diff --git a/src/vs/workbench/parts/logs/electron-browser/logsActions.ts b/src/vs/workbench/parts/logs/electron-browser/logsActions.ts index e9695b3cde0..0920a329064 100644 --- a/src/vs/workbench/parts/logs/electron-browser/logsActions.ts +++ b/src/vs/workbench/parts/logs/electron-browser/logsActions.ts @@ -16,6 +16,7 @@ import { ICommandService } from 'vs/platform/commands/common/commands'; import URI from 'vs/base/common/uri'; import { IWorkspaceContextService } from 'vs/platform/workspace/common/workspace'; import { IQuickPickItem, IQuickInputService } from 'vs/platform/quickinput/common/quickInput'; +import { IUriLabelService } from 'vs/platform/uriLabel/common/uriLabel'; export class OpenLogsFolderAction extends Action { @@ -42,14 +43,16 @@ export class ShowLogsAction extends Action { constructor(id: string, label: string, @IQuickInputService private quickInputService: IQuickInputService, @IOutputService private outputService: IOutputService, - @IWorkspaceContextService private contextService: IWorkspaceContextService + @IWorkspaceContextService private contextService: IWorkspaceContextService, + @IUriLabelService private uriLabelService: IUriLabelService ) { super(id, label); } run(): TPromise<void> { + const workspaceName = this.uriLabelService.getWorkspaceLabel(this.contextService.getWorkspace()); const entries: IQuickPickItem[] = [ - { id: Constants.rendererLogChannelId, label: this.contextService.getWorkspace().name ? nls.localize('rendererProcess', "Window ({0})", this.contextService.getWorkspace().name) : nls.localize('emptyWindow', "Window") }, + { id: Constants.rendererLogChannelId, label: workspaceName ? nls.localize('rendererProcess', "Window ({0})", workspaceName) : nls.localize('emptyWindow', "Window") }, { id: Constants.extHostLogChannelId, label: nls.localize('extensionHost', "Extension Host") }, { id: Constants.sharedLogChannelId, label: nls.localize('sharedProcess', "Shared") }, { id: Constants.mainLogChannelId, label: nls.localize('mainProcess', "Main") } @@ -75,14 +78,16 @@ export class OpenLogFileAction extends Action { @IEnvironmentService private environmentService: IEnvironmentService, @ICommandService private commandService: ICommandService, @IWindowService private windowService: IWindowService, - @IWorkspaceContextService private contextService: IWorkspaceContextService + @IWorkspaceContextService private contextService: IWorkspaceContextService, + @IUriLabelService private uriLabelService: IUriLabelService ) { super(id, label); } run(): TPromise<void> { + const workspaceName = this.uriLabelService.getWorkspaceLabel(this.contextService.getWorkspace()); const entries: IQuickPickItem[] = [ - { id: URI.file(paths.join(this.environmentService.logsPath, `renderer${this.windowService.getCurrentWindowId()}.log`)).fsPath, label: this.contextService.getWorkspace().name ? nls.localize('rendererProcess', "Window ({0})", this.contextService.getWorkspace().name) : nls.localize('emptyWindow', "Window") }, + { id: URI.file(paths.join(this.environmentService.logsPath, `renderer${this.windowService.getCurrentWindowId()}.log`)).fsPath, label: workspaceName ? nls.localize('rendererProcess', "Window ({0})", workspaceName) : nls.localize('emptyWindow', "Window") }, { id: URI.file(paths.join(this.environmentService.logsPath, `exthost${this.windowService.getCurrentWindowId()}.log`)).fsPath, label: nls.localize('extensionHost', "Extension Host") }, { id: URI.file(paths.join(this.environmentService.logsPath, `sharedprocess.log`)).fsPath, label: nls.localize('sharedProcess', "Shared") }, { id: URI.file(paths.join(this.environmentService.logsPath, `main.log`)).fsPath, label: nls.localize('mainProcess', "Main") }, @@ -142,4 +147,4 @@ export class SetLogLevelAction extends Action { } return void 0; } -} \ No newline at end of file +} diff --git a/src/vs/workbench/parts/search/test/common/queryBuilder.test.ts b/src/vs/workbench/parts/search/test/common/queryBuilder.test.ts index 4ac216e7e23..82ef9f6b2fa 100644 --- a/src/vs/workbench/parts/search/test/common/queryBuilder.test.ts +++ b/src/vs/workbench/parts/search/test/common/queryBuilder.test.ts @@ -41,7 +41,7 @@ suite('QueryBuilder', () => { instantiationService.stub(IConfigurationService, mockConfigService); mockContextService = new TestContextService(); - mockWorkspace = new Workspace('workspace', 'workspace', toWorkspaceFolders([{ path: ROOT_1_URI.fsPath }])); + mockWorkspace = new Workspace('workspace', toWorkspaceFolders([{ path: ROOT_1_URI.fsPath }])); mockContextService.setWorkspace(mockWorkspace); instantiationService.stub(IWorkspaceContextService, mockContextService); diff --git a/src/vs/workbench/services/backup/test/electron-browser/backupFileService.test.ts b/src/vs/workbench/services/backup/test/electron-browser/backupFileService.test.ts index 3af98297733..8148609ee53 100644 --- a/src/vs/workbench/services/backup/test/electron-browser/backupFileService.test.ts +++ b/src/vs/workbench/services/backup/test/electron-browser/backupFileService.test.ts @@ -39,7 +39,7 @@ const untitledBackupPath = path.join(workspaceBackupPath, 'untitled', crypto.cre class TestBackupFileService extends BackupFileService { constructor(workspace: Uri, backupHome: string, workspacesJsonPath: string) { - const fileService = new FileService(new TestContextService(new Workspace(workspace.fsPath, workspace.fsPath, toWorkspaceFolders([{ path: workspace.fsPath }]))), TestEnvironmentService, new TestTextResourceConfigurationService(), new TestConfigurationService(), new TestLifecycleService(), new TestStorageService(), new TestNotificationService(), { disableWatcher: true }); + const fileService = new FileService(new TestContextService(new Workspace(workspace.fsPath, toWorkspaceFolders([{ path: workspace.fsPath }]))), TestEnvironmentService, new TestTextResourceConfigurationService(), new TestConfigurationService(), new TestLifecycleService(), new TestStorageService(), new TestNotificationService(), { disableWatcher: true }); super(workspaceBackupPath, fileService); } diff --git a/src/vs/workbench/services/configuration/node/configurationService.ts b/src/vs/workbench/services/configuration/node/configurationService.ts index 340c8499127..2576c9e4cfc 100644 --- a/src/vs/workbench/services/configuration/node/configurationService.ts +++ b/src/vs/workbench/services/configuration/node/configurationService.ts @@ -41,7 +41,6 @@ import { UserConfiguration } from 'vs/platform/configuration/node/configuration' import { IJSONSchema, IJSONSchemaMap } from 'vs/base/common/jsonSchema'; import { localize } from 'vs/nls'; import { isEqual } from 'vs/base/common/resources'; -import { IUriLabelService } from 'vs/platform/uriLabel/common/uriLabel'; export class WorkspaceService extends Disposable implements IWorkspaceConfigurationService, IWorkspaceContextService { @@ -72,7 +71,7 @@ export class WorkspaceService extends Disposable implements IWorkspaceConfigurat private configurationEditingService: ConfigurationEditingService; private jsonEditingService: JSONEditingService; - constructor(private environmentService: IEnvironmentService, private uriLabelService: IUriLabelService, private workspaceSettingsRootFolder: string = FOLDER_CONFIG_FOLDER_NAME) { + constructor(private environmentService: IEnvironmentService, private workspaceSettingsRootFolder: string = FOLDER_CONFIG_FOLDER_NAME) { super(); this.defaultConfiguration = new DefaultConfigurationModel(); @@ -341,8 +340,7 @@ export class WorkspaceService extends Disposable implements IWorkspaceConfigurat .then(() => { const workspaceFolders = toWorkspaceFolders(this.workspaceConfiguration.getFolders(), URI.file(dirname(workspaceConfigPath.fsPath))); const workspaceId = workspaceIdentifier.id; - const workspaceName = this.uriLabelService.getWorkspaceLabel({ id: workspaceId, configPath: workspaceConfigPath.fsPath }); - return new Workspace(workspaceId, workspaceName, workspaceFolders, workspaceConfigPath); + return new Workspace(workspaceId, workspaceFolders, workspaceConfigPath); }); } @@ -364,11 +362,11 @@ export class WorkspaceService extends Disposable implements IWorkspaceConfigurat } const id = createHash('md5').update(folder.fsPath).update(ctime ? String(ctime) : '').digest('hex'); - return new Workspace(id, this.uriLabelService.getWorkspaceLabel(folder), toWorkspaceFolders([{ path: folder.fsPath }]), null, ctime); + return new Workspace(id, toWorkspaceFolders([{ path: folder.fsPath }]), null, ctime); }); } else { const id = createHash('md5').update(folder.toString()).digest('hex'); - return TPromise.as(new Workspace(id, this.uriLabelService.getWorkspaceLabel(folder), toWorkspaceFolders([{ uri: folder.toString() }]), null)); + return TPromise.as(new Workspace(id, toWorkspaceFolders([{ uri: folder.toString() }]), null)); } } diff --git a/src/vs/workbench/services/configuration/test/common/configurationModels.test.ts b/src/vs/workbench/services/configuration/test/common/configurationModels.test.ts index ec8107bed48..b9fb772b270 100644 --- a/src/vs/workbench/services/configuration/test/common/configurationModels.test.ts +++ b/src/vs/workbench/services/configuration/test/common/configurationModels.test.ts @@ -115,7 +115,7 @@ suite('WorkspaceConfigurationChangeEvent', () => { configurationChangeEvent.change(['window.restoreWindows'], URI.file('folder2')); configurationChangeEvent.telemetryData(ConfigurationTarget.WORKSPACE, {}); - let testObject = new WorkspaceConfigurationChangeEvent(configurationChangeEvent, new Workspace('id', 'name', + let testObject = new WorkspaceConfigurationChangeEvent(configurationChangeEvent, new Workspace('id', [new WorkspaceFolder({ index: 0, name: '1', uri: URI.file('folder1') }), new WorkspaceFolder({ index: 1, name: '2', uri: URI.file('folder2') }), new WorkspaceFolder({ index: 2, name: '3', uri: URI.file('folder3') })])); 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 f201f562127..a6ab72cead7 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 { INotificationService } from 'vs/platform/notification/common/notificati import { ICommandService } from 'vs/platform/commands/common/commands'; import { CommandService } from 'vs/workbench/services/commands/common/commandService'; import URI from 'vs/base/common/uri'; -import { UriLabelService } from 'vs/platform/uriLabel/common/uriLabel'; class SettingsTestEnvironmentService extends EnvironmentService { @@ -103,7 +102,7 @@ suite('ConfigurationEditingService', () => { instantiationService = <TestInstantiationService>workbenchInstantiationService(); const environmentService = new SettingsTestEnvironmentService(parseArgs(process.argv), process.execPath, globalSettingsFile); instantiationService.stub(IEnvironmentService, environmentService); - const workspaceService = new WorkspaceService(environmentService, new UriLabelService(environmentService)); + const workspaceService = new WorkspaceService(environmentService); instantiationService.stub(IWorkspaceContextService, workspaceService); return workspaceService.initialize(noWorkspace ? {} as IWindowConfiguration : URI.file(workspaceDir)).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 d4bc36c32d6..64e9352f99a 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 @@ -35,7 +35,6 @@ import { IJSONEditingService } from 'vs/workbench/services/configuration/common/ import { JSONEditingService } from 'vs/workbench/services/configuration/node/jsonEditingService'; import { IWorkspaceConfigurationService } from 'vs/workbench/services/configuration/common/configuration'; import { IWindowConfiguration } from 'vs/platform/windows/common/windows'; -import { UriLabelService } from 'vs/platform/uriLabel/common/uriLabel'; class SettingsTestEnvironmentService extends EnvironmentService { @@ -87,8 +86,7 @@ suite('WorkspaceContextService - Folder', () => { workspaceResource = folderDir; const globalSettingsFile = path.join(parentDir, 'settings.json'); const environmentService = new SettingsTestEnvironmentService(parseArgs(process.argv), process.execPath, globalSettingsFile); - const uriLabelService = new UriLabelService(environmentService); - workspaceContextService = new WorkspaceService(environmentService, uriLabelService); + workspaceContextService = new WorkspaceService(environmentService); return (<WorkspaceService>workspaceContextService).initialize(URI.file(folderDir)); }); }); @@ -145,8 +143,7 @@ suite('WorkspaceContextService - Workspace', () => { parentResource = parentDir; const environmentService = new SettingsTestEnvironmentService(parseArgs(process.argv), process.execPath, path.join(parentDir, 'settings.json')); - const uriLabelService = new UriLabelService(environmentService); - const workspaceService = new WorkspaceService(environmentService, uriLabelService); + const workspaceService = new WorkspaceService(environmentService); const instantiationService = <TestInstantiationService>workbenchInstantiationService(); instantiationService.stub(IWorkspaceContextService, workspaceService); @@ -409,8 +406,7 @@ suite('WorkspaceService - Initialization', () => { const instantiationService = <TestInstantiationService>workbenchInstantiationService(); const environmentService = new SettingsTestEnvironmentService(parseArgs(process.argv), process.execPath, globalSettingsFile); - const uriLabelService = new UriLabelService(environmentService); - const workspaceService = new WorkspaceService(environmentService, uriLabelService); + const workspaceService = new WorkspaceService(environmentService); instantiationService.stub(IWorkspaceContextService, workspaceService); instantiationService.stub(IConfigurationService, workspaceService); instantiationService.stub(IEnvironmentService, environmentService); @@ -665,8 +661,7 @@ suite('WorkspaceConfigurationService - Folder', () => { const instantiationService = <TestInstantiationService>workbenchInstantiationService(); const environmentService = new SettingsTestEnvironmentService(parseArgs(process.argv), process.execPath, globalSettingsFile); - const uriLabelService = new UriLabelService(environmentService); - const workspaceService = new WorkspaceService(environmentService, uriLabelService); + const workspaceService = new WorkspaceService(environmentService); instantiationService.stub(IWorkspaceContextService, workspaceService); instantiationService.stub(IConfigurationService, workspaceService); instantiationService.stub(IEnvironmentService, environmentService); @@ -941,8 +936,7 @@ suite('WorkspaceConfigurationService-Multiroot', () => { parentResource = parentDir; environmentService = new SettingsTestEnvironmentService(parseArgs(process.argv), process.execPath, path.join(parentDir, 'settings.json')); - const uriLabelService = new UriLabelService(environmentService); - const workspaceService = new WorkspaceService(environmentService, uriLabelService); + const workspaceService = new WorkspaceService(environmentService); const instantiationService = <TestInstantiationService>workbenchInstantiationService(); instantiationService.stub(IWorkspaceContextService, workspaceService); diff --git a/src/vs/workbench/services/extensions/electron-browser/extensionHost.ts b/src/vs/workbench/services/extensions/electron-browser/extensionHost.ts index 48e978387d3..d74d74631cc 100644 --- a/src/vs/workbench/services/extensions/electron-browser/extensionHost.ts +++ b/src/vs/workbench/services/extensions/electron-browser/extensionHost.ts @@ -23,7 +23,7 @@ import { IMessagePassingProtocol } from 'vs/base/parts/ipc/node/ipc'; import { generateRandomPipeName, Protocol } from 'vs/base/parts/ipc/node/ipc.net'; import { createServer, Server, Socket } from 'net'; import { Event, Emitter, debounceEvent, mapEvent, anyEvent, fromNodeEventEmitter } from 'vs/base/common/event'; -import { IInitData, IWorkspaceData, IConfigurationInitData } from 'vs/workbench/api/node/extHost.protocol'; +import { IInitData, IConfigurationInitData } from 'vs/workbench/api/node/extHost.protocol'; import { IExtensionDescription } from 'vs/workbench/services/extensions/common/extensions'; import { IWorkspaceConfigurationService } from 'vs/workbench/services/configuration/common/configuration'; import { ICrashReporterService } from 'vs/workbench/services/crashReporter/electron-browser/crashReporterService'; @@ -38,6 +38,7 @@ import { INotificationService, Severity } from 'vs/platform/notification/common/ import { getPathFromAmdModule } from 'vs/base/common/amd'; import { timeout } from 'vs/base/common/async'; import { isMessageOfType, MessageType, createMessageOfType } from 'vs/workbench/common/extensionHostProtocol'; +import { IUriLabelService } from 'vs/platform/uriLabel/common/uriLabel'; export interface IExtensionHostStarter { readonly onCrashed: Event<[number, string]>; @@ -81,7 +82,8 @@ export class ExtensionHostProcessWorker implements IExtensionHostStarter { @IWorkspaceConfigurationService private readonly _configurationService: IWorkspaceConfigurationService, @ITelemetryService private readonly _telemetryService: ITelemetryService, @ICrashReporterService private readonly _crashReporterService: ICrashReporterService, - @ILogService private readonly _logService: ILogService + @ILogService private readonly _logService: ILogService, + @IUriLabelService private readonly _uriLabelService: IUriLabelService ) { // handle extension host lifecycle a bit special when we know we are developing an extension that runs inside this._isExtensionDevHost = this._environmentService.isExtensionDevelopment; @@ -371,6 +373,7 @@ export class ExtensionHostProcessWorker implements IExtensionHostStarter { private _createExtHostInitData(): TPromise<IInitData> { return TPromise.join([this._telemetryService.getTelemetryInfo(), this._extensions]).then(([telemetryInfo, extensionDescriptions]) => { const configurationData: IConfigurationInitData = { ...this._configurationService.getConfigurationData(), configurationScopes: {} }; + const workspace = this._contextService.getWorkspace(); const r: IInitData = { parentPid: process.pid, environment: { @@ -380,7 +383,12 @@ export class ExtensionHostProcessWorker implements IExtensionHostStarter { extensionDevelopmentPath: this._environmentService.extensionDevelopmentPath, extensionTestsPath: this._environmentService.extensionTestsPath }, - workspace: this._contextService.getWorkbenchState() === WorkbenchState.EMPTY ? null : <IWorkspaceData>this._contextService.getWorkspace(), + workspace: this._contextService.getWorkbenchState() === WorkbenchState.EMPTY ? null : { + configuration: workspace.configuration, + folders: workspace.folders, + id: workspace.id, + name: this._uriLabelService.getWorkspaceLabel(workspace) + }, extensions: extensionDescriptions, // Send configurations scopes only in development mode. configuration: !this._environmentService.isBuilt || this._environmentService.isExtensionDevelopment ? { ...configurationData, configurationScopes: getScopes() } : configurationData, diff --git a/src/vs/workbench/services/files/test/electron-browser/fileService.test.ts b/src/vs/workbench/services/files/test/electron-browser/fileService.test.ts index 6d834e52b6a..43e10816ddb 100644 --- a/src/vs/workbench/services/files/test/electron-browser/fileService.test.ts +++ b/src/vs/workbench/services/files/test/electron-browser/fileService.test.ts @@ -37,7 +37,7 @@ suite('FileService', () => { const sourceDir = getPathFromAmdModule(require, './fixtures/service'); return pfs.copy(sourceDir, testDir).then(() => { - service = new FileService(new TestContextService(new Workspace(testDir, testDir, toWorkspaceFolders([{ path: testDir }]))), TestEnvironmentService, new TestTextResourceConfigurationService(), new TestConfigurationService(), new TestLifecycleService(), new TestStorageService(), new TestNotificationService(), { disableWatcher: true }); + service = new FileService(new TestContextService(new Workspace(testDir, toWorkspaceFolders([{ path: testDir }]))), TestEnvironmentService, new TestTextResourceConfigurationService(), new TestConfigurationService(), new TestLifecycleService(), new TestStorageService(), new TestNotificationService(), { disableWatcher: true }); }); }); @@ -853,7 +853,7 @@ suite('FileService', () => { const textResourceConfigurationService = new TestTextResourceConfigurationService(configurationService); const _service = new FileService( - new TestContextService(new Workspace(_testDir, _testDir, toWorkspaceFolders([{ path: _testDir }]))), + new TestContextService(new Workspace(_testDir, toWorkspaceFolders([{ path: _testDir }]))), TestEnvironmentService, textResourceConfigurationService, configurationService, @@ -898,7 +898,7 @@ suite('FileService', () => { const textResourceConfigurationService = new TestTextResourceConfigurationService(configurationService); const _service = new FileService( - new TestContextService(new Workspace(_testDir, _testDir, toWorkspaceFolders([{ path: _testDir }]))), + new TestContextService(new Workspace(_testDir, toWorkspaceFolders([{ path: _testDir }]))), TestEnvironmentService, textResourceConfigurationService, configurationService, @@ -932,7 +932,7 @@ suite('FileService', () => { const resource = uri.file(path.join(testDir, 'index.html')); const _service = new FileService( - new TestContextService(new Workspace(_testDir, _testDir, toWorkspaceFolders([{ path: _testDir }]))), + new TestContextService(new Workspace(_testDir, toWorkspaceFolders([{ path: _testDir }]))), TestEnvironmentService, new TestTextResourceConfigurationService(), new TestConfigurationService(), diff --git a/src/vs/workbench/services/keybinding/test/electron-browser/keybindingEditing.test.ts b/src/vs/workbench/services/keybinding/test/electron-browser/keybindingEditing.test.ts index 92fba70ec97..cb922f849d5 100644 --- a/src/vs/workbench/services/keybinding/test/electron-browser/keybindingEditing.test.ts +++ b/src/vs/workbench/services/keybinding/test/electron-browser/keybindingEditing.test.ts @@ -86,7 +86,7 @@ suite('KeybindingsEditing', () => { instantiationService.stub(ILogService, new TestLogService()); instantiationService.stub(IModelService, instantiationService.createInstance(ModelServiceImpl)); instantiationService.stub(IFileService, new FileService( - new TestContextService(new Workspace(testDir, testDir, toWorkspaceFolders([{ path: testDir }]))), + new TestContextService(new Workspace(testDir, toWorkspaceFolders([{ path: testDir }]))), TestEnvironmentService, new TestTextResourceConfigurationService(), new TestConfigurationService(), diff --git a/src/vs/workbench/test/browser/parts/editor/breadcrumbModel.test.ts b/src/vs/workbench/test/browser/parts/editor/breadcrumbModel.test.ts index e524bcd9ef2..95113e157fe 100644 --- a/src/vs/workbench/test/browser/parts/editor/breadcrumbModel.test.ts +++ b/src/vs/workbench/test/browser/parts/editor/breadcrumbModel.test.ts @@ -16,7 +16,7 @@ import { FileKind } from 'vs/platform/files/common/files'; suite('Breadcrumb Model', function () { - const workspaceService = new TestContextService(new Workspace('ffff', 'Test', [new WorkspaceFolder({ uri: URI.parse('foo:/bar/baz/ws'), name: 'ws', index: 0 })])); + const workspaceService = new TestContextService(new Workspace('ffff', [new WorkspaceFolder({ uri: URI.parse('foo:/bar/baz/ws'), name: 'ws', index: 0 })])); const configService = new class extends TestConfigurationService { getValue(...args: any[]) { if (args[0] === 'breadcrumbs.filePath') { diff --git a/src/vs/workbench/test/electron-browser/api/mainThreadEditors.test.ts b/src/vs/workbench/test/electron-browser/api/mainThreadEditors.test.ts index 0013574b689..19ef6688f08 100644 --- a/src/vs/workbench/test/electron-browser/api/mainThreadEditors.test.ts +++ b/src/vs/workbench/test/electron-browser/api/mainThreadEditors.test.ts @@ -21,7 +21,7 @@ import { Range } from 'vs/editor/common/core/range'; import { Position } from 'vs/editor/common/core/position'; import { IModelService } from 'vs/editor/common/services/modelService'; import { EditOperation } from 'vs/editor/common/core/editOperation'; -import { TestFileService, TestEditorService, TestEditorGroupsService, TestEnvironmentService } from 'vs/workbench/test/workbenchTestServices'; +import { TestFileService, TestEditorService, TestEditorGroupsService, TestEnvironmentService, TestContextService } from 'vs/workbench/test/workbenchTestServices'; import { TPromise } from 'vs/base/common/winjs.base'; import { ResourceTextEdit } from 'vs/editor/common/modes'; import { BulkEditService } from 'vs/workbench/services/bulkEdit/electron-browser/bulkEditService'; @@ -84,7 +84,7 @@ suite('MainThreadEditors', () => { } }; - const bulkEditService = new BulkEditService(new NullLogService(), modelService, new TestEditorService(), textModelService, new TestFileService(), textFileService, new UriLabelService(TestEnvironmentService)); + const bulkEditService = new BulkEditService(new NullLogService(), modelService, new TestEditorService(), textModelService, new TestFileService(), textFileService, new UriLabelService(TestEnvironmentService, new TestContextService())); const rpcProtocol = new TestRPCProtocol(); rpcProtocol.set(ExtHostContext.ExtHostDocuments, new class extends mock<ExtHostDocumentsShape>() { diff --git a/src/vs/workbench/test/workbenchTestServices.ts b/src/vs/workbench/test/workbenchTestServices.ts index 16c593921a9..28b58ffa681 100644 --- a/src/vs/workbench/test/workbenchTestServices.ts +++ b/src/vs/workbench/test/workbenchTestServices.ts @@ -271,7 +271,7 @@ export function workbenchInstantiationService(): IInstantiationService { instantiationService.stub(IHashService, new TestHashService()); instantiationService.stub(ILogService, new TestLogService()); instantiationService.stub(IEditorGroupsService, new TestEditorGroupsService([new TestEditorGroup(0)])); - instantiationService.stub(IUriLabelService, new UriLabelService(TestEnvironmentService)); + instantiationService.stub(IUriLabelService, new UriLabelService(TestEnvironmentService, workspaceContextService)); const editorService = new TestEditorService(); instantiationService.stub(IEditorService, editorService); instantiationService.stub(ICodeEditorService, new TestCodeEditorService()); From c64ceff97b151f1e69c6c2b807158def5a28276c Mon Sep 17 00:00:00 2001 From: Matt Bierner <matb@microsoft.com> Date: Thu, 23 Aug 2018 12:18:26 +0200 Subject: [PATCH 1153/1276] Fix potential npe Fixes #57058 --- src/vs/editor/contrib/codeAction/codeActionCommands.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vs/editor/contrib/codeAction/codeActionCommands.ts b/src/vs/editor/contrib/codeAction/codeActionCommands.ts index 5dd721207d4..d8d998a1fb8 100644 --- a/src/vs/editor/contrib/codeAction/codeActionCommands.ts +++ b/src/vs/editor/contrib/codeAction/codeActionCommands.ts @@ -124,7 +124,7 @@ export class QuickFixController implements IEditorContribution { } private _handleLightBulbSelect(coords: { x: number, y: number }): void { - if (this._lightBulbWidget.model.actions) { + if (this._lightBulbWidget.model && this._lightBulbWidget.model.actions) { this._codeActionContextMenu.show(this._lightBulbWidget.model.actions, coords); } } From 1b07ac78bae7b255e963751390b72a3c172588fe Mon Sep 17 00:00:00 2001 From: isidor <inikolic@microsoft.com> Date: Thu, 23 Aug 2018 12:27:32 +0200 Subject: [PATCH 1154/1276] remove console.log --- src/vs/platform/uriLabel/common/uriLabel.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/src/vs/platform/uriLabel/common/uriLabel.ts b/src/vs/platform/uriLabel/common/uriLabel.ts index f676d7582ea..1212469e636 100644 --- a/src/vs/platform/uriLabel/common/uriLabel.ts +++ b/src/vs/platform/uriLabel/common/uriLabel.ts @@ -109,7 +109,6 @@ export class UriLabelService implements IUriLabelService { } // Workspace: Saved - console.log(workspace.configPath); const filename = basename(workspace.configPath); const workspaceName = filename.substr(0, filename.length - WORKSPACE_EXTENSION.length - 1); if (options && options.verbose) { From 18c3630d9be841bb285f544e0b061a3ebb92cc24 Mon Sep 17 00:00:00 2001 From: Sandeep Somavarapu <sasomava@microsoft.com> Date: Thu, 23 Aug 2018 12:26:48 +0200 Subject: [PATCH 1155/1276] Trigger installing in all servers simultaneously --- .../common/multiExtensionManagement.ts | 41 ++++++++++--------- 1 file changed, 22 insertions(+), 19 deletions(-) diff --git a/src/vs/platform/extensionManagement/common/multiExtensionManagement.ts b/src/vs/platform/extensionManagement/common/multiExtensionManagement.ts index d5e6c985b33..034d60be816 100644 --- a/src/vs/platform/extensionManagement/common/multiExtensionManagement.ts +++ b/src/vs/platform/extensionManagement/common/multiExtensionManagement.ts @@ -17,15 +17,16 @@ import { localize } from 'vs/nls'; import { IWindowService } from 'vs/platform/windows/common/windows'; import { Action } from 'vs/base/common/actions'; import { ILogService } from 'vs/platform/log/common/log'; +import { Disposable } from 'vs/base/common/lifecycle'; -export class MulitExtensionManagementService implements IExtensionManagementService { +export class MulitExtensionManagementService extends Disposable implements IExtensionManagementService { _serviceBrand: any; - onInstallExtension: Event<InstallExtensionEvent>; - onDidInstallExtension: Event<DidInstallExtensionEvent>; - onUninstallExtension: Event<IExtensionIdentifier>; - onDidUninstallExtension: Event<DidUninstallExtensionEvent>; + readonly onInstallExtension: Event<InstallExtensionEvent>; + readonly onDidInstallExtension: Event<DidInstallExtensionEvent>; + readonly onUninstallExtension: Event<IExtensionIdentifier>; + readonly onDidUninstallExtension: Event<DidUninstallExtensionEvent>; private readonly servers: IExtensionManagementServer[]; private readonly localServer: IExtensionManagementServer; @@ -38,13 +39,15 @@ export class MulitExtensionManagementService implements IExtensionManagementServ @ILogService private logService: ILogService, @IExtensionGalleryService private extensionGalleryService: IExtensionGalleryService ) { + super(); this.servers = this.extensionManagementServerService.extensionManagementServers; this.localServer = this.extensionManagementServerService.getLocalExtensionManagementServer(); this.otherServers = this.servers.filter(s => s !== this.localServer); - this.onInstallExtension = this.servers.reduce((emitter: EventMultiplexer<InstallExtensionEvent>, server) => { emitter.add(server.extensionManagementService.onInstallExtension); return emitter; }, new EventMultiplexer<InstallExtensionEvent>()).event; - this.onDidInstallExtension = this.servers.reduce((emitter: EventMultiplexer<DidInstallExtensionEvent>, server) => { emitter.add(server.extensionManagementService.onDidInstallExtension); return emitter; }, new EventMultiplexer<DidInstallExtensionEvent>()).event; - this.onUninstallExtension = this.servers.reduce((emitter: EventMultiplexer<IExtensionIdentifier>, server) => { emitter.add(server.extensionManagementService.onUninstallExtension); return emitter; }, new EventMultiplexer<IExtensionIdentifier>()).event; - this.onDidUninstallExtension = this.servers.reduce((emitter: EventMultiplexer<DidUninstallExtensionEvent>, server) => { emitter.add(server.extensionManagementService.onDidUninstallExtension); return emitter; }, new EventMultiplexer<DidUninstallExtensionEvent>()).event; + + this.onInstallExtension = this._register(this.servers.reduce((emitter: EventMultiplexer<InstallExtensionEvent>, server) => { emitter.add(server.extensionManagementService.onInstallExtension); return emitter; }, new EventMultiplexer<InstallExtensionEvent>())).event; + this.onDidInstallExtension = this._register(this.servers.reduce((emitter: EventMultiplexer<DidInstallExtensionEvent>, server) => { emitter.add(server.extensionManagementService.onDidInstallExtension); return emitter; }, new EventMultiplexer<DidInstallExtensionEvent>())).event; + this.onUninstallExtension = this._register(this.servers.reduce((emitter: EventMultiplexer<IExtensionIdentifier>, server) => { emitter.add(server.extensionManagementService.onUninstallExtension); return emitter; }, new EventMultiplexer<IExtensionIdentifier>())).event; + this.onDidUninstallExtension = this._register(this.servers.reduce((emitter: EventMultiplexer<DidUninstallExtensionEvent>, server) => { emitter.add(server.extensionManagementService.onDidUninstallExtension); return emitter; }, new EventMultiplexer<DidUninstallExtensionEvent>())).event; if (this.otherServers.length) { this.syncExtensions(); @@ -90,15 +93,14 @@ export class MulitExtensionManagementService implements IExtensionManagementServ } installFromGallery(gallery: IGalleryExtension): TPromise<void> { - return this.localServer.extensionManagementService.installFromGallery(gallery) - .then(() => this.localServer.extensionManagementService.getInstalled(LocalExtensionType.User)) - .then(installed => { - const extension = installed.filter(i => areSameExtensions(i.galleryIdentifier, gallery.identifier))[0]; - if (extension && isWorkspaceExtension(extension.manifest)) { - return TPromise.join(this.otherServers.map(server => server.extensionManagementService.installFromGallery(gallery))) - .then(() => null); - } - return null; + if (this.otherServers.length === 0) { + return this.localServer.extensionManagementService.installFromGallery(gallery); + } + return this.extensionGalleryService.getManifest(gallery) + .then(manifest => { + const servers = isWorkspaceExtension(manifest) ? this.servers : [this.localServer]; + return TPromise.join(servers.map(server => server.extensionManagementService.installFromGallery(gallery))) + .then(() => null); }); } @@ -155,7 +157,8 @@ export class MulitExtensionManagementService implements IExtensionManagementServ for (const extension of extensions) { if (ids.indexOf(extension.galleryIdentifier.id) === -1) { ids.push(extension.galleryIdentifier.id); - zipLocationResolvers.push(this.downloadFromGallery(extension).then(location => location ? { location, vsix: true } : this.localServer.extensionManagementService.zip(extension).then(location => ({ location, vsix: false })))); + zipLocationResolvers.push(this.downloadFromGallery(extension) + .then(location => location ? { location, vsix: true } : this.localServer.extensionManagementService.zip(extension).then(location => ({ location, vsix: false })))); } } }); From eb93ebcb0b671f75e7a40a56668367f4e29209f8 Mon Sep 17 00:00:00 2001 From: Johannes Rieken <johannes.rieken@gmail.com> Date: Thu, 23 Aug 2018 11:53:21 +0200 Subject: [PATCH 1156/1276] breadcrumb - allow uparrow to move to tree --- src/vs/platform/list/browser/listService.ts | 51 +++++++++++---------- 1 file changed, 26 insertions(+), 25 deletions(-) diff --git a/src/vs/platform/list/browser/listService.ts b/src/vs/platform/list/browser/listService.ts index 8df85fe9180..5c2a847b523 100644 --- a/src/vs/platform/list/browser/listService.ts +++ b/src/vs/platform/list/browser/listService.ts @@ -4,34 +4,34 @@ *--------------------------------------------------------------------------------------------*/ 'use strict'; -import { ITree, ITreeConfiguration, ITreeOptions, IRenderer as ITreeRenderer } from 'vs/base/parts/tree/browser/tree'; -import { List, IListOptions, isSelectionRangeChangeEvent, isSelectionSingleChangeEvent, IMultipleSelectionController, IOpenController, DefaultStyleController } from 'vs/base/browser/ui/list/listWidget'; -import { createDecorator, IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; -import { IDisposable, toDisposable, combinedDisposable, dispose, Disposable } from 'vs/base/common/lifecycle'; -import { IContextKeyService, IContextKey, RawContextKey, ContextKeyExpr } from 'vs/platform/contextkey/common/contextkey'; -import { PagedList, IPagedRenderer } from 'vs/base/browser/ui/list/listPaging'; -import { IVirtualDelegate, IRenderer, IListMouseEvent, IListTouchEvent } from 'vs/base/browser/ui/list/list'; +import { addClass, addStandardDisposableListener, createStyleSheet, getTotalHeight, removeClass } from 'vs/base/browser/dom'; +import { IKeyboardEvent } from 'vs/base/browser/keyboardEvent'; +import { IInputOptions, InputBox } from 'vs/base/browser/ui/inputbox/inputBox'; +import { IListMouseEvent, IListTouchEvent, IRenderer, IVirtualDelegate } from 'vs/base/browser/ui/list/list'; +import { IPagedRenderer, PagedList } from 'vs/base/browser/ui/list/listPaging'; +import { DefaultStyleController, IListOptions, IMultipleSelectionController, IOpenController, isSelectionRangeChangeEvent, isSelectionSingleChangeEvent, List } from 'vs/base/browser/ui/list/listWidget'; +import { canceled, onUnexpectedError } from 'vs/base/common/errors'; +import { Emitter, Event } from 'vs/base/common/event'; +import { KeyCode } from 'vs/base/common/keyCodes'; +import { combinedDisposable, Disposable, dispose, IDisposable, toDisposable } from 'vs/base/common/lifecycle'; +import { ScrollbarVisibility } from 'vs/base/common/scrollable'; +import { isUndefinedOrNull } from 'vs/base/common/types'; +import { TPromise } from 'vs/base/common/winjs.base'; +import { IRenderer as ITreeRenderer, ITree, ITreeConfiguration, ITreeOptions } from 'vs/base/parts/tree/browser/tree'; +import { ClickBehavior, DefaultController, DefaultTreestyler, IControllerOptions, OpenMode } from 'vs/base/parts/tree/browser/treeDefaults'; import { Tree } from 'vs/base/parts/tree/browser/treeImpl'; -import { attachListStyler, defaultListStyles, computeStyles, attachInputBoxStyler } from 'vs/platform/theme/common/styler'; +import { localize } from 'vs/nls'; +import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; +import { Extensions as ConfigurationExtensions, IConfigurationRegistry } from 'vs/platform/configuration/common/configurationRegistry'; +import { ContextKeyExpr, IContextKey, IContextKeyService, RawContextKey } from 'vs/platform/contextkey/common/contextkey'; +import { IContextViewService } from 'vs/platform/contextview/browser/contextView'; +import { IEditorOptions } from 'vs/platform/editor/common/editor'; +import { createDecorator, IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; +import { IKeybindingService } from 'vs/platform/keybinding/common/keybinding'; +import { Registry } from 'vs/platform/registry/common/platform'; +import { attachInputBoxStyler, attachListStyler, computeStyles, defaultListStyles } from 'vs/platform/theme/common/styler'; import { IThemeService } from 'vs/platform/theme/common/themeService'; import { InputFocusedContextKey } from 'vs/platform/workbench/common/contextkeys'; -import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; -import { localize } from 'vs/nls'; -import { Registry } from 'vs/platform/registry/common/platform'; -import { Extensions as ConfigurationExtensions, IConfigurationRegistry } from 'vs/platform/configuration/common/configurationRegistry'; -import { DefaultController, IControllerOptions, OpenMode, ClickBehavior, DefaultTreestyler } from 'vs/base/parts/tree/browser/treeDefaults'; -import { isUndefinedOrNull } from 'vs/base/common/types'; -import { IEditorOptions } from 'vs/platform/editor/common/editor'; -import { Event, Emitter } from 'vs/base/common/event'; -import { createStyleSheet, addStandardDisposableListener, getTotalHeight, removeClass, addClass } from 'vs/base/browser/dom'; -import { ScrollbarVisibility } from 'vs/base/common/scrollable'; -import { InputBox, IInputOptions } from 'vs/base/browser/ui/inputbox/inputBox'; -import { IContextViewService } from 'vs/platform/contextview/browser/contextView'; -import { TPromise } from 'vs/base/common/winjs.base'; -import { onUnexpectedError, canceled } from 'vs/base/common/errors'; -import { KeyCode } from 'vs/base/common/keyCodes'; -import { IKeyboardEvent } from 'vs/base/browser/keyboardEvent'; -import { IKeybindingService } from 'vs/platform/keybinding/common/keybinding'; export type ListWidget = List<any> | PagedList<any> | ITree; @@ -650,6 +650,7 @@ export class HighlightingWorkbenchTree extends WorkbenchTree { this.disposables.push(addStandardDisposableListener(this.input.inputElement, 'keydown', event => { //todo@joh make this command/context-key based switch (event.keyCode) { + case KeyCode.UpArrow: case KeyCode.DownArrow: case KeyCode.Tab: this.domFocus(); From 3663d1f07c5489e9494c871fdc56086d7e53da00 Mon Sep 17 00:00:00 2001 From: Johannes Rieken <johannes.rieken@gmail.com> Date: Thu, 23 Aug 2018 12:37:19 +0200 Subject: [PATCH 1157/1276] extract highlight knowledge as prep to filter, #55004 --- src/vs/base/common/filters.ts | 16 +++++-- .../contrib/documentSymbols/outlineModel.ts | 28 ++++++----- src/vs/platform/list/browser/listService.ts | 45 +++++++++++++----- .../browser/parts/editor/breadcrumbsPicker.ts | 46 ++++++++----------- 4 files changed, 81 insertions(+), 54 deletions(-) diff --git a/src/vs/base/common/filters.ts b/src/vs/base/common/filters.ts index 5f052e2e02a..da02dae8613 100644 --- a/src/vs/base/common/filters.ts +++ b/src/vs/base/common/filters.ts @@ -4,9 +4,9 @@ *--------------------------------------------------------------------------------------------*/ 'use strict'; -import * as strings from 'vs/base/common/strings'; -import { LRUCache } from 'vs/base/common/map'; import { CharCode } from 'vs/base/common/charCode'; +import { LRUCache } from 'vs/base/common/map'; +import * as strings from 'vs/base/common/strings'; export interface IFilter { // Returns null if word doesn't match. @@ -362,13 +362,19 @@ export function anyScore(pattern: string, word: string, patternMaxWhitespaceIgno //#region --- fuzzyScore --- -export function createMatches(position: number[]): IMatch[] { +export function createMatches(offsetOrScore: number[] | FuzzyScore): IMatch[] { let ret: IMatch[] = []; - if (!position) { + if (!offsetOrScore) { return ret; } + let offsets: number[]; + if (Array.isArray(offsetOrScore[1])) { + offsets = (offsetOrScore as FuzzyScore)[1]; + } else { + offsets = offsetOrScore as number[]; + } let last: IMatch; - for (const pos of position) { + for (const pos of offsets) { if (last && last.end === pos) { last.end += 1; } else { diff --git a/src/vs/editor/contrib/documentSymbols/outlineModel.ts b/src/vs/editor/contrib/documentSymbols/outlineModel.ts index 38157732bfa..c980bd1f32c 100644 --- a/src/vs/editor/contrib/documentSymbols/outlineModel.ts +++ b/src/vs/editor/contrib/documentSymbols/outlineModel.ts @@ -4,18 +4,18 @@ *--------------------------------------------------------------------------------------------*/ 'use strict'; -import { DocumentSymbolProviderRegistry, DocumentSymbolProvider, DocumentSymbol } from 'vs/editor/common/modes'; -import { ITextModel } from 'vs/editor/common/model'; -import { fuzzyScore, FuzzyScore } from 'vs/base/common/filters'; -import { IPosition } from 'vs/editor/common/core/position'; -import { Range, IRange } from 'vs/editor/common/core/range'; -import { first, size, forEach } from 'vs/base/common/collections'; -import { isFalsyOrEmpty, binarySearch, coalesce } from 'vs/base/common/arrays'; -import { commonPrefixLength } from 'vs/base/common/strings'; -import { IMarker, MarkerSeverity } from 'vs/platform/markers/common/markers'; -import { onUnexpectedExternalError } from 'vs/base/common/errors'; -import { LRUCache } from 'vs/base/common/map'; +import { binarySearch, coalesce, isFalsyOrEmpty } from 'vs/base/common/arrays'; import { CancellationToken, CancellationTokenSource } from 'vs/base/common/cancellation'; +import { first, forEach, size } from 'vs/base/common/collections'; +import { onUnexpectedExternalError } from 'vs/base/common/errors'; +import { fuzzyScore, FuzzyScore } from 'vs/base/common/filters'; +import { LRUCache } from 'vs/base/common/map'; +import { commonPrefixLength } from 'vs/base/common/strings'; +import { IPosition } from 'vs/editor/common/core/position'; +import { IRange, Range } from 'vs/editor/common/core/range'; +import { ITextModel } from 'vs/editor/common/model'; +import { DocumentSymbol, DocumentSymbolProvider, DocumentSymbolProviderRegistry } from 'vs/editor/common/modes'; +import { IMarker, MarkerSeverity } from 'vs/platform/markers/common/markers'; export abstract class TreeElement { @@ -393,11 +393,17 @@ export class OutlineModel extends TreeElement { return true; } + private _matches: [string, OutlineElement]; + updateMatches(pattern: string): OutlineElement { + if (this._matches && this._matches[0] === pattern) { + return this._matches[1]; + } let topMatch: OutlineElement; for (const key in this._groups) { topMatch = this._groups[key].updateMatches(pattern, topMatch); } + this._matches = [pattern, topMatch]; return topMatch; } diff --git a/src/vs/platform/list/browser/listService.ts b/src/vs/platform/list/browser/listService.ts index 5c2a847b523..8dd1e6580ce 100644 --- a/src/vs/platform/list/browser/listService.ts +++ b/src/vs/platform/list/browser/listService.ts @@ -12,12 +12,13 @@ import { IPagedRenderer, PagedList } from 'vs/base/browser/ui/list/listPaging'; import { DefaultStyleController, IListOptions, IMultipleSelectionController, IOpenController, isSelectionRangeChangeEvent, isSelectionSingleChangeEvent, List } from 'vs/base/browser/ui/list/listWidget'; import { canceled, onUnexpectedError } from 'vs/base/common/errors'; import { Emitter, Event } from 'vs/base/common/event'; +import { FuzzyScore } from 'vs/base/common/filters'; import { KeyCode } from 'vs/base/common/keyCodes'; import { combinedDisposable, Disposable, dispose, IDisposable, toDisposable } from 'vs/base/common/lifecycle'; import { ScrollbarVisibility } from 'vs/base/common/scrollable'; import { isUndefinedOrNull } from 'vs/base/common/types'; import { TPromise } from 'vs/base/common/winjs.base'; -import { IRenderer as ITreeRenderer, ITree, ITreeConfiguration, ITreeOptions } from 'vs/base/parts/tree/browser/tree'; +import { ITree, ITreeConfiguration, ITreeOptions } from 'vs/base/parts/tree/browser/tree'; import { ClickBehavior, DefaultController, DefaultTreestyler, IControllerOptions, OpenMode } from 'vs/base/parts/tree/browser/treeDefaults'; import { Tree } from 'vs/base/parts/tree/browser/treeImpl'; import { localize } from 'vs/nls'; @@ -562,16 +563,13 @@ export class TreeResourceNavigator extends Disposable { } } - -export interface IHighlightingRenderer extends ITreeRenderer { - /** - * Update hightlights and return the best matching element - */ - updateHighlights(tree: ITree, pattern: string): any; +export interface IHighlighter { + getHighlights(tree: ITree, element: any, pattern: string): FuzzyScore; + getHighlightsStorageKey?(element: any): any; } export interface IHighlightingTreeConfiguration extends ITreeConfiguration { - renderer: IHighlightingRenderer & ITreeRenderer; + highlighter: IHighlighter; } export class HighlightingTreeController extends WorkbenchTreeController { @@ -607,7 +605,8 @@ export class HighlightingWorkbenchTree extends WorkbenchTree { protected readonly inputContainer: HTMLElement; protected readonly input: InputBox; - protected readonly renderer: IHighlightingRenderer; + protected readonly highlighter: IHighlighter; + protected readonly highlights: Map<any, FuzzyScore>; constructor( parent: HTMLElement, @@ -635,7 +634,8 @@ export class HighlightingWorkbenchTree extends WorkbenchTree { // create tree treeConfiguration.controller = treeConfiguration.controller || instantiationService.createInstance(HighlightingTreeController, {}, () => this.onTypeInTree()); super(treeContainer, treeConfiguration, treeOptions, contextKeyService, listService, themeService, instantiationService, configurationService); - this.renderer = treeConfiguration.renderer; + this.highlighter = treeConfiguration.highlighter; + this.highlights = new Map<any, FuzzyScore>(); this.domNode = container; addClass(this.domNode, 'inactive'); @@ -705,7 +705,19 @@ export class HighlightingWorkbenchTree extends WorkbenchTree { this.lastSelection = []; } - const topElement = this.renderer.updateHighlights(this, pattern); + let nav = this.getNavigator(undefined, false); + let topScore: FuzzyScore; + let topElement: any; + while (nav.next()) { + let element = nav.current(); + let score = this.highlighter.getHighlights(this, element, pattern); + this.highlights.set(this._getHighlightsStorageKey(element), score); + element.foo = 1; + if (!topScore || score && topScore[0] < score[0]) { + topScore = score; + topElement = element; + } + } this.refresh().then(() => { if (topElement && pattern) { @@ -715,9 +727,20 @@ export class HighlightingWorkbenchTree extends WorkbenchTree { }); } else { this.setSelection(defaultSelection, this); + this.highlights.clear(); } }, onUnexpectedError); } + + getHighlights(element: any): FuzzyScore { + return this.highlights.get(this._getHighlightsStorageKey(element)); + } + + private _getHighlightsStorageKey(element: any): any { + return typeof this.highlighter.getHighlightsStorageKey === 'function' + ? this.highlighter.getHighlightsStorageKey(element) + : element; + } } const configurationRegistry = Registry.as<IConfigurationRegistry>(ConfigurationExtensions.Configuration); diff --git a/src/vs/workbench/browser/parts/editor/breadcrumbsPicker.ts b/src/vs/workbench/browser/parts/editor/breadcrumbsPicker.ts index 46296d827e9..c842ac046e0 100644 --- a/src/vs/workbench/browser/parts/editor/breadcrumbsPicker.ts +++ b/src/vs/workbench/browser/parts/editor/breadcrumbsPicker.ts @@ -23,7 +23,7 @@ import { localize } from 'vs/nls'; 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 { HighlightingWorkbenchTree, IHighlightingRenderer, IHighlightingTreeConfiguration } from 'vs/platform/list/browser/listService'; +import { HighlightingWorkbenchTree, IHighlighter, IHighlightingTreeConfiguration } from 'vs/platform/list/browser/listService'; import { breadcrumbsPickerBackground, widgetShadow } from 'vs/platform/theme/common/colorRegistry'; import { IThemeService } from 'vs/platform/theme/common/themeService'; import { IWorkspace, IWorkspaceContextService, IWorkspaceFolder } from 'vs/platform/workspace/common/workspace'; @@ -79,7 +79,7 @@ export abstract class BreadcrumbsPicker { this._treeContainer.style.boxShadow = `0px 5px 8px ${this._themeService.getTheme().getColor(widgetShadow)}`; this._domNode.appendChild(this._treeContainer); - const treeConifg = this._completeTreeConfiguration({ dataSource: undefined, renderer: undefined }); + const treeConifg = this._completeTreeConfiguration({ dataSource: undefined, renderer: undefined, highlighter: undefined }); this._tree = this._instantiationService.createInstance( HighlightingWorkbenchTree, this._treeContainer, @@ -259,9 +259,16 @@ export class FileFilter implements IFilter { } } -export class FileRenderer implements IRenderer, IHighlightingRenderer { +export class FileHighlighter implements IHighlighter { + getHighlightsStorageKey(element: IFileStat | IWorkspaceFolder): string { + return IWorkspaceFolder.isIWorkspaceFolder(element) ? element.uri.toString() : element.resource.toString(); + } + getHighlights(tree: ITree, element: IFileStat | IWorkspaceFolder, pattern: string): FuzzyScore { + return fuzzyScore(pattern, element.name, undefined, true); + } +} - private readonly _scores = new Map<string, FuzzyScore>(); +export class FileRenderer implements IRenderer { constructor( @IInstantiationService private readonly _instantiationService: IInstantiationService, @@ -295,7 +302,7 @@ export class FileRenderer implements IRenderer, IHighlightingRenderer { fileKind, hidePath: true, fileDecorations: fileDecorations, - matches: createMatches((this._scores.get(resource.toString()) || [, []])[1]), + matches: createMatches((tree as HighlightingWorkbenchTree).getHighlights(element)), extraClasses: ['picker-item'] }); } @@ -303,22 +310,6 @@ export class FileRenderer implements IRenderer, IHighlightingRenderer { disposeTemplate(tree: ITree, templateId: string, templateData: FileLabel): void { templateData.dispose(); } - - updateHighlights(tree: ITree, pattern: string): any { - let nav = tree.getNavigator(undefined, false); - let topScore: FuzzyScore; - let topElement: any; - while (nav.next()) { - let element = nav.current() as IFileStat | IWorkspaceFolder; - let score = fuzzyScore(pattern, element.name, undefined, true); - this._scores.set(IWorkspaceFolder.isIWorkspaceFolder(element) ? element.uri.toString() : element.resource.toString(), score); - if (!topScore || score && topScore[0] < score[0]) { - topScore = score; - topElement = element; - } - } - return topElement; - } } export class FileSorter implements ISorter { @@ -379,6 +370,7 @@ export class BreadcrumbsFilePicker extends BreadcrumbsPicker { config.dataSource = this._instantiationService.createInstance(FileDataSource); config.renderer = this._instantiationService.createInstance(FileRenderer); config.sorter = new FileSorter(); + config.highlighter = new FileHighlighter(); config.filter = filter; return config; } @@ -393,11 +385,10 @@ export class BreadcrumbsFilePicker extends BreadcrumbsPicker { //#region - Symbols -class HighlightingOutlineRenderer extends OutlineRenderer implements IHighlightingRenderer { - - updateHighlights(tree: ITree, pattern: string): any { - let model = OutlineModel.get(tree.getInput()); - return model.updateMatches(pattern); +class OutlineHighlighter implements IHighlighter { + getHighlights(tree: ITree, element: OutlineElement, pattern: string): FuzzyScore { + OutlineModel.get(element).updateMatches(pattern); + return element.score; } } @@ -416,8 +407,9 @@ export class BreadcrumbsOutlinePicker extends BreadcrumbsPicker { protected _completeTreeConfiguration(config: IHighlightingTreeConfiguration): IHighlightingTreeConfiguration { config.dataSource = this._instantiationService.createInstance(OutlineDataSource); - config.renderer = this._instantiationService.createInstance(HighlightingOutlineRenderer); + config.renderer = this._instantiationService.createInstance(OutlineRenderer); config.sorter = new OutlineItemComparator(); + config.highlighter = new OutlineHighlighter(); return config; } From de38bb2ea3acca0599aec73679fe8d1defe22930 Mon Sep 17 00:00:00 2001 From: Sandeep Somavarapu <sasomava@microsoft.com> Date: Thu, 23 Aug 2018 12:47:39 +0200 Subject: [PATCH 1158/1276] Customise workspace extensions from config --- .../common/extensionManagement.ts | 1 + .../common/extensionManagementUtil.ts | 18 ++++++++++++++++-- .../common/multiExtensionManagement.ts | 10 ++++++---- 3 files changed, 23 insertions(+), 6 deletions(-) diff --git a/src/vs/platform/extensionManagement/common/extensionManagement.ts b/src/vs/platform/extensionManagement/common/extensionManagement.ts index 12243f5f237..3f6e9a49fbe 100644 --- a/src/vs/platform/extensionManagement/common/extensionManagement.ts +++ b/src/vs/platform/extensionManagement/common/extensionManagement.ts @@ -122,6 +122,7 @@ export interface IExtensionManifest { main?: string; icon?: string; categories?: string[]; + keywords?: string[]; activationEvents?: string[]; extensionDependencies?: string[]; extensionPack?: string[]; diff --git a/src/vs/platform/extensionManagement/common/extensionManagementUtil.ts b/src/vs/platform/extensionManagement/common/extensionManagementUtil.ts index 208631c7b63..0f626331d1d 100644 --- a/src/vs/platform/extensionManagement/common/extensionManagementUtil.ts +++ b/src/vs/platform/extensionManagement/common/extensionManagementUtil.ts @@ -6,6 +6,7 @@ 'use strict'; import { ILocalExtension, IGalleryExtension, EXTENSION_IDENTIFIER_REGEX, IExtensionIdentifier, IReportedExtension, IExtensionManifest } from 'vs/platform/extensionManagement/common/extensionManagement'; +import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; export function areSameExtensions(a: IExtensionIdentifier, b: IExtensionIdentifier): boolean { if (a.uuid && b.uuid) { @@ -119,9 +120,22 @@ export function getMaliciousExtensionsSet(report: IReportedExtension[]): Set<str return result; } -export function isWorkspaceExtension(manifest: IExtensionManifest): boolean { +export function isWorkspaceExtension(manifest: IExtensionManifest, configurationService: IConfigurationService): boolean { + const extensionId = getGalleryExtensionId(manifest.publisher, manifest.name); + const workspaceExtensions = configurationService.getValue<string[]>('_workbench.workspaceExtensions') || []; + if (workspaceExtensions.length) { + if (workspaceExtensions.indexOf(extensionId) !== -1) { + return true; + } + if (workspaceExtensions.indexOf(`-${extensionId}`) !== -1) { + return false; + } + } + if (manifest.main) { - const extensionId = getGalleryExtensionId(manifest.publisher, manifest.name); + if ((manifest.keywords || []).indexOf('capability_fs') !== -1) { + return true; + } return [ 'vscode.extension-editing', 'vscode.configuration-editing', diff --git a/src/vs/platform/extensionManagement/common/multiExtensionManagement.ts b/src/vs/platform/extensionManagement/common/multiExtensionManagement.ts index 034d60be816..852ccee6bfc 100644 --- a/src/vs/platform/extensionManagement/common/multiExtensionManagement.ts +++ b/src/vs/platform/extensionManagement/common/multiExtensionManagement.ts @@ -18,6 +18,7 @@ import { IWindowService } from 'vs/platform/windows/common/windows'; import { Action } from 'vs/base/common/actions'; import { ILogService } from 'vs/platform/log/common/log'; import { Disposable } from 'vs/base/common/lifecycle'; +import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; export class MulitExtensionManagementService extends Disposable implements IExtensionManagementService { @@ -37,7 +38,8 @@ export class MulitExtensionManagementService extends Disposable implements IExte @INotificationService private notificationService: INotificationService, @IWindowService private windowService: IWindowService, @ILogService private logService: ILogService, - @IExtensionGalleryService private extensionGalleryService: IExtensionGalleryService + @IExtensionGalleryService private extensionGalleryService: IExtensionGalleryService, + @IConfigurationService private configurationService: IConfigurationService ) { super(); this.servers = this.extensionManagementServerService.extensionManagementServers; @@ -84,7 +86,7 @@ export class MulitExtensionManagementService extends Disposable implements IExte .then(extensionIdentifer => this.localServer.extensionManagementService.getInstalled(LocalExtensionType.User) .then(installed => { const extension = installed.filter(i => areSameExtensions(i.identifier, extensionIdentifer))[0]; - if (extension && isWorkspaceExtension(extension.manifest)) { + if (this.otherServers.length && extension && isWorkspaceExtension(extension.manifest, this.configurationService)) { return TPromise.join(this.otherServers.map(server => server.extensionManagementService.install(vsix))) .then(() => extensionIdentifer); } @@ -98,7 +100,7 @@ export class MulitExtensionManagementService extends Disposable implements IExte } return this.extensionGalleryService.getManifest(gallery) .then(manifest => { - const servers = isWorkspaceExtension(manifest) ? this.servers : [this.localServer]; + const servers = isWorkspaceExtension(manifest, this.configurationService) ? this.servers : [this.localServer]; return TPromise.join(servers.map(server => server.extensionManagementService.installFromGallery(gallery))) .then(() => null); }); @@ -115,7 +117,7 @@ export class MulitExtensionManagementService extends Disposable implements IExte private async syncExtensions(): Promise<void> { this.localServer.extensionManagementService.getInstalled(LocalExtensionType.User) .then(async localExtensions => { - const workspaceExtensions = localExtensions.filter(e => isWorkspaceExtension(e.manifest)); + const workspaceExtensions = localExtensions.filter(e => isWorkspaceExtension(e.manifest, this.configurationService)); const extensionsToSync: Map<IExtensionManagementServer, ILocalExtension[]> = await this.getExtensionsToSync(workspaceExtensions); if (extensionsToSync.size > 0) { const handler = this.notificationService.notify({ severity: Severity.Info, message: localize('synchronising', "Synchronising workspace extensions...") }); From 9a57f2e00b6172acd8150a976faa500ec95d896a Mon Sep 17 00:00:00 2001 From: isidor <inikolic@microsoft.com> Date: Thu, 23 Aug 2018 12:57:22 +0200 Subject: [PATCH 1159/1276] IUriLabelService -> ILabelService --- src/vs/base/common/labels.ts | 2 +- src/vs/code/electron-main/app.ts | 8 +++--- src/vs/code/electron-main/main.ts | 6 ++-- src/vs/code/electron-main/menubar.ts | 10 +++---- src/vs/code/electron-main/menus.ts | 10 +++---- .../referenceSearch/referencesWidget.ts | 12 ++++---- .../standalone/browser/simpleServices.ts | 6 ++-- .../standalone/browser/standaloneServices.ts | 4 +-- .../electron-main/historyMainService.ts | 8 +++--- .../uriLabel.ts => label/common/label.ts} | 16 +++++------ .../electron-browser/label.contribution.ts} | 12 ++++---- .../{uriLabel => label}/test/uriLabel.test.ts | 18 ++++++------ .../electron-browser/mainThreadFileSystem.ts | 6 ++-- .../electron-browser/mainThreadWorkspace.ts | 6 ++-- src/vs/workbench/api/node/extHost.protocol.ts | 2 +- .../workbench/api/node/extHostFileSystem.ts | 2 +- .../browser/actions/workspaceCommands.ts | 6 ++-- src/vs/workbench/browser/labels.ts | 12 ++++---- .../parts/quickopen/quickOpenController.ts | 6 ++-- .../browser/parts/titlebar/menubarControl.ts | 10 +++---- .../browser/parts/titlebar/titlebarPart.ts | 10 +++---- .../common/editor/untitledEditorInput.ts | 14 +++++----- src/vs/workbench/electron-browser/actions.ts | 28 +++++++++---------- src/vs/workbench/electron-browser/shell.ts | 6 ++-- .../workbench/electron-browser/workbench.ts | 6 ++-- .../parts/debug/browser/breakpointsView.ts | 6 ++-- .../debug/electron-browser/callStackView.ts | 6 ++-- .../debug/electron-browser/replViewer.ts | 6 ++-- .../files/common/editors/fileEditorInput.ts | 14 +++++----- .../files/electron-browser/fileCommands.ts | 12 ++++---- .../electron-browser/files.contribution.ts | 6 ++-- .../electron-browser/views/explorerView.ts | 6 ++-- .../electron-browser/localizationsActions.ts | 6 ++-- .../logs/electron-browser/logsActions.ts | 10 +++---- .../electron-browser/markersTreeViewer.ts | 12 ++++---- .../parts/search/browser/openFileHandler.ts | 6 ++-- .../parts/search/browser/openSymbolHandler.ts | 6 ++-- .../parts/search/browser/searchResultsView.ts | 6 ++-- .../page/electron-browser/welcomePage.ts | 10 +++---- .../electron-browser/bulkEditService.ts | 10 +++---- .../services/editor/browser/editorService.ts | 10 +++---- .../electron-browser/extensionHost.ts | 6 ++-- .../preferences/browser/preferencesService.ts | 6 ++-- .../api/mainThreadEditors.test.ts | 4 +-- .../workbench/test/workbenchTestServices.ts | 4 +-- src/vs/workbench/workbench.main.ts | 2 +- 46 files changed, 190 insertions(+), 190 deletions(-) rename src/vs/platform/{uriLabel/common/uriLabel.ts => label/common/label.ts} (91%) rename src/vs/platform/{uriLabel/electron-browser/uriLabel.contribution.ts => label/electron-browser/label.contribution.ts} (68%) rename src/vs/platform/{uriLabel => label}/test/uriLabel.test.ts (72%) diff --git a/src/vs/base/common/labels.ts b/src/vs/base/common/labels.ts index 44d9373ab80..3e50bf58495 100644 --- a/src/vs/base/common/labels.ts +++ b/src/vs/base/common/labels.ts @@ -23,7 +23,7 @@ export interface IUserHomeProvider { } /** - * @deprecated use UriLabelService instead + * @deprecated use LabelService instead */ export function getPathLabel(resource: URI | string, userHomeProvider: IUserHomeProvider, rootProvider?: IWorkspaceFolderProvider): string { if (!resource) { diff --git a/src/vs/code/electron-main/app.ts b/src/vs/code/electron-main/app.ts index d68fb99ae68..c783bbd281d 100644 --- a/src/vs/code/electron-main/app.ts +++ b/src/vs/code/electron-main/app.ts @@ -63,7 +63,7 @@ import { serve as serveDriver } from 'vs/platform/driver/electron-main/driver'; import { IMenubarService } from 'vs/platform/menubar/common/menubar'; import { MenubarService } from 'vs/platform/menubar/electron-main/menubarService'; import { MenubarChannel } from 'vs/platform/menubar/node/menubarIpc'; -import { IUriLabelService } from 'vs/platform/uriLabel/common/uriLabel'; +import { ILabelService } from 'vs/platform/label/common/label'; import { CodeMenu } from 'vs/code/electron-main/menus'; import { hasArgs } from 'vs/platform/environment/node/argv'; import { RunOnceScheduler } from 'vs/base/common/async'; @@ -90,7 +90,7 @@ export class CodeApplication { @IConfigurationService private configurationService: ConfigurationService, @IStateService private stateService: IStateService, @IHistoryMainService private historyMainService: IHistoryMainService, - @IUriLabelService private uriLabelService: IUriLabelService + @ILabelService private labelService: ILabelService ) { this.toDispose = [mainIpcServer, configurationService]; @@ -228,8 +228,8 @@ export class CodeApplication { } }); - ipc.on('vscode:uriLabelRegisterFormater', (event: any, { scheme, formater }) => { - this.uriLabelService.registerFormater(scheme, formater); + ipc.on('vscode:labelRegisterFormater', (event: any, { scheme, formater }) => { + this.labelService.registerFormater(scheme, formater); }); // Keyboard layout changes diff --git a/src/vs/code/electron-main/main.ts b/src/vs/code/electron-main/main.ts index 3c2c255e3f7..683164272f8 100644 --- a/src/vs/code/electron-main/main.ts +++ b/src/vs/code/electron-main/main.ts @@ -50,7 +50,7 @@ import { uploadLogs } from 'vs/code/electron-main/logUploader'; import { setUnexpectedErrorHandler } from 'vs/base/common/errors'; import { IDialogService } from 'vs/platform/dialogs/common/dialogs'; import { CommandLineDialogService } from 'vs/platform/dialogs/node/dialogService'; -import { IUriLabelService, UriLabelService } from 'vs/platform/uriLabel/common/uriLabel'; +import { ILabelService, LabelService } from 'vs/platform/label/common/label'; function createServices(args: ParsedArgs, bufferLogService: BufferLogService): IInstantiationService { const services = new ServiceCollection(); @@ -58,7 +58,7 @@ function createServices(args: ParsedArgs, bufferLogService: BufferLogService): I const environmentService = new EnvironmentService(args, process.execPath); const consoleLogService = new ConsoleLogMainService(getLogLevel(environmentService)); const logService = new MultiplexLogService([consoleLogService, bufferLogService]); - const uriLabelService = new UriLabelService(environmentService, undefined); + const labelService = new LabelService(environmentService, undefined); process.once('exit', () => logService.dispose()); @@ -66,7 +66,7 @@ function createServices(args: ParsedArgs, bufferLogService: BufferLogService): I setTimeout(() => cleanupOlderLogs(environmentService).then(null, err => console.error(err)), 10000); services.set(IEnvironmentService, environmentService); - services.set(IUriLabelService, uriLabelService); + services.set(ILabelService, labelService); services.set(ILogService, logService); services.set(IWorkspacesMainService, new SyncDescriptor(WorkspacesMainService)); services.set(IHistoryMainService, new SyncDescriptor(HistoryMainService)); diff --git a/src/vs/code/electron-main/menubar.ts b/src/vs/code/electron-main/menubar.ts index 9aca1cca19f..1e883015480 100644 --- a/src/vs/code/electron-main/menubar.ts +++ b/src/vs/code/electron-main/menubar.ts @@ -22,7 +22,7 @@ import { IHistoryMainService } from 'vs/platform/history/common/history'; import { IWorkspaceIdentifier, ISingleFolderWorkspaceIdentifier, isSingleFolderWorkspaceIdentifier, isWorkspaceIdentifier } from 'vs/platform/workspaces/common/workspaces'; import { IMenubarData, IMenubarKeybinding, MenubarMenuItem, isMenubarMenuItemSeparator, isMenubarMenuItemSubmenu, isMenubarMenuItemAction } from 'vs/platform/menubar/common/menubar'; import URI from 'vs/base/common/uri'; -import { IUriLabelService } from 'vs/platform/uriLabel/common/uriLabel'; +import { ILabelService } from 'vs/platform/label/common/label'; const telemetryFrom = 'menu'; @@ -49,7 +49,7 @@ export class Menubar { @IEnvironmentService private environmentService: IEnvironmentService, @ITelemetryService private telemetryService: ITelemetryService, @IHistoryMainService private historyMainService: IHistoryMainService, - @IUriLabelService private uriLabelService: IUriLabelService + @ILabelService private labelService: ILabelService ) { this.menuUpdater = new RunOnceScheduler(() => this.doUpdateMenu(), 0); @@ -563,13 +563,13 @@ export class Menubar { let label: string; let uri: URI; if (isSingleFolderWorkspaceIdentifier(workspaceOrFile) && !isFile) { - label = unmnemonicLabel(this.uriLabelService.getWorkspaceLabel(workspaceOrFile, { verbose: true })); + label = unmnemonicLabel(this.labelService.getWorkspaceLabel(workspaceOrFile, { verbose: true })); uri = workspaceOrFile; } else if (isWorkspaceIdentifier(workspaceOrFile)) { - label = this.uriLabelService.getWorkspaceLabel(workspaceOrFile, { verbose: true }); + label = this.labelService.getWorkspaceLabel(workspaceOrFile, { verbose: true }); uri = URI.file(workspaceOrFile.configPath); } else { - label = unmnemonicLabel(this.uriLabelService.getLabel(workspaceOrFile)); + label = unmnemonicLabel(this.labelService.getUriLabel(workspaceOrFile)); uri = workspaceOrFile; } diff --git a/src/vs/code/electron-main/menus.ts b/src/vs/code/electron-main/menus.ts index 3a27ba9c4d8..118192b01b4 100644 --- a/src/vs/code/electron-main/menus.ts +++ b/src/vs/code/electron-main/menus.ts @@ -24,7 +24,7 @@ import { IWindowsMainService, IWindowsCountChangedEvent } from 'vs/platform/wind import { IHistoryMainService } from 'vs/platform/history/common/history'; import { IWorkspaceIdentifier, ISingleFolderWorkspaceIdentifier, isSingleFolderWorkspaceIdentifier, isWorkspaceIdentifier } from 'vs/platform/workspaces/common/workspaces'; import URI from 'vs/base/common/uri'; -import { IUriLabelService } from 'vs/platform/uriLabel/common/uriLabel'; +import { ILabelService } from 'vs/platform/label/common/label'; interface IMenuItemClickHandler { inDevTools: (contents: Electron.WebContents) => void; @@ -68,7 +68,7 @@ export class CodeMenu { @IEnvironmentService private environmentService: IEnvironmentService, @ITelemetryService private telemetryService: ITelemetryService, @IHistoryMainService private historyMainService: IHistoryMainService, - @IUriLabelService private uriLabelService: IUriLabelService + @ILabelService private labelService: ILabelService ) { this.nativeTabMenuItems = []; @@ -491,14 +491,14 @@ export class CodeMenu { let label: string; let uri: URI; if (isSingleFolderWorkspaceIdentifier(workspace)) { - label = unmnemonicLabel(this.uriLabelService.getWorkspaceLabel(workspace, { verbose: true })); + label = unmnemonicLabel(this.labelService.getWorkspaceLabel(workspace, { verbose: true })); uri = workspace; } else if (isWorkspaceIdentifier(workspace)) { - label = this.uriLabelService.getWorkspaceLabel(workspace, { verbose: true }); + label = this.labelService.getWorkspaceLabel(workspace, { verbose: true }); uri = URI.file(workspace.configPath); } else { uri = URI.file(workspace); - label = unmnemonicLabel(this.uriLabelService.getLabel(uri)); + label = unmnemonicLabel(this.labelService.getUriLabel(uri)); } return new MenuItem(this.likeAction(commandId, { diff --git a/src/vs/editor/contrib/referenceSearch/referencesWidget.ts b/src/vs/editor/contrib/referenceSearch/referencesWidget.ts index da6bf29eb68..ce56fc0822e 100644 --- a/src/vs/editor/contrib/referenceSearch/referencesWidget.ts +++ b/src/vs/editor/contrib/referenceSearch/referencesWidget.ts @@ -40,7 +40,7 @@ import { WorkbenchTree, WorkbenchTreeController } from 'vs/platform/list/browser import { RawContextKey } from 'vs/platform/contextkey/common/contextkey'; import { Location } from 'vs/editor/common/modes'; import { ClickBehavior } from 'vs/base/parts/tree/browser/treeDefaults'; -import { IUriLabelService } from 'vs/platform/uriLabel/common/uriLabel'; +import { ILabelService } from 'vs/platform/label/common/label'; import { dirname, basenameOrAuthority } from 'vs/base/common/resources'; import { getBaseLabel } from 'vs/base/common/labels'; @@ -300,7 +300,7 @@ class FileReferencesTemplate { constructor( container: HTMLElement, - @IUriLabelService private readonly _uriLabel: IUriLabelService, + @ILabelService private readonly _uriLabel: ILabelService, @IThemeService themeService: IThemeService, ) { const parent = document.createElement('div'); @@ -319,7 +319,7 @@ class FileReferencesTemplate { set(element: FileReferences) { let parent = dirname(element.uri); - this.file.setValue(getBaseLabel(element.uri), parent ? this._uriLabel.getLabel(parent, true) : undefined, { title: this._uriLabel.getLabel(element.uri) }); + this.file.setValue(getBaseLabel(element.uri), parent ? this._uriLabel.getUriLabel(parent, true) : undefined, { title: this._uriLabel.getUriLabel(element.uri) }); const len = element.children.length; this.badge.setCount(len); if (element.failure) { @@ -368,7 +368,7 @@ class Renderer implements tree.IRenderer { constructor( @IThemeService private readonly _themeService: IThemeService, - @IUriLabelService private readonly _uriLabel: IUriLabelService, + @ILabelService private readonly _uriLabel: ILabelService, ) { // } @@ -532,7 +532,7 @@ export class ReferenceWidget extends PeekViewWidget { @IThemeService themeService: IThemeService, @ITextModelService private _textModelResolverService: ITextModelService, @IInstantiationService private _instantiationService: IInstantiationService, - @IUriLabelService private _uriLabel: IUriLabelService + @ILabelService private _uriLabel: ILabelService ) { super(editor, { showFrame: false, showArrow: true, isResizeable: true, isAccessible: true }); @@ -778,7 +778,7 @@ export class ReferenceWidget extends PeekViewWidget { // Update widget header if (reference.uri.scheme !== Schemas.inMemory) { - this.setTitle(basenameOrAuthority(reference.uri), this._uriLabel.getLabel(dirname(reference.uri), false)); + this.setTitle(basenameOrAuthority(reference.uri), this._uriLabel.getUriLabel(dirname(reference.uri), false)); } else { this.setTitle(nls.localize('peekView.alternateTitle', "References")); } diff --git a/src/vs/editor/standalone/browser/simpleServices.ts b/src/vs/editor/standalone/browser/simpleServices.ts index 2bd024ca87d..fc453105c2c 100644 --- a/src/vs/editor/standalone/browser/simpleServices.ts +++ b/src/vs/editor/standalone/browser/simpleServices.ts @@ -45,7 +45,7 @@ import { WorkspaceEdit, isResourceTextEdit, TextEdit } from 'vs/editor/common/mo import { IModelService } from 'vs/editor/common/services/modelService'; import { EditOperation } from 'vs/editor/common/core/editOperation'; import { localize } from 'vs/nls'; -import { IUriLabelService, UriLabelRules } from 'vs/platform/uriLabel/common/uriLabel'; +import { ILabelService, UriLabelRules } from 'vs/platform/label/common/label'; export class SimpleModel implements ITextEditorModel { @@ -596,13 +596,13 @@ export class SimpleBulkEditService implements IBulkEditService { } } -export class SimpleUriLabelService implements IUriLabelService { +export class SimpleUriLabelService implements ILabelService { _serviceBrand: any; private readonly _onDidRegisterFormater: Emitter<{ scheme: string, formater: UriLabelRules }> = new Emitter<{ scheme: string, formater: UriLabelRules }>(); public readonly onDidRegisterFormater: Event<{ scheme: string, formater: UriLabelRules }> = this._onDidRegisterFormater.event; - public getLabel(resource: URI, relative?: boolean): string { + public getUriLabel(resource: URI, relative?: boolean): string { if (resource.scheme === 'file') { return resource.fsPath; } diff --git a/src/vs/editor/standalone/browser/standaloneServices.ts b/src/vs/editor/standalone/browser/standaloneServices.ts index d20dc25b60e..c6ca31a3c08 100644 --- a/src/vs/editor/standalone/browser/standaloneServices.ts +++ b/src/vs/editor/standalone/browser/standaloneServices.ts @@ -44,7 +44,7 @@ import { INotificationService } from 'vs/platform/notification/common/notificati import { IDialogService } from 'vs/platform/dialogs/common/dialogs'; import { IListService, ListService } from 'vs/platform/list/browser/listService'; import { IBulkEditService } from 'vs/editor/browser/services/bulkEditService'; -import { IUriLabelService } from 'vs/platform/uriLabel/common/uriLabel'; +import { ILabelService } from 'vs/platform/label/common/label'; export interface IEditorOverrideServices { [index: string]: any; @@ -122,7 +122,7 @@ export module StaticServices { export const contextService = define(IWorkspaceContextService, () => new SimpleWorkspaceContextService()); - export const uriLabelService = define(IUriLabelService, () => new SimpleUriLabelService()); + export const labelService = define(ILabelService, () => new SimpleUriLabelService()); export const telemetryService = define(ITelemetryService, () => new StandaloneTelemetryService()); diff --git a/src/vs/platform/history/electron-main/historyMainService.ts b/src/vs/platform/history/electron-main/historyMainService.ts index aaaeca45452..a3defec9a9a 100644 --- a/src/vs/platform/history/electron-main/historyMainService.ts +++ b/src/vs/platform/history/electron-main/historyMainService.ts @@ -21,7 +21,7 @@ import { RunOnceScheduler } from 'vs/base/common/async'; import { getComparisonKey, isEqual as areResourcesEqual, dirname } from 'vs/base/common/resources'; import URI, { UriComponents } from 'vs/base/common/uri'; import { Schemas } from 'vs/base/common/network'; -import { IUriLabelService } from 'vs/platform/uriLabel/common/uriLabel'; +import { ILabelService } from 'vs/platform/label/common/label'; interface ISerializedRecentlyOpened { workspaces2: (IWorkspaceIdentifier | string)[]; // IWorkspaceIdentifier or URI.toString() @@ -51,7 +51,7 @@ export class HistoryMainService implements IHistoryMainService { @IStateService private stateService: IStateService, @ILogService private logService: ILogService, @IWorkspacesMainService private workspacesMainService: IWorkspacesMainService, - @IUriLabelService private uriLabelService: IUriLabelService + @ILabelService private labelService: ILabelService ) { this.macOSRecentDocumentsUpdater = new RunOnceScheduler(() => this.updateMacOSRecentDocuments(), 800); @@ -366,11 +366,11 @@ export class HistoryMainService implements IHistoryMainService { type: 'custom', name: nls.localize('recentFolders', "Recent Workspaces"), items: this.getRecentlyOpened().workspaces.slice(0, 7 /* limit number of entries here */).map(workspace => { - const title = this.uriLabelService.getWorkspaceLabel(workspace); + const title = this.labelService.getWorkspaceLabel(workspace); let description; let args; if (isSingleFolderWorkspaceIdentifier(workspace)) { - description = nls.localize('folderDesc', "{0} {1}", getBaseLabel(workspace), this.uriLabelService.getLabel(dirname(workspace))); + description = nls.localize('folderDesc', "{0} {1}", getBaseLabel(workspace), this.labelService.getUriLabel(dirname(workspace))); args = `--folder-uri "${workspace.toString()}"`; } else { description = nls.localize('codeWorkspace', "Code Workspace"); diff --git a/src/vs/platform/uriLabel/common/uriLabel.ts b/src/vs/platform/label/common/label.ts similarity index 91% rename from src/vs/platform/uriLabel/common/uriLabel.ts rename to src/vs/platform/label/common/label.ts index 1212469e636..1348437a295 100644 --- a/src/vs/platform/uriLabel/common/uriLabel.ts +++ b/src/vs/platform/label/common/label.ts @@ -18,9 +18,9 @@ import { localize } from 'vs/nls'; import { isParent } from 'vs/platform/files/common/files'; import { basename, dirname, join } from 'vs/base/common/paths'; -export interface IUriLabelService { +export interface ILabelService { _serviceBrand: any; - getLabel(resource: URI, relative?: boolean, forceNoTildify?: boolean): string; + getUriLabel(resource: URI, relative?: boolean, forceNoTildify?: boolean): string; getWorkspaceLabel(workspace: (IWorkspaceIdentifier | ISingleFolderWorkspaceIdentifier | IWorkspace), options?: { verbose: boolean }): string; registerFormater(schema: string, formater: UriLabelRules): IDisposable; onDidRegisterFormater: Event<{ scheme: string, formater: UriLabelRules }>; @@ -33,7 +33,7 @@ export interface UriLabelRules { normalizeDriveLetter?: boolean; } -const URI_LABEL_SERVICE_ID = 'uriLabel'; +const LABEL_SERVICE_ID = 'label'; const sepRegexp = /\//g; const labelMatchingRegexp = /\$\{scheme\}|\$\{authority\}|\$\{path\}/g; @@ -41,7 +41,7 @@ function hasDriveLetter(path: string): boolean { return isWindows && path && path[2] === ':'; } -export class UriLabelService implements IUriLabelService { +export class LabelService implements ILabelService { _serviceBrand: any; private readonly formaters = new Map<string, UriLabelRules>(); @@ -56,7 +56,7 @@ export class UriLabelService implements IUriLabelService { return this._onDidRegisterFormater.event; } - getLabel(resource: URI, relative?: boolean, forceNoTildify?: boolean): string { + getUriLabel(resource: URI, relative?: boolean, forceNoTildify?: boolean): string { if (!resource) { return undefined; } @@ -100,7 +100,7 @@ export class UriLabelService implements IUriLabelService { // Workspace: Single Folder if (isSingleFolderWorkspaceIdentifier(workspace)) { // Folder on disk - return options && options.verbose ? this.getLabel(workspace) : basenameOrAuthority(workspace); + return options && options.verbose ? this.getUriLabel(workspace) : basenameOrAuthority(workspace); } // Workspace: Untitled @@ -112,7 +112,7 @@ export class UriLabelService implements IUriLabelService { const filename = basename(workspace.configPath); const workspaceName = filename.substr(0, filename.length - WORKSPACE_EXTENSION.length - 1); if (options && options.verbose) { - return localize('workspaceNameVerbose', "{0} (Workspace)", this.getLabel(URI.file(join(dirname(workspace.configPath), workspaceName)))); + return localize('workspaceNameVerbose', "{0} (Workspace)", this.getUriLabel(URI.file(join(dirname(workspace.configPath), workspaceName)))); } return localize('workspaceName', "{0} (Workspace)", workspaceName); @@ -150,4 +150,4 @@ export class UriLabelService implements IUriLabelService { } } -export const IUriLabelService = createDecorator<IUriLabelService>(URI_LABEL_SERVICE_ID); +export const ILabelService = createDecorator<ILabelService>(LABEL_SERVICE_ID); diff --git a/src/vs/platform/uriLabel/electron-browser/uriLabel.contribution.ts b/src/vs/platform/label/electron-browser/label.contribution.ts similarity index 68% rename from src/vs/platform/uriLabel/electron-browser/uriLabel.contribution.ts rename to src/vs/platform/label/electron-browser/label.contribution.ts index bbd24220002..f3b6c6ba189 100644 --- a/src/vs/platform/uriLabel/electron-browser/uriLabel.contribution.ts +++ b/src/vs/platform/label/electron-browser/label.contribution.ts @@ -4,7 +4,7 @@ *--------------------------------------------------------------------------------------------*/ import { IWorkbenchContribution, IWorkbenchContributionsRegistry, Extensions as WorkbenchExtensions } from 'vs/workbench/common/contributions'; -import { IUriLabelService } from 'vs/platform/uriLabel/common/uriLabel'; +import { ILabelService } from 'vs/platform/label/common/label'; import { ipcRenderer as ipc } from 'electron'; import { Registry } from 'vs/platform/registry/common/platform'; import { LifecyclePhase } from 'vs/platform/lifecycle/common/lifecycle'; @@ -13,13 +13,13 @@ import { LifecyclePhase } from 'vs/platform/lifecycle/common/lifecycle'; * Uri display registration needs to be shared from renderer to main. * Since there will be another instance of the uri display service running on main. */ -class UriLabelRegistrationContribution implements IWorkbenchContribution { +class LabelRegistrationContribution implements IWorkbenchContribution { - constructor(@IUriLabelService uriLabelService: IUriLabelService) { - uriLabelService.onDidRegisterFormater(data => { - ipc.send('vscode:uriLabelRegisterFormater', data); + constructor(@ILabelService labelService: ILabelService) { + labelService.onDidRegisterFormater(data => { + ipc.send('vscode:labelRegisterFormater', data); }); } } -Registry.as<IWorkbenchContributionsRegistry>(WorkbenchExtensions.Workbench).registerWorkbenchContribution(UriLabelRegistrationContribution, LifecyclePhase.Starting); +Registry.as<IWorkbenchContributionsRegistry>(WorkbenchExtensions.Workbench).registerWorkbenchContribution(LabelRegistrationContribution, LifecyclePhase.Starting); diff --git a/src/vs/platform/uriLabel/test/uriLabel.test.ts b/src/vs/platform/label/test/uriLabel.test.ts similarity index 72% rename from src/vs/platform/uriLabel/test/uriLabel.test.ts rename to src/vs/platform/label/test/uriLabel.test.ts index 6efc8d528e9..f1d9f85b72a 100644 --- a/src/vs/platform/uriLabel/test/uriLabel.test.ts +++ b/src/vs/platform/label/test/uriLabel.test.ts @@ -4,7 +4,7 @@ *--------------------------------------------------------------------------------------------*/ import * as assert from 'assert'; -import { UriLabelService } from 'vs/platform/uriLabel/common/uriLabel'; +import { LabelService } from 'vs/platform/label/common/label'; import { TestEnvironmentService, TestContextService } from 'vs/workbench/test/workbenchTestServices'; import { Schemas } from 'vs/base/common/network'; import { TestWorkspace } from 'vs/platform/workspace/test/common/testWorkspace'; @@ -14,14 +14,14 @@ import { isWindows } from 'vs/base/common/platform'; suite('URI Label', () => { - let uriLabelService: UriLabelService; + let labelService: LabelService; setup(() => { - uriLabelService = new UriLabelService(TestEnvironmentService, new TestContextService()); + labelService = new LabelService(TestEnvironmentService, new TestContextService()); }); test('file scheme', function () { - uriLabelService.registerFormater(Schemas.file, { + labelService.registerFormater(Schemas.file, { label: '${path}', separator: nativeSep, tildify: !isWindows, @@ -29,15 +29,15 @@ suite('URI Label', () => { }); const uri1 = TestWorkspace.folders[0].uri.with({ path: TestWorkspace.folders[0].uri.path.concat('/a/b/c/d') }); - assert.equal(uriLabelService.getLabel(uri1, true), isWindows ? 'a\\b\\c\\d' : 'a/b/c/d'); - assert.equal(uriLabelService.getLabel(uri1, false), isWindows ? 'C:\\testWorkspace\\a\\b\\c\\d' : '/testWorkspace/a/b/c/d'); + assert.equal(labelService.getUriLabel(uri1, true), isWindows ? 'a\\b\\c\\d' : 'a/b/c/d'); + assert.equal(labelService.getUriLabel(uri1, false), isWindows ? 'C:\\testWorkspace\\a\\b\\c\\d' : '/testWorkspace/a/b/c/d'); const uri2 = URI.file('c:\\1/2/3'); - assert.equal(uriLabelService.getLabel(uri2, false), isWindows ? 'C:\\1\\2\\3' : '/c:\\1/2/3'); + assert.equal(labelService.getUriLabel(uri2, false), isWindows ? 'C:\\1\\2\\3' : '/c:\\1/2/3'); }); test('custom scheme', function () { - uriLabelService.registerFormater(Schemas.vscode, { + labelService.registerFormater(Schemas.vscode, { label: 'LABEL/${path}/${authority}/END', separator: '/', tildify: true, @@ -45,6 +45,6 @@ suite('URI Label', () => { }); const uri1 = URI.parse('vscode://microsoft.com/1/2/3/4/5'); - assert.equal(uriLabelService.getLabel(uri1, false), 'LABEL//1/2/3/4/5/microsoft.com/END'); + assert.equal(labelService.getUriLabel(uri1, false), 'LABEL//1/2/3/4/5/microsoft.com/END'); }); }); diff --git a/src/vs/workbench/api/electron-browser/mainThreadFileSystem.ts b/src/vs/workbench/api/electron-browser/mainThreadFileSystem.ts index 164d458a3ed..b448699381b 100644 --- a/src/vs/workbench/api/electron-browser/mainThreadFileSystem.ts +++ b/src/vs/workbench/api/electron-browser/mainThreadFileSystem.ts @@ -11,7 +11,7 @@ import { TPromise } from 'vs/base/common/winjs.base'; import { FileWriteOptions, FileSystemProviderCapabilities, IFileChange, IFileService, IFileSystemProvider, IStat, IWatchOptions, FileType, FileOverwriteOptions, FileDeleteOptions } from 'vs/platform/files/common/files'; import { extHostNamedCustomer } from 'vs/workbench/api/electron-browser/extHostCustomers'; import { ExtHostContext, ExtHostFileSystemShape, IExtHostContext, IFileChangeDto, MainContext, MainThreadFileSystemShape } from '../node/extHost.protocol'; -import { UriLabelRules, IUriLabelService } from 'vs/platform/uriLabel/common/uriLabel'; +import { UriLabelRules, ILabelService } from 'vs/platform/label/common/label'; @extHostNamedCustomer(MainContext.MainThreadFileSystem) export class MainThreadFileSystem implements MainThreadFileSystemShape { @@ -22,7 +22,7 @@ export class MainThreadFileSystem implements MainThreadFileSystemShape { constructor( extHostContext: IExtHostContext, @IFileService private readonly _fileService: IFileService, - @IUriLabelService private readonly _uriLabelService: IUriLabelService + @ILabelService private readonly _labelService: ILabelService ) { this._proxy = extHostContext.getProxy(ExtHostContext.ExtHostFileSystem); } @@ -42,7 +42,7 @@ export class MainThreadFileSystem implements MainThreadFileSystemShape { } $setUriFormatter(scheme: string, formatter: UriLabelRules): void { - this._uriLabelService.registerFormater(scheme, formatter); + this._labelService.registerFormater(scheme, formatter); } $onFileSystemChange(handle: number, changes: IFileChangeDto[]): void { diff --git a/src/vs/workbench/api/electron-browser/mainThreadWorkspace.ts b/src/vs/workbench/api/electron-browser/mainThreadWorkspace.ts index 03f782d04e2..4f072168bc2 100644 --- a/src/vs/workbench/api/electron-browser/mainThreadWorkspace.ts +++ b/src/vs/workbench/api/electron-browser/mainThreadWorkspace.ts @@ -23,7 +23,7 @@ import { CommandsRegistry } from 'vs/platform/commands/common/commands'; import { IExtensionService } from 'vs/workbench/services/extensions/common/extensions'; import { areSameExtensions } from 'vs/platform/extensionManagement/common/extensionManagementUtil'; import { IWindowService } from 'vs/platform/windows/common/windows'; -import { IUriLabelService } from 'vs/platform/uriLabel/common/uriLabel'; +import { ILabelService } from 'vs/platform/label/common/label'; @extHostNamedCustomer(MainContext.MainThreadWorkspace) export class MainThreadWorkspace implements MainThreadWorkspaceShape { @@ -41,7 +41,7 @@ export class MainThreadWorkspace implements MainThreadWorkspaceShape { @IWorkspaceEditingService private readonly _workspaceEditingService: IWorkspaceEditingService, @IStatusbarService private readonly _statusbarService: IStatusbarService, @IInstantiationService private readonly _instantiationService: IInstantiationService, - @IUriLabelService private readonly _uriLabelService: IUriLabelService + @ILabelService private readonly _labelService: ILabelService ) { this._proxy = extHostContext.getProxy(ExtHostContext.ExtHostWorkspace); this._contextService.onDidChangeWorkspaceFolders(this._onDidChangeWorkspace, this, this._toDispose); @@ -106,7 +106,7 @@ export class MainThreadWorkspace implements MainThreadWorkspaceShape { configuration: workspace.configuration, folders: workspace.folders, id: workspace.id, - name: this._uriLabelService.getWorkspaceLabel(workspace) + name: this._labelService.getWorkspaceLabel(workspace) } : null); } diff --git a/src/vs/workbench/api/node/extHost.protocol.ts b/src/vs/workbench/api/node/extHost.protocol.ts index edb764542ad..d4dd60c6d53 100644 --- a/src/vs/workbench/api/node/extHost.protocol.ts +++ b/src/vs/workbench/api/node/extHost.protocol.ts @@ -40,7 +40,7 @@ import { IExtensionDescription } from 'vs/workbench/services/extensions/common/e import { createExtHostContextProxyIdentifier as createExtId, createMainContextProxyIdentifier as createMainId, IRPCProtocol, ProxyIdentifier } from 'vs/workbench/services/extensions/node/proxyIdentifier'; import { IProgressOptions, IProgressStep } from 'vs/workbench/services/progress/common/progress'; import { SaveReason } from 'vs/workbench/services/textfile/common/textfiles'; -import { UriLabelRules } from 'vs/platform/uriLabel/common/uriLabel'; +import { UriLabelRules } from 'vs/platform/label/common/label'; import * as vscode from 'vscode'; export interface IEnvironment { diff --git a/src/vs/workbench/api/node/extHostFileSystem.ts b/src/vs/workbench/api/node/extHostFileSystem.ts index 732d21cd761..74f9610976f 100644 --- a/src/vs/workbench/api/node/extHostFileSystem.ts +++ b/src/vs/workbench/api/node/extHostFileSystem.ts @@ -15,7 +15,7 @@ import { values } from 'vs/base/common/map'; import { Range, FileChangeType } from 'vs/workbench/api/node/extHostTypes'; import { ExtHostLanguageFeatures } from 'vs/workbench/api/node/extHostLanguageFeatures'; import { Schemas } from 'vs/base/common/network'; -import { UriLabelRules } from 'vs/platform/uriLabel/common/uriLabel'; +import { UriLabelRules } from 'vs/platform/label/common/label'; class FsLinkProvider implements vscode.DocumentLinkProvider { diff --git a/src/vs/workbench/browser/actions/workspaceCommands.ts b/src/vs/workbench/browser/actions/workspaceCommands.ts index 055f30bd49d..20cb58d1da7 100644 --- a/src/vs/workbench/browser/actions/workspaceCommands.ts +++ b/src/vs/workbench/browser/actions/workspaceCommands.ts @@ -22,7 +22,7 @@ import { FileKind, isParent } from 'vs/platform/files/common/files'; import { IEnvironmentService } from 'vs/platform/environment/common/environment'; import { ServicesAccessor } from 'vs/platform/instantiation/common/instantiation'; import { isLinux } from 'vs/base/common/platform'; -import { IUriLabelService } from 'vs/platform/uriLabel/common/uriLabel'; +import { ILabelService } from 'vs/platform/label/common/label'; import { IQuickInputService, IPickOptions, IQuickPickItem } from 'vs/platform/quickinput/common/quickInput'; import { getIconClasses } from 'vs/workbench/browser/labels'; import { IModelService } from 'vs/editor/common/services/modelService'; @@ -163,7 +163,7 @@ CommandsRegistry.registerCommand({ CommandsRegistry.registerCommand(PICK_WORKSPACE_FOLDER_COMMAND_ID, function (accessor, args?: [IPickOptions<IQuickPickItem>, CancellationToken]) { const quickInputService = accessor.get(IQuickInputService); - const uriLabelService = accessor.get(IUriLabelService); + const labelService = accessor.get(ILabelService); const contextService = accessor.get(IWorkspaceContextService); const modelService = accessor.get(IModelService); const modeService = accessor.get(IModeService); @@ -176,7 +176,7 @@ CommandsRegistry.registerCommand(PICK_WORKSPACE_FOLDER_COMMAND_ID, function (acc const folderPicks = folders.map(folder => { return { label: folder.name, - description: uriLabelService.getLabel(resources.dirname(folder.uri), true), + description: labelService.getUriLabel(resources.dirname(folder.uri), true), folder, iconClasses: getIconClasses(modelService, modeService, folder.uri, FileKind.ROOT_FOLDER) } as IQuickPickItem; diff --git a/src/vs/workbench/browser/labels.ts b/src/vs/workbench/browser/labels.ts index 7a1b6e0aedc..fa7213df83f 100644 --- a/src/vs/workbench/browser/labels.ts +++ b/src/vs/workbench/browser/labels.ts @@ -23,7 +23,7 @@ import { ITextModel } from 'vs/editor/common/model'; import { IThemeService } from 'vs/platform/theme/common/themeService'; import { Event, Emitter } from 'vs/base/common/event'; import { DataUri } from 'vs/workbench/common/resources'; -import { IUriLabelService } from 'vs/platform/uriLabel/common/uriLabel'; +import { ILabelService } from 'vs/platform/label/common/label'; export interface IResourceLabel { name: string; @@ -56,7 +56,7 @@ export class ResourceLabel extends IconLabel { @IModelService private modelService: IModelService, @IDecorationsService protected decorationsService: IDecorationsService, @IThemeService private themeService: IThemeService, - @IUriLabelService protected uriLabelService: IUriLabelService + @ILabelService protected labelService: ILabelService ) { super(container, options); @@ -191,7 +191,7 @@ export class ResourceLabel extends IconLabel { iconLabelOptions.title = this.options.title; } else if (resource && resource.scheme !== Schemas.data /* do not accidentally inline Data URIs */) { if (!this.computedPathLabel) { - this.computedPathLabel = this.uriLabelService.getLabel(resource); + this.computedPathLabel = this.labelService.getUriLabel(resource); } iconLabelOptions.title = this.computedPathLabel; @@ -274,9 +274,9 @@ export class FileLabel extends ResourceLabel { @IDecorationsService decorationsService: IDecorationsService, @IThemeService themeService: IThemeService, @IUntitledEditorService private untitledEditorService: IUntitledEditorService, - @IUriLabelService uriLabelService: IUriLabelService + @ILabelService labelService: ILabelService ) { - super(container, options, extensionService, configurationService, modeService, modelService, decorationsService, themeService, uriLabelService); + super(container, options, extensionService, configurationService, modeService, modelService, decorationsService, themeService, labelService); } setFile(resource: uri, options?: IFileLabelOptions): void { @@ -298,7 +298,7 @@ export class FileLabel extends ResourceLabel { let description: string; const hidePath = (options && options.hidePath) || (resource.scheme === Schemas.untitled && !this.untitledEditorService.hasAssociatedFilePath(resource)); if (!hidePath) { - description = this.uriLabelService.getLabel(resources.dirname(resource), true); + description = this.labelService.getUriLabel(resources.dirname(resource), true); } this.setLabel({ resource, name, description }, options); diff --git a/src/vs/workbench/browser/parts/quickopen/quickOpenController.ts b/src/vs/workbench/browser/parts/quickopen/quickOpenController.ts index 428a391e24b..279febbdff1 100644 --- a/src/vs/workbench/browser/parts/quickopen/quickOpenController.ts +++ b/src/vs/workbench/browser/parts/quickopen/quickOpenController.ts @@ -49,7 +49,7 @@ import { INotificationService } from 'vs/platform/notification/common/notificati import { Dimension, addClass } from 'vs/base/browser/dom'; import { IEditorService, ACTIVE_GROUP, SIDE_GROUP } from 'vs/workbench/services/editor/common/editorService'; import { IEditorGroupsService } from 'vs/workbench/services/group/common/editorGroupsService'; -import { IUriLabelService } from 'vs/platform/uriLabel/common/uriLabel'; +import { ILabelService } from 'vs/platform/label/common/label'; import { timeout } from 'vs/base/common/async'; import { IQuickInputService, IQuickPickItem } from 'vs/platform/quickinput/common/quickInput'; @@ -684,7 +684,7 @@ export class EditorHistoryEntry extends EditorQuickOpenEntry { @IModelService private modelService: IModelService, @ITextFileService private textFileService: ITextFileService, @IConfigurationService private configurationService: IConfigurationService, - @IUriLabelService uriLabelService: IUriLabelService, + @ILabelService labelService: ILabelService, @IFileService fileService: IFileService ) { super(editorService); @@ -700,7 +700,7 @@ export class EditorHistoryEntry extends EditorQuickOpenEntry { const resourceInput = input as IResourceInput; this.resource = resourceInput.resource; this.label = resources.basenameOrAuthority(resourceInput.resource); - this.description = uriLabelService.getLabel(resources.dirname(this.resource), true); + this.description = labelService.getUriLabel(resources.dirname(this.resource), true); this.dirty = this.resource && this.textFileService.isDirty(this.resource); if (this.dirty && this.textFileService.getAutoSaveMode() === AutoSaveMode.AFTER_SHORT_DELAY) { diff --git a/src/vs/workbench/browser/parts/titlebar/menubarControl.ts b/src/vs/workbench/browser/parts/titlebar/menubarControl.ts index 676e4ab348a..dbcb3c29de4 100644 --- a/src/vs/workbench/browser/parts/titlebar/menubarControl.ts +++ b/src/vs/workbench/browser/parts/titlebar/menubarControl.ts @@ -29,7 +29,7 @@ import { IWorkspaceIdentifier, ISingleFolderWorkspaceIdentifier, isSingleFolderW import { RunOnceScheduler } from 'vs/base/common/async'; import { MENUBAR_SELECTION_FOREGROUND, MENUBAR_SELECTION_BACKGROUND, MENUBAR_SELECTION_BORDER, TITLE_BAR_ACTIVE_FOREGROUND, TITLE_BAR_INACTIVE_FOREGROUND, MENU_BACKGROUND, MENU_FOREGROUND, MENU_SELECTION_BACKGROUND, MENU_SELECTION_FOREGROUND, MENU_SELECTION_BORDER } from 'vs/workbench/common/theme'; import URI from 'vs/base/common/uri'; -import { IUriLabelService } from 'vs/platform/uriLabel/common/uriLabel'; +import { ILabelService } from 'vs/platform/label/common/label'; import { foreground } from 'vs/platform/theme/common/colorRegistry'; import { IUpdateService, StateType } from 'vs/platform/update/common/update'; @@ -121,7 +121,7 @@ export class MenubarControl extends Disposable { @IContextKeyService private contextKeyService: IContextKeyService, @IKeybindingService private keybindingService: IKeybindingService, @IConfigurationService private configurationService: IConfigurationService, - @IUriLabelService private uriLabelService: IUriLabelService, + @ILabelService private labelService: ILabelService, @IUpdateService private updateService: IUpdateService ) { @@ -531,14 +531,14 @@ export class MenubarControl extends Disposable { let uri: URI; if (isSingleFolderWorkspaceIdentifier(workspace) && !isFile) { - label = this.uriLabelService.getWorkspaceLabel(workspace, { verbose: true }); + label = this.labelService.getWorkspaceLabel(workspace, { verbose: true }); uri = workspace; } else if (isWorkspaceIdentifier(workspace)) { - label = this.uriLabelService.getWorkspaceLabel(workspace, { verbose: true }); + label = this.labelService.getWorkspaceLabel(workspace, { verbose: true }); uri = URI.file(workspace.configPath); } else { uri = workspace; - label = this.uriLabelService.getLabel(uri); + label = this.labelService.getUriLabel(uri); } return new Action(commandId, label, undefined, undefined, (event) => { diff --git a/src/vs/workbench/browser/parts/titlebar/titlebarPart.ts b/src/vs/workbench/browser/parts/titlebar/titlebarPart.ts index 597f47f2881..dffc7b7dcdf 100644 --- a/src/vs/workbench/browser/parts/titlebar/titlebarPart.ts +++ b/src/vs/workbench/browser/parts/titlebar/titlebarPart.ts @@ -34,7 +34,7 @@ import { addDisposableListener, EventType, EventHelper, Dimension } from 'vs/bas import { MenubarControl } from 'vs/workbench/browser/parts/titlebar/menubarControl'; import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; import { template, getBaseLabel } from 'vs/base/common/labels'; -import { IUriLabelService } from 'vs/platform/uriLabel/common/uriLabel'; +import { ILabelService } from 'vs/platform/label/common/label'; import { Event } from 'vs/base/common/event'; export class TitlebarPart extends Part implements ITitleService { @@ -84,7 +84,7 @@ export class TitlebarPart extends Part implements ITitleService { @IWorkspaceContextService private contextService: IWorkspaceContextService, @IInstantiationService private instantiationService: IInstantiationService, @IThemeService themeService: IThemeService, - @IUriLabelService private uriLabelService: IUriLabelService + @ILabelService private labelService: ILabelService ) { super(id, { hasTitle: false }, themeService); @@ -243,10 +243,10 @@ export class TitlebarPart extends Part implements ITitleService { const activeEditorShort = editor ? editor.getTitle(Verbosity.SHORT) : ''; const activeEditorMedium = editor ? editor.getTitle(Verbosity.MEDIUM) : activeEditorShort; const activeEditorLong = editor ? editor.getTitle(Verbosity.LONG) : activeEditorMedium; - const rootName = root ? this.uriLabelService.getWorkspaceLabel(root) : ''; - const rootPath = root ? this.uriLabelService.getLabel(root) : ''; + const rootName = root ? this.labelService.getWorkspaceLabel(root) : ''; + const rootPath = root ? this.labelService.getUriLabel(root) : ''; const folderName = folder ? folder.name : ''; - const folderPath = folder ? this.uriLabelService.getLabel(folder.uri) : ''; + const folderPath = folder ? this.labelService.getUriLabel(folder.uri) : ''; const dirty = editor && editor.isDirty() ? TitlebarPart.TITLE_DIRTY : ''; const appName = this.environmentService.appNameLong; const separator = TitlebarPart.TITLE_SEPARATOR; diff --git a/src/vs/workbench/common/editor/untitledEditorInput.ts b/src/vs/workbench/common/editor/untitledEditorInput.ts index 93d3f05fdec..cdd5ab7c14d 100644 --- a/src/vs/workbench/common/editor/untitledEditorInput.ts +++ b/src/vs/workbench/common/editor/untitledEditorInput.ts @@ -18,7 +18,7 @@ import { Event, Emitter } from 'vs/base/common/event'; import { ITextFileService } from 'vs/workbench/services/textfile/common/textfiles'; import { telemetryURIDescriptor } from 'vs/platform/telemetry/common/telemetryUtils'; import { IHashService } from 'vs/workbench/services/hash/common/hashService'; -import { IUriLabelService } from 'vs/platform/uriLabel/common/uriLabel'; +import { ILabelService } from 'vs/platform/label/common/label'; /** * An editor input to be used for untitled text buffers. @@ -46,7 +46,7 @@ export class UntitledEditorInput extends EditorInput implements IEncodingSupport @IInstantiationService private instantiationService: IInstantiationService, @ITextFileService private textFileService: ITextFileService, @IHashService private hashService: IHashService, - @IUriLabelService private uriLabelService: IUriLabelService + @ILabelService private labelService: ILabelService ) { super(); @@ -79,17 +79,17 @@ export class UntitledEditorInput extends EditorInput implements IEncodingSupport @memoize private get shortDescription(): string { - return paths.basename(this.uriLabelService.getLabel(resources.dirname(this.resource))); + return paths.basename(this.labelService.getUriLabel(resources.dirname(this.resource))); } @memoize private get mediumDescription(): string { - return this.uriLabelService.getLabel(resources.dirname(this.resource), true); + return this.labelService.getUriLabel(resources.dirname(this.resource), true); } @memoize private get longDescription(): string { - return this.uriLabelService.getLabel(resources.dirname(this.resource)); + return this.labelService.getUriLabel(resources.dirname(this.resource)); } getDescription(verbosity: Verbosity = Verbosity.MEDIUM): string { @@ -121,12 +121,12 @@ export class UntitledEditorInput extends EditorInput implements IEncodingSupport @memoize private get mediumTitle(): string { - return this.uriLabelService.getLabel(this.resource, true); + return this.labelService.getUriLabel(this.resource, true); } @memoize private get longTitle(): string { - return this.uriLabelService.getLabel(this.resource); + return this.labelService.getUriLabel(this.resource); } getTitle(verbosity: Verbosity): string { diff --git a/src/vs/workbench/electron-browser/actions.ts b/src/vs/workbench/electron-browser/actions.ts index 33500ca8c7e..64f774f9f35 100644 --- a/src/vs/workbench/electron-browser/actions.ts +++ b/src/vs/workbench/electron-browser/actions.ts @@ -40,7 +40,7 @@ import { IContextKeyService } from 'vs/platform/contextkey/common/contextkey'; import { Context } from 'vs/platform/contextkey/browser/contextKeyService'; import { IWorkbenchIssueService } from 'vs/workbench/services/issue/common/issue'; import { INotificationService } from 'vs/platform/notification/common/notification'; -import { IUriLabelService } from 'vs/platform/uriLabel/common/uriLabel'; +import { ILabelService } from 'vs/platform/label/common/label'; import { dirname } from 'vs/base/common/resources'; import { IModelService } from 'vs/editor/common/services/modelService'; import { IModeService } from 'vs/editor/common/services/modeService'; @@ -418,7 +418,7 @@ export abstract class BaseOpenRecentAction extends Action { private quickInputService: IQuickInputService, private contextService: IWorkspaceContextService, private environmentService: IEnvironmentService, - private uriLabelService: IUriLabelService, + private labelService: ILabelService, private keybindingService: IKeybindingService, private modelService: IModelService, private modeService: IModeService, @@ -435,22 +435,22 @@ export abstract class BaseOpenRecentAction extends Action { private openRecent(recentWorkspaces: (IWorkspaceIdentifier | ISingleFolderWorkspaceIdentifier)[], recentFiles: URI[]): void { - const toPick = (workspace: IWorkspaceIdentifier | ISingleFolderWorkspaceIdentifier | URI, fileKind: FileKind, environmentService: IEnvironmentService, uriLabelService: IUriLabelService, buttons: IQuickInputButton[]) => { + const toPick = (workspace: IWorkspaceIdentifier | ISingleFolderWorkspaceIdentifier | URI, fileKind: FileKind, environmentService: IEnvironmentService, labelService: ILabelService, buttons: IQuickInputButton[]) => { let resource: URI; let label: string; let description: string; if (isSingleFolderWorkspaceIdentifier(workspace) && fileKind !== FileKind.FILE) { resource = workspace; - label = uriLabelService.getWorkspaceLabel(workspace); - description = uriLabelService.getLabel(dirname(resource)); + label = labelService.getWorkspaceLabel(workspace); + description = labelService.getUriLabel(dirname(resource)); } else if (isWorkspaceIdentifier(workspace)) { resource = URI.file(workspace.configPath); - label = uriLabelService.getWorkspaceLabel(workspace); - description = uriLabelService.getLabel(dirname(resource)); + label = labelService.getWorkspaceLabel(workspace); + description = labelService.getUriLabel(dirname(resource)); } else { resource = workspace; label = getBaseLabel(workspace); - description = uriLabelService.getLabel(dirname(resource)); + description = labelService.getUriLabel(dirname(resource)); } return { @@ -469,8 +469,8 @@ export abstract class BaseOpenRecentAction extends Action { return this.windowService.openWindow([resource], { forceNewWindow, forceOpenWorkspaceAsFile: isFile }); }; - const workspacePicks = recentWorkspaces.map(workspace => toPick(workspace, isSingleFolderWorkspaceIdentifier(workspace) ? FileKind.FOLDER : FileKind.ROOT_FOLDER, this.environmentService, this.uriLabelService, !this.isQuickNavigate() ? [this.removeFromRecentlyOpened] : void 0)); - const filePicks = recentFiles.map(p => toPick(p, FileKind.FILE, this.environmentService, this.uriLabelService, !this.isQuickNavigate() ? [this.removeFromRecentlyOpened] : void 0)); + const workspacePicks = recentWorkspaces.map(workspace => toPick(workspace, isSingleFolderWorkspaceIdentifier(workspace) ? FileKind.FOLDER : FileKind.ROOT_FOLDER, this.environmentService, this.labelService, !this.isQuickNavigate() ? [this.removeFromRecentlyOpened] : void 0)); + const filePicks = recentFiles.map(p => toPick(p, FileKind.FILE, this.environmentService, this.labelService, !this.isQuickNavigate() ? [this.removeFromRecentlyOpened] : void 0)); // focus second entry if the first recent workspace is the current workspace let autoFocusSecondEntry: boolean = recentWorkspaces[0] && this.contextService.isCurrentWorkspace(recentWorkspaces[0]); @@ -518,9 +518,9 @@ export class OpenRecentAction extends BaseOpenRecentAction { @IKeybindingService keybindingService: IKeybindingService, @IModelService modelService: IModelService, @IModeService modeService: IModeService, - @IUriLabelService uriLabelService: IUriLabelService + @ILabelService labelService: ILabelService ) { - super(id, label, windowService, windowsService, quickInputService, contextService, environmentService, uriLabelService, keybindingService, modelService, modeService); + super(id, label, windowService, windowsService, quickInputService, contextService, environmentService, labelService, keybindingService, modelService, modeService); } protected isQuickNavigate(): boolean { @@ -544,9 +544,9 @@ export class QuickOpenRecentAction extends BaseOpenRecentAction { @IKeybindingService keybindingService: IKeybindingService, @IModelService modelService: IModelService, @IModeService modeService: IModeService, - @IUriLabelService uriLabelService: IUriLabelService + @ILabelService labelService: ILabelService ) { - super(id, label, windowService, windowsService, quickInputService, contextService, environmentService, uriLabelService, keybindingService, modelService, modeService); + super(id, label, windowService, windowsService, quickInputService, contextService, environmentService, labelService, keybindingService, modelService, modeService); } protected isQuickNavigate(): boolean { diff --git a/src/vs/workbench/electron-browser/shell.ts b/src/vs/workbench/electron-browser/shell.ts index 4b366a0299c..b6db73f5201 100644 --- a/src/vs/workbench/electron-browser/shell.ts +++ b/src/vs/workbench/electron-browser/shell.ts @@ -98,7 +98,7 @@ import { ExtensionManagementServerService } from 'vs/workbench/services/extensio import { DownloadServiceChannel } from 'vs/platform/download/node/downloadIpc'; import { DefaultURITransformer } from 'vs/base/common/uriIpc'; import { ExtensionGalleryService } from 'vs/platform/extensionManagement/node/extensionGalleryService'; -import { IUriLabelService } from 'vs/platform/uriLabel/common/uriLabel'; +import { ILabelService } from 'vs/platform/label/common/label'; /** * Services that we require for the Shell @@ -118,7 +118,7 @@ export interface ICoreServices { export class WorkbenchShell extends Disposable { private storageService: IStorageService; private environmentService: IEnvironmentService; - private uriLabelService: IUriLabelService; + private labelService: ILabelService; private logService: ILogService; private configurationService: IConfigurationService; private contextService: IWorkspaceContextService; @@ -318,7 +318,7 @@ export class WorkbenchShell extends Disposable { serviceCollection.set(IWorkspaceContextService, this.contextService); serviceCollection.set(IConfigurationService, this.configurationService); serviceCollection.set(IEnvironmentService, this.environmentService); - serviceCollection.set(IUriLabelService, this.uriLabelService); + serviceCollection.set(ILabelService, this.labelService); serviceCollection.set(ILogService, this._register(this.logService)); serviceCollection.set(IStorageService, this.storageService); diff --git a/src/vs/workbench/electron-browser/workbench.ts b/src/vs/workbench/electron-browser/workbench.ts index 851611cc3b3..5b8ee0b77fc 100644 --- a/src/vs/workbench/electron-browser/workbench.ts +++ b/src/vs/workbench/electron-browser/workbench.ts @@ -116,7 +116,7 @@ import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry'; import { TelemetryService } from 'vs/platform/telemetry/common/telemetryService'; import { WorkbenchThemeService } from 'vs/workbench/services/themes/electron-browser/workbenchThemeService'; import { IWorkbenchThemeService } from 'vs/workbench/services/themes/common/workbenchThemeService'; -import { UriLabelService, IUriLabelService } from 'vs/platform/uriLabel/common/uriLabel'; +import { LabelService, ILabelService } from 'vs/platform/label/common/label'; interface WorkbenchParams { configuration: IWindowConfiguration; @@ -337,8 +337,8 @@ export class Workbench extends Disposable implements IPartService { serviceCollection.set(IClipboardService, new ClipboardService()); // Uri Display - const uriLabelService = new UriLabelService(this.environmentService, this.contextService); - serviceCollection.set(IUriLabelService, uriLabelService); + const labelService = new LabelService(this.environmentService, this.contextService); + serviceCollection.set(ILabelService, labelService); // Status bar this.statusbarPart = this.instantiationService.createInstance(StatusbarPart, Identifiers.STATUSBAR_PART); diff --git a/src/vs/workbench/parts/debug/browser/breakpointsView.ts b/src/vs/workbench/parts/debug/browser/breakpointsView.ts index 45f200e54b0..dd75a8196d4 100644 --- a/src/vs/workbench/parts/debug/browser/breakpointsView.ts +++ b/src/vs/workbench/parts/debug/browser/breakpointsView.ts @@ -32,7 +32,7 @@ import { IConfigurationService } from 'vs/platform/configuration/common/configur import { ITextFileService } from 'vs/workbench/services/textfile/common/textfiles'; import { IEditorService, SIDE_GROUP, ACTIVE_GROUP } from 'vs/workbench/services/editor/common/editorService'; import { ViewletPanel, IViewletPanelOptions } from 'vs/workbench/browser/parts/views/panelViewlet'; -import { IUriLabelService } from 'vs/platform/uriLabel/common/uriLabel'; +import { ILabelService } from 'vs/platform/label/common/label'; const $ = dom.$; @@ -296,7 +296,7 @@ class BreakpointsRenderer implements IRenderer<IBreakpoint, IBreakpointTemplateD constructor( @IDebugService private debugService: IDebugService, - @IUriLabelService private uriLabelService: IUriLabelService, + @ILabelService private labelService: ILabelService, @ITextFileService private textFileService: ITextFileService ) { // noop @@ -340,7 +340,7 @@ class BreakpointsRenderer implements IRenderer<IBreakpoint, IBreakpointTemplateD if (breakpoint.column) { data.lineNumber.textContent += `:${breakpoint.column}`; } - data.filePath.textContent = this.uriLabelService.getLabel(resources.dirname(breakpoint.uri), true); + data.filePath.textContent = this.labelService.getUriLabel(resources.dirname(breakpoint.uri), true); data.checkbox.checked = breakpoint.enabled; const { message, className } = getBreakpointMessageAndClassName(this.debugService, this.textFileService, breakpoint); diff --git a/src/vs/workbench/parts/debug/electron-browser/callStackView.ts b/src/vs/workbench/parts/debug/electron-browser/callStackView.ts index 0298950898c..19e41a6c3c3 100644 --- a/src/vs/workbench/parts/debug/electron-browser/callStackView.ts +++ b/src/vs/workbench/parts/debug/electron-browser/callStackView.ts @@ -27,7 +27,7 @@ import { IConfigurationService } from 'vs/platform/configuration/common/configur import { Separator } from 'vs/base/browser/ui/actionbar/actionbar'; import { IContextKey, IContextKeyService } from 'vs/platform/contextkey/common/contextkey'; import { IViewletPanelOptions } from 'vs/workbench/browser/parts/views/panelViewlet'; -import { IUriLabelService } from 'vs/platform/uriLabel/common/uriLabel'; +import { ILabelService } from 'vs/platform/label/common/label'; import { Session } from 'vs/workbench/parts/debug/electron-browser/debugSession'; const $ = dom.$; @@ -399,7 +399,7 @@ class CallStackRenderer implements IRenderer { constructor( @IWorkspaceContextService private contextService: IWorkspaceContextService, - @IUriLabelService private uriLabelService: IUriLabelService + @ILabelService private labelService: ILabelService ) { // noop } @@ -518,7 +518,7 @@ class CallStackRenderer implements IRenderer { dom.toggleClass(data.stackFrame, 'label', stackFrame.presentationHint === 'label'); dom.toggleClass(data.stackFrame, 'subtle', stackFrame.presentationHint === 'subtle'); - data.file.title = stackFrame.source.inMemory ? stackFrame.source.name : this.uriLabelService.getLabel(stackFrame.source.uri); + data.file.title = stackFrame.source.inMemory ? stackFrame.source.name : this.labelService.getUriLabel(stackFrame.source.uri); if (stackFrame.source.raw.origin) { data.file.title += `\n${stackFrame.source.raw.origin}`; } diff --git a/src/vs/workbench/parts/debug/electron-browser/replViewer.ts b/src/vs/workbench/parts/debug/electron-browser/replViewer.ts index e354f781465..cbc0efa5f74 100644 --- a/src/vs/workbench/parts/debug/electron-browser/replViewer.ts +++ b/src/vs/workbench/parts/debug/electron-browser/replViewer.ts @@ -24,7 +24,7 @@ import { IInstantiationService } from 'vs/platform/instantiation/common/instanti import { IEditorService } from 'vs/workbench/services/editor/common/editorService'; import { LinkDetector } from 'vs/workbench/parts/debug/browser/linkDetector'; import { handleANSIOutput } from 'vs/workbench/parts/debug/browser/debugANSIHandling'; -import { IUriLabelService } from 'vs/platform/uriLabel/common/uriLabel'; +import { ILabelService } from 'vs/platform/label/common/label'; const $ = dom.$; @@ -97,7 +97,7 @@ export class ReplExpressionsRenderer implements IRenderer { constructor( @IEditorService private editorService: IEditorService, @IInstantiationService private instantiationService: IInstantiationService, - @IUriLabelService private uriLabelService: IUriLabelService + @ILabelService private labelService: ILabelService ) { this.linkDetector = this.instantiationService.createInstance(LinkDetector); } @@ -260,7 +260,7 @@ export class ReplExpressionsRenderer implements IRenderer { dom.addClass(templateData.value, (element.severity === severity.Warning) ? 'warn' : (element.severity === severity.Error) ? 'error' : (element.severity === severity.Ignore) ? 'ignore' : 'info'); templateData.source.textContent = element.sourceData ? `${element.sourceData.source.name}:${element.sourceData.lineNumber}` : ''; - templateData.source.title = element.sourceData ? this.uriLabelService.getLabel(element.sourceData.source.uri) : ''; + templateData.source.title = element.sourceData ? this.labelService.getUriLabel(element.sourceData.source.uri) : ''; templateData.getReplElementSource = () => element.sourceData; } diff --git a/src/vs/workbench/parts/files/common/editors/fileEditorInput.ts b/src/vs/workbench/parts/files/common/editors/fileEditorInput.ts index 232a677b82c..7954c9cb400 100644 --- a/src/vs/workbench/parts/files/common/editors/fileEditorInput.ts +++ b/src/vs/workbench/parts/files/common/editors/fileEditorInput.ts @@ -21,7 +21,7 @@ import { telemetryURIDescriptor } from 'vs/platform/telemetry/common/telemetryUt import { ITextModelService } from 'vs/editor/common/services/resolverService'; import { IHashService } from 'vs/workbench/services/hash/common/hashService'; import { FILE_EDITOR_INPUT_ID, TEXT_FILE_EDITOR_ID, BINARY_FILE_EDITOR_ID } from 'vs/workbench/parts/files/common/files'; -import { IUriLabelService } from 'vs/platform/uriLabel/common/uriLabel'; +import { ILabelService } from 'vs/platform/label/common/label'; /** * A file editor input is the input type for the file editor of file system resources. @@ -43,7 +43,7 @@ export class FileEditorInput extends EditorInput implements IFileEditorInput { @ITextFileService private textFileService: ITextFileService, @ITextModelService private textModelResolverService: ITextModelService, @IHashService private hashService: IHashService, - @IUriLabelService private uriLabelService: IUriLabelService + @ILabelService private labelService: ILabelService ) { super(); @@ -132,17 +132,17 @@ export class FileEditorInput extends EditorInput implements IFileEditorInput { @memoize private get shortDescription(): string { - return paths.basename(this.uriLabelService.getLabel(resources.dirname(this.resource))); + return paths.basename(this.labelService.getUriLabel(resources.dirname(this.resource))); } @memoize private get mediumDescription(): string { - return this.uriLabelService.getLabel(resources.dirname(this.resource), true); + return this.labelService.getUriLabel(resources.dirname(this.resource), true); } @memoize private get longDescription(): string { - return this.uriLabelService.getLabel(resources.dirname(this.resource), true); + return this.labelService.getUriLabel(resources.dirname(this.resource), true); } getDescription(verbosity: Verbosity = Verbosity.MEDIUM): string { @@ -170,12 +170,12 @@ export class FileEditorInput extends EditorInput implements IFileEditorInput { @memoize private get mediumTitle(): string { - return this.uriLabelService.getLabel(this.resource, true); + return this.labelService.getUriLabel(this.resource, true); } @memoize private get longTitle(): string { - return this.uriLabelService.getLabel(this.resource); + return this.labelService.getUriLabel(this.resource); } getTitle(verbosity: Verbosity): string { diff --git a/src/vs/workbench/parts/files/electron-browser/fileCommands.ts b/src/vs/workbench/parts/files/electron-browser/fileCommands.ts index a62dc4a0bdf..2e4edb6e547 100644 --- a/src/vs/workbench/parts/files/electron-browser/fileCommands.ts +++ b/src/vs/workbench/parts/files/electron-browser/fileCommands.ts @@ -41,7 +41,7 @@ import { INotificationService } from 'vs/platform/notification/common/notificati import { EditorContextKeys } from 'vs/editor/common/editorContextKeys'; import { IEditorService, SIDE_GROUP } from 'vs/workbench/services/editor/common/editorService'; import { IEditorGroupsService } from 'vs/workbench/services/group/common/editorGroupsService'; -import { IUriLabelService } from 'vs/platform/uriLabel/common/uriLabel'; +import { ILabelService } from 'vs/platform/label/common/label'; // Commands @@ -387,11 +387,11 @@ KeybindingsRegistry.registerCommandAndKeybindingRule({ } }); -function resourcesToClipboard(resources: URI[], relative: boolean, clipboardService: IClipboardService, notificationService: INotificationService, uriLabelService: IUriLabelService): void { +function resourcesToClipboard(resources: URI[], relative: boolean, clipboardService: IClipboardService, notificationService: INotificationService, labelService: ILabelService): void { if (resources.length) { const lineDelimiter = isWindows ? '\r\n' : '\n'; - const text = resources.map(resource => uriLabelService.getLabel(resource, relative, true)) + const text = resources.map(resource => labelService.getUriLabel(resource, relative, true)) .join(lineDelimiter); clipboardService.writeText(text); } else { @@ -409,7 +409,7 @@ KeybindingsRegistry.registerCommandAndKeybindingRule({ id: COPY_PATH_COMMAND_ID, handler: (accessor, resource: URI | object) => { const resources = getMultiSelectedResources(resource, accessor.get(IListService), accessor.get(IEditorService)); - resourcesToClipboard(resources, false, accessor.get(IClipboardService), accessor.get(INotificationService), accessor.get(IUriLabelService)); + resourcesToClipboard(resources, false, accessor.get(IClipboardService), accessor.get(INotificationService), accessor.get(ILabelService)); } }); @@ -423,7 +423,7 @@ KeybindingsRegistry.registerCommandAndKeybindingRule({ id: COPY_RELATIVE_PATH_COMMAND_ID, handler: (accessor, resource: URI | object) => { const resources = getMultiSelectedResources(resource, accessor.get(IListService), accessor.get(IEditorService)); - resourcesToClipboard(resources, true, accessor.get(IClipboardService), accessor.get(INotificationService), accessor.get(IUriLabelService)); + resourcesToClipboard(resources, true, accessor.get(IClipboardService), accessor.get(INotificationService), accessor.get(ILabelService)); } }); @@ -436,7 +436,7 @@ KeybindingsRegistry.registerCommandAndKeybindingRule({ const editorService = accessor.get(IEditorService); const activeInput = editorService.activeEditor; const resources = activeInput && activeInput.getResource() ? [activeInput.getResource()] : []; - resourcesToClipboard(resources, false, accessor.get(IClipboardService), accessor.get(INotificationService), accessor.get(IUriLabelService)); + resourcesToClipboard(resources, false, accessor.get(IClipboardService), accessor.get(INotificationService), accessor.get(ILabelService)); } }); diff --git a/src/vs/workbench/parts/files/electron-browser/files.contribution.ts b/src/vs/workbench/parts/files/electron-browser/files.contribution.ts index 39594b253a5..3e3039936bb 100644 --- a/src/vs/workbench/parts/files/electron-browser/files.contribution.ts +++ b/src/vs/workbench/parts/files/electron-browser/files.contribution.ts @@ -34,7 +34,7 @@ import { DataUriEditorInput } from 'vs/workbench/common/editor/dataUriEditorInpu import { LifecyclePhase } from 'vs/platform/lifecycle/common/lifecycle'; import { IEditorService } from 'vs/workbench/services/editor/common/editorService'; import { IEditorGroupsService } from 'vs/workbench/services/group/common/editorGroupsService'; -import { IUriLabelService } from 'vs/platform/uriLabel/common/uriLabel'; +import { ILabelService } from 'vs/platform/label/common/label'; import { Schemas } from 'vs/base/common/network'; import { nativeSep } from 'vs/base/common/paths'; @@ -55,8 +55,8 @@ export class OpenExplorerViewletAction extends ToggleViewletAction { class FileUriLabelContribution implements IWorkbenchContribution { - constructor(@IUriLabelService uriLabelService: IUriLabelService) { - uriLabelService.registerFormater(Schemas.file, { + constructor(@ILabelService labelService: ILabelService) { + labelService.registerFormater(Schemas.file, { label: '${path}', separator: nativeSep, tildify: !platform.isWindows, diff --git a/src/vs/workbench/parts/files/electron-browser/views/explorerView.ts b/src/vs/workbench/parts/files/electron-browser/views/explorerView.ts index 59f058f4c0b..d97f3fba2d4 100644 --- a/src/vs/workbench/parts/files/electron-browser/views/explorerView.ts +++ b/src/vs/workbench/parts/files/electron-browser/views/explorerView.ts @@ -43,7 +43,7 @@ import { Schemas } from 'vs/base/common/network'; import { INotificationService } from 'vs/platform/notification/common/notification'; import { IEditorService } from 'vs/workbench/services/editor/common/editorService'; import { IViewletPanelOptions } from 'vs/workbench/browser/parts/views/panelViewlet'; -import { IUriLabelService } from 'vs/platform/uriLabel/common/uriLabel'; +import { ILabelService } from 'vs/platform/label/common/label'; export interface IExplorerViewOptions extends IViewletViewOptions { viewletState: FileViewletState; @@ -96,7 +96,7 @@ export class ExplorerView extends TreeViewsViewletPanel implements IExplorerView @IContextKeyService contextKeyService: IContextKeyService, @IConfigurationService configurationService: IConfigurationService, @IDecorationsService decorationService: IDecorationsService, - @IUriLabelService private uriLabelService: IUriLabelService + @ILabelService private labelService: ILabelService ) { super({ ...(options as IViewletPanelOptions), ariaHeaderLabel: nls.localize('explorerSection', "Files Explorer Section") }, keybindingService, contextMenuService, configurationService); @@ -149,7 +149,7 @@ export class ExplorerView extends TreeViewsViewletPanel implements IExplorerView } public get name(): string { - return this.uriLabelService.getWorkspaceLabel(this.contextService.getWorkspace()); + return this.labelService.getWorkspaceLabel(this.contextService.getWorkspace()); } public get title(): string { diff --git a/src/vs/workbench/parts/localizations/electron-browser/localizationsActions.ts b/src/vs/workbench/parts/localizations/electron-browser/localizationsActions.ts index 3eeb2028a11..1e70b6279fa 100644 --- a/src/vs/workbench/parts/localizations/electron-browser/localizationsActions.ts +++ b/src/vs/workbench/parts/localizations/electron-browser/localizationsActions.ts @@ -13,7 +13,7 @@ import { join } from 'vs/base/common/paths'; import URI from 'vs/base/common/uri'; import { IEditorService } from 'vs/workbench/services/editor/common/editorService'; import { language } from 'vs/base/common/platform'; -import { IUriLabelService } from 'vs/platform/uriLabel/common/uriLabel'; +import { ILabelService } from 'vs/platform/label/common/label'; export class ConfigureLocaleAction extends Action { public static readonly ID = 'workbench.action.configureLocale'; @@ -32,7 +32,7 @@ export class ConfigureLocaleAction extends Action { @IFileService private fileService: IFileService, @IEnvironmentService private environmentService: IEnvironmentService, @IEditorService private editorService: IEditorService, - @IUriLabelService private uriLabelService: IUriLabelService + @ILabelService private labelService: ILabelService ) { super(id, label); } @@ -49,7 +49,7 @@ export class ConfigureLocaleAction extends Action { resource: stat.resource }); }, (error) => { - throw new Error(localize('fail.createSettings', "Unable to create '{0}' ({1}).", this.uriLabelService.getLabel(file, true), error)); + throw new Error(localize('fail.createSettings', "Unable to create '{0}' ({1}).", this.labelService.getUriLabel(file, true), error)); }); } } diff --git a/src/vs/workbench/parts/logs/electron-browser/logsActions.ts b/src/vs/workbench/parts/logs/electron-browser/logsActions.ts index 0920a329064..9d1ae739a25 100644 --- a/src/vs/workbench/parts/logs/electron-browser/logsActions.ts +++ b/src/vs/workbench/parts/logs/electron-browser/logsActions.ts @@ -16,7 +16,7 @@ import { ICommandService } from 'vs/platform/commands/common/commands'; import URI from 'vs/base/common/uri'; import { IWorkspaceContextService } from 'vs/platform/workspace/common/workspace'; import { IQuickPickItem, IQuickInputService } from 'vs/platform/quickinput/common/quickInput'; -import { IUriLabelService } from 'vs/platform/uriLabel/common/uriLabel'; +import { ILabelService } from 'vs/platform/label/common/label'; export class OpenLogsFolderAction extends Action { @@ -44,13 +44,13 @@ export class ShowLogsAction extends Action { @IQuickInputService private quickInputService: IQuickInputService, @IOutputService private outputService: IOutputService, @IWorkspaceContextService private contextService: IWorkspaceContextService, - @IUriLabelService private uriLabelService: IUriLabelService + @ILabelService private labelService: ILabelService ) { super(id, label); } run(): TPromise<void> { - const workspaceName = this.uriLabelService.getWorkspaceLabel(this.contextService.getWorkspace()); + const workspaceName = this.labelService.getWorkspaceLabel(this.contextService.getWorkspace()); const entries: IQuickPickItem[] = [ { id: Constants.rendererLogChannelId, label: workspaceName ? nls.localize('rendererProcess', "Window ({0})", workspaceName) : nls.localize('emptyWindow', "Window") }, { id: Constants.extHostLogChannelId, label: nls.localize('extensionHost', "Extension Host") }, @@ -79,13 +79,13 @@ export class OpenLogFileAction extends Action { @ICommandService private commandService: ICommandService, @IWindowService private windowService: IWindowService, @IWorkspaceContextService private contextService: IWorkspaceContextService, - @IUriLabelService private uriLabelService: IUriLabelService + @ILabelService private labelService: ILabelService ) { super(id, label); } run(): TPromise<void> { - const workspaceName = this.uriLabelService.getWorkspaceLabel(this.contextService.getWorkspace()); + const workspaceName = this.labelService.getWorkspaceLabel(this.contextService.getWorkspace()); const entries: IQuickPickItem[] = [ { id: URI.file(paths.join(this.environmentService.logsPath, `renderer${this.windowService.getCurrentWindowId()}.log`)).fsPath, label: workspaceName ? nls.localize('rendererProcess', "Window ({0})", workspaceName) : nls.localize('emptyWindow', "Window") }, { id: URI.file(paths.join(this.environmentService.logsPath, `exthost${this.windowService.getCurrentWindowId()}.log`)).fsPath, label: nls.localize('extensionHost', "Extension Host") }, diff --git a/src/vs/workbench/parts/markers/electron-browser/markersTreeViewer.ts b/src/vs/workbench/parts/markers/electron-browser/markersTreeViewer.ts index 60deb20c1e7..4e35e7e3ccb 100644 --- a/src/vs/workbench/parts/markers/electron-browser/markersTreeViewer.ts +++ b/src/vs/workbench/parts/markers/electron-browser/markersTreeViewer.ts @@ -21,7 +21,7 @@ import { IThemeService } from 'vs/platform/theme/common/themeService'; import { IDisposable } from 'vs/base/common/lifecycle'; import { ActionBar, IActionItemProvider } from 'vs/base/browser/ui/actionbar/actionbar'; import { QuickFixAction } from 'vs/workbench/parts/markers/electron-browser/markersPanelActions'; -import { IUriLabelService } from 'vs/platform/uriLabel/common/uriLabel'; +import { ILabelService } from 'vs/platform/label/common/label'; import { dirname } from 'vs/base/common/resources'; interface IResourceMarkersTemplateData { @@ -100,7 +100,7 @@ export class Renderer implements IRenderer { private actionItemProvider: IActionItemProvider, @IInstantiationService private instantiationService: IInstantiationService, @IThemeService private themeService: IThemeService, - @IUriLabelService private uriLabelService: IUriLabelService + @ILabelService private labelService: ILabelService ) { } @@ -209,7 +209,7 @@ export class Renderer implements IRenderer { if (templateData.resourceLabel instanceof FileLabel) { templateData.resourceLabel.setFile(element.uri, { matches: element.uriMatches }); } else { - templateData.resourceLabel.setLabel({ name: element.name, description: this.uriLabelService.getLabel(dirname(element.uri), true), resource: element.uri }, { matches: element.uriMatches }); + templateData.resourceLabel.setLabel({ name: element.name, description: this.labelService.getUriLabel(dirname(element.uri), true), resource: element.uri }, { matches: element.uriMatches }); } (<IResourceMarkersTemplateData>templateData).count.setCount(element.filteredCount); } @@ -235,7 +235,7 @@ export class Renderer implements IRenderer { private renderRelatedInfoElement(tree: ITree, element: RelatedInformation, templateData: IRelatedInformationTemplateData) { templateData.resourceLabel.set(paths.basename(element.raw.resource.fsPath), element.uriMatches); - templateData.resourceLabel.element.title = this.uriLabelService.getLabel(element.raw.resource, true); + templateData.resourceLabel.element.title = this.labelService.getUriLabel(element.raw.resource, true); templateData.lnCol.textContent = Messages.MARKERS_PANEL_AT_LINE_COL_NUMBER(element.raw.startLineNumber, element.raw.startColumn); templateData.description.set(element.raw.message, element.messageMatches); templateData.description.element.title = element.raw.message; @@ -273,13 +273,13 @@ export class Renderer implements IRenderer { export class MarkersTreeAccessibilityProvider implements IAccessibilityProvider { constructor( - @IUriLabelService private uriLabelServie: IUriLabelService + @ILabelService private labelServie: ILabelService ) { } public getAriaLabel(tree: ITree, element: any): string { if (element instanceof ResourceMarkers) { - const path = this.uriLabelServie.getLabel(element.uri, true) || element.uri.fsPath; + const path = this.labelServie.getUriLabel(element.uri, true) || element.uri.fsPath; return Messages.MARKERS_TREE_ARIA_LABEL_RESOURCE(element.filteredCount, element.name, paths.dirname(path)); } if (element instanceof Marker) { diff --git a/src/vs/workbench/parts/search/browser/openFileHandler.ts b/src/vs/workbench/parts/search/browser/openFileHandler.ts index ea39b43e3b4..74ecdb47103 100644 --- a/src/vs/workbench/parts/search/browser/openFileHandler.ts +++ b/src/vs/workbench/parts/search/browser/openFileHandler.ts @@ -33,7 +33,7 @@ import { getOutOfWorkspaceEditorResources } from 'vs/workbench/parts/search/comm import { IEditorService } from 'vs/workbench/services/editor/common/editorService'; import { prepareQuery, IPreparedQuery } from 'vs/base/parts/quickopen/common/quickOpenScorer'; import { IFileService } from 'vs/platform/files/common/files'; -import { IUriLabelService } from 'vs/platform/uriLabel/common/uriLabel'; +import { ILabelService } from 'vs/platform/label/common/label'; import { untildify } from 'vs/base/common/labels'; export class FileQuickOpenModel extends QuickOpenModel { @@ -127,7 +127,7 @@ export class OpenFileHandler extends QuickOpenHandler { @ISearchService private searchService: ISearchService, @IEnvironmentService private environmentService: IEnvironmentService, @IFileService private fileService: IFileService, - @IUriLabelService private uriLabelService: IUriLabelService + @ILabelService private labelService: ILabelService ) { super(); @@ -173,7 +173,7 @@ export class OpenFileHandler extends QuickOpenHandler { const fileMatch = complete.results[i]; const label = paths.basename(fileMatch.resource.fsPath); - const description = this.uriLabelService.getLabel(resources.dirname(fileMatch.resource), true); + const description = this.labelService.getUriLabel(resources.dirname(fileMatch.resource), true); results.push(this.instantiationService.createInstance(FileEntry, fileMatch.resource, label, description, iconClass)); } diff --git a/src/vs/workbench/parts/search/browser/openSymbolHandler.ts b/src/vs/workbench/parts/search/browser/openSymbolHandler.ts index cf6acbc1f1e..14a26b1b5de 100644 --- a/src/vs/workbench/parts/search/browser/openSymbolHandler.ts +++ b/src/vs/workbench/parts/search/browser/openSymbolHandler.ts @@ -23,7 +23,7 @@ import { IConfigurationService } from 'vs/platform/configuration/common/configur import { IWorkspaceSymbolProvider, getWorkspaceSymbols, IWorkspaceSymbol } from 'vs/workbench/parts/search/common/search'; import { basename } from 'vs/base/common/paths'; import { IEditorService } from 'vs/workbench/services/editor/common/editorService'; -import { IUriLabelService } from 'vs/platform/uriLabel/common/uriLabel'; +import { ILabelService } from 'vs/platform/label/common/label'; class SymbolEntry extends EditorQuickOpenEntry { @@ -34,7 +34,7 @@ class SymbolEntry extends EditorQuickOpenEntry { private _provider: IWorkspaceSymbolProvider, @IConfigurationService private readonly _configurationService: IConfigurationService, @IEditorService editorService: IEditorService, - @IUriLabelService private _uriLabelService: IUriLabelService + @ILabelService private _labelService: ILabelService ) { super(editorService); } @@ -53,7 +53,7 @@ class SymbolEntry extends EditorQuickOpenEntry { if (containerName) { return `${containerName} — ${basename(this._bearing.location.uri.fsPath)}`; } else { - return this._uriLabelService.getLabel(this._bearing.location.uri, true); + return this._labelService.getUriLabel(this._bearing.location.uri, true); } } return containerName; diff --git a/src/vs/workbench/parts/search/browser/searchResultsView.ts b/src/vs/workbench/parts/search/browser/searchResultsView.ts index 628d70b17e7..88e4943184b 100644 --- a/src/vs/workbench/parts/search/browser/searchResultsView.ts +++ b/src/vs/workbench/parts/search/browser/searchResultsView.ts @@ -27,7 +27,7 @@ import { IContextMenuService } from 'vs/platform/contextview/browser/contextView import { IMenuService, MenuId, IMenu } from 'vs/platform/actions/common/actions'; import { WorkbenchTreeController, WorkbenchTree } from 'vs/platform/list/browser/listService'; import { fillInContextMenuActions } from 'vs/platform/actions/browser/menuItemActionItem'; -import { IUriLabelService } from 'vs/platform/uriLabel/common/uriLabel'; +import { ILabelService } from 'vs/platform/label/common/label'; export class SearchDataSource implements IDataSource { @@ -329,7 +329,7 @@ export class SearchRenderer extends Disposable implements IRenderer { export class SearchAccessibilityProvider implements IAccessibilityProvider { constructor( - @IUriLabelService private uriLabelService: IUriLabelService + @ILabelService private labelService: ILabelService ) { } @@ -341,7 +341,7 @@ export class SearchAccessibilityProvider implements IAccessibilityProvider { } if (element instanceof FileMatch) { - const path = this.uriLabelService.getLabel(element.resource(), true) || element.resource().fsPath; + const path = this.labelService.getUriLabel(element.resource(), true) || element.resource().fsPath; return nls.localize('fileMatchAriaLabel', "{0} matches in file {1} of folder {2}, Search result", element.count(), element.name(), paths.dirname(path)); } diff --git a/src/vs/workbench/parts/welcome/page/electron-browser/welcomePage.ts b/src/vs/workbench/parts/welcome/page/electron-browser/welcomePage.ts index d0a84ee058b..f2b267da9e9 100644 --- a/src/vs/workbench/parts/welcome/page/electron-browser/welcomePage.ts +++ b/src/vs/workbench/parts/welcome/page/electron-browser/welcomePage.ts @@ -39,7 +39,7 @@ import { getIdAndVersionFromLocalExtensionId } from 'vs/platform/extensionManage import { INotificationService, Severity } from 'vs/platform/notification/common/notification'; import { TimeoutTimer } from 'vs/base/common/async'; import { areSameExtensions } from 'vs/platform/extensionManagement/common/extensionManagementUtil'; -import { IUriLabelService } from 'vs/platform/uriLabel/common/uriLabel'; +import { ILabelService } from 'vs/platform/label/common/label'; used(); @@ -223,7 +223,7 @@ class WelcomePage { @IWorkspaceContextService private contextService: IWorkspaceContextService, @IConfigurationService private configurationService: IConfigurationService, @IEnvironmentService private environmentService: IEnvironmentService, - @IUriLabelService private uriLabelService: IUriLabelService, + @ILabelService private labelService: ILabelService, @INotificationService private notificationService: INotificationService, @IExtensionEnablementService private extensionEnablementService: IExtensionEnablementService, @IExtensionGalleryService private extensionGalleryService: IExtensionGalleryService, @@ -280,9 +280,9 @@ class WelcomePage { let resource: URI; if (isSingleFolderWorkspaceIdentifier(workspace)) { resource = workspace; - label = this.uriLabelService.getWorkspaceLabel(workspace); + label = this.labelService.getWorkspaceLabel(workspace); } else if (isWorkspaceIdentifier(workspace)) { - label = this.uriLabelService.getWorkspaceLabel(workspace); + label = this.labelService.getWorkspaceLabel(workspace); resource = URI.file(workspace.configPath); } else { label = getBaseLabel(workspace); @@ -304,7 +304,7 @@ class WelcomePage { } parentFolderPath = tildify(parentFolder, this.environmentService.userHome); } else { - parentFolderPath = this.uriLabelService.getLabel(resource); + parentFolderPath = this.labelService.getUriLabel(resource); } diff --git a/src/vs/workbench/services/bulkEdit/electron-browser/bulkEditService.ts b/src/vs/workbench/services/bulkEdit/electron-browser/bulkEditService.ts index 8e787b56880..8086e115ae4 100644 --- a/src/vs/workbench/services/bulkEdit/electron-browser/bulkEditService.ts +++ b/src/vs/workbench/services/bulkEdit/electron-browser/bulkEditService.ts @@ -24,7 +24,7 @@ import { ILogService } from 'vs/platform/log/common/log'; import { emptyProgressRunner, IProgress, IProgressRunner } from 'vs/platform/progress/common/progress'; import { IEditorService } from 'vs/workbench/services/editor/common/editorService'; import { ITextFileService } from 'vs/workbench/services/textfile/common/textfiles'; -import { IUriLabelService } from 'vs/platform/uriLabel/common/uriLabel'; +import { ILabelService } from 'vs/platform/label/common/label'; abstract class Recording { @@ -236,7 +236,7 @@ export class BulkEdit { @ITextModelService private readonly _textModelService: ITextModelService, @IFileService private readonly _fileService: IFileService, @ITextFileService private readonly _textFileService: ITextFileService, - @IUriLabelService private readonly _uriLabelServie: IUriLabelService + @ILabelService private readonly _uriLabelServie: ILabelService ) { this._editor = editor; this._progress = progress || emptyProgressRunner; @@ -342,7 +342,7 @@ export class BulkEdit { const conflicts = edits .filter(edit => recording.hasChanged(edit.resource)) - .map(edit => this._uriLabelServie.getLabel(edit.resource, true)); + .map(edit => this._uriLabelServie.getUriLabel(edit.resource, true)); recording.stop(); @@ -372,7 +372,7 @@ export class BulkEditService implements IBulkEditService { @ITextModelService private readonly _textModelService: ITextModelService, @IFileService private readonly _fileService: IFileService, @ITextFileService private readonly _textFileService: ITextFileService, - @IUriLabelService private readonly _uriLabelService: IUriLabelService + @ILabelService private readonly _labelService: ILabelService ) { } @@ -403,7 +403,7 @@ export class BulkEditService implements IBulkEditService { } } - const bulkEdit = new BulkEdit(options.editor, options.progress, this._logService, this._textModelService, this._fileService, this._textFileService, this._uriLabelService); + const bulkEdit = new BulkEdit(options.editor, options.progress, this._logService, this._textModelService, this._fileService, this._textFileService, this._labelService); bulkEdit.add(edits); return TPromise.wrap(bulkEdit.perform().then(() => { diff --git a/src/vs/workbench/services/editor/browser/editorService.ts b/src/vs/workbench/services/editor/browser/editorService.ts index 32c50e0a867..1ee855ef3d5 100644 --- a/src/vs/workbench/services/editor/browser/editorService.ts +++ b/src/vs/workbench/services/editor/browser/editorService.ts @@ -28,7 +28,7 @@ import { Disposable, IDisposable, dispose, toDisposable } from 'vs/base/common/l import { coalesce } from 'vs/base/common/arrays'; import { isCodeEditor, isDiffEditor, ICodeEditor, IDiffEditor } from 'vs/editor/browser/editorBrowser'; import { IEditorGroupView, IEditorOpeningEvent, EditorGroupsServiceImpl, EditorServiceImpl } from 'vs/workbench/browser/parts/editor/editor'; -import { IUriLabelService } from 'vs/platform/uriLabel/common/uriLabel'; +import { ILabelService } from 'vs/platform/label/common/label'; type ICachedEditorInput = ResourceEditorInput | IFileEditorInput | DataUriEditorInput; @@ -64,7 +64,7 @@ export class EditorService extends Disposable implements EditorServiceImpl { @IEditorGroupsService private editorGroupService: EditorGroupsServiceImpl, @IUntitledEditorService private untitledEditorService: IUntitledEditorService, @IInstantiationService private instantiationService: IInstantiationService, - @IUriLabelService private uriLabelService: IUriLabelService, + @ILabelService private labelService: ILabelService, @IFileService private fileService: IFileService, @IConfigurationService private configurationService: IConfigurationService ) { @@ -563,7 +563,7 @@ export class EditorService extends Disposable implements EditorServiceImpl { } // Otherwise: for diff labels prefer to see the path as part of the label - return this.uriLabelService.getLabel(res, true); + return this.labelService.getUriLabel(res, true); } //#endregion @@ -584,7 +584,7 @@ export class DelegatingEditorService extends EditorService { @IEditorGroupsService editorGroupService: EditorGroupsServiceImpl, @IUntitledEditorService untitledEditorService: IUntitledEditorService, @IInstantiationService instantiationService: IInstantiationService, - @IUriLabelService uriLabelService: IUriLabelService, + @ILabelService labelService: ILabelService, @IFileService fileService: IFileService, @IConfigurationService configurationService: IConfigurationService ) { @@ -592,7 +592,7 @@ export class DelegatingEditorService extends EditorService { editorGroupService, untitledEditorService, instantiationService, - uriLabelService, + labelService, fileService, configurationService ); diff --git a/src/vs/workbench/services/extensions/electron-browser/extensionHost.ts b/src/vs/workbench/services/extensions/electron-browser/extensionHost.ts index d74d74631cc..6919dec0c92 100644 --- a/src/vs/workbench/services/extensions/electron-browser/extensionHost.ts +++ b/src/vs/workbench/services/extensions/electron-browser/extensionHost.ts @@ -38,7 +38,7 @@ import { INotificationService, Severity } from 'vs/platform/notification/common/ import { getPathFromAmdModule } from 'vs/base/common/amd'; import { timeout } from 'vs/base/common/async'; import { isMessageOfType, MessageType, createMessageOfType } from 'vs/workbench/common/extensionHostProtocol'; -import { IUriLabelService } from 'vs/platform/uriLabel/common/uriLabel'; +import { ILabelService } from 'vs/platform/label/common/label'; export interface IExtensionHostStarter { readonly onCrashed: Event<[number, string]>; @@ -83,7 +83,7 @@ export class ExtensionHostProcessWorker implements IExtensionHostStarter { @ITelemetryService private readonly _telemetryService: ITelemetryService, @ICrashReporterService private readonly _crashReporterService: ICrashReporterService, @ILogService private readonly _logService: ILogService, - @IUriLabelService private readonly _uriLabelService: IUriLabelService + @ILabelService private readonly _labelService: ILabelService ) { // handle extension host lifecycle a bit special when we know we are developing an extension that runs inside this._isExtensionDevHost = this._environmentService.isExtensionDevelopment; @@ -387,7 +387,7 @@ export class ExtensionHostProcessWorker implements IExtensionHostStarter { configuration: workspace.configuration, folders: workspace.folders, id: workspace.id, - name: this._uriLabelService.getWorkspaceLabel(workspace) + name: this._labelService.getWorkspaceLabel(workspace) }, extensions: extensionDescriptions, // Send configurations scopes only in development mode. diff --git a/src/vs/workbench/services/preferences/browser/preferencesService.ts b/src/vs/workbench/services/preferences/browser/preferencesService.ts index c7d519cf89f..77a3cc9a1af 100644 --- a/src/vs/workbench/services/preferences/browser/preferencesService.ts +++ b/src/vs/workbench/services/preferences/browser/preferencesService.ts @@ -36,7 +36,7 @@ import { INotificationService } from 'vs/platform/notification/common/notificati import { assign } from 'vs/base/common/objects'; import { IEditorService } from 'vs/workbench/services/editor/common/editorService'; import { IEditorGroup, IEditorGroupsService, GroupDirection } from 'vs/workbench/services/group/common/editorGroupsService'; -import { IUriLabelService } from 'vs/platform/uriLabel/common/uriLabel'; +import { ILabelService } from 'vs/platform/label/common/label'; const emptyEditableSettingsContent = '{\n}'; @@ -71,7 +71,7 @@ export class PreferencesService extends Disposable implements IPreferencesServic @IModelService private modelService: IModelService, @IJSONEditingService private jsonEditingService: IJSONEditingService, @IModeService private modeService: IModeService, - @IUriLabelService private uriLabelService: IUriLabelService + @ILabelService private labelService: ILabelService ) { super(); // The default keybindings.json updates based on keyboard layouts, so here we make sure @@ -508,7 +508,7 @@ export class PreferencesService extends Disposable implements IPreferencesServic return this.fileService.resolveContent(resource, { acceptTextOnly: true }).then(null, error => { if ((<FileOperationError>error).fileOperationResult === FileOperationResult.FILE_NOT_FOUND) { return this.fileService.updateContent(resource, contents).then(null, error => { - return TPromise.wrapError(new Error(nls.localize('fail.createSettings', "Unable to create '{0}' ({1}).", this.uriLabelService.getLabel(resource, true), error))); + return TPromise.wrapError(new Error(nls.localize('fail.createSettings', "Unable to create '{0}' ({1}).", this.labelService.getUriLabel(resource, true), error))); }); } diff --git a/src/vs/workbench/test/electron-browser/api/mainThreadEditors.test.ts b/src/vs/workbench/test/electron-browser/api/mainThreadEditors.test.ts index 19ef6688f08..047e1cdd3da 100644 --- a/src/vs/workbench/test/electron-browser/api/mainThreadEditors.test.ts +++ b/src/vs/workbench/test/electron-browser/api/mainThreadEditors.test.ts @@ -28,7 +28,7 @@ import { BulkEditService } from 'vs/workbench/services/bulkEdit/electron-browser import { NullLogService } from 'vs/platform/log/common/log'; import { ITextModelService, ITextEditorModel } from 'vs/editor/common/services/resolverService'; import { IReference, ImmortalReference } from 'vs/base/common/lifecycle'; -import { UriLabelService } from 'vs/platform/uriLabel/common/uriLabel'; +import { LabelService } from 'vs/platform/label/common/label'; suite('MainThreadEditors', () => { @@ -84,7 +84,7 @@ suite('MainThreadEditors', () => { } }; - const bulkEditService = new BulkEditService(new NullLogService(), modelService, new TestEditorService(), textModelService, new TestFileService(), textFileService, new UriLabelService(TestEnvironmentService, new TestContextService())); + const bulkEditService = new BulkEditService(new NullLogService(), modelService, new TestEditorService(), textModelService, new TestFileService(), textFileService, new LabelService(TestEnvironmentService, new TestContextService())); const rpcProtocol = new TestRPCProtocol(); rpcProtocol.set(ExtHostContext.ExtHostDocuments, new class extends mock<ExtHostDocumentsShape>() { diff --git a/src/vs/workbench/test/workbenchTestServices.ts b/src/vs/workbench/test/workbenchTestServices.ts index 28b58ffa681..cd10de36a94 100644 --- a/src/vs/workbench/test/workbenchTestServices.ts +++ b/src/vs/workbench/test/workbenchTestServices.ts @@ -75,7 +75,7 @@ import { IDecorationRenderOptions } from 'vs/editor/common/editorCommon'; import { EditorGroup } from 'vs/workbench/common/editor/editorGroup'; import { Dimension } from 'vs/base/browser/dom'; import { ILogService, LogLevel } from 'vs/platform/log/common/log'; -import { IUriLabelService, UriLabelService } from 'vs/platform/uriLabel/common/uriLabel'; +import { ILabelService, LabelService } from 'vs/platform/label/common/label'; export function createFileInput(instantiationService: IInstantiationService, resource: URI): FileEditorInput { return instantiationService.createInstance(FileEditorInput, resource, void 0); @@ -271,7 +271,7 @@ export function workbenchInstantiationService(): IInstantiationService { instantiationService.stub(IHashService, new TestHashService()); instantiationService.stub(ILogService, new TestLogService()); instantiationService.stub(IEditorGroupsService, new TestEditorGroupsService([new TestEditorGroup(0)])); - instantiationService.stub(IUriLabelService, new UriLabelService(TestEnvironmentService, workspaceContextService)); + instantiationService.stub(ILabelService, new LabelService(TestEnvironmentService, workspaceContextService)); const editorService = new TestEditorService(); instantiationService.stub(IEditorService, editorService); instantiationService.stub(ICodeEditorService, new TestCodeEditorService()); diff --git a/src/vs/workbench/workbench.main.ts b/src/vs/workbench/workbench.main.ts index 184ccb27ce7..ce9193eb9cf 100644 --- a/src/vs/workbench/workbench.main.ts +++ b/src/vs/workbench/workbench.main.ts @@ -17,7 +17,7 @@ import 'vs/editor/editor.all'; // Platform import 'vs/platform/widget/browser/contextScopedHistoryWidget'; -import 'vs/platform/uriLabel/electron-browser/uriLabel.contribution'; +import 'vs/platform/label/electron-browser/label.contribution'; // Menus/Actions import 'vs/workbench/services/actions/electron-browser/menusExtensionPoint'; From 8f96ce69e2191f08740877c7b293382964a4a711 Mon Sep 17 00:00:00 2001 From: Benjamin Pasero <benjpas@microsoft.com> Date: Thu, 23 Aug 2018 13:02:33 +0200 Subject: [PATCH 1160/1276] debt - reduce usage of electron remote module --- .../electron-browser/issue/issueReporter.js | 6 ++--- .../issue/issueReporterMain.ts | 20 ++++++++--------- .../processExplorer/processExplorer.js | 6 ++--- .../processExplorer/processExplorerMain.ts | 2 +- src/vs/code/electron-browser/proxy/auth.html | 5 ----- src/vs/code/electron-main/app.ts | 22 ++++++++++++++----- .../issue/electron-main/issueService.ts | 22 ++++++++++++------- .../electron-browser/bootstrap/index.js | 7 +++--- 8 files changed, 51 insertions(+), 39 deletions(-) diff --git a/src/vs/code/electron-browser/issue/issueReporter.js b/src/vs/code/electron-browser/issue/issueReporter.js index 53abd748d7b..949609d7682 100644 --- a/src/vs/code/electron-browser/issue/issueReporter.js +++ b/src/vs/code/electron-browser/issue/issueReporter.js @@ -7,7 +7,7 @@ const path = require('path'); const fs = require('fs'); -const remote = require('electron').remote; +const ipc = require('electron').ipcRenderer; function assign(destination, source) { return Object.keys(source) @@ -97,9 +97,9 @@ function main() { window.addEventListener('keydown', function (e) { const key = extractKey(e); if (key === TOGGLE_DEV_TOOLS_KB) { - remote.getCurrentWebContents().toggleDevTools(); + ipc.send('vscode:toggleDevTools'); } else if (key === RELOAD_KB) { - remote.getCurrentWindow().reload(); + ipc.send('vscode:reloadWindow'); } }); diff --git a/src/vs/code/electron-browser/issue/issueReporterMain.ts b/src/vs/code/electron-browser/issue/issueReporterMain.ts index 66861d351bf..cd5c7bb1251 100644 --- a/src/vs/code/electron-browser/issue/issueReporterMain.ts +++ b/src/vs/code/electron-browser/issue/issueReporterMain.ts @@ -6,7 +6,7 @@ 'use strict'; import 'vs/css!./media/issueReporter'; -import { shell, ipcRenderer, webFrame, remote, clipboard } from 'electron'; +import { shell, ipcRenderer, webFrame, clipboard } from 'electron'; import { localize } from 'vs/nls'; import { $ } from 'vs/base/browser/dom'; import * as collections from 'vs/base/common/collections'; @@ -91,7 +91,7 @@ export class IssueReporter extends Disposable { this.previewButton = new Button(document.getElementById('issue-reporter')); - ipcRenderer.on('issuePerformanceInfoResponse', (event, info) => { + ipcRenderer.on('vscode:issuePerformanceInfoResponse', (event, info) => { this.logService.trace('issueReporter: Received performance data'); this.issueReporterModel.update(info); this.receivedPerformanceInfo = true; @@ -102,7 +102,7 @@ export class IssueReporter extends Disposable { this.updatePreviewButtonState(); }); - ipcRenderer.on('issueSystemInfoResponse', (event, info) => { + ipcRenderer.on('vscode:issueSystemInfoResponse', (event, info) => { this.logService.trace('issueReporter: Received system data'); this.issueReporterModel.update({ systemInfo: info }); this.receivedSystemInfo = true; @@ -111,9 +111,9 @@ export class IssueReporter extends Disposable { this.updatePreviewButtonState(); }); - ipcRenderer.send('issueSystemInfoRequest'); + ipcRenderer.send('vscode:issueSystemInfoRequest'); if (configuration.data.issueType === IssueType.PerformanceIssue) { - ipcRenderer.send('issuePerformanceInfoRequest'); + ipcRenderer.send('vscode:issuePerformanceInfoRequest'); } this.logService.trace('issueReporter: Sent data requests'); @@ -308,7 +308,7 @@ export class IssueReporter extends Disposable { const issueType = parseInt((<HTMLInputElement>event.target).value); this.issueReporterModel.update({ issueType: issueType }); if (issueType === IssueType.PerformanceIssue && !this.receivedPerformanceInfo) { - ipcRenderer.send('issuePerformanceInfoRequest'); + ipcRenderer.send('vscode:issuePerformanceInfoRequest'); } this.updatePreviewButtonState(); this.render(); @@ -384,14 +384,14 @@ export class IssueReporter extends Disposable { this.previewButton.onDidClick(() => this.createIssue()); this.addEventListener('disableExtensions', 'click', () => { - ipcRenderer.send('workbenchCommand', 'workbench.action.reloadWindowWithExtensionsDisabled'); + ipcRenderer.send('vscode:workbenchCommand', 'workbench.action.reloadWindowWithExtensionsDisabled'); }); this.addEventListener('disableExtensions', 'keydown', (e: KeyboardEvent) => { e.stopPropagation(); if (e.keyCode === 13 || e.keyCode === 32) { - ipcRenderer.send('workbenchCommand', 'workbench.extensions.action.disableAll'); - ipcRenderer.send('workbenchCommand', 'workbench.action.reloadWindow'); + ipcRenderer.send('vscode:workbenchCommand', 'workbench.extensions.action.disableAll'); + ipcRenderer.send('vscode:workbenchCommand', 'workbench.action.reloadWindow'); } }); @@ -400,7 +400,7 @@ export class IssueReporter extends Disposable { // Cmd/Ctrl+Enter previews issue and closes window if (cmdOrCtrlKey && e.keyCode === 13) { if (this.createIssue()) { - remote.getCurrentWindow().close(); + ipcRenderer.send('vscode:closeIssueReporter'); } } diff --git a/src/vs/code/electron-browser/processExplorer/processExplorer.js b/src/vs/code/electron-browser/processExplorer/processExplorer.js index 0a798fb876d..92ffa3e6c9e 100644 --- a/src/vs/code/electron-browser/processExplorer/processExplorer.js +++ b/src/vs/code/electron-browser/processExplorer/processExplorer.js @@ -7,7 +7,7 @@ const path = require('path'); const fs = require('fs'); -const remote = require('electron').remote; +const ipc = require('electron').ipcRenderer; function assign(destination, source) { return Object.keys(source) @@ -141,9 +141,9 @@ function main() { window.addEventListener('keydown', function (e) { const key = extractKey(e); if (key === TOGGLE_DEV_TOOLS_KB) { - remote.getCurrentWebContents().toggleDevTools(); + ipc.send('vscode:toggleDevTools'); } else if (key === RELOAD_KB) { - remote.getCurrentWindow().reload(); + ipc.send('vscode:reloadWindow'); } }); diff --git a/src/vs/code/electron-browser/processExplorer/processExplorerMain.ts b/src/vs/code/electron-browser/processExplorer/processExplorerMain.ts index fe402f18792..379eab77cf3 100644 --- a/src/vs/code/electron-browser/processExplorer/processExplorerMain.ts +++ b/src/vs/code/electron-browser/processExplorer/processExplorerMain.ts @@ -198,7 +198,7 @@ export function startup(data: ProcessExplorerData): void { applyZoom(data.zoomLevel); // Map window process pids to titles, annotate process names with this when rendering to distinguish between them - ipcRenderer.on('windowsInfoResponse', (event, windows) => { + ipcRenderer.on('vscode:windowsInfoResponse', (event, windows) => { mapPidToWindowTitle = new Map<number, string>(); windows.forEach(window => mapPidToWindowTitle.set(window.pid, window.title)); }); diff --git a/src/vs/code/electron-browser/proxy/auth.html b/src/vs/code/electron-browser/proxy/auth.html index e27ec2fc02e..f01e2b70601 100644 --- a/src/vs/code/electron-browser/proxy/auth.html +++ b/src/vs/code/electron-browser/proxy/auth.html @@ -79,11 +79,6 @@ </body> <script> - const electron = require('electron'); - const shell = electron.shell; - const ipc = electron.ipcRenderer; - const remote = electron.remote; - const currentWindow = remote.getCurrentWindow(); function promptForCredentials(data) { return new Promise((c, e) => { diff --git a/src/vs/code/electron-main/app.ts b/src/vs/code/electron-main/app.ts index c783bbd281d..9cf82bb50de 100644 --- a/src/vs/code/electron-main/app.ts +++ b/src/vs/code/electron-main/app.ts @@ -5,7 +5,7 @@ 'use strict'; -import { app, ipcMain as ipc, systemPreferences, shell } from 'electron'; +import { app, ipcMain as ipc, systemPreferences, shell, Event } from 'electron'; import * as platform from 'vs/base/common/platform'; import { WindowsManager } from 'vs/code/electron-main/windows'; import { IWindowsService, OpenContext, ActiveWindowManager } from 'vs/platform/windows/common/windows'; @@ -194,15 +194,15 @@ export class CodeApplication { this.windowsMainService.openNewWindow(OpenContext.DESKTOP); //macOS native tab "+" button }); - ipc.on('vscode:exit', (event: any, code: number) => { + ipc.on('vscode:exit', (event: Event, code: number) => { this.logService.trace('IPC#vscode:exit', code); this.dispose(); this.lifecycleService.kill(code); }); - ipc.on('vscode:fetchShellEnv', event => { - const webContents = event.sender.webContents; + ipc.on('vscode:fetchShellEnv', (event: Event) => { + const webContents = event.sender; getShellEnvironment().then(shellEnv => { if (!webContents.isDestroyed()) { webContents.send('vscode:acceptShellEnv', shellEnv); @@ -216,7 +216,7 @@ export class CodeApplication { }); }); - ipc.on('vscode:broadcast', (event: any, windowId: number, broadcast: { channel: string; payload: any; }) => { + ipc.on('vscode:broadcast', (event: Event, windowId: number, broadcast: { channel: string; payload: any; }) => { if (this.windowsMainService && broadcast.channel && !isUndefinedOrNull(broadcast.payload)) { this.logService.trace('IPC#vscode:broadcast', broadcast.channel, broadcast.payload); @@ -232,6 +232,18 @@ export class CodeApplication { this.labelService.registerFormater(scheme, formater); }); + ipc.on('vscode:toggleDevTools', (event: Event) => { + event.sender.toggleDevTools(); + }); + + ipc.on('vscode:openDevTools', (event: Event) => { + event.sender.openDevTools(); + }); + + ipc.on('vscode:reloadWindow', (event: Event) => { + event.sender.reload(); + }); + // Keyboard layout changes KeyboardLayoutMonitor.INSTANCE.onDidChangeKeyboardLayout(() => { if (this.windowsMainService) { diff --git a/src/vs/platform/issue/electron-main/issueService.ts b/src/vs/platform/issue/electron-main/issueService.ts index cebb4e61237..475deedd92d 100644 --- a/src/vs/platform/issue/electron-main/issueService.ts +++ b/src/vs/platform/issue/electron-main/issueService.ts @@ -10,7 +10,7 @@ import { localize } from 'vs/nls'; import * as objects from 'vs/base/common/objects'; import { parseArgs } from 'vs/platform/environment/node/argv'; import { IIssueService, IssueReporterData, IssueReporterFeatures, ProcessExplorerData } from 'vs/platform/issue/common/issue'; -import { BrowserWindow, ipcMain, screen } from 'electron'; +import { BrowserWindow, ipcMain, screen, Event } from 'electron'; import { ILaunchService } from 'vs/code/electron-main/launch'; import { getPerformanceInfo, PerformanceInfo, getSystemInfo, SystemInfo } from 'vs/code/electron-main/diagnostics'; import { IEnvironmentService } from 'vs/platform/environment/common/environment'; @@ -34,22 +34,28 @@ export class IssueService implements IIssueService { ) { } openReporter(data: IssueReporterData): TPromise<void> { - ipcMain.on('issueSystemInfoRequest', event => { + ipcMain.on('vscode:issueSystemInfoRequest', (event: Event) => { this.getSystemInformation().then(msg => { - event.sender.send('issueSystemInfoResponse', msg); + event.sender.send('vscode:issueSystemInfoResponse', msg); }); }); - ipcMain.on('issuePerformanceInfoRequest', event => { + ipcMain.on('vscode:issuePerformanceInfoRequest', (event: Event) => { this.getPerformanceInfo().then(msg => { - event.sender.send('issuePerformanceInfoResponse', msg); + event.sender.send('vscode:issuePerformanceInfoResponse', msg); }); }); - ipcMain.on('workbenchCommand', (event, arg) => { + ipcMain.on('vscode:workbenchCommand', (event, arg) => { this._issueParentWindow.webContents.send('vscode:runAction', { id: arg, from: 'issueReporter' }); }); + ipcMain.on('vscode:closeIssueReporter', (event: Event) => { + if (this._issueWindow) { + this._issueWindow.close(); + } + }); + this._issueParentWindow = BrowserWindow.getFocusedWindow(); const position = this.getWindowPosition(this._issueParentWindow, 700, 800); if (!this._issueWindow) { @@ -91,9 +97,9 @@ export class IssueService implements IIssueService { } openProcessExplorer(data: ProcessExplorerData): TPromise<void> { - ipcMain.on('windowsInfoRequest', event => { + ipcMain.on('windowsInfoRequest', (event: Event) => { this.launchService.getMainProcessInfo().then(info => { - event.sender.send('windowsInfoResponse', info.windows); + event.sender.send('vscode:windowsInfoResponse', info.windows); }); }); diff --git a/src/vs/workbench/electron-browser/bootstrap/index.js b/src/vs/workbench/electron-browser/bootstrap/index.js index 74ad36e324a..6d4706fc371 100644 --- a/src/vs/workbench/electron-browser/bootstrap/index.js +++ b/src/vs/workbench/electron-browser/bootstrap/index.js @@ -13,7 +13,6 @@ perf.mark('renderer/started'); const path = require('path'); const fs = require('fs'); const electron = require('electron'); -const remote = electron.remote; const ipc = electron.ipcRenderer; Error.stackTraceLimit = 100; // increase number of stack frames (from 10, https://github.com/v8/v8/wiki/Stack-Trace-API) @@ -35,7 +34,7 @@ process.lazyEnv = new Promise(function (resolve) { function onError(error, enableDeveloperTools) { if (enableDeveloperTools) { - remote.getCurrentWebContents().openDevTools(); + ipc.send('vscode:openDevTools'); } console.error('[uncaught exception]: ' + error); @@ -168,9 +167,9 @@ function registerListeners(enableDeveloperTools) { listener = function (e) { const key = extractKey(e); if (key === TOGGLE_DEV_TOOLS_KB) { - remote.getCurrentWebContents().toggleDevTools(); + ipc.send('vscode:toggleDevTools'); } else if (key === RELOAD_KB) { - remote.getCurrentWindow().reload(); + ipc.send('vscode:reloadWindow'); } }; window.addEventListener('keydown', listener); From 1a0311ae4e303de98c2d60b2ca80928ad37878b4 Mon Sep 17 00:00:00 2001 From: isidor <inikolic@microsoft.com> Date: Thu, 23 Aug 2018 15:48:56 +0200 Subject: [PATCH 1161/1276] labelService: allow to register workspace label formater --- src/vs/code/electron-main/app.ts | 2 +- .../standalone/browser/simpleServices.ts | 8 +-- src/vs/platform/label/common/label.ts | 59 +++++++++++-------- .../electron-browser/label.contribution.ts | 2 +- .../test/{uriLabel.test.ts => label.test.ts} | 24 ++++---- .../electron-browser/mainThreadFileSystem.ts | 6 +- src/vs/workbench/api/node/extHost.protocol.ts | 4 +- .../workbench/api/node/extHostFileSystem.ts | 4 +- .../electron-browser/files.contribution.ts | 12 ++-- 9 files changed, 67 insertions(+), 54 deletions(-) rename src/vs/platform/label/test/{uriLabel.test.ts => label.test.ts} (82%) diff --git a/src/vs/code/electron-main/app.ts b/src/vs/code/electron-main/app.ts index 9cf82bb50de..9aa88125994 100644 --- a/src/vs/code/electron-main/app.ts +++ b/src/vs/code/electron-main/app.ts @@ -229,7 +229,7 @@ export class CodeApplication { }); ipc.on('vscode:labelRegisterFormater', (event: any, { scheme, formater }) => { - this.labelService.registerFormater(scheme, formater); + this.labelService.registerFormatter(scheme, formater); }); ipc.on('vscode:toggleDevTools', (event: Event) => { diff --git a/src/vs/editor/standalone/browser/simpleServices.ts b/src/vs/editor/standalone/browser/simpleServices.ts index fc453105c2c..b7e07e8bd6f 100644 --- a/src/vs/editor/standalone/browser/simpleServices.ts +++ b/src/vs/editor/standalone/browser/simpleServices.ts @@ -45,7 +45,7 @@ import { WorkspaceEdit, isResourceTextEdit, TextEdit } from 'vs/editor/common/mo import { IModelService } from 'vs/editor/common/services/modelService'; import { EditOperation } from 'vs/editor/common/core/editOperation'; import { localize } from 'vs/nls'; -import { ILabelService, UriLabelRules } from 'vs/platform/label/common/label'; +import { ILabelService, LabelRules } from 'vs/platform/label/common/label'; export class SimpleModel implements ITextEditorModel { @@ -599,8 +599,8 @@ export class SimpleBulkEditService implements IBulkEditService { export class SimpleUriLabelService implements ILabelService { _serviceBrand: any; - private readonly _onDidRegisterFormater: Emitter<{ scheme: string, formater: UriLabelRules }> = new Emitter<{ scheme: string, formater: UriLabelRules }>(); - public readonly onDidRegisterFormater: Event<{ scheme: string, formater: UriLabelRules }> = this._onDidRegisterFormater.event; + private readonly _onDidRegisterFormatter: Emitter<{ scheme: string, formatter: LabelRules }> = new Emitter<{ scheme: string, formatter: LabelRules }>(); + public readonly onDidRegisterFormatter: Event<{ scheme: string, formatter: LabelRules }> = this._onDidRegisterFormatter.event; public getUriLabel(resource: URI, relative?: boolean): string { if (resource.scheme === 'file') { @@ -613,7 +613,7 @@ export class SimpleUriLabelService implements ILabelService { return ''; } - public registerFormater(schema: string, formater: UriLabelRules): IDisposable { + public registerFormatter(schema: string, formatter: LabelRules): IDisposable { throw new Error('Not implemented'); } } diff --git a/src/vs/platform/label/common/label.ts b/src/vs/platform/label/common/label.ts index 1348437a295..b5f776ea950 100644 --- a/src/vs/platform/label/common/label.ts +++ b/src/vs/platform/label/common/label.ts @@ -22,15 +22,20 @@ export interface ILabelService { _serviceBrand: any; getUriLabel(resource: URI, relative?: boolean, forceNoTildify?: boolean): string; getWorkspaceLabel(workspace: (IWorkspaceIdentifier | ISingleFolderWorkspaceIdentifier | IWorkspace), options?: { verbose: boolean }): string; - registerFormater(schema: string, formater: UriLabelRules): IDisposable; - onDidRegisterFormater: Event<{ scheme: string, formater: UriLabelRules }>; + registerFormatter(schema: string, formatter: LabelRules): IDisposable; + onDidRegisterFormatter: Event<{ scheme: string, formatter: LabelRules }>; } -export interface UriLabelRules { - label: string; // myLabel:/${path} - separator: '/' | '\\' | ''; - tildify?: boolean; - normalizeDriveLetter?: boolean; +export interface LabelRules { + uri: { + label: string; // myLabel:/${path} + separator: '/' | '\\' | ''; + tildify?: boolean; + normalizeDriveLetter?: boolean; + }; + workspace?: { + suffix: string; + }; } const LABEL_SERVICE_ID = 'label'; @@ -44,24 +49,24 @@ function hasDriveLetter(path: string): boolean { export class LabelService implements ILabelService { _serviceBrand: any; - private readonly formaters = new Map<string, UriLabelRules>(); - private readonly _onDidRegisterFormater = new Emitter<{ scheme: string, formater: UriLabelRules }>(); + private readonly formatters = new Map<string, LabelRules>(); + private readonly _onDidRegisterFormatter = new Emitter<{ scheme: string, formatter: LabelRules }>(); constructor( @IEnvironmentService private environmentService: IEnvironmentService, @IWorkspaceContextService private contextService: IWorkspaceContextService ) { } - get onDidRegisterFormater(): Event<{ scheme: string, formater: UriLabelRules }> { - return this._onDidRegisterFormater.event; + get onDidRegisterFormatter(): Event<{ scheme: string, formatter: LabelRules }> { + return this._onDidRegisterFormatter.event; } getUriLabel(resource: URI, relative?: boolean, forceNoTildify?: boolean): string { if (!resource) { return undefined; } - const formater = this.formaters.get(resource.scheme); - if (!formater) { + const formatter = this.formatters.get(resource.scheme); + if (!formatter) { return getPathLabel(resource.path, this.environmentService, relative ? this.contextService : undefined); } @@ -72,8 +77,8 @@ export class LabelService implements ILabelService { if (isEqual(baseResource.uri, resource, !isLinux)) { relativeLabel = ''; // no label if resources are identical } else { - const baseResourceLabel = this.formatUri(baseResource.uri, formater, forceNoTildify); - relativeLabel = ltrim(this.formatUri(resource, formater, forceNoTildify).substring(baseResourceLabel.length), formater.separator); + const baseResourceLabel = this.formatUri(baseResource.uri, formatter, forceNoTildify); + relativeLabel = ltrim(this.formatUri(resource, formatter, forceNoTildify).substring(baseResourceLabel.length), formatter.uri.separator); } const hasMultipleRoots = this.contextService.getWorkspace().folders.length > 1; @@ -86,7 +91,7 @@ export class LabelService implements ILabelService { } } - return this.formatUri(resource, formater, forceNoTildify); + return this.formatUri(resource, formatter, forceNoTildify); } getWorkspaceLabel(workspace: (IWorkspaceIdentifier | ISingleFolderWorkspaceIdentifier | IWorkspace), options?: { verbose: boolean }): string { @@ -100,7 +105,9 @@ export class LabelService implements ILabelService { // Workspace: Single Folder if (isSingleFolderWorkspaceIdentifier(workspace)) { // Folder on disk - return options && options.verbose ? this.getUriLabel(workspace) : basenameOrAuthority(workspace); + const formatter = this.formatters.get(workspace.scheme); + const label = options && options.verbose ? this.getUriLabel(workspace) : basenameOrAuthority(workspace); + return formatter && formatter.workspace && formatter.workspace.suffix ? `${label} (${formatter.workspace.suffix})` : label; } // Workspace: Untitled @@ -118,17 +125,17 @@ export class LabelService implements ILabelService { return localize('workspaceName', "{0} (Workspace)", workspaceName); } - registerFormater(scheme: string, formater: UriLabelRules): IDisposable { - this.formaters.set(scheme, formater); - this._onDidRegisterFormater.fire({ scheme, formater }); + registerFormatter(scheme: string, formatter: LabelRules): IDisposable { + this.formatters.set(scheme, formatter); + this._onDidRegisterFormatter.fire({ scheme, formatter }); return { - dispose: () => this.formaters.delete(scheme) + dispose: () => this.formatters.delete(scheme) }; } - private formatUri(resource: URI, formater: UriLabelRules, forceNoTildify: boolean): string { - let label = formater.label.replace(labelMatchingRegexp, match => { + private formatUri(resource: URI, formatter: LabelRules, forceNoTildify: boolean): string { + let label = formatter.uri.label.replace(labelMatchingRegexp, match => { switch (match) { case '${scheme}': return resource.scheme; case '${authority}': return resource.authority; @@ -138,15 +145,15 @@ export class LabelService implements ILabelService { }); // convert \c:\something => C:\something - if (formater.normalizeDriveLetter && hasDriveLetter(label)) { + if (formatter.uri.normalizeDriveLetter && hasDriveLetter(label)) { label = label.charAt(1).toUpperCase() + label.substr(2); } - if (formater.tildify && !forceNoTildify) { + if (formatter.uri.tildify && !forceNoTildify) { label = tildify(label, this.environmentService.userHome); } - return label.replace(sepRegexp, formater.separator); + return label.replace(sepRegexp, formatter.uri.separator); } } diff --git a/src/vs/platform/label/electron-browser/label.contribution.ts b/src/vs/platform/label/electron-browser/label.contribution.ts index f3b6c6ba189..748d595cb70 100644 --- a/src/vs/platform/label/electron-browser/label.contribution.ts +++ b/src/vs/platform/label/electron-browser/label.contribution.ts @@ -16,7 +16,7 @@ import { LifecyclePhase } from 'vs/platform/lifecycle/common/lifecycle'; class LabelRegistrationContribution implements IWorkbenchContribution { constructor(@ILabelService labelService: ILabelService) { - labelService.onDidRegisterFormater(data => { + labelService.onDidRegisterFormatter(data => { ipc.send('vscode:labelRegisterFormater', data); }); } diff --git a/src/vs/platform/label/test/uriLabel.test.ts b/src/vs/platform/label/test/label.test.ts similarity index 82% rename from src/vs/platform/label/test/uriLabel.test.ts rename to src/vs/platform/label/test/label.test.ts index f1d9f85b72a..cae23fdbc44 100644 --- a/src/vs/platform/label/test/uriLabel.test.ts +++ b/src/vs/platform/label/test/label.test.ts @@ -21,11 +21,13 @@ suite('URI Label', () => { }); test('file scheme', function () { - labelService.registerFormater(Schemas.file, { - label: '${path}', - separator: nativeSep, - tildify: !isWindows, - normalizeDriveLetter: isWindows + labelService.registerFormatter(Schemas.file, { + uri: { + label: '${path}', + separator: nativeSep, + tildify: !isWindows, + normalizeDriveLetter: isWindows + } }); const uri1 = TestWorkspace.folders[0].uri.with({ path: TestWorkspace.folders[0].uri.path.concat('/a/b/c/d') }); @@ -37,11 +39,13 @@ suite('URI Label', () => { }); test('custom scheme', function () { - labelService.registerFormater(Schemas.vscode, { - label: 'LABEL/${path}/${authority}/END', - separator: '/', - tildify: true, - normalizeDriveLetter: true + labelService.registerFormatter(Schemas.vscode, { + uri: { + label: 'LABEL/${path}/${authority}/END', + separator: '/', + tildify: true, + normalizeDriveLetter: true + } }); const uri1 = URI.parse('vscode://microsoft.com/1/2/3/4/5'); diff --git a/src/vs/workbench/api/electron-browser/mainThreadFileSystem.ts b/src/vs/workbench/api/electron-browser/mainThreadFileSystem.ts index b448699381b..657cbbcdca5 100644 --- a/src/vs/workbench/api/electron-browser/mainThreadFileSystem.ts +++ b/src/vs/workbench/api/electron-browser/mainThreadFileSystem.ts @@ -11,7 +11,7 @@ import { TPromise } from 'vs/base/common/winjs.base'; import { FileWriteOptions, FileSystemProviderCapabilities, IFileChange, IFileService, IFileSystemProvider, IStat, IWatchOptions, FileType, FileOverwriteOptions, FileDeleteOptions } from 'vs/platform/files/common/files'; import { extHostNamedCustomer } from 'vs/workbench/api/electron-browser/extHostCustomers'; import { ExtHostContext, ExtHostFileSystemShape, IExtHostContext, IFileChangeDto, MainContext, MainThreadFileSystemShape } from '../node/extHost.protocol'; -import { UriLabelRules, ILabelService } from 'vs/platform/label/common/label'; +import { LabelRules, ILabelService } from 'vs/platform/label/common/label'; @extHostNamedCustomer(MainContext.MainThreadFileSystem) export class MainThreadFileSystem implements MainThreadFileSystemShape { @@ -41,8 +41,8 @@ export class MainThreadFileSystem implements MainThreadFileSystemShape { this._fileProvider.delete(handle); } - $setUriFormatter(scheme: string, formatter: UriLabelRules): void { - this._labelService.registerFormater(scheme, formatter); + $setUriFormatter(scheme: string, formatter: LabelRules): void { + this._labelService.registerFormatter(scheme, formatter); } $onFileSystemChange(handle: number, changes: IFileChangeDto[]): void { diff --git a/src/vs/workbench/api/node/extHost.protocol.ts b/src/vs/workbench/api/node/extHost.protocol.ts index d4dd60c6d53..1c9399cb60a 100644 --- a/src/vs/workbench/api/node/extHost.protocol.ts +++ b/src/vs/workbench/api/node/extHost.protocol.ts @@ -40,7 +40,7 @@ import { IExtensionDescription } from 'vs/workbench/services/extensions/common/e import { createExtHostContextProxyIdentifier as createExtId, createMainContextProxyIdentifier as createMainId, IRPCProtocol, ProxyIdentifier } from 'vs/workbench/services/extensions/node/proxyIdentifier'; import { IProgressOptions, IProgressStep } from 'vs/workbench/services/progress/common/progress'; import { SaveReason } from 'vs/workbench/services/textfile/common/textfiles'; -import { UriLabelRules } from 'vs/platform/label/common/label'; +import { LabelRules } from 'vs/platform/label/common/label'; import * as vscode from 'vscode'; export interface IEnvironment { @@ -483,7 +483,7 @@ export interface IFileChangeDto { export interface MainThreadFileSystemShape extends IDisposable { $registerFileSystemProvider(handle: number, scheme: string, capabilities: FileSystemProviderCapabilities): void; $unregisterProvider(handle: number): void; - $setUriFormatter(scheme: string, formatter: UriLabelRules): void; + $setUriFormatter(scheme: string, formatter: LabelRules): void; $onFileSystemChange(handle: number, resource: IFileChangeDto[]): void; } diff --git a/src/vs/workbench/api/node/extHostFileSystem.ts b/src/vs/workbench/api/node/extHostFileSystem.ts index 74f9610976f..67508b9b339 100644 --- a/src/vs/workbench/api/node/extHostFileSystem.ts +++ b/src/vs/workbench/api/node/extHostFileSystem.ts @@ -15,7 +15,7 @@ import { values } from 'vs/base/common/map'; import { Range, FileChangeType } from 'vs/workbench/api/node/extHostTypes'; import { ExtHostLanguageFeatures } from 'vs/workbench/api/node/extHostLanguageFeatures'; import { Schemas } from 'vs/base/common/network'; -import { UriLabelRules } from 'vs/platform/label/common/label'; +import { LabelRules } from 'vs/platform/label/common/label'; class FsLinkProvider implements vscode.DocumentLinkProvider { @@ -142,7 +142,7 @@ export class ExtHostFileSystem implements ExtHostFileSystemShape { }); } - setUriFormatter(scheme: string, formatter: UriLabelRules): void { + setUriFormatter(scheme: string, formatter: LabelRules): void { this._proxy.$setUriFormatter(scheme, formatter); } diff --git a/src/vs/workbench/parts/files/electron-browser/files.contribution.ts b/src/vs/workbench/parts/files/electron-browser/files.contribution.ts index 3e3039936bb..13694d24cd7 100644 --- a/src/vs/workbench/parts/files/electron-browser/files.contribution.ts +++ b/src/vs/workbench/parts/files/electron-browser/files.contribution.ts @@ -56,11 +56,13 @@ export class OpenExplorerViewletAction extends ToggleViewletAction { class FileUriLabelContribution implements IWorkbenchContribution { constructor(@ILabelService labelService: ILabelService) { - labelService.registerFormater(Schemas.file, { - label: '${path}', - separator: nativeSep, - tildify: !platform.isWindows, - normalizeDriveLetter: platform.isWindows + labelService.registerFormatter(Schemas.file, { + uri: { + label: '${path}', + separator: nativeSep, + tildify: !platform.isWindows, + normalizeDriveLetter: platform.isWindows + } }); } } From ebc9f5cdc617ec0c1b6d495f2a627b08088649dc Mon Sep 17 00:00:00 2001 From: Johannes Rieken <johannes.rieken@gmail.com> Date: Thu, 23 Aug 2018 16:14:27 +0200 Subject: [PATCH 1162/1276] fix error when not having a code editor --- .../browser/parts/editor/breadcrumbsControl.ts | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/vs/workbench/browser/parts/editor/breadcrumbsControl.ts b/src/vs/workbench/browser/parts/editor/breadcrumbsControl.ts index f589bdf3995..892108aad9e 100644 --- a/src/vs/workbench/browser/parts/editor/breadcrumbsControl.ts +++ b/src/vs/workbench/browser/parts/editor/breadcrumbsControl.ts @@ -296,7 +296,7 @@ export class BreadcrumbsControl { this._revealInEditor(event, data.target, this._getEditorGroup(data.payload && data.payload.originalEvent)); }); let focusListener = picker.onDidFocusElement(data => { - if (!(data.target instanceof OutlineElement)) { + if (!editor || !(data.target instanceof OutlineElement)) { return; } if (!editorViewState) { @@ -346,9 +346,11 @@ export class BreadcrumbsControl { return { x, y }; }, onHide: (data) => { - editor.deltaDecorations(editorDecorations, []); - if (editorViewState) { - editor.restoreViewState(editorViewState); + if (editor) { + editor.deltaDecorations(editorDecorations, []); + if (editorViewState) { + editor.restoreViewState(editorViewState); + } } this._breadcrumbsPickerShowing = false; this._updateCkBreadcrumbsActive(); From 95e4df26809417d14dd5025578d2cc070544f920 Mon Sep 17 00:00:00 2001 From: Johannes Rieken <johannes.rieken@gmail.com> Date: Thu, 23 Aug 2018 16:15:43 +0200 Subject: [PATCH 1163/1276] add filtering to breadcrumbs picker, #55004 --- src/vs/platform/list/browser/listService.ts | 79 +++++++++++++++---- .../browser/parts/editor/breadcrumbs.ts | 22 ++++-- .../browser/parts/editor/breadcrumbsPicker.ts | 13 ++- 3 files changed, 86 insertions(+), 28 deletions(-) diff --git a/src/vs/platform/list/browser/listService.ts b/src/vs/platform/list/browser/listService.ts index 8dd1e6580ce..cc9318c6dcf 100644 --- a/src/vs/platform/list/browser/listService.ts +++ b/src/vs/platform/list/browser/listService.ts @@ -18,7 +18,7 @@ import { combinedDisposable, Disposable, dispose, IDisposable, toDisposable } fr import { ScrollbarVisibility } from 'vs/base/common/scrollable'; import { isUndefinedOrNull } from 'vs/base/common/types'; import { TPromise } from 'vs/base/common/winjs.base'; -import { ITree, ITreeConfiguration, ITreeOptions } from 'vs/base/parts/tree/browser/tree'; +import { IFilter, ITree, ITreeConfiguration, ITreeOptions } from 'vs/base/parts/tree/browser/tree'; import { ClickBehavior, DefaultController, DefaultTreestyler, IControllerOptions, OpenMode } from 'vs/base/parts/tree/browser/treeDefaults'; import { Tree } from 'vs/base/parts/tree/browser/treeImpl'; import { localize } from 'vs/nls'; @@ -572,6 +572,10 @@ export interface IHighlightingTreeConfiguration extends ITreeConfiguration { highlighter: IHighlighter; } +export interface IHighlightingTreeOptions extends ITreeOptions { + filterOnType?: boolean; +} + export class HighlightingTreeController extends WorkbenchTreeController { constructor( @@ -599,6 +603,41 @@ export class HighlightingTreeController extends WorkbenchTreeController { } } +class HightlightsFilter implements IFilter { + + static add(config: ITreeConfiguration, options: IHighlightingTreeOptions): ITreeConfiguration { + let myFilter = new HightlightsFilter(); + myFilter.enabled = options.filterOnType; + if (!config.filter) { + config.filter = myFilter; + } else { + let otherFilter = config.filter; + config.filter = { + isVisible(tree: ITree, element: any): boolean { + return myFilter.isVisible(tree, element) && otherFilter.isVisible(tree, element); + } + }; + } + return config; + } + + enabled: boolean = true; + + isVisible(tree: ITree, element: any): boolean { + if (!this.enabled) { + return true; + } + let tree2 = (tree as HighlightingWorkbenchTree); + if (!tree2.isHighlighterScoring()) { + return true; + } + if (tree2.getHighlighterScore(element)) { + return true; + } + return false; + } +} + export class HighlightingWorkbenchTree extends WorkbenchTree { protected readonly domNode: HTMLElement; @@ -611,7 +650,7 @@ export class HighlightingWorkbenchTree extends WorkbenchTree { constructor( parent: HTMLElement, treeConfiguration: IHighlightingTreeConfiguration, - treeOptions: ITreeOptions, + treeOptions: IHighlightingTreeOptions, listOptions: IInputOptions, @IContextKeyService contextKeyService: IContextKeyService, @IContextViewService contextViewService: IContextViewService, @@ -633,7 +672,7 @@ export class HighlightingWorkbenchTree extends WorkbenchTree { // create tree treeConfiguration.controller = treeConfiguration.controller || instantiationService.createInstance(HighlightingTreeController, {}, () => this.onTypeInTree()); - super(treeContainer, treeConfiguration, treeOptions, contextKeyService, listService, themeService, instantiationService, configurationService); + super(treeContainer, HightlightsFilter.add(treeConfiguration, treeOptions), treeOptions, contextKeyService, listService, themeService, instantiationService, configurationService); this.highlighter = treeConfiguration.highlighter; this.highlights = new Map<any, FuzzyScore>(); @@ -705,34 +744,42 @@ export class HighlightingWorkbenchTree extends WorkbenchTree { this.lastSelection = []; } - let nav = this.getNavigator(undefined, false); - let topScore: FuzzyScore; let topElement: any; - while (nav.next()) { - let element = nav.current(); - let score = this.highlighter.getHighlights(this, element, pattern); - this.highlights.set(this._getHighlightsStorageKey(element), score); - element.foo = 1; - if (!topScore || score && topScore[0] < score[0]) { - topScore = score; - topElement = element; + if (pattern) { + let nav = this.getNavigator(undefined, false); + let topScore: FuzzyScore; + while (nav.next()) { + let element = nav.current(); + let score = this.highlighter.getHighlights(this, element, pattern); + this.highlights.set(this._getHighlightsStorageKey(element), score); + element.foo = 1; + if (!topScore || score && topScore[0] < score[0]) { + topScore = score; + topElement = element; + } } + } else { + // no pattern, clear highlights + this.highlights.clear(); } this.refresh().then(() => { - if (topElement && pattern) { + if (topElement) { this.reveal(topElement, .5).then(_ => { this.setSelection([topElement], this); this.setFocus(topElement, this); }); } else { this.setSelection(defaultSelection, this); - this.highlights.clear(); } }, onUnexpectedError); } - getHighlights(element: any): FuzzyScore { + isHighlighterScoring(): boolean { + return this.highlights.size > 0; + } + + getHighlighterScore(element: any): FuzzyScore { return this.highlights.get(this._getHighlightsStorageKey(element)); } diff --git a/src/vs/workbench/browser/parts/editor/breadcrumbs.ts b/src/vs/workbench/browser/parts/editor/breadcrumbs.ts index 940ddfdc570..75077d4db4d 100644 --- a/src/vs/workbench/browser/parts/editor/breadcrumbs.ts +++ b/src/vs/workbench/browser/parts/editor/breadcrumbs.ts @@ -6,16 +6,16 @@ 'use strict'; import { BreadcrumbsWidget } from 'vs/base/browser/ui/breadcrumbs/breadcrumbsWidget'; -import { IDisposable } from 'vs/base/common/lifecycle'; -import { createDecorator } from 'vs/platform/instantiation/common/instantiation'; -import { GroupIdentifier } from 'vs/workbench/common/editor'; -import { registerSingleton } from 'vs/platform/instantiation/common/extensions'; -import { IConfigurationService, IConfigurationOverrides } from 'vs/platform/configuration/common/configuration'; import { Emitter, Event } from 'vs/base/common/event'; -import { Registry } from 'vs/platform/registry/common/platform'; -import { IConfigurationRegistry, Extensions } from 'vs/platform/configuration/common/configurationRegistry'; -import { localize } from 'vs/nls'; import * as glob from 'vs/base/common/glob'; +import { IDisposable } from 'vs/base/common/lifecycle'; +import { localize } from 'vs/nls'; +import { IConfigurationOverrides, IConfigurationService } from 'vs/platform/configuration/common/configuration'; +import { Extensions, IConfigurationRegistry } from 'vs/platform/configuration/common/configurationRegistry'; +import { registerSingleton } from 'vs/platform/instantiation/common/extensions'; +import { createDecorator } from 'vs/platform/instantiation/common/instantiation'; +import { Registry } from 'vs/platform/registry/common/platform'; +import { GroupIdentifier } from 'vs/workbench/common/editor'; export const IBreadcrumbsService = createDecorator<IBreadcrumbsService>('IEditorBreadcrumbsService'); @@ -72,6 +72,7 @@ export abstract class BreadcrumbsConfig<T> { static UseQuickPick = BreadcrumbsConfig._stub<boolean>('breadcrumbs.useQuickPick'); static FilePath = BreadcrumbsConfig._stub<'on' | 'off' | 'last'>('breadcrumbs.filePath'); static SymbolPath = BreadcrumbsConfig._stub<'on' | 'off' | 'last'>('breadcrumbs.symbolPath'); + static FilterOnType = BreadcrumbsConfig._stub<boolean>('breadcrumbs.filterOnType'); static FileExcludes = BreadcrumbsConfig._stub<glob.IExpression>('files.exclude'); @@ -143,6 +144,11 @@ Registry.as<IConfigurationRegistry>(Extensions.Configuration).registerConfigurat localize('symbolpath.last', "Only show the current symbol in the breadcrumbs view."), ] }, + '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 c842ac046e0..cdcf5418c16 100644 --- a/src/vs/workbench/browser/parts/editor/breadcrumbsPicker.ts +++ b/src/vs/workbench/browser/parts/editor/breadcrumbsPicker.ts @@ -23,7 +23,7 @@ import { localize } from 'vs/nls'; 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 { HighlightingWorkbenchTree, IHighlighter, IHighlightingTreeConfiguration } from 'vs/platform/list/browser/listService'; +import { HighlightingWorkbenchTree, IHighlighter, IHighlightingTreeConfiguration, IHighlightingTreeOptions } from 'vs/platform/list/browser/listService'; import { breadcrumbsPickerBackground, widgetShadow } from 'vs/platform/theme/common/colorRegistry'; import { IThemeService } from 'vs/platform/theme/common/themeService'; import { IWorkspace, IWorkspaceContextService, IWorkspaceFolder } from 'vs/platform/workspace/common/workspace'; @@ -55,6 +55,7 @@ export abstract class BreadcrumbsPicker { parent: HTMLElement, @IInstantiationService protected readonly _instantiationService: IInstantiationService, @IThemeService protected readonly _themeService: IThemeService, + @IConfigurationService private readonly _configurationService: IConfigurationService, ) { this._domNode = document.createElement('div'); this._domNode.className = 'monaco-breadcrumbs-picker show-file-icons'; @@ -79,12 +80,15 @@ 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); + const treeConifg = this._completeTreeConfiguration({ dataSource: undefined, renderer: undefined, highlighter: undefined }); this._tree = this._instantiationService.createInstance( HighlightingWorkbenchTree, this._treeContainer, treeConifg, - { useShadows: false }, + <IHighlightingTreeOptions>{ useShadows: false, filterOnType: filterConfig.getValue() }, { placeholder: localize('placeholder', "Find") } ); this._disposables.push(this._tree.onDidChangeSelection(e => { @@ -302,7 +306,7 @@ export class FileRenderer implements IRenderer { fileKind, hidePath: true, fileDecorations: fileDecorations, - matches: createMatches((tree as HighlightingWorkbenchTree).getHighlights(element)), + matches: createMatches((tree as HighlightingWorkbenchTree).getHighlighterScore(element)), extraClasses: ['picker-item'] }); } @@ -335,9 +339,10 @@ export class BreadcrumbsFilePicker extends BreadcrumbsPicker { parent: HTMLElement, @IInstantiationService instantiationService: IInstantiationService, @IThemeService themeService: IThemeService, + @IConfigurationService configService: IConfigurationService, @IWorkspaceContextService private readonly _workspaceService: IWorkspaceContextService, ) { - super(parent, instantiationService, themeService); + super(parent, instantiationService, themeService, configService); } protected _getInput(input: BreadcrumbElement): any { From c051db534321ea8eb6fc2d7ca96f4e7d07e2f952 Mon Sep 17 00:00:00 2001 From: Sandeep Somavarapu <sasomava@microsoft.com> Date: Thu, 23 Aug 2018 16:30:26 +0200 Subject: [PATCH 1164/1276] Use Workspace Extension category --- .../common/extensionManagementUtil.ts | 55 ++++++++++--------- 1 file changed, 29 insertions(+), 26 deletions(-) diff --git a/src/vs/platform/extensionManagement/common/extensionManagementUtil.ts b/src/vs/platform/extensionManagement/common/extensionManagementUtil.ts index 0f626331d1d..4241abb9f91 100644 --- a/src/vs/platform/extensionManagement/common/extensionManagementUtil.ts +++ b/src/vs/platform/extensionManagement/common/extensionManagementUtil.ts @@ -120,43 +120,46 @@ export function getMaliciousExtensionsSet(report: IReportedExtension[]): Set<str return result; } +const workspaceExtensions = new Set<string>(); +[ + 'vscode.extension-editing', + 'vscode.configuration-editing', + 'vscode.search-rg', + 'vscode.css-language-features', + 'vscode.git', + 'vscode.grunt', + 'vscode.gulp', + 'vscode.html-language-features', + 'vscode.json-language-features', + 'vscode.markdown-language-features', + 'vscode.npm', + 'vscode.php-language-features', + 'vscode.typescript-language-features', + 'ms-vscode.node-debug', + 'ms-vscode.node-debug2', + 'ms-python.python', + 'eg2.tslint', + 'dbaeumer.vscode-eslint', + 'eamodio.gitlens' +].forEach(extension => workspaceExtensions.add(extension)); + export function isWorkspaceExtension(manifest: IExtensionManifest, configurationService: IConfigurationService): boolean { const extensionId = getGalleryExtensionId(manifest.publisher, manifest.name); - const workspaceExtensions = configurationService.getValue<string[]>('_workbench.workspaceExtensions') || []; - if (workspaceExtensions.length) { - if (workspaceExtensions.indexOf(extensionId) !== -1) { + const configuredWorkspaceExtensions = configurationService.getValue<string[]>('_workbench.workspaceExtensions') || []; + if (configuredWorkspaceExtensions.length) { + if (configuredWorkspaceExtensions.indexOf(extensionId) !== -1) { return true; } - if (workspaceExtensions.indexOf(`-${extensionId}`) !== -1) { + if (configuredWorkspaceExtensions.indexOf(`-${extensionId}`) !== -1) { return false; } } if (manifest.main) { - if ((manifest.keywords || []).indexOf('capability_fs') !== -1) { + if ((manifest.categories || []).indexOf('Workspace Extension') !== -1) { return true; } - return [ - 'vscode.extension-editing', - 'vscode.configuration-editing', - 'vscode.search-rg', - 'vscode.css-language-features', - 'vscode.git', - 'vscode.grunt', - 'vscode.gulp', - 'vscode.html-language-features', - 'vscode.json-language-features', - 'vscode.markdown-language-features', - 'vscode.npm', - 'vscode.php-language-features', - 'vscode.typescript-language-features', - 'ms-vscode.node-debug', - 'ms-vscode.node-debug2', - 'ms-python.python', - 'eg2.tslint', - 'dbaeumer.vscode-eslint', - 'eamodio.gitlens' - ].indexOf(extensionId) !== -1; + return workspaceExtensions.has(extensionId); } return false; } \ No newline at end of file From ef4382dce3eaff7fad052c50d58033c011eb8b66 Mon Sep 17 00:00:00 2001 From: Alex Dima <alexdima@microsoft.com> Date: Thu, 23 Aug 2018 16:37:28 +0200 Subject: [PATCH 1165/1276] First cut at binary encoding messages for ext host --- .../services/extensions/node/rpcProtocol.ts | 452 +++++++++++++++--- 1 file changed, 376 insertions(+), 76 deletions(-) diff --git a/src/vs/workbench/services/extensions/node/rpcProtocol.ts b/src/vs/workbench/services/extensions/node/rpcProtocol.ts index a2b4a81e145..5694010268e 100644 --- a/src/vs/workbench/services/extensions/node/rpcProtocol.ts +++ b/src/vs/workbench/services/extensions/node/rpcProtocol.ts @@ -164,54 +164,92 @@ export class RPCProtocol implements IRPCProtocol { return; } - let msg = <RPCMessage>JSON.parse(rawmsg.toString()); - if (this._uriTransformer) { - msg = transformIncomingURIs(msg, this._uriTransformer); - } + let offset = 0; + const messageType = MessageIO.deserializeMessageType(rawmsg, offset); offset += 1; + const req = MessageIO.deserializeReq(rawmsg, offset); offset += 4; - switch (msg.type) { - case MessageType.Request: - this._receiveRequest(msg); + switch (messageType) { + case MessageType.RequestJSONArgs: { + let { rpcId, method, args } = MessageIO.deserializeRequestJSONArgs(rawmsg, offset); + if (this._uriTransformer) { + args = transformIncomingURIs(args, this._uriTransformer); + } + this._receiveRequest(req, rpcId, method, args); break; - case MessageType.Cancel: - this._receiveCancel(msg); + } + case MessageType.RequestMixedArgs: { + let { rpcId, method, args } = MessageIO.deserializeRequestMixedArgs(rawmsg, offset); + if (this._uriTransformer) { + args = transformIncomingURIs(args, this._uriTransformer); + } + this._receiveRequest(req, rpcId, method, args); break; - case MessageType.Reply: - this._receiveReply(msg); + } + case MessageType.Cancel: { + this._receiveCancel(req); break; - case MessageType.ReplyErr: - this._receiveReplyErr(msg); + } + case MessageType.ReplyOKEmpty: { + this._receiveReply(req, undefined); break; + } + case MessageType.ReplyOKJSON: { + let value = MessageIO.deserializeReplyOKJSON(rawmsg, offset); + if (this._uriTransformer) { + value = transformIncomingURIs(value, this._uriTransformer); + } + this._receiveReply(req, value); + break; + } + case MessageType.ReplyOKBuffer: { + let value = MessageIO.deserializeReplyOKBuffer(rawmsg, offset); + this._receiveReply(req, value); + break; + } + case MessageType.ReplyErrError: { + let err = MessageIO.deserializeReplyErrError(rawmsg, offset); + if (this._uriTransformer) { + err = transformIncomingURIs(err, this._uriTransformer); + } + this._receiveReplyErr(req, err); + break; + } + case MessageType.ReplyErrEmpty: { + this._receiveReplyErr(req, undefined); + break; + } } } - private _receiveRequest(msg: RequestMessage): void { - const callId = msg.id; - const proxyId = msg.proxyId; + private _receiveRequest(req: number, rpcId: string, method: string, args: any[]): void { + // console.log(`receiveRequest: ${req}, ${rpcId}.${method}`, args); + const callId = String(req); - this._invokedHandlers[callId] = this._invokeHandler(proxyId, msg.method, msg.args); + this._invokedHandlers[callId] = this._invokeHandler(rpcId, method, args); this._invokedHandlers[callId].then((r) => { delete this._invokedHandlers[callId]; if (this._uriTransformer) { r = transformOutgoingURIs(r, this._uriTransformer); } - this._multiplexor.send(Buffer.from(MessageFactory.replyOK(callId, r))); + this._multiplexor.send(MessageIO.serializeReplyOK(req, r)); }, (err) => { delete this._invokedHandlers[callId]; - this._multiplexor.send(Buffer.from(MessageFactory.replyErr(callId, err))); + this._multiplexor.send(MessageIO.serializeReplyErr(req, err)); }); } - private _receiveCancel(msg: CancelMessage): void { - const callId = msg.id; + private _receiveCancel(req: number): void { + // console.log(`receiveCancel: ${req}`); + const callId = String(req); if (this._invokedHandlers[callId]) { this._invokedHandlers[callId].cancel(); } } - private _receiveReply(msg: ReplyMessage): void { - const callId = msg.id; + private _receiveReply(req: number, value: any): void { + // console.log(`receiveReply: ${req}`, value); + const callId = String(req); if (!this._pendingRPCReplies.hasOwnProperty(callId)) { return; } @@ -219,11 +257,11 @@ export class RPCProtocol implements IRPCProtocol { const pendingReply = this._pendingRPCReplies[callId]; delete this._pendingRPCReplies[callId]; - pendingReply.resolveOk(msg.res); + pendingReply.resolveOk(value); } - private _receiveReplyErr(msg: ReplyErrMessage): void { - const callId = msg.id; + private _receiveReplyErr(req: number, value: any): void { + const callId = String(req); if (!this._pendingRPCReplies.hasOwnProperty(callId)) { return; } @@ -232,11 +270,11 @@ export class RPCProtocol implements IRPCProtocol { delete this._pendingRPCReplies[callId]; let err: Error = null; - if (msg.err && msg.err.$isError) { + if (value && value.$isError) { err = new Error(); - err.name = msg.err.name; - err.message = msg.err.message; - err.stack = msg.err.stack; + err.name = value.name; + err.message = value.message; + err.stack = value.stack; } pendingReply.resolveErr(err); } @@ -266,16 +304,17 @@ export class RPCProtocol implements IRPCProtocol { return TPromise.wrapError<any>(errors.canceled()); } - const callId = String(++this._lastMessageId); + const nCallId = ++this._lastMessageId; + const callId = String(nCallId); const result = new LazyPromise(() => { - this._multiplexor.send(Buffer.from(MessageFactory.cancel(callId))); + this._multiplexor.send(MessageIO.serializeCancel(nCallId)); }); this._pendingRPCReplies[callId] = result; if (this._uriTransformer) { args = transformOutgoingURIs(args, this._uriTransformer); } - this._multiplexor.send(Buffer.from(MessageFactory.request(callId, proxyId, methodName, args))); + this._multiplexor.send(MessageIO.serializeRequest(nCallId, proxyId, methodName, args)); return result; } } @@ -302,7 +341,7 @@ class RPCMultiplexer { let i = 0; while (i < data.length) { - const size = data.readUInt32BE(i); + const size = data.readUInt32LE(i); onMessage(data.slice(i + 4, i + 4 + size)); i += 4 + size; } @@ -310,14 +349,13 @@ class RPCMultiplexer { } private _sendAccumulated(): void { - const size = this._messagesToSend.reduce((r, b) => r + 4 + b.byteLength, 0); + const size = this._messagesToSend.reduce((r, b) => r + b.byteLength, 0); const buffer = Buffer.allocUnsafe(size); - let i = 0; + let offset = 0; for (const msg of this._messagesToSend) { - buffer.writeUInt32BE(msg.byteLength, i); - msg.copy(buffer, i + 4); - i += 4 + msg.byteLength; + msg.copy(buffer, offset); + offset += msg.byteLength; } this._messagesToSend = []; @@ -332,57 +370,319 @@ class RPCMultiplexer { } } -class MessageFactory { - public static cancel(req: string): string { - return `{"type":${MessageType.Cancel},"id":"${req}"}`; +class MessageIO { + private static arrayContainsBuffer(arr: any[]): boolean { + for (let i = 0, len = arr.length; i < len; i++) { + if (Buffer.isBuffer(arr[i])) { + return true; + } + } + return false; } - public static request(req: string, rpcId: string, method: string, args: any[]): string { - return `{"type":${MessageType.Request},"id":"${req}","proxyId":"${rpcId}","method":"${method}","args":${JSON.stringify(args)}}`; + public static serializeRequest(req: number, rpcId: string, method: string, args: any[]): Buffer { + if (this.arrayContainsBuffer(args)) { + let massagedArgs: (string | Buffer)[] = new Array(args.length); + let argsLengths: number[] = new Array(args.length); + for (let i = 0, len = args.length; i < len; i++) { + const arg = args[i]; + if (Buffer.isBuffer(arg)) { + massagedArgs[i] = arg; + argsLengths[i] = arg.byteLength; + } else { + massagedArgs[i] = JSON.stringify(arg); + argsLengths[i] = Buffer.byteLength(massagedArgs[i]); + } + } + return this._requestMixedArgs(req, rpcId, method, massagedArgs, argsLengths); + } + return this._requestJSONArgs(req, rpcId, method, JSON.stringify(args)); } - public static replyOK(req: string, res: any): string { + public static deserializeMessageType(buff: Buffer, offset: number): MessageType { + return buff[offset]; + } + + public static deserializeReq(buff: Buffer, offset: number): number { + return buff.readUInt32LE(offset, true); + } + + private static _requestJSONArgs(req: number, rpcId: string, method: string, args: string): Buffer { + const rpcIdByteLength = Buffer.byteLength(rpcId); + const methodByteLength = Buffer.byteLength(method); + const argsByteLength = Buffer.byteLength(args); + + let len = 0; + // len += 4; // msg length + len += 1; // msg type + len += 4; // req + len += 1; // rpcId length + len += rpcIdByteLength; + len += 1; // method length + len += methodByteLength; + len += 4; // arg length + len += argsByteLength; + + let result = Buffer.allocUnsafe(len + 4); + let offset = 0; + + result.writeUInt32LE(len, offset, true); offset += 4; + result.writeUInt8(MessageType.RequestJSONArgs, offset, true); offset += 1; + result.writeUInt32LE(req, offset, true); offset += 4; + result.writeUInt8(rpcIdByteLength, offset, true); offset += 1; + result.write(rpcId, offset, rpcIdByteLength, 'utf8'); offset += rpcIdByteLength; + result.writeUInt8(methodByteLength, offset, true); offset += 1; + result.write(method, offset, methodByteLength, 'utf8'); offset += methodByteLength; + result.writeUInt32LE(argsByteLength, offset, true); offset += 4; + result.write(args, offset, argsByteLength, 'utf8'); offset += argsByteLength; + + return result; + } + + public static deserializeRequestJSONArgs(buff: Buffer, offset: number): { rpcId: string; method: string; args: any[]; } { + const rpcIdByteLength = buff.readUInt8(offset, true); offset += 1; + const rpcId = buff.toString('utf8', offset, offset + rpcIdByteLength); offset += rpcIdByteLength; + const methodByteLength = buff.readUInt8(offset, true); offset += 1; + const method = buff.toString('utf8', offset, offset + methodByteLength); offset += methodByteLength; + const argsByteLength = buff.readUInt32LE(offset, true); offset += 4; + const args = buff.toString('utf8', offset, offset + argsByteLength); offset += argsByteLength; + return { + rpcId: rpcId, + method: method, + args: JSON.parse(args) + }; + } + + private static _requestMixedArgs(req: number, rpcId: string, method: string, args: (string | Buffer)[], argsLengths: number[]): Buffer { + const rpcIdByteLength = Buffer.byteLength(rpcId); + const methodByteLength = Buffer.byteLength(method); + + let len = 0; + // len += 4; // msg length + len += 1; // msg type + len += 4; // req + len += 1; // rpcId length + len += rpcIdByteLength; + len += 1; // method length + len += methodByteLength; + len += 1; // arg count + for (let i = 0, len = args.length; i < len; i++) { + len += 1; // arg type + len += 4; // buffer length + len += argsLengths[i]; + } + + let result = Buffer.allocUnsafe(len + 4); + let offset = 0; + + result.writeUInt32LE(len, offset, true); offset += 4; + result.writeUInt8(MessageType.RequestMixedArgs, offset, true); offset += 1; + result.writeUInt32LE(req, offset, true); offset += 4; + result.writeUInt8(rpcIdByteLength, offset, true); offset += 1; + result.write(rpcId, offset, rpcIdByteLength, 'utf8'); offset += rpcIdByteLength; + result.writeUInt8(methodByteLength, offset, true); offset += 1; + result.write(method, offset, methodByteLength, 'utf8'); offset += methodByteLength; + result.writeUInt8(args.length, offset, true); offset += 1; + for (let i = 0, len = args.length; i < len; i++) { + const arg = args[i]; + if (typeof arg === 'string') { + result.writeUInt8(ArgType.ArgString, offset, true); offset += 1; + result.writeUInt32LE(argsLengths[i], offset, true); offset += 4; + result.write(arg, offset, argsLengths[i], 'utf8'); offset += argsLengths[i]; + } else { + result.writeUInt8(ArgType.ArgBuffer, offset, true); offset += 1; + result.writeUInt32LE(argsLengths[i], offset, true); offset += 4; + arg.copy(result, offset); offset += argsLengths[i]; + } + } + + return result; + } + + public static deserializeRequestMixedArgs(buff: Buffer, offset: number): { rpcId: string; method: string; args: any[]; } { + const rpcIdByteLength = buff.readUInt8(offset, true); offset += 1; + const rpcId = buff.toString('utf8', offset, offset + rpcIdByteLength); offset += rpcIdByteLength; + const methodByteLength = buff.readUInt8(offset, true); offset += 1; + const method = buff.toString('utf8', offset, offset + methodByteLength); offset += methodByteLength; + const argsCount = buff.readUInt8(offset, true); offset += 1; + let args: any[] = new Array(argsCount); + for (let i = 0; i < argsCount; i++) { + const argType = buff.readUInt8(offset, true); offset += 1; + const argLength = buff.readUInt32LE(offset, true); offset += 4; + if (argType === ArgType.ArgString) { + args[i] = JSON.parse(buff.toString('utf8', offset, offset + argLength)); offset += argLength; + } else { + args[i] = buff.slice(offset, offset + argLength); offset += argLength; + } + } + return { + rpcId: rpcId, + method: method, + args: args + }; + } + + public static serializeCancel(req: number): Buffer { + let len = 0; + // len += 4; // msg length + len += 1; // msg type + len += 4; // req + + let result = Buffer.allocUnsafe(len + 4); + let offset = 0; + + result.writeUInt32LE(len, offset, true); offset += 4; + result.writeUInt8(MessageType.Cancel, offset, true); offset += 1; + result.writeUInt32LE(req, offset, true); offset += 4; + + return result; + } + + public static serializeReplyOK(req: number, res: any): Buffer { if (typeof res === 'undefined') { - return `{"type":${MessageType.Reply},"id":"${req}"}`; + return this._serializeReplyOKEmpty(req); } - return `{"type":${MessageType.Reply},"id":"${req}","res":${JSON.stringify(res)}}`; + if (Buffer.isBuffer(res)) { + return this._serializeReplyOKBuffer(req, res); + } + return this._serializeReplyOKJSON(req, JSON.stringify(res)); } - public static replyErr(req: string, err: any): string { + private static _serializeReplyOKEmpty(req: number): Buffer { + let len = 0; + // len += 4; // msg length + len += 1; // msg type + len += 4; // req + + let result = Buffer.allocUnsafe(len + 4); + let offset = 0; + + result.writeUInt32LE(len, offset, true); offset += 4; + result.writeUInt8(MessageType.ReplyOKEmpty, offset, true); offset += 1; + result.writeUInt32LE(req, offset, true); offset += 4; + + return result; + } + + private static _serializeReplyOKBuffer(req: number, res: Buffer): Buffer { + let len = 0; + // len += 4; // msg length + len += 1; // msg type + len += 4; // req + len += 4; // res length + len += res.byteLength; + + let result = Buffer.allocUnsafe(len + 4); + let offset = 0; + + result.writeUInt32LE(len, offset, true); offset += 4; + result.writeUInt8(MessageType.ReplyOKBuffer, offset, true); offset += 1; + result.writeUInt32LE(req, offset, true); offset += 4; + result.writeUInt32LE(res.byteLength, offset, true); offset += 4; + res.copy(result, offset); offset += res.byteLength; + + return result; + } + + public static deserializeReplyOKBuffer(buff: Buffer, offset: number): Buffer { + const resByteLength = buff.readUInt32LE(offset, true); offset += 4; + const res = buff.slice(offset, offset + resByteLength); offset += resByteLength; + return res; + } + + private static _serializeReplyOKJSON(req: number, res: string): Buffer { + const resByteLength = Buffer.byteLength(res); + + let len = 0; + // len += 4; // msg length + len += 1; // msg type + len += 4; // req + len += 4; // res length + len += resByteLength; + + let result = Buffer.allocUnsafe(len + 4); + let offset = 0; + + result.writeUInt32LE(len, offset, true); offset += 4; + result.writeUInt8(MessageType.ReplyOKJSON, offset, true); offset += 1; + result.writeUInt32LE(req, offset, true); offset += 4; + result.writeUInt32LE(resByteLength, offset, true); offset += 4; + result.write(res, offset, resByteLength, 'utf8'); offset += resByteLength; + + return result; + } + + public static deserializeReplyOKJSON(buff: Buffer, offset: number): any { + const resByteLength = buff.readUInt32LE(offset, true); offset += 4; + const res = buff.toString('utf8', offset, offset + resByteLength); offset += resByteLength; + return JSON.parse(res); + } + + public static serializeReplyErr(req: number, err: any): Buffer { if (err instanceof Error) { - return `{"type":${MessageType.ReplyErr},"id":"${req}","err":${JSON.stringify(errors.transformErrorForSerialization(err))}}`; + return this._serializeReplyErrEror(req, err); } - return `{"type":${MessageType.ReplyErr},"id":"${req}","err":null}`; + return this._serializeReplyErrEmpty(err); + } + + private static _serializeReplyErrEror(req: number, _err: Error): Buffer { + const err = JSON.stringify(errors.transformErrorForSerialization(_err)); + const errByteLength = Buffer.byteLength(err); + + let len = 0; + len += 1; // msg type + len += 4; // req + len += 4; // err length + len += errByteLength; + + let result = Buffer.allocUnsafe(len + 4); + let offset = 0; + + result.writeUInt32LE(len, offset, true); offset += 4; + result.writeUInt8(MessageType.ReplyErrError, offset, true); offset += 1; + result.writeUInt32LE(req, offset, true); offset += 4; + result.writeUInt32LE(errByteLength, offset, true); offset += 4; + result.write(err, offset, errByteLength, 'utf8'); offset += errByteLength; + + console.log(result); + + return result; + } + + public static deserializeReplyErrError(buff: Buffer, offset: number): Error { + const errByteLength = buff.readUInt32LE(offset, true); offset += 4; + const err = buff.toString('utf8', offset, offset + errByteLength); offset += errByteLength; + return JSON.parse(err); + } + + private static _serializeReplyErrEmpty(req: number): Buffer { + let len = 0; + len += 1; // msg type + len += 4; // req + + let result = Buffer.allocUnsafe(len + 4); + let offset = 0; + + result.writeUInt32LE(len, offset, true); offset += 4; + result.writeUInt8(MessageType.ReplyErrEmpty, offset, true); offset += 1; + result.writeUInt32LE(req, offset, true); offset += 4; + + return result; } } const enum MessageType { - Request = 1, - Cancel = 2, - Reply = 3, - ReplyErr = 4 + RequestJSONArgs = 1, + RequestMixedArgs = 2, + Cancel = 3, + ReplyOKEmpty = 4, + ReplyOKBuffer = 5, + ReplyOKJSON = 6, + ReplyErrError = 7, + ReplyErrEmpty = 8, } -class RequestMessage { - type: MessageType.Request; - id: string; - proxyId: string; - method: string; - args: any[]; +const enum ArgType { + ArgString = 1, + ArgBuffer = 2 } -class CancelMessage { - type: MessageType.Cancel; - id: string; -} -class ReplyMessage { - type: MessageType.Reply; - id: string; - res: any; -} -class ReplyErrMessage { - type: MessageType.ReplyErr; - id: string; - err: errors.SerializedError; -} - -type RPCMessage = RequestMessage | CancelMessage | ReplyMessage | ReplyErrMessage; From 9710c0aa6d9962819da97917675c4695a680f9d4 Mon Sep 17 00:00:00 2001 From: Alex Dima <alexdima@microsoft.com> Date: Thu, 23 Aug 2018 16:46:00 +0200 Subject: [PATCH 1166/1276] Use allocUnsafe to benefit from buffer pool --- src/vs/base/parts/ipc/node/ipc.net.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vs/base/parts/ipc/node/ipc.net.ts b/src/vs/base/parts/ipc/node/ipc.net.ts index 3360b004e34..cd6474e039c 100644 --- a/src/vs/base/parts/ipc/node/ipc.net.ts +++ b/src/vs/base/parts/ipc/node/ipc.net.ts @@ -164,7 +164,7 @@ export class Protocol implements IDisposable, IMessagePassingProtocol { } send(buffer: Buffer): void { - const header = Buffer.alloc(Protocol._headerLen); + const header = Buffer.allocUnsafe(Protocol._headerLen); header.writeUInt32BE(buffer.length, 0, true); this._writeSoon(header, buffer); } From c1126302de7261d7d2bf3ada2fbfda5cb881b244 Mon Sep 17 00:00:00 2001 From: Benjamin Pasero <benjpas@microsoft.com> Date: Thu, 23 Aug 2018 16:48:34 +0200 Subject: [PATCH 1167/1276] back to old solution to fix #57056 --- 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 9aa88125994..5a56a7abf29 100644 --- a/src/vs/code/electron-main/app.ts +++ b/src/vs/code/electron-main/app.ts @@ -319,7 +319,7 @@ export class CodeApplication { // See: https://github.com/Microsoft/vscode/issues/35361#issuecomment-399794085 try { if (platform.isMacintosh && this.configurationService.getValue<boolean>('window.nativeTabs') === true && !systemPreferences.getUserDefault('NSUseImprovedLayoutPass', 'boolean')) { - systemPreferences.registerDefaults({ NSUseImprovedLayoutPass: true }); + systemPreferences.setUserDefault('NSUseImprovedLayoutPass', 'boolean', true as any); } } catch (error) { this.logService.error(error); From f0e2534ad1e9acc6e9287c7ea8597b70b40af49f Mon Sep 17 00:00:00 2001 From: Matt Bierner <matb@microsoft.com> Date: Thu, 23 Aug 2018 17:57:50 +0200 Subject: [PATCH 1168/1276] Update markdown grammar --- .../syntaxes/markdown.tmLanguage.json | 32 +++++++++---------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/extensions/markdown-basics/syntaxes/markdown.tmLanguage.json b/extensions/markdown-basics/syntaxes/markdown.tmLanguage.json index 1036f52cab4..216edc2b74c 100644 --- a/extensions/markdown-basics/syntaxes/markdown.tmLanguage.json +++ b/extensions/markdown-basics/syntaxes/markdown.tmLanguage.json @@ -4,7 +4,7 @@ "If you want to provide a fix or improvement, please create a pull request against the original repository.", "Once accepted there, we are happy to receive an update request." ], - "version": "https://github.com/microsoft/vscode-markdown-tm-grammar/commit/935f7a6d1da73e16231be18c545d7991d3698075", + "version": "https://github.com/microsoft/vscode-markdown-tm-grammar/commit/3445afdd642f67052a21c0f86bf76b3deb45fd26", "name": "Markdown", "scopeName": "text.html.markdown", "patterns": [ @@ -1986,7 +1986,7 @@ "include": "#list_paragraph" } ], - "while": "((^|\\G)([ ]{4}|\\t))|(^[ \\t]*$)" + "while": "((^|\\G)([ ]{2,4}|\\t))|(^[ \\t]*$)" }, { "begin": "(^|\\G)([ ]{0,3})([0-9]+\\.)([ ]{1,3}|\\t)", @@ -2004,7 +2004,7 @@ "include": "#list_paragraph" } ], - "while": "((^|\\G)([ ]{4}|\\t))|(^[ \\t]*$)" + "while": "((^|\\G)([ ]{2,4}|\\t))|(^[ \\t]*$)" } ] }, @@ -2343,32 +2343,32 @@ "7": { "name": "markup.underline.link.markdown" }, - "8": { + "9": { "name": "punctuation.definition.link.markdown" }, - "9": { - "name": "string.other.link.description.title.markdown" - }, "10": { - "name": "punctuation.definition.string.begin.markdown" + "name": "string.other.link.description.title.markdown" }, "11": { - "name": "punctuation.definition.string.end.markdown" - }, - "12": { - "name": "string.other.link.description.title.markdown" - }, - "13": { "name": "punctuation.definition.string.begin.markdown" }, - "14": { + "12": { "name": "punctuation.definition.string.end.markdown" }, + "13": { + "name": "string.other.link.description.title.markdown" + }, + "14": { + "name": "punctuation.definition.string.begin.markdown" + }, "15": { + "name": "punctuation.definition.string.end.markdown" + }, + "16": { "name": "punctuation.definition.metadata.markdown" } }, - "match": "(?x)\n (\\[)((?<square>[^\\[\\]\\\\]|\\\\.|\\[\\g<square>*+\\])*+)(\\])\n # Match the link text.\n (\\() # Opening paren for url\n (<?)(.*?)(>?) # The url\n [ \\t]* # Optional whitespace\n (?:\n ((\\().+?(\\))) # Match title in parens…\n | ((\").+?(\")) # or in quotes.\n )? # Title is optional\n \\s* # Optional whitespace\n (\\))\n", + "match": "(?x)\n (\\[)((?<square>[^\\[\\]\\\\]|\\\\.|\\[\\g<square>*+\\])*+)(\\])\n # Match the link text.\n (\\() # Opening paren for url\n (<?)((?<url>[^\\s()]+|\\(\\g<url>*\\))*)(>?) # The url\n [ \\t]* # Optional whitespace\n (?:\n ((\\().+?(\\))) # Match title in parens…\n | ((\").+?(\")) # or in quotes.\n )? # Title is optional\n \\s* # Optional whitespace\n (\\))\n", "name": "meta.link.inline.markdown" }, "link-ref": { From 7756abfff9b85a99fe89cadab11691bd1dc74d6c Mon Sep 17 00:00:00 2001 From: Christopher Leidigh <cleidigh@Gmail.com> Date: Thu, 23 Aug 2018 15:42:58 -0400 Subject: [PATCH 1169/1276] Settings: Allow description to toggle checkbox Fixes: #54053 (#57103) --- .../parts/preferences/browser/settingsTree.ts | 23 +++++++++++++++++-- 1 file changed, 21 insertions(+), 2 deletions(-) diff --git a/src/vs/workbench/parts/preferences/browser/settingsTree.ts b/src/vs/workbench/parts/preferences/browser/settingsTree.ts index 57614ee92f5..7e1e278edf6 100644 --- a/src/vs/workbench/parts/preferences/browser/settingsTree.ts +++ b/src/vs/workbench/parts/preferences/browser/settingsTree.ts @@ -673,6 +673,21 @@ export class SettingsRenderer implements ITreeRenderer { template.onChange(checkbox.checked); } })); + + // Need to listen for mouse clicks on description and toggle checkbox - use target ID for safety + // Also have to ignore embedded links - too buried to stop propagation + toDispose.push(DOM.addDisposableListener(descriptionElement, DOM.EventType.MOUSE_DOWN, (e) => { + const targetElement = <HTMLElement>e.toElement; + const targetId = descriptionElement.getAttribute('checkboxLabelTargetId'); + + // Make sure we are not a link and the target ID matches + // Toggle target checkbox + if (targetElement.tagName !== 'A' && targetId === template.checkbox.domNode.id) { + template.checkbox.checked = template.checkbox.checked ? false : true; + } + DOM.EventHelper.stop(e); + })); + checkbox.domNode.classList.add(SettingsRenderer.CONTROL_CLASS); const toolbar = this.renderSettingToolbar(container); toDispose.push(toolbar); @@ -917,6 +932,10 @@ export class SettingsRenderer implements ITreeRenderer { template.descriptionElement.innerText = element.description; } + // Add checkbox target to description clickable and able to toggle checkbox + const checkbox_id = (element.displayCategory + '_' + element.displayLabel).replace(/ /g, '_') + '_Item'; + template.descriptionElement.setAttribute('checkboxLabelTargetId', checkbox_id); + if (element.overriddenScopeList.length) { let otherOverridesLabel = element.isConfigured ? localize('alsoConfiguredIn', "Also modified in") : @@ -988,9 +1007,9 @@ export class SettingsRenderer implements ITreeRenderer { // Labels will not be read on descendent input elements of the parent treeitem // unless defined as role=treeitem and indirect aria-labelledby approach // TODO: Determine method to normally label input items with value read last - template.checkbox.domNode.setAttribute('id', id + 'item'); + template.checkbox.domNode.setAttribute('id', id + '_Item'); template.checkbox.domNode.setAttribute('role', 'treeitem'); - template.checkbox.domNode.setAttribute('aria-labelledby', id + 'item ' + id); + template.checkbox.domNode.setAttribute('aria-labelledby', id + '_Item ' + id); } From fd9d375827b0191bf7c576cd89a99b2ae740ca7b Mon Sep 17 00:00:00 2001 From: Ramya Achutha Rao <ramyar@microsoft.com> Date: Thu, 23 Aug 2018 12:55:20 -0700 Subject: [PATCH 1170/1276] Use editor.fontweight in suggest widget #53469 --- src/vs/editor/contrib/suggest/suggestWidget.ts | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/vs/editor/contrib/suggest/suggestWidget.ts b/src/vs/editor/contrib/suggest/suggestWidget.ts index a221be2731d..8f5b76048ac 100644 --- a/src/vs/editor/contrib/suggest/suggestWidget.ts +++ b/src/vs/editor/contrib/suggest/suggestWidget.ts @@ -110,10 +110,12 @@ class Renderer implements IRenderer<ICompletionItem, ISuggestionTemplateData> { const fontFamily = configuration.fontInfo.fontFamily; const fontSize = configuration.contribInfo.suggestFontSize || configuration.fontInfo.fontSize; const lineHeight = configuration.contribInfo.suggestLineHeight || configuration.fontInfo.lineHeight; + const fontWeight = configuration.fontInfo.fontWeight; const fontSizePx = `${fontSize}px`; const lineHeightPx = `${lineHeight}px`; data.root.style.fontSize = fontSizePx; + data.root.style.fontWeight = fontWeight; main.style.fontFamily = fontFamily; main.style.lineHeight = lineHeightPx; data.icon.style.height = lineHeightPx; @@ -330,10 +332,12 @@ class SuggestionDetails { const fontFamily = configuration.fontInfo.fontFamily; const fontSize = configuration.contribInfo.suggestFontSize || configuration.fontInfo.fontSize; const lineHeight = configuration.contribInfo.suggestLineHeight || configuration.fontInfo.lineHeight; + const fontWeight = configuration.fontInfo.fontWeight; const fontSizePx = `${fontSize}px`; const lineHeightPx = `${lineHeight}px`; this.el.style.fontSize = fontSizePx; + this.el.style.fontWeight = fontWeight; this.type.style.fontFamily = fontFamily; this.close.style.height = lineHeightPx; this.close.style.width = lineHeightPx; From 1b7289782a8bd99ce9f47b6485509e8dfb56d93a Mon Sep 17 00:00:00 2001 From: Miguel Solorio <miguel.solorio@microsoft.com> Date: Thu, 23 Aug 2018 13:32:13 -0700 Subject: [PATCH 1171/1276] Make stop icon smaller and less brighter --- src/vs/workbench/parts/search/browser/media/stop-inverse.svg | 4 +++- src/vs/workbench/parts/search/browser/media/stop.svg | 4 +++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/src/vs/workbench/parts/search/browser/media/stop-inverse.svg b/src/vs/workbench/parts/search/browser/media/stop-inverse.svg index ef79528e9c8..3740e50c8c0 100644 --- a/src/vs/workbench/parts/search/browser/media/stop-inverse.svg +++ b/src/vs/workbench/parts/search/browser/media/stop-inverse.svg @@ -1 +1,3 @@ -<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" enable-background="new 0 0 16 16" height="16" width="16"><path fill="#F6F6F6" d="M13 13h-10v-10h10v10z"/><path fill="#C5C5C5" d="M12 12h-8v-8h8v8z"/></svg> \ No newline at end of file +<svg width="14" height="14" viewBox="0 0 14 14" fill="none" xmlns="http://www.w3.org/2000/svg"> +<path d="M11 11H3V3H11V11Z" fill="#C5C5C5"/> +</svg> \ No newline at end of file diff --git a/src/vs/workbench/parts/search/browser/media/stop.svg b/src/vs/workbench/parts/search/browser/media/stop.svg index 0b36e84ac92..9a036f2e620 100644 --- a/src/vs/workbench/parts/search/browser/media/stop.svg +++ b/src/vs/workbench/parts/search/browser/media/stop.svg @@ -1 +1,3 @@ -<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" enable-background="new 0 0 16 16" height="16" width="16"><path fill="#F6F6F6" d="M13 13h-10v-10h10v10z"/><path fill="#424242" d="M12 12h-8v-8h8v8z"/></svg> \ No newline at end of file +<svg width="14" height="14" viewBox="0 0 14 14" fill="none" xmlns="http://www.w3.org/2000/svg"> +<path d="M11 11H3V3H11V11Z" fill="#424242"/> +</svg> \ No newline at end of file From 80fca4c016d6edb3aa2cf5f35158f2e2d6e57e9b Mon Sep 17 00:00:00 2001 From: Aldo Donetti <aldonetti@users.noreply.github.com> Date: Thu, 23 Aug 2018 23:16:34 +0200 Subject: [PATCH 1172/1276] missing word in string (#57084) --- src/vs/editor/common/config/commonEditorConfig.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vs/editor/common/config/commonEditorConfig.ts b/src/vs/editor/common/config/commonEditorConfig.ts index bed782369b0..e8bc9eb8882 100644 --- a/src/vs/editor/common/config/commonEditorConfig.ts +++ b/src/vs/editor/common/config/commonEditorConfig.ts @@ -522,7 +522,7 @@ const editorConfiguration: IConfigurationNode = { '', ], 'default': EDITOR_DEFAULTS.autoClosingQuotes, - 'description': nls.localize('autoClosingQuotes', "Controls whether the editor should automatically close quotes the user adds an opening quote.") + 'description': nls.localize('autoClosingQuotes', "Controls whether the editor should automatically close quotes after the user adds an opening quote.") }, 'editor.autoWrapping': { type: 'string', From 1eeb5b93775c076e65ded040496bcd5b10dff648 Mon Sep 17 00:00:00 2001 From: Rob Lourens <roblourens@gmail.com> Date: Thu, 23 Aug 2018 14:41:52 -0700 Subject: [PATCH 1173/1276] Fix #57077 - remember replace state correctly --- src/vs/workbench/parts/search/browser/searchView.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vs/workbench/parts/search/browser/searchView.ts b/src/vs/workbench/parts/search/browser/searchView.ts index fe81d90a0f5..89b830a0b79 100644 --- a/src/vs/workbench/parts/search/browser/searchView.ts +++ b/src/vs/workbench/parts/search/browser/searchView.ts @@ -404,7 +404,7 @@ export class SearchView extends Viewlet implements IViewlet, IPanel { if (!isReplaceShown) { this.storageService.store(SearchView.SHOW_REPLACE_STORAGE_KEY, false, StorageScope.WORKSPACE); } else { - this.storageService.remove(SearchView.SHOW_REPLACE_STORAGE_KEY); + this.storageService.remove(SearchView.SHOW_REPLACE_STORAGE_KEY, StorageScope.WORKSPACE); } } From 4ed24e070ab4bf4995af829e5cfaabcf01ff4d45 Mon Sep 17 00:00:00 2001 From: Daniel Imms <daimms@microsoft.com> Date: Thu, 23 Aug 2018 15:28:25 -0700 Subject: [PATCH 1174/1276] Defer terminal process creation to allow container to be created Fixes #48136 --- .../parts/terminal/electron-browser/terminalInstance.ts | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/vs/workbench/parts/terminal/electron-browser/terminalInstance.ts b/src/vs/workbench/parts/terminal/electron-browser/terminalInstance.ts index 04d9dcba251..dd08c8bf750 100644 --- a/src/vs/workbench/parts/terminal/electron-browser/terminalInstance.ts +++ b/src/vs/workbench/parts/terminal/electron-browser/terminalInstance.ts @@ -713,8 +713,6 @@ export class TerminalInstance implements ITerminalInstance { this._processManager = this._instantiationService.createInstance(TerminalProcessManager, this._id, this._configHelper); this._processManager.onProcessReady(() => this._onProcessIdReady.fire(this)); this._processManager.onProcessExit(exitCode => this._onProcessExit(exitCode)); - this._processManager.createProcess(this._shellLaunchConfig, this._cols, this._rows); - this._processManager.onProcessData(data => this._onData.fire(data)); if (this._shellLaunchConfig.name) { @@ -734,6 +732,12 @@ 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); + }, 0); } private _onProcessData(data: string): void { From fc300b4640a6d4f618351cd65607ad164ad0cde8 Mon Sep 17 00:00:00 2001 From: SteVen Batten <stbatt@microsoft.com> Date: Thu, 23 Aug 2018 16:31:43 -0700 Subject: [PATCH 1175/1276] fixes #56990 --- src/vs/workbench/electron-browser/workbench.ts | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/vs/workbench/electron-browser/workbench.ts b/src/vs/workbench/electron-browser/workbench.ts index 5b8ee0b77fc..b469db36738 100644 --- a/src/vs/workbench/electron-browser/workbench.ts +++ b/src/vs/workbench/electron-browser/workbench.ts @@ -537,6 +537,10 @@ export class Workbench extends Disposable implements IPartService { this.menubarToggled = visible; if (this.menubarVisibility === 'toggle' || (browser.isFullscreen() && this.menubarVisibility === 'default')) { + if (browser.isFullscreen() && this.menubarVisibility === 'default') { + this._onTitleBarVisibilityChange.fire(); + } + this.layout(); } } From ec95562121af15f56a68bca0f552f8d0d8c2c69a Mon Sep 17 00:00:00 2001 From: Ramya Achutha Rao <ramyar@microsoft.com> Date: Thu, 23 Aug 2018 17:46:19 -0700 Subject: [PATCH 1176/1276] Update distro --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 01a6d5185fb..79163bd2c96 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "code-oss-dev", "version": "1.27.0", - "distro": "a4155d9780fbbc94ead6cb3017dd0fc3806c57b8", + "distro": "4bd49e564426e4719c8f9f522a4d67d89de3fb26", "author": { "name": "Microsoft Corporation" }, From 322390ca644696df9c32836acbbc61e162689b08 Mon Sep 17 00:00:00 2001 From: Ramya Achutha Rao <ramyar@microsoft.com> Date: Thu, 23 Aug 2018 17:59:20 -0700 Subject: [PATCH 1177/1276] Check other experiment dependencies before running experiment --- .../experiments/node/experimentService.ts | 35 +++++++++++-------- 1 file changed, 21 insertions(+), 14 deletions(-) diff --git a/src/vs/workbench/parts/experiments/node/experimentService.ts b/src/vs/workbench/parts/experiments/node/experimentService.ts index 96777a2416c..30e8e987ef9 100644 --- a/src/vs/workbench/parts/experiments/node/experimentService.ts +++ b/src/vs/workbench/parts/experiments/node/experimentService.ts @@ -279,6 +279,24 @@ export class ExperimentService extends Disposable implements IExperimentService } } + private checkExperimentDependencies(experiment: IRawExperiment): boolean { + if (experiment.condition.experimentsPreviouslyRun) { + const runExperimentIdsFromStorage: string[] = safeParse(this.storageService.get('currentOrPreviouslyRunExperiments', StorageScope.GLOBAL), []); + let includeCheck = true; + let excludeCheck = true; + if (Array.isArray(experiment.condition.experimentsPreviouslyRun.includes)) { + includeCheck = runExperimentIdsFromStorage.some(x => experiment.condition.experimentsPreviouslyRun.includes.indexOf(x) > -1); + } + if (includeCheck && Array.isArray(experiment.condition.experimentsPreviouslyRun.excludes)) { + excludeCheck = !runExperimentIdsFromStorage.some(x => experiment.condition.experimentsPreviouslyRun.excludes.indexOf(x) > -1); + } + if (!includeCheck || !excludeCheck) { + return false; + } + } + return true; + } + private shouldRunExperiment(experiment: IRawExperiment, processedExperiment: IExperiment): TPromise<ExperimentState> { if (processedExperiment.state !== ExperimentState.Evaluating) { return TPromise.wrap(processedExperiment.state); @@ -292,19 +310,8 @@ export class ExperimentService extends Disposable implements IExperimentService return TPromise.wrap(ExperimentState.Run); } - if (experiment.condition.experimentsPreviouslyRun) { - const runExperimentIdsFromStorage: string[] = safeParse(this.storageService.get('currentOrPreviouslyRunExperiments', StorageScope.GLOBAL), []); - let includeCheck = true; - let excludeCheck = true; - if (Array.isArray(experiment.condition.experimentsPreviouslyRun.includes)) { - includeCheck = runExperimentIdsFromStorage.some(x => experiment.condition.experimentsPreviouslyRun.includes.indexOf(x) > -1); - } - if (includeCheck && Array.isArray(experiment.condition.experimentsPreviouslyRun.excludes)) { - excludeCheck = !runExperimentIdsFromStorage.some(x => experiment.condition.experimentsPreviouslyRun.excludes.indexOf(x) > -1); - } - if (!includeCheck || !excludeCheck) { - return TPromise.wrap(ExperimentState.NoRun); - } + if (!this.checkExperimentDependencies(experiment)) { + return TPromise.wrap(ExperimentState.NoRun); } if (this.environmentService.appQuality === 'stable' && experiment.condition.insidersOnly === true) { @@ -399,7 +406,7 @@ export class ExperimentService extends Disposable implements IExperimentService } }); if (latestExperimentState.editCount >= experiment.condition.fileEdits.minEditCount) { - processedExperiment.state = latestExperimentState.state = Math.random() < experiment.condition.userProbability ? ExperimentState.Run : ExperimentState.NoRun; + processedExperiment.state = latestExperimentState.state = (Math.random() < experiment.condition.userProbability && this.checkExperimentDependencies(experiment)) ? ExperimentState.Run : ExperimentState.NoRun; this.storageService.store(storageKey, JSON.stringify(latestExperimentState), StorageScope.GLOBAL); if (latestExperimentState.state === ExperimentState.Run && ExperimentActionType[experiment.action.type] === ExperimentActionType.Prompt) { this.fireRunExperiment(processedExperiment); From 4ae39646f9b4db1d91e49ee27232b5c8d15633cc Mon Sep 17 00:00:00 2001 From: Jackson Kearl <jkearl@mit.edu> Date: Thu, 23 Aug 2018 18:01:24 -0700 Subject: [PATCH 1178/1276] Add underline on hover for links --- .../parts/preferences/browser/media/settingsEditor2.css | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/vs/workbench/parts/preferences/browser/media/settingsEditor2.css b/src/vs/workbench/parts/preferences/browser/media/settingsEditor2.css index 368bec216c8..70a86e090fe 100644 --- a/src/vs/workbench/parts/preferences/browser/media/settingsEditor2.css +++ b/src/vs/workbench/parts/preferences/browser/media/settingsEditor2.css @@ -363,6 +363,11 @@ .settings-editor > .settings-body > .settings-tree-container .setting-item .setting-item-description-markdown a:focus { outline: 1px solid -webkit-focus-ring-color; outline-offset: -1px; + text-decoration: underline; +} + +.settings-editor > .settings-body > .settings-tree-container .setting-item .setting-item-description-markdown a:hover { + text-decoration: underline; } .settings-editor > .settings-body > .settings-tree-container .setting-item .setting-item-description-markdown code { From 3cbd552f3dc8a89cf59bc933ce4a206cf1a8e87e Mon Sep 17 00:00:00 2001 From: Ramya Achutha Rao <ramyar@microsoft.com> Date: Thu, 23 Aug 2018 18:56:28 -0700 Subject: [PATCH 1179/1276] Skip suggestwidget telemetry if its already open Fixes #54667 --- .../editor/contrib/suggest/suggestWidget.ts | 27 ++++++++++--------- 1 file changed, 15 insertions(+), 12 deletions(-) diff --git a/src/vs/editor/contrib/suggest/suggestWidget.ts b/src/vs/editor/contrib/suggest/suggestWidget.ts index 8f5b76048ac..90e7748c573 100644 --- a/src/vs/editor/contrib/suggest/suggestWidget.ts +++ b/src/vs/editor/contrib/suggest/suggestWidget.ts @@ -704,18 +704,21 @@ export class SuggestWidget implements IContentWidget, IVirtualDelegate<ICompleti this.completionModel = null; } else { - const { stats } = this.completionModel; - stats['wasAutomaticallyTriggered'] = !!isAuto; - /* __GDPR__ - "suggestWidget" : { - "wasAutomaticallyTriggered" : { "classification": "SystemMetaData", "purpose": "FeatureInsight", "isMeasurement": true }, - "${include}": [ - "${ICompletionStats}", - "${EditorTelemetryData}" - ] - } - */ - this.telemetryService.publicLog('suggestWidget', { ...stats, ...this.editor.getTelemetryData() }); + + if (this.state !== State.Open) { + const { stats } = this.completionModel; + stats['wasAutomaticallyTriggered'] = !!isAuto; + /* __GDPR__ + "suggestWidget" : { + "wasAutomaticallyTriggered" : { "classification": "SystemMetaData", "purpose": "FeatureInsight", "isMeasurement": true }, + "${include}": [ + "${ICompletionStats}", + "${EditorTelemetryData}" + ] + } + */ + this.telemetryService.publicLog('suggestWidget', { ...stats, ...this.editor.getTelemetryData() }); + } this.list.splice(0, this.list.length, this.completionModel.items); From 346018a80dd299c50cbf213e0a706ef0f35f3a67 Mon Sep 17 00:00:00 2001 From: Jackson Kearl <jkearl11@gmail.com> Date: Thu, 23 Aug 2018 21:39:51 -0700 Subject: [PATCH 1180/1276] Enum descriptions in new settings editor via SelectBox widget (#57050) * Create initial implementation of details selectbox via SelectBox * Add markdown support * Remove click handling support --- src/vs/base/browser/ui/selectBox/selectBox.ts | 11 ++- .../browser/ui/selectBox/selectBoxCustom.css | 24 ++++++ .../browser/ui/selectBox/selectBoxCustom.ts | 77 +++++++++++++++++-- .../browser/ui/selectBox/selectBoxNative.ts | 4 + src/vs/platform/theme/common/styler.ts | 5 +- .../preferences/browser/settingsEditor2.ts | 1 + .../parts/preferences/browser/settingsTree.ts | 50 ++++++------ .../preferences/browser/settingsWidgets.ts | 7 +- 8 files changed, 146 insertions(+), 33 deletions(-) diff --git a/src/vs/base/browser/ui/selectBox/selectBox.ts b/src/vs/base/browser/ui/selectBox/selectBox.ts index 5c7a28190a3..40a4d7c9a35 100644 --- a/src/vs/base/browser/ui/selectBox/selectBox.ts +++ b/src/vs/base/browser/ui/selectBox/selectBox.ts @@ -14,6 +14,7 @@ import { IListStyles } from 'vs/base/browser/ui/list/listWidget'; import { SelectBoxNative } from 'vs/base/browser/ui/selectBox/selectBoxNative'; import { SelectBoxList } from 'vs/base/browser/ui/selectBox/selectBoxCustom'; import { isMacintosh } from 'vs/base/common/platform'; +import { IContentActionHandler } from 'vs/base/browser/htmlContentRenderer'; // Public SelectBox interface - Calls routed to appropriate select implementation class @@ -24,6 +25,7 @@ export interface ISelectBoxDelegate { setOptions(options: string[], selected?: number, disabled?: number): void; select(index: number): void; setAriaLabel(label: string); + setDetailsProvider(provider: (index: number) => { details: string, isMarkdown: boolean }); focus(): void; blur(): void; dispose(): void; @@ -37,6 +39,8 @@ export interface ISelectBoxDelegate { export interface ISelectBoxOptions { ariaLabel?: string; minBottomMargin?: number; + hasDetails?: boolean; + markdownActionHandler?: IContentActionHandler; } export interface ISelectBoxStyles extends IListStyles { @@ -44,6 +48,7 @@ export interface ISelectBoxStyles extends IListStyles { selectListBackground?: Color; selectForeground?: Color; selectBorder?: Color; + selectListBorder?: Color; focusBorder?: Color; } @@ -68,7 +73,7 @@ export class SelectBox extends Widget implements ISelectBoxDelegate { mixin(this.styles, defaultStyles, false); // Instantiate select implementation based on platform - if (isMacintosh) { + if (isMacintosh && !(selectBoxOptions && selectBoxOptions.hasDetails)) { this.selectBoxDelegate = new SelectBoxNative(options, selected, styles, selectBoxOptions); } else { this.selectBoxDelegate = new SelectBoxList(options, selected, contextViewProvider, styles, selectBoxOptions); @@ -95,6 +100,10 @@ export class SelectBox extends Widget implements ISelectBoxDelegate { this.selectBoxDelegate.setAriaLabel(label); } + public setDetailsProvider(provider: (index: number) => { details: string, isMarkdown: boolean }): void { + this.selectBoxDelegate.setDetailsProvider(provider); + } + public focus(): void { this.selectBoxDelegate.focus(); } diff --git a/src/vs/base/browser/ui/selectBox/selectBoxCustom.css b/src/vs/base/browser/ui/selectBox/selectBoxCustom.css index dcf29613a97..72901ceaaaa 100644 --- a/src/vs/base/browser/ui/selectBox/selectBoxCustom.css +++ b/src/vs/base/browser/ui/selectBox/selectBoxCustom.css @@ -16,8 +16,28 @@ .monaco-select-box-dropdown-container { display: none; + -webkit-box-sizing: border-box; + -o-box-sizing: border-box; + -moz-box-sizing: border-box; + -ms-box-sizing: border-box; + box-sizing: border-box; } +.monaco-select-box-dropdown-container > .select-box-details-pane > .select-box-description-markdown * { + margin: 0; +} + +.monaco-select-box-dropdown-container > .select-box-details-pane > .select-box-description-markdown a:focus { + outline: 1px solid -webkit-focus-ring-color; + outline-offset: -1px; +} + +.monaco-select-box-dropdown-container > .select-box-details-pane > .select-box-description-markdown code { + line-height: 15px; /** For some reason, this is needed, otherwise <code> will take up 20px height */ + font-family: Menlo, Monaco, Consolas, "Droid Sans Mono", "Courier New", monospace, "Droid Sans Fallback"; +} + + .monaco-select-box-dropdown-container.visible { display: flex; flex-direction: column; @@ -42,6 +62,10 @@ box-sizing: border-box; } +.monaco-select-box-dropdown-container > .select-box-details-pane { + padding: 5px; +} + .hc-black .monaco-select-box-dropdown-container > .select-box-dropdown-list-container { padding-top: var(--dropdown-padding-top); padding-bottom: var(--dropdown-padding-bottom); diff --git a/src/vs/base/browser/ui/selectBox/selectBoxCustom.ts b/src/vs/base/browser/ui/selectBox/selectBoxCustom.ts index 7a4b27ed1cf..d0817b49ba0 100644 --- a/src/vs/base/browser/ui/selectBox/selectBoxCustom.ts +++ b/src/vs/base/browser/ui/selectBox/selectBoxCustom.ts @@ -14,11 +14,12 @@ import * as dom from 'vs/base/browser/dom'; import * as arrays from 'vs/base/common/arrays'; import { IContextViewProvider, AnchorPosition } from 'vs/base/browser/ui/contextview/contextview'; import { List } from 'vs/base/browser/ui/list/listWidget'; -import { IVirtualDelegate, IRenderer } from 'vs/base/browser/ui/list/list'; +import { IVirtualDelegate, IRenderer, IListEvent } from 'vs/base/browser/ui/list/list'; import { domEvent } from 'vs/base/browser/event'; import { ScrollbarVisibility } from 'vs/base/common/scrollable'; import { ISelectBoxDelegate, ISelectBoxOptions, ISelectBoxStyles, ISelectData } from 'vs/base/browser/ui/selectBox/selectBox'; import { isMacintosh } from 'vs/base/common/platform'; +import { renderMarkdown } from 'vs/base/browser/htmlContentRenderer'; const $ = dom.$; @@ -103,6 +104,11 @@ export class SelectBoxList implements ISelectBoxDelegate, IVirtualDelegate<ISele private widthControlElement: HTMLElement; private _currentSelection: number; private _dropDownPosition: AnchorPosition; + private detailsProvider: (index: number) => { details: string, isMarkdown: boolean }; + private selectionDetailsPane: HTMLElement; + + + private _sticky: boolean = false; // for dev purposes only constructor(options: string[], selected: number, contextViewProvider: IContextViewProvider, styles: ISelectBoxStyles, selectBoxOptions?: ISelectBoxOptions) { @@ -153,6 +159,7 @@ export class SelectBoxList implements ISelectBoxDelegate, IVirtualDelegate<ISele dom.addClass(this.selectDropDownContainer, 'monaco-select-box-dropdown-padding'); // Setup list for drop-down select this.createSelectList(this.selectDropDownContainer); + this.selectionDetailsPane = dom.append(this.selectDropDownContainer, $('.select-box-details-pane')); // Create span flex box item/div we can measure and control let widthControlOuterDiv = dom.append(this.selectDropDownContainer, $('.select-box-dropdown-container-width-control')); @@ -285,6 +292,10 @@ export class SelectBoxList implements ISelectBoxDelegate, IVirtualDelegate<ISele this.selectList.getHTMLElement().setAttribute('aria-label', this.selectBoxOptions.ariaLabel); } + public setDetailsProvider(provider: (index: number) => { details: string, isMarkdown: boolean }): void { + this.detailsProvider = provider; + } + public focus(): void { if (this.selectElement) { this.selectElement.focus(); @@ -320,6 +331,15 @@ export class SelectBoxList implements ISelectBoxDelegate, IVirtualDelegate<ISele content.push(`.monaco-select-box-dropdown-container > .select-box-dropdown-list-container .monaco-list .monaco-list-row.focused:not(:hover) { color: ${this.styles.listFocusForeground} !important; }`); } + if (!this.styles.selectBorder.equals(this.styles.selectBackground)) { + content.push(`.monaco-select-box-dropdown-container { border: 1px solid ${this.styles.selectBorder} } `); + content.push(`.monaco-select-box-dropdown-container > .select-box-details-pane { border-top: 1px solid ${this.styles.selectBorder} } `); + } + else if (this.styles.selectListBorder) { + content.push(`.monaco-select-box-dropdown-container { border: 1px solid ${this.styles.selectListBorder} } `); + content.push(`.monaco-select-box-dropdown-container > .select-box-details-pane { border-top: 1px solid ${this.styles.selectListBorder} } `); + } + // Hover foreground - ignore for disabled options if (this.styles.listHoverForeground) { content.push(`.monaco-select-box-dropdown-container > .select-box-dropdown-list-container .monaco-list .monaco-list-row:hover { color: ${this.styles.listHoverForeground} !important; }`); @@ -370,6 +390,7 @@ export class SelectBoxList implements ISelectBoxDelegate, IVirtualDelegate<ISele let listBackground = this.styles.selectListBackground ? this.styles.selectListBackground.toString() : background; this.selectDropDownListContainer.style.backgroundColor = listBackground; + this.selectionDetailsPane.style.backgroundColor = listBackground; const optionsBorder = this.styles.focusBorder ? this.styles.focusBorder.toString() : null; this.selectDropDownContainer.style.outlineColor = optionsBorder; this.selectDropDownContainer.style.outlineOffset = '-1px'; @@ -543,9 +564,6 @@ export class SelectBoxList implements ISelectBoxDelegate, IVirtualDelegate<ISele this.selectList.reveal(this.selectList.getFocus()[0] || 0); } - // Set final container height after adjustments - this.selectDropDownContainer.style.height = (listHeight + verticalPadding) + 'px'; - // Determine optimal width - min(longest option), opt(parent select, excluding margins), max(ContextView controlled) const selectWidth = this.selectElement.offsetWidth; const selectMinWidth = this.setWidthControlElement(this.widthControlElement); @@ -556,7 +574,6 @@ export class SelectBoxList implements ISelectBoxDelegate, IVirtualDelegate<ISele // Maintain focus outline on parent select as well as list container - tabindex for focus this.selectDropDownListContainer.setAttribute('tabindex', '0'); dom.toggleClass(this.selectElement, 'synthetic-focus', true); - dom.toggleClass(this.selectDropDownContainer, 'synthetic-focus', true); return true; } else { return false; @@ -626,7 +643,11 @@ export class SelectBoxList implements ISelectBoxDelegate, IVirtualDelegate<ISele .filter(() => this.selectList.length > 0) .on(e => this.onMouseUp(e), this, this.toDispose); - this.toDispose.push(this.selectList.onDidBlur(e => this.onListBlur())); + this.toDispose.push( + this.selectList.onDidBlur(e => this.onListBlur()), + this.selectList.onMouseOver(e => this.selectList.setFocus([e.index])), + this.selectList.onFocusChange(e => this.onListFocus(e)) + ); this.selectList.getHTMLElement().setAttribute('aria-expanded', 'true'); } @@ -672,7 +693,7 @@ export class SelectBoxList implements ISelectBoxDelegate, IVirtualDelegate<ISele // List Exit - passive - implicit no selection change, hide drop-down private onListBlur(): void { - + if (this._sticky) { return; } if (this.selected !== this._currentSelection) { // Reset selected to current if no change this.select(this._currentSelection); @@ -681,6 +702,48 @@ export class SelectBoxList implements ISelectBoxDelegate, IVirtualDelegate<ISele this.hideSelectDropDown(false); } + + private renderDescriptionMarkdown(text: string): HTMLElement { + const cleanRenderedMarkdown = (element: Node) => { + for (let i = 0; i < element.childNodes.length; i++) { + const child = element.childNodes.item(i); + + const tagName = (<Element>child).tagName && (<Element>child).tagName.toLowerCase(); + if (tagName === 'img') { + element.removeChild(child); + } else { + cleanRenderedMarkdown(child); + } + } + }; + + const renderedMarkdown = renderMarkdown({ value: text }, { + actionHandler: this.selectBoxOptions.markdownActionHandler + }); + + renderedMarkdown.classList.add('select-box-description-markdown'); + cleanRenderedMarkdown(renderedMarkdown); + + return renderedMarkdown; + } + + // List Focus Change - passive - update details pane with newly focused element's data + private onListFocus(e: IListEvent<ISelectOptionItem>) { + this.selectionDetailsPane.innerText = ''; + const selectedIndex = e.indexes[0]; + let description = this.detailsProvider ? this.detailsProvider(selectedIndex) : { details: '', isMarkdown: false }; + if (description.details) { + if (description.isMarkdown) { + this.selectionDetailsPane.appendChild(this.renderDescriptionMarkdown(description.details)); + } else { + this.selectionDetailsPane.innerText = description.details; + } + this.selectionDetailsPane.style.display = 'block'; + } else { + this.selectionDetailsPane.style.display = 'none'; + } + } + // List keyboard controller // List exit - active - hide ContextView dropdown, reset selection, return focus to parent select diff --git a/src/vs/base/browser/ui/selectBox/selectBoxNative.ts b/src/vs/base/browser/ui/selectBox/selectBoxNative.ts index ecd7fcca737..c748d0c1e57 100644 --- a/src/vs/base/browser/ui/selectBox/selectBoxNative.ts +++ b/src/vs/base/browser/ui/selectBox/selectBoxNative.ts @@ -113,6 +113,10 @@ export class SelectBoxNative implements ISelectBoxDelegate { this.selectElement.setAttribute('aria-label', label); } + public setDetailsProvider(provider: any): void { + console.error('details are not available for native select boxes'); + } + public focus(): void { if (this.selectElement) { this.selectElement.focus(); diff --git a/src/vs/platform/theme/common/styler.ts b/src/vs/platform/theme/common/styler.ts index 67e889439b7..50ef1ebe5c6 100644 --- a/src/vs/platform/theme/common/styler.ts +++ b/src/vs/platform/theme/common/styler.ts @@ -6,7 +6,7 @@ 'use strict'; 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 } 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 } 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'; @@ -129,7 +129,8 @@ export function attachSelectBoxStyler(widget: IThemable, themeService: IThemeSer listFocusOutline: (style && style.listFocusOutline) || activeContrastBorder, listHoverBackground: (style && style.listHoverBackground) || listHoverBackground, listHoverForeground: (style && style.listHoverForeground) || listHoverForeground, - listHoverOutline: (style && style.listFocusOutline) || activeContrastBorder + listHoverOutline: (style && style.listFocusOutline) || activeContrastBorder, + selectListBorder: (style && style.selectListBorder) || editorWidgetBorder } as ISelectBoxStyleOverrides, widget); } diff --git a/src/vs/workbench/parts/preferences/browser/settingsEditor2.ts b/src/vs/workbench/parts/preferences/browser/settingsEditor2.ts index ca45a7487bf..c4732771624 100644 --- a/src/vs/workbench/parts/preferences/browser/settingsEditor2.ts +++ b/src/vs/workbench/parts/preferences/browser/settingsEditor2.ts @@ -494,6 +494,7 @@ export class SettingsEditor2 extends BaseEditor { } private updateTreeScrollSync(): void { + this.settingsTreeRenderer.cancelSuggesters(); if (this.searchResultModel) { return; } diff --git a/src/vs/workbench/parts/preferences/browser/settingsTree.ts b/src/vs/workbench/parts/preferences/browser/settingsTree.ts index 7e1e278edf6..964371c14b2 100644 --- a/src/vs/workbench/parts/preferences/browser/settingsTree.ts +++ b/src/vs/workbench/parts/preferences/browser/settingsTree.ts @@ -41,7 +41,7 @@ import { attachButtonStyler, attachInputBoxStyler, attachSelectBoxStyler, attach import { ICssStyleCollector, ITheme, IThemeService, registerThemingParticipant } from 'vs/platform/theme/common/themeService'; import { ITOCEntry } from 'vs/workbench/parts/preferences/browser/settingsLayout'; import { ISettingsEditorViewState, isExcludeSetting, SettingsTreeElement, SettingsTreeGroupElement, SettingsTreeNewExtensionsElement, SettingsTreeSettingElement, settingKeyToDisplayFormat } from 'vs/workbench/parts/preferences/browser/settingsTreeModels'; -import { ExcludeSettingWidget, IExcludeDataItem, settingsHeaderForeground, settingsNumberInputBackground, settingsNumberInputBorder, settingsNumberInputForeground, settingsSelectBackground, settingsSelectBorder, settingsSelectForeground, settingsTextInputBackground, settingsTextInputBorder, settingsTextInputForeground } from 'vs/workbench/parts/preferences/browser/settingsWidgets'; +import { ExcludeSettingWidget, IExcludeDataItem, settingsHeaderForeground, settingsNumberInputBackground, settingsNumberInputBorder, settingsNumberInputForeground, settingsSelectBackground, settingsSelectBorder, settingsSelectListBorder, settingsSelectForeground, settingsTextInputBackground, settingsTextInputBorder, settingsTextInputForeground } from 'vs/workbench/parts/preferences/browser/settingsWidgets'; import { ISetting, ISettingsGroup } from 'vs/workbench/services/preferences/common/preferences'; const $ = DOM.$; @@ -721,15 +721,32 @@ export class SettingsRenderer implements ITreeRenderer { return template; } + public cancelSuggesters() { + this.contextViewService.hideContextView(); + } + private renderSettingEnumTemplate(tree: ITree, container: HTMLElement): ISettingEnumItemTemplate { const common = this.renderCommonTemplate(tree, container, 'enum'); - const selectBox = new SelectBox([], undefined, this.contextViewService); + const selectBox = new SelectBox([], undefined, this.contextViewService, undefined, { + hasDetails: true, markdownActionHandler: { + callback: (content: string) => { + if (startsWith(content, '#')) { + this._onDidClickSettingLink.fire(content.substr(1)); + } else { + this.openerService.open(URI.parse(content)).then(void 0, onUnexpectedError); + } + }, + disposeables: common.toDispose + } + }); + common.toDispose.push(selectBox); common.toDispose.push(attachSelectBoxStyler(selectBox, this.themeService, { selectBackground: settingsSelectBackground, selectForeground: settingsSelectForeground, - selectBorder: settingsSelectBorder + selectBorder: settingsSelectBorder, + selectListBorder: settingsSelectListBorder })); selectBox.render(common.controlElement); const selectElement = common.controlElement.querySelector('select'); @@ -1016,6 +1033,13 @@ export class SettingsRenderer implements ITreeRenderer { private renderEnum(dataElement: SettingsTreeSettingElement, template: ISettingEnumItemTemplate, onChange: (value: string) => void): void { const displayOptions = getDisplayEnumOptions(dataElement.setting); template.selectBox.setOptions(displayOptions); + const descriptions = dataElement.setting.enumDescriptions; + const descriptionsAreMarkdown = dataElement.setting.descriptionIsMarkdown; + template.selectBox.setDetailsProvider(index => + ({ + details: descriptions && descriptions[index] && (descriptionsAreMarkdown ? fixSettingLinks(descriptions[index]) : descriptions[index]), + isMarkdown: descriptionsAreMarkdown + })); const modifiedText = dataElement.isConfigured ? 'Modified' : ''; const label = ' ' + dataElement.displayCategory + ' ' + dataElement.displayLabel + ' combobox ' + modifiedText; @@ -1033,24 +1057,6 @@ export class SettingsRenderer implements ITreeRenderer { } template.enumDescriptionElement.innerHTML = ''; - // if (dataElement.setting.enumDescriptions && dataElement.setting.enum && dataElement.setting.enum.length < SettingsRenderer.MAX_ENUM_DESCRIPTIONS) { - // if (isSelected) { - // let enumDescriptionText = '\n' + dataElement.setting.enumDescriptions - // .map((desc, i) => { - // const displayEnum = escapeInvisibleChars(dataElement.setting.enum[i]); - // return desc ? - // ` - \`${displayEnum}\`: ${desc}` : - // ` - \`${dataElement.setting.enum[i]}\``; - // }) - // .filter(desc => !!desc) - // .join('\n'); - - // const renderedMarkdown = this.renderDescriptionMarkdown(fixSettingLinks(enumDescriptionText), template.toDispose); - // template.enumDescriptionElement.appendChild(renderedMarkdown); - // } - - // return { overflows: true }; - // } } private renderText(dataElement: SettingsTreeSettingElement, template: ISettingTextItemTemplate, onChange: (value: string) => void): void { @@ -1245,7 +1251,7 @@ export class SettingsTreeController extends WorkbenchTreeController { const isLink = eventish.target.tagName.toLowerCase() === 'a' || eventish.target.parentElement.tagName.toLowerCase() === 'a'; // <code> inside <a> - if (isLink && DOM.findParentWithClass(eventish.target, 'setting-item-description-markdown', tree.getHTMLElement())) { + if (isLink && (DOM.findParentWithClass(eventish.target, 'setting-item-description-markdown', tree.getHTMLElement()) || DOM.findParentWithClass(eventish.target, 'select-box-description-markdown'))) { return true; } diff --git a/src/vs/workbench/parts/preferences/browser/settingsWidgets.ts b/src/vs/workbench/parts/preferences/browser/settingsWidgets.ts index 9cb48336843..998e7f67552 100644 --- a/src/vs/workbench/parts/preferences/browser/settingsWidgets.ts +++ b/src/vs/workbench/parts/preferences/browser/settingsWidgets.ts @@ -16,7 +16,7 @@ import { Disposable, dispose, IDisposable } from 'vs/base/common/lifecycle'; import 'vs/css!./media/settingsWidgets'; import { localize } from 'vs/nls'; import { IContextViewService } from 'vs/platform/contextview/browser/contextView'; -import { foreground, inputBackground, inputBorder, inputForeground, listActiveSelectionBackground, listActiveSelectionForeground, listHoverBackground, listHoverForeground, listInactiveSelectionBackground, listInactiveSelectionForeground, registerColor, selectBackground, selectBorder, selectForeground, textLinkForeground, textPreformatForeground } from 'vs/platform/theme/common/colorRegistry'; +import { foreground, inputBackground, inputBorder, inputForeground, listActiveSelectionBackground, listActiveSelectionForeground, listHoverBackground, listHoverForeground, listInactiveSelectionBackground, listInactiveSelectionForeground, registerColor, selectBackground, selectBorder, selectForeground, textLinkForeground, textPreformatForeground, editorWidgetBorder } from 'vs/platform/theme/common/colorRegistry'; import { attachButtonStyler, attachInputBoxStyler } from 'vs/platform/theme/common/styler'; import { ICssStyleCollector, ITheme, IThemeService, registerThemingParticipant } from 'vs/platform/theme/common/themeService'; @@ -32,6 +32,7 @@ export const modifiedItemIndicator = registerColor('settings.modifiedItemIndicat export const settingsSelectBackground = registerColor('settings.dropdownBackground', { dark: selectBackground, light: selectBackground, hc: selectBackground }, localize('settingsDropdownBackground', "(For settings editor preview) Settings editor dropdown background.")); export const settingsSelectForeground = registerColor('settings.dropdownForeground', { dark: selectForeground, light: selectForeground, hc: selectForeground }, localize('settingsDropdownForeground', "(For settings editor preview) Settings editor dropdown foreground.")); export const settingsSelectBorder = registerColor('settings.dropdownBorder', { dark: selectBorder, light: selectBorder, hc: selectBorder }, localize('settingsDropdownBorder', "(For settings editor preview) Settings editor dropdown border.")); +export const settingsSelectListBorder = registerColor('settings.dropdownListBorder', { dark: editorWidgetBorder, light: editorWidgetBorder, hc: editorWidgetBorder }, localize('settingsDropdownListBorder', "(For settings editor preview) Settings editor dropdown list border. This surrounds the options and separates the options from the description.")); // Bool control colors export const settingsCheckboxBackground = registerColor('settings.checkboxBackground', { dark: selectBackground, light: selectBackground, hc: selectBackground }, localize('settingsCheckboxBackground', "(For settings editor preview) Settings editor checkbox background.")); @@ -63,6 +64,8 @@ registerThemingParticipant((theme: ITheme, collector: ICssStyleCollector) => { if (link) { collector.addRule(`.settings-editor > .settings-body > .settings-tree-container .setting-item .setting-item-description-markdown a { color: ${link}; }`); collector.addRule(`.settings-editor > .settings-body > .settings-tree-container .setting-item .setting-item-description-markdown a > code { color: ${link}; }`); + collector.addRule(`.monaco-select-box-dropdown-container > .select-box-details-pane > .select-box-description-markdown a { color: ${link}; }`); + collector.addRule(`.monaco-select-box-dropdown-container > .select-box-details-pane > .select-box-description-markdown a > code { color: ${link}; }`); } const headerForegroundColor = theme.getColor(settingsHeaderForeground); @@ -109,6 +112,8 @@ registerThemingParticipant((theme: ITheme, collector: ICssStyleCollector) => { const codeTextForegroundColor = theme.getColor(textPreformatForeground); if (codeTextForegroundColor) { collector.addRule(`.settings-editor > .settings-body > .settings-tree-container .setting-item .setting-item-description-markdown code { color: ${codeTextForegroundColor} }`); + collector.addRule(`.monaco-select-box-dropdown-container > .select-box-details-pane > .select-box-description-markdown code { color: ${codeTextForegroundColor} }`); + } const modifiedItemIndicatorColor = theme.getColor(modifiedItemIndicator); From 803542327fe29bc7bd733b316a0460222ef78b22 Mon Sep 17 00:00:00 2001 From: Rob Lourens <roblourens@gmail.com> Date: Thu, 23 Aug 2018 22:04:31 -0700 Subject: [PATCH 1181/1276] Fix #57046 - workspaceContains should search using search providers, not its own DiskSearch instance --- src/vs/base/common/numbers.ts | 10 ++++- .../electron-browser/mainThreadWorkspace.ts | 35 ++++++++++++---- src/vs/workbench/api/node/extHost.protocol.ts | 5 ++- src/vs/workbench/api/node/extHostWorkspace.ts | 14 +++---- src/vs/workbench/node/extensionHostMain.ts | 16 ++++++-- .../api/extHostConfiguration.test.ts | 11 ++--- .../api/extHostWorkspace.test.ts | 41 ++++++++++--------- 7 files changed, 86 insertions(+), 46 deletions(-) diff --git a/src/vs/base/common/numbers.ts b/src/vs/base/common/numbers.ts index fa4932e9ec7..9c31e269491 100644 --- a/src/vs/base/common/numbers.ts +++ b/src/vs/base/common/numbers.ts @@ -11,4 +11,12 @@ export function clamp(value: number, min: number, max: number): number { export function rot(index: number, modulo: number): number { return (modulo + (index % modulo)) % modulo; -} \ No newline at end of file +} + +export class Counter { + private _next = 0; + + getNext(): number { + return this._next++; + } +} diff --git a/src/vs/workbench/api/electron-browser/mainThreadWorkspace.ts b/src/vs/workbench/api/electron-browser/mainThreadWorkspace.ts index 4f072168bc2..b5eb1639ae0 100644 --- a/src/vs/workbench/api/electron-browser/mainThreadWorkspace.ts +++ b/src/vs/workbench/api/electron-browser/mainThreadWorkspace.ts @@ -9,27 +9,27 @@ import { dispose, IDisposable } from 'vs/base/common/lifecycle'; import URI, { UriComponents } from 'vs/base/common/uri'; import { TPromise } from 'vs/base/common/winjs.base'; import { localize } from 'vs/nls'; +import { CommandsRegistry } from 'vs/platform/commands/common/commands'; import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; +import { areSameExtensions } from 'vs/platform/extensionManagement/common/extensionManagementUtil'; import { IInstantiationService, ServicesAccessor } from 'vs/platform/instantiation/common/instantiation'; -import { IFolderQuery, IPatternInfo, IQueryOptions, ISearchConfiguration, ISearchQuery, ISearchService, QueryType, ISearchProgressItem } from 'vs/platform/search/common/search'; +import { ILabelService } from 'vs/platform/label/common/label'; +import { IFolderQuery, IPatternInfo, IQueryOptions, ISearchConfiguration, ISearchProgressItem, ISearchQuery, ISearchService, QueryType } from 'vs/platform/search/common/search'; import { IStatusbarService } from 'vs/platform/statusbar/common/statusbar'; +import { IWindowService } from 'vs/platform/windows/common/windows'; import { IWorkspaceContextService, WorkbenchState } from 'vs/platform/workspace/common/workspace'; import { extHostNamedCustomer } from 'vs/workbench/api/electron-browser/extHostCustomers'; import { QueryBuilder } from 'vs/workbench/parts/search/common/queryBuilder'; +import { IExtensionService } from 'vs/workbench/services/extensions/common/extensions'; import { ITextFileService } from 'vs/workbench/services/textfile/common/textfiles'; import { IWorkspaceEditingService } from 'vs/workbench/services/workspace/common/workspaceEditing'; import { ExtHostContext, ExtHostWorkspaceShape, IExtHostContext, MainContext, MainThreadWorkspaceShape } from '../node/extHost.protocol'; -import { CommandsRegistry } from 'vs/platform/commands/common/commands'; -import { IExtensionService } from 'vs/workbench/services/extensions/common/extensions'; -import { areSameExtensions } from 'vs/platform/extensionManagement/common/extensionManagementUtil'; -import { IWindowService } from 'vs/platform/windows/common/windows'; -import { ILabelService } from 'vs/platform/label/common/label'; @extHostNamedCustomer(MainContext.MainThreadWorkspace) export class MainThreadWorkspace implements MainThreadWorkspaceShape { private readonly _toDispose: IDisposable[] = []; - private readonly _activeSearches: { [id: number]: TPromise<URI[]> } = Object.create(null); + private readonly _activeSearches: { [id: number]: TPromise<any> } = Object.create(null); private readonly _proxy: ExtHostWorkspaceShape; constructor( @@ -205,6 +205,27 @@ export class MainThreadWorkspace implements MainThreadWorkspaceShape { return search; } + $checkExists(query: ISearchQuery, requestId: number): TPromise<boolean> { + query.exists = true; + const search = this._searchService.search(query).then( + result => { + delete this._activeSearches[requestId]; + return result.limitHit; + }, + err => { + delete this._activeSearches[requestId]; + if (!isPromiseCanceledError(err)) { + return TPromise.wrapError(err); + } + + return undefined; + }); + + this._activeSearches[requestId] = search; + + return search; + } + $cancelSearch(requestId: number): Thenable<boolean> { const search = this._activeSearches[requestId]; if (search) { diff --git a/src/vs/workbench/api/node/extHost.protocol.ts b/src/vs/workbench/api/node/extHost.protocol.ts index 1c9399cb60a..d0b857acad5 100644 --- a/src/vs/workbench/api/node/extHost.protocol.ts +++ b/src/vs/workbench/api/node/extHost.protocol.ts @@ -22,10 +22,11 @@ import { ICommandHandlerDescription } from 'vs/platform/commands/common/commands import { ConfigurationTarget, IConfigurationData, IConfigurationModel } from 'vs/platform/configuration/common/configuration'; import { ConfigurationScope } from 'vs/platform/configuration/common/configurationRegistry'; import { FileChangeType, FileDeleteOptions, FileOverwriteOptions, FileSystemProviderCapabilities, FileType, FileWriteOptions, IStat, IWatchOptions } from 'vs/platform/files/common/files'; +import { LabelRules } from 'vs/platform/label/common/label'; import { LogLevel } from 'vs/platform/log/common/log'; import { IMarkerData } from 'vs/platform/markers/common/markers'; import { IPickOptions, IQuickInputButton, IQuickPickItem } from 'vs/platform/quickinput/common/quickInput'; -import { IPatternInfo, IQueryOptions, IRawFileMatch2, IRawSearchQuery, ISearchCompleteStats } from 'vs/platform/search/common/search'; +import { IPatternInfo, IQueryOptions, IRawFileMatch2, IRawSearchQuery, ISearchCompleteStats, ISearchQuery } from 'vs/platform/search/common/search'; import { StatusbarAlignment as MainThreadStatusBarAlignment } from 'vs/platform/statusbar/common/statusbar'; import { ITelemetryInfo } from 'vs/platform/telemetry/common/telemetry'; import { ThemeColor } from 'vs/platform/theme/common/themeService'; @@ -40,7 +41,6 @@ import { IExtensionDescription } from 'vs/workbench/services/extensions/common/e import { createExtHostContextProxyIdentifier as createExtId, createMainContextProxyIdentifier as createMainId, IRPCProtocol, ProxyIdentifier } from 'vs/workbench/services/extensions/node/proxyIdentifier'; import { IProgressOptions, IProgressStep } from 'vs/workbench/services/progress/common/progress'; import { SaveReason } from 'vs/workbench/services/textfile/common/textfiles'; -import { LabelRules } from 'vs/platform/label/common/label'; import * as vscode from 'vscode'; export interface IEnvironment { @@ -470,6 +470,7 @@ export interface ExtHostUrlsShape { export interface MainThreadWorkspaceShape extends IDisposable { $startFileSearch(includePattern: string, includeFolder: string, excludePatternOrDisregardExcludes: string | false, maxResults: number, requestId: number): Thenable<UriComponents[]>; $startTextSearch(query: IPatternInfo, options: IQueryOptions, requestId: number): TPromise<void>; + $checkExists(query: ISearchQuery, requestId: number): TPromise<boolean>; $cancelSearch(requestId: number): Thenable<boolean>; $saveAll(includeUntitled?: boolean): Thenable<boolean>; $updateWorkspaceFolders(extensionName: string, index: number, deleteCount: number, workspaceFoldersToAdd: { uri: UriComponents, name?: string }[]): Thenable<void>; diff --git a/src/vs/workbench/api/node/extHostWorkspace.ts b/src/vs/workbench/api/node/extHostWorkspace.ts index e15ee1d920e..b4ec5af0c5a 100644 --- a/src/vs/workbench/api/node/extHostWorkspace.ts +++ b/src/vs/workbench/api/node/extHostWorkspace.ts @@ -4,13 +4,14 @@ *--------------------------------------------------------------------------------------------*/ 'use strict'; -import { relative, join } from 'path'; +import { join, relative } from 'path'; import { delta as arrayDelta } from 'vs/base/common/arrays'; import { Emitter, Event } from 'vs/base/common/event'; import { TernarySearchTree } from 'vs/base/common/map'; +import { Counter } from 'vs/base/common/numbers'; import { normalize } from 'vs/base/common/paths'; import { isLinux } from 'vs/base/common/platform'; -import { basenameOrAuthority, isEqual, dirname } from 'vs/base/common/resources'; +import { basenameOrAuthority, dirname, isEqual } from 'vs/base/common/resources'; import { compare } from 'vs/base/common/strings'; import URI from 'vs/base/common/uri'; import { TPromise } from 'vs/base/common/winjs.base'; @@ -140,8 +141,6 @@ class ExtHostWorkspaceImpl extends Workspace { export class ExtHostWorkspace implements ExtHostWorkspaceShape { - private static _requestIdPool = 0; - private readonly _onDidChangeWorkspace = new Emitter<vscode.WorkspaceFoldersChangeEvent>(); private readonly _proxy: MainThreadWorkspaceShape; @@ -157,7 +156,8 @@ export class ExtHostWorkspace implements ExtHostWorkspaceShape { constructor( mainContext: IMainContext, data: IWorkspaceData, - private _logService: ILogService + private _logService: ILogService, + private _requestIdProvider: Counter ) { this._proxy = mainContext.getProxy(MainContext.MainThreadWorkspace); this._messageService = mainContext.getProxy(MainContext.MainThreadMessageService); @@ -348,7 +348,7 @@ export class ExtHostWorkspace implements ExtHostWorkspaceShape { findFiles(include: vscode.GlobPattern, exclude: vscode.GlobPattern, maxResults: number, extensionId: string, token?: vscode.CancellationToken): Thenable<vscode.Uri[]> { this._logService.trace(`extHostWorkspace#findFiles: fileSearch, extension: ${extensionId}, entryPoint: findFiles`); - const requestId = ExtHostWorkspace._requestIdPool++; + const requestId = this._requestIdProvider.getNext(); let includePattern: string; let includeFolder: string; @@ -382,7 +382,7 @@ export class ExtHostWorkspace implements ExtHostWorkspaceShape { findTextInFiles(query: vscode.TextSearchQuery, options: vscode.FindTextInFilesOptions, callback: (result: vscode.TextSearchResult) => void, extensionId: string, token?: vscode.CancellationToken) { this._logService.trace(`extHostWorkspace#findTextInFiles: textSearch, extension: ${extensionId}, entryPoint: findTextInFiles`); - const requestId = ExtHostWorkspace._requestIdPool++; + const requestId = this._requestIdProvider.getNext(); const globPatternToString = (pattern: vscode.GlobPattern | string) => { if (typeof pattern === 'string') { diff --git a/src/vs/workbench/node/extensionHostMain.ts b/src/vs/workbench/node/extensionHostMain.ts index 60c93fae43e..8c1726b919f 100644 --- a/src/vs/workbench/node/extensionHostMain.ts +++ b/src/vs/workbench/node/extensionHostMain.ts @@ -15,7 +15,7 @@ import { ExtHostWorkspace } from 'vs/workbench/api/node/extHostWorkspace'; import { IExtensionDescription } from 'vs/workbench/services/extensions/common/extensions'; import { QueryType, ISearchQuery } from 'vs/platform/search/common/search'; import { DiskSearch } from 'vs/workbench/services/search/node/searchService'; -import { IInitData, IEnvironment, IWorkspaceData, MainContext } from 'vs/workbench/api/node/extHost.protocol'; +import { IInitData, IEnvironment, IWorkspaceData, MainContext, MainThreadWorkspaceShape } from 'vs/workbench/api/node/extHost.protocol'; import * as errors from 'vs/base/common/errors'; import * as glob from 'vs/base/common/glob'; import { ExtensionActivatedByEvent } from 'vs/workbench/api/node/extHostExtensionActivator'; @@ -25,6 +25,7 @@ import { RPCProtocol } from 'vs/workbench/services/extensions/node/rpcProtocol'; import URI from 'vs/base/common/uri'; import { ExtHostLogService } from 'vs/workbench/api/node/extHostLogService'; import { timeout } from 'vs/base/common/async'; +import { Counter } from 'vs/base/common/numbers'; const nativeExit = process.exit.bind(process); function patchProcess(allowExit: boolean) { @@ -85,6 +86,9 @@ export class ExtensionHostMain { private _extHostLogService: ExtHostLogService; private disposables: IDisposable[] = []; + private _searchRequestIdProvider: Counter; + private _mainThreadWorkspace: MainThreadWorkspaceShape; + constructor(protocol: IMessagePassingProtocol, initData: IInitData) { this._environment = initData.environment; @@ -99,7 +103,9 @@ export class ExtensionHostMain { this._extHostLogService = new ExtHostLogService(initData.windowId, initData.logLevel, initData.logsPath); this.disposables.push(this._extHostLogService); - const extHostWorkspace = new ExtHostWorkspace(rpcProtocol, initData.workspace, this._extHostLogService); + + this._searchRequestIdProvider = new Counter(); + const extHostWorkspace = new ExtHostWorkspace(rpcProtocol, initData.workspace, this._extHostLogService, this._searchRequestIdProvider); this._extHostLogService.info('extension host started'); this._extHostLogService.trace('initData', initData); @@ -139,6 +145,8 @@ export class ExtensionHostMain { mainThreadErrors.$onUnexpectedError(data); } }); + + this._mainThreadWorkspace = rpcProtocol.getProxy(MainContext.MainThreadWorkspace); } start(): TPromise<void> { @@ -282,8 +290,8 @@ export class ExtensionHostMain { ignoreSymlinks: !followSymlinks }; - const result = await this._diskSearch.search(query); - if (result.limitHit) { + const exists = await this._mainThreadWorkspace.$checkExists(query, this._searchRequestIdProvider.getNext()); + if (exists) { // a file was found matching one of the glob patterns return ( this._extensionService.activateById(extensionId, new ExtensionActivatedByEvent(true, `workspaceContains:${globPatterns.join(',')}`)) diff --git a/src/vs/workbench/test/electron-browser/api/extHostConfiguration.test.ts b/src/vs/workbench/test/electron-browser/api/extHostConfiguration.test.ts index 6638722bd03..763d55eb2b4 100644 --- a/src/vs/workbench/test/electron-browser/api/extHostConfiguration.test.ts +++ b/src/vs/workbench/test/electron-browser/api/extHostConfiguration.test.ts @@ -18,6 +18,7 @@ import { IWorkspaceFolder, WorkspaceFolder } from 'vs/platform/workspace/common/ import { ConfigurationTarget } from 'vs/platform/configuration/common/configuration'; import { NullLogService } from 'vs/platform/log/common/log'; import { assign } from 'vs/base/common/objects'; +import { Counter } from 'vs/base/common/numbers'; suite('ExtHostConfiguration', function () { @@ -33,7 +34,7 @@ suite('ExtHostConfiguration', function () { if (!shape) { shape = new class extends mock<MainThreadConfigurationShape>() { }; } - return new ExtHostConfiguration(shape, new ExtHostWorkspace(new TestRPCProtocol(), null, new NullLogService()), createConfigurationData(contents)); + return new ExtHostConfiguration(shape, new ExtHostWorkspace(new TestRPCProtocol(), null, new NullLogService(), new Counter()), createConfigurationData(contents)); } function createConfigurationData(contents: any): IConfigurationInitData { @@ -267,7 +268,7 @@ suite('ExtHostConfiguration', function () { test('inspect in no workspace context', function () { const testObject = new ExtHostConfiguration( new class extends mock<MainThreadConfigurationShape>() { }, - new ExtHostWorkspace(new TestRPCProtocol(), null, new NullLogService()), + new ExtHostWorkspace(new TestRPCProtocol(), null, new NullLogService(), new Counter()), { defaults: new ConfigurationModel({ 'editor': { @@ -314,7 +315,7 @@ suite('ExtHostConfiguration', function () { 'id': 'foo', 'folders': [aWorkspaceFolder(URI.file('foo'), 0)], 'name': 'foo' - }, new NullLogService()), + }, new NullLogService(), new Counter()), { defaults: new ConfigurationModel({ 'editor': { @@ -388,7 +389,7 @@ suite('ExtHostConfiguration', function () { 'id': 'foo', 'folders': [aWorkspaceFolder(firstRoot, 0), aWorkspaceFolder(secondRoot, 1)], 'name': 'foo' - }, new NullLogService()), + }, new NullLogService(), new Counter()), { defaults: new ConfigurationModel({ 'editor': { @@ -597,7 +598,7 @@ suite('ExtHostConfiguration', function () { 'id': 'foo', 'folders': [workspaceFolder], 'name': 'foo' - }, new NullLogService()), + }, new NullLogService(), new Counter()), createConfigurationData({ 'farboo': { 'config': false, diff --git a/src/vs/workbench/test/electron-browser/api/extHostWorkspace.test.ts b/src/vs/workbench/test/electron-browser/api/extHostWorkspace.test.ts index 4568ce2703c..1b58bc98dd9 100644 --- a/src/vs/workbench/test/electron-browser/api/extHostWorkspace.test.ts +++ b/src/vs/workbench/test/electron-browser/api/extHostWorkspace.test.ts @@ -15,6 +15,7 @@ import { IWorkspaceFolderData } from 'vs/platform/workspace/common/workspace'; import { IExtensionDescription } from 'vs/workbench/services/extensions/common/extensions'; import { NullLogService } from 'vs/platform/log/common/log'; import { IMainContext } from 'vs/workbench/api/node/extHost.protocol'; +import { Counter } from 'vs/base/common/numbers'; suite('ExtHostWorkspace', function () { @@ -41,7 +42,7 @@ suite('ExtHostWorkspace', function () { test('asRelativePath', function () { - const ws = new ExtHostWorkspace(new TestRPCProtocol(), { id: 'foo', folders: [aWorkspaceFolderData(URI.file('/Coding/Applications/NewsWoWBot'), 0)], name: 'Test' }, new NullLogService()); + const ws = new ExtHostWorkspace(new TestRPCProtocol(), { id: 'foo', folders: [aWorkspaceFolderData(URI.file('/Coding/Applications/NewsWoWBot'), 0)], name: 'Test' }, new NullLogService(), new Counter()); assertAsRelativePath(ws, '/Coding/Applications/NewsWoWBot/bernd/das/brot', 'bernd/das/brot'); assertAsRelativePath(ws, '/Apps/DartPubCache/hosted/pub.dartlang.org/convert-2.0.1/lib/src/hex.dart', @@ -55,7 +56,7 @@ suite('ExtHostWorkspace', function () { test('asRelativePath, same paths, #11402', function () { const root = '/home/aeschli/workspaces/samples/docker'; const input = '/home/aeschli/workspaces/samples/docker'; - const ws = new ExtHostWorkspace(new TestRPCProtocol(), { id: 'foo', folders: [aWorkspaceFolderData(URI.file(root), 0)], name: 'Test' }, new NullLogService()); + const ws = new ExtHostWorkspace(new TestRPCProtocol(), { id: 'foo', folders: [aWorkspaceFolderData(URI.file(root), 0)], name: 'Test' }, new NullLogService(), new Counter()); assertAsRelativePath(ws, (input), input); @@ -64,20 +65,20 @@ suite('ExtHostWorkspace', function () { }); test('asRelativePath, no workspace', function () { - const ws = new ExtHostWorkspace(new TestRPCProtocol(), null, new NullLogService()); + const ws = new ExtHostWorkspace(new TestRPCProtocol(), null, new NullLogService(), new Counter()); assertAsRelativePath(ws, (''), ''); assertAsRelativePath(ws, ('/foo/bar'), '/foo/bar'); }); test('asRelativePath, multiple folders', function () { - const ws = new ExtHostWorkspace(new TestRPCProtocol(), { id: 'foo', folders: [aWorkspaceFolderData(URI.file('/Coding/One'), 0), aWorkspaceFolderData(URI.file('/Coding/Two'), 1)], name: 'Test' }, new NullLogService()); + const ws = new ExtHostWorkspace(new TestRPCProtocol(), { id: 'foo', folders: [aWorkspaceFolderData(URI.file('/Coding/One'), 0), aWorkspaceFolderData(URI.file('/Coding/Two'), 1)], name: 'Test' }, new NullLogService(), new Counter()); assertAsRelativePath(ws, '/Coding/One/file.txt', 'One/file.txt'); assertAsRelativePath(ws, '/Coding/Two/files/out.txt', 'Two/files/out.txt'); assertAsRelativePath(ws, '/Coding/Two2/files/out.txt', '/Coding/Two2/files/out.txt'); }); test('slightly inconsistent behaviour of asRelativePath and getWorkspaceFolder, #31553', function () { - const mrws = new ExtHostWorkspace(new TestRPCProtocol(), { id: 'foo', folders: [aWorkspaceFolderData(URI.file('/Coding/One'), 0), aWorkspaceFolderData(URI.file('/Coding/Two'), 1)], name: 'Test' }, new NullLogService()); + const mrws = new ExtHostWorkspace(new TestRPCProtocol(), { id: 'foo', folders: [aWorkspaceFolderData(URI.file('/Coding/One'), 0), aWorkspaceFolderData(URI.file('/Coding/Two'), 1)], name: 'Test' }, new NullLogService(), new Counter()); assertAsRelativePath(mrws, '/Coding/One/file.txt', 'One/file.txt'); assertAsRelativePath(mrws, '/Coding/One/file.txt', 'One/file.txt', true); @@ -89,7 +90,7 @@ suite('ExtHostWorkspace', function () { assertAsRelativePath(mrws, '/Coding/Two2/files/out.txt', '/Coding/Two2/files/out.txt', true); assertAsRelativePath(mrws, '/Coding/Two2/files/out.txt', '/Coding/Two2/files/out.txt', false); - const srws = new ExtHostWorkspace(new TestRPCProtocol(), { id: 'foo', folders: [aWorkspaceFolderData(URI.file('/Coding/One'), 0)], name: 'Test' }, new NullLogService()); + const srws = new ExtHostWorkspace(new TestRPCProtocol(), { id: 'foo', folders: [aWorkspaceFolderData(URI.file('/Coding/One'), 0)], name: 'Test' }, new NullLogService(), new Counter()); assertAsRelativePath(srws, '/Coding/One/file.txt', 'file.txt'); assertAsRelativePath(srws, '/Coding/One/file.txt', 'file.txt', false); assertAsRelativePath(srws, '/Coding/One/file.txt', 'One/file.txt', true); @@ -99,24 +100,24 @@ suite('ExtHostWorkspace', function () { }); test('getPath, legacy', function () { - let ws = new ExtHostWorkspace(new TestRPCProtocol(), { id: 'foo', name: 'Test', folders: [] }, new NullLogService()); + let ws = new ExtHostWorkspace(new TestRPCProtocol(), { id: 'foo', name: 'Test', folders: [] }, new NullLogService(), new Counter()); assert.equal(ws.getPath(), undefined); - ws = new ExtHostWorkspace(new TestRPCProtocol(), null, new NullLogService()); + ws = new ExtHostWorkspace(new TestRPCProtocol(), null, new NullLogService(), new Counter()); assert.equal(ws.getPath(), undefined); - ws = new ExtHostWorkspace(new TestRPCProtocol(), undefined, new NullLogService()); + ws = new ExtHostWorkspace(new TestRPCProtocol(), undefined, new NullLogService(), new Counter()); assert.equal(ws.getPath(), undefined); - ws = new ExtHostWorkspace(new TestRPCProtocol(), { id: 'foo', name: 'Test', folders: [aWorkspaceFolderData(URI.file('Folder'), 0), aWorkspaceFolderData(URI.file('Another/Folder'), 1)] }, new NullLogService()); + ws = new ExtHostWorkspace(new TestRPCProtocol(), { id: 'foo', name: 'Test', folders: [aWorkspaceFolderData(URI.file('Folder'), 0), aWorkspaceFolderData(URI.file('Another/Folder'), 1)] }, new NullLogService(), new Counter()); assert.equal(ws.getPath().replace(/\\/g, '/'), '/Folder'); - ws = new ExtHostWorkspace(new TestRPCProtocol(), { id: 'foo', name: 'Test', folders: [aWorkspaceFolderData(URI.file('/Folder'), 0)] }, new NullLogService()); + ws = new ExtHostWorkspace(new TestRPCProtocol(), { id: 'foo', name: 'Test', folders: [aWorkspaceFolderData(URI.file('/Folder'), 0)] }, new NullLogService(), new Counter()); assert.equal(ws.getPath().replace(/\\/g, '/'), '/Folder'); }); test('WorkspaceFolder has name and index', function () { - const ws = new ExtHostWorkspace(new TestRPCProtocol(), { id: 'foo', folders: [aWorkspaceFolderData(URI.file('/Coding/One'), 0), aWorkspaceFolderData(URI.file('/Coding/Two'), 1)], name: 'Test' }, new NullLogService()); + const ws = new ExtHostWorkspace(new TestRPCProtocol(), { id: 'foo', folders: [aWorkspaceFolderData(URI.file('/Coding/One'), 0), aWorkspaceFolderData(URI.file('/Coding/Two'), 1)], name: 'Test' }, new NullLogService(), new Counter()); const [one, two] = ws.getWorkspaceFolders(); @@ -135,7 +136,7 @@ suite('ExtHostWorkspace', function () { aWorkspaceFolderData(URI.file('/Coding/Two'), 1), aWorkspaceFolderData(URI.file('/Coding/Two/Nested'), 2) ] - }, new NullLogService()); + }, new NullLogService(), new Counter()); let folder = ws.getWorkspaceFolder(URI.file('/foo/bar')); assert.equal(folder, undefined); @@ -175,7 +176,7 @@ suite('ExtHostWorkspace', function () { }); test('Multiroot change event should have a delta, #29641', function (done) { - let ws = new ExtHostWorkspace(new TestRPCProtocol(), { id: 'foo', name: 'Test', folders: [] }, new NullLogService()); + let ws = new ExtHostWorkspace(new TestRPCProtocol(), { id: 'foo', name: 'Test', folders: [] }, new NullLogService(), new Counter()); let finished = false; const finish = (error?: any) => { @@ -238,7 +239,7 @@ suite('ExtHostWorkspace', function () { }); test('Multiroot change keeps existing workspaces live', function () { - let ws = new ExtHostWorkspace(new TestRPCProtocol(), { id: 'foo', name: 'Test', folders: [aWorkspaceFolderData(URI.parse('foo:bar'), 0)] }, new NullLogService()); + let ws = new ExtHostWorkspace(new TestRPCProtocol(), { id: 'foo', name: 'Test', folders: [aWorkspaceFolderData(URI.parse('foo:bar'), 0)] }, new NullLogService(), new Counter()); let firstFolder = ws.getWorkspaceFolders()[0]; ws.$acceptWorkspaceData({ id: 'foo', name: 'Test', folders: [aWorkspaceFolderData(URI.parse('foo:bar2'), 0), aWorkspaceFolderData(URI.parse('foo:bar'), 1, 'renamed')] }); @@ -258,7 +259,7 @@ suite('ExtHostWorkspace', function () { }); test('updateWorkspaceFolders - invalid arguments', function () { - let ws = new ExtHostWorkspace(new TestRPCProtocol(), { id: 'foo', name: 'Test', folders: [] }, new NullLogService()); + let ws = new ExtHostWorkspace(new TestRPCProtocol(), { id: 'foo', name: 'Test', folders: [] }, new NullLogService(), new Counter()); assert.equal(false, ws.updateWorkspaceFolders(extensionDescriptor, null, null)); assert.equal(false, ws.updateWorkspaceFolders(extensionDescriptor, 0, 0)); @@ -267,7 +268,7 @@ suite('ExtHostWorkspace', function () { assert.equal(false, ws.updateWorkspaceFolders(extensionDescriptor, -1, 0)); assert.equal(false, ws.updateWorkspaceFolders(extensionDescriptor, -1, -1)); - ws = new ExtHostWorkspace(new TestRPCProtocol(), { id: 'foo', name: 'Test', folders: [aWorkspaceFolderData(URI.parse('foo:bar'), 0)] }, new NullLogService()); + ws = new ExtHostWorkspace(new TestRPCProtocol(), { id: 'foo', name: 'Test', folders: [aWorkspaceFolderData(URI.parse('foo:bar'), 0)] }, new NullLogService(), new Counter()); assert.equal(false, ws.updateWorkspaceFolders(extensionDescriptor, 1, 1)); assert.equal(false, ws.updateWorkspaceFolders(extensionDescriptor, 0, 2)); @@ -289,7 +290,7 @@ suite('ExtHostWorkspace', function () { assertRegistered: undefined }; - const ws = new ExtHostWorkspace(protocol, { id: 'foo', name: 'Test', folders: [] }, new NullLogService()); + const ws = new ExtHostWorkspace(protocol, { id: 'foo', name: 'Test', folders: [] }, new NullLogService(), new Counter()); // // Add one folder @@ -522,7 +523,7 @@ suite('ExtHostWorkspace', function () { } }; - let ws = new ExtHostWorkspace(new TestRPCProtocol(), { id: 'foo', name: 'Test', folders: [] }, new NullLogService()); + let ws = new ExtHostWorkspace(new TestRPCProtocol(), { id: 'foo', name: 'Test', folders: [] }, new NullLogService(), new Counter()); let sub = ws.onDidChangeWorkspace(e => { try { assert.throws(() => { @@ -545,7 +546,7 @@ suite('ExtHostWorkspace', function () { id: 'foo', name: 'Test', folders: [ aWorkspaceFolderData(URI.file('c:/Users/marek/Desktop/vsc_test/'), 0) ] - }, new NullLogService()); + }, new NullLogService(), new Counter()); assert.ok(ws.getWorkspaceFolder(URI.file('c:/Users/marek/Desktop/vsc_test/a.txt'))); assert.ok(ws.getWorkspaceFolder(URI.file('C:/Users/marek/Desktop/vsc_test/b.txt'))); From d200e76c4902ea4904915a6511386a9bf1d981aa Mon Sep 17 00:00:00 2001 From: Christopher Leidigh <cleidigh@Gmail.com> Date: Fri, 24 Aug 2018 01:32:16 -0400 Subject: [PATCH 1182/1276] Settings: Only add label target for checkbox (#57129) --- .../parts/preferences/browser/settingsTree.ts | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/src/vs/workbench/parts/preferences/browser/settingsTree.ts b/src/vs/workbench/parts/preferences/browser/settingsTree.ts index 964371c14b2..21d0bb57bee 100644 --- a/src/vs/workbench/parts/preferences/browser/settingsTree.ts +++ b/src/vs/workbench/parts/preferences/browser/settingsTree.ts @@ -678,11 +678,11 @@ export class SettingsRenderer implements ITreeRenderer { // Also have to ignore embedded links - too buried to stop propagation toDispose.push(DOM.addDisposableListener(descriptionElement, DOM.EventType.MOUSE_DOWN, (e) => { const targetElement = <HTMLElement>e.toElement; - const targetId = descriptionElement.getAttribute('checkboxLabelTargetId'); + const targetId = descriptionElement.getAttribute('checkbox-label-target-id'); // Make sure we are not a link and the target ID matches // Toggle target checkbox - if (targetElement.tagName !== 'A' && targetId === template.checkbox.domNode.id) { + if (targetElement.tagName.toLowerCase() !== 'a' && targetId === template.checkbox.domNode.id) { template.checkbox.checked = template.checkbox.checked ? false : true; } DOM.EventHelper.stop(e); @@ -949,9 +949,11 @@ export class SettingsRenderer implements ITreeRenderer { template.descriptionElement.innerText = element.description; } - // Add checkbox target to description clickable and able to toggle checkbox - const checkbox_id = (element.displayCategory + '_' + element.displayLabel).replace(/ /g, '_') + '_Item'; - template.descriptionElement.setAttribute('checkboxLabelTargetId', checkbox_id); + if (templateId === SETTINGS_BOOL_TEMPLATE_ID) { + // Add checkbox target to description clickable and able to toggle checkbox + const checkbox_id = (element.displayCategory + '_' + element.displayLabel).replace(/ /g, '_') + '_Item'; + template.descriptionElement.setAttribute('checkbox-label-target-id', checkbox_id); + } if (element.overriddenScopeList.length) { let otherOverridesLabel = element.isConfigured ? From 6e17ed2917de29aeefe82e0d4fd1442728259867 Mon Sep 17 00:00:00 2001 From: isidor <inikolic@microsoft.com> Date: Fri, 24 Aug 2018 09:50:24 +0200 Subject: [PATCH 1183/1276] Line breakpoint: fix disabled icon css rule fixes #57132 --- .../parts/debug/browser/media/debug.contribution.css | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/vs/workbench/parts/debug/browser/media/debug.contribution.css b/src/vs/workbench/parts/debug/browser/media/debug.contribution.css index 6637cb84e53..0785081abcb 100644 --- a/src/vs/workbench/parts/debug/browser/media/debug.contribution.css +++ b/src/vs/workbench/parts/debug/browser/media/debug.contribution.css @@ -53,7 +53,7 @@ } .debug-breakpoint, -.monaco-editor .debug-breakpoint-column.debug-breakpoint-column::before { +.monaco-editor .debug-breakpoint-column::before { background: url('breakpoint.svg') center center no-repeat; } @@ -90,11 +90,13 @@ background: url('breakpoint-log.svg') center center no-repeat; } -.debug-breakpoint-log-disabled { +.debug-breakpoint-log-disabled, +.monaco-editor .debug-breakpoint-log-disabled-column::before { background: url('breakpoint-log-disabled.svg') center center no-repeat; } -.debug-breakpoint-log-unverified { +.debug-breakpoint-log-unverified, +.monaco-editor .debug-breakpoint-log-unverified-column::before { background: url('breakpoint-log-unverified.svg') center center no-repeat; } From 74bd9b1d27cbde167f89f1321c123c7801796b74 Mon Sep 17 00:00:00 2001 From: Alex Dima <alexdima@microsoft.com> Date: Fri, 24 Aug 2018 09:52:46 +0200 Subject: [PATCH 1184/1276] Remove RPCMultiplexer; Add tests --- .../services/extensions/node/rpcProtocol.ts | 102 +++---------- .../extensions/test/node/rpcProtocol.test.ts | 144 ++++++++++++++++++ 2 files changed, 162 insertions(+), 84 deletions(-) create mode 100644 src/vs/workbench/services/extensions/test/node/rpcProtocol.test.ts diff --git a/src/vs/workbench/services/extensions/node/rpcProtocol.ts b/src/vs/workbench/services/extensions/node/rpcProtocol.ts index 5694010268e..e648dbbedec 100644 --- a/src/vs/workbench/services/extensions/node/rpcProtocol.ts +++ b/src/vs/workbench/services/extensions/node/rpcProtocol.ts @@ -94,7 +94,7 @@ export class RPCProtocol implements IRPCProtocol { private _lastMessageId: number; private readonly _invokedHandlers: { [req: string]: TPromise<any>; }; private readonly _pendingRPCReplies: { [msgId: string]: LazyPromise; }; - private readonly _multiplexor: RPCMultiplexer; + private readonly _protocol: IMessagePassingProtocol; constructor(protocol: IMessagePassingProtocol, transformer: IURITransformer = null) { this._uriTransformer = transformer; @@ -104,7 +104,8 @@ export class RPCProtocol implements IRPCProtocol { this._lastMessageId = 0; this._invokedHandlers = Object.create(null); this._pendingRPCReplies = {}; - this._multiplexor = new RPCMultiplexer(protocol, (msg) => this._receiveOneMessage(msg)); + this._protocol = protocol; + this._protocol.onMessage((msg) => this._receiveOneMessage(msg)); } public dispose(): void { @@ -232,10 +233,10 @@ export class RPCProtocol implements IRPCProtocol { if (this._uriTransformer) { r = transformOutgoingURIs(r, this._uriTransformer); } - this._multiplexor.send(MessageIO.serializeReplyOK(req, r)); + this._protocol.send(MessageIO.serializeReplyOK(req, r)); }, (err) => { delete this._invokedHandlers[callId]; - this._multiplexor.send(MessageIO.serializeReplyErr(req, err)); + this._protocol.send(MessageIO.serializeReplyErr(req, err)); }); } @@ -307,69 +308,18 @@ export class RPCProtocol implements IRPCProtocol { const nCallId = ++this._lastMessageId; const callId = String(nCallId); const result = new LazyPromise(() => { - this._multiplexor.send(MessageIO.serializeCancel(nCallId)); + this._protocol.send(MessageIO.serializeCancel(nCallId)); }); this._pendingRPCReplies[callId] = result; if (this._uriTransformer) { args = transformOutgoingURIs(args, this._uriTransformer); } - this._multiplexor.send(MessageIO.serializeRequest(nCallId, proxyId, methodName, args)); + this._protocol.send(MessageIO.serializeRequest(nCallId, proxyId, methodName, args)); return result; } } -/** - * Sends/Receives multiple messages in one go: - * - multiple messages to be sent from one stack get sent in bulk at `process.nextTick`. - * - each incoming message is handled in a separate `process.nextTick`. - */ -class RPCMultiplexer { - - private readonly _protocol: IMessagePassingProtocol; - private readonly _sendAccumulatedBound: () => void; - - private _messagesToSend: Buffer[]; - - constructor(protocol: IMessagePassingProtocol, onMessage: (msg: Buffer) => void) { - this._protocol = protocol; - this._sendAccumulatedBound = this._sendAccumulated.bind(this); - - this._messagesToSend = []; - - this._protocol.onMessage(data => { - let i = 0; - - while (i < data.length) { - const size = data.readUInt32LE(i); - onMessage(data.slice(i + 4, i + 4 + size)); - i += 4 + size; - } - }); - } - - private _sendAccumulated(): void { - const size = this._messagesToSend.reduce((r, b) => r + b.byteLength, 0); - const buffer = Buffer.allocUnsafe(size); - - let offset = 0; - for (const msg of this._messagesToSend) { - msg.copy(buffer, offset); - offset += msg.byteLength; - } - - this._messagesToSend = []; - this._protocol.send(buffer); - } - - public send(msg: Buffer): void { - if (this._messagesToSend.length === 0) { - process.nextTick(this._sendAccumulatedBound); - } - this._messagesToSend.push(msg); - } -} - class MessageIO { private static arrayContainsBuffer(arr: any[]): boolean { for (let i = 0, len = arr.length; i < len; i++) { @@ -413,7 +363,6 @@ class MessageIO { const argsByteLength = Buffer.byteLength(args); let len = 0; - // len += 4; // msg length len += 1; // msg type len += 4; // req len += 1; // rpcId length @@ -423,10 +372,9 @@ class MessageIO { len += 4; // arg length len += argsByteLength; - let result = Buffer.allocUnsafe(len + 4); + let result = Buffer.allocUnsafe(len); let offset = 0; - result.writeUInt32LE(len, offset, true); offset += 4; result.writeUInt8(MessageType.RequestJSONArgs, offset, true); offset += 1; result.writeUInt32LE(req, offset, true); offset += 4; result.writeUInt8(rpcIdByteLength, offset, true); offset += 1; @@ -458,7 +406,6 @@ class MessageIO { const methodByteLength = Buffer.byteLength(method); let len = 0; - // len += 4; // msg length len += 1; // msg type len += 4; // req len += 1; // rpcId length @@ -466,16 +413,15 @@ class MessageIO { len += 1; // method length len += methodByteLength; len += 1; // arg count - for (let i = 0, len = args.length; i < len; i++) { + for (let i = 0, argsLen = args.length; i < argsLen; i++) { len += 1; // arg type len += 4; // buffer length len += argsLengths[i]; } - let result = Buffer.allocUnsafe(len + 4); + let result = Buffer.allocUnsafe(len); let offset = 0; - result.writeUInt32LE(len, offset, true); offset += 4; result.writeUInt8(MessageType.RequestMixedArgs, offset, true); offset += 1; result.writeUInt32LE(req, offset, true); offset += 4; result.writeUInt8(rpcIdByteLength, offset, true); offset += 1; @@ -483,7 +429,7 @@ class MessageIO { result.writeUInt8(methodByteLength, offset, true); offset += 1; result.write(method, offset, methodByteLength, 'utf8'); offset += methodByteLength; result.writeUInt8(args.length, offset, true); offset += 1; - for (let i = 0, len = args.length; i < len; i++) { + for (let i = 0, argsLen = args.length; i < argsLen; i++) { const arg = args[i]; if (typeof arg === 'string') { result.writeUInt8(ArgType.ArgString, offset, true); offset += 1; @@ -524,14 +470,12 @@ class MessageIO { public static serializeCancel(req: number): Buffer { let len = 0; - // len += 4; // msg length len += 1; // msg type len += 4; // req - let result = Buffer.allocUnsafe(len + 4); + let result = Buffer.allocUnsafe(len); let offset = 0; - result.writeUInt32LE(len, offset, true); offset += 4; result.writeUInt8(MessageType.Cancel, offset, true); offset += 1; result.writeUInt32LE(req, offset, true); offset += 4; @@ -550,14 +494,12 @@ class MessageIO { private static _serializeReplyOKEmpty(req: number): Buffer { let len = 0; - // len += 4; // msg length len += 1; // msg type len += 4; // req - let result = Buffer.allocUnsafe(len + 4); + let result = Buffer.allocUnsafe(len); let offset = 0; - result.writeUInt32LE(len, offset, true); offset += 4; result.writeUInt8(MessageType.ReplyOKEmpty, offset, true); offset += 1; result.writeUInt32LE(req, offset, true); offset += 4; @@ -566,16 +508,14 @@ class MessageIO { private static _serializeReplyOKBuffer(req: number, res: Buffer): Buffer { let len = 0; - // len += 4; // msg length len += 1; // msg type len += 4; // req len += 4; // res length len += res.byteLength; - let result = Buffer.allocUnsafe(len + 4); + let result = Buffer.allocUnsafe(len); let offset = 0; - result.writeUInt32LE(len, offset, true); offset += 4; result.writeUInt8(MessageType.ReplyOKBuffer, offset, true); offset += 1; result.writeUInt32LE(req, offset, true); offset += 4; result.writeUInt32LE(res.byteLength, offset, true); offset += 4; @@ -594,16 +534,14 @@ class MessageIO { const resByteLength = Buffer.byteLength(res); let len = 0; - // len += 4; // msg length len += 1; // msg type len += 4; // req len += 4; // res length len += resByteLength; - let result = Buffer.allocUnsafe(len + 4); + let result = Buffer.allocUnsafe(len); let offset = 0; - result.writeUInt32LE(len, offset, true); offset += 4; result.writeUInt8(MessageType.ReplyOKJSON, offset, true); offset += 1; result.writeUInt32LE(req, offset, true); offset += 4; result.writeUInt32LE(resByteLength, offset, true); offset += 4; @@ -622,7 +560,7 @@ class MessageIO { if (err instanceof Error) { return this._serializeReplyErrEror(req, err); } - return this._serializeReplyErrEmpty(err); + return this._serializeReplyErrEmpty(req); } private static _serializeReplyErrEror(req: number, _err: Error): Buffer { @@ -635,17 +573,14 @@ class MessageIO { len += 4; // err length len += errByteLength; - let result = Buffer.allocUnsafe(len + 4); + let result = Buffer.allocUnsafe(len); let offset = 0; - result.writeUInt32LE(len, offset, true); offset += 4; result.writeUInt8(MessageType.ReplyErrError, offset, true); offset += 1; result.writeUInt32LE(req, offset, true); offset += 4; result.writeUInt32LE(errByteLength, offset, true); offset += 4; result.write(err, offset, errByteLength, 'utf8'); offset += errByteLength; - console.log(result); - return result; } @@ -660,10 +595,9 @@ class MessageIO { len += 1; // msg type len += 4; // req - let result = Buffer.allocUnsafe(len + 4); + let result = Buffer.allocUnsafe(len); let offset = 0; - result.writeUInt32LE(len, offset, true); offset += 4; result.writeUInt8(MessageType.ReplyErrEmpty, offset, true); offset += 1; result.writeUInt32LE(req, offset, true); offset += 4; diff --git a/src/vs/workbench/services/extensions/test/node/rpcProtocol.test.ts b/src/vs/workbench/services/extensions/test/node/rpcProtocol.test.ts new file mode 100644 index 00000000000..602a7d37d62 --- /dev/null +++ b/src/vs/workbench/services/extensions/test/node/rpcProtocol.test.ts @@ -0,0 +1,144 @@ +/*--------------------------------------------------------------------------------------------- + * 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 * as assert from 'assert'; +import { RPCProtocol } from 'vs/workbench/services/extensions/node/rpcProtocol'; +import { IMessagePassingProtocol } from 'vs/base/parts/ipc/node/ipc'; +import { Event, Emitter } from 'vs/base/common/event'; +import { ProxyIdentifier } from 'vs/workbench/services/extensions/node/proxyIdentifier'; +import { TPromise } from 'vs/base/common/winjs.base'; + +suite('RPCProtocol', () => { + + class MessagePassingProtocol implements IMessagePassingProtocol { + private _pair: MessagePassingProtocol; + + private readonly _onMessage: Emitter<Buffer> = new Emitter<Buffer>(); + public readonly onMessage: Event<Buffer> = this._onMessage.event; + + public setPair(other: MessagePassingProtocol) { + this._pair = other; + } + + public send(buffer: Buffer): void { + process.nextTick(() => { + this._pair._onMessage.fire(buffer); + }); + } + } + + let delegate: (a1: any, a2: any) => any; + let bProxy: BClass; + class BClass { + $m(a1: any, a2: any): TPromise<any> { + return TPromise.as(delegate.call(null, a1, a2)); + } + } + + setup(() => { + let a_protocol = new MessagePassingProtocol(); + let b_protocol = new MessagePassingProtocol(); + a_protocol.setPair(b_protocol); + b_protocol.setPair(a_protocol); + + let A = new RPCProtocol(a_protocol); + let B = new RPCProtocol(b_protocol); + + delegate = null; + + const bIdentifier = new ProxyIdentifier<BClass>(false, 'bb'); + const bInstance = new BClass(); + B.set(bIdentifier, bInstance); + bProxy = A.getProxy(bIdentifier); + }); + + test('simple call', function (done) { + delegate = (a1: number, a2: number) => a1 + a2; + bProxy.$m(4, 1).then((res: number) => { + assert.equal(res, 5); + done(null); + }, done); + }); + + test('simple call without result', function (done) { + delegate = (a1: number, a2: number) => { }; + bProxy.$m(4, 1).then((res: number) => { + assert.equal(res, undefined); + done(null); + }, done); + }); + + test('passing buffer as argument', function (done) { + delegate = (a1: Buffer, a2: number) => { + assert.ok(Buffer.isBuffer(a1)); + return a1[a2]; + }; + let b = Buffer.allocUnsafe(4); + b[0] = 1; + b[1] = 2; + b[2] = 3; + b[3] = 4; + bProxy.$m(b, 2).then((res: number) => { + assert.equal(res, 3); + done(null); + }, done); + }); + + test('returning a buffer', function (done) { + delegate = (a1: number, a2: number) => { + let b = Buffer.allocUnsafe(4); + b[0] = 1; + b[1] = 2; + b[2] = 3; + b[3] = 4; + return b; + }; + bProxy.$m(4, 1).then((res: Buffer) => { + assert.ok(Buffer.isBuffer(res)); + assert.equal(res[0], 1); + assert.equal(res[1], 2); + assert.equal(res[2], 3); + assert.equal(res[3], 4); + done(null); + }, done); + }); + + test('cancelling a call', function () { + delegate = (a1: number, a2: number) => a1 + a2; + let p = bProxy.$m(4, 1); + p.then((res: number) => { + assert.fail('should not receive result'); + }); + p.cancel(); + }); + + test('throwing an error', function (done) { + delegate = (a1: number, a2: number) => { + throw new Error(`nope`); + }; + bProxy.$m(4, 1).then((res) => { + assert.fail('unexpected'); + done(null); + }, (err) => { + assert.equal(err.message, 'nope'); + done(null); + }); + }); + + test('error promise', function (done) { + delegate = (a1: number, a2: number) => { + return TPromise.wrapError(undefined); + }; + bProxy.$m(4, 1).then((res) => { + assert.fail('unexpected'); + done(null); + }, (err) => { + assert.equal(err, undefined); + done(null); + }); + }); +}); From 8d72e849d358efce78a0cd5dc9bfb7ef03e19410 Mon Sep 17 00:00:00 2001 From: Benjamin Pasero <benjamin.pasero@gmail.com> Date: Fri, 24 Aug 2018 09:54:25 +0200 Subject: [PATCH 1185/1276] Debt: avoid electron remote module (#57134) * debt - avoid usages of electron remote module * debt - comment out remote & sendSync from electron.d.ts --- src/typings/electron.d.ts | 4 +- src/vs/base/browser/contextmenu.ts | 4 +- .../parts/contextmenu/common/contextmenu.ts | 45 +++++ .../electron-browser/contextmenu.ts | 50 ++++++ .../contextmenu/electron-main/contextmenu.ts | 65 +++++++ .../processExplorer/processExplorerMain.ts | 34 ++-- src/vs/code/electron-main/app.ts | 4 + src/vs/code/electron-main/windows.ts | 1 + .../driver/electron-browser/driver.ts | 2 +- src/vs/platform/issue/common/issue.ts | 1 + src/vs/platform/windows/common/windows.ts | 2 + .../electron-browser/contextmenuService.ts | 170 +++++++++--------- .../electron-browser/workbenchIssueService.ts | 9 +- 13 files changed, 283 insertions(+), 108 deletions(-) create mode 100644 src/vs/base/parts/contextmenu/common/contextmenu.ts create mode 100644 src/vs/base/parts/contextmenu/electron-browser/contextmenu.ts create mode 100644 src/vs/base/parts/contextmenu/electron-main/contextmenu.ts diff --git a/src/typings/electron.d.ts b/src/typings/electron.d.ts index 56c03cf5e2d..a13e294afe5 100644 --- a/src/typings/electron.d.ts +++ b/src/typings/electron.d.ts @@ -104,7 +104,7 @@ declare namespace Electron { const powerMonitor: PowerMonitor; const powerSaveBlocker: PowerSaveBlocker; const protocol: Protocol; - const remote: Remote; + // const remote: Remote; ### VSCODE CHANGE (we do not want to use remote) const screen: Screen; type session = Session; const session: typeof Session; @@ -2962,7 +2962,7 @@ declare namespace Electron { * event.returnValue. Note: Sending a synchronous message will block the whole * renderer process, unless you know what you are doing you should never use it. */ - sendSync(channel: string, ...args: any[]): any; + // sendSync(channel: string, ...args: any[]): any; ### VSCODE CHANGE (we do not want to use sendSync) /** * Sends a message to a window with windowid via channel. */ diff --git a/src/vs/base/browser/contextmenu.ts b/src/vs/base/browser/contextmenu.ts index c303d45eeb3..5dd631aa97f 100644 --- a/src/vs/base/browser/contextmenu.ts +++ b/src/vs/base/browser/contextmenu.ts @@ -10,7 +10,7 @@ import { TPromise } from 'vs/base/common/winjs.base'; import { ResolvedKeybinding } from 'vs/base/common/keyCodes'; import { SubmenuAction } from 'vs/base/browser/ui/menu/menu'; -export interface IEvent { +export interface IContextMenuEvent { shiftKey?: boolean; ctrlKey?: boolean; altKey?: boolean; @@ -27,7 +27,7 @@ export interface IContextMenuDelegate { getAnchor(): HTMLElement | { x: number; y: number; }; getActions(): TPromise<(IAction | ContextSubMenu)[]>; getActionItem?(action: IAction): IActionItem; - getActionsContext?(event?: IEvent): any; + getActionsContext?(event?: IContextMenuEvent): any; getKeyBinding?(action: IAction): ResolvedKeybinding; getMenuClassName?(): string; onHide?(didCancel: boolean): void; diff --git a/src/vs/base/parts/contextmenu/common/contextmenu.ts b/src/vs/base/parts/contextmenu/common/contextmenu.ts new file mode 100644 index 00000000000..6998c66916f --- /dev/null +++ b/src/vs/base/parts/contextmenu/common/contextmenu.ts @@ -0,0 +1,45 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +'use strict'; + +export interface ICommonContextMenuItem { + label?: string; + + type?: 'normal' | 'separator' | 'submenu' | 'checkbox' | 'radio'; + + accelerator?: string; + + enabled?: boolean; + visible?: boolean; + checked?: boolean; +} + +export interface ISerializableContextMenuItem extends ICommonContextMenuItem { + id: number; + submenu?: ISerializableContextMenuItem[]; +} + +export interface IContextMenuItem extends ICommonContextMenuItem { + click?: (event: IContextMenuEvent) => void; + submenu?: IContextMenuItem[]; +} + +export interface IContextMenuEvent { + shiftKey?: boolean; + ctrlKey?: boolean; + altKey?: boolean; + metaKey?: boolean; +} + +export interface IPopupOptions { + x?: number; + y?: number; + positioningItem?: number; + onHide?: () => void; +} + +export const CONTEXT_MENU_CHANNEL = 'vscode:contextmenu'; +export const CONTEXT_MENU_CLOSE_CHANNEL = 'vscode:onCloseContextMenu'; \ No newline at end of file diff --git a/src/vs/base/parts/contextmenu/electron-browser/contextmenu.ts b/src/vs/base/parts/contextmenu/electron-browser/contextmenu.ts new file mode 100644 index 00000000000..f5e4d2b8dfe --- /dev/null +++ b/src/vs/base/parts/contextmenu/electron-browser/contextmenu.ts @@ -0,0 +1,50 @@ +/*--------------------------------------------------------------------------------------------- + * 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 { ipcRenderer, Event } from 'electron'; +import { IContextMenuItem, ISerializableContextMenuItem, CONTEXT_MENU_CLOSE_CHANNEL, CONTEXT_MENU_CHANNEL, IPopupOptions, IContextMenuEvent } from 'vs/base/parts/contextmenu/common/contextmenu'; + +let onClickChannelIds = 0; + +export function popup(items: IContextMenuItem[], options?: IPopupOptions): void { + const processedItems: IContextMenuItem[] = []; + + const onClickChannel = `vscode:onContextMenu${onClickChannelIds++}`; + const onClickChannelHandler = (event: Event, itemId: number, context: IContextMenuEvent) => processedItems[itemId].click(context); + + ipcRenderer.once(onClickChannel, onClickChannelHandler); + ipcRenderer.once(CONTEXT_MENU_CLOSE_CHANNEL, () => { + ipcRenderer.removeListener(onClickChannel, onClickChannelHandler); + + if (options && options.onHide) { + options.onHide(); + } + }); + + ipcRenderer.send(CONTEXT_MENU_CHANNEL, items.map(item => createItem(item, processedItems)), onClickChannel, options); +} + +function createItem(item: IContextMenuItem, processedItems: IContextMenuItem[]): ISerializableContextMenuItem { + const serializableItem = { + id: processedItems.length, + label: item.label, + type: item.type, + accelerator: item.accelerator, + checked: item.checked, + enabled: typeof item.enabled === 'boolean' ? item.enabled : true, + visible: typeof item.visible === 'boolean' ? item.visible : true + } as ISerializableContextMenuItem; + + processedItems.push(item); + + // Submenu + if (Array.isArray(item.submenu)) { + serializableItem.submenu = item.submenu.map(submenuItem => createItem(submenuItem, processedItems)); + } + + return serializableItem; +} \ No newline at end of file diff --git a/src/vs/base/parts/contextmenu/electron-main/contextmenu.ts b/src/vs/base/parts/contextmenu/electron-main/contextmenu.ts new file mode 100644 index 00000000000..5afeaad9c1c --- /dev/null +++ b/src/vs/base/parts/contextmenu/electron-main/contextmenu.ts @@ -0,0 +1,65 @@ +/*--------------------------------------------------------------------------------------------- + * 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 { Menu, MenuItem, BrowserWindow, Event, ipcMain } from 'electron'; +import { ISerializableContextMenuItem, CONTEXT_MENU_CLOSE_CHANNEL, CONTEXT_MENU_CHANNEL, IPopupOptions } from 'vs/base/parts/contextmenu/common/contextmenu'; + +export function registerContextMenuListener(): void { + ipcMain.on(CONTEXT_MENU_CHANNEL, (event: Event, items: ISerializableContextMenuItem[], onClickChannel: string, options?: IPopupOptions) => { + const menu = createMenu(event, onClickChannel, items); + + menu.popup({ + window: BrowserWindow.fromWebContents(event.sender), + x: options ? options.x : void 0, + y: options ? options.y : void 0, + positioningItem: options ? options.positioningItem : void 0, + callback: () => { + event.sender.send(CONTEXT_MENU_CLOSE_CHANNEL); + } + }); + }); +} + +function createMenu(event: Event, onClickChannel: string, items: ISerializableContextMenuItem[]): Menu { + const menu = new Menu(); + + items.forEach(item => { + let menuitem: MenuItem; + + // Separator + if (item.type === 'separator') { + menuitem = new MenuItem({ + type: item.type, + }); + } + + // Sub Menu + else if (Array.isArray(item.submenu)) { + menuitem = new MenuItem({ + submenu: createMenu(event, onClickChannel, item.submenu), + label: item.label + }); + } + + // Normal Menu Item + else { + menuitem = new MenuItem({ + label: item.label, + type: item.type, + accelerator: item.accelerator, + checked: item.checked, + enabled: item.enabled, + visible: item.visible, + click: (menuItem, win, contextmenuEvent) => event.sender.send(onClickChannel, item.id, contextmenuEvent) + }); + } + + menu.append(menuitem); + }); + + return menu; +} \ No newline at end of file diff --git a/src/vs/code/electron-browser/processExplorer/processExplorerMain.ts b/src/vs/code/electron-browser/processExplorer/processExplorerMain.ts index 379eab77cf3..645bf682472 100644 --- a/src/vs/code/electron-browser/processExplorer/processExplorerMain.ts +++ b/src/vs/code/electron-browser/processExplorer/processExplorerMain.ts @@ -7,7 +7,7 @@ import 'vs/css!./media/processExplorer'; import { listProcesses, ProcessItem } from 'vs/base/node/ps'; -import { remote, webFrame, ipcRenderer, clipboard } from 'electron'; +import { webFrame, ipcRenderer, clipboard } from 'electron'; import { repeat } from 'vs/base/common/strings'; import { totalmem } from 'os'; import product from 'vs/platform/node/product'; @@ -15,6 +15,8 @@ import { localize } from 'vs/nls'; import { ProcessExplorerStyles, ProcessExplorerData } from 'vs/platform/issue/common/issue'; import * as browser from 'vs/base/browser/browser'; import * as platform from 'vs/base/common/platform'; +import { IContextMenuItem } from 'vs/base/parts/contextmenu/common/contextmenu'; +import { popup } from 'vs/base/parts/contextmenu/electron-browser/contextmenu'; let processList: any[]; let mapPidToWindowTitle = new Map<number, string>(); @@ -137,29 +139,29 @@ function applyZoom(zoomLevel: number): void { function showContextMenu(e) { e.preventDefault(); - const menu = new remote.Menu(); + const items: IContextMenuItem[] = []; const pid = parseInt(e.currentTarget.id); if (pid && typeof pid === 'number') { - menu.append(new remote.MenuItem({ + items.push({ label: localize('killProcess', "Kill Process"), click() { process.kill(pid, 'SIGTERM'); } - })); + }); - menu.append(new remote.MenuItem({ + items.push({ label: localize('forceKillProcess', "Force Kill Process"), click() { process.kill(pid, 'SIGKILL'); } - })); + }); - menu.append(new remote.MenuItem({ + items.push({ type: 'separator' - })); + }); - menu.append(new remote.MenuItem({ + items.push({ label: localize('copy', "Copy"), click() { const row = document.getElementById(pid.toString()); @@ -167,9 +169,9 @@ function showContextMenu(e) { clipboard.writeText(row.innerText); } } - })); + }); - menu.append(new remote.MenuItem({ + items.push({ label: localize('copyAll', "Copy All"), click() { const processList = document.getElementById('process-list'); @@ -177,9 +179,9 @@ function showContextMenu(e) { clipboard.writeText(processList.innerText); } } - })); + }); } else { - menu.append(new remote.MenuItem({ + items.push({ label: localize('copyAll', "Copy All"), click() { const processList = document.getElementById('process-list'); @@ -187,10 +189,10 @@ function showContextMenu(e) { clipboard.writeText(processList.innerText); } } - })); + }); } - menu.popup({ window: remote.getCurrentWindow() }); + popup(items); } export function startup(data: ProcessExplorerData): void { @@ -206,7 +208,7 @@ export function startup(data: ProcessExplorerData): void { setInterval(() => { ipcRenderer.send('windowsInfoRequest'); - listProcesses(remote.process.pid).then(processes => { + listProcesses(data.pid).then(processes => { processList = getProcessList(processes); updateProcessInfo(processList); diff --git a/src/vs/code/electron-main/app.ts b/src/vs/code/electron-main/app.ts index 5a56a7abf29..bb199729fac 100644 --- a/src/vs/code/electron-main/app.ts +++ b/src/vs/code/electron-main/app.ts @@ -67,6 +67,7 @@ import { ILabelService } from 'vs/platform/label/common/label'; import { CodeMenu } from 'vs/code/electron-main/menus'; import { hasArgs } from 'vs/platform/environment/node/argv'; import { RunOnceScheduler } from 'vs/base/common/async'; +import { registerContextMenuListener } from 'vs/base/parts/contextmenu/electron-main/contextmenu'; export class CodeApplication { @@ -104,6 +105,9 @@ export class CodeApplication { process.on('uncaughtException', err => this.onUnexpectedError(err)); process.on('unhandledRejection', (reason: any, promise: Promise<any>) => errors.onUnexpectedError(reason)); + // Contextmenu via IPC support + registerContextMenuListener(); + app.on('will-quit', () => { this.logService.trace('App#will-quit: disposing resources'); diff --git a/src/vs/code/electron-main/windows.ts b/src/vs/code/electron-main/windows.ts index 5c9051ca65d..55d5cf9e53c 100644 --- a/src/vs/code/electron-main/windows.ts +++ b/src/vs/code/electron-main/windows.ts @@ -1182,6 +1182,7 @@ export class WindowsManager implements IWindowsMainService { const configuration: IWindowConfiguration = mixin({}, options.cli); // inherit all properties from CLI configuration.appRoot = this.environmentService.appRoot; configuration.machineId = this.machineId; + configuration.mainPid = process.pid; configuration.execPath = process.execPath; configuration.userEnv = assign({}, this.initialUserEnv, options.userEnv || {}); configuration.isInitialStartup = options.initialStartup; diff --git a/src/vs/platform/driver/electron-browser/driver.ts b/src/vs/platform/driver/electron-browser/driver.ts index 46a202f2c79..a2305e2d393 100644 --- a/src/vs/platform/driver/electron-browser/driver.ts +++ b/src/vs/platform/driver/electron-browser/driver.ts @@ -86,7 +86,7 @@ class WindowDriver implements IWindowDriver { private _click(selector: string, clickCount: number, xoffset?: number, yoffset?: number): TPromise<void> { return this._getElementXY(selector, xoffset, yoffset).then(({ x, y }) => { - const webContents = electron.remote.getCurrentWebContents(); + const webContents: electron.WebContents = (electron as any).remote.getCurrentWebContents(); webContents.sendInputEvent({ type: 'mouseDown', x, y, button: 'left', clickCount } as any); return TPromise.timeout(10).then(() => { diff --git a/src/vs/platform/issue/common/issue.ts b/src/vs/platform/issue/common/issue.ts index 46d378dc8d4..fef600c10f5 100644 --- a/src/vs/platform/issue/common/issue.ts +++ b/src/vs/platform/issue/common/issue.ts @@ -74,6 +74,7 @@ export interface ProcessExplorerStyles extends WindowStyles { } export interface ProcessExplorerData extends WindowData { + pid: number; styles: ProcessExplorerStyles; } diff --git a/src/vs/platform/windows/common/windows.ts b/src/vs/platform/windows/common/windows.ts index 4b199d0e3e9..eedeaca472b 100644 --- a/src/vs/platform/windows/common/windows.ts +++ b/src/vs/platform/windows/common/windows.ts @@ -336,6 +336,8 @@ export interface IWindowConfiguration extends ParsedArgs { windowId: number; logLevel: LogLevel; + mainPid: number; + appRoot: string; execPath: string; isInitialStartup?: boolean; diff --git a/src/vs/workbench/services/contextview/electron-browser/contextmenuService.ts b/src/vs/workbench/services/contextview/electron-browser/contextmenuService.ts index 22429b85715..668c8fa75fa 100644 --- a/src/vs/workbench/services/contextview/electron-browser/contextmenuService.ts +++ b/src/vs/workbench/services/contextview/electron-browser/contextmenuService.ts @@ -12,13 +12,15 @@ import * as dom from 'vs/base/browser/dom'; import { IContextMenuService } from 'vs/platform/contextview/browser/contextView'; import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry'; import { IKeybindingService } from 'vs/platform/keybinding/common/keybinding'; -import { remote, webFrame } from 'electron'; +import { webFrame } from 'electron'; import { unmnemonicLabel } from 'vs/base/common/labels'; import { Event, Emitter } from 'vs/base/common/event'; import { INotificationService } from 'vs/platform/notification/common/notification'; -import { IContextMenuDelegate, ContextSubMenu, IEvent } from 'vs/base/browser/contextmenu'; +import { IContextMenuDelegate, ContextSubMenu, IContextMenuEvent } from 'vs/base/browser/contextmenu'; import { once } from 'vs/base/common/functional'; import { Disposable } from 'vs/base/common/lifecycle'; +import { IContextMenuItem } from 'vs/base/parts/contextmenu/common/contextmenu'; +import { popup } from 'vs/base/parts/contextmenu/electron-browser/contextmenu'; export class ContextMenuService extends Disposable implements IContextMenuService { @@ -38,101 +40,101 @@ export class ContextMenuService extends Disposable implements IContextMenuServic showContextMenu(delegate: IContextMenuDelegate): void { delegate.getActions().then(actions => { if (actions.length) { - setTimeout(() => { - const onHide = once(() => { - if (delegate.onHide) { - delegate.onHide(undefined); - } - - this._onDidContextMenu.fire(); - }); - - const menu = this.createMenu(delegate, actions, onHide); - const anchor = delegate.getAnchor(); - let x: number, y: number; - - if (dom.isHTMLElement(anchor)) { - let elementPosition = dom.getDomNodePagePosition(anchor); - - x = elementPosition.left; - y = elementPosition.top + elementPosition.height; - } else { - const pos = <{ x: number; y: number; }>anchor; - x = pos.x + 1; /* prevent first item from being selected automatically under mouse */ - y = pos.y; + const onHide = once(() => { + if (delegate.onHide) { + delegate.onHide(undefined); } - let zoom = webFrame.getZoomFactor(); - x *= zoom; - y *= zoom; - - menu.popup({ - window: remote.getCurrentWindow(), - x: Math.floor(x), - y: Math.floor(y), - positioningItem: delegate.autoSelectFirstItem ? 0 : void 0, - callback: () => onHide() - }); - }, 0); // https://github.com/Microsoft/vscode/issues/3638 - } - }); - } - - private createMenu(delegate: IContextMenuDelegate, entries: (IAction | ContextSubMenu)[], onHide: () => void): Electron.Menu { - const menu = new remote.Menu(); - const actionRunner = delegate.actionRunner || new ActionRunner(); - - entries.forEach(e => { - if (e instanceof Separator) { - menu.append(new remote.MenuItem({ type: 'separator' })); - } else if (e instanceof ContextSubMenu) { - const submenu = new remote.MenuItem({ - submenu: this.createMenu(delegate, e.entries, onHide), - label: unmnemonicLabel(e.label) + this._onDidContextMenu.fire(); }); - menu.append(submenu); - } else { - const options: Electron.MenuItemConstructorOptions = { - label: unmnemonicLabel(e.label), - checked: !!e.checked || !!e.radio, - type: !!e.checked ? 'checkbox' : !!e.radio ? 'radio' : void 0, - enabled: !!e.enabled, - click: (menuItem, win, event) => { + const menu = this.createMenu(delegate, actions, onHide); + const anchor = delegate.getAnchor(); + let x: number, y: number; - // To preserve pre-electron-2.x behaviour, we first trigger - // the onHide callback and then the action. - // Fixes https://github.com/Microsoft/vscode/issues/45601 - onHide(); + if (dom.isHTMLElement(anchor)) { + let elementPosition = dom.getDomNodePagePosition(anchor); - // Run action which will close the menu - this.runAction(actionRunner, e, delegate, event); - } - }; - - const keybinding = !!delegate.getKeyBinding ? delegate.getKeyBinding(e) : this.keybindingService.lookupKeybinding(e.id); - if (keybinding) { - const electronAccelerator = keybinding.getElectronAccelerator(); - if (electronAccelerator) { - options.accelerator = electronAccelerator; - } else { - const label = keybinding.getLabel(); - if (label) { - options.label = `${options.label} [${label}]`; - } - } + x = elementPosition.left; + y = elementPosition.top + elementPosition.height; + } else { + const pos = <{ x: number; y: number; }>anchor; + x = pos.x + 1; /* prevent first item from being selected automatically under mouse */ + y = pos.y; } - const item = new remote.MenuItem(options); + let zoom = webFrame.getZoomFactor(); + x *= zoom; + y *= zoom; - menu.append(item); + popup(menu, { + x: Math.floor(x), + y: Math.floor(y), + positioningItem: delegate.autoSelectFirstItem ? 0 : void 0, + onHide: () => onHide() + }); } }); - - return menu; } - private runAction(actionRunner: IActionRunner, actionToRun: IAction, delegate: IContextMenuDelegate, event: IEvent): void { + private createMenu(delegate: IContextMenuDelegate, entries: (IAction | ContextSubMenu)[], onHide: () => void): IContextMenuItem[] { + const actionRunner = delegate.actionRunner || new ActionRunner(); + + return entries.map(entry => this.createMenuItem(delegate, entry, actionRunner, onHide)); + } + + private createMenuItem(delegate: IContextMenuDelegate, entry: IAction | ContextSubMenu, actionRunner: IActionRunner, onHide: () => void): IContextMenuItem { + + // Separator + if (entry instanceof Separator) { + return { type: 'separator' } as IContextMenuItem; + } + + // Submenu + if (entry instanceof ContextSubMenu) { + return { + label: unmnemonicLabel(entry.label), + submenu: this.createMenu(delegate, entry.entries, onHide) + } as IContextMenuItem; + } + + // Normal Menu Item + else { + const item: IContextMenuItem = { + label: unmnemonicLabel(entry.label), + checked: !!entry.checked || !!entry.radio, + type: !!entry.checked ? 'checkbox' : !!entry.radio ? 'radio' : void 0, + enabled: !!entry.enabled, + click: event => { + + // To preserve pre-electron-2.x behaviour, we first trigger + // the onHide callback and then the action. + // Fixes https://github.com/Microsoft/vscode/issues/45601 + onHide(); + + // Run action which will close the menu + this.runAction(actionRunner, entry, delegate, event); + } + }; + + const keybinding = !!delegate.getKeyBinding ? delegate.getKeyBinding(entry) : this.keybindingService.lookupKeybinding(entry.id); + if (keybinding) { + const electronAccelerator = keybinding.getElectronAccelerator(); + if (electronAccelerator) { + item.accelerator = electronAccelerator; + } else { + const label = keybinding.getLabel(); + if (label) { + item.label = `${item.label} [${label}]`; + } + } + } + + return item; + } + } + + private runAction(actionRunner: IActionRunner, actionToRun: IAction, delegate: IContextMenuDelegate, event: IContextMenuEvent): void { /* __GDPR__ "workbenchActionExecuted" : { "id" : { "classification": "SystemMetaData", "purpose": "FeatureInsight" }, diff --git a/src/vs/workbench/services/issue/electron-browser/workbenchIssueService.ts b/src/vs/workbench/services/issue/electron-browser/workbenchIssueService.ts index a3e9e3727bd..3ef280db960 100644 --- a/src/vs/workbench/services/issue/electron-browser/workbenchIssueService.ts +++ b/src/vs/workbench/services/issue/electron-browser/workbenchIssueService.ts @@ -5,7 +5,7 @@ 'use strict'; -import { IssueReporterStyles, IIssueService, IssueReporterData } from 'vs/platform/issue/common/issue'; +import { IssueReporterStyles, IIssueService, IssueReporterData, ProcessExplorerData } from 'vs/platform/issue/common/issue'; import { TPromise } from 'vs/base/common/winjs.base'; import { ITheme, IThemeService } from 'vs/platform/theme/common/themeService'; import { textLinkForeground, inputBackground, inputBorder, inputForeground, buttonBackground, buttonHoverBackground, buttonForeground, inputValidationErrorBorder, foreground, inputActiveOptionBorder, scrollbarSliderActiveBackground, scrollbarSliderBackground, scrollbarSliderHoverBackground, editorBackground, editorForeground, listHoverBackground, listHoverForeground, listHighlightForeground, textLinkActiveForeground } from 'vs/platform/theme/common/colorRegistry'; @@ -14,6 +14,7 @@ import { IExtensionManagementService, IExtensionEnablementService, LocalExtensio import { webFrame } from 'electron'; import { assign } from 'vs/base/common/objects'; import { IWorkbenchIssueService } from 'vs/workbench/services/issue/common/issue'; +import { IWindowService } from 'vs/platform/windows/common/windows'; export class WorkbenchIssueService implements IWorkbenchIssueService { _serviceBrand: any; @@ -22,7 +23,8 @@ export class WorkbenchIssueService implements IWorkbenchIssueService { @IIssueService private issueService: IIssueService, @IThemeService private themeService: IThemeService, @IExtensionManagementService private extensionManagementService: IExtensionManagementService, - @IExtensionEnablementService private extensionEnablementService: IExtensionEnablementService + @IExtensionEnablementService private extensionEnablementService: IExtensionEnablementService, + @IWindowService private windowService: IWindowService ) { } @@ -44,7 +46,8 @@ export class WorkbenchIssueService implements IWorkbenchIssueService { openProcessExplorer(): TPromise<void> { const theme = this.themeService.getTheme(); - const data = { + const data: ProcessExplorerData = { + pid: this.windowService.getConfiguration().mainPid, zoomLevel: webFrame.getZoomLevel(), styles: { backgroundColor: theme.getColor(editorBackground) && theme.getColor(editorBackground).toString(), From 561f8d6b339509faaaca1c06a86223861de44695 Mon Sep 17 00:00:00 2001 From: Johannes Rieken <johannes.rieken@gmail.com> Date: Fri, 24 Aug 2018 10:07:48 +0200 Subject: [PATCH 1186/1276] add `adjustWhitespace`-flag to snippet controller, #57093 --- .../contrib/snippet/snippetController2.ts | 34 +++++++++-------- .../editor/contrib/snippet/snippetSession.ts | 38 ++++++++++--------- .../snippet/test/snippetSession.test.ts | 20 +++++++--- 3 files changed, 53 insertions(+), 39 deletions(-) diff --git a/src/vs/editor/contrib/snippet/snippetController2.ts b/src/vs/editor/contrib/snippet/snippetController2.ts index 9a3a443b47a..03e9a581b1a 100644 --- a/src/vs/editor/contrib/snippet/snippetController2.ts +++ b/src/vs/editor/contrib/snippet/snippetController2.ts @@ -5,22 +5,22 @@ 'use strict'; -import { RawContextKey, IContextKey, IContextKeyService, ContextKeyExpr } from 'vs/platform/contextkey/common/contextkey'; -import { registerEditorContribution, EditorCommand, registerEditorCommand } from 'vs/editor/browser/editorExtensions'; -import { dispose, IDisposable } from 'vs/base/common/lifecycle'; -import { SnippetSession } from './snippetSession'; -import { EditorContextKeys } from 'vs/editor/common/editorContextKeys'; import { KeyCode, KeyMod } from 'vs/base/common/keyCodes'; -import { showSimpleSuggestions } from 'vs/editor/contrib/suggest/suggest'; -import { ISuggestion } from 'vs/editor/common/modes'; -import { Selection } from 'vs/editor/common/core/selection'; -import { Range } from 'vs/editor/common/core/range'; -import { Choice } from 'vs/editor/contrib/snippet/snippetParser'; +import { dispose, IDisposable } from 'vs/base/common/lifecycle'; import { repeat } from 'vs/base/common/strings'; import { ICodeEditor } from 'vs/editor/browser/editorBrowser'; -import { KeybindingWeight } from 'vs/platform/keybinding/common/keybindingsRegistry'; +import { EditorCommand, registerEditorCommand, registerEditorContribution } from 'vs/editor/browser/editorExtensions'; +import { Range } from 'vs/editor/common/core/range'; +import { Selection } from 'vs/editor/common/core/selection'; import { IEditorContribution } from 'vs/editor/common/editorCommon'; +import { EditorContextKeys } from 'vs/editor/common/editorContextKeys'; +import { ISuggestion } from 'vs/editor/common/modes'; +import { Choice } from 'vs/editor/contrib/snippet/snippetParser'; +import { showSimpleSuggestions } from 'vs/editor/contrib/suggest/suggest'; +import { ContextKeyExpr, IContextKey, IContextKeyService, RawContextKey } from 'vs/platform/contextkey/common/contextkey'; +import { KeybindingWeight } from 'vs/platform/keybinding/common/keybindingsRegistry'; import { ILogService } from 'vs/platform/log/common/log'; +import { SnippetSession } from './snippetSession'; export class SnippetController2 implements IEditorContribution { @@ -65,13 +65,14 @@ export class SnippetController2 implements IEditorContribution { insert( template: string, overwriteBefore: number = 0, overwriteAfter: number = 0, - undoStopBefore: boolean = true, undoStopAfter: boolean = true + undoStopBefore: boolean = true, undoStopAfter: boolean = true, + adjustWhitespace: boolean = true, ): void { // this is here to find out more about the yet-not-understood // error that sometimes happens when we fail to inserted a nested // snippet try { - this._doInsert(template, overwriteBefore, overwriteAfter, undoStopBefore, undoStopAfter); + this._doInsert(template, overwriteBefore, overwriteAfter, undoStopBefore, undoStopAfter, adjustWhitespace); } catch (e) { this.cancel(); @@ -85,7 +86,8 @@ export class SnippetController2 implements IEditorContribution { private _doInsert( template: string, overwriteBefore: number = 0, overwriteAfter: number = 0, - undoStopBefore: boolean = true, undoStopAfter: boolean = true + undoStopBefore: boolean = true, undoStopAfter: boolean = true, + adjustWhitespace: boolean = true, ): void { // don't listen while inserting the snippet @@ -98,10 +100,10 @@ export class SnippetController2 implements IEditorContribution { if (!this._session) { this._modelVersionId = this._editor.getModel().getAlternativeVersionId(); - this._session = new SnippetSession(this._editor, template, overwriteBefore, overwriteAfter); + this._session = new SnippetSession(this._editor, template, overwriteBefore, overwriteAfter, adjustWhitespace); this._session.insert(); } else { - this._session.merge(template, overwriteBefore, overwriteAfter); + this._session.merge(template, overwriteBefore, overwriteAfter, adjustWhitespace); } if (undoStopAfter) { diff --git a/src/vs/editor/contrib/snippet/snippetSession.ts b/src/vs/editor/contrib/snippet/snippetSession.ts index ba550ec1d24..65d1fe67f3d 100644 --- a/src/vs/editor/contrib/snippet/snippetSession.ts +++ b/src/vs/editor/contrib/snippet/snippetSession.ts @@ -5,21 +5,21 @@ 'use strict'; -import 'vs/css!./snippetSession'; -import { getLeadingWhitespace } from 'vs/base/common/strings'; -import { ITextModel, TrackedRangeStickiness, IIdentifiedSingleEditOperation } from 'vs/editor/common/model'; -import { EditOperation } from 'vs/editor/common/core/editOperation'; -import { TextmateSnippet, Placeholder, Choice, Text, SnippetParser } from './snippetParser'; -import { Selection } from 'vs/editor/common/core/selection'; -import { Range } from 'vs/editor/common/core/range'; -import { IPosition } from 'vs/editor/common/core/position'; import { groupBy } from 'vs/base/common/arrays'; import { dispose } from 'vs/base/common/lifecycle'; -import { SelectionBasedVariableResolver, CompositeSnippetVariableResolver, ModelBasedVariableResolver, ClipboardBasedVariableResolver, TimeBasedVariableResolver } from './snippetVariables'; -import { ModelDecorationOptions } from 'vs/editor/common/model/textModel'; +import { getLeadingWhitespace } from 'vs/base/common/strings'; +import 'vs/css!./snippetSession'; import { ICodeEditor } from 'vs/editor/browser/editorBrowser'; +import { EditOperation } from 'vs/editor/common/core/editOperation'; +import { IPosition } from 'vs/editor/common/core/position'; +import { Range } from 'vs/editor/common/core/range'; +import { Selection } from 'vs/editor/common/core/selection'; +import { IIdentifiedSingleEditOperation, ITextModel, TrackedRangeStickiness } from 'vs/editor/common/model'; +import { ModelDecorationOptions } from 'vs/editor/common/model/textModel'; import { IClipboardService } from 'vs/platform/clipboard/common/clipboardService'; import { optional } from 'vs/platform/instantiation/common/instantiation'; +import { Choice, Placeholder, SnippetParser, Text, TextmateSnippet } from './snippetParser'; +import { ClipboardBasedVariableResolver, CompositeSnippetVariableResolver, ModelBasedVariableResolver, SelectionBasedVariableResolver, TimeBasedVariableResolver } from './snippetVariables'; export class OneSnippet { @@ -271,7 +271,7 @@ export class OneSnippet { export class SnippetSession { - static adjustWhitespace2(model: ITextModel, position: IPosition, snippet: TextmateSnippet): void { + static adjustWhitespace(model: ITextModel, position: IPosition, snippet: TextmateSnippet): void { const line = model.getLineContent(position.lineNumber); const lineLeadingWhitespace = getLeadingWhitespace(line, 0, position.column - 1); @@ -317,7 +317,7 @@ export class SnippetSession { return selection; } - static createEditsAndSnippets(editor: ICodeEditor, template: string, overwriteBefore: number, overwriteAfter: number, enforceFinalTabstop: boolean): { edits: IIdentifiedSingleEditOperation[], snippets: OneSnippet[] } { + static createEditsAndSnippets(editor: ICodeEditor, template: string, overwriteBefore: number, overwriteAfter: number, enforceFinalTabstop: boolean, adjustWhitespace: boolean): { edits: IIdentifiedSingleEditOperation[], snippets: OneSnippet[] } { const model = editor.getModel(); const edits: IIdentifiedSingleEditOperation[] = []; @@ -365,7 +365,9 @@ export class SnippetSession { // adjust the template string to match the indentation and // whitespace rules of this insert location (can be different for each cursor) const start = snippetSelection.getStartPosition(); - SnippetSession.adjustWhitespace2(model, start, snippet); + if (adjustWhitespace) { + SnippetSession.adjustWhitespace(model, start, snippet); + } snippet.resolveVariables(new CompositeSnippetVariableResolver([ modelBasedVariableResolver, @@ -392,13 +394,15 @@ export class SnippetSession { private readonly _templateMerges: [number, number, string][] = []; private readonly _overwriteBefore: number; private readonly _overwriteAfter: number; + private readonly _adjustWhitespace: boolean; private _snippets: OneSnippet[] = []; - constructor(editor: ICodeEditor, template: string, overwriteBefore: number = 0, overwriteAfter: number = 0) { + constructor(editor: ICodeEditor, template: string, overwriteBefore: number = 0, overwriteAfter: number = 0, adjustWhitespace: boolean = true) { this._editor = editor; this._template = template; this._overwriteBefore = overwriteBefore; this._overwriteAfter = overwriteAfter; + this._adjustWhitespace = adjustWhitespace; } dispose(): void { @@ -414,7 +418,7 @@ export class SnippetSession { const model = this._editor.getModel(); // make insert edit and start with first selections - const { edits, snippets } = SnippetSession.createEditsAndSnippets(this._editor, this._template, this._overwriteBefore, this._overwriteAfter, false); + const { edits, snippets } = SnippetSession.createEditsAndSnippets(this._editor, this._template, this._overwriteBefore, this._overwriteAfter, false, this._adjustWhitespace); this._snippets = snippets; const selections = model.pushEditOperations(this._editor.getSelections(), edits, undoEdits => { @@ -428,9 +432,9 @@ export class SnippetSession { this._editor.revealRange(selections[0]); } - merge(template: string, overwriteBefore: number = 0, overwriteAfter: number = 0): void { + merge(template: string, overwriteBefore: number = 0, overwriteAfter: number = 0, adjustWhitespace: boolean = true): void { this._templateMerges.push([this._snippets[0]._nestingLevel, this._snippets[0]._placeholderGroupsIdx, template]); - const { edits, snippets } = SnippetSession.createEditsAndSnippets(this._editor, template, overwriteBefore, overwriteAfter, true); + const { edits, snippets } = SnippetSession.createEditsAndSnippets(this._editor, template, overwriteBefore, overwriteAfter, true, adjustWhitespace); this._editor.setSelections(this._editor.getModel().pushEditOperations(this._editor.getSelections(), edits, undoEdits => { diff --git a/src/vs/editor/contrib/snippet/test/snippetSession.test.ts b/src/vs/editor/contrib/snippet/test/snippetSession.test.ts index 2787ad8e2a1..361e3d57009 100644 --- a/src/vs/editor/contrib/snippet/test/snippetSession.test.ts +++ b/src/vs/editor/contrib/snippet/test/snippetSession.test.ts @@ -5,14 +5,14 @@ 'use strict'; import * as assert from 'assert'; -import { Selection } from 'vs/editor/common/core/selection'; -import { Range } from 'vs/editor/common/core/range'; +import { ICodeEditor } from 'vs/editor/browser/editorBrowser'; import { IPosition, Position } from 'vs/editor/common/core/position'; +import { Range } from 'vs/editor/common/core/range'; +import { Selection } from 'vs/editor/common/core/selection'; +import { TextModel } from 'vs/editor/common/model/textModel'; +import { SnippetParser } from 'vs/editor/contrib/snippet/snippetParser'; import { SnippetSession } from 'vs/editor/contrib/snippet/snippetSession'; import { createTestCodeEditor } from 'vs/editor/test/browser/testCodeEditor'; -import { TextModel } from 'vs/editor/common/model/textModel'; -import { ICodeEditor } from 'vs/editor/browser/editorBrowser'; -import { SnippetParser } from 'vs/editor/contrib/snippet/snippetParser'; suite('SnippetSession', function () { @@ -43,7 +43,7 @@ suite('SnippetSession', function () { function assertNormalized(position: IPosition, input: string, expected: string): void { const snippet = new SnippetParser().parse(input); - SnippetSession.adjustWhitespace2(model, position, snippet); + SnippetSession.adjustWhitespace(model, position, snippet); assert.equal(snippet.toTextmateString(), expected); } @@ -125,6 +125,14 @@ suite('SnippetSession', function () { assertSelections(editor, new Selection(3, 1, 3, 1), new Selection(6, 5, 6, 5)); }); + test('snippets, newline NO whitespace adjust', () => { + + editor.setSelection(new Selection(2, 5, 2, 5)); + const session = new SnippetSession(editor, 'abc\n foo\n bar\n$0', 0, 0, false); + session.insert(); + assert.equal(editor.getModel().getValue(), 'function foo() {\n abc\n foo\n bar\nconsole.log(a);\n}'); + }); + test('snippets, selections -> next/prev', () => { const session = new SnippetSession(editor, 'f$1oo${2:bar}foo$0'); From 20b2782ffa7ef868e04f93aea42d3c8462821702 Mon Sep 17 00:00:00 2001 From: isidor <inikolic@microsoft.com> Date: Fri, 24 Aug 2018 10:06:53 +0200 Subject: [PATCH 1187/1276] line height for breakpoints view fixes #57131 --- src/vs/workbench/parts/debug/browser/media/debugViewlet.css | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/vs/workbench/parts/debug/browser/media/debugViewlet.css b/src/vs/workbench/parts/debug/browser/media/debugViewlet.css index 09cf7033e9a..48ab4d9099a 100644 --- a/src/vs/workbench/parts/debug/browser/media/debugViewlet.css +++ b/src/vs/workbench/parts/debug/browser/media/debugViewlet.css @@ -109,6 +109,7 @@ font-size: 0.9em; padding: 0 3px; margin-left: 0.8em; + line-height: 20px; } .debug-viewlet .monaco-tree .monaco-tree-row.selected .line-number, @@ -350,6 +351,10 @@ /* Breakpoints */ +.debug-viewlet .monaco-list-row { + line-height: 22px; +} + .debug-viewlet .debug-breakpoints .monaco-list-row .breakpoint { padding-left: 2px; } From 35b36b75d01a952a5447f47c8b2aaa5191e7d606 Mon Sep 17 00:00:00 2001 From: Sandeep Somavarapu <sasomava@microsoft.com> Date: Fri, 24 Aug 2018 10:25:00 +0200 Subject: [PATCH 1188/1276] #56649 Add logs to diagnose --- .../test/electron-browser/configurationService.test.ts | 2 +- 1 file changed, 1 insertion(+), 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 64e9352f99a..078f5e4fb0d 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 @@ -247,7 +247,7 @@ suite('WorkspaceContextService - Workspace', () => { const addedFolders = [{ uri: URI.file(path.join(workspaceDir, 'd')) }, { uri: URI.file(path.join(workspaceDir, 'c')) }]; return testObject.addFolders(addedFolders) .then(() => { - assert.ok(target.calledOnce); + assert.equal(target.callCount, 1, `Should be called only once but called ${target.callCount} times`); const actual = <IWorkspaceFoldersChangeEvent>target.args[0][0]; assert.deepEqual(actual.added.map(r => r.uri.toString()), addedFolders.map(a => a.uri.toString())); assert.deepEqual(actual.removed, []); From 9d2f309e45941019ad12e8f740cfd008cdfb466f Mon Sep 17 00:00:00 2001 From: Johannes Rieken <johannes.rieken@gmail.com> Date: Fri, 24 Aug 2018 10:20:28 +0200 Subject: [PATCH 1189/1276] add `ISuggestion#noWhitespaceAdjust` to internal suggest api, #57093 --- src/vs/editor/common/modes.ts | 23 +++++------ .../contrib/suggest/suggestController.ts | 39 ++++++++++--------- 2 files changed, 32 insertions(+), 30 deletions(-) diff --git a/src/vs/editor/common/modes.ts b/src/vs/editor/common/modes.ts index 6a4abcffa36..e5078f5be8b 100644 --- a/src/vs/editor/common/modes.ts +++ b/src/vs/editor/common/modes.ts @@ -4,21 +4,21 @@ *--------------------------------------------------------------------------------------------*/ 'use strict'; +import { CancellationToken } from 'vs/base/common/cancellation'; +import { Color } from 'vs/base/common/color'; +import { Event } from 'vs/base/common/event'; import { IMarkdownString } from 'vs/base/common/htmlContent'; import { IDisposable } from 'vs/base/common/lifecycle'; -import URI from 'vs/base/common/uri'; -import { TokenizationResult, TokenizationResult2 } from 'vs/editor/common/core/token'; -import LanguageFeatureRegistry from 'vs/editor/common/modes/languageFeatureRegistry'; -import { CancellationToken } from 'vs/base/common/cancellation'; -import { Position } from 'vs/editor/common/core/position'; -import { Range, IRange } from 'vs/editor/common/core/range'; -import { Event } from 'vs/base/common/event'; -import { TokenizationRegistryImpl } from 'vs/editor/common/modes/tokenizationRegistry'; -import { Color } from 'vs/base/common/color'; -import { IMarkerData } from 'vs/platform/markers/common/markers'; -import * as model from 'vs/editor/common/model'; import { isObject } from 'vs/base/common/types'; +import URI from 'vs/base/common/uri'; +import { Position } from 'vs/editor/common/core/position'; +import { IRange, Range } from 'vs/editor/common/core/range'; import { Selection } from 'vs/editor/common/core/selection'; +import { TokenizationResult, TokenizationResult2 } from 'vs/editor/common/core/token'; +import * as model from 'vs/editor/common/model'; +import LanguageFeatureRegistry from 'vs/editor/common/modes/languageFeatureRegistry'; +import { TokenizationRegistryImpl } from 'vs/editor/common/modes/tokenizationRegistry'; +import { IMarkerData } from 'vs/platform/markers/common/markers'; /** * Open ended enum at runtime @@ -301,6 +301,7 @@ export interface ISuggestion { additionalTextEdits?: model.ISingleEditOperation[]; command?: Command; snippetType?: SnippetType; + noWhitespaceAdjust?: boolean; } /** diff --git a/src/vs/editor/contrib/suggest/suggestController.ts b/src/vs/editor/contrib/suggest/suggestController.ts index edb083518f5..8fbac1b8084 100644 --- a/src/vs/editor/contrib/suggest/suggestController.ts +++ b/src/vs/editor/contrib/suggest/suggestController.ts @@ -4,30 +4,30 @@ *--------------------------------------------------------------------------------------------*/ 'use strict'; -import * as nls from 'vs/nls'; -import { KeyCode, KeyMod } from 'vs/base/common/keyCodes'; -import { onUnexpectedError } from 'vs/base/common/errors'; -import { isFalsyOrEmpty } from 'vs/base/common/arrays'; -import { IDisposable, dispose } from 'vs/base/common/lifecycle'; -import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; -import { ContextKeyExpr, IContextKeyService } from 'vs/platform/contextkey/common/contextkey'; -import { ICommandService } from 'vs/platform/commands/common/commands'; -import { IEditorContribution, ScrollType } from 'vs/editor/common/editorCommon'; -import { EditorContextKeys } from 'vs/editor/common/editorContextKeys'; -import { registerEditorAction, registerEditorContribution, ServicesAccessor, EditorAction, EditorCommand, registerEditorCommand } from 'vs/editor/browser/editorExtensions'; -import { ICodeEditor } from 'vs/editor/browser/editorBrowser'; import { alert } from 'vs/base/browser/ui/aria/aria'; +import { isFalsyOrEmpty } from 'vs/base/common/arrays'; +import { onUnexpectedError } from 'vs/base/common/errors'; +import { KeyCode, KeyMod } from 'vs/base/common/keyCodes'; +import { dispose, IDisposable } from 'vs/base/common/lifecycle'; +import { ICodeEditor } from 'vs/editor/browser/editorBrowser'; +import { EditorAction, EditorCommand, registerEditorAction, registerEditorCommand, registerEditorContribution, ServicesAccessor } from 'vs/editor/browser/editorExtensions'; import { EditOperation } from 'vs/editor/common/core/editOperation'; import { Range } from 'vs/editor/common/core/range'; +import { IEditorContribution, ScrollType } from 'vs/editor/common/editorCommon'; +import { EditorContextKeys } from 'vs/editor/common/editorContextKeys'; import { ISuggestSupport } from 'vs/editor/common/modes'; -import { SnippetParser } from 'vs/editor/contrib/snippet/snippetParser'; import { SnippetController2 } from 'vs/editor/contrib/snippet/snippetController2'; -import { Context as SuggestContext } from './suggest'; -import { SuggestModel, State } from './suggestModel'; -import { ICompletionItem } from './completionModel'; -import { SuggestWidget, ISelectedSuggestion } from './suggestWidget'; -import { KeybindingWeight } from 'vs/platform/keybinding/common/keybindingsRegistry'; +import { SnippetParser } from 'vs/editor/contrib/snippet/snippetParser'; import { SuggestMemories } from 'vs/editor/contrib/suggest/suggestMemory'; +import * as nls from 'vs/nls'; +import { ICommandService } from 'vs/platform/commands/common/commands'; +import { ContextKeyExpr, IContextKeyService } from 'vs/platform/contextkey/common/contextkey'; +import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; +import { KeybindingWeight } from 'vs/platform/keybinding/common/keybindingsRegistry'; +import { ICompletionItem } from './completionModel'; +import { Context as SuggestContext } from './suggest'; +import { State, SuggestModel } from './suggestModel'; +import { ISelectedSuggestion, SuggestWidget } from './suggestWidget'; class AcceptOnCharacterOracle { @@ -223,7 +223,8 @@ export class SuggestController implements IEditorContribution { insertText, suggestion.overwriteBefore + columnDelta, suggestion.overwriteAfter, - false, false + false, false, + !suggestion.noWhitespaceAdjust ); this._editor.pushUndoStop(); From b7483ab8aef5673623da43e274ffff7c3a35b898 Mon Sep 17 00:00:00 2001 From: Matt Bierner <matb@microsoft.com> Date: Fri, 24 Aug 2018 10:30:02 +0200 Subject: [PATCH 1190/1276] Update markdown grammar --- .../syntaxes/markdown.tmLanguage.json | 28 ++++++++++- .../test/colorize-results/test_md.json | 46 ++++++++++++++++++- 2 files changed, 71 insertions(+), 3 deletions(-) diff --git a/extensions/markdown-basics/syntaxes/markdown.tmLanguage.json b/extensions/markdown-basics/syntaxes/markdown.tmLanguage.json index 216edc2b74c..ce6b2ab2605 100644 --- a/extensions/markdown-basics/syntaxes/markdown.tmLanguage.json +++ b/extensions/markdown-basics/syntaxes/markdown.tmLanguage.json @@ -4,7 +4,7 @@ "If you want to provide a fix or improvement, please create a pull request against the original repository.", "Once accepted there, we are happy to receive an update request." ], - "version": "https://github.com/microsoft/vscode-markdown-tm-grammar/commit/3445afdd642f67052a21c0f86bf76b3deb45fd26", + "version": "https://github.com/microsoft/vscode-markdown-tm-grammar/commit/2544443db4402b3271b1b99bd9a1efb2c757c3d5", "name": "Markdown", "scopeName": "text.html.markdown", "patterns": [ @@ -1948,7 +1948,7 @@ "name": "punctuation.definition.string.end.markdown" } }, - "match": "(?x)\n \\s* # Leading whitespace\n (\\[)(.+?)(\\])(:) # Reference name\n [ \\t]* # Optional whitespace\n (<?)(\\S+?)(>?) # The url\n [ \\t]* # Optional whitespace\n (?:\n ((\\().+?(\\))) # Match title in quotes…\n | ((\").+?(\")) # or in parens.\n )? # Title is optional\n \\s* # Optional whitespace\n $\n", + "match": "(?x)\n \\s* # Leading whitespace\n (\\[)([\\w ]+?)(\\])(:) # Reference name\n [ \\t]* # Optional whitespace\n (<?)(\\S+?)(>?) # The url\n [ \\t]* # Optional whitespace\n (?:\n ((\\().+?(\\))) # Match title in quotes…\n | ((\").+?(\")) # or in parens.\n )? # Title is optional\n \\s* # Optional whitespace\n $\n", "name": "meta.link.reference.def.markdown" }, "list_paragraph": { @@ -2085,6 +2085,9 @@ }, { "include": "#link-ref-literal" + }, + { + "include": "#link-ref-shortcut" } ], "repository": { @@ -2151,6 +2154,9 @@ }, { "include": "#link-ref" + }, + { + "include": "#link-ref-shortcut" } ] }, @@ -2290,6 +2296,9 @@ }, { "include": "#link-ref" + }, + { + "include": "#link-ref-shortcut" } ] }, @@ -2416,6 +2425,21 @@ "match": "(\\[)((?<square>[^\\[\\]\\\\]|\\\\.|\\[\\g<square>*+\\])*+)(\\])[ ]?(\\[)(\\])", "name": "meta.link.reference.literal.markdown" }, + "link-ref-shortcut": { + "captures": { + "1": { + "name": "punctuation.definition.string.begin.markdown" + }, + "2": { + "name": "string.other.link.title.markdown" + }, + "4": { + "name": "punctuation.definition.string.end.markdown" + } + }, + "match": "(\\[)(\\S+?)(\\])", + "name": "meta.link.reference.markdown" + }, "raw": { "captures": { "1": { diff --git a/extensions/markdown-basics/test/colorize-results/test_md.json b/extensions/markdown-basics/test/colorize-results/test_md.json index 143c79aefd7..faa18bc663b 100644 --- a/extensions/markdown-basics/test/colorize-results/test_md.json +++ b/extensions/markdown-basics/test/colorize-results/test_md.json @@ -2486,7 +2486,51 @@ } }, { - "c": "*[ABBR]: Markdown plus abbreviations (produces an ", + "c": "*", + "t": "text.html.markdown meta.paragraph.markdown", + "r": { + "dark_plus": "default: #D4D4D4", + "light_plus": "default: #000000", + "dark_vs": "default: #D4D4D4", + "light_vs": "default: #000000", + "hc_black": "default: #FFFFFF" + } + }, + { + "c": "[", + "t": "text.html.markdown meta.paragraph.markdown meta.link.reference.markdown punctuation.definition.string.begin.markdown", + "r": { + "dark_plus": "default: #D4D4D4", + "light_plus": "default: #000000", + "dark_vs": "default: #D4D4D4", + "light_vs": "default: #000000", + "hc_black": "default: #FFFFFF" + } + }, + { + "c": "ABBR", + "t": "text.html.markdown meta.paragraph.markdown meta.link.reference.markdown string.other.link.title.markdown", + "r": { + "dark_plus": "string: #CE9178", + "light_plus": "string: #A31515", + "dark_vs": "string: #CE9178", + "light_vs": "string: #A31515", + "hc_black": "string: #CE9178" + } + }, + { + "c": "]", + "t": "text.html.markdown meta.paragraph.markdown meta.link.reference.markdown", + "r": { + "dark_plus": "default: #D4D4D4", + "light_plus": "default: #000000", + "dark_vs": "default: #D4D4D4", + "light_vs": "default: #000000", + "hc_black": "default: #FFFFFF" + } + }, + { + "c": ": Markdown plus abbreviations (produces an ", "t": "text.html.markdown meta.paragraph.markdown", "r": { "dark_plus": "default: #D4D4D4", From 7a5dec3842aa12a2184c041aa64c1ee06ecb5772 Mon Sep 17 00:00:00 2001 From: Sandeep Somavarapu <sasomava@microsoft.com> Date: Fri, 24 Aug 2018 10:32:26 +0200 Subject: [PATCH 1191/1276] Fix #55480 --- .../parts/output/electron-browser/outputServices.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/vs/workbench/parts/output/electron-browser/outputServices.ts b/src/vs/workbench/parts/output/electron-browser/outputServices.ts index 32fc13e7979..d4682f95819 100644 --- a/src/vs/workbench/parts/output/electron-browser/outputServices.ts +++ b/src/vs/workbench/parts/output/electron-browser/outputServices.ts @@ -288,7 +288,7 @@ class OutputChannelBackedByFile extends AbstractFileOutputChannel implements Out } private loadFile(): TPromise<string> { - return this.fileService.resolveContent(this.file, { position: this.startOffset }) + return this.fileService.resolveContent(this.file, { position: this.startOffset, encoding: 'utf8' }) .then(content => this.appendedMessage ? content.value + this.appendedMessage : content.value); } @@ -374,7 +374,7 @@ class FileOutputChannel extends AbstractFileOutputChannel implements OutputChann } loadModel(): TPromise<ITextModel> { - return this.fileService.resolveContent(this.file, { position: this.startOffset }) + return this.fileService.resolveContent(this.file, { position: this.startOffset, encoding: 'utf8' }) .then(content => { this.endOffset = this.startOffset + Buffer.from(content.value).byteLength; return this.createModel(content.value); @@ -387,7 +387,7 @@ class FileOutputChannel extends AbstractFileOutputChannel implements OutputChann protected updateModel(): void { if (this.model) { - this.fileService.resolveContent(this.file, { position: this.endOffset }) + this.fileService.resolveContent(this.file, { position: this.endOffset, encoding: 'utf8' }) .then(content => { if (content.value) { this.endOffset = this.endOffset + Buffer.from(content.value).byteLength; From 3a86741def0eaf72f88aec41c7fdaf8282298c9b Mon Sep 17 00:00:00 2001 From: isidor <inikolic@microsoft.com> Date: Fri, 24 Aug 2018 10:43:16 +0200 Subject: [PATCH 1192/1276] fix title part getting the workspace label fixes #57130 --- src/vs/workbench/browser/parts/titlebar/titlebarPart.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vs/workbench/browser/parts/titlebar/titlebarPart.ts b/src/vs/workbench/browser/parts/titlebar/titlebarPart.ts index dffc7b7dcdf..19b4476fc35 100644 --- a/src/vs/workbench/browser/parts/titlebar/titlebarPart.ts +++ b/src/vs/workbench/browser/parts/titlebar/titlebarPart.ts @@ -243,7 +243,7 @@ export class TitlebarPart extends Part implements ITitleService { const activeEditorShort = editor ? editor.getTitle(Verbosity.SHORT) : ''; const activeEditorMedium = editor ? editor.getTitle(Verbosity.MEDIUM) : activeEditorShort; const activeEditorLong = editor ? editor.getTitle(Verbosity.LONG) : activeEditorMedium; - const rootName = root ? this.labelService.getWorkspaceLabel(root) : ''; + const rootName = root ? this.labelService.getWorkspaceLabel(workspace) : ''; const rootPath = root ? this.labelService.getUriLabel(root) : ''; const folderName = folder ? folder.name : ''; const folderPath = folder ? this.labelService.getUriLabel(folder.uri) : ''; From cb1f945d6445e39b62bfc85f7f6c39712e614e53 Mon Sep 17 00:00:00 2001 From: isidor <inikolic@microsoft.com> Date: Fri, 24 Aug 2018 10:44:40 +0200 Subject: [PATCH 1193/1276] title: no need for null check #57130 --- src/vs/workbench/browser/parts/titlebar/titlebarPart.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vs/workbench/browser/parts/titlebar/titlebarPart.ts b/src/vs/workbench/browser/parts/titlebar/titlebarPart.ts index 19b4476fc35..a81ca96efd8 100644 --- a/src/vs/workbench/browser/parts/titlebar/titlebarPart.ts +++ b/src/vs/workbench/browser/parts/titlebar/titlebarPart.ts @@ -243,7 +243,7 @@ export class TitlebarPart extends Part implements ITitleService { const activeEditorShort = editor ? editor.getTitle(Verbosity.SHORT) : ''; const activeEditorMedium = editor ? editor.getTitle(Verbosity.MEDIUM) : activeEditorShort; const activeEditorLong = editor ? editor.getTitle(Verbosity.LONG) : activeEditorMedium; - const rootName = root ? this.labelService.getWorkspaceLabel(workspace) : ''; + const rootName = this.labelService.getWorkspaceLabel(workspace); const rootPath = root ? this.labelService.getUriLabel(root) : ''; const folderName = folder ? folder.name : ''; const folderPath = folder ? this.labelService.getUriLabel(folder.uri) : ''; From 8af86c73e62a3ec456e95eb512acd9ccd5fd17fa Mon Sep 17 00:00:00 2001 From: Matt Bierner <matb@microsoft.com> Date: Fri, 24 Aug 2018 10:44:17 +0200 Subject: [PATCH 1194/1276] Update markdown grammar --- .../markdown-basics/syntaxes/markdown.tmLanguage.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/extensions/markdown-basics/syntaxes/markdown.tmLanguage.json b/extensions/markdown-basics/syntaxes/markdown.tmLanguage.json index ce6b2ab2605..a81c3615bb5 100644 --- a/extensions/markdown-basics/syntaxes/markdown.tmLanguage.json +++ b/extensions/markdown-basics/syntaxes/markdown.tmLanguage.json @@ -4,7 +4,7 @@ "If you want to provide a fix or improvement, please create a pull request against the original repository.", "Once accepted there, we are happy to receive an update request." ], - "version": "https://github.com/microsoft/vscode-markdown-tm-grammar/commit/2544443db4402b3271b1b99bd9a1efb2c757c3d5", + "version": "https://github.com/microsoft/vscode-markdown-tm-grammar/commit/5f5b3d7eaced763432867f8eb6d3d768f6cd2acc", "name": "Markdown", "scopeName": "text.html.markdown", "patterns": [ @@ -1970,7 +1970,7 @@ "lists": { "patterns": [ { - "begin": "(^|\\G)([ ]{0,3})([*+-])([ ]{1,3}|\\t)", + "begin": "(^|\\G)([ ]{0,3})([*+-])([ \\t])", "beginCaptures": { "3": { "name": "punctuation.definition.list.begin.markdown" @@ -1989,7 +1989,7 @@ "while": "((^|\\G)([ ]{2,4}|\\t))|(^[ \\t]*$)" }, { - "begin": "(^|\\G)([ ]{0,3})([0-9]+\\.)([ ]{1,3}|\\t)", + "begin": "(^|\\G)([ ]{0,3})([0-9]+\\.)([ \\t])", "beginCaptures": { "3": { "name": "punctuation.definition.list.begin.markdown" From cea2cf05b01805e51f8cf6d7d620eec4ea54aa73 Mon Sep 17 00:00:00 2001 From: Alex Dima <alexdima@microsoft.com> Date: Fri, 24 Aug 2018 10:57:43 +0200 Subject: [PATCH 1195/1276] Simplify binary protocol writing --- .../services/extensions/node/rpcProtocol.ts | 297 +++++++++--------- 1 file changed, 150 insertions(+), 147 deletions(-) diff --git a/src/vs/workbench/services/extensions/node/rpcProtocol.ts b/src/vs/workbench/services/extensions/node/rpcProtocol.ts index e648dbbedec..63075595b5c 100644 --- a/src/vs/workbench/services/extensions/node/rpcProtocol.ts +++ b/src/vs/workbench/services/extensions/node/rpcProtocol.ts @@ -320,8 +320,115 @@ export class RPCProtocol implements IRPCProtocol { } } +class MessageBuffer { + + public static alloc(type: MessageType, req: number, messageSize: number): MessageBuffer { + let buff = Buffer.allocUnsafe(messageSize + 1 /* type */ + 4 /* req */); + let offset = 0; + buff.writeUInt8(type, offset, true); offset += 1; + buff.writeUInt32LE(req, offset, true); offset += 4; + return new MessageBuffer(buff, offset); + } + + private _buff: Buffer; + private _offset: number; + + public get buffer(): Buffer { + return this._buff; + } + + private constructor(buff: Buffer, offset: number) { + this._buff = buff; + this._offset = offset; + } + + public static sizeShortString(str: string, strByteLength: number): number { + return 1 /* string length */ + strByteLength /* actual string */; + } + + public writeShortString(str: string, strByteLength: number): void { + this._buff.writeUInt8(strByteLength, this._offset, true); this._offset += 1; + this._buff.write(str, this._offset, strByteLength, 'utf8'); this._offset += strByteLength; + } + + public readShortString(): string { + const strLength = this._buff.readUInt8(this._offset, true); this._offset += 1; + const str = this._buff.toString('utf8', this._offset, this._offset + strLength); this._offset += strLength; + return str; + } + + public static sizeLongString(str: string, strByteLength: number): number { + return 4 /* string length */ + strByteLength /* actual string */; + } + + public writeLongString(str: string, strByteLength: number): void { + this._buff.writeUInt32LE(strByteLength, this._offset, true); this._offset += 4; + this._buff.write(str, this._offset, strByteLength, 'utf8'); this._offset += strByteLength; + } + + public readLongString(): string { + const strLength = this._buff.readUInt32LE(this._offset, true); this._offset += 4; + const str = this._buff.toString('utf8', this._offset, this._offset + strLength); this._offset += strLength; + return str; + } + + public static sizeBuffer(buff: Buffer, buffByteLength: number): number { + return 4 /* buffer length */ + buffByteLength /* actual buffer */; + } + + public writeBuffer(buff: Buffer, buffByteLength: number): void { + this._buff.writeUInt32LE(buffByteLength, this._offset, true); this._offset += 4; + buff.copy(this._buff, this._offset); this._offset += buffByteLength; + } + + public readBuffer(): Buffer { + const buffLength = this._buff.readUInt32LE(this._offset, true); this._offset += 4; + const buff = this._buff.slice(this._offset, this._offset + buffLength); this._offset += buffLength; + return buff; + } + + public static sizeMixedArray(arr: (string | Buffer)[], arrLengths: number[]): number { + let size = 0; + size += 1; // arr length + for (let i = 0, len = arr.length; i < len; i++) { + const el = arr[i]; + const elLength = arrLengths[i]; + size += 1; // arg type + if (typeof el === 'string') { + size += this.sizeLongString(el, elLength); + } else { + size += this.sizeBuffer(el, elLength); + } + } + return size; + } + + public writeMixedArray(arr: (string | Buffer)[], arrLengths: number[]): void { + this._buff.writeUInt8(arr.length, this._offset, true); this._offset += 1; + for (let i = 0, len = arr.length; i < len; i++) { + const el = arr[i]; + const elLength = arrLengths[i]; + if (typeof el === 'string') { + this._buff.writeUInt8(ArgType.ArgString, this._offset, true); this._offset += 1; + this.writeLongString(el, elLength); + } else { + this._buff.writeUInt8(ArgType.ArgBuffer, this._offset, true); this._offset += 1; + this.writeBuffer(el, elLength); + } + } + } +} + class MessageIO { - private static arrayContainsBuffer(arr: any[]): boolean { + public static deserializeMessageType(buff: Buffer, offset: number): MessageType { + return buff[offset]; + } + + public static deserializeReq(buff: Buffer, offset: number): number { + return buff.readUInt32LE(offset, true); + } + + private static _arrayContainsBuffer(arr: any[]): boolean { for (let i = 0, len = arr.length; i < len; i++) { if (Buffer.isBuffer(arr[i])) { return true; @@ -331,7 +438,7 @@ class MessageIO { } public static serializeRequest(req: number, rpcId: string, method: string, args: any[]): Buffer { - if (this.arrayContainsBuffer(args)) { + if (this._arrayContainsBuffer(args)) { let massagedArgs: (string | Buffer)[] = new Array(args.length); let argsLengths: number[] = new Array(args.length); for (let i = 0, len = args.length; i < len; i++) { @@ -341,7 +448,7 @@ class MessageIO { argsLengths[i] = arg.byteLength; } else { massagedArgs[i] = JSON.stringify(arg); - argsLengths[i] = Buffer.byteLength(massagedArgs[i]); + argsLengths[i] = Buffer.byteLength(massagedArgs[i], 'utf8'); } } return this._requestMixedArgs(req, rpcId, method, massagedArgs, argsLengths); @@ -349,42 +456,21 @@ class MessageIO { return this._requestJSONArgs(req, rpcId, method, JSON.stringify(args)); } - public static deserializeMessageType(buff: Buffer, offset: number): MessageType { - return buff[offset]; - } - - public static deserializeReq(buff: Buffer, offset: number): number { - return buff.readUInt32LE(offset, true); - } - private static _requestJSONArgs(req: number, rpcId: string, method: string, args: string): Buffer { - const rpcIdByteLength = Buffer.byteLength(rpcId); - const methodByteLength = Buffer.byteLength(method); - const argsByteLength = Buffer.byteLength(args); + const rpcIdByteLength = Buffer.byteLength(rpcId, 'utf8'); + const methodByteLength = Buffer.byteLength(method, 'utf8'); + const argsByteLength = Buffer.byteLength(args, 'utf8'); let len = 0; - len += 1; // msg type - len += 4; // req - len += 1; // rpcId length - len += rpcIdByteLength; - len += 1; // method length - len += methodByteLength; - len += 4; // arg length - len += argsByteLength; + len += MessageBuffer.sizeShortString(rpcId, rpcIdByteLength); + len += MessageBuffer.sizeShortString(method, methodByteLength); + len += MessageBuffer.sizeLongString(args, argsByteLength); - let result = Buffer.allocUnsafe(len); - let offset = 0; - - result.writeUInt8(MessageType.RequestJSONArgs, offset, true); offset += 1; - result.writeUInt32LE(req, offset, true); offset += 4; - result.writeUInt8(rpcIdByteLength, offset, true); offset += 1; - result.write(rpcId, offset, rpcIdByteLength, 'utf8'); offset += rpcIdByteLength; - result.writeUInt8(methodByteLength, offset, true); offset += 1; - result.write(method, offset, methodByteLength, 'utf8'); offset += methodByteLength; - result.writeUInt32LE(argsByteLength, offset, true); offset += 4; - result.write(args, offset, argsByteLength, 'utf8'); offset += argsByteLength; - - return result; + let result = MessageBuffer.alloc(MessageType.RequestJSONArgs, req, len); + result.writeShortString(rpcId, rpcIdByteLength); + result.writeShortString(method, methodByteLength); + result.writeLongString(args, argsByteLength); + return result.buffer; } public static deserializeRequestJSONArgs(buff: Buffer, offset: number): { rpcId: string; method: string; args: any[]; } { @@ -402,47 +488,19 @@ class MessageIO { } private static _requestMixedArgs(req: number, rpcId: string, method: string, args: (string | Buffer)[], argsLengths: number[]): Buffer { - const rpcIdByteLength = Buffer.byteLength(rpcId); - const methodByteLength = Buffer.byteLength(method); + const rpcIdByteLength = Buffer.byteLength(rpcId, 'utf8'); + const methodByteLength = Buffer.byteLength(method, 'utf8'); let len = 0; - len += 1; // msg type - len += 4; // req - len += 1; // rpcId length - len += rpcIdByteLength; - len += 1; // method length - len += methodByteLength; - len += 1; // arg count - for (let i = 0, argsLen = args.length; i < argsLen; i++) { - len += 1; // arg type - len += 4; // buffer length - len += argsLengths[i]; - } + len += MessageBuffer.sizeShortString(rpcId, rpcIdByteLength); + len += MessageBuffer.sizeShortString(method, methodByteLength); + len += MessageBuffer.sizeMixedArray(args, argsLengths); - let result = Buffer.allocUnsafe(len); - let offset = 0; - - result.writeUInt8(MessageType.RequestMixedArgs, offset, true); offset += 1; - result.writeUInt32LE(req, offset, true); offset += 4; - result.writeUInt8(rpcIdByteLength, offset, true); offset += 1; - result.write(rpcId, offset, rpcIdByteLength, 'utf8'); offset += rpcIdByteLength; - result.writeUInt8(methodByteLength, offset, true); offset += 1; - result.write(method, offset, methodByteLength, 'utf8'); offset += methodByteLength; - result.writeUInt8(args.length, offset, true); offset += 1; - for (let i = 0, argsLen = args.length; i < argsLen; i++) { - const arg = args[i]; - if (typeof arg === 'string') { - result.writeUInt8(ArgType.ArgString, offset, true); offset += 1; - result.writeUInt32LE(argsLengths[i], offset, true); offset += 4; - result.write(arg, offset, argsLengths[i], 'utf8'); offset += argsLengths[i]; - } else { - result.writeUInt8(ArgType.ArgBuffer, offset, true); offset += 1; - result.writeUInt32LE(argsLengths[i], offset, true); offset += 4; - arg.copy(result, offset); offset += argsLengths[i]; - } - } - - return result; + let result = MessageBuffer.alloc(MessageType.RequestMixedArgs, req, len); + result.writeShortString(rpcId, rpcIdByteLength); + result.writeShortString(method, methodByteLength); + result.writeMixedArray(args, argsLengths); + return result.buffer; } public static deserializeRequestMixedArgs(buff: Buffer, offset: number): { rpcId: string; method: string; args: any[]; } { @@ -469,17 +527,7 @@ class MessageIO { } public static serializeCancel(req: number): Buffer { - let len = 0; - len += 1; // msg type - len += 4; // req - - let result = Buffer.allocUnsafe(len); - let offset = 0; - - result.writeUInt8(MessageType.Cancel, offset, true); offset += 1; - result.writeUInt32LE(req, offset, true); offset += 4; - - return result; + return MessageBuffer.alloc(MessageType.Cancel, req, 0).buffer; } public static serializeReplyOK(req: number, res: any): Buffer { @@ -493,35 +541,18 @@ class MessageIO { } private static _serializeReplyOKEmpty(req: number): Buffer { - let len = 0; - len += 1; // msg type - len += 4; // req - - let result = Buffer.allocUnsafe(len); - let offset = 0; - - result.writeUInt8(MessageType.ReplyOKEmpty, offset, true); offset += 1; - result.writeUInt32LE(req, offset, true); offset += 4; - - return result; + return MessageBuffer.alloc(MessageType.ReplyOKEmpty, req, 0).buffer; } private static _serializeReplyOKBuffer(req: number, res: Buffer): Buffer { + const resByteLength = res.byteLength; + let len = 0; - len += 1; // msg type - len += 4; // req - len += 4; // res length - len += res.byteLength; + len += MessageBuffer.sizeBuffer(res, resByteLength); - let result = Buffer.allocUnsafe(len); - let offset = 0; - - result.writeUInt8(MessageType.ReplyOKBuffer, offset, true); offset += 1; - result.writeUInt32LE(req, offset, true); offset += 4; - result.writeUInt32LE(res.byteLength, offset, true); offset += 4; - res.copy(result, offset); offset += res.byteLength; - - return result; + let result = MessageBuffer.alloc(MessageType.ReplyOKBuffer, req, len); + result.writeBuffer(res, resByteLength); + return result.buffer; } public static deserializeReplyOKBuffer(buff: Buffer, offset: number): Buffer { @@ -531,23 +562,14 @@ class MessageIO { } private static _serializeReplyOKJSON(req: number, res: string): Buffer { - const resByteLength = Buffer.byteLength(res); + const resByteLength = Buffer.byteLength(res, 'utf8'); let len = 0; - len += 1; // msg type - len += 4; // req - len += 4; // res length - len += resByteLength; + len += MessageBuffer.sizeLongString(res, resByteLength); - let result = Buffer.allocUnsafe(len); - let offset = 0; - - result.writeUInt8(MessageType.ReplyOKJSON, offset, true); offset += 1; - result.writeUInt32LE(req, offset, true); offset += 4; - result.writeUInt32LE(resByteLength, offset, true); offset += 4; - result.write(res, offset, resByteLength, 'utf8'); offset += resByteLength; - - return result; + let result = MessageBuffer.alloc(MessageType.ReplyOKJSON, req, len); + result.writeLongString(res, resByteLength); + return result.buffer; } public static deserializeReplyOKJSON(buff: Buffer, offset: number): any { @@ -565,23 +587,14 @@ class MessageIO { private static _serializeReplyErrEror(req: number, _err: Error): Buffer { const err = JSON.stringify(errors.transformErrorForSerialization(_err)); - const errByteLength = Buffer.byteLength(err); + const errByteLength = Buffer.byteLength(err, 'utf8'); let len = 0; - len += 1; // msg type - len += 4; // req - len += 4; // err length - len += errByteLength; + len += MessageBuffer.sizeLongString(err, errByteLength); - let result = Buffer.allocUnsafe(len); - let offset = 0; - - result.writeUInt8(MessageType.ReplyErrError, offset, true); offset += 1; - result.writeUInt32LE(req, offset, true); offset += 4; - result.writeUInt32LE(errByteLength, offset, true); offset += 4; - result.write(err, offset, errByteLength, 'utf8'); offset += errByteLength; - - return result; + let result = MessageBuffer.alloc(MessageType.ReplyErrError, req, len); + result.writeLongString(err, errByteLength); + return result.buffer; } public static deserializeReplyErrError(buff: Buffer, offset: number): Error { @@ -591,17 +604,7 @@ class MessageIO { } private static _serializeReplyErrEmpty(req: number): Buffer { - let len = 0; - len += 1; // msg type - len += 4; // req - - let result = Buffer.allocUnsafe(len); - let offset = 0; - - result.writeUInt8(MessageType.ReplyErrEmpty, offset, true); offset += 1; - result.writeUInt32LE(req, offset, true); offset += 4; - - return result; + return MessageBuffer.alloc(MessageType.ReplyErrEmpty, req, 0).buffer; } } From 7a6a466cab6afadf3f7abedddb1940af8a32e0e1 Mon Sep 17 00:00:00 2001 From: Johannes Rieken <johannes.rieken@gmail.com> Date: Fri, 24 Aug 2018 10:52:47 +0200 Subject: [PATCH 1196/1276] tweak all those copies of uriFromPath, #56691 --- src/bootstrap-amd.js | 3 +- .../electron-browser/issue/issueReporter.js | 2 +- .../processExplorer/processExplorer.js | 2 +- .../sharedProcess/sharedProcess.js | 8 +-- src/vs/loader.js | 54 +++++++++---------- .../electron-browser/bootstrap/index.js | 2 +- test/electron/renderer.js | 2 +- 7 files changed, 36 insertions(+), 37 deletions(-) diff --git a/src/bootstrap-amd.js b/src/bootstrap-amd.js index 752d996f6b9..c9a33c0d3d8 100644 --- a/src/bootstrap-amd.js +++ b/src/bootstrap-amd.js @@ -9,12 +9,11 @@ var loader = require('./vs/loader'); function uriFromPath(_path) { var pathName = path.resolve(_path).replace(/\\/g, '/'); - if (pathName.length > 0 && pathName.charAt(0) !== '/') { pathName = '/' + pathName; } - return encodeURI('file://' + pathName); + return encodeURI('file://' + pathName).replace(/#/g, '%23'); } function readFile(file) { diff --git a/src/vs/code/electron-browser/issue/issueReporter.js b/src/vs/code/electron-browser/issue/issueReporter.js index 949609d7682..62c33c672d3 100644 --- a/src/vs/code/electron-browser/issue/issueReporter.js +++ b/src/vs/code/electron-browser/issue/issueReporter.js @@ -30,7 +30,7 @@ function uriFromPath(_path) { pathName = '/' + pathName; } - return encodeURI('file://' + pathName); + return encodeURI('file://' + pathName).replace(/#/g, '%23'); } function readFile(file) { diff --git a/src/vs/code/electron-browser/processExplorer/processExplorer.js b/src/vs/code/electron-browser/processExplorer/processExplorer.js index 92ffa3e6c9e..d351b0ff848 100644 --- a/src/vs/code/electron-browser/processExplorer/processExplorer.js +++ b/src/vs/code/electron-browser/processExplorer/processExplorer.js @@ -30,7 +30,7 @@ function uriFromPath(_path) { pathName = '/' + pathName; } - return encodeURI('file://' + pathName); + return encodeURI('file://' + pathName).replace(/#/g, '%23'); } function readFile(file) { diff --git a/src/vs/code/electron-browser/sharedProcess/sharedProcess.js b/src/vs/code/electron-browser/sharedProcess/sharedProcess.js index d7dd08b4e3d..06fa3ea00a8 100644 --- a/src/vs/code/electron-browser/sharedProcess/sharedProcess.js +++ b/src/vs/code/electron-browser/sharedProcess/sharedProcess.js @@ -38,12 +38,12 @@ function uriFromPath(_path) { pathName = '/' + pathName; } - return encodeURI('file://' + pathName); + return encodeURI('file://' + pathName).replace(/#/g, '%23'); } function readFile(file) { - return new Promise(function(resolve, reject) { - fs.readFile(file, 'utf8', function(err, data) { + return new Promise(function (resolve, reject) { + fs.readFile(file, 'utf8', function (err, data) { if (err) { reject(err); return; @@ -102,7 +102,7 @@ function main() { if (nlsConfig._resolvedLanguagePackCoreLocation) { let bundles = Object.create(null); - nlsConfig.loadBundle = function(bundle, language, cb) { + nlsConfig.loadBundle = function (bundle, language, cb) { let result = bundles[bundle]; if (result) { cb(undefined, result); diff --git a/src/vs/loader.js b/src/vs/loader.js index d2b9f26ab38..406eaf4b65a 100644 --- a/src/vs/loader.js +++ b/src/vs/loader.js @@ -22,7 +22,7 @@ var _amdLoaderGlobal = this; var AMDLoader; (function (AMDLoader) { AMDLoader.global = _amdLoaderGlobal; - var Environment = /** @class */ (function () { + var Environment = (function () { function Environment() { this._detected = false; this._isWindows = false; @@ -93,7 +93,7 @@ var AMDLoader; *--------------------------------------------------------------------------------------------*/ var AMDLoader; (function (AMDLoader) { - var LoaderEvent = /** @class */ (function () { + var LoaderEvent = (function () { function LoaderEvent(type, detail, timestamp) { this.type = type; this.detail = detail; @@ -102,7 +102,7 @@ var AMDLoader; return LoaderEvent; }()); AMDLoader.LoaderEvent = LoaderEvent; - var LoaderEventRecorder = /** @class */ (function () { + var LoaderEventRecorder = (function () { function LoaderEventRecorder(loaderAvailableTimestamp) { this._events = [new LoaderEvent(1 /* LoaderAvailable */, '', loaderAvailableTimestamp)]; } @@ -115,7 +115,7 @@ var AMDLoader; return LoaderEventRecorder; }()); AMDLoader.LoaderEventRecorder = LoaderEventRecorder; - var NullLoaderEventRecorder = /** @class */ (function () { + var NullLoaderEventRecorder = (function () { function NullLoaderEventRecorder() { } NullLoaderEventRecorder.prototype.record = function (type, detail) { @@ -124,9 +124,9 @@ var AMDLoader; NullLoaderEventRecorder.prototype.getEvents = function () { return []; }; - NullLoaderEventRecorder.INSTANCE = new NullLoaderEventRecorder(); return NullLoaderEventRecorder; }()); + NullLoaderEventRecorder.INSTANCE = new NullLoaderEventRecorder(); AMDLoader.NullLoaderEventRecorder = NullLoaderEventRecorder; })(AMDLoader || (AMDLoader = {})); /*--------------------------------------------------------------------------------------------- @@ -135,14 +135,14 @@ var AMDLoader; *--------------------------------------------------------------------------------------------*/ var AMDLoader; (function (AMDLoader) { - var Utilities = /** @class */ (function () { + var Utilities = (function () { function Utilities() { } /** * This method does not take care of / vs \ */ Utilities.fileUriToFilePath = function (isWindows, uri) { - uri = decodeURI(uri); + uri = decodeURI(uri).replace(/%23/g, '#'); if (isWindows) { if (/^file:\/\/\//.test(uri)) { // This is a URI without a hostname => return only the path segment @@ -221,11 +221,11 @@ var AMDLoader; } return (this.HAS_PERFORMANCE_NOW ? AMDLoader.global.performance.now() : Date.now()); }; - Utilities.NEXT_ANONYMOUS_ID = 1; - Utilities.PERFORMANCE_NOW_PROBED = false; - Utilities.HAS_PERFORMANCE_NOW = false; return Utilities; }()); + Utilities.NEXT_ANONYMOUS_ID = 1; + Utilities.PERFORMANCE_NOW_PROBED = false; + Utilities.HAS_PERFORMANCE_NOW = false; AMDLoader.Utilities = Utilities; })(AMDLoader || (AMDLoader = {})); /*--------------------------------------------------------------------------------------------- @@ -234,7 +234,7 @@ var AMDLoader; *--------------------------------------------------------------------------------------------*/ var AMDLoader; (function (AMDLoader) { - var ConfigurationOptionsUtil = /** @class */ (function () { + var ConfigurationOptionsUtil = (function () { function ConfigurationOptionsUtil() { } /** @@ -340,7 +340,7 @@ var AMDLoader; return ConfigurationOptionsUtil; }()); AMDLoader.ConfigurationOptionsUtil = ConfigurationOptionsUtil; - var Configuration = /** @class */ (function () { + var Configuration = (function () { function Configuration(env, options) { this._env = env; this.options = ConfigurationOptionsUtil.mergeConfigurationOptions(options); @@ -551,7 +551,7 @@ var AMDLoader; /** * Load `scriptSrc` only once (avoid multiple <script> tags) */ - var OnlyOnceScriptLoader = /** @class */ (function () { + var OnlyOnceScriptLoader = (function () { function OnlyOnceScriptLoader(env) { this._env = env; this._scriptLoader = null; @@ -593,7 +593,7 @@ var AMDLoader; }; return OnlyOnceScriptLoader; }()); - var BrowserScriptLoader = /** @class */ (function () { + var BrowserScriptLoader = (function () { function BrowserScriptLoader() { } /** @@ -626,7 +626,7 @@ var AMDLoader; }; return BrowserScriptLoader; }()); - var WorkerScriptLoader = /** @class */ (function () { + var WorkerScriptLoader = (function () { function WorkerScriptLoader() { } WorkerScriptLoader.prototype.load = function (moduleManager, scriptSrc, callback, errorback) { @@ -640,7 +640,7 @@ var AMDLoader; }; return WorkerScriptLoader; }()); - var NodeScriptLoader = /** @class */ (function () { + var NodeScriptLoader = (function () { function NodeScriptLoader(env) { this._env = env; this._didInitialize = false; @@ -847,9 +847,9 @@ var AMDLoader; var timeout = minTimeout + Math.ceil(Math.random() * minTimeout); setTimeout(callback, timeout); }; - NodeScriptLoader._BOM = 0xFEFF; return NodeScriptLoader; }()); + NodeScriptLoader._BOM = 0xFEFF; function createScriptLoader(env) { return new OnlyOnceScriptLoader(env); } @@ -863,7 +863,7 @@ var AMDLoader; (function (AMDLoader) { // ------------------------------------------------------------------------ // ModuleIdResolver - var ModuleIdResolver = /** @class */ (function () { + var ModuleIdResolver = (function () { function ModuleIdResolver(fromModuleId) { var lastSlash = fromModuleId.lastIndexOf('/'); if (lastSlash !== -1) { @@ -906,13 +906,13 @@ var AMDLoader; } return result; }; - ModuleIdResolver.ROOT = new ModuleIdResolver(''); return ModuleIdResolver; }()); + ModuleIdResolver.ROOT = new ModuleIdResolver(''); AMDLoader.ModuleIdResolver = ModuleIdResolver; // ------------------------------------------------------------------------ // Module - var Module = /** @class */ (function () { + var Module = (function () { function Module(id, strId, dependencies, callback, errorback, moduleIdResolver) { this.id = id; this.strId = strId; @@ -1002,7 +1002,7 @@ var AMDLoader; return Module; }()); AMDLoader.Module = Module; - var ModuleIdProvider = /** @class */ (function () { + var ModuleIdProvider = (function () { function ModuleIdProvider() { this._nextId = 0; this._strModuleIdToIntModuleId = new Map(); @@ -1029,17 +1029,17 @@ var AMDLoader; }; return ModuleIdProvider; }()); - var RegularDependency = /** @class */ (function () { + var RegularDependency = (function () { function RegularDependency(id) { this.id = id; } - RegularDependency.EXPORTS = new RegularDependency(0 /* EXPORTS */); - RegularDependency.MODULE = new RegularDependency(1 /* MODULE */); - RegularDependency.REQUIRE = new RegularDependency(2 /* REQUIRE */); return RegularDependency; }()); + RegularDependency.EXPORTS = new RegularDependency(0 /* EXPORTS */); + RegularDependency.MODULE = new RegularDependency(1 /* MODULE */); + RegularDependency.REQUIRE = new RegularDependency(2 /* REQUIRE */); AMDLoader.RegularDependency = RegularDependency; - var PluginDependency = /** @class */ (function () { + var PluginDependency = (function () { function PluginDependency(id, pluginId, pluginParam) { this.id = id; this.pluginId = pluginId; @@ -1048,7 +1048,7 @@ var AMDLoader; return PluginDependency; }()); AMDLoader.PluginDependency = PluginDependency; - var ModuleManager = /** @class */ (function () { + var ModuleManager = (function () { function ModuleManager(env, scriptLoader, defineFunc, requireFunc, loaderAvailableTimestamp) { if (loaderAvailableTimestamp === void 0) { loaderAvailableTimestamp = 0; } this._env = env; diff --git a/src/vs/workbench/electron-browser/bootstrap/index.js b/src/vs/workbench/electron-browser/bootstrap/index.js index 6d4706fc371..4d16cd36a71 100644 --- a/src/vs/workbench/electron-browser/bootstrap/index.js +++ b/src/vs/workbench/electron-browser/bootstrap/index.js @@ -64,7 +64,7 @@ function uriFromPath(_path) { pathName = '/' + pathName; } - return encodeURI('file://' + pathName); + return encodeURI('file://' + pathName).replace(/#/g, '%23'); } function readFile(file) { diff --git a/test/electron/renderer.js b/test/electron/renderer.js index 35f970c5c8c..08c94b4287d 100644 --- a/test/electron/renderer.js +++ b/test/electron/renderer.js @@ -29,7 +29,7 @@ function uriFromPath(_path) { pathName = '/' + pathName; } - return encodeURI('file://' + pathName); + return encodeURI('file://' + pathName).replace(/#/g, '%23'); } function initLoader(opts) { From c3c75a237b820620bf228ea5304f0e6005ac8a2c Mon Sep 17 00:00:00 2001 From: Matt Bierner <matb@microsoft.com> Date: Fri, 24 Aug 2018 10:51:47 +0200 Subject: [PATCH 1197/1276] Extract getHeaderFoldingRanges --- .../src/features/foldingProvider.ts | 24 ++++++++----------- 1 file changed, 10 insertions(+), 14 deletions(-) diff --git a/extensions/markdown-language-features/src/features/foldingProvider.ts b/extensions/markdown-language-features/src/features/foldingProvider.ts index 5f0d6480ff3..aa4d7a19eb5 100644 --- a/extensions/markdown-language-features/src/features/foldingProvider.ts +++ b/extensions/markdown-language-features/src/features/foldingProvider.ts @@ -6,7 +6,7 @@ import * as vscode from 'vscode'; import { MarkdownEngine } from '../markdownEngine'; -import { TableOfContentsProvider } from '../tableOfContentsProvider'; +import { TableOfContentsProvider, TocEntry } from '../tableOfContentsProvider'; import { Token } from 'markdown-it'; const rangeLimit = 5000; @@ -50,14 +50,14 @@ export default class MarkdownFoldingProvider implements vscode.FoldingRangeProvi _: vscode.FoldingContext, _token: vscode.CancellationToken ): Promise<vscode.FoldingRange[]> { + const [regions, sections] = await Promise.all([this.getRegions(document), this.getHeaderFoldingRanges(document)]); + return [...regions, ...sections].slice(0, rangeLimit); + } + + private async getHeaderFoldingRanges(document: vscode.TextDocument) { const tocProvider = new TableOfContentsProvider(this.engine, document); - let [regions, toc] = await Promise.all([this.getRegions(document), tocProvider.getToc()]); - - if (toc.length > rangeLimit - regions.length) { - toc = toc.slice(0, rangeLimit - regions.length); - } - - const foldingRanges = toc.map((entry, startIndex) => { + const toc = await tocProvider.getToc(); + return toc.map((entry, startIndex) => { const start = entry.line; let end: number | undefined = undefined; for (let i = startIndex + 1; i < toc.length; ++i) { @@ -69,11 +69,7 @@ export default class MarkdownFoldingProvider implements vscode.FoldingRangeProvi break; } } - return new vscode.FoldingRange( - start, - typeof end === 'number' ? end : document.lineCount - 1); + return new vscode.FoldingRange(start, typeof end === 'number' ? end : document.lineCount - 1); }); - - return [...regions, ...foldingRanges]; } -} \ No newline at end of file +} From 2c43eaebeccb4cba48f3aa6c54b020e1dd477c19 Mon Sep 17 00:00:00 2001 From: Matt Bierner <matb@microsoft.com> Date: Fri, 24 Aug 2018 11:01:09 +0200 Subject: [PATCH 1198/1276] Fix markdown document symbols not having full range of section --- .../src/features/foldingProvider.ts | 22 +++------------- .../src/tableOfContentsProvider.ts | 25 ++++++++++++++++++- 2 files changed, 28 insertions(+), 19 deletions(-) diff --git a/extensions/markdown-language-features/src/features/foldingProvider.ts b/extensions/markdown-language-features/src/features/foldingProvider.ts index aa4d7a19eb5..42a4c083d76 100644 --- a/extensions/markdown-language-features/src/features/foldingProvider.ts +++ b/extensions/markdown-language-features/src/features/foldingProvider.ts @@ -3,11 +3,10 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -import * as vscode from 'vscode'; - -import { MarkdownEngine } from '../markdownEngine'; -import { TableOfContentsProvider, TocEntry } from '../tableOfContentsProvider'; import { Token } from 'markdown-it'; +import * as vscode from 'vscode'; +import { MarkdownEngine } from '../markdownEngine'; +import { TableOfContentsProvider } from '../tableOfContentsProvider'; const rangeLimit = 5000; @@ -57,19 +56,6 @@ export default class MarkdownFoldingProvider implements vscode.FoldingRangeProvi private async getHeaderFoldingRanges(document: vscode.TextDocument) { const tocProvider = new TableOfContentsProvider(this.engine, document); const toc = await tocProvider.getToc(); - return toc.map((entry, startIndex) => { - const start = entry.line; - let end: number | undefined = undefined; - for (let i = startIndex + 1; i < toc.length; ++i) { - if (toc[i].level <= entry.level) { - end = toc[i].line - 1; - if (document.lineAt(end).isEmptyOrWhitespace && end >= start + 1) { - end = end - 1; - } - break; - } - } - return new vscode.FoldingRange(start, typeof end === 'number' ? end : document.lineCount - 1); - }); + return toc.map((entry) => new vscode.FoldingRange(entry.line, entry.location.range.end.line)); } } diff --git a/extensions/markdown-language-features/src/tableOfContentsProvider.ts b/extensions/markdown-language-features/src/tableOfContentsProvider.ts index ff2cd01ad24..4991f06726d 100644 --- a/extensions/markdown-language-features/src/tableOfContentsProvider.ts +++ b/extensions/markdown-language-features/src/tableOfContentsProvider.ts @@ -17,6 +17,7 @@ export interface TocEntry { export interface SkinnyTextDocument { readonly uri: vscode.Uri; + readonly lineCount: number; getText(): string; lineAt(line: number): vscode.TextLine; } @@ -61,7 +62,29 @@ export class TableOfContentsProvider { location: new vscode.Location(document.uri, line.range) }); } - return toc; + + // Get full range of section + return toc.map((entry, startIndex): TocEntry => { + const start = entry.line; + let end: number | undefined = undefined; + for (let i = startIndex + 1; i < toc.length; ++i) { + if (toc[i].level <= entry.level) { + end = toc[i].line - 1; + if (document.lineAt(end).isEmptyOrWhitespace && end >= start + 1) { + end = end - 1; + } + break; + } + } + const endLine = typeof end === 'number' ? end : document.lineCount - 1; + return { + ...entry, + location: new vscode.Location(document.uri, + new vscode.Range( + entry.location.range.start, + new vscode.Position(endLine, document.lineAt(endLine).range.end.character))) + }; + }); } private static getHeaderLevel(markup: string): number { From 3b34fc88b36f926a3c0a351e616b7fbc4511b378 Mon Sep 17 00:00:00 2001 From: Alex Dima <alexdima@microsoft.com> Date: Fri, 24 Aug 2018 11:13:16 +0200 Subject: [PATCH 1199/1276] Simplify binary message parsing --- .../services/extensions/node/rpcProtocol.ts | 124 ++++++++++-------- 1 file changed, 71 insertions(+), 53 deletions(-) diff --git a/src/vs/workbench/services/extensions/node/rpcProtocol.ts b/src/vs/workbench/services/extensions/node/rpcProtocol.ts index 63075595b5c..b928c8052ea 100644 --- a/src/vs/workbench/services/extensions/node/rpcProtocol.ts +++ b/src/vs/workbench/services/extensions/node/rpcProtocol.ts @@ -165,13 +165,13 @@ export class RPCProtocol implements IRPCProtocol { return; } - let offset = 0; - const messageType = MessageIO.deserializeMessageType(rawmsg, offset); offset += 1; - const req = MessageIO.deserializeReq(rawmsg, offset); offset += 4; + const buff = MessageBuffer.read(rawmsg, 0); + const messageType = <MessageType>buff.readUInt8(); + const req = buff.readUInt32(); switch (messageType) { case MessageType.RequestJSONArgs: { - let { rpcId, method, args } = MessageIO.deserializeRequestJSONArgs(rawmsg, offset); + let { rpcId, method, args } = MessageIO.deserializeRequestJSONArgs(buff); if (this._uriTransformer) { args = transformIncomingURIs(args, this._uriTransformer); } @@ -179,7 +179,7 @@ export class RPCProtocol implements IRPCProtocol { break; } case MessageType.RequestMixedArgs: { - let { rpcId, method, args } = MessageIO.deserializeRequestMixedArgs(rawmsg, offset); + let { rpcId, method, args } = MessageIO.deserializeRequestMixedArgs(buff); if (this._uriTransformer) { args = transformIncomingURIs(args, this._uriTransformer); } @@ -195,7 +195,7 @@ export class RPCProtocol implements IRPCProtocol { break; } case MessageType.ReplyOKJSON: { - let value = MessageIO.deserializeReplyOKJSON(rawmsg, offset); + let value = MessageIO.deserializeReplyOKJSON(buff); if (this._uriTransformer) { value = transformIncomingURIs(value, this._uriTransformer); } @@ -203,12 +203,12 @@ export class RPCProtocol implements IRPCProtocol { break; } case MessageType.ReplyOKBuffer: { - let value = MessageIO.deserializeReplyOKBuffer(rawmsg, offset); + let value = MessageIO.deserializeReplyOKBuffer(buff); this._receiveReply(req, value); break; } case MessageType.ReplyErrError: { - let err = MessageIO.deserializeReplyErrError(rawmsg, offset); + let err = MessageIO.deserializeReplyErrError(buff); if (this._uriTransformer) { err = transformIncomingURIs(err, this._uriTransformer); } @@ -323,10 +323,13 @@ export class RPCProtocol implements IRPCProtocol { class MessageBuffer { public static alloc(type: MessageType, req: number, messageSize: number): MessageBuffer { - let buff = Buffer.allocUnsafe(messageSize + 1 /* type */ + 4 /* req */); - let offset = 0; - buff.writeUInt8(type, offset, true); offset += 1; - buff.writeUInt32LE(req, offset, true); offset += 4; + let result = new MessageBuffer(Buffer.allocUnsafe(messageSize + 1 /* type */ + 4 /* req */), 0); + result.writeUInt8(type); + result.writeUInt32(req); + return result; + } + + public static read(buff: Buffer, offset: number): MessageBuffer { return new MessageBuffer(buff, offset); } @@ -342,6 +345,24 @@ class MessageBuffer { this._offset = offset; } + public writeUInt8(n: number): void { + this._buff.writeUInt8(n, this._offset, true); this._offset += 1; + } + + public readUInt8(): number { + const n = this._buff.readUInt8(this._offset, true); this._offset += 1; + return n; + } + + public writeUInt32(n: number): void { + this._buff.writeUInt32BE(n, this._offset, true); this._offset += 4; + } + + public readUInt32(): number { + const n = this._buff.readUInt32BE(this._offset, true); this._offset += 4; + return n; + } + public static sizeShortString(str: string, strByteLength: number): number { return 1 /* string length */ + strByteLength /* actual string */; } @@ -409,24 +430,31 @@ class MessageBuffer { const el = arr[i]; const elLength = arrLengths[i]; if (typeof el === 'string') { - this._buff.writeUInt8(ArgType.ArgString, this._offset, true); this._offset += 1; + this.writeUInt8(ArgType.String); this.writeLongString(el, elLength); } else { - this._buff.writeUInt8(ArgType.ArgBuffer, this._offset, true); this._offset += 1; + this.writeUInt8(ArgType.Buffer); this.writeBuffer(el, elLength); } } } + + public readMixedArray(): (string | Buffer)[] { + const arrLen = this._buff.readUInt8(this._offset, true); this._offset += 1; + let arr: (string | Buffer)[] = new Array(arrLen); + for (let i = 0; i < arrLen; i++) { + const argType = <ArgType>this.readUInt8(); + if (argType === ArgType.String) { + arr[i] = this.readLongString(); + } else { + arr[i] = this.readBuffer(); + } + } + return arr; + } } class MessageIO { - public static deserializeMessageType(buff: Buffer, offset: number): MessageType { - return buff[offset]; - } - - public static deserializeReq(buff: Buffer, offset: number): number { - return buff.readUInt32LE(offset, true); - } private static _arrayContainsBuffer(arr: any[]): boolean { for (let i = 0, len = arr.length; i < len; i++) { @@ -473,13 +501,10 @@ class MessageIO { return result.buffer; } - public static deserializeRequestJSONArgs(buff: Buffer, offset: number): { rpcId: string; method: string; args: any[]; } { - const rpcIdByteLength = buff.readUInt8(offset, true); offset += 1; - const rpcId = buff.toString('utf8', offset, offset + rpcIdByteLength); offset += rpcIdByteLength; - const methodByteLength = buff.readUInt8(offset, true); offset += 1; - const method = buff.toString('utf8', offset, offset + methodByteLength); offset += methodByteLength; - const argsByteLength = buff.readUInt32LE(offset, true); offset += 4; - const args = buff.toString('utf8', offset, offset + argsByteLength); offset += argsByteLength; + public static deserializeRequestJSONArgs(buff: MessageBuffer): { rpcId: string; method: string; args: any[]; } { + const rpcId = buff.readShortString(); + const method = buff.readShortString(); + const args = buff.readLongString(); return { rpcId: rpcId, method: method, @@ -503,20 +528,17 @@ class MessageIO { return result.buffer; } - public static deserializeRequestMixedArgs(buff: Buffer, offset: number): { rpcId: string; method: string; args: any[]; } { - const rpcIdByteLength = buff.readUInt8(offset, true); offset += 1; - const rpcId = buff.toString('utf8', offset, offset + rpcIdByteLength); offset += rpcIdByteLength; - const methodByteLength = buff.readUInt8(offset, true); offset += 1; - const method = buff.toString('utf8', offset, offset + methodByteLength); offset += methodByteLength; - const argsCount = buff.readUInt8(offset, true); offset += 1; - let args: any[] = new Array(argsCount); - for (let i = 0; i < argsCount; i++) { - const argType = buff.readUInt8(offset, true); offset += 1; - const argLength = buff.readUInt32LE(offset, true); offset += 4; - if (argType === ArgType.ArgString) { - args[i] = JSON.parse(buff.toString('utf8', offset, offset + argLength)); offset += argLength; + public static deserializeRequestMixedArgs(buff: MessageBuffer): { rpcId: string; method: string; args: any[]; } { + const rpcId = buff.readShortString(); + const method = buff.readShortString(); + const rawargs = buff.readMixedArray(); + const args: any[] = new Array(rawargs.length); + for (let i = 0, len = rawargs.length; i < len; i++) { + const rawarg = rawargs[i]; + if (typeof rawarg === 'string') { + args[i] = JSON.parse(rawarg); } else { - args[i] = buff.slice(offset, offset + argLength); offset += argLength; + args[i] = rawarg; } } return { @@ -555,10 +577,8 @@ class MessageIO { return result.buffer; } - public static deserializeReplyOKBuffer(buff: Buffer, offset: number): Buffer { - const resByteLength = buff.readUInt32LE(offset, true); offset += 4; - const res = buff.slice(offset, offset + resByteLength); offset += resByteLength; - return res; + public static deserializeReplyOKBuffer(buff: MessageBuffer): Buffer { + return buff.readBuffer(); } private static _serializeReplyOKJSON(req: number, res: string): Buffer { @@ -572,9 +592,8 @@ class MessageIO { return result.buffer; } - public static deserializeReplyOKJSON(buff: Buffer, offset: number): any { - const resByteLength = buff.readUInt32LE(offset, true); offset += 4; - const res = buff.toString('utf8', offset, offset + resByteLength); offset += resByteLength; + public static deserializeReplyOKJSON(buff: MessageBuffer): any { + const res = buff.readLongString(); return JSON.parse(res); } @@ -597,9 +616,8 @@ class MessageIO { return result.buffer; } - public static deserializeReplyErrError(buff: Buffer, offset: number): Error { - const errByteLength = buff.readUInt32LE(offset, true); offset += 4; - const err = buff.toString('utf8', offset, offset + errByteLength); offset += errByteLength; + public static deserializeReplyErrError(buff: MessageBuffer): Error { + const err = buff.readLongString(); return JSON.parse(err); } @@ -620,6 +638,6 @@ const enum MessageType { } const enum ArgType { - ArgString = 1, - ArgBuffer = 2 + String = 1, + Buffer = 2 } From 6d2598ad889e8b3332b94c79e8c977c62d73ea4b Mon Sep 17 00:00:00 2001 From: Joao Moreno <joao.moreno@microsoft.com> Date: Fri, 24 Aug 2018 09:49:48 +0200 Subject: [PATCH 1200/1276] git api: repository state --- extensions/git/src/api/api1.ts | 19 ++++++++++--- extensions/git/src/api/git.d.ts | 49 ++++++++++++++++++++++++++++++-- extensions/git/src/commands.ts | 3 +- extensions/git/src/git.ts | 36 ++++------------------- extensions/git/src/repository.ts | 3 +- extensions/git/src/statusbar.ts | 2 +- 6 files changed, 72 insertions(+), 40 deletions(-) diff --git a/extensions/git/src/api/api1.ts b/extensions/git/src/api/api1.ts index 0057e80fdeb..ca79572b6bc 100644 --- a/extensions/git/src/api/api1.ts +++ b/extensions/git/src/api/api1.ts @@ -7,7 +7,7 @@ import { Model } from '../model'; import { Repository as BaseRepository } from '../repository'; -import { InputBox, Git, API, Repository, Remote } from './git'; +import { InputBox, Git, API, Repository, Remote, RepositoryState, Branch, Ref, Submodule, Commit } from './git'; import { Event, SourceControlInputBox, Uri } from 'vscode'; import { mapEvent } from '../util'; @@ -17,13 +17,24 @@ class ApiInputBox implements InputBox { constructor(private _inputBox: SourceControlInputBox) { } } +export class ApiRepositoryState implements RepositoryState { + + get HEAD(): Branch | undefined { return this._repository.HEAD; } + get refs(): Ref[] { return [...this._repository.refs]; } + get remotes(): Remote[] { return [...this._repository.remotes]; } + get submodules(): Submodule[] { return [...this._repository.submodules]; } + get rebaseCommit(): Commit | undefined { return this._repository.rebaseCommit; } + + readonly onDidChange: Event<void> = this._repository.onDidRunGitStatus; + + constructor(private _repository: BaseRepository) { } +} + export class ApiRepository implements Repository { readonly rootUri: Uri = Uri.file(this._repository.root); readonly inputBox: InputBox = new ApiInputBox(this._repository.inputBox); - get remotes(): Remote[] { return [...this._repository.remotes]; } - - readonly onDidRunGitStatus: Event<void> = this._repository.onDidRunGitStatus; + readonly state: RepositoryState = new ApiRepositoryState(this._repository); constructor(private _repository: BaseRepository) { } diff --git a/extensions/git/src/api/git.d.ts b/extensions/git/src/api/git.d.ts index 7ba18e0d70a..caeaafa13a0 100644 --- a/extensions/git/src/api/git.d.ts +++ b/extensions/git/src/api/git.d.ts @@ -14,6 +14,42 @@ export interface InputBox { value: string; } +export const enum RefType { + Head, + RemoteHead, + Tag +} + +export interface Ref { + readonly type: RefType; + readonly name?: string; + readonly commit?: string; + readonly remote?: string; +} + +export interface UpstreamRef { + readonly remote: string; + readonly name: string; +} + +export interface Branch extends Ref { + readonly upstream?: UpstreamRef; + readonly ahead?: number; + readonly behind?: number; +} + +export interface Commit { + readonly hash: string; + readonly message: string; + readonly parents: string[]; +} + +export interface Submodule { + readonly name: string; + readonly path: string; + readonly url: string; +} + export interface Remote { readonly name: string; readonly fetchUrl?: string; @@ -21,12 +57,19 @@ export interface Remote { readonly isReadOnly: boolean; } +export interface RepositoryState { + readonly HEAD: Branch | undefined; + readonly refs: Ref[]; + readonly remotes: Remote[]; + readonly submodules: Submodule[]; + readonly rebaseCommit: Commit | undefined; + readonly onDidChange: Event<void>; +} + export interface Repository { readonly rootUri: Uri; readonly inputBox: InputBox; - readonly remotes: Remote[]; - - readonly onDidRunGitStatus: Event<void>; + readonly state: RepositoryState; status(): Promise<void>; } diff --git a/extensions/git/src/commands.ts b/extensions/git/src/commands.ts index 2e1c115c14f..25f3bc2979e 100644 --- a/extensions/git/src/commands.ts +++ b/extensions/git/src/commands.ts @@ -6,7 +6,7 @@ 'use strict'; import { Uri, commands, Disposable, window, workspace, QuickPickItem, OutputChannel, Range, WorkspaceEdit, Position, LineChange, SourceControlResourceState, TextDocumentShowOptions, ViewColumn, ProgressLocation, TextEditor, MessageOptions } from 'vscode'; -import { Ref, RefType, Git, GitErrorCodes, Branch } from './git'; +import { Git, GitErrorCodes } from './git'; import { Repository, Resource, Status, CommitOptions, ResourceGroupType } from './repository'; import { Model } from './model'; import { toGitUri, fromGitUri } from './uri'; @@ -17,6 +17,7 @@ import { lstat, Stats } from 'fs'; import * as os from 'os'; import TelemetryReporter from 'vscode-extension-telemetry'; import * as nls from 'vscode-nls'; +import { Ref, RefType, Branch } from './api/git'; const localize = nls.loadMessageBundle(); diff --git a/extensions/git/src/git.ts b/extensions/git/src/git.ts index 01e08bd3878..36e7b4f53ec 100644 --- a/extensions/git/src/git.ts +++ b/extensions/git/src/git.ts @@ -16,6 +16,7 @@ import * as filetype from 'file-type'; import { assign, groupBy, denodeify, IDisposable, toDisposable, dispose, mkdirp, readBytes, detectUnicodeEncoding, Encoding, onceEvent } from './util'; import { CancellationToken } from 'vscode'; import { detectEncoding } from './encoding'; +import { Ref, RefType, Branch, Remote } from './api/git'; const readfile = denodeify<string, string | null, string>(fs.readFile); @@ -31,40 +32,15 @@ export interface IFileStatus { rename?: string; } -export interface Remote { - name: string; - fetchUrl?: string; - pushUrl?: string; - isReadOnly: boolean; -} - export interface Stash { index: number; description: string; } -export enum RefType { - Head, - RemoteHead, - Tag -} - -export interface Ref { - type: RefType; - name?: string; - commit?: string; - remote?: string; -} - -export interface UpstreamRef { - remote: string; - name: string; -} - -export interface Branch extends Ref { - upstream?: UpstreamRef; - ahead?: number; - behind?: number; +interface MutableRemote extends Remote { + fetchUrl?: string; + pushUrl?: string; + isReadOnly: boolean; } function parseVersion(raw: string): string { @@ -1320,7 +1296,7 @@ export class Repository { async getRemotes(): Promise<Remote[]> { const result = await this.run(['remote', '--verbose']); const lines = result.stdout.trim().split('\n').filter(l => !!l); - const remotes: Remote[] = []; + const remotes: MutableRemote[] = []; for (const line of lines) { const parts = line.split(/\s/); diff --git a/extensions/git/src/repository.ts b/extensions/git/src/repository.ts index c2c9a2f344d..2135fa69091 100644 --- a/extensions/git/src/repository.ts +++ b/extensions/git/src/repository.ts @@ -6,7 +6,7 @@ 'use strict'; 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 { Repository as BaseRepository, Ref, Branch, Remote, Commit, GitErrorCodes, Stash, RefType, GitError, Submodule, DiffOptions } from './git'; +import { Repository as BaseRepository, Commit, GitErrorCodes, Stash, GitError, Submodule, DiffOptions } from './git'; import { anyEvent, filterEvent, eventToPromise, dispose, find, isDescendant, IDisposable, onceEvent, EmptyDisposable, debounceEvent } from './util'; import { memoize, throttle, debounce } from './decorators'; import { toGitUri } from './uri'; @@ -15,6 +15,7 @@ import * as path from 'path'; import * as nls from 'vscode-nls'; import * as fs from 'fs'; import { StatusBarCommands } from './statusbar'; +import { Branch, Ref, Remote, RefType } from './api/git'; const timeout = (millis: number) => new Promise(c => setTimeout(c, millis)); diff --git a/extensions/git/src/statusbar.ts b/extensions/git/src/statusbar.ts index 979c961f64d..8cabe51c016 100644 --- a/extensions/git/src/statusbar.ts +++ b/extensions/git/src/statusbar.ts @@ -6,10 +6,10 @@ 'use strict'; import { Disposable, Command, EventEmitter, Event } from 'vscode'; -import { Branch } from './git'; import { Repository, Operation } from './repository'; import { anyEvent, dispose } from './util'; import * as nls from 'vscode-nls'; +import { Branch } from './api/git'; const localize = nls.loadMessageBundle(); From 811a6be05b1e6a23a78ed4016fd6d231a56b3389 Mon Sep 17 00:00:00 2001 From: Joao Moreno <joao.moreno@microsoft.com> Date: Fri, 24 Aug 2018 09:49:59 +0200 Subject: [PATCH 1201/1276] :lipstick: --- extensions/git/src/api/git.d.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/extensions/git/src/api/git.d.ts b/extensions/git/src/api/git.d.ts index caeaafa13a0..698fcc4fb16 100644 --- a/extensions/git/src/api/git.d.ts +++ b/extensions/git/src/api/git.d.ts @@ -4,7 +4,6 @@ *--------------------------------------------------------------------------------------------*/ import { Uri, SourceControlInputBox, Event, CancellationToken } from 'vscode'; -import * as cp from 'child_process'; export interface Git { readonly path: string; From 493b6e76f2170f48ce39d8fdd76d86f068dc57c6 Mon Sep 17 00:00:00 2001 From: Sandeep Somavarapu <sasomava@microsoft.com> Date: Fri, 24 Aug 2018 11:18:04 +0200 Subject: [PATCH 1202/1276] Fix #57076 --- .../parts/search/browser/replaceService.ts | 62 ++++++++++++------- 1 file changed, 41 insertions(+), 21 deletions(-) diff --git a/src/vs/workbench/parts/search/browser/replaceService.ts b/src/vs/workbench/parts/search/browser/replaceService.ts index 73fe8903f8a..32bd1d50ed6 100644 --- a/src/vs/workbench/parts/search/browser/replaceService.ts +++ b/src/vs/workbench/parts/search/browser/replaceService.ts @@ -24,6 +24,9 @@ import { ResourceTextEdit } from 'vs/editor/common/modes'; import { createTextBufferFactoryFromSnapshot } from 'vs/editor/common/model/textModel'; import { ITextFileService } from 'vs/workbench/services/textfile/common/textfiles'; import { IBulkEditService } from 'vs/editor/browser/services/bulkEditService'; +import { Range } from 'vs/editor/common/core/range'; +import { EditOperation } from 'vs/editor/common/core/editOperation'; +import { mergeSort } from 'vs/base/common/arrays'; const REPLACE_PREVIEW = 'replacePreview'; @@ -103,26 +106,7 @@ export class ReplaceService implements IReplaceService { public replace(match: FileMatchOrMatch, progress?: IProgressRunner, resource?: URI): TPromise<any>; public replace(arg: any, progress: IProgressRunner = null, resource: URI = null): TPromise<any> { - const edits: ResourceTextEdit[] = []; - - if (arg instanceof Match) { - let match = <Match>arg; - edits.push(this.createEdit(match, match.replaceString, resource)); - } - - if (arg instanceof FileMatch) { - arg = [arg]; - } - - if (arg instanceof Array) { - arg.forEach(element => { - let fileMatch = <FileMatch>element; - if (fileMatch.count() > 0) { - edits.push(...fileMatch.matches().map(match => this.createEdit(match, match.replaceString, resource))); - } - }); - } - + const edits: ResourceTextEdit[] = this.createEdits(arg, resource); return this.bulkEditorService.apply({ edits }, { progress }).then(() => this.textFileService.saveAll(edits.map(e => e.resource))); } @@ -163,7 +147,7 @@ export class ReplaceService implements IReplaceService { } else { replaceModel.undo(); } - returnValue = this.replace(fileMatch, null, replacePreviewUri); + this.applyEditsToPreview(fileMatch, replaceModel); } return returnValue.then(() => { sourceModelRef.dispose(); @@ -172,6 +156,42 @@ export class ReplaceService implements IReplaceService { }); } + private applyEditsToPreview(fileMatch: FileMatch, replaceModel: ITextModel): void { + const resourceEdits = this.createEdits(fileMatch, replaceModel.uri); + const modelEdits = []; + for (const resourceEdit of resourceEdits) { + for (const edit of resourceEdit.edits) { + const range = Range.lift(edit.range); + modelEdits.push(EditOperation.replaceMove(range, edit.text)); + } + } + replaceModel.pushEditOperations([], mergeSort(modelEdits, (a, b) => Range.compareRangesUsingStarts(a.range, b.range)), () => []); + } + + private createEdits(arg: FileMatchOrMatch | FileMatch[], resource: URI = null): ResourceTextEdit[] { + const edits: ResourceTextEdit[] = []; + + if (arg instanceof Match) { + let match = <Match>arg; + edits.push(this.createEdit(match, match.replaceString, resource)); + } + + if (arg instanceof FileMatch) { + arg = [arg]; + } + + if (arg instanceof Array) { + arg.forEach(element => { + let fileMatch = <FileMatch>element; + if (fileMatch.count() > 0) { + edits.push(...fileMatch.matches().map(match => this.createEdit(match, match.replaceString, resource))); + } + }); + } + + return edits; + } + private createEdit(match: Match, text: string, resource: URI = null): ResourceTextEdit { let fileMatch: FileMatch = match.parent(); let resourceEdit: ResourceTextEdit = { From 28d2b5d2d6715b8bcba79a922fdaf27bb83b10ad Mon Sep 17 00:00:00 2001 From: Joao Moreno <joao.moreno@microsoft.com> Date: Fri, 24 Aug 2018 11:16:28 +0200 Subject: [PATCH 1203/1276] wip: git api --- extensions/git/src/api/git.d.ts | 47 ++++++++++++++++++++++++ extensions/git/src/autofetch.ts | 2 +- extensions/git/src/commands.ts | 4 +-- extensions/git/src/contentProvider.ts | 2 +- extensions/git/src/git.ts | 51 ++++++++++++++++++++++----- extensions/git/src/repository.ts | 12 ++++--- 6 files changed, 102 insertions(+), 16 deletions(-) diff --git a/extensions/git/src/api/git.d.ts b/extensions/git/src/api/git.d.ts index 698fcc4fb16..7d6f07a963d 100644 --- a/extensions/git/src/api/git.d.ts +++ b/extensions/git/src/api/git.d.ts @@ -56,21 +56,68 @@ export interface Remote { readonly isReadOnly: boolean; } +export interface Change { + // TODO +} + export interface RepositoryState { readonly HEAD: Branch | undefined; readonly refs: Ref[]; readonly remotes: Remote[]; readonly submodules: Submodule[]; readonly rebaseCommit: Commit | undefined; + + readonly mergeChanges: Change[]; + readonly indexChanges: Change[]; + readonly workingTreeChanges: Change[]; + readonly onDidChange: Event<void>; } +export const enum ConfigScope { + System, + Global, + Local +} + export interface Repository { + readonly rootUri: Uri; readonly inputBox: InputBox; readonly state: RepositoryState; + getConfigs(scope: ConfigScope): Promise<{ key: string; value: string; }[]>; + getConfig(scope: ConfigScope, key: string): Promise<string>; + setConfig(scope: ConfigScope, key: string, value: string): Promise<string>; + + show(ref: string, path: string): Promise<string>; + getCommit(ref: string): Promise<Commit>; + getObjectDetails(treeish: string, path: string): Promise<{ mode: string, object: string, size: number }>; + + diffWithHEAD(path: string): Promise<string>; + diffWith(ref: string, path: string): Promise<string>; + diffIndexWithHEAD(path: string): Promise<string>; + diffIndexWith(ref: string, path: string): Promise<string>; + diffBlobs(object1: string, object2: string): Promise<string>; + diffBetween(ref1: string, ref2: string, path: string): Promise<string>; + + hashObject(data: string): Promise<string>; + + createBranch(name: string, checkout: boolean, ref?: string): Promise<void>; + deleteBranch(name: string): Promise<void>; + getBranch(name: string): Promise<Branch>; + setBranchUpstream(name: string, upstream: string): Promise<void>; + + getMergeBase(ref1: string, ref2: string): Promise<string>; + status(): Promise<void>; + checkout(treeish: string): Promise<void>; + + addRemote(name: string, url: string): Promise<void>; + removeRemote(name: string): Promise<void>; + + fetch(remote?: string, ref?: string): Promise<void>; + pull(): Promise<void>; } export interface API { diff --git a/extensions/git/src/autofetch.ts b/extensions/git/src/autofetch.ts index 758dc82182c..3522414fb79 100644 --- a/extensions/git/src/autofetch.ts +++ b/extensions/git/src/autofetch.ts @@ -102,7 +102,7 @@ export class AutoFetcher { } try { - await this.repository.fetch(); + await this.repository.fetchDefault(); } catch (err) { if (err.gitErrorCode === GitErrorCodes.AuthenticationFailed) { this.disable(); diff --git a/extensions/git/src/commands.ts b/extensions/git/src/commands.ts index 25f3bc2979e..13f6f4b687e 100644 --- a/extensions/git/src/commands.ts +++ b/extensions/git/src/commands.ts @@ -1235,7 +1235,7 @@ export class CommandCenter { } const name = result.replace(/^\.|\/\.|\.\.|~|\^|:|\/$|\.lock$|\.lock\/|\\|\*|\s|^\s*$|\.$/g, '-'); - await repository.branch(name); + await repository.branch(name, true); } @command('git.deleteBranch', { repository: true }) @@ -1355,7 +1355,7 @@ export class CommandCenter { return; } - await repository.fetch(); + await repository.fetchDefault(); } @command('git.pullFrom', { repository: true }) diff --git a/extensions/git/src/contentProvider.ts b/extensions/git/src/contentProvider.ts index 443dd774f2a..5c3dd22b1e4 100644 --- a/extensions/git/src/contentProvider.ts +++ b/extensions/git/src/contentProvider.ts @@ -92,7 +92,7 @@ export class GitContentProvider { return ''; } - return await repository.diff(path, { cached: ref === 'index' }); + return await repository.diff(path, ref === 'index'); } const repository = this.model.getRepository(uri); diff --git a/extensions/git/src/git.ts b/extensions/git/src/git.ts index 36e7b4f53ec..f861de0393a 100644 --- a/extensions/git/src/git.ts +++ b/extensions/git/src/git.ts @@ -654,10 +654,6 @@ export function parseLsFiles(raw: string): LsFilesElement[] { .map(([, mode, object, stage, file]) => ({ mode, object, stage, file })); } -export interface DiffOptions { - cached?: boolean; -} - export class Repository { constructor( @@ -828,10 +824,10 @@ export class Repository { } } - async diff(path: string, options: DiffOptions = {}): Promise<string> { + async diff(path: string, cached = false): Promise<string> { const args = ['diff']; - if (options.cached) { + if (cached) { args.push('--cached'); } @@ -841,6 +837,20 @@ export class Repository { return result.stdout; } + async diffBetween(ref1: string, ref2: string, path: string): Promise<string> { + const args = ['diff', `${ref1}...${ref2}`, '--', path]; + const result = await this.run(args); + + return result.stdout.trim(); + } + + async getMergeBase(ref1: string, ref2: string): Promise<string> { + const args = ['merge-base', ref1, ref2]; + const result = await this.run(args); + + return result.stdout.trim(); + } + async add(paths: string[]): Promise<void> { const args = ['add', '-A', '--']; @@ -961,8 +971,13 @@ export class Repository { throw commitErr; } - async branch(name: string, checkout: boolean): Promise<void> { + async branch(name: string, checkout: boolean, ref?: string): Promise<void> { const args = checkout ? ['checkout', '-q', '-b', name] : ['branch', '-q', name]; + + if (ref) { + args.push(ref); + } + await this.run(args); } @@ -976,6 +991,11 @@ export class Repository { await this.run(args); } + async setBranchUpstream(name: string, upstream: string): Promise<void> { + const args = ['branch', '--set-upstream-to', upstream, name]; + await this.run(args); + } + async deleteRef(ref: string): Promise<void> { const args = ['update-ref', '-d', ref]; await this.run(args); @@ -1073,7 +1093,22 @@ export class Repository { } } - async fetch(): Promise<void> { + async addRemote(name: string, url: string): Promise<void> { + const args = ['remote', 'add', name, url]; + await this.run(args); + } + + async fetch(remote?: string, ref?: string): Promise<void> { + const args = ['fetch']; + + if (remote) { + args.push(remote); + + if (ref) { + args.push(ref); + } + } + try { await this.run(['fetch']); } catch (err) { diff --git a/extensions/git/src/repository.ts b/extensions/git/src/repository.ts index 2135fa69091..d9caa7787d2 100644 --- a/extensions/git/src/repository.ts +++ b/extensions/git/src/repository.ts @@ -655,8 +655,8 @@ export class Repository implements Disposable { await this.run(Operation.Status); } - diff(path: string, options: DiffOptions = {}): Promise<string> { - return this.run(Operation.Diff, () => this.repository.diff(path, options)); + diff(path: string, cached = false): Promise<string> { + return this.run(Operation.Diff, () => this.repository.diff(path, cached)); } async add(resources: Uri[]): Promise<void> { @@ -746,7 +746,7 @@ export class Repository implements Disposable { }); } - async branch(name: string): Promise<void> { + async branch(name: string, checkout: boolean, ref?: string): Promise<void> { await this.run(Operation.Branch, () => this.repository.branch(name, true)); } @@ -783,7 +783,11 @@ export class Repository implements Disposable { } @throttle - async fetch(): Promise<void> { + async fetchDefault(): Promise<void> { + await this.run(Operation.Fetch, () => this.repository.fetch()); + } + + async fetch(remote?: string, ref?: string): Promise<void> { await this.run(Operation.Fetch, () => this.repository.fetch()); } From 7009b8320f39ee650dbda216394c49a5aae9ce6f Mon Sep 17 00:00:00 2001 From: Sandeep Somavarapu <sasomava@microsoft.com> Date: Fri, 24 Aug 2018 11:33:59 +0200 Subject: [PATCH 1204/1276] Fix #55833 --- .../parts/extensions/electron-browser/extensionEditor.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/vs/workbench/parts/extensions/electron-browser/extensionEditor.ts b/src/vs/workbench/parts/extensions/electron-browser/extensionEditor.ts index 69bc1703280..76f96cf4612 100644 --- a/src/vs/workbench/parts/extensions/electron-browser/extensionEditor.ts +++ b/src/vs/workbench/parts/extensions/electron-browser/extensionEditor.ts @@ -350,6 +350,8 @@ export class ExtensionEditor extends BaseEditor { this.name.onclick = null; this.rating.onclick = null; this.publisher.onclick = null; + this.license.onclick = null; + this.license.style.display = 'none'; } if (extension.repository) { From dbd5597b4b4ec671c5c10542a1d22447e8d97282 Mon Sep 17 00:00:00 2001 From: Alex Dima <alexdima@microsoft.com> Date: Fri, 24 Aug 2018 11:37:52 +0200 Subject: [PATCH 1205/1276] Add logging to RPCProtocol --- .../electron-browser/extensionService.ts | 26 +++---- .../services/extensions/node/rpcProtocol.ts | 72 +++++++++++++------ 2 files changed, 62 insertions(+), 36 deletions(-) diff --git a/src/vs/workbench/services/extensions/electron-browser/extensionService.ts b/src/vs/workbench/services/extensions/electron-browser/extensionService.ts index ebac0353572..0e19784bf4a 100644 --- a/src/vs/workbench/services/extensions/electron-browser/extensionService.ts +++ b/src/vs/workbench/services/extensions/electron-browser/extensionService.ts @@ -39,7 +39,7 @@ import { Event, Emitter } from 'vs/base/common/event'; import { ExtensionHostProfiler } from 'vs/workbench/services/extensions/electron-browser/extensionHostProfiler'; import product from 'vs/platform/node/product'; import * as strings from 'vs/base/common/strings'; -import { RPCProtocol } from 'vs/workbench/services/extensions/node/rpcProtocol'; +import { RPCProtocol, IRPCProtocolLogger } from 'vs/workbench/services/extensions/node/rpcProtocol'; import { INotificationService, Severity } from 'vs/platform/notification/common/notification'; import { isFalsyOrEmpty } from 'vs/base/common/arrays'; import { Schemas } from 'vs/base/common/network'; @@ -179,11 +179,12 @@ export class ExtensionHostProcessManager extends Disposable { private _createExtensionHostCustomers(protocol: IMessagePassingProtocol): ExtHostExtensionServiceShape { + let logger: IRPCProtocolLogger = null; if (logExtensionHostCommunication || this._environmentService.logExtensionHostCommunication) { - protocol = asLoggingProtocol(protocol); + logger = new RPCLogger(); } - this._extensionHostProcessRPCProtocol = new RPCProtocol(protocol); + this._extensionHostProcessRPCProtocol = new RPCProtocol(protocol, logger); const extHostContext: IExtHostContext = { getProxy: <T>(identifier: ProxyIdentifier<T>): T => this._extensionHostProcessRPCProtocol.getProxy(identifier), set: <T, R extends T>(identifier: ProxyIdentifier<T>, instance: R): R => this._extensionHostProcessRPCProtocol.set(identifier, instance), @@ -954,20 +955,15 @@ export class ExtensionService extends Disposable implements IExtensionService { } } -function asLoggingProtocol(protocol: IMessagePassingProtocol): IMessagePassingProtocol { +class RPCLogger implements IRPCProtocolLogger { - protocol.onMessage(msg => { - console.log('%c[Extension \u2192 Window]%c[len: ' + strings.pad(msg.length, 5, ' ') + ']', 'color: darkgreen', 'color: grey', msg); - }); + logIncoming(msgLength: number, str: string, data?: any): void { + console.log('%c[Extension \u2192 Window]%c[len: ' + strings.pad(msgLength, 5, ' ') + ']', 'color: darkgreen', 'color: grey', str, data); + } - return { - onMessage: protocol.onMessage, - - send(msg: any) { - protocol.send(msg); - console.log('%c[Window \u2192 Extension]%c[len: ' + strings.pad(msg.length, 5, ' ') + ']', 'color: darkgreen', 'color: grey', msg); - } - }; + logOutgoing(msgLength: number, str: string, data?: any): void { + console.log('%c[Window \u2192 Extension]%c[len: ' + strings.pad(msgLength, 5, ' ') + ']', 'color: darkgreen', 'color: grey', str, data); + } } interface IExtensionCacheData { diff --git a/src/vs/workbench/services/extensions/node/rpcProtocol.ts b/src/vs/workbench/services/extensions/node/rpcProtocol.ts index b928c8052ea..effdbaf5518 100644 --- a/src/vs/workbench/services/extensions/node/rpcProtocol.ts +++ b/src/vs/workbench/services/extensions/node/rpcProtocol.ts @@ -85,8 +85,15 @@ function transformIncomingURIs(obj: any, transformer: IURITransformer): any { return result; } +export interface IRPCProtocolLogger { + logIncoming(msgLength: number, str: string, data?: any): void; + logOutgoing(msgLength: number, str: string, data?: any): void; +} + export class RPCProtocol implements IRPCProtocol { + private readonly _protocol: IMessagePassingProtocol; + private readonly _logger: IRPCProtocolLogger; private readonly _uriTransformer: IURITransformer; private _isDisposed: boolean; private readonly _locals: { [id: string]: any; }; @@ -94,9 +101,10 @@ export class RPCProtocol implements IRPCProtocol { private _lastMessageId: number; private readonly _invokedHandlers: { [req: string]: TPromise<any>; }; private readonly _pendingRPCReplies: { [msgId: string]: LazyPromise; }; - private readonly _protocol: IMessagePassingProtocol; - constructor(protocol: IMessagePassingProtocol, transformer: IURITransformer = null) { + constructor(protocol: IMessagePassingProtocol, logger: IRPCProtocolLogger = null, transformer: IURITransformer = null) { + this._protocol = protocol; + this._logger = logger; this._uriTransformer = transformer; this._isDisposed = false; this._locals = Object.create(null); @@ -104,7 +112,6 @@ export class RPCProtocol implements IRPCProtocol { this._lastMessageId = 0; this._invokedHandlers = Object.create(null); this._pendingRPCReplies = {}; - this._protocol = protocol; this._protocol.onMessage((msg) => this._receiveOneMessage(msg)); } @@ -165,6 +172,7 @@ export class RPCProtocol implements IRPCProtocol { return; } + const msgLength = rawmsg.length; const buff = MessageBuffer.read(rawmsg, 0); const messageType = <MessageType>buff.readUInt8(); const req = buff.readUInt32(); @@ -175,7 +183,7 @@ export class RPCProtocol implements IRPCProtocol { if (this._uriTransformer) { args = transformIncomingURIs(args, this._uriTransformer); } - this._receiveRequest(req, rpcId, method, args); + this._receiveRequest(msgLength, req, rpcId, method, args); break; } case MessageType.RequestMixedArgs: { @@ -183,15 +191,15 @@ export class RPCProtocol implements IRPCProtocol { if (this._uriTransformer) { args = transformIncomingURIs(args, this._uriTransformer); } - this._receiveRequest(req, rpcId, method, args); + this._receiveRequest(msgLength, req, rpcId, method, args); break; } case MessageType.Cancel: { - this._receiveCancel(req); + this._receiveCancel(msgLength, req); break; } case MessageType.ReplyOKEmpty: { - this._receiveReply(req, undefined); + this._receiveReply(msgLength, req, undefined); break; } case MessageType.ReplyOKJSON: { @@ -199,12 +207,12 @@ export class RPCProtocol implements IRPCProtocol { if (this._uriTransformer) { value = transformIncomingURIs(value, this._uriTransformer); } - this._receiveReply(req, value); + this._receiveReply(msgLength, req, value); break; } case MessageType.ReplyOKBuffer: { let value = MessageIO.deserializeReplyOKBuffer(buff); - this._receiveReply(req, value); + this._receiveReply(msgLength, req, value); break; } case MessageType.ReplyErrError: { @@ -222,8 +230,10 @@ export class RPCProtocol implements IRPCProtocol { } } - private _receiveRequest(req: number, rpcId: string, method: string, args: any[]): void { - // console.log(`receiveRequest: ${req}, ${rpcId}.${method}`, args); + private _receiveRequest(msgLength: number, req: number, rpcId: string, method: string, args: any[]): void { + if (this._logger) { + this._logger.logIncoming(msgLength, `receiveRequest ${req}, ${rpcId}.${method}:`, args); + } const callId = String(req); this._invokedHandlers[callId] = this._invokeHandler(rpcId, method, args); @@ -233,23 +243,35 @@ export class RPCProtocol implements IRPCProtocol { if (this._uriTransformer) { r = transformOutgoingURIs(r, this._uriTransformer); } - this._protocol.send(MessageIO.serializeReplyOK(req, r)); + const msg = MessageIO.serializeReplyOK(req, r); + if (this._logger) { + this._logger.logOutgoing(msg.byteLength, `replyOK ${req}:`, r); + } + this._protocol.send(msg); }, (err) => { delete this._invokedHandlers[callId]; - this._protocol.send(MessageIO.serializeReplyErr(req, err)); + const msg = MessageIO.serializeReplyErr(req, err); + if (this._logger) { + this._logger.logOutgoing(msg.byteLength, `replyErr ${req}:`, err); + } + this._protocol.send(msg); }); } - private _receiveCancel(req: number): void { - // console.log(`receiveCancel: ${req}`); + private _receiveCancel(msgLength: number, req: number): void { + if (this._logger) { + this._logger.logIncoming(msgLength, `receiveCancel ${req}`); + } const callId = String(req); if (this._invokedHandlers[callId]) { this._invokedHandlers[callId].cancel(); } } - private _receiveReply(req: number, value: any): void { - // console.log(`receiveReply: ${req}`, value); + private _receiveReply(msgLength: number, req: number, value: any): void { + if (this._logger) { + this._logger.logIncoming(msgLength, `receiveReply ${req}:`, value); + } const callId = String(req); if (!this._pendingRPCReplies.hasOwnProperty(callId)) { return; @@ -305,17 +327,25 @@ export class RPCProtocol implements IRPCProtocol { return TPromise.wrapError<any>(errors.canceled()); } - const nCallId = ++this._lastMessageId; - const callId = String(nCallId); + const req = ++this._lastMessageId; + const callId = String(req); const result = new LazyPromise(() => { - this._protocol.send(MessageIO.serializeCancel(nCallId)); + const msg = MessageIO.serializeCancel(req); + if (this._logger) { + this._logger.logOutgoing(msg.byteLength, `cancel ${req}`); + } + this._protocol.send(MessageIO.serializeCancel(req)); }); this._pendingRPCReplies[callId] = result; if (this._uriTransformer) { args = transformOutgoingURIs(args, this._uriTransformer); } - this._protocol.send(MessageIO.serializeRequest(nCallId, proxyId, methodName, args)); + const msg = MessageIO.serializeRequest(req, proxyId, methodName, args); + if (this._logger) { + this._logger.logOutgoing(msg.byteLength, `request ${req}: ${proxyId}.${methodName}:`, args); + } + this._protocol.send(msg); return result; } } From 30d0a61a8f5dfa5d8a59009bff073b0310cc9d9c Mon Sep 17 00:00:00 2001 From: Martin Aeschlimann <martinae@microsoft.com> Date: Fri, 24 Aug 2018 11:03:30 +0200 Subject: [PATCH 1206/1276] allow extensionDevelopmentPath to be a URI --- .../sharedProcess/sharedProcessMain.ts | 4 ++-- src/vs/code/node/cliProcessMain.ts | 4 ++-- src/vs/code/node/windowsFinder.ts | 2 +- .../platform/environment/common/environment.ts | 3 ++- .../environment/node/environmentService.ts | 12 +++++++++++- src/vs/workbench/api/node/extHost.protocol.ts | 2 +- src/vs/workbench/node/extensionHostMain.ts | 2 +- .../debug/electron-browser/debugService.ts | 4 ++-- .../electron-browser/extensionTipsService.ts | 2 +- .../electron-browser/extensionHost.ts | 13 +++++++------ .../electron-browser/extensionService.ts | 18 +++++++++--------- 11 files changed, 39 insertions(+), 27 deletions(-) diff --git a/src/vs/code/electron-browser/sharedProcess/sharedProcessMain.ts b/src/vs/code/electron-browser/sharedProcess/sharedProcessMain.ts index ca030d19918..8d33d957398 100644 --- a/src/vs/code/electron-browser/sharedProcess/sharedProcessMain.ts +++ b/src/vs/code/electron-browser/sharedProcess/sharedProcessMain.ts @@ -99,7 +99,7 @@ function main(server: Server, initData: ISharedProcessInitData, configuration: I instantiationService.invokeFunction(accessor => { const services = new ServiceCollection(); const environmentService = accessor.get(IEnvironmentService); - const { appRoot, extensionsPath, extensionDevelopmentPath, isBuilt, installSourcePath } = environmentService; + const { appRoot, extensionsPath, extensionDevelopmentLocationURI, isBuilt, installSourcePath } = environmentService; const telemetryLogService = new FollowerLogService(logLevelClient, createSpdLogService('telemetry', initData.logLevel, environmentService.logsPath)); let appInsightsAppender: ITelemetryAppender = NullAppender; @@ -109,7 +109,7 @@ function main(server: Server, initData: ISharedProcessInitData, configuration: I } server.registerChannel('telemetryAppender', new TelemetryAppenderChannel(appInsightsAppender)); - if (!extensionDevelopmentPath && !environmentService.args['disable-telemetry'] && product.enableTelemetry) { + if (!extensionDevelopmentLocationURI && !environmentService.args['disable-telemetry'] && product.enableTelemetry) { const config: ITelemetryServiceConfig = { appender: combinedAppender(appInsightsAppender, new LogAppender(logService)), commonProperties: resolveCommonProperties(product.commit, pkg.version, configuration.machineId, installSourcePath), diff --git a/src/vs/code/node/cliProcessMain.ts b/src/vs/code/node/cliProcessMain.ts index 0731a9d7b13..2e2ff5d98af 100644 --- a/src/vs/code/node/cliProcessMain.ts +++ b/src/vs/code/node/cliProcessMain.ts @@ -233,7 +233,7 @@ export function main(argv: ParsedArgs): TPromise<void> { const stateService = accessor.get(IStateService); return TPromise.join([envService.appSettingsHome, envService.extensionsPath].map(p => mkdirp(p))).then(() => { - const { appRoot, extensionsPath, extensionDevelopmentPath, isBuilt, installSourcePath } = envService; + const { appRoot, extensionsPath, extensionDevelopmentLocationURI, isBuilt, installSourcePath } = envService; const services = new ServiceCollection(); services.set(IConfigurationService, new SyncDescriptor(ConfigurationService)); @@ -243,7 +243,7 @@ export function main(argv: ParsedArgs): TPromise<void> { services.set(IDialogService, new SyncDescriptor(CommandLineDialogService)); const appenders: AppInsightsAppender[] = []; - if (isBuilt && !extensionDevelopmentPath && !envService.args['disable-telemetry'] && product.enableTelemetry) { + if (isBuilt && !extensionDevelopmentLocationURI && !envService.args['disable-telemetry'] && product.enableTelemetry) { if (product.aiConfig && product.aiConfig.asimovKey) { appenders.push(new AppInsightsAppender(eventPrefix, null, product.aiConfig.asimovKey, logService)); diff --git a/src/vs/code/node/windowsFinder.ts b/src/vs/code/node/windowsFinder.ts index b69d3eec0db..22488f44ad6 100644 --- a/src/vs/code/node/windowsFinder.ts +++ b/src/vs/code/node/windowsFinder.ts @@ -92,7 +92,7 @@ export function findWindowOnWorkspace<W extends ISimpleWindow>(windows: W[], wor export function findWindowOnExtensionDevelopmentPath<W extends ISimpleWindow>(windows: W[], extensionDevelopmentPath: string): W { for (const window of windows) { - // match on extension development path + // match on extension development path. The path can be a path or uri string, using paths.isEqual is not 100% correct but good enough if (paths.isEqual(window.extensionDevelopmentPath, extensionDevelopmentPath, !platform.isLinux /* ignorecase */)) { return window; } diff --git a/src/vs/platform/environment/common/environment.ts b/src/vs/platform/environment/common/environment.ts index 7338d3e798d..d97203a0530 100644 --- a/src/vs/platform/environment/common/environment.ts +++ b/src/vs/platform/environment/common/environment.ts @@ -4,6 +4,7 @@ *--------------------------------------------------------------------------------------------*/ import { createDecorator } from 'vs/platform/instantiation/common/instantiation'; +import URI from 'vs/base/common/uri'; export interface ParsedArgs { [arg: string]: any; @@ -107,7 +108,7 @@ export interface IEnvironmentService { disableExtensions: boolean | string[]; builtinExtensionsPath: string; extensionsPath: string; - extensionDevelopmentPath: string; + extensionDevelopmentLocationURI: URI; extensionTestsPath: string; debugExtensionHost: IExtensionHostDebugParams; diff --git a/src/vs/platform/environment/node/environmentService.ts b/src/vs/platform/environment/node/environmentService.ts index 1117c904fb7..fdd300c54e4 100644 --- a/src/vs/platform/environment/node/environmentService.ts +++ b/src/vs/platform/environment/node/environmentService.ts @@ -14,6 +14,7 @@ import product from 'vs/platform/node/product'; import { toLocalISOString } from 'vs/base/common/date'; import { isWindows, isLinux } from 'vs/base/common/platform'; import { getPathFromAmdModule } from 'vs/base/common/amd'; +import URI from 'vs/base/common/uri'; // Read this before there's any chance it is overwritten // Related to https://github.com/Microsoft/vscode/issues/30624 @@ -158,7 +159,16 @@ export class EnvironmentService implements IEnvironmentService { } @memoize - get extensionDevelopmentPath(): string { return this._args.extensionDevelopmentPath ? path.normalize(this._args.extensionDevelopmentPath) : this._args.extensionDevelopmentPath; } + get extensionDevelopmentLocationURI(): URI { + const s = this._args.extensionDevelopmentPath; + if (s) { + if (/^[^:/?#]+?:\/\//.test(s)) { + return URI.parse(s); + } + return URI.file(path.normalize(s)); + } + return void 0; + } @memoize get extensionTestsPath(): string { return this._args.extensionTestsPath ? path.normalize(this._args.extensionTestsPath) : this._args.extensionTestsPath; } diff --git a/src/vs/workbench/api/node/extHost.protocol.ts b/src/vs/workbench/api/node/extHost.protocol.ts index d0b857acad5..e95a1c07de7 100644 --- a/src/vs/workbench/api/node/extHost.protocol.ts +++ b/src/vs/workbench/api/node/extHost.protocol.ts @@ -47,7 +47,7 @@ export interface IEnvironment { isExtensionDevelopmentDebug: boolean; appRoot: string; appSettingsHome: string; - extensionDevelopmentPath: string; + extensionDevelopmentLocationURI: URI; extensionTestsPath: string; } diff --git a/src/vs/workbench/node/extensionHostMain.ts b/src/vs/workbench/node/extensionHostMain.ts index 8c1726b919f..c71e0dd2f54 100644 --- a/src/vs/workbench/node/extensionHostMain.ts +++ b/src/vs/workbench/node/extensionHostMain.ts @@ -303,7 +303,7 @@ export class ExtensionHostMain { } private handleExtensionTests(): TPromise<void> { - if (!this._environment.extensionTestsPath || !this._environment.extensionDevelopmentPath) { + if (!this._environment.extensionTestsPath || !this._environment.extensionDevelopmentLocationURI) { return TPromise.as(null); } diff --git a/src/vs/workbench/parts/debug/electron-browser/debugService.ts b/src/vs/workbench/parts/debug/electron-browser/debugService.ts index 21e321d5ea5..9e75e40b95e 100644 --- a/src/vs/workbench/parts/debug/electron-browser/debugService.ts +++ b/src/vs/workbench/parts/debug/electron-browser/debugService.ts @@ -749,7 +749,7 @@ export class DebugService implements IDebugService { if (equalsIgnoreCase(session.configuration.type, 'extensionhost') && session.state === State.Running && session.configuration.noDebug) { this.broadcastService.broadcast({ channel: EXTENSION_CLOSE_EXTHOST_BROADCAST_CHANNEL, - payload: [session.root.uri.fsPath] + payload: [session.root.uri.toString()] }); } @@ -918,7 +918,7 @@ export class DebugService implements IDebugService { if (equalsIgnoreCase(session.configuration.type, 'extensionHost') && session.root) { return this.broadcastService.broadcast({ channel: EXTENSION_RELOAD_BROADCAST_CHANNEL, - payload: [session.root.uri.fsPath] + payload: [session.root.uri.toString()] }); } diff --git a/src/vs/workbench/parts/extensions/electron-browser/extensionTipsService.ts b/src/vs/workbench/parts/extensions/electron-browser/extensionTipsService.ts index 6f9d4a74f5f..4e0524ccdc6 100644 --- a/src/vs/workbench/parts/extensions/electron-browser/extensionTipsService.ts +++ b/src/vs/workbench/parts/extensions/electron-browser/extensionTipsService.ts @@ -179,7 +179,7 @@ export class ExtensionTipsService extends Disposable implements IExtensionTipsSe } private isEnabled(): boolean { - return this._galleryService.isEnabled() && !this.environmentService.extensionDevelopmentPath; + return this._galleryService.isEnabled() && !this.environmentService.extensionDevelopmentLocationURI; } getAllRecommendationsWithReason(): { [id: string]: { reasonId: ExtensionRecommendationReason, reasonText: string }; } { diff --git a/src/vs/workbench/services/extensions/electron-browser/extensionHost.ts b/src/vs/workbench/services/extensions/electron-browser/extensionHost.ts index 6919dec0c92..45c186eb197 100644 --- a/src/vs/workbench/services/extensions/electron-browser/extensionHost.ts +++ b/src/vs/workbench/services/extensions/electron-browser/extensionHost.ts @@ -9,7 +9,7 @@ import * as nls from 'vs/nls'; import { toErrorMessage } from 'vs/base/common/errorMessage'; import * as objects from 'vs/base/common/objects'; import { TPromise } from 'vs/base/common/winjs.base'; -import { isWindows, isLinux } from 'vs/base/common/platform'; +import { isWindows } from 'vs/base/common/platform'; import { findFreePort } from 'vs/base/node/ports'; import { ILifecycleService, ShutdownEvent } from 'vs/platform/lifecycle/common/lifecycle'; import { IWindowsService, IWindowService } from 'vs/platform/windows/common/windows'; @@ -28,7 +28,7 @@ import { IExtensionDescription } from 'vs/workbench/services/extensions/common/e import { IWorkspaceConfigurationService } from 'vs/workbench/services/configuration/common/configuration'; import { ICrashReporterService } from 'vs/workbench/services/crashReporter/electron-browser/crashReporterService'; import { IBroadcastService, IBroadcast } from 'vs/platform/broadcast/electron-browser/broadcastService'; -import { isEqual } from 'vs/base/common/paths'; +import { isEqual } from 'vs/base/common/resources'; import { EXTENSION_CLOSE_EXTHOST_BROADCAST_CHANNEL, EXTENSION_RELOAD_BROADCAST_CHANNEL, EXTENSION_ATTACH_BROADCAST_CHANNEL, EXTENSION_LOG_BROADCAST_CHANNEL, EXTENSION_TERMINATE_BROADCAST_CHANNEL } from 'vs/platform/extensions/common/extensionHost'; import { IDisposable, dispose, toDisposable } from 'vs/base/common/lifecycle'; import { IRemoteConsoleLog, log, parse } from 'vs/base/node/console'; @@ -39,6 +39,7 @@ import { getPathFromAmdModule } from 'vs/base/common/amd'; import { timeout } from 'vs/base/common/async'; import { isMessageOfType, MessageType, createMessageOfType } from 'vs/workbench/common/extensionHostProtocol'; import { ILabelService } from 'vs/platform/label/common/label'; +import URI from 'vs/base/common/uri'; export interface IExtensionHostStarter { readonly onCrashed: Event<[number, string]>; @@ -120,15 +121,15 @@ export class ExtensionHostProcessWorker implements IExtensionHostStarter { // Close Ext Host Window Request if (broadcast.channel === EXTENSION_CLOSE_EXTHOST_BROADCAST_CHANNEL && this._isExtensionDevHost) { - const extensionPaths = broadcast.payload as string[]; - if (Array.isArray(extensionPaths) && extensionPaths.some(path => isEqual(this._environmentService.extensionDevelopmentPath, path, !isLinux))) { + const extensionLocations = broadcast.payload as string[]; + if (Array.isArray(extensionLocations) && extensionLocations.some(uriString => isEqual(this._environmentService.extensionDevelopmentLocationURI, URI.parse(uriString)))) { this._windowService.closeWindow(); } } if (broadcast.channel === EXTENSION_RELOAD_BROADCAST_CHANNEL && this._isExtensionDevHost) { const extensionPaths = broadcast.payload as string[]; - if (Array.isArray(extensionPaths) && extensionPaths.some(path => isEqual(this._environmentService.extensionDevelopmentPath, path, !isLinux))) { + if (Array.isArray(extensionPaths) && extensionPaths.some(uriString => isEqual(this._environmentService.extensionDevelopmentLocationURI, URI.parse(uriString)))) { this._windowService.reloadWindow(); } } @@ -380,7 +381,7 @@ export class ExtensionHostProcessWorker implements IExtensionHostStarter { isExtensionDevelopmentDebug: this._isExtensionDevDebug, appRoot: this._environmentService.appRoot, appSettingsHome: this._environmentService.appSettingsHome, - extensionDevelopmentPath: this._environmentService.extensionDevelopmentPath, + extensionDevelopmentLocationURI: this._environmentService.extensionDevelopmentLocationURI, extensionTestsPath: this._environmentService.extensionTestsPath }, workspace: this._contextService.getWorkbenchState() === WorkbenchState.EMPTY ? null : { diff --git a/src/vs/workbench/services/extensions/electron-browser/extensionService.ts b/src/vs/workbench/services/extensions/electron-browser/extensionService.ts index ebac0353572..170a3dd9db7 100644 --- a/src/vs/workbench/services/extensions/electron-browser/extensionService.ts +++ b/src/vs/workbench/services/extensions/electron-browser/extensionService.ts @@ -44,6 +44,7 @@ import { INotificationService, Severity } from 'vs/platform/notification/common/ import { isFalsyOrEmpty } from 'vs/base/common/arrays'; import { Schemas } from 'vs/base/common/network'; import { getPathFromAmdModule } from 'vs/base/common/amd'; +import { isEqualOrParent } from 'vs/base/common/resources'; let _SystemExtensionsRoot: string = null; function getSystemExtensionsRoot(): string { @@ -564,11 +565,11 @@ export class ExtensionService extends Disposable implements IExtensionService { } const enableProposedApiForAll = !this._environmentService.isBuilt || - (!!this._environmentService.extensionDevelopmentPath && product.nameLong.indexOf('Insiders') >= 0) || + (!!this._environmentService.extensionDevelopmentLocationURI && product.nameLong.indexOf('Insiders') >= 0) || (enableProposedApiFor.length === 0 && 'enable-proposed-api' in this._environmentService.args); for (const extension of allExtensions) { - const isExtensionUnderDevelopment = this._environmentService.isExtensionDevelopment && extension.extensionLocation.scheme === Schemas.file && extension.extensionLocation.fsPath.indexOf(this._environmentService.extensionDevelopmentPath) === 0; + const isExtensionUnderDevelopment = this._environmentService.isExtensionDevelopment && isEqualOrParent(extension.extensionLocation, this._environmentService.extensionDevelopmentLocationURI); // Do not disable extensions under development if (!isExtensionUnderDevelopment) { if (disabledExtensions.some(disabled => areSameExtensions(disabled, extension))) { @@ -861,13 +862,12 @@ export class ExtensionService extends Disposable implements IExtensionService { ); // Always load developed extensions while extensions development - const developedExtensions = ( - environmentService.isExtensionDevelopment - ? ExtensionScanner.scanOneOrMultipleExtensions( - new ExtensionScannerInput(version, commit, locale, devMode, environmentService.extensionDevelopmentPath, false, true, translations), log - ) - : TPromise.as([]) - ); + let developedExtensions = TPromise.as([]); + if (environmentService.isExtensionDevelopment && environmentService.extensionDevelopmentLocationURI.scheme === Schemas.file) { + developedExtensions = ExtensionScanner.scanOneOrMultipleExtensions( + new ExtensionScannerInput(version, commit, locale, devMode, environmentService.extensionDevelopmentLocationURI.fsPath, false, true, translations), log + ); + } return TPromise.join([finalBuiltinExtensions, userExtensions, developedExtensions]).then((extensionDescriptions: IExtensionDescription[][]) => { const system = extensionDescriptions[0]; From 230a2890deabdd39a87bd3abef3e071a24729510 Mon Sep 17 00:00:00 2001 From: Alex Dima <alexdima@microsoft.com> Date: Fri, 24 Aug 2018 11:47:13 +0200 Subject: [PATCH 1207/1276] Also log total messages size --- .../extensions/electron-browser/extensionService.ts | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/vs/workbench/services/extensions/electron-browser/extensionService.ts b/src/vs/workbench/services/extensions/electron-browser/extensionService.ts index 0e19784bf4a..52951d238a8 100644 --- a/src/vs/workbench/services/extensions/electron-browser/extensionService.ts +++ b/src/vs/workbench/services/extensions/electron-browser/extensionService.ts @@ -957,12 +957,17 @@ export class ExtensionService extends Disposable implements IExtensionService { class RPCLogger implements IRPCProtocolLogger { + private _totalIncoming = 0; + private _totalOutgoing = 0; + logIncoming(msgLength: number, str: string, data?: any): void { - console.log('%c[Extension \u2192 Window]%c[len: ' + strings.pad(msgLength, 5, ' ') + ']', 'color: darkgreen', 'color: grey', str, data); + this._totalIncoming += msgLength; + console.log(`%c[Extension \u2192 Window]%c[${strings.pad(this._totalIncoming, 7, ' ')}]%c[len: ${strings.pad(msgLength, 5, ' ')}]`, 'color: darkgreen', 'color: grey', 'color: grey', str, data); } logOutgoing(msgLength: number, str: string, data?: any): void { - console.log('%c[Window \u2192 Extension]%c[len: ' + strings.pad(msgLength, 5, ' ') + ']', 'color: darkgreen', 'color: grey', str, data); + this._totalOutgoing += msgLength; + console.log(`%c[Window \u2192 Extension]%c[${strings.pad(this._totalOutgoing, 7, ' ')}]%c[len: ${strings.pad(msgLength, 5, ' ')}]`, 'color: darkgreen', 'color: grey', 'color: grey', str, data); } } From 49edd3d0384e8196fc45bf1a465a434a84ed430e Mon Sep 17 00:00:00 2001 From: Matt Bierner <matb@microsoft.com> Date: Fri, 24 Aug 2018 12:01:06 +0200 Subject: [PATCH 1208/1276] markdown toc should include full span to next header The folding range should exclude blank lines before the next header level --- .../src/features/foldingProvider.ts | 8 +++++++- .../src/tableOfContentsProvider.ts | 4 ---- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/extensions/markdown-language-features/src/features/foldingProvider.ts b/extensions/markdown-language-features/src/features/foldingProvider.ts index 42a4c083d76..3874cc32f87 100644 --- a/extensions/markdown-language-features/src/features/foldingProvider.ts +++ b/extensions/markdown-language-features/src/features/foldingProvider.ts @@ -56,6 +56,12 @@ export default class MarkdownFoldingProvider implements vscode.FoldingRangeProvi private async getHeaderFoldingRanges(document: vscode.TextDocument) { const tocProvider = new TableOfContentsProvider(this.engine, document); const toc = await tocProvider.getToc(); - return toc.map((entry) => new vscode.FoldingRange(entry.line, entry.location.range.end.line)); + return toc.map(entry => { + let endLine = entry.location.range.end.line; + if (document.lineAt(endLine).isEmptyOrWhitespace && endLine >= entry.line + 1) { + endLine = endLine - 1; + } + return new vscode.FoldingRange(entry.line, endLine); + }); } } diff --git a/extensions/markdown-language-features/src/tableOfContentsProvider.ts b/extensions/markdown-language-features/src/tableOfContentsProvider.ts index 4991f06726d..944fc750734 100644 --- a/extensions/markdown-language-features/src/tableOfContentsProvider.ts +++ b/extensions/markdown-language-features/src/tableOfContentsProvider.ts @@ -65,14 +65,10 @@ export class TableOfContentsProvider { // Get full range of section return toc.map((entry, startIndex): TocEntry => { - const start = entry.line; let end: number | undefined = undefined; for (let i = startIndex + 1; i < toc.length; ++i) { if (toc[i].level <= entry.level) { end = toc[i].line - 1; - if (document.lineAt(end).isEmptyOrWhitespace && end >= start + 1) { - end = end - 1; - } break; } } From 103715c3cc6fbf3f7ea90a47058812ecf6d52ce8 Mon Sep 17 00:00:00 2001 From: Joao Moreno <joao.moreno@microsoft.com> Date: Fri, 24 Aug 2018 12:04:29 +0200 Subject: [PATCH 1209/1276] git: implement API --- extensions/git/src/api/api1.ts | 105 +++++++++++++++++++++++++- extensions/git/src/api/git.d.ts | 12 +-- extensions/git/src/contentProvider.ts | 6 +- extensions/git/src/git.ts | 62 ++++++++++++++- extensions/git/src/repository.ts | 70 ++++++++++++++++- 5 files changed, 238 insertions(+), 17 deletions(-) diff --git a/extensions/git/src/api/api1.ts b/extensions/git/src/api/api1.ts index ca79572b6bc..fdf0142fb45 100644 --- a/extensions/git/src/api/api1.ts +++ b/extensions/git/src/api/api1.ts @@ -6,8 +6,8 @@ 'use strict'; import { Model } from '../model'; -import { Repository as BaseRepository } from '../repository'; -import { InputBox, Git, API, Repository, Remote, RepositoryState, Branch, Ref, Submodule, Commit } from './git'; +import { Repository as BaseRepository, Resource } from '../repository'; +import { InputBox, Git, API, Repository, Remote, RepositoryState, Branch, Ref, Submodule, Commit, Change } from './git'; import { Event, SourceControlInputBox, Uri } from 'vscode'; import { mapEvent } from '../util'; @@ -17,6 +17,11 @@ class ApiInputBox implements InputBox { constructor(private _inputBox: SourceControlInputBox) { } } +export class ApiChange implements Change { + + constructor(_resource: Resource) { } +} + export class ApiRepositoryState implements RepositoryState { get HEAD(): Branch | undefined { return this._repository.HEAD; } @@ -25,6 +30,10 @@ export class ApiRepositoryState implements RepositoryState { get submodules(): Submodule[] { return [...this._repository.submodules]; } get rebaseCommit(): Commit | undefined { return this._repository.rebaseCommit; } + get mergeChanges(): Change[] { return this._repository.mergeGroup.resourceStates.map(r => new ApiChange(r)); } + get indexChanges(): Change[] { return this._repository.indexGroup.resourceStates.map(r => new ApiChange(r)); } + get workingTreeChanges(): Change[] { return this._repository.workingTreeGroup.resourceStates.map(r => new ApiChange(r)); } + readonly onDidChange: Event<void> = this._repository.onDidRunGitStatus; constructor(private _repository: BaseRepository) { } @@ -38,9 +47,101 @@ export class ApiRepository implements Repository { constructor(private _repository: BaseRepository) { } + getConfigs(): Promise<{ key: string; value: string; }[]> { + return this._repository.getConfigs(); + } + + getConfig(key: string): Promise<string> { + return this._repository.getConfig(key); + } + + setConfig(key: string, value: string): Promise<string> { + return this._repository.setConfig(key, value); + } + + show(ref: string, path: string): Promise<string> { + return this._repository.show(ref, path); + } + + getCommit(ref: string): Promise<Commit> { + return this._repository.getCommit(ref); + } + + getObjectDetails(treeish: string, path: string): Promise<{ mode: string; object: string; size: number; }> { + return this._repository.getObjectDetails(treeish, path); + } + + diffWithHEAD(path: string): Promise<string> { + return this._repository.diffWithHEAD(path); + } + + diffWith(ref: string, path: string): Promise<string> { + return this._repository.diffWith(ref, path); + } + + diffIndexWithHEAD(path: string): Promise<string> { + return this._repository.diffIndexWithHEAD(path); + } + + diffIndexWith(ref: string, path: string): Promise<string> { + return this._repository.diffIndexWith(ref, path); + } + + diffBlobs(object1: string, object2: string): Promise<string> { + return this._repository.diffBlobs(object1, object2); + } + + diffBetween(ref1: string, ref2: string, path: string): Promise<string> { + return this._repository.diffBetween(ref1, ref2, path); + } + + hashObject(data: string): Promise<string> { + return this._repository.hashObject(data); + } + + createBranch(name: string, checkout: boolean, ref?: string | undefined): Promise<void> { + return this._repository.branch(name, checkout, ref); + } + + deleteBranch(name: string): Promise<void> { + return this._repository.deleteBranch(name); + } + + getBranch(name: string): Promise<Branch> { + return this._repository.getBranch(name); + } + + setBranchUpstream(name: string, upstream: string): Promise<void> { + return this._repository.setBranchUpstream(name, upstream); + } + + getMergeBase(ref1: string, ref2: string): Promise<string> { + throw new Error('Method not implemented.'); + } + status(): Promise<void> { return this._repository.status(); } + + checkout(treeish: string): Promise<void> { + return this._repository.checkout(treeish); + } + + addRemote(name: string, url: string): Promise<void> { + return this._repository.addRemote(name, url); + } + + removeRemote(name: string): Promise<void> { + return this._repository.removeRemote(name); + } + + fetch(remote?: string | undefined, ref?: string | undefined): Promise<void> { + return this._repository.fetch(remote, ref); + } + + pull(): Promise<void> { + return this._repository.pull(); + } } export class ApiGit implements Git { diff --git a/extensions/git/src/api/git.d.ts b/extensions/git/src/api/git.d.ts index 7d6f07a963d..ca103c592e7 100644 --- a/extensions/git/src/api/git.d.ts +++ b/extensions/git/src/api/git.d.ts @@ -74,21 +74,15 @@ export interface RepositoryState { readonly onDidChange: Event<void>; } -export const enum ConfigScope { - System, - Global, - Local -} - export interface Repository { readonly rootUri: Uri; readonly inputBox: InputBox; readonly state: RepositoryState; - getConfigs(scope: ConfigScope): Promise<{ key: string; value: string; }[]>; - getConfig(scope: ConfigScope, key: string): Promise<string>; - setConfig(scope: ConfigScope, key: string, value: string): Promise<string>; + getConfigs(): Promise<{ key: string; value: string; }[]>; + getConfig(key: string): Promise<string>; + setConfig(key: string, value: string): Promise<string>; show(ref: string, path: string): Promise<string>; getCommit(ref: string): Promise<Commit>; diff --git a/extensions/git/src/contentProvider.ts b/extensions/git/src/contentProvider.ts index 5c3dd22b1e4..e03a97bd29b 100644 --- a/extensions/git/src/contentProvider.ts +++ b/extensions/git/src/contentProvider.ts @@ -92,7 +92,11 @@ export class GitContentProvider { return ''; } - return await repository.diff(path, ref === 'index'); + if (ref === 'index') { + return await repository.diffIndexWithHEAD(path); + } else { + return await repository.diffWithHEAD(path); + } } const repository = this.model.getRepository(uri); diff --git a/extensions/git/src/git.ts b/extensions/git/src/git.ts index f861de0393a..93ee513cddf 100644 --- a/extensions/git/src/git.ts +++ b/extensions/git/src/git.ts @@ -682,7 +682,7 @@ export class Repository { return this.git.spawn(args, options); } - async config(scope: string, key: string, value: any, options: SpawnOptions): Promise<string> { + async config(scope: string, key: string, value: any = null, options: SpawnOptions = {}): Promise<string> { const args = ['config']; if (scope) { @@ -699,6 +699,24 @@ export class Repository { return result.stdout; } + async getConfigs(scope: string): Promise<{ key: string; value: string; }[]> { + const args = ['config']; + + if (scope) { + args.push('--' + scope); + } + + args.push('-l'); + + const result = await this.run(args); + const lines = result.stdout.trim().split(/\r|\r\n|\n/); + + return lines.map(entry => { + const equalsIndex = entry.indexOf('='); + return { key: entry.substr(0, equalsIndex), value: entry.substr(equalsIndex + 1) }; + }); + } + async bufferString(object: string, encoding: string = 'utf8', autoGuessEncoding = false): Promise<string> { const stdout = await this.buffer(object); @@ -837,6 +855,36 @@ export class Repository { return result.stdout; } + async diffWithHEAD(path: string): Promise<string> { + const args = ['diff', '--', path]; + const result = await this.run(args); + return result.stdout; + } + + async diffWith(ref: string, path: string): Promise<string> { + const args = ['diff', ref, '--', path]; + const result = await this.run(args); + return result.stdout; + } + + async diffIndexWithHEAD(path: string): Promise<string> { + const args = ['diff', '--cached', '--', path]; + const result = await this.run(args); + return result.stdout; + } + + async diffIndexWith(ref: string, path: string): Promise<string> { + const args = ['diff', '--cached', ref, '--', path]; + const result = await this.run(args); + return result.stdout; + } + + async diffBlobs(object1: string, object2: string): Promise<string> { + const args = ['diff', object1, object2]; + const result = await this.run(args); + return result.stdout; + } + async diffBetween(ref1: string, ref2: string, path: string): Promise<string> { const args = ['diff', `${ref1}...${ref2}`, '--', path]; const result = await this.run(args); @@ -851,6 +899,13 @@ export class Repository { return result.stdout.trim(); } + async hashObject(data: string): Promise<string> { + const args = ['hash-object', '-w', '--stdin']; + const result = await this.run(args, { input: data }); + + return result.stdout.trim(); + } + async add(paths: string[]): Promise<void> { const args = ['add', '-A', '--']; @@ -1098,6 +1153,11 @@ export class Repository { await this.run(args); } + async removeRemote(name: string): Promise<void> { + const args = ['remote', 'rm', name]; + await this.run(args); + } + async fetch(remote?: string, ref?: string): Promise<void> { const args = ['fetch']; diff --git a/extensions/git/src/repository.ts b/extensions/git/src/repository.ts index d9caa7787d2..055af72527c 100644 --- a/extensions/git/src/repository.ts +++ b/extensions/git/src/repository.ts @@ -6,7 +6,7 @@ 'use strict'; 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 { Repository as BaseRepository, Commit, GitErrorCodes, Stash, GitError, Submodule, DiffOptions } from './git'; +import { Repository as BaseRepository, Commit, GitErrorCodes, Stash, GitError, Submodule } from './git'; import { anyEvent, filterEvent, eventToPromise, dispose, find, isDescendant, IDisposable, onceEvent, EmptyDisposable, debounceEvent } from './util'; import { memoize, throttle, debounce } from './decorators'; import { toGitUri } from './uri'; @@ -277,14 +277,20 @@ export class Resource implements SourceControlResourceState { export enum Operation { Status = 'Status', + Config = 'Config', Diff = 'Diff', + MergeBase = 'MergeBase', Add = 'Add', RevertFiles = 'RevertFiles', Commit = 'Commit', Clean = 'Clean', Branch = 'Branch', + GetBranch = 'GetBranch', + SetBranchUpstream = 'SetBranchUpstream', + HashObject = 'HashObject', Checkout = 'Checkout', Reset = 'Reset', + Remote = 'Remote', Fetch = 'Fetch', Pull = 'Pull', Push = 'Push', @@ -650,13 +656,53 @@ export class Repository implements Disposable { } } + getConfigs(): Promise<{ key: string; value: string; }[]> { + return this.run(Operation.Config, () => this.repository.getConfigs('local')); + } + + getConfig(key: string): Promise<string> { + return this.run(Operation.Config, () => this.repository.config('local', key)); + } + + setConfig(key: string, value: string): Promise<string> { + return this.run(Operation.Config, () => this.repository.config('local', key, value)); + } + @throttle async status(): Promise<void> { await this.run(Operation.Status); } - diff(path: string, cached = false): Promise<string> { - return this.run(Operation.Diff, () => this.repository.diff(path, cached)); + diffWithHEAD(path: string): Promise<string> { + return this.run(Operation.Diff, () => this.repository.diffWithHEAD(path)); + } + + diffWith(ref: string, path: string): Promise<string> { + return this.run(Operation.Diff, () => this.repository.diffWith(ref, path)); + } + + diffIndexWithHEAD(path: string): Promise<string> { + return this.run(Operation.Diff, () => this.repository.diffIndexWithHEAD(path)); + } + + diffIndexWith(ref: string, path: string): Promise<string> { + return this.run(Operation.Diff, () => this.repository.diffIndexWith(ref, path)); + } + + diffBlobs(object1: string, object2: string): Promise<string> { + return this.run(Operation.Diff, () => this.repository.diffBlobs(object1, object2)); + } + + diffBetween(ref1: string, ref2: string, path: string): Promise<string> { + return this.run(Operation.Diff, () => this.repository.diffBetween(ref1, ref2, path)); + } + + getMergeBase(ref1: string, ref2: string): Promise<string> { + return this.run(Operation.MergeBase, () => this.repository.getMergeBase(ref1, ref2)); + } + + async hashObject(data: string): Promise<string> { + return this.run(Operation.HashObject, () => this.repository.hashObject(data)); } async add(resources: Uri[]): Promise<void> { @@ -758,6 +804,14 @@ export class Repository implements Disposable { await this.run(Operation.RenameBranch, () => this.repository.renameBranch(name)); } + async getBranch(name: string): Promise<Branch> { + return await this.run(Operation.GetBranch, () => this.repository.getBranch(name)); + } + + async setBranchUpstream(name: string, upstream: string): Promise<void> { + await this.run(Operation.SetBranchUpstream, () => this.repository.setBranchUpstream(name, upstream)); + } + async merge(ref: string): Promise<void> { await this.run(Operation.Merge, () => this.repository.merge(ref)); } @@ -782,6 +836,14 @@ export class Repository implements Disposable { await this.run(Operation.DeleteRef, () => this.repository.deleteRef(ref)); } + async addRemote(name: string, url: string): Promise<void> { + await this.run(Operation.Remote, () => this.repository.addRemote(name, url)); + } + + async removeRemote(name: string): Promise<void> { + await this.run(Operation.Remote, () => this.repository.removeRemote(name)); + } + @throttle async fetchDefault(): Promise<void> { await this.run(Operation.Fetch, () => this.repository.fetch()); @@ -805,7 +867,7 @@ export class Repository implements Disposable { } @throttle - async pull(head: Branch | undefined): Promise<void> { + async pull(head?: Branch): Promise<void> { let remote: string | undefined; let branch: string | undefined; From 8e35ed1df2d1abf2b2bd2866ae1e6c8527dcff67 Mon Sep 17 00:00:00 2001 From: Alex Dima <alexdima@microsoft.com> Date: Fri, 24 Aug 2018 12:04:35 +0200 Subject: [PATCH 1210/1276] Use real buffers (since the RPC protocol can handle them now) --- .../api/electron-browser/mainThreadFileSystem.ts | 8 +++----- src/vs/workbench/api/node/extHost.protocol.ts | 4 ++-- src/vs/workbench/api/node/extHostFileSystem.ts | 8 ++++---- 3 files changed, 9 insertions(+), 11 deletions(-) diff --git a/src/vs/workbench/api/electron-browser/mainThreadFileSystem.ts b/src/vs/workbench/api/electron-browser/mainThreadFileSystem.ts index 164d458a3ed..e93e8173175 100644 --- a/src/vs/workbench/api/electron-browser/mainThreadFileSystem.ts +++ b/src/vs/workbench/api/electron-browser/mainThreadFileSystem.ts @@ -99,15 +99,13 @@ class RemoteFileSystemProvider implements IFileSystemProvider { } readFile(resource: URI): TPromise<Uint8Array> { - return this._proxy.$readFile(this._handle, resource).then(encoded => { - return Buffer.from(encoded, 'base64'); - }); + return this._proxy.$readFile(this._handle, resource); } writeFile(resource: URI, content: Uint8Array, opts: FileWriteOptions): TPromise<void> { let encoded = Buffer.isBuffer(content) - ? content.toString('base64') - : Buffer.from(content.buffer, content.byteOffset, content.byteLength).toString('base64'); + ? content + : Buffer.from(content.buffer, content.byteOffset, content.byteLength); return this._proxy.$writeFile(this._handle, resource, encoded, opts); } diff --git a/src/vs/workbench/api/node/extHost.protocol.ts b/src/vs/workbench/api/node/extHost.protocol.ts index edb764542ad..477f60f32b7 100644 --- a/src/vs/workbench/api/node/extHost.protocol.ts +++ b/src/vs/workbench/api/node/extHost.protocol.ts @@ -679,8 +679,8 @@ export interface ExtHostWorkspaceShape { export interface ExtHostFileSystemShape { $stat(handle: number, resource: UriComponents): TPromise<IStat>; $readdir(handle: number, resource: UriComponents): TPromise<[string, FileType][]>; - $readFile(handle: number, resource: UriComponents): TPromise<string>; - $writeFile(handle: number, resource: UriComponents, base64Encoded: string, opts: FileWriteOptions): TPromise<void>; + $readFile(handle: number, resource: UriComponents): TPromise<Buffer>; + $writeFile(handle: number, resource: UriComponents, content: Buffer, opts: FileWriteOptions): TPromise<void>; $rename(handle: number, resource: UriComponents, target: UriComponents, opts: FileOverwriteOptions): TPromise<void>; $copy(handle: number, resource: UriComponents, target: UriComponents, opts: FileOverwriteOptions): TPromise<void>; $mkdir(handle: number, resource: UriComponents): TPromise<void>; diff --git a/src/vs/workbench/api/node/extHostFileSystem.ts b/src/vs/workbench/api/node/extHostFileSystem.ts index 732d21cd761..5bacd68adf3 100644 --- a/src/vs/workbench/api/node/extHostFileSystem.ts +++ b/src/vs/workbench/api/node/extHostFileSystem.ts @@ -159,16 +159,16 @@ export class ExtHostFileSystem implements ExtHostFileSystemShape { return asWinJsPromise(() => this._fsProvider.get(handle).readDirectory(URI.revive(resource))); } - $readFile(handle: number, resource: UriComponents): TPromise<string> { + $readFile(handle: number, resource: UriComponents): TPromise<Buffer> { return asWinJsPromise(() => { return this._fsProvider.get(handle).readFile(URI.revive(resource)); }).then(data => { - return Buffer.isBuffer(data) ? data.toString('base64') : Buffer.from(data.buffer, data.byteOffset, data.byteLength).toString('base64'); + return Buffer.isBuffer(data) ? data : Buffer.from(data.buffer, data.byteOffset, data.byteLength); }); } - $writeFile(handle: number, resource: UriComponents, base64Content: string, opts: files.FileWriteOptions): TPromise<void> { - return asWinJsPromise(() => this._fsProvider.get(handle).writeFile(URI.revive(resource), Buffer.from(base64Content, 'base64'), opts)); + $writeFile(handle: number, resource: UriComponents, content: Buffer, opts: files.FileWriteOptions): TPromise<void> { + return asWinJsPromise(() => this._fsProvider.get(handle).writeFile(URI.revive(resource), content, opts)); } $delete(handle: number, resource: UriComponents, opts: files.FileDeleteOptions): TPromise<void> { From bc477a962c18421286f2e686db962cbbda5e6ae9 Mon Sep 17 00:00:00 2001 From: Martin Aeschlimann <martinae@microsoft.com> Date: Fri, 24 Aug 2018 12:07:36 +0200 Subject: [PATCH 1211/1276] fix test failure from `extensionDevelopmentPath to be a URI` --- .../test/electron-browser/extensionsTipsService.test.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vs/workbench/parts/extensions/test/electron-browser/extensionsTipsService.test.ts b/src/vs/workbench/parts/extensions/test/electron-browser/extensionsTipsService.test.ts index 89cbd28c3d6..4fd3b6cc212 100644 --- a/src/vs/workbench/parts/extensions/test/electron-browser/extensionsTipsService.test.ts +++ b/src/vs/workbench/parts/extensions/test/electron-browser/extensionsTipsService.test.ts @@ -316,7 +316,7 @@ suite('ExtensionsTipsService Test', () => { }); test('ExtensionTipsService: No Prompt for valid workspace recommendations during extension development', () => { - instantiationService.stub(IEnvironmentService, { extensionDevelopmentPath: true }); + instantiationService.stub(IEnvironmentService, { extensionDevelopmentLocationURI: true }); return testNoPromptOrRecommendationsForValidRecommendations(mockTestData.validRecommendedExtensions); }); From 6a733c7fff071de3ecb827b14a057d711d53672f Mon Sep 17 00:00:00 2001 From: Sandeep Somavarapu <sasomava@microsoft.com> Date: Fri, 24 Aug 2018 12:07:45 +0200 Subject: [PATCH 1212/1276] Fix #57145 --- src/vs/workbench/browser/parts/compositeBar.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vs/workbench/browser/parts/compositeBar.ts b/src/vs/workbench/browser/parts/compositeBar.ts index 266ad88a156..fa12612a68a 100644 --- a/src/vs/workbench/browser/parts/compositeBar.ts +++ b/src/vs/workbench/browser/parts/compositeBar.ts @@ -471,7 +471,7 @@ class CompositeBarModel { } return changed; } else { - const item = this.createCompositeBarItem(id, name, order, false, true); + const item = this.createCompositeBarItem(id, name, order, true, true); if (isUndefinedOrNull(order)) { this.items.push(item); } else { From 6e909d413279099659f2f38541bdc9b1cb4f6b93 Mon Sep 17 00:00:00 2001 From: Joao Moreno <joao.moreno@microsoft.com> Date: Fri, 24 Aug 2018 12:24:32 +0200 Subject: [PATCH 1213/1276] git: expose error codes in API --- extensions/git/src/api/git.d.ts | 31 ++++++++++++++++++++++ extensions/git/src/autofetch.ts | 2 +- extensions/git/src/commands.ts | 4 +-- extensions/git/src/decorationProvider.ts | 2 +- extensions/git/src/git.ts | 33 +----------------------- extensions/git/src/model.ts | 3 ++- extensions/git/src/repository.ts | 4 +-- 7 files changed, 40 insertions(+), 39 deletions(-) diff --git a/extensions/git/src/api/git.d.ts b/extensions/git/src/api/git.d.ts index ca103c592e7..b86b263b940 100644 --- a/extensions/git/src/api/git.d.ts +++ b/extensions/git/src/api/git.d.ts @@ -130,4 +130,35 @@ export interface GitExtension { * @returns API instance */ getAPI(version: 1): API; +} + +export const enum GitErrorCodes { + BadConfigFile = 'BadConfigFile', + AuthenticationFailed = 'AuthenticationFailed', + NoUserNameConfigured = 'NoUserNameConfigured', + NoUserEmailConfigured = 'NoUserEmailConfigured', + NoRemoteRepositorySpecified = 'NoRemoteRepositorySpecified', + NotAGitRepository = 'NotAGitRepository', + NotAtRepositoryRoot = 'NotAtRepositoryRoot', + Conflict = 'Conflict', + UnmergedChanges = 'UnmergedChanges', + PushRejected = 'PushRejected', + RemoteConnectionError = 'RemoteConnectionError', + DirtyWorkTree = 'DirtyWorkTree', + CantOpenResource = 'CantOpenResource', + GitNotFound = 'GitNotFound', + CantCreatePipe = 'CantCreatePipe', + CantAccessRemote = 'CantAccessRemote', + RepositoryNotFound = 'RepositoryNotFound', + RepositoryIsLocked = 'RepositoryIsLocked', + BranchNotFullyMerged = 'BranchNotFullyMerged', + NoRemoteReference = 'NoRemoteReference', + InvalidBranchName = 'InvalidBranchName', + BranchAlreadyExists = 'BranchAlreadyExists', + NoLocalChanges = 'NoLocalChanges', + NoStashFound = 'NoStashFound', + LocalChangesOverwritten = 'LocalChangesOverwritten', + NoUpstreamBranch = 'NoUpstreamBranch', + IsInSubmodule = 'IsInSubmodule', + WrongCase = 'WrongCase', } \ No newline at end of file diff --git a/extensions/git/src/autofetch.ts b/extensions/git/src/autofetch.ts index 3522414fb79..33439a8d315 100644 --- a/extensions/git/src/autofetch.ts +++ b/extensions/git/src/autofetch.ts @@ -6,10 +6,10 @@ 'use strict'; import { workspace, Disposable, EventEmitter, Memento, window, MessageItem, ConfigurationTarget } from 'vscode'; -import { GitErrorCodes } from './git'; import { Repository, Operation } from './repository'; import { eventToPromise, filterEvent, onceEvent } from './util'; import * as nls from 'vscode-nls'; +import { GitErrorCodes } from './api/git'; const localize = nls.loadMessageBundle(); diff --git a/extensions/git/src/commands.ts b/extensions/git/src/commands.ts index 13f6f4b687e..11e02c23814 100644 --- a/extensions/git/src/commands.ts +++ b/extensions/git/src/commands.ts @@ -6,7 +6,7 @@ 'use strict'; import { Uri, commands, Disposable, window, workspace, QuickPickItem, OutputChannel, Range, WorkspaceEdit, Position, LineChange, SourceControlResourceState, TextDocumentShowOptions, ViewColumn, ProgressLocation, TextEditor, MessageOptions } from 'vscode'; -import { Git, GitErrorCodes } from './git'; +import { Git } from './git'; import { Repository, Resource, Status, CommitOptions, ResourceGroupType } from './repository'; import { Model } from './model'; import { toGitUri, fromGitUri } from './uri'; @@ -17,7 +17,7 @@ import { lstat, Stats } from 'fs'; import * as os from 'os'; import TelemetryReporter from 'vscode-extension-telemetry'; import * as nls from 'vscode-nls'; -import { Ref, RefType, Branch } from './api/git'; +import { Ref, RefType, Branch, GitErrorCodes } from './api/git'; const localize = nls.loadMessageBundle(); diff --git a/extensions/git/src/decorationProvider.ts b/extensions/git/src/decorationProvider.ts index 4d15bb814ac..05eff573e72 100644 --- a/extensions/git/src/decorationProvider.ts +++ b/extensions/git/src/decorationProvider.ts @@ -11,7 +11,7 @@ import { Repository, GitResourceGroup, Status } from './repository'; import { Model } from './model'; import { debounce } from './decorators'; import { filterEvent, dispose, anyEvent, fireEvent } from './util'; -import { GitErrorCodes } from './git'; +import { GitErrorCodes } from './api/git'; type Callback = { resolve: (status: boolean) => void, reject: (err: any) => void }; diff --git a/extensions/git/src/git.ts b/extensions/git/src/git.ts index 93ee513cddf..3069b8fd77b 100644 --- a/extensions/git/src/git.ts +++ b/extensions/git/src/git.ts @@ -16,7 +16,7 @@ import * as filetype from 'file-type'; import { assign, groupBy, denodeify, IDisposable, toDisposable, dispose, mkdirp, readBytes, detectUnicodeEncoding, Encoding, onceEvent } from './util'; import { CancellationToken } from 'vscode'; import { detectEncoding } from './encoding'; -import { Ref, RefType, Branch, Remote } from './api/git'; +import { Ref, RefType, Branch, Remote, GitErrorCodes } from './api/git'; const readfile = denodeify<string, string | null, string>(fs.readFile); @@ -285,37 +285,6 @@ export interface IGitOptions { env?: any; } -export const GitErrorCodes = { - BadConfigFile: 'BadConfigFile', - AuthenticationFailed: 'AuthenticationFailed', - NoUserNameConfigured: 'NoUserNameConfigured', - NoUserEmailConfigured: 'NoUserEmailConfigured', - NoRemoteRepositorySpecified: 'NoRemoteRepositorySpecified', - NotAGitRepository: 'NotAGitRepository', - NotAtRepositoryRoot: 'NotAtRepositoryRoot', - Conflict: 'Conflict', - UnmergedChanges: 'UnmergedChanges', - PushRejected: 'PushRejected', - RemoteConnectionError: 'RemoteConnectionError', - DirtyWorkTree: 'DirtyWorkTree', - CantOpenResource: 'CantOpenResource', - GitNotFound: 'GitNotFound', - CantCreatePipe: 'CantCreatePipe', - CantAccessRemote: 'CantAccessRemote', - RepositoryNotFound: 'RepositoryNotFound', - RepositoryIsLocked: 'RepositoryIsLocked', - BranchNotFullyMerged: 'BranchNotFullyMerged', - NoRemoteReference: 'NoRemoteReference', - InvalidBranchName: 'InvalidBranchName', - BranchAlreadyExists: 'BranchAlreadyExists', - NoLocalChanges: 'NoLocalChanges', - NoStashFound: 'NoStashFound', - LocalChangesOverwritten: 'LocalChangesOverwritten', - NoUpstreamBranch: 'NoUpstreamBranch', - IsInSubmodule: 'IsInSubmodule', - WrongCase: 'WrongCase', -}; - function getGitErrorCode(stderr: string): string | undefined { if (/Another git process seems to be running in this repository|If no other git process is currently running/.test(stderr)) { return GitErrorCodes.RepositoryIsLocked; diff --git a/extensions/git/src/model.ts b/extensions/git/src/model.ts index f28f71324ca..42011b06c65 100644 --- a/extensions/git/src/model.ts +++ b/extensions/git/src/model.ts @@ -9,11 +9,12 @@ import { workspace, WorkspaceFoldersChangeEvent, Uri, window, Event, EventEmitte import { Repository, RepositoryState } from './repository'; import { memoize, sequentialize, debounce } from './decorators'; import { dispose, anyEvent, filterEvent, isDescendant, firstIndex } from './util'; -import { Git, GitErrorCodes } from './git'; +import { Git } from './git'; import * as path from 'path'; import * as fs from 'fs'; import * as nls from 'vscode-nls'; import { fromGitUri } from './uri'; +import { GitErrorCodes } from './api/git'; const localize = nls.loadMessageBundle(); diff --git a/extensions/git/src/repository.ts b/extensions/git/src/repository.ts index 055af72527c..b63466635d4 100644 --- a/extensions/git/src/repository.ts +++ b/extensions/git/src/repository.ts @@ -6,7 +6,7 @@ 'use strict'; 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 { Repository as BaseRepository, Commit, GitErrorCodes, Stash, GitError, Submodule } from './git'; +import { Repository as BaseRepository, Commit, Stash, GitError, Submodule } from './git'; import { anyEvent, filterEvent, eventToPromise, dispose, find, isDescendant, IDisposable, onceEvent, EmptyDisposable, debounceEvent } from './util'; import { memoize, throttle, debounce } from './decorators'; import { toGitUri } from './uri'; @@ -15,7 +15,7 @@ import * as path from 'path'; import * as nls from 'vscode-nls'; import * as fs from 'fs'; import { StatusBarCommands } from './statusbar'; -import { Branch, Ref, Remote, RefType } from './api/git'; +import { Branch, Ref, Remote, RefType, GitErrorCodes } from './api/git'; const timeout = (millis: number) => new Promise(c => setTimeout(c, millis)); From 7b21b23496e7941c3635e51cb4fc8db0e424f750 Mon Sep 17 00:00:00 2001 From: Matt Bierner <matb@microsoft.com> Date: Fri, 24 Aug 2018 12:10:38 +0200 Subject: [PATCH 1214/1276] Remove out of date comments --- .../src/features/languageConfiguration.ts | 2 -- 1 file changed, 2 deletions(-) diff --git a/extensions/typescript-language-features/src/features/languageConfiguration.ts b/extensions/typescript-language-features/src/features/languageConfiguration.ts index 8ee1cfecdad..b4532187a9c 100644 --- a/extensions/typescript-language-features/src/features/languageConfiguration.ts +++ b/extensions/typescript-language-features/src/features/languageConfiguration.ts @@ -14,9 +14,7 @@ import * as languageModeIds from '../utils/languageModeIds'; const jsTsLanguageConfiguration: vscode.LanguageConfiguration = { indentationRules: { - // ^(.*\*/)?\s*\}.*$ decreaseIndentPattern: /^((?!.*?\/\*).*\*\/)?\s*[\}\]\)].*$/, - // ^.*\{[^}"']*$ increaseIndentPattern: /^((?!\/\/).)*(\{[^}"'`]*|\([^)"'`]*|\[[^\]"'`]*)$/ }, wordPattern: /(-?\d*\.\d\w*)|([^\`\~\!\@\#\%\^\&\*\(\)\-\=\+\[\{\]\}\\\|\;\:\'\"\,\.\<\>\/\?\s]+)/g, From ae5fff075dd54ff339d19fc1149effe63d581480 Mon Sep 17 00:00:00 2001 From: Matt Bierner <matb@microsoft.com> Date: Fri, 24 Aug 2018 12:26:15 +0200 Subject: [PATCH 1215/1276] Don't explicitly de-indent on ) in js/ts Fixes #56275 --- .../src/features/languageConfiguration.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/extensions/typescript-language-features/src/features/languageConfiguration.ts b/extensions/typescript-language-features/src/features/languageConfiguration.ts index b4532187a9c..b7f9b1e083e 100644 --- a/extensions/typescript-language-features/src/features/languageConfiguration.ts +++ b/extensions/typescript-language-features/src/features/languageConfiguration.ts @@ -14,7 +14,7 @@ import * as languageModeIds from '../utils/languageModeIds'; const jsTsLanguageConfiguration: vscode.LanguageConfiguration = { indentationRules: { - decreaseIndentPattern: /^((?!.*?\/\*).*\*\/)?\s*[\}\]\)].*$/, + decreaseIndentPattern: /^((?!.*?\/\*).*\*\/)?\s*[\}\]].*$/, increaseIndentPattern: /^((?!\/\/).)*(\{[^}"'`]*|\([^)"'`]*|\[[^\]"'`]*)$/ }, wordPattern: /(-?\d*\.\d\w*)|([^\`\~\!\@\#\%\^\&\*\(\)\-\=\+\[\{\]\}\\\|\;\:\'\"\,\.\<\>\/\?\s]+)/g, From 5ac625f8831c0aaf2c9248e48aec66f2a24f833b Mon Sep 17 00:00:00 2001 From: isidor <inikolic@microsoft.com> Date: Fri, 24 Aug 2018 12:27:20 +0200 Subject: [PATCH 1216/1276] debug: fix breakpoint line for dirty files fixes #56398 --- .../parts/debug/browser/breakpointsView.ts | 21 ++++--------- .../debug/browser/debugEditorModelManager.ts | 4 +-- .../parts/debug/common/debugModel.ts | 30 +++++++++++++++---- .../debug/electron-browser/debugService.ts | 4 +-- .../test/electron-browser/debugModel.test.ts | 2 +- 5 files changed, 34 insertions(+), 27 deletions(-) diff --git a/src/vs/workbench/parts/debug/browser/breakpointsView.ts b/src/vs/workbench/parts/debug/browser/breakpointsView.ts index dd75a8196d4..99e546e6d1a 100644 --- a/src/vs/workbench/parts/debug/browser/breakpointsView.ts +++ b/src/vs/workbench/parts/debug/browser/breakpointsView.ts @@ -29,7 +29,6 @@ import { IViewletViewOptions } from 'vs/workbench/browser/parts/views/viewsViewl import { attachInputBoxStyler } from 'vs/platform/theme/common/styler'; import { isCodeEditor } from 'vs/editor/browser/editorBrowser'; import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; -import { ITextFileService } from 'vs/workbench/services/textfile/common/textfiles'; import { IEditorService, SIDE_GROUP, ACTIVE_GROUP } from 'vs/workbench/services/editor/common/editorService'; import { ViewletPanel, IViewletPanelOptions } from 'vs/workbench/browser/parts/views/panelViewlet'; import { ILabelService } from 'vs/platform/label/common/label'; @@ -296,8 +295,7 @@ class BreakpointsRenderer implements IRenderer<IBreakpoint, IBreakpointTemplateD constructor( @IDebugService private debugService: IDebugService, - @ILabelService private labelService: ILabelService, - @ITextFileService private textFileService: ITextFileService + @ILabelService private labelService: ILabelService ) { // noop } @@ -343,7 +341,7 @@ class BreakpointsRenderer implements IRenderer<IBreakpoint, IBreakpointTemplateD data.filePath.textContent = this.labelService.getUriLabel(resources.dirname(breakpoint.uri), true); data.checkbox.checked = breakpoint.enabled; - const { message, className } = getBreakpointMessageAndClassName(this.debugService, this.textFileService, breakpoint); + const { message, className } = getBreakpointMessageAndClassName(this.debugService, breakpoint); data.icon.className = className + ' icon'; data.breakpoint.title = breakpoint.message || message || ''; @@ -413,8 +411,7 @@ class ExceptionBreakpointsRenderer implements IRenderer<IExceptionBreakpoint, IB class FunctionBreakpointsRenderer implements IRenderer<FunctionBreakpoint, IBaseBreakpointWithIconTemplateData> { constructor( - @IDebugService private debugService: IDebugService, - @ITextFileService private textFileService: ITextFileService + @IDebugService private debugService: IDebugService ) { // noop } @@ -447,7 +444,7 @@ class FunctionBreakpointsRenderer implements IRenderer<FunctionBreakpoint, IBase renderElement(functionBreakpoint: FunctionBreakpoint, index: number, data: IBaseBreakpointWithIconTemplateData): void { data.context = functionBreakpoint; data.name.textContent = functionBreakpoint.name; - const { className, message } = getBreakpointMessageAndClassName(this.debugService, this.textFileService, functionBreakpoint); + const { className, message } = getBreakpointMessageAndClassName(this.debugService, functionBreakpoint); data.icon.className = className + ' icon'; data.icon.title = message ? message : ''; data.checkbox.checked = functionBreakpoint.enabled; @@ -577,7 +574,7 @@ export function openBreakpointSource(breakpoint: IBreakpoint, sideBySide: boolea }, sideBySide ? SIDE_GROUP : ACTIVE_GROUP); } -export function getBreakpointMessageAndClassName(debugService: IDebugService, textFileService: ITextFileService, breakpoint: IBreakpoint | FunctionBreakpoint): { message?: string, className: string } { +export function getBreakpointMessageAndClassName(debugService: IDebugService, breakpoint: IBreakpoint | FunctionBreakpoint): { message?: string, className: string } { const state = debugService.state; const debugActive = state === State.Running || state === State.Stopped; @@ -612,14 +609,6 @@ export function getBreakpointMessageAndClassName(debugService: IDebugService, te }; } - if (debugActive && textFileService.isDirty(breakpoint.uri)) { - return { - className: 'debug-breakpoint-unverified', - message: appendMessage(nls.localize('breakpointDirtydHover', "Unverified breakpoint. File is modified, please restart debug session.")), - }; - } - - if (breakpoint.logMessage || breakpoint.condition || breakpoint.hitCondition) { const messages = []; if (breakpoint.logMessage) { diff --git a/src/vs/workbench/parts/debug/browser/debugEditorModelManager.ts b/src/vs/workbench/parts/debug/browser/debugEditorModelManager.ts index 4b21fa882fb..185e38174a3 100644 --- a/src/vs/workbench/parts/debug/browser/debugEditorModelManager.ts +++ b/src/vs/workbench/parts/debug/browser/debugEditorModelManager.ts @@ -12,7 +12,6 @@ import { IDebugService, IBreakpoint, State, IBreakpointUpdateData } from 'vs/wor import { IModelService } from 'vs/editor/common/services/modelService'; import { MarkdownString } from 'vs/base/common/htmlContent'; import { getBreakpointMessageAndClassName } from 'vs/workbench/parts/debug/browser/breakpointsView'; -import { ITextFileService } from 'vs/workbench/services/textfile/common/textfiles'; interface IBreakpointDecoration { decorationId: string; @@ -38,7 +37,6 @@ export class DebugEditorModelManager implements IWorkbenchContribution { constructor( @IModelService private modelService: IModelService, @IDebugService private debugService: IDebugService, - @ITextFileService private textFileService: ITextFileService ) { this.modelDataMap = new Map<string, IDebugEditorModelData>(); this.toDispose = []; @@ -277,7 +275,7 @@ export class DebugEditorModelManager implements IWorkbenchContribution { } private getBreakpointDecorationOptions(breakpoint: IBreakpoint): IModelDecorationOptions { - const { className, message } = getBreakpointMessageAndClassName(this.debugService, this.textFileService, breakpoint); + const { className, message } = getBreakpointMessageAndClassName(this.debugService, breakpoint); let glyphMarginHoverMessage: MarkdownString; if (message) { diff --git a/src/vs/workbench/parts/debug/common/debugModel.ts b/src/vs/workbench/parts/debug/common/debugModel.ts index 4ff1423918e..29fbe3310dd 100644 --- a/src/vs/workbench/parts/debug/common/debugModel.ts +++ b/src/vs/workbench/parts/debug/common/debugModel.ts @@ -24,6 +24,7 @@ import { Source } from 'vs/workbench/parts/debug/common/debugSource'; import { commonSuffixLength } from 'vs/base/common/strings'; import { sep } from 'vs/base/common/paths'; import { IEditorService } from 'vs/workbench/services/editor/common/editorService'; +import { ITextFileService } from 'vs/workbench/services/textfile/common/textfiles'; const MAX_REPL_LENGTH = 10000; @@ -622,6 +623,7 @@ export class Breakpoint extends BaseBreakpoint implements IBreakpoint { hitCondition: string, logMessage: string, private _adapterData: any, + private textFileService: ITextFileService, id = generateUuid() ) { super(enabled, hitCondition, condition, logMessage, id); @@ -629,7 +631,16 @@ export class Breakpoint extends BaseBreakpoint implements IBreakpoint { public get lineNumber(): number { const data = this.getSessionData(); - return data && typeof data.line === 'number' ? data.line : this._lineNumber; + return this.verified && data && typeof data.line === 'number' ? data.line : this._lineNumber; + } + + public get verified(): boolean { + const data = this.getSessionData(); + if (data) { + return data.verified && !this.textFileService.isDirty(this.uri); + } + + return true; } public get column(): number { @@ -640,7 +651,14 @@ export class Breakpoint extends BaseBreakpoint implements IBreakpoint { public get message(): string { const data = this.getSessionData(); - return data ? data.message : undefined; + if (!data) { + return undefined; + } + if (this.textFileService.isDirty(this.uri)) { + return nls.localize('breakpointDirtydHover', "Unverified breakpoint. File is modified, please restart debug session."); + } + + return data.message; } public get adapterData(): any { @@ -695,7 +713,8 @@ export class FunctionBreakpoint extends BaseBreakpoint implements IFunctionBreak hitCondition: string, condition: string, logMessage: string, - id = generateUuid()) { + id = generateUuid() + ) { super(enabled, hitCondition, condition, logMessage, id); } @@ -748,7 +767,8 @@ export class Model implements IModel { private breakpointsActivated: boolean, private functionBreakpoints: FunctionBreakpoint[], private exceptionBreakpoints: ExceptionBreakpoint[], - private watchExpressions: Expression[] + private watchExpressions: Expression[], + private textFileService: ITextFileService ) { this.sessions = []; this.replElements = []; @@ -886,7 +906,7 @@ export class Model implements IModel { } public addBreakpoints(uri: uri, rawData: IBreakpointData[], fireEvent = true): IBreakpoint[] { - const newBreakpoints = rawData.map(rawBp => new Breakpoint(uri, rawBp.lineNumber, rawBp.column, rawBp.enabled, rawBp.condition, rawBp.hitCondition, rawBp.logMessage, undefined, rawBp.id)); + const newBreakpoints = rawData.map(rawBp => new Breakpoint(uri, rawBp.lineNumber, rawBp.column, rawBp.enabled, rawBp.condition, rawBp.hitCondition, rawBp.logMessage, undefined, this.textFileService, rawBp.id)); newBreakpoints.forEach(bp => bp.setSessionId(this.breakpointsSessionId)); this.breakpoints = this.breakpoints.concat(newBreakpoints); this.breakpointsActivated = true; diff --git a/src/vs/workbench/parts/debug/electron-browser/debugService.ts b/src/vs/workbench/parts/debug/electron-browser/debugService.ts index 9e75e40b95e..037465b796b 100644 --- a/src/vs/workbench/parts/debug/electron-browser/debugService.ts +++ b/src/vs/workbench/parts/debug/electron-browser/debugService.ts @@ -114,7 +114,7 @@ export class DebugService implements IDebugService { this.inDebugMode = CONTEXT_IN_DEBUG_MODE.bindTo(contextKeyService); this.model = new Model(this.loadBreakpoints(), this.storageService.getBoolean(DEBUG_BREAKPOINTS_ACTIVATED_KEY, StorageScope.WORKSPACE, true), this.loadFunctionBreakpoints(), - this.loadExceptionBreakpoints(), this.loadWatchExpressions()); + this.loadExceptionBreakpoints(), this.loadWatchExpressions(), this.textFileService); this.toDispose.push(this.model); this.viewModel = new ViewModel(contextKeyService); @@ -267,7 +267,7 @@ export class DebugService implements IDebugService { let result: Breakpoint[]; try { result = JSON.parse(this.storageService.get(DEBUG_BREAKPOINTS_KEY, StorageScope.WORKSPACE, '[]')).map((breakpoint: any) => { - return new Breakpoint(uri.parse(breakpoint.uri.external || breakpoint.source.uri.external), breakpoint.lineNumber, breakpoint.column, breakpoint.enabled, breakpoint.condition, breakpoint.hitCondition, breakpoint.logMessage, breakpoint.adapterData); + return new Breakpoint(uri.parse(breakpoint.uri.external || breakpoint.source.uri.external), breakpoint.lineNumber, breakpoint.column, breakpoint.enabled, breakpoint.condition, breakpoint.hitCondition, breakpoint.logMessage, breakpoint.adapterData, this.textFileService); }); } catch (e) { } diff --git a/src/vs/workbench/parts/debug/test/electron-browser/debugModel.test.ts b/src/vs/workbench/parts/debug/test/electron-browser/debugModel.test.ts index bfde392d588..d72aeacfb53 100644 --- a/src/vs/workbench/parts/debug/test/electron-browser/debugModel.test.ts +++ b/src/vs/workbench/parts/debug/test/electron-browser/debugModel.test.ts @@ -17,7 +17,7 @@ suite('Debug - Model', () => { let rawSession: MockRawSession; setup(() => { - model = new Model([], true, [], [], []); + model = new Model([], true, [], [], [], <any>{ isDirty: (e: any) => false }); rawSession = new MockRawSession(); }); From bd6bd5f73dc4500bc6e027c7a75e9df35c1ea635 Mon Sep 17 00:00:00 2001 From: Matt Bierner <matb@microsoft.com> Date: Fri, 24 Aug 2018 12:43:33 +0200 Subject: [PATCH 1217/1276] Don't try showing tiffs as images Fixes #55987 Chrome does not support displaying tiffs --- src/vs/workbench/browser/parts/editor/resourceViewer.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/vs/workbench/browser/parts/editor/resourceViewer.ts b/src/vs/workbench/browser/parts/editor/resourceViewer.ts index 61c35f3f786..f61b6d341f5 100644 --- a/src/vs/workbench/browser/parts/editor/resourceViewer.ts +++ b/src/vs/workbench/browser/parts/editor/resourceViewer.ts @@ -107,7 +107,8 @@ export class ResourceViewer { private static isImageResource(descriptor: IResourceDescriptor) { const mime = getMime(descriptor); - return mime.indexOf('image/') >= 0; + // Chrome does not support tiffs + return mime.indexOf('image/') >= 0 && mime !== 'image/tiff'; } } From 099d99b76c6c4dd3ce5b10eabecb50acd63ae8b2 Mon Sep 17 00:00:00 2001 From: Johannes Rieken <johannes.rieken@gmail.com> Date: Fri, 24 Aug 2018 14:54:50 +0200 Subject: [PATCH 1218/1276] wip --- .../extension.webpack.config.js | 23 +++++++++++++++++++ .../typescript-language-features/package.json | 8 ++++--- .../src/utils/telemetry.ts | 15 ++++++------ .../src/utils/versionProvider.ts | 6 ++--- .../typescript-language-features/yarn.lock | 12 +++++----- 5 files changed, 44 insertions(+), 20 deletions(-) create mode 100644 extensions/typescript-language-features/extension.webpack.config.js diff --git a/extensions/typescript-language-features/extension.webpack.config.js b/extensions/typescript-language-features/extension.webpack.config.js new file mode 100644 index 00000000000..664dfb35f6f --- /dev/null +++ b/extensions/typescript-language-features/extension.webpack.config.js @@ -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. + *--------------------------------------------------------------------------------------------*/ + +//@ts-check + +'use strict'; + +const withDefaults = require('../shared.webpack.config'); + +module.exports = withDefaults({ + context: __dirname, + node: { + __dirname: false, + }, + resolve: { + mainFields: ['module', 'main'] + }, + entry: { + extension: './src/extension.ts', + } +}); diff --git a/extensions/typescript-language-features/package.json b/extensions/typescript-language-features/package.json index 1f06df0476d..50a132b565b 100644 --- a/extensions/typescript-language-features/package.json +++ b/extensions/typescript-language-features/package.json @@ -17,13 +17,13 @@ ], "dependencies": { "jsonc-parser": "^2.0.1", - "semver": "4.3.6", + "semver": "5.5.1", "vscode-extension-telemetry": "0.0.18", "vscode-nls": "^3.2.4" }, "devDependencies": { "@types/node": "8.0.33", - "@types/semver": "5.4.0", + "@types/semver": "^5.5.0", "vscode": "^1.1.10" }, "scripts": { @@ -71,7 +71,9 @@ "default": false, "description": "%typescript.disableAutomaticTypeAcquisition%", "scope": "window", - "tags": ["usesOnlineServices"] + "tags": [ + "usesOnlineServices" + ] }, "typescript.npm": { "type": [ diff --git a/extensions/typescript-language-features/src/utils/telemetry.ts b/extensions/typescript-language-features/src/utils/telemetry.ts index 8f83e2cc904..4ac7a953937 100644 --- a/extensions/typescript-language-features/src/utils/telemetry.ts +++ b/extensions/typescript-language-features/src/utils/telemetry.ts @@ -3,7 +3,7 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -import * as path from 'path'; +import * as vscode from 'vscode'; import VsCodeTelemetryReporter from 'vscode-extension-telemetry'; import { memoize } from './memoize'; @@ -59,15 +59,14 @@ export default class TelemetryReporter { @memoize private get packageInfo(): IPackageInfo | null { - const packagePath = path.join(__dirname, '..', '..', 'package.json'); - const extensionPackage = require(packagePath); - if (extensionPackage) { + const { packageJSON } = vscode.extensions.getExtension('vscode.typescript-language-features')!; + if (packageJSON) { return { - name: extensionPackage.name, - version: extensionPackage.version, - aiKey: extensionPackage.aiKey + name: packageJSON.name, + version: packageJSON.version, + aiKey: packageJSON.aiKey }; } return null; } -} \ No newline at end of file +} diff --git a/extensions/typescript-language-features/src/utils/versionProvider.ts b/extensions/typescript-language-features/src/utils/versionProvider.ts index 3061f1576b9..8787d174667 100644 --- a/extensions/typescript-language-features/src/utils/versionProvider.ts +++ b/extensions/typescript-language-features/src/utils/versionProvider.ts @@ -140,9 +140,9 @@ export class TypeScriptVersionProvider { public get bundledVersion(): TypeScriptVersion { try { - const bundledVersion = new TypeScriptVersion( - path.dirname(require.resolve('typescript/lib/tsserver.js')), - ''); + const { extensionPath } = vscode.extensions.getExtension('vscode.typescript-language-features')!; + const typescriptPath = path.join(extensionPath, '../node_modules/typescript/lib'); + const bundledVersion = new TypeScriptVersion(typescriptPath, ''); if (bundledVersion.isValid) { return bundledVersion; } diff --git a/extensions/typescript-language-features/yarn.lock b/extensions/typescript-language-features/yarn.lock index b0a99345853..ccd1c649622 100644 --- a/extensions/typescript-language-features/yarn.lock +++ b/extensions/typescript-language-features/yarn.lock @@ -6,9 +6,9 @@ version "8.0.33" resolved "https://registry.yarnpkg.com/@types/node/-/node-8.0.33.tgz#1126e94374014e54478092830704f6ea89df04cd" -"@types/semver@5.4.0": - version "5.4.0" - resolved "https://registry.yarnpkg.com/@types/semver/-/semver-5.4.0.tgz#f3658535af7f1f502acd6da7daf405ffeb1f7ee4" +"@types/semver@^5.5.0": + version "5.5.0" + resolved "https://registry.yarnpkg.com/@types/semver/-/semver-5.5.0.tgz#146c2a29ee7d3bae4bf2fcb274636e264c813c45" ajv@^5.1.0: version "5.5.2" @@ -1274,9 +1274,9 @@ safe-buffer@^5.0.1, safe-buffer@^5.1.1, safe-buffer@~5.1.0, safe-buffer@~5.1.1: version "5.1.2" resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.2.tgz#991ec69d296e0313747d59bdfd2b745c35f8828d" -semver@4.3.6: - version "4.3.6" - resolved "https://registry.yarnpkg.com/semver/-/semver-4.3.6.tgz#300bc6e0e86374f7ba61068b5b1ecd57fc6532da" +semver@5.5.1: + version "5.5.1" + resolved "https://registry.yarnpkg.com/semver/-/semver-5.5.1.tgz#7dfdd8814bdb7cabc7be0fb1d734cfb66c940477" semver@^5.3.0, semver@^5.4.1: version "5.5.0" From 6ba52f7b25fa81c75064cd1e777e4b1f8a7c1103 Mon Sep 17 00:00:00 2001 From: Johannes Rieken <johannes.rieken@gmail.com> Date: Fri, 24 Aug 2018 15:04:36 +0200 Subject: [PATCH 1219/1276] copy nls --- extensions/git/extension.webpack.config.js | 1 - .../extension.webpack.config.js | 8 +++++++- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/extensions/git/extension.webpack.config.js b/extensions/git/extension.webpack.config.js index 5f3997a61ca..dd6c7a23b2d 100644 --- a/extensions/git/extension.webpack.config.js +++ b/extensions/git/extension.webpack.config.js @@ -10,7 +10,6 @@ const withDefaults = require('../shared.webpack.config'); const CopyWebpackPlugin = require('copy-webpack-plugin'); - module.exports = withDefaults({ context: __dirname, node: { diff --git a/extensions/typescript-language-features/extension.webpack.config.js b/extensions/typescript-language-features/extension.webpack.config.js index 664dfb35f6f..dd31f6c49c5 100644 --- a/extensions/typescript-language-features/extension.webpack.config.js +++ b/extensions/typescript-language-features/extension.webpack.config.js @@ -8,6 +8,7 @@ 'use strict'; const withDefaults = require('../shared.webpack.config'); +const CopyWebpackPlugin = require('copy-webpack-plugin'); module.exports = withDefaults({ context: __dirname, @@ -19,5 +20,10 @@ module.exports = withDefaults({ }, entry: { extension: './src/extension.ts', - } + }, + plugins: [ + new CopyWebpackPlugin([ + { from: './out/nls.*.json', to: '[name].json' } + ]) + ] }); From a8756e8d74f8a7f37791233981df843ba1f43b3f Mon Sep 17 00:00:00 2001 From: isidor <inikolic@microsoft.com> Date: Fri, 24 Aug 2018 15:28:05 +0200 Subject: [PATCH 1220/1276] introduce fileDialog context --- .../platform/workbench/common/contextkeys.ts | 7 +- .../electron-browser/main.contribution.ts | 102 +++++++++--------- .../workbench/electron-browser/workbench.ts | 8 +- .../fileActions.contribution.ts | 6 +- 4 files changed, 67 insertions(+), 56 deletions(-) diff --git a/src/vs/platform/workbench/common/contextkeys.ts b/src/vs/platform/workbench/common/contextkeys.ts index c4a740d8c28..d513b3e6c91 100644 --- a/src/vs/platform/workbench/common/contextkeys.ts +++ b/src/vs/platform/workbench/common/contextkeys.ts @@ -6,6 +6,11 @@ 'use strict'; import { RawContextKey } from 'vs/platform/contextkey/common/contextkey'; +import { isMacintosh, isLinux, isWindows } from 'vs/base/common/platform'; export const InputFocusedContextKey = 'inputFocus'; -export const InputFocusedContext = new RawContextKey<boolean>(InputFocusedContextKey, false); \ No newline at end of file +export const InputFocusedContext = new RawContextKey<boolean>(InputFocusedContextKey, false); +export const FileDialogContext = new RawContextKey<string>('fileDialog', 'local'); +export const IsMacContext = new RawContextKey<boolean>('isMac', isMacintosh); +export const IsLinuxContext = new RawContextKey<boolean>('isLinux', isLinux); +export const IsWindowsContext = new RawContextKey<boolean>('isWindows', isWindows); diff --git a/src/vs/workbench/electron-browser/main.contribution.ts b/src/vs/workbench/electron-browser/main.contribution.ts index b5ea1f2025f..14cc4706bbd 100644 --- a/src/vs/workbench/electron-browser/main.contribution.ts +++ b/src/vs/workbench/electron-browser/main.contribution.ts @@ -22,6 +22,8 @@ import { inQuickOpenContext, getQuickNavigateHandler } from 'vs/workbench/browse import { KeybindingsRegistry, KeybindingWeight } from 'vs/platform/keybinding/common/keybindingsRegistry'; import { CommandsRegistry } from 'vs/platform/commands/common/commands'; import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; +import { ADD_ROOT_FOLDER_COMMAND_ID } from 'vs/workbench/browser/actions/workspaceCommands'; +import { FileDialogContext, IsMacContext } from 'vs/platform/workbench/common/contextkeys'; // Contribute Commands registerCommands(); @@ -161,34 +163,35 @@ MenuRegistry.appendMenuItem(MenuId.MenubarFileMenu, { order: 2 }); -if (!isMacintosh) { - 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: OpenFileAction.ID, + title: nls.localize({ key: 'miOpenFile', comment: ['&& denotes a mnemonic'] }, "&&Open File...") + }, + order: 1, + when: ContextKeyExpr.and(IsMacContext.toNegated(), FileDialogContext.isEqualTo('local')) +}); - MenuRegistry.appendMenuItem(MenuId.MenubarFileMenu, { - group: '2_open', - command: { - id: OpenFolderAction.ID, - title: nls.localize({ key: 'miOpenFolder', comment: ['&& denotes a mnemonic'] }, "Open &&Folder...") - }, - order: 2 - }); -} else { - MenuRegistry.appendMenuItem(MenuId.MenubarFileMenu, { - group: '2_open', - command: { - id: OpenFileFolderAction.ID, - title: nls.localize({ key: 'miOpen', comment: ['&& denotes a mnemonic'] }, "&&Open...") - }, - 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, + when: ContextKeyExpr.and(IsMacContext.toNegated(), FileDialogContext.isEqualTo('local')) +}); + +MenuRegistry.appendMenuItem(MenuId.MenubarFileMenu, { + group: '2_open', + command: { + id: OpenFileFolderAction.ID, + title: nls.localize({ key: 'miOpen', comment: ['&& denotes a mnemonic'] }, "&&Open...") + }, + order: 1, + when: ContextKeyExpr.and(IsMacContext, FileDialogContext.isEqualTo('local')) +}); MenuRegistry.appendMenuItem(MenuId.MenubarFileMenu, { group: '2_open', @@ -196,7 +199,8 @@ MenuRegistry.appendMenuItem(MenuId.MenubarFileMenu, { id: OpenWorkspaceAction.ID, title: nls.localize({ key: 'miOpenWorkspace', comment: ['&& denotes a mnemonic'] }, "Open Wor&&kspace...") }, - order: 3 + order: 3, + when: FileDialogContext.isEqualTo('local') }); MenuRegistry.appendMenuItem(MenuId.MenubarFileMenu, { @@ -220,10 +224,11 @@ MenuRegistry.appendMenuItem(MenuId.MenubarRecentMenu, { MenuRegistry.appendMenuItem(MenuId.MenubarFileMenu, { group: '3_workspace', command: { - id: AddRootFolderAction.ID, + id: ADD_ROOT_FOLDER_COMMAND_ID, title: nls.localize({ key: 'miAddFolderToWorkspace', comment: ['&& denotes a mnemonic'] }, "A&&dd Folder to Workspace...") }, - order: 1 + order: 1, + when: FileDialogContext.isEqualTo('local') }); MenuRegistry.appendMenuItem(MenuId.MenubarFileMenu, { @@ -232,17 +237,17 @@ MenuRegistry.appendMenuItem(MenuId.MenubarFileMenu, { id: SaveWorkspaceAsAction.ID, title: nls.localize('miSaveWorkspaceAs', "Save Workspace As...") }, - order: 2 + order: 2, + when: FileDialogContext.isEqualTo('local') }); -if (!isMacintosh) { - MenuRegistry.appendMenuItem(MenuId.MenubarFileMenu, { - title: nls.localize({ key: 'miPreferences', comment: ['&& denotes a mnemonic'] }, "&&Preferences"), - submenu: MenuId.MenubarPreferencesMenu, - group: '5_autosave', - order: 2 - }); -} +MenuRegistry.appendMenuItem(MenuId.MenubarFileMenu, { + title: nls.localize({ key: 'miPreferences', comment: ['&& denotes a mnemonic'] }, "&&Preferences"), + submenu: MenuId.MenubarPreferencesMenu, + group: '5_autosave', + order: 2, + when: IsMacContext.toNegated() +}); MenuRegistry.appendMenuItem(MenuId.MenubarFileMenu, { group: '6_close', @@ -455,16 +460,15 @@ MenuRegistry.appendMenuItem(MenuId.MenubarHelpMenu, { }); // About -if (!isMacintosh) { - MenuRegistry.appendMenuItem(MenuId.MenubarHelpMenu, { - group: 'z_about', - command: { - id: 'workbench.action.showAboutDialog', - title: nls.localize({ key: 'miAbout', comment: ['&& denotes a mnemonic'] }, "&&About") - }, - order: 1 - }); -} +MenuRegistry.appendMenuItem(MenuId.MenubarHelpMenu, { + group: 'z_about', + command: { + id: 'workbench.action.showAboutDialog', + title: nls.localize({ key: 'miAbout', comment: ['&& denotes a mnemonic'] }, "&&About") + }, + order: 1, + when: IsMacContext.toNegated() +}); // Configuration: Workbench const configurationRegistry = Registry.as<IConfigurationRegistry>(ConfigurationExtensions.Configuration); diff --git a/src/vs/workbench/electron-browser/workbench.ts b/src/vs/workbench/electron-browser/workbench.ts index b469db36738..1295eac41da 100644 --- a/src/vs/workbench/electron-browser/workbench.ts +++ b/src/vs/workbench/electron-browser/workbench.ts @@ -93,7 +93,7 @@ import { IDecorationsService } from 'vs/workbench/services/decorations/browser/d import { ActivityService } from 'vs/workbench/services/activity/browser/activityService'; import URI from 'vs/base/common/uri'; import { IListService, ListService } from 'vs/platform/list/browser/listService'; -import { InputFocusedContext } from 'vs/platform/workbench/common/contextkeys'; +import { InputFocusedContext, IsMacContext, IsLinuxContext, IsWindowsContext } from 'vs/platform/workbench/common/contextkeys'; import { IViewsService } from 'vs/workbench/common/views'; import { ViewsService } from 'vs/workbench/browser/parts/views/views'; import { INotificationService } from 'vs/platform/notification/common/notification'; @@ -613,9 +613,9 @@ export class Workbench extends Disposable implements IPartService { private handleContextKeys(): void { this.inZenMode = InEditorZenModeContext.bindTo(this.contextKeyService); - (new RawContextKey<boolean>('isMac', isMacintosh)).bindTo(this.contextKeyService); - (new RawContextKey<boolean>('isLinux', isLinux)).bindTo(this.contextKeyService); - (new RawContextKey<boolean>('isWindows', isWindows)).bindTo(this.contextKeyService); + IsMacContext.bindTo(this.contextKeyService); + IsLinuxContext.bindTo(this.contextKeyService); + IsWindowsContext.bindTo(this.contextKeyService); const sidebarVisibleContextRaw = new RawContextKey<boolean>('sidebarVisible', false); this.sideBarVisibleContext = sidebarVisibleContextRaw.bindTo(this.contextKeyService); diff --git a/src/vs/workbench/parts/files/electron-browser/fileActions.contribution.ts b/src/vs/workbench/parts/files/electron-browser/fileActions.contribution.ts index 7a417cc526c..3dc3343b7eb 100644 --- a/src/vs/workbench/parts/files/electron-browser/fileActions.contribution.ts +++ b/src/vs/workbench/parts/files/electron-browser/fileActions.contribution.ts @@ -25,6 +25,7 @@ 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 { FileDialogContext } from 'vs/platform/workbench/common/contextkeys'; // Contribute Global Actions const category = nls.localize('filesCategory', "File"); @@ -425,7 +426,7 @@ MenuRegistry.appendMenuItem(MenuId.ExplorerContext, { id: ADD_ROOT_FOLDER_COMMAND_ID, title: ADD_ROOT_FOLDER_LABEL }, - when: ExplorerRootContext + when: ContextKeyExpr.and(ExplorerRootContext, FileDialogContext.isEqualTo('local')) }); MenuRegistry.appendMenuItem(MenuId.ExplorerContext, { @@ -505,7 +506,8 @@ MenuRegistry.appendMenuItem(MenuId.MenubarFileMenu, { id: SAVE_FILE_AS_COMMAND_ID, title: nls.localize({ key: 'miSaveAs', comment: ['&& denotes a mnemonic'] }, "Save &&As...") }, - order: 2 + order: 2, + when: FileDialogContext.isEqualTo('local') }); MenuRegistry.appendMenuItem(MenuId.MenubarFileMenu, { From a8d7c6343c03f2d4760610853996be2abbb7257a Mon Sep 17 00:00:00 2001 From: Matt Bierner <matb@microsoft.com> Date: Fri, 24 Aug 2018 14:51:42 +0200 Subject: [PATCH 1221/1276] Don't request refactorings for empty selections --- .../typescript-language-features/src/features/refactor.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/extensions/typescript-language-features/src/features/refactor.ts b/extensions/typescript-language-features/src/features/refactor.ts index bdc5d4eb25e..7817a2fef68 100644 --- a/extensions/typescript-language-features/src/features/refactor.ts +++ b/extensions/typescript-language-features/src/features/refactor.ts @@ -200,7 +200,7 @@ class TypeScriptRefactorProvider implements vscode.CodeActionProvider { return false; } - return rangeOrSelection instanceof vscode.Selection; + return rangeOrSelection instanceof vscode.Selection && !rangeOrSelection.isEmpty; } private static getKind(refactor: Proto.RefactorActionInfo) { From cd9beb845cb50c7dd639fa23e0868d0b961880df Mon Sep 17 00:00:00 2001 From: Matt Bierner <matb@microsoft.com> Date: Fri, 24 Aug 2018 16:02:32 +0200 Subject: [PATCH 1222/1276] Disable node_modules check for update paths on file rename Fixes #55882 This check was originally added to workaround a TS issue which should now be fixed. If it is not fixed, we want to know about it so that we can get TS to fix it upstream --- .../src/features/updatePathsOnRename.ts | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/extensions/typescript-language-features/src/features/updatePathsOnRename.ts b/extensions/typescript-language-features/src/features/updatePathsOnRename.ts index 44c05cd7b4a..3d266ef00ec 100644 --- a/extensions/typescript-language-features/src/features/updatePathsOnRename.ts +++ b/extensions/typescript-language-features/src/features/updatePathsOnRename.ts @@ -245,13 +245,15 @@ class UpdateImportsOnFileRenameHandler { const edits: Proto.FileCodeEdits[] = []; for (const edit of response.body) { // Workaround for https://github.com/Microsoft/vscode/issues/52675 - if ((edit as Proto.FileCodeEdits).fileName.match(/[\/\\]node_modules[\/\\]/gi)) { - continue; - } - for (const change of (edit as Proto.FileCodeEdits).textChanges) { - if (change.newText.match(/\/node_modules\//gi)) { + if (!this.client.apiVersion.gte(API.v300)) { + if ((edit as Proto.FileCodeEdits).fileName.match(/[\/\\]node_modules[\/\\]/gi)) { continue; } + for (const change of (edit as Proto.FileCodeEdits).textChanges) { + if (change.newText.match(/\/node_modules\//gi)) { + continue; + } + } } edits.push(await this.fixEdit(edit, isDirectoryRename, oldFile, newFile)); From 2f0a98d288c4ae6ae5e2afe28d255d429ce783ec Mon Sep 17 00:00:00 2001 From: isidor <inikolic@microsoft.com> Date: Fri, 24 Aug 2018 16:20:39 +0200 Subject: [PATCH 1223/1276] explorer: always show root if it can not be resolved fixes #54988 --- .../electron-browser/views/explorerView.ts | 27 ++++++++++++------- 1 file changed, 17 insertions(+), 10 deletions(-) diff --git a/src/vs/workbench/parts/files/electron-browser/views/explorerView.ts b/src/vs/workbench/parts/files/electron-browser/views/explorerView.ts index d97f3fba2d4..175ad41be2e 100644 --- a/src/vs/workbench/parts/files/electron-browser/views/explorerView.ts +++ b/src/vs/workbench/parts/files/electron-browser/views/explorerView.ts @@ -801,14 +801,21 @@ export class ExplorerView extends TreeViewsViewletPanel implements IExplorerView private resolveRoots(targetsToResolve: { root: ExplorerItem, resource: URI, options: { resolveTo: any[] } }[], targetsToExpand: URI[]): TPromise<any> { // Display roots only when multi folder workspace - const input = this.contextService.getWorkbenchState() === WorkbenchState.FOLDER ? this.model.roots[0] : this.model; - const errorFileStat = (resource: URI, root: ExplorerItem) => ExplorerItem.create({ - resource: resource, - name: paths.basename(resource.fsPath), - mtime: 0, - etag: undefined, - isDirectory: true - }, root, undefined, true); + let input = this.contextService.getWorkbenchState() === WorkbenchState.FOLDER ? this.model.roots[0] : this.model; + + const errorRoot = (resource: URI, root: ExplorerItem) => { + if (input === this.model.roots[0]) { + input = this.model; + } + + return ExplorerItem.create({ + resource: resource, + name: paths.basename(resource.fsPath), + mtime: 0, + etag: undefined, + isDirectory: true + }, root, undefined, true); + }; const setInputAndExpand = (input: ExplorerItem | Model, statsToExpand: ExplorerItem[]) => { // Make sure to expand all folders that where expanded in the previous session @@ -829,7 +836,7 @@ export class ExplorerView extends TreeViewsViewletPanel implements IExplorerView return ExplorerItem.create(result.stat, targetsToResolve[index].root, targetsToResolve[index].options.resolveTo); } - return errorFileStat(targetsToResolve[index].resource, targetsToResolve[index].root); + return errorRoot(targetsToResolve[index].resource, targetsToResolve[index].root); }); // Subsequent refresh: Merge stat into our local model and refresh tree modelStats.forEach((modelStat, index) => { @@ -852,7 +859,7 @@ export class ExplorerView extends TreeViewsViewletPanel implements IExplorerView let delayer = new Delayer(100); let delayerPromise: TPromise; return TPromise.join(targetsToResolve.map((target, index) => this.fileService.resolveFile(target.resource, target.options) - .then(result => result.isDirectory ? ExplorerItem.create(result, target.root, target.options.resolveTo) : errorFileStat(target.resource, target.root), () => errorFileStat(target.resource, target.root)) + .then(result => result.isDirectory ? ExplorerItem.create(result, target.root, target.options.resolveTo) : errorRoot(target.resource, target.root), () => errorRoot(target.resource, target.root)) .then(modelStat => { // Subsequent refresh: Merge stat into our local model and refresh tree if (index < this.model.roots.length) { From ad972a1d3ea04f539cc20250365cb53427358068 Mon Sep 17 00:00:00 2001 From: Benjamin Pasero <benjpas@microsoft.com> Date: Fri, 24 Aug 2018 16:27:23 +0200 Subject: [PATCH 1224/1276] debt - deprecate builder and remove usage in some places --- src/vs/base/browser/builder.ts | 58 ++++++------- src/vs/base/browser/ui/button/button.ts | 86 +++++++++---------- .../browser/ui/progressbar/progressbar.ts | 60 +++++++------ src/vs/base/test/browser/builder.test.ts | 48 +++++------ .../contextview/browser/contextMenuHandler.ts | 13 +-- .../commentsEditorContribution.ts | 4 +- .../electron-browser/feedbackStatusbarItem.ts | 13 ++- .../files/electron-browser/views/emptyView.ts | 30 ++++--- .../parts/search/browser/searchView.ts | 2 +- .../parts/search/browser/searchWidget.ts | 9 +- 10 files changed, 166 insertions(+), 157 deletions(-) diff --git a/src/vs/base/browser/builder.ts b/src/vs/base/browser/builder.ts index 9c285274a99..6abfaece89d 100644 --- a/src/vs/base/browser/builder.ts +++ b/src/vs/base/browser/builder.ts @@ -12,23 +12,9 @@ import * as assert from 'vs/base/common/assert'; import * as DOM from 'vs/base/browser/dom'; /** - * Welcome to the monaco builder. The recommended way to use it is: + * !!! DO NOT USE. USE vs/base/browser/dom.$ INSTEAD !!! * - * import Builder = require('vs/base/browser/builder'); - * let $ = Builder.$; - * $(....).fn(...); - * - * See below for examples how to invoke the $(): - * - * $() - creates an offdom builder - * $(builder) - wraps the given builder - * $(builder[]) - wraps the given builders into a multibuilder - * $('div') - creates a div - * $('.big') - creates a div with class `big` - * $('#head') - creates a div with id `head` - * $('ul#head') - creates an unordered list with id `head` - * $('<a href="back"></a>') - constructs a builder from the given HTML - * $('a', { href: 'back'}) - constructs a builder, similarly to the Builder#element() call + * @deprecated !!! DO NOT USE. USE vs/base/browser/dom.$ INSTEAD !!! */ export interface QuickBuilder { (): Builder; @@ -62,7 +48,9 @@ function hasData(element: any): boolean { } /** - * Wraps around the provided element to manipulate it and add more child elements. + * !!! DO NOT USE. USE vs/base/browser/dom.$ INSTEAD !!! + * + * @deprecated !!! DO NOT USE. USE vs/base/browser/dom.$ INSTEAD !!! */ export class Builder implements IDisposable { private currentElement: HTMLElement; @@ -199,7 +187,7 @@ export class Builder implements IDisposable { assert.ok(child, 'Need a child to append'); if (DOM.isHTMLElement(child)) { - child = withElement(child); + child = _withElement(child); } assert.ok(child instanceof Builder || child instanceof MultiBuilder, 'Need a child to append'); @@ -1018,7 +1006,7 @@ export class Builder implements IDisposable { * Allows to store arbritary data into the current element. */ setProperty(key: string, value: any): Builder { - setPropertyOnElement(this.currentElement, key, value); + _setPropertyOnElement(this.currentElement, key, value); return this; } @@ -1027,7 +1015,7 @@ export class Builder implements IDisposable { * Allows to get arbritary data from the current element. */ getProperty(key: string, fallback?: any): any { - return getPropertyFromElement(this.currentElement, key, fallback); + return _getPropertyFromElement(this.currentElement, key, fallback); } /** @@ -1047,7 +1035,7 @@ export class Builder implements IDisposable { child(index = 0): Builder { let children = this.currentElement.children; - return withElement(<HTMLElement>children.item(index)); + return _withElement(<HTMLElement>children.item(index)); } /** @@ -1191,8 +1179,9 @@ export class Builder implements IDisposable { } /** - * The multi builder provides the same methods as the builder, but allows to call - * them on an array of builders. + * !!! DO NOT USE. USE vs/base/browser/dom.$ INSTEAD !!! + * + * @deprecated !!! DO NOT USE. USE vs/base/browser/dom.$ INSTEAD !!! */ export class MultiBuilder extends Builder { @@ -1215,7 +1204,7 @@ export class MultiBuilder extends Builder { if (types.isArray(builders)) { for (let i = 0; i < builders.length; i++) { if (builders[i] instanceof HTMLElement) { - this.push(withElement(builders[i])); + this.push(_withElement(builders[i])); } else { this.push(builders[i]); } @@ -1302,7 +1291,7 @@ function withBuilder(builder: Builder, offdom?: boolean): Builder { return new Builder(builder.getHTMLElement(), offdom); } -export function withElement(element: HTMLElement, offdom?: boolean): Builder { +export function _withElement(element: HTMLElement, offdom?: boolean): Builder { return new Builder(element, offdom); } @@ -1315,14 +1304,14 @@ function offDOM(): Builder { /** * Allows to store arbritary data into element. */ -export function setPropertyOnElement(element: HTMLElement, key: string, value: any): void { +export function _setPropertyOnElement(element: HTMLElement, key: string, value: any): void { data(element)[key] = value; } /** * Allows to get arbritary data from element. */ -export function getPropertyFromElement(element: HTMLElement, key: string, fallback?: any): any { +export function _getPropertyFromElement(element: HTMLElement, key: string, fallback?: any): any { if (hasData(element)) { let value = data(element)[key]; if (!types.isUndefined(value)) { @@ -1337,12 +1326,17 @@ export function getPropertyFromElement(element: HTMLElement, key: string, fallba * Adds the provided object as property to the given element. Call getBinding() * to retrieve it again. */ -export function bindElement(element: HTMLElement, object: any): void { - setPropertyOnElement(element, DATA_BINDING_ID, object); +export function _bindElement(element: HTMLElement, object: any): void { + _setPropertyOnElement(element, DATA_BINDING_ID, object); } let SELECTOR_REGEX = /([\w\-]+)?(#([\w\-]+))?((.([\w\-]+))*)/; +/** + * !!! DO NOT USE. USE vs/base/browser/dom.$ INSTEAD !!! + * + * @deprecated !!! DO NOT USE. USE vs/base/browser/dom.$ INSTEAD !!! + */ export const $: QuickBuilder = function (arg?: any): Builder { // Off-DOM use @@ -1357,7 +1351,7 @@ export const $: QuickBuilder = function (arg?: any): Builder { // Wrap the given element if (DOM.isHTMLElement(arg) || arg === window) { - return withElement(arg); + return _withElement(arg); } // Wrap the given builders @@ -1386,14 +1380,14 @@ export const $: QuickBuilder = function (arg?: any): Builder { element = container.firstChild; container.removeChild(element); - return withElement(<HTMLElement>element); + return _withElement(<HTMLElement>element); } let builders: Builder[] = []; while (container.firstChild) { element = container.firstChild; container.removeChild(element); - builders.push(withElement(<HTMLElement>element)); + builders.push(_withElement(<HTMLElement>element)); } return new MultiBuilder(builders); diff --git a/src/vs/base/browser/ui/button/button.ts b/src/vs/base/browser/ui/button/button.ts index dec147c543d..0ac9201ce67 100644 --- a/src/vs/base/browser/ui/button/button.ts +++ b/src/vs/base/browser/ui/button/button.ts @@ -7,14 +7,13 @@ import 'vs/css!./button'; import * as DOM from 'vs/base/browser/dom'; -import { Builder, $ } from 'vs/base/browser/builder'; import { StandardKeyboardEvent } from 'vs/base/browser/keyboardEvent'; import { KeyCode } from 'vs/base/common/keyCodes'; import { Color } from 'vs/base/common/color'; import { mixin } from 'vs/base/common/objects'; import { Event as BaseEvent, Emitter } from 'vs/base/common/event'; import { Disposable } from 'vs/base/common/lifecycle'; -import { Gesture, EventType } from 'vs/base/browser/touch'; +import { Gesture } from 'vs/base/browser/touch'; export interface IButtonOptions extends IButtonStyles { title?: boolean; @@ -35,7 +34,7 @@ const defaultOptions: IButtonStyles = { export class Button extends Disposable { - private $el: Builder; + private $el: HTMLElement; private options: IButtonOptions; private buttonBackground: Color; @@ -59,50 +58,52 @@ export class Button extends Disposable { this.buttonForeground = this.options.buttonForeground; this.buttonBorder = this.options.buttonBorder; - this.$el = this._register($('a.monaco-button').attr({ - 'tabIndex': '0', - 'role': 'button' - }).appendTo(container)); + this.$el = document.createElement('a'); + DOM.addClass(this.$el, 'monaco-button'); + this.$el.tabIndex = 0; + this.$el.setAttribute('role', 'button'); - Gesture.addTarget(this.$el.getHTMLElement()); + container.appendChild(this.$el); - this.$el.on([DOM.EventType.CLICK, EventType.Tap], e => { + Gesture.addTarget(this.$el); + + this._register(DOM.addDisposableListener(this.$el, DOM.EventType.CLICK, e => { if (!this.enabled) { DOM.EventHelper.stop(e); return; } this._onDidClick.fire(e); - }); + })); - this.$el.on(DOM.EventType.KEY_DOWN, e => { + this._register(DOM.addDisposableListener(this.$el, DOM.EventType.KEY_DOWN, e => { const event = new StandardKeyboardEvent(e as KeyboardEvent); let eventHandled = false; if (this.enabled && event.equals(KeyCode.Enter) || event.equals(KeyCode.Space)) { this._onDidClick.fire(e); eventHandled = true; } else if (event.equals(KeyCode.Escape)) { - this.$el.domBlur(); + this.$el.blur(); eventHandled = true; } if (eventHandled) { DOM.EventHelper.stop(event, true); } - }); + })); - this.$el.on(DOM.EventType.MOUSE_OVER, e => { - if (!this.$el.hasClass('disabled')) { + this._register(DOM.addDisposableListener(this.$el, DOM.EventType.MOUSE_OVER, e => { + if (!DOM.hasClass(this.$el, 'disabled')) { this.setHoverBackground(); } - }); + })); - this.$el.on(DOM.EventType.MOUSE_OUT, e => { + this._register(DOM.addDisposableListener(this.$el, DOM.EventType.MOUSE_OUT, e => { this.applyStyles(); // restore standard styles - }); + })); // Also set hover background when button is focused for feedback - this.focusTracker = this._register(DOM.trackFocus(this.$el.getHTMLElement())); + this.focusTracker = this._register(DOM.trackFocus(this.$el)); this._register(this.focusTracker.onDidFocus(() => this.setHoverBackground())); this._register(this.focusTracker.onDidBlur(() => this.applyStyles())); // restore standard styles @@ -112,7 +113,7 @@ export class Button extends Disposable { private setHoverBackground(): void { const hoverBackground = this.buttonHoverBackground ? this.buttonHoverBackground.toString() : null; if (hoverBackground) { - this.$el.style('background-color', hoverBackground); + this.$el.style.backgroundColor = hoverBackground; } } @@ -131,53 +132,51 @@ export class Button extends Disposable { const foreground = this.buttonForeground ? this.buttonForeground.toString() : null; const border = this.buttonBorder ? this.buttonBorder.toString() : null; - this.$el.style('color', foreground); - this.$el.style('background-color', background); + this.$el.style.color = foreground; + this.$el.style.backgroundColor = background; - this.$el.style('border-width', border ? '1px' : null); - this.$el.style('border-style', border ? 'solid' : null); - this.$el.style('border-color', border); + this.$el.style.borderWidth = border ? '1px' : null; + this.$el.style.borderStyle = border ? 'solid' : null; + this.$el.style.borderColor = border; } } get element(): HTMLElement { - return this.$el.getHTMLElement(); + return this.$el; } set label(value: string) { - if (!this.$el.hasClass('monaco-text-button')) { - this.$el.addClass('monaco-text-button'); + if (!DOM.hasClass(this.$el, 'monaco-text-button')) { + DOM.addClass(this.$el, 'monaco-text-button'); } - this.$el.text(value); + this.$el.innerText = value; if (this.options.title) { - this.$el.title(value); + this.$el.title = value; } } set icon(iconClassName: string) { - this.$el.addClass(iconClassName); + DOM.addClass(this.$el, iconClassName); } set enabled(value: boolean) { if (value) { - this.$el.removeClass('disabled'); - this.$el.attr({ - 'aria-disabled': 'false', - 'tabIndex': '0' - }); + DOM.removeClass(this.$el, 'disabled'); + this.$el.setAttribute('aria-disabled', String(false)); + this.$el.tabIndex = 0; } else { - this.$el.addClass('disabled'); - this.$el.attr('aria-disabled', String(true)); - DOM.removeTabIndexAndUpdateFocus(this.$el.getHTMLElement()); + DOM.addClass(this.$el, 'disabled'); + this.$el.setAttribute('aria-disabled', String(true)); + DOM.removeTabIndexAndUpdateFocus(this.$el); } } get enabled() { - return !this.$el.hasClass('disabled'); + return !DOM.hasClass(this.$el, 'disabled'); } focus(): void { - this.$el.domFocus(); + this.$el.focus(); } } @@ -201,7 +200,7 @@ export class ButtonGroup extends Disposable { // Implement keyboard access in buttons if there are multiple if (count > 1) { - $(button.element).on(DOM.EventType.KEY_DOWN, e => { + this._register(DOM.addDisposableListener(button.element, DOM.EventType.KEY_DOWN, e => { const event = new StandardKeyboardEvent(e as KeyboardEvent); let eventHandled = true; @@ -219,7 +218,8 @@ export class ButtonGroup extends Disposable { this._buttons[buttonIndexToFocus].focus(); DOM.EventHelper.stop(e, true); } - }, this.toDispose); + + })); } } } diff --git a/src/vs/base/browser/ui/progressbar/progressbar.ts b/src/vs/base/browser/ui/progressbar/progressbar.ts index 602b7d93dd9..5db9797a33a 100644 --- a/src/vs/base/browser/ui/progressbar/progressbar.ts +++ b/src/vs/base/browser/ui/progressbar/progressbar.ts @@ -7,10 +7,11 @@ import 'vs/css!./progressbar'; import * as assert from 'vs/base/common/assert'; -import { Builder, $ } from 'vs/base/browser/builder'; import { Disposable } from 'vs/base/common/lifecycle'; import { Color } from 'vs/base/common/color'; import { mixin } from 'vs/base/common/objects'; +import { removeClasses, addClass, hasClass, addClasses, removeClass, hide, show } from 'vs/base/browser/dom'; +import { RunOnceScheduler } from 'vs/base/common/async'; const css_done = 'done'; const css_active = 'active'; @@ -36,10 +37,11 @@ const defaultOpts = { export class ProgressBar extends Disposable { private options: IProgressBarOptions; private workedVal: number; - private element: Builder; + private element: HTMLElement; private bit: HTMLElement; private totalWork: number; private progressBarBackground: Color; + private showDelayedScheduler: RunOnceScheduler; constructor(container: HTMLElement, options?: IProgressBarOptions) { super(); @@ -51,14 +53,19 @@ export class ProgressBar extends Disposable { this.progressBarBackground = this.options.progressBarBackground; + this._register(this.showDelayedScheduler = new RunOnceScheduler(() => show(this.element), 0)); + this.create(container); } private create(container: HTMLElement): void { - $(container).div({ 'class': css_progress_container }, builder => { - this.element = builder.clone(); - this.bit = builder.div({ 'class': css_progress_bit }).getHTMLElement(); - }); + this.element = document.createElement('div'); + addClass(this.element, css_progress_container); + container.appendChild(this.element); + + this.bit = document.createElement('div'); + addClass(this.bit, css_progress_bit); + this.element.appendChild(this.bit); this.applyStyles(); } @@ -66,9 +73,7 @@ export class ProgressBar extends Disposable { private off(): void { this.bit.style.width = 'inherit'; this.bit.style.opacity = '1'; - this.element.removeClass(css_active); - this.element.removeClass(css_infinite); - this.element.removeClass(css_discrete); + removeClasses(this.element, css_active, css_infinite, css_discrete); this.workedVal = 0; this.totalWork = undefined; @@ -89,10 +94,10 @@ export class ProgressBar extends Disposable { } private doDone(delayed: boolean): ProgressBar { - this.element.addClass(css_done); + addClass(this.element, css_done); // let it grow to 100% width and hide afterwards - if (!this.element.hasClass(css_infinite)) { + if (!hasClass(this.element, css_infinite)) { this.bit.style.width = 'inherit'; if (delayed) { @@ -122,10 +127,8 @@ export class ProgressBar extends Disposable { this.bit.style.width = '2%'; this.bit.style.opacity = '1'; - this.element.removeClass(css_discrete); - this.element.removeClass(css_done); - this.element.addClass(css_active); - this.element.addClass(css_infinite); + removeClasses(this.element, css_discrete, css_done); + addClasses(this.element, css_active, css_infinite); return this; } @@ -176,20 +179,20 @@ export class ProgressBar extends Disposable { this.workedVal = value; this.workedVal = Math.min(this.totalWork, this.workedVal); - if (this.element.hasClass(css_infinite)) { - this.element.removeClass(css_infinite); + if (hasClass(this.element, css_infinite)) { + removeClass(this.element, css_infinite); } - if (this.element.hasClass(css_done)) { - this.element.removeClass(css_done); + if (hasClass(this.element, css_done)) { + removeClass(this.element, css_done); } - if (!this.element.hasClass(css_active)) { - this.element.addClass(css_active); + if (!hasClass(this.element, css_active)) { + addClass(this.element, css_active); } - if (!this.element.hasClass(css_discrete)) { - this.element.addClass(css_discrete); + if (!hasClass(this.element, css_discrete)) { + addClass(this.element, css_discrete); } this.bit.style.width = 100 * (this.workedVal / this.totalWork) + '%'; @@ -198,19 +201,22 @@ export class ProgressBar extends Disposable { } getContainer(): HTMLElement { - return this.element.getHTMLElement(); + return this.element; } show(delay?: number): void { + this.showDelayedScheduler.cancel(); + if (typeof delay === 'number') { - this.element.showDelayed(delay); + this.showDelayedScheduler.schedule(delay); } else { - this.element.show(); + show(this.element); } } hide(): void { - this.element.hide(); + hide(this.element); + this.showDelayedScheduler.cancel(); } style(styles: IProgressBarStyles): void { diff --git a/src/vs/base/test/browser/builder.test.ts b/src/vs/base/test/browser/builder.test.ts index d46dff04c97..f592174bd50 100644 --- a/src/vs/base/test/browser/builder.test.ts +++ b/src/vs/base/test/browser/builder.test.ts @@ -5,7 +5,7 @@ 'use strict'; import * as assert from 'assert'; -import { Builder, MultiBuilder, $, bindElement, withElement, setPropertyOnElement, getPropertyFromElement } from 'vs/base/browser/builder'; +import { Builder, MultiBuilder, $, _bindElement, _withElement, _setPropertyOnElement, _getPropertyFromElement } from 'vs/base/browser/builder'; import * as Types from 'vs/base/common/types'; import * as DomUtils from 'vs/base/browser/dom'; import { IDisposable } from 'vs/base/common/lifecycle'; @@ -48,7 +48,7 @@ function select(builder: Builder, selector: string, offdom?: boolean): MultiBuil let builders: Builder[] = []; for (let i = 0; i < elements.length; i++) { - builders.push(withElement(<HTMLElement>elements.item(i), offdom)); + builders.push(_withElement(<HTMLElement>elements.item(i), offdom)); } return new MultiBuilder(builders); @@ -75,17 +75,17 @@ suite('Builder', () => { assert(element); // Properties - setPropertyOnElement(element, 'foo', 'bar'); - assert.strictEqual(getPropertyFromElement(element, 'foo'), 'bar'); + _setPropertyOnElement(element, 'foo', 'bar'); + assert.strictEqual(_getPropertyFromElement(element, 'foo'), 'bar'); - setPropertyOnElement(element, 'foo', { foo: 'bar' }); - assert.deepEqual(getPropertyFromElement(element, 'foo'), { foo: 'bar' }); + _setPropertyOnElement(element, 'foo', { foo: 'bar' }); + assert.deepEqual(_getPropertyFromElement(element, 'foo'), { foo: 'bar' }); - setPropertyOnElement(element, 'bar', 'bar'); - assert.strictEqual(getPropertyFromElement(element, 'bar'), 'bar'); + _setPropertyOnElement(element, 'bar', 'bar'); + assert.strictEqual(_getPropertyFromElement(element, 'bar'), 'bar'); - setPropertyOnElement(element, 'bar', { foo: 'bar' }); - assert.deepEqual(getPropertyFromElement(element, 'bar'), { foo: 'bar' }); + _setPropertyOnElement(element, 'bar', { foo: 'bar' }); + assert.deepEqual(_getPropertyFromElement(element, 'bar'), { foo: 'bar' }); }); test('Select', function () { @@ -801,7 +801,7 @@ suite('Builder', () => { let counter7 = 0; b.div(function (div: Builder) { - bindElement(div.getHTMLElement(), 'Foo Bar'); + _bindElement(div.getHTMLElement(), 'Foo Bar'); div.setProperty('Foo', 'Bar'); bindings.push(div.clone()); @@ -814,7 +814,7 @@ suite('Builder', () => { inputs.push(div.clone()); div.p(function (p: Builder) { - bindElement(p.getHTMLElement(), 'Foo Bar'); + _bindElement(p.getHTMLElement(), 'Foo Bar'); p.setProperty('Foo', 'Bar'); bindings.push(p.clone()); @@ -827,7 +827,7 @@ suite('Builder', () => { inputs.push(p.clone()); p.ul(function (ul: Builder) { - bindElement(ul.getHTMLElement(), 'Foo Bar'); + _bindElement(ul.getHTMLElement(), 'Foo Bar'); ul.setProperty('Foo', 'Bar'); bindings.push(ul.clone()); @@ -840,7 +840,7 @@ suite('Builder', () => { inputs.push(ul.clone()); ul.li(function (li: Builder) { - bindElement(li.getHTMLElement(), 'Foo Bar'); + _bindElement(li.getHTMLElement(), 'Foo Bar'); li.setProperty('Foo', 'Bar'); bindings.push(li.clone()); @@ -856,7 +856,7 @@ suite('Builder', () => { id: 'builderspan', innerHtml: 'Foo Bar' }, function (span) { - bindElement(span.getHTMLElement(), 'Foo Bar'); + _bindElement(span.getHTMLElement(), 'Foo Bar'); span.setProperty('Foo', 'Bar'); bindings.push(span.clone()); @@ -873,7 +873,7 @@ suite('Builder', () => { id: 'builderimg', src: '#' }, function (img) { - bindElement(img.getHTMLElement(), 'Foo Bar'); + _bindElement(img.getHTMLElement(), 'Foo Bar'); img.setProperty('Foo', 'Bar'); bindings.push(img.clone()); @@ -891,7 +891,7 @@ suite('Builder', () => { href: '#', innerHtml: 'Link' }, function (a) { - bindElement(a.getHTMLElement(), 'Foo Bar'); + _bindElement(a.getHTMLElement(), 'Foo Bar'); a.setProperty('Foo', 'Bar'); bindings.push(a.clone()); @@ -986,7 +986,7 @@ suite('Builder', () => { let counter7 = 0; b.div(function (div: Builder) { - bindElement(div.getHTMLElement(), 'Foo Bar'); + _bindElement(div.getHTMLElement(), 'Foo Bar'); div.setProperty('Foo', 'Bar'); bindings.push(div.clone()); @@ -999,7 +999,7 @@ suite('Builder', () => { inputs.push(div.clone()); div.p(function (p: Builder) { - bindElement(p.getHTMLElement(), 'Foo Bar'); + _bindElement(p.getHTMLElement(), 'Foo Bar'); p.setProperty('Foo', 'Bar'); bindings.push(p.clone()); @@ -1012,7 +1012,7 @@ suite('Builder', () => { inputs.push(p.clone()); p.ul(function (ul: Builder) { - bindElement(ul.getHTMLElement(), 'Foo Bar'); + _bindElement(ul.getHTMLElement(), 'Foo Bar'); ul.setProperty('Foo', 'Bar'); bindings.push(ul.clone()); @@ -1025,7 +1025,7 @@ suite('Builder', () => { inputs.push(ul.clone()); ul.li(function (li: Builder) { - bindElement(li.getHTMLElement(), 'Foo Bar'); + _bindElement(li.getHTMLElement(), 'Foo Bar'); li.setProperty('Foo', 'Bar'); bindings.push(li.clone()); @@ -1041,7 +1041,7 @@ suite('Builder', () => { id: 'builderspan', innerHtml: 'Foo Bar' }, function (span) { - bindElement(span.getHTMLElement(), 'Foo Bar'); + _bindElement(span.getHTMLElement(), 'Foo Bar'); span.setProperty('Foo', 'Bar'); bindings.push(span.clone()); @@ -1058,7 +1058,7 @@ suite('Builder', () => { id: 'builderimg', src: '#' }, function (img) { - bindElement(img.getHTMLElement(), 'Foo Bar'); + _bindElement(img.getHTMLElement(), 'Foo Bar'); img.setProperty('Foo', 'Bar'); bindings.push(img.clone()); @@ -1076,7 +1076,7 @@ suite('Builder', () => { href: '#', innerHtml: 'Link' }, function (a) { - bindElement(a.getHTMLElement(), 'Foo Bar'); + _bindElement(a.getHTMLElement(), 'Foo Bar'); a.setProperty('Foo', 'Bar'); bindings.push(a.clone()); diff --git a/src/vs/platform/contextview/browser/contextMenuHandler.ts b/src/vs/platform/contextview/browser/contextMenuHandler.ts index 836a08a9935..d1db0a1a2d4 100644 --- a/src/vs/platform/contextview/browser/contextMenuHandler.ts +++ b/src/vs/platform/contextview/browser/contextMenuHandler.ts @@ -6,8 +6,7 @@ 'use strict'; import 'vs/css!./contextMenuHandler'; -import { $, Builder } from 'vs/base/browser/builder'; -import { combinedDisposable, IDisposable } from 'vs/base/common/lifecycle'; +import { combinedDisposable, IDisposable, dispose } from 'vs/base/common/lifecycle'; import { StandardMouseEvent } from 'vs/base/browser/mouseEvent'; import { ActionRunner, IAction, IRunEvent } from 'vs/base/common/actions'; import { Menu } from 'vs/base/browser/ui/menu/menu'; @@ -16,6 +15,7 @@ import { IContextViewService } from 'vs/platform/contextview/browser/contextView import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry'; import { INotificationService } from 'vs/platform/notification/common/notification'; import { IContextMenuDelegate } from 'vs/base/browser/contextmenu'; +import { addDisposableListener } from 'vs/base/browser/dom'; export class ContextMenuHandler { @@ -23,7 +23,8 @@ export class ContextMenuHandler { private notificationService: INotificationService; private telemetryService: ITelemetryService; - private $el: Builder; + private $el: HTMLElement; + private $elDisposable: IDisposable; private menuContainerElement: HTMLElement; private focusToReturn: HTMLElement; @@ -39,12 +40,12 @@ export class ContextMenuHandler { public setContainer(container: HTMLElement): void { if (this.$el) { - this.$el.off(['click', 'mousedown']); + this.$elDisposable = dispose(this.$elDisposable); this.$el = null; } if (container) { - this.$el = $(container); - this.$el.on('mousedown', (e: Event) => this.onMouseDown(e as MouseEvent)); + this.$el = container; + this.$elDisposable = addDisposableListener(this.$el, 'mousedown', (e) => this.onMouseDown(e as MouseEvent)); } } diff --git a/src/vs/workbench/parts/comments/electron-browser/commentsEditorContribution.ts b/src/vs/workbench/parts/comments/electron-browser/commentsEditorContribution.ts index 60b5c2f04d0..ffa0cbae652 100644 --- a/src/vs/workbench/parts/comments/electron-browser/commentsEditorContribution.ts +++ b/src/vs/workbench/parts/comments/electron-browser/commentsEditorContribution.ts @@ -6,7 +6,7 @@ import 'vs/css!./media/review'; import * as nls from 'vs/nls'; -import { $ } from 'vs/base/browser/builder'; +import { $ } from 'vs/base/browser/dom'; import { findFirstInSorted } from 'vs/base/common/arrays'; import { KeyCode, KeyMod } from 'vs/base/common/keyCodes'; import { IDisposable, dispose } from 'vs/base/common/lifecycle'; @@ -48,7 +48,7 @@ export class ReviewViewZone implements IViewZone { this.afterLineNumber = afterLineNumber; this.callback = onDomNodeTop; - this.domNode = $('.review-viewzone').getHTMLElement(); + this.domNode = $('.review-viewzone'); } onDomNodeTop(top: number): void { diff --git a/src/vs/workbench/parts/feedback/electron-browser/feedbackStatusbarItem.ts b/src/vs/workbench/parts/feedback/electron-browser/feedbackStatusbarItem.ts index 38b00d07f94..738ee925110 100644 --- a/src/vs/workbench/parts/feedback/electron-browser/feedbackStatusbarItem.ts +++ b/src/vs/workbench/parts/feedback/electron-browser/feedbackStatusbarItem.ts @@ -16,8 +16,7 @@ import { IThemeService, registerThemingParticipant, ITheme, ICssStyleCollector } import { IWorkspaceContextService, WorkbenchState } from 'vs/platform/workspace/common/workspace'; import { IWorkspaceConfigurationService } from 'vs/workbench/services/configuration/common/configuration'; import { IConfigurationChangeEvent } from 'vs/platform/configuration/common/configuration'; -import { clearNode, EventHelper, addClass, removeClass } from 'vs/base/browser/dom'; -import { $ } from 'vs/base/browser/builder'; +import { clearNode, EventHelper, addClass, removeClass, addDisposableListener } from 'vs/base/browser/dom'; import { localize } from 'vs/nls'; import { TPromise } from 'vs/base/common/winjs.base'; import { Action } from 'vs/base/common/actions'; @@ -94,7 +93,7 @@ export class FeedbackStatusbarItem extends Themable implements IStatusbarItem { super.updateStyles(); if (this.dropdown) { - $(this.dropdown.label).style('background-color', this.getColor(this.contextService.getWorkbenchState() !== WorkbenchState.EMPTY ? STATUS_BAR_FOREGROUND : STATUS_BAR_NO_FOLDER_FOREGROUND)); + this.dropdown.label.style.backgroundColor = (this.getColor(this.contextService.getWorkbenchState() !== WorkbenchState.EMPTY ? STATUS_BAR_FOREGROUND : STATUS_BAR_NO_FOLDER_FOREGROUND)); } } @@ -102,21 +101,21 @@ export class FeedbackStatusbarItem extends Themable implements IStatusbarItem { this.container = element; // Prevent showing dropdown on anything but left click - $(this.container).on('mousedown', (e: MouseEvent) => { + this.toDispose.push(addDisposableListener(this.container, 'mousedown', (e: MouseEvent) => { if (e.button !== 0) { EventHelper.stop(e, true); } - }, this.toDispose, true); + }, true)); // Offer context menu to hide status bar entry - $(this.container).on('contextmenu', e => { + this.toDispose.push(addDisposableListener(this.container, 'contextmenu', e => { EventHelper.stop(e, true); this.contextMenuService.showContextMenu({ getAnchor: () => this.container, getActions: () => TPromise.as([this.hideAction]) }); - }, this.toDispose); + })); return this.update(); } diff --git a/src/vs/workbench/parts/files/electron-browser/views/emptyView.ts b/src/vs/workbench/parts/files/electron-browser/views/emptyView.ts index 46326cd24ee..3eca44e9bfa 100644 --- a/src/vs/workbench/parts/files/electron-browser/views/emptyView.ts +++ b/src/vs/workbench/parts/files/electron-browser/views/emptyView.ts @@ -11,7 +11,6 @@ import * as DOM from 'vs/base/browser/dom'; import { TPromise } from 'vs/base/common/winjs.base'; import { IAction } from 'vs/base/common/actions'; import { Button } from 'vs/base/browser/ui/button/button'; -import { $, Builder } from 'vs/base/browser/builder'; import { IActionItem } from 'vs/base/browser/ui/actionbar/actionbar'; import { IViewletViewOptions } from 'vs/workbench/browser/parts/views/viewsViewlet'; import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; @@ -33,8 +32,8 @@ export class EmptyView extends ViewletPanel { public static readonly NAME = nls.localize('noWorkspace', "No Folder Opened"); private button: Button; - private messageDiv: Builder; - private titleDiv: Builder; + private messageElement: HTMLElement; + private titleElement: HTMLElement; constructor( options: IViewletViewOptions, @@ -50,17 +49,26 @@ export class EmptyView extends ViewletPanel { } public renderHeader(container: HTMLElement): void { - this.titleDiv = $('span').text(name).appendTo($('div.title').appendTo(container)); + const titleContainer = document.createElement('div'); + DOM.addClass(titleContainer, 'title'); + container.appendChild(titleContainer); + + this.titleElement = document.createElement('span'); + this.titleElement.textContent = name; + titleContainer.appendChild(this.titleElement); } protected renderBody(container: HTMLElement): void { DOM.addClass(container, 'explorer-empty-view'); - this.messageDiv = $('p').appendTo($('div.section').appendTo(container)); + const messageContainer = document.createElement('div'); + DOM.addClass(messageContainer, 'section'); + container.appendChild(messageContainer); - const section = $('div.section').appendTo(container); + this.messageElement = document.createElement('p'); + messageContainer.appendChild(this.messageElement); - this.button = new Button(section.getHTMLElement()); + this.button = new Button(messageContainer); attachButtonStyler(this.button, this.themeService); this.disposables.push(this.button.onDidClick(() => { @@ -99,17 +107,17 @@ export class EmptyView extends ViewletPanel { private setLabels(): void { if (this.contextService.getWorkbenchState() === WorkbenchState.WORKSPACE) { - this.messageDiv.text(nls.localize('noWorkspaceHelp', "You have not yet added a folder to the workspace.")); + this.messageElement.textContent = nls.localize('noWorkspaceHelp', "You have not yet added a folder to the workspace."); if (this.button) { this.button.label = nls.localize('addFolder', "Add Folder"); } - this.titleDiv.text(EmptyView.NAME); + this.titleElement.textContent = EmptyView.NAME; } else { - this.messageDiv.text(nls.localize('noFolderHelp', "You have not yet opened a folder.")); + this.messageElement.textContent = nls.localize('noFolderHelp', "You have not yet opened a folder."); if (this.button) { this.button.label = nls.localize('openFolder', "Open Folder"); } - this.titleDiv.text(this.title); + this.titleElement.textContent = this.title; } } diff --git a/src/vs/workbench/parts/search/browser/searchView.ts b/src/vs/workbench/parts/search/browser/searchView.ts index 89b830a0b79..301c4fc6f08 100644 --- a/src/vs/workbench/parts/search/browser/searchView.ts +++ b/src/vs/workbench/parts/search/browser/searchView.ts @@ -343,7 +343,7 @@ export class SearchView extends Viewlet implements IViewlet, IPanel { let searchHistory = history.search || this.viewletSettings['query.searchHistory'] || []; let replaceHistory = history.replace || this.viewletSettings['query.replaceHistory'] || []; - this.searchWidget = this._register(this.instantiationService.createInstance(SearchWidget, builder, <ISearchWidgetOptions>{ + this.searchWidget = this._register(this.instantiationService.createInstance(SearchWidget, builder.getHTMLElement(), <ISearchWidgetOptions>{ value: contentPattern, isRegex: isRegex, isCaseSensitive: isCaseSensitive, diff --git a/src/vs/workbench/parts/search/browser/searchWidget.ts b/src/vs/workbench/parts/search/browser/searchWidget.ts index 86bf8193435..5b96310a51d 100644 --- a/src/vs/workbench/parts/search/browser/searchWidget.ts +++ b/src/vs/workbench/parts/search/browser/searchWidget.ts @@ -20,7 +20,6 @@ import { ContextKeyExpr, IContextKeyService, IContextKey } from 'vs/platform/con import { IContextViewService } from 'vs/platform/contextview/browser/contextView'; import { KeyCode, KeyMod } from 'vs/base/common/keyCodes'; import { Event, Emitter } from 'vs/base/common/event'; -import { Builder } from 'vs/base/browser/builder'; import { IViewletService } from 'vs/workbench/services/viewlet/browser/viewlet'; import { isSearchViewFocused, appendKeyBindingLabel } from 'vs/workbench/parts/search/browser/searchActions'; import * as Constants from 'vs/workbench/parts/search/common/constants'; @@ -122,7 +121,7 @@ export class SearchWidget extends Widget { public readonly onBlur: Event<void> = this._onBlur.event; constructor( - container: Builder, + container: HTMLElement, options: ISearchWidgetOptions, @IContextViewService private contextViewService: IContextViewService, @IThemeService private themeService: IThemeService, @@ -228,8 +227,10 @@ export class SearchWidget extends Widget { this.searchInput.focusOnRegex(); } - private render(container: Builder, options: ISearchWidgetOptions): void { - this.domNode = container.div({ 'class': 'search-widget' }).style({ position: 'relative' }).getHTMLElement(); + private render(container: HTMLElement, options: ISearchWidgetOptions): void { + this.domNode = dom.append(container, dom.$('.search-widget')); + this.domNode.style.position = 'relative'; + this.renderToggleReplaceButton(this.domNode); this.renderSearchInput(this.domNode, options); From cdb9c0a8f4754646459536b27bbf79eb526a6218 Mon Sep 17 00:00:00 2001 From: Johannes Rieken <johannes.rieken@gmail.com> Date: Fri, 24 Aug 2018 16:37:10 +0200 Subject: [PATCH 1225/1276] update vscode-nls-dev to fixed version, share more config between extensions --- extensions/git/extension.webpack.config.js | 9 +-------- extensions/shared.webpack.config.js | 13 +++++++++++-- .../extension.webpack.config.js | 8 +------- package.json | 2 +- yarn.lock | 6 +++--- 5 files changed, 17 insertions(+), 21 deletions(-) diff --git a/extensions/git/extension.webpack.config.js b/extensions/git/extension.webpack.config.js index dd6c7a23b2d..ac1ed5928a9 100644 --- a/extensions/git/extension.webpack.config.js +++ b/extensions/git/extension.webpack.config.js @@ -8,7 +8,6 @@ 'use strict'; const withDefaults = require('../shared.webpack.config'); -const CopyWebpackPlugin = require('copy-webpack-plugin'); module.exports = withDefaults({ context: __dirname, @@ -18,11 +17,5 @@ module.exports = withDefaults({ entry: { main: './src/main.ts', ['askpass-main']: './src/askpass-main.ts' - }, - plugins: [ - new CopyWebpackPlugin([ - { from: './out/*.sh', to: '[name].sh' }, - { from: './out/nls.*.json', to: '[name].json' } - ]) - ] + } }); diff --git a/extensions/shared.webpack.config.js b/extensions/shared.webpack.config.js index ad169b3eb88..d816578c6e5 100644 --- a/extensions/shared.webpack.config.js +++ b/extensions/shared.webpack.config.js @@ -10,6 +10,7 @@ const path = require('path'); const merge = require('merge-options'); +const CopyWebpackPlugin = require('copy-webpack-plugin'); module.exports = function withDefaults(/**@type WebpackConfig*/extConfig) { @@ -29,7 +30,10 @@ module.exports = function withDefaults(/**@type WebpackConfig*/extConfig) { use: [{ // vscode-nls-dev loader: // * rewrite nls-calls - loader: 'vscode-nls-dev/lib/webpack-loader' + loader: 'vscode-nls-dev/lib/webpack-loader', + options: { + base: path.join(extConfig.context, 'src') + } }, { // configure TypeScript loader: // * only transpile because we have a separate compilation pipeline @@ -58,7 +62,12 @@ module.exports = function withDefaults(/**@type WebpackConfig*/extConfig) { libraryTarget: "commonjs", }, // yes, really source maps - devtool: 'source-map' + devtool: 'source-map', + plugins: [ + new CopyWebpackPlugin([ + { from: './out/**/*', to: '.', ignore: ['*.js', '*.js.map'], flatten: true } + ]) + ], }; return merge(defaultConfig, extConfig); diff --git a/extensions/typescript-language-features/extension.webpack.config.js b/extensions/typescript-language-features/extension.webpack.config.js index dd31f6c49c5..664dfb35f6f 100644 --- a/extensions/typescript-language-features/extension.webpack.config.js +++ b/extensions/typescript-language-features/extension.webpack.config.js @@ -8,7 +8,6 @@ 'use strict'; const withDefaults = require('../shared.webpack.config'); -const CopyWebpackPlugin = require('copy-webpack-plugin'); module.exports = withDefaults({ context: __dirname, @@ -20,10 +19,5 @@ module.exports = withDefaults({ }, entry: { extension: './src/extension.ts', - }, - plugins: [ - new CopyWebpackPlugin([ - { from: './out/nls.*.json', to: '[name].json' } - ]) - ] + } }); diff --git a/package.json b/package.json index 79163bd2c96..06337bac1e0 100644 --- a/package.json +++ b/package.json @@ -128,7 +128,7 @@ "vinyl": "^0.4.5", "vinyl-fs": "^2.4.3", "vsce": "1.33.2", - "vscode-nls-dev": "3.2.1", + "vscode-nls-dev": "3.2.2", "webpack": "^4.16.5", "webpack-cli": "^3.1.0", "webpack-stream": "^5.1.1" diff --git a/yarn.lock b/yarn.lock index 8c39006188f..cd85c0c3020 100644 --- a/yarn.lock +++ b/yarn.lock @@ -7905,9 +7905,9 @@ vscode-fsevents@0.3.8: dependencies: nan "^2.3.0" -vscode-nls-dev@3.2.1: - version "3.2.1" - resolved "https://registry.yarnpkg.com/vscode-nls-dev/-/vscode-nls-dev-3.2.1.tgz#8aa9537b67d1e6e7ea4c6c4f80043c46c8a725ea" +vscode-nls-dev@3.2.2: + version "3.2.2" + resolved "https://registry.yarnpkg.com/vscode-nls-dev/-/vscode-nls-dev-3.2.2.tgz#5855c9b3e566dd00fd6108f9c2e1bd02c925c153" dependencies: clone "^2.1.1" event-stream "^3.3.4" From 7eb84eff08dab3e1f20ffb3f4735eb475aaa9619 Mon Sep 17 00:00:00 2001 From: Alex Dima <alexdima@microsoft.com> Date: Fri, 24 Aug 2018 16:48:17 +0200 Subject: [PATCH 1226/1276] Remove stdFork since it is no longer used --- src/vs/base/node/stdFork.ts | 140 ---------------------- src/vs/base/node/stdForkStart.js | 197 ------------------------------- 2 files changed, 337 deletions(-) delete mode 100644 src/vs/base/node/stdFork.ts delete mode 100644 src/vs/base/node/stdForkStart.js diff --git a/src/vs/base/node/stdFork.ts b/src/vs/base/node/stdFork.ts deleted file mode 100644 index 17782445328..00000000000 --- a/src/vs/base/node/stdFork.ts +++ /dev/null @@ -1,140 +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'; - -import * as path from 'path'; -import * as os from 'os'; -import * as net from 'net'; -import * as cp from 'child_process'; -import { getPathFromAmdModule } from 'vs/base/common/amd'; - -export interface IForkOpts { - cwd?: string; - env?: any; - encoding?: string; - execArgv?: string[]; -} - -function makeRandomHexString(length: number): string { - let chars = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f']; - let result = ''; - for (let i = 0; i < length; i++) { - let idx = Math.floor(chars.length * Math.random()); - result += chars[idx]; - } - return result; -} - -function generatePipeName(): string { - let randomName = 'vscode-std-' + makeRandomHexString(40); - if (process.platform === 'win32') { - return '\\\\.\\pipe\\' + randomName + '-sock'; - } - - // Mac/Unix: use socket file - return path.join(os.tmpdir(), randomName + '.sock'); -} - -function generatePatchedEnv(env: any, stdInPipeName: string, stdOutPipeName: string, stdErrPipeName: string): any { - // Set the two unique pipe names and the electron flag as process env - - let newEnv: any = {}; - for (let key in env) { - newEnv[key] = env[key]; - } - - newEnv['STDIN_PIPE_NAME'] = stdInPipeName; - newEnv['STDOUT_PIPE_NAME'] = stdOutPipeName; - newEnv['STDERR_PIPE_NAME'] = stdErrPipeName; - newEnv['ELECTRON_RUN_AS_NODE'] = '1'; - - return newEnv; -} - -export function fork(modulePath: string, args: string[], options: IForkOpts, callback: (error: any, cp: cp.ChildProcess) => void): void { - - let callbackCalled = false; - let resolve = (result: cp.ChildProcess) => { - if (callbackCalled) { - return; - } - callbackCalled = true; - callback(null, result); - }; - let reject = (err: any) => { - if (callbackCalled) { - return; - } - callbackCalled = true; - callback(err, null); - }; - - // Generate three unique pipe names - let stdInPipeName = generatePipeName(); - let stdOutPipeName = generatePipeName(); - let stdErrPipeName = generatePipeName(); - - let newEnv = generatePatchedEnv(options.env || process.env, stdInPipeName, stdOutPipeName, stdErrPipeName); - - let childProcess: cp.ChildProcess; - - // Begin listening to stderr pipe - let stdErrServer = net.createServer((stdErrStream) => { - // From now on the childProcess.stderr is available for reading - childProcess.stderr = stdErrStream; - }); - stdErrServer.listen(stdErrPipeName); - - // Begin listening to stdout pipe - let stdOutServer = net.createServer((stdOutStream) => { - // The child process will write exactly one chunk with content `ready` when it has installed a listener to the stdin pipe - - stdOutStream.once('data', (chunk: Buffer) => { - // The child process is sending me the `ready` chunk, time to connect to the stdin pipe - childProcess.stdin = <any>net.connect(stdInPipeName); - - // From now on the childProcess.stdout is available for reading - childProcess.stdout = stdOutStream; - - resolve(childProcess); - }); - }); - stdOutServer.listen(stdOutPipeName); - - let serverClosed = false; - let closeServer = () => { - if (serverClosed) { - return; - } - - serverClosed = true; - process.removeListener('exit', closeServer); - stdOutServer.close(); - stdErrServer.close(); - }; - - // Create the process - let bootstrapperPath = (getPathFromAmdModule(require, './stdForkStart.js')); - childProcess = cp.fork(bootstrapperPath, [modulePath].concat(args), { - silent: true, - cwd: options.cwd, - env: newEnv, - execArgv: options.execArgv - }); - - childProcess.once('error', (err: Error) => { - closeServer(); - reject(err); - }); - - childProcess.once('exit', (err: Error) => { - closeServer(); - reject(err); - }); - - // On vscode exit still close server #7758 - process.once('exit', closeServer); -} diff --git a/src/vs/base/node/stdForkStart.js b/src/vs/base/node/stdForkStart.js deleted file mode 100644 index 42226f9a08d..00000000000 --- a/src/vs/base/node/stdForkStart.js +++ /dev/null @@ -1,197 +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 net = require('net'); -const fs = require('fs'); -// const stream = require('stream'); -// const util = require('util'); - -var ENABLE_LOGGING = false; - -var log = (function () { - if (!ENABLE_LOGGING) { - return function () { }; - } - var isFirst = true; - var LOG_LOCATION = 'C:\\stdFork.log'; - return function log(str) { - if (isFirst) { - isFirst = false; - fs.writeFileSync(LOG_LOCATION, str + '\n'); - return; - } - fs.appendFileSync(LOG_LOCATION, str + '\n'); - }; -})(); - -var stdInPipeName = process.env['STDIN_PIPE_NAME']; -var stdOutPipeName = process.env['STDOUT_PIPE_NAME']; -var stdErrPipeName = process.env['STDERR_PIPE_NAME']; - -log('STDIN_PIPE_NAME: ' + stdInPipeName); -log('STDOUT_PIPE_NAME: ' + stdOutPipeName); -log('STDERR_PIPE_NAME: ' + stdErrPipeName); -log('ELECTRON_RUN_AS_NODE: ' + process.env['ELECTRON_RUN_AS_NODE']); - -// stdout redirection to named pipe -(function () { - log('Beginning stdout redirection...'); - - // Create a writing stream to the stdout pipe - var stdOutStream = net.connect(stdOutPipeName); - - // unref stdOutStream to behave like a normal standard out - stdOutStream.unref(); - - // handle process.stdout - process.__defineGetter__('stdout', function () { return stdOutStream; }); - - // Create a writing stream to the stderr pipe - var stdErrStream = net.connect(stdErrPipeName); - - // unref stdErrStream to behave like a normal standard out - stdErrStream.unref(); - - // handle process.stderr - process.__defineGetter__('stderr', function () { return stdErrStream; }); - - var fsWriteSyncString = function (fd, str, position, encoding) { - // fs.writeSync(fd, string[, position[, encoding]]); - var buf = Buffer.from(str, encoding || 'utf8'); - return fsWriteSyncBuffer(fd, buf, 0, buf.length); - }; - - var fsWriteSyncBuffer = function (fd, buffer, off, len/* , position */) { - off = Math.abs(off | 0); - len = Math.abs(len | 0); - - // fs.writeSync(fd, buffer, offset, length[, position]); - var buffer_length = buffer.length; - - if (off > buffer_length) { - throw new Error('offset out of bounds'); - } - if (len > buffer_length) { - throw new Error('length out of bounds'); - } - if (((off + len) | 0) < off) { - throw new Error('off + len overflow'); - } - if (buffer_length - off < len) { - // Asking for more than is left over in the buffer - throw new Error('off + len > buffer.length'); - } - - var slicedBuffer = buffer; - if (off !== 0 || len !== buffer_length) { - slicedBuffer = buffer.slice(off, off + len); - } - - if (fd === 1) { - stdOutStream.write(slicedBuffer); - } else { - stdErrStream.write(slicedBuffer); - } - return slicedBuffer.length; - }; - - // handle fs.writeSync(1, ...) and fs.writeSync(2, ...) - var originalWriteSync = fs.writeSync; - fs.writeSync = function (fd, data/* , position, encoding */) { - if (fd !== 1 && fd !== 2) { - return originalWriteSync.apply(fs, arguments); - } - // usage: - // fs.writeSync(fd, buffer, offset, length[, position]); - // OR - // fs.writeSync(fd, string[, position[, encoding]]); - - if (data instanceof Buffer) { - return fsWriteSyncBuffer.apply(null, arguments); - } - - // For compatibility reasons with fs.writeSync, writing null will write "null", etc - if (typeof data !== 'string') { - data += ''; - } - - return fsWriteSyncString.apply(null, arguments); - }; - - log('Finished defining process.stdout, process.stderr and fs.writeSync'); -})(); - -// stdin redirection to named pipe -(function () { - - // Begin listening to stdin pipe - var server = net.createServer(function (stream) { - // Stop accepting new connections, keep the existing one alive - server.close(); - - log('Parent process has connected to my stdin. All should be good now.'); - - // handle process.stdin - process.__defineGetter__('stdin', function () { - return stream; - }); - - // Remove myself from process.argv - process.argv.splice(1, 1); - - // Load the actual program - var program = process.argv[1]; - log('Loading program: ' + program); - - // Unset the custom environmental variables that should not get inherited - delete process.env['STDIN_PIPE_NAME']; - delete process.env['STDOUT_PIPE_NAME']; - delete process.env['STDERR_PIPE_NAME']; - delete process.env['ELECTRON_RUN_AS_NODE']; - - require(program); - - log('Finished loading program.'); - - var stdinIsReferenced = true; - var timer = setInterval(function () { - var listenerCount = ( - stream.listeners('data').length + - stream.listeners('end').length + - stream.listeners('close').length + - stream.listeners('error').length - ); - // log('listenerCount: ' + listenerCount); - if (listenerCount <= 1) { - // No more "actual" listeners, only internal node - if (stdinIsReferenced) { - stdinIsReferenced = false; - // log('unreferencing stream!!!'); - stream.unref(); - } - } else { - // There are "actual" listeners - if (!stdinIsReferenced) { - stdinIsReferenced = true; - stream.ref(); - } - } - // log( - // '' + stream.listeners('data').length + - // ' ' + stream.listeners('end').length + - // ' ' + stream.listeners('close').length + - // ' ' + stream.listeners('error').length - // ); - }, 1000); - timer.unref(); - }); - - - server.listen(stdInPipeName, function () { - // signal via stdout that the parent process can now begin writing to stdin pipe - process.stdout.write('ready'); - }); - -})(); From 1f616aaee8e25a42281a2ff74a3765e500305a6a Mon Sep 17 00:00:00 2001 From: Johannes Rieken <johannes.rieken@gmail.com> Date: Fri, 24 Aug 2018 16:46:21 +0200 Subject: [PATCH 1227/1276] update ignore file --- extensions/typescript-language-features/.vscodeignore | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/extensions/typescript-language-features/.vscodeignore b/extensions/typescript-language-features/.vscodeignore index d257eda277b..7992329e90a 100644 --- a/extensions/typescript-language-features/.vscodeignore +++ b/extensions/typescript-language-features/.vscodeignore @@ -1,4 +1,7 @@ build/** src/** test/** -tsconfig.json \ No newline at end of file +tsconfig.json +node_modules/jsonc-parser/** +node_modules/semver/** + From ef159be3e6b83cfcd4c8c661081c9ba2b6786216 Mon Sep 17 00:00:00 2001 From: Rob Lourens <roblourens@gmail.com> Date: Thu, 23 Aug 2018 22:32:26 -0700 Subject: [PATCH 1228/1276] search-rg extension - slight perf improvement --- extensions/search-rg/src/extension.ts | 3 +-- extensions/search-rg/src/utils.ts | 6 ------ 2 files changed, 1 insertion(+), 8 deletions(-) diff --git a/extensions/search-rg/src/extension.ts b/extensions/search-rg/src/extension.ts index 1447f03d331..9c725266796 100644 --- a/extensions/search-rg/src/extension.ts +++ b/extensions/search-rg/src/extension.ts @@ -6,7 +6,6 @@ import * as vscode from 'vscode'; import { RipgrepFileSearchEngine } from './ripgrepFileSearch'; import { RipgrepTextSearchEngine } from './ripgrepTextSearch'; -import { joinPath } from './utils'; export function activate(): void { if (vscode.workspace.getConfiguration('searchRipgrep').get('enable')) { @@ -37,7 +36,7 @@ class RipgrepSearchProvider implements vscode.FileIndexProvider, vscode.TextSear const results: vscode.Uri[] = []; const onResult = relativePathMatch => { - results.push(joinPath(options.folder, relativePathMatch)); + results.push(vscode.Uri.file(options.folder.fsPath + '/' + relativePathMatch)); }; return this.withEngine(engine, () => engine.provideFileSearchResults(options, { report: onResult }, token)) diff --git a/extensions/search-rg/src/utils.ts b/extensions/search-rg/src/utils.ts index d06e4f1ab8a..449395fd05f 100644 --- a/extensions/search-rg/src/utils.ts +++ b/extensions/search-rg/src/utils.ts @@ -6,7 +6,6 @@ 'use strict'; import * as path from 'path'; -import * as vscode from 'vscode'; export function fixDriveC(_path: string): string { const root = path.parse(_path).root; @@ -18,8 +17,3 @@ export function fixDriveC(_path: string): string { export function anchorGlob(glob: string): string { return glob.startsWith('**') || glob.startsWith('/') ? glob : `/${glob}`; } - -export function joinPath(resource: vscode.Uri, pathFragment: string): vscode.Uri { - const joinedPath = path.join(resource.fsPath || '/', pathFragment); - return vscode.Uri.file(joinedPath); -} From 77abb3291f82a1440df755819dc9199908261206 Mon Sep 17 00:00:00 2001 From: Rob Lourens <roblourens@gmail.com> Date: Fri, 24 Aug 2018 08:51:41 -0700 Subject: [PATCH 1229/1276] Fix search widget error --- src/vs/workbench/parts/search/browser/searchWidget.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/vs/workbench/parts/search/browser/searchWidget.ts b/src/vs/workbench/parts/search/browser/searchWidget.ts index 5b96310a51d..0f834a38ad8 100644 --- a/src/vs/workbench/parts/search/browser/searchWidget.ts +++ b/src/vs/workbench/parts/search/browser/searchWidget.ts @@ -246,7 +246,8 @@ export class SearchWidget extends Widget { }; this.toggleReplaceButton = this._register(new Button(parent, opts)); this.toggleReplaceButton.element.setAttribute('aria-expanded', 'false'); - this.toggleReplaceButton.icon = 'toggle-replace-button collapse'; + this.toggleReplaceButton.element.classList.add('collapse'); + this.toggleReplaceButton.icon = 'toggle-replace-button'; // TODO@joh need to dispose this listener eventually this.toggleReplaceButton.onDidClick(() => this.onToggleReplaceButton()); this.toggleReplaceButton.element.title = nls.localize('search.replace.toggle.button.title', "Toggle Replace"); From 3149c5b4dae01a68f8ae761c0cf038bef2f682b6 Mon Sep 17 00:00:00 2001 From: isidor <inikolic@microsoft.com> Date: Fri, 24 Aug 2018 17:52:44 +0200 Subject: [PATCH 1230/1276] introduce isFileSystemResourceOrUntitled to be used for compare fixes #56316 --- src/vs/workbench/common/resources.ts | 6 ++++++ .../files/electron-browser/fileActions.contribution.ts | 6 +++--- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/src/vs/workbench/common/resources.ts b/src/vs/workbench/common/resources.ts index 52710ab2a8c..1727311648e 100644 --- a/src/vs/workbench/common/resources.ts +++ b/src/vs/workbench/common/resources.ts @@ -11,6 +11,7 @@ import { RawContextKey, IContextKeyService, IContextKey } from 'vs/platform/cont import { IModeService } from 'vs/editor/common/services/modeService'; import { IFileService } from 'vs/platform/files/common/files'; import { dispose, IDisposable } from 'vs/base/common/lifecycle'; +import { Schemas } from 'vs/base/common/network'; export class ResourceContextKey implements IContextKey<URI>, IDisposable { @@ -21,6 +22,7 @@ export class ResourceContextKey implements IContextKey<URI>, IDisposable { static Extension = new RawContextKey<string>('resourceExtname', undefined); static HasResource = new RawContextKey<boolean>('resourceSet', false); static IsFileSystemResource = new RawContextKey<boolean>('isFileSystemResource', false); + static IsFileSystemResourceOrUntitled = new RawContextKey<boolean>('isFileSystemResourceOrUntitled', false); private _resourceKey: IContextKey<URI>; private _schemeKey: IContextKey<string>; @@ -29,6 +31,7 @@ export class ResourceContextKey implements IContextKey<URI>, IDisposable { private _extensionKey: IContextKey<string>; private _hasResource: IContextKey<boolean>; private _isfileSystemResource: IContextKey<boolean>; + private _isFileSystemResourceOrUntitled: IContextKey<boolean>; private toDispose: IDisposable[] = []; constructor( @@ -43,9 +46,11 @@ export class ResourceContextKey implements IContextKey<URI>, IDisposable { this._extensionKey = ResourceContextKey.Extension.bindTo(contextKeyService); this._hasResource = ResourceContextKey.HasResource.bindTo(contextKeyService); this._isfileSystemResource = ResourceContextKey.IsFileSystemResource.bindTo(contextKeyService); + this._isFileSystemResourceOrUntitled = ResourceContextKey.IsFileSystemResourceOrUntitled.bindTo(contextKeyService); this.toDispose.push(_fileService.onDidChangeFileSystemProviderRegistrations(() => { const resource = this._resourceKey.get(); this._isfileSystemResource.set(resource && _fileService.canHandleResource(resource)); + this._isFileSystemResourceOrUntitled.set(this._isfileSystemResource.get() || this._schemeKey.get() === Schemas.untitled); })); } @@ -57,6 +62,7 @@ export class ResourceContextKey implements IContextKey<URI>, IDisposable { this._extensionKey.set(value && paths.extname(value.fsPath)); this._hasResource.set(!!value); this._isfileSystemResource.set(value && this._fileService.canHandleResource(value)); + this._isFileSystemResourceOrUntitled.set(this._isfileSystemResource.get() || this._schemeKey.get() === Schemas.untitled); } reset(): void { diff --git a/src/vs/workbench/parts/files/electron-browser/fileActions.contribution.ts b/src/vs/workbench/parts/files/electron-browser/fileActions.contribution.ts index 3dc3343b7eb..a6d11d8e009 100644 --- a/src/vs/workbench/parts/files/electron-browser/fileActions.contribution.ts +++ b/src/vs/workbench/parts/files/electron-browser/fileActions.contribution.ts @@ -268,7 +268,7 @@ MenuRegistry.appendMenuItem(MenuId.OpenEditorsContext, { group: '3_compare', order: 20, command: compareResourceCommand, - when: ContextKeyExpr.and(ResourceContextKey.IsFileSystemResource, ResourceSelectedForCompareContext, WorkbenchListDoubleSelection.toNegated()) + when: ContextKeyExpr.and(ResourceContextKey.IsFileSystemResourceOrUntitled, ResourceSelectedForCompareContext, WorkbenchListDoubleSelection.toNegated()) }); const selectForCompareCommand = { @@ -279,7 +279,7 @@ MenuRegistry.appendMenuItem(MenuId.OpenEditorsContext, { group: '3_compare', order: 30, command: selectForCompareCommand, - when: ContextKeyExpr.and(ResourceContextKey.IsFileSystemResource, WorkbenchListDoubleSelection.toNegated()) + when: ContextKeyExpr.and(ResourceContextKey.IsFileSystemResourceOrUntitled, WorkbenchListDoubleSelection.toNegated()) }); const compareSelectedCommand = { @@ -290,7 +290,7 @@ MenuRegistry.appendMenuItem(MenuId.OpenEditorsContext, { group: '3_compare', order: 30, command: compareSelectedCommand, - when: ContextKeyExpr.and(ResourceContextKey.IsFileSystemResource, WorkbenchListDoubleSelection) + when: ContextKeyExpr.and(ResourceContextKey.IsFileSystemResourceOrUntitled, WorkbenchListDoubleSelection) }); MenuRegistry.appendMenuItem(MenuId.OpenEditorsContext, { From 716a83d78f1d3314650569495d4b871888ab6856 Mon Sep 17 00:00:00 2001 From: Rob Lourens <roblourens@gmail.com> Date: Fri, 24 Aug 2018 09:09:33 -0700 Subject: [PATCH 1231/1276] Fix quickopen --- src/vs/base/parts/quickopen/browser/quickOpenWidget.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vs/base/parts/quickopen/browser/quickOpenWidget.ts b/src/vs/base/parts/quickopen/browser/quickOpenWidget.ts index 0b73a959113..fdcbaf9ffdf 100644 --- a/src/vs/base/parts/quickopen/browser/quickOpenWidget.ts +++ b/src/vs/base/parts/quickopen/browser/quickOpenWidget.ts @@ -168,7 +168,7 @@ export class QuickOpenWidget extends Disposable implements IModelProvider { .on(DOM.EventType.BLUR, (e: FocusEvent) => this.loosingFocus(e), null, true); // Progress Bar - this.progressBar = this._register(new ProgressBar(div.clone(), { progressBarBackground: this.styles.progressBarBackground })); + this.progressBar = this._register(new ProgressBar(div.getHTMLElement(), { progressBarBackground: this.styles.progressBarBackground })); this.progressBar.hide(); // Input Field From d9e6f53c1c1eba5ae305b1b6ce24e90a92ba5f9d Mon Sep 17 00:00:00 2001 From: Jackson Kearl <jkearl@mit.edu> Date: Fri, 24 Aug 2018 09:42:39 -0700 Subject: [PATCH 1232/1276] Notify of no need to save on first edit --- .../parts/preferences/browser/settingsEditor2.ts | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/src/vs/workbench/parts/preferences/browser/settingsEditor2.ts b/src/vs/workbench/parts/preferences/browser/settingsEditor2.ts index ca45a7487bf..ac39b66435c 100644 --- a/src/vs/workbench/parts/preferences/browser/settingsEditor2.ts +++ b/src/vs/workbench/parts/preferences/browser/settingsEditor2.ts @@ -45,6 +45,8 @@ import { SettingsEditor2Input } from 'vs/workbench/services/preferences/common/p import { DefaultSettingsEditorModel } from 'vs/workbench/services/preferences/common/preferencesModels'; import { ResourceEditorModel } from 'vs/workbench/common/editor/resourceEditorModel'; import { badgeBackground, contrastBorder, badgeForeground, editorForeground } from 'vs/platform/theme/common/colorRegistry'; +import { IStorageService, StorageScope } from 'vs/platform/storage/common/storage'; +import { INotificationService } from 'vs/platform/notification/common/notification'; const $ = DOM.$; @@ -111,7 +113,9 @@ export class SettingsEditor2 extends BaseEditor { @ILogService private logService: ILogService, @IEnvironmentService private environmentService: IEnvironmentService, @IContextKeyService contextKeyService: IContextKeyService, - @IContextMenuService private contextMenuService: IContextMenuService + @IContextMenuService private contextMenuService: IContextMenuService, + @IStorageService private storageService: IStorageService, + @INotificationService private notificationService: INotificationService ) { super(SettingsEditor2.ID, telemetryService, themeService); this.delayedFilterLogging = new Delayer<void>(1000); @@ -485,6 +489,11 @@ export class SettingsEditor2 extends BaseEditor { } private onDidChangeSetting(key: string, value: any): void { + if (!this.storageService.getBoolean('hasNotifiedOfSettingsAutosave', StorageScope.GLOBAL, false)) { + this.storageService.store('hasNotifiedOfSettingsAutosave', true, StorageScope.GLOBAL); + this.notificationService.info(localize('settingsNoSaveNeeded', "Your changes are automatically saved as you edit.")); + } + if (this.pendingSettingUpdate && this.pendingSettingUpdate.key !== key) { this.updateChangedSetting(key, value); } From cb366e2871ca0275590332f0b84b07cae01544b1 Mon Sep 17 00:00:00 2001 From: Jackson Kearl <jkearl@mit.edu> Date: Fri, 24 Aug 2018 09:43:19 -0700 Subject: [PATCH 1233/1276] Organize imports --- .../parts/preferences/browser/settingsEditor2.ts | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/vs/workbench/parts/preferences/browser/settingsEditor2.ts b/src/vs/workbench/parts/preferences/browser/settingsEditor2.ts index 6badba1d9e9..e68f38cf190 100644 --- a/src/vs/workbench/parts/preferences/browser/settingsEditor2.ts +++ b/src/vs/workbench/parts/preferences/browser/settingsEditor2.ts @@ -26,11 +26,15 @@ import { IEnvironmentService } from 'vs/platform/environment/common/environment' import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; import { WorkbenchTree } from 'vs/platform/list/browser/listService'; import { ILogService } from 'vs/platform/log/common/log'; +import { INotificationService } from 'vs/platform/notification/common/notification'; +import { IStorageService, StorageScope } from 'vs/platform/storage/common/storage'; import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry'; +import { badgeBackground, badgeForeground, contrastBorder, editorForeground } from 'vs/platform/theme/common/colorRegistry'; import { attachButtonStyler, attachStylerCallback } from 'vs/platform/theme/common/styler'; import { IThemeService } from 'vs/platform/theme/common/themeService'; import { BaseEditor } from 'vs/workbench/browser/parts/editor/baseEditor'; import { EditorOptions, IEditor } from 'vs/workbench/common/editor'; +import { ResourceEditorModel } from 'vs/workbench/common/editor/resourceEditorModel'; import { SuggestEnabledInput } from 'vs/workbench/parts/codeEditor/browser/suggestEnabledInput'; import { PreferencesEditor } from 'vs/workbench/parts/preferences/browser/preferencesEditor'; import { SettingsTarget, SettingsTargetsWidget } from 'vs/workbench/parts/preferences/browser/preferencesWidgets'; @@ -43,10 +47,6 @@ import { IEditorGroup } from 'vs/workbench/services/group/common/editorGroupsSer import { IPreferencesService, ISearchResult, ISettingsEditorModel } from 'vs/workbench/services/preferences/common/preferences'; import { SettingsEditor2Input } from 'vs/workbench/services/preferences/common/preferencesEditorInput'; import { DefaultSettingsEditorModel } from 'vs/workbench/services/preferences/common/preferencesModels'; -import { ResourceEditorModel } from 'vs/workbench/common/editor/resourceEditorModel'; -import { badgeBackground, contrastBorder, badgeForeground, editorForeground } from 'vs/platform/theme/common/colorRegistry'; -import { IStorageService, StorageScope } from 'vs/platform/storage/common/storage'; -import { INotificationService } from 'vs/platform/notification/common/notification'; const $ = DOM.$; From fc739fedbd1b1a50efb7e7c08d6ce9a141878154 Mon Sep 17 00:00:00 2001 From: Jackson Kearl <jkearl@mit.edu> Date: Fri, 24 Aug 2018 10:02:35 -0700 Subject: [PATCH 1234/1276] Notify no need to save on save --- .../parts/files/electron-browser/fileCommands.ts | 6 ++++++ .../parts/preferences/browser/settingsEditor2.ts | 8 ++++++-- 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/src/vs/workbench/parts/files/electron-browser/fileCommands.ts b/src/vs/workbench/parts/files/electron-browser/fileCommands.ts index 2e4edb6e547..5729f0571c8 100644 --- a/src/vs/workbench/parts/files/electron-browser/fileCommands.ts +++ b/src/vs/workbench/parts/files/electron-browser/fileCommands.ts @@ -42,6 +42,7 @@ import { EditorContextKeys } from 'vs/editor/common/editorContextKeys'; import { IEditorService, SIDE_GROUP } from 'vs/workbench/services/editor/common/editorService'; import { IEditorGroupsService } from 'vs/workbench/services/group/common/editorGroupsService'; import { ILabelService } from 'vs/platform/label/common/label'; +import { SettingsEditor2 } from 'vs/workbench/parts/preferences/browser/settingsEditor2'; // Commands @@ -161,6 +162,11 @@ function save( // Just save return textFileService.save(resource, { force: true /* force a change to the file to trigger external watchers if any */ }); + } else if (resource && resource.scheme === Schemas.vscode) { + const activeControl = editorService.activeControl; + if (activeControl instanceof SettingsEditor2) { + activeControl.notifyNoSaveNeeded(); + } } return TPromise.as(false); diff --git a/src/vs/workbench/parts/preferences/browser/settingsEditor2.ts b/src/vs/workbench/parts/preferences/browser/settingsEditor2.ts index e68f38cf190..2b9867a41b8 100644 --- a/src/vs/workbench/parts/preferences/browser/settingsEditor2.ts +++ b/src/vs/workbench/parts/preferences/browser/settingsEditor2.ts @@ -488,11 +488,15 @@ export class SettingsEditor2 extends BaseEditor { })); } - private onDidChangeSetting(key: string, value: any): void { - if (!this.storageService.getBoolean('hasNotifiedOfSettingsAutosave', StorageScope.GLOBAL, false)) { + public notifyNoSaveNeeded(force: boolean = true) { + if (force || !this.storageService.getBoolean('hasNotifiedOfSettingsAutosave', StorageScope.GLOBAL, false)) { this.storageService.store('hasNotifiedOfSettingsAutosave', true, StorageScope.GLOBAL); this.notificationService.info(localize('settingsNoSaveNeeded', "Your changes are automatically saved as you edit.")); } + } + + private onDidChangeSetting(key: string, value: any): void { + this.notifyNoSaveNeeded(false); if (this.pendingSettingUpdate && this.pendingSettingUpdate.key !== key) { this.updateChangedSetting(key, value); From 0c83ba6b80681b9aac54faf81fbb53461b0c2c94 Mon Sep 17 00:00:00 2001 From: Jackson Kearl <jkearl@mit.edu> Date: Fri, 24 Aug 2018 10:13:39 -0700 Subject: [PATCH 1235/1276] Remove "Copy Setting Name", move "Reset Setting" to top --- .../parts/preferences/browser/settingsTree.ts | 31 +++---------------- 1 file changed, 5 insertions(+), 26 deletions(-) diff --git a/src/vs/workbench/parts/preferences/browser/settingsTree.ts b/src/vs/workbench/parts/preferences/browser/settingsTree.ts index 21d0bb57bee..caf1f7ff361 100644 --- a/src/vs/workbench/parts/preferences/browser/settingsTree.ts +++ b/src/vs/workbench/parts/preferences/browser/settingsTree.ts @@ -318,17 +318,16 @@ export class SettingsRenderer implements ITreeRenderer { this.descriptionMeasureContainer))); this.settingActions = [ - this.instantiationService.createInstance(CopySettingNameAction), - this.instantiationService.createInstance(CopySettingIdAction), - this.instantiationService.createInstance(CopySettingAsJSONAction), - new Separator(), new Action('settings.resetSetting', localize('resetSettingLabel', "Reset Setting"), undefined, undefined, (context: SettingsTreeSettingElement) => { if (context) { this._onDidChangeSetting.fire({ key: context.setting.key, value: undefined }); } return TPromise.wrap(null); - }) + }), + new Separator(), + this.instantiationService.createInstance(CopySettingIdAction), + this.instantiationService.createInstance(CopySettingAsJSONAction), ]; } @@ -1482,24 +1481,4 @@ class CopySettingAsJSONAction extends Action { return TPromise.as(null); } -} - -class CopySettingNameAction extends Action { - static readonly ID = 'settings.copySettingName'; - static readonly LABEL = localize('copySettingNameLabel', "Copy Setting Name"); - - constructor( - @IClipboardService private clipboardService: IClipboardService - ) { - super(CopySettingNameAction.ID, CopySettingNameAction.LABEL); - } - - run(context: SettingsTreeSettingElement): TPromise<void> { - if (context) { - const name = `${context.displayCategory}: ${context.displayLabel}`; - this.clipboardService.writeText(name); - } - - return TPromise.as(null); - } -} +} \ No newline at end of file From 304284313ef4a1c7b815f03dfd8640e8e3458637 Mon Sep 17 00:00:00 2001 From: Jackson Kearl <jkearl@mit.edu> Date: Fri, 24 Aug 2018 10:35:00 -0700 Subject: [PATCH 1236/1276] Add element with tooltip as modifided indicator --- .../preferences/browser/media/settingsEditor2.css | 13 ++++++++++--- .../parts/preferences/browser/settingsTree.ts | 5 +++++ .../parts/preferences/browser/settingsWidgets.ts | 2 +- 3 files changed, 16 insertions(+), 4 deletions(-) diff --git a/src/vs/workbench/parts/preferences/browser/media/settingsEditor2.css b/src/vs/workbench/parts/preferences/browser/media/settingsEditor2.css index 70a86e090fe..67c8790f01a 100644 --- a/src/vs/workbench/parts/preferences/browser/media/settingsEditor2.css +++ b/src/vs/workbench/parts/preferences/browser/media/settingsEditor2.css @@ -281,17 +281,24 @@ text-overflow: ellipsis; } -.settings-editor > .settings-body > .settings-tree-container .setting-item.is-configured::after { + +.settings-editor > .settings-body > .settings-tree-container .setting-item > .setting-item-modified-indicator { + display: none; +} + +.settings-editor > .settings-body > .settings-tree-container .setting-item.is-configured > .setting-item-modified-indicator { display: block; content: ' '; position: absolute; - width: 2px; + width: 6px; + border-left-width: 2px; + border-left-style: solid; left: 0px; top: 15px; bottom: 16px; } -.settings-editor > .settings-body > .settings-tree-container .setting-item-bool.setting-item.is-configured::after { +.settings-editor > .settings-body > .settings-tree-container .setting-item-bool.is-configured > .setting-item-modified-indicator { bottom: 23px; } diff --git a/src/vs/workbench/parts/preferences/browser/settingsTree.ts b/src/vs/workbench/parts/preferences/browser/settingsTree.ts index caf1f7ff361..a750bd5987b 100644 --- a/src/vs/workbench/parts/preferences/browser/settingsTree.ts +++ b/src/vs/workbench/parts/preferences/browser/settingsTree.ts @@ -521,6 +521,8 @@ export class SettingsRenderer implements ITreeRenderer { const labelElement = DOM.append(labelCategoryContainer, $('span.setting-item-label')); const otherOverridesElement = DOM.append(titleElement, $('span.setting-item-overrides')); const descriptionElement = DOM.append(container, $('.setting-item-description')); + const modifiedIndicatorElement = DOM.append(container, $('.setting-item-modified-indicator')); + modifiedIndicatorElement.title = localize('modified', "Modified"); const valueElement = DOM.append(container, $('.setting-item-value')); const controlElement = DOM.append(valueElement, $('div.setting-item-control')); @@ -660,6 +662,9 @@ export class SettingsRenderer implements ITreeRenderer { const descriptionAndValueElement = DOM.append(container, $('.setting-item-value-description')); const controlElement = DOM.append(descriptionAndValueElement, $('.setting-item-bool-control')); const descriptionElement = DOM.append(descriptionAndValueElement, $('.setting-item-description')); + const modifiedIndicatorElement = DOM.append(container, $('.setting-item-modified-indicator')); + modifiedIndicatorElement.title = localize('modified', "Modified"); + const deprecationWarningElement = DOM.append(container, $('.setting-item-deprecation-message')); diff --git a/src/vs/workbench/parts/preferences/browser/settingsWidgets.ts b/src/vs/workbench/parts/preferences/browser/settingsWidgets.ts index 998e7f67552..84516598f85 100644 --- a/src/vs/workbench/parts/preferences/browser/settingsWidgets.ts +++ b/src/vs/workbench/parts/preferences/browser/settingsWidgets.ts @@ -118,7 +118,7 @@ registerThemingParticipant((theme: ITheme, collector: ICssStyleCollector) => { const modifiedItemIndicatorColor = theme.getColor(modifiedItemIndicator); if (modifiedItemIndicatorColor) { - collector.addRule(`.settings-editor > .settings-body > .settings-tree-container .setting-item.is-configured::after { background-color: ${modifiedItemIndicatorColor}; }`); + collector.addRule(`.settings-editor > .settings-body > .settings-tree-container .setting-item > .setting-item-modified-indicator { border-color: ${modifiedItemIndicatorColor}; }`); } }); From 76e67274589ded43f638d187d6756ad527b2d4ed Mon Sep 17 00:00:00 2001 From: Jackson Kearl <jkearl11@gmail.com> Date: Fri, 24 Aug 2018 10:52:33 -0700 Subject: [PATCH 1237/1276] Simplify and fix bugs in no results/result count message logic (#57116) * Simplify and fix bugs in no results/result count message logic * Put count render logic behind debouncer * formatting * remove log --- .../parts/preferences/browser/settingsEditor2.ts | 15 ++++++--------- .../preferences/browser/settingsTreeModels.ts | 16 ++++++++++++++++ 2 files changed, 22 insertions(+), 9 deletions(-) diff --git a/src/vs/workbench/parts/preferences/browser/settingsEditor2.ts b/src/vs/workbench/parts/preferences/browser/settingsEditor2.ts index c4732771624..90bd7ee07c7 100644 --- a/src/vs/workbench/parts/preferences/browser/settingsEditor2.ts +++ b/src/vs/workbench/parts/preferences/browser/settingsEditor2.ts @@ -36,7 +36,7 @@ import { PreferencesEditor } from 'vs/workbench/parts/preferences/browser/prefer import { SettingsTarget, SettingsTargetsWidget } from 'vs/workbench/parts/preferences/browser/preferencesWidgets'; import { commonlyUsedData, tocData } from 'vs/workbench/parts/preferences/browser/settingsLayout'; import { resolveExtensionsSettings, resolveSettingsTree, SettingsRenderer, SettingsTree } from 'vs/workbench/parts/preferences/browser/settingsTree'; -import { ISettingsEditorViewState, MODIFIED_SETTING_TAG, ONLINE_SERVICES_SETTING_TAG, SearchResultIdx, SearchResultModel, SettingsTreeGroupElement, SettingsTreeModel, SettingsTreeSettingElement } from 'vs/workbench/parts/preferences/browser/settingsTreeModels'; +import { ISettingsEditorViewState, MODIFIED_SETTING_TAG, ONLINE_SERVICES_SETTING_TAG, SearchResultIdx, SearchResultModel, SettingsTreeGroupElement, SettingsTreeModel, SettingsTreeSettingElement, countSettingGroupChildrenWithPredicate } from 'vs/workbench/parts/preferences/browser/settingsTreeModels'; import { TOCRenderer, TOCTree, TOCTreeModel } from 'vs/workbench/parts/preferences/browser/tocTree'; import { CONTEXT_SETTINGS_EDITOR, CONTEXT_SETTINGS_SEARCH_FOCUS, CONTEXT_TOC_ROW_FOCUS, IPreferencesSearchService, ISearchProvider } from 'vs/workbench/parts/preferences/common/preferences'; import { IEditorGroup } from 'vs/workbench/services/group/common/editorGroupsService'; @@ -769,7 +769,6 @@ export class SettingsEditor2 extends BaseEditor { private onSearchInputChanged(): void { const query = this.searchWidget.getValue().trim(); - if (query === '') { this.countElement.style.display = 'none'; this.noResultsMessage.style.display = 'none'; } this.delayedFilterLogging.cancel(); this.triggerSearch(query.replace(/›/g, ' ')).then(() => { if (query && this.searchResultModel) { @@ -822,9 +821,9 @@ export class SettingsEditor2 extends BaseEditor { collapseAll(this.tocTree); if (this.searchResultModel) { - return this.settingsTree.setInput(this.searchResultModel.root); + return this.settingsTree.setInput(this.searchResultModel.root).then(() => this.renderResultCountMessages()); } else { - return this.settingsTree.setInput(this.settingsTreeModel.root); + return this.settingsTree.setInput(this.settingsTreeModel.root).then(() => this.renderResultCountMessages()); } } } @@ -908,7 +907,7 @@ export class SettingsEditor2 extends BaseEditor { TPromise.wrap(null); }); } - }); + }).then(() => this.renderResultCountMessages()); } else { return TPromise.wrap(null); } @@ -945,12 +944,9 @@ export class SettingsEditor2 extends BaseEditor { this.settingsTree.setInput(this.searchResultModel.root); } else { this.tocTreeModel.update(); - expandAll(this.tocTree); this.searchResultModel.setResult(type, result); } - let count = this.searchResultModel.getUniqueResults().map(result => result ? result.filterMatches.length : 0).reduce((a, b) => a + b); - this.renderResultCountMessages(count); this.tocTree.setSelection([]); expandAll(this.tocTree); @@ -959,7 +955,8 @@ export class SettingsEditor2 extends BaseEditor { }); } - private renderResultCountMessages(count: number) { + private renderResultCountMessages() { + let count = countSettingGroupChildrenWithPredicate(this.settingsTree.getInput() as SettingsTreeGroupElement, element => element.matchesAllTags(this.viewState.tagFilters)); switch (count) { case 0: this.countElement.innerText = localize('noResults', "No Settings Found"); break; case 1: this.countElement.innerText = localize('oneResult', "1 Setting Found"); break; diff --git a/src/vs/workbench/parts/preferences/browser/settingsTreeModels.ts b/src/vs/workbench/parts/preferences/browser/settingsTreeModels.ts index b113a1343e0..cbbc0a6672a 100644 --- a/src/vs/workbench/parts/preferences/browser/settingsTreeModels.ts +++ b/src/vs/workbench/parts/preferences/browser/settingsTreeModels.ts @@ -175,6 +175,22 @@ export class SettingsTreeSettingElement extends SettingsTreeElement { } } +export function countSettingGroupChildrenWithPredicate(tree: SettingsTreeGroupElement, predicate: (setting: SettingsTreeSettingElement) => boolean): number { + const recursiveCounter: (root: SettingsTreeGroupElement | SettingsTreeSettingElement | SettingsTreeNewExtensionsElement) => number = + root => { + if (root instanceof SettingsTreeGroupElement) { + return root.children.map(child => recursiveCounter(child)).reduce((a, b) => a + b, 0); + } else if (root instanceof SettingsTreeSettingElement) { + return +predicate(root); + } else if (root instanceof SettingsTreeNewExtensionsElement) { + return 0; + } + + throw new Error('Argument to settingsTreeChildrenCount should only have group, setting, or extension elements'); + }; + return recursiveCounter(tree); +} + export class SettingsTreeModel { protected _root: SettingsTreeGroupElement; private _treeElementsById = new Map<string, SettingsTreeElement>(); From c2d594a4c2e270821a2110b2dc205c60c1066ba2 Mon Sep 17 00:00:00 2001 From: Jackson Kearl <jkearl@mit.edu> Date: Fri, 24 Aug 2018 11:00:20 -0700 Subject: [PATCH 1238/1276] Fix bug causing exclude control add button to not actually add. Fixes #57167. --- src/vs/workbench/parts/preferences/browser/settingsWidgets.ts | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/vs/workbench/parts/preferences/browser/settingsWidgets.ts b/src/vs/workbench/parts/preferences/browser/settingsWidgets.ts index 84516598f85..ae0ad8a2d15 100644 --- a/src/vs/workbench/parts/preferences/browser/settingsWidgets.ts +++ b/src/vs/workbench/parts/preferences/browser/settingsWidgets.ts @@ -403,9 +403,8 @@ export class ExcludeSettingWidget extends Disposable { pattern, sibling: siblingInput && siblingInput.value.trim() }); - } else { - this.renderList(); } + this.renderList(); }; const onKeydown = (e: StandardKeyboardEvent) => { From 537a5479dd1a914ceacaf0c686c03a5041b0121c Mon Sep 17 00:00:00 2001 From: SteVen Batten <6561887+sbatten@users.noreply.github.com> Date: Fri, 24 Aug 2018 14:26:20 -0700 Subject: [PATCH 1239/1276] Accessibility Updates for Mnemonics and Structuring (#57114) * several accessibility fixes * add checked item aria tag * more cleanup * add ts type --- src/vs/base/browser/ui/actionbar/actionbar.ts | 4 +-- src/vs/base/browser/ui/menu/menu.ts | 29 ++++++++++++------- .../browser/parts/titlebar/menubarControl.ts | 24 ++++++++++----- 3 files changed, 36 insertions(+), 21 deletions(-) diff --git a/src/vs/base/browser/ui/actionbar/actionbar.ts b/src/vs/base/browser/ui/actionbar/actionbar.ts index 0dc7a39304b..fd0a1c2e2f1 100644 --- a/src/vs/base/browser/ui/actionbar/actionbar.ts +++ b/src/vs/base/browser/ui/actionbar/actionbar.ts @@ -694,7 +694,7 @@ export class ActionBar implements IActionRunner { protected updateFocus(fromRight?: boolean): void { if (typeof this.focusedItem === 'undefined') { - this.domNode.focus(); + this.actionsList.focus(); } for (let i = 0; i < this.items.length; i++) { @@ -707,7 +707,7 @@ export class ActionBar implements IActionRunner { if (actionItem.isEnabled() && types.isFunction(actionItem.focus)) { actionItem.focus(fromRight); } else { - this.domNode.focus(); + this.actionsList.focus(); } } } else { diff --git a/src/vs/base/browser/ui/menu/menu.ts b/src/vs/base/browser/ui/menu/menu.ts index b4a02afc7dc..b4c67882ff6 100644 --- a/src/vs/base/browser/ui/menu/menu.ts +++ b/src/vs/base/browser/ui/menu/menu.ts @@ -61,7 +61,7 @@ export class Menu extends ActionBar { this.actionsList.setAttribute('role', 'menu'); - this.domNode.tabIndex = 0; + this.actionsList.tabIndex = 0; this.menuDisposables = []; @@ -208,8 +208,8 @@ interface IMenuItemOptions extends IActionItemOptions { } class MenuActionItem extends BaseActionItem { - static MNEMONIC_REGEX: RegExp = /&&(.)/g; - static ESCAPED_MNEMONIC_REGEX: RegExp = /&&(.)/g; + static MNEMONIC_REGEX: RegExp = /&&(.)/; + static ESCAPED_MNEMONIC_REGEX: RegExp = /&&(.)/; public container: HTMLElement; protected $e: Builder; @@ -251,13 +251,16 @@ class MenuActionItem extends BaseActionItem { this.$e.attr({ role: 'presentation' }); } else { this.$e.attr({ role: 'menuitem' }); + if (this.mnemonic) { + this.$e.attr({ 'aria-keyshortcuts': this.mnemonic }); + } } - this.$check = $('span.menu-item-check').appendTo(this.$e); - this.$label = $('span.action-label').appendTo(this.$e); + this.$check = $('span.menu-item-check').attr({ 'role': 'none' }).appendTo(this.$e); + this.$label = $('span.action-label').attr({ 'role': 'none' }).appendTo(this.$e); if (this.options.label && this.options.keybinding) { - $('span.keybinding').text(this.options.keybinding).appendTo(this.$e); + $('span.keybinding').attr({ 'role': 'none' }).text(this.options.keybinding).appendTo(this.$e); } this._updateClass(); @@ -275,10 +278,11 @@ class MenuActionItem extends BaseActionItem { _updateLabel(): void { if (this.options.label) { let label = this.getAction().label; + let mnemonic: string; if (label) { let matches = MenuActionItem.MNEMONIC_REGEX.exec(label); if (matches && matches.length === 2) { - let mnemonic = matches[1]; + mnemonic = matches[1]; let ariaLabel = label.replace(MenuActionItem.MNEMONIC_REGEX, mnemonic); @@ -289,8 +293,9 @@ class MenuActionItem extends BaseActionItem { this.$label.attr('aria-label', label); } - if (this.options.enableMnemonics) { + if (this.options.enableMnemonics && mnemonic) { label = strings.escape(label).replace(MenuActionItem.ESCAPED_MNEMONIC_REGEX, '<u>$1</u>'); + this.$e.attr({ 'aria-keyshortcuts': mnemonic.toLocaleLowerCase() }); } else { label = strings.escape(label).replace(MenuActionItem.ESCAPED_MNEMONIC_REGEX, '$1'); } @@ -350,8 +355,10 @@ class MenuActionItem extends BaseActionItem { _updateChecked(): void { if (this.getAction().checked) { this.$e.addClass('checked'); + this.$e.attr({ 'role': 'menuitemcheckbox', 'aria-checked': true }); } else { this.$e.removeClass('checked'); + this.$e.attr({ 'role': 'menuitem', 'aria-checked': false }); } } @@ -395,11 +402,11 @@ class SubmenuActionItem extends MenuActionItem { this.$e.addClass('monaco-submenu-item'); this.$e.attr('aria-haspopup', 'true'); - $('span.submenu-indicator').text('\u25B6').appendTo(this.$e); + $('span.submenu-indicator').attr('aria-hidden', 'true').text('\u25B6').appendTo(this.$e); $(this.builder).on(EventType.KEY_UP, (e) => { let event = new StandardKeyboardEvent(e as KeyboardEvent); - if (event.equals(KeyCode.RightArrow)) { + if (event.equals(KeyCode.RightArrow) || event.equals(KeyCode.Enter)) { EventHelper.stop(e, true); this.createSubmenu(true); @@ -408,7 +415,7 @@ class SubmenuActionItem extends MenuActionItem { $(this.builder).on(EventType.KEY_DOWN, (e) => { let event = new StandardKeyboardEvent(e as KeyboardEvent); - if (event.equals(KeyCode.RightArrow)) { + if (event.equals(KeyCode.RightArrow) || event.equals(KeyCode.Enter)) { EventHelper.stop(e, true); } }); diff --git a/src/vs/workbench/browser/parts/titlebar/menubarControl.ts b/src/vs/workbench/browser/parts/titlebar/menubarControl.ts index dbcb3c29de4..3650edb20d2 100644 --- a/src/vs/workbench/browser/parts/titlebar/menubarControl.ts +++ b/src/vs/workbench/browser/parts/titlebar/menubarControl.ts @@ -336,6 +336,7 @@ export class MenubarControl extends Disposable { } else { DOM.addClass(this.container, 'inactive'); this.setUnfocusedState(); + this.awaitingAltRelease = false; } } } @@ -659,8 +660,8 @@ export class MenubarControl extends Disposable { // Create the top level menu button element if (firstTimeSetup) { - const buttonElement = $('div.menubar-menu-button', { 'role': 'menu', 'tabindex': 0, 'aria-label': this.topLevelTitles[menuTitle].replace(/&&(.)/g, '$1') }); - const titleElement = $('div.menubar-menu-title', { 'aria-hidden': true }); + const buttonElement = $('div.menubar-menu-button', { 'role': 'menuitem', 'tabindex': 0, 'aria-label': this.topLevelTitles[menuTitle].replace(/&&(.)/g, '$1'), 'aria-haspopup': true }); + const titleElement = $('div.menubar-menu-title', { 'role': 'none', 'aria-hidden': true }); buttonElement.appendChild(titleElement); this.container.appendChild(buttonElement); @@ -673,15 +674,21 @@ export class MenubarControl extends Disposable { } // Update the button label to reflect mnemonics - let displayTitle = this.topLevelTitles[menuTitle].replace(/&&(.)/g, this.currentEnableMenuBarMnemonics ? '<mnemonic>$1</mnemonic>' : '$1'); + let displayTitle = this.topLevelTitles[menuTitle].replace(/&&(.)/g, this.currentEnableMenuBarMnemonics ? '<mnemonic aria-hidden="true">$1</mnemonic>' : '$1'); this.customMenus[menuIndex].titleElement.innerHTML = displayTitle; // Register mnemonics - if (firstTimeSetup) { - let mnemonic = (/&&(.)/g).exec(this.topLevelTitles[menuTitle]); - if (mnemonic && mnemonic[1]) { + let mnemonic = (/&&(.)/g).exec(this.topLevelTitles[menuTitle]); + if (mnemonic && mnemonic[1]) { + if (firstTimeSetup) { this.registerMnemonic(menuIndex, mnemonic[1]); } + + if (this.currentEnableMenuBarMnemonics) { + this.customMenus[menuIndex].buttonElement.setAttribute('aria-keyshortcuts', 'Alt+' + mnemonic[1].toLocaleLowerCase()); + } else { + this.customMenus[menuIndex].buttonElement.removeAttribute('aria-keyshortcuts'); + } } // Update the menu actions @@ -845,7 +852,7 @@ export class MenubarControl extends Disposable { } } else { this.focusedMenu = { index: menuIndex }; - this.openedViaKeyboard = clicked; + this.openedViaKeyboard = !clicked; this.focusState = MenubarState.OPEN; } } @@ -1021,7 +1028,8 @@ export class MenubarControl extends Disposable { let menuOptions: IMenuOptions = { getKeyBinding: (action) => this.keybindingService.lookupKeybinding(action.id), actionRunner: this.actionRunner, - enableMnemonics: this.mnemonicsInUse + enableMnemonics: this.mnemonicsInUse, + ariaLabel: customMenu.buttonElement.attributes['aria-label'].value }; let menuWidget = this._register(new Menu(menuHolder, customMenu.actions, menuOptions)); From 51fca9825b5de17004a2ef258c521e59e96b9988 Mon Sep 17 00:00:00 2001 From: Jackson Kearl <jkearl@mit.edu> Date: Fri, 24 Aug 2018 14:50:03 -0700 Subject: [PATCH 1240/1276] Exclude control new items go to bottom of list rather than top, when conditions can be edited --- .../parts/preferences/browser/settingsTree.ts | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/src/vs/workbench/parts/preferences/browser/settingsTree.ts b/src/vs/workbench/parts/preferences/browser/settingsTree.ts index a750bd5987b..146448cfe11 100644 --- a/src/vs/workbench/parts/preferences/browser/settingsTree.ts +++ b/src/vs/workbench/parts/preferences/browser/settingsTree.ts @@ -48,7 +48,7 @@ const $ = DOM.$; function getExcludeDisplayValue(element: SettingsTreeSettingElement): IExcludeDataItem[] { const data = element.isConfigured ? - objects.mixin({ ...element.scopeValue }, element.defaultValue, false) : + { ...element.defaultValue, ...element.scopeValue } : element.defaultValue; return Object.keys(data) @@ -801,12 +801,20 @@ export class SettingsRenderer implements ITreeRenderer { if (e.pattern) { if (e.originalPattern in newValue) { // editing something present in the value - newValue[e.pattern] = newValue[e.originalPattern]; - delete newValue[e.originalPattern]; + if (e.pattern === e.originalPattern) { + // editing the when condition + newValue[e.pattern] = e.sibling ? { when: e.sibling } : true; + } else { + newValue[e.pattern] = newValue[e.originalPattern]; + delete newValue[e.originalPattern]; + } } else if (e.originalPattern) { // editing a default newValue[e.originalPattern] = false; newValue[e.pattern] = template.context.defaultValue[e.originalPattern]; + } else if (e.pattern in newValue) { + // Adding back an explicity overridden default pattern + delete newValue[e.pattern]; } else { // adding a new pattern newValue[e.pattern] = true; @@ -823,7 +831,7 @@ export class SettingsRenderer implements ITreeRenderer { this._onDidChangeSetting.fire({ key: template.context.setting.key, - value: newValue + value: Object.keys(newValue).length === 0 ? undefined : newValue }); } })); From 1ae8d0168e1ce3cadf053f6edf7ea8e706af766c Mon Sep 17 00:00:00 2001 From: Andre Weinand <weinand@mac.com> Date: Sat, 25 Aug 2018 00:19:46 +0200 Subject: [PATCH 1241/1276] auto-attach cleanup --- extensions/debug-auto-launch/src/extension.ts | 100 ++++++++++-------- 1 file changed, 57 insertions(+), 43 deletions(-) diff --git a/extensions/debug-auto-launch/src/extension.ts b/extensions/debug-auto-launch/src/extension.ts index 2676fbf6cd0..3f101d071bf 100644 --- a/extensions/debug-auto-launch/src/extension.ts +++ b/extensions/debug-auto-launch/src/extension.ts @@ -13,68 +13,72 @@ const ON_TEXT = localize('status.text.auto.attach.on', "Auto Attach: On"); const OFF_TEXT = localize('status.text.auto.attach.off', "Auto Attach: Off"); const TOGGLE_COMMAND = 'extension.node-debug.toggleAutoAttach'; +const DEBUG_SETTINGS = 'debug.node'; +const AUTO_ATTACH_SETTING = 'autoAttach'; -let currentState: string; +type AUTO_ATTACH_VALUES = 'disabled' | 'on' | 'off'; + +let currentState: AUTO_ATTACH_VALUES = 'disabled'; // on activation this feature is always disabled and +let statusItem: vscode.StatusBarItem | undefined; // there is no status bar item let autoAttachStarted = false; -let statusItem: vscode.StatusBarItem | undefined = undefined; export function activate(context: vscode.ExtensionContext): void { - context.subscriptions.push(vscode.commands.registerCommand(TOGGLE_COMMAND, toggleAutoAttach)); + context.subscriptions.push(vscode.commands.registerCommand(TOGGLE_COMMAND, toggleAutoAttachSetting)); context.subscriptions.push(vscode.workspace.onDidChangeConfiguration(e => { - if (e.affectsConfiguration('debug.node.autoAttach')) { - updateAutoAttachInStatus(context); + if (e.affectsConfiguration(DEBUG_SETTINGS + '.' + AUTO_ATTACH_SETTING)) { + updateAutoAttach(context); } })); - updateAutoAttachInStatus(context); + updateAutoAttach(context); } export function deactivate(): void { } -function toggleAutoAttach(context: vscode.ExtensionContext) { +function toggleAutoAttachSetting(context: vscode.ExtensionContext) { - const conf = vscode.workspace.getConfiguration('debug.node'); + const conf = vscode.workspace.getConfiguration(DEBUG_SETTINGS); + if (conf) { + let value = <AUTO_ATTACH_VALUES>conf.get(AUTO_ATTACH_SETTING); + if (value === 'on') { + value = 'off'; + } else { + value = 'on'; + } - let value = conf.get('autoAttach'); - if (value === 'on') { - value = 'off'; - } else { - value = 'on'; - } - - const info = conf.inspect('autoAttach'); - let target: vscode.ConfigurationTarget = vscode.ConfigurationTarget.Global; - if (info) { - if (info.workspaceFolderValue) { - target = vscode.ConfigurationTarget.WorkspaceFolder; - } else if (info.workspaceValue) { - target = vscode.ConfigurationTarget.Workspace; - } else if (info.globalValue) { - target = vscode.ConfigurationTarget.Global; - } else if (info.defaultValue) { - // setting not yet used: store setting in workspace - if (vscode.workspace.workspaceFolders) { + const info = conf.inspect(AUTO_ATTACH_SETTING); + let target: vscode.ConfigurationTarget = vscode.ConfigurationTarget.Global; + if (info) { + if (info.workspaceFolderValue) { + target = vscode.ConfigurationTarget.WorkspaceFolder; + } else if (info.workspaceValue) { target = vscode.ConfigurationTarget.Workspace; + } else if (info.globalValue) { + target = vscode.ConfigurationTarget.Global; + } else if (info.defaultValue) { + // setting not yet used: store setting in workspace + if (vscode.workspace.workspaceFolders) { + target = vscode.ConfigurationTarget.Workspace; + } } } + conf.update(AUTO_ATTACH_SETTING, value, target); } - conf.update('autoAttach', value, target); - - updateAutoAttachInStatus(context); } -function updateAutoAttachInStatus(context: vscode.ExtensionContext) { +/** + * Updates the auto attach feature based on the user or workspace setting + */ +function updateAutoAttach(context: vscode.ExtensionContext) { - const newState = <string>vscode.workspace.getConfiguration('debug.node').get('autoAttach'); + const newState = <AUTO_ATTACH_VALUES>vscode.workspace.getConfiguration(DEBUG_SETTINGS).get(AUTO_ATTACH_SETTING); if (newState !== currentState) { - currentState = newState; - if (newState === 'disabled') { // turn everything off @@ -83,8 +87,10 @@ function updateAutoAttachInStatus(context: vscode.ExtensionContext) { statusItem.text = OFF_TEXT; } if (autoAttachStarted) { - autoAttachStarted = false; - vscode.commands.executeCommand('extension.node-debug.stopAutoAttach'); + vscode.commands.executeCommand('extension.node-debug.stopAutoAttach').then(_ => { + currentState = newState; + autoAttachStarted = false; + }); } } else { // 'on' or 'off' @@ -93,7 +99,6 @@ function updateAutoAttachInStatus(context: vscode.ExtensionContext) { if (!statusItem) { statusItem = vscode.window.createStatusBarItem(vscode.StatusBarAlignment.Left); statusItem.command = TOGGLE_COMMAND; - statusItem.text = OFF_TEXT; statusItem.tooltip = localize('status.tooltip.auto.attach', "Automatically attach to node.js processes in debug mode"); statusItem.show(); context.subscriptions.push(statusItem); @@ -102,18 +107,27 @@ function updateAutoAttachInStatus(context: vscode.ExtensionContext) { } if (newState === 'off') { - statusItem.text = OFF_TEXT; if (autoAttachStarted) { - autoAttachStarted = false; - vscode.commands.executeCommand('extension.node-debug.stopAutoAttach'); + vscode.commands.executeCommand('extension.node-debug.stopAutoAttach').then(_ => { + currentState = newState; + if (statusItem) { + statusItem.text = OFF_TEXT; + } + autoAttachStarted = false; + }); } } else if (newState === 'on') { - statusItem.text = ON_TEXT; + const vscode_pid = process.env['VSCODE_PID']; const rootPid = vscode_pid ? parseInt(vscode_pid) : 0; - vscode.commands.executeCommand('extension.node-debug.startAutoAttach', rootPid); - autoAttachStarted = true; + vscode.commands.executeCommand('extension.node-debug.startAutoAttach', rootPid).then(_ => { + if (statusItem) { + statusItem.text = ON_TEXT; + } + currentState = newState; + autoAttachStarted = true; + }); } } } From 568d99275d8eabab3df5ab2f9c0ae92f2714a801 Mon Sep 17 00:00:00 2001 From: Rob Lourens <roblourens@gmail.com> Date: Fri, 24 Aug 2018 15:43:27 -0700 Subject: [PATCH 1242/1276] #56950 - telemetry for search folder uri scheme --- .../workbench/parts/search/common/searchModel.ts | 13 +++++++++++-- .../services/search/node/searchService.ts | 16 +++++++++++++--- 2 files changed, 24 insertions(+), 5 deletions(-) diff --git a/src/vs/workbench/parts/search/common/searchModel.ts b/src/vs/workbench/parts/search/common/searchModel.ts index cb1aa7e2c70..a4597dd28b6 100644 --- a/src/vs/workbench/parts/search/common/searchModel.ts +++ b/src/vs/workbench/parts/search/common/searchModel.ts @@ -812,13 +812,21 @@ export class SearchModel extends Disposable { const stats = completed && completed.stats as ITextSearchStats; + const fileSchemeOnly = this._searchQuery.folderQueries.every(fq => fq.folder.scheme === 'file'); + const otherSchemeOnly = this._searchQuery.folderQueries.every(fq => fq.folder.scheme !== 'file'); + const scheme = fileSchemeOnly ? 'file' : + otherSchemeOnly ? 'other' : + 'mixed'; + /* __GDPR__ "searchResultsShown" : { "count" : { "classification": "SystemMetaData", "purpose": "FeatureInsight", "isMeasurement": true }, "fileCount": { "classification": "SystemMetaData", "purpose": "FeatureInsight", "isMeasurement": true }, "options": { "${inline}": [ "${IPatternInfo}" ] }, "duration": { "classification": "SystemMetaData", "purpose": "PerformanceAndHealth", "isMeasurement": true }, - "useRipgrep": { "classification": "SystemMetaData", "purpose": "FeatureInsight", "isMeasurement": true } + "useRipgrep": { "classification": "SystemMetaData", "purpose": "FeatureInsight", "isMeasurement": true }, + "type" : { "classification": "SystemMetaData", "purpose": "PerformanceAndHealth" }, + "scheme" : { "classification": "SystemMetaData", "purpose": "PerformanceAndHealth" } } */ this.telemetryService.publicLog('searchResultsShown', { @@ -827,7 +835,8 @@ export class SearchModel extends Disposable { options, duration, useRipgrep: this._searchQuery.useRipgrep, - type: stats && stats.type + type: stats && stats.type, + scheme }); return completed; } diff --git a/src/vs/workbench/services/search/node/searchService.ts b/src/vs/workbench/services/search/node/searchService.ts index c961c514b68..1d2b87147d9 100644 --- a/src/vs/workbench/services/search/node/searchService.ts +++ b/src/vs/workbench/services/search/node/searchService.ts @@ -231,6 +231,12 @@ export class SearchService extends Disposable implements ISearchService { } private sendTelemetry(query: ISearchQuery, endToEndTime: number, complete: ISearchComplete): void { + const fileSchemeOnly = query.folderQueries.every(fq => fq.folder.scheme === 'file'); + const otherSchemeOnly = query.folderQueries.every(fq => fq.folder.scheme !== 'file'); + const scheme = fileSchemeOnly ? 'file' : + otherSchemeOnly ? 'other' : + 'mixed'; + if (query.type === QueryType.File && complete.stats) { const fileSearchStats = complete.stats as IFileSearchStats; if (fileSearchStats.fromCache) { @@ -247,6 +253,7 @@ export class SearchService extends Disposable implements ISearchService { "cacheLookupTime" : { "classification": "SystemMetaData", "purpose": "PerformanceAndHealth", "isMeasurement": true }, "cacheFilterTime" : { "classification": "SystemMetaData", "purpose": "PerformanceAndHealth", "isMeasurement": true }, "cacheEntryCount" : { "classification": "SystemMetaData", "purpose": "PerformanceAndHealth", "isMeasurement": true }, + "scheme" : { "classification": "SystemMetaData", "purpose": "PerformanceAndHealth" }, } */ this.telemetryService.publicLog('cachedSearchComplete', { @@ -258,7 +265,8 @@ export class SearchService extends Disposable implements ISearchService { cacheWasResolved: cacheStats.cacheWasResolved, cacheLookupTime: cacheStats.cacheLookupTime, cacheFilterTime: cacheStats.cacheFilterTime, - cacheEntryCount: cacheStats.cacheEntryCount + cacheEntryCount: cacheStats.cacheEntryCount, + scheme }); } else { const searchEngineStats: ISearchEngineStats = fileSearchStats.detailStats as ISearchEngineStats; @@ -275,7 +283,8 @@ export class SearchService extends Disposable implements ISearchService { "directoriesWalked" : { "classification": "SystemMetaData", "purpose": "PerformanceAndHealth", "isMeasurement": true }, "filesWalked" : { "classification": "SystemMetaData", "purpose": "PerformanceAndHealth", "isMeasurement": true }, "cmdTime" : { "classification": "SystemMetaData", "purpose": "PerformanceAndHealth", "isMeasurement": true }, - "cmdResultCount" : { "classification": "SystemMetaData", "purpose": "PerformanceAndHealth", "isMeasurement": true } + "cmdResultCount" : { "classification": "SystemMetaData", "purpose": "PerformanceAndHealth", "isMeasurement": true }, + "scheme" : { "classification": "SystemMetaData", "purpose": "PerformanceAndHealth" }, } */ this.telemetryService.publicLog('searchComplete', { @@ -289,7 +298,8 @@ export class SearchService extends Disposable implements ISearchService { directoriesWalked: searchEngineStats.directoriesWalked, filesWalked: searchEngineStats.filesWalked, cmdTime: searchEngineStats.cmdTime, - cmdResultCount: searchEngineStats.cmdResultCount + cmdResultCount: searchEngineStats.cmdResultCount, + scheme }); } } From 849322bcc4ef26c0886a63fe750508a12111cc58 Mon Sep 17 00:00:00 2001 From: Jackson Kearl <jkearl@mit.edu> Date: Fri, 24 Aug 2018 15:53:24 -0700 Subject: [PATCH 1243/1276] Simplify exclude state change logic and fix bugs: unable to edit a when setting in some cases unable to edit a defualt setting to/from a nondefault one and probbaly some others. --- .../parts/preferences/browser/settingsTree.ts | 43 +++++++------------ 1 file changed, 15 insertions(+), 28 deletions(-) diff --git a/src/vs/workbench/parts/preferences/browser/settingsTree.ts b/src/vs/workbench/parts/preferences/browser/settingsTree.ts index 146448cfe11..ca990138fff 100644 --- a/src/vs/workbench/parts/preferences/browser/settingsTree.ts +++ b/src/vs/workbench/parts/preferences/browser/settingsTree.ts @@ -794,38 +794,25 @@ export class SettingsRenderer implements ITreeRenderer { common.toDispose.push(excludeWidget.onDidChangeExclude(e => { if (template.context) { - const newValue = { - ...template.context.scopeValue - }; + let newValue = { ...template.context.scopeValue }; - if (e.pattern) { - if (e.originalPattern in newValue) { - // editing something present in the value - if (e.pattern === e.originalPattern) { - // editing the when condition - newValue[e.pattern] = e.sibling ? { when: e.sibling } : true; - } else { - newValue[e.pattern] = newValue[e.originalPattern]; - delete newValue[e.originalPattern]; - } - } else if (e.originalPattern) { - // editing a default + // first delete the existing entry, if present + if (e.originalPattern) { + if (e.originalPattern in template.context.defaultValue) { + // delete a default by overriding it newValue[e.originalPattern] = false; - newValue[e.pattern] = template.context.defaultValue[e.originalPattern]; - } else if (e.pattern in newValue) { - // Adding back an explicity overridden default pattern + } else { + delete newValue[e.originalPattern]; + } + } + + // then add the new or updated entry, if present + if (e.pattern) { + if (e.pattern in template.context.defaultValue && !e.sibling) { + // add a default by deleting its override delete newValue[e.pattern]; } else { - // adding a new pattern - newValue[e.pattern] = true; - } - } else { - if (e.originalPattern in newValue) { - // deleting a configured pattern - delete newValue[e.originalPattern]; - } else if (e.originalPattern) { - // "deleting" a default by overriding it - newValue[e.originalPattern] = false; + newValue[e.pattern] = e.sibling ? { when: e.sibling } : true; } } From 30b1a27aaeb7077c4e44b8e87ade1c243ff014d4 Mon Sep 17 00:00:00 2001 From: Jackson Kearl <jkearl@mit.edu> Date: Fri, 24 Aug 2018 16:18:06 -0700 Subject: [PATCH 1244/1276] Keep display of exclude rows sorted --- .../parts/preferences/browser/settingsTree.ts | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/src/vs/workbench/parts/preferences/browser/settingsTree.ts b/src/vs/workbench/parts/preferences/browser/settingsTree.ts index ca990138fff..34833b637e9 100644 --- a/src/vs/workbench/parts/preferences/browser/settingsTree.ts +++ b/src/vs/workbench/parts/preferences/browser/settingsTree.ts @@ -21,7 +21,6 @@ import { onUnexpectedError } from 'vs/base/common/errors'; import { Emitter, Event } from 'vs/base/common/event'; import { KeyCode } from 'vs/base/common/keyCodes'; import { dispose, IDisposable } from 'vs/base/common/lifecycle'; -import * as objects from 'vs/base/common/objects'; import { escapeRegExpCharacters, startsWith } from 'vs/base/common/strings'; import URI from 'vs/base/common/uri'; import { TPromise } from 'vs/base/common/winjs.base'; @@ -816,9 +815,21 @@ export class SettingsRenderer implements ITreeRenderer { } } + const sortKeys = (obj) => { + const keyArray = Object.keys(obj) + .map(key => ({ key, val: obj[key] })) + .sort((a, b) => a.key.localeCompare(b.key)); + + const retVal = {}; + keyArray.forEach(pair => { + retVal[pair.key] = pair.val; + }); + return retVal; + }; + this._onDidChangeSetting.fire({ key: template.context.setting.key, - value: Object.keys(newValue).length === 0 ? undefined : newValue + value: Object.keys(newValue).length === 0 ? undefined : sortKeys(newValue) }); } })); From 5106fb50b63bd3a0194d275a99ac8377f0942fe2 Mon Sep 17 00:00:00 2001 From: Jackson Kearl <jkearl@mit.edu> Date: Fri, 24 Aug 2018 16:29:46 -0700 Subject: [PATCH 1245/1276] Enable live update of exclude settings --- src/vs/workbench/parts/preferences/browser/settingsEditor2.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/vs/workbench/parts/preferences/browser/settingsEditor2.ts b/src/vs/workbench/parts/preferences/browser/settingsEditor2.ts index 2b9867a41b8..37e6c8b6fb2 100644 --- a/src/vs/workbench/parts/preferences/browser/settingsEditor2.ts +++ b/src/vs/workbench/parts/preferences/browser/settingsEditor2.ts @@ -741,7 +741,9 @@ export class SettingsEditor2 extends BaseEditor { // If a single setting is being refreshed, it's ok to refresh now if that is not the focused setting if (key) { const focusedKey = focusedSetting.getAttribute(SettingsRenderer.SETTING_KEY_ATTR); - if (focusedKey === key) { + if (focusedKey === key && + !DOM.hasClass(focusedSetting, 'setting-item-exclude')) { // update `exclude`s live, as they have a separate "submit edit" step built in before this + this.updateModifiedLabelForKey(key); this.scheduleRefresh(focusedSetting, key); return TPromise.wrap(null); From d791150025573cef995214dd4e07077b297b47f0 Mon Sep 17 00:00:00 2001 From: Christopher Leidigh <cleidigh@Gmail.com> Date: Fri, 24 Aug 2018 19:32:22 -0400 Subject: [PATCH 1246/1276] Settings: call onChange for checkbox toggle (#57184) --- src/vs/workbench/parts/preferences/browser/settingsTree.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/src/vs/workbench/parts/preferences/browser/settingsTree.ts b/src/vs/workbench/parts/preferences/browser/settingsTree.ts index 21d0bb57bee..02addf156b6 100644 --- a/src/vs/workbench/parts/preferences/browser/settingsTree.ts +++ b/src/vs/workbench/parts/preferences/browser/settingsTree.ts @@ -684,6 +684,7 @@ export class SettingsRenderer implements ITreeRenderer { // Toggle target checkbox if (targetElement.tagName.toLowerCase() !== 'a' && targetId === template.checkbox.domNode.id) { template.checkbox.checked = template.checkbox.checked ? false : true; + template.onChange(checkbox.checked); } DOM.EventHelper.stop(e); })); From 3d69f45361df61314010d696f97efe5e0f734923 Mon Sep 17 00:00:00 2001 From: rebornix <penn.lv@gmail.com> Date: Fri, 24 Aug 2018 16:59:06 -0700 Subject: [PATCH 1247/1276] Fix microsoft/vscode-pull-request-github#258. Dipose decorations when it's not a valid comment thread. --- .../parts/comments/electron-browser/commentThreadWidget.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vs/workbench/parts/comments/electron-browser/commentThreadWidget.ts b/src/vs/workbench/parts/comments/electron-browser/commentThreadWidget.ts index 098bc78a191..7dce0085037 100644 --- a/src/vs/workbench/parts/comments/electron-browser/commentThreadWidget.ts +++ b/src/vs/workbench/parts/comments/electron-browser/commentThreadWidget.ts @@ -582,7 +582,7 @@ export class ReviewZoneWidget extends ZoneWidget { this.show({ lineNumber: lineNumber, column: 1 }, 2); } else { this.hide(); - if (this._commentThread === null) { + if (this._commentThread === null || this._commentThread.threadId === null) { this.dispose(); } } From de70176d06e457c96bdbeecea4f4c3aaa4208d92 Mon Sep 17 00:00:00 2001 From: Rob Lourens <roblourens@gmail.com> Date: Fri, 24 Aug 2018 20:36:07 -0700 Subject: [PATCH 1248/1276] Fix #57186, Fix #31551 - implement previewOptions for text search API --- extensions/search-rg/src/ripgrepTextSearch.ts | 18 +- src/vs/platform/search/common/search.ts | 70 ++++++-- src/vs/vscode.proposed.d.ts | 11 +- .../api/electron-browser/mainThreadSearch.ts | 6 +- .../electron-browser/mainThreadWorkspace.ts | 2 +- src/vs/workbench/api/node/extHostSearch.ts | 47 +++-- .../parts/search/browser/searchView.ts | 10 +- .../parts/search/common/queryBuilder.ts | 3 +- .../parts/search/common/searchModel.ts | 88 +++++----- .../search/test/browser/searchActions.test.ts | 19 ++- .../search/test/browser/searchViewlet.test.ts | 31 +++- .../search/test/common/searchModel.test.ts | 38 +++-- .../search/test/common/searchResult.test.ts | 161 +++++++++--------- .../services/search/node/ripgrepTextSearch.ts | 19 ++- .../workbench/services/search/node/search.ts | 57 ++----- .../services/search/node/searchService.ts | 17 +- .../services/search/node/textSearch.ts | 4 +- .../search/node/worker/searchWorker.ts | 24 ++- .../search/node/worker/searchWorkerIpc.ts | 3 +- .../test/node/ripgrepTextSearch.test.ts | 50 ++++-- .../api/extHostSearch.test.ts | 17 +- 21 files changed, 407 insertions(+), 288 deletions(-) diff --git a/extensions/search-rg/src/ripgrepTextSearch.ts b/extensions/search-rg/src/ripgrepTextSearch.ts index 7ba477c724c..07d6541dd73 100644 --- a/extensions/search-rg/src/ripgrepTextSearch.ts +++ b/extensions/search-rg/src/ripgrepTextSearch.ts @@ -67,7 +67,7 @@ export class RipgrepTextSearchEngine { }); let gotResult = false; - this.ripgrepParser = new RipgrepParser(MAX_TEXT_RESULTS, cwd); + this.ripgrepParser = new RipgrepParser(MAX_TEXT_RESULTS, cwd, options.previewOptions); this.ripgrepParser.on('result', (match: vscode.TextSearchResult) => { gotResult = true; progress.report(match); @@ -160,7 +160,7 @@ export class RipgrepParser extends EventEmitter { private numResults = 0; - constructor(private maxResults: number, private rootFolder: string) { + constructor(private maxResults: number, private rootFolder: string, private previewOptions?: vscode.TextSearchPreviewOptions) { super(); this.stringDecoder = new StringDecoder(); } @@ -293,12 +293,22 @@ export class RipgrepParser extends EventEmitter { lineMatches .map(range => { + let trimmedPreview = preview; + let trimmedPreviewRange = range; + if (this.previewOptions) { + const previewStart = Math.max(range.start.character - this.previewOptions.leadingChars, 0); + trimmedPreview = preview.substr(previewStart, this.previewOptions.totalChars - previewStart); + if (previewStart > 0) { + trimmedPreviewRange = new vscode.Range(0, range.start.character - previewStart, 0, range.end.character - previewStart); + } + } + return <vscode.TextSearchResult>{ uri: vscode.Uri.file(path.join(this.rootFolder, this.currentFile)), range, preview: { - text: preview, - match: new vscode.Range(0, range.start.character, 0, range.end.character) + text: trimmedPreview, + match: trimmedPreviewRange || new vscode.Range(0, range.start.character, 0, range.end.character) } }; }) diff --git a/src/vs/platform/search/common/search.ts b/src/vs/platform/search/common/search.ts index 5129ea788b9..b27650c5057 100644 --- a/src/vs/platform/search/common/search.ts +++ b/src/vs/platform/search/common/search.ts @@ -85,6 +85,7 @@ export interface ICommonQueryOptions<U> { disregardExcludeSettings?: boolean; ignoreSymlinks?: boolean; maxFileSize?: number; + previewOptions?: ITextSearchPreviewOptions; } export interface IQueryOptions extends ICommonQueryOptions<uri> { @@ -132,15 +133,33 @@ export interface IPatternInfo { export interface IFileMatch<U extends UriComponents = uri> { resource?: U; - lineMatches?: ILineMatch[]; + matches?: ITextSearchResult[]; } export type IRawFileMatch2 = IFileMatch<UriComponents>; -export interface ILineMatch { - preview: string; - lineNumber: number; - offsetAndLengths: number[][]; +export interface ITextSearchPreviewOptions { + maxLines: number; + leadingChars: number; + totalChars: number; +} + +export interface ISearchRange { + readonly startLineNumber: number; + readonly startColumn: number; + readonly endLineNumber: number; + readonly endColumn: number; +} + +export interface ITextSearchResultPreview { + text: string; + match: ISearchRange; +} + +export interface ITextSearchResult { + uri?: uri; + range: ISearchRange; + preview: ITextSearchResultPreview; } export interface IProgress { @@ -204,18 +223,47 @@ export interface IFileIndexProviderStats { filesWalked: number; } -// ---- very simple implementation of the search model -------------------- - export class FileMatch implements IFileMatch { - public lineMatches: LineMatch[] = []; + public matches: ITextSearchResult[] = []; constructor(public resource: uri) { // empty } } -export class LineMatch implements ILineMatch { - constructor(public preview: string, public lineNumber: number, public offsetAndLengths: number[][]) { - // empty +export class TextSearchResult implements ITextSearchResult { + range: ISearchRange; + preview: ITextSearchResultPreview; + + constructor(fullLine: string, range: ISearchRange, previewOptions?: ITextSearchPreviewOptions) { + this.range = range; + if (previewOptions) { + const previewStart = Math.max(range.startColumn - previewOptions.leadingChars, 0); + const previewEnd = Math.max(previewOptions.totalChars + previewStart, range.endColumn); + + this.preview = { + text: fullLine.substring(previewStart, previewEnd), + match: new OneLineRange(0, range.startColumn - previewStart, range.endColumn - previewStart) + }; + } else { + this.preview = { + text: fullLine, + match: new OneLineRange(0, range.startColumn, range.endColumn) + }; + } + } +} + +export class OneLineRange implements ISearchRange { + startLineNumber: number; + startColumn: number; + endLineNumber: number; + endColumn: number; + + constructor(lineNumber: number, startColumn: number, endColumn: number) { + this.startLineNumber = lineNumber; + this.startColumn = startColumn; + this.endLineNumber = lineNumber; + this.endColumn = endColumn; } } diff --git a/src/vs/vscode.proposed.d.ts b/src/vs/vscode.proposed.d.ts index 48b1f768187..30b4867e085 100644 --- a/src/vs/vscode.proposed.d.ts +++ b/src/vs/vscode.proposed.d.ts @@ -77,6 +77,12 @@ declare module 'vscode' { followSymlinks: boolean; } + export interface TextSearchPreviewOptions { + maxLines: number; + leadingChars: number; + totalChars: number; + } + /** * Options that apply to text search. */ @@ -86,10 +92,7 @@ declare module 'vscode' { */ maxResults: number; - /** - * TODO@roblou - total length? # of context lines? leading and trailing # of chars? - */ - previewOptions?: any; + previewOptions?: TextSearchPreviewOptions; /** * Exclude files larger than `maxFileSize` in bytes. diff --git a/src/vs/workbench/api/electron-browser/mainThreadSearch.ts b/src/vs/workbench/api/electron-browser/mainThreadSearch.ts index 9028249c12b..1021d2d8c71 100644 --- a/src/vs/workbench/api/electron-browser/mainThreadSearch.ts +++ b/src/vs/workbench/api/electron-browser/mainThreadSearch.ts @@ -78,7 +78,7 @@ class SearchOperation { addMatch(match: IFileMatch): void { if (this.matches.has(match.resource.toString())) { // Merge with previous IFileMatches - this.matches.get(match.resource.toString()).lineMatches.push(...match.lineMatches); + this.matches.get(match.resource.toString()).matches.push(...match.matches); } else { this.matches.set(match.resource.toString(), match); } @@ -149,10 +149,10 @@ class RemoteSearchProvider implements ISearchResultProvider, IDisposable { const searchOp = this._searches.get(session); dataOrUri.forEach(result => { - if ((<IRawFileMatch2>result).lineMatches) { + if ((<IRawFileMatch2>result).matches) { searchOp.addMatch({ resource: URI.revive((<IRawFileMatch2>result).resource), - lineMatches: (<IRawFileMatch2>result).lineMatches + matches: (<IRawFileMatch2>result).matches }); } else { searchOp.addMatch({ diff --git a/src/vs/workbench/api/electron-browser/mainThreadWorkspace.ts b/src/vs/workbench/api/electron-browser/mainThreadWorkspace.ts index b5eb1639ae0..e2148ffffc2 100644 --- a/src/vs/workbench/api/electron-browser/mainThreadWorkspace.ts +++ b/src/vs/workbench/api/electron-browser/mainThreadWorkspace.ts @@ -181,7 +181,7 @@ export class MainThreadWorkspace implements MainThreadWorkspaceShape { const query = queryBuilder.text(pattern, folders, options); const onProgress = (p: ISearchProgressItem) => { - if (p.lineMatches) { + if (p.matches) { this._proxy.$handleTextSearchResult(p, requestId); } }; diff --git a/src/vs/workbench/api/node/extHostSearch.ts b/src/vs/workbench/api/node/extHostSearch.ts index afdaaa29ef2..58b755902c6 100644 --- a/src/vs/workbench/api/node/extHostSearch.ts +++ b/src/vs/workbench/api/node/extHostSearch.ts @@ -5,20 +5,20 @@ 'use strict'; import * as path from 'path'; -import { CancellationTokenSource, CancellationToken } from 'vs/base/common/cancellation'; +import { CancellationToken, CancellationTokenSource } from 'vs/base/common/cancellation'; import { toErrorMessage } from 'vs/base/common/errorMessage'; +import { isPromiseCanceledError } from 'vs/base/common/errors'; import * as glob from 'vs/base/common/glob'; +import { toDisposable } from 'vs/base/common/lifecycle'; import * as resources from 'vs/base/common/resources'; +import { StopWatch } from 'vs/base/common/stopwatch'; import URI, { UriComponents } from 'vs/base/common/uri'; import { TPromise } from 'vs/base/common/winjs.base'; import * as extfs from 'vs/base/node/extfs'; -import { IFileMatch, IFolderQuery, IPatternInfo, IRawSearchQuery, ISearchCompleteStats, ISearchQuery, IFileSearchProviderStats } from 'vs/platform/search/common/search'; +import { IFileMatch, IFileSearchProviderStats, IFolderQuery, IPatternInfo, IRawSearchQuery, ISearchCompleteStats, ISearchQuery, ITextSearchResult } from 'vs/platform/search/common/search'; +import { FileIndexSearchManager, IDirectoryEntry, IDirectoryTree, IInternalFileMatch, QueryGlobTester, resolvePatternsForProvider } from 'vs/workbench/api/node/extHostSearch.fileIndex'; import * as vscode from 'vscode'; import { ExtHostSearchShape, IMainContext, MainContext, MainThreadSearchShape } from './extHost.protocol'; -import { toDisposable } from 'vs/base/common/lifecycle'; -import { IInternalFileMatch, QueryGlobTester, resolvePatternsForProvider, IDirectoryTree, IDirectoryEntry, FileIndexSearchManager } from 'vs/workbench/api/node/extHostSearch.fileIndex'; -import { StopWatch } from 'vs/base/common/stopwatch'; -import { isPromiseCanceledError } from 'vs/base/common/errors'; export interface ISchemeTransformer { transformOutgoing(scheme: string): string; @@ -172,22 +172,16 @@ class TextSearchResultsCollector { if (!this._currentFileMatch) { this._currentFileMatch = { resource: data.uri, - lineMatches: [] + matches: [] }; } - // TODO@roblou - line text is sent for every match - const matchRange = data.preview.match; - this._currentFileMatch.lineMatches.push({ - lineNumber: data.range.start.line, - preview: data.preview.text, - offsetAndLengths: [[matchRange.start.character, matchRange.end.character - matchRange.start.character]] - }); + this._currentFileMatch.matches.push(extensionResultToFrontendResult(data)); } private pushToCollector(): void { const size = this._currentFileMatch ? - this._currentFileMatch.lineMatches.reduce((acc, match) => acc + match.offsetAndLengths.length, 0) : + this._currentFileMatch.matches.length : 0; this._batchedCollector.addItem(this._currentFileMatch, size); } @@ -202,6 +196,26 @@ class TextSearchResultsCollector { } } +function extensionResultToFrontendResult(data: vscode.TextSearchResult): ITextSearchResult { + return { + preview: { + match: { + startLineNumber: data.preview.match.start.line, + startColumn: data.preview.match.start.character, + endLineNumber: data.preview.match.end.line, + endColumn: data.preview.match.end.character + }, + text: data.preview.text + }, + range: { + startLineNumber: data.range.start.line, + startColumn: data.range.start.character, + endLineNumber: data.range.end.line, + endColumn: data.range.end.character + } + }; +} + /** * Collects items that have a size - before the cumulative size of collected items reaches START_BATCH_AFTER_COUNT, the callback is called for every * set of items collected. @@ -414,7 +428,8 @@ class TextSearchEngine { followSymlinks: !this.config.ignoreSymlinks, encoding: this.config.fileEncoding, maxFileSize: this.config.maxFileSize, - maxResults: this.config.maxResults + maxResults: this.config.maxResults, + previewOptions: this.config.previewOptions }; } } diff --git a/src/vs/workbench/parts/search/browser/searchView.ts b/src/vs/workbench/parts/search/browser/searchView.ts index 301c4fc6f08..b589ee18ac2 100644 --- a/src/vs/workbench/parts/search/browser/searchView.ts +++ b/src/vs/workbench/parts/search/browser/searchView.ts @@ -108,6 +108,7 @@ export class SearchView extends Viewlet implements IViewlet, IPanel { private readonly selectCurrentMatchEmitter: Emitter<string>; private delayedRefresh: Delayer<void>; private changedWhileHidden: boolean; + private isWide: boolean; private searchWithoutFolderMessageBuilder: Builder; @@ -826,8 +827,10 @@ export class SearchView extends Viewlet implements IViewlet, IPanel { } if (this.size.width >= SearchView.WIDE_VIEW_SIZE) { + this.isWide = true; dom.addClass(this.getContainer(), SearchView.WIDE_CLASS_NAME); } else { + this.isWide = false; dom.removeClass(this.getContainer(), SearchView.WIDE_CLASS_NAME); } @@ -1081,7 +1084,12 @@ export class SearchView extends Viewlet implements IViewlet, IPanel { disregardIgnoreFiles: !useExcludesAndIgnoreFiles, disregardExcludeSettings: !useExcludesAndIgnoreFiles, excludePattern, - includePattern + includePattern, + previewOptions: { + leadingChars: 5, + maxLines: 1, + totalChars: this.isWide ? 1000 : 100 + } }; const folderResources = this.contextService.getWorkspace().folders; diff --git a/src/vs/workbench/parts/search/common/queryBuilder.ts b/src/vs/workbench/parts/search/common/queryBuilder.ts index 08bea8ac1cd..1ee9968ff2e 100644 --- a/src/vs/workbench/parts/search/common/queryBuilder.ts +++ b/src/vs/workbench/parts/search/common/queryBuilder.ts @@ -95,7 +95,8 @@ export class QueryBuilder { useRipgrep, disregardIgnoreFiles: options.disregardIgnoreFiles || !useIgnoreFiles, disregardExcludeSettings: options.disregardExcludeSettings, - ignoreSymlinks + ignoreSymlinks, + previewOptions: options.previewOptions }; // Filter extraFileResources against global include/exclude patterns - they are already expected to not belong to a workspace diff --git a/src/vs/workbench/parts/search/common/searchModel.ts b/src/vs/workbench/parts/search/common/searchModel.ts index a4597dd28b6..376fe0f666a 100644 --- a/src/vs/workbench/parts/search/common/searchModel.ts +++ b/src/vs/workbench/parts/search/common/searchModel.ts @@ -3,39 +3,50 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -import * as objects from 'vs/base/common/objects'; -import * as strings from 'vs/base/common/strings'; -import * as errors from 'vs/base/common/errors'; import { RunOnceScheduler } from 'vs/base/common/async'; -import { IDisposable, Disposable } from 'vs/base/common/lifecycle'; -import { TPromise } from 'vs/base/common/winjs.base'; +import * as errors from 'vs/base/common/errors'; +import { anyEvent, Emitter, Event, fromPromise, stopwatch } from 'vs/base/common/event'; +import { getBaseLabel } from 'vs/base/common/labels'; +import { Disposable, IDisposable } from 'vs/base/common/lifecycle'; +import { ResourceMap, TernarySearchTree, values } from 'vs/base/common/map'; +import * as objects from 'vs/base/common/objects'; import URI from 'vs/base/common/uri'; -import { values, ResourceMap, TernarySearchTree } from 'vs/base/common/map'; -import { Event, Emitter, fromPromise, stopwatch, anyEvent } from 'vs/base/common/event'; -import { ISearchService, ISearchProgressItem, ISearchComplete, ISearchQuery, IPatternInfo, IFileMatch, ITextSearchStats } from 'vs/platform/search/common/search'; -import { ReplacePattern } from 'vs/platform/search/common/replace'; -import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry'; +import { TPromise } from 'vs/base/common/winjs.base'; import { Range } from 'vs/editor/common/core/range'; -import { ITextModel, IModelDeltaDecoration, OverviewRulerLane, TrackedRangeStickiness, FindMatch } from 'vs/editor/common/model'; -import { IInstantiationService, createDecorator } from 'vs/platform/instantiation/common/instantiation'; -import { IModelService } from 'vs/editor/common/services/modelService'; -import { IReplaceService } from 'vs/workbench/parts/search/common/replace'; -import { IProgressRunner } from 'vs/platform/progress/common/progress'; +import { FindMatch, IModelDeltaDecoration, ITextModel, OverviewRulerLane, TrackedRangeStickiness } from 'vs/editor/common/model'; import { ModelDecorationOptions } from 'vs/editor/common/model/textModel'; +import { IModelService } from 'vs/editor/common/services/modelService'; +import { createDecorator, IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; +import { IProgressRunner } from 'vs/platform/progress/common/progress'; +import { ReplacePattern } from 'vs/platform/search/common/replace'; +import { IFileMatch, IPatternInfo, ISearchComplete, ISearchProgressItem, ISearchQuery, ISearchService, ITextSearchPreviewOptions, ITextSearchResult, ITextSearchStats, TextSearchResult } from 'vs/platform/search/common/search'; +import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry'; import { overviewRulerFindMatchForeground } from 'vs/platform/theme/common/colorRegistry'; import { themeColorFromId } from 'vs/platform/theme/common/themeService'; -import { getBaseLabel } from 'vs/base/common/labels'; +import { IReplaceService } from 'vs/workbench/parts/search/common/replace'; export class Match { - private _lineText: string; private _id: string; private _range: Range; + private _previewText: string; + private _rangeInPreviewText: Range; - constructor(private _parent: FileMatch, text: string, lineNumber: number, offset: number, length: number) { - this._lineText = text; - this._range = new Range(1 + lineNumber, 1 + offset, 1 + lineNumber, 1 + offset + length); - this._id = this._parent.id() + '>' + lineNumber + '>' + offset + this.getMatchString(); + constructor(private _parent: FileMatch, _result: ITextSearchResult) { + this._range = new Range( + _result.range.startLineNumber + 1, + _result.range.startColumn + 1, + _result.range.endLineNumber + 1, + _result.range.endColumn + 1); + + this._rangeInPreviewText = new Range( + _result.preview.match.startLineNumber + 1, + _result.preview.match.startColumn + 1, + _result.preview.match.endLineNumber + 1, + _result.preview.match.endColumn + 1); + this._previewText = _result.preview.text; + + this._id = this._parent.id() + '>' + this._range + this.getMatchString(); } public id(): string { @@ -47,7 +58,7 @@ export class Match { } public text(): string { - return this._lineText; + return this._previewText; } public range(): Range { @@ -55,11 +66,9 @@ export class Match { } public preview(): { before: string; inside: string; after: string; } { - let before = this._lineText.substring(0, this._range.startColumn - 1), + const before = this._previewText.substring(0, this._rangeInPreviewText.startColumn - 1), inside = this.getMatchString(), - after = this._lineText.substring(this._range.endColumn - 1, Math.min(this._range.endColumn + 150, this._lineText.length)); - - before = strings.lcut(before, 26); + after = this._previewText.substring(this._rangeInPreviewText.endColumn - 1); return { before, @@ -75,7 +84,7 @@ export class Match { // If match string is not matching then regex pattern has a lookahead expression if (replaceString === null) { - replaceString = searchModel.replacePattern.getReplaceString(matchString + this._lineText.substring(this._range.endColumn - 1)); + replaceString = searchModel.replacePattern.getReplaceString(matchString + this._previewText.substring(this._rangeInPreviewText.endColumn - 1)); } // Match string is still not matching. Could be unsupported matches (multi-line). @@ -87,7 +96,7 @@ export class Match { } public getMatchString(): string { - return this._lineText.substring(this._range.startColumn - 1, this._range.endColumn - 1); + return this._previewText.substring(this._rangeInPreviewText.startColumn - 1, this._rangeInPreviewText.endColumn - 1); } } @@ -134,7 +143,7 @@ export class FileMatch extends Disposable { private _updateScheduler: RunOnceScheduler; private _modelDecorations: string[] = []; - constructor(private _query: IPatternInfo, private _maxResults: number, private _parent: FolderMatch, private rawMatch: IFileMatch, + constructor(private _query: IPatternInfo, private _previewOptions: ITextSearchPreviewOptions, private _maxResults: number, private _parent: FolderMatch, private rawMatch: IFileMatch, @IModelService private modelService: IModelService, @IReplaceService private replaceService: IReplaceService) { super(); this._resource = this.rawMatch.resource; @@ -152,11 +161,9 @@ export class FileMatch extends Disposable { this.bindModel(model); this.updateMatchesForModel(); } else { - this.rawMatch.lineMatches.forEach((rawLineMatch) => { - rawLineMatch.offsetAndLengths.forEach(offsetAndLength => { - let match = new Match(this, rawLineMatch.preview, rawLineMatch.lineNumber, offsetAndLength[0], offsetAndLength[1]); - this.add(match); - }); + this.rawMatch.matches.forEach((rawLineMatch) => { + let match = new Match(this, rawLineMatch); + this.add(match); }); } } @@ -222,7 +229,12 @@ export class FileMatch extends Disposable { private updateMatches(matches: FindMatch[], modelChange: boolean) { matches.forEach(m => { - let match = new Match(this, this._model.getLineContent(m.range.startLineNumber), m.range.startLineNumber - 1, m.range.startColumn - 1, m.range.endColumn - m.range.startColumn); + const textSearchResult = new TextSearchResult( + this._model.getLineContent(m.range.startLineNumber), + new Range(m.range.startLineNumber - 1, m.range.startColumn - 1, m.range.startLineNumber - 1, m.range.endColumn), + this._previewOptions); + const match = new Match(this, textSearchResult); + if (!this._removedMatches.has(match.id())) { this.add(match); if (this.isMatchSelected(match)) { @@ -392,16 +404,16 @@ export class FolderMatch extends Disposable { } public add(raw: IFileMatch[], silent: boolean): void { - let changed: FileMatch[] = []; + const changed: FileMatch[] = []; raw.forEach((rawFileMatch) => { if (this._fileMatches.has(rawFileMatch.resource)) { this._fileMatches.get(rawFileMatch.resource).dispose(); } - let fileMatch = this.instantiationService.createInstance(FileMatch, this._query.contentPattern, this._query.maxResults, this, rawFileMatch); + const fileMatch = this.instantiationService.createInstance(FileMatch, this._query.contentPattern, this._query.previewOptions, this._query.maxResults, this, rawFileMatch); this.doAdd(fileMatch); changed.push(fileMatch); - let disposable = fileMatch.onChange(() => this.onFileChange(fileMatch)); + const disposable = fileMatch.onChange(() => this.onFileChange(fileMatch)); fileMatch.onDispose(() => disposable.dispose()); }); if (!silent && changed.length) { diff --git a/src/vs/workbench/parts/search/test/browser/searchActions.test.ts b/src/vs/workbench/parts/search/test/browser/searchActions.test.ts index 47f5db6be49..8a46a0b3801 100644 --- a/src/vs/workbench/parts/search/test/browser/searchActions.test.ts +++ b/src/vs/workbench/parts/search/test/browser/searchActions.test.ts @@ -129,13 +129,26 @@ suite('Search Actions', () => { function aFileMatch(): FileMatch { let rawMatch: IFileMatch = { resource: URI.file('somepath' + ++counter), - lineMatches: [] + matches: [] }; - return instantiationService.createInstance(FileMatch, null, null, null, rawMatch); + return instantiationService.createInstance(FileMatch, null, null, null, null, rawMatch); } function aMatch(fileMatch: FileMatch): Match { - let match = new Match(fileMatch, 'some match', ++counter, 0, 2); + const line = ++counter; + const range = { + startLineNumber: line, + startColumn: 0, + endLineNumber: line, + endColumn: 2 + }; + let match = new Match(fileMatch, { + preview: { + text: 'some match', + match: range + }, + range + }); fileMatch.add(match); return match; } diff --git a/src/vs/workbench/parts/search/test/browser/searchViewlet.test.ts b/src/vs/workbench/parts/search/test/browser/searchViewlet.test.ts index 2c273d2744a..45eb45be630 100644 --- a/src/vs/workbench/parts/search/test/browser/searchViewlet.test.ts +++ b/src/vs/workbench/parts/search/test/browser/searchViewlet.test.ts @@ -9,7 +9,7 @@ import uri from 'vs/base/common/uri'; import { Match, FileMatch, SearchResult } from 'vs/workbench/parts/search/common/searchModel'; import { TestInstantiationService } from 'vs/platform/instantiation/test/common/instantiationServiceMock'; import { SearchDataSource, SearchSorter } from 'vs/workbench/parts/search/browser/searchResultsView'; -import { IFileMatch, ILineMatch } from 'vs/platform/search/common/search'; +import { IFileMatch, TextSearchResult, OneLineRange, ITextSearchResult } from 'vs/platform/search/common/search'; import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; import { TestConfigurationService } from 'vs/platform/configuration/test/common/testConfigurationService'; import { ModelServiceImpl } from 'vs/editor/common/services/modelServiceImpl'; @@ -31,9 +31,22 @@ suite('Search - Viewlet', () => { let ds = instantiation.createInstance(SearchDataSource); let result: SearchResult = instantiation.createInstance(SearchResult, null); result.query = { type: 1, folderQueries: [{ folder: uri.parse('file://c:/') }] }; + + const range = { + startLineNumber: 1, + startColumn: 0, + endLineNumber: 1, + endColumn: 1 + }; result.add([{ resource: uri.parse('file:///c:/foo'), - lineMatches: [{ lineNumber: 1, preview: 'bar', offsetAndLengths: [[0, 1]] }] + matches: [{ + preview: { + text: 'bar', + match: range + }, + range + }] }]); let fileMatch = result.matches()[0]; @@ -41,7 +54,7 @@ suite('Search - Viewlet', () => { assert.equal(ds.getId(null, result), 'root'); assert.equal(ds.getId(null, fileMatch), 'file:///c%3A/foo'); - assert.equal(ds.getId(null, lineMatch), 'file:///c%3A/foo>1>0b'); + assert.equal(ds.getId(null, lineMatch), 'file:///c%3A/foo>[2,1 -> 2,2]b'); assert(!ds.hasChildren(null, 'foo')); assert(ds.hasChildren(null, result)); @@ -53,9 +66,9 @@ suite('Search - Viewlet', () => { let fileMatch1 = aFileMatch('C:\\foo'); let fileMatch2 = aFileMatch('C:\\with\\path'); let fileMatch3 = aFileMatch('C:\\with\\path\\foo'); - let lineMatch1 = new Match(fileMatch1, 'bar', 1, 1, 1); - let lineMatch2 = new Match(fileMatch1, 'bar', 2, 1, 1); - let lineMatch3 = new Match(fileMatch1, 'bar', 2, 1, 1); + let lineMatch1 = new Match(fileMatch1, new TextSearchResult('bar', new OneLineRange(0, 1, 1))); + let lineMatch2 = new Match(fileMatch1, new TextSearchResult('bar', new OneLineRange(2, 1, 1))); + let lineMatch3 = new Match(fileMatch1, new TextSearchResult('bar', new OneLineRange(2, 1, 1))); let s = new SearchSorter(); @@ -69,12 +82,12 @@ suite('Search - Viewlet', () => { assert(s.compare(null, lineMatch2, lineMatch3) === 0); }); - function aFileMatch(path: string, searchResult?: SearchResult, ...lineMatches: ILineMatch[]): FileMatch { + function aFileMatch(path: string, searchResult?: SearchResult, ...lineMatches: ITextSearchResult[]): FileMatch { let rawMatch: IFileMatch = { resource: uri.file('C:\\' + path), - lineMatches: lineMatches + matches: lineMatches }; - return instantiation.createInstance(FileMatch, null, null, searchResult, rawMatch); + return instantiation.createInstance(FileMatch, null, null, null, searchResult, rawMatch); } function stubModelService(instantiationService: TestInstantiationService): IModelService { diff --git a/src/vs/workbench/parts/search/test/common/searchModel.test.ts b/src/vs/workbench/parts/search/test/common/searchModel.test.ts index d505add8c44..56125398146 100644 --- a/src/vs/workbench/parts/search/test/common/searchModel.test.ts +++ b/src/vs/workbench/parts/search/test/common/searchModel.test.ts @@ -16,7 +16,7 @@ import { ModelServiceImpl } from 'vs/editor/common/services/modelServiceImpl'; import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; import { TestConfigurationService } from 'vs/platform/configuration/test/common/testConfigurationService'; import { TestInstantiationService } from 'vs/platform/instantiation/test/common/instantiationServiceMock'; -import { IFileMatch, IFileSearchStats, IFolderQuery, ILineMatch, ISearchComplete, ISearchProgressItem, ISearchQuery, ISearchService } from 'vs/platform/search/common/search'; +import { IFileMatch, IFileSearchStats, IFolderQuery, ISearchComplete, ISearchProgressItem, ISearchQuery, ISearchService, ITextSearchResult, TextSearchResult, OneLineRange } from 'vs/platform/search/common/search'; import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry'; import { NullTelemetryService } from 'vs/platform/telemetry/common/telemetryUtils'; import { SearchModel } from 'vs/workbench/parts/search/common/searchModel'; @@ -41,6 +41,7 @@ const nullEvent = new class { } }; +const lineOneRange = new OneLineRange(1, 0, 1); suite('SearchModel', () => { @@ -104,7 +105,11 @@ suite('SearchModel', () => { } test('Search Model: Search adds to results', async () => { - let results = [aRawMatch('file://c:/1', aLineMatch('preview 1', 1, [[1, 3], [4, 7]])), aRawMatch('file://c:/2', aLineMatch('preview 2'))]; + let results = [ + aRawMatch('file://c:/1', + new TextSearchResult('preview 1', new OneLineRange(1, 1, 4)), + new TextSearchResult('preview 1', new OneLineRange(1, 4, 11))), + aRawMatch('file://c:/2', new TextSearchResult('preview 2', lineOneRange))]; instantiationService.stub(ISearchService, searchServiceWithResults(results)); let testObject: SearchModel = instantiationService.createInstance(SearchModel); @@ -130,7 +135,12 @@ suite('SearchModel', () => { test('Search Model: Search reports telemetry on search completed', async () => { let target = instantiationService.spy(ITelemetryService, 'publicLog'); - let results = [aRawMatch('file://c:/1', aLineMatch('preview 1', 1, [[1, 3], [4, 7]])), aRawMatch('file://c:/2', aLineMatch('preview 2'))]; + let results = [ + aRawMatch('file://c:/1', + new TextSearchResult('preview 1', new OneLineRange(1, 1, 4)), + new TextSearchResult('preview 1', new OneLineRange(1, 4, 11))), + aRawMatch('file://c:/2', + new TextSearchResult('preview 2', lineOneRange))]; instantiationService.stub(ISearchService, searchServiceWithResults(results)); let testObject: SearchModel = instantiationService.createInstance(SearchModel); @@ -168,7 +178,7 @@ suite('SearchModel', () => { instantiationService.stub(ITelemetryService, 'publicLog', target1); instantiationService.stub(ISearchService, searchServiceWithResults( - [aRawMatch('file://c:/1', aLineMatch('some preview'))], + [aRawMatch('file://c:/1', new TextSearchResult('some preview', lineOneRange))], { results: [], stats: testSearchStats })); let testObject = instantiationService.createInstance(SearchModel); @@ -229,7 +239,12 @@ suite('SearchModel', () => { }); test('Search Model: Search results are cleared during search', async () => { - let results = [aRawMatch('file://c:/1', aLineMatch('preview 1', 1, [[1, 3], [4, 7]])), aRawMatch('file://c:/2', aLineMatch('preview 2'))]; + let results = [ + aRawMatch('file://c:/1', + new TextSearchResult('preview 1', new OneLineRange(1, 1, 4)), + new TextSearchResult('preview 1', new OneLineRange(1, 4, 11))), + aRawMatch('file://c:/2', + new TextSearchResult('preview 2', lineOneRange))]; instantiationService.stub(ISearchService, searchServiceWithResults(results)); let testObject: SearchModel = instantiationService.createInstance(SearchModel); await testObject.search({ contentPattern: { pattern: 'somestring' }, type: 1, folderQueries }); @@ -254,7 +269,10 @@ suite('SearchModel', () => { }); test('getReplaceString returns proper replace string for regExpressions', async () => { - let results = [aRawMatch('file://c:/1', aLineMatch('preview 1', 1, [[1, 3], [4, 7]]))]; + let results = [ + aRawMatch('file://c:/1', + new TextSearchResult('preview 1', new OneLineRange(1, 1, 4)), + new TextSearchResult('preview 1', new OneLineRange(1, 4, 11)))]; instantiationService.stub(ISearchService, searchServiceWithResults(results)); let testObject: SearchModel = instantiationService.createInstance(SearchModel); @@ -281,12 +299,8 @@ suite('SearchModel', () => { assert.equal('helloe', match.replaceString); }); - function aRawMatch(resource: string, ...lineMatches: ILineMatch[]): IFileMatch { - return { resource: URI.parse(resource), lineMatches }; - } - - function aLineMatch(preview: string, lineNumber: number = 1, offsetAndLengths: number[][] = [[0, 1]]): ILineMatch { - return { preview, lineNumber, offsetAndLengths }; + function aRawMatch(resource: string, ...matches: ITextSearchResult[]): IFileMatch { + return { resource: URI.parse(resource), matches }; } function stub(arg1: any, arg2: any, arg3: any): sinon.SinonStub { diff --git a/src/vs/workbench/parts/search/test/common/searchResult.test.ts b/src/vs/workbench/parts/search/test/common/searchResult.test.ts index e9f486bc193..2d324073590 100644 --- a/src/vs/workbench/parts/search/test/common/searchResult.test.ts +++ b/src/vs/workbench/parts/search/test/common/searchResult.test.ts @@ -9,7 +9,7 @@ import * as sinon from 'sinon'; import { TestInstantiationService } from 'vs/platform/instantiation/test/common/instantiationServiceMock'; import { Match, FileMatch, SearchResult, SearchModel } from 'vs/workbench/parts/search/common/searchModel'; import URI from 'vs/base/common/uri'; -import { IFileMatch, ILineMatch } from 'vs/platform/search/common/search'; +import { IFileMatch, TextSearchResult, OneLineRange, ITextSearchResult } from 'vs/platform/search/common/search'; import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry'; import { NullTelemetryService } from 'vs/platform/telemetry/common/telemetryUtils'; import { Range } from 'vs/editor/common/core/range'; @@ -19,6 +19,8 @@ import { ModelServiceImpl } from 'vs/editor/common/services/modelServiceImpl'; import { IModelService } from 'vs/editor/common/services/modelService'; import { IReplaceService } from 'vs/workbench/parts/search/common/replace'; +const lineOneRange = new OneLineRange(1, 0, 1); + suite('SearchResult', () => { let instantiationService: TestInstantiationService; @@ -33,21 +35,17 @@ suite('SearchResult', () => { test('Line Match', function () { let fileMatch = aFileMatch('folder/file.txt', null); - let lineMatch = new Match(fileMatch, 'foo bar', 1, 0, 3); + let lineMatch = new Match(fileMatch, new TextSearchResult('foo bar', new OneLineRange(1, 0, 3))); assert.equal(lineMatch.text(), 'foo bar'); assert.equal(lineMatch.range().startLineNumber, 2); assert.equal(lineMatch.range().endLineNumber, 2); assert.equal(lineMatch.range().startColumn, 1); assert.equal(lineMatch.range().endColumn, 4); - assert.equal('file:///folder/file.txt>1>0foo', lineMatch.id()); + assert.equal('file:///folder/file.txt>[2,1 -> 2,4]foo', lineMatch.id()); }); test('Line Match - Remove', function () { - let fileMatch = aFileMatch('folder/file.txt', aSearchResult(), ...[{ - preview: 'foo bar', - lineNumber: 1, - offsetAndLengths: [[0, 3]] - }]); + let fileMatch = aFileMatch('folder/file.txt', aSearchResult(), new TextSearchResult('foo bar', new OneLineRange(1, 0, 3))); let lineMatch = fileMatch.matches()[0]; fileMatch.remove(lineMatch); assert.equal(fileMatch.matches().length, 0); @@ -66,15 +64,11 @@ suite('SearchResult', () => { }); test('File Match: Select an existing match', function () { - let testObject = aFileMatch('folder/file.txt', aSearchResult(), ...[{ - preview: 'foo', - lineNumber: 1, - offsetAndLengths: [[0, 3]] - }, { - preview: 'bar', - lineNumber: 1, - offsetAndLengths: [[5, 3]] - }]); + let testObject = aFileMatch( + 'folder/file.txt', + aSearchResult(), + new TextSearchResult('foo', new OneLineRange(1, 0, 3)), + new TextSearchResult('bar', new OneLineRange(1, 5, 3))); testObject.setSelectedMatch(testObject.matches()[0]); @@ -82,15 +76,11 @@ suite('SearchResult', () => { }); test('File Match: Select non existing match', function () { - let testObject = aFileMatch('folder/file.txt', aSearchResult(), ...[{ - preview: 'foo', - lineNumber: 1, - offsetAndLengths: [[0, 3]] - }, { - preview: 'bar', - lineNumber: 1, - offsetAndLengths: [[5, 3]] - }]); + let testObject = aFileMatch( + 'folder/file.txt', + aSearchResult(), + new TextSearchResult('foo', new OneLineRange(1, 0, 3)), + new TextSearchResult('bar', new OneLineRange(1, 5, 3))); let target = testObject.matches()[0]; testObject.remove(target); @@ -100,15 +90,11 @@ suite('SearchResult', () => { }); test('File Match: isSelected return true for selected match', function () { - let testObject = aFileMatch('folder/file.txt', aSearchResult(), ...[{ - preview: 'foo', - lineNumber: 1, - offsetAndLengths: [[0, 3]] - }, { - preview: 'bar', - lineNumber: 1, - offsetAndLengths: [[5, 3]] - }]); + let testObject = aFileMatch( + 'folder/file.txt', + aSearchResult(), + new TextSearchResult('foo', new OneLineRange(1, 0, 3)), + new TextSearchResult('bar', new OneLineRange(1, 5, 3))); let target = testObject.matches()[0]; testObject.setSelectedMatch(target); @@ -116,32 +102,20 @@ suite('SearchResult', () => { }); test('File Match: isSelected return false for un-selected match', function () { - let testObject = aFileMatch('folder/file.txt', aSearchResult(), ...[{ - preview: 'foo', - lineNumber: 1, - offsetAndLengths: [[0, 3]] - }, { - preview: 'bar', - lineNumber: 1, - offsetAndLengths: [[5, 3]] - }]); - + let testObject = aFileMatch('folder/file.txt', + aSearchResult(), + new TextSearchResult('foo', new OneLineRange(1, 0, 3)), + new TextSearchResult('bar', new OneLineRange(1, 5, 3))); testObject.setSelectedMatch(testObject.matches()[0]); - assert.ok(!testObject.isMatchSelected(testObject.matches()[1])); }); test('File Match: unselect', function () { - let testObject = aFileMatch('folder/file.txt', aSearchResult(), ...[{ - preview: 'foo', - lineNumber: 1, - offsetAndLengths: [[0, 3]] - }, { - preview: 'bar', - lineNumber: 1, - offsetAndLengths: [[5, 3]] - }]); - + let testObject = aFileMatch( + 'folder/file.txt', + aSearchResult(), + new TextSearchResult('foo', new OneLineRange(1, 0, 3)), + new TextSearchResult('bar', new OneLineRange(1, 5, 3))); testObject.setSelectedMatch(testObject.matches()[0]); testObject.setSelectedMatch(null); @@ -149,16 +123,11 @@ suite('SearchResult', () => { }); test('File Match: unselect when not selected', function () { - let testObject = aFileMatch('folder/file.txt', aSearchResult(), ...[{ - preview: 'foo', - lineNumber: 1, - offsetAndLengths: [[0, 3]] - }, { - preview: 'bar', - lineNumber: 1, - offsetAndLengths: [[5, 3]] - }]); - + let testObject = aFileMatch( + 'folder/file.txt', + aSearchResult(), + new TextSearchResult('foo', new OneLineRange(1, 0, 3)), + new TextSearchResult('bar', new OneLineRange(1, 5, 3))); testObject.setSelectedMatch(null); assert.equal(null, testObject.getSelectedMatch()); @@ -167,7 +136,7 @@ suite('SearchResult', () => { test('Alle Drei Zusammen', function () { let searchResult = instantiationService.createInstance(SearchResult, null); let fileMatch = aFileMatch('far/boo', searchResult); - let lineMatch = new Match(fileMatch, 'foo bar', 1, 0, 3); + let lineMatch = new Match(fileMatch, new TextSearchResult('foo bar', new OneLineRange(1, 0, 3))); assert(lineMatch.parent() === fileMatch); assert(fileMatch.parent() === searchResult); @@ -175,7 +144,10 @@ suite('SearchResult', () => { test('Adding a raw match will add a file match with line matches', function () { let testObject = aSearchResult(); - let target = [aRawMatch('file://c:/', aLineMatch('preview 1', 1, [[1, 3], [4, 7]]), aLineMatch('preview 2'))]; + let target = [aRawMatch('file://c:/', + new TextSearchResult('preview 1', new OneLineRange(1, 1, 4)), + new TextSearchResult('preview 1', new OneLineRange(1, 4, 11)), + new TextSearchResult('preview 2', lineOneRange))]; testObject.add(target); @@ -200,7 +172,12 @@ suite('SearchResult', () => { test('Adding multiple raw matches', function () { let testObject = aSearchResult(); - let target = [aRawMatch('file://c:/1', aLineMatch('preview 1', 1, [[1, 3], [4, 7]])), aRawMatch('file://c:/2', aLineMatch('preview 2'))]; + let target = [ + aRawMatch('file://c:/1', + new TextSearchResult('preview 1', new OneLineRange(1, 1, 4)), + new TextSearchResult('preview 1', new OneLineRange(1, 4, 11))), + aRawMatch('file://c:/2', + new TextSearchResult('preview 2', lineOneRange))]; testObject.add(target); @@ -228,7 +205,11 @@ suite('SearchResult', () => { let target2 = sinon.spy(); let testObject = aSearchResult(); - testObject.add([aRawMatch('file://c:/1', aLineMatch('preview 1')), aRawMatch('file://c:/2', aLineMatch('preview 2'))]); + testObject.add([ + aRawMatch('file://c:/1', + new TextSearchResult('preview 1', lineOneRange)), + aRawMatch('file://c:/2', + new TextSearchResult('preview 2', lineOneRange))]); testObject.matches()[0].onDispose(target1); testObject.matches()[1].onDispose(target2); @@ -243,7 +224,9 @@ suite('SearchResult', () => { test('remove triggers change event', function () { let target = sinon.spy(); let testObject = aSearchResult(); - testObject.add([aRawMatch('file://c:/1', aLineMatch('preview 1'))]); + testObject.add([ + aRawMatch('file://c:/1', + new TextSearchResult('preview 1', lineOneRange))]); let objectRoRemove = testObject.matches()[0]; testObject.onChange(target); @@ -256,7 +239,9 @@ suite('SearchResult', () => { test('remove triggers change event', function () { let target = sinon.spy(); let testObject = aSearchResult(); - testObject.add([aRawMatch('file://c:/1', aLineMatch('preview 1'))]); + testObject.add([ + aRawMatch('file://c:/1', + new TextSearchResult('preview 1', lineOneRange))]); let objectRoRemove = testObject.matches()[0]; testObject.onChange(target); @@ -268,7 +253,9 @@ suite('SearchResult', () => { test('Removing all line matches and adding back will add file back to result', function () { let testObject = aSearchResult(); - testObject.add([aRawMatch('file://c:/1', aLineMatch('preview 1'))]); + testObject.add([ + aRawMatch('file://c:/1', + new TextSearchResult('preview 1', lineOneRange))]); let target = testObject.matches()[0]; let matchToRemove = target.matches()[0]; target.remove(matchToRemove); @@ -283,7 +270,9 @@ suite('SearchResult', () => { test('replace should remove the file match', function () { instantiationService.stubPromise(IReplaceService, 'replace', null); let testObject = aSearchResult(); - testObject.add([aRawMatch('file://c:/1', aLineMatch('preview 1'))]); + testObject.add([ + aRawMatch('file://c:/1', + new TextSearchResult('preview 1', lineOneRange))]); testObject.replace(testObject.matches()[0]); @@ -294,7 +283,9 @@ suite('SearchResult', () => { let target = sinon.spy(); instantiationService.stubPromise(IReplaceService, 'replace', null); let testObject = aSearchResult(); - testObject.add([aRawMatch('file://c:/1', aLineMatch('preview 1'))]); + testObject.add([ + aRawMatch('file://c:/1', + new TextSearchResult('preview 1', lineOneRange))]); testObject.onChange(target); let objectRoRemove = testObject.matches()[0]; @@ -307,7 +298,11 @@ suite('SearchResult', () => { test('replaceAll should remove all file matches', function () { instantiationService.stubPromise(IReplaceService, 'replace', null); let testObject = aSearchResult(); - testObject.add([aRawMatch('file://c:/1', aLineMatch('preview 1')), aRawMatch('file://c:/2', aLineMatch('preview 2'))]); + testObject.add([ + aRawMatch('file://c:/1', + new TextSearchResult('preview 1', lineOneRange)), + aRawMatch('file://c:/2', + new TextSearchResult('preview 2', lineOneRange))]); testObject.replaceAll(null); @@ -358,12 +353,12 @@ suite('SearchResult', () => { // lineHasNoDecoration(oneModel, 2); //}); - function aFileMatch(path: string, searchResult?: SearchResult, ...lineMatches: ILineMatch[]): FileMatch { + function aFileMatch(path: string, searchResult?: SearchResult, ...lineMatches: ITextSearchResult[]): FileMatch { let rawMatch: IFileMatch = { resource: URI.file('/' + path), - lineMatches: lineMatches + matches: lineMatches }; - return instantiationService.createInstance(FileMatch, null, null, searchResult, rawMatch); + return instantiationService.createInstance(FileMatch, null, null, null, searchResult, rawMatch); } function aSearchResult(): SearchResult { @@ -372,12 +367,8 @@ suite('SearchResult', () => { return searchModel.searchResult; } - function aRawMatch(resource: string, ...lineMatches: ILineMatch[]): IFileMatch { - return { resource: URI.parse(resource), lineMatches }; - } - - function aLineMatch(preview: string, lineNumber: number = 1, offsetAndLengths: number[][] = [[0, 1]]): ILineMatch { - return { preview, lineNumber, offsetAndLengths }; + function aRawMatch(resource: string, ...matches: ITextSearchResult[]): IFileMatch { + return { resource: URI.parse(resource), matches }; } function stubModelService(instantiationService: TestInstantiationService): IModelService { diff --git a/src/vs/workbench/services/search/node/ripgrepTextSearch.ts b/src/vs/workbench/services/search/node/ripgrepTextSearch.ts index 5acd1f01b5c..94751dc40b8 100644 --- a/src/vs/workbench/services/search/node/ripgrepTextSearch.ts +++ b/src/vs/workbench/services/search/node/ripgrepTextSearch.ts @@ -16,9 +16,10 @@ import * as strings from 'vs/base/common/strings'; import { TPromise } from 'vs/base/common/winjs.base'; import * as encoding from 'vs/base/node/encoding'; import * as extfs from 'vs/base/node/extfs'; -import { IProgress, ITextSearchStats } from 'vs/platform/search/common/search'; +import { IRange, Range } from 'vs/editor/common/core/range'; +import { IProgress, ITextSearchPreviewOptions, ITextSearchStats, TextSearchResult } from 'vs/platform/search/common/search'; import { rgPath } from 'vscode-ripgrep'; -import { FileMatch, IFolderSearch, IRawSearch, ISerializedFileMatch, LineMatch, ISerializedSearchSuccess } from './search'; +import { FileMatch, IFolderSearch, IRawSearch, ISerializedFileMatch, ISerializedSearchSuccess } from './search'; // If vscode-ripgrep is in an .asar file, then the binary is unpacked. const rgDiskPath = rgPath.replace(/\bnode_modules\.asar\b/, 'node_modules.asar.unpacked'); @@ -77,7 +78,7 @@ export class RipgrepEngine { this.rgProc = cp.spawn(rgDiskPath, rgArgs.args, { cwd }); process.once('exit', this.killRgProcFn); - this.ripgrepParser = new RipgrepParser(this.config.maxResults, cwd, this.config.extraFiles); + this.ripgrepParser = new RipgrepParser(this.config.maxResults, cwd, this.config.extraFiles, this.config.previewOptions); this.ripgrepParser.on('result', (match: ISerializedFileMatch) => { if (this.postProcessExclusions) { const handleResultP = (<TPromise<string>>this.postProcessExclusions(match.path, undefined, glob.hasSiblingPromiseFn(() => getSiblings(match.path)))) @@ -197,7 +198,7 @@ export class RipgrepParser extends EventEmitter { private numResults = 0; - constructor(private maxResults: number, private rootFolder: string, extraFiles?: string[]) { + constructor(private maxResults: number, private rootFolder: string, extraFiles?: string[], private previewOptions?: ITextSearchPreviewOptions) { super(); this.stringDecoder = new StringDecoder(); @@ -275,7 +276,6 @@ export class RipgrepParser extends EventEmitter { text = strings.stripUTF8BOM(text); } - const lineMatch = new LineMatch(text, lineNum); if (!this.fileMatch) { // When searching a single file and no folderQueries, rg does not print the file line, so create it here const singleFile = this.extraSearchFiles[0]; @@ -286,8 +286,6 @@ export class RipgrepParser extends EventEmitter { this.fileMatch = this.getFileMatch(singleFile); } - this.fileMatch.addMatch(lineMatch); - let lastMatchEndPos = 0; let matchTextStartPos = -1; @@ -296,6 +294,7 @@ export class RipgrepParser extends EventEmitter { let textRealIdx = 0; let hitLimit = false; + const matchRanges: IRange[] = []; const realTextParts: string[] = []; for (let i = 0; i < text.length - (RipgrepParser.MATCH_END_MARKER.length - 1);) { @@ -311,7 +310,7 @@ export class RipgrepParser extends EventEmitter { const chunk = text.slice(matchTextStartPos, i); realTextParts.push(chunk); if (!hitLimit) { - lineMatch.addMatch(matchTextStartRealIdx, textRealIdx - matchTextStartRealIdx); + matchRanges.push(new Range(lineNum, matchTextStartRealIdx, lineNum, textRealIdx)); } matchTextStartPos = -1; @@ -336,7 +335,9 @@ export class RipgrepParser extends EventEmitter { // Replace preview with version without color codes const preview = realTextParts.join(''); - lineMatch.preview = preview; + matchRanges + .map(r => new TextSearchResult(preview, r, this.previewOptions)) + .forEach(m => this.fileMatch.addMatch(m)); if (hitLimit) { this.cancel(); diff --git a/src/vs/workbench/services/search/node/search.ts b/src/vs/workbench/services/search/node/search.ts index 5bf3d2059e2..e3f65aa8fbe 100644 --- a/src/vs/workbench/services/search/node/search.ts +++ b/src/vs/workbench/services/search/node/search.ts @@ -5,11 +5,11 @@ 'use strict'; -import { TPromise } from 'vs/base/common/winjs.base'; -import { IExpression } from 'vs/base/common/glob'; -import { IProgress, ILineMatch, IPatternInfo, IFileSearchStats, ISearchEngineStats, ITextSearchStats } from 'vs/platform/search/common/search'; -import { ITelemetryData } from 'vs/platform/telemetry/common/telemetry'; import { Event } from 'vs/base/common/event'; +import { IExpression } from 'vs/base/common/glob'; +import { TPromise } from 'vs/base/common/winjs.base'; +import { IFileSearchStats, IPatternInfo, IProgress, ISearchEngineStats, ITextSearchPreviewOptions, ITextSearchResult, ITextSearchStats } from 'vs/platform/search/common/search'; +import { ITelemetryData } from 'vs/platform/telemetry/common/telemetry'; export interface IFolderSearch { folder: string; @@ -34,6 +34,7 @@ export interface IRawSearch { maxFilesize?: number; useRipgrep?: boolean; disregardIgnoreFiles?: boolean; + previewOptions?: ITextSearchPreviewOptions; } export interface ITelemetryEvent { @@ -96,7 +97,7 @@ export function isSerializedSearchSuccess(arg: ISerializedSearchComplete): arg i export interface ISerializedFileMatch { path: string; - lineMatches?: ILineMatch[]; + matches?: ITextSearchResult[]; numMatches?: number; } @@ -107,56 +108,22 @@ export type IFileSearchProgressItem = IRawFileMatch | IRawFileMatch[] | IProgres export class FileMatch implements ISerializedFileMatch { path: string; - lineMatches: LineMatch[]; + matches: ITextSearchResult[]; constructor(path: string) { this.path = path; - this.lineMatches = []; + this.matches = []; } - addMatch(lineMatch: LineMatch): void { - this.lineMatches.push(lineMatch); + addMatch(match: ITextSearchResult): void { + this.matches.push(match); } serialize(): ISerializedFileMatch { - let lineMatches: ILineMatch[] = []; - let numMatches = 0; - - for (let i = 0; i < this.lineMatches.length; i++) { - numMatches += this.lineMatches[i].offsetAndLengths.length; - lineMatches.push(this.lineMatches[i].serialize()); - } - return { path: this.path, - lineMatches, - numMatches + matches: this.matches, + numMatches: this.matches.length }; } } - -export class LineMatch implements ILineMatch { - preview: string; - lineNumber: number; - offsetAndLengths: number[][]; - - constructor(preview: string, lineNumber: number) { - this.preview = preview.replace(/(\r|\n)*$/, ''); - this.lineNumber = lineNumber; - this.offsetAndLengths = []; - } - - addMatch(offset: number, length: number): void { - this.offsetAndLengths.push([offset, length]); - } - - serialize(): ILineMatch { - const result = { - preview: this.preview, - lineNumber: this.lineNumber, - offsetAndLengths: this.offsetAndLengths - }; - - return result; - } -} \ No newline at end of file diff --git a/src/vs/workbench/services/search/node/searchService.ts b/src/vs/workbench/services/search/node/searchService.ts index 1d2b87147d9..b27c2476c58 100644 --- a/src/vs/workbench/services/search/node/searchService.ts +++ b/src/vs/workbench/services/search/node/searchService.ts @@ -22,13 +22,14 @@ import { IModelService } from 'vs/editor/common/services/modelService'; import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; import { IDebugParams, IEnvironmentService } from 'vs/platform/environment/common/environment'; import { ILogService } from 'vs/platform/log/common/log'; -import { FileMatch, ICachedSearchStats, IFileMatch, IFolderQuery, IProgress, ISearchComplete, ISearchConfiguration, ISearchEngineStats, ISearchProgressItem, ISearchQuery, ISearchResultProvider, ISearchService, LineMatch, pathIncludedInQuery, QueryType, SearchProviderType, IFileSearchStats } from 'vs/platform/search/common/search'; +import { FileMatch, ICachedSearchStats, IFileMatch, IFolderQuery, IProgress, ISearchComplete, ISearchConfiguration, ISearchEngineStats, ISearchProgressItem, ISearchQuery, ISearchResultProvider, ISearchService, pathIncludedInQuery, QueryType, SearchProviderType, IFileSearchStats, TextSearchResult } from 'vs/platform/search/common/search'; import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry'; import { IEditorService } from 'vs/workbench/services/editor/common/editorService'; import { IExtensionService } from 'vs/workbench/services/extensions/common/extensions'; import { IUntitledEditorService } from 'vs/workbench/services/untitled/common/untitledEditorService'; import { IRawSearch, IRawSearchService, ISerializedFileMatch, ISerializedSearchComplete, ISerializedSearchProgressItem, isSerializedSearchComplete, isSerializedSearchSuccess } from './search'; import { ISearchChannel, SearchChannelClient } from './searchIpc'; +import { Range } from 'vs/editor/common/core/range'; export class SearchService extends Disposable implements ISearchService { public _serviceBrand: any; @@ -346,7 +347,10 @@ export class SearchService extends Disposable implements ISearchService { localResults.set(resource, fileMatch); matches.forEach((match) => { - fileMatch.lineMatches.push(new LineMatch(model.getLineContent(match.range.startLineNumber), match.range.startLineNumber - 1, [[match.range.startColumn - 1, match.range.endColumn - match.range.startColumn]])); + fileMatch.matches.push(new TextSearchResult( + model.getLineContent(match.range.startLineNumber), + new Range(match.range.startLineNumber - 1, match.range.startColumn - 1, match.range.startLineNumber - 1, match.range.endColumn), + query.previewOptions)); }); } else { localResults.set(resource, null); @@ -458,7 +462,8 @@ export class DiskSearch implements ISearchResultProvider { cacheKey: query.cacheKey, useRipgrep: query.useRipgrep, disregardIgnoreFiles: query.disregardIgnoreFiles, - ignoreSymlinks: query.ignoreSymlinks + ignoreSymlinks: query.ignoreSymlinks, + previewOptions: query.previewOptions }; for (const q of existingFolders) { @@ -536,10 +541,8 @@ export class DiskSearch implements ISearchResultProvider { private static createFileMatch(data: ISerializedFileMatch): FileMatch { let fileMatch = new FileMatch(uri.file(data.path)); - if (data.lineMatches) { - for (let j = 0; j < data.lineMatches.length; j++) { - fileMatch.lineMatches.push(new LineMatch(data.lineMatches[j].preview, data.lineMatches[j].lineNumber, data.lineMatches[j].offsetAndLengths)); - } + if (data.matches) { + fileMatch.matches.push(...data.matches); // TODO why } return fileMatch; } diff --git a/src/vs/workbench/services/search/node/textSearch.ts b/src/vs/workbench/services/search/node/textSearch.ts index 5c7cb143ea9..02b15dafa4a 100644 --- a/src/vs/workbench/services/search/node/textSearch.ts +++ b/src/vs/workbench/services/search/node/textSearch.ts @@ -11,7 +11,7 @@ import { IProgress } from 'vs/platform/search/common/search'; import { FileWalker } from 'vs/workbench/services/search/node/fileSearch'; import { IRawSearch, ISearchEngine, ISearchEngineSuccess, ISerializedFileMatch } from './search'; import { ITextSearchWorkerProvider } from './textSearchWorkerProvider'; -import { ISearchWorker } from './worker/searchWorkerIpc'; +import { ISearchWorker, ISearchWorkerSearchArgs } from './worker/searchWorkerIpc'; export class Engine implements ISearchEngine<ISerializedFileMatch[]> { @@ -95,7 +95,7 @@ export class Engine implements ISearchEngine<ISerializedFileMatch[]> { this.nextWorker = (this.nextWorker + 1) % this.workers.length; const maxResults = this.config.maxResults && (this.config.maxResults - this.numResults); - const searchArgs = { absolutePaths: batch, maxResults, pattern: this.config.contentPattern, fileEncoding }; + const searchArgs: ISearchWorkerSearchArgs = { absolutePaths: batch, maxResults, pattern: this.config.contentPattern, fileEncoding, previewOptions: this.config.previewOptions }; worker.search(searchArgs).then(result => { if (!result || this.limitReached || this.isCanceled) { return unwind(batchBytes); diff --git a/src/vs/workbench/services/search/node/worker/searchWorker.ts b/src/vs/workbench/services/search/node/worker/searchWorker.ts index d35999d4eda..b1e340ac07b 100644 --- a/src/vs/workbench/services/search/node/worker/searchWorker.ts +++ b/src/vs/workbench/services/search/node/worker/searchWorker.ts @@ -7,16 +7,17 @@ import * as fs from 'fs'; import * as gracefulFs from 'graceful-fs'; -gracefulFs.gracefulify(fs); - import { onUnexpectedError } from 'vs/base/common/errors'; import * as strings from 'vs/base/common/strings'; import { TPromise } from 'vs/base/common/winjs.base'; -import { LineMatch, FileMatch } from '../search'; -import { UTF16le, UTF16be, UTF8, UTF8_with_bom, encodingExists, decode, bomLength, detectEncodingFromBuffer } from 'vs/base/node/encoding'; - +import { bomLength, decode, detectEncodingFromBuffer, encodingExists, UTF16be, UTF16le, UTF8, UTF8_with_bom } from 'vs/base/node/encoding'; +import { Range } from 'vs/editor/common/core/range'; +import { ITextSearchPreviewOptions, TextSearchResult } from 'vs/platform/search/common/search'; +import { FileMatch } from '../search'; import { ISearchWorker, ISearchWorkerSearchArgs, ISearchWorkerSearchResult } from './searchWorkerIpc'; +gracefulFs.gracefulify(fs); + interface ReadLinesOptions { bufferLength: number; encoding: string; @@ -95,7 +96,7 @@ export class SearchWorkerEngine { // Search in the given path, and when it's finished, search in the next path in absolutePaths const startSearchInFile = (absolutePath: string): TPromise<void> => { - return this.searchInFile(absolutePath, contentPattern, fileEncoding, args.maxResults && (args.maxResults - result.numMatches)).then(fileResult => { + return this.searchInFile(absolutePath, contentPattern, fileEncoding, args.maxResults && (args.maxResults - result.numMatches), args.previewOptions).then(fileResult => { // Finish early if search is canceled if (this.isCanceled) { return; @@ -124,13 +125,12 @@ export class SearchWorkerEngine { this.isCanceled = true; } - private searchInFile(absolutePath: string, contentPattern: RegExp, fileEncoding: string, maxResults?: number): TPromise<IFileSearchResult> { + private searchInFile(absolutePath: string, contentPattern: RegExp, fileEncoding: string, maxResults?: number, previewOptions?: ITextSearchPreviewOptions): TPromise<IFileSearchResult> { let fileMatch: FileMatch = null; let limitReached = false; let numMatches = 0; const perLineCallback = (line: string, lineNumber: number) => { - let lineMatch: LineMatch = null; let match = contentPattern.exec(line); // Record all matches into file result @@ -139,12 +139,8 @@ export class SearchWorkerEngine { fileMatch = new FileMatch(absolutePath); } - if (lineMatch === null) { - lineMatch = new LineMatch(line, lineNumber); - fileMatch.addMatch(lineMatch); - } - - lineMatch.addMatch(match.index, match[0].length); + const lineMatch = new TextSearchResult(line, new Range(lineNumber, match.index, lineNumber, match.index + match[0].length), previewOptions); + fileMatch.addMatch(lineMatch); numMatches++; if (maxResults && numMatches >= maxResults) { diff --git a/src/vs/workbench/services/search/node/worker/searchWorkerIpc.ts b/src/vs/workbench/services/search/node/worker/searchWorkerIpc.ts index be137d2fc97..5fed1210eec 100644 --- a/src/vs/workbench/services/search/node/worker/searchWorkerIpc.ts +++ b/src/vs/workbench/services/search/node/worker/searchWorkerIpc.ts @@ -8,7 +8,7 @@ import { TPromise } from 'vs/base/common/winjs.base'; import { IChannel } from 'vs/base/parts/ipc/node/ipc'; import { ISerializedFileMatch } from '../search'; -import { IPatternInfo } from 'vs/platform/search/common/search'; +import { IPatternInfo, ITextSearchPreviewOptions } from 'vs/platform/search/common/search'; import { SearchWorker } from './searchWorker'; import { Event } from 'vs/base/common/event'; @@ -17,6 +17,7 @@ export interface ISearchWorkerSearchArgs { fileEncoding: string; absolutePaths: string[]; maxResults?: number; + previewOptions?: ITextSearchPreviewOptions; } export interface ISearchWorkerSearchResult { diff --git a/src/vs/workbench/services/search/test/node/ripgrepTextSearch.test.ts b/src/vs/workbench/services/search/test/node/ripgrepTextSearch.test.ts index f55b1f172c7..8e2f789924c 100644 --- a/src/vs/workbench/services/search/test/node/ripgrepTextSearch.test.ts +++ b/src/vs/workbench/services/search/test/node/ripgrepTextSearch.test.ts @@ -5,16 +5,13 @@ 'use strict'; -import * as path from 'path'; import * as assert from 'assert'; - +import * as path from 'path'; import * as arrays from 'vs/base/common/arrays'; import * as platform from 'vs/base/common/platform'; - -import { RipgrepParser, getAbsoluteGlob, fixDriveC, fixRegexEndingPattern } from 'vs/workbench/services/search/node/ripgrepTextSearch'; +import { fixDriveC, fixRegexEndingPattern, getAbsoluteGlob, RipgrepParser } from 'vs/workbench/services/search/node/ripgrepTextSearch'; import { ISerializedFileMatch } from 'vs/workbench/services/search/node/search'; - suite('RipgrepParser', () => { const rootFolder = '/workspace'; const fileSectionEnd = '\n'; @@ -76,16 +73,40 @@ suite('RipgrepParser', () => { <ISerializedFileMatch>{ numMatches: 2, path: path.join(rootFolder, 'a.txt'), - lineMatches: [ + matches: [ { - lineNumber: 0, - preview: 'beforematchafter', - offsetAndLengths: [[6, 5]] + preview: { + match: { + endColumn: 11, + endLineNumber: 0, + startColumn: 6, + startLineNumber: 0, + }, + text: 'beforematchafter' + }, + range: { + endColumn: 11, + endLineNumber: 0, + startColumn: 6, + startLineNumber: 0, + } }, { - lineNumber: 1, - preview: 'beforematchafter', - offsetAndLengths: [[6, 5]] + preview: { + match: { + endColumn: 11, + endLineNumber: 0, + startColumn: 6, + startLineNumber: 0, + }, + text: 'beforematchafter' + }, + range: { + endColumn: 11, + endLineNumber: 1, + startColumn: 6, + startLineNumber: 1, + } } ] }); @@ -168,8 +189,9 @@ suite('RipgrepParser', () => { const results = parseInput(inputBufs); assert.equal(results.length, 1); - assert.equal(results[0].lineMatches.length, 1); - assert.deepEqual(results[0].lineMatches[0].offsetAndLengths, [[7, 5]]); + assert.equal(results[0].matches.length, 1); + assert.equal(results[0].matches[0].range.startColumn, 7); + assert.equal(results[0].matches[0].range.endColumn, 12); } }); }); diff --git a/src/vs/workbench/test/electron-browser/api/extHostSearch.test.ts b/src/vs/workbench/test/electron-browser/api/extHostSearch.test.ts index d1a70c00f48..67628e45629 100644 --- a/src/vs/workbench/test/electron-browser/api/extHostSearch.test.ts +++ b/src/vs/workbench/test/electron-browser/api/extHostSearch.test.ts @@ -650,14 +650,15 @@ suite('ExtHostSearch', () => { const actualTextSearchResults: vscode.TextSearchResult[] = []; for (let fileMatch of actual) { // Make relative - for (let lineMatch of fileMatch.lineMatches) { - for (let [offset, length] of lineMatch.offsetAndLengths) { - actualTextSearchResults.push({ - preview: { text: lineMatch.preview, match: null }, - range: new Range(lineMatch.lineNumber, offset, lineMatch.lineNumber, length + offset), - uri: fileMatch.resource - }); - } + for (let lineMatch of fileMatch.matches) { + actualTextSearchResults.push({ + preview: { + text: lineMatch.preview.text, + match: new Range(lineMatch.preview.match.startLineNumber, lineMatch.preview.match.startColumn, lineMatch.preview.match.endLineNumber, lineMatch.preview.match.endColumn) + }, + range: new Range(lineMatch.range.startLineNumber, lineMatch.range.startColumn, lineMatch.range.endLineNumber, lineMatch.range.endColumn), + uri: fileMatch.resource + }); } } From 02420dbede10d10a5020bd5228a0244fb82fba21 Mon Sep 17 00:00:00 2001 From: Rob Lourens <roblourens@gmail.com> Date: Fri, 24 Aug 2018 21:02:03 -0700 Subject: [PATCH 1249/1276] Disable findTextInFiles test temp --- .../vscode-api-tests/src/singlefolder-tests/workspace.test.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 41305d076b2..ff1de333dff 100644 --- a/extensions/vscode-api-tests/src/singlefolder-tests/workspace.test.ts +++ b/extensions/vscode-api-tests/src/singlefolder-tests/workspace.test.ts @@ -510,7 +510,7 @@ suite('workspace-namespace', () => { }); }); - test('findTextInFiles', async () => { + test.skip('findTextInFiles', async () => { const results: vscode.TextSearchResult[] = []; await vscode.workspace.findTextInFiles({ pattern: 'foo' }, { include: '*.ts' }, result => { results.push(result); From fd76ad9f002825b9d3d5b659c2fe7916959da27e Mon Sep 17 00:00:00 2001 From: Rob Lourens <roblourens@gmail.com> Date: Sat, 25 Aug 2018 11:21:40 -0700 Subject: [PATCH 1250/1276] #57186 - fix findTextInFiles --- .../src/singlefolder-tests/workspace.test.ts | 2 +- src/vs/workbench/api/node/extHostWorkspace.ts | 18 +++++++++--------- 2 files changed, 10 insertions(+), 10 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 ff1de333dff..41305d076b2 100644 --- a/extensions/vscode-api-tests/src/singlefolder-tests/workspace.test.ts +++ b/extensions/vscode-api-tests/src/singlefolder-tests/workspace.test.ts @@ -510,7 +510,7 @@ suite('workspace-namespace', () => { }); }); - test.skip('findTextInFiles', async () => { + test('findTextInFiles', async () => { const results: vscode.TextSearchResult[] = []; await vscode.workspace.findTextInFiles({ pattern: 'foo' }, { include: '*.ts' }, result => { results.push(result); diff --git a/src/vs/workbench/api/node/extHostWorkspace.ts b/src/vs/workbench/api/node/extHostWorkspace.ts index b4ec5af0c5a..f115f45be43 100644 --- a/src/vs/workbench/api/node/extHostWorkspace.ts +++ b/src/vs/workbench/api/node/extHostWorkspace.ts @@ -151,7 +151,7 @@ export class ExtHostWorkspace implements ExtHostWorkspaceShape { readonly onDidChangeWorkspace: Event<vscode.WorkspaceFoldersChangeEvent> = this._onDidChangeWorkspace.event; - private readonly _activeSearchCallbacks = []; + private readonly _activeSearchCallbacks: ((match: IRawFileMatch2) => any)[] = []; constructor( mainContext: IMainContext, @@ -410,14 +410,14 @@ export class ExtHostWorkspace implements ExtHostWorkspaceShape { return; } - p.lineMatches.forEach(lineMatch => { - lineMatch.offsetAndLengths.forEach(offsetAndLength => { - const range = new Range(lineMatch.lineNumber, offsetAndLength[0], lineMatch.lineNumber, offsetAndLength[0] + offsetAndLength[1]); - callback({ - uri: URI.revive(p.resource), - preview: { text: lineMatch.preview, match: range }, - range - }); + p.matches.forEach(match => { + callback({ + uri: URI.revive(p.resource), + preview: { + text: match.preview.text, + match: new Range(match.preview.match.startLineNumber, match.preview.match.startColumn, match.preview.match.endLineNumber, match.preview.match.endColumn) + }, + range: new Range(match.range.startLineNumber, match.range.startColumn, match.range.endLineNumber, match.range.endColumn) }); }); }; From 3f7afc65043ae493eaa5009f84b4004c442a8637 Mon Sep 17 00:00:00 2001 From: Rob Lourens <roblourens@gmail.com> Date: Sat, 25 Aug 2018 11:27:49 -0700 Subject: [PATCH 1251/1276] #57186 - implement previewOptions for findTextInFiles --- .../src/singlefolder-tests/workspace.test.ts | 12 +++++++++++- src/vs/vscode.proposed.d.ts | 2 ++ src/vs/workbench/api/node/extHostWorkspace.ts | 1 + src/vs/workbench/parts/search/browser/searchView.ts | 4 ++-- 4 files changed, 16 insertions(+), 3 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 41305d076b2..fbfe2e98bab 100644 --- a/extensions/vscode-api-tests/src/singlefolder-tests/workspace.test.ts +++ b/extensions/vscode-api-tests/src/singlefolder-tests/workspace.test.ts @@ -511,12 +511,22 @@ suite('workspace-namespace', () => { }); test('findTextInFiles', async () => { + const options: vscode.FindTextInFilesOptions = { + include: '*.ts', + previewOptions: { + leadingChars: 2, + maxLines: 1, + totalChars: 100 + } + }; + const results: vscode.TextSearchResult[] = []; - await vscode.workspace.findTextInFiles({ pattern: 'foo' }, { include: '*.ts' }, result => { + await vscode.workspace.findTextInFiles({ pattern: 'foo' }, options, result => { results.push(result); }); assert.equal(results.length, 1); + assert.equal(results[0].preview.text, 'n foo(): void {'); assert.equal(vscode.workspace.asRelativePath(results[0].uri), '10linefile.ts'); }); diff --git a/src/vs/vscode.proposed.d.ts b/src/vs/vscode.proposed.d.ts index 30b4867e085..638695fb00c 100644 --- a/src/vs/vscode.proposed.d.ts +++ b/src/vs/vscode.proposed.d.ts @@ -260,6 +260,8 @@ declare module 'vscode' { * See the vscode setting `"files.encoding"` */ encoding?: string; + + previewOptions?: TextSearchPreviewOptions; } export namespace workspace { diff --git a/src/vs/workbench/api/node/extHostWorkspace.ts b/src/vs/workbench/api/node/extHostWorkspace.ts index f115f45be43..9d2cfe912d6 100644 --- a/src/vs/workbench/api/node/extHostWorkspace.ts +++ b/src/vs/workbench/api/node/extHostWorkspace.ts @@ -398,6 +398,7 @@ export class ExtHostWorkspace implements ExtHostWorkspaceShape { disregardExcludeSettings: options.exclude === null, fileEncoding: options.encoding, maxResults: options.maxResults, + previewOptions: options.previewOptions, includePattern: options.include && globPatternToString(options.include), excludePattern: options.exclude && globPatternToString(options.exclude) diff --git a/src/vs/workbench/parts/search/browser/searchView.ts b/src/vs/workbench/parts/search/browser/searchView.ts index b589ee18ac2..7dc0e16dfdd 100644 --- a/src/vs/workbench/parts/search/browser/searchView.ts +++ b/src/vs/workbench/parts/search/browser/searchView.ts @@ -1086,9 +1086,9 @@ export class SearchView extends Viewlet implements IViewlet, IPanel { excludePattern, includePattern, previewOptions: { - leadingChars: 5, + leadingChars: 20, maxLines: 1, - totalChars: this.isWide ? 1000 : 100 + totalChars: this.isWide ? 250 : 75 } }; const folderResources = this.contextService.getWorkspace().folders; From 8f130e01199a7699386fec7866ad23705623fd91 Mon Sep 17 00:00:00 2001 From: Rob Lourens <roblourens@gmail.com> Date: Sat, 25 Aug 2018 11:55:32 -0700 Subject: [PATCH 1252/1276] #57186 add tests for TextSearchResult --- .../search/test/common/search.test.ts | 97 +++++++++++++++++++ 1 file changed, 97 insertions(+) create mode 100644 src/vs/platform/search/test/common/search.test.ts diff --git a/src/vs/platform/search/test/common/search.test.ts b/src/vs/platform/search/test/common/search.test.ts new file mode 100644 index 00000000000..28fe393b3cd --- /dev/null +++ b/src/vs/platform/search/test/common/search.test.ts @@ -0,0 +1,97 @@ +/*--------------------------------------------------------------------------------------------- + * 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 * as assert from 'assert'; +import { TextSearchResult, OneLineRange, ITextSearchResult, ITextSearchPreviewOptions } from 'vs/platform/search/common/search'; + +suite('TextSearchResult', () => { + + const previewOptions1: ITextSearchPreviewOptions = { + leadingChars: 10, + maxLines: 1, + totalChars: 100 + }; + + test('empty', () => { + assert.deepEqual( + new TextSearchResult('', new OneLineRange(5, 0, 0)), + <ITextSearchResult>{ + preview: { + text: '', + match: new OneLineRange(0, 0, 0) + }, + range: new OneLineRange(5, 0, 0) + }); + + assert.deepEqual( + new TextSearchResult('', new OneLineRange(5, 0, 0), previewOptions1), + <ITextSearchResult>{ + preview: { + text: '', + match: new OneLineRange(0, 0, 0) + }, + range: new OneLineRange(5, 0, 0) + }); + }); + + test('short', () => { + assert.deepEqual( + new TextSearchResult('foo bar', new OneLineRange(5, 4, 7)), + <ITextSearchResult>{ + preview: { + text: 'foo bar', + match: new OneLineRange(0, 4, 7) + }, + range: new OneLineRange(5, 4, 7) + }); + + assert.deepEqual( + new TextSearchResult('foo bar', new OneLineRange(5, 4, 7), previewOptions1), + <ITextSearchResult>{ + preview: { + text: 'foo bar', + match: new OneLineRange(0, 4, 7) + }, + range: new OneLineRange(5, 4, 7) + }); + }); + + test('leading', () => { + assert.deepEqual( + new TextSearchResult('long text very long text foo', new OneLineRange(5, 25, 28), previewOptions1), + <ITextSearchResult>{ + preview: { + text: 'long text foo', + match: new OneLineRange(0, 10, 13) + }, + range: new OneLineRange(5, 25, 28) + }); + }); + + test('trailing', () => { + assert.deepEqual( + new TextSearchResult('foo long text very long text long text very long text long text very long text long text very long text long text very long text', new OneLineRange(5, 0, 3), previewOptions1), + <ITextSearchResult>{ + preview: { + text: 'foo long text very long text long text very long text long text very long text long text very long t', + match: new OneLineRange(0, 0, 3) + }, + range: new OneLineRange(5, 0, 3) + }); + }); + + test('middle', () => { + assert.deepEqual( + new TextSearchResult('long text very long text long foo text very long text long text very long text long text very long text long text very long text', new OneLineRange(5, 30, 33), previewOptions1), + <ITextSearchResult>{ + preview: { + text: 'text long foo text very long text long text very long text long text very long text long text very l', + match: new OneLineRange(0, 10, 13) + }, + range: new OneLineRange(5, 30, 33) + }); + }); +}); \ No newline at end of file From 3d28155dfd1f8ac00ea5f36962130cb0e46df8cc Mon Sep 17 00:00:00 2001 From: Rob Lourens <roblourens@gmail.com> Date: Sat, 25 Aug 2018 13:10:32 -0700 Subject: [PATCH 1253/1276] #57186 - add API comments --- src/vs/vscode.proposed.d.ts | 25 ++++++++++++++++++++++++- 1 file changed, 24 insertions(+), 1 deletion(-) diff --git a/src/vs/vscode.proposed.d.ts b/src/vs/vscode.proposed.d.ts index 638695fb00c..eb07f1e7658 100644 --- a/src/vs/vscode.proposed.d.ts +++ b/src/vs/vscode.proposed.d.ts @@ -77,9 +77,23 @@ declare module 'vscode' { followSymlinks: boolean; } + /** + * Options to specify the size of the result text preview. + */ export interface TextSearchPreviewOptions { + /** + * The maximum number of lines in the preview. + */ maxLines: number; + + /** + * The maximum number of characters included before the start of the match. + */ leadingChars: number; + + /** + * The maximum number of characters included per line. + */ totalChars: number; } @@ -92,6 +106,9 @@ declare module 'vscode' { */ maxResults: number; + /** + * Options to specify the size of the result text preview. + */ previewOptions?: TextSearchPreviewOptions; /** @@ -131,6 +148,9 @@ declare module 'vscode' { */ export interface FileIndexOptions extends SearchOptions { } + /** + * A preview of the text result. + */ export interface TextSearchResultPreview { /** * The matching line of text, or a portion of the matching line that contains the match. @@ -159,7 +179,7 @@ declare module 'vscode' { range: Range; /** - * A preview of the matching line + * A preview of the text result. */ preview: TextSearchResultPreview; } @@ -261,6 +281,9 @@ declare module 'vscode' { */ encoding?: string; + /** + * Options to specify the size of the result text preview. + */ previewOptions?: TextSearchPreviewOptions; } From 6cc41bc1ab678fb9b4276cddfba7d46e43957698 Mon Sep 17 00:00:00 2001 From: Rob Lourens <roblourens@gmail.com> Date: Sat, 25 Aug 2018 13:21:49 -0700 Subject: [PATCH 1254/1276] #57186 - add tests for search-rg extension --- extensions/search-rg/src/ripgrepTextSearch.ts | 26 +--- .../search-rg/src/test/searchrg.test.ts | 113 ++++++++++++++++++ extensions/search-rg/src/utils.ts | 25 ++++ scripts/test-integration.sh | 1 + 4 files changed, 143 insertions(+), 22 deletions(-) create mode 100644 extensions/search-rg/src/test/searchrg.test.ts diff --git a/extensions/search-rg/src/ripgrepTextSearch.ts b/extensions/search-rg/src/ripgrepTextSearch.ts index 07d6541dd73..6853cec9deb 100644 --- a/extensions/search-rg/src/ripgrepTextSearch.ts +++ b/extensions/search-rg/src/ripgrepTextSearch.ts @@ -11,7 +11,7 @@ import * as path from 'path'; import { NodeStringDecoder, StringDecoder } from 'string_decoder'; import * as vscode from 'vscode'; import { rgPath } from './ripgrep'; -import { anchorGlob } from './utils'; +import { anchorGlob, createTextSearchResult } from './utils'; // If vscode-ripgrep is in an .asar file, then the binary is unpacked. const rgDiskPath = rgPath.replace(/\bnode_modules\.asar\b/, 'node_modules.asar.unpacked'); @@ -289,29 +289,11 @@ export class RipgrepParser extends EventEmitter { realTextParts.push(chunk); // Get full real text line without color codes - const preview = realTextParts.join(''); + const previewText = realTextParts.join(''); + const uri = vscode.Uri.file(path.join(this.rootFolder, this.currentFile)); lineMatches - .map(range => { - let trimmedPreview = preview; - let trimmedPreviewRange = range; - if (this.previewOptions) { - const previewStart = Math.max(range.start.character - this.previewOptions.leadingChars, 0); - trimmedPreview = preview.substr(previewStart, this.previewOptions.totalChars - previewStart); - if (previewStart > 0) { - trimmedPreviewRange = new vscode.Range(0, range.start.character - previewStart, 0, range.end.character - previewStart); - } - } - - return <vscode.TextSearchResult>{ - uri: vscode.Uri.file(path.join(this.rootFolder, this.currentFile)), - range, - preview: { - text: trimmedPreview, - match: trimmedPreviewRange || new vscode.Range(0, range.start.character, 0, range.end.character) - } - }; - }) + .map(range => createTextSearchResult(uri, previewText, range, this.previewOptions)) .forEach(match => this.onResult(match)); if (hitLimit) { diff --git a/extensions/search-rg/src/test/searchrg.test.ts b/extensions/search-rg/src/test/searchrg.test.ts new file mode 100644 index 00000000000..3407245bb1a --- /dev/null +++ b/extensions/search-rg/src/test/searchrg.test.ts @@ -0,0 +1,113 @@ +/*--------------------------------------------------------------------------------------------- + * 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 'mocha'; +import * as assert from 'assert'; +import * as vscode from 'vscode'; +import * as path from 'path'; +import { createTextSearchResult } from '../utils'; + +function createOneLineRange(lineNumber: number, startCol: number, endCol: number): vscode.Range { + return new vscode.Range(lineNumber, startCol, lineNumber, endCol); +} + +const uri = vscode.Uri.file('/foo/bar'); + +suite('search-rg', () => { + const previewOptions1: vscode.TextSearchPreviewOptions = { + leadingChars: 10, + maxLines: 1, + totalChars: 100 + }; + + test('empty', () => { + assert.deepEqual( + createTextSearchResult(uri, '', createOneLineRange(5, 0, 0)), + <vscode.TextSearchResult>{ + preview: { + text: '', + match: createOneLineRange(0, 0, 0) + }, + range: createOneLineRange(5, 0, 0), + uri + }); + + assert.deepEqual( + createTextSearchResult(uri, '', createOneLineRange(5, 0, 0), previewOptions1), + <vscode.TextSearchResult>{ + preview: { + text: '', + match: createOneLineRange(0, 0, 0) + }, + range: createOneLineRange(5, 0, 0), + uri + }); + }); + + test('short', () => { + assert.deepEqual( + createTextSearchResult(uri, 'foo bar', createOneLineRange(5, 4, 7)), + <vscode.TextSearchResult>{ + preview: { + text: 'foo bar', + match: createOneLineRange(0, 4, 7) + }, + range: createOneLineRange(5, 4, 7), + uri + }); + + assert.deepEqual( + createTextSearchResult(uri, 'foo bar', createOneLineRange(5, 4, 7), previewOptions1), + <vscode.TextSearchResult>{ + preview: { + text: 'foo bar', + match: createOneLineRange(0, 4, 7) + }, + range: createOneLineRange(5, 4, 7), + uri + }); + }); + + test('leading', () => { + assert.deepEqual( + createTextSearchResult(uri, 'long text very long text foo', createOneLineRange(5, 25, 28), previewOptions1), + <vscode.TextSearchResult>{ + preview: { + text: 'long text foo', + match: createOneLineRange(0, 10, 13) + }, + range: createOneLineRange(5, 25, 28), + uri + }); + }); + + test('trailing', () => { + assert.deepEqual( + createTextSearchResult(uri, 'foo long text very long text long text very long text long text very long text long text very long text long text very long text', createOneLineRange(5, 0, 3), previewOptions1), + <vscode.TextSearchResult>{ + preview: { + text: 'foo long text very long text long text very long text long text very long text long text very long t', + match: createOneLineRange(0, 0, 3) + }, + range: createOneLineRange(5, 0, 3), + uri + }); + }); + + test('middle', () => { + assert.deepEqual( + createTextSearchResult(uri, 'long text very long text long foo text very long text long text very long text long text very long text long text very long text', createOneLineRange(5, 30, 33), previewOptions1), + <vscode.TextSearchResult>{ + preview: { + text: 'text long foo text very long text long text very long text long text very long text long text very l', + match: createOneLineRange(0, 10, 13) + }, + range: createOneLineRange(5, 30, 33), + uri + }); + }); +}); \ No newline at end of file diff --git a/extensions/search-rg/src/utils.ts b/extensions/search-rg/src/utils.ts index 449395fd05f..86303ed79ee 100644 --- a/extensions/search-rg/src/utils.ts +++ b/extensions/search-rg/src/utils.ts @@ -6,6 +6,7 @@ 'use strict'; import * as path from 'path'; +import * as vscode from 'vscode'; export function fixDriveC(_path: string): string { const root = path.parse(_path).root; @@ -17,3 +18,27 @@ export function fixDriveC(_path: string): string { export function anchorGlob(glob: string): string { return glob.startsWith('**') || glob.startsWith('/') ? glob : `/${glob}`; } + +export function createTextSearchResult(uri: vscode.Uri, fullText: string, range: vscode.Range, previewOptions?: vscode.TextSearchPreviewOptions): vscode.TextSearchResult { + let preview: vscode.TextSearchResultPreview; + if (previewOptions) { + const previewStart = Math.max(range.start.character - previewOptions.leadingChars, 0); + const previewEnd = Math.max(previewOptions.totalChars + previewStart, range.end.character); + + preview = { + text: fullText.substring(previewStart, previewEnd), + match: new vscode.Range(0, range.start.character - previewStart, 0, range.end.character - previewStart) + }; + } else { + preview = { + text: fullText, + match: new vscode.Range(0, range.start.character, 0, range.end.character) + }; + } + + return <vscode.TextSearchResult>{ + uri, + range, + preview + }; +} diff --git a/scripts/test-integration.sh b/scripts/test-integration.sh index d2225c4475d..dc5e38c31e5 100755 --- a/scripts/test-integration.sh +++ b/scripts/test-integration.sh @@ -17,6 +17,7 @@ cd $ROOT ./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 --disableExtensions --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 --disableExtensions --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 --disableExtensions --user-data-dir=$VSCODEUSERDATADIR --skip-getting-started +./scripts/code.sh $ROOT/extensions/search-rg/test-fixtures --extensionDevelopmentPath=$ROOT/extensions/search-rg --extensionTestsPath=$ROOT/extensions/search-rg/out/test --disableExtensions --user-data-dir=$VSCODEUSERDATADIR --skip-getting-started mkdir $ROOT/extensions/emmet/test-fixtures ./scripts/code.sh $ROOT/extensions/emmet/test-fixtures --extensionDevelopmentPath=$ROOT/extensions/emmet --extensionTestsPath=$ROOT/extensions/emmet/out/test --disableExtensions --user-data-dir=$VSCODEUSERDATADIR --skip-getting-started . From 367d0adc51917178c93700c1b3500f6459f98d1a Mon Sep 17 00:00:00 2001 From: Rob Lourens <roblourens@gmail.com> Date: Sat, 25 Aug 2018 13:39:33 -0700 Subject: [PATCH 1255/1276] #57033 don't show notification on cmd+s --- .../workbench/parts/files/electron-browser/fileCommands.ts | 6 ------ 1 file changed, 6 deletions(-) diff --git a/src/vs/workbench/parts/files/electron-browser/fileCommands.ts b/src/vs/workbench/parts/files/electron-browser/fileCommands.ts index 5729f0571c8..2e4edb6e547 100644 --- a/src/vs/workbench/parts/files/electron-browser/fileCommands.ts +++ b/src/vs/workbench/parts/files/electron-browser/fileCommands.ts @@ -42,7 +42,6 @@ import { EditorContextKeys } from 'vs/editor/common/editorContextKeys'; import { IEditorService, SIDE_GROUP } from 'vs/workbench/services/editor/common/editorService'; import { IEditorGroupsService } from 'vs/workbench/services/group/common/editorGroupsService'; import { ILabelService } from 'vs/platform/label/common/label'; -import { SettingsEditor2 } from 'vs/workbench/parts/preferences/browser/settingsEditor2'; // Commands @@ -162,11 +161,6 @@ function save( // Just save return textFileService.save(resource, { force: true /* force a change to the file to trigger external watchers if any */ }); - } else if (resource && resource.scheme === Schemas.vscode) { - const activeControl = editorService.activeControl; - if (activeControl instanceof SettingsEditor2) { - activeControl.notifyNoSaveNeeded(); - } } return TPromise.as(false); From 387dc226118f8b4d9f927446bde7d07fe49798ca Mon Sep 17 00:00:00 2001 From: Rob Lourens <roblourens@gmail.com> Date: Sat, 25 Aug 2018 16:42:54 -0700 Subject: [PATCH 1256/1276] Settings editor - load settings in pages for much better perf #56296 --- src/vs/base/parts/tree/browser/treeView.ts | 2 +- .../preferences/browser/settingsEditor2.ts | 29 ++++++++-- .../parts/preferences/browser/settingsTree.ts | 55 ++++++++++++++++++- .../preferences/browser/settingsTreeModels.ts | 22 ++++++-- 4 files changed, 95 insertions(+), 13 deletions(-) diff --git a/src/vs/base/parts/tree/browser/treeView.ts b/src/vs/base/parts/tree/browser/treeView.ts index 5616313787e..0eb524c5247 100644 --- a/src/vs/base/parts/tree/browser/treeView.ts +++ b/src/vs/base/parts/tree/browser/treeView.ts @@ -673,7 +673,7 @@ export class TreeView extends HeightMap { } public getLastVisibleElement(): any { - const item = this.itemAtIndex(this.indexAt(this.lastRenderTop + this.lastRenderHeight)); + const item = this.itemAtIndex(this.indexAt(this.lastRenderTop + this.lastRenderHeight - 1)); return item && item.model.getElement(); } diff --git a/src/vs/workbench/parts/preferences/browser/settingsEditor2.ts b/src/vs/workbench/parts/preferences/browser/settingsEditor2.ts index e39c293743a..d891a63aabc 100644 --- a/src/vs/workbench/parts/preferences/browser/settingsEditor2.ts +++ b/src/vs/workbench/parts/preferences/browser/settingsEditor2.ts @@ -39,8 +39,8 @@ import { SuggestEnabledInput } from 'vs/workbench/parts/codeEditor/browser/sugge import { PreferencesEditor } from 'vs/workbench/parts/preferences/browser/preferencesEditor'; import { SettingsTarget, SettingsTargetsWidget } from 'vs/workbench/parts/preferences/browser/preferencesWidgets'; import { commonlyUsedData, tocData } from 'vs/workbench/parts/preferences/browser/settingsLayout'; -import { resolveExtensionsSettings, resolveSettingsTree, SettingsRenderer, SettingsTree } from 'vs/workbench/parts/preferences/browser/settingsTree'; -import { ISettingsEditorViewState, MODIFIED_SETTING_TAG, ONLINE_SERVICES_SETTING_TAG, SearchResultIdx, SearchResultModel, SettingsTreeGroupElement, SettingsTreeModel, SettingsTreeSettingElement, countSettingGroupChildrenWithPredicate } from 'vs/workbench/parts/preferences/browser/settingsTreeModels'; +import { resolveExtensionsSettings, resolveSettingsTree, SettingsRenderer, SettingsTree, SimplePagedDataSource, SettingsDataSource } from 'vs/workbench/parts/preferences/browser/settingsTree'; +import { ISettingsEditorViewState, MODIFIED_SETTING_TAG, ONLINE_SERVICES_SETTING_TAG, SearchResultIdx, SearchResultModel, SettingsTreeGroupElement, SettingsTreeModel, countSettingGroupChildrenWithPredicate, SettingsTreeSettingElement } from 'vs/workbench/parts/preferences/browser/settingsTreeModels'; import { TOCRenderer, TOCTree, TOCTreeModel } from 'vs/workbench/parts/preferences/browser/tocTree'; import { CONTEXT_SETTINGS_EDITOR, CONTEXT_SETTINGS_SEARCH_FOCUS, CONTEXT_TOC_ROW_FOCUS, IPreferencesSearchService, ISearchProvider } from 'vs/workbench/parts/preferences/common/preferences'; import { IEditorGroup } from 'vs/workbench/services/group/common/editorGroupsService'; @@ -71,6 +71,7 @@ export class SettingsEditor2 extends BaseEditor { private settingsTreeContainer: HTMLElement; private settingsTree: Tree; private settingsTreeRenderer: SettingsRenderer; + private settingsTreeDataSource: SimplePagedDataSource; private tocTreeModel: TOCTreeModel; private settingsTreeModel: SettingsTreeModel; private noResultsMessage: HTMLElement; @@ -426,14 +427,19 @@ export class SettingsEditor2 extends BaseEditor { })); this._register(this.tocTree.onDidChangeFocus(e => { - const element = e.focus; + const element: SettingsTreeGroupElement = e.focus; if (this.searchResultModel) { this.viewState.filterToCategory = element; this.renderTree(); } if (element && (!e.payload || !e.payload.fromScroll)) { - this.settingsTree.reveal(element, 0); + let refreshP = TPromise.wrap(null); + if (this.settingsTreeDataSource.pageTo(element.index)) { + refreshP = this.renderTree(); + } + + refreshP.then(() => this.settingsTree.reveal(element, 0)); } })); @@ -463,11 +469,15 @@ export class SettingsEditor2 extends BaseEditor { this.settingsTree.reveal(element); })); + this.settingsTreeDataSource = this.instantiationService.createInstance(SimplePagedDataSource, + this.instantiationService.createInstance(SettingsDataSource, this.viewState)); + this.settingsTree = this._register(this.instantiationService.createInstance(SettingsTree, this.settingsTreeContainer, this.viewState, { - renderer: this.settingsTreeRenderer + renderer: this.settingsTreeRenderer, + dataSource: this.settingsTreeDataSource })); this.settingsTree.getHTMLElement().attributes.removeNamedItem('tabindex'); @@ -516,6 +526,8 @@ export class SettingsEditor2 extends BaseEditor { return; } + this.updateTreePagingByScroll(); + const elementToSync = this.settingsTree.getFirstVisibleElement(); const element = elementToSync instanceof SettingsTreeSettingElement ? elementToSync.parent : elementToSync instanceof SettingsTreeGroupElement ? elementToSync : @@ -536,6 +548,13 @@ export class SettingsEditor2 extends BaseEditor { } } + private updateTreePagingByScroll(): void { + const lastVisibleElement = this.settingsTree.getLastVisibleElement(); + if (lastVisibleElement && this.settingsTreeDataSource.pageTo(lastVisibleElement.index)) { + this.renderTree(); + } + } + private updateChangedSetting(key: string, value: any): TPromise<void> { // ConfigurationService displays the error if this fails. // Force a render afterwards because onDidConfigurationUpdate doesn't fire if the update doesn't result in an effective setting value change diff --git a/src/vs/workbench/parts/preferences/browser/settingsTree.ts b/src/vs/workbench/parts/preferences/browser/settingsTree.ts index 30418278f38..e1816a4ca4e 100644 --- a/src/vs/workbench/parts/preferences/browser/settingsTree.ts +++ b/src/vs/workbench/parts/preferences/browser/settingsTree.ts @@ -39,7 +39,7 @@ import { editorBackground, errorForeground, focusBorder, foreground, inputValida import { attachButtonStyler, attachInputBoxStyler, attachSelectBoxStyler, attachStyler } from 'vs/platform/theme/common/styler'; import { ICssStyleCollector, ITheme, IThemeService, registerThemingParticipant } from 'vs/platform/theme/common/themeService'; import { ITOCEntry } from 'vs/workbench/parts/preferences/browser/settingsLayout'; -import { ISettingsEditorViewState, isExcludeSetting, SettingsTreeElement, SettingsTreeGroupElement, SettingsTreeNewExtensionsElement, SettingsTreeSettingElement, settingKeyToDisplayFormat } from 'vs/workbench/parts/preferences/browser/settingsTreeModels'; +import { ISettingsEditorViewState, isExcludeSetting, SettingsTreeElement, SettingsTreeGroupElement, SettingsTreeNewExtensionsElement, settingKeyToDisplayFormat, SettingsTreeSettingElement } from 'vs/workbench/parts/preferences/browser/settingsTreeModels'; import { ExcludeSettingWidget, IExcludeDataItem, settingsHeaderForeground, settingsNumberInputBackground, settingsNumberInputBorder, settingsNumberInputForeground, settingsSelectBackground, settingsSelectBorder, settingsSelectListBorder, settingsSelectForeground, settingsTextInputBackground, settingsTextInputBorder, settingsTextInputForeground } from 'vs/workbench/parts/preferences/browser/settingsWidgets'; import { ISetting, ISettingsGroup } from 'vs/workbench/services/preferences/common/preferences'; @@ -206,6 +206,58 @@ export class SettingsDataSource implements IDataSource { } } +export class SimplePagedDataSource implements IDataSource { + private static readonly SETTINGS_PER_PAGE = 30; + + private loadedToIndex: number; + + constructor(private realDataSource: IDataSource) { + this.loadedToIndex = SimplePagedDataSource.SETTINGS_PER_PAGE * 2; + } + + pageTo(index: number): boolean { + if (index > this.loadedToIndex - SimplePagedDataSource.SETTINGS_PER_PAGE) { + this.loadedToIndex = (Math.ceil(index / SimplePagedDataSource.SETTINGS_PER_PAGE) + 1) * SimplePagedDataSource.SETTINGS_PER_PAGE; + return true; + } else { + return false; + } + } + + getId(tree: ITree, element: any): string { + return this.realDataSource.getId(tree, element); + } + + hasChildren(tree: ITree, element: any): boolean { + return this.realDataSource.hasChildren(tree, element); + } + + getChildren(tree: ITree, element: SettingsTreeGroupElement): TPromise<any> { + return this.realDataSource.getChildren(tree, element).then(realChildren => { + return this._getChildren(realChildren); + }); + } + + _getChildren(realChildren: SettingsTreeElement[]): any[] { + const lastChild = realChildren[realChildren.length - 1]; + if (lastChild && lastChild.index > this.loadedToIndex) { + return realChildren.filter(child => { + return child.index < this.loadedToIndex; + }); + } else { + return realChildren; + } + } + + getParent(tree: ITree, element: any): TPromise<any> { + return this.realDataSource.getParent(tree, element); + } + + shouldAutoexpand(tree: ITree, element: any): boolean { + return this.realDataSource.shouldAutoexpand(tree, element); + } +} + interface IDisposableTemplate { toDispose: IDisposable[]; } @@ -1374,7 +1426,6 @@ export class SettingsTree extends NonExpandableOrSelectableTree { const controller = instantiationService.createInstance(SettingsTreeController); const fullConfiguration = <ITreeConfiguration>{ - dataSource: instantiationService.createInstance(SettingsDataSource, viewState), controller, accessibilityProvider: instantiationService.createInstance(SettingsAccessibilityProvider), filter: instantiationService.createInstance(SettingsTreeFilter, viewState), diff --git a/src/vs/workbench/parts/preferences/browser/settingsTreeModels.ts b/src/vs/workbench/parts/preferences/browser/settingsTreeModels.ts index cbbc0a6672a..9626898d470 100644 --- a/src/vs/workbench/parts/preferences/browser/settingsTreeModels.ts +++ b/src/vs/workbench/parts/preferences/browser/settingsTreeModels.ts @@ -25,6 +25,11 @@ export interface ISettingsEditorViewState { export abstract class SettingsTreeElement { id: string; parent: SettingsTreeGroupElement; + + /** + * Index assigned in display order, used for paging. + */ + index: number; } export class SettingsTreeGroupElement extends SettingsTreeElement { @@ -42,8 +47,8 @@ export class SettingsTreeNewExtensionsElement extends SettingsTreeElement { export class SettingsTreeSettingElement extends SettingsTreeElement { setting: ISetting; - _displayCategory: string; - _displayLabel: string; + private _displayCategory: string; + private _displayLabel: string; /** * scopeValue || defaultValue, for rendering convenience. @@ -70,8 +75,9 @@ export class SettingsTreeSettingElement extends SettingsTreeElement { description: string; valueType: 'enum' | 'string' | 'integer' | 'number' | 'boolean' | 'exclude' | 'complex' | 'nullable-integer' | 'nullable-number'; - constructor(setting: ISetting, parent: SettingsTreeGroupElement, inspectResult: IInspectResult) { + constructor(setting: ISetting, parent: SettingsTreeGroupElement, index: number, inspectResult: IInspectResult) { super(); + this.index = index; this.setting = setting; this.parent = parent; this.id = sanitizeId(parent.id + '_' + setting.key); @@ -193,7 +199,7 @@ export function countSettingGroupChildrenWithPredicate(tree: SettingsTreeGroupEl export class SettingsTreeModel { protected _root: SettingsTreeGroupElement; - private _treeElementsById = new Map<string, SettingsTreeElement>(); + protected _treeElementsById = new Map<string, SettingsTreeElement>(); private _treeElementsBySettingName = new Map<string, SettingsTreeSettingElement[]>(); private _tocRoot: ITOCEntry; @@ -243,6 +249,8 @@ export class SettingsTreeModel { private createSettingsTreeGroupElement(tocEntry: ITOCEntry, parent?: SettingsTreeGroupElement): SettingsTreeGroupElement { const element = new SettingsTreeGroupElement(); + const index = this._treeElementsById.size; + element.index = index; element.id = tocEntry.id; element.label = tocEntry.label; element.parent = parent; @@ -273,8 +281,9 @@ export class SettingsTreeModel { } private createSettingsTreeSettingElement(setting: ISetting, parent: SettingsTreeGroupElement): SettingsTreeSettingElement { + const index = this._treeElementsById.size; const inspectResult = inspectSetting(setting.key, this._viewState.settingsTarget, this._configurationService); - const element = new SettingsTreeSettingElement(setting, parent, inspectResult); + const element = new SettingsTreeSettingElement(setting, parent, index, inspectResult); this._treeElementsById.set(element.id, element); const nameElements = this._treeElementsBySettingName.get(setting.key) || []; @@ -449,8 +458,11 @@ export class SearchResultModel extends SettingsTreeModel { if (this.newExtensionSearchResults && this.newExtensionSearchResults.filterMatches.length) { const newExtElement = new SettingsTreeNewExtensionsElement(); + newExtElement.index = this._treeElementsById.size; newExtElement.parent = this._root; newExtElement.id = 'newExtensions'; + this._treeElementsById.set(newExtElement.id, newExtElement); + const resultExtensionIds = this.newExtensionSearchResults.filterMatches .map(result => (<IExtensionSetting>result.setting)) .filter(setting => setting.extensionName && setting.extensionPublisher) From 2c9408fecfc0507e78e1ac008e220d433cfef295 Mon Sep 17 00:00:00 2001 From: SteVen Batten <stbatt@microsoft.com> Date: Sun, 26 Aug 2018 12:32:24 -0700 Subject: [PATCH 1257/1276] fixes #53217 also just a clean up so there is one source for mnemoic regex --- src/vs/base/browser/ui/menu/menu.ts | 58 ++++++++++--------- .../browser/parts/titlebar/menubarControl.ts | 27 +++++---- 2 files changed, 49 insertions(+), 36 deletions(-) diff --git a/src/vs/base/browser/ui/menu/menu.ts b/src/vs/base/browser/ui/menu/menu.ts index b4c67882ff6..5fdb8d19292 100644 --- a/src/vs/base/browser/ui/menu/menu.ts +++ b/src/vs/base/browser/ui/menu/menu.ts @@ -17,6 +17,9 @@ import { $, Builder } from 'vs/base/browser/builder'; import { RunOnceScheduler } from 'vs/base/common/async'; import { IDisposable } from 'vs/base/common/lifecycle'; +export const MENU_MNEMONIC_REGEX: RegExp = /\(&{1,2}(\w)\)|&{1,2}(\w)/; +export const MENU_ESCAPED_MNEMONIC_REGEX: RegExp = /(?:&){1,2}(\w)/; + export interface IMenuOptions { context?: any; actionItemProvider?: IActionItemProvider; @@ -208,9 +211,6 @@ interface IMenuItemOptions extends IActionItemOptions { } class MenuActionItem extends BaseActionItem { - static MNEMONIC_REGEX: RegExp = /&&(.)/; - static ESCAPED_MNEMONIC_REGEX: RegExp = /&&(.)/; - public container: HTMLElement; protected $e: Builder; protected $label: Builder; @@ -232,9 +232,9 @@ class MenuActionItem extends BaseActionItem { if (this.options.label && options.enableMnemonics) { let label = this.getAction().label; if (label) { - let matches = MenuActionItem.MNEMONIC_REGEX.exec(label); - if (matches && matches.length === 2) { - this.mnemonic = KeyCodeUtils.fromString(matches[1].toLocaleLowerCase()); + let matches = MENU_MNEMONIC_REGEX.exec(label); + if (matches) { + this.mnemonic = KeyCodeUtils.fromString((!!matches[1] ? matches[1] : matches[2]).toLocaleLowerCase()); } } } @@ -257,10 +257,10 @@ class MenuActionItem extends BaseActionItem { } this.$check = $('span.menu-item-check').attr({ 'role': 'none' }).appendTo(this.$e); - this.$label = $('span.action-label').attr({ 'role': 'none' }).appendTo(this.$e); + this.$label = $('span.action-label').appendTo(this.$e); if (this.options.label && this.options.keybinding) { - $('span.keybinding').attr({ 'role': 'none' }).text(this.options.keybinding).appendTo(this.$e); + $('span.keybinding').text(this.options.keybinding).appendTo(this.$e); } this._updateClass(); @@ -278,30 +278,23 @@ class MenuActionItem extends BaseActionItem { _updateLabel(): void { if (this.options.label) { let label = this.getAction().label; - let mnemonic: string; if (label) { - let matches = MenuActionItem.MNEMONIC_REGEX.exec(label); - if (matches && matches.length === 2) { - mnemonic = matches[1]; - - let ariaLabel = label.replace(MenuActionItem.MNEMONIC_REGEX, mnemonic); - - this.mnemonic = KeyCodeUtils.fromString(mnemonic.toLocaleLowerCase()); - - this.$label.attr('aria-label', ariaLabel); - } else { - this.$label.attr('aria-label', label); + const cleanLabel = cleanMnemonic(label); + if (!this.options.enableMnemonics) { + label = cleanLabel; } - if (this.options.enableMnemonics && mnemonic) { - label = strings.escape(label).replace(MenuActionItem.ESCAPED_MNEMONIC_REGEX, '<u>$1</u>'); - this.$e.attr({ 'aria-keyshortcuts': mnemonic.toLocaleLowerCase() }); - } else { - label = strings.escape(label).replace(MenuActionItem.ESCAPED_MNEMONIC_REGEX, '$1'); + this.$label.attr('aria-label', cleanLabel); + + const matches = MENU_MNEMONIC_REGEX.exec(label); + + if (matches) { + label = strings.escape(label).replace(MENU_ESCAPED_MNEMONIC_REGEX, '<u aria-hidden="true">$1</u>'); + this.$e.attr({ 'aria-keyshortcuts': (!!matches[1] ? matches[1] : matches[2]).toLocaleLowerCase() }); } } - this.$label.innerHtml(label); + this.$label.innerHtml(label.trim()); } } @@ -524,3 +517,16 @@ class SubmenuActionItem extends MenuActionItem { } } } + +export function cleanMnemonic(label: string): string { + const regex = MENU_MNEMONIC_REGEX; + + const matches = regex.exec(label); + if (!matches) { + return label; + } + + const mnemonicInText = matches[0].charAt(0) === '&'; + + return label.replace(regex, mnemonicInText ? '$2' : '').trim(); +} \ No newline at end of file diff --git a/src/vs/workbench/browser/parts/titlebar/menubarControl.ts b/src/vs/workbench/browser/parts/titlebar/menubarControl.ts index 3650edb20d2..ea32ff76863 100644 --- a/src/vs/workbench/browser/parts/titlebar/menubarControl.ts +++ b/src/vs/workbench/browser/parts/titlebar/menubarControl.ts @@ -7,6 +7,7 @@ import * as nls from 'vs/nls'; import * as browser from 'vs/base/browser/browser'; +import * as strings from 'vs/base/common/strings'; import { IMenubarMenu, IMenubarMenuItemAction, IMenubarMenuItemSubmenu, IMenubarKeybinding } from 'vs/platform/menubar/common/menubar'; import { IMenuService, MenuId, IMenu, SubmenuItemAction } from 'vs/platform/actions/common/actions'; import { IThemeService, registerThemingParticipant, ITheme, ICssStyleCollector } from 'vs/platform/theme/common/themeService'; @@ -17,7 +18,7 @@ import { Separator } from 'vs/base/browser/ui/actionbar/actionbar'; import * as DOM from 'vs/base/browser/dom'; import { IKeybindingService } from 'vs/platform/keybinding/common/keybinding'; import { isMacintosh } from 'vs/base/common/platform'; -import { Menu, IMenuOptions, SubmenuAction } from 'vs/base/browser/ui/menu/menu'; +import { Menu, IMenuOptions, SubmenuAction, MENU_MNEMONIC_REGEX, cleanMnemonic, MENU_ESCAPED_MNEMONIC_REGEX } from 'vs/base/browser/ui/menu/menu'; import { KeyCode, KeyCodeUtils } from 'vs/base/common/keyCodes'; import { StandardKeyboardEvent } from 'vs/base/browser/keyboardEvent'; import { IConfigurationService, IConfigurationChangeEvent } from 'vs/platform/configuration/common/configuration'; @@ -523,7 +524,7 @@ export class MenubarControl extends Disposable { break; } - return this.currentEnableMenuBarMnemonics ? label : label.replace(/&&(.)/g, '$1'); + return label; } private createOpenRecentMenuAction(workspace: IWorkspaceIdentifier | ISingleFolderWorkspaceIdentifier | URI, commandId: string, isFile: boolean): IAction { @@ -657,10 +658,12 @@ export class MenubarControl extends Disposable { for (let menuTitle of Object.keys(this.topLevelMenus)) { const menu: IMenu = this.topLevelMenus[menuTitle]; let menuIndex = idx++; + const cleanMenuLabel = cleanMnemonic(this.topLevelTitles[menuTitle]); // Create the top level menu button element if (firstTimeSetup) { - const buttonElement = $('div.menubar-menu-button', { 'role': 'menuitem', 'tabindex': 0, 'aria-label': this.topLevelTitles[menuTitle].replace(/&&(.)/g, '$1'), 'aria-haspopup': true }); + + const buttonElement = $('div.menubar-menu-button', { 'role': 'menuitem', 'tabindex': 0, 'aria-label': cleanMenuLabel, 'aria-haspopup': true }); const titleElement = $('div.menubar-menu-title', { 'role': 'none', 'aria-hidden': true }); buttonElement.appendChild(titleElement); @@ -674,18 +677,22 @@ export class MenubarControl extends Disposable { } // Update the button label to reflect mnemonics - let displayTitle = this.topLevelTitles[menuTitle].replace(/&&(.)/g, this.currentEnableMenuBarMnemonics ? '<mnemonic aria-hidden="true">$1</mnemonic>' : '$1'); - this.customMenus[menuIndex].titleElement.innerHTML = displayTitle; + this.customMenus[menuIndex].titleElement.innerHTML = this.currentEnableMenuBarMnemonics ? + strings.escape(this.topLevelTitles[menuTitle]).replace(MENU_ESCAPED_MNEMONIC_REGEX, '<mnemonic aria-hidden="true">$1</mnemonic>') : + cleanMenuLabel; + + let mnemonicMatches = MENU_MNEMONIC_REGEX.exec(this.topLevelTitles[menuTitle]); // Register mnemonics - let mnemonic = (/&&(.)/g).exec(this.topLevelTitles[menuTitle]); - if (mnemonic && mnemonic[1]) { + if (mnemonicMatches) { + let mnemonic = !!mnemonicMatches[1] ? mnemonicMatches[1] : mnemonicMatches[2]; + if (firstTimeSetup) { - this.registerMnemonic(menuIndex, mnemonic[1]); + this.registerMnemonic(menuIndex, mnemonic); } if (this.currentEnableMenuBarMnemonics) { - this.customMenus[menuIndex].buttonElement.setAttribute('aria-keyshortcuts', 'Alt+' + mnemonic[1].toLocaleLowerCase()); + this.customMenus[menuIndex].buttonElement.setAttribute('aria-keyshortcuts', 'Alt+' + mnemonic.toLocaleLowerCase()); } else { this.customMenus[menuIndex].buttonElement.removeAttribute('aria-keyshortcuts'); } @@ -1028,7 +1035,7 @@ export class MenubarControl extends Disposable { let menuOptions: IMenuOptions = { getKeyBinding: (action) => this.keybindingService.lookupKeybinding(action.id), actionRunner: this.actionRunner, - enableMnemonics: this.mnemonicsInUse, + enableMnemonics: this.mnemonicsInUse && this.currentEnableMenuBarMnemonics, ariaLabel: customMenu.buttonElement.attributes['aria-label'].value }; From 5a8a6a71ff276ce813e040582cc9b8d983ee4218 Mon Sep 17 00:00:00 2001 From: Andre Weinand <aweinand@microsoft.com> Date: Sun, 26 Aug 2018 19:41:17 +0200 Subject: [PATCH 1258/1276] ignore auto attach timeouts; fixes #57232 --- src/vs/workbench/parts/debug/common/debug.ts | 1 + .../workbench/parts/debug/electron-browser/debugService.ts | 6 +++++- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/src/vs/workbench/parts/debug/common/debug.ts b/src/vs/workbench/parts/debug/common/debug.ts index 0c28a3e0db4..95dcc3ec20e 100644 --- a/src/vs/workbench/parts/debug/common/debug.ts +++ b/src/vs/workbench/parts/debug/common/debug.ts @@ -405,6 +405,7 @@ export interface IConfig extends IEnvConfig { // internals __sessionId?: string; __restart?: any; + __autoAttach?: boolean; port?: number; // TODO } diff --git a/src/vs/workbench/parts/debug/electron-browser/debugService.ts b/src/vs/workbench/parts/debug/electron-browser/debugService.ts index 037465b796b..cadb15fa3e5 100644 --- a/src/vs/workbench/parts/debug/electron-browser/debugService.ts +++ b/src/vs/workbench/parts/debug/electron-browser/debugService.ts @@ -717,7 +717,11 @@ export class DebugService implements IDebugService { this.panelService.openPanel(REPL_ID, false).done(undefined, errors.onUnexpectedError); } - this.showError(errorMessage, errors.isErrorWithActions(error) ? error.actions : []); + if (resolved && resolved.request === 'attach' && resolved.__autoAttach) { + // ignore attach timeouts in auto attach mode + } else { + this.showError(errorMessage, errors.isErrorWithActions(error) ? error.actions : []); + } return undefined; }); }); From c937afe0c5a702e6336a06c440888b8129d42ead Mon Sep 17 00:00:00 2001 From: Andre Weinand <aweinand@microsoft.com> Date: Sun, 26 Aug 2018 19:43:20 +0200 Subject: [PATCH 1259/1276] node-debug@1.27.5 --- build/builtInExtensions.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build/builtInExtensions.json b/build/builtInExtensions.json index 57f248322f1..e737360a6fa 100644 --- a/build/builtInExtensions.json +++ b/build/builtInExtensions.json @@ -1,7 +1,7 @@ [ { "name": "ms-vscode.node-debug", - "version": "1.27.4", + "version": "1.27.5", "repo": "https://github.com/Microsoft/vscode-node-debug" }, { From e700d600de8b5bc89cd4fd6744f4e0c47cb1d9a0 Mon Sep 17 00:00:00 2001 From: Rob Lourens <roblourens@gmail.com> Date: Sat, 25 Aug 2018 16:52:08 -0700 Subject: [PATCH 1260/1276] Settings editor - add min score to 'new extension' search results --- .../preferences/electron-browser/preferencesSearch.ts | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/vs/workbench/parts/preferences/electron-browser/preferencesSearch.ts b/src/vs/workbench/parts/preferences/electron-browser/preferencesSearch.ts index ba12960ff57..e80122a5a66 100644 --- a/src/vs/workbench/parts/preferences/electron-browser/preferencesSearch.ts +++ b/src/vs/workbench/parts/preferences/electron-browser/preferencesSearch.ts @@ -160,8 +160,9 @@ interface IBingRequestDetails { class RemoteSearchProvider implements ISearchProvider { // Must keep extension filter size under 8kb. 42 filters puts us there. - private static MAX_REQUEST_FILTERS = 42; - private static MAX_REQUESTS = 10; + private static readonly MAX_REQUEST_FILTERS = 42; + private static readonly MAX_REQUESTS = 10; + private static readonly NEW_EXTENSIONS_MIN_SCORE = 1; private _remoteSearchP: TPromise<IFilterMetadata>; @@ -190,7 +191,8 @@ class RemoteSearchProvider implements ISearchProvider { const highScore = highScoreKey ? remoteResult.scoredResults[highScoreKey].score : 0; const minScore = highScore / 5; if (this.options.newExtensionsOnly) { - const passingScoreKeys = resultKeys.filter(k => remoteResult.scoredResults[k].score >= minScore); + const newExtsMinScore = Math.max(RemoteSearchProvider.NEW_EXTENSIONS_MIN_SCORE, minScore); + const passingScoreKeys = resultKeys.filter(k => remoteResult.scoredResults[k].score >= newExtsMinScore); const filterMatches: ISettingMatch[] = passingScoreKeys.map(k => { const remoteSetting = remoteResult.scoredResults[k]; const setting = remoteSettingToISetting(remoteSetting); From c4aa2b5da3e4021ecf23350d1b0cc01d13145575 Mon Sep 17 00:00:00 2001 From: Benjamin Pasero <benjpas@microsoft.com> Date: Mon, 27 Aug 2018 07:35:04 +0200 Subject: [PATCH 1261/1276] debt - more builder removal --- src/vs/base/browser/dom.ts | 8 +- src/vs/base/browser/ui/actionbar/actionbar.ts | 93 ++++---- .../browser/ui/contextview/contextview.ts | 77 +++--- src/vs/base/browser/ui/dropdown/dropdown.ts | 76 +++--- src/vs/base/browser/ui/menu/menu.ts | 10 +- .../actions/browser/menuItemActionItem.ts | 12 +- .../parts/activitybar/activitybarActions.ts | 15 +- .../workbench/browser/parts/compositeBar.ts | 13 +- .../browser/parts/compositeBarActions.ts | 221 +++++++++--------- .../workbench/browser/parts/compositePart.ts | 81 +++---- .../browser/parts/statusbar/statusbarPart.ts | 29 ++- .../electron-browser/extensionsActions.ts | 2 +- .../electron-browser/markersPanelActions.ts | 2 +- .../preferences/browser/preferencesWidgets.ts | 3 +- .../parts/scm/electron-browser/scmViewlet.ts | 2 +- src/vs/workbench/test/browser/part.test.ts | 65 +++--- 16 files changed, 363 insertions(+), 346 deletions(-) diff --git a/src/vs/base/browser/dom.ts b/src/vs/base/browser/dom.ts index 55d7a57ba6a..f82eec031b4 100644 --- a/src/vs/base/browser/dom.ts +++ b/src/vs/base/browser/dom.ts @@ -16,12 +16,18 @@ import { CharCode } from 'vs/base/common/charCode'; import { Event, Emitter } from 'vs/base/common/event'; import { domEvent } from 'vs/base/browser/event'; -export function clearNode(node: HTMLElement) { +export function clearNode(node: HTMLElement): void { while (node.firstChild) { node.removeChild(node.firstChild); } } +export function removeNode(node: HTMLElement): void { + if (node.parentNode) { + node.parentNode.removeChild(node); + } +} + export function isInDOM(node: Node): boolean { while (node) { if (node === document.body) { diff --git a/src/vs/base/browser/ui/actionbar/actionbar.ts b/src/vs/base/browser/ui/actionbar/actionbar.ts index fd0a1c2e2f1..05e61cae92a 100644 --- a/src/vs/base/browser/ui/actionbar/actionbar.ts +++ b/src/vs/base/browser/ui/actionbar/actionbar.ts @@ -10,7 +10,6 @@ import * as platform from 'vs/base/common/platform'; import * as nls from 'vs/nls'; import * as lifecycle from 'vs/base/common/lifecycle'; import { TPromise } from 'vs/base/common/winjs.base'; -import { Builder, $ } from 'vs/base/browser/builder'; import { SelectBox, ISelectBoxOptions } from 'vs/base/browser/ui/selectBox/selectBox'; import { IAction, IActionRunner, Action, IActionChangeEvent, ActionRunner, IRunEvent } from 'vs/base/common/actions'; import * as DOM from 'vs/base/browser/dom'; @@ -38,7 +37,7 @@ export interface IBaseActionItemOptions { export class BaseActionItem implements IActionItem { - public builder: Builder; + public builder: HTMLElement; public _callOnDispose: lifecycle.IDisposable[]; public _context: any; public _action: IAction; @@ -106,7 +105,7 @@ export class BaseActionItem implements IActionItem { } public render(container: HTMLElement): void { - this.builder = $(container); + this.builder = container; Gesture.addTarget(container); const enableDragging = this.options && this.options.draggable; @@ -114,20 +113,20 @@ export class BaseActionItem implements IActionItem { container.draggable = true; } - this.builder.on(EventType.Tap, e => this.onClick(e)); + this._callOnDispose.push(DOM.addDisposableListener(this.builder, EventType.Tap, e => this.onClick(e))); - this.builder.on(DOM.EventType.MOUSE_DOWN, (e) => { + this._callOnDispose.push(DOM.addDisposableListener(this.builder, DOM.EventType.MOUSE_DOWN, e => { if (!enableDragging) { DOM.EventHelper.stop(e, true); // do not run when dragging is on because that would disable it } const mouseEvent = e as MouseEvent; if (this._action.enabled && mouseEvent.button === 0) { - this.builder.addClass('active'); + DOM.addClass(this.builder, 'active'); } - }); + })); - this.builder.on(DOM.EventType.CLICK, (e) => { + this._callOnDispose.push(DOM.addDisposableListener(this.builder, DOM.EventType.CLICK, e => { DOM.EventHelper.stop(e, true); // See https://developer.mozilla.org/en-US/Add-ons/WebExtensions/Interact_with_the_clipboard // > Writing to the clipboard @@ -142,11 +141,13 @@ export class BaseActionItem implements IActionItem { } else { platform.setImmediate(() => this.onClick(e)); } - }); + })); - this.builder.on([DOM.EventType.MOUSE_UP, DOM.EventType.MOUSE_OUT], (e) => { - DOM.EventHelper.stop(e); - this.builder.removeClass('active'); + [DOM.EventType.MOUSE_UP, DOM.EventType.MOUSE_OUT].forEach(event => { + this._callOnDispose.push(DOM.addDisposableListener(this.builder, event, e => { + DOM.EventHelper.stop(e); + DOM.removeClass(this.builder, 'active'); + })); }); } @@ -169,15 +170,15 @@ export class BaseActionItem implements IActionItem { public focus(): void { if (this.builder) { - this.builder.domFocus(); - this.builder.addClass('focused'); + this.builder.focus(); + DOM.addClass(this.builder, 'focused'); } } public blur(): void { if (this.builder) { - this.builder.domBlur(); - this.builder.removeClass('focused'); + this.builder.blur(); + DOM.removeClass(this.builder, 'focused'); } } @@ -203,7 +204,7 @@ export class BaseActionItem implements IActionItem { public dispose(): void { if (this.builder) { - this.builder.destroy(); + DOM.removeNode(this.builder); this.builder = null; } @@ -232,7 +233,7 @@ export interface IActionItemOptions extends IBaseActionItemOptions { export class ActionItem extends BaseActionItem { - protected $e: Builder; + protected $e: HTMLElement; protected options: IActionItemOptions; private cssClass: string; @@ -248,20 +249,20 @@ export class ActionItem extends BaseActionItem { public render(container: HTMLElement): void { super.render(container); - this.$e = $('a.action-label').appendTo(this.builder); + this.$e = DOM.append(this.builder, DOM.$('a.action-label')); if (this._action.id === Separator.ID) { // A separator is a presentation item - this.$e.attr({ role: 'presentation' }); + this.$e.setAttribute('role', 'presentation'); } else { if (this.options.isMenu) { - this.$e.attr({ role: 'menuitem' }); + this.$e.setAttribute('role', 'menuitem'); } else { - this.$e.attr({ role: 'button' }); + this.$e.setAttribute('role', 'button'); } } if (this.options.label && this.options.keybinding) { - $('span.keybinding').text(this.options.keybinding).appendTo(this.builder); + DOM.append(this.builder, DOM.$('span.keybinding')).textContent = this.options.keybinding; } this._updateClass(); @@ -273,12 +274,12 @@ export class ActionItem extends BaseActionItem { public focus(): void { super.focus(); - this.$e.domFocus(); + this.$e.focus(); } public _updateLabel(): void { if (this.options.label) { - this.$e.text(this.getAction().label); + this.$e.textContent = this.getAction().label; } } @@ -297,43 +298,43 @@ export class ActionItem extends BaseActionItem { } if (title) { - this.$e.attr({ title: title }); + this.$e.title = title; } } public _updateClass(): void { if (this.cssClass) { - this.$e.removeClass(this.cssClass); + DOM.removeClasses(this.$e, this.cssClass); } if (this.options.icon) { this.cssClass = this.getAction().class; - this.$e.addClass('icon'); + DOM.addClass(this.$e, 'icon'); if (this.cssClass) { - this.$e.addClass(this.cssClass); + DOM.addClasses(this.$e, this.cssClass); } this._updateEnabled(); } else { - this.$e.removeClass('icon'); + DOM.removeClass(this.$e, 'icon'); } } public _updateEnabled(): void { if (this.getAction().enabled) { - this.builder.removeClass('disabled'); - this.$e.removeClass('disabled'); - this.$e.attr({ tabindex: 0 }); + DOM.removeClass(this.builder, 'disabled'); + DOM.removeClass(this.$e, 'disabled'); + this.$e.tabIndex = 0; } else { - this.builder.addClass('disabled'); - this.$e.addClass('disabled'); - DOM.removeTabIndexAndUpdateFocus(this.$e.getHTMLElement()); + DOM.addClass(this.builder, 'disabled'); + DOM.addClass(this.$e, 'disabled'); + DOM.removeTabIndexAndUpdateFocus(this.$e); } } public _updateChecked(): void { if (this.getAction().checked) { - this.$e.addClass('checked'); + DOM.addClass(this.$e, 'checked'); } else { - this.$e.removeClass('checked'); + DOM.removeClass(this.$e, 'checked'); } } } @@ -439,7 +440,7 @@ export class ActionBar implements IActionRunner { break; } - $(this.domNode).on(DOM.EventType.KEY_DOWN, (e) => { + this.toDispose.push(DOM.addDisposableListener(this.domNode, DOM.EventType.KEY_DOWN, e => { let event = new StandardKeyboardEvent(e as KeyboardEvent); let eventHandled = true; @@ -459,9 +460,9 @@ export class ActionBar implements IActionRunner { event.preventDefault(); event.stopPropagation(); } - }); + })); - $(this.domNode).on(DOM.EventType.KEY_UP, (e) => { + this.toDispose.push(DOM.addDisposableListener(this.domNode, DOM.EventType.KEY_UP, e => { let event = new StandardKeyboardEvent(e as KeyboardEvent); // Run action on Enter/Space @@ -475,7 +476,7 @@ export class ActionBar implements IActionRunner { else if (event.equals(KeyCode.Tab) || event.equals(KeyMod.Shift | KeyCode.Tab)) { this.updateFocusedItem(); } - }); + })); this.focusTracker = DOM.trackFocus(this.domNode); this.toDispose.push(this.focusTracker.onDidBlur(() => { @@ -570,10 +571,10 @@ export class ActionBar implements IActionRunner { actionItemElement.setAttribute('role', 'presentation'); // Prevent native context menu on actions - $(actionItemElement).on(DOM.EventType.CONTEXT_MENU, (e: DOM.EventLike) => { + this.toDispose.push(DOM.addDisposableListener(actionItemElement, DOM.EventType.CONTEXT_MENU, (e: DOM.EventLike) => { e.preventDefault(); e.stopPropagation(); - }); + })); let item: IActionItem = null; @@ -626,7 +627,7 @@ export class ActionBar implements IActionRunner { public clear(): void { this.items = lifecycle.dispose(this.items); - $(this.actionsList).empty(); + DOM.clearNode(this.actionsList); } public length(): number { @@ -756,7 +757,7 @@ export class ActionBar implements IActionRunner { this.toDispose = lifecycle.dispose(this.toDispose); - $(this.getContainer()).destroy(); + DOM.removeNode(this.getContainer()); } } diff --git a/src/vs/base/browser/ui/contextview/contextview.ts b/src/vs/base/browser/ui/contextview/contextview.ts index c16fc27af11..15ad50296cb 100644 --- a/src/vs/base/browser/ui/contextview/contextview.ts +++ b/src/vs/base/browser/ui/contextview/contextview.ts @@ -6,9 +6,8 @@ 'use strict'; import 'vs/css!./contextview'; -import { Builder, $ } from 'vs/base/browser/builder'; import * as DOM from 'vs/base/browser/dom'; -import { IDisposable, dispose, toDisposable } from 'vs/base/common/lifecycle'; +import { IDisposable, dispose, toDisposable, combinedDisposable } from 'vs/base/common/lifecycle'; export interface IAnchor { x: number; @@ -101,39 +100,50 @@ export class ContextView { private static readonly BUBBLE_UP_EVENTS = ['click', 'keydown', 'focus', 'blur']; private static readonly BUBBLE_DOWN_EVENTS = ['click']; - private $container: Builder; - private $view: Builder; + private $container: HTMLElement; + private $view: HTMLElement; private delegate: IDelegate; private toDispose: IDisposable[]; private toDisposeOnClean: IDisposable; + private toDisposeOnSetContainer: IDisposable; constructor(container: HTMLElement) { - this.$view = $('.context-view').hide(); + this.$view = DOM.$('.context-view'); + + DOM.hide(this.$view); + this.setContainer(container); this.toDispose = [toDisposable(() => { this.setContainer(null); })]; - - this.toDisposeOnClean = null; } public setContainer(container: HTMLElement): void { if (this.$container) { - this.$container.getHTMLElement().removeChild(this.$view.getHTMLElement()); - this.$container.off(ContextView.BUBBLE_UP_EVENTS); - this.$container.off(ContextView.BUBBLE_DOWN_EVENTS, true); + this.toDisposeOnSetContainer = dispose(this.toDisposeOnSetContainer); + this.$container.removeChild(this.$view); this.$container = null; } if (container) { - this.$container = $(container); - this.$view.appendTo(this.$container); - this.$container.on(ContextView.BUBBLE_UP_EVENTS, (e: Event) => { - this.onDOMEvent(e, <HTMLElement>document.activeElement, false); + this.$container = container; + this.$container.appendChild(this.$view); + + const toDispose: IDisposable[] = []; + + ContextView.BUBBLE_UP_EVENTS.forEach(event => { + toDispose.push(DOM.addStandardDisposableListener(this.$container, event, (e: Event) => { + this.onDOMEvent(e, <HTMLElement>document.activeElement, false); + })); }); - this.$container.on(ContextView.BUBBLE_DOWN_EVENTS, (e: Event) => { - this.onDOMEvent(e, <HTMLElement>document.activeElement, true); - }, null, true); + + ContextView.BUBBLE_DOWN_EVENTS.forEach(event => { + toDispose.push(DOM.addStandardDisposableListener(this.$container, event, (e: Event) => { + this.onDOMEvent(e, <HTMLElement>document.activeElement, true); + }, true)); + }); + + this.toDisposeOnSetContainer = combinedDisposable(toDispose); } } @@ -143,10 +153,14 @@ export class ContextView { } // Show static box - this.$view.setClass('context-view').empty().style({ top: '0px', left: '0px' }).show(); + DOM.clearNode(this.$view); + this.$view.className = 'context-view'; + this.$view.style.top = '0px'; + this.$view.style.left = '0px'; + DOM.show(this.$view); // Render content - this.toDisposeOnClean = delegate.render(this.$view.getHTMLElement()); + this.toDisposeOnClean = delegate.render(this.$view); // Set active delegate this.delegate = delegate; @@ -205,7 +219,9 @@ export class ContextView { }; } - const viewSize = this.$view.getTotalSize(); + const viewSizeWidth = DOM.getTotalWidth(this.$view); + const viewSizeHeight = DOM.getTotalHeight(this.$view); + const anchorPosition = this.delegate.anchorPosition || AnchorPosition.BELOW; const anchorAlignment = this.delegate.anchorAlignment || AnchorAlignment.LEFT; @@ -219,14 +235,17 @@ export class ContextView { horizontalAnchor = { offset: around.left + around.width, size: 0, position: LayoutAnchorPosition.After }; } - const containerPosition = DOM.getDomNodePagePosition(this.$container.getHTMLElement()); - const top = layout(window.innerHeight, viewSize.height, verticalAnchor) - containerPosition.top; - const left = layout(window.innerWidth, viewSize.width, horizontalAnchor) - containerPosition.left; + const containerPosition = DOM.getDomNodePagePosition(this.$container); + const top = layout(window.innerHeight, viewSizeHeight, verticalAnchor) - containerPosition.top; + const left = layout(window.innerWidth, viewSizeWidth, horizontalAnchor) - containerPosition.left; - this.$view.removeClass('top', 'bottom', 'left', 'right'); - this.$view.addClass(anchorPosition === AnchorPosition.BELOW ? 'bottom' : 'top'); - this.$view.addClass(anchorAlignment === AnchorAlignment.LEFT ? 'left' : 'right'); - this.$view.style({ top: `${top}px`, left: `${left}px`, width: 'initial' }); + DOM.removeClasses(this.$view, 'top', 'bottom', 'left', 'right'); + DOM.addClass(this.$view, anchorPosition === AnchorPosition.BELOW ? 'bottom' : 'top'); + DOM.addClass(this.$view, anchorAlignment === AnchorAlignment.LEFT ? 'left' : 'right'); + + this.$view.style.top = `${top}px`; + this.$view.style.left = `${left}px`; + this.$view.style.width = 'initial'; } public hide(data?: any): void { @@ -241,7 +260,7 @@ export class ContextView { this.toDisposeOnClean = null; } - this.$view.hide(); + DOM.hide(this.$view); } private isVisible(): boolean { @@ -252,7 +271,7 @@ export class ContextView { if (this.delegate) { if (this.delegate.onDOMEvent) { this.delegate.onDOMEvent(e, <HTMLElement>document.activeElement); - } else if (onCapture && !DOM.isAncestor(<HTMLElement>e.target, this.$container.getHTMLElement())) { + } else if (onCapture && !DOM.isAncestor(<HTMLElement>e.target, this.$container)) { this.hide(); } } diff --git a/src/vs/base/browser/ui/dropdown/dropdown.ts b/src/vs/base/browser/ui/dropdown/dropdown.ts index f2b9a1f842e..a2fd1d60735 100644 --- a/src/vs/base/browser/ui/dropdown/dropdown.ts +++ b/src/vs/base/browser/ui/dropdown/dropdown.ts @@ -6,7 +6,6 @@ 'use strict'; import 'vs/css!./dropdown'; -import { Builder, $ } from 'vs/base/browser/builder'; import { TPromise } from 'vs/base/common/winjs.base'; import { Gesture, EventType as GestureEventType } from 'vs/base/browser/touch'; import { ActionRunner, IAction, IActionRunner } from 'vs/base/common/actions'; @@ -15,7 +14,7 @@ import { IDisposable, dispose } from 'vs/base/common/lifecycle'; import { IContextViewProvider, IAnchor } from 'vs/base/browser/ui/contextview/contextview'; import { IMenuOptions } from 'vs/base/browser/ui/menu/menu'; import { ResolvedKeybinding } from 'vs/base/common/keyCodes'; -import { EventHelper, EventType, removeClass, addClass } from 'vs/base/browser/dom'; +import { EventHelper, EventType, removeClass, addClass, append, $, removeNode, addDisposableListener, addClasses } from 'vs/base/browser/dom'; import { IContextMenuDelegate } from 'vs/base/browser/contextmenu'; export interface ILabelRenderer { @@ -30,47 +29,52 @@ export interface IBaseDropdownOptions { export class BaseDropdown extends ActionRunner { private _toDispose: IDisposable[] = []; - private $el: Builder; - private $boxContainer: Builder; - private $label: Builder; - private $contents: Builder; + private $el: HTMLElement; + private $boxContainer: HTMLElement; + private $label: HTMLElement; + private $contents: HTMLElement; private visible: boolean; constructor(container: HTMLElement, options: IBaseDropdownOptions) { super(); - this.$el = $('.monaco-dropdown').appendTo(container); + this.$el = append(container, $('.monaco-dropdown')); - this.$label = $('.dropdown-label'); + this.$label = append(this.$el, $('.dropdown-label')); let labelRenderer = options.labelRenderer; if (!labelRenderer) { labelRenderer = (container: HTMLElement): IDisposable => { - $(container).text(options.label || ''); + container.textContent = options.label || ''; + return null; }; } - this.$label.on([EventType.CLICK, EventType.MOUSE_DOWN, GestureEventType.Tap], (e: Event) => { - EventHelper.stop(e, true); // prevent default click behaviour to trigger - }).on([EventType.MOUSE_DOWN, GestureEventType.Tap], (e: Event) => { - if (e instanceof MouseEvent && e.detail > 1) { - return; // prevent multiple clicks to open multiple context menus (https://github.com/Microsoft/vscode/issues/41363) - } + [EventType.CLICK, EventType.MOUSE_DOWN, GestureEventType.Tap].forEach(event => { + this._toDispose.push(addDisposableListener(this.$label, event, e => EventHelper.stop(e, true))); // prevent default click behaviour to trigger + }); - if (this.visible) { - this.hide(); - } else { - this.show(); - } - }).appendTo(this.$el); + [EventType.MOUSE_DOWN, GestureEventType.Tap].forEach(event => { + this._toDispose.push(addDisposableListener(this.$label, event, e => { + if (e instanceof MouseEvent && e.detail > 1) { + return; // prevent multiple clicks to open multiple context menus (https://github.com/Microsoft/vscode/issues/41363) + } - const cleanupFn = labelRenderer(this.$label.getHTMLElement()); + if (this.visible) { + this.hide(); + } else { + this.show(); + } + })); + }); + + const cleanupFn = labelRenderer(this.$label); if (cleanupFn) { this._toDispose.push(cleanupFn); } - Gesture.addTarget(this.$label.getHTMLElement()); + Gesture.addTarget(this.$label); } get toDispose(): IDisposable[] { @@ -78,15 +82,15 @@ export class BaseDropdown extends ActionRunner { } get element(): HTMLElement { - return this.$el.getHTMLElement(); + return this.$el; } get label(): HTMLElement { - return this.$label.getHTMLElement(); + return this.$label; } set tooltip(tooltip: string) { - this.$label.title(tooltip); + this.$label.title = tooltip; } show(): void { @@ -108,17 +112,17 @@ export class BaseDropdown extends ActionRunner { this._toDispose = dispose(this.toDispose); if (this.$boxContainer) { - this.$boxContainer.destroy(); + removeNode(this.$boxContainer); this.$boxContainer = null; } if (this.$contents) { - this.$contents.destroy(); + removeNode(this.$contents); this.$contents = null; } if (this.$label) { - this.$label.destroy(); + removeNode(this.$label); this.$label = null; } } @@ -279,15 +283,13 @@ export class DropdownMenuActionItem extends BaseActionItem { render(container: HTMLElement): void { const labelRenderer: ILabelRenderer = (el: HTMLElement): IDisposable => { - this.builder = $('a.action-label').attr({ - tabIndex: '0', - role: 'button', - 'aria-haspopup': 'true', - title: this._action.label || '', - class: this.clazz - }); + this.builder = append(el, $('a.action-label')); + addClasses(this.builder, this.clazz); - this.builder.appendTo(el); + this.builder.tabIndex = 0; + this.builder.setAttribute('role', 'button'); + this.builder.setAttribute('aria-haspopup', 'true'); + this.builder.title = this._action.label || ''; return null; }; diff --git a/src/vs/base/browser/ui/menu/menu.ts b/src/vs/base/browser/ui/menu/menu.ts index 5fdb8d19292..a2d946073e1 100644 --- a/src/vs/base/browser/ui/menu/menu.ts +++ b/src/vs/base/browser/ui/menu/menu.ts @@ -11,7 +11,7 @@ import * as strings from 'vs/base/common/strings'; import { IActionRunner, IAction, Action } from 'vs/base/common/actions'; import { ActionBar, IActionItemProvider, ActionsOrientation, Separator, ActionItem, IActionItemOptions, BaseActionItem } from 'vs/base/browser/ui/actionbar/actionbar'; import { ResolvedKeybinding, KeyCode, KeyCodeUtils } from 'vs/base/common/keyCodes'; -import { addClass, EventType, EventHelper, EventLike, removeTabIndexAndUpdateFocus, isAncestor, hasClass, addDisposableListener } from 'vs/base/browser/dom'; +import { addClass, EventType, EventHelper, EventLike, removeTabIndexAndUpdateFocus, isAncestor, hasClass, addDisposableListener, removeClass } from 'vs/base/browser/dom'; import { StandardKeyboardEvent } from 'vs/base/browser/keyboardEvent'; import { $, Builder } from 'vs/base/browser/builder'; import { RunOnceScheduler } from 'vs/base/common/async'; @@ -335,11 +335,11 @@ class MenuActionItem extends BaseActionItem { _updateEnabled(): void { if (this.getAction().enabled) { - this.builder.removeClass('disabled'); + removeClass(this.builder, 'disabled'); this.$e.removeClass('disabled'); this.$e.attr({ tabindex: 0 }); } else { - this.builder.addClass('disabled'); + addClass(this.builder, 'disabled'); this.$e.addClass('disabled'); removeTabIndexAndUpdateFocus(this.$e.getHTMLElement()); } @@ -383,7 +383,7 @@ class SubmenuActionItem extends MenuActionItem { }, 250); this.hideScheduler = new RunOnceScheduler(() => { - if ((!isAncestor(document.activeElement, this.builder.getHTMLElement()) && this.parentData.submenu === this.mysubmenu)) { + if ((!isAncestor(document.activeElement, this.builder) && this.parentData.submenu === this.mysubmenu)) { this.parentData.parent.focus(false); this.cleanupExistingSubmenu(true); } @@ -426,7 +426,7 @@ class SubmenuActionItem extends MenuActionItem { }); $(this.builder).on(EventType.FOCUS_OUT, (e) => { - if (!isAncestor(document.activeElement, this.builder.getHTMLElement())) { + if (!isAncestor(document.activeElement, this.builder)) { this.hideScheduler.schedule(); } }); diff --git a/src/vs/platform/actions/browser/menuItemActionItem.ts b/src/vs/platform/actions/browser/menuItemActionItem.ts index a8ff208c0a6..20de6c969d2 100644 --- a/src/vs/platform/actions/browser/menuItemActionItem.ts +++ b/src/vs/platform/actions/browser/menuItemActionItem.ts @@ -9,13 +9,13 @@ import { localize } from 'vs/nls'; import { IKeybindingService } from 'vs/platform/keybinding/common/keybinding'; import { IMenu, MenuItemAction, IMenuActionOptions, ICommandAction, SubmenuItemAction } from 'vs/platform/actions/common/actions'; import { IAction } from 'vs/base/common/actions'; -import { IDisposable, dispose } from 'vs/base/common/lifecycle'; +import { IDisposable, dispose, toDisposable } from 'vs/base/common/lifecycle'; import { ActionItem, Separator } from 'vs/base/browser/ui/actionbar/actionbar'; import { domEvent } from 'vs/base/browser/event'; import { Emitter } from 'vs/base/common/event'; import { IContextMenuService } from 'vs/platform/contextview/browser/contextView'; import { IdGenerator } from 'vs/base/common/idGenerator'; -import { createCSSRule } from 'vs/base/browser/dom'; +import { createCSSRule, addClasses, removeClasses } from 'vs/base/browser/dom'; import { INotificationService } from 'vs/platform/notification/common/notification'; import { isWindows, isLinux } from 'vs/base/common/platform'; @@ -217,12 +217,12 @@ export class MenuItemActionItem extends ActionItem { _updateLabel(): void { if (this.options.label) { - this.$e.text(this._commandAction.label); + this.$e.textContent = this._commandAction.label; } } _updateTooltip(): void { - const element = this.$e.getHTMLElement(); + const element = this.$e; const keybinding = this._keybindingService.lookupKeybinding(this._commandAction.id); const keybindingLabel = keybinding && keybinding.getLabel(); @@ -259,8 +259,8 @@ export class MenuItemActionItem extends ActionItem { MenuItemActionItem.ICON_PATH_TO_CSS_RULES.set(iconPathMapKey, iconClass); } - this.$e.getHTMLElement().classList.add('icon', iconClass); - this._itemClassDispose = { dispose: () => this.$e.getHTMLElement().classList.remove('icon', iconClass) }; + addClasses(this.$e, 'icon', iconClass); + this._itemClassDispose = toDisposable(() => removeClasses(this.$e, 'icon', iconClass)); } } diff --git a/src/vs/workbench/browser/parts/activitybar/activitybarActions.ts b/src/vs/workbench/browser/parts/activitybar/activitybarActions.ts index 773bbe0d763..da7c06bd2d9 100644 --- a/src/vs/workbench/browser/parts/activitybar/activitybarActions.ts +++ b/src/vs/workbench/browser/parts/activitybar/activitybarActions.ts @@ -122,28 +122,29 @@ export class GlobalActivityActionItem extends ActivityActionItem { // Context menus are triggered on mouse down so that an item can be picked // and executed with releasing the mouse over it - this.$container.on(DOM.EventType.MOUSE_DOWN, (e: MouseEvent) => { + + this.callOnDispose.push(DOM.addDisposableListener(this.$container, DOM.EventType.MOUSE_DOWN, (e: MouseEvent) => { DOM.EventHelper.stop(e, true); const event = new StandardMouseEvent(e); this.showContextMenu({ x: event.posx, y: event.posy }); - }); + })); - this.$container.on(DOM.EventType.KEY_UP, (e: KeyboardEvent) => { + this.callOnDispose.push(DOM.addDisposableListener(this.$container, DOM.EventType.KEY_UP, (e: KeyboardEvent) => { let event = new StandardKeyboardEvent(e); if (event.equals(KeyCode.Enter) || event.equals(KeyCode.Space)) { DOM.EventHelper.stop(e, true); - this.showContextMenu(this.$container.getHTMLElement()); + this.showContextMenu(this.$container); } - }); + })); - this.$container.on(TouchEventType.Tap, (e: GestureEvent) => { + this.callOnDispose.push(DOM.addDisposableListener(this.$container, TouchEventType.Tap, (e: GestureEvent) => { DOM.EventHelper.stop(e, true); const event = new StandardMouseEvent(e); this.showContextMenu({ x: event.posx, y: event.posy }); - }); + })); } private showContextMenu(location: HTMLElement | { x: number, y: number }): void { diff --git a/src/vs/workbench/browser/parts/compositeBar.ts b/src/vs/workbench/browser/parts/compositeBar.ts index fa12612a68a..f1a10123c37 100644 --- a/src/vs/workbench/browser/parts/compositeBar.ts +++ b/src/vs/workbench/browser/parts/compositeBar.ts @@ -14,13 +14,14 @@ import { IBadge } from 'vs/workbench/services/activity/common/activity'; import { IStorageService, StorageScope } from 'vs/platform/storage/common/storage'; import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; import { ActionBar, ActionsOrientation, Separator } from 'vs/base/browser/ui/actionbar/actionbar'; -import { CompositeActionItem, CompositeOverflowActivityAction, ICompositeActivity, CompositeOverflowActivityActionItem, ActivityAction, ICompositeBar, ICompositeBarColors } from 'vs/workbench/browser/parts/compositeBarActions'; +import { CompositeActionItem, CompositeOverflowActivityAction, ICompositeActivity, CompositeOverflowActivityActionItem, ActivityAction, ICompositeBar, ICompositeBarColors, DraggedCompositeIdentifier } from 'vs/workbench/browser/parts/compositeBarActions'; import { TPromise } from 'vs/base/common/winjs.base'; import { Dimension, $, addDisposableListener, EventType, EventHelper } from 'vs/base/browser/dom'; import { StandardMouseEvent } from 'vs/base/browser/mouseEvent'; import { IContextMenuService } from 'vs/platform/contextview/browser/contextView'; import { Widget } from 'vs/base/browser/ui/widget'; import { isUndefinedOrNull } from 'vs/base/common/types'; +import { LocalSelectionTransfer } from 'vs/workbench/browser/dnd'; export interface ICompositeBarOptions { icon: boolean; @@ -50,6 +51,8 @@ export class CompositeBar extends Widget implements ICompositeBar { private visibleComposites: string[]; private compositeSizeInBar: Map<string, number>; + private compositeTransfer: LocalSelectionTransfer<DraggedCompositeIdentifier>; + constructor( private options: ICompositeBarOptions, @IInstantiationService private instantiationService: IInstantiationService, @@ -61,6 +64,7 @@ export class CompositeBar extends Widget implements ICompositeBar { this.model = new CompositeBarModel(options, storageService); this.visibleComposites = []; this.compositeSizeInBar = new Map<string, number>(); + this.compositeTransfer = LocalSelectionTransfer.getInstance<DraggedCompositeIdentifier>(); } create(parent: HTMLElement): HTMLElement { @@ -83,10 +87,11 @@ export class CompositeBar extends Widget implements ICompositeBar { // Allow to drop at the end to move composites to the end this._register(addDisposableListener(parent, EventType.DROP, (e: DragEvent) => { - const draggedCompositeId = CompositeActionItem.getDraggedCompositeId(); - if (draggedCompositeId) { + if (this.compositeTransfer.hasData(DraggedCompositeIdentifier.prototype)) { EventHelper.stop(e, true); - CompositeActionItem.clearDraggedComposite(); + + const draggedCompositeId = this.compositeTransfer.getData(DraggedCompositeIdentifier.prototype)[0].id; + this.compositeTransfer.clearData(DraggedCompositeIdentifier.prototype); const targetItem = this.model.visibleItems[this.model.visibleItems.length - 1]; if (targetItem && targetItem.id !== draggedCompositeId) { diff --git a/src/vs/workbench/browser/parts/compositeBarActions.ts b/src/vs/workbench/browser/parts/compositeBarActions.ts index eed75df278b..3b275abc9cd 100644 --- a/src/vs/workbench/browser/parts/compositeBarActions.ts +++ b/src/vs/workbench/browser/parts/compositeBarActions.ts @@ -9,7 +9,6 @@ import * as nls from 'vs/nls'; import { Action } from 'vs/base/common/actions'; import { TPromise } from 'vs/base/common/winjs.base'; import * as dom from 'vs/base/browser/dom'; -import { Builder, $ } from 'vs/base/browser/builder'; import { BaseActionItem, IBaseActionItemOptions, Separator } from 'vs/base/browser/ui/actionbar/actionbar'; import { ICommandService } from 'vs/platform/commands/common/commands'; import { dispose, IDisposable, Disposable, toDisposable } from 'vs/base/common/lifecycle'; @@ -22,6 +21,7 @@ import { DelayedDragHandler } from 'vs/base/browser/dnd'; import { IActivity } from 'vs/workbench/common/activity'; import { IKeybindingService } from 'vs/platform/keybinding/common/keybinding'; import { Event, Emitter } from 'vs/base/common/event'; +import { DragAndDropObserver, LocalSelectionTransfer } from 'vs/workbench/browser/dnd'; export interface ICompositeActivity { badge: IBadge; @@ -124,12 +124,12 @@ export interface IActivityActionItemOptions extends IBaseActionItemOptions { } export class ActivityActionItem extends BaseActionItem { - protected $container: Builder; - protected $label: Builder; - protected $badge: Builder; + protected $container: HTMLElement; + protected $label: HTMLElement; + protected $badge: HTMLElement; protected options: IActivityActionItemOptions; - private $badgeContent: Builder; + private $badgeContent: HTMLElement; private badgeDisposable: IDisposable = Disposable.None; private mouseUpTimeout: number; @@ -156,7 +156,7 @@ export class ActivityActionItem extends BaseActionItem { if (this.$label && this.options.icon) { const background = theme.getColor(this.options.colors.backgroundColor); - this.$label.style('background-color', background ? background.toString() : null); + this.$label.style.backgroundColor = background ? background.toString() : null; } // Badge @@ -165,46 +165,47 @@ export class ActivityActionItem extends BaseActionItem { const badgeBackground = theme.getColor(this.options.colors.badgeBackground); const contrastBorderColor = theme.getColor(contrastBorder); - this.$badgeContent.style('color', badgeForeground ? badgeForeground.toString() : null); - this.$badgeContent.style('background-color', badgeBackground ? badgeBackground.toString() : null); + this.$badgeContent.style.color = badgeForeground ? badgeForeground.toString() : null; + this.$badgeContent.style.backgroundColor = badgeBackground ? badgeBackground.toString() : null; - this.$badgeContent.style('border-style', contrastBorderColor ? 'solid' : null); - this.$badgeContent.style('border-width', contrastBorderColor ? '1px' : null); - this.$badgeContent.style('border-color', contrastBorderColor ? contrastBorderColor.toString() : null); + this.$badgeContent.style.borderStyle = contrastBorderColor ? 'solid' : null; + this.$badgeContent.style.borderWidth = contrastBorderColor ? '1px' : null; + this.$badgeContent.style.borderColor = contrastBorderColor ? contrastBorderColor.toString() : null; } } render(container: HTMLElement): void { super.render(container); + this.$container = container; + // Make the container tab-able for keyboard navigation - this.$container = $(container).attr({ - tabIndex: '0', - role: 'button' - }); + this.$container.tabIndex = 0; + this.$container.setAttribute('role', 'button'); // Try hard to prevent keyboard only focus feedback when using mouse - this.$container.on(dom.EventType.MOUSE_DOWN, () => { - this.$container.addClass('clicked'); - }); + this.callOnDispose.push(dom.addDisposableListener(this.$container, dom.EventType.MOUSE_DOWN, () => { + dom.addClass(this.$container, 'clicked'); + })); - this.$container.on(dom.EventType.MOUSE_UP, () => { + this.callOnDispose.push(dom.addDisposableListener(this.$container, dom.EventType.MOUSE_UP, () => { if (this.mouseUpTimeout) { clearTimeout(this.mouseUpTimeout); } this.mouseUpTimeout = setTimeout(() => { - this.$container.removeClass('clicked'); + dom.removeClass(this.$container, 'clicked'); }, 800); // delayed to prevent focus feedback from showing on mouse up - }); + })); // Label - this.$label = $('a.action-label').appendTo(this.builder); + this.$label = dom.append(this.builder, dom.$('a.action-label')); - this.$badge = this.builder.clone().div({ 'class': 'badge' }, badge => { - this.$badgeContent = badge.div({ 'class': 'badge-content' }); - }); - this.$badge.hide(); + // Badge + this.$badge = dom.append(this.builder, dom.$('.badge')); + this.$badgeContent = dom.append(this.$badge, dom.$('.badge-content')); + + dom.hide(this.$badge); this.updateActivity(); this.updateStyles(); @@ -232,8 +233,8 @@ export class ActivityActionItem extends BaseActionItem { this.badgeDisposable.dispose(); this.badgeDisposable = Disposable.None; - this.$badgeContent.empty(); - this.$badge.hide(); + dom.clearNode(this.$badgeContent); + dom.hide(this.$badge); if (badge) { @@ -246,30 +247,30 @@ export class ActivityActionItem extends BaseActionItem { } else if (badge.number > 999) { number = number.charAt(0) + 'k'; } - this.$badgeContent.text(number); - this.$badge.show(); + this.$badgeContent.textContent = number; + dom.show(this.$badge); } } // Text else if (badge instanceof TextBadge) { - this.$badgeContent.text(badge.text); - this.$badge.show(); + this.$badgeContent.textContent = badge.text; + dom.show(this.$badge); } // Text else if (badge instanceof IconBadge) { - this.$badge.show(); + dom.show(this.$badge); } // Progress else if (badge instanceof ProgressBadge) { - this.$badge.show(); + dom.show(this.$badge); } if (clazz) { - this.$badge.addClass(clazz); - this.badgeDisposable = toDisposable(() => this.$badge.removeClass(clazz)); + dom.addClasses(this.$badge, clazz); + this.badgeDisposable = toDisposable(() => dom.removeClasses(this.$badge, clazz)); } } @@ -289,18 +290,18 @@ export class ActivityActionItem extends BaseActionItem { private updateLabel(): void { if (this.activity.cssClass) { - this.$label.addClass(this.activity.cssClass); + dom.addClasses(this.$label, this.activity.cssClass); } if (!this.options.icon) { - this.$label.text(this.getAction().label); + this.$label.textContent = this.getAction().label; } } private updateTitle(title: string): void { - [this.$label, this.$badge, this.$container].forEach(b => { - if (b) { - b.attr('aria-label', title); - b.title(title); + [this.$label, this.$badge, this.$container].forEach(element => { + if (element) { + element.setAttribute('aria-label', title); + element.title = title; } }); } @@ -312,7 +313,7 @@ export class ActivityActionItem extends BaseActionItem { clearTimeout(this.mouseUpTimeout); } - this.$badge.destroy(); + dom.removeNode(this.$badge); } } @@ -359,7 +360,7 @@ export class CompositeOverflowActivityActionItem extends ActivityActionItem { this.actions = this.getActions(); this.contextMenuService.showContextMenu({ - getAnchor: () => this.builder.getHTMLElement(), + getAnchor: () => this.builder, getActions: () => TPromise.as(this.actions), onHide: () => dispose(this.actions) }); @@ -408,13 +409,21 @@ class ManageExtensionAction extends Action { } } +export class DraggedCompositeIdentifier { + constructor(private _compositeId: string) { } + + get id(): string { + return this._compositeId; + } +} + export class CompositeActionItem extends ActivityActionItem { private static manageExtensionAction: ManageExtensionAction; - private static draggedCompositeId: string; private compositeActivity: IActivity; private cssClass: string; + private compositeTransfer: LocalSelectionTransfer<DraggedCompositeIdentifier>; constructor( private compositeActivityAction: ActivityAction, @@ -430,6 +439,7 @@ export class CompositeActionItem extends ActivityActionItem { super(compositeActivityAction, { draggable: true, colors, icon }, themeService); this.cssClass = compositeActivityAction.class; + this.compositeTransfer = LocalSelectionTransfer.getInstance<DraggedCompositeIdentifier>(); if (!CompositeActionItem.manageExtensionAction) { CompositeActionItem.manageExtensionAction = instantiationService.createInstance(ManageExtensionAction); @@ -473,71 +483,64 @@ export class CompositeActionItem extends ActivityActionItem { this._updateChecked(); this._updateEnabled(); - this.$container.on('contextmenu', e => { + this.callOnDispose.push(dom.addDisposableListener(this.$container, dom.EventType.CONTEXT_MENU, e => { dom.EventHelper.stop(e, true); this.showContextMenu(container); - }); + })); // Allow to drag - this.$container.on(dom.EventType.DRAG_START, (e: DragEvent) => { + this.callOnDispose.push(dom.addDisposableListener(this.$container, dom.EventType.DRAG_START, (e: DragEvent) => { e.dataTransfer.effectAllowed = 'move'; - this.setDraggedComposite(this.activity.id); + + // Registe as dragged to local transfer + this.compositeTransfer.setData([new DraggedCompositeIdentifier(this.activity.id)], DraggedCompositeIdentifier.prototype); // Trigger the action even on drag start to prevent clicks from failing that started a drag if (!this.getAction().checked) { this.getAction().run(); } - }); + })); - // Drag enter - let counter = 0; // see https://github.com/Microsoft/vscode/issues/14470 - this.$container.on(dom.EventType.DRAG_ENTER, (e: DragEvent) => { - const draggedCompositeId = CompositeActionItem.getDraggedCompositeId(); - if (draggedCompositeId && draggedCompositeId !== this.activity.id) { - counter++; - this.updateFromDragging(container, true); - } - }); + this.callOnDispose.push(new DragAndDropObserver(this.$container, { + onDragEnter: e => { + if (this.compositeTransfer.hasData(DraggedCompositeIdentifier.prototype) && this.compositeTransfer.getData(DraggedCompositeIdentifier.prototype)[0].id !== this.activity.id) { + this.updateFromDragging(container, true); + } + }, - // Drag leave - this.$container.on(dom.EventType.DRAG_LEAVE, (e: DragEvent) => { - const draggedCompositeId = CompositeActionItem.getDraggedCompositeId(); - if (draggedCompositeId) { - counter--; - if (counter === 0) { + onDragLeave: e => { + if (this.compositeTransfer.hasData(DraggedCompositeIdentifier.prototype)) { this.updateFromDragging(container, false); } + }, + + onDragEnd: e => { + if (this.compositeTransfer.hasData(DraggedCompositeIdentifier.prototype)) { + this.updateFromDragging(container, false); + + this.compositeTransfer.clearData(DraggedCompositeIdentifier.prototype); + } + }, + + onDrop: e => { + dom.EventHelper.stop(e, true); + + if (this.compositeTransfer.hasData(DraggedCompositeIdentifier.prototype)) { + const draggedCompositeId = this.compositeTransfer.getData(DraggedCompositeIdentifier.prototype)[0].id; + if (draggedCompositeId !== this.activity.id) { + this.updateFromDragging(container, false); + this.compositeTransfer.clearData(DraggedCompositeIdentifier.prototype); + + this.compositeBar.move(draggedCompositeId, this.activity.id); + } + } } - }); - - // Drag end - this.$container.on(dom.EventType.DRAG_END, (e: DragEvent) => { - const draggedCompositeId = CompositeActionItem.getDraggedCompositeId(); - if (draggedCompositeId) { - counter = 0; - this.updateFromDragging(container, false); - - CompositeActionItem.clearDraggedComposite(); - } - }); - - // Drop - this.$container.on(dom.EventType.DROP, (e: DragEvent) => { - dom.EventHelper.stop(e, true); - - const draggedCompositeId = CompositeActionItem.getDraggedCompositeId(); - if (draggedCompositeId && draggedCompositeId !== this.activity.id) { - this.updateFromDragging(container, false); - CompositeActionItem.clearDraggedComposite(); - - this.compositeBar.move(draggedCompositeId, this.activity.id); - } - }); + })); // Activate on drag over to reveal targets - [this.$badge, this.$label].forEach(b => new DelayedDragHandler(b.getHTMLElement(), () => { - if (!CompositeActionItem.getDraggedCompositeId() && !this.getAction().checked) { + [this.$badge, this.$label].forEach(b => new DelayedDragHandler(b, () => { + if (!this.compositeTransfer.hasData(DraggedCompositeIdentifier.prototype) && !this.getAction().checked) { this.getAction().run(); } })); @@ -552,18 +555,6 @@ export class CompositeActionItem extends ActivityActionItem { element.style.backgroundColor = isDragging && dragBackground ? dragBackground.toString() : null; } - static getDraggedCompositeId(): string { - return CompositeActionItem.draggedCompositeId; - } - - private setDraggedComposite(compositeId: string): void { - CompositeActionItem.draggedCompositeId = compositeId; - } - - static clearDraggedComposite(): void { - CompositeActionItem.draggedCompositeId = void 0; - } - private showContextMenu(container: HTMLElement): void { const actions: Action[] = [this.toggleCompositePinnedAction]; if ((<any>this.compositeActivityAction.activity).extensionId) { @@ -587,44 +578,44 @@ export class CompositeActionItem extends ActivityActionItem { } focus(): void { - this.$container.domFocus(); + this.$container.focus(); } protected _updateClass(): void { if (this.cssClass) { - this.$label.removeClass(this.cssClass); + dom.removeClasses(this.$label, this.cssClass); } this.cssClass = this.getAction().class; if (this.cssClass) { - this.$label.addClass(this.cssClass); + dom.addClasses(this.$label, this.cssClass); } } protected _updateChecked(): void { if (this.getAction().checked) { - this.$container.addClass('checked'); - this.$container.attr('aria-label', nls.localize('compositeActive', "{0} active", this.$container.getHTMLElement().title)); + dom.addClass(this.$container, 'checked'); + this.$container.setAttribute('aria-label', nls.localize('compositeActive', "{0} active", this.$container.title)); } else { - this.$container.removeClass('checked'); - this.$container.attr('aria-label', this.$container.getHTMLElement().title); + dom.removeClass(this.$container, 'checked'); + this.$container.setAttribute('aria-label', this.$container.title); } } protected _updateEnabled(): void { if (this.getAction().enabled) { - this.builder.removeClass('disabled'); + dom.removeClass(this.builder, 'disabled'); } else { - this.builder.addClass('disabled'); + dom.addClass(this.builder, 'disabled'); } } dispose(): void { super.dispose(); - CompositeActionItem.clearDraggedComposite(); + this.compositeTransfer.clearData(DraggedCompositeIdentifier.prototype); - this.$label.destroy(); + dom.removeNode(this.$label); } } diff --git a/src/vs/workbench/browser/parts/compositePart.ts b/src/vs/workbench/browser/parts/compositePart.ts index 52578559e00..70b3371097b 100644 --- a/src/vs/workbench/browser/parts/compositePart.ts +++ b/src/vs/workbench/browser/parts/compositePart.ts @@ -10,7 +10,6 @@ import * as nls from 'vs/nls'; import { defaultGenerator } from 'vs/base/common/idGenerator'; import { TPromise } from 'vs/base/common/winjs.base'; import { IDisposable, dispose } from 'vs/base/common/lifecycle'; -import { Builder, $ } from 'vs/base/browser/builder'; import * as strings from 'vs/base/common/strings'; import { Emitter } from 'vs/base/common/event'; import * as types from 'vs/base/common/types'; @@ -35,7 +34,7 @@ import { IKeybindingService } from 'vs/platform/keybinding/common/keybinding'; import { IThemeService } from 'vs/platform/theme/common/themeService'; import { attachProgressBarStyler } from 'vs/platform/theme/common/styler'; import { INotificationService } from 'vs/platform/notification/common/notification'; -import { Dimension } from 'vs/base/browser/dom'; +import { Dimension, append, $, addClass, hide, removeNode, show, addClasses } from 'vs/base/browser/dom'; export interface ICompositeTitleLabel { @@ -58,7 +57,7 @@ export abstract class CompositePart<T extends Composite> extends Part { protected toolBar: ToolBar; private instantiatedCompositeListeners: IDisposable[]; - private mapCompositeToCompositeContainer: { [compositeId: string]: Builder; }; + private mapCompositeToCompositeContainer: { [compositeId: string]: HTMLElement; }; private mapActionsBindingToComposite: { [compositeId: string]: () => void; }; private mapProgressServiceToComposite: { [compositeId: string]: IProgressService; }; private activeComposite: Composite; @@ -222,13 +221,12 @@ export abstract class CompositePart<T extends Composite> extends Part { if (!compositeContainer) { // Build Container off-DOM - compositeContainer = $().div({ - 'class': ['composite', this.compositeCSSClass], - id: composite.getId() - }, div => { - createCompositePromise = composite.create(div.getHTMLElement()).then(() => { - composite.updateStyles(); - }); + compositeContainer = $('.composite'); + addClasses(compositeContainer, this.compositeCSSClass); + compositeContainer.id = composite.getId(); + + createCompositePromise = composite.create(compositeContainer).then(() => { + composite.updateStyles(); }); // Remember composite container @@ -255,8 +253,8 @@ export abstract class CompositePart<T extends Composite> extends Part { } // Take Composite on-DOM and show - compositeContainer.build(this.getContentArea()); - compositeContainer.show(); + this.getContentArea().appendChild(compositeContainer); + show(compositeContainer); // Setup action runner this.toolBar.actionRunner = composite.getActionRunner(); @@ -389,8 +387,8 @@ export abstract class CompositePart<T extends Composite> extends Part { return composite.setVisible(false).then(() => { // Take Container Off-DOM and hide - compositeContainer.offDOM(); - compositeContainer.hide(); + removeNode(compositeContainer); + hide(compositeContainer); // Clear any running Progress this.progressBar.stop().hide(); @@ -406,45 +404,38 @@ export abstract class CompositePart<T extends Composite> extends Part { createTitleArea(parent: HTMLElement): HTMLElement { // Title Area Container - const titleArea = $(parent).div({ - 'class': ['composite', 'title'] - }); + const titleArea = append(parent, $('.composite')); + addClass(titleArea, 'title'); // Left Title Label - this.titleLabel = this.createTitleLabel(titleArea.getHTMLElement()); + this.titleLabel = this.createTitleLabel(titleArea); // Right Actions Container - $(titleArea).div({ - 'class': 'title-actions' - }, div => { + const titleActionsContainer = append(titleArea, $('.title-actions')); - // Toolbar - this.toolBar = this._register(new ToolBar(div.getHTMLElement(), this.contextMenuService, { - actionItemProvider: action => this.actionItemProvider(action as Action), - orientation: ActionsOrientation.HORIZONTAL, - getKeyBinding: action => this.keybindingService.lookupKeybinding(action.id) - })); - }); + // Toolbar + this.toolBar = this._register(new ToolBar(titleActionsContainer, this.contextMenuService, { + actionItemProvider: action => this.actionItemProvider(action as Action), + orientation: ActionsOrientation.HORIZONTAL, + getKeyBinding: action => this.keybindingService.lookupKeybinding(action.id) + })); - return titleArea.getHTMLElement(); + return titleArea; } protected createTitleLabel(parent: HTMLElement): ICompositeTitleLabel { - let titleLabel: Builder; - $(parent).div({ - 'class': 'title-label' - }, div => { - titleLabel = div.element('h2'); - }); + const titleContainer = append(parent, $('.title-label')); + const titleLabel = append(titleContainer, $('h2')); const $this = this; return { updateTitle: (id, title, keybinding) => { - titleLabel.safeInnerHtml(title); - titleLabel.title(keybinding ? nls.localize('titleTooltip', "{0} ({1})", title, keybinding) : title); + titleLabel.innerHTML = strings.escape(title); + titleLabel.title = keybinding ? nls.localize('titleTooltip', "{0} ({1})", title, keybinding) : title; }, + updateStyles: () => { - titleLabel.style('color', $this.getColor($this.titleForegroundColor)); + titleLabel.style.color = $this.getColor($this.titleForegroundColor); } }; } @@ -467,13 +458,13 @@ export abstract class CompositePart<T extends Composite> extends Part { } createContentArea(parent: HTMLElement): HTMLElement { - return $(parent).div({ - 'class': 'content' - }, div => { - this.progressBar = this._register(new ProgressBar(div.getHTMLElement())); - this._register(attachProgressBarStyler(this.progressBar, this.themeService)); - this.progressBar.hide(); - }).getHTMLElement(); + const contentContainer = append(parent, $('.content')); + + this.progressBar = this._register(new ProgressBar(contentContainer)); + this._register(attachProgressBarStyler(this.progressBar, this.themeService)); + this.progressBar.hide(); + + return contentContainer; } private onError(error: any): void { diff --git a/src/vs/workbench/browser/parts/statusbar/statusbarPart.ts b/src/vs/workbench/browser/parts/statusbar/statusbarPart.ts index d0c0302f07c..baccf0bc4f9 100644 --- a/src/vs/workbench/browser/parts/statusbar/statusbarPart.ts +++ b/src/vs/workbench/browser/parts/statusbar/statusbarPart.ts @@ -10,7 +10,6 @@ import * as nls from 'vs/nls'; import { toErrorMessage } from 'vs/base/common/errorMessage'; import { TPromise } from 'vs/base/common/winjs.base'; import { dispose, IDisposable, toDisposable } from 'vs/base/common/lifecycle'; -import { $ } from 'vs/base/browser/builder'; import { OcticonLabel } from 'vs/base/browser/ui/octiconLabel/octiconLabel'; import { Registry } from 'vs/platform/registry/common/platform'; import { ICommandService } from 'vs/platform/commands/common/commands'; @@ -28,15 +27,15 @@ import { IWorkspaceContextService, WorkbenchState } from 'vs/platform/workspace/ import { contrastBorder } from 'vs/platform/theme/common/colorRegistry'; import { isThemeColor } from 'vs/editor/common/editorCommon'; import { Color } from 'vs/base/common/color'; -import { addClass, EventHelper, createStyleSheet } from 'vs/base/browser/dom'; +import { addClass, EventHelper, createStyleSheet, addDisposableListener, removeNode } from 'vs/base/browser/dom'; import { INotificationService } from 'vs/platform/notification/common/notification'; export class StatusbarPart extends Part implements IStatusbarService { _serviceBrand: any; - private static readonly PRIORITY_PROP = 'priority'; - private static readonly ALIGNMENT_PROP = 'alignment'; + private static readonly PRIORITY_PROP = 'statusbar-entry-priority'; + private static readonly ALIGNMENT_PROP = 'statusbar-entry-alignment'; private statusItemsContainer: HTMLElement; private statusMsgDispose: IDisposable; @@ -71,7 +70,7 @@ export class StatusbarPart extends Part implements IStatusbarService { let inserted = false; for (let i = 0; i < neighbours.length; i++) { const neighbour = neighbours[i]; - const nPriority = $(neighbour).getProperty(StatusbarPart.PRIORITY_PROP); + const nPriority = Number(neighbour.getAttribute(StatusbarPart.PRIORITY_PROP)); if ( alignment === StatusbarAlignment.LEFT && nPriority < priority || alignment === StatusbarAlignment.RIGHT && nPriority > priority @@ -87,7 +86,7 @@ export class StatusbarPart extends Part implements IStatusbarService { } return toDisposable(() => { - $(el).destroy(); + removeNode(el); if (toDispose) { toDispose.dispose(); @@ -102,7 +101,7 @@ export class StatusbarPart extends Part implements IStatusbarService { const children = container.children; for (let i = 0; i < children.length; i++) { const childElement = <HTMLElement>children.item(i); - if ($(childElement).getProperty(StatusbarPart.ALIGNMENT_PROP) === alignment) { + if (Number(childElement.getAttribute(StatusbarPart.ALIGNMENT_PROP)) === alignment) { entries.push(childElement); } } @@ -168,8 +167,8 @@ export class StatusbarPart extends Part implements IStatusbarService { addClass(el, 'left'); } - $(el).setProperty(StatusbarPart.PRIORITY_PROP, priority); - $(el).setProperty(StatusbarPart.ALIGNMENT_PROP, alignment); + el.setAttribute(StatusbarPart.PRIORITY_PROP, String(priority)); + el.setAttribute(StatusbarPart.ALIGNMENT_PROP, String(alignment)); return el; } @@ -242,7 +241,7 @@ class StatusBarEntryItem implements IStatusbarItem { if (this.entry.command) { textContainer = document.createElement('a'); - $(textContainer).on('click', () => this.executeCommand(this.entry.command, this.entry.arguments), toDispose); + toDispose.push(addDisposableListener(textContainer, 'click', () => this.executeCommand(this.entry.command, this.entry.arguments))); } else { textContainer = document.createElement('span'); } @@ -252,7 +251,7 @@ class StatusBarEntryItem implements IStatusbarItem { // Tooltip if (this.entry.tooltip) { - $(textContainer).title(this.entry.tooltip); + textContainer.title = this.entry.tooltip; } // Color @@ -263,15 +262,15 @@ class StatusBarEntryItem implements IStatusbarItem { color = (this.themeService.getTheme().getColor(colorId) || Color.transparent).toString(); toDispose.push(this.themeService.onThemeChange(theme => { let colorValue = (this.themeService.getTheme().getColor(colorId) || Color.transparent).toString(); - $(textContainer).color(colorValue); + textContainer.style.color = colorValue; })); } - $(textContainer).color(color); + textContainer.style.color = color; } // Context Menu if (this.entry.extensionId) { - $(textContainer).on('contextmenu', e => { + toDispose.push(addDisposableListener(textContainer, 'contextmenu', e => { EventHelper.stop(e, true); this.contextMenuService.showContextMenu({ @@ -279,7 +278,7 @@ class StatusBarEntryItem implements IStatusbarItem { getActionsContext: () => this.entry.extensionId, getActions: () => TPromise.as([manageExtensionAction]) }); - }, toDispose); + })); } el.appendChild(textContainer); diff --git a/src/vs/workbench/parts/extensions/electron-browser/extensionsActions.ts b/src/vs/workbench/parts/extensions/electron-browser/extensionsActions.ts index 753719af952..1bf667f3452 100644 --- a/src/vs/workbench/parts/extensions/electron-browser/extensionsActions.ts +++ b/src/vs/workbench/parts/extensions/electron-browser/extensionsActions.ts @@ -377,7 +377,7 @@ export class DropDownMenuActionItem extends ActionItem { public showMenu(): void { const actions = this.getActions(); - let elementPosition = DOM.getDomNodePagePosition(this.builder.getHTMLElement()); + let elementPosition = DOM.getDomNodePagePosition(this.builder); const anchor = { x: elementPosition.left, y: elementPosition.top + elementPosition.height + 10 }; this.contextMenuService.showContextMenu({ getAnchor: () => anchor, diff --git a/src/vs/workbench/parts/markers/electron-browser/markersPanelActions.ts b/src/vs/workbench/parts/markers/electron-browser/markersPanelActions.ts index d20ed821f30..f351fb2a143 100644 --- a/src/vs/workbench/parts/markers/electron-browser/markersPanelActions.ts +++ b/src/vs/workbench/parts/markers/electron-browser/markersPanelActions.ts @@ -354,7 +354,7 @@ export class QuickFixActionItem extends ActionItem { public onClick(event: DOM.EventLike): void { DOM.EventHelper.stop(event, true); - const elementPosition = DOM.getDomNodePagePosition(this.builder.getHTMLElement()); + const elementPosition = DOM.getDomNodePagePosition(this.builder); this.contextMenuService.showContextMenu({ getAnchor: () => ({ x: elementPosition.left + 10, y: elementPosition.top + elementPosition.height }), getActions: () => TPromise.wrap((<QuickFixAction>this.getAction()).getQuickFixActions()), diff --git a/src/vs/workbench/parts/preferences/browser/preferencesWidgets.ts b/src/vs/workbench/parts/preferences/browser/preferencesWidgets.ts index 3c57b2f5fcb..725a95e7de2 100644 --- a/src/vs/workbench/parts/preferences/browser/preferencesWidgets.ts +++ b/src/vs/workbench/parts/preferences/browser/preferencesWidgets.ts @@ -5,7 +5,6 @@ import { localize } from 'vs/nls'; import URI from 'vs/base/common/uri'; -import { $ } from 'vs/base/browser/builder'; import * as DOM from 'vs/base/browser/dom'; import { TPromise } from 'vs/base/common/winjs.base'; import { Disposable, IDisposable, dispose } from 'vs/base/common/lifecycle'; @@ -318,7 +317,7 @@ export class FolderSettingsActionItem extends BaseActionItem { } public render(container: HTMLElement): void { - this.builder = $(container); + this.builder = container; this.container = container; this.labelElement = DOM.$('.action-title'); diff --git a/src/vs/workbench/parts/scm/electron-browser/scmViewlet.ts b/src/vs/workbench/parts/scm/electron-browser/scmViewlet.ts index 4a9da7a25f7..d4ffc1ea54e 100644 --- a/src/vs/workbench/parts/scm/electron-browser/scmViewlet.ts +++ b/src/vs/workbench/parts/scm/electron-browser/scmViewlet.ts @@ -109,7 +109,7 @@ class StatusBarActionItem extends ActionItem { _updateLabel(): void { if (this.options.label) { - this.$e.innerHtml(renderOcticons(this.getAction().label)); + this.$e.innerHTML = renderOcticons(this.getAction().label); } } } diff --git a/src/vs/workbench/test/browser/part.test.ts b/src/vs/workbench/test/browser/part.test.ts index 22c8a969e55..c4a78a473c6 100644 --- a/src/vs/workbench/test/browser/part.test.ts +++ b/src/vs/workbench/test/browser/part.test.ts @@ -6,13 +6,13 @@ 'use strict'; import * as assert from 'assert'; -import { Builder, $ } from 'vs/base/browser/builder'; import { Part } from 'vs/workbench/browser/part'; import * as Types from 'vs/base/common/types'; import { IStorageService } from 'vs/platform/storage/common/storage'; import { StorageService, InMemoryLocalStorage } from 'vs/platform/storage/common/storageService'; import { TestThemeService } from 'vs/platform/theme/test/common/testThemeService'; import { TestWorkspace } from 'vs/platform/workspace/test/common/testWorkspace'; +import { append, $, hide } from 'vs/base/browser/dom'; class MyPart extends Part { @@ -42,21 +42,21 @@ class MyPart2 extends Part { } public createTitleArea(parent: HTMLElement): HTMLElement { - return $(parent).div(function (div) { - div.span({ - id: 'myPart.title', - innerHtml: 'Title' - }); - }).getHTMLElement(); + const titleContainer = append(parent, $('div')); + const titleLabel = append(titleContainer, $('span')); + titleLabel.id = 'myPart.title'; + titleLabel.innerHTML = 'Title'; + + return titleContainer; } public createContentArea(parent: HTMLElement): HTMLElement { - return $(parent).div(function (div) { - div.span({ - id: 'myPart.content', - innerHtml: 'Content' - }); - }).getHTMLElement(); + const contentContainer = append(parent, $('div')); + const contentSpan = append(contentContainer, $('span')); + contentSpan.id = 'myPart.content'; + contentSpan.innerHTML = 'Content'; + + return contentContainer; } } @@ -71,12 +71,12 @@ class MyPart3 extends Part { } public createContentArea(parent: HTMLElement): HTMLElement { - return $(parent).div(function (div) { - div.span({ - id: 'myPart.content', - innerHtml: 'Content' - }); - }).getHTMLElement(); + const contentContainer = append(parent, $('div')); + const contentSpan = append(contentContainer, $('span')); + contentSpan.id = 'myPart.content'; + contentSpan.innerHTML = 'Content'; + + return contentContainer; } } @@ -97,11 +97,12 @@ suite('Workbench parts', () => { }); test('Creation', function () { - let b = new Builder(document.getElementById(fixtureId)); - b.div().hide(); + let b = document.createElement('div'); + document.getElementById(fixtureId).appendChild(b); + hide(b); - let part = new MyPart(b.getHTMLElement()); - part.create(b.getHTMLElement()); + let part = new MyPart(b); + part.create(b); assert.strictEqual(part.getId(), 'myPart'); @@ -114,7 +115,7 @@ suite('Workbench parts', () => { part.shutdown(); // Re-Create to assert memento contents - part = new MyPart(b.getHTMLElement()); + part = new MyPart(b); memento = part.getMemento(storage); assert(memento); @@ -126,29 +127,31 @@ suite('Workbench parts', () => { delete memento.bar; part.shutdown(); - part = new MyPart(b.getHTMLElement()); + part = new MyPart(b); memento = part.getMemento(storage); assert(memento); assert.strictEqual(Types.isEmptyObject(memento), true); }); test('Part Layout with Title and Content', function () { - let b = new Builder(document.getElementById(fixtureId)); - b.div().hide(); + let b = document.createElement('div'); + document.getElementById(fixtureId).appendChild(b); + hide(b); let part = new MyPart2(); - part.create(b.getHTMLElement()); + part.create(b); assert(document.getElementById('myPart.title')); assert(document.getElementById('myPart.content')); }); test('Part Layout with Content only', function () { - let b = new Builder(document.getElementById(fixtureId)); - b.div().hide(); + let b = document.createElement('div'); + document.getElementById(fixtureId).appendChild(b); + hide(b); let part = new MyPart3(); - part.create(b.getHTMLElement()); + part.create(b); assert(!document.getElementById('myPart.title')); assert(document.getElementById('myPart.content')); From dbd3e70395ca1e1bf2890949856f03f108860e44 Mon Sep 17 00:00:00 2001 From: Benjamin Pasero <benjpas@microsoft.com> Date: Mon, 27 Aug 2018 07:35:28 +0200 Subject: [PATCH 1262/1276] debt - more builder cleanup --- src/vs/base/browser/touch.ts | 17 ++- src/vs/base/browser/ui/actionbar/actionbar.ts | 140 ++++++++---------- src/vs/base/browser/ui/button/button.ts | 70 ++++----- .../browser/ui/contextview/contextview.ts | 73 +++++---- src/vs/base/browser/ui/dropdown/dropdown.ts | 56 +++---- src/vs/base/browser/ui/menu/menu.ts | 24 +-- .../actions/browser/menuItemActionItem.ts | 14 +- .../contextview/browser/contextMenuHandler.ts | 14 +- .../parts/activitybar/activitybarActions.ts | 8 +- .../browser/parts/compositeBarActions.ts | 114 +++++++------- .../notifications/notificationsCenter.ts | 4 +- .../notifications/notificationsViewer.ts | 4 +- src/vs/workbench/common/resources.ts | 14 +- .../electron-browser/extensionsActions.ts | 2 +- .../electron-browser/markersPanelActions.ts | 19 +-- .../preferences/browser/preferencesWidgets.ts | 2 +- .../parts/scm/electron-browser/scmViewlet.ts | 2 +- 17 files changed, 276 insertions(+), 301 deletions(-) diff --git a/src/vs/base/browser/touch.ts b/src/vs/base/browser/touch.ts index 5620c65ccb6..7dac4446b02 100644 --- a/src/vs/base/browser/touch.ts +++ b/src/vs/base/browser/touch.ts @@ -5,7 +5,7 @@ 'use strict'; import * as arrays from 'vs/base/common/arrays'; -import { IDisposable, dispose } from 'vs/base/common/lifecycle'; +import { IDisposable, Disposable } from 'vs/base/common/lifecycle'; import * as DomUtils from 'vs/base/browser/dom'; import { memoize } from 'vs/base/common/decorators'; @@ -64,7 +64,7 @@ interface TouchEvent extends Event { changedTouches: TouchList; } -export class Gesture implements IDisposable { +export class Gesture extends Disposable { private static readonly SCROLL_FRICTION = -0.005; private static INSTANCE: Gesture; @@ -72,19 +72,19 @@ export class Gesture implements IDisposable { private dispatched: boolean; private targets: HTMLElement[]; - private toDispose: IDisposable[]; private handle: IDisposable; private activeTouches: { [id: number]: TouchData; }; private constructor() { - this.toDispose = []; + super(); + this.activeTouches = {}; this.handle = null; this.targets = []; - this.toDispose.push(DomUtils.addDisposableListener(document, 'touchstart', (e) => this.onTouchStart(e))); - this.toDispose.push(DomUtils.addDisposableListener(document, 'touchend', (e) => this.onTouchEnd(e))); - this.toDispose.push(DomUtils.addDisposableListener(document, 'touchmove', (e) => this.onTouchMove(e))); + this._register(DomUtils.addDisposableListener(document, 'touchstart', (e) => this.onTouchStart(e))); + this._register(DomUtils.addDisposableListener(document, 'touchend', (e) => this.onTouchEnd(e))); + this._register(DomUtils.addDisposableListener(document, 'touchmove', (e) => this.onTouchMove(e))); } public static addTarget(element: HTMLElement): void { @@ -106,9 +106,10 @@ export class Gesture implements IDisposable { public dispose(): void { if (this.handle) { this.handle.dispose(); - dispose(this.toDispose); this.handle = null; } + + super.dispose(); } private onTouchStart(e: TouchEvent): void { diff --git a/src/vs/base/browser/ui/actionbar/actionbar.ts b/src/vs/base/browser/ui/actionbar/actionbar.ts index 05e61cae92a..8898840ba5e 100644 --- a/src/vs/base/browser/ui/actionbar/actionbar.ts +++ b/src/vs/base/browser/ui/actionbar/actionbar.ts @@ -35,23 +35,23 @@ export interface IBaseActionItemOptions { isMenu?: boolean; } -export class BaseActionItem implements IActionItem { +export class BaseActionItem extends lifecycle.Disposable implements IActionItem { - public builder: HTMLElement; - public _callOnDispose: lifecycle.IDisposable[]; + public element: HTMLElement; public _context: any; public _action: IAction; private _actionRunner: IActionRunner; constructor(context: any, action: IAction, protected options?: IBaseActionItemOptions) { - this._callOnDispose = []; + super(); + this._context = context || this; this._action = action; if (action instanceof Action) { - this._callOnDispose.push(action.onDidChange(event => { - if (!this.builder) { + this._register(action.onDidChange(event => { + if (!this.element) { // we have not been rendered yet, so there // is no point in updating the UI return; @@ -80,10 +80,6 @@ export class BaseActionItem implements IActionItem { } } - public get callOnDispose() { - return this._callOnDispose; - } - public set actionRunner(actionRunner: IActionRunner) { this._actionRunner = actionRunner; } @@ -105,7 +101,7 @@ export class BaseActionItem implements IActionItem { } public render(container: HTMLElement): void { - this.builder = container; + this.element = container; Gesture.addTarget(container); const enableDragging = this.options && this.options.draggable; @@ -113,20 +109,20 @@ export class BaseActionItem implements IActionItem { container.draggable = true; } - this._callOnDispose.push(DOM.addDisposableListener(this.builder, EventType.Tap, e => this.onClick(e))); + this._register(DOM.addDisposableListener(this.element, EventType.Tap, e => this.onClick(e))); - this._callOnDispose.push(DOM.addDisposableListener(this.builder, DOM.EventType.MOUSE_DOWN, e => { + this._register(DOM.addDisposableListener(this.element, DOM.EventType.MOUSE_DOWN, e => { if (!enableDragging) { DOM.EventHelper.stop(e, true); // do not run when dragging is on because that would disable it } const mouseEvent = e as MouseEvent; if (this._action.enabled && mouseEvent.button === 0) { - DOM.addClass(this.builder, 'active'); + DOM.addClass(this.element, 'active'); } })); - this._callOnDispose.push(DOM.addDisposableListener(this.builder, DOM.EventType.CLICK, e => { + this._register(DOM.addDisposableListener(this.element, DOM.EventType.CLICK, e => { DOM.EventHelper.stop(e, true); // See https://developer.mozilla.org/en-US/Add-ons/WebExtensions/Interact_with_the_clipboard // > Writing to the clipboard @@ -144,9 +140,9 @@ export class BaseActionItem implements IActionItem { })); [DOM.EventType.MOUSE_UP, DOM.EventType.MOUSE_OUT].forEach(event => { - this._callOnDispose.push(DOM.addDisposableListener(this.builder, event, e => { + this._register(DOM.addDisposableListener(this.element, event, e => { DOM.EventHelper.stop(e); - DOM.removeClass(this.builder, 'active'); + DOM.removeClass(this.element, 'active'); })); }); } @@ -169,16 +165,16 @@ export class BaseActionItem implements IActionItem { } public focus(): void { - if (this.builder) { - this.builder.focus(); - DOM.addClass(this.builder, 'focused'); + if (this.element) { + this.element.focus(); + DOM.addClass(this.element, 'focused'); } } public blur(): void { - if (this.builder) { - this.builder.blur(); - DOM.removeClass(this.builder, 'focused'); + if (this.element) { + this.element.blur(); + DOM.removeClass(this.element, 'focused'); } } @@ -203,12 +199,12 @@ export class BaseActionItem implements IActionItem { } public dispose(): void { - if (this.builder) { - DOM.removeNode(this.builder); - this.builder = null; + if (this.element) { + DOM.removeNode(this.element); + this.element = null; } - this._callOnDispose = lifecycle.dispose(this._callOnDispose); + super.dispose(); } } @@ -233,8 +229,9 @@ export interface IActionItemOptions extends IBaseActionItemOptions { export class ActionItem extends BaseActionItem { - protected $e: HTMLElement; + protected label: HTMLElement; protected options: IActionItemOptions; + private cssClass: string; constructor(context: any, action: IAction, options: IActionItemOptions = {}) { @@ -249,20 +246,20 @@ export class ActionItem extends BaseActionItem { public render(container: HTMLElement): void { super.render(container); - this.$e = DOM.append(this.builder, DOM.$('a.action-label')); + this.label = DOM.append(this.element, DOM.$('a.action-label')); if (this._action.id === Separator.ID) { // A separator is a presentation item - this.$e.setAttribute('role', 'presentation'); + this.label.setAttribute('role', 'presentation'); } else { if (this.options.isMenu) { - this.$e.setAttribute('role', 'menuitem'); + this.label.setAttribute('role', 'menuitem'); } else { - this.$e.setAttribute('role', 'button'); + this.label.setAttribute('role', 'button'); } } if (this.options.label && this.options.keybinding) { - DOM.append(this.builder, DOM.$('span.keybinding')).textContent = this.options.keybinding; + DOM.append(this.element, DOM.$('span.keybinding')).textContent = this.options.keybinding; } this._updateClass(); @@ -274,12 +271,12 @@ export class ActionItem extends BaseActionItem { public focus(): void { super.focus(); - this.$e.focus(); + this.label.focus(); } public _updateLabel(): void { if (this.options.label) { - this.$e.textContent = this.getAction().label; + this.label.textContent = this.getAction().label; } } @@ -298,43 +295,43 @@ export class ActionItem extends BaseActionItem { } if (title) { - this.$e.title = title; + this.label.title = title; } } public _updateClass(): void { if (this.cssClass) { - DOM.removeClasses(this.$e, this.cssClass); + DOM.removeClasses(this.label, this.cssClass); } if (this.options.icon) { this.cssClass = this.getAction().class; - DOM.addClass(this.$e, 'icon'); + DOM.addClass(this.label, 'icon'); if (this.cssClass) { - DOM.addClasses(this.$e, this.cssClass); + DOM.addClasses(this.label, this.cssClass); } this._updateEnabled(); } else { - DOM.removeClass(this.$e, 'icon'); + DOM.removeClass(this.label, 'icon'); } } public _updateEnabled(): void { if (this.getAction().enabled) { - DOM.removeClass(this.builder, 'disabled'); - DOM.removeClass(this.$e, 'disabled'); - this.$e.tabIndex = 0; + DOM.removeClass(this.element, 'disabled'); + DOM.removeClass(this.label, 'disabled'); + this.label.tabIndex = 0; } else { - DOM.addClass(this.builder, 'disabled'); - DOM.addClass(this.$e, 'disabled'); - DOM.removeTabIndexAndUpdateFocus(this.$e); + DOM.addClass(this.element, 'disabled'); + DOM.addClass(this.label, 'disabled'); + DOM.removeTabIndexAndUpdateFocus(this.label); } } public _updateChecked(): void { if (this.getAction().checked) { - DOM.addClass(this.$e, 'checked'); + DOM.addClass(this.label, 'checked'); } else { - DOM.removeClass(this.$e, 'checked'); + DOM.removeClass(this.label, 'checked'); } } } @@ -368,7 +365,7 @@ export interface IActionOptions extends IActionItemOptions { index?: number; } -export class ActionBar implements IActionRunner { +export class ActionBar extends lifecycle.Disposable implements IActionRunner { public options: IActionBarOptions; @@ -384,26 +381,25 @@ export class ActionBar implements IActionRunner { public domNode: HTMLElement; protected actionsList: HTMLElement; - private toDispose: lifecycle.IDisposable[]; - private _onDidBlur = new Emitter<void>(); private _onDidCancel = new Emitter<void>(); private _onDidRun = new Emitter<IRunEvent>(); private _onDidBeforeRun = new Emitter<IRunEvent>(); constructor(container: HTMLElement, options: IActionBarOptions = defaultOptions) { + super(); + this.options = options; this._context = options.context; - this.toDispose = []; this._actionRunner = this.options.actionRunner; if (!this._actionRunner) { this._actionRunner = new ActionRunner(); - this.toDispose.push(this._actionRunner); + this._register(this._actionRunner); } - this.toDispose.push(this._actionRunner.onDidRun(e => this._onDidRun.fire(e))); - this.toDispose.push(this._actionRunner.onDidBeforeRun(e => this._onDidBeforeRun.fire(e))); + this._register(this._actionRunner.onDidRun(e => this._onDidRun.fire(e))); + this._register(this._actionRunner.onDidBeforeRun(e => this._onDidBeforeRun.fire(e))); this.items = []; this.focusedItem = undefined; @@ -440,7 +436,7 @@ export class ActionBar implements IActionRunner { break; } - this.toDispose.push(DOM.addDisposableListener(this.domNode, DOM.EventType.KEY_DOWN, e => { + this._register(DOM.addDisposableListener(this.domNode, DOM.EventType.KEY_DOWN, e => { let event = new StandardKeyboardEvent(e as KeyboardEvent); let eventHandled = true; @@ -462,7 +458,7 @@ export class ActionBar implements IActionRunner { } })); - this.toDispose.push(DOM.addDisposableListener(this.domNode, DOM.EventType.KEY_UP, e => { + this._register(DOM.addDisposableListener(this.domNode, DOM.EventType.KEY_UP, e => { let event = new StandardKeyboardEvent(e as KeyboardEvent); // Run action on Enter/Space @@ -478,15 +474,15 @@ export class ActionBar implements IActionRunner { } })); - this.focusTracker = DOM.trackFocus(this.domNode); - this.toDispose.push(this.focusTracker.onDidBlur(() => { + this.focusTracker = this._register(DOM.trackFocus(this.domNode)); + this._register(this.focusTracker.onDidBlur(() => { if (document.activeElement === this.domNode || !DOM.isAncestor(document.activeElement, this.domNode)) { this._onDidBlur.fire(); this.focusedItem = undefined; } })); - this.toDispose.push(this.focusTracker.onDidFocus(() => this.updateFocusedItem())); + this._register(this.focusTracker.onDidFocus(() => this.updateFocusedItem())); this.actionsList = document.createElement('ul'); this.actionsList.className = 'actions-container'; @@ -571,7 +567,7 @@ export class ActionBar implements IActionRunner { actionItemElement.setAttribute('role', 'presentation'); // Prevent native context menu on actions - this.toDispose.push(DOM.addDisposableListener(actionItemElement, DOM.EventType.CONTEXT_MENU, (e: DOM.EventLike) => { + this._register(DOM.addDisposableListener(actionItemElement, DOM.EventType.CONTEXT_MENU, (e: DOM.EventLike) => { e.preventDefault(); e.stopPropagation(); })); @@ -750,28 +746,22 @@ export class ActionBar implements IActionRunner { } this.items = null; - if (this.focusTracker) { - this.focusTracker.dispose(); - this.focusTracker = null; - } - - this.toDispose = lifecycle.dispose(this.toDispose); - DOM.removeNode(this.getContainer()); + + super.dispose(); } } export class SelectActionItem extends BaseActionItem { protected selectBox: SelectBox; - protected toDispose: lifecycle.IDisposable[]; constructor(ctx: any, action: IAction, options: string[], selected: number, contextViewProvider: IContextViewProvider, selectBoxOptions?: ISelectBoxOptions ) { super(ctx, action); + this.selectBox = new SelectBox(options, selected, contextViewProvider, null, selectBoxOptions); - this.toDispose = []; - this.toDispose.push(this.selectBox); + this._register(this.selectBox); this.registerListeners(); } @@ -784,7 +774,7 @@ export class SelectActionItem extends BaseActionItem { } private registerListeners(): void { - this.toDispose.push(this.selectBox.onDidSelect(e => { + this._register(this.selectBox.onDidSelect(e => { this.actionRunner.run(this._action, this.getActionContext(e.selected)).done(); })); } @@ -808,10 +798,4 @@ export class SelectActionItem extends BaseActionItem { public render(container: HTMLElement): void { this.selectBox.render(container); } - - public dispose(): void { - this.toDispose = lifecycle.dispose(this.toDispose); - - super.dispose(); - } } \ No newline at end of file diff --git a/src/vs/base/browser/ui/button/button.ts b/src/vs/base/browser/ui/button/button.ts index 0ac9201ce67..5bee0452536 100644 --- a/src/vs/base/browser/ui/button/button.ts +++ b/src/vs/base/browser/ui/button/button.ts @@ -34,7 +34,7 @@ const defaultOptions: IButtonStyles = { export class Button extends Disposable { - private $el: HTMLElement; + private _element: HTMLElement; private options: IButtonOptions; private buttonBackground: Color; @@ -58,16 +58,16 @@ export class Button extends Disposable { this.buttonForeground = this.options.buttonForeground; this.buttonBorder = this.options.buttonBorder; - this.$el = document.createElement('a'); - DOM.addClass(this.$el, 'monaco-button'); - this.$el.tabIndex = 0; - this.$el.setAttribute('role', 'button'); + this._element = document.createElement('a'); + DOM.addClass(this._element, 'monaco-button'); + this._element.tabIndex = 0; + this._element.setAttribute('role', 'button'); - container.appendChild(this.$el); + container.appendChild(this._element); - Gesture.addTarget(this.$el); + Gesture.addTarget(this._element); - this._register(DOM.addDisposableListener(this.$el, DOM.EventType.CLICK, e => { + this._register(DOM.addDisposableListener(this._element, DOM.EventType.CLICK, e => { if (!this.enabled) { DOM.EventHelper.stop(e); return; @@ -76,14 +76,14 @@ export class Button extends Disposable { this._onDidClick.fire(e); })); - this._register(DOM.addDisposableListener(this.$el, DOM.EventType.KEY_DOWN, e => { + this._register(DOM.addDisposableListener(this._element, DOM.EventType.KEY_DOWN, e => { const event = new StandardKeyboardEvent(e as KeyboardEvent); let eventHandled = false; if (this.enabled && event.equals(KeyCode.Enter) || event.equals(KeyCode.Space)) { this._onDidClick.fire(e); eventHandled = true; } else if (event.equals(KeyCode.Escape)) { - this.$el.blur(); + this._element.blur(); eventHandled = true; } @@ -92,18 +92,18 @@ export class Button extends Disposable { } })); - this._register(DOM.addDisposableListener(this.$el, DOM.EventType.MOUSE_OVER, e => { - if (!DOM.hasClass(this.$el, 'disabled')) { + this._register(DOM.addDisposableListener(this._element, DOM.EventType.MOUSE_OVER, e => { + if (!DOM.hasClass(this._element, 'disabled')) { this.setHoverBackground(); } })); - this._register(DOM.addDisposableListener(this.$el, DOM.EventType.MOUSE_OUT, e => { + this._register(DOM.addDisposableListener(this._element, DOM.EventType.MOUSE_OUT, e => { this.applyStyles(); // restore standard styles })); // Also set hover background when button is focused for feedback - this.focusTracker = this._register(DOM.trackFocus(this.$el)); + this.focusTracker = this._register(DOM.trackFocus(this._element)); this._register(this.focusTracker.onDidFocus(() => this.setHoverBackground())); this._register(this.focusTracker.onDidBlur(() => this.applyStyles())); // restore standard styles @@ -113,7 +113,7 @@ export class Button extends Disposable { private setHoverBackground(): void { const hoverBackground = this.buttonHoverBackground ? this.buttonHoverBackground.toString() : null; if (hoverBackground) { - this.$el.style.backgroundColor = hoverBackground; + this._element.style.backgroundColor = hoverBackground; } } @@ -127,56 +127,56 @@ export class Button extends Disposable { } private applyStyles(): void { - if (this.$el) { + if (this._element) { const background = this.buttonBackground ? this.buttonBackground.toString() : null; const foreground = this.buttonForeground ? this.buttonForeground.toString() : null; const border = this.buttonBorder ? this.buttonBorder.toString() : null; - this.$el.style.color = foreground; - this.$el.style.backgroundColor = background; + this._element.style.color = foreground; + this._element.style.backgroundColor = background; - this.$el.style.borderWidth = border ? '1px' : null; - this.$el.style.borderStyle = border ? 'solid' : null; - this.$el.style.borderColor = border; + this._element.style.borderWidth = border ? '1px' : null; + this._element.style.borderStyle = border ? 'solid' : null; + this._element.style.borderColor = border; } } get element(): HTMLElement { - return this.$el; + return this._element; } set label(value: string) { - if (!DOM.hasClass(this.$el, 'monaco-text-button')) { - DOM.addClass(this.$el, 'monaco-text-button'); + if (!DOM.hasClass(this._element, 'monaco-text-button')) { + DOM.addClass(this._element, 'monaco-text-button'); } - this.$el.innerText = value; + this._element.textContent = value; if (this.options.title) { - this.$el.title = value; + this._element.title = value; } } set icon(iconClassName: string) { - DOM.addClass(this.$el, iconClassName); + DOM.addClass(this._element, iconClassName); } set enabled(value: boolean) { if (value) { - DOM.removeClass(this.$el, 'disabled'); - this.$el.setAttribute('aria-disabled', String(false)); - this.$el.tabIndex = 0; + DOM.removeClass(this._element, 'disabled'); + this._element.setAttribute('aria-disabled', String(false)); + this._element.tabIndex = 0; } else { - DOM.addClass(this.$el, 'disabled'); - this.$el.setAttribute('aria-disabled', String(true)); - DOM.removeTabIndexAndUpdateFocus(this.$el); + DOM.addClass(this._element, 'disabled'); + this._element.setAttribute('aria-disabled', String(true)); + DOM.removeTabIndexAndUpdateFocus(this._element); } } get enabled() { - return !DOM.hasClass(this.$el, 'disabled'); + return !DOM.hasClass(this._element, 'disabled'); } focus(): void { - this.$el.focus(); + this._element.focus(); } } diff --git a/src/vs/base/browser/ui/contextview/contextview.ts b/src/vs/base/browser/ui/contextview/contextview.ts index 15ad50296cb..1b6b190e533 100644 --- a/src/vs/base/browser/ui/contextview/contextview.ts +++ b/src/vs/base/browser/ui/contextview/contextview.ts @@ -7,7 +7,7 @@ import 'vs/css!./contextview'; import * as DOM from 'vs/base/browser/dom'; -import { IDisposable, dispose, toDisposable, combinedDisposable } from 'vs/base/common/lifecycle'; +import { IDisposable, dispose, toDisposable, combinedDisposable, Disposable } from 'vs/base/common/lifecycle'; export interface IAnchor { x: number; @@ -95,55 +95,54 @@ export function layout(viewportSize: number, viewSize: number, anchor: ILayoutAn } } -export class ContextView { +export class ContextView extends Disposable { private static readonly BUBBLE_UP_EVENTS = ['click', 'keydown', 'focus', 'blur']; private static readonly BUBBLE_DOWN_EVENTS = ['click']; - private $container: HTMLElement; - private $view: HTMLElement; + private container: HTMLElement; + private view: HTMLElement; private delegate: IDelegate; - private toDispose: IDisposable[]; private toDisposeOnClean: IDisposable; private toDisposeOnSetContainer: IDisposable; constructor(container: HTMLElement) { - this.$view = DOM.$('.context-view'); + super(); - DOM.hide(this.$view); + this.view = DOM.$('.context-view'); + + DOM.hide(this.view); this.setContainer(container); - this.toDispose = [toDisposable(() => { - this.setContainer(null); - })]; + this._register(toDisposable(() => this.setContainer(null))); } public setContainer(container: HTMLElement): void { - if (this.$container) { + if (this.container) { this.toDisposeOnSetContainer = dispose(this.toDisposeOnSetContainer); - this.$container.removeChild(this.$view); - this.$container = null; + this.container.removeChild(this.view); + this.container = null; } if (container) { - this.$container = container; - this.$container.appendChild(this.$view); + this.container = container; + this.container.appendChild(this.view); - const toDispose: IDisposable[] = []; + const toDisposeOnSetContainer: IDisposable[] = []; ContextView.BUBBLE_UP_EVENTS.forEach(event => { - toDispose.push(DOM.addStandardDisposableListener(this.$container, event, (e: Event) => { + toDisposeOnSetContainer.push(DOM.addStandardDisposableListener(this.container, event, (e: Event) => { this.onDOMEvent(e, <HTMLElement>document.activeElement, false); })); }); ContextView.BUBBLE_DOWN_EVENTS.forEach(event => { - toDispose.push(DOM.addStandardDisposableListener(this.$container, event, (e: Event) => { + toDisposeOnSetContainer.push(DOM.addStandardDisposableListener(this.container, event, (e: Event) => { this.onDOMEvent(e, <HTMLElement>document.activeElement, true); }, true)); }); - this.toDisposeOnSetContainer = combinedDisposable(toDispose); + this.toDisposeOnSetContainer = combinedDisposable(toDisposeOnSetContainer); } } @@ -153,14 +152,14 @@ export class ContextView { } // Show static box - DOM.clearNode(this.$view); - this.$view.className = 'context-view'; - this.$view.style.top = '0px'; - this.$view.style.left = '0px'; - DOM.show(this.$view); + DOM.clearNode(this.view); + this.view.className = 'context-view'; + this.view.style.top = '0px'; + this.view.style.left = '0px'; + DOM.show(this.view); // Render content - this.toDisposeOnClean = delegate.render(this.$view); + this.toDisposeOnClean = delegate.render(this.view); // Set active delegate this.delegate = delegate; @@ -219,8 +218,8 @@ export class ContextView { }; } - const viewSizeWidth = DOM.getTotalWidth(this.$view); - const viewSizeHeight = DOM.getTotalHeight(this.$view); + const viewSizeWidth = DOM.getTotalWidth(this.view); + const viewSizeHeight = DOM.getTotalHeight(this.view); const anchorPosition = this.delegate.anchorPosition || AnchorPosition.BELOW; const anchorAlignment = this.delegate.anchorAlignment || AnchorAlignment.LEFT; @@ -235,17 +234,17 @@ export class ContextView { horizontalAnchor = { offset: around.left + around.width, size: 0, position: LayoutAnchorPosition.After }; } - const containerPosition = DOM.getDomNodePagePosition(this.$container); + const containerPosition = DOM.getDomNodePagePosition(this.container); const top = layout(window.innerHeight, viewSizeHeight, verticalAnchor) - containerPosition.top; const left = layout(window.innerWidth, viewSizeWidth, horizontalAnchor) - containerPosition.left; - DOM.removeClasses(this.$view, 'top', 'bottom', 'left', 'right'); - DOM.addClass(this.$view, anchorPosition === AnchorPosition.BELOW ? 'bottom' : 'top'); - DOM.addClass(this.$view, anchorAlignment === AnchorAlignment.LEFT ? 'left' : 'right'); + DOM.removeClasses(this.view, 'top', 'bottom', 'left', 'right'); + DOM.addClass(this.view, anchorPosition === AnchorPosition.BELOW ? 'bottom' : 'top'); + DOM.addClass(this.view, anchorAlignment === AnchorAlignment.LEFT ? 'left' : 'right'); - this.$view.style.top = `${top}px`; - this.$view.style.left = `${left}px`; - this.$view.style.width = 'initial'; + this.view.style.top = `${top}px`; + this.view.style.left = `${left}px`; + this.view.style.width = 'initial'; } public hide(data?: any): void { @@ -260,7 +259,7 @@ export class ContextView { this.toDisposeOnClean = null; } - DOM.hide(this.$view); + DOM.hide(this.view); } private isVisible(): boolean { @@ -271,7 +270,7 @@ export class ContextView { if (this.delegate) { if (this.delegate.onDOMEvent) { this.delegate.onDOMEvent(e, <HTMLElement>document.activeElement); - } else if (onCapture && !DOM.isAncestor(<HTMLElement>e.target, this.$container)) { + } else if (onCapture && !DOM.isAncestor(<HTMLElement>e.target, this.container)) { this.hide(); } } @@ -280,6 +279,6 @@ export class ContextView { public dispose(): void { this.hide(); - this.toDispose = dispose(this.toDispose); + super.dispose(); } } \ No newline at end of file diff --git a/src/vs/base/browser/ui/dropdown/dropdown.ts b/src/vs/base/browser/ui/dropdown/dropdown.ts index a2fd1d60735..3035fa9f768 100644 --- a/src/vs/base/browser/ui/dropdown/dropdown.ts +++ b/src/vs/base/browser/ui/dropdown/dropdown.ts @@ -29,18 +29,18 @@ export interface IBaseDropdownOptions { export class BaseDropdown extends ActionRunner { private _toDispose: IDisposable[] = []; - private $el: HTMLElement; - private $boxContainer: HTMLElement; - private $label: HTMLElement; - private $contents: HTMLElement; + private _element: HTMLElement; + private boxContainer: HTMLElement; + private _label: HTMLElement; + private contents: HTMLElement; private visible: boolean; constructor(container: HTMLElement, options: IBaseDropdownOptions) { super(); - this.$el = append(container, $('.monaco-dropdown')); + this._element = append(container, $('.monaco-dropdown')); - this.$label = append(this.$el, $('.dropdown-label')); + this._label = append(this._element, $('.dropdown-label')); let labelRenderer = options.labelRenderer; if (!labelRenderer) { @@ -52,11 +52,11 @@ export class BaseDropdown extends ActionRunner { } [EventType.CLICK, EventType.MOUSE_DOWN, GestureEventType.Tap].forEach(event => { - this._toDispose.push(addDisposableListener(this.$label, event, e => EventHelper.stop(e, true))); // prevent default click behaviour to trigger + this._toDispose.push(addDisposableListener(this._label, event, e => EventHelper.stop(e, true))); // prevent default click behaviour to trigger }); [EventType.MOUSE_DOWN, GestureEventType.Tap].forEach(event => { - this._toDispose.push(addDisposableListener(this.$label, event, e => { + this._toDispose.push(addDisposableListener(this._label, event, e => { if (e instanceof MouseEvent && e.detail > 1) { return; // prevent multiple clicks to open multiple context menus (https://github.com/Microsoft/vscode/issues/41363) } @@ -69,12 +69,12 @@ export class BaseDropdown extends ActionRunner { })); }); - const cleanupFn = labelRenderer(this.$label); + const cleanupFn = labelRenderer(this._label); if (cleanupFn) { this._toDispose.push(cleanupFn); } - Gesture.addTarget(this.$label); + Gesture.addTarget(this._label); } get toDispose(): IDisposable[] { @@ -82,15 +82,15 @@ export class BaseDropdown extends ActionRunner { } get element(): HTMLElement { - return this.$el; + return this._element; } get label(): HTMLElement { - return this.$label; + return this._label; } set tooltip(tooltip: string) { - this.$label.title = tooltip; + this._label.title = tooltip; } show(): void { @@ -111,19 +111,19 @@ export class BaseDropdown extends ActionRunner { this._toDispose = dispose(this.toDispose); - if (this.$boxContainer) { - removeNode(this.$boxContainer); - this.$boxContainer = null; + if (this.boxContainer) { + removeNode(this.boxContainer); + this.boxContainer = null; } - if (this.$contents) { - removeNode(this.$contents); - this.$contents = null; + if (this.contents) { + removeNode(this.contents); + this.contents = null; } - if (this.$label) { - removeNode(this.$label); - this.$label = null; + if (this._label) { + removeNode(this._label); + this._label = null; } } } @@ -283,13 +283,13 @@ export class DropdownMenuActionItem extends BaseActionItem { render(container: HTMLElement): void { const labelRenderer: ILabelRenderer = (el: HTMLElement): IDisposable => { - this.builder = append(el, $('a.action-label')); - addClasses(this.builder, this.clazz); + this.element = append(el, $('a.action-label')); + addClasses(this.element, this.clazz); - this.builder.tabIndex = 0; - this.builder.setAttribute('role', 'button'); - this.builder.setAttribute('aria-haspopup', 'true'); - this.builder.title = this._action.label || ''; + this.element.tabIndex = 0; + this.element.setAttribute('role', 'button'); + this.element.setAttribute('aria-haspopup', 'true'); + this.element.title = this._action.label || ''; return null; }; diff --git a/src/vs/base/browser/ui/menu/menu.ts b/src/vs/base/browser/ui/menu/menu.ts index a2d946073e1..4be890a1a1a 100644 --- a/src/vs/base/browser/ui/menu/menu.ts +++ b/src/vs/base/browser/ui/menu/menu.ts @@ -245,7 +245,7 @@ class MenuActionItem extends BaseActionItem { this.container = container; - this.$e = $('a.action-menu-item').appendTo(this.builder); + this.$e = $('a.action-menu-item').appendTo(this.element); if (this._action.id === Separator.ID) { // A separator is a presentation item this.$e.attr({ role: 'presentation' }); @@ -335,11 +335,11 @@ class MenuActionItem extends BaseActionItem { _updateEnabled(): void { if (this.getAction().enabled) { - removeClass(this.builder, 'disabled'); + removeClass(this.element, 'disabled'); this.$e.removeClass('disabled'); this.$e.attr({ tabindex: 0 }); } else { - addClass(this.builder, 'disabled'); + addClass(this.element, 'disabled'); this.$e.addClass('disabled'); removeTabIndexAndUpdateFocus(this.$e.getHTMLElement()); } @@ -383,7 +383,7 @@ class SubmenuActionItem extends MenuActionItem { }, 250); this.hideScheduler = new RunOnceScheduler(() => { - if ((!isAncestor(document.activeElement, this.builder) && this.parentData.submenu === this.mysubmenu)) { + if ((!isAncestor(document.activeElement, this.element) && this.parentData.submenu === this.mysubmenu)) { this.parentData.parent.focus(false); this.cleanupExistingSubmenu(true); } @@ -397,7 +397,7 @@ class SubmenuActionItem extends MenuActionItem { this.$e.attr('aria-haspopup', 'true'); $('span.submenu-indicator').attr('aria-hidden', 'true').text('\u25B6').appendTo(this.$e); - $(this.builder).on(EventType.KEY_UP, (e) => { + $(this.element).on(EventType.KEY_UP, (e) => { let event = new StandardKeyboardEvent(e as KeyboardEvent); if (event.equals(KeyCode.RightArrow) || event.equals(KeyCode.Enter)) { EventHelper.stop(e, true); @@ -406,14 +406,14 @@ class SubmenuActionItem extends MenuActionItem { } }); - $(this.builder).on(EventType.KEY_DOWN, (e) => { + $(this.element).on(EventType.KEY_DOWN, (e) => { let event = new StandardKeyboardEvent(e as KeyboardEvent); if (event.equals(KeyCode.RightArrow) || event.equals(KeyCode.Enter)) { EventHelper.stop(e, true); } }); - $(this.builder).on(EventType.MOUSE_OVER, (e) => { + $(this.element).on(EventType.MOUSE_OVER, (e) => { if (!this.mouseOver) { this.mouseOver = true; @@ -421,12 +421,12 @@ class SubmenuActionItem extends MenuActionItem { } }); - $(this.builder).on(EventType.MOUSE_LEAVE, (e) => { + $(this.element).on(EventType.MOUSE_LEAVE, (e) => { this.mouseOver = false; }); - $(this.builder).on(EventType.FOCUS_OUT, (e) => { - if (!isAncestor(document.activeElement, this.builder)) { + $(this.element).on(EventType.FOCUS_OUT, (e) => { + if (!isAncestor(document.activeElement, this.element)) { this.hideScheduler.schedule(); } }); @@ -454,10 +454,10 @@ class SubmenuActionItem extends MenuActionItem { private createSubmenu(selectFirstItem = true) { if (!this.parentData.submenu) { - this.submenuContainer = $(this.builder).div({ class: 'monaco-submenu menubar-menu-items-holder context-view' }); + this.submenuContainer = $(this.element).div({ class: 'monaco-submenu menubar-menu-items-holder context-view' }); $(this.submenuContainer).style({ - 'left': `${$(this.builder).getClientArea().width}px` + 'left': `${$(this.element).getClientArea().width}px` }); $(this.submenuContainer).on(EventType.KEY_UP, (e) => { diff --git a/src/vs/platform/actions/browser/menuItemActionItem.ts b/src/vs/platform/actions/browser/menuItemActionItem.ts index 20de6c969d2..85d70509ab6 100644 --- a/src/vs/platform/actions/browser/menuItemActionItem.ts +++ b/src/vs/platform/actions/browser/menuItemActionItem.ts @@ -199,17 +199,17 @@ export class MenuItemActionItem extends ActionItem { } }; - this._callOnDispose.push(alternativeKeyEmitter.event(value => { + this._register(alternativeKeyEmitter.event(value => { alternativeKeyDown = value; updateAltState(); })); - this._callOnDispose.push(domEvent(container, 'mouseleave')(_ => { + this._register(domEvent(container, 'mouseleave')(_ => { mouseOver = false; updateAltState(); })); - this._callOnDispose.push(domEvent(container, 'mouseenter')(e => { + this._register(domEvent(container, 'mouseenter')(e => { mouseOver = true; updateAltState(); })); @@ -217,12 +217,12 @@ export class MenuItemActionItem extends ActionItem { _updateLabel(): void { if (this.options.label) { - this.$e.textContent = this._commandAction.label; + this.label.textContent = this._commandAction.label; } } _updateTooltip(): void { - const element = this.$e; + const element = this.label; const keybinding = this._keybindingService.lookupKeybinding(this._commandAction.id); const keybindingLabel = keybinding && keybinding.getLabel(); @@ -259,8 +259,8 @@ export class MenuItemActionItem extends ActionItem { MenuItemActionItem.ICON_PATH_TO_CSS_RULES.set(iconPathMapKey, iconClass); } - addClasses(this.$e, 'icon', iconClass); - this._itemClassDispose = toDisposable(() => removeClasses(this.$e, 'icon', iconClass)); + addClasses(this.label, 'icon', iconClass); + this._itemClassDispose = toDisposable(() => removeClasses(this.label, 'icon', iconClass)); } } diff --git a/src/vs/platform/contextview/browser/contextMenuHandler.ts b/src/vs/platform/contextview/browser/contextMenuHandler.ts index d1db0a1a2d4..b39ec136593 100644 --- a/src/vs/platform/contextview/browser/contextMenuHandler.ts +++ b/src/vs/platform/contextview/browser/contextMenuHandler.ts @@ -23,8 +23,8 @@ export class ContextMenuHandler { private notificationService: INotificationService; private telemetryService: ITelemetryService; - private $el: HTMLElement; - private $elDisposable: IDisposable; + private element: HTMLElement; + private elementDisposable: IDisposable; private menuContainerElement: HTMLElement; private focusToReturn: HTMLElement; @@ -39,13 +39,13 @@ export class ContextMenuHandler { } public setContainer(container: HTMLElement): void { - if (this.$el) { - this.$elDisposable = dispose(this.$elDisposable); - this.$el = null; + if (this.element) { + this.elementDisposable = dispose(this.elementDisposable); + this.element = null; } if (container) { - this.$el = container; - this.$elDisposable = addDisposableListener(this.$el, 'mousedown', (e) => this.onMouseDown(e as MouseEvent)); + this.element = container; + this.elementDisposable = addDisposableListener(this.element, 'mousedown', (e) => this.onMouseDown(e as MouseEvent)); } } diff --git a/src/vs/workbench/browser/parts/activitybar/activitybarActions.ts b/src/vs/workbench/browser/parts/activitybar/activitybarActions.ts index da7c06bd2d9..005e8bfdd3e 100644 --- a/src/vs/workbench/browser/parts/activitybar/activitybarActions.ts +++ b/src/vs/workbench/browser/parts/activitybar/activitybarActions.ts @@ -123,23 +123,23 @@ export class GlobalActivityActionItem extends ActivityActionItem { // Context menus are triggered on mouse down so that an item can be picked // and executed with releasing the mouse over it - this.callOnDispose.push(DOM.addDisposableListener(this.$container, DOM.EventType.MOUSE_DOWN, (e: MouseEvent) => { + this._register(DOM.addDisposableListener(this.container, DOM.EventType.MOUSE_DOWN, (e: MouseEvent) => { DOM.EventHelper.stop(e, true); const event = new StandardMouseEvent(e); this.showContextMenu({ x: event.posx, y: event.posy }); })); - this.callOnDispose.push(DOM.addDisposableListener(this.$container, DOM.EventType.KEY_UP, (e: KeyboardEvent) => { + this._register(DOM.addDisposableListener(this.container, DOM.EventType.KEY_UP, (e: KeyboardEvent) => { let event = new StandardKeyboardEvent(e); if (event.equals(KeyCode.Enter) || event.equals(KeyCode.Space)) { DOM.EventHelper.stop(e, true); - this.showContextMenu(this.$container); + this.showContextMenu(this.container); } })); - this.callOnDispose.push(DOM.addDisposableListener(this.$container, TouchEventType.Tap, (e: GestureEvent) => { + this._register(DOM.addDisposableListener(this.container, TouchEventType.Tap, (e: GestureEvent) => { DOM.EventHelper.stop(e, true); const event = new StandardMouseEvent(e); diff --git a/src/vs/workbench/browser/parts/compositeBarActions.ts b/src/vs/workbench/browser/parts/compositeBarActions.ts index 3b275abc9cd..59d52a54eb3 100644 --- a/src/vs/workbench/browser/parts/compositeBarActions.ts +++ b/src/vs/workbench/browser/parts/compositeBarActions.ts @@ -124,12 +124,12 @@ export interface IActivityActionItemOptions extends IBaseActionItemOptions { } export class ActivityActionItem extends BaseActionItem { - protected $container: HTMLElement; - protected $label: HTMLElement; - protected $badge: HTMLElement; + protected container: HTMLElement; + protected label: HTMLElement; + protected badge: HTMLElement; protected options: IActivityActionItemOptions; - private $badgeContent: HTMLElement; + private badgeContent: HTMLElement; private badgeDisposable: IDisposable = Disposable.None; private mouseUpTimeout: number; @@ -140,9 +140,9 @@ export class ActivityActionItem extends BaseActionItem { ) { super(null, action, options); - this.themeService.onThemeChange(this.onThemeChange, this, this._callOnDispose); - action.onDidChangeActivity(this.updateActivity, this, this._callOnDispose); - action.onDidChangeBadge(this.updateBadge, this, this._callOnDispose); + this._register(this.themeService.onThemeChange(this.onThemeChange, this)); + this._register(action.onDidChangeActivity(this.updateActivity, this)); + this._register(action.onDidChangeBadge(this.updateBadge, this)); } protected get activity(): IActivity { @@ -153,59 +153,59 @@ export class ActivityActionItem extends BaseActionItem { const theme = this.themeService.getTheme(); // Label - if (this.$label && this.options.icon) { + if (this.label && this.options.icon) { const background = theme.getColor(this.options.colors.backgroundColor); - this.$label.style.backgroundColor = background ? background.toString() : null; + this.label.style.backgroundColor = background ? background.toString() : null; } // Badge - if (this.$badgeContent) { + if (this.badgeContent) { const badgeForeground = theme.getColor(this.options.colors.badgeForeground); const badgeBackground = theme.getColor(this.options.colors.badgeBackground); const contrastBorderColor = theme.getColor(contrastBorder); - this.$badgeContent.style.color = badgeForeground ? badgeForeground.toString() : null; - this.$badgeContent.style.backgroundColor = badgeBackground ? badgeBackground.toString() : null; + this.badgeContent.style.color = badgeForeground ? badgeForeground.toString() : null; + this.badgeContent.style.backgroundColor = badgeBackground ? badgeBackground.toString() : null; - this.$badgeContent.style.borderStyle = contrastBorderColor ? 'solid' : null; - this.$badgeContent.style.borderWidth = contrastBorderColor ? '1px' : null; - this.$badgeContent.style.borderColor = contrastBorderColor ? contrastBorderColor.toString() : null; + this.badgeContent.style.borderStyle = contrastBorderColor ? 'solid' : null; + this.badgeContent.style.borderWidth = contrastBorderColor ? '1px' : null; + this.badgeContent.style.borderColor = contrastBorderColor ? contrastBorderColor.toString() : null; } } render(container: HTMLElement): void { super.render(container); - this.$container = container; + this.container = container; // Make the container tab-able for keyboard navigation - this.$container.tabIndex = 0; - this.$container.setAttribute('role', 'button'); + this.container.tabIndex = 0; + this.container.setAttribute('role', 'button'); // Try hard to prevent keyboard only focus feedback when using mouse - this.callOnDispose.push(dom.addDisposableListener(this.$container, dom.EventType.MOUSE_DOWN, () => { - dom.addClass(this.$container, 'clicked'); + this._register(dom.addDisposableListener(this.container, dom.EventType.MOUSE_DOWN, () => { + dom.addClass(this.container, 'clicked'); })); - this.callOnDispose.push(dom.addDisposableListener(this.$container, dom.EventType.MOUSE_UP, () => { + this._register(dom.addDisposableListener(this.container, dom.EventType.MOUSE_UP, () => { if (this.mouseUpTimeout) { clearTimeout(this.mouseUpTimeout); } this.mouseUpTimeout = setTimeout(() => { - dom.removeClass(this.$container, 'clicked'); + dom.removeClass(this.container, 'clicked'); }, 800); // delayed to prevent focus feedback from showing on mouse up })); // Label - this.$label = dom.append(this.builder, dom.$('a.action-label')); + this.label = dom.append(this.element, dom.$('a.action-label')); // Badge - this.$badge = dom.append(this.builder, dom.$('.badge')); - this.$badgeContent = dom.append(this.$badge, dom.$('.badge-content')); + this.badge = dom.append(this.element, dom.$('.badge')); + this.badgeContent = dom.append(this.badge, dom.$('.badge-content')); - dom.hide(this.$badge); + dom.hide(this.badge); this.updateActivity(); this.updateStyles(); @@ -223,7 +223,7 @@ export class ActivityActionItem extends BaseActionItem { protected updateBadge(): void { const action = this.getAction(); - if (!this.$badge || !this.$badgeContent || !(action instanceof ActivityAction)) { + if (!this.badge || !this.badgeContent || !(action instanceof ActivityAction)) { return; } @@ -233,8 +233,8 @@ export class ActivityActionItem extends BaseActionItem { this.badgeDisposable.dispose(); this.badgeDisposable = Disposable.None; - dom.clearNode(this.$badgeContent); - dom.hide(this.$badge); + dom.clearNode(this.badgeContent); + dom.hide(this.badge); if (badge) { @@ -247,30 +247,30 @@ export class ActivityActionItem extends BaseActionItem { } else if (badge.number > 999) { number = number.charAt(0) + 'k'; } - this.$badgeContent.textContent = number; - dom.show(this.$badge); + this.badgeContent.textContent = number; + dom.show(this.badge); } } // Text else if (badge instanceof TextBadge) { - this.$badgeContent.textContent = badge.text; - dom.show(this.$badge); + this.badgeContent.textContent = badge.text; + dom.show(this.badge); } // Text else if (badge instanceof IconBadge) { - dom.show(this.$badge); + dom.show(this.badge); } // Progress else if (badge instanceof ProgressBadge) { - dom.show(this.$badge); + dom.show(this.badge); } if (clazz) { - dom.addClasses(this.$badge, clazz); - this.badgeDisposable = toDisposable(() => dom.removeClasses(this.$badge, clazz)); + dom.addClasses(this.badge, clazz); + this.badgeDisposable = toDisposable(() => dom.removeClasses(this.badge, clazz)); } } @@ -290,15 +290,15 @@ export class ActivityActionItem extends BaseActionItem { private updateLabel(): void { if (this.activity.cssClass) { - dom.addClasses(this.$label, this.activity.cssClass); + dom.addClasses(this.label, this.activity.cssClass); } if (!this.options.icon) { - this.$label.textContent = this.getAction().label; + this.label.textContent = this.getAction().label; } } private updateTitle(title: string): void { - [this.$label, this.$badge, this.$container].forEach(element => { + [this.label, this.badge, this.container].forEach(element => { if (element) { element.setAttribute('aria-label', title); element.title = title; @@ -313,7 +313,7 @@ export class ActivityActionItem extends BaseActionItem { clearTimeout(this.mouseUpTimeout); } - dom.removeNode(this.$badge); + dom.removeNode(this.badge); } } @@ -360,7 +360,7 @@ export class CompositeOverflowActivityActionItem extends ActivityActionItem { this.actions = this.getActions(); this.contextMenuService.showContextMenu({ - getAnchor: () => this.builder, + getAnchor: () => this.element, getActions: () => TPromise.as(this.actions), onHide: () => dispose(this.actions) }); @@ -445,7 +445,7 @@ export class CompositeActionItem extends ActivityActionItem { CompositeActionItem.manageExtensionAction = instantiationService.createInstance(ManageExtensionAction); } - compositeActivityAction.onDidChangeActivity(() => { this.compositeActivity = null; this.updateActivity(); }, this, this._callOnDispose); + this._register(compositeActivityAction.onDidChangeActivity(() => { this.compositeActivity = null; this.updateActivity(); }, this)); } protected get activity(): IActivity { @@ -483,14 +483,14 @@ export class CompositeActionItem extends ActivityActionItem { this._updateChecked(); this._updateEnabled(); - this.callOnDispose.push(dom.addDisposableListener(this.$container, dom.EventType.CONTEXT_MENU, e => { + this._register(dom.addDisposableListener(this.container, dom.EventType.CONTEXT_MENU, e => { dom.EventHelper.stop(e, true); this.showContextMenu(container); })); // Allow to drag - this.callOnDispose.push(dom.addDisposableListener(this.$container, dom.EventType.DRAG_START, (e: DragEvent) => { + this._register(dom.addDisposableListener(this.container, dom.EventType.DRAG_START, (e: DragEvent) => { e.dataTransfer.effectAllowed = 'move'; // Registe as dragged to local transfer @@ -502,7 +502,7 @@ export class CompositeActionItem extends ActivityActionItem { } })); - this.callOnDispose.push(new DragAndDropObserver(this.$container, { + this._register(new DragAndDropObserver(this.container, { onDragEnter: e => { if (this.compositeTransfer.hasData(DraggedCompositeIdentifier.prototype) && this.compositeTransfer.getData(DraggedCompositeIdentifier.prototype)[0].id !== this.activity.id) { this.updateFromDragging(container, true); @@ -539,7 +539,7 @@ export class CompositeActionItem extends ActivityActionItem { })); // Activate on drag over to reveal targets - [this.$badge, this.$label].forEach(b => new DelayedDragHandler(b, () => { + [this.badge, this.label].forEach(b => new DelayedDragHandler(b, () => { if (!this.compositeTransfer.hasData(DraggedCompositeIdentifier.prototype) && !this.getAction().checked) { this.getAction().run(); } @@ -578,35 +578,35 @@ export class CompositeActionItem extends ActivityActionItem { } focus(): void { - this.$container.focus(); + this.container.focus(); } protected _updateClass(): void { if (this.cssClass) { - dom.removeClasses(this.$label, this.cssClass); + dom.removeClasses(this.label, this.cssClass); } this.cssClass = this.getAction().class; if (this.cssClass) { - dom.addClasses(this.$label, this.cssClass); + dom.addClasses(this.label, this.cssClass); } } protected _updateChecked(): void { if (this.getAction().checked) { - dom.addClass(this.$container, 'checked'); - this.$container.setAttribute('aria-label', nls.localize('compositeActive', "{0} active", this.$container.title)); + dom.addClass(this.container, 'checked'); + this.container.setAttribute('aria-label', nls.localize('compositeActive', "{0} active", this.container.title)); } else { - dom.removeClass(this.$container, 'checked'); - this.$container.setAttribute('aria-label', this.$container.title); + dom.removeClass(this.container, 'checked'); + this.container.setAttribute('aria-label', this.container.title); } } protected _updateEnabled(): void { if (this.getAction().enabled) { - dom.removeClass(this.builder, 'disabled'); + dom.removeClass(this.element, 'disabled'); } else { - dom.addClass(this.builder, 'disabled'); + dom.addClass(this.element, 'disabled'); } } @@ -615,7 +615,7 @@ export class CompositeActionItem extends ActivityActionItem { this.compositeTransfer.clearData(DraggedCompositeIdentifier.prototype); - dom.removeNode(this.$label); + dom.removeNode(this.label); } } diff --git a/src/vs/workbench/browser/parts/notifications/notificationsCenter.ts b/src/vs/workbench/browser/parts/notifications/notificationsCenter.ts index fd3ecd2e007..c1aae8802de 100644 --- a/src/vs/workbench/browser/parts/notifications/notificationsCenter.ts +++ b/src/vs/workbench/browser/parts/notifications/notificationsCenter.ts @@ -106,9 +106,9 @@ export class NotificationsCenter extends Themable { private updateTitle(): void { if (this.model.notifications.length === 0) { - this.notificationsCenterTitle.innerText = localize('notificationsEmpty', "No new notifications"); + this.notificationsCenterTitle.textContent = localize('notificationsEmpty', "No new notifications"); } else { - this.notificationsCenterTitle.innerText = localize('notifications', "Notifications"); + this.notificationsCenterTitle.textContent = localize('notifications', "Notifications"); } } diff --git a/src/vs/workbench/browser/parts/notifications/notificationsViewer.ts b/src/vs/workbench/browser/parts/notifications/notificationsViewer.ts index 7e88bde2337..84a1f8fcfa2 100644 --- a/src/vs/workbench/browser/parts/notifications/notificationsViewer.ts +++ b/src/vs/workbench/browser/parts/notifications/notificationsViewer.ts @@ -426,10 +426,10 @@ export class NotificationTemplateRenderer { private renderSource(notification): void { if (notification.expanded && notification.source) { - this.template.source.innerText = localize('notificationSource', "Source: {0}", notification.source); + this.template.source.textContent = localize('notificationSource', "Source: {0}", notification.source); this.template.source.title = notification.source; } else { - this.template.source.innerText = ''; + this.template.source.textContent = ''; this.template.source.removeAttribute('title'); } } diff --git a/src/vs/workbench/common/resources.ts b/src/vs/workbench/common/resources.ts index 1727311648e..a044403632b 100644 --- a/src/vs/workbench/common/resources.ts +++ b/src/vs/workbench/common/resources.ts @@ -10,10 +10,10 @@ import * as paths from 'vs/base/common/paths'; import { RawContextKey, IContextKeyService, IContextKey } from 'vs/platform/contextkey/common/contextkey'; import { IModeService } from 'vs/editor/common/services/modeService'; import { IFileService } from 'vs/platform/files/common/files'; -import { dispose, IDisposable } from 'vs/base/common/lifecycle'; +import { Disposable } from 'vs/base/common/lifecycle'; import { Schemas } from 'vs/base/common/network'; -export class ResourceContextKey implements IContextKey<URI>, IDisposable { +export class ResourceContextKey extends Disposable implements IContextKey<URI> { static Scheme = new RawContextKey<string>('resourceScheme', undefined); static Filename = new RawContextKey<string>('resourceFilename', undefined); @@ -32,13 +32,14 @@ export class ResourceContextKey implements IContextKey<URI>, IDisposable { private _hasResource: IContextKey<boolean>; private _isfileSystemResource: IContextKey<boolean>; private _isFileSystemResourceOrUntitled: IContextKey<boolean>; - private toDispose: IDisposable[] = []; constructor( @IContextKeyService contextKeyService: IContextKeyService, @IFileService private readonly _fileService: IFileService, @IModeService private readonly _modeService: IModeService ) { + super(); + this._schemeKey = ResourceContextKey.Scheme.bindTo(contextKeyService); this._filenameKey = ResourceContextKey.Filename.bindTo(contextKeyService); this._langIdKey = ResourceContextKey.LangId.bindTo(contextKeyService); @@ -47,7 +48,8 @@ export class ResourceContextKey implements IContextKey<URI>, IDisposable { this._hasResource = ResourceContextKey.HasResource.bindTo(contextKeyService); this._isfileSystemResource = ResourceContextKey.IsFileSystemResource.bindTo(contextKeyService); this._isFileSystemResourceOrUntitled = ResourceContextKey.IsFileSystemResourceOrUntitled.bindTo(contextKeyService); - this.toDispose.push(_fileService.onDidChangeFileSystemProviderRegistrations(() => { + + this._register(_fileService.onDidChangeFileSystemProviderRegistrations(() => { const resource = this._resourceKey.get(); this._isfileSystemResource.set(resource && _fileService.canHandleResource(resource)); this._isFileSystemResourceOrUntitled.set(this._isfileSystemResource.get() || this._schemeKey.get() === Schemas.untitled); @@ -77,10 +79,6 @@ export class ResourceContextKey implements IContextKey<URI>, IDisposable { get(): URI { return this._resourceKey.get(); } - - dispose(): void { - this.toDispose = dispose(this.toDispose); - } } /** diff --git a/src/vs/workbench/parts/extensions/electron-browser/extensionsActions.ts b/src/vs/workbench/parts/extensions/electron-browser/extensionsActions.ts index 1bf667f3452..0b5c603141a 100644 --- a/src/vs/workbench/parts/extensions/electron-browser/extensionsActions.ts +++ b/src/vs/workbench/parts/extensions/electron-browser/extensionsActions.ts @@ -377,7 +377,7 @@ export class DropDownMenuActionItem extends ActionItem { public showMenu(): void { const actions = this.getActions(); - let elementPosition = DOM.getDomNodePagePosition(this.builder); + let elementPosition = DOM.getDomNodePagePosition(this.element); const anchor = { x: elementPosition.left, y: elementPosition.top + elementPosition.height + 10 }; this.contextMenuService.showContextMenu({ getAnchor: () => anchor, diff --git a/src/vs/workbench/parts/markers/electron-browser/markersPanelActions.ts b/src/vs/workbench/parts/markers/electron-browser/markersPanelActions.ts index f351fb2a143..d231e7b99fc 100644 --- a/src/vs/workbench/parts/markers/electron-browser/markersPanelActions.ts +++ b/src/vs/workbench/parts/markers/electron-browser/markersPanelActions.ts @@ -93,14 +93,12 @@ export interface IMarkersFilterActionItemOptions { export class MarkersFilterActionItem extends BaseActionItem { - private _toDispose: IDisposable[] = []; - private readonly _onDidChange: Emitter<void> = this._register(new Emitter<void>()); readonly onDidChange: Event<void> = this._onDidChange.event; private delayedFilterUpdate: Delayer<void>; private container: HTMLElement; - private element: HTMLElement; + private filterContainer: HTMLElement; private filterInputBox: HistoryInputBox; private controlsContainer: HTMLInputElement; private filterBadge: HTMLInputElement; @@ -123,7 +121,7 @@ export class MarkersFilterActionItem extends BaseActionItem { render(container: HTMLElement): void { this.container = container; DOM.addClass(this.container, 'markers-panel-action-filter-container'); - DOM.append(this.container, this.element); + DOM.append(this.container, this.filterContainer); this.adjustInputBox(); } @@ -157,9 +155,9 @@ export class MarkersFilterActionItem extends BaseActionItem { } private create(itemOptions: IMarkersFilterActionItemOptions): void { - this.element = DOM.$('.markers-panel-action-filter'); - this.createInput(this.element, itemOptions); - this.createControls(this.element, itemOptions); + this.filterContainer = DOM.$('.markers-panel-action-filter'); + this.createInput(this.filterContainer, itemOptions); + this.createControls(this.filterContainer, itemOptions); } private createInput(container: HTMLElement, itemOptions: IMarkersFilterActionItemOptions): void { @@ -271,11 +269,6 @@ export class MarkersFilterActionItem extends BaseActionItem { */ this.telemetryService.publicLog('problems.filter', data); } - - private _register<T extends IDisposable>(t: T): T { - this._toDispose.push(t); - return t; - } } export class QuickFixAction extends Action { @@ -354,7 +347,7 @@ export class QuickFixActionItem extends ActionItem { public onClick(event: DOM.EventLike): void { DOM.EventHelper.stop(event, true); - const elementPosition = DOM.getDomNodePagePosition(this.builder); + const elementPosition = DOM.getDomNodePagePosition(this.element); this.contextMenuService.showContextMenu({ getAnchor: () => ({ x: elementPosition.left + 10, y: elementPosition.top + elementPosition.height }), getActions: () => TPromise.wrap((<QuickFixAction>this.getAction()).getQuickFixActions()), diff --git a/src/vs/workbench/parts/preferences/browser/preferencesWidgets.ts b/src/vs/workbench/parts/preferences/browser/preferencesWidgets.ts index 725a95e7de2..642fc76e4e4 100644 --- a/src/vs/workbench/parts/preferences/browser/preferencesWidgets.ts +++ b/src/vs/workbench/parts/preferences/browser/preferencesWidgets.ts @@ -317,7 +317,7 @@ export class FolderSettingsActionItem extends BaseActionItem { } public render(container: HTMLElement): void { - this.builder = container; + this.element = container; this.container = container; this.labelElement = DOM.$('.action-title'); diff --git a/src/vs/workbench/parts/scm/electron-browser/scmViewlet.ts b/src/vs/workbench/parts/scm/electron-browser/scmViewlet.ts index d4ffc1ea54e..9c8b0a5b069 100644 --- a/src/vs/workbench/parts/scm/electron-browser/scmViewlet.ts +++ b/src/vs/workbench/parts/scm/electron-browser/scmViewlet.ts @@ -109,7 +109,7 @@ class StatusBarActionItem extends ActionItem { _updateLabel(): void { if (this.options.label) { - this.$e.innerHTML = renderOcticons(this.getAction().label); + this.label.innerHTML = renderOcticons(this.getAction().label); } } } From c739104cc1a4b1a76a4cab6c71ee14e316c3f12c Mon Sep 17 00:00:00 2001 From: Benjamin Pasero <benjpas@microsoft.com> Date: Mon, 27 Aug 2018 07:36:03 +0200 Subject: [PATCH 1263/1276] fix FileDialogContext not being bound --- src/vs/workbench/electron-browser/workbench.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/vs/workbench/electron-browser/workbench.ts b/src/vs/workbench/electron-browser/workbench.ts index 1295eac41da..c4c00dc70ca 100644 --- a/src/vs/workbench/electron-browser/workbench.ts +++ b/src/vs/workbench/electron-browser/workbench.ts @@ -93,7 +93,7 @@ import { IDecorationsService } from 'vs/workbench/services/decorations/browser/d import { ActivityService } from 'vs/workbench/services/activity/browser/activityService'; import URI from 'vs/base/common/uri'; import { IListService, ListService } from 'vs/platform/list/browser/listService'; -import { InputFocusedContext, IsMacContext, IsLinuxContext, IsWindowsContext } from 'vs/platform/workbench/common/contextkeys'; +import { InputFocusedContext, IsMacContext, IsLinuxContext, IsWindowsContext, FileDialogContext } from 'vs/platform/workbench/common/contextkeys'; import { IViewsService } from 'vs/workbench/common/views'; import { ViewsService } from 'vs/workbench/browser/parts/views/views'; import { INotificationService } from 'vs/platform/notification/common/notification'; @@ -616,6 +616,7 @@ export class Workbench extends Disposable implements IPartService { IsMacContext.bindTo(this.contextKeyService); IsLinuxContext.bindTo(this.contextKeyService); IsWindowsContext.bindTo(this.contextKeyService); + FileDialogContext.bindTo(this.contextKeyService); const sidebarVisibleContextRaw = new RawContextKey<boolean>('sidebarVisible', false); this.sideBarVisibleContext = sidebarVisibleContextRaw.bindTo(this.contextKeyService); From 3f8088b5c5f1d44b5e1af4a8e67448abbe66470e Mon Sep 17 00:00:00 2001 From: Joao Moreno <joao.moreno@microsoft.com> Date: Mon, 27 Aug 2018 09:14:48 +0200 Subject: [PATCH 1264/1276] remove transpileOnly flag from webpack --- extensions/shared.webpack.config.js | 2 -- 1 file changed, 2 deletions(-) diff --git a/extensions/shared.webpack.config.js b/extensions/shared.webpack.config.js index d816578c6e5..716610dc733 100644 --- a/extensions/shared.webpack.config.js +++ b/extensions/shared.webpack.config.js @@ -36,11 +36,9 @@ module.exports = function withDefaults(/**@type WebpackConfig*/extConfig) { } }, { // configure TypeScript loader: - // * only transpile because we have a separate compilation pipeline // * enable sources maps for end-to-end source maps loader: 'ts-loader', options: { - transpileOnly: true, compilerOptions: { "sourceMap": true, } From 47ab09936cbeea5f452243f12f850f44c801f145 Mon Sep 17 00:00:00 2001 From: Alex Dima <alexdima@microsoft.com> Date: Mon, 27 Aug 2018 09:47:42 +0200 Subject: [PATCH 1265/1276] Remove empty line in uri jsdoc --- src/vs/base/common/uri.ts | 1 - src/vs/monaco.d.ts | 1 - 2 files changed, 2 deletions(-) diff --git a/src/vs/base/common/uri.ts b/src/vs/base/common/uri.ts index eec9ccb001a..971bd2f13b0 100644 --- a/src/vs/base/common/uri.ts +++ b/src/vs/base/common/uri.ts @@ -275,7 +275,6 @@ export default class URI implements UriComponents { good.scheme === 'file'; good.path === '/coding/c#/project1'; good.fragment === ''; - const bad = URI.parse('file://' + '/coding/c#/project1'); bad.scheme === 'file'; bad.path === '/coding/c'; // path is now broken diff --git a/src/vs/monaco.d.ts b/src/vs/monaco.d.ts index 5db15b7f9a5..a7154a7bd85 100644 --- a/src/vs/monaco.d.ts +++ b/src/vs/monaco.d.ts @@ -181,7 +181,6 @@ declare namespace monaco { good.scheme === 'file'; good.path === '/coding/c#/project1'; good.fragment === ''; - const bad = Uri.parse('file://' + '/coding/c#/project1'); bad.scheme === 'file'; bad.path === '/coding/c'; // path is now broken From e8b3a72e8306105a4d559d2e85b36cec13dcb10d Mon Sep 17 00:00:00 2001 From: Sandeep Somavarapu <sasomava@microsoft.com> Date: Mon, 27 Aug 2018 10:41:40 +0200 Subject: [PATCH 1266/1276] Fix #57143 --- src/vs/workbench/parts/search/browser/replaceService.ts | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/vs/workbench/parts/search/browser/replaceService.ts b/src/vs/workbench/parts/search/browser/replaceService.ts index 32bd1d50ed6..bea4869c5e9 100644 --- a/src/vs/workbench/parts/search/browser/replaceService.ts +++ b/src/vs/workbench/parts/search/browser/replaceService.ts @@ -124,6 +124,10 @@ export class ReplaceService implements IReplaceService { revealIfVisible: true } }).then(editor => { + const disposable = fileMatch.onDispose(() => { + editor.input.dispose(); + disposable.dispose(); + }); this.updateReplacePreview(fileMatch).then(() => { let editorControl = editor.getControl(); if (element instanceof Match) { From 217d6cc7b76b15f76a3a061d3536b488f7099430 Mon Sep 17 00:00:00 2001 From: Johannes Rieken <johannes.rieken@gmail.com> Date: Mon, 27 Aug 2018 11:41:55 +0200 Subject: [PATCH 1267/1276] fix #57115 --- .../browser/parts/editor/breadcrumbsPicker.ts | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/src/vs/workbench/browser/parts/editor/breadcrumbsPicker.ts b/src/vs/workbench/browser/parts/editor/breadcrumbsPicker.ts index cdcf5418c16..07b284cb200 100644 --- a/src/vs/workbench/browser/parts/editor/breadcrumbsPicker.ts +++ b/src/vs/workbench/browser/parts/editor/breadcrumbsPicker.ts @@ -25,11 +25,11 @@ import { FileKind, IFileService, IFileStat } from 'vs/platform/files/common/file import { IConstructorSignature1, IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; import { HighlightingWorkbenchTree, IHighlighter, IHighlightingTreeConfiguration, IHighlightingTreeOptions } from 'vs/platform/list/browser/listService'; import { breadcrumbsPickerBackground, widgetShadow } from 'vs/platform/theme/common/colorRegistry'; -import { IThemeService } from 'vs/platform/theme/common/themeService'; import { IWorkspace, IWorkspaceContextService, IWorkspaceFolder } from 'vs/platform/workspace/common/workspace'; import { FileLabel } from 'vs/workbench/browser/labels'; import { BreadcrumbsConfig } from 'vs/workbench/browser/parts/editor/breadcrumbs'; import { BreadcrumbElement, FileElement } from 'vs/workbench/browser/parts/editor/breadcrumbsModel'; +import { IFileIconTheme, IWorkbenchThemeService } from 'vs/workbench/services/themes/common/workbenchThemeService'; export function createBreadcrumbsPicker(instantiationService: IInstantiationService, parent: HTMLElement, element: BreadcrumbElement): BreadcrumbsPicker { let ctor: IConstructorSignature1<HTMLElement, BreadcrumbsPicker> = element instanceof FileElement ? BreadcrumbsFilePicker : BreadcrumbsOutlinePicker; @@ -54,7 +54,7 @@ export abstract class BreadcrumbsPicker { constructor( parent: HTMLElement, @IInstantiationService protected readonly _instantiationService: IInstantiationService, - @IThemeService protected readonly _themeService: IThemeService, + @IWorkbenchThemeService protected readonly _themeService: IWorkbenchThemeService, @IConfigurationService private readonly _configurationService: IConfigurationService, ) { this._domNode = document.createElement('div'); @@ -88,7 +88,7 @@ export abstract class BreadcrumbsPicker { HighlightingWorkbenchTree, this._treeContainer, treeConifg, - <IHighlightingTreeOptions>{ useShadows: false, filterOnType: filterConfig.getValue() }, + <IHighlightingTreeOptions>{ useShadows: false, filterOnType: filterConfig.getValue(), showTwistie: false, twistiePixels: 12 }, { placeholder: localize('placeholder', "Find") } ); this._disposables.push(this._tree.onDidChangeSelection(e => { @@ -108,6 +108,16 @@ export abstract class BreadcrumbsPicker { } })); + // tree icon theme specials + dom.addClass(this._treeContainer, 'file-icon-themable-tree'); + dom.addClass(this._treeContainer, 'show-file-icons'); + const onFileIconThemeChange = (fileIconTheme: IFileIconTheme) => { + dom.toggleClass(this._treeContainer, 'align-icons-and-twisties', fileIconTheme.hasFileIcons && !fileIconTheme.hasFolderIcons); + dom.toggleClass(this._treeContainer, 'hide-arrows', fileIconTheme.hidesExplorerArrows === true); + }; + this._disposables.push(_themeService.onDidFileIconThemeChange(onFileIconThemeChange)); + onFileIconThemeChange(_themeService.getFileIconTheme()); + this._domNode.focus(); } @@ -338,7 +348,7 @@ export class BreadcrumbsFilePicker extends BreadcrumbsPicker { constructor( parent: HTMLElement, @IInstantiationService instantiationService: IInstantiationService, - @IThemeService themeService: IThemeService, + @IWorkbenchThemeService themeService: IWorkbenchThemeService, @IConfigurationService configService: IConfigurationService, @IWorkspaceContextService private readonly _workspaceService: IWorkspaceContextService, ) { From f5c03d09cd139989ff8b01784db5625eed3b7581 Mon Sep 17 00:00:00 2001 From: Sandeep Somavarapu <sasomava@microsoft.com> Date: Mon, 27 Aug 2018 11:51:44 +0200 Subject: [PATCH 1268/1276] Fix #47883 --- .../output/electron-browser/outputServices.ts | 154 +----------------- 1 file changed, 3 insertions(+), 151 deletions(-) diff --git a/src/vs/workbench/parts/output/electron-browser/outputServices.ts b/src/vs/workbench/parts/output/electron-browser/outputServices.ts index d4682f95819..52c5d9c1f1f 100644 --- a/src/vs/workbench/parts/output/electron-browser/outputServices.ts +++ b/src/vs/workbench/parts/output/electron-browser/outputServices.ts @@ -5,7 +5,6 @@ import * as nls from 'vs/nls'; import * as paths from 'vs/base/common/paths'; -import * as strings from 'vs/base/common/strings'; import * as extfs from 'vs/base/node/extfs'; import * as fs from 'fs'; import { TPromise } from 'vs/base/common/winjs.base'; @@ -17,7 +16,7 @@ import { IInstantiationService } from 'vs/platform/instantiation/common/instanti import { IStorageService, StorageScope } from 'vs/platform/storage/common/storage'; import { Registry } from 'vs/platform/registry/common/platform'; import { EditorOptions } from 'vs/workbench/common/editor'; -import { IOutputChannelIdentifier, IOutputChannel, IOutputService, Extensions, OUTPUT_PANEL_ID, IOutputChannelRegistry, OUTPUT_SCHEME, OUTPUT_MIME, MAX_OUTPUT_LENGTH, LOG_SCHEME, LOG_MIME, CONTEXT_ACTIVE_LOG_OUTPUT } from 'vs/workbench/parts/output/common/output'; +import { IOutputChannelIdentifier, IOutputChannel, IOutputService, Extensions, OUTPUT_PANEL_ID, IOutputChannelRegistry, OUTPUT_SCHEME, OUTPUT_MIME, LOG_SCHEME, LOG_MIME, CONTEXT_ACTIVE_LOG_OUTPUT } from 'vs/workbench/parts/output/common/output'; import { OutputPanel } from 'vs/workbench/parts/output/browser/outputPanel'; import { IPanelService } from 'vs/workbench/services/panel/common/panelService'; import { IModelService } from 'vs/editor/common/services/modelService'; @@ -37,7 +36,6 @@ import { RotatingLogger } from 'spdlog'; import { toLocalISOString } from 'vs/base/common/date'; import { IWindowService } from 'vs/platform/windows/common/windows'; import { ILogService } from 'vs/platform/log/common/log'; -import { binarySearch } from 'vs/base/common/arrays'; import { Schemas } from 'vs/base/common/network'; import { ILifecycleService } from 'vs/platform/lifecycle/common/lifecycle'; import { IContextKeyService } from 'vs/platform/contextkey/common/contextkey'; @@ -584,13 +582,7 @@ export class OutputService extends Disposable implements IOutputService, ITextMo if (channelData && channelData.file) { return this.instantiationService.createInstance(FileOutputChannel, channelData, uri); } - try { - return this.instantiationService.createInstance(OutputChannelBackedByFile, { id, label: channelData ? channelData.label : '' }, this.outputDir, uri); - } catch (e) { - // Do not crash if spdlog rotating logger cannot be loaded (workaround for https://github.com/Microsoft/vscode/issues/47883) - this.logService.error(e); - return this.instantiationService.createInstance(BufferredOutputChannel, { id, label: channelData ? channelData.label : '' }); - } + return this.instantiationService.createInstance(OutputChannelBackedByFile, { id, label: channelData ? channelData.label : '' }, this.outputDir, uri); } private doShowChannel(channel: IOutputChannel, preserveFocus: boolean): Thenable<void> { @@ -660,144 +652,4 @@ export class LogContentProvider { } return channel; } -} -// Remove this channel when https://github.com/Microsoft/vscode/issues/47883 is fixed -class BufferredOutputChannel extends Disposable implements OutputChannel { - - readonly id: string; - readonly label: string; - readonly file: URI = null; - scrollLock: boolean = false; - - protected _onDidAppendedContent: Emitter<void> = new Emitter<void>(); - readonly onDidAppendedContent: Event<void> = this._onDidAppendedContent.event; - - private readonly _onDispose: Emitter<void> = new Emitter<void>(); - readonly onDispose: Event<void> = this._onDispose.event; - - private modelUpdater: RunOnceScheduler; - private model: ITextModel; - private readonly bufferredContent: BufferedContent; - private lastReadId: number = void 0; - - constructor( - protected readonly outputChannelIdentifier: IOutputChannelIdentifier, - @IModelService private modelService: IModelService, - @IModeService private modeService: IModeService - ) { - super(); - - this.id = outputChannelIdentifier.id; - this.label = outputChannelIdentifier.label; - - this.modelUpdater = new RunOnceScheduler(() => this.updateModel(), 300); - this._register(toDisposable(() => this.modelUpdater.cancel())); - - this.bufferredContent = new BufferedContent(); - this._register(toDisposable(() => this.bufferredContent.clear())); - } - - append(output: string) { - this.bufferredContent.append(output); - if (!this.modelUpdater.isScheduled()) { - this.modelUpdater.schedule(); - } - } - - clear(): void { - if (this.modelUpdater.isScheduled()) { - this.modelUpdater.cancel(); - } - if (this.model) { - this.model.setValue(''); - } - this.bufferredContent.clear(); - this.lastReadId = void 0; - } - - loadModel(): TPromise<ITextModel> { - const { value, id } = this.bufferredContent.getDelta(this.lastReadId); - if (this.model) { - this.model.setValue(value); - } else { - this.model = this.createModel(value); - } - this.lastReadId = id; - return TPromise.as(this.model); - } - - private createModel(content: string): ITextModel { - const model = this.modelService.createModel(content, this.modeService.getOrCreateMode(OUTPUT_MIME), URI.from({ scheme: OUTPUT_SCHEME, path: this.id })); - const disposables: IDisposable[] = []; - disposables.push(model.onWillDispose(() => { - this.model = null; - dispose(disposables); - })); - return model; - } - - private updateModel(): void { - if (this.model) { - const { value, id } = this.bufferredContent.getDelta(this.lastReadId); - this.lastReadId = id; - const lastLine = this.model.getLineCount(); - const lastLineMaxColumn = this.model.getLineMaxColumn(lastLine); - this.model.applyEdits([EditOperation.insert(new Position(lastLine, lastLineMaxColumn), value)]); - this._onDidAppendedContent.fire(); - } - } - - dispose(): void { - this._onDispose.fire(); - super.dispose(); - } -} - -class BufferedContent { - - private data: string[] = []; - private dataIds: number[] = []; - private idPool = 0; - private length = 0; - - public append(content: string): void { - this.data.push(content); - this.dataIds.push(++this.idPool); - this.length += content.length; - this.trim(); - } - - public clear(): void { - this.data.length = 0; - this.dataIds.length = 0; - this.length = 0; - } - - private trim(): void { - if (this.length < MAX_OUTPUT_LENGTH * 1.2) { - return; - } - - while (this.length > MAX_OUTPUT_LENGTH) { - this.dataIds.shift(); - const removed = this.data.shift(); - this.length -= removed.length; - } - } - - public getDelta(previousId?: number): { value: string, id: number } { - let idx = -1; - if (previousId !== void 0) { - idx = binarySearch(this.dataIds, previousId, (a, b) => a - b); - } - - const id = this.idPool; - if (idx >= 0) { - const value = strings.removeAnsiEscapeCodes(this.data.slice(idx + 1).join('')); - return { value, id }; - } else { - const value = strings.removeAnsiEscapeCodes(this.data.join('')); - return { value, id }; - } - } -} +} \ No newline at end of file From 861f85fcd0264f729a44ff3e1ac5f9912a1c786d Mon Sep 17 00:00:00 2001 From: Sandeep Somavarapu <sasomava@microsoft.com> Date: Mon, 27 Aug 2018 12:00:45 +0200 Subject: [PATCH 1269/1276] Fix #54757 --- .../parts/extensions/common/extensions.ts | 2 +- .../electron-browser/extensionEditor.ts | 2 +- .../extensions/electron-browser/extensionsList.ts | 8 +++++--- .../extensions/node/extensionsWorkbenchService.ts | 15 ++++++++------- 4 files changed, 15 insertions(+), 12 deletions(-) diff --git a/src/vs/workbench/parts/extensions/common/extensions.ts b/src/vs/workbench/parts/extensions/common/extensions.ts index f80eddc2997..8b3d72dff9f 100644 --- a/src/vs/workbench/parts/extensions/common/extensions.ts +++ b/src/vs/workbench/parts/extensions/common/extensions.ts @@ -52,7 +52,7 @@ export interface IExtension { extensionPack: string[]; telemetryData: any; preview: boolean; - getManifest(): TPromise<IExtensionManifest>; + getManifest(): TPromise<IExtensionManifest | undefined>; getReadme(): TPromise<string>; hasReadme(): boolean; getChangelog(): TPromise<string>; diff --git a/src/vs/workbench/parts/extensions/electron-browser/extensionEditor.ts b/src/vs/workbench/parts/extensions/electron-browser/extensionEditor.ts index 76f96cf4612..22151f18517 100644 --- a/src/vs/workbench/parts/extensions/electron-browser/extensionEditor.ts +++ b/src/vs/workbench/parts/extensions/electron-browser/extensionEditor.ts @@ -429,7 +429,7 @@ export class ExtensionEditor extends BaseEditor { if (extension.extensionPack.length) { this.navbar.push(NavbarSection.ExtensionPack, localize('extensionPack', "Extension Pack"), localize('extensionsPack', "Set of extensions that can be installed together")); } - if (manifest.contributes) { + if (manifest && manifest.contributes) { this.navbar.push(NavbarSection.Contributions, localize('contributions', "Contributions"), localize('contributionstooltip', "Lists contributions to VS Code by this extension")); } if (extension.hasChangelog()) { diff --git a/src/vs/workbench/parts/extensions/electron-browser/extensionsList.ts b/src/vs/workbench/parts/extensions/electron-browser/extensionsList.ts index f6663b8a9bc..961904fe50b 100644 --- a/src/vs/workbench/parts/extensions/electron-browser/extensionsList.ts +++ b/src/vs/workbench/parts/extensions/electron-browser/extensionsList.ts @@ -181,9 +181,11 @@ export class Renderer implements IPagedRenderer<IExtension, ITemplateData> { data.extension = extension; extension.getManifest().then(manifest => { - const name = manifest && manifest.contributes && manifest.contributes.localizations && manifest.contributes.localizations.length > 0 && manifest.contributes.localizations[0].localizedLanguageName; - if (name) { data.description.textContent = name[0].toLocaleUpperCase() + name.slice(1); } - }, () => { }); + if (manifest) { + const name = manifest && manifest.contributes && manifest.contributes.localizations && manifest.contributes.localizations.length > 0 && manifest.contributes.localizations[0].localizedLanguageName; + if (name) { data.description.textContent = name[0].toLocaleUpperCase() + name.slice(1); } + } + }); } disposeElement(): void { diff --git a/src/vs/workbench/parts/extensions/node/extensionsWorkbenchService.ts b/src/vs/workbench/parts/extensions/node/extensionsWorkbenchService.ts index cf54929edc3..f35a103ec82 100644 --- a/src/vs/workbench/parts/extensions/node/extensionsWorkbenchService.ts +++ b/src/vs/workbench/parts/extensions/node/extensionsWorkbenchService.ts @@ -54,7 +54,8 @@ class Extension implements IExtension { private stateProvider: IExtensionStateProvider<ExtensionState>, public locals: ILocalExtension[], public gallery: IGalleryExtension, - private telemetryService: ITelemetryService + private telemetryService: ITelemetryService, + private logService: ILogService ) { } get type(): LocalExtensionType { @@ -210,8 +211,8 @@ class Extension implements IExtension { if (this.gallery.assets.manifest) { return this.galleryService.getManifest(this.gallery); } - this.telemetryService.publicLog('extensions:NotFoundManifest', this.telemetryData); - return TPromise.wrapError<IExtensionManifest>(new Error('not available')); + this.logService.error(nls.localize('Manifest is not found', "Manifest is not found"), this.id); + return TPromise.as(undefined); } return TPromise.as(this.local.manifest); @@ -441,7 +442,7 @@ export class ExtensionsWorkbenchService implements IExtensionsWorkbenchService, const locals = groupById[getGalleryExtensionIdFromLocal(local)]; locals.splice(locals.indexOf(local), 1); locals.splice(0, 0, local); - const extension = installedById[local.identifier.id] || new Extension(this.galleryService, this.stateProvider, locals, null, this.telemetryService); + const extension = installedById[local.identifier.id] || new Extension(this.galleryService, this.stateProvider, locals, null, this.telemetryService, this.logService); extension.locals = locals; extension.enablementState = this.extensionEnablementService.getEnablementState(local); return extension; @@ -560,7 +561,7 @@ export class ExtensionsWorkbenchService implements IExtensionsWorkbenchService, this.syncLocalWithGalleryExtension(result, gallery); } } else { - result = new Extension(this.galleryService, this.stateProvider, [], gallery, this.telemetryService); + result = new Extension(this.galleryService, this.stateProvider, [], gallery, this.telemetryService, this.logService); } if (maliciousExtensionSet.has(result.id)) { @@ -901,7 +902,7 @@ export class ExtensionsWorkbenchService implements IExtensionsWorkbenchService, let extension = this.installed.filter(e => areSameExtensions(e, gallery.identifier))[0]; if (!extension) { - extension = new Extension(this.galleryService, this.stateProvider, [], gallery, this.telemetryService); + extension = new Extension(this.galleryService, this.stateProvider, [], gallery, this.telemetryService, this.logService); } extension.gallery = gallery; @@ -914,7 +915,7 @@ export class ExtensionsWorkbenchService implements IExtensionsWorkbenchService, private onDidInstallExtension(event: DidInstallExtensionEvent): void { const { local, zipPath, error, gallery } = event; const installingExtension = gallery ? this.installing.filter(e => areSameExtensions(e, gallery.identifier))[0] : null; - const extension: Extension = installingExtension ? installingExtension : zipPath ? new Extension(this.galleryService, this.stateProvider, [local], null, this.telemetryService) : null; + const extension: Extension = installingExtension ? installingExtension : zipPath ? new Extension(this.galleryService, this.stateProvider, [local], null, this.telemetryService, this.logService) : null; if (extension) { this.installing = installingExtension ? this.installing.filter(e => e !== installingExtension) : this.installing; if (!error) { From a03ee32cd4d734c74b05682fec625dc9d5f3f693 Mon Sep 17 00:00:00 2001 From: isidor <inikolic@microsoft.com> Date: Mon, 27 Aug 2018 12:07:46 +0200 Subject: [PATCH 1270/1276] debug: make sure to dispose session if initialize or launc/ attach return an error fixes #57255 --- .../parts/debug/electron-browser/debugService.ts | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/src/vs/workbench/parts/debug/electron-browser/debugService.ts b/src/vs/workbench/parts/debug/electron-browser/debugService.ts index cadb15fa3e5..7a12d373bb5 100644 --- a/src/vs/workbench/parts/debug/electron-browser/debugService.ts +++ b/src/vs/workbench/parts/debug/electron-browser/debugService.ts @@ -693,6 +693,10 @@ export class DebugService implements IDebugService { launchJsonExists: root && !!this.configurationService.getValue<IGlobalConfig>('launch', { resource: root.uri }) }); }).then(() => session, (error: Error | string) => { + if (session) { + session.dispose(); + } + if (errors.isPromiseCanceledError(error)) { // Do not show 'canceled' error messages to the user #7906 return TPromise.as(null); @@ -706,11 +710,6 @@ export class DebugService implements IDebugService { } */ this.telemetryService.publicLog('debugMisconfiguration', { type: resolved ? resolved.type : undefined, error: errorMessage }); - if (!raw.disconnected) { - raw.disconnect(); - } else if (session) { - dispose(session); - } // Show the repl if some error got logged there #5870 if (this.model.getReplElements().length > 0) { @@ -724,6 +723,12 @@ export class DebugService implements IDebugService { } return undefined; }); + }).then(undefined, err => { + if (session) { + session.dispose(); + } + + return TPromise.wrapError(err); }); } From e68d2918640e994dd391ec140d473c718e9b656d Mon Sep 17 00:00:00 2001 From: Benjamin Pasero <benjpas@microsoft.com> Date: Mon, 27 Aug 2018 12:30:17 +0200 Subject: [PATCH 1271/1276] update distro for OSS --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 06337bac1e0..501755f95a4 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "code-oss-dev", "version": "1.27.0", - "distro": "4bd49e564426e4719c8f9f522a4d67d89de3fb26", + "distro": "280911fc2dd6bc4d1fe8320e5b7d611c034b87fb", "author": { "name": "Microsoft Corporation" }, From b7cbc1d2878e290f6ef3880e557c3386d5191969 Mon Sep 17 00:00:00 2001 From: isidor <inikolic@microsoft.com> Date: Mon, 27 Aug 2018 12:31:37 +0200 Subject: [PATCH 1272/1276] bulkEditService: do not throw if there is a readonly model #57032 --- .../services/bulkEdit/electron-browser/bulkEditService.ts | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/vs/workbench/services/bulkEdit/electron-browser/bulkEditService.ts b/src/vs/workbench/services/bulkEdit/electron-browser/bulkEditService.ts index 8086e115ae4..2d542bc09cf 100644 --- a/src/vs/workbench/services/bulkEdit/electron-browser/bulkEditService.ts +++ b/src/vs/workbench/services/bulkEdit/electron-browser/bulkEditService.ts @@ -180,9 +180,6 @@ class BulkEditModel implements IDisposable { if (!model || !model.textEditorModel) { throw new Error(`Cannot load file ${key}`); } - if (model.isReadonly()) { - throw new Error(localize('editorIsReadonly', "Cannot edit a read-only editor.")); - } let task: ModelEditTask; if (this._editor && this._editor.getModel().uri.toString() === model.textEditorModel.uri.toString()) { From 99188f71749b01f96f1bc78136c4a2858eb46909 Mon Sep 17 00:00:00 2001 From: isidor <inikolic@microsoft.com> Date: Mon, 27 Aug 2018 12:45:36 +0200 Subject: [PATCH 1273/1276] debug view model: first set focused stack frame and thread and only then emit fixes #57215 --- src/vs/workbench/parts/debug/common/debugViewModel.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/vs/workbench/parts/debug/common/debugViewModel.ts b/src/vs/workbench/parts/debug/common/debugViewModel.ts index efb8ee26930..b2d6e7b6d89 100644 --- a/src/vs/workbench/parts/debug/common/debugViewModel.ts +++ b/src/vs/workbench/parts/debug/common/debugViewModel.ts @@ -61,14 +61,14 @@ export class ViewModel implements IViewModel { } setFocus(stackFrame: IStackFrame, thread: IThread, session: ISession, explicit: boolean): void { - let shouldEmit = this._focusedSession !== session || this._focusedThread !== thread || this._focusedStackFrame !== stackFrame; + const shouldEmit = this._focusedSession !== session || this._focusedThread !== thread || this._focusedStackFrame !== stackFrame; + this._focusedStackFrame = stackFrame; + this._focusedThread = thread; if (this._focusedSession !== session) { this._focusedSession = session; this._onDidFocusSession.fire(session); } - this._focusedThread = thread; - this._focusedStackFrame = stackFrame; this.loadedScriptsSupportedContextKey.set(session && session.raw.capabilities.supportsLoadedSourcesRequest); From 169fdac3b936d932636950c1a87a487a21d5f947 Mon Sep 17 00:00:00 2001 From: Benjamin Pasero <benjpas@microsoft.com> Date: Mon, 27 Aug 2018 13:04:11 +0200 Subject: [PATCH 1274/1276] file watching - tweak loggers for more useful output --- .../services/files/electron-browser/fileService.ts | 4 ++-- .../files/node/watcher/nsfw/nsfwWatcherService.ts | 6 ++++++ .../files/node/watcher/nsfw/watcherService.ts | 2 +- .../files/node/watcher/unix/watcherService.ts | 2 +- .../node/watcher/win32/csharpWatcherService.ts | 14 +++++++++----- 5 files changed, 19 insertions(+), 9 deletions(-) diff --git a/src/vs/workbench/services/files/electron-browser/fileService.ts b/src/vs/workbench/services/files/electron-browser/fileService.ts index 44a594f32b3..ac357fc3700 100644 --- a/src/vs/workbench/services/files/electron-browser/fileService.ts +++ b/src/vs/workbench/services/files/electron-browser/fileService.ts @@ -1052,7 +1052,7 @@ export class FileService extends Disposable implements IFileService { this.undeliveredRawFileChangesEvents.push(event); if (this.environmentService.verbose) { - console.log('%c[node.js Watcher]%c', 'color: green', 'color: black', event.type === FileChangeType.ADDED ? '[ADDED]' : event.type === FileChangeType.DELETED ? '[DELETED]' : '[CHANGED]', event.path); + console.log('%c[File Watcher (node.js)]%c', 'color: blue', 'color: black', event.type === FileChangeType.ADDED ? '[ADDED]' : event.type === FileChangeType.DELETED ? '[DELETED]' : '[CHANGED]', event.path); } // handle emit through delayer to accommodate for bulk changes @@ -1066,7 +1066,7 @@ export class FileService extends Disposable implements IFileService { // Logging if (this.environmentService.verbose) { normalizedEvents.forEach(r => { - console.log('%c[node.js Watcher]%c >> normalized', 'color: green', 'color: black', r.type === FileChangeType.ADDED ? '[ADDED]' : r.type === FileChangeType.DELETED ? '[DELETED]' : '[CHANGED]', r.path); + console.log('%c[File Watcher (node.js)]%c >> normalized', 'color: blue', 'color: black', r.type === FileChangeType.ADDED ? '[ADDED]' : r.type === FileChangeType.DELETED ? '[DELETED]' : '[CHANGED]', r.path); }); } diff --git a/src/vs/workbench/services/files/node/watcher/nsfw/nsfwWatcherService.ts b/src/vs/workbench/services/files/node/watcher/nsfw/nsfwWatcherService.ts index 98691d9a030..02e302838be 100644 --- a/src/vs/workbench/services/files/node/watcher/nsfw/nsfwWatcherService.ts +++ b/src/vs/workbench/services/files/node/watcher/nsfw/nsfwWatcherService.ts @@ -87,10 +87,14 @@ export class NsfwWatcherService implements IWatcherService { absolutePath = path.join(e.directory, e.oldFile); if (!this._isPathIgnored(absolutePath, this._pathWatchers[request.basePath].ignored)) { undeliveredFileEvents.push({ type: FileChangeType.DELETED, path: absolutePath }); + } else if (this._verboseLogging) { + console.log(' >> ignored', absolutePath); } absolutePath = path.join(e.directory, e.newFile); if (!this._isPathIgnored(absolutePath, this._pathWatchers[request.basePath].ignored)) { undeliveredFileEvents.push({ type: FileChangeType.ADDED, path: absolutePath }); + } else if (this._verboseLogging) { + console.log(' >> ignored', absolutePath); } } else { absolutePath = path.join(e.directory, e.file); @@ -99,6 +103,8 @@ export class NsfwWatcherService implements IWatcherService { type: nsfwActionToRawChangeType[e.action], path: absolutePath }); + } else if (this._verboseLogging) { + console.log(' >> ignored', absolutePath); } } } diff --git a/src/vs/workbench/services/files/node/watcher/nsfw/watcherService.ts b/src/vs/workbench/services/files/node/watcher/nsfw/watcherService.ts index 680109ec93a..a0fc530b01d 100644 --- a/src/vs/workbench/services/files/node/watcher/nsfw/watcherService.ts +++ b/src/vs/workbench/services/files/node/watcher/nsfw/watcherService.ts @@ -41,7 +41,7 @@ export class FileWatcher { const client = new Client( getPathFromAmdModule(require, 'bootstrap'), { - serverName: 'Watcher', + serverName: 'File Watcher (nsfw)', args: ['--type=watcherService'], env: { AMD_ENTRYPOINT: 'vs/workbench/services/files/node/watcher/nsfw/watcherApp', 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 a83b1e7590e..475bdfca4ce 100644 --- a/src/vs/workbench/services/files/node/watcher/unix/watcherService.ts +++ b/src/vs/workbench/services/files/node/watcher/unix/watcherService.ts @@ -44,7 +44,7 @@ export class FileWatcher { const client = new Client( getPathFromAmdModule(require, 'bootstrap'), { - serverName: 'Watcher', + serverName: 'File Watcher (chokidar)', args, env: { AMD_ENTRYPOINT: 'vs/workbench/services/files/node/watcher/unix/watcherApp', diff --git a/src/vs/workbench/services/files/node/watcher/win32/csharpWatcherService.ts b/src/vs/workbench/services/files/node/watcher/win32/csharpWatcherService.ts index 93dc71bd159..4b5b8c78676 100644 --- a/src/vs/workbench/services/files/node/watcher/win32/csharpWatcherService.ts +++ b/src/vs/workbench/services/files/node/watcher/win32/csharpWatcherService.ts @@ -61,6 +61,10 @@ export class OutOfProcessWin32FolderWatcher { // Support ignores if (this.ignored && this.ignored.some(ignore => glob.match(ignore, absolutePath))) { + if (this.verboseLogging) { + console.log('%c[File Watcher (C#)]', 'color: blue', ' >> ignored', absolutePath); + } + return; } @@ -73,7 +77,7 @@ export class OutOfProcessWin32FolderWatcher { // 3 Logging else { - console.log('%c[File Watcher]', 'color: darkgreen', eventParts[1]); + console.log('%c[File Watcher (C#)]', 'color: blue', eventParts[1]); } } }); @@ -93,19 +97,19 @@ export class OutOfProcessWin32FolderWatcher { } private onError(error: Error | Buffer): void { - this.errorCallback('[FileWatcher] process error: ' + error.toString()); + this.errorCallback('[File Watcher (C#)] process error: ' + error.toString()); } private onExit(code: number, signal: string): void { if (this.handle) { // exit while not yet being disposed is unexpected! - this.errorCallback(`[FileWatcher] terminated unexpectedly (code: ${code}, signal: ${signal})`); + this.errorCallback(`[File Watcher (C#)] terminated unexpectedly (code: ${code}, signal: ${signal})`); if (this.restartCounter <= OutOfProcessWin32FolderWatcher.MAX_RESTARTS) { - this.errorCallback('[FileWatcher] is restarted again...'); + this.errorCallback('[File Watcher (C#)] is restarted again...'); this.restartCounter++; this.startWatcher(); // restart } else { - this.errorCallback('[FileWatcher] Watcher failed to start after retrying for some time, giving up. Please report this as a bug report!'); + this.errorCallback('[File Watcher (C#)] Watcher failed to start after retrying for some time, giving up. Please report this as a bug report!'); } } } From 2920b3f56e3c4aa89a3d21f4c09a489606629d07 Mon Sep 17 00:00:00 2001 From: isidor <inikolic@microsoft.com> Date: Mon, 27 Aug 2018 13:04:42 +0200 Subject: [PATCH 1275/1276] debug: reveal debugService.sendAllBreakpoints fixes #57214 --- src/vs/workbench/parts/debug/common/debug.ts | 6 ++++++ .../workbench/parts/debug/electron-browser/debugService.ts | 2 +- .../workbench/parts/debug/electron-browser/debugSession.ts | 2 +- src/vs/workbench/parts/debug/test/common/mockDebug.ts | 4 ++++ 4 files changed, 12 insertions(+), 2 deletions(-) diff --git a/src/vs/workbench/parts/debug/common/debug.ts b/src/vs/workbench/parts/debug/common/debug.ts index 95dcc3ec20e..799ba33fb8e 100644 --- a/src/vs/workbench/parts/debug/common/debug.ts +++ b/src/vs/workbench/parts/debug/common/debug.ts @@ -669,6 +669,12 @@ export interface IDebugService { */ removeFunctionBreakpoints(id?: string): TPromise<void>; + /** + * Sends all breakpoints to the passed session. + * If session is not passed, sends all breakpoints to each session. + */ + sendAllBreakpoints(session?: ISession): TPromise<any>; + /** * Adds a new expression to the repl. */ diff --git a/src/vs/workbench/parts/debug/electron-browser/debugService.ts b/src/vs/workbench/parts/debug/electron-browser/debugService.ts index 7a12d373bb5..7c923be3ad0 100644 --- a/src/vs/workbench/parts/debug/electron-browser/debugService.ts +++ b/src/vs/workbench/parts/debug/electron-browser/debugService.ts @@ -992,7 +992,7 @@ export class DebugService implements IDebugService { return this.configurationManager; } - private sendAllBreakpoints(session?: ISession): TPromise<any> { + sendAllBreakpoints(session?: ISession): TPromise<any> { return TPromise.join(distinct(this.model.getBreakpoints(), bp => bp.uri.toString()).map(bp => this.sendBreakpoints(bp.uri, false, session))) .then(() => this.sendFunctionBreakpoints(session)) // send exception breakpoints at the end since some debug adapters rely on the order diff --git a/src/vs/workbench/parts/debug/electron-browser/debugSession.ts b/src/vs/workbench/parts/debug/electron-browser/debugSession.ts index b9d3af99d1f..ae2b8c72761 100644 --- a/src/vs/workbench/parts/debug/electron-browser/debugSession.ts +++ b/src/vs/workbench/parts/debug/electron-browser/debugSession.ts @@ -268,7 +268,7 @@ export class Session implements ISession { }; // Send all breakpoints - this.debugService.setBreakpointsActivated(true).then(sendConfigurationDone, sendConfigurationDone) + this.debugService.sendAllBreakpoints(this).then(sendConfigurationDone, sendConfigurationDone) .done(() => this.fetchThreads(), errors.onUnexpectedError); })); diff --git a/src/vs/workbench/parts/debug/test/common/mockDebug.ts b/src/vs/workbench/parts/debug/test/common/mockDebug.ts index 6e272e451b8..eaa8b94a0c3 100644 --- a/src/vs/workbench/parts/debug/test/common/mockDebug.ts +++ b/src/vs/workbench/parts/debug/test/common/mockDebug.ts @@ -39,6 +39,10 @@ export class MockDebugService implements IDebugService { public focusStackFrame(focusedStackFrame: IStackFrame): void { } + sendAllBreakpoints(session?: ISession): TPromise<any> { + return TPromise.as(null); + } + public addBreakpoints(uri: uri, rawBreakpoints: IBreakpointData[]): TPromise<IBreakpoint[]> { return TPromise.as(null); } From 7a803e5a05cc9fc1364fbc237ddf2ec58081ebf1 Mon Sep 17 00:00:00 2001 From: Johannes Rieken <johannes.rieken@gmail.com> Date: Mon, 27 Aug 2018 13:47:53 +0200 Subject: [PATCH 1276/1276] don't expose the filter on type option yet, #55004 --- src/vs/workbench/browser/parts/editor/breadcrumbs.ts | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/vs/workbench/browser/parts/editor/breadcrumbs.ts b/src/vs/workbench/browser/parts/editor/breadcrumbs.ts index 75077d4db4d..5a11594b7d8 100644 --- a/src/vs/workbench/browser/parts/editor/breadcrumbs.ts +++ b/src/vs/workbench/browser/parts/editor/breadcrumbs.ts @@ -144,11 +144,11 @@ Registry.as<IConfigurationRegistry>(Extensions.Configuration).registerConfigurat localize('symbolpath.last', "Only show the current symbol in the breadcrumbs view."), ] }, - 'breadcrumbs.filterOnType': { - description: localize('filterOnType', "Controls whether the breadcrumb picker filters or highlights when typing."), - type: 'boolean', - default: false - }, + // 'breadcrumbs.filterOnType': { + // description: localize('filterOnType', "Controls whether the breadcrumb picker filters or highlights when typing."), + // type: 'boolean', + // default: false + // }, } });